自學編程,十年磨一劍 原 薦

原文鏈接 Teach Yourself Programming in Ten Years 作者 Peter Norvig

原文幾經修改,已有的翻譯 慘不忍睹,多處翻譯得背道相馳,怒而重新翻譯,是爲此文。2017.11.5

爲什麼每個人都如此急於求成?

在任何書店裏你都能看到類似於《24 小時 Java 無師自通》這樣的書,以及旁邊無窮無盡的變種,試圖教你在短時間內學會 C、SQL、Ruby、算法等等技能。

我在亞馬遜在線書店搜索“自學”“小時”“2000年以後出版”等關鍵字,找到了 512 本類似書籍。前十名有九個都是編程書。

似乎一切都昭示着,要麼當下人們迫切地想學會編程,要麼學會編程是相當容易的一件事。在其他領域裏,你很難找到諸如此類的書,甚至是《狗狗餵養指南》都鮮有“幾日速成”這種說法。你不奇怪嗎?

是的,Felleisen 等人也注意到了,他們的著作《如何設計程序》裏提到了這種速成書氾濫的趨勢,並給出評論“拙劣的編程水平確實相當容易達成。傻子都能在 21 天裏學會,哪怕他們天生就是個白癡。”。Abtruse Goose 的漫畫《如何自學編程》也有類似的表達。

讓我們試着分析一下,一本《24 小時 C++ 無師自通》意味着什麼:

1.24 小時: 有限的時間,意味着精簡過的內容。

2.C++: 如果你學過其他編程語言,那麼你可能會學到一門新語言的語法。然而你仍然無法學到怎麼去原汁原味地使用它。簡言之,你可能能夠以 Basic 語言的風格來使用 C++ 的語法,但無法發揮出 C++ 本身的優勢(甚至其缺點你都不知道)。這意味着什麼?Alan Perlis 說過,“如果一門語言不能影響你的編程思維,那麼不學也罷。” 當然,你也可能學會用這一點點 C++ 來完成特定的接口編碼任務,但這只是完成了任務,你並沒有學會怎麼用 C++ 去編程。試着理解這種區別。

3.無師自通: 你不會有什麼時間寫幾個有意義的程序,也沒法從中吸取什麼成功或者失敗的經驗。你也不可能有時間和老練的程序員一起工作和交流,沒法去理解真正的 C++ 工程的工作環境是什麼樣子。簡言之,你學不到什麼。你能從這類書中得到的只有粗淺的印象。就像是英國詩人亞歷山大所說:“淺嘗輒止,甚是危險。”

用十年時間自學編程

大量的研究者發現,在很多領域裏達到專業級別的水平,大概需要十年時間。研究對象涉及下棋、作曲、發報、繪畫、鋼琴演奏、游泳、網球,還有神經心理學和拓撲學。

關鍵在於“刻意練習”:不要機械地重複一件事,而是發起挑戰,試圖超越已有的能力範圍,不斷嘗試,不斷分析、總結、糾正錯誤。

捷徑是不存在的。即使天才如莫扎特,4 歲開始作曲,也是在 13 年以後才創作出世界級的音樂鉅作。

Malcolm Gladwell 提出了著名的一萬小時定律

Henri Cartier-Bresson (1908-2004) 曾說過:“你攝影生涯中的前一萬張,都是垃圾。” 當然,他沒能預料到的是,隨着數碼相機的普及,人們甚至可以在一週內達成這項成就。

Samuel Johnson (1709-1784) 也說過:“在任何一個領域裏想要做到極好,勢必要窮盡一生的努力,沒有代價更低的辦法了。”

Chaucer (1340-1400) 也發出過“生命如此短暫,技藝卻如此高深”的感嘆。這句話來自更古老的一條格言:“生命短暫,技藝高深,機遇易逝,探索難得,抉擇困難重重。”

當然,學會一項技術需要多久,沒有絕對的終極答案,不同的技能也各有不同。但有一件事應當成爲共識:掌握一門技能,不是短短的十幾二十小時的事,而是要下每週十幾二十小時的功夫。

你想成爲真正的編程專家嗎?

下面是我給出的成功“指南”:

對編程感興趣。出於興趣地去做點什麼。保持這種感興趣的狀態,這是確保你能夠持續投入時間的絕佳保障。

動手寫程序。最好的學習方式是“在實踐中學習”。更專業的說法是“一個人在一個領域內的最高水平,並不是隨着經驗增長而自動獲得的,而是爲了進步而刻意努力產生的結果。”。《實踐中的認知:日常生活中的思維、數學和文化》一書說:“最有效的學習需要滿足這麼幾點:明確且對學習者來說難度適當的任務,及時的信息反饋,重新開始和改正錯誤的機會”(p.20-21)。

與他人交流,讀他人的程序。相信我,交流遠比看書和上培訓班重要。

