Go 爲什麼能成功

大家在入門 Go 語言時,多埋頭於 Go 語法,忙於練手或快速完成公司的項目,無暇思考。

但當大家到了要進階,要衝刺高級階段的時候,我建議你不能再稀裏糊塗了。既然入了 Go 這個坑,在進入高級階段前,我們最好在門口的 “影壁牆” 前駐留一下。

仔細思考一下我們投入這麼多精力研究的 Go 爲什麼能成功,後續還能否持續成功下去。你要有自己的基本的判斷,自我暗示也好,堅定信心也罷,我們要爲繼續攀登 Go 高峯進行蓄能

一. 頭腦風暴一下 Go 成功的因素

相信無論針對哪個 gopher 羣體做頭腦風暴,讓大家列舉 Go 成功的因素,大家的主流答案也無外乎下圖中這些:

圖中的各個因素與 Go 的成功都不無干系,但是究竟哪個或哪幾個是決定性的呢?

二. Go 成功的根本因素

很顯然,這個問題是沒有標準答案,是見仁見智的。這裏我列舉一下我的觀點,供大家參考。

直接上結論,我認爲 Go 成功的根本因素就一個:Google

爲什麼這麼說呢?下面我們展開來看 (見下圖)!

我將 Go 社區比做一支軍隊,而 Go 就是 Go 社區的武器,與其他編程語言搏殺,佔地盤 (fans)。下面我們就來解構一下這支軍隊的構成以及爲什麼這支軍隊目前有諸多成功案例!

1. Google 爲 Go 社區提供了統帥與武器

衆所周知,2007 年 Google 的三名員工 Robert Griesemer、Rob Pike 和 Ken Thompson(retire 很早,精神上領袖,給予 Go 名譽上的背書) 一起發明了 Go 語言,2009 年 Go 開源後,Go 社區逐漸形成。統帥是一支軍隊的靈魂,他們做出了影響 Go 和 Go 社區的最初的也是最重要的決策和這背後的 Go 設計哲學!

a) 設計決策

在 2022 年,Go 團隊在美國計算機學會通訊 (Communications of the ACM)[1] 期刊上發表 paper:《Go 編程語言與環境 [2]》,對當年做出的諸多決策做了細緻說明,這裏對其中兩個最重要的決策做簡單說明:

Go 語言之父們認爲語言特性僅是編程語言的一部分,而編程環境特性與語言特性同等重要,這些環境特性包括:庫、工具、慣例和針對軟件工程的整體做法,它們都對使用 Go 語言編程提供了支持,不可或缺。而這些環境特性恰恰是在傳統的編程語言設計中並沒有受到應有的重視的。

這樣的決策讓 Go 在開源之初就爲開發者提供了使用 Go 進行編程所需的幾乎一切:包括功能豐富、開箱即用的標準庫以及全面的工具集,代碼格式化、代碼靜態檢查、依賴關係管理、構建 (包括跨平臺交叉編譯)、測試、性能剖析、查看和生成文檔等,並且這些工具集在今天都統一放在了 go 命令的下面。這個決策也幫助 Go 在開源後吸引了第一批 Go 社區用戶。

Go 的一個目標是讓它在不同的實現、執行環境中,甚至在不同的時間內表現出相同的行爲。所以,Go 語言儘可能地規定了一致的結果。比如:Go 程序生命週期內一致的性能 (相對於使用 JIT 慢啓動的語言)、一致的 GC 的開銷等。甚至對於最常見的編程錯誤提供了明確定義的語義,這有助於可理解性和調試,而不是像 C/C++ 中那樣,充斥着各種未定義的行爲。

而我認爲最重要的一致性則是從 2012 年發佈的 Go 1.0 開始,Go 團隊公開承諾只對語言和標準庫進行向後兼容的修改,這樣程序在編譯到較新的 Go 版本時可以繼續運行而不發生變化。這一承諾對業界產生了吸引力,它不僅鼓勵了那些長聲明週期的工程項目 (比如 Google 內部的一些大型項目或者像 Kubernetes 這樣的社區頂級項目),也鼓勵了其他努力,如書籍、培訓課程和第三方軟件包的繁榮生態系統。這一一致性的決策也爲 Go 招募了相當數量的擁躉。 Go1 兼容性,同樣可以避免社區分裂(像 python2/python3 那樣),即便是 10 多年來變更最大的泛型語法落地 [3],也沒有違反 Go1 兼容性,這實屬不易。

b) 設計哲學

上述的設計決策的背後蘊含着 Go 語言之父們的設計哲學。

Tony Hoare 在 1980 年圖靈獎演講中說了這樣的觀點:“我的結論是,構建軟件設計有兩種方法:一種方法是讓它變得如此簡單,顯然沒有缺陷,另一種方法是讓它變得如此複雜,以至於沒有明顯的缺陷。第一種方法要困難得多。它需要同樣的技能,奉獻,洞察力,甚至靈感,就像發現作爲自然複雜現象基礎的簡單物理定律一樣。它還要求願意接受受物理,邏輯和技術限制的目標,並在無法實現衝突目標時接受妥協。”

Go 選擇的正是 Tony Hoare 演進中的第一種構建軟件的設計方法。Rob Pike 說過的一句 Go 流行諺語 "less is exponentially more" 與此異曲同工。Go 的語法簡單,API 簡單,這些爲 Gopher 提供了極大便利,但這些簡單的背後其實是 Go 團隊長時間的複雜的思考與實現,努力將語法和 API 簡化爲最小、最有用、最接近本質的努力工作。

同時,簡單意味着可讀性、可維護性,意味着代碼的清晰。另一句 Go 諺語 “Clear is better than clever” 告誡 Gopher 們編寫平淡如水的 Go 代碼纔是 “政治正確” 的,不要炫技。

多核時代,Go 將併發作爲語言內置特性。Go 內置併發原語,包括 goroutine、channel、select 等。

Go 鼓勵在較高級別使用併發性,特別是通過通信的方式。我們耳熟能詳的一句 Go 諺語是 “Don't communicate by sharing memory. Share memory by communicating” 就是併發哲學的外在體現。

Go 擁有類型,類型可以有 method,這似乎像是一種面向對象 style 的實現,但 Go 並沒有 OO 語言那種類型層次體系 (type hierarchy),在 Go 中,組合纔是 Go 類型之間建立聯繫的最主要手段,而 interface 和類型嵌入恰是這種組合哲學的具體體現。

2012 年, Go 開源元年,Rob Pike 就在 SPLASH 2012 大會上以 “Google 的 Go:爲軟件工程服務的語言設計”[4] 爲題,講解了 Go 是如何圍繞 Google 內部存在的軟件工程問題進行有針對性的語言設計的。可以看出,Go 從誕生伊始就將解決軟件工程領域問題作爲語言的目標。同時,我們看到面向工程這個哲學與上面的旨在成爲一個編程環境的決策息息相關。

除了統帥之外,Go 社區的治理架構也是以 Google“將領” 爲核心的,我們繼續來看。

2. Google 出錢:以 Google“將領”(googler and ex-googler) 爲核心的 Go 社區治理架構

Go 開源 10 年了,Go 社區形成了以 Googler 和 ex-googler(前 google 員工) 爲核心的 Go 社區治理架構,這些人就是上圖中的那些 “將領”,他們是 Go 項目某個細分領域,比如:編譯器、運行時 goroutine 調度、GC、內存管理、網絡、安全等的領頭人。根據 Go 項目一名產品經理的描述:2021 年,Google Go 項目的專職人員多達 50 多人 [5],Google 這個 “親爹” 在金錢的投入上顯然表現的十分大方,不得不承認:在編程語言領域裏,有個有錢的 “親爹” 就是好 [6]。

這種以 googler 和 Ex-googler 爲開源社區治理核心的架構決定了 Go 社區採用的是一種我稱之爲 “民主集中制” 的決策機制。在 Go 社區你不要幻想會有絕對的公平投票,Go 項目決策向來是由少數 Googler 和 ex-googler 主導的。這樣意味着很多情況下,核心治理團隊的人提出的 proposal 以及 Google 內部 gopher 提出 proposal 很容易被 accept,而來自外部社區的 proposal 要想被 accept,可能難度就要大一些。怎麼說呢?Google 的方案不一定總是最好的,但我們也不能不承認多數情況下,Googler 提的 proposal 還是更優的,並且通常這些 proposal 對應的實現都已經在 google 內部測試過了,甚至和 Go 決策組在公司內部“吹過風”,如果你是 Go 社區的決策人,你會怎麼做呢?你是更相信 Googler 還是外部一個沒有任何背景的 gopher 呢?

我覺得在 Google 依然引領 IT 前沿的今天以及未來若干年,這種機制可能還是有利於 Go 的蓬勃發展的。

