エンジニアの学び方─効率的に知識を得て、成果に結び付ける

第2章最初の一歩をどう踏み出すか―必要なところを学ぶ、全体像をつかむ、写経する

本章では「勉強したいと思っているが『やる気』が出ない」という状態を解決し、一歩踏み出す方法について解説します。

やる気が出ない場合、⁠勉強」を漠然とした大きなタスクとしてとらえていて、その大きさに圧倒されていることがよくあります。ゴールの見えないマラソンでは、走り続ける「やる気」を出すのは難しいことです。もっと近いゴールを設定し、そこまで走ることを目標にすることが必要です。つまり「勉強」をもっと細かいタスクに分割することが必要です。

勉強を分割する方法は次の3つです。

  • 必要なところから学ぶ
  • 大まかに全体像をつかむ
  • 片っ端から写経する

上のものほど効率が良いのですが、より多くの前提知識を必要とします。

必要なところから学ぶ

たとえば、プログラミング言語を学ぼうとしているとしましょう。その言語を使って作りたいものが決まっているなら、それに必要なところから学ぶと効率が良いです。この方法は「遅延評価的勉強法」とも呼ばれます[1]⁠。遅延評価とは「式の値を、その値が必要になるまで計算しない」という意味の言葉です。YAGNIYou ain't gonna need it.という言葉もあります。これは、⁠機能は実際に必要となるまでは追加しないのがよい」という意味の言葉です。

これは本を読むときなら、⁠必要なところを開いてそこだけ読む」に相当します。不真面目なように思うかもしれません。しかし、学ぶことが目的なのか、学ぶことは別の目的を達成するための手段なのかは区別したほうがよいでしょう。手段として学ぶ場合に、必要ないことまで学ぶのは不必要なコストを支払っていることになり、経済的に合理的ではありません。

前提条件

必要なところから学ぶためには、前提条件があります。

目標が明確化されている

まず、目標の明確化が必要です。目標は「達成したかどうか」を判断できることが必要です。つまり「勉強する」は適切ではありません。⁠勉強する」という目標は、いくら努力しても達成できず、心が折れます。そうではなく、たとえば「Rubyの処理系をソースコードからビルドする」などがよいでしょう。これは達成したかどうかが判断できます。

目標が実現可能である

次に、目標はあなたにとって「たどり着けそう」であることが必要です。他人が何を目標にしているかではなく、あなたがあなた自身に適切な目標を決める必要があります。筆者の友人は「新しい言語を勉強するときには、その言語でレイトレーシング[2]を実装する」と言っていました。彼はレイトレーシングの実装に慣れていて、目標として適当なのでしょう。一方、筆者はレイトレーシングの実装に慣れていないので、新しい言語を学ぶための目標としては不適切です[3]⁠。

大まかに全体像を把握している

目的が明確で、目標がたどり着けそうでも、まだ十分ではありません。必要な情報を見つけるためにどこを探せばよいのか、大まかに全体像を把握できていることが必要です。⁠きっとあのあたりにドキュメントがあるだろう」「あのあたり」を思い付くことができないのであれば、あなたは先に次の節「大まかに全体像をつかむ」を行うほうがよいでしょう[4]⁠。

学びの理想的な状態

これは学びの軸の「広い知識」⁠深い理解」⁠応用対象」の全部にある程度の知識があり、学びの3つのフェーズ「情報収集」⁠抽象化」⁠応用」のサイクルがぐるぐる回っている状況です。どこに情報があるか大まかな位置がわかり、見つけた情報をすぐ応用し、動かしてみてその結果を見て、ほかに何が必要かがわかるわけです。

この学びができている状態が理想です。しかし、これは対象に十分詳しいからこそできることです。新しい分野にチャレンジしたときには使えません。なので最初からこの学び方ができないとしても悲観することはありません。

大まかに全体像をつかむ

もし必要な情報を見つけることができていないのなら、まず全体像を把握することが必要です。

たとえばソースコードを読むことを考えてみましょう。どうやって読めばよいでしょうか? 本を読むように頭から順番に? いいえ、違います。

まずは大まかに、徐々に詳細に

『Rubyソースコード完全解説』という本のソースコードの読み方の解説がとても簡潔にまとまっています[5]⁠。ぜひ一読をお勧めします。ここでは、その中から「静的な解析」の節を簡単に解説します[6]⁠。

