1. 程式人生 > >Peter Norvig:十年學會編程

Peter Norvig:十年學會編程

結果 足夠 學生 尋找 reac 嘗試 設計 測試 激發

為啥都想速成?

隨便逛一下書店,你會看到《7天自學Java》等諸如此類的N天甚至N小時學習Visual Basic、Windows、Internet的書。我用亞馬遜網站的搜索功能,出版年份選1992年以後,書名關鍵詞是:“天”、“自學”、“教你”,查到248個結果,前78個是計算機類圖書,第79個是《30天學孟加拉語》。我用“天”換成“小時”,結果更驚人,有多達253本書,前77本是計算機圖書,第78是《24小時自學語法句式》。在前200名中,96%是計算機的書。

結論就是:要麽人們急於學習電腦,要麽計算機比其他東西學起來要異常簡單。沒有任何書是關於幾天學習貝多芬或量子物理的,甚至連犬類裝扮都沒有。費雷森(Felleisen)等人在其著作《如何設計程序》中同意這個趨勢,其中提到:“壞設計很簡單,笨蛋才用21天學,盡管他們還是真傻。”

讓我們看看《三日學會C++》這個書名意味著什麽:

◇學習:
三天內你可能沒有時間寫出有意義的程序,或者從中積累經驗。你不可能有時間去跟職業編程者一起去理解在C++環境下的狀況。簡而言之,你沒有充足的時間學很多。所以這本書只能說膚淺的知識。正如亞歷山大·波普(Alexander Pope)所言:一知半解是很危險的。

◇C++:
三天內你可能學會C++的句法(如果你已經了解其他的語言),但你還不會使用它。打個比方,假如你是個Basic程序員,你可能寫出Basic風格的C++程序,而無法理解C++的真實好處。那要點是什麽?艾倫·佩裏斯(Alan Perlis)曾經說過:“一門不能影響你編程觀點的語言不足學的。”有可能你學了一點點C++(或者諸如Javascript、Flex之類),因為你需要和現成的工具接口以完成手頭的任務。這種情況下,你不是在學習如何編程,只是在學習如何完成任務。

◇三日:
不幸地是,這遠遠不夠,下一部分會詳細講。

如何用十年掌握編程



研究人員(Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973))得出結論:想要在諸多領域達到職業水平需要十年,比如國際象棋,作曲,電報操作,繪畫,彈鋼琴,遊泳,網球以及神經心理學和拓撲學的研究。關鍵是精心練習,只是一遍一遍地重復是不夠的,必須挑戰恰好超越你能限的事情,嘗試並思考你的表現,並自我矯正。周而復始。這並無捷徑!4歲的音樂奇才莫紮特用了13年才能創作世界級的音樂。另外,披頭士樂隊似乎在1964年的埃德·蘇利文( Ed Sullivan show)演出中一炮而紅,但是他們自從1957年就在利物浦和漢堡的酒吧演出,在取得廣泛關註後,第一部重量級作品《佩珀軍士》(Sgt. Peppers)是在1967年發行。馬爾科姆·格拉德威爾(Malcolm Gladwell)撰文描述了一項針對柏林音樂學院學生的研究,他們被分為尖子,中等和不足三類,並被問到他們練琴的情況:
所有三組中的人,開始學琴的年齡大概相差無幾,五歲左右。在剛開始的幾年,所有人練習量也差不多,一周兩三個小時。自八歲開始,實質性變化就有了。那些精英學生開始比其他人練習更多:九歲的時候一周六個小時,十二歲的時候一周八個小時,十四歲的時候一周十六個小時,一直到二十歲的時候一周要超過三十小時。截止到二十歲,在他們的生涯裏已經有總計一萬小時練琴。僅僅表現可以的那部分學生加起來是八千小時,那些未來的音樂老師有四千小時。


所以,更確切地說,一萬小時,而非十年,是個神奇之數。薩繆爾·約翰遜(Samuel Johnson, 1709-1784)認為還需更長時間:“卓越乃一生之追求,而非其它”。 喬叟(Chaucer, 1340-1400)抱怨道"the lyf so short, the craft so long to lerne." (生之有限,學也無涯)。希波克拉底(Hippocrates, c. 400BC)因這句話被世人所知:"ars longa, vita brevis"(譯註:拉丁語,意為“藝無盡,生有涯”),更長的版本是 "Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile",翻譯成英文就是 "Life is short, (the) craft long, opportunity fleeting, experiment treacherous, judgment difficult." (生有涯,藝無盡,機遇瞬逝,踐行誤導,決斷不易)。

