🧠

プログラマー脳 〜優れたプログラマーになるための認知科学に基づくアプローチ 読書メモ

2024/01/03に公開

https://www.amazon.co.jp/プログラマー脳-~優れたプログラマーになるための認知科学に基づくアプローチ-Felienne-Hermans/dp/4798068535

Part 1 コードをよりよく読むために

Chapter 1 コーディング中の混乱を紐解く

コーディング中の混乱は、知識不足、情報不足、処理能力不足によって引き起こされる。
認知プロセス
長期記憶
 知識と呼ばれるもの。ライブラリメソッドのふるまいなど
短期記憶
 情報と呼ばれるもの。メソッドの変数や名前の情報
ワーキングメモリ
 処理能。コードを擬似的にトレース実行することで何をしているのかなどを判断している

Chapter 2 コードを速読する

初心者と熟練者の違い
 熟練者は初心者と違い、チェスの盤面(プログラム)をより完成度高く再現できる。
熟練者は短期記憶の容量が大きいのでしょうか、それは違います。
熟練者は覚え方が異なる。陣形とその差分を覚えている。

チャンク
情報を覚える一塊
チャンク化しやすいコードを書く
何を覚えているのかではなく、どのように覚えたか

デザインパターンを利用する
デザインパターンを学ぶことでコードのチャンク化する能力が向上する

コメント
開発者はコメントを読むが、チャンク化のプロセスの邪魔をする

ビーコン
特徴を示す符牒

Chapter 3 プログラミング言語の文法を素早く習得する方法

文法の話
文法は調べたら出てきますが、都度調べていることは非効率的ですしチャンクの妨げになる。

文法を身につける方法
説明文と実装を反復して覚える
定期的に練習する
頭の中を思い出す記憶検索を実施する
調べた情報について考える(精緻化)

Chapter 4 複雑なコードの読み方

認知的負荷と認知的リファクタリング
ワーキングメモリの処理能には限界があり、コードを適切に処理できなくなる。
プログラムに関する認知的負荷は、コード固有の複雑さによるものとコードを書いた人と読む人の知識の差によるものがある。
本来のリファクタリングが結合度や複雑さを改善し、拡張や修正をしやすくするものだが読む人にとって読みやすくなるとは限らない。
読む人にとって読みやすくするリファクタリングを認知的リファクタリングという。

コードを読む練習
変数を丸でかこむ、同じ変数を線で繋ぐ
(メソッドや関数も同様)
状態遷移表に変数の遷移を書く

Part 2 コードについて考える

Chapter 5 コードの深い理解に到達する

変数の役割…固定値、ステッパー、フラグ、ウォーカー、直近の値の保持者、最も重要な値の保持者、収集者、コンテナ、フォロワー、オーガナイザー、テンポラリ

コード理解に必要なテキスト構造と計画の理解
1.フォーカルポイントを見つける
2.フォーカルポイントから知識を拡張する
3.関連する要素からコードの概念を理解する
4.複数の要素にまたがる概念を理解する

文書を読むこととコードを読むことは似ている
コンピュータサイエンスの学習とプログラミング言語の学習能力の高さに相関はなく、自然言語の学習能力の高さに相関がある。

初心者と熟練者のコードの読み方は異なっている
熟練者はまずはコードをスキャンして(ざっと眺めて)プログラムの動作を把握する。
自然言語で利用される理解手法の多くはプログラミング言語にも流用できる。

Chapter 6 プログラミングに関する問題をよりうまく解決するには

モデル化
計算式やダイアグラムなど現実を単純化した表現をモデルと言い、頭の中で利用し問題を考えるときに使うモデルをメンタルモデルという。
目の前の課題を推論するために、ワーキングメモリの中で概念を抽象化するものである。

メンタルモデルを効果的に使う方法
メンタルモデルを正しく具体化する。
 1.局所的なモデルの構築から開始する
 2.関連するオブジェクトと関係を表に書き出す
 3.自問自答し、モデルを改良する
