【絶対やめろ】デバッグが遅いエンジニアの共通点とは?劇的改善法を大公開!

校長
校長
Cover Image for 【絶対やめろ】デバッグが遅いエンジニアの共通点とは?劇的改善法を大公開!

はじめに

どうも私立YouTube高専校長です。

私がこれまで、見てきた仕事の遅いエンジニアには、ある共通点があります。 それは、不具合の解決を自力で出来なかったり、あるいは非常に時間がかかってしまうということです。

あなたは、なにかソフトウェアを開発していて、意図通りに動かないという経験をしたことがあると思います。 いわゆるバグだとか、不具合と呼ばれるものです。そして、そのような不具合を解決するのに非常に時間がかかった、あるいは、最終的には諦めてしまったという経験もあるのではないでしょうか。もちろん、私にもそのような経験があります。

これから、CopilotやChatGPTのようなAIがコーディングをある程度自動化してくれるようになると、エンジニアに求められる、検証能力や不具合解決能力というのは、さらに上がっていきます。

コーディングがたとえ全自動化されたとしても、このような検証や問題解決するための時間がボトルネックになると、結局生産性を上げることが出来なくなってしまいます。

そこで、今回の動画では、バグが解決できない、あるいは解決するのに時間がかかってしまう理由と、それを改善するための具体的な方法(FTA)を紹介したいと思います。これは、コンピュータに関する特定の分野の知識というよりも、不具合を特定するための思考プロセスのような話で、コツさえ掴めば、あなたも明日からすぐにでも実践できる方法になります。

FTAの知名度は低いですが、どんな言語で、何を開発するにしても、めちゃくちゃ重要で、一生役立つ思考プロセスなので、是非最後までご覧ください。

また、FTAは、体系的な思考プロセスなので、人の能力によらず再現性が高いです。なので、デバッグが苦手な本人に限らず、若手を指導中の方や、教壇に立つ立場の方も参考になると思います。

実際に、私も東京大学で研究している頃にはFTAを知らなかったのですが、日系の世界的メーカーでこの思考プロセスを伝授して貰ってからは、それまでは、諦めていたような複雑な問題も、自力で解決できるようなり、自分の技術力を一段上に引き上げる事ができました。

また今回紹介する情報以外にも、こういった有益なコンピュータ関連の技術情報を発信しているので、 そういった動画を見逃したくない方は、今のうちにチャンネル登録しておいて貰えればと思います。

それでは、本編どうぞ

バグが解決できない理由

それでは、なぜあなたはバグを解決できないのか、あるいは時間がかかってしまうのか。結論から述べたいと思います。

それはずばり、あなたが『直感に基づいて、デバッグをしているから』です。 たしかに、直感で解決できる不具合もあるし、簡単な問題ならば、その方が早いこともあります。 しかし、問題が複雑になってくると、直感によるデバッグだけでは、太刀打ちできなくなってきます。

コンピューターは非常に複雑なシステムで、多くの部品が複雑に依存し合っていて、一つでもそのピースが狂うと、正常に動きません。

したがって、直感だけに頼ったデバッグだけでは、直感が通用しなかった時に、やるべき事を見失い、何をしたらいいのか分からなくなり、作業が止まってしまいます。

この状態になると最悪で、何をすべきか分からないので、一切問題解決の足がかりがなくなってしまします。 この状態は、精神的にも、良くないので、多くのエンジニアは、この段階で、諦めて、投げ出したくなってしまいます。中には、余り笑えませんが、一生帰ってこない人もいます。

そのうえ、直感というのはその日のコンディションや、人の能力に非常に大きく依存してしまうので、再現性が確保できません。また、直感は人に教えることもできないので、指導する事も困難です。これは、チーム開発だと、一人のエースに依存してしまうような脆弱な開発体制になってしまいます。

しかし、実はこのような直感によるデバッグの限界に陥ったとしても、 次にご紹介する方法を使えば、やるべきことが明確になり、前に進む事ができます。

人は、やるべき事が分かっていれば、どんな困難な不具合に立ち向かっても、前向きに開発を進められます。 続いて、その素晴らしい方法をご紹介したいと思います。

Fault Tree Analysis

