如何學會所有的程式語言?

infoq 發佈 2020-02-26T00:22:20+00:00

世界上有幾千種程式語言,其中只有20 多種在 IT 界裡被廣泛使用。對於我個人而言,我最喜歡的語言是 C 語言 /Ruby/Lua/OCaml。

新手在開始學習編程時通常會問這個問題:

「我要從哪一門程式語言開始學起?」

在學會了幾門程式語言之後,很多開發者會問這個問題:

「哪一門程式語言是最好的?」

我將會在這篇文章里給出我的答案。不過,比得到答案更重要的是:掌握學習新程式語言的能力。

授之以魚不如授之以漁

對於一個編程老手來說,學習新的程式語言應該很容易。他們只需要一個周末甚至是幾個小時就可以開始用新學的程式語言寫代碼了。優秀的程式設計師可以為了完成某個任務使用任何一門程式語言。畢竟,程式語言只是工具。

話是沒錯,不過更重要的你要學會「如何學習新的程式語言」,而不只是學會某一門具體的語言。要掌握「學會所有程式語言」的能力,你不需要是一個天才,你要做的是掌握程式語言的核心知識,並知道所以,代碼實際上就是你傳達給人類和計算機的「消息」。這也是在設計和實現程式語言時需要考慮的權衡點。因為:一些最佳實踐。

下面讓我來具體解釋一下。

如果把程式語言比作汽車

要記住,程式語言只是工具,它們也是由程式設計師發明出來的。世界上有幾千種程式語言,其中只有 20 多種在 IT 界裡被廣泛使用。如果你稍微想一想,就會發現這些程式語言有一些共同點。

我們以汽車為例,世界上有很牌子的汽車。有些車子緊湊但動力十足,有些車子笨重開得慢,不同牌子的車子具有不同的駕駛體驗。

如果你知道怎麼開其中一種車型,也就知道怎麼開其他大部分車型,儘管它們的牌子不一樣。

為什麼這麼說呢?因為不同牌子的車子有一些共同點——它們都有發動機和輪胎。它們的作用都是一樣的:把你送到目的地。

程式語言的作用是幫助程式設計師表達想法

為什麼會有這麼多程式語言

程式語言是一種表達工具,包含了兩個方面:

  1. 向其他程式設計師表達想法,這樣別人就可以了解你寫的代碼,並一起參與代碼維護。
  2. 把你的想法傳達給計算機(通過編譯器或者解釋器),讓計算機執行你的指令。

所以,代碼實際上就是你傳達給人類和計算機的「消息」。這也是在設計和實現程式語言時需要考慮的權衡點。因為:

  1. 硬體和計算機語言在發展演化。一般來說,程式語言應該越來越容易使用,在表達想法方面越來越強大。
  2. 隨著計算機應用越來越廣泛,越來越多的領域需要使用計算機,於是不同的程式語言被發明出來,用於解決不同領域的問題。
  3. 不同的程式語言代表了不同的思維風格。

不同的程式語言有不同的語法和特性,但它們都是圖靈完備的。通俗地說就是:所有的程式語言都可以用來實現任意一種算法。

當然,你不需要學會所有的程式語言,但學會的程式語言越多,就越容易為要完成的任務選擇合適的語言。

程式語言基礎

幾乎所有的程式語言都包含了幾類元素,它們都與「抽象」有關:

  1. 數據類型和數據抽象;
  2. 控制流程和控制抽象;
  3. 底層抽象;
  4. 對特定領域的補充和抽象。

程式語言有很多公共特性,因此,我們能夠學會所有程式語言的主要原因是:程式語言的概念其實是很有限的。常用的程式語言概念不會超過 15 個:

  • 過程;
  • 遞歸;
  • 靜態類型;
  • 動態類型;
  • 類型推斷;
  • lambda 表達式;
  • 面向對象;
  • 垃圾回收;
  • 指針;
  • 連續性;
  • 元編程;
  • 宏;
  • 異常。

程式語言的概念基本上是不怎麼變的,就像設計原則一樣。

程式語言的作者們相互借鑑想法,只是實現不一樣罷了。有時候,我們可以說語言 C 是語言 A 和 B 的兒子,那麼整個程式語言的家譜可能像這樣:

理解好這些概念,不僅可以幫你快速學會程式語言,還會讓你寫出更好的代碼。例如,函數式程式語言和過程式程式語言的代碼風格和抽象方式是非常不一樣的,如果沒有領會到它的重點,可能就寫不好代碼。

專注在語言概念上,而不是語法

因此,我們要學習程式語言概念,但該怎麼學呢?

我建議去了解某個語言概念或特性要解決的問題是什麼,它有哪些好處和不足,而且最好可以知道它是怎麼實現的。

我們以 GC 為例,那麼第一問題就是:GC 是什麼東西?

