Effective Debugging 読書ノート

著者:

Diomidis Spinellis

訳者:

黒川 利明

出版社:

オライリー・ジャパン

ISBN:

978-4-87311-799-7

関連 URL:

O’Reilly Japan - Effective Debugging

まえがき

  • 本書は経験を積んだ開発者向けに書かれている。

  • 本書で紹介するデバッグ技法は、あえて詳細にまでこだわって記述した。

本書の内容

  • 本書で扱うテーマは、一般的なものからより特殊なものに並んでいる。

本書の利用法

  1. 戦略と手法

  2. スキルとツール

    • <慣れ親しんだツールを使い続ける安楽さを放棄して、より高度なツールを習得する学習に挑戦する>

  3. 技法のアイデア

仕事の流儀

  1. ソフトウェア設計で行うすべての事項

    • 最高水準のメカニズム

    • デバッグモード

    • ログのメカニズム

    • コマンドラインツールによるスクリプトで分析する

    • エラーを見せる

    • コアダンプを取得する方法を用意する

    • 非決定性のあるものを最小化する

  2. ソフトウェア構築の手順

    • 同僚

    • 単体テスト

    • assertion

    • コードの品質

    • 非決定性のあるもの排除

  3. 開発と運用の管理で行うこと

    • 課題管理システム

    • 問題をトリアージ(この本はどういうわけか医療用語がしばしば現れる)

    • バージョン管理システム

    • ツールや環境の多様性を担保する

    • ライブラリーのソースや高度なツールを買う

    • etc.

用語についての注意

  • ISO/IEC/IEEE 24765:2010 という規格で用語が定義されているので、それに準拠すると言っている。

    • 「故障」「欠陥」は fault, defect, bug の意味にとる。

    • 「障害」は failure の意味にとる。

    • <故障や欠陥という用語が障害を表すのに使われることが、IOS 標準でも認められているが、混乱を招くことがある>

  • Unix を Unix の原則や API に従うシステムすべてに使う。

  • ルーチンをメンバー関数、メソッド、関数、手続き、サブルーチンの総称として使う。

本書の表記法

  • <コマンドラインツールのインターフェースは何十年も変わらないのに、GUI ではバージョンごとに異なる>

1 章 高水準戦略

項目 1: あらゆる問題を課題管理システムで扱う

  • <課題管理システムに登録されていない問題を扱うことは断固拒否すること> か。これは肝に銘じておきたい。

  • 問題の関係者(取引先の名前とか)を明らかにするのは優先度を決めるのに有用だ。

  • 進捗のドキュメントを残すことも重要だ。

知らなかった単語:

JIRA, SaaS, オンプレミス

項目 2: 問題に対する洞察を得るにはウェブで焦点を絞って検索する

  • コード専用の検索エンジンを使ってみるのも吉。

  • 質問の出し方

知らなかった単語:

SSCCE, SourceLair, JSFiddle

項目 3: 前条件と後条件が満たされていることを確認する

  • ルーチンだけでなく、高水準の操作や設定に対しても同じ手法を使える。

項目 4: 問題からバグをドリルアップするかプログラムの先頭からバグへドリルダウンする

  • ドリルアップ

    1. デバッガーやコアダンプが使える場合は簡単。

    2. フリーズの場合はうまく↑に帰着させる。

    3. エラーメッセージが出る場合は grep する。

  • ドリルダウンはプロファイルや脆弱性診断

    • メモリ食い過ぎ

    • 時間かかり過ぎ

    • セキュリティー

    • 信頼性

項目 5: 既知の正常なシステムと問題を起こしているシステムとの違いを検出する

  • トレースツールについて

    • 汎用:DTrace, SystemTap

    • システムコール:strace, truss, Procmon

    • DLL トレース: ltrace, Procmon

    • ネットワークトレース: tcpdump, Wireshark

    • その他 SQL データベース呼び出しをトレースするもの等

  • 環境変数、OS, etc. 多過ぎるシステムの振る舞いに影響する要素。

  • バージョン間二分探索 (git bisect)

  • ログファイルの diff では先に本質的でない行をフィルターしておくのがコツだ。例えば grep -v などでノイズを除去する。場合によっては sort してからの comm の投入まである。

    • 本書のコマンドライン例では awksort の結果二つのストリームを comm -23 しているものを紹介している。

項目 6: ソフトウェアのデバッグ機能を使う

  • シェルの -x オプション。

  • 各種コマンドラインツールの --verbose オプション。

  • SQL の explain 文。

