どんどんと新しいテクノロジーが勃興し、古いテクノロジーも更新されていくので、ソフトウェア開発者はキャリアを通じて多くのプログラミング言語やフレームワークを学ぶことになります。しかし学ぶことが多いからといって、どのように学べばいいか、どのように学ばせればいいかを理解しているわけではないとして、月刊誌「Communications of the ACM」が、「学習」において知っておくべきことをまとめています。

10 Things Software Developers Should Learn about Learning | January 2024 | Communications of the ACM

https://cacm.acm.org/magazines/2024/1/278891-10-things-software-developers-should-learn-about-learning/fulltext



1:人間の記憶はビット構造ではない

2020年に発表された論文に「学習するということは長期記憶に変化があったということを意味する」という言葉があるように、学習の中心にあるのは人間の記憶です。ソフトウェア開発者であれば、一連のビットを保存しておけば、あとでそのまま正確な一連のビットを取り出せるコンピューターのメモリーの能力を身をもって知っていますが、人間の記憶はそこまで正確ではなく、信頼性も高くありません。

しかし、コンピューターのメモリーとは違って、何かを思い出そうとしたときに関連する知識と結びつけることで、問題解決や深い理解に大きな影響を及ぼすこともあります。

2:人間の記憶は長期記憶と作業記憶で構成される

長期記憶は、情報が永続的に保存される場所で、PCでいうとストレージのようなもの。作業記憶は、限られた量の情報をリアルタイムで保存してアクセスしやすくし、問題解決のための推論に利用する場所です。作業記憶の容量は出生時にほぼ固定されていて、容量が大きいほど学習速度は上がりますが、作業記憶能力がパフォーマンスのすべてではありません。熟練エンジニアが専門家たりえるのは、長期記憶の内容によるものだとのこと。

一方で、新たなツールやスキルを学ぶためには、そのタスクの認知負荷、つまり作業記憶容量の理解が重要だとのこと。認知負荷には、タスクを達成するのに必要な固有負荷と、必要というわけではない外部負荷があります。初心者はどの部分が固有負荷なのか区別することができないため、無関係な負荷に苦しむことになります。

一例として「Communications of the ACM」が挙げたのは、同じデータベーススキーマについての2種類の記述です。左で図示されているものと、右に文章で説明されているものは同じ内容なのですが、文章は頭の中で変換する必要があるため負荷は高くなります。



処理できないような大きなタスク、複雑な問題であっても、細かい断片に分割すると最終的には処理可能ということもあります。初心者や若手が目の前のタスクに苦しんでいる場合は、上記のことを念頭に置くと、どうすればクリアできるかの指針ができるかもしれません。

3:熟練者は認識する、初心者は理屈を考える

初心者と熟練者の違いの1つは、熟練者はすでにそのことを経験済みであるという点です。

チェスのプロを対象とした研究によると、プロが有利なのは盤面の状態を記憶して認識する能力にあり、素早く少ない労力で、対応方法がわかるのだそうです。

開発者の例だと、熟練者がコードの特定部分に着目して「これはソートアルゴリズムを実行しようとしているのだな」とわかる場合でも、初心者は全体像がつかめず、一行ずつ読まなければならないことがあります。

つまり、初心者も、多くのコードを読んで理解すれば熟練者になれるということです。より多くの数と種類のコードを読むことで、プログラミングの熟練度は向上します。

4:コンセプトを抽象から具体へ、また反対へと理解する

プログラミングでは、抽象的な概念を学ぶことがよくあります。人々は多くの場合、たとえば数値の絶対数を返す関数などを調べるために、概念の具体的なインスタンス化を目指しますが、問題は、概念がより抽象的になるにつれて、具体的な例までどんどん遠くなっていくことです。

救いは、抽象的な概念を学べば学ぶほど、だんだん具体的なものになっていくことです。たとえば「関数」は抽象的な概念ですが、何度も学ぶことで、開発者にとって具体的なものとなり、次のレベルの抽象化を学ぶことがでるとのこと。

5:間隔と繰り返しが重要

「スペーシング効果」によれば、人間は理想的には複数の週間にわたって練習間隔を空けることにより、練習内容を最もよく学習できます。ただし、提唱者自身も多くの人は短期間に詰め込むのが好きだということは理解しているとのこと。

1日の学習時間は90分が限度で、これを超えると集中力が低下します。1回の学習のあとは、少なくとも20分の休息が必要です。休息とは、他の仕事をしたり、ネットをぼんやり見たり、他の人と雑談したりするのではなく、散歩に行ったり静かに座ったりすることを指します。