あなたは、FTAという言葉をご存知でしょうか。ソフトウェアやプログラミングの勉強だけをしているとなかなか聞き慣れない言葉かもしれません。

これは、Fault Tree Analysisと呼ばれるフレームワークで、ベル研究所のH.A Watsonが考案し、現在も世界中のメーカーで、不具合の原因を特定するために使われる体系的な方法論です。

ソフトウェアの世界だとあまり知名度はないのですが、FTAは、ソフトウェアの世界において、凄まじい有効性を発揮します。

具体的に、FTAによって、どのように不具合原因を特定するのかご説明したいと思います。

まず、トップ事象として、問題になっている不具合を書きます。 そして、そのトップ事象がどのような原因があったら発生しうるのかを、AND条件とOR条件を考慮して、デジタル回路のように書きます。これを、再帰的に繰り返して、思いつく限りのすべての原因を書き出していきます。これが、FTAです。

そうして、次は書き出した一つずつの原因の真偽を検証していきます。 このとき、出来るだけトップ事象に近いところから、検証していくのがコツです。なぜそうするかというと、トップ事象に近いところで、否定された原因については、その原因のさらに原因については検証する必要がなくなるので、調査を省略できるからです。

この説明だけでは、まだ分かりにくいと思うので、具体的な不具合を題材にして、FTAによって原因を特定する過程・思考プロセスを臨場感を交えて、解説したいと思います。

実習: FTA

それでは、C言語のプログラムの不具合に基づいて、FTAの考え方を説明したいと思います。 ソースコードはGitHubにあるので、興味があったら動画の詳細欄から、クローンして下さい。

このプログラムは足し算のマクロを定義して、足し算を計算するプログラムです。 最初に、1+2を計算して、そのあとに、(1+2)*3を計算しています。答えはそれぞれ、3と9になるはずです。 実際に実行してみましょう。Ctrl+Shift+Bでビルドして、ターミナルから実行ファイルを実行してみます。

おっと、意図した値が出力されませんね。1+2は意図通りに計算できていますが、(1+2)*3は、9になるはずが、7になってしまいました。 これはなぜでしょうか?FTAに則って、考えてみましょう。

ます、トップ事象は、『(1+2)*3=7になる』です。 その原因として、今回は3つの可能性を考えました。

1つめが、計算は正しいが、表示がおかしいという可能性です。その場合、なぜ、表示がおかしくなるのかというと、printf関数にバグがある。あるいは、シェルにバグがあって、表示がおかしくなるということを可能性として上げています。

次に、実行するファイルが間違えているということも考えられます。これは、意外に馬鹿にできなくて、gitでhard resetすると、タイムスタンプが過去に戻るので、フルビルドしないと、現在のソースコードが実行ファイルに反映されていなかったり、純粋に作業するディレクトリを間違えている事が少なくないです。この場合、実行するファイルが間違えている原因としては、Visual Studio CodeのBuild Taskの出力ファイルの定義を間違えている可能性、作業ディレクトリを間違えている可能性、再ビルドを忘れて、以前ビルドしたプログラムを実行している可能性が考えられます。

3つめは、計算そのものが間違えている可能性です。その原因としては、オーバーフローやアンダーフローが起きている可能性、あるいは計算順序が間違えていることが考えられます。そして、計算順序が間違えている原因としては、コンパイラや定義したマクロが間違えている事が考えられます。

以上で、考えらえる原因をFTAによって、書き出す事が出来たので、一つずつ原因を検証していきましょう。

まず1つ目、『計算は正しいが、表示がおかしい』についてです。 こちらは、まず、printf関数もシェルも非常に歴史と実績があるプログラムです。したがって、可能性としては否定できませんが、疑いは極めて低いです。さらに、printf関数やシェルの実装を追うのは、非常に時間がかかるため、検証を後回しにします。このように実績のあるもの、比較的信頼できるものは、検証を後回しにすることで、結果的に時短になり、生産性を上げることが出来ます。

それでは、次は、実行ファイルを間違えている場合を考えてみましょう。 この問題の検証は、簡単にできます。まず、現在ある実行ファイルを消します。これで、再びビルドして、実行ファイルが生成されていれば、間違いなくそれは、現在のソースコードが反映された実行ファイルです。 実際に実行ファイルを消して、Ctrl+Shift+Bでビルドして、実行ファイルを実行します。