知らなかった単語:

Postfix

項目 7: ビルドと実行環境を多様化する

  • 実行環境を変えてみることで、意外なバグが見つかるかもしれない。C/C++ のようにハードウェアと強く結びつく言語で書かれたソフトウェアでは特に期待できる。

  • 他の実行環境でデバッグする三つの方式

    1. 仮想マシンソフト

    2. 小型の安価な計算機 e.g. Raspberry Pi; Windows や OS X ユーザーには有益。

    3. クラウドベースのホストを借りる

  • 他のコンパイラーによるセカンドオピニオンが役に立つ。

  • アルゴリズム自体のデバッグとして、他言語(普通は高水準なもの)でコードを書き起こすという手法もある。

項目 8: 作業の焦点を最も重要な問題に絞る

  • デバッグの効率を上げるため、バグの優先度をつける。

  • 優先度が低いものは思い切って無視する。

  • レガシーサポート、後方互換性、見てくれ、使用頻度の低い機能は優先しない。

2 章 汎用の手法と実践

項目 9: デバッグを成功させるために心の準備をする

  • <問題が再現可能な場合は、間違いなく解決できる>

  • <寝ている間も取り組む>

  • <継続的に環境、ツール、知識に投資しなければならない>

項目 10: 問題の効率的な再現を可能にする

  • 問題再現の最短手順のことを SSCCE と呼ぶようだ。

  • 再現可能な実行環境。

知らなかった単語:

Docker, Ansible, CFEngine, Chef, Puppet, Salt

システム構成管理ツール

項目 11: 変更から結果までのターンアラウンド時間を最小化する

ラウンドトリップ時間のようなものか。

項目 12: 複雑なテストシナリオを自動化する

  • Lua という言語で C 言語の三角関数のテストコードを書いているのだが、利点が何なのかわかりにくい。テストコードの生産性が C より高いとか?

項目 13: デバッグデータを包括的に概観する

  • データ全てを目の前に適切に並べると良い。関連性、パターンが見つかりやすくなる。

  • 老眼鏡をかけてでもフォントを小さくしてモニターに映る情報量を増やす。

  • モニターで見るものと紙で見るものを動と静で区別する。

項目 14: ソフトウェアのアップデートを考える

  • 大抵の場合、サードパーティー製コードのせいだと思ったバグは、自分の問題によるものだ。

項目 15: サードパーティソースコードを調べて洞察を得る

  • どのように動作するのかをよく理解するための工程。

  • IDE や ctags のコードナビゲーション機能を上手く活用して目当てのコードを探しやすくする。

  • ライブラリーがオープンソースであれば問答無用。商用であっても保険だと思ってコードを買う。

項目 16: 特別な監視およびテスト装置を使う

  • 前半はスペシャル過ぎて私の参考にならない。

  • I/O やネットワークとかハード間のやりとり。

知らなかった単語:

Wireshark, tcpdump -w

項目 17: 失敗による結果をさらに際立たせる

  • ロボトミー(この本は医療用語がよく出るな)して、望みのように実行パスを強制する。例えば if 文の条件などは容易に改造できる。

  • 定数を極端な値に書き換えて、正常時との振る舞いの差を際立たせる。本書では CAD の例や RPG のキャラクターの属性値を挙げている。

知らなかった単語:

ファジング (fuzzing?)

項目 18: 手に負えないシステムのデバッグを自分のデスクで行えるようにする

  • リモートアクセスの話題。

  • 本書では KVM over IP と標語的に表現している。

知らなかった単語:

TeamViewer, strace, truss, シム

項目 19: デバッグタスクを自動化する

  • which コマンドの実行が遅いのを調べる例は興味深い。自分でもやってみたい。

    • Cygwin でちょっと試したら、シェル組み込みの time しかなくてダメだった。インストーラーで明示的にパッケージを取得する必要がある。

項目 20: デバッグの前後で大掃除をする

  • コードクリーニングにはリスクがないこともない。

  • 作業の過程で得られた assertion, ログ出力文、デバッグコマンドは何らかの形で残す。

項目 21: 問題を起こすクラスのすべてのインスタンスを修正する

  • 同じ欠陥を同時に潰すのが肝要。なおかつ、二度と起こらないように処置する。

  • この過程でも grepsort -u が役に立つ。

3 章 汎用ツールと技法

The Art of Command Line は気になるから確認しよう。