在網上搜一下,可以找到這個維基百科的解釋。GC 是用來解決內存管理問題的,可以減少程序的內存錯誤。有了 GC,代碼寫起來更容易了,因為我們不需要手動管理內存,但這是以犧牲性能為代價的。如果你的程式語言使用了 GC,要注意 GC 是如何幫你處理內存的。

隨後,你需要知道 GC 的工作原理。它們使用了什麼算法?GC 有很多種,而且它們的種類還在不斷發展演化中。

開始學習新的程式語言正是學習程式語言概念的一個好時機。例如,如果 Ruby 是你的第一門面向對象程式語言,就可以借這個機會深入了解一下面向對象編程的優點和不足。

對面向對象編程有了很好的理解,再去學習其他面向對象程式語言就會容易得多。

自己發明或實現一門程式語言

如果語法不是很複雜,要實現一門程式語言並不需要做太多工作。可以看看這個項目,任何一門語言都可以被用來實現 Lisp。 8cc 是 C 語言的一個編譯器,如果你想自己寫一個編譯器,可以參考這個項目。

除了這些,還有一些書可以看:

《程式語言要領》介紹了很多種解釋器,《程式語言編譯器實踐》也是一本適合用來學習程式語言的書。

學習一門新語言的步驟

如果你遵循以下這些步驟,就可以快速「學會所有的程式語言」。

第一步:理解這門語言的設計理念和通用的語言特性

例如,如果你要學 Ruby,那就先看一下 Ruby 有什麼特別的?

Ruby 是一門開源的動態程式語言,專注易用性和效率。它的語法很優雅,代碼讀起來很自然,寫起來也很自然。

讓我們更深入地看一下:

http://www.ruby-lang.org/en/about/

那麼,在學習 Ruby 之前,需要了解的重點是:

  • Ruby 專注於易用性和效率,代碼容易閱讀;
  • Ruby 是解釋執行的,所以使用了 GC,也就是說對於某些任務,性能可能會是個問題;
  • 在 Ruby 中,所有東西都是對象,所以它是面向對象程式語言,而且是純面向對象的;
  • Ruby 很靈活,我們可以重新定義它的一些東西。

了解這門語言最重要的特性,包括它的優點和不足。

第二步:通過教程或書籍學習語法和最佳實踐

在第二步,你需要掌握語法、基本的 IO、調試工具和單元測試。

如果你剛開始學習編程,最好找那種「權威指南」之類的書籍,比如語言作者寫的書,或者在網上書店搜索這門程式語言,找到好評如潮的書。

如果你是個編程老手,只需要找一些簡單的指南或示例代碼就可以了,可以看看這個。

記住,在學習語法時,你需要動手寫代碼,不要只是拷貝黏貼。你可以在這個網站上練習寫代碼,有人會審閱你的代碼,並免費為你提供建議。

第三步:使用新學的語言寫更多的代碼

現在,你需要使用新學的語言開始一個項目,包括與這門語言有關的生態系統、工具和庫。你可以從簡單的開始,比如一個猜數字小遊戲、簡單的網上書店或者 TODO 應用程式。在 GitHub 上可以找到很多類似的項目。

第四步:了解語言的實現細節

這一步並非都是必需的。不過,有追求的程式設計師對程式語言的實現細節會感興趣。有時候,因為對程式語言的實現細節不是很了解,容易寫出 bug。

那麼,我應該先學哪一門語言?

好吧,現在我們來回答這個問題。這個問題的答案取決於很多因素,但簡單地說就是:

1:有人教你嗎?或者說你在上程式語言課程嗎?

如果你的老師要你學習 C 語言,那麼 C 語言就是你的第一門需要學習的程式語言,因為有人教你,你還有同學,學習起來會更容易。

2:你打算用它來做什麼?

如果你要開發 Web 應用程式,就學習 JavaScript/Python/Ruby。如果你要開發遊戲,就學習 C++。如果你要處理數據,就學習 Python/R 語言。如果你要開發 Android App,就學 Java/Kotlin。

3:你需要用它來找工作嗎?

如果是這樣,按照崗位的要求來學就好了。

哪一種程式語言是最好的?

這個也取決於實際情況。每一門程式語言都有自己的優點和不足。適合用來處理所有任務的程式語言是不存在的。如果存在,我們只需要學習一門就夠了,不是嗎?記住,這個世界上沒有萬靈丹。

對於我個人而言,我最喜歡的語言是 C 語言 /Ruby/Lua/OCaml。

有人說,在掌握 5 門程式語言之前,不要把自己當成高級程式設計師。當正如之前所說的,不要專注於學習更多的程式語言,而是試著學習更多的程式語言概念和設計原則。

如果你在工作中使用的是結構化的程式語言,為什麼不試著學習一門函數式程式語言?如果你的語言是動態類型的,為什麼不試著學習一門靜態類型的語言?


關注我並轉發此篇文章,私信我「領取資料」,即可免費獲得InfoQ價值4999元迷你書!

關鍵字: