高手問答精選:Go 語言 —— 雲計算時代的 C 語言(類似於一個FAQ)


Go 語言被稱為雲計算時代的 C 語言,它在軟件開發效率和運行效率之間做出了絕佳的權衡。這使得它既適應於互聯網應用的極速開發,又能在高並發、高性能的開發場景中如魚得水。正因如此,許多互聯網公司,尤其是雲計算領域的創業公司都選擇 Go 語言作為其技術棧的重要組成部分。因此,對於廣大的開發者而言,關注和學習 Go 語言就十分有必要了。

高手問答第 149 期中,我們圍繞 Go 進行了提問,並邀請了 @hyper0x(郝林)作為高手嘉賓。

本文整理了此次高手問答中一些精彩的問答。

Go 語言使用場景相關的問題

Go 的主要使用場景:

  • 主要場景有很多,比如網絡編程,包括 Web 系統、API 應用、下載應用、游戲后端,以及各種服務器編程,例如處理日志、數據打包、虛擬機處理、文件系統,等等。相關的項目在 GitHub 上十分多,也可以參考:https://github.com/GoHackers/awesome-go-China
  • 除了這些,Go 還適合分布式系統、網關類系統(微服務網關)、數據庫代理器、基礎服務等的開發,只要有高並發高可用需求的服務端程序都可以用 Go 開發。
  • 內存數據庫,谷歌開發的 groupcache,couchbase 的部分組建。
  • 雲平台,目前國外很多雲平台采用 Go 開發,CloudFoundy 的部分組建。
  • 另外 IoT 方面有 Gobot 框架,移動開發方面也有官方的解決方案(雖然還有待進一步發展)。

Go 在大數據領域的應用,以及在大數據領域的應用(海量存儲,批處理,流處理,數據預測等方面)有哪些比較看好的開源或商業項目嗎?

  • 在數據挖掘(尤其是爬蟲)、數據分析、數據存儲方面,Go 都非常適合。在 GitHub 上邊有很多這方面的庫,尤其是挖掘和存儲方面。(國產的有很多,比如:pholcus(爬蟲)、TiDB(存儲)等等)。
  • 海量存儲有很多,比如 InfuxDB、CockroachDB、TiDB。其他方面在 GitHub 上也有很多開源項目,不一一列舉了。不過商業的項目目前並不多見。
  • 在大數據領域,Go 和 Python 也是十分優秀的組合。

Go 作為系統編程語言意在取代 C/C++,請問有哪些系統編程使用場景?

  • 誰也取代不了誰,誰也不會被輕易取代,只能說在新的時代更加適合做基礎性的工作,“雲計算時代的C語言”的意思是在雲計算時代更適合做基礎性的工作,實際情況也印證了這一點。我們可以用 Go 輕易編寫系統級的基礎命令,也可以用 Go 編寫軟件替代 C/C++ 軟件,比如 Caddy 可以替代 Nginx,等等。

目前很多電商平台是用 PHP 開發的,Go 適合做電商平台的開發語言嗎?

  • 我司就用 Go 寫了 API 網關、基礎服務和基礎組件,以及一些需要較高性能的應用級系統,都是全局性的基礎系統。優勢很明顯,在開發效率和運行效率上都可以滿足要求,而且綽綽有余。
  • 電商用 PHP 主要都是因為開發快,但是從節省運維成本和提高運行效率的角度講,Go 也是很不錯的選擇。PHP 更容易做頁面渲染,而 Go 更擅長做並發任務處理。在我司是這么划分的。PHP 在某些任務的開發效率上可能更高,但是程序運行效率是比不上 Go 的。

人工智能之類的有名的項目,目前沒有是 Go 做的,如何用 Go 做人工智能?

  • Go 語言由於 Google 的推動進入 AI 領域是必然的。目前 Go 做人工智能相關的工作主要是搭 Tensorflow 的車,因為深度學習框架 Tensorflow 已經有 Go 的 API 了。相信 Go 會逐漸成為主要角色的。

創業公司都選擇 Go 語言作為其技術棧合適嗎?

  • 現在有很多公司都這么做,不過一個技術型公司一般不會只選用一種語言作為基礎技術棧的。我推薦創業團隊選用 Go 語言作為其基礎技術棧(之一)。

Go 語言的優勢

Go 有什么優勢:

  • 部署簡單:Go 編譯生成的是一個靜態的可執行文件,除了 glibc 外沒有其他外部依賴。這讓部署變得異常方便
  • 並發性好:語言層面支持並發,這個是 Go 最大的特色。Goroutine 和 channel 使得編寫高並發的服務端軟件變得十分容易,很多情況下不需要考慮鎖機制以及由此帶來的各種問題。
  • 良好的語言設計:從工程的角度看,Go 的規范簡單靈活,自帶完善的工具鏈,例如 gofmt 可自動排版代碼
  • 執行性能好:適合編寫瓶頸業務,非常節省內存
  • 豐富的標准庫:內置了大量的庫,還有強大的網絡庫

