仕事の生産性が高い人は何が違うのか。米マイクロソフトのシニアエンジニアの牛尾剛さんは「例えばプログラムに問題があったとき、一流のエンジニアは試行錯誤をしない。作業をすることより、自分の頭で仮説を立てることを優先する。その結果、生産性は天地ほど違ってしまう」という――。
※本稿は、牛尾剛『世界一流エンジニアの思考法』(文藝春秋)の一部を再編集したものです。
■「世界一流と仕事できてうれしいだろ?」
あるとき、同僚のポールと仕事をする機会に恵まれた。ポールはチームの初期からアーキテクチャ(情報システムの設計)をつくり上げてきたメンバーで、私が人生で出会った中でもっとも賢い男だ。何をやっても高速で丁寧、どんな問題が発生しても短時間で解決するその技術力はため息が出るほど素晴らしく、新しいアーキテクチャに関する論文をいくつも執筆している。
彼と仕事をし始めたとき、私のスキップマネージャ(2つ上の上司)が「世界一流のエンジニアと仕事できてうれしいだろ?」と誇らしげに声をかけてきた。自分は「もちろん」と即答したが、それほどまでに彼は社内評価も高いエンジニアなのだ。
ポールは私より頭の回転も速いし、記憶力も抜群に良かったが、同時にこう確信した。
「彼は人生で自分が会った中でもっとも賢い人だけど、それでも、自分と比べてとても追いつけないほど脳みその性能が違うわけではない」
衝撃を受けつつも、私でも真似のできた、彼の思考回路をたどっていこう。
■ポールがとった「まさかの行動」
ある日、私のプログラムが上手く動かないときがあった。もちろんこれを自力で直しても良いのだが、今までの経験からすると、原因究明に何時間、もしくは何日かかかるだろう。
ポールだったらどういう風に思考するのだろうと思って、「ペアプログラミング」をお願いすることにした。ペアプログラミングというのは、2人1組で1台のPCを共有し、一緒にプログラミングする手法で、互いの技術を学んだり、コードのコンテキスト(背景)を理解・共有するのにもすごく有効だ。私はポールに言った。
「私のプログラムで問題が起きている。私はいつも生産性がよくないので、何か悪い癖があると思うんだ。君だったらどうやるのかを学びたいと思っているから、ペアプログラミングをしてくれないか?」
「君が何を求めているのかはわからないけど、いいよ」
そうしてセッションは始まった。
私は自分のプログラムに問題があることを示す「ログ」を表示していた。ログとは、プログラムが内部でどのように動いているかを示す記録だ。それを見ることでプログラムが正しく動いているのか、問題が発生しているのかをチェックすることができる。
普段の私なら、ログで問題を見つけたら、「ここが原因かもしれない」「いや、あそこの不具合だろうか」と試行錯誤をする場面だ。あたりをつけて修正して、プログラムをサーバーに移動させて、動かして、またログを見る。ログは反映されるまでに15分くらいかかるから、いくつか試すのもかなり時間がかかる。
ところが、ポールがとった行動は、私と真逆のアプローチだった。彼は最初の一つのログだけを見て「仮説」を立て始めた。手は一切動かさない。
■仕事のデキる人とデキない人の違い
「このログが出ているということは、自分の推測では、内部でこういうことが起こっている可能性が非常に高い。そこを鑑みると、調べるべきは……」とぶつぶつと独り言をいいながら、データベースを閲覧するソフトを起動し、クエリ(システムへの命令文)を一つだけ書いてこう言った。
「ここだろう」
なんとそのクエリの結果は、私のプログラムの問題の根本原因をズバリ指し示すものだった。彼が手を動かしたのはその一回きりだ。
自分だったらああでもない、こうでもないといろいろクエリしたりコードを見たりして数時間かかる問題を一瞬で魔法のように解いて見せたのだ。
私は雷に打たれたような気分だった。恐ろしいことに、そのコードベースに関して、彼は経験がほとんどない。そのプログラムが書かれたサービスのコードは、むしろ私のほうが知っている。
ソフトウェアの世界では、できるプログラマとできないプログラマの差は25倍あると言われているが、こういうことなのだと実感できる出来事だった。ただ、彼は人間に不可能なことを実行したわけではない。同僚のバーラが言っていたことを思い出した。
■手ではなく頭を使うべき
「障害を調査するとき、いきなり手を動かして、試行錯誤していろいろクエリを投げてはダメなんだ。ログを見て、自分で多分こういうことが起こっていると推測して、その推測に合ったクエリを投げてそれを証明するんだよ」
いきなり手を動かさない。まずは、事実(データ)を一つ見つける→いくつかの仮説を立てる→その仮説を証明するための行動をとる。
つまり、むやみやたらに試行錯誤するのではなく、まず自分の頭のメンタルモデルを使って仮説を立て証明する。メンタルモデルの構築については後ほど詳述するが、この一連の手順が、手当たり次第に可能性を試すことによる時間のロスを排除し、圧倒的な効率を生んでいるのだ。
プログラミングの生産性というのは「頭脳労働」であるということを実感した瞬間だった。頭の使い方によって、生産性が天地ほど違うというのはこういうことなのだろう。
■試行錯誤の結果、起きたこと
日本では、まず自分の力で試行錯誤することが尊ばれるし、まわりからも評価される。だが、IT技術者には試行錯誤がとても良くないのである。もう一つ例を挙げよう。
あるとき日本に一時帰国中に作業していると、ログを管理するプラットフォームで、ログファイルを見ると完全に正常に動いているようにしか見えないのにクラウドのポータル(最初に表示されるWebサイト)のほうには、遠隔からのデータ(テレメトリ)が来ていないという奇妙な現象が生じた。
チームのメンバーにTeamsで画面共有をして、「ほら、出ないでしょ?」と見せると、なぜかそのときはテレメトリがポータルに来ている。その後自分で何回試してもやっぱり出ない。
もう一回別のメンバーに助けを求めるチャットを書いて「Fiddler(ネットワークのモニタリングを行うツール)使って分析したらいいんじゃね?」とアドバイスをもらった瞬間にポータルを見ると、今回だけテレメトリが出ているというまるで呪いのような症状だ。
そこで私は、いろいろと試行錯誤した。パケットがたくさん送られたときにカットされてしまうのが原因か、ポータル側でフィルターがかかったのか等、様々なアイデアが錯綜(さくそう)する。
スクリプト(簡易的なプログラミング言語)を改造したり、ログ出力をファイルのみにしてみたり、スクリプトの実行パターンを数個だけにしたり……私は各パターンを試して問題解決をはかろうとした。
■「何も成長していない」
だが、丸一日つぶしたあげく、これらの試行錯誤はすべて失敗に終わった。ふと、チームの一人が「ちゃんとデータは出ているよ」と説明してくれたことが脳裏によぎった。そう言えば、彼女は、スクリプトを使わず手動でテストしていた。
自分も試しにスクリプトを使わず、手動で実施してみた。すると完璧に動作した。
問題は「スクリプト」だったのだ! そこから意味不明の挙動の正体を特定し、問題を完全に解決した。
問題は解決できた。一日以上使ってやっと。
しかも振り返ってみれば、丸一日かけたのに、私は「何も成長していない」のだ。単に思いつきでいろいろなパターンを試して正解を探しているだけなので、とても時間がかかる上、新しい知識を何も学んでいない。
まったく同じ状況で、同じ問題が起こったら、メモをとっておけば、次回の解決に役立つだろうが、問題が少しでも違えばお手上げだ。似たような問題が生じれば、また同じだけ時間を使ってしまうことも十分あり得るのが残念すぎる。
■試行錯誤は悪である
プログラマとして問題を一瞬で解決する達人のトラスクが、私にアドバイスしたのは、試行錯誤するのではなく「Fiddlerで分析したら?」だった。
Fiddlerを使えば、Application Insightsからどういうデータが出ているかはチェックできる。私はそれをどうやって適用するのかがわからず、どうにもならなくなったらやろうと考えて、最後にとっておいたのだ。
私のとるべき行動は、まずFiddlerでモニタリングすることだった。Fiddlerを見たら、WSL2側からテレメトリが来ていないことが一発でわかったはずだ。
もしもそのルートを選んでいれば、問題の原因にかなり早くたどり着けただけでなく、「FiddlerをWSL2と一緒に使う」やり方を試すこともできた。つまり、特定の状況に限定されず、さまざまなケースで使えるツールの使い方を学ぶ機会となり、「未来の生産性」が向上したはずなのだ。
思いつきによる試行錯誤は「悪」なのだということを、身をもって実感した出来事だった。
———-
牛尾 剛(うしお・つよし)
マイクロソフトエンジニア
1971年、大阪府生まれ。米マイクロソフトAzure FunctionsプロダクトTチーム シニアソフトウェアエンジニア。シアトル在住。関西大学卒業後、大手SIerでITエンジニアをはじめ、2009年に独立。アジャイル、DevOpsのコンサルタントとして数多くのコンサルティングや講演を手掛けてきた。2015年、米国マイクロソフトに入社。エバンジェリストとしての活躍を経て、2019年より米国本社でAzure Functionsの開発に従事する。著作に『ITエンジニアのゼロから始める英語勉強法』などがある。
———-
(マイクロソフトエンジニア 牛尾 剛)