10年かけて独学でプログラミングを学ぶ(1998年)
(norvig.com)- プログラミングの実力は24時間・21日ものの入門書では身につきにくく、短期間の学習で得られるものはたいてい 表面的な親しみ に近い
- チェス・作曲・絵画・水泳・研究など、さまざまな分野の専門性に関する研究では、高い水準に達するまでおよそ 10年 かかり、重要なのは単なる反復ではなく 意図的な練習 であることが示されている
- 優れたプログラマーになるには、楽しさを保ちながら自分で作り、他人のコードを読み、より上手い人と一緒に働き、フィードバックを受ける必要がある
- 大学教育や本は資格・体系性・深さを補ってくれるが、実際のプロジェクトで失敗を修正し、保守まで経験することの代わりにはならない
- 最初の言語は友人やコミュニティ、シンプルさ、対話的な実行環境を基準に選べばよく、大事なのは一つ選んで 継続的に始めること である
短時間でプログラミングを学べるという約束の限界
- 書店やオンラインには、Java、C、SQL、Ruby、アルゴリズムなどを数日や数時間で教えるとうたう本が数多くある
- Amazon の詳細検索で 2000年以降にタイトルへ
teach yourself hoursを含む本を調べると 512冊 が見つかり、上位10冊のうち9冊がプログラミング本だった teach yourselfをlearnに変えたり、hoursをdaysに変えたりしても似たような結果になる
- Amazon の詳細検索で 2000年以降にタイトルへ
- こうしたタイトルは、人々がプログラミングを急いで学ぼうとしているか、あるいはプログラミングが他分野よりずっと学びやすいという印象を与える
- Felleisen らの How to Design Programs は、「悪いプログラミングは簡単だ。愚か者でも21日で学べる」といった形でこの流れを風刺している
“Teach Yourself C++ in 24 Hours” が実際に意味しうること
-
Teach Yourself
- 24時間では、意味のあるプログラムをいくつも書き、成功と失敗から学び、経験豊富なプログラマーと一緒に働き、C++ の世界で生きるとは何かを理解する時間はない
- したがって、得られるのは深い理解ではなく 上辺だけの慣れ に近い
-
C++
- すでに別の言語を知っていれば、24時間で C++ の文法の一部は学べる
- しかし、C++ が何に向き何に向かないのか、その言語を実際にどう使うべきかを学ぶのは難しい
- Alan Perlis の言葉を借りれば、「プログラミングに対する考え方を変えない言語は、知る価値がない」
-
24 Hours
- 特定のツールとつなぐために C++ や JavaScript、Processing のようなものを少し学ぶことはできる
- この場合、それはプログラミングそのものというより 特定の作業を実行する方法 を学ぶことに近い
専門性には時間がかかる
- Bloom、Bryan & Harter、Hayes、Simon & Chase などの研究は、さまざまな分野で専門性が形成されるまでにおよそ 10年 かかることを示している
- 例として、チェス、作曲、電信、絵画、ピアノ、水泳、テニス、神経心理学や位相幾何学の研究が含まれる
- 重要なのは単純な反復ではなく 意図的な練習(deliberative practice) である
- 現在の能力より少し難しい課題を選ぶ
- 実行中および実行後に結果を分析する
- ミスを修正して再び繰り返す
- Mozart は4歳で音楽の神童だったが、世界水準の音楽を作るまでにはさらに13年かかった
- Beatles は1964年の Ed Sullivan ショーや1位ヒット曲で注目されたが、1957年から Liverpool や Hamburg の小さなクラブで演奏しており、批評的に大きな成功を収めた Sgt. Pepper’s は1967年に出た
- Malcolm Gladwell は 10,000時間 という表現を広めたが、重要なのは正確な数字よりも、何年にもわたる継続的な練習である
- K. Anders Ericsson にとって 10,000時間とは、最高レベルに到達するには才能のある人でも週10〜20時間を何年も費やす必要があるという感覚を与える数字である
- 一つの数字がすべての答えになるわけではない
- プログラミング、チェス、チェッカー、音楽がすべてまったく同じ時間を要すると考えるのは難しい
- すべての人が同じ速度で学ぶとも限らない
プログラマーになるための実践法
- プログラミングに 興味 を持ち、楽しみとして始めるべきである
- 10年または10,000時間を投入できるほど、楽しさが続く必要がある
- 自分で プログラミング しなければならない
- 最良の学習は実践を通じた学習である
- 効果的な学習には、その人に合った難易度の明確な課題、有益なフィードバック、反復とエラー修正の機会が必要である
- 他のプログラマーと話し、他人が書いたプログラムを読むべきである
- これはどんな本や教育課程よりも重要である
- 望むなら大学で4年を過ごしたり、大学院でさらに学んだりしてもよい
- 学位は資格を求める職業への道を開き、その分野への深い理解を与えてくれる
- 学校が性に合わなくても、献身によって独学や現場で似た経験を得ることもできる
- 本だけで学ぶのでは十分ではない
- 他のプログラマーと 共同プロジェクト に取り組むべきである
- あるプロジェクトでは最も優れたプログラマーとなって、リーダーシップとビジョンを試せる
- 別のプロジェクトでは最も未熟な人になって、熟練者が何をし、何をしたがらないのかを学べる
- 他のプログラマーが去った後の 既存プロジェクト を扱うべきである
- 他人の書いたプログラムを理解し修正するには何が必要かを学べる
- 将来それを保守する人のために、どう設計すべきかも考えるようになる
言語とシステムに関する幅広い経験
- 少なくとも6つの プログラミング言語 を学ぶべきである
- クラス抽象化を強調する言語: Java, C++
- 関数型抽象化を強調する言語: Lisp, ML, Haskell
- 構文抽象化を支援する言語: Lisp
- 宣言的仕様を支援する言語: Prolog, C++ templates
- 並行性を強調する言語: Clojure, Go
- “computer science” には computer が入っていることを忘れてはならない
- 命令実行、メモリからのワード取得、キャッシュミス、ディスクのシーケンシャル読み出し、ディスク seek にかかる時間を知るべきである
- 言語 標準化 の活動に関わってみるのも役に立つ
- ANSI C++ 委員会のような大規模な活動かもしれないし、ローカルなコーディングスタイルでインデントを2スペースにするか4スペースにするかを決める程度かもしれない
- 他の人が言語の何を好み、なぜ強く感じるのかを学べる
- 標準化活動では、できるだけ早く抜ける 見識 も必要である
本と教育だけでは十分ではない
- 育児に関する本をたくさん読んでも、最初の子どもが生まれれば初心者のように感じることがあり、二人目の子どもが生まれる頃には再び本に戻るより個人的経験に頼るようになる
- Fred Brooks の No Silver Bullet は、優れたソフトウェア設計者を見つけるための3部構成の計画を提案している
- 優秀な設計者をできるだけ早い段階で体系的に見極める
- キャリアメンターを割り当て、成長への責任を持たせ、キャリアファイルを管理する
- 成長中の設計者たちが互いに交流し、刺激し合える機会を提供する
- Alan Perlis は「誰でも彫刻を学べるが、Michelangelo には彫刻しない方法を教える必要があっただろう」と述べている
- 卓越したプログラマーには、訓練を超えた内面的特性があるのかもしれないが、それが生まれつきか勤勉さによって育つものかは断定していない
- Java、Ruby、JavaScript、PHP の本は役に立つかもしれないが、24時間や21日で人生や専門性全体を変えることはできない
- 24か月にわたって改善し続けようと懸命に努力することは、意味のある出発点になる
コンピュータ動作時間の感覚
- 一般的な PC でさまざまな作業にかかるおおよその時間は次のとおりである
- 通常の命令実行: 1ナノ秒
- L1 キャッシュメモリからの取得: 0.5ナノ秒
- 分岐予測ミス: 5ナノ秒
- L2 キャッシュメモリからの取得: 7ナノ秒
- Mutex ロック/アンロック: 25ナノ秒
- メインメモリからの取得: 100ナノ秒
- 1Gbps ネットワークで 2KB 転送: 20,000ナノ秒
- メモリから 1MB をシーケンシャル読み出し: 250,000ナノ秒
- ディスクの新しい位置への seek: 8,000,000ナノ秒
- ディスクから 1MB をシーケンシャル読み出し: 20,000,000ナノ秒
- 米国と欧州の間でのパケット往復: 150ミリ秒、つまり 150,000,000ナノ秒
最初のプログラミング言語を選ぶ基準
- 最初の言語に唯一の正解はない
- 友人やコミュニティ を基準にできる
- OS を選ぶときに、友人が使っているものを使えという答えに近い
- 友人から学べる利点は、OS や言語そのものの違いを相殺しうる
- 選んだ言語に成長しているコミュニティ、本、Webサイト、オンラインフォーラムがあるかも考慮すべきである
- シンプルさ が重要である
- C++ や Java は経験豊富なプログラマーが大規模チームで専門的に開発するために設計されており、実行効率を考慮した複雑な部分がある
- 初学者にその複雑さは必要ない
- 対話的な実行環境 が学習を容易にする
- ピアノで鍵盤を押した瞬間に音を聞けるやり方が、曲全体を弾き終えてから聞くバッチ方式より学びやすいのと同じである
- プログラミングでも対話モードを提供する言語が有利である
- こうした基準から、最初の言語として Python または Scheme を勧める
- JavaScript は初心者向けに完璧に設計された言語だからではなく、オンラインチュートリアルが多いため候補になりうる
- 例として Khan Academy のチュートリアル がある
- 一桁年齢の学習者は Alice、Squeak、Blockly を好むかもしれず、年長の学習者でも楽しめる
- 重要なのは一つ選んで 始めること である
推薦図書と資料
- 本だけでは十分ではないが、次の資料は学習の助けになる
-
Structure and Interpretation of Computer Programs
- Structure and Interpretation of Computer Programs はコンピュータサイエンスの入門書として非常に優れており、コンピュータサイエンスを理解する方法としてプログラミングを教える
- 講義動画 と オンライン全文 を見ることができる
- 難度の高い本であり、別のアプローチで成功できる一部の学習者をふるい落としてしまう可能性もある
-
How to Design Programs
- How to Design Programs は Scheme を使って、エレガントで関数型的なやり方でプログラムを実際に設計する方法を扱う優れた本の一つである
-
Python
- Python Programming: An Intro to CS は Python を使う良い入門書である
- Python.org にはさまざまな 初心者向けチュートリアル がある
-
Oz
- Concepts, Techniques, and Models of Computer Programming は、Abelson & Sussman の現代的な後継だと見る人もいる
- プログラミングの大きなアイデアを幅広く扱っており、Oz という広く知られてはいない言語を使うが、他の言語を学ぶ土台になりうる
1件のコメント
Hacker News の意見
1999年に CompUSA で「Sams Teach Yourself C++ in 24 Hours」を買ったら、レジの店員がそれを見て笑い、この文章を教えてくれた
16歳のとき Borders でプログラミングの本を見ていたら、ある人が「The C Programming Language」を手渡してくれて、それが人生を変えた
キャリアのかなりの部分は、現実世界で開発者やプログラミングに興味のある人と偶然出会うことで形作られた
最後にそんな感覚を味わったのは、Microcenter で新しい MacBook と iPod Touch を持って出てきて、次の Angry Birds を作る準備ができたと感じたときだった
約8年後に Turbo Pascal を買ったときも、必要な資料がすべて入っていたので素早く習得できたし、1995年に Linux を始めたときは man ページと info ドキュメントだけで、そのシステムでプログラムを書くのに必要なほぼすべてを学べた
90年代末には EGCS マニュアルを最初から最後まで読んだ記憶もある
ソフトウェアが必要な情報をすべて同梱していた時代が懐かしいし、今のように製品ページやマニュアルを探すために Google を掘り回さなければならないやり方は残念だ
5年もしたら、関連情報が Discord にしか投稿されずインデックスされないせいで、マニュアル代わりに使っていた Google 検索すら懐かしく思うことになりそうだ
2000年代初頭の Linux と FreeBSD のソケットプログラミングも man ページだけで学び、後で Stevens の本を読んだときには、すでに man ページといくつかのプログラム作成経験のおかげで非常に速く読み進められた
AOL でメール添付ファイル100個に分割された Visual Basic 3.0 をダウンロードして、punter/prog の作り方を学びたかった
本のコードを写して、プログラム起動時に音声ファイルを再生しようとしたら、実際に動いたときは本当に驚いた
その後、ソフトウェア開発をキャリアにできたのは大きな幸運だった
90年代には、助言どころか信じられないという反応だけが返ってくることがかなり普通にあった
すべての開発者は、たとえすぐに C を忘れてしまうとしても、少なくとも一度は C と K&Rを読み、学ぶべきだ
この記事は、コーディングを学び始めたばかりの10代の頃に初めて読んだので、個人的に特別な意味がある
読み返してみると Malcolm Gladwell が出てきて驚いた。Outliers が話題になったのはもっと後だったと記憶していたからだ
Ratatouille への言及を見て初めて、1998年の公開後に記事が更新されていたことに気づいた。原文はアーカイブに残っており、ずっと短い: https://web.archive.org/web/19980206223800/https://norvig.co...
Peter Norvig が何年にもわたって自分の記事を直し続けてきたことは尊敬に値する
引用されすぎているし、1万時間の法則はいまや単なるミームのように感じる
今では独学でプログラミングを身につけたが、その道のりは当時想像していたよりもはるかに難しく、曲がりくねっていた
私は本で学ぶタイプでもあるが、そういう姿勢は変化の遅い数学・物理のような非コンピュータ分野のほうが合うことが多い
最近の悪い例は O'Reilly の Quantum Programming の本で、量子回路について、自分が何をしているのか本当に理解できるほど詳しく扱っていなかった
ただし、それは量子コンピューティング自体の見せかけかもしれないし、今読んでいる Nielsen/Chuang は非常に理論的だが説明がとても明快なので、後でまた戻るかもしれない
本は学習ツールにすぎず、趣味プロジェクトも経験が積めるという点では、むしろより効果的な学習ツールになり得る
それでも知識は力であり、本は自分のニーズに合う本を見つけたという前提で、正しい方向をつかむのに優れている
本を最後まで読める確信がなければそもそも開かない人たちも知っているが、そういう態度はばかげていると思う
さっき O'Reilly の Generative Deep Learning の本を注文したところで、キャリアに使える断片をいくつか拾えるだけでも十分に得だ
少なくとも本棚では見栄えがするはずだ
毎週新しいフロントエンドフレームワークが出てくるが、結局はどれも HTML を生成しているだけだ
16年分のスレッドです
再投稿は1年ほど経てば問題なく、過去スレッドへのリンクは、さらに知りたい読者のためのものです
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=33287618 - 2022年10月、コメント112件
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=27411276 - 2021年6月、コメント115件
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=20543495 - 2019年7月、コメント87件
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=16574248 - 2018年3月、コメント51件
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=9395284 - 2015年4月、コメント61件
Teach Yourself Programming in Ten Years (1998) - https://news.ycombinator.com/item?id=5519158 - 2013年4月、コメント86件
Teach Yourself Programming in Ten Years by Peter Norvig (2001) - https://news.ycombinator.com/item?id=3439772 - 2012年1月、コメント29件
Teach Yourself Programming in 10 Years. - https://news.ycombinator.com/item?id=1060176 - 2010年1月、コメント32件
Teach Yourself Programming in Ten Years - https://news.ycombinator.com/item?id=191235 - 2008年5月、コメント19件
Norvig: Teach Yourself Programming in Ten Years - https://news.ycombinator.com/item?id=43243 - 2007年8月、コメント7件
ページにある古いAmazon.comリンクが、かなり複雑なクエリパラメータまで付いているにもかかわらず、今でも関連する結果を返してくれる点が印象的です
“Cool URIs don't change”の好例です
[0] http://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=s...
[1] https://www.w3.org/Provider/Style/URI
職場などで、プログラミングの仕事をどうすれば得られるのかと聞いてくる人にかなり会ったことがある。
子どものころから学び始め、大きな趣味にし、コンピュータサイエンスの学位とインターンを経たという自分の経路を話すと、近道はないのだと驚き、がっかりされる。
それとも近道はあるのだろうか? 0から1へ行くブートキャンプを成功裏に終えた人がいるのか気になる。
高校と大学で趣味としてプログラミングの授業をいくつか取ったが、知識はかなり限られていた。
そのブートキャンプは名に恥じないもので、基本時間は9時〜5時だったが、多くの人が朝7時に来て夜10時に帰ることもあった。
週末にも通い、日曜日だけ休むこともあった。
あえて別の都市のブートキャンプを選び、社交生活に邪魔されないようにした。
RubyとJavaScriptに集中し、卒業から数か月後にC#/.NETのインターンとして就職した。
いきなりジュニア開発者の職に就くのは説得が難しそうだったのでインターンを選び、2週間でジュニア開発者に昇進した。
その学校はKaplanに買収された後、消滅した。
母の家の地下室で8か月間JavaScriptの基礎を独学し、就職できた。
その後はものすごく多くの時間をプログラミングに費やし、今までに数万時間を超えている。
コンパイラ、3Dグラフィックス、半導体、ゲームエンジンを扱ってきた。
自分の経験は、両方の見方を裏づけているように思う。
2012年ごろは、少ない経験でも比較的簡単に業界へ入れたが、その後、興味深いプロジェクトを持つ人たちが採用したいと思う良いエンジニアになるには、途方もない努力が必要だった。
限られたデータで見ると、伝統的な教育を受けた開発者と同じく当たり外れがある。
最も良い結果は、物理・化学・工学のような古典的な訓練を受けた人がキャリアチェンジを望む場合で、学習曲線の速い上級ジュニアに近かった。
純粋なプログラミングの比重が低いソフトウェア領域に意欲ある新人を入れたいなら、優れた採用になり得る。
標準偏差は大きいが、2年制卒業者より大きいかどうかはよく分からない。
大学では人文学を学び、コーディングはしたことがなかった。
最初の2年は本当に大変で、基礎がないため、ずっと流れに逆らって泳いでいるような感覚だった。
2年間のプログラムが終わるころになってようやく、独立して価値を出せると感じた。
自分の知識はかなり応用寄りで、コンピュータサイエンスの基礎が不足しているため、途中途中で基本を学びながら進まなければならず、より難しく感じることがある。
ただし現在の役割はデータエンジニアなので、データ構造やアルゴリズムのような伝統的なコンピュータサイエンス領域は相対的にそれほど要求されない。
核心は意図的な練習である。
ただ繰り返すのではなく、現在の能力より少し難しい課題に挑み、試し、実行中と実行後に分析し、ミスを直してからまた繰り返す必要がある。
学び続けるには、自分に挑戦し、コンフォートゾーンの外へ出なければならない。
数か月使っていたところ、たまたまログアウトされていたのだが、公式ドキュメントを探すちょっとした不便さをむしろ価値あるものに感じている。
最初の週は、ずっともたつく感じがして驚いた。
一次資料を通じて学ぶために追加のステップを踏み、ときには不便さを大切にすることが、プログラマーとして成長するうえで重要だ。
特に1〜2年生レベルの課題をCopilotだけで完成させたなら、自分自身の有用性を自動化で消しているのと同じになり得る。
一方で、「iPadキッズ」についても似たような話をしてきた。
iPadにもファイルシステムはあり、アプリもAppleが承認したやり方の範囲内で機能が増え続けているので、ノートPCの悪い近似とは言えないと思う。
自分もCopilotを使うが、主に変数の設定や些細な反復作業のための賢いオートコンプリートとして使っている。
問題解決を文脈化し、チームメンバーとやり取りするために使うべき時間を節約する用途であり、エンジニアを置き換えるものではない。
専門性は経験から来て、経験は何度も戻ってきて初めて積み上がる。
果てしない苦労へ自分を追い込める人もいるが、普通の人にとっては心から愛せるソフトウェアの一部を見つけ、それを育てるところから始めるのが賢明だ。
コーディングの分野で、自分より明らかに賢い人たちが、あまりに賢すぎて離れていくのを見てきた。
もう挑戦的ではないと感じたり、「ほかの人たちが追いつくのを待つ」ような間違った挑戦に疲れたと感じたりしたためだ。
たいていは、数年後に標準になる最先端技術を扱っていた人たちだった。
魅了されることが動機なら、自分が賢すぎないことを幸運に思ってもいいのかもしれない。
1998年の記事と表示されているが、ClojureやGoのような言及が含まれているので、その後更新された記事のように見える。
良い文章だと思う
1日8時間、週40時間を基準に1万時間を満たすには250週かかる
ほとんど休まずプログラミングしても約5年で、現実的には目標に到達するまで10年により近い
たくさんプログラミングすれば、年間3000時間にも簡単に到達できる
私はほとんどの日に1日12時間、ほとんどの週に週6〜7日プログラミングしている
やる気が非常に強い日は18時間やることもある
ほぼ10年近くこうしてきて、たまに1カ月ほど休みながら週3〜4日の長時間作業に減らすこともある
控えめに計算しても年3500時間くらいになる
これほど多く働く理由は、プログラミングを本当に愛していて、朝のサーフィンを除けばそれ以上にやりたいことがないからだ
それでも、堅実な開発者になるのにプロとしての経験10年ほどというのは、おおむね妥当に見える
5年で本当にそのレベルに到達した人は見たことがない
十代の頃から執着するようにやってきた人は数年短縮することもあるが、ある時点からはその期間も重なってくる
もちろん「1年の経験を10回繰り返しただけ」という問題を指す昔からの言葉もある
10年以上の開発者でも、堅実ではない人はたくさん見てきた
ジュニアの役割で入って、5年間働きながら上がっていけばよいように見える
直感は、だんだん難しい課題に取り組みながら積み上がる
ある瞬間に、ある領域で知っていることを別の領域へ結び付けて応用できるようになり、そのとき創造性が働き始める
5〜6年前に見た動画の出典は見つけられないが、プログラマーの数が増えるにつれて、その多数が経験5年未満だという趣旨を述べていた
ITとWebが生活にますます大きく関わるという文脈では納得できた
[0] https://youtu.be/ecIWPzGEbFc?si=A4qBR2YdX-0CV2bM wild_eggのコメントのおかげで見つけた
20年やってみると、今では自分がもう知る必要のない情報もかなりあり、経験5年未満の人たちにはおそらくまったく必要ない情報も多い
一方で経験は経験であり、物事が作られた構造と存在理由を知ることは常に役に立つ
私より経験が少なくても、私には想像すらできない多くのことができるプログラマーもたくさんいる
正直、チューリング完全性のあるこの分野はかなり広い
構文は別に暗記したことがなく、いつもmanページとマニュアルを開いたままプログラミングしていた
しかし学んだすべての言語と技術は、コンピューティングとシステムの根本問題について、有用な何かを教えてくれた
問題への取り組み方は違う服をまとうが、問題そのものは変わらない
近道はなく、プログラマーとしての今の私は5年目の自分より何桁も有能だと確信している
新しく学び、新しいことをするのがこれまで以上に楽しみなのは、それらがこの技術のさらに多くの部分を開いてくれるからだ
心配なのは、いつか体と心がついてこなくなることだけで、学ぶものが尽きることや若い人たちに追い越されることではない
https://youtu.be/ecIWPzGEbFc?si=A4qBR2YdX-0CV2bM
まだ錬金術師の時代のように感じる
いつか化学者たちが現れて、場当たり的な観察を体系化し、多くのものを捨てるだろう
それまでは……Newtonも錬金術師だったが、それでもかなり大きな貢献をした