1. 程式人生 > >如何學習一門新語言

如何學習一門新語言

  首先要說,這並不是一篇教你如何學習的文章,因為到今天為止我也沒有找到一種通用的方法來解決如何學習的問題。但是在探索的道路上,我確實產生過一些思路,我想把這些思考的過程分享出來讓大家探討。如果這對你有幫助的話,那我會非常高興。

  我最近在學習 Rust ,這是一門很酷但是相對冷門的語言(學習冷門語言可能是我的一大愛好,比如我就非常喜歡 CoffeeScript ,這是 JavaScript 的一門方言)。自從在某些語言的舒適區待久之後,經常會產生自己無所不能的錯覺,這也是我不斷想學習新語言的一大動力。

  而我的學習過程跟大多數人類似,就是先在網上找文件然後自學。而在看文件的過程中,我就發現了一些問題。

手冊的作用

  “去看文件嘍。”這是老鳥在面對新手時最喜歡扔的一句話,我通常也是這麼扔給自己的。但當你開啟一門語言的手冊,你會發現它除了教你語法外,幾乎沒有教你什麼其它東西。於是你會陷入這樣一個境地:

  “背下來了麼?”   “背不下來,太難懂了。”   “再看一遍,給我背下來。”   。。。   “背下來了麼?”   “大部分背下來了。”   “給我寫個程式,實現個XX功能。”   “不會。。。”   “。。。”

  在一個高階開發者眼裡,你會了語法理所當然就應該會寫程式了,但實際情況並非如此。這讓我想起前段時間跟一個朋友關於目前程式設計教育市場的一個討論。我出於自己的經驗提出一個想法:讓大牛開發者來教新手入門。在我的設想中,大牛開發者擁有強大的實戰經驗,以及豐富的專業知識,更是自帶光環,這不比現在市場上那些半吊子的講師好多了。在我為自己“偉大”的想法得意的時候,朋友給我澆了一盆冷水。他告訴我這樣根本行不通,大牛根本不知道菜鳥需要什麼知識,你可能以為基礎語法講清楚就好了,人家卻連編輯器是什麼都不清楚。設想一下,讓一個大學教授去教一群小學生,這對兩者來說都是一種災難吧。

  這些語言的創造者,或者文件的作者,無疑都是一些大神。它們在撰寫一個語言手冊的過程中,只能儘量負責地把這個語言的全貌準確地有組織地展現給你。然而這種全面的展現,對於一個沒有任何引導的初學者來說並不完全是一件好事。簡單來說就是,你會在一些次要的事情上浪費太多時間,而一些主要的概念又沒有理解透徹。

關於看真實程式碼

  當覺得文件滿足不了你的時候,老鳥們往往會扔給你第二招:看程式碼。看什麼程式碼呢?那還用說,當然是被業界奉為經典的,在 GitHub 上至少有一萬顆星的知名開源專案程式碼啦。

  當你懷著崇敬的心情,開啟扔給你的網址,看著滿螢幕的程式碼時,你會對自己問出那三個經典的哲學問題。這是什麼東西?它是怎麼做到的?為什麼要這麼寫?搞不好某些人還會因為驚嚇過度,從而失去了學習下去的信心。

  那麼讓我們一起來看看這些程式碼裡有什麼鬼東西,會嚇得新手信心不足。

大段的註釋

  說一件事你們不要笑,在我還是個萌新的時候,我曾經對這些穿插在程式碼中的神祕文字產生了深深的困惑,我還以為它們對程式碼有某種加成作用,以至於我還試驗過把註釋去掉會對程式碼執行產生什麼影響。而現實中好的程式碼會讓後面的維護者方便很多,但不好的甚至錯誤的註釋會讓人迷惑不已。

語法糖

  語法糖是個好東西,它大大簡化了我們的程式設計過程,高手用起語法糖寫起程式碼來簡直不要太爽,所以越強大的專案這玩意兒越多。但是對於初學者來說,語法糖隱藏了一些細節,而且讓語法看起來很怪異。有些程式碼如果你用標準語法來寫是很好懂的,但如果用語法糖來寫的話很難讓人一下子明白。

  初學者為了弄懂這些語法往往要花大量時間,但其實這些時間在這個階段是沒必要的浪費。你看不懂它覺得它是一個很重要的東西,其實它只是一個做工精巧的小玩意兒,離開了它這些程式碼照樣能工作。而隨著你的經驗豐富,也可以隨時隨地用起來,用的方法可能也不盡相同。