項目 22: デバッグデータを Unix コマンドラインツールで分析する

  • IDE だけでは問題を検討する能力が十分でないことがある。

  • Unix ツールボックスのプログラムを短いパイプラインに組み合わせ、コマンドラインプロンプトから実行する方法が(スクリプトの使用より)効果を発揮する。

  • Windows では Cygwin がいちばんだ。

  • テキストでないデータはテキストに変換してから処理する。

知らなかった単語:

nm, dumpbin, javap

項目 23: コマンドラインツールのオプションとイディオムを活用する

  • grep のコツについて。特にオプション -l, -r, -v, --color など。

  • リダイレクト command 2>&1 | more のようにすると標準出力と標準エラーを同時に流せる。

  • 長い時間がかかるコマンドの実行に printf 'a' を添えて音を鳴らす。

    • 今試したら無音だった……。

項目 24: デバッグデータをエディタで調べる

  • 本物のエディターを使うこと。

  • テキスト同士の差分を比較する前に、本質的でない違いを「処理」しておくと効率的だ。

項目 25: 作業環境を最適化する

  • CPU やメモリは強力にしておくのが鉄則。

  • キーバインド、エイリアス、スクリプト、ショートカット、環境変数等々の個人的設定も入念に整える。

  • テキスト入力についての自動補完は重要。

この項目に関しては本書をいちいち参照したほうがよさそうだ。

  • <ツールに費やした投資が何倍にもなって返ってくる> (p. 61)

  • ssh 関連のアドバイスを理解する知識がない。まずい。

  • GUI とプロンプトを行ったり来たりする「コスト」を最小化しておく。

  • いわゆるドットファイルのリポジトリーを構築しておき、あらゆるホスト(仕事場)で同じ設定を利用できるようにしておく。

項目 26: バグの原因と経緯とをバージョン管理システムで探す

git のよく使うコマンドラインが紹介されている。

項目 27: 独立なプロセスからなるシステムの監視ツールを使う

知らなかった単語:

Nagios

4 章 デバッガ技法

項目 28: シンボリックデバッグ用にコンパイルしたコードを使う

  • コンパイラーやリンカーのオプションで、各ソースファイルに関連する命令、メモリアドレス、行番号、等々をオブジェクトコードに埋め込めるものがある。

  • いわゆるデバッグビルドの話題。最適化オプションは「なし」とする。

項目 29: コードをステップ実行する

  • ステップ実行中は step over やブレイクポイントを使いこなしたい。

項目 30: コードとデータのブレークポイントを活用する

  • 行、ルーチンに対してブレイクポイントを設定できる。場合によっては exitabort にも設定することがある。

  • データに対するブレイクポイントも存在する。これはウォッチポイントなどと呼ぶものだ。

項目 31: 逆デバッグ機能をよく知っておく

  • Visual Studio でいうところの IntelliTrace の機能を逆デバッグ機能と呼ぶ。

  • gdb では reverse- で始まるコマンド群が相当する。

項目 32: ルーチン間の呼び出しに沿って探索する

  • スタックフレームの話題。

  • gdb では frame n, up, down のコマンドがある。

項目 33: 変数と式の値を調べてエラーを見つける

  • 特にローカル変数に対して値を調べる。

  • 任意の式の値も表示できる。Visual Studio ならば Quick Watch であり、 gdb ならば expression がその機能だ。

  • リアルタイムで監視するならばウォッチが有用だ。

  • 特別なデータ構造のオブジェクトについては専用のデバッガー拡張、ツールを用いる。

項目 34: 実行プロセスにどのようにデバッガをアタッチするかを知っておく

これは高級で手に負えない。

項目 35: コアダンプの扱い方を知っておく

  • Windows の場合は注意を要する。専用の API を呼ばないとプロセスはダンプを生成しない。

  • マネージド環境の言語ではコアダンプ的なものは期待できない。

  • コアダンプのデバッグには p. 90 にあるように事前に組織的な準備が必要。ユーザーからデータを送信することが必要なので、開発側に相当な覚悟がいる。

項目 36: デバッグツールを整備する

  • <デバッグは GUI を使うほうが常に生産性が上がる> (p. 91)

  • IDE を使用しているならばまずは OK だ。色々考えないといけないのは gdb のようなタイプのデバッグツールメインのときだ。

知らなかった単語:

DDD, bashdb, remake, pydb

  • .gdbinit の内容いろいろ。

  • gdb スクリプトなるものもある。

