十年內(nèi)自學(xué)編程
彼得·諾維格
為什么大家都這么著急蟀淮?
走進(jìn)任何一家書(shū)店宝踪,您將看到如何在24小時(shí)內(nèi)教會(huì)自己Java,以及提供在幾天或幾小時(shí)內(nèi)教授C李皇、SQL削茁、Ruby宙枷、算法等的無(wú)休止的變體掉房。亞馬遜高級(jí)搜索[標(biāo)題:教學(xué),你自己慰丛,小時(shí)卓囚,自2000年以來(lái),發(fā)現(xiàn)512這樣的書(shū)诅病。在前十名中哪亿,有九本是編程書(shū)(另一本是關(guān)于簿記的)。類似的結(jié)果來(lái)自于將“自學(xué)”改為“學(xué)習(xí)”贤笆,或?qū)ⅰ靶r(shí)”替換為“天”蝇棉。
結(jié)論是,要么人們急于學(xué)習(xí)編程芥永,要么編程比其他任何東西都容易得多篡殷。費(fèi)萊森等人在他們的“如何設(shè)計(jì)程序”(How To Design Program)一書(shū)中,他們表示:“糟糕的編程很容易埋涧,白癡可以在21天內(nèi)學(xué)會(huì)它板辽,即使他們是假人〖撸”這位狂暴的鵝漫畫(huà)也有自己的想法劲弦。
讓我們分析24小時(shí)內(nèi)自學(xué)C++這樣的標(biāo)題可能意味著什么:
自學(xué):在24小時(shí)內(nèi),你就沒(méi)有時(shí)間寫(xiě)幾個(gè)重要的程序醇坝,從你的成功和失敗中吸取教訓(xùn)邑跪。您將沒(méi)有時(shí)間與有經(jīng)驗(yàn)的程序員一起工作,并了解在C++環(huán)境中生活是什么感覺(jué)呼猪』總之,你沒(méi)有時(shí)間學(xué)到很多東西郑叠。因此夜赵,這本書(shū)只能談?wù)撘环N膚淺的熟悉,而不是一種深刻的理解乡革。正如亞歷山大·波普所說(shuō)寇僧,一點(diǎn)點(diǎn)學(xué)習(xí)是一件危險(xiǎn)的事情摊腋。
C++:在24小時(shí)內(nèi),您可能可以學(xué)習(xí)C++的一些語(yǔ)法(如果您已經(jīng)知道另一種語(yǔ)言)嘁傀,但您無(wú)法了解如何使用該語(yǔ)言兴蒸。簡(jiǎn)單地說(shuō),如果你是一個(gè)基本程序員细办,你可以學(xué)習(xí)用C++語(yǔ)法以Basic的方式編寫(xiě)程序橙凳,但是你不能知道C++實(shí)際上是好的(和壞的)什么。那有什么意義笑撞?AlanPerlis曾經(jīng)說(shuō)過(guò):“一種不影響你對(duì)編程的思考方式的語(yǔ)言是不值得知道的”岛啸。一個(gè)可能的問(wèn)題是,您必須學(xué)習(xí)一點(diǎn)C++(或者更可能的是茴肥,類似JavaScript或處理的東西)坚踩,因?yàn)槟枰c現(xiàn)有工具接口來(lái)完成特定的任務(wù)。但是你不是在學(xué)習(xí)如何編程瓤狐,而是在學(xué)習(xí)如何完成這個(gè)任務(wù)瞬铸。
在24小時(shí)內(nèi):不幸的是,這還不夠础锐,正如下一節(jié)所示嗓节。
十年內(nèi)自學(xué)編程
研究人員(Bloom(1985)、Bryan&Harter(1899年)皆警、Hayes(1989)拦宣、Simmon&Chase(1973))已經(jīng)證明,在包括國(guó)際象棋耀怜、音樂(lè)創(chuàng)作恢着、電報(bào)運(yùn)算、繪畫(huà)财破、鋼琴演奏掰派、游泳、網(wǎng)球以及神經(jīng)心理學(xué)和拓?fù)鋵W(xué)研究在內(nèi)的任何廣泛領(lǐng)域左痢,都需要十年的時(shí)間才能發(fā)展出專門(mén)知識(shí)靡羡。關(guān)鍵在于深思熟慮的練習(xí):不只是一次又一次地去做,而是用一項(xiàng)超出你目前能力范圍的任務(wù)來(lái)挑戰(zhàn)自己俊性,嘗試它略步,分析你在做的時(shí)候和之后的表現(xiàn),并糾正任何錯(cuò)誤定页。那就重復(fù)一遍趟薄。再重復(fù)一遍。似乎沒(méi)有真正的捷徑:即使是莫扎特典徊,他在4歲時(shí)是一個(gè)音樂(lè)天才杭煎,花了13年才開(kāi)始創(chuàng)作世界級(jí)的音樂(lè)恩够。在另一種類型中,披頭士樂(lè)隊(duì)似乎以一連串的#1熱門(mén)和1964年的埃德·沙利文秀出現(xiàn)在現(xiàn)場(chǎng)羡铲。但從1957年起蜂桶,他們就一直在利物浦和漢堡打小俱樂(lè)部,雖然他們很早就有了很大的吸引力也切,但他們的第一個(gè)重大成功扑媚,佩珀斯中士,在1967年被釋放了雷恃。
馬爾科姆·格拉德威爾(Malcolm Gladwell)推廣了這一理念疆股,盡管他專注于1萬(wàn)小時(shí),而不是10年褂萧。HenriCartier-Bresson(1908-2004)有另一個(gè)指標(biāo):“你的前10,000張照片是你最差的押桃。”(他沒(méi)有預(yù)料到导犹,使用數(shù)碼相機(jī),一些人可以在一周內(nèi)達(dá)到這一目標(biāo)羡忘。)真正的專業(yè)知識(shí)可能需要一生的時(shí)間:塞繆爾·約翰遜(1709-1784)說(shuō):“任何部門(mén)的卓越都只能靠一生的勞動(dòng)才能實(shí)現(xiàn)谎痢;不能以較低的價(jià)格購(gòu)買(mǎi)【淼瘢”喬叟(1340-1400)抱怨道:“萊夫太短了节猿,手藝太長(zhǎng)了÷瘢”Hippocrates(公元前400年)以摘錄“Ars Longa滨嘱,vita brevis”而聞名,這是較長(zhǎng)的引語(yǔ)“Ars Longa浸间,vita brevis太雨,ocus o precep,實(shí)驗(yàn)性的周膜魁蒜,艱難的分枝”的一部分囊扳,在英語(yǔ)中,它表現(xiàn)為“生命短兜看,工藝長(zhǎng)锥咸,機(jī)會(huì)短暫,實(shí)驗(yàn)變化無(wú)常细移,判斷困難”搏予。當(dāng)然,沒(méi)有一個(gè)數(shù)字是最終的答案:似乎不合理地假定所有技能(例如編程弧轧、下棋雪侥、跳棋和音樂(lè)演奏)都需要完全相同的時(shí)間來(lái)掌握球涛,也不認(rèn)為所有人都需要完全相同的時(shí)間。正如K·安德斯·愛(ài)立信教授所言:“在大多數(shù)領(lǐng)域校镐,即使是最有才華的人也需要多少時(shí)間才能達(dá)到最高水平的業(yè)績(jī)亿扁,這是非常了不起的。10,000小時(shí)的數(shù)字讓你感覺(jué)到鸟廓,我們說(shuō)的是每周10到20小時(shí)从祝,有些人會(huì)認(rèn)為這些人是最有天賦的人,但他們?nèi)匀恍枰_(dá)到最高水平引谜‰鼓埃“
所以你想成為一名程序員
下面是我編程成功的秘訣:
對(duì)編程感興趣,并做一些员咽,因?yàn)樗怯腥さ亩窘АR欢ㄒ3肿銐虻臉?lè)趣,這樣你就會(huì)愿意投入你的10年/10,000小時(shí)贝室。
節(jié)目契讲。最好的學(xué)習(xí)方式是邊做邊學(xué)。更嚴(yán)格地說(shuō)滑频,“在某一領(lǐng)域捡偏,個(gè)人的最高業(yè)績(jī)水平并不是隨著經(jīng)驗(yàn)的擴(kuò)展而自動(dòng)達(dá)到的,但即使是經(jīng)驗(yàn)豐富的個(gè)人峡迷,也可以通過(guò)刻意改進(jìn)而提高業(yè)績(jī)水平银伟。”(第366頁(yè))和“最有效的學(xué)習(xí)需要一個(gè)明確的任務(wù)绘搞,適當(dāng)?shù)碾y度水平彤避,為特定的個(gè)人,信息反饋夯辖,并有機(jī)會(huì)重復(fù)和糾正錯(cuò)誤琉预。”(第20-21頁(yè))“實(shí)踐中的認(rèn)知:日常生活中的思想楼雹、數(shù)學(xué)和文化”是這一觀點(diǎn)的有趣參考模孩。
與其他程序員交談;閱讀其他程序贮缅。這比任何書(shū)籍或培訓(xùn)課程都更重要榨咐。
如果你愿意,在一所大學(xué)(或更多的研究生院)待四年谴供。這會(huì)讓你獲得一些需要資格證書(shū)的工作块茁,也會(huì)讓你對(duì)這個(gè)領(lǐng)域有更深入的了解,但如果你不喜歡上學(xué),你可以(用一些奉獻(xiàn)精神)獨(dú)自或在工作中獲得類似的經(jīng)驗(yàn)数焊。無(wú)論如何永淌,光靠書(shū)本學(xué)習(xí)是不夠的∨宥“計(jì)算機(jī)科學(xué)教育不能使任何人成為專業(yè)程序員遂蛀,就像研究畫(huà)筆和顏料可以使人成為專業(yè)畫(huà)家一樣”,“新黑客詞典”的作者埃里克·雷蒙德說(shuō)干厚。我雇過(guò)的最好的程序員之一只有高中學(xué)位李滴,他制作了很多很棒的軟件,有自己的新聞組蛮瞄,并且有足夠的股票期權(quán)來(lái)購(gòu)買(mǎi)自己的夜總會(huì)所坯。
與其他程序員一起完成項(xiàng)目。在某些項(xiàng)目中做最好的程序員挂捅;在其他項(xiàng)目上做最差的程序員芹助。當(dāng)你是最好的,你可以測(cè)試你的能力來(lái)領(lǐng)導(dǎo)一個(gè)項(xiàng)目闲先,并用你的遠(yuǎn)見(jiàn)激勵(lì)別人状土。當(dāng)你是最壞的時(shí)候,你學(xué)會(huì)了主人做什么饵蒂,你學(xué)會(huì)了他們不喜歡做什么(因?yàn)樗麄冏屇銥樗麄冏?声诸。
工作項(xiàng)目后,其他程序員退盯。理解別人寫(xiě)的程序⌒嚎希看看當(dāng)原來(lái)的程序員不在的時(shí)候渊迁,需要什么才能理解和修復(fù)它。想一想如何設(shè)計(jì)你的程序灶挟,讓那些在你之后維護(hù)它們的人更容易琉朽。
至少學(xué)習(xí)六種編程語(yǔ)言。包括一種強(qiáng)調(diào)類抽象的語(yǔ)言(比如Java或C++)稚铣、一種強(qiáng)調(diào)函數(shù)抽象(比如Lisp箱叁、ML或Haskell)、一種支持語(yǔ)法抽象(比如Lisp)惕医、一種支持聲明性規(guī)范(比如Prolog或C++模板)耕漱、一種強(qiáng)調(diào)并行性(比如Clojure或Go)。
記住抬伺,在“計(jì)算機(jī)科學(xué)”中有一個(gè)“計(jì)算機(jī)”螟够。知道您的計(jì)算機(jī)執(zhí)行指令、從內(nèi)存中獲取一個(gè)單詞(是否有緩存丟失)、從磁盤(pán)中讀取連續(xù)單詞以及尋找磁盤(pán)上的新位置需要多長(zhǎng)時(shí)間妓笙。(答案在這里)
參與語(yǔ)言標(biāo)準(zhǔn)化工作若河。它可能是ANSI C++委員會(huì),也可能是決定您的本地編碼風(fēng)格將有2或4個(gè)空間縮進(jìn)水平寞宫。不管是哪種方式萧福,你都可以了解到其他人在一種語(yǔ)言中喜歡什么,他們有多深辈赋,也許還有一點(diǎn)是關(guān)于為什么他們會(huì)這樣想的鲫忍。
有良好的判斷力,盡快擺脫語(yǔ)言標(biāo)準(zhǔn)化的努力炭庙。
考慮到所有這些饲窿,僅僅通過(guò)書(shū)本學(xué)習(xí),你能走多遠(yuǎn)是值得懷疑的焕蹄。在我的第一個(gè)孩子出生之前逾雄,我讀了所有的書(shū),仍然覺(jué)得自己是一個(gè)無(wú)知的新手腻脏。30個(gè)月后鸦泳,當(dāng)我的第二個(gè)孩子即將出生時(shí),我是否又回到書(shū)本上復(fù)習(xí)了一下永品?沒(méi)有做鹰。相反,我依靠的是我個(gè)人的經(jīng)驗(yàn)鼎姐,這比專家們寫(xiě)的幾千頁(yè)更有用钾麸,也更讓我放心。
弗雷德·布魯克斯(FredBrooks)在他的文章“沒(méi)有銀彈”中指出了一個(gè)尋找優(yōu)秀軟件設(shè)計(jì)師的三部分計(jì)劃:
系統(tǒng)地盡早確定頂級(jí)設(shè)計(jì)師炕桨。
指派一位職業(yè)導(dǎo)師負(fù)責(zé)前景的發(fā)展饭尝,并仔細(xì)保存一份職業(yè)檔案。
為不斷成長(zhǎng)的設(shè)計(jì)師提供互動(dòng)和相互激勵(lì)的機(jī)會(huì)献宫。
這假設(shè)有些人已經(jīng)具備了成為一名偉大設(shè)計(jì)師所必需的素質(zhì)钥平,其工作就是恰當(dāng)?shù)匾龑?dǎo)他們堅(jiān)持下去。艾倫·佩利斯(AlanPerlis)更簡(jiǎn)潔地說(shuō):“每個(gè)人都可以學(xué)會(huì)雕刻:米開(kāi)朗基羅(Michelangelo)必須學(xué)會(huì)如何不去做姊途,偉大的程序員也是如此涉瘾。”佩利斯說(shuō)捷兰,偉大的球員有一些超越他們訓(xùn)練的內(nèi)在素質(zhì)立叛。但是質(zhì)量是從哪里來(lái)的呢?是天生的嗎寂殉?或者他們是通過(guò)勤奮來(lái)發(fā)展的呢囚巴?正如奧古斯特·古斯托(Ratatouille中虛構(gòu)的廚師)所言:“任何人都能做飯,但只有無(wú)畏的人才能做得很好⊥妫”我認(rèn)為它更多的是愿意把一個(gè)人一生中的大部分時(shí)間花在深思熟慮的實(shí)踐上庶柿。但也許無(wú)畏是總結(jié)這一點(diǎn)的一種方式』嘟剑或者浮庐,正如古斯托的批評(píng)家安東·伊戈所說(shuō):“不是每個(gè)人都能成為偉大的藝術(shù)家,但偉大的藝術(shù)家可以來(lái)自任何地方柬焕∩蟛校”
因此,繼續(xù)購(gòu)買(mǎi)Java/Ruby/Javascript/PHP書(shū)籍斑举;您可能會(huì)從中得到一些使用搅轿。但你不會(huì)在24小時(shí)或21天內(nèi)改變你的生活,也不會(huì)改變你作為程序員的真正專業(yè)知識(shí)富玷。在過(guò)去的24個(gè)月里璧坟,努力工作,不斷提高赎懦,怎么樣雀鹃?現(xiàn)在你開(kāi)始有進(jìn)展了..。
參考文獻(xiàn)
布盧姆励两,本杰明(編輯)“發(fā)展青年人才”黎茎,巴蘭汀,1985年当悔。
布魯克斯傅瞻,弗雷德,沒(méi)有銀子彈盲憎,IEEE計(jì)算機(jī)俭正,第20卷,第4期焙畔,1987年,第10-19頁(yè)串远。
Bryan宏多,W.L.&Harter,N.“電報(bào)語(yǔ)言研究:習(xí)慣層次的習(xí)得”澡罚,“心理學(xué)評(píng)論”伸但,1899年,8,345-375留搔。
海斯更胖,約翰R.,完全問(wèn)題解決者勞倫斯厄爾鮑姆,1989年却妨。
放大圖片作者:William G.&Simon饵逐,Herbert A.“象棋中的知覺(jué)”,“認(rèn)知心理學(xué)”彪标,1973倍权,4,55-81捞烟。
“實(shí)踐中的認(rèn)知:日常生活中的思想薄声、數(shù)學(xué)和文化”,劍橋大學(xué)出版社题画,1988年默辨。
答案
典型PC上各種操作的大致時(shí)間:
執(zhí)行典型指令1/1,000,000,000秒=1納塞克
從L1高速緩存存儲(chǔ)器0.5納塞克中提取
支路誤判5納秒
從L2高速緩存存儲(chǔ)器7納塞克中提取
互斥鎖/解鎖25納塞克
從主存100納塞克中提取
在1Gbps網(wǎng)絡(luò)上發(fā)送2K字節(jié)20,000納秒
從內(nèi)存250,000納塞克中順序讀取1MB
從新磁盤(pán)位置(查找)獲取8,000,000納塞克
從磁盤(pán)按順序讀取1MB 20,000,000納塞克
將數(shù)據(jù)包US發(fā)送到歐洲,返回150毫秒=150,000,000納塞克
附錄:語(yǔ)言選擇
有幾個(gè)人問(wèn)他們應(yīng)該先學(xué)哪種編程語(yǔ)言苍息。沒(méi)有一個(gè)答案缩幸,但請(qǐng)考慮以下幾點(diǎn):
利用你的朋友。當(dāng)被問(wèn)到“我應(yīng)該使用什么操作系統(tǒng)档叔,Windows桌粉,Unix還是Mac?”時(shí)衙四,我的回答通常是:“使用任何你的朋友使用的操作系統(tǒng)铃肯。”你從朋友那里學(xué)到的優(yōu)勢(shì)將抵消操作系統(tǒng)之間或編程語(yǔ)言之間的任何內(nèi)在差異传蹈。還要考慮你未來(lái)的朋友:如果你繼續(xù)的話押逼,你會(huì)成為程序員社區(qū)的一部分。你所選擇的語(yǔ)言是有一個(gè)龐大的成長(zhǎng)社區(qū)惦界,還是一個(gè)正在消亡的小群體挑格?有沒(méi)有書(shū)籍,網(wǎng)站和在線論壇可以得到答案沾歪?你喜歡那些論壇上的人嗎漂彤?
保持簡(jiǎn)單。編程語(yǔ)言(如C++和Java)是為專業(yè)開(kāi)發(fā)而設(shè)計(jì)的灾搏,由大量經(jīng)驗(yàn)豐富的程序員組成挫望,他們關(guān)心代碼的運(yùn)行時(shí)效率。因此狂窑,這些語(yǔ)言具有為這些情況設(shè)計(jì)的復(fù)雜部分媳板。你關(guān)心的是學(xué)習(xí)編程。你不需要那種并發(fā)癥泉哈。你想要一種語(yǔ)言蛉幸,它被設(shè)計(jì)成一個(gè)簡(jiǎn)單易學(xué)的語(yǔ)言破讨,并被一個(gè)新的程序員記住。
玩奕纫。你更愿意學(xué)習(xí)彈鋼琴的哪一種方式:普通的提陶,交互式的,在你一按下鍵就聽(tīng)到每個(gè)音符的方式若锁,還是“分批”模式搁骑,只有在你唱完整首歌之后才能聽(tīng)到音符?顯然又固,交互模式使鋼琴和編程更容易學(xué)習(xí)仲器。堅(jiān)持一種互動(dòng)的語(yǔ)言,并使用它仰冠。
考慮到這些標(biāo)準(zhǔn)乏冀,我對(duì)第一種編程語(yǔ)言的建議將是Python或Scheme。另一個(gè)選擇是Javascript洋只,并不是因?yàn)樗鼮槌鯇W(xué)者設(shè)計(jì)得非常好辆沦,而是因?yàn)樗泻芏嘣诰€教程,比如Khan Academy的教程识虚。但你的情況可能會(huì)有所不同肢扯,還有其他好的選擇。如果你的年齡是個(gè)位數(shù)担锤,你可能更喜歡愛(ài)麗絲蔚晨、斯奎克或布洛克里(年長(zhǎng)的學(xué)習(xí)者也會(huì)喜歡這些)。重要的是你選擇并開(kāi)始肛循。
附錄:書(shū)籍和其他資源
有幾個(gè)人問(wèn)他們應(yīng)該從哪些書(shū)籍和網(wǎng)頁(yè)中學(xué)習(xí)铭腕。我再說(shuō)一遍,“光靠書(shū)本學(xué)習(xí)是不夠的”多糠,但我可以推薦以下幾點(diǎn):
方案:計(jì)算機(jī)程序的結(jié)構(gòu)和解釋(Abelson&Sussman)可能是計(jì)算機(jī)科學(xué)的最佳入門(mén)累舷,它確實(shí)教授編程作為理解計(jì)算機(jī)科學(xué)的一種方式。你可以在這本書(shū)上看到講座的在線視頻夹孔,也可以在網(wǎng)上看到完整的文本被盈。這本書(shū)具有挑戰(zhàn)性,并將淘汰出一些可能通過(guò)另一種方法獲得成功的人搭伤。
方案:如何設(shè)計(jì)程序(Felleisen等人)是關(guān)于如何以優(yōu)雅和實(shí)用的方式實(shí)際設(shè)計(jì)程序的最好的書(shū)籍之一害捕。
Python:PythonProgramming:IntrotoCS(Zelle)是使用Python的一個(gè)很好的介紹。
Python:幾個(gè)在線教程可以在Python.org上找到闷畸。
奧茲:計(jì)算機(jī)編程的概念、技術(shù)和模型(VanRoy&Haridi)被一些人視為現(xiàn)代阿貝爾森和蘇斯曼的繼承者吞滞。它是一個(gè)關(guān)于編程的偉大思想的旅行佑菩,涵蓋的范圍比Abelson&Sussman更廣泛盾沫,而且可能更容易閱讀和跟蹤。它使用的一種語(yǔ)言殿漠,Oz赴精,并不廣為人知,但作為學(xué)習(xí)其他語(yǔ)言的基礎(chǔ)绞幌。<
注記
T.Capey指出蕾哟,亞馬遜上的完整問(wèn)題解決方案頁(yè)面現(xiàn)在有“21天內(nèi)教你自己孟加拉語(yǔ)”和“教你自己語(yǔ)法和風(fēng)格”的書(shū),在“為這個(gè)項(xiàng)目購(gòu)物的顧客也在購(gòu)買(mǎi)這些物品”部分下莲蜘。我想看那本書(shū)的人中有很大一部分是從這一頁(yè)來(lái)的谭确。感謝羅斯·科恩幫助希波克拉底∑鼻【】