学習効率をハックするための考え方

# はじめに


:::note

下記の記事にてよりわかりやすい説明を施しました。

https://qiita.com/DaikiSuyama/items/1be9d19352e62614ce35

:::

エンジニアは、刻一刻と変化する技術に合わせて学習を効率よく進める必要がある職業であるため、いかに学習を高速化するかが重要となる。

本記事では、エンジニアに必要な**学習の観点**について再考し、**学習を高速化するための方法**について提言する。

プログラミングに関連する多くの知識に対して汎用性高くアプローチできるように記事を書いているので、ぜひ参考にされたい。

# 学習の観点

## 学習とは

本記事では、「**あるドメインを構造的に理解すること**」を学習と定義する。PHPやPythonのような言語、LaravelやDjangoのようなフレームワークなど、様々なものがここでのドメインに相当する。

そして、本記事では、学習の観点として**広さ・深さ・関係性**の3種類を定義する。また、ドメインを簡易的に木構造として表現した下図も理解の参考にされたい[^2]。加えて、これらの3種類については、学習の軸として持ちながら常に更新し続けることが重要だと自分は思っている。

<img width="600px" alt="3direction" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331393/cf2c3242-fcee-5a6e-3f75-f2a94e27e32c.png">

## 広さ

### 定義

「あるドメインを一定のまとまりを持ったグループごとに分割した時のグループの個数」を広さと定義する。上図においては、赤線で区切られたまとまりがグループであり、この赤線が多くなるほど広さが大きくなるイメージである。

ドメインを構造的に学習する際、**ドメインの全体像を把握すること**が前提にある。そのため、広さの観点での学習が必要である。

### 学習方法

広さの観点での学習に適しているのは、各ドメインの**チュートリアル**であると考える。チュートリアルは初学者を対象としたそのドメインへの導入のための資料と考えられ、深さや関係性といった部分よりは広さという部分に焦点を当てて作られていることが多いためである。

また、初心者のうちは、後述する深さや関係性の観点については意識しすぎず、広さのみに焦点を当てて素早く学習することをお勧めする。学習コストが高く、入門する前に諦める可能性を低くするためである。

そして、ある程度そのドメインの知識がついてきた段階では、さらにドメインをより大きく捉えるために、記事やスライドや本などの様々なアプローチで広さの観点での学習を進めることをお勧めする。

### 実体験

広さの観点での学習に失敗したのは、初めてWebアプリを作成しようと思ってRailsチュートリアルに取り組んだ時である。Railsチュートリアルは内容の豊富さが故に広さの観点での学習が難しく挫折した。当時から広さの観点での学習を意識していれば、**自分に適切な広さを選択して素早く学習できた**ように思える。

## 深さ

### 定義

「あるドメインをグループごとに分割した時のグループの要素数」を深さと定義する。上図においては、赤線で区切られたグループがさらに青線で区切られており、この青線が多くなるほど深さが大きくなるイメージである。

ドメインを構造的に学習する際、全体像を捉えられている元でさらにそのドメインの理解を深めるには、**それぞれのグループの理解を深める**必要がある。そのため、深さの観点での学習が必要である。

### 学習方法

深さの観点での学習に適しているのは、各ドメインの**ドキュメントやソースコード**であると考える。チュートリアルの広さや深さをより拡張したのがドキュメントであると考えられ、より深い理解を得ることができる。そして、ソースコードの場合、それぞれの挙動をコードベースで追うことができるため、ドキュメントからは推測できない仕様等まで深く理解することができる。

また、この段階では、**学習をより実践的にする**必要があると考えている。ただ読んで理解するのではなく、業務等で実践する際に必要となった生きた知識として理解していくことをおすすめする。

### 実体験

深さの観点での学習の必要性を感じたのは、コードレビューの時である。まだ十分に実装力がない場合、調べて出てきたコードを理解せずに使うのは深さの観点での学習が足りない。しかし、コードレビューの中では、明らかにドキュメントすら読んでないようなその場しのぎのコードを見つけることがある。どこまで深掘りするかは時間の問題もあるが、深さの観点を持っているだけでも、実装力の向上につながる。