程式碼裡的重點

  對於一個開源專案來說,往往 50% 的程式碼可能都是在適配各種不同的執行環境,將系統的 API 抽象成專案裡通用的介面,這部分程式碼除非你自己要做類似的專案,要不然的話對初學者來說參考意義不大。更何況,為了適配某些系統奇葩的執行環境,開發者往往會大開腦洞,創造出一些非常奇怪的程式碼。這些旁門左道充滿了玄學和不確定性,初學者看多了可能會發生如武俠小說裡練功出差錯的結果:走火入魔。

  剩下的程式碼裡 20% 是專案內部的介面抽象和定義,最後 30% 才是真正值得看的東西,它們往往散落在各個地方,但又為了一個設計核心服務。讓初學者識別出這些程式碼來,未免太強人所難。

野文件

  這是我自己的一個定義,我把一切非官方的開發文件都稱為野文件。初學者會在搜尋引擎裡得到大量的相關文件,他們很多是學習心得,很多人在寫這篇文章時水平可能比你也高不了多少。這就造成了這些文件的水平參差不齊,所面向的重點也不同,也許你花了大把時間弄懂的是一個錯誤的或者過時的知識。而大部分號稱教你入門的文章,可能也就是告訴了你如何搭建一個執行環境,這門語言的精髓和重點作者自己估計也沒弄明白。

  而如果你碰到一篇被奉為經典的好的入門文章,那你真的要好好感謝作者。因為這意味著作者付出了大量的深入思考,深入淺出這四個字說起來簡單,做起來可是需要相當的功底的。

相對較好的做法

  在這麼多語言的學習過程中,我也總結了一些相對比較好的學習方法。我認為看程式碼是非常有必要的,因為光死記語法是無法掌握好這門語言的。但是去看一些大型專案程式碼的缺點我在上面也說了,到底該如何是好呢?

  我建議大家可以去看官方給出的,專門供初學者學習的 Step-By-Step 程式碼,這種程式碼一般在官方的文件頁就可以找到連結入口,它有如下好處:

  1. 由淺入深,富有層次。這些程式碼往往是跟隨者文件的深入,慢慢把語法細節展開的。不會一下給你展現太多,讓你無法 GET 到重點。每段程式碼都會有一個重點要表現的特性,這樣看起來會一目瞭然。
  2. 有質量保證。這些程式碼的撰寫一般是官方人員負責,這可以在很大程度上保證準確性。
  3. 更新及時。我們知道很多語言的細節是會隨著版本的升級有所改變的,而很多網上的第三方文件往往缺乏維護,但官方文件一般都會同步更新。

  我建議大家一邊看手冊一邊看程式碼,這樣印象會更深刻。眼睛看了之後,我認為要儘快找一些好的例子來練手,不需要一上來就搞比較複雜的大型專案,也是由淺入深。這種練手專案去哪裡找呢,很多語言的 tutorial 板塊就是幹這個的,做的比較完善的甚至還提供線上的教學體驗環境,大家應該好好利用。

寫在最後

  這篇討論學習方法的文章引發了我的一些額外思考。我經常在開發者社群裡看到老鳥和初學者互懟,寫這篇文章的過程也讓我理性思考了產生這些矛盾的原因。總的來說就是一些資訊的不對稱造成的。老鳥認為這個問題根本不是問題,網上一搜一大把,不願多講甚至冷嘲熱諷。而初學者卻覺得這些資訊根本理解不能,老鳥的嘲諷就是一種羞辱。

  我認為要打破這種不對稱需要雙方付出耐心,而這種耐心的付出是相互的,你付出的多回報的就越多。而最先邁出付出這一步的,應該是初學者,畢竟從情理上來說是你請求人家辦事。而你需要付出的不過是把自己的問題講明白,說出你的思考過程,附上必要的資訊。一個好學的人是不會讓人討厭的,但前提是你得有一個不讓人討厭的姿態展現出來。