プログラマー脳
長年プログラミング教育の研究に取り組んでいる著者が、最新の「認知科学」に基づいて、プログラミングの際のさまざまな作業や技術の取得を効率的に行うための方法を解説しています。
まずは、コードを書いたり読んだりするときに「プログラマーの脳」がどのように働くかという認知プロセスについて説明しています。なぜなら、作業が異なれば、利用する認知プロセスも異なり、使うべきテクニックも変わってくるからです。
認知プロセスの段階や相互作用について理解したところで、「コードを速く、深く読む」「コードを読みやすくする」「新しい言語を短時間で習得する」といったことについて、どの認知プロセスを活用しているのかを考えて、どのような方法を採るべきかなのかを具体例を挙げて説明しています。また、プログラミングそのものではありませんが、新しい開発者を迎え入れる際のオンボーディングプロセスについても、認知科学的な側面から掘り下げています。
masuyama13.iconまとめ
メモ
コーディング中の混乱のタイプ
知識不足 = 長期記憶の問題
情報不足 = 短期記憶の問題
処理能力不足 = ワーキングメモリの問題
コードの速読法
短期記憶は6つ程度しかできない
すぐに消えていく
熟練者は初心者よりもたくさん記憶できる
知っているものは長期記憶になる
長期記憶を増やす
チャンク
ビーコン
デザインパターン
文法を覚えることは大事
長期記憶になっていればその分処理能力が上がる
Web検索などの割り込みは生産性を著しく低下させる
フラッシュカードを使う
定期的に復習する
情報をただ見るだけでは不十分
毎回調べることは非効率だが簡単なので、脳は覚える必要がないと思ってしまう
思い出そうとすることで記憶が強化される
検索強度を高める必要がある
精緻化
覚えたいことを考え、既存の記憶と関連付けネットワークを強化
思い出しやすくなる
ワーキングメモリ
問題の処理に用いられる短期記憶
短期記憶と同じなので6つまで
認知的負荷
認知的リファクタリング
インライン化などの逆リファクタリング
自分が読みやすい書き方にしてコードリーディングの認知負荷を下げる
依存関係グラフ
コードを PDF 保存して手書きで書き込む
状態遷移表
PythonTutor
変数の役割フレームワーク(P84)
11種類しかない
固定値
円周率
ステッパー
ループのたびに値が変更される変数
フラグ
ウォーカー
ステッパーと同様データ構造を走査するために利用されるが、どのように走査を行うのか未知のケース
直近の値の保持者
最も重要な値の保持者
収集者
コンテナ
リスト、配列、スタック、ツリーなど
フォロワー
後から参照するために前の値や次の値を保持する
オーガナイザー
データ整形や並べ替え
テンポラリ
コードを PDF 保存して変数の役割を書き込む
プログラム理解のステップ(エラー発生時など)
1. フォーカルポイントを見つける
2. そのフォーカルポイントから知識を拡張していく
3. 関連している要素から、そのコードに利用されている概念を理解する
呼び出されているメソッドを近くに移動させて負荷を下げる
4. 複数の要素を横断して利用されている概念を理解する
コードを深く理解するためのステップ
1. すべての変数を丸で囲む
2. 類似した変数を線でつなぐ
3. すべてのメソッドや関数を丸で囲む
4. メソッド/関数呼び出しをその定義場所を線でつなぐ
5. クラスのインスタンスをすべて丸で囲む
6. クラス定義とそのインスタンスの間に線を引く
コードを読むことは文章を読むことと似ている
自然言語の学習能力と相関がある
コードを読むときは、自分が何を読んでいるのか、理解できているのかを把握し続けること
どの行が重要なのかを判断する
変数の名前の意味を考える
コードの要約
このコードの目的
最も重要な行
最も関連深いビジネス領域の概念
最も関連深いプログラムの構造
コード作者の下した決定
コードについて考えるためにモデルを利用する
メンタルモデル
目の前の問題について推論するために、ワーキングメモリの中で概念を抽象化するもの
データ構造
デザインパターン
アーキテクチャパターン
長期記憶とワーキングメモリの両方に存在する
転移
正の転移
負の転移
すでにある知識のせいで誤解してしまうこと
転移が無意識に起こることはほぼない
あるプログラミング言語を習得したことが新しい言語の習得に役立つとは限らない
類似点と相違点をよく意識することが大事
誤認識
バグ調査
思い込みがあるために間違いに気づけない
概念変化
メンタルモデルを置き換える
新しい概念を学んでも、古い記憶が思い出されることがある
同じ順番でコードを学んだ人に、誤認識しやすいポイントを聞く
名前重要
名前は
コードの大部分を占める
ドキュメントである
ビーコンである
名前チェック
事前知識がなくても意味のわかる変数名になっているか
勘違いしやすそうな略語が使われていないか
類似した他の名前はあるか?ある場合、類似したオブジェクトに用いられているか
スネークケースよりキャメルケースの方が覚えやすい
よくない名前が使われているコードはバグを生みやすい
名前づけのステップ
1. 名前に含めるべき概念を選択する
2. それらの各概念を表す単語を選ぶ
3. それらの単語を使って命名を行う
コードの臭い
言語的アンチパターン
メソッド名と実際の処理が異なる場合、間違ったチャンク化が行われやすい
問題解決
手書き記憶(潜在記憶)
意識せずに行うことができるもの(自転車の乗り方など)
宣言的記憶(顕在記憶)
記憶していることを自覚している記憶
アンラーニングは難しい
負の転移が起こる
例)Qwerty キーボードに慣れると他のキーボードを使うのは難しい
プログラミングに関する潜在記憶(意識せずともできること)が多いと認知的負荷が下がり、より複雑な問題解決が可能となる
スキルを自動化する
意図的な反復練習
学習関連負荷
認知的負荷が高いと学習関連負荷(脳が情報を長期記憶に戻して保存するのにかかる負荷)の余地がなくなり、後から思い出すことができない
コードリーディングクラブ
自分が使っているライブラリのコードを読む
プログラミング中に行う作業
検索
コードリーディングするときはコメントを書き込むとよい
理解
転写
コードを書くこと(長期記憶を使う)
増強
探索
割り込み
再開するのに25分かかる
回復を助けるテクニック
メンタルモデルを保存する
コメントを書いておく
展望記憶を補助する
TODO コメント
下位目標のラベルづけ
あらかじめ手順を書いておく
割り込みが入るとネガティブな感情が湧く
イライラ、不安
生産性が低下する
人はマルチタスクができない
熟達者と初心者はまったく異なる考え方・行動をする
熟達者
長期記憶の蓄積があるためチャンク化が容易
抽象的に見ることができる
初心者
コードの細部に注目する傾向がある
新しい概念を学ぶとき、抽象と具体の両方を知る必要がある
既存の知識と結びつけて覚えるための時間が必要