プログラムが動かない…こんなときにどうするか。 昔は「もっと"コーディング能力"を伸ばさねば…なんの本を読んだらいいだろう?」と考えていたが、 実際に必要なのは、問題解決への正しいアプローチ方法だ。
コーディング能力は二次的な問題 🔗
正しく動くプログラムを書くには、大きく2つの能力が必要だ: 言語のシンタックスや関数の使い方を守ってコードを書く「コーディング能力」と、直面している問題解くために思考の道筋を組み立てる「問題解決能力」である。 プログラミングの初学者にとって、コーディングはいかにも「プログラミングしています感」がとても強いので、学習対象として認識されやすい部分だ。 この理由から、プログラムが意図通りに動かない時、初学者はその原因を自らのコーディング能力の不足と思い込む傾向があるが、ここに大きな落とし穴がある。
コーディング能力は「知識量」に関係した能力だがが、プログラミングの世界は広く深いため、知識をいくらインプットしても、知識量が十分な状態で課題に取り組めるようになることはほとんどない。 一方で問題解決能力は、知識が不足した状況においても、直面している問題の解決に必要な知識を現地調達し、ものごとを前に進める能力だ。 プログラムを動かすために鍛錬すべきはまさにこの問題解決能力であり、これを身につければコーディング能力も書籍に頼ることなく自力で伸ばしていくことができる。
エラーに直面した初学者がやりがちな NG 行動 🔗
仕事柄、プログラミング初学者の方がエラーに直面する場面を数え切れないほど見てきたので、頻出パターンを挙げてみる:
- パターン 1. 上流でエラーが起きたことに気づかないまま、下流の部分のエラーで悩む
- パターン 2. エラーメッセージを全く読まずに「あっ、なんか動かない。どうしたらいい?」と思考停止する
- パターン 3. 起きている問題を、エラーメッセージの中で目に入ったいくつかの単語から「想像」し、それを解決するようにコードを変更する
- パターン 4. エラーメッセージの意味は理解できているが、根本原因を特定しないままコードの修正に着手する
上の例は頻出順ではなく、問題解決まで遠い順に並べている。
問題解決まで最も遠いところにあるのはもちろん パターン 1. だが、ここで躓く割合としてはそんなに多くない印象がある。
パターン 2. はプログラミングを初めたばかりの初学者によく見られる反応で、その後慣れるにつれて パターン 3. へと移行していく。
どちらもアドバイスとしては「エラーメッセージをよく読もう」に尽きるが、エラーメッセージは敵ではなくむしろ問題解決の味方であることをほんとうに腹落ちできるまで、パターン 3. の状態はかなり長くつづくことがある。
また パターン 3. でも試行錯誤によってたまたま問題を解決できることもあるため、そもそも自身の問題解決アプローチに問題であることを認識していないケースもある。
試行錯誤でエラーが解決するのは単なる「まぐれ」であり、実際には何も成長していないことを認識することはけっこう重要だ。
パターン 4. は一見良さそうではあり、この方法で解決できてしまうことも実際にはそこそこあるが、実は問題の特定をスキップしているため(エラーメッセージは根本原因を示しているわけではない)、状況によっては泥沼にはまることがある。
本業プログラマーも含めて、かなりプログラミングに慣れている人でも、この パターン 4.に留まっている人はけっこう多い。
問題解決の基本ステップ 🔗
プログラミングに限らず、問題解決は下記のステップで実施する:
- 問題特定: システムや実行環境の現在の状態を確認し、起きている問題を明確にする
- 問題を正しく特定できているかを調べる仮説検証を挟むこともある
- 仮説立案: プログムをどのように変更すると問題を解決できるかを考える
- 仮説検証: 変更によって問題が解決したかを確認する
類似の問題をどれだけ経験してきたかによって、上流のステップを省略することはあるが、基本的には常にこの流れで考える。
はじめは簡単と思っていた問題でも、なにか予想と違う結果が得られたときには、前のステップに戻って丁寧に確認するとよい。
3. で問題が解決したあとも、別の解法がないか振り返るとパーフェクトだ(数学の「別解」と同じだ)。
2. で立てた仮説が間違っていた場合でも、それは失敗ではない。
むしろ、検討すべき選択肢が絞られたことで問題解決に近づいたわけで、得られた知見を基に、新たな仮説を立てて検証するだけである。
思考実験:コーディングを外注したら解決するか? 🔗
問題解決能力の重要性を理解する思考実験として、「スーパープログラマー」にコーディングだけ依頼するケースを考えてみる。
残念ながら、「どう書くか」の技術的不安がなくなったとしても、問題解決能力がなければ、現状を把握するためになにを調べたらよいかの指示を出すことができない。
コード変更の指示をいきなり出すことはできるかもしれないが(NG 行動 パターン 4.)、その指示が見当違いになる可能性もあるため、コーディング能力が高くても全く意味がないのだ。
進行方向が誤っているならば、速度が速いことは却って害なのである。
まとめ 🔗
プログラミングの問題解決において最も重要なのは、技術的なコーディング能力ではなく、問題を体系的に理解し、仮説を立てて検証する能力だ。 というか、この能力はプログラミングに限らず仕事一般において…いやそもそも、自分の人生のハンドルを自分で握るためにも重要だ。 今さら私がいうまでもなかったかもしれない。