花個十年學習寫程式吧!

原文“Teach Yourself Programming in ten years."

為什麼大家總是這麼想短時間內學會一個程式語言呢?
筆者發現一個很有趣的現象,當他用"day" & “teach yourself"的關鍵字搜尋近十幾年的書,結果有73/248電腦相關的書籍,更令人訝異的是,當筆者再把"day"換成"hours"之後,竟然出現了77/253電腦相關的書籍,不管是電腦或是非電腦,都比"day"還多…

那讓我們挑本書來看看Learn C++ in Three Days這樣的標題代表著什麼含意
學到:這三天你可能根本不會寫到什麼有意義的程式,或是從程式的錯誤中學習,也沒有時間跟有經驗的程式設計師一起工作並瞭解C++的執行環境。簡單來說,你根本學不到什麼,所以書本只是讓你懂一些膚淺的概念,就像Alexander Pope說的, a little learning is a dangerous thing.
C++:這三天或許可以學到一些語法,但卻學不到如何去使用,簡而言之,你只會用基本的語法,但你卻不知道C++真正的長處以及短處,Alan Perlis once said: “A language that doesn’t affect the way you think about programming, is not worth knowing"這種書或許可以幫助你把一些存在的工具或程式碼兜在一起以完成一件工作,但是你不是在學習如何寫程式,你是在學如何完成工作。
三天:不幸的,完全不夠,請繼續看下去。

花個十年學習寫程式吧!
一些神經心理與拓樸學研究人員已經證明了在各式各樣的領域(如:下棋、作曲、印刷、彈琴、游泳、網球) ,要成為專家,差不多要花十年的功夫。關鍵就是自省訓練(deliberate practice),什麼是自省訓練?不像是一般的訓練只是持續不斷的練習,而是每一次都不斷的藉由設定超出自己目前能力的目標挑戰自我,嘗試去做,並且在練習結束之後進行分析,分析為什麼沒有做到更好?要如何再下一次的訓練中更加進步?然後不斷的重複自省訓練,這之間沒有任何捷徑,即使像是莫扎特,在四歲就被稱為音樂神童,在成名之前還是花了十三年的練習才寫出世界級的歌曲。在另一個領域,披頭四似乎突然就爆紅於1964,但是實際上他們也已從那七年之前就開始在小間的歌廳駐唱,而且雖然他們早就有一堆粉絲,但真正的成功卻是在1967年Sgt. Peppers發行之後。Malcolm Gladwell針對柏林音樂學院的不同程度學生做了一些研究:
不論程度高、中、或低的學生,他們都在差不多五歲的時間開始接觸音樂,在一開始的幾年,大家都差不多,都一個禮拜練習個兩三小時。但是當他們到了八歲左右,差異就開始浮現了,最後會被視為程度好的學生開始增加訓練時間:9歲一個禮拜6小時、12歲8小時、14歲16小時、跟著時間一直遞增,直到了二十歲,一個禮拜的練習已經超過三十個小時了,而二十歲為止,一些菁英表演者已經累計練習了10000小時,而所謂的優秀學生相比之下,則只有8000小時,而將成為未來的音樂老師只要超過4000小時。
所以其實標題應該把十年改成一萬小時的,這是個魔術數字,Samuel Johnson認為應該還要比一萬小時長:“Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price."但Chaucer就抱怨了:“the lyf so short, the craft so long to lerne."這句話是從“Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile"引用出來的,意思是說生命太短,要學的技藝卻很多,機會稍縱即逝。

重點來了,以下是筆者對於有效學習程式的看法:
1. 要用熱情、興趣,必須確認他有足夠的樂趣讓你可以投注十年的時間下去。
2. 跟其他程式設計師討論、多看程式碼,這比看書或上訓練課程還重要
3. 寫程式。最好的學習就是做中學,更技術上的說法:"個人在特定領域上的最佳程度表現可能不會因為你的經驗增加就能達到,但是至少會讓你的程度提昇"、"最有效的學習需要用具有以下特性的工作來學習:適當難度、針對人設計、資訊回饋、以及有重複修正錯誤的的機會。
4. 學校教育固然可以給你對該領域更深入的瞭解,但是只有讀書是不夠的。
5. 跟其他程式設計師一起開發專案,在某些專案中你必須成為最優秀的,而在某些專案中你必須成為最弱的,當你是最優秀的時候,你就有機會讓你知道你是否具有帶領整個專案與以你的視野激勵他人的能力。當你是最弱的,你也可以學到別的強者都怎麼做的,而你會知道他們不喜歡做什麼事(因為他們會叫你做)
6. 參與一些已開發完成的專案,瞭解程式是怎麼被寫出來的,當遇到問題的時候原作者無法給予幫助要有能力可以解決它,並解思考如何設計你的程式使得日後的人更好維護。
7. 至少要會6種程式語言,
Include one language that supports class abstractions (like Java or C++), one that supports functional abstraction (like Lisp or ML), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), one that supports coroutines (like Icon or Scheme), and one that supports parallelism (like Sisal).
8. 記住computer science之中是有"computer",所以你至少要對電腦執行指令,抓取字組,等等的時間有點概念。
9. 參與程式語言標準化的工作,像是ANSI C++ committee,不然你也可以從別人身上瞭解他為什麼喜歡某個語言,深度的去瞭解他們的想法,甚至解他們為什麼這麼覺得。
10. 要有良好的判斷力,該離開標準化的工作時就要儘快離開。

照他的說法,是不是要花60年才能學會六種程式語言啊Orz