プログラミングは実験科学に似ている

プログラミングというかソフトウェア開発は実験科学と似たところがあると思う。開発中に、自動単体テストを走らせて結果が正しいことだけでなく、パフォーマンスやメモリ消費のデータを常に収集してバグ混入による異常値がないかを常時監視する。グラフを描いたり統計処理をしたりもする。主成分分析を行い、ボトルネックを見つけ改善策を模索する。

デバッグはまさに実験科学である。

簡単には潰せないバグは、まずはじっくりと観察する。特に企業における大規模ソフト開発では、ソースが提供されないモジュールやコミュニケーションが密に取れない他チームのモジュールを利用しているときには、観察することしかできない。入力データをいろいろ与えてみて、どのような挙動になるかを調べる。その際、なんらかの仮説と予想を持つことが重要である。原因を仮定して、結果がこうなる筈だという予想を立てて、実際に実験してみる。予想が当たることもあれば、外れることもある。当たったときは嬉しいが、外れたときの意外性も面白い。仮説も1つではなく、可能性として考えられるものは並行して複数の仮説の元に実験を行う。そうすると徐々に新たな現象が蓄積され、仮説も絞られてくる。バグの原因に目星がついたら、その原因がそれまでの現象を論理的に説明できるかを考察してみる。それが無理なく無矛盾であればコードを修正して結果を検証する。

つまり、デバッグは仮説、実験、考察、検証という作業の繰り返しである。仮説をどう立てるかは経験と勘によるところが大きいが、大部分は論理的思考が重要である。推論過程に論理的な飛躍がないか、検証していない何か暗黙の仮定を無意識に置いていないかなど常に意識する必要がある。

しかし、スキルの低い人ほど、事実なのか、またはその人の考えなのかの区別が曖昧なことが多い。実際に確認することが面倒なのか、あるいは自信があるのかわからないが、確認しなくても明らかだという思い込みが多いように思える。他の人のバグだと思って指摘したものが、結局は自分のコードのバグだった、なんていうことはプログラマなら誰しも経験があることだろう。経験を積んだ人ほど一見当たり前だと思えることでもしっかりと確認する。

バグの前には謙虚でなければならない。

先入観を捨てて無条件で事実は受け止める必要がある。そんなことは起こりえないと思っていても、そんなことが実際に起こるのである。言い訳など考えても無意味だ。しかし、どんなに摩訶不思議な現象が発生しても、原因は必ずあり、解決は可能である。

ソフト開発ではプロジェクト管理やツールや言語などを使いこなせる個々の技術も重要であるが、実験科学的な論理的思考スキルはもっと重要ではないかと思う。