Go 語言被稱爲雲計算時代的 C 語言,它在軟件開發效率和運行效率之間作出了絕佳的權衡。這使得它既適應於互聯網應用的極速開發,又能在高併發、高性能的開發場景中如魚得水。正因如此,許多互聯網公司,尤爲是雲計算領域的創業公司都選擇 Go 語言做爲其技術棧的重要組成部分。所以,對於廣大的開發者而言,關注和學習 Go 語言就十分有必要了。git
在高手問答第 149 期中,咱們圍繞 Go 進行了提問,並邀請了 @hyper0x(郝林)做爲高手嘉賓。程序員
本文整理了這次高手問答中一些精彩的問答。github
Go 的主要使用場景:golang
- 主要場景有不少,好比網絡編程,包括 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++,請問有哪些系統編程使用場景?npm
- 誰也取代不了誰,誰也不會被輕易取代,只能說在新的時代更加適合作基礎性的工做,「雲計算時代的C語言」的意思是在雲計算時代更適合作基礎性的工做,實際狀況也印證了這一點。咱們能夠用 Go 輕易編寫系統級的基礎命令,也能夠用 Go 編寫軟件替代 C/C++ 軟件,好比 Caddy 能夠替代 Nginx,等等。
目前不少電商平臺是用 PHP 開發的,Go 適合作電商平臺的開發語言嗎?編程
- 我司就用 Go 寫了 API 網關、基礎服務和基礎組件,以及一些須要較高性能的應用級系統,都是全局性的基礎系統。優點很明顯,在開發效率和運行效率上均可以知足要求,並且綽綽有餘。
- 電商用 PHP 主要都是由於開發快,可是從節省運維成本和提升運行效率的角度講,Go 也是很不錯的選擇。PHP 更容易作頁面渲染,而 Go 更擅長作併發任務處理。在我司是這麼劃分的。PHP 在某些任務的開發效率上可能更高,可是程序運行效率是比不上 Go 的。
人工智能之類的有名的項目,目前沒有是 Go 作的,如何用 Go 作人工智能?json
- Go 語言因爲 Google 的推進進入 AI 領域是必然的。目前 Go 作人工智能相關的工做主要是搭 Tensorflow 的車,由於深度學習框架 Tensorflow 已經有 Go 的 API 了。相信 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 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 的 GC 機制存在缺陷,會致使服務進程阻塞,併發機制短暫失效,這個問題在 1.8 中有解決嗎?
- 早在 Go 1.4,Go 官方就已經開始着手改進 GC 了,通過這麼多版本的努力,至今的 GC 已經徹底不是問題了,具體介紹請見:http://www.infoq.com/cn/articles/2016-review-go
Golang 運行時是包含 runtime 的,也是擁有垃圾回收的,與傳統的 Java 相比性能有優點麼?您在使用 Golang 語言的過程當中遇到過那些問題呢?
- 關於對比,你能夠參考這篇文章:https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice
- Go 語言之前被人詬病的是 GC 形成的調度停頓時間太長,可是如今已經徹底不是問題了。
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,這樣並無信息輸出。
- 請參考 https://golang.org/pkg/runtime/#hdr-Environment_Variables。另外你要確認環境變量是否設置正確。
目前作 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