如果你願意,讀個計算機學位。這將給你機會去接觸那些需要專業認證的工作,也會給你提供本行業更深的理解。當然這不是必須的,你也可以通過工作來積累經驗。無論通過哪種方式,你要明白,書本學習很重要,但是隻有書本學習是遠遠不夠的。Eric Raymond 說過:“如果說僅僅靠學習油畫和調色技術無法成爲出頂尖的畫家的話,那麼光靠學習計算機科學課程也不能造就頂尖的編程專家。”。舉個例子,有一個人,他是我所僱用過的最好的程序員之一,他只有高中學歷,但他寫了很多偉大的軟件,他有他自己的新聞組,並且通過股權賺夠了錢,還開了家屬於自己的夜店。(譯註:這個人是 Jamie Zawinski,Netscape 的早期開發者,Mozilla 和 XEmacs 的主要貢獻者)

與其他人一起做項目。俗話說雞頭鳳尾。在一些項目裏爭取成爲雞頭,也要加入一些你會是鳳尾的項目。成爲雞頭,你會有機會鍛鍊自己的領導能力,也可以激發遠見;成爲鳳尾,你會跟隨大師學習如何行事,也會接觸到項目中大師們不會親自處理的瑣事雜事。

加入他人的項目。試着理解別人寫的代碼,嘗試在找不到原作者的情況下修復代碼中的問題,從中體會這需要多大的代價。試着思考如何讓自己的程序更容易被他人理解和維護。

學會多門編程語言。不同的編程語言有不同的抽象模型、不同的側重點和優勢。如經典的命令式編程語言、廣泛使用的面向對象編程語言、聲明式編程語言、函數式編程語言等等,都值得一學。

理解計算機。計算機科學這個概念,可是有“計算機”三個字的。比如:瞭解計算機執行指令需要花多久,從內存中獲取一個字(word)會遇到什麼、花多久,從硬盤裏讀取連續的字(word)會花多久,以及在硬盤上重新定位到一個新的位置要花多久。這很重要。

參與語言的標準化過程。雖然很難加入 ANSI 委員會,但你能夠使自己的編程風格、編碼規範得到統一。比如縮進用 Tab 還是空格,幾個空格寬。無論如何,你都能夠了解那些被大家所接受的“事實標準”的語言偏好,試着體會他們從中感悟到了什麼,試着思考他們爲什麼接受這個標準。

保持敏銳,儘快適應語言的標準化,形成習慣。不要忘記,你要與他人協作,要產生他人能讀的懂的程序。

要做到上面所說的這些,光靠讀書應該是不夠的。在我的第一個孩子出生前,我讀遍了所有的《如何……》類書籍,然而還是感覺自己是個菜鳥。30 個月後,我的第二個孩子快出生了,我還要回去讀書嗎?當然不,這次我會更多地依賴於我的個人經驗,這遠比專家寫的上千頁紙更有用和令人安心。

Fred Brooks 在他的著作《沒有銀彈》 裏揭示了發現優秀軟件設計師的三步計劃:

  1. 儘早地系統地辨認出頂級的設計師
  2. 指派一名職業導師爲其指點迷津,並謹慎留存他的職業檔案
  3. 爲成長中的設計師提供互動的機會,使其互相促進

即使有一部分人已經具有了成爲優秀設計師的素質,但仍然需要正確的引導。Alan Perlis 說的更直接:“任何人都能被教會如何雕塑,但米開朗琪羅必須被教會怎樣才能不被他人教導。這道理對編程專家同樣有用。” 他的意思是偉大的人有其特質,但這些特質從哪來?與生俱來的還是後天可培養的?《料理鼠王》裏的 Auguste Gusteau 說:“任何人都會做飯,但只有無所畏懼者(the fearless)才能成爲大廚。” 無所畏懼是天生的嗎?我很願意投入生命中的一大部分精力用於刻意練習,但可能“無所畏懼”的精神纔是量變到質變的關鍵所在。《料理鼠王》裏與 Gusteau 作對的美食評論家 Anton Ego 說:“不是任何人都能成爲偉大的藝術家,但偉大的藝術家在成名前可能是任何人。” 或許這傢伙的話纔是對的。

所以,儘管去書店買那些速成書籍吧,你也許發現他們真的挺管用。但這不會改變你的人生,也不會讓你的編程水平有什麼本質的提高。當你開始思考“要不要試着通過 24 個月的不懈努力來持續提高自己?”的時候,那麼恭喜你,你上道了。

附錄A 哪一個編程語言是我要先學習的?

總有人問這種問題,雖然沒有標準答案,但還是說了幾句。

這裏不通篇翻譯了,取其精髓。作者的意思是選擇那些“你朋友們都在用的,簡單的,可以輕鬆運行的”,比如 Python 或 Scheme。當然那也不強求你追隨別人的腳步。

附錄B 哪裏能找到真正的學習書籍或相關資源?

總有人問這種問題,雖然很難回答,而且也肯定學的不夠全面,但還是推薦一些。

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