項目 37: アセンブラコードとハードのメモリ内容を確認する方法を知っておく

  • 計算機の内部表現をよく知っていると、機械語レベルのデータをデバッグできる。

  • 昔のゲーム機のエミュレーターも教えてあげたい。

5 章 プログラミング技法

項目 38: 怪しいコードをレビューして手動で実行する

  • アナログ手法でコード(アルゴリズム)をデバッグする。

    • 敢えて電卓を使う。

    • データ構造を紙やホワイトボードにペンで描く。キャンバスは大きいほど良い。

  • 物理的なオブジェクトもムリヤリ使うとなお良い。

項目 39: コードとその内容を同僚に説明する

  • コードを説明すると、脳の異なる部分が働いて問題の原因が明らかになりやすい。というか、レビューしてもらうと有益な指摘が返ってくることが普通に期待できる。

  • マルチパーティーアルゴリズムとは何だ?

項目 40: デバッグ機能を追加する

  • ログ出力、情報表示、専用コマンドなどを有効化するモード。

  • マインクラフトのデバッグワールドの例は面白い。

  • 組み込みの事情はよくわからないので飛ばす。

項目 41: ロギング文を追加する

  • ログ出力とデバッガーは相補的に利用できる。

  • ログテキストに適切な書式を与えておくことで、後々のフィルターやクエリーが効率よくなる。

  • ログ出力には自作ではなく専用フレームワークを利用する。

  • 組み込みの事情はよくわからないので飛ばす。

  • なお、非テキストベースのソフトウェアでは「ログ」に工夫が要る。メッセージボックスを出すような。

項目 42: ユニットテストを使う

  • 単体テストのフレームワークを利用する。次のような利点が考えられる:

    • テストを反復的に実施しやすくなる。

    • リファクタリングを気兼ねなしに?実施しやすくなる。

項目 43: アサーションを使う

  • 隙あらば assert 文をコードに埋め込む。事前条件、不変条件、事後条件を明白にできる。

  • コンパイルオプションを設定して assert 文をデバッグビルドでのみ有効化する。

項目 44: デバッグしたプログラムに変動を与えて推理を検証する

  • これは学習目的か?

項目 45: 稼働例と問題コードとの相違を最小化する

  • 一方を他方に「変形」させていく途中で問題を生じさせる何かを発見できるはずだ。

項目 46: 怪しいコードを単純にする

  • 分割統治の話か。

項目 47: 怪しいコードを他の言語で書き直す

  • 問題コードをより表現力に富む言語で書き直す。

  • 元の問題を解決するには、書き直したものにすっかり置き換えるか、項目 45 の技法を両者に対して適用するか。

項目 48: 怪しいコードの可読性と構造を改善する

本項はリファクタリングについての基本的な事項が詳細に述べられている。必要に応じて本書を参照したい。

項目 49: バグの症状を取り除くのではなく、原因を取り除く

  • 問題を一般化して考えてから解決する。

  • 背後にある原因の方を重視するのが本質的な解決法であって、対処療法的修正は意味がない。

6 章 コンパイル時の技法

項目 50: 生成コードを調べる

  • プリプロセッサーを経た直後の C/C++ のコードを得るには、

    • gcc ならば -E を、

    • cl ならば /E オプションを指定する。

  • マクロ展開を確認するのに役に立つ。

  • アセンブリコードを得るには

    • gcc ならば -S を、

    • cl ならば /Fa オプションを指定する。

    • Java ならば javap -c とする。

  • ここで挙げられている Java の文字列接続の例で、ソースコードにはない StringBuilder がアセンブリコードに出現するという話が面白い。

項目 51: 静的プログラム解析ツールを使う

  • 静的プログラム解析ツールとは、ソースコードを診断するツールという解釈でよいか?

    • コンパイラーも静的プログラム解析ツールの一種であると解釈したい。

  • GrammaTech CodeSonar, Coverity Code Advisor, FindBugs, Polyspace Bug Finder などの解析ツールがある。

    • 他に知りたければ static code analyzer で検索すればいい。

    また、言語によっては lint で終わる名前の解析ツールがある。

    • xmllint, pylint, etc.

  • 警告レベルを最高にするときは、コンパイラーで最適化オプションを最大レベルにしてからにする。警告をエラー扱いにするのはその後とする。

    • gcc -Wallcl \WX のように指定する。

  • 複数のツールを併用するといい。

  • 解析ツールによる診断工程をビルドサイクルに組み込む。