Go 語言相比 Java、PHP 這類時下用得最廣的語言在執行速度跟並發編程上優勢很明顯,除了這兩點外,Go 還有別的優勢嗎?

  • 工程化能力、開發和運行效率上的權衡是 Go 很突出的兩個特色。這兩方面初看沒什么,但細究起來真正是為軟件工程的實施准備的,能起到非常大的作用。當一個團隊去做一大坨項目或者很大的工程的時候,優勢還是很明顯的。

Rust 沒有 GC,Nim 有 GC 但編譯成 C 性能更好,請問 Golang 在和 Rust、Nim 的競爭中會逐漸處於弱勢嗎?

  • 看一門語言要看它的“干爹”、生態建設和發展歷史。Nim的語法我也很喜歡,但是沒有大公司支持,發展沒有保障。
  • Rust 也是一門很不錯的語言,基本上是純社區支持,但是學習門檻很高,生態也不是太萬重山,需要觀望。
  • 對於我來說,Go 非常適合技術團隊使用。當然,如果只是把玩的話 Nim 還是很不錯的,如果想鍛煉心智 Rust 也是一個很不錯的選擇。

Go 語言和 Python 相比,感覺 Python 語言在雲計算、數據挖掘和機器學習更加有優勢。看了好多機器學習的庫都有 Python 版本的而沒有 Go 版本的。一直聽說 Go 語言的性能比 Python 強悍,不知道具體哪方面強於 Python。

  • Go 語言已經涉足數據挖掘領域,正在開始涉足數據分析和機器學習領域。
  • 性能強是肯定的,只考慮解釋型語言與編譯型語言的差別就可以斷定性能差別,更何況 Go 語言的性能在編譯型語言中也是佼佼者。可以自己用不同語言寫同一個 Web Server 測試一下。

相比於 Python、Perl、Ruby 等后端開發語言,Go 有哪些優勢呢?

  • 與腳本語言相比,Go 的優勢很明顯 — 性能好。當然,缺點就是語法糖太少,不過這也是 Go 的工程化理念的一種體現。
  • Go 的並發編程模型是非常獨特的,它省去了開發者自己去處理復雜的並發處理場景。這一點非常值得廣大開發者研習。

Go 語言支持多線程嗎?

  • Go 語言在內核線程之上構建了用戶級線程機制和模型,可以說 Go 的並發模型就是建立在內核線程之上的。Go 完美地包裝了傳統的多線程編程模型,並且有效屏蔽了多線程編程的復雜度。

Go 語言生態發展相關的問題

Go 2.x 可能會有哪些變化?你認為泛型等高級語法,Go 會支持嗎?

  • 現在談 Go 2.x 還太早,你可以到 GitHub 上的 Go 官方項目中搜索帶 go2 標簽的 issue。不過即使這樣也無法完全推測 Go 2.x 的確切特性集合。
  • Go 發布 2.x 的時候會支持范型,就我個人而言,最希望添加的特性也是泛型,但並不是沒有泛型就不行。

谷歌會不會部署 pip、npm 這樣的中心倉庫來推動 Go 的發展?感覺目前 Go 的管理太過松散了。

  • Go 官方正在開發第三方依賴管理工具 dep,但沒聽說准備開發類似 maven 的工具,不過后者其實可以很容易通過 dep(或glide)+自制中轉站+GitLab 來滿足大部分需要。

Java 的生態非常繁榮,Go 在生態建設方面發展如何?

  • Go 的生態的優勢目前還是在雲計算、微服務和數據挖掘,正在向機器學習等新興領域延伸。據我所知,一些機器學習和機器人領域的創業公司已經在使用它了。
  • 作為使用人數較多的國家,Go 在我們國內的發展勢頭非常好。無論大公司還是創業公司,使用 Go 的比例在不斷增大。

Golang 會取代 Java 的地位嗎?未來 Go 的發展前景如何?

  • 基礎技術棧是很難被取代的。我們應該采取開放的心態,多個技術棧並行使用。
  • 有着 Google 引領的技術潮流,Go 應該會有着很好的發展前景。

Go 使用過程中的相關問題:

之前了解到 Go 的 GC 機制存在缺陷,會導致服務進程阻塞,並發機制短暫失效,這個問題在 1.8 中有解決嗎?

Golang 運行時是包含 runtime 的,也是擁有垃圾回收的,與傳統的 Java 相比性能有優勢么?您在使用 Golang 語言的過程中遇到過那些問題呢?

Golang 可以通過什么方式與其他語言進行交互,取長補短呢?

  • 在語言層面有官方的 cgo。
  • 不過建議使用基於通用協議的方式進行交互,比如 thrift、grpc 等,異構系統就是這么來的。

Go 語言使用消息傳遞的方式實現並發,同時也是支持同步鎖並發,請問 channel 方式和同步鎖方式的優缺點;Go 語言目前通道是在單應用內,后續是否可以支持分布式通道開發呢?

  • channel 更符合 Go 的風格,被傳輸的值會被復制,所以一般來說很安全,鎖的適用場景一般是封裝並發安全對象或者保護全局變量。channel 最大的優勢是讓並發編程非常方便和清晰,缺點是稍微比鎖重一些。
  • 分布式通道的其實可以用很多第三方框架或軟件實現,比如 gPRC、Thrift 或者各種 MQ。

