十年學會編程(Decade of Programming Institute)

爲何人人都這麼着急?

信步走進任何一家書店,你會看到名爲《如何在7天內學會Java》的書,還有各種各樣類似的書:在幾天內或幾小時內學會Visual Basic, Windows, Internet等等,一眼望不到盡頭。我在Amazon 上做了如下的 強力檢索 :
pubdate: after 1992 and title: days and(title: learn or title: teach yourself)

得到了248個結果。前78個都是計算機類書籍(第79個是 Learn Bengali in 30 days)。我用”hours”替換”days”,得到了類似的結果:更多的253書。前77本是計算機類書籍,第78本是 Teach Yourself Grammar and Style in 24 Hours。在前200本書中,有96% 是計算機類書籍。

結論是:要麼人們都在忙忙地學習計算機,要麼計算機比其它任何東西都容易學。沒有書籍教你在幾天內學會古典音樂、量子物理,或者是養狗。

讓我們分析一下,象一本名爲《三天內學會Pascal》的書意味着什麼:

* 學習: 在三天裏,你沒有時間寫一些重大的程序,並從成功或失敗中得益。你沒有時間與有經驗的程序員合作,並理解在那樣的環境下工作是怎麼回事。一句話,你不會有時間學到太多東西。因此他們只能談論一些膚淺的東西,而不是深入的理解。正如亞力山大教皇所說,淺嘗輒止是危險的事情。

* Pascal: 在三天時間裏,你可能學會Pascal的語法(如果你已經學過類似的語言),但你學不到更多的如何使用這些語法的知識。也就是說,假如你曾是個BASIC 程序員,你可以學着用Pascal語法寫出BASIC風格的程序,但你不可能瞭解Pascal真正的好處(和壞處)。那麼關鍵是什麼? Alan Perlis 說過:“一種不改變你編程的思維方式的語言,不值得去學。” 一種可能的情況是:你必須學一點兒Pascal(或可能性更大的象Visual Basic 或 JavaScript之類),因爲你爲了完成某種特定的任務,需要與一個現存的工具建立接口。不過那不是學習如何編程,而是在學習如何完成那個任務。

* 三天內: 很不幸,這不夠,原因由下一節告訴我們。

在十年裏學會編程

研究表明 (Hayes,Bloom) 在任何一種領域內,象下棋、作曲、繪畫、鋼琴演奏、游泳、網球、以及原子物理學和拓撲學,等等,要達到專家水平大約都要化十年時間。沒有真正的捷徑:即使是莫扎特,4歲時就是音樂神童,13年後纔開始寫出世界級的作品。在另一方面,披頭士似乎在1964年的Ed Sullivan表演上一炮走紅。但他們從1957年就開始表演,在獲得大衆青睞後,他們的第一個重大成功,Sgt. Peppers,是1967年發行的。Samuel Johnson (塞繆爾·約翰遜,英國辭典編纂家及作家)認爲要花比十年更長的時間:“在任何領域中出類拔萃都要用畢生的勞作來取得;它不可能用較低的代價獲得。”而Chaucer(喬叟,英國詩人)感嘆到:“人生短暫,學海無涯。”

這是我爲編程成功開出的方子:

* 設法對編程感興趣,並且因爲它有趣而編一些程序。確保編程一直充滿足夠樂趣,這樣你才願意投入十年寶貴時間。

* 與其他程序員交流; 閱讀其它程序。這比任何書本或訓練課程都重要。

* 寫程序。 最好的學習方式是從實踐中學習。用更技術性的話說,“在一個給定的領域內,個人的最大能力不是自動地由擴展了的經驗取得的,但即使是高度有經驗的人也可以通過有意識的努力來提高自己的能力”(p. 366) 和“最有效的學習需要因人而異的適當難度,目標明確的任務,豐富的信息反饋,以及重複的機會和錯誤修正。” (p. 20-21) 此書 Cognition in Practice: Mind,Mathematics,and Culture in Everyday Life 是闡明此觀點的令人感興趣的參考文獻。

* 如果願意,在大學裏呆上4年或更長(在研究生院裏)。你會接觸到一些需要學歷證明的工作,你會對此領域有更深的理解。如果你不喜歡學校,你可以(通過一些貢獻)在工作中獲得相似的經驗。在任何情況下,光啃書本是不夠的。Eric Raymond,The New Hacker’s Dictionary一書的作者,說過,“計算機科學不能把任何人變成編程專家,就象光研究刷子和顏料不會使人變成畫家一樣。” 我僱傭過的最好的程序員之一僅有高中程度;他做出了許多優秀的 軟件,有他自己的新聞組,而且通過股票期權,他無疑比我富有的多。

* 和其他程序員一起做項目。在其中的一些項目中作爲最好的程序員; 而在另一些項目中是最差的。當你是最好的,你能測試領導項目的能力,用你的觀點激發別人。當你是最差的,你學習傑出者是怎麼做的,瞭解他們不喜歡做什麼(因爲他們吩咐你做事)。

* 在其他程序員之後接手項目。使自己理解別人寫的程序。當程序的原作者不在的時候,研究什麼需要理解並且修改它。思考如何設計你的程序以便後來者的維護。