項目 52: ビルドと実行を決定的に構成する

翻訳本によるあるように、本書でも英語の deterministic を「決定的」とい表現している。辞書で調べると、計算機科学の文脈では次の意味にとるのが妥当らしい:

Having each state depend only on the immediately previous state, as opposed to having some states depend on backtracking where there may be multiple possible next actions and no way to choose between them except by trying each one and backtracking upon failure.

  • ある実行で生じた問題が、別の実行では生じない。こういう現象は起こってほしくない。

  • ASLR: これはわからない。

  • 同じコードをビルドする度にバイナリーレベルで異なるものが生成されるのはできれば避けたい。しかし、これは意外に簡単ではない。

項目 53: デバッグライブラリを使用してチェックするよう構成する

特に C/C++ の話となる。

  • C++ の STL を利用したコードをデバッグビルドするときの例を説明している。GNU の実装では _GLIBCXX_DEBUG をプリプロセッサーに定義しておくことで、有害なコードに対しての警告メッセージが有効になる。

  • メモリー確保および解放コードについてもサポートがあるものが多い。 mtrace のようなツールもある。

7 章 実行時の技法

テスト、ログ、監視ツールの話題。

項目 54: テストケースを作って問題を発見する

  • Defect-Driving Testing

  • テストケース、手順、材料はパッケージということか。これらは最小化すること。

  • 結果がわかったらテストケースに対応するテストを追加する。

  • カバレッジツールいろいろ。

項目 55: 迅速に失敗させる

  • 最速で問題を起こすようにソフトウェアを構成する。

  • assert 文やシェルの -e オプションのことを含む。

項目 56: アプリケーションのログファイルを調べる

  • 障害を検討するのならば、まずはログファイルを調べる。

  • ログファイルの在り処がわからない場合を説明している。

    • Unix では /var/logs を検索する。

    • Windows では Event Viewer を検索する。

  • ソフトウェアはログの出力量を制御できるはずなので、適宜設定し直す。

  • syslogd の話がわからない。

  • Java の Apache log4j の紹介。

  • ログレコードの分析方法など。

  • ELK, Logstash, loggy, Splunk, wevtutil

  • 障害が起こった時刻の前後のエントリーを調べるか、失敗したコマンド名のような、関係する文字列をログから検索する。その後にログを遡る。

  • 基本的にはテキスト処理になる。

項目 57: システムとプロセスの演算操作のプロファイルをとる

  • 性能のデバッグ。

  • Unix ならば top で、Windows ならば Task Manager でプロファイルを見る。

  • マルチコアマシンでは CPU 利用率のパーセントの解釈に注意。例えば 12% で安心だと思ったら 8 コアマシンなので実質 100% に近いということもある。

  • 飽和度の概念が難しい。

  • CPU, I/O, メモリ別に対策が異なる。

    • CPU は前述のとおり。

    • メモリは working set memory size でソートをすることでわかる。

    • I/O は以下のツールを用いる:

      • Unix: iostat, netstat, nfsstat, vmstat

      • Windows: perfmon

  • プロファイル対策は p. 159 に詳細に述べられている。

  • メモリモニターは色々ある:

項目 58: コード実行をトレースする

  • サードパーティーライブラリーや OS のコンポーネントへの呼び出しを調べたい。

  • 呼び出しトレースツールには次のようなものがある:

    • ltrace, strace, ktrace, truss, JProfiler, Process Monitor

  • トレーサーの出力を Unix ツールで処理して、デバッグ能力を向上させる。 strace -fo >( ... ) prog のようにする。

  • インタープリター形式言語のほとんどがトレースオプションを提供している。

    • Python で言えば python -m trae --trace ... が該当する。

  • DTrace, SystemTap, LTTng

  • dtrace コマンドの紹介をしている。

  • JVM には Byteman を使う。

  • Windows ならば Windows ADK が含む WPT が含む WPR と WPA を使う。

項目 59: 動的なプログラム解析ツールを使う

  • 実行が劇的に遅いので、デバッグ中の問題を示すためだけの特別なテストに対して使うのが最良。

  • この手のツールは未初期化変数の使用、リーク、不当なメモリアクセスの検出機能を備えている。

  • Valgrind が広く使われている。

  • JavaScript ならば Jalangi が使える。

8 章 マルチスレッドコードのデバッグ