Go 開發中有什么坑或注意點?例如因為跟其他常規語言的編程或設計思路不同,而容易導致錯誤的使用。

  • 簡要說一下,在使用 slice類型、channel類型、go語句、defer語句、函數傳參、變量賦值、接口運用等方面都有一些需要注意的地方。例如,一個 slice 值的底層數組在什么情況下是什么樣子的,知道了這個才能更好地運用 slice。
  • 又例如,怎樣操縱 channel 值才能避免阻塞或 panic。

Go 的一些模塊比較慢,比如 Go 的 log,json 部分都有些慢,請問生產環境只能用一些第三方來替代么?關於這里踩過哪些坑,你們又是如何填坑的呢?

  • log 也是 IO,所以必然慢,這需要在性能和日志完備性方面做權衡。在很多時候,日志的內容需要仔細斟酌。慢一般有兩方面原因,一個是有計算量(直接原因),一個是有額外內存分配(間接原因),需要從這兩方面優化。
  • 另外我們是在 logrus 和 Uber 的 zap 上簡單的封裝了一層,統一接口,前者擴展性好,后者性能較好。json 這塊其實我們還是用的官方方案,不過有些簡單 json 就直接拼接字符串了,性能會好一些。

並發和並行有些區別,請問寫出真正並行的程序有什么建議呢,現在只是配置下 GOMAXPROCS。

  • Go 1.5 以后就不用設置這個環境變量了,默認值與當前機器的邏輯 CPU 數量相同,可以充分利用多核計算。
  • 用 Go 語言寫程序只要關注怎么並發就行了,並行的事情交給 runtime。但是與很多技術一樣,需要知道底層的原理才能更好的搭建上層建築。

Go 的底層是如何實現“鴨子模式”的,原理是什么?對性能是否有影響?

  • 你可以看一下這里 https://golang.org/doc/faq#guarantee_satisfies_interface,具體的方式可以閱讀 Go 編譯器的源碼。
  • 當然會有性能影響,但是寫程序和做軟件一定要考慮維護期(生命周期的 90%),要有良好的設計。這很重要。另外,把一個非接口類型(且非指針類型)的值賦給一個接口類型的變量會產生新的內存分配。這點需要注意。

Go 的包管理有什么好的成熟方案嗎?

  • Go 官方在做一個叫 dep 的官方解決方案,但是正式放出還有一段時間。在這之前,我個人首推 Glide,另外 gb 在一些情況下也是適用的。

有什么比較強大的 Go 開發工具?

  • 個人覺得圖形化的開發工具中,VS Code、gogland、LiteIDE 都比較好用
  • Intellj IDEA + Go plugin 也是不錯的選擇

書中有 Go Tool Trace 的使用么,求推薦 Golang 各種 tool 的教程說明,pprof、cpu、內存、競態條件等。

  • 書中並沒有 Go Tool Trace 的使用方法,我另外有一份免費的 Go 命令教程,地址是: https://github.com/gohackers/go_command_tutorial。這份教程上有大多數 Go 命令的使用介紹,但是由於精力有限,沒有 Go Tool Trace 的使用方法。我也希望能有 gopher 幫我完善這份教程。當然,一旦我有時間也會去補上。

在 Windows 環境下,想輸出 GC 信息,CMD 中:set GODEBUG=gctrace=1 mygoapp.exe,這樣並沒有信息輸出。

其他相關問題

目前做 Java 開發,但是非常喜歡Go,准備轉到 Go,對於國內 Go 的行情您認為怎樣?有什么要注意的?

  • 行情肯定是沒有 Java 和 PHP 好,但是正在快速向前沖。如果你真心喜歡 Go 語言,建議找一個專職的 Go 開發工作。當然,在目前崗位上直接用 Go 去寫一些東西、完成一些任務,是更穩妥的辦法。把這門技術應用於實際、產生價值,才是最重要的。
  • 主要需要注意設計和編寫程序的方式,Java 太 OO 了,所以 Java 程序員很容易陷入 OO 思想不能自拔,其實除了 OO 還有其他優秀的編程思想。BTW,我當初就是從 Java 轉過來的。
  • 關於編程思想的轉變方面,還可以參考一位 Go 大牛博客 http://tonybai.com/2017/04/20/go-coding-in-go-way 中的內容。

之前用了五六年的 C#,后來轉成 Node.js 開發,到現在有三年了,使用 Go 開發相比 Node.js 有什么優勢?有必要學習 Go 語言嗎?

  • 如果你厭惡 Node.js 的 callback hell,可以毅然決然的轉 Go,Go 的並發編程模型會大大降低開發者的心智負擔,讓你輕松開發並發程序。
  • 此外,Go 的程序設計哲學與 Unix 的哲學很相近,工程化的理念也非常值得吸納。

 

https://my.oschina.net/editorial-story/blog/967845#comment-list


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM