<meta charset="utf-8">
<meta charset="utf-8">
相信很多做技術(shù)的同學(xué)都自學(xué)過(guò)辫封,也看過(guò)“Teach Yourself Programming in Ten Years”這篇文章。雖然離初次發(fā)表已經(jīng)好幾年了抹估,但所有試圖自學(xué)編程的人都應(yīng)該發(fā)自內(nèi)心的同意它的說(shuō)法(除去少數(shù)過(guò)時(shí)的具體技術(shù)部分)缠黍。直到今天,這篇經(jīng)典的文章依然很有借鑒意義药蜻。以下是這篇文章的中文版瓷式。
為什么每個(gè)人都這么匆忙?
走進(jìn)任何書店语泽,你都會(huì)看到如何在 24 小時(shí)內(nèi)自學(xué) Java贸典,同時(shí)你還可以看到很多在幾天或幾小時(shí)內(nèi)學(xué)會(huì) C、SQL踱卵、Ruby廊驼、算法等等的書籍。在亞馬遜使用“title: teach, yourself, hours, since: 2000”進(jìn)行高級(jí)搜索,我發(fā)現(xiàn)了 512 本這樣的書妒挎。在排在前十名的書籍中绳锅,有九本是編程書籍,剩下一本是關(guān)于財(cái)務(wù)管理的饥漫。用“teach yourself”代替“l(fā)earn”榨呆,或者用“day”代替“hours”產(chǎn)生的結(jié)果類似罗标。
結(jié)論是庸队,要么人們急于學(xué)習(xí)編程,要么編程比其他任何東西都更容易學(xué)習(xí)闯割。Felleisen 等人在他們的書《How to Design Programs》中提到彻消,“糟糕的編程很容易,即便是白癡都可以在 21 天內(nèi)學(xué)會(huì)”時(shí)宙拉,請(qǐng)對(duì)這一觀點(diǎn)表示贊同宾尚。
讓我們來(lái)分析一下在 24 小時(shí)內(nèi)學(xué)會(huì) C++意味著什么:
自學(xué):24 小時(shí)內(nèi),你將沒(méi)有時(shí)間寫幾個(gè)重要的程序谢澈,并從成功和失敗中吸取教訓(xùn)煌贴。你將沒(méi)有時(shí)間和一個(gè)有經(jīng)驗(yàn)的程序員一起工作,并理解在 C++環(huán)境中編程會(huì)是什么樣子锥忿。簡(jiǎn)而言之牛郑,你將沒(méi)有時(shí)間去學(xué)習(xí)多少東西。所以這本書只能說(shuō)是膚淺的熟悉敬鬓,而不是深刻的理解淹朋。正如 Alexander Pope 所說(shuō),只學(xué)會(huì)一點(diǎn)點(diǎn)點(diǎn)東西是危險(xiǎn)的
C++:在 24 小時(shí)內(nèi)钉答,你也許能夠?qū)W習(xí) C++的一些語(yǔ)法(前提是你已經(jīng)知道了另一種語(yǔ)言)础芍,但是你不能學(xué)到多少關(guān)于如何使用這門語(yǔ)言的知識(shí)。簡(jiǎn)而言之数尿,如果你是一個(gè)基層的程序員仑性,你可以學(xué)習(xí)用 C++語(yǔ)法編寫 BASIC 程序,但是你不能學(xué)習(xí)到 C++真正的優(yōu)缺點(diǎn)右蹦。那又有什么意義呢虏缸?Alan Perlis 曾經(jīng)說(shuō)過(guò):“一種不影響你編程思維方式的語(yǔ)言,是不值得學(xué)習(xí)的嫩实」粽蓿”有一種可能是,你必須學(xué)習(xí)一點(diǎn) C++(或者是 JavaScript 之類的東西)甲献,因?yàn)槟阈枰矛F(xiàn)有的工具接口來(lái)完成特定的任務(wù)宰缤。但這種情況下,你不是在學(xué)習(xí)如何編程,而是在學(xué)習(xí)如何完成這項(xiàng)任務(wù)慨灭。
在 24 小時(shí)內(nèi):不幸的是朦乏,這根本不夠,正如下面所說(shuō)的那樣氧骤。
用十年時(shí)間自學(xué)編程
很多研究人員發(fā)現(xiàn)呻疹,在各種領(lǐng)域要成為專家大約需要十年時(shí)間,這些領(lǐng)域包括國(guó)際象棋筹陵、音樂(lè)創(chuàng)作刽锤、電報(bào)、繪畫朦佩、鋼琴演奏并思、游泳、網(wǎng)球和科學(xué)研究语稠、神經(jīng)心理學(xué)和拓?fù)鋵W(xué)等等宋彼。成功的關(guān)鍵是不斷的實(shí)踐:不只是一次又一次地做,而是每次都用一個(gè)超出你目前能力的任務(wù)挑戰(zhàn)你自己仙畦,嘗試去解決它输涕,在做它的同時(shí)和之后分析你的表現(xiàn),糾正錯(cuò)誤慨畸,然后重復(fù)這個(gè)循環(huán)莱坎。人和事情都沒(méi)有真正的捷徑:即便對(duì)莫扎特來(lái)說(shuō)也是如此。4 歲就被稱為音樂(lè)天才的他先口,在開(kāi)始創(chuàng)作世界級(jí)的音樂(lè)之前又花了 13 年時(shí)間來(lái)打磨自己型奥。另一個(gè)例子是披頭士樂(lè)隊(duì)。披頭士樂(lè)隊(duì)似乎以一系列的熱門歌曲和 1964 年在艾德沙利文秀上的亮相而一夜成名碉京。但實(shí)際上自從 1957 年以來(lái)厢汹,他們一直在 Liverpool 和 Hamburg 的小酒吧里面演出,雖然很早以前他們就受到大眾的歡迎谐宙,但他們第一次取得重大成功的專輯“Sgt. Peppers”是在 1967 年發(fā)布的烫葬。
Malcolm Gladwell 已經(jīng)普及了這個(gè)想法,盡管他的觀點(diǎn)是 10000 小時(shí)專注的努力凡蜻,而不是 10 年搭综。Henri Cartier-Bresson (1908-2004) 有一句名言:“你的前 10000 張照片是你最差的作品』ǎ”(他沒(méi)有預(yù)料到使用數(shù)碼相機(jī)兑巾,有些人可以在一周內(nèi)就拍完 10000 張照片。)真正成為專家可能需要一輩子:Samuel Johnson(1709-1784)說(shuō):“成為任何領(lǐng)域的卓越人士都需要畢生的努力忠荞,投機(jī)取巧并不可行”蒋歌。Chaucer (1340-1400) 抱怨說(shuō):“人生太短暫了帅掘,而知識(shí)是無(wú)窮的”。Hippocrates (約公元前 400 年) 因?yàn)槟蔷涿浴癮rs longa, vita brevis”而被人稱頌堂油,這句話的原文是“Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile”修档,意思是“生命很短暫,但是技藝卻很高深府框,機(jī)遇轉(zhuǎn)瞬即逝吱窝,探索難以捉摸,抉擇困難重重”迫靖。
當(dāng)然院峡,沒(méi)有一個(gè)數(shù)字可以作為最終的答案,假定所有的技能(如編程袜香、下棋撕予、跳棋和音樂(lè)演奏)都需要完全相同的時(shí)間來(lái)掌握蜈首,或者所有人都需要完全相同的時(shí)間是不合理的。正如 K. Anders Ericsson 教授所說(shuō)欢策,“在大多數(shù)領(lǐng)域,即使是最有才華的人也需要很多時(shí)間才能達(dá)到最高水平踩寇,這是非常值得注意的。10000 小時(shí)這個(gè)數(shù)字讓你感覺(jué)到俺孙,我們說(shuō)的是一周 10 到 20 個(gè)小時(shí)【﹂”
你想成為一名程序員
以下是我的編程秘訣:
對(duì)編程感興趣,因?yàn)榕d趣而編程场靴。請(qǐng)保持足夠的興趣,以便你愿意投入你的 10 年或者 10000 小時(shí)港准。
編碼旨剥。最好的學(xué)習(xí)方式是實(shí)踐。更嚴(yán)格地說(shuō)浅缸,“在特定領(lǐng)域中轨帜,一個(gè)人的最高水平不是由于經(jīng)驗(yàn)的積累自動(dòng)獲得的,而是經(jīng)過(guò)深思熟慮的改進(jìn)衩椒,經(jīng)驗(yàn)豐富的人也可以提高水平蚌父〔侠瘢”,“最有效的學(xué)習(xí)需要有一個(gè)明確的任務(wù)梢什,對(duì)特定的人來(lái)說(shuō)難度適中奠蹬,還要有信息反饋以及重復(fù)試錯(cuò)和糾正錯(cuò)誤的機(jī)會(huì)∥宋纾”“Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life”這本書正是這一觀點(diǎn)的有趣參考囤躁。
與其他程序員交談;閱讀其他程序荔睹。這比任何書籍或培訓(xùn)課程都重要狸演。
如果你愿意,可以在大學(xué)(或研究生院)呆四年僻他。這將使你有機(jī)會(huì)獲得一份需要證書的工作宵距,讓你對(duì)這個(gè)領(lǐng)域有更深的了解,但如果你不喜歡學(xué)校吨拗,你可以自學(xué)或在工作中獲得類似的經(jīng)驗(yàn)满哪。無(wú)論如何,光靠書本知識(shí)是遠(yuǎn)遠(yuǎn)不夠的劝篷∩谘迹“The New Hacker's Dictionary”的作者 Eric Raymond 說(shuō):“計(jì)算機(jī)科學(xué)教育不能使任何人成為一個(gè)專業(yè)的程序員,就像學(xué)習(xí)刷子和顏料不可以使某人成為一個(gè)專業(yè)的畫家一樣娇妓∠窦Γ”我雇用過(guò)的最好的程序員之一只有高中學(xué)歷,他開(kāi)發(fā)了許多優(yōu)秀的軟件哈恰,擁有自己的團(tuán)隊(duì)只估,并且擁有足夠買下一個(gè)夜店的股票期權(quán)。
與其他程序員一起做項(xiàng)目着绷。在某些項(xiàng)目上你是最好的程序員蛔钙,而在某些項(xiàng)目上你是最差的程序員蓬戚。當(dāng)你是最好的時(shí)候,你可以鍛煉主導(dǎo)一個(gè)項(xiàng)目的能力豫喧,并用你的遠(yuǎn)見(jiàn)激勵(lì)別人紧显。當(dāng)你是最壞的時(shí)候孵班,你可以學(xué)習(xí)大師們做什么,觀察他們不喜歡做什么(因?yàn)樗麄儠?huì)讓你為他們做自己不喜歡的事情)枷畏。
接手其他程序員的項(xiàng)目虱饿,理解別人寫的程序氮发。當(dāng)原來(lái)的程序員不在時(shí)爽冕,學(xué)習(xí)需要怎樣理解和修復(fù)程序。想想如何設(shè)計(jì)你的程序乌奇,讓那些在你之后的人維護(hù)它們更容易些华弓。
學(xué)習(xí)至少六種編程語(yǔ)言困乒。包括一種強(qiáng)調(diào)類抽象的語(yǔ)言(如 Java 或 C++)娜搂,它強(qiáng)調(diào)函數(shù)抽象的語(yǔ)言(如 Lisp 或 ML 或 Haskell)百宇,一種支持句法抽象的語(yǔ)言(如 Lisp)携御,一種支持聲明性規(guī)范的語(yǔ)言(如 Prolog 或 C++模板)既绕,一種強(qiáng)調(diào)并發(fā)性的語(yǔ)言(像 Clojure 或 Go)凄贩。
記住“computer science”中有一個(gè)“computer”。知道計(jì)算機(jī)執(zhí)行一條指令昵时、從內(nèi)存中提取一個(gè)字符(有或沒(méi)有緩存)、從磁盤中讀取連續(xù)的字符以及在磁盤上尋找新的位置需要多長(zhǎng)時(shí)間救巷。
參與語(yǔ)言標(biāo)準(zhǔn)化工作句柠。它可能是 ANSI C++委員會(huì),也可以是決定你自己的本地編碼風(fēng)格是有 2 個(gè)或者 4 個(gè)空間縮進(jìn)俄占。無(wú)論哪種方式,你都可以了解到其他人對(duì)一種語(yǔ)言的喜好渤弛,他們的感受有多深她肯,甚至可能了解他們的感受晴氨。
有很好的判斷力,盡快適應(yīng)語(yǔ)言的標(biāo)準(zhǔn)化
考慮到這一切籽前,僅僅通過(guò)書本學(xué)習(xí)你能走多遠(yuǎn)是個(gè)值得懷疑的問(wèn)題枝哄。在我的第一個(gè)孩子出生之前阻荒,我讀完了所有的“How To”類型的書侨赡,但仍然覺(jué)得自己像個(gè)笨手笨腳的新手。30 個(gè)月后蓖宦,當(dāng)我的第二個(gè)孩子出生時(shí)球昨,我重新學(xué)習(xí)了那些書本知識(shí)嗎?不主慰,相反共螺,我依靠的是我的個(gè)人經(jīng)驗(yàn),這比專家們寫的幾千頁(yè)書更有用匀哄,更讓我放心涎嚼。
Fred Brooks 在他的論文《No Silver Bullet》中指出了尋找優(yōu)秀軟件設(shè)計(jì)師的三個(gè)步驟:
盡早系統(tǒng)地發(fā)掘頂級(jí)程序員法梯。
指派一名職業(yè)導(dǎo)師負(fù)責(zé)指導(dǎo)他犀概,并謹(jǐn)慎對(duì)待履歷。
為成長(zhǎng)中的程序員提供相互交流和互相激勵(lì)的機(jī)會(huì)铛绰。
這假設(shè)一些人已經(jīng)具備成為一個(gè)偉大的程序師所必需的素質(zhì)捂掰,那么你的工作就是適當(dāng)?shù)睾弪_他們尘颓。Alan Perlis 的說(shuō)法更加簡(jiǎn)潔:“每個(gè)人都可以學(xué)會(huì)雕刻晦譬,但 Michelangelo 必須學(xué)會(huì)如何不雕刻敛腌。對(duì)偉大的程序員來(lái)說(shuō)也是如此像樊∩鳎”Perlis 認(rèn)為媳谁,偉人有一些超越訓(xùn)練的內(nèi)在品質(zhì)。但是這些品質(zhì)是從哪里來(lái)的呢缔杉?是先天的嗎或详?或者他們是通過(guò)勤奮養(yǎng)成的郭计?正如 Auguste Gusteau 所說(shuō):“任何人都能學(xué)會(huì)做飯,但只有無(wú)畏的人才是偉大的沈贝∷蜗拢”我認(rèn)為這更像是愿意將一生中大部分時(shí)間投入到某種實(shí)踐中学歧,但也許無(wú)畏是總結(jié)這一點(diǎn)的一種方式各吨。或者横浑,正如 Gusteau 的批評(píng)家 Anton Ego 所說(shuō):“不是每個(gè)人都能成為偉大的藝術(shù)家徙融,但偉大的藝術(shù)家可以來(lái)自任何地方瑰谜∫”
所以繼續(xù)購(gòu)買 Java/Ruby /JavaScript /PHP 書籍吧渤早,你可能會(huì)從中得到一些有用的東西。但是它們不會(huì)在 24 小時(shí)或 21 天內(nèi)改變你的生活,也不會(huì)教會(huì)你作為一個(gè)程序員所需要的所有專業(yè)知識(shí)称勋。何不努力工作,在接下來(lái)的 24 個(gè)月內(nèi)不斷改進(jìn)空厌?
參考書籍
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.
前面問(wèn)題的答案
典型 PC 上各種操作所需要的大致時(shí)間:
執(zhí)行典型指令:1/100000000 秒赋朦,即 1 納秒
從一級(jí)緩存中提壤钇啤:0.5 納秒
分支預(yù)測(cè)失誤:5 納秒
從二級(jí)緩存獲让怠:7 納秒
互斥鎖/解鎖:25 納秒
從主存儲(chǔ)器提瘸性痢:100 納秒
通過(guò) 1Gbps 網(wǎng)絡(luò)發(fā)送 2K 字節(jié):20000 納秒
從內(nèi)存中按順序讀取 1MB :250000 納秒
從新磁盤位置(SEEK)獲却惩拧:8000000 納秒
從磁盤中按順序讀取 1MB:20000000 納秒
將數(shù)據(jù)包發(fā)送到歐洲并返回:150 毫秒房交,即 150000000 納秒
附:語(yǔ)言選擇
有人會(huì)問(wèn)涌萤,他們應(yīng)該先學(xué)什么編程語(yǔ)言负溪。這里沒(méi)有標(biāo)準(zhǔn)答案济炎,但請(qǐng)考慮以下幾點(diǎn):
參考你的朋友。當(dāng)被問(wèn)到“我應(yīng)該使用什么操作系統(tǒng)侍咱,Windows楔脯、Unix 或 Mac昧廷?”我的回答通常是:“使用你的朋友使用的任何東西木柬∶颊恚”你從朋友那里學(xué)到的優(yōu)勢(shì)將抵消操作系統(tǒng)或編程語(yǔ)言之間的任何內(nèi)在差異速挑。還要考慮你未來(lái)的朋友:程序員社區(qū)的人姥宝,如果你繼續(xù)的話伶授,你將成為其中的一員糜烹。你所選擇的語(yǔ)言有一個(gè)大的正在成長(zhǎng)的群體還是一個(gè)小的正在消亡的群體疮蹦?有書愕乎、網(wǎng)站和在線論壇可以得到答案嗎感论?你喜歡那些論壇里的人嗎紊册?
簡(jiǎn)單實(shí)用比肄。諸如 C++和 Java 這樣的編程語(yǔ)言是由有經(jīng)驗(yàn)的程序員團(tuán)隊(duì)設(shè)計(jì)的,這些程序員關(guān)心他們代碼的運(yùn)行時(shí)效率。因此芳绩,為了應(yīng)對(duì)這些情況掀亥,這些語(yǔ)言有些地方是很復(fù)雜的。你關(guān)心的是學(xué)習(xí)編程妥色。你不需要那么復(fù)雜搪花。你需要的是一種語(yǔ)言,它對(duì)于新手程序員來(lái)說(shuō)也可以可以很容易地學(xué)習(xí)和記憶嘹害。
互動(dòng)撮竿。你更愿意用哪種方式學(xué)彈鋼琴:普通的,互動(dòng)的方式倚聚,你一按一個(gè)鍵就聽(tīng)到一個(gè)音符枯跑;或者“批量”模式,在這種模式下续扔,你只在完成一整首歌后才聽(tīng)到音符堡赔?顯然,互動(dòng)模式使鋼琴學(xué)習(xí)和更容易。對(duì)編程來(lái)說(shuō)也是如此洒扎,堅(jiān)持使用互動(dòng)模式的語(yǔ)言并使用它猫牡。
考慮到這些標(biāo)準(zhǔn)骇陈,對(duì)于要學(xué)習(xí)的第一種編程語(yǔ)言我的建議是 Python 或 Scheme。另一個(gè)選擇是 JavaScript,這不是因?yàn)樗菫槌鯇W(xué)者精心設(shè)計(jì)的,而是因?yàn)樗泻芏嘣诰€教程,比如 Khan Academy 的教程。但每個(gè)人的情況都略有不同挡篓,還有一些其他的好選擇闯睹。如果你還是隔小孩妄讯,你可能更喜歡 Alice 或 Squeak 或 Blockly(年長(zhǎng)的學(xué)習(xí)者也可能喜歡這些)炕置。這些都沒(méi)關(guān)系此虑,重要的是你要選擇并開(kāi)始。
附錄:書籍和其他資源
有人問(wèn)他們應(yīng)該從哪些書和網(wǎng)頁(yè)上學(xué)習(xí)。我再重復(fù)一遍:僅僅看書是不夠的。但我可以推薦以下資源:
Scheme:“Structure and Interpretation of Computer Programs (Abelson & Sussman)”可能是計(jì)算機(jī)科學(xué)最好的導(dǎo)論書籍浇揩,它也確實(shí)將教授編程作為理解計(jì)算機(jī)科學(xué)的一種方式。你可以在網(wǎng)上看到關(guān)于這本書的講座視頻适篙,以及完整的文本虎锚。這本書讀起來(lái)具有挑戰(zhàn)性柄慰,將淘汰一些可能通過(guò)這種方法獲得成功的人。
Scheme:“How to Design Programs (Felleisen et al.)”是關(guān)于在實(shí)踐中如何以優(yōu)雅和實(shí)用的方式設(shè)計(jì)程序的最佳書籍之一业踏。
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)代繼承人。讀這本書會(huì)讓你理解編程思想,它的涵蓋范圍比 Abelson 和 Sussman 更廣泛开瞭,同時(shí)可能更容易閱讀和理解。它使用的語(yǔ)言是 Oz烘绽,這種語(yǔ)言并不廣為人知呀打,但它卻是學(xué)習(xí)其他語(yǔ)言的基礎(chǔ)。