程序員必讀經(jīng)典長文:用十年時間自學(xué)編程
本文轉(zhuǎn)自雷鋒網(wǎng),如需轉(zhuǎn)載請至雷鋒網(wǎng)官網(wǎng)申請授權(quán)。
相信很多做技術(shù)的同學(xué)都自學(xué)過,也看過「Teach Yourself Programming in Ten Years」這篇文章。雖然離初次發(fā)表已經(jīng)好幾年了,但所有試圖自學(xué)編程的人都應(yīng)該發(fā)自內(nèi)心的同意它的說法(除去少數(shù)過時的具體技術(shù)部分)。直到今天,這篇經(jīng)典的文章依然很有借鑒意義。以下是這篇文章的中文版。
為什么每個人都這么匆忙?
走進任何書店,你都會看到如何在 24 小時內(nèi)自學(xué) Java,同時你還可以看到很多在幾天或幾小時內(nèi)學(xué)會 C、SQL、Ruby、算法等等的書籍。在亞馬遜使用「title: teach, yourself, hours, since: 2000」進行高級搜索,我發(fā)現(xiàn)了 512 本這樣的書。在排在前十名的書籍中,有九本是編程書籍,剩下一本是關(guān)于財務(wù)管理的。用「teach yourself」代替「learn」,或者用「day」代替「hours」產(chǎn)生的結(jié)果類似。
結(jié)論是,要么人們急于學(xué)習(xí)編程,要么編程比其他任何東西都更容易學(xué)習(xí)。Felleisen 等人在他們的書《How to Design Programs》中提到,「糟糕的編程很容易,即便是白癡都可以在 21 天內(nèi)學(xué)會」時,請對這一觀點表示贊同。
讓我們來分析一下在 24 小時內(nèi)學(xué)會 C++意味著什么:
-
自學(xué):24 小時內(nèi),你將沒有時間寫幾個重要的程序,并從成功和失敗中吸取教訓(xùn)。你將沒有時間和一個有經(jīng)驗的程序員一起工作,并理解在 C++環(huán)境中編程會是什么樣子。簡而言之,你將沒有時間去學(xué)習(xí)多少東西。所以這本書只能說是膚淺的熟悉,而不是深刻的理解。正如 Alexander Pope 所說,只學(xué)會一點點點東西是危險的
-
C++:在 24 小時內(nèi),你也許能夠?qū)W習(xí) C++的一些語法(前提是你已經(jīng)知道了另一種語言),但是你不能學(xué)到多少關(guān)于如何使用這門語言的知識。簡而言之,如果你是一個基層的程序員,你可以學(xué)習(xí)用 C++語法編寫 BASIC 程序,但是你不能學(xué)習(xí)到 C++真正的優(yōu)缺點。那又有什么意義呢?Alan Perlis 曾經(jīng)說過:「一種不影響你編程思維方式的語言,是不值得學(xué)習(xí)的。」有一種可能是,你必須學(xué)習(xí)一點 C++(或者是 JavaScript 之類的東西),因為你需要用現(xiàn)有的工具接口來完成特定的任務(wù)。但這種情況下,你不是在學(xué)習(xí)如何編程,而是在學(xué)習(xí)如何完成這項任務(wù)。
-
在 24 小時內(nèi):不幸的是,這根本不夠,正如下面所說的那樣。
用十年時間自學(xué)編程
很多研究人員發(fā)現(xiàn),在各種領(lǐng)域要成為專家大約需要十年時間,這些領(lǐng)域包括國際象棋、音樂創(chuàng)作、電報、繪畫、鋼琴演奏、游泳、網(wǎng)球和科學(xué)研究、神經(jīng)心理學(xué)和拓撲學(xué)等等。成功的關(guān)鍵是不斷的實踐:不只是一次又一次地做,而是每次都用一個超出你目前能力的任務(wù)挑戰(zhàn)你自己,嘗試去解決它,在做它的同時和之后分析你的表現(xiàn),糾正錯誤,然后重復(fù)這個循環(huán)。人和事情都沒有真正的捷徑:即便對莫扎特來說也是如此。4 歲就被稱為音樂天才的他,在開始創(chuàng)作世界級的音樂之前又花了 13 年時間來打磨自己。另一個例子是披頭士樂隊。披頭士樂隊似乎以一系列的熱門歌曲和 1964 年在艾德沙利文秀上的亮相而一夜成名。但實際上自從 1957 年以來,他們一直在 Liverpool 和 Hamburg 的小酒吧里面演出,雖然很早以前他們就受到大眾的歡迎,但他們第一次取得重大成功的專輯「Sgt. Peppers」是在 1967 年發(fā)布的。
Malcolm Gladwell 已經(jīng)普及了這個想法,盡管他的觀點是 10000 小時專注的努力,而不是 10 年。Henri Cartier-Bresson (1908-2004) 有一句名言:「你的前 10000 張照片是你最差的作品。」(他沒有預(yù)料到使用數(shù)碼相機,有些人可以在一周內(nèi)就拍完 10000 張照片。)真正成為專家可能需要一輩子:Samuel Johnson(1709-1784)說:「成為任何領(lǐng)域的卓越人士都需要畢生的努力,投機取巧并不可行」。Chaucer (1340-1400) 抱怨說:「人生太短暫了,而知識是無窮的」。Hippocrates (約公元前 400 年) 因為那句名言「ars longa, vita brevis」而被人稱頌,這句話的原文是「Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile」,意思是「生命很短暫,但是技藝卻很高深,機遇轉(zhuǎn)瞬即逝,探索難以捉摸,抉擇困難重重」。
當(dāng)然,沒有一個數(shù)字可以作為最終的答案,假定所有的技能(如編程、下棋、跳棋和音樂演奏)都需要完全相同的時間來掌握,或者所有人都需要完全相同的時間是不合理的。正如 K. Anders Ericsson 教授所說,「在大多數(shù)領(lǐng)域,即使是最有才華的人也需要很多時間才能達到最高水平,這是非常值得注意的。10000 小時這個數(shù)字讓你感覺到,我們說的是一周 10 到 20 個小時。」
你想成為一名程序員
以下是我的編程秘訣:
-
對編程感興趣,因為興趣而編程。請保持足夠的興趣,以便你愿意投入你的 10 年或者 10000 小時。
-
編碼。最好的學(xué)習(xí)方式是實踐。更嚴格地說,「在特定領(lǐng)域中,一個人的最高水平不是由于經(jīng)驗的積累自動獲得的,而是經(jīng)過深思熟慮的改進,經(jīng)驗豐富的人也可以提高水平?!?,「最有效的學(xué)習(xí)需要有一個明確的任務(wù),對特定的人來說難度適中,還要有信息反饋以及重復(fù)試錯和糾正錯誤的機會?!埂窩ognition in Practice: Mind, Mathematics, and Culture in Everyday Life」這本書正是這一觀點的有趣參考。
-
與其他程序員交談;閱讀其他程序。這比任何書籍或培訓(xùn)課程都重要。
-
如果你愿意,可以在大學(xué)(或研究生院)呆四年。這將使你有機會獲得一份需要證書的工作,讓你對這個領(lǐng)域有更深的了解,但如果你不喜歡學(xué)校,你可以自學(xué)或在工作中獲得類似的經(jīng)驗。無論如何,光靠書本知識是遠遠不夠的。「The New Hacker's Dictionary」的作者 Eric Raymond 說:「計算機科學(xué)教育不能使任何人成為一個專業(yè)的程序員,就像學(xué)習(xí)刷子和顏料不可以使某人成為一個專業(yè)的畫家一樣?!刮夜陀眠^的最好的程序員之一只有高中學(xué)歷,他開發(fā)了許多優(yōu)秀的軟件,擁有自己的團隊,并且擁有足夠買下一個夜店的股票期權(quán)。
-
與其他程序員一起做項目。在某些項目上你是最好的程序員,而在某些項目上你是最差的程序員。當(dāng)你是最好的時候,你可以鍛煉主導(dǎo)一個項目的能力,并用你的遠見激勵別人。當(dāng)你是最壞的時候,你可以學(xué)習(xí)大師們做什么,觀察他們不喜歡做什么(因為他們會讓你為他們做自己不喜歡的事情)。
-
接手其他程序員的項目,理解別人寫的程序。當(dāng)原來的程序員不在時,學(xué)習(xí)需要怎樣理解和修復(fù)程序。想想如何設(shè)計你的程序,讓那些在你之后的人維護它們更容易些。
-
學(xué)習(xí)至少六種編程語言。包括一種強調(diào)類抽象的語言(如 Java 或 C++),它強調(diào)函數(shù)抽象的語言(如 Lisp 或 ML 或 Haskell),一種支持句法抽象的語言(如 Lisp),一種支持聲明性規(guī)范的語言(如 Prolog 或 C++模板),一種強調(diào)并發(fā)性的語言(像 Clojure 或 Go)。
-
記住「computer science」中有一個「computer」。知道計算機執(zhí)行一條指令、從內(nèi)存中提取一個字符(有或沒有緩存)、從磁盤中讀取連續(xù)的字符以及在磁盤上尋找新的位置需要多長時間。
-
參與語言標準化工作。它可能是 ANSI C++委員會,也可以是決定你自己的本地編碼風(fēng)格是有 2 個或者 4 個空間縮進。無論哪種方式,你都可以了解到其他人對一種語言的喜好,他們的感受有多深,甚至可能了解他們的感受。
-
有很好的判斷力,盡快適應(yīng)語言的標準化
考慮到這一切,僅僅通過書本學(xué)習(xí)你能走多遠是個值得懷疑的問題。在我的第一個孩子出生之前,我讀完了所有的「How To」類型的書,但仍然覺得自己像個笨手笨腳的新手。30 個月后,當(dāng)我的第二個孩子出生時,我重新學(xué)習(xí)了那些書本知識嗎?不,相反,我依靠的是我的個人經(jīng)驗,這比專家們寫的幾千頁書更有用,更讓我放心。
Fred Brooks 在他的論文《No Silver Bullet》中指出了尋找優(yōu)秀軟件設(shè)計師的三個步驟:
-
盡早系統(tǒng)地發(fā)掘頂級程序員。
-
指派一名職業(yè)導(dǎo)師負責(zé)指導(dǎo)他,并謹慎對待履歷。
-
為成長中的程序員提供相互交流和互相激勵的機會。
這假設(shè)一些人已經(jīng)具備成為一個偉大的程序師所必需的素質(zhì),那么你的工作就是適當(dāng)?shù)睾弪_他們。Alan Perlis 的說法更加簡潔:「每個人都可以學(xué)會雕刻,但 Michelangelo 必須學(xué)會如何不雕刻。對偉大的程序員來說也是如此。」Perlis 認為,偉人有一些超越訓(xùn)練的內(nèi)在品質(zhì)。但是這些品質(zhì)是從哪里來的呢?是先天的嗎?或者他們是通過勤奮養(yǎng)成的?正如 Auguste Gusteau 所說:「任何人都能學(xué)會做飯,但只有無畏的人才是偉大的?!刮艺J為這更像是愿意將一生中大部分時間投入到某種實踐中,但也許無畏是總結(jié)這一點的一種方式?;蛘?,正如 Gusteau 的批評家 Anton Ego 所說:「不是每個人都能成為偉大的藝術(shù)家,但偉大的藝術(shù)家可以來自任何地方?!?/p>
所以繼續(xù)購買 Java/Ruby /JavaScript /PHP 書籍吧,你可能會從中得到一些有用的東西。但是它們不會在 24 小時或 21 天內(nèi)改變你的生活,也不會教會你作為一個程序員所需要的所有專業(yè)知識。何不努力工作,在接下來的 24 個月內(nèi)不斷改進?
參考書籍
-
Bloom, Benjamin (ed.)《Developing Talent in Young People》, Ballantine, 1985.
-
Brooks, Fred,《No Silver Bullets》, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.
-
Bryan, W.L. & Harter, N.《Studies on the telegraphic language: The acquisition of a hierarchy of habits》. Psychology Review, 1899, 8, 345-375
-
Hayes, John R.,《Complete Problem Solver》Lawrence Erlbaum, 1989.
-
Chase, William G. & Simon, Herbert A.《Perception in Chess》,Cognitive Psychology, 1973, 4, 55-81.
-
Lave, Jean,《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》, Cambridge University Press, 1988.
前面問題的答案
典型 PC 上各種操作所需要的大致時間:
-
執(zhí)行典型指令:1/100000000 秒,即 1 納秒
-
從一級緩存中提取:0.5 納秒
-
分支預(yù)測失誤:5 納秒
-
從二級緩存獲?。? 納秒
-
互斥鎖/解鎖:25 納秒
-
從主存儲器提?。?00 納秒
-
通過 1Gbps 網(wǎng)絡(luò)發(fā)送 2K 字節(jié):20000 納秒
-
從內(nèi)存中按順序讀取 1MB :250000 納秒
-
從新磁盤位置(SEEK)獲取:8000000 納秒
-
從磁盤中按順序讀取 1MB:20000000 納秒
-
將數(shù)據(jù)包發(fā)送到歐洲并返回:150 毫秒,即 150000000 納秒
附:語言選擇
有人會問,他們應(yīng)該先學(xué)什么編程語言。這里沒有標準答案,但請考慮以下幾點:
-
參考你的朋友。當(dāng)被問到「我應(yīng)該使用什么操作系統(tǒng),Windows、Unix 或 Mac?」我的回答通常是:「使用你的朋友使用的任何東西?!鼓銖呐笥涯抢飳W(xué)到的優(yōu)勢將抵消操作系統(tǒng)或編程語言之間的任何內(nèi)在差異。還要考慮你未來的朋友:程序員社區(qū)的人,如果你繼續(xù)的話,你將成為其中的一員。你所選擇的語言有一個大的正在成長的群體還是一個小的正在消亡的群體?有書、網(wǎng)站和在線論壇可以得到答案嗎?你喜歡那些論壇里的人嗎?
-
簡單實用。諸如 C++和 Java 這樣的編程語言是由有經(jīng)驗的程序員團隊設(shè)計的,這些程序員關(guān)心他們代碼的運行時效率。因此,為了應(yīng)對這些情況,這些語言有些地方是很復(fù)雜的。你關(guān)心的是學(xué)習(xí)編程。你不需要那么復(fù)雜。你需要的是一種語言,它對于新手程序員來說也可以可以很容易地學(xué)習(xí)和記憶。
-
互動。你更愿意用哪種方式學(xué)彈鋼琴:普通的,互動的方式,你一按一個鍵就聽到一個音符;或者「批量」模式,在這種模式下,你只在完成一整首歌后才聽到音符?顯然,互動模式使鋼琴學(xué)習(xí)和更容易。對編程來說也是如此,堅持使用互動模式的語言并使用它。
考慮到這些標準,對于要學(xué)習(xí)的第一種編程語言我的建議是 Python 或 Scheme。另一個選擇是 JavaScript,這不是因為它是為初學(xué)者精心設(shè)計的,而是因為它有很多在線教程,比如 Khan Academy 的教程。但每個人的情況都略有不同,還有一些其他的好選擇。如果你還是隔小孩,你可能更喜歡 Alice 或 Squeak 或 Blockly(年長的學(xué)習(xí)者也可能喜歡這些)。這些都沒關(guān)系,重要的是你要選擇并開始。
附錄:書籍和其他資源
有人問他們應(yīng)該從哪些書和網(wǎng)頁上學(xué)習(xí)。我再重復(fù)一遍:僅僅看書是不夠的。但我可以推薦以下資源:
-
Scheme:「Structure and Interpretation of Computer Programs (Abelson & Sussman)」可能是計算機科學(xué)最好的導(dǎo)論書籍,它也確實將教授編程作為理解計算機科學(xué)的一種方式。你可以在網(wǎng)上看到關(guān)于這本書的講座視頻,以及完整的文本。這本書讀起來具有挑戰(zhàn)性,將淘汰一些可能通過這種方法獲得成功的人。
-
Scheme:「How to Design Programs (Felleisen et al.)」是關(guān)于在實踐中如何以優(yōu)雅和實用的方式設(shè)計程序的最佳書籍之一。
-
Python:「Python Programming: An Intro to CS (Zelle)」很好地介紹了如何使用 Python。
-
Python:Python.org 上有一些在線教程。
-
Oz:「Concepts, Techniques, and Models of Computer Programming (Van Roy & Haridi)」被一些人視為 Abelson 和 Sussman 的現(xiàn)代繼承人。讀這本書會讓你理解編程思想,它的涵蓋范圍比 Abelson 和 Sussman 更廣泛,同時可能更容易閱讀和理解。它使用的語言是 Oz,這種語言并不廣為人知,但它卻是學(xué)習(xí)其他語言的基礎(chǔ)。
備注
T. Capey 指出,Amazon 網(wǎng)頁上那個「Complete Problem Solver」頁面把《Teach Yourself Bengali in 21 days》以及《Teach Yourself Grammar and Style》這兩本書移到了「購買此書的用戶還購買過這些產(chǎn)品」這個區(qū)域內(nèi)。我估計大部分人就是從這個區(qū)域看到這本書的。感謝 Ross Cohen 的幫助。
via:http://norvig.com/21-days.html