* 學習至少半打的編程語言。包括一種支持類抽象的語言(象Java 或C++),一種支持函數化抽象的語言(象Lisp或ML),一種支持語法抽象的語言(象 Lisp),一種支持聲明規格說明的語言(象Prolog或C++ 的模板),一種支持共行程序(coroutine)的語言(象Icon或Scheme),一種支持並行的語言(象Sisal)。

* 請記住“計算機科學”中有“計算機”一詞。瞭解你的計算機要花多長時間執行一條指令,從內存中取一個字(有cache),從磁盤中讀取連續的字,和在磁盤中找到新的位置。(答案)

* 參與一種語言標準化的工作。它可以是ANSI C++委員會,也可以是決定你周圍小範圍內的編程風格是應該兩個還是四個空格縮進。通過任何一種方式,你瞭解到其他人在某種語言中的想法,他們的理解深度,甚至一些他們這樣想的原因。

* 找到適當的理由儘快地從語言標準化的努力中脫身。

明白了這些,僅從書本中你能得到多少就成了一個問題。在我第一個孩子出生前,我讀了所有的(關於育兒的)How to 書籍,仍然感覺是個手足無措的新手。30個月以後,我的第二個孩子快要出生了,我回頭溫習這些書了嗎? 沒有。相反,我依靠我的個人經驗,它比專家寫的數千頁書更有用和可靠。

Fred Brooks在他的隨筆 《沒有銀彈》 中定出了一個尋找優秀軟件設計者的三步計劃:

1. 儘可能早地,有系統地識別頂級的設計人員。

2. 爲設計人員指派一位職業導師,負責他們技術方面的成長,仔細地爲他們規劃職業生涯。

3. 爲成長中的設計人員提供相互交流和學習的機會。

此計劃假設某些人已經具備了傑出設計者的必要才能; 要做的只是如何恰當地誘導他們。 Alan Perlis 說得更簡明扼要:“每個人都能被教會雕刻:對米開朗其羅而言,反倒是告訴他哪些事不要做。同樣的道理也適用於優秀的程序員。”

所以儘管買那本Java的書吧。你可能會從中學到點兒東西。但作爲一個程序員,你不會在幾天內或24小時內,哪怕是幾個月內改變你的人生,或你實際的水平。

參考文獻
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.
Hayes, John R., Complete Problem Solver, Lawrence Erlbaum, 1989.
Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.

2001年夏天典型的1GHz PC的各種操作要花的時間答案
各種操作的計時,2001年夏天在一臺典型的1GHz PC上完成:
    執行單條指令            1 納秒 = (1/1,000,000,000) 秒
    從L1緩存中取一個word        2 納秒
    從主內存中取一個word        10 納秒
    從連續的磁盤位置中取一個word    200 納秒
    從新的磁盤位置中取一個word(尋址) 8,000,000納秒 = 8毫秒

不少人問我,他們首先該學哪種編程語言。沒有絕對的答案,不過請考慮以下幾點:

* 用你的朋友的。當被問起“我該用哪種操作系統,Windows,Unix,還是Mac?”,我總是回答:“你朋友用什麼,你就用什麼。” 你從朋友那能學到知識,這種優勢可以抵銷不同操作系統或語言之間本質的差異。也考慮你將來的朋友:程序員社區 — 你將成爲它的一部分如果你繼續往前走的話。你選擇的語言是否有一個成長中的社區,還是人數不多、即將消亡? 有沒有書籍、網站、在線論壇回答你的問題?你喜歡論壇裏的那些人嗎?

* Keep it simple, stupid. 象C++和Java這樣的語言是爲經驗豐富的程序員組成的團隊進行專業開發而設計的,他們專注於代碼運行時的效率。因此,這些語言有些部分非常複雜。 而你關注的是如何編程,不需要那些複雜性。你需要的是這樣的語言: 對單個的編程新手來說,它易學易記。

* 練習。你偏愛哪種學彈鋼琴的方式:通常的交互式的方式,你一按下琴鍵就能聽到音符;還是“批量”模式,你只有彈完整首曲子才能聽到音符?顯然,用交互模式學習彈鋼琴更容易些,編程也一樣。堅持用交互模式學習並使用一種語言。

有了上面的準則,我推薦的第一個編程語言是Python或Scheme。因人而異,還有其它好的選擇。如果你的年紀是10歲以下,你可能更喜歡Alice。關鍵是你要選擇並開始實踐。
附錄:書籍和其它資源

不少人問我,他們該從什麼書籍或網頁開始學起。我重申“僅從書本里學習是不夠的。” 但我還是推薦:

* Scheme: Structure and Interpretation of Computer Programs (Abelson & Sussman)可能是最好的計算機科學的入門書,而且它的確把講授編程作爲理解計算機科學的一種方法。但它具有挑戰性,會讓許多通過其它方式可能成功的人望而卻步。

* Scheme: How to Design Programs (Felleisen et al.)是關於如何用一種優美的、函數化的方式設計程序的最好的書之一。

* 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的當代繼承者。它是對編程的高層次概念的巡視。涉及的範圍比Abelson & Sussman更廣,同時可能更容易學習和跟進。 它用了叫做Oz的語言,不太知名,卻可以作爲學習其它語言的基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章