## 関係性

### 定義

「あるドメインをグループごとに分割した時のグループ間または要素間での関係性」を関係性と定義する。上図においては、黄線が関係性に相当し、黄線が多くなるほど関係性も増えるイメージである。

ドメインを構造的に学習する際、任意の要素を学習したと仮定しても関係性を捉えていなければただの暗記に留まり、**実用性が低い**。そのため、関係性の観点での学習が必要である。

### 学習方法

関係性の観点での学習に適しているのは、**専門書の類**であると考える[^5]。専門書の場合、筆者の視点から構造的にあるドメインを説明していると考えられ、より関係性の観点での理解を深めることができる。

また、専門書であってもその著者による観点しか得られないため、複数の本を読んで多様な観点から関係性を捉える必要があると考えている。加えて、関係性は抽象度の高い概念であるため、関係性を図示するなどにより、頭の中を整理する必要が出てくる場合も時にはある。

### 実体験

関係性の観点での学習が必要なのは、資格は持っているが業務には生かせない人であると思う。このような人の場合、暗記のみに留まり、あるドメインを構造化して捉えられてないのではないだろうか。

# いかにして学習を高速化するか

## ドメイン間での関係性

学習を高速化するには、**学習しているドメインと過去のドメインとの間での関係性を捉えること**が必要であると考える。この時、学習しているドメインと過去のドメインを包含するようなドメインを上位ドメインとして仮定すると、上位ドメイン内での関係性が捉えたい関係性に相当する。

例えば、過去にDjangoを学習していてLaravelを学習したい時、その上位ドメインとしてはWebアプリケーションフレームワークが相当する。つまり、このような拡張を行うことで、ドメイン内での関係性の理解に落とし込むことができる。

## 共通部分と差分

ドメイン間での関係性を元に**共通部分と差分に着目すること**で学習を高速化することができる。

例えば、プログラミング言語を学習する際に、既にある言語を理解していれば他の言語を高速に学習することができる。この高速化の要因は、基本文法の部分にのみ差異があって他の部分は共通していることである。

また、プログラミング言語に習熟している方であれば、「基本文法の部分にのみ差異がある」が間違いであることはわかると思う。それぞれの言語の作られた背景が異なるため、プログラミングパラダイムや型付けなど様々な相違点が存在するからだ。つまり、共通部分と差分を意識して学習を高速化することは重要であるが、**それぞれのドメインの理解度も同時に重要である**と考えられる。

## 抽象化

先程の共通部分と差分のところでプログラミング言語を例として紹介したが、一見すると関係性の無いドメイン同士であっても**抽象化によって共通部分や差分を捉えること**ができ、学習を高速化することができる。

例えば、VueとLaravelの場合、前者はUIを構築するためのフレームワークで後者はWebアプリケーションを構築するためのフレームワークであり、両者の間には関係性がないようにも思える。しかし、両者の間にコンポーネントという単位で構成されているフレームワークという共通部分が実はある[^6]。

# まとめ

本記事では、学習の観点を3種類提示し、学習の高速化の方法についても3段階紹介した。ただ、抽象化して捉えるまで到達するには多くの経験が必要であると思う。しかし、本記事のように**捉え方を変えることで学習を少しずつ高速化すること**は可能であると考える。

また、本記事で提言したのは一つの学習方法であり、学習の高速化のための方法は世の中に沢山ある。様々な学習方法を参考に自分に最適な学習方法へと磨き上げていく行為を続けていくのが重要であるとも考える。

# 追記

- 本記事で書いたことをビジネス的な観点から捉えているスライドを発見したので、ぜひ参考にされたい。

https://speakerdeck.com/tumada/jie-xiang-du-wogao-meru


[^2]: 本記事では説明をしやすくするために木構造としてドメインを表現したが、実際にはより複雑なグラフ構造となる。

[^5]: 自分の場合は専門書というよりは信頼できる筆者の記事やスライド等を読んでいるが、こちらでも代用可能な場合は多い。

[^6]: 正確には、関心の分離という観点からコンポーネントでの構成という流れであるため恣意的な順序での説明とはなる。