キャリア
10年かけてプログラミングを学ぶ
Teach yourself programming in ten years (1998) (norvig.com)
要約
この記事は、数時間や数日でプログラミングを習得できると謳う書籍の風潮に疑問を呈しています。真の専門知識は、チェスや音楽などの分野と同様に、約10年または1万時間の意図的な練習(deliberate practice)を通じて培われると論じています。成功への道は、楽しみながら継続的に実践し、他のプログラマーと交流し、多様な言語を学ぶことにあると提唱しています。
全文翻訳
10年かけてプログラミングを学ぶ
Peter Norvig
なぜ誰もがこんなに急いでいるのでしょうか? 書店に入ってみると、「24時間でJavaを学ぶ方法」といった本が、数日や数時間でC、SQL、Ruby、アルゴリズムなどを学べるという無数のバリエーションと共に並んでいます。Amazonで「teach」「yourself」「hours」「since: 2000」で高度な検索をかけると、512件のそのような書籍が見つかりました。そのうち上位10件のうち9件はプログラミング関連の本でした(残りの1件は簿記に関するものです)。「teach yourself」を「learn」に置き換えたり、「hours」を「days」に置き換えたりしても、同様の結果が得られます。このことから、人々がプログラミングを学ぶことに非常に焦っているのか、あるいはプログラミングが他の何よりも驚くほど簡単に学べるかのどちらかだと結論付けられます。Felleisenらは、彼らの著書「How to Design Programs」の中で、「悪いプログラミングは簡単だ。愚か者でも21日で学べる、たとえそれがドジな人でも」と述べることで、この傾向に言及しています。Abtruse Gooseのコミックもこの件について独自の解釈をしていました。
「24時間でC++を独学する」のようなタイトルの意味を分析してみましょう。
独学する:24時間では、いくつかの重要なプログラムを作成し、それらでの成功と失敗から学ぶ時間はありません。経験豊富なプログラマーと協力して、C++環境で生活することがどのようなものかを理解する時間もありません。要するに、あまり多くを学ぶ時間はないということです。したがって、その本は深い理解ではなく、表面的な知識についてしか語ることができません。Alexander Popeが言ったように、少しの知識は危険なものです。
C++:24時間あれば、C++の構文の一部(すでに別の言語を知っている場合)を学ぶことはできるかもしれませんが、その言語をどのように使うかについてはあまり学べません。要するに、もしあなたが例えばBasicプログラマーだったなら、C++の構文を使ってBasicスタイルのプログラムを書くことは学べますが、C++が実際に何に適しているか(そして何に不向きか)を学ぶことはできないでしょう。
では、そのポイントは何でしょうか? Alan Perlisはかつてこう言いました。「プログラミングについての考え方に影響を与えない言語は、知る価値がない」。可能性のあるポイントの1つは、特定のタスクを達成するために既存のツールと連携する必要があるため、C++(あるいはそれよりもJavaScriptやProcessingのようなもの)を少し学ぶ必要があるということです。しかし、その場合、あなたはプログラミングを学んでいるのではなく、そのタスクを達成する方法を学んでいるのです。
24時間で:残念ながら、これは十分ではありません。次のセクションで示します。
10年かけてプログラミングを学ぶ
研究者(Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973))は、チェス、作曲、電信操作、絵画、ピアノ演奏、水泳、テニス、神経心理学やトポロジーの研究など、さまざまな分野で専門知識を開発するには約10年かかることを示しています。鍵となるのは意図的な練習(deliberative practice)です。ただ何度も繰り返すだけでなく、現在の能力を少し超えたタスクに挑戦し、それを実行し、実行中および実行後に自分のパフォーマンスを分析し、間違いを修正することです。そして繰り返します。さらに繰り返します。近道は実際にはないようです。4歳で音楽の天才だったモーツァルトでさえ、世界クラスの音楽を作り始めるまでさらに13年かかりました。別のジャンルでは、ビートルズは1964年に次々と1位を獲得し、エド・サリバン・ショーに出演してシーンに登場したように見えました。しかし、彼らは1957年からリバプールとハンブルクの小さなクラブで演奏しており、初期には大衆的な人気がありましたが、彼らの最初の偉大な批評的成功である「サージェント・ペパーズ」は1967年にリリースされました。Malcolm Gladwellはこのアイデアを広めましたが、彼は10年ではなく1万時間に焦点を当てています。Henri Cartier-Bresson (1908-2004) は別の指標を持っていました。「あなたの最初の1万枚の写真は最悪だ」(彼はデジタルカメラの登場で、人々が1週間でその数に達することができるとは予想していませんでした)。真の専門知識は一生かかるかもしれません。Samuel Johnson (1709-1784) は「あらゆる分野での卓越性は、一生の労働によってのみ達成できる。それより安い価格で購入することはできない」と言いました。そしてChaucer (1340-1400) は「人生はあまりに短く、技術は学ぶのがあまりに長い」と不平を言いました。Hippocrates (紀元前400年頃) は「ars longa, vita brevis」(芸術は長く、人生は短い)という抜粋で知られていますが、これは「Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile」(人生は短く、技術は長く、機会は逃げやすく、実験は危険で、判断は難しい)というより長い引用の一部です。
もちろん、単一の数字が最終的な答えになることはありません。すべてのスキル(例えば、プログラミング、チェス、チェッカー、音楽演奏)が習得に全く同じ時間だけ必要だと仮定するのは合理的ではないようですし、すべての人々が全く同じ時間を要するわけでもありません。K. Anders Ericsson教授が言うように、「ほとんどの領域において、最も才能のある個人でさえ、最高のパフォーマンスレベルに到達するためにどれだけの時間が必要かというのは驚くべきことだ。1万時間という数字は、週に10〜20時間で数年かかるという感覚を与えるだけであり、これは最も生まれつき才能のあるとされる人々でさえ最高のレベルに到達するために必要な時間である」。
したがって、あなたはプログラマーになりたい
私のプログラミング成功へのレシピは次のとおりです。
プログラミングに興味を持ち、楽しいからという理由でいくつかやってみてください。それが十分に楽しいままであることを確認してください。そうすれば、10年/1万時間を費やすことを厭わなくなるでしょう。
プログラムを書くこと。学習の最良の方法は、実践による学習です。より技術的に言えば、「特定の領域における個人の最大限のパフォーマンスレベルは、長期間の経験の関数として自動的に達成されるのではなく、パフォーマンスレベルは、改善のための意図的な努力の結果として、経験豊富な個人でさえ向上させることができる」(p. 366)そして「最も効果的な学習には、個人に合った適切な難易度の明確に定義されたタスク、有益なフィードバック、そして繰り返しとエラー修正の機会が必要である」(p. 20-21)。「Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life」という本は、この見解に関する興味深い参考資料です。
他のプログラマーと話すこと。他のプログラムを読むこと。これは、どんな本やトレーニングコースよりも重要です。
もし望むなら、大学に4年間通うこと(あるいは大学院でそれ以上)。これにより、資格が必要な仕事にアクセスでき、分野への深い理解が得られますが、学校が楽しめない場合は、献身次第で自分で、あるいは仕事で同様の経験を得ることができます。いずれにせよ、本を読むだけの学習では不十分です。「ブラシと絵の具を研究しても、誰かを熟練した画家にはできないのと同じように、コンピュータサイエンスの教育では誰かを熟練したプログラマーにすることはできない」と、「The New Hacker's Dictionary」の著者であるEric Raymondは述べています。私が雇った中で最も優れたプログラマーの一人は、高校卒業資格しか持っていませんでしたが、彼は多くの素晴らしいソフトウェアを作成し、独自のニュースグループを持ち、ストックオプションで自身のナイトクラブを購入できるほど稼ぎました。
他のプログラマーと一緒にプロジェクトに取り組むこと。いくつかのプロジェクトでは最高のプログラマーになり、他のプロジェクトでは最低になりましょう。最高であるときは、プロジェクトをリードする能力を試し、あなたのビジョンで他の人を鼓舞することができます。最低であるときは、マスターが何をするか、そして彼らが(あなたにやらせるから)何をしたくないかを学びます。
他のプログラマーが作成したプロジェクトに取り組むこと。誰かが書いたプログラムを理解すること。元のプログラマーがいない場合に、それを理解し修正するために何が必要かを見ること。あなたが去った後に保守する人々にとって、プログラムを設計しやすくする方法について考えること。
少なくとも6つのプログラミング言語を学ぶこと。クラス抽象化を重視する言語(JavaやC++など)、関数抽象化を重視する言語(Lisp、ML、Haskellなど)、構文抽象化をサポートする言語(Lispなど)、宣言的仕様をサポートする言語(PrologやC++テンプレートなど)、並列処理を重視する言語(ClojureやGoなど)を含めてください。コンピュータサイエンスには「コンピュータ」があることを忘れないでください。コンピュータが実行にどれだけの時間がかかるかを知ること