十年內(nèi)自學(xué)編程
彼得·諾維格
為什么大家都這么著急琴拧?
走進任何一家書店,您將看到如何在24小時內(nèi)教會自己Java挣饥,以及提供在幾天或幾小時內(nèi)教授C沛膳、SQL、Ruby茧吊、算法等的無休止的變體。亞馬遜高級搜索[標(biāo)題:教學(xué)瞄桨,你自己芯侥,小時,自2000年以來廓俭,發(fā)現(xiàn)512這樣的書研乒。在前十名中淋硝,有九本是編程書(另一本是關(guān)于簿記的)谣膳。類似的結(jié)果來自于將“自學(xué)”改為“學(xué)習(xí)”,或?qū)ⅰ靶r”替換為“天”烈菌。
結(jié)論是,要么人們急于學(xué)習(xí)編程,要么編程比其他任何東西都容易得多捂襟。費萊森等人在他們的“如何設(shè)計程序”(How To Design Program)一書中葬荷,他們表示:“糟糕的編程很容易宠漩,白癡可以在21天內(nèi)學(xué)會它,即使他們是假人火鼻】鳎”這位狂暴的鵝漫畫也有自己的想法盼铁。
讓我們分析24小時內(nèi)自學(xué)C++這樣的標(biāo)題可能意味著什么:
自學(xué):在24小時內(nèi)饶火,你就沒有時間寫幾個重要的程序,從你的成功和失敗中吸取教訓(xùn)当辐。您將沒有時間與有經(jīng)驗的程序員一起工作缘揪,并了解在C++環(huán)境中生活是什么感覺刨摩≡枭玻總之,你沒有時間學(xué)到很多東西锻全。因此谎碍,這本書只能談?wù)撘环N膚淺的熟悉兢榨,而不是一種深刻的理解。正如亞歷山大·波普所說,一點點學(xué)習(xí)是一件危險的事情。
C++:在24小時內(nèi),您可能可以學(xué)習(xí)C++的一些語法(如果您已經(jīng)知道另一種語言),但您無法了解如何使用該語言料祠。簡單地說,如果你是一個基本程序員,你可以學(xué)習(xí)用C++語法以Basic的方式編寫程序启盛,但是你不能知道C++實際上是好的(和壞的)什么卧抗。那有什么意義藤滥?AlanPerlis曾經(jīng)說過:“一種不影響你對編程的思考方式的語言是不值得知道的”。一個可能的問題是社裆,您必須學(xué)習(xí)一點C++(或者更可能的是拙绊,類似JavaScript或處理的東西),因為您需要與現(xiàn)有工具接口來完成特定的任務(wù)泳秀。但是你不是在學(xué)習(xí)如何編程时呀,而是在學(xué)習(xí)如何完成這個任務(wù)。
在24小時內(nèi):不幸的是晶默,這還不夠谨娜,正如下一節(jié)所示。
十年內(nèi)自學(xué)編程
研究人員(Bloom(1985)磺陡、Bryan&Harter(1899年)趴梢、Hayes(1989)、Simmon&Chase(1973))已經(jīng)證明币他,在包括國際象棋坞靶、音樂創(chuàng)作、電報運算蝴悉、繪畫彰阴、鋼琴演奏、游泳拍冠、網(wǎng)球以及神經(jīng)心理學(xué)和拓撲學(xué)研究在內(nèi)的任何廣泛領(lǐng)域尿这,都需要十年的時間才能發(fā)展出專門知識。關(guān)鍵在于深思熟慮的練習(xí):不只是一次又一次地去做庆杜,而是用一項超出你目前能力范圍的任務(wù)來挑戰(zhàn)自己射众,嘗試它,分析你在做的時候和之后的表現(xiàn)晃财,并糾正任何錯誤叨橱。那就重復(fù)一遍。再重復(fù)一遍断盛。似乎沒有真正的捷徑:即使是莫扎特罗洗,他在4歲時是一個音樂天才,花了13年才開始創(chuàng)作世界級的音樂钢猛。在另一種類型中伙菜,披頭士樂隊似乎以一連串的#1熱門和1964年的埃德·沙利文秀出現(xiàn)在現(xiàn)場。但從1957年起厢洞,他們就一直在利物浦和漢堡打小俱樂部仇让,雖然他們很早就有了很大的吸引力典奉,但他們的第一個重大成功,佩珀斯中士丧叽,在1967年被釋放了卫玖。
馬爾科姆·格拉德威爾(Malcolm Gladwell)推廣了這一理念,盡管他專注于1萬小時踊淳,而不是10年假瞬。HenriCartier-Bresson(1908-2004)有另一個指標(biāo):“你的前10,000張照片是你最差的∮爻ⅲ”(他沒有預(yù)料到脱茉,使用數(shù)碼相機,一些人可以在一周內(nèi)達到這一目標(biāo)垄开。)真正的專業(yè)知識可能需要一生的時間:塞繆爾·約翰遜(1709-1784)說:“任何部門的卓越都只能靠一生的勞動才能實現(xiàn)琴许;不能以較低的價格購買「榷悖”喬叟(1340-1400)抱怨道:“萊夫太短了榜田,手藝太長了《褪幔”Hippocrates(公元前400年)以摘錄“Ars Longa箭券,vita brevis”而聞名,這是較長的引語“Ars Longa疑枯,vita brevis辩块,ocus o precep,實驗性的周膜荆永,艱難的分枝”的一部分废亭,在英語中,它表現(xiàn)為“生命短屁魏,工藝長滔以,機會短暫,實驗變化無常氓拼,判斷困難”。當(dāng)然抵碟,沒有一個數(shù)字是最終的答案:似乎不合理地假定所有技能(例如編程桃漾、下棋、跳棋和音樂演奏)都需要完全相同的時間來掌握拟逮,也不認(rèn)為所有人都需要完全相同的時間撬统。正如K·安德斯·愛立信(K.Anders Ericsson)教授所言,“在大多數(shù)領(lǐng)域敦迄,即便是最有才華的人恋追,也需要多少時間才能達到最高水平凭迹。1萬小時的時間讓你感覺到,我們所說的每周10到20個小時苦囱,有些人會認(rèn)為嗅绸,那些天生最有天賦的人仍然需要達到最高水平∷和”
所以你想成為一名程序員
下面是我編程成功的秘訣:
對編程感興趣鱼鸠,并做一些,因為它是有趣的羹铅。一定要保持足夠的樂趣蚀狰,這樣你就會愿意投入你的10年/10,000小時。
節(jié)目职员。最好的學(xué)習(xí)方式是邊做邊學(xué)麻蹋。更嚴(yán)格地說,“在某一領(lǐng)域焊切,個人的最高業(yè)績水平并不是隨著經(jīng)驗的擴展而自動達到的扮授,但即使是經(jīng)驗豐富的個人,也可以通過刻意改進而提高業(yè)績水平蛛蒙〔诠浚”(第366頁)和“最有效的學(xué)習(xí)需要一個明確的任務(wù),適當(dāng)?shù)碾y度水平牵祟,為特定的個人深夯,信息反饋,并有機會重復(fù)和糾正錯誤诺苹」窘”(第20-21頁)“實踐中的認(rèn)知:日常生活中的思想、數(shù)學(xué)和文化”是這一觀點的有趣參考收奔。
與其他程序員交談掌呜;閱讀其他程序。這比任何書籍或培訓(xùn)課程都更重要坪哄。
如果你愿意质蕉,在一所大學(xué)(或更多的研究生院)待四年。這會讓你獲得一些需要資格證書的工作翩肌,也會讓你對這個領(lǐng)域有更深入的了解模暗,但如果你不喜歡上學(xué),你可以(用一些奉獻精神)獨自或在工作中獲得類似的經(jīng)驗念祭。無論如何兑宇,光靠書本學(xué)習(xí)是不夠的×焕ぃ“計算機科學(xué)教育不能使任何人成為專業(yè)程序員隶糕,就像研究畫筆和顏料可以使人成為專業(yè)畫家一樣”瓷产,“新黑客詞典”的作者埃里克·雷蒙德說。我雇過的最好的程序員之一只有高中學(xué)位枚驻,他制作了很多很棒的軟件濒旦,有自己的新聞組,并且有足夠的股票期權(quán)來購買自己的夜總會测秸。
與其他程序員一起完成項目疤估。在某些項目中做最好的程序員;在其他項目上做最差的程序員霎冯。當(dāng)你是最好的铃拇,你可以測試你的能力來領(lǐng)導(dǎo)一個項目,并用你的遠見激勵別人沈撞。當(dāng)你是最壞的時候慷荔,你學(xué)會了主人做什么,你學(xué)會了他們不喜歡做什么(因為他們讓你為他們做)缠俺。
工作項目后显晶,其他程序員。理解別人寫的程序壹士×坠停看看當(dāng)原來的程序員不在的時候,需要什么才能理解和修復(fù)它躏救。想一想如何設(shè)計你的程序唯笙,讓那些在你之后維護它們的人更容易。
至少學(xué)習(xí)六種編程語言盒使。包括一種強調(diào)類抽象的語言(比如Java或C++)崩掘、一種強調(diào)函數(shù)抽象(比如Lisp、ML或Haskell)少办、一種支持語法抽象(比如Lisp)苞慢、一種支持聲明性規(guī)范(比如Prolog或C++模板)、一種強調(diào)并行性(比如Clojure或Go)英妓。
記住挽放,在“計算機科學(xué)”中有一個“計算機”。知道您的計算機執(zhí)行指令蔓纠、從內(nèi)存中獲取一個單詞(是否有緩存丟失)骂维、從磁盤中讀取連續(xù)單詞以及尋找磁盤上的新位置需要多長時間。(答案在這里)
參與語言標(biāo)準(zhǔn)化工作贺纲。它可能是ANSI C++委員會,也可能是決定您的本地編碼風(fēng)格將有2或4個空間縮進水平褪测。不管是哪種方式猴誊,你都可以了解到其他人在一種語言中喜歡什么潦刃,他們有多深,也許還有一點是關(guān)于為什么他們會這樣想的懈叹。
有良好的判斷力乖杠,盡快擺脫語言標(biāo)準(zhǔn)化的努力。
考慮到所有這些澄成,僅僅通過書本學(xué)習(xí)胧洒,你能走多遠是值得懷疑的。在我的第一個孩子出生之前墨状,我讀了所有的書卫漫,仍然覺得自己是一個無知的新手。30個月后肾砂,當(dāng)我的第二個孩子即將出生時列赎,我是否又回到書本上復(fù)習(xí)了一下?沒有镐确。相反包吝,我依靠的是我個人的經(jīng)驗,這比專家們寫的幾千頁更有用源葫,也更讓我放心诗越。
弗雷德·布魯克斯(FredBrooks)在他的文章“沒有銀彈”中指出了一個尋找優(yōu)秀軟件設(shè)計師的三部分計劃:
系統(tǒng)地盡早確定頂級設(shè)計師。
指派一位職業(yè)導(dǎo)師負責(zé)前景的發(fā)展息堂,并仔細保存一份職業(yè)檔案嚷狞。
為不斷成長的設(shè)計師提供互動和相互激勵的機會。
這假設(shè)有些人已經(jīng)具備了成為一名偉大設(shè)計師所必需的素質(zhì)储矩,其工作就是恰當(dāng)?shù)匾龑?dǎo)他們堅持下去感耙。艾倫·佩利斯(AlanPerlis)更簡潔地說:“每個人都可以學(xué)會雕刻:米開朗基羅(Michelangelo)必須學(xué)會如何不去做,偉大的程序員也是如此持隧〖磁穑”佩利斯說,偉大的球員有一些超越他們訓(xùn)練的內(nèi)在素質(zhì)屡拨。但是質(zhì)量是從哪里來的呢只酥?是天生的嗎?或者他們是通過勤奮來發(fā)展的呢呀狼?正如奧古斯特·古斯托(Ratatouille中虛構(gòu)的廚師)所言:“任何人都能做飯裂允,但只有無畏的人才能做得很好「缤В”我認(rèn)為它更多的是愿意把一個人一生中的大部分時間花在深思熟慮的實踐上绝编。但也許無畏是總結(jié)這一點的一種方式。或者十饥,正如古斯托的批評家安東·伊戈所說:“不是每個人都能成為偉大的藝術(shù)家窟勃,但偉大的藝術(shù)家可以來自任何地方《憾拢”
因此秉氧,繼續(xù)購買Java/Ruby/Javascript/PHP書籍;您可能會從中得到一些使用蜒秤。但你不會在24小時或21天內(nèi)改變你的生活汁咏,也不會改變你作為程序員的真正專業(yè)知識。在過去的24個月里作媚,努力工作攘滩,不斷提高,怎么樣掂骏?現(xiàn)在你開始有進展了..轰驳。
參考文獻
布盧姆,本杰明(編輯)“發(fā)展青年人才”弟灼,巴蘭汀级解,1985年。
布魯克斯田绑,弗雷德勤哗,沒有銀子彈,IEEE計算機第20卷掩驱,第4期芒划,1987年,第10-19頁欧穴。
Bryan民逼,W.L.&Harter,N.“電報語言研究:習(xí)慣層次的習(xí)得”涮帘,“心理學(xué)評論”拼苍,1899年,8,345-375调缨。
海斯疮鲫,約翰R.,完全問題解決者勞倫斯厄爾鮑姆弦叶,1989年俊犯。
放大圖片作者:William G.&Simon,Herbert A.“象棋中的知覺”伤哺,“認(rèn)知心理學(xué)”燕侠,1973者祖,4,55-81贬循。
“實踐中的認(rèn)知:日常生活中的思想咸包、數(shù)學(xué)和文化”,劍橋大學(xué)出版社杖虾,1988年。
答案
典型PC上各種操作的大致時間:
執(zhí)行典型指令1/1,000,000,000秒=1納塞克
從L1高速緩存存儲器0.5納塞克中提取
支路誤判5納秒
從L2高速緩存存儲器7納塞克中提取
互斥鎖/解鎖25納塞克
從主存100納塞克中提取
在1Gbps網(wǎng)絡(luò)上發(fā)送2K字節(jié)20,000納秒
從內(nèi)存250,000納塞克中順序讀取1MB
從新磁盤位置(查找)獲取8,000,000納塞克
從磁盤按順序讀取1MB 20,000,000納塞克
將數(shù)據(jù)包US發(fā)送到歐洲媒熊,返回150毫秒=150,000,000納塞克
附錄:語言選擇
有幾個人問他們應(yīng)該先學(xué)哪種編程語言奇适。沒有一個答案,但請考慮以下幾點:
利用你的朋友芦鳍。當(dāng)被問到“我應(yīng)該使用什么操作系統(tǒng)嚷往,Windows,Unix還是Mac柠衅?”時皮仁,我的回答通常是:“使用任何你的朋友使用的操作系統(tǒng)》蒲纾”你從朋友那里學(xué)到的優(yōu)勢將抵消操作系統(tǒng)之間或編程語言之間的任何內(nèi)在差異贷祈。還要考慮你未來的朋友:如果你繼續(xù)的話,你會成為程序員社區(qū)的一部分喝峦。你所選擇的語言是有一個龐大的成長社區(qū)势誊,還是一個正在消亡的小群體?有沒有書籍谣蠢,網(wǎng)站和在線論壇可以得到答案粟耻?你喜歡那些論壇上的人嗎?
保持簡單眉踱。編程語言(如C++和Java)是為專業(yè)開發(fā)而設(shè)計的挤忙,由大量經(jīng)驗豐富的程序員組成,他們關(guān)心代碼的運行時效率谈喳。因此册烈,這些語言具有為這些情況設(shè)計的復(fù)雜部分。你關(guān)心的是學(xué)習(xí)編程叁执。你不需要那種并發(fā)癥茄厘。你想要一種語言,它被設(shè)計成一個簡單易學(xué)的語言谈宛,并被一個新的程序員記住次哈。
玩。你更愿意學(xué)習(xí)彈鋼琴的哪一種方式:普通的吆录,交互式的窑滞,在你一按下鍵就聽到每個音符的方式,還是“分批”模式,只有在你唱完整首歌之后才能聽到音符哀卫?顯然巨坊,交互模式使鋼琴和編程更容易學(xué)習(xí)。堅持一種互動的語言此改,并使用它趾撵。
考慮到這些標(biāo)準(zhǔn),我對第一種編程語言的建議將是Python或Scheme共啃。另一個選擇是Javascript占调,并不是因為它為初學(xué)者設(shè)計得非常好,而是因為它有很多在線教程移剪,比如Khan Academy的教程究珊。但你的情況可能會有所不同,還有其他好的選擇纵苛。如果你的年齡是個位數(shù)剿涮,你可能更喜歡愛麗絲、斯奎克或布洛克里(年長的學(xué)習(xí)者也會喜歡這些)攻人。重要的是你選擇并開始取试。
附錄:書籍和其他資源
有幾個人問他們應(yīng)該從哪些書籍和網(wǎng)頁中學(xué)習(xí)。我再說一遍贝椿,“光靠書本學(xué)習(xí)是不夠的”想括,但我可以推薦以下幾點:
方案:計算機程序的結(jié)構(gòu)和解釋(Abelson&Sussman)可能是計算機科學(xué)的最佳入門,它確實教授編程作為理解計算機科學(xué)的一種方式烙博。你可以在這本書上看到講座的在線視頻瑟蜈,也可以在網(wǎng)上看到完整的文本。這本書具有挑戰(zhàn)性渣窜,并將淘汰出一些可能通過另一種方法獲得成功的人铺根。
方案:如何設(shè)計程序(Felleisen等人)是關(guān)于如何以優(yōu)雅和實用的方式實際設(shè)計程序的最好的書籍之一。
Python:PythonProgramming:IntrotoCS(Zelle)是使用Python的一個很好的介紹乔宿。
Python:幾個在線教程可以在Python.org上找到位迂。
奧茲:計算機編程的概念、技術(shù)和模型(VanRoy&Haridi)被一些人視為現(xiàn)代阿貝爾森和蘇斯曼的繼承者详瑞。它是一個關(guān)于編程的偉大思想的旅行掂林,涵蓋的范圍比Abelson&Sussman更廣泛,而且可能更容易閱讀和跟蹤坝橡。它使用的一種語言泻帮,Oz,并不廣為人知计寇,但作為學(xué)習(xí)其他語言的基礎(chǔ)锣杂。
注記
T.Capey指出脂倦,亞馬遜上的完整問題解決方案頁面現(xiàn)在有“21天內(nèi)教你自己孟加拉語”和“教你自己語法和風(fēng)格”的書,在“為這個項目購物的顧客也在購買這些物品”部分下元莫。我想看那本書的人中有很大一部分是從這一頁來的赖阻。感謝羅斯·科恩幫助希波克拉底。