結果は変わりませんでした。相変わらず、7と表示されてしまします。これで、実行するファイルが間違えているという原因を否定することが出来ました。

この時重要なのは、実行するファイルが間違えているという原因を否定することが出来たので、それより下の、Build Taskの確認や作業ディレクトリや再ビルドの確認はするまでもなく、次の検証に移る事が出来ることです。

最後に、単純に計算が間違えているという原因を検証してみましょう。まず、オーバーフロー/アンダーフローについてですが、今回は、32bitの変数で10以下の値を計算しているので、ソースコードを見るだけで、静的に否定することができます。静的というのは、実行せずにコードを読むだけで、判断するという意味です。

次に、計算順序が間違えている可能性です。察しの良い方は気づいているかもしれませんが、2*3を先に計算すると、7になってしまいます。これは、非常に怪しいですね。 printf関数やシェルと同様に、コンパイラも、非常に実績のあるプログラムです。なので、マクロ定義を先に検証しましょう。

検証方法は簡単で、実際に、マクロがプリプロセッサによって展開された出力を確認します。ビルド時に、-save-tempsオプションを付けることで、main.iというファイルが出力されるので、このファイルを見てみましょう。

おっと!これをみると、実際に計算されているのが、1+(2*3)であることがあります。C言語を含むほとんどすべてのプログラミング言語では、足し算より掛け算が優先されるので、これでは意図した計算結果には絶対なりません。

実際に、マクロに、括弧を追加して再ビルドして、実行してみましょう。

このように、正しい結果が表示されました。 これで原因が、マクロの定義にあることを特定できました。

ちなみに、本題からずれるので、詳細は解説しませんが、インライン関数を使うことも有効な対処法です。

もし書き出したすべての原因を検証しても、真の原因に辿り着かなかった場合は、さらに深く広く可能性を書きだしていく必要があります。 たとえば、今回は省略しましたが、標準ライブラリであるprintf関数やシェルを深く追わざるを得ない場合もあります。

したがって、あなたのFTAに対して、他の人からフィードバックを貰うと、FTAはさらに強力な手段となります。 FTAを人に見せることで、自分が見落としている観点を見つけることができて、さらに深く広く可能性を書き出すことができます。

それだけでなく、フィードバックを与える同僚や指導者の目線だと、あなたが何を根拠に、何をして、どのような結果が得られたのかの過程を一目で理解することができるので、より適切な助言を与えることが出来ます。

したがって、このFTAを意識してデバッグしているかどうかで、会話が通じるか通じないかのレベルで、重要な概念になります。

今回は、非常に単純なバグに基づいて、FTAによる不具合原因の特定方法を解説しましたが、 このFTAという考え方はソフトウェアをデバッグする上で、本当に、すさまじく有効な手法です。 続いては、なぜ、そこまでFTAがソフトウェア開発で有効なのか、その理由を解説したいと思います。

ソフトウェア開発でFTAが有効な理由

それでは、FTAがソフトウェアのデバッグにおいて極めて有効な理由について解説したいと思います。

それはずばり、ソフトウェアが徹頭徹尾論理的なものだからです。良くも悪くも、一切の忖度をしません。

コンピュータというのは、ソフトウェアから見ると、0と1でデータを表現し処理するように見えるように設計されているので、ソフトウェアは完全に論理的です。 したがって、ハードウェアの不具合を無視すれば、必ずこのFTAで真の原因を発見することができます。

ただし、あなたがどれくらい深く広くFTAを書き出せるかどうかは、そのトップ事象が正常に機能するための前提条件を、あなたがどれくらい理解しているのかに依存します。

言い換えると、動作の仕組みを完全に理解していないと、全ての可能性を書き出す事が出来ません。したがって、その場合は、原因を特定することが出来ない可能性があります。

しかし、逆に、FTAをしていると、この様な前提条件があるはず、というような、自分が欠けている知識、ピースが明らかになることもあります。これは、パズルをしていて、あるはずの足りないピースを見つけるようなものです。