ソースコードをどう読むのか? まず「構造を解説したドキュメント」を読みます。次に「ディレクトリ構造」を読みます。そして「ファイル構成」を読み、略語を調査し、と徐々に細かい単位にします。いきなり関数の中身を読みはじめたりせず、まずは大まかに全体像を見るところから始めるわけです。

書籍を読むときでも同じです。多くの速読の教科書では目次や章タイトルに注目することを勧めています。まずは大まかに、徐々に詳細に、というわけです。

ドキュメントの大まかな構造

実話を例に挙げます。先日「Pythonのglobalはファイル単位のスコープだ」という話を某所でしたところ、Xさんに『Python言語リファレンス』のglobal文の説明にはそんなこと書いていないけど、どこに書いてあるの?」と質問されました。これを聞いた筆者が最初に思ったことは、⁠チュートリアルに書いてあったはず。あと言語リファレンス見るにしてもそこは文法定義の章だから違う。もっと手前に実行モデルの章があったはずだ」でした。

そして数回Googleで検索して、『Pythonチュートリアル 9.2. Pythonのスコープと名前空間』に書かれています。あと言語リファレンスで言うなら『名前づけと束縛(naming and binding⁠⁠』です」と答えました。

X氏はけっしてプログラマとして能力が劣るわけではありません。違いは、筆者にはPythonのドキュメントの大まかな構造がわかっていたという点です。

英語の論文の大まかな構造

別の実話をします。筆者は「この論文を読むといいよ」と英語の論文を渡されました。それは筆者の思い付きと似たことをやっている先行事例でした。これを読むと、⁠自分の思い付きはすでにやられていることだ」という残念な結論になるかもしれません。無意識にそう考えたのか、なかなか読む気が起きませんでした。

頑張って最初から読んでも全然頭に入りません。苦痛です。そこでまず論文を印刷し、25分間で章見出しとキーワードを赤ペンで囲う作業をしました。⁠論文を理解する」というあいまいな目標の代わりに、時間を区切って明確なゴールを作り、大まかな構造を頭に入れようとしたわけです。そうすると、この論文は議論の出発点は筆者とかなり近いが、途中で予想と違う方向へ話が進んでいる、ということがわかりました。この結果「なぜ予想と違う方向へ進んだのか?」の答えを見つけるという「明確な目標」ができ、それがどこに書いてありそうかも大まかに理解できました。あとは簡単でした。

原因は、⁠この目的にはAにすべきところをBにしている」でした。今になって考えると、まず概要を読んで「やろうとしていることは筆者とまったく同じだな」と思ったのに、次に結論を読んで「さっぱり意味がわからない」と思ったのは、筆者が当然Aだと思っている前提をその論文の著者がBにしているせいだったわけです。大まかに全体像をつかんだことで筆者の考えと論文著者の考えがずれはじめるポイントがわかるようになったわけです。

深い理解が必要

この学び方を行うには、⁠応用対象」軸の知識は必要ありません。しかし、⁠深い理解」軸の知識は必要です。たとえばRubyのソースコードのファイル名を見てみましょう。compile.cというファイル名を見ても、コンパイルという概念を知らなければ何も読み取れません。知っていれば「ああ、ここがコンパイルをするんだな」とわかります。もっと理解が深ければ「ああ、ここがきっと抽象構文木を受け取ってVMのバイトコードを生成するんだろう」とわかるわけです。

片っ端から写経する

全体像を把握することもできない状態は、理解を組み立てるための材料が足りていません。大まかな説明を読んでも頭の中でイメージが湧かないのは、イメージするための知識がそもそも欠けているからです。

「何から学べば効率が良いか」と考えて足踏みをしてしまうことはよくあります。しかし、最初は誰でも「何から学べば効率が良いか」を判断する材料すら持っていません。そこで足踏みをしないで、まずは材料を手に入れることが必要です。

写経

新しいプログラミング言語を学ぶうえで「写経」というテクニックがあります。教科書などに載っているソースコードを、自分でキーボードで入力し実行する、というものです。効率はとても悪いのですが、まったく知識を持たない人が最初の一歩を踏み出すためには有用です。

しかし「写経」という言葉が原因で、いくつか誤解もあるようです。⁠原典に疑問を持ってはいけない」⁠雑念を捨てて無にならなければならない⁠⁠─⁠─これらは誤解です。それはただでさえ低い写経の学習効

率をさらに下げてしまいます[7]

「あれ、これ前にも出てきたな」とか「いつものパターンに似てるけどちょっと違うな」とか考えることが大事です。入力しながら類似点・相違点を発見することで、あなたの中に抽象的な知識が溜まっています。

また「なぜこうなっているのだろう」とか「ここをこう書き換えたらどうなるのだろう」という気持ちが湧いてくるととても良いです。それは「疑問を解決したい」⁠書き換えて試してみよう」という「明確な目的」につながります。

書籍でも同じ

これはプログラミングに限りません。ざっと眺めてもわからない本は、しっかり読むしかないのです。そして、しっかり読んでもわからないのであれば、手を動かしながら読むしかないのです。

手を動かしながら読むのは、ただ読むのよりもさらに時間がかかります。だから、なんとかして効率化できないかを考える必要があります。まず「必要なところだけ手を動かす」ができないかを考えます。必要なところがどこかわからないのであれば、⁠全体像をつかむために手を動かす」ができないかを考えます。そしてどちらもできないのであれば、粛々と手を動かすしかありません。しかし、たとえば「重要な点だけ簡潔にまとめられないか」⁠何度も出てくる単語を記号にできないか」⁠言葉で説明しているけど図を書いたほうが手っ取り早くないか」ということを考えながら書き写すのです。

特に数学のような、本の前のほうで定義した内容を使って続きの部分を圧縮している本では、ざっと眺めても後半が全然頭に入りません。後半を理解できるようになるために、まずは前半をしっかり理解しなければならないのです。一見逆説的に見えますが、手を動かしながらじっくり時間をかけて読むことで、全体の労力が減るのです。

時間を区切ろう

本1冊を丸ごと写経するとどれくらいの時間がかかるでしょう。ゴールが見えないのでは、やる気がなくなります。そこで、時間を区切りましょう。たとえば「今から25分でできるところまで写経するぞ」と目標を設定するのです[8]⁠。

25分やってみると、やる前よりもいろいろなことがわかるようになります。⁠知りたいこと」が生まれているかもしれません。全体像がなんとなくわかったかもしれません。自分がわかることは何か、わからないことは何か、何をもっと知りたいか、何にはあまり興味がないか、などが写経を行う前よりも具体的になったはずです。もし何も得られた感じがしないのであれば、その本はあなたのニーズやレベルに合っていません。

25分でたとえば5ページ写せたとします。教科書が300ページだったら、ざっくり言ってあと25時間写経すれば全部を写し終わります。最悪でも25時間を投入すれば、教科書を1冊写したという実績が得られるわけです。それを目指すべきでしょうか? いいえ。写経は目的ではなく手段です。必要がないと感じたらやめてもかまいません。

おわりに

本章では1人で勉強することを前提にして、独力で一歩踏み出すための方法について解説しました。しかし、もし良い教師を見つけられるなら、⁠教師が適切と思う順番に教えてもらう」という方法もあります。独力では「必要なところから」⁠大まかに」ができなくても、教えてもらいながらならできるわけです。大学のカリキュラムなども「教師が適切と思う順番」を知るうえで参考になります。大学の講義をネット上で受けられるサービスもあるのでそれを使うのもよいでしょう。

時間を割いて教えてくれる人がいない場合でも、すでに習得している人を見つけ、その人の行動を観察することで勝手に教師にすることができます。彼の行動を理解するのは同じことをするために「必要な」ことですし、彼が調べ物をするときにどういうキーワードを入れるのか、何を使うのかが、⁠大まかに」どこに情報があるかを知る助けになります。プログラミングの教育で「ペアプログラミング」が行われるのもこの理由です。

みなさんは、今は親切に教えてくれる社内研修の教師や技を盗める身近な先輩がいるかもしれません。しかし、これは恵まれた状況です。そういう人がいないときには、知識の交換によって学ぶことになります。お互いに相手の教師になるわけです。知識の交換がお互いにとって有益であるためには、お互いに相手よりも詳しい領域を持っていることが必要です。

おすすめ記事

記事・ニュース一覧