学習効率を上げるには、解決する問題の順序をランダムにするという方法があります。これにより、さまざまな概念が長期記憶で活性化されるようになります。ただし、効率向上とともにより多くの労力が必要になるので、2〜5分ごとに10秒の休息を挟むようにするのがおすすめだとのこと。

6:インターネットによって学習が時代遅れになるわけではない

インターネットやAIによって、必要なコードをAIがほぼ正確に作ってくれるようになったからといって、何かを学ぶことの価値がなくなったわけではありません。十分な学習を行わず、脳内に知識がない場合、脳は知識間のつながりを形成できないため、高レベルの理解や抽象化ができません。

また、ネット検索は書籍に比べて情報を記憶するのに効率が悪いという研究もあります。また、検索は情報を思い出すことで記憶力を強化する効果を奪ってしまう可能性も示唆されています。

7:問題解決は一般的なスキルではない

ソフトウェア開発における一般的な考え方の1つとして、問題解決を特定のスキルとして直接教え、設計やデバッグといった開発の別の側面にも適用するというものがありますが、これは間違いであるとCommunications of the ACMは述べています。

人間は「問題を解決する方法」を直接的に学ぶことはできないので、「プログラミングの問題を解決する方法」「チェスの最良の手を探る方法」「編み物の模様を作る方法」のように、個別にスキルを学びます。これらはそれぞれ独立していて、お互いに影響を与えることはありません。事実、チェスに関する研究で、チェスを学んだからと学業スキルや認知スキルには影響はほとんど、あるいはまったくなかったことがわかっています。「脳トレーニング」が一般的な知能開発に効果がないのと同様です。

唯一の例外は「頭の中でテトリスのテトリミノを生み出し回転させることができる」のような空間スキルで、トレーニングによって、他分野の学習を向上させることができるとのこと。

採用の観点からいえば、プログラマー候補のテストで「ジャンボジェット機の重量の量り方は?」や頭の体操パズルのような内容を出題するのはまったく無意味で、プログラミング能力を測りたいのであればプログラミングの問題を出すべきだとのこと。

8:専門知識は状況によっては問題になる可能性がある

プログラマーは数々のツールや補助機能で仕事の効率を高めますが、こうしたツールは使い手によって受ける影響が大きく異なり、プロ仕様のツールを初心者が使おうとすると、選べる選択肢の多さに圧倒されてしまう可能性があります。

熟練者が初心者を教える場合も同様で、教育した経験の浅い熟練者は、初心者が違う考え方をしていることに気づかないことがあります。熟練者が初心者の目で物事を見られなくなるのは「エキスパートの盲点」としてよくあることです。この問題は、初心者が現在どこまで理解しているのかを聞き、その内容に応じて説明を調整することで克服可能です。

9:プログラミング能力の予測因子は不明確

Communications of the ACMによると、プログラミング学習の成功はほとんどのアクティビティと同様、生来の適性と実践の組み合わせによって成り立っていると考えられます。

プログラミングの適性を予測するための研究は数多く行われていますが、いずれも信頼できるほどの結果は出ておらず、性別、年齢、専攻、人種、数学の成績、別のプログラミング言語の経験、コンピュータサイエンスに対する認識、人文科学または科学の好みなどからは、まったく予測できないということがわかっています。

技術者コミュニティのStack Overflowでは、年齢と評判の間に相関関係が見られ、年齢の高い人ほど評判が高くなっていますが、近年の研究ではキャリアの比較的初期だと仕事の腕との間の相関関係は弱く、経験よりも適性の方が影響が大きいとみられます。

これらのことから、「プログラマーを採用するにあたって、プログラミング能力を測るための近道はない」とCommunications of the ACMはまとめています。

10:考え方が重要

プログラミングは「できる」か「できない」かという二項対立の考え方がある一方、競合する理論も多々あります。たとえば、苦手だったとしても、物理学は誰でも学ぶことができます。しかし現実問題、誰でもノーベル物理学賞を取れるわけではありません。この両極端の間で我々は自分の能力の境界を見つけようとしており、教師と学習者が成長するというマインドセットでタスクに挑むことで、困難を乗り越えて失敗を克服できる傾向があります。

研究により、人の考え方を成長志向に変えるのは難しいことが示されています。しかしCommunications of the ACMは、新たなスキルの習得や訓練においては、「成長マインドセットでタスクに取り組むこと」が効果的であると同時に、開発すべきスキルでもあることを覚えておいてほしいと述べています。

また、メンターの場合は、メンティーの伸びた部分を褒め、怒ることなく、失敗を受け入れろとCommunications of the ACMは記しており、「やめたくなったら休憩したり散歩したりして、戦略を検討してから、もう一度やり直してください」と締めくくっています。