コンピューターは徹頭徹尾論理的なシステムなので、全てのピースが完全にはまって、初めて望んだ結果が得られます。 そのため、深く広くFTAを書き出し、FTAをより強力な武器として活用するためには、コンピューターの仕組みを理解する必要があります。

逆に言うと、プログラムを書くだけ、作業するだけなら、誰にでも、今やChatGPTにですら、できます。 作業ができることももちろん重要ですが、それ以上に不具合が発生したときに、それを解決できるかどうかが大事なんです。 コンピュータの仕組みを理解していれば、原理まで遡ってFTAを書き出せば、理論上どんな問題でも必ず解決出来ます。

そうすると、仕組みをろくに理解せずに、ChatGPTの出力をコピペして、問題が発生したら、直感に基づいたデバッグをして、分からなくなったら、投げ出してしまうようなエンジニアとは一線を画す存在になります。

**その分学習コストも高いですが、安心してください。**私のチャンネルでは、コンピュータの仕組みを理解するために必要な、コンピュータ関連の技術を原理から分かりやすく解説しています。 この動画を見ているあなたは、迅速・確実に問題解決ができるようになるかと、不安になる必要はまったくありません。

なぜかというと、こんなデバッグのコツを説明するだけの動画を、15分も聞ける、あなたはポテンシャルの塊だからです。 自信を持って好奇心のままに勉強してください。自信を無くして、投げ出してしまう人が殆どです。 5年後には、天地の差が開いています。

もし、なにかまだ分からない事があったら、ぜひコメントで教えてください。

自分もまだまだ知らないことはあるので、一緒に勉強していきましょう。 私が高専・東大・スタートアップ・日系大手メーカー・外資ハイテク企業と、、、人生の大半をコンピュータに投下して、学んできた全てをこのチャンネルにぶつけるので、私の動画を見ることによって、他では得られないコンピュータの原理的な考え方が身に付きます。

絶対にできます!一緒に頑張りましょう! 最後に復習をして、本日の動画を終わりにしたいと思います。

復習

本日は、バグが解決できない、あるいは解決に時間がかかってしまう理由と、それを改善するための具体的な方法をご紹介しました。

バグが解決できない理由は、『直感に基づいたデバッグをしている』ことであると説明しました。 問題が複雑になってくると、直感によるデバッグだけでは、太刀打ちできなくなってきます。 また、直感というのはその日のコンディションや、人の能力に非常に大きく依存してしまうので、再現性が確保できません。

じゃあ、代わりにどうすればいいのかということで、FTAという手法をご紹介しました。FTAは、世界中のメーカーで、不具合の原因を特定するために使われている体系的な方法論です。 そして、FTAというのは、ソフトウェアの世界において、凄まじい有効性を発揮します。実際に、C言語のプログラムの不具合に基づいて、FTAによって、原因を特定するまでの過程・思考プロセスを説明しました。

そして、最後にFTAがソフトウェアの世界において、極めて有効な理由をご説明しました。 その理由は、ソフトウェアが徹頭徹尾論理的なものだからです。良くも悪くも、一切の忖度をしてくれません。 コンピュータというのは、ソフトウェアから見ると、0と1でデータを表現し処理するように見えるように設計されているので、完全に論理的です。したがって、ハードウェアの不具合を無視すれば、必ずこのFTAで真の原因を発見することができます。

しかし、FTAにも限界はあって、あなたがどれくらい深く広くFTAを書き出せるかどうかは、そのトップ事象が正常に機能するための前提条件を、どれくらい理解しているのかに依存します。言い換えると、その機能が動くための仕組みを完全に理解していないと、全ての原因を書き出す事が出来ません。したがって、その場合は、原因を特定することが出来ない可能性があります。

したがって、やみくもにChatGPTの出力をコピペするのではなく、仕組みを理解しながら開発を進めないと、バグは解決できません。 作業は、どんどん自動化して、AIに任せる時代が来れば、ソフトウェア開発の生産性はまだまだ上げると思います。

あなたが、次にバグに出会ったときは、本日ご紹介したFTAを思い出し、効率的に、確実に問題を解決することが出来れば幸いです。

本日の動画の内容は以上になります。ここまでご視聴ありがとうございました。

Reference

ソースコード

Fault tree analysis