我的編程成功秘笈是:

◇首先要對編程感興趣,能從編程中得到樂趣。一定要讓它足夠有趣,因為你要保持你的興趣長達十年。

◇與別的程序員交流;閱讀別人的代碼——這比看任何書或參加培訓課都重要。

◇實踐。最好的學習乃實踐。俗話說:“編程的至高境界一定要通過充分的實踐才能達到,而個人的能力可通過不懈努力獲得顯著提升。” (p. 366) “最有效率的學習需要明確的目標,適當的難度,知識回饋,並容許重復或修正錯誤。” (p. 20-21) 《實踐認知:每日的思維、數學及文化》(Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life) 在這方面可做參考。

◇如果你願意,花四年學習大學課程(或者再加上讀研)。這將給你贏得某些工作機會,並給予你在該領域的深層見解。但如果你不喜歡學校的學習,你同樣可以在工作中獲得相似的經驗。無論如何,單靠書本是遠遠不夠的。“學習計算機科學不會讓你成為編程專家,如同學習繪畫和色彩理論不會讓你成為畫家一樣”。這是埃裏克·雷蒙德(Eric Raymond)說的,他是《新黑客字典》(The New Hacker‘s Dictionary)的作者。我雇用過的最優秀程序員,只有高中文憑。但他開發過許多偉大軟件,有自己的新聞組,通過公司認股賺的錢就讓他買下了自己的夜店。

◇和其他程序員一起參與工程項目。在某些項目中擔當最優秀程序員,在另一些項目中充當最差勁程序員。充當領頭羊的時候,你要測試你領導一項工程的能力,並用你的視野來激發他人;如果在項目組中墊底,就應該學習其它牛人在做些啥,以及他們不喜歡做的(看他們把哪些活讓給你做)。

◇繼續別人的工程項目。去理解先前程序員寫的程序。學習如何理解並解決先前程序員沒有考慮到的問題。思考你的程序該如何設計以便讓之後的程序員更容易維護。

◇至少學6種程序語言。其中包括一種支持類抽象的(Java和C++),一種支持函數抽象的(如Lisp或ML),一種支持語義抽象的(Lisp),一種支援聲明規範的(如Prolog或C++模板),還有一種支援協程的(Icon或Scheme),另外一種支持並發的(Sisal)。

◇記住,在“計算機科學”裏有“計算機”一詞。理解計算機執行你的代碼的時候花費的時間。比如:從內存中取一個字(考慮有無緩存未命中情形),連續從磁盤讀字,或者在磁盤中定位。

◇參加語言標準化工作。這可能是有關 ANSI C++ 委員會,也可能是決定你編碼風格是兩格縮進或四格縮進。無論如何,你要知道其他人對語言的喜好程度,有時還要想想他們為什麽喜歡這樣。

◇知道自己應該在何時脫身於語言標準化

所有上述這些,很難通過書本的學習來達到。我頭一個孩子出生時,我讀了所有的“如何做”(How To)系列的書籍,卻依然對育嬰毫無頭緒。30個月後,我第二個孩子出生,我還需要溫習一下那些書嗎?絕對不!相反,我完全可以參照個人經驗,而結果相當有效。這更讓我確信:我的經驗勝過那些專家們寫的上千頁文字。

弗雷德·布魯克斯(Fred Brooks)在《沒有銀彈》(No Silver Bullet)一書給出了尋找頂級設計師的三條建議:
◇盡早系統地識別出頂級設計師。
◇分配一個人作為其職業規劃的導師。
◇給予機遇讓成長中的設計師互相磨礪。

此處假定有部分人已經有成為偉大設計師的潛質,你所需的就是要誘導他們。艾倫·佩裏斯(Alan Perlis)一針見血地指出:"假如人人都可以學雕刻,那就得教米開朗基羅如何不去幹雕刻。對於偉大程序員,也是如此。”

所以,簡單地買一本Java書,你或許能找到些有用的東西,但絕不會讓你在24小時內甚至24天抑或24月內,成為行家裏手。

Peter Norvig:十年學會編程