本章の内容は低水準並行処理機能を明示的に使用したコードについてのものだ(普通は高水準 API を使用する)。

項目 60: デッドロックを事後検討デバッグで分析する

  • 二人が同じ何かを譲り合って先に進まない状態がデッドロックだ。

  • <デッドロックは実は並行性のバグの中で一番分析しやすい種類> (p. 170) のものらしい。

  • 対象のプログラムをフリーズするまで実行を繰り返し呼び出すためのシェルコードが印象的だ。その手があるかという感じだ。

  • 実際の手順例:

    1. まずはプロセスを kill してコアダンプを生成する。

    2. コアダンプに対して gdb を実行する。このときコマンドライン引数には実行プログラムとコアダンプの両方を指定する。

    3. デバッグセッションで info threads コマンドを実行し、スレッドを一覧する。

    4. そのうちひとつのスレッドのスタックフレームを backtrace することでロック箇所が判明する。

    5. もう一方のスレッドについても同様の手順を適用する。

  • デッドロック対策は設計に含めておくこと。

  • Java ならば jstack コマンドを利用する。

項目 61: キャプチャして複製する

  • 非決定的バグをデバッグする話題。競合状態が起こることがあるコードを題材としている。

  1. gdb_record prog を実行する。

    • 適宜 break ポイントを設定する。

  2. デバッグセッションで pin record on コマンドを実行する。

  3. replay pinball/log_0 を実行する。

  4. gdb_replay pinball/log_0 prog を実行する。

    • デバッグセッションで pin trace を実行する。XXX at LINENUM

  5. pin break 16 if tmp == value のように、条件付きブレイクポイントを設定する。

項目 62: 専用ツールでデッドロックと競合条件を見つける

  • FindBugs (Java)

  • OpenMP, POSIX Threads のコードの問題の特定。Intel Inspector

  • valgrind --tool=helgrind prog で潜在的デッドロックを検出する。

項目 63: 非決定性を切り分けて取り除く

  • 隔離方式:決定性のものと非決定性のものとの直和になるようにプログラムを設計する。

  • 削除方式:置き換え。あくまでもデバッグとテストの用途とし、本番のコードとはしない。

項目 64: 競合制約状態を調べてスケーラビリティ問題を検討する

  • 英語の contention のこの文脈での意味がよくわからない。

  • Java Flight Recorder, VTune Amplifier

項目 65: 性能カウンタを使ってフォールスシェアリングを探す

  • False Sharing とは何かを説明できるようにすること。

  • CPU の性能カウンター

    • Visual Studio: Concurrency Visualizer

    • Intel: VTune Performance Analyzer

    • Linux: perf

  1. perf stat --event=LCC-loads prog1perf stat --event=LCC-loads prog2 をそれぞれ実行する。

  2. perf record --event=LCC-loads prog2 を実行することで関連イベントを記録する。

  3. perf annotate により、キャッシュミスを引き起こした部分を特定する。

  • LLC-load は「最終レベルキャッシュミス」を測定することを意味する。

項目 66: 高水準な抽象化を用いてコードを書き直すことを検討する

  • 並列性に関するバグを回避するコードを書く(転嫁と言っている)。

    • 信頼できる既成ミドルウェアを使用する。 SQL なりリクエスト処理なりを提供しているはずなので、それを利用する。

    • 独立プロセスに処理を分離する。パイプが要る。

    • GNU parallel で複数コアに作業を分割する。コマンドライン例を引用する:

      bash$ ls *.jpg | parallel 'djpeg -scale 1/16 {} | cjpeg > thumb/{}'
      
  • Java には Collections.parallelStream がある。

  • C++ の Qt ライブラリーには QtConcurrent がある。

  • Apache Hadoop 分散処理。

  • MapReduce 技法

  • BLAS が使えるときはそうする。

  • マルチコアを意識したプログラミング言語を採用する。

    • Clojure, Scale, F#, Haskell, R, Erlang.

  • 反応型イベント駆動フレームワーク (Vert.x)

  • 高水準基本命令。Java の例だが、多言語にも類似の要素があるだろう:

    • 並行コレクション、イテレーター。

    • Executor/ExecutorService, CompletableFuture, parallel stream, future tasks, lambda, etc.

訳者あとがき

  • システム管理者(企画、運用担当含む)管理者にも本書を勧める。

  • デバッグは重要であるが、文献が少ない。

  • The Art of Command Line は気になるので是非チェックしたい。