メンタルモデルは長期記憶とワーキングメモリの両方に存在する
長期記憶に存在する(例:UML)
ワーキングメモリに存在する(例:UMLを利用してデザインパターンを理解する)

想定マシンはインタプリタとかさらに深い箇所の話なので割愛...

Chapter 7 誤認識:思考に潜むバグ

2つ目以降のプログラミング言語の習得が早いのはなぜか。
長期記憶に蓄えた知識は新しい状況に転移できる。
既存の知識を活用して早く習得できることを正の転移と言い、逆に悪影響を与えることを負の転移という。

誤認識
古いモデルによって、自身が誤っている(そしてそれに気づけない)ということが発生する。
誤認識を解消するには、間違っている可能性があることを自覚する。
チェックリストを用いる。
すでに習得しているプログラマーにアドバイスをもらう。

誤認識を知覚するためにはテストを実施することも有益である。

Part 3 より良いコードを書くために

Chapter 8 より良い命名を行う方法

よりよい命名を行う方法
より良い命名をされた変数やメソッド名を使ったコードはそうではないコードに比べコードの理解を助け、バグの発見を手助けする。
命名に重要なこと

  • 一貫性のあること
  • 明快(明確)であること
  • 必要な情報が含まれていること

略すべきか略さざるべきか
省略については一貫している事が重要
異なる略称が複数存在するくらいであれば省略しない方が良い

フェイテルソンの3ステップモデル
①名前に含めるべき概念を選択する
②それらの各概念を表す単語を選択する
③それらの単語を使って命名する

Chapter 9 汚いコードとそれによる認知的負荷を避けるための2つのフレームワーク

コードの臭いと認知負荷の話
コードの臭い(詳細はリファクタリングより)があることで認知負荷が上昇する。
理由は色々あるが、単純に構造化されていないことはそれだけ短期記憶で保持しなければならないものや時間が多くなる。

認知負荷を計測する
まずコードを9段階で評価する
そして理由を考える
これだけでもコードのアンチパターンを覚える事ができるので良い

言語的アンチパターン
命名と実装が異なっていることにより高い認知負荷を及ぼす。やりすぎ注意。

Chapter 10 複雑な問題をより上手に解決するために

複雑な問題をより上手に解決するために
問題解決のステップ
ゴール状態
スタート状態
ルール状態
そしてスタート状態からゴール状態へ遷移するための状態空間

問題解決能力とは
問題解決とはアプローチ(方法)が存在するだけでプロセスでもスキルでもない。
有名なプロセス(How to Solve Itより)
1.問題を理解する
2.計画を立てる
3.計画を実行する

問題解決のための記憶の種類
手続き記憶(潜在記憶)…意識せず行うことができる技能に関する記憶
宣言的記憶(顕在記憶)
 エピソード記憶…経験に基づく記憶
 意味記憶…概念、事実に関する記憶

問題解決のための記憶を培うテクニック
自動化…自身の記憶を潜在記憶に昇華させる
潜在記憶の改善…習得したいスキルや、違った新しいプログラムを書くことで潜在記憶を自律的段階に昇華させる

その他①学習関連負荷
脳が情報を長期記憶として保存するのにかかる負荷
問題解決を0ベースで行うよりも、前提となるレシピを渡し、長期記憶に保持する余裕が必要。ワーキングメモリには限界がある。
「専門家になるには、専門的なことをすればいいというものではない」

その他②コードを学習する際に利用可能な情報源

  • ペアプロ、モブプロ
  • OSSを読む
  • 技術記事を読む

Part 4 コーディングにおける共同作業

Chapter 11 コードを書くという行為

コードを書くという行為
プログラミングには検索、理解、転写、増強、探索といったアクティビティが存在し、異なるタイプの記憶システムを刺激する。