3. Google 爲 Go 社區提供戰場 / 試驗場

就像上面所說的那樣,Go 是有着非常鮮明 Google 烙印的編程語言,除了 Go 語言之父都來自 google,Go 社區治理架構的核心都來自 Google 和前 google 員工外,Google 內部爲 Go 的設計提供了足夠的一流的問題域,也爲 Go 的真實應用提供了試驗場和真實戰場,即便 Go 至今沒有成爲 Google 內部的第一語言。面向 Google 的一手且一流問題域,讓 Go 設計者和 Go 開發者能夠獲得一手的反饋,從而對 Go 做進一步的打磨。

舉幾個例子:

同時 Google 內部系統爲了支持 Go 的內部試驗也是不遺餘力,比如:每當 Go 發佈大版本的 RC 版本,甚至是 Beta 版本時,Google App Engine 都會首當其衝的充當 “小白鼠”,在生產環境支持尚未發佈正式版的 Go。

另外 Google 在業內的領先性也讓 “近水樓臺” 的 Go 受益,比如像容器調度編排這樣的平臺,Google 十年前就有了(borg),後續 Googler 以另起開源項目的方式將其中經驗外溢輸出,讓 Kubernetes 最終選擇了 Go 作爲開發語言,從而成爲 Go 的最大的也是最典型的成功戰例。

綜上,我們看到 Google 對 Go 成功的決定性作用,這種作用可決不能被理解爲簡單的金錢上的支撐。

三. Go 語言演進歷史

進入 Go 高級階段後,對 Go 語言的演化歷史要知道,當然能做到如數家珍更佳,即便不能,也要能記住 Go 語言的主要演化歷史:

四. 小結

C++ 之父說過:“世上只有兩種編程語言:一種是總是被人抱怨的,一種是從來沒人用的”。

Go 屬於前者。世界上沒有完美的編程語言,Go 經過十年的打磨已經有了長足的進步,並且取得了不錯的戰績,尤其是在雲基礎設施和雲原生因公領域,就連 Rob Pike 也承認 Go 確實已成爲雲基礎架構的語言 [7]。而這個 Go 走向成功的過程中,Google 起着根本性的作用。

不過中國古語有云:成也蕭何,敗也蕭何!目前 Google 仍然引領 IT 技術前沿,這對 Go 的發展來說是一個利好,也會不斷推動 Go 向着好的方向發展。

但我大膽預測一下:“成也 Google,敗也 Google”,一旦 Google 開始走下坡路的那天,Go 語言成功的根基就不在了,Go 還能像今天這樣順風順水麼?如果 Go 社區治理結構不重構,很可能不會再有今天這樣的良好狀態。大家覺得呢?

五. 參考資料

-《Go 編程語言與環境:萬字長文覆盤導致 Go 語言成功的那些設計決策 [8]》 -《Go 內存模型》- https://research.swtch.com/gomm -《Go 語言真正的問題》 - https://vanitynotes.com/posts/20221101-the-real-problem-with-go


我的聯繫方式:

參考資料

[1] 

美國計算機學會通訊 (Communications of the ACM): https://cacm.acm.org/

[2] 

Go 編程語言與環境: https://tonybai.com/2022/05/04/the-paper-of-go-programming-language-and-environment

[3] 

10 多年來變更最大的泛型語法落地: https://tonybai.com/2022/04/20/some-changes-in-go-1-18

[4] 

“Google 的 Go:爲軟件工程服務的語言設計”: https://go.dev/talks/2012/splash.article

[5] 

2021 年,Google Go 項目的專職人員多達 50 多人: https://tonybai.com/2022/01/16/the-2021-review-of-go-programming-language

[6] 

在編程語言領域裏,有個有錢的 “親爹” 就是好: https://tonybai.com/2012/10/08/the-new-age-of-programming-language/

[7] 

Go 確實已成爲雲基礎架構的語言: https://tonybai.com/2020/05/01/rob-pike-interview-go-become-the-language-of-cloud-infrastructure/

[8] 

Go 編程語言與環境:萬字長文覆盤導致 Go 語言成功的那些設計決策: https://tonybai.com/2022/05/04/the-paper-of-go-programming-language-and-environment

[9] 

“Gopher 部落” 知識星球: https://wx.zsxq.com/dweb2/index/group/51284458844544

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ID3_MtZIg7jkkbTTPSTgKA