忌まわしき『割り込み』
タスクの割り込みが発生すると、作業者には不安や苛立ちなど心理的負荷と共に、メンタルモデルの再構築のため時間を要するため生産性が低下してしまう。

『割り込み』と付き合うために
メンタルモデルの再構築に時間がかかるため、メンタルモデルの保存、つまりドキュメントやメモに書き出しておくことが必要。できるならばメンタルモデル毎に分割し完了していると良い。

Slackのステータスなどで認知的負荷の高低をアピールする。

Chapter 12 より大きなシステムの設計と改善

コードベースの認知特性を調べる
CDN…表記表の認知特性
CDCB…コードベースの認知特性、異なる幾つかの特性からコードベースのユーザビリティを評価する

エラーの発生しやすさ…エラー全般の発生頻度、型推論を用いる言語はエラーの発生頻度は下がるがバグの発生頻度は上がる
一貫性…システム内の変数の命名やインデントに関する規則、フレームワークに一貫性がない場合、より高い認知負荷を及ぼす
拡散性…プログラミングにおける構成要素がどれだけ多くの記述や長さを要するのか
隠れた依存性…メソッドが別のクラスを参照していて更にその振る舞いが呼び出し側から見えない(隠れている)状態
暫定性…どれだけ自律的段階でのコーディングを進めることができるか(コーディングが容易であるのか)
粘性…変更容易性
段階的評価…部分的な作業のチェックや実行の容易性
役割表現力…コードのさまざまな部分における役割の理解容易性
マッピングの近接度…コードの内容がどれほどビジネス領域に近いか
ハードな心的操作…コードベース上の記憶領域への要求度合い
副次的表記…余計な意味をコードに追加する可能性
抽象化…システム全体と利用者の抽象化度合い(?)
視認性…システムのさまざまな部分をどれだけ簡単に見ることができるかを示す

それぞれの特性の評価を基に改善を行う

Chapter 13 新しい開発者のオンボーディング

良くないオンボーディングプロセス

  1. ジュニアに対して一度に大量の情報を与える
  2. その後質問やタスクを与える
  3. 新人の認知的負荷が高まり、上手くオンボーディングできなくなる

専門知識の呪い(curse of expertise)
何かのスキルや知識を会得してしまうと、その会得がいかに大変だったか忘れてしまうこと
この呪いが新人に対して過負荷となる情報やタスクを渡してしまう原因となる

ピアジェのオリジナルモデル
感覚運動期(0〜2歳)…物事を経験し行動することしかできない
前操作期(2〜7歳)…観察したものに対して仮説や計画を立てるが思考に活かすことはできない
具体的操作期(7〜11歳)…目に見える事象に仮説を立てて説明ができるが、一般化や最適解を出せない
形式的操作期(11歳以上)…形式的な推論ができる

新人のオンボーディングをサポートする
長期記憶のサポート…
 コード内で遭遇するビジネス領域の知識や概念をドキュメントにまとめる
 ビジネス領域の学習とプログラミング領域の学習を分けて行う
短期記憶のサポート…
 小さくて1つのことに特化したタスクを用意する
 理解だけに特化したタスクを与える(すべてをやらせない)
ワーキングメモリのサポート…
 ダイアグラムを描く※ダイアグラムが理解を助けることに有益ではない場合はやめる

コードを一緒に読む
 自然言語に共通する7つの戦略

読了と感想

認知科学、主に記憶と思考のアプローチからコードを読むときにどういった思考をしているのかがまとめられている。
 今まで言語化していなかったモデル化の手法や頭の中のどういう知識を使っているのかということを改めて考えるきっかけとなった。
 エンジニア界隈でよく聞く(言う)『完全に理解した』やシニアvsジュニア論争は耳が痛い話…
演習がプロダクトコード相手に使える内容であることも良かった。望むらくは、あと1年早く読んでおきたかった本(発売されてないけど...)

Discussion