如何客觀的評價 Go 語言

我是從 2015 年開始接觸 Golang,並在以後開始在某出行公司的線上環境大規模使用,同時我的還利用我的時間深刻研究過 Golang 的底層實現機制,包括內存管理、GC 機制、Runtime Scheduler、Interface、Channel 等。這篇文章力求客觀的討論一下 Golang 的利弊。程序員

優勢

1. 簡單

簡單應該是 Golang 最大的優點。Golang 的語言特性簡單,學習週期短,熟悉其餘編程語言的開發者基本均可以在短期學會並寫出各方面都還不錯的代碼。所謂各方面都還不錯是說新手開發者寫出來的代碼和一些有經驗的開發者寫出來的代碼差異並不會太大。golang

Golang 語言層面上的簡潔性讓一些新手程序員也能寫出性能不錯,bug 很少的程序,這個相比其餘高級語言,好比 C++,是一個很是大的提高。MIT 的一個很是有名的課程 6.824 最開始使用功能的 C++,後來改爲了 Golang,就是爲了讓你們能夠專一於分佈式算法自己,而不是陷入到語言細節的調試當中去。web

2. 兼顧開發效率和性能

Golang 因爲豐富的原生庫和周邊生態的支持,開發效率甚至能夠比肩 Python。不少公司早期,或者項目早期的時候爲了趕開發進度都會將開發效率放在第一位,好比 Python,PHP 這種動態語言。可是動態語言的性能劣勢很是明顯。如今的一個好現象就是 Golang 已經愈來愈多的被小公司採用了,畢竟寫一個 http server 不過三行代碼。算法

另外在開發效率的前提下,Golang 還具備很是高的性能。這一方面得益於靜態語言,另外一方面和其自己的語言設計也有不少關係。可是這裏說的很是高的性能有點不太嚴謹,相比 C++/Java 這種老牌的高級語言,在某些場景下的 benchmark 仍是要略遜一籌的。編程

3. 語言級別的特性支持

所謂語言級別的併發支持,就是使用 go func 直接啓動一個 goroutine,外加 select/chan 等周邊。在沒有語言級別的支持以前的異步編程簡直就是 callback 噩夢。記得雲風大神以前對 Golang 的一段評價: 我發現我花了四年時間錘鍊本身用 C 語言構建系統的能力,試圖找到一個規範,能夠更好的編寫軟件。結果發現只是對 Go 的模仿。缺少語言層面的支持,只能是一個拙劣的模仿。 雲風 如今不少人使用一門新語言的時候,有時候還會問:「有對應的 coroutine 庫嗎?」 Golang 的語言層面的支持極大的解放了開發者的心智負擔。微信

缺點

1. runtime

支持 runtime 的編程語言一個沒法繞開的問題就是 runtime 帶來的一系列問題,好比性能損耗。在 rust 語言介紹本身的優點的時候有一點就是 no runtime。併發

Golang 的線程模型調度是 M:N,runtime 調度模型是 GMP 模型,僞搶佔式的。簡單點來講就是 runtime scheduler 能夠類比成操做系統,可是缺少硬件層面上對操做系統的支持,好比硬件中斷,這就對 sheduler 的設計要求的很是高,可是 Golang 的實現並無想象中的那麼好。異步

2. 並不能作到真正高併發高性能

Golang 的高併發使用原生庫來實現的話通常都是經過多 goroutine + select/channel,可是咱們看 channel 源碼,發現這個東西就是一個隊列+一把鎖。這也就意味着沒法避免多個 goroutine 帶來的競爭問題。我以前測試過在多個 goroutine 競爭同一個 channel 的時候,性能急劇降低。因此不少高性能的高併發程序若是是用 Golang 來寫,不少都會避免使用 channel 來傳遞數據,而是借用相似 disruptor 的 ringbuffer 技術。編程語言

可是這並非說 Golang 在高併發場景下性能不行,對於平常的 io 密集型的 web server,能夠說性能是足夠了。分佈式

其餘

這裏談一下 Golang 自問世以來一直被詬病的幾個問題。

1. GC

大概從 1.0 版本以來,GC 就一直被詬病。值得欣慰的是,Golang 的 GC 一直在發展,基本在每一個版本都有必定的改進。1.8 版本是 GC 的一個里程碑,使用併發三色標記法的 GC 算法的stw 時間甚至達到了微秒級。目前社區貌似在討論分代 GC 的方案,這個後面專門寫一篇文章細說。

2. 包管理

包管理也是一直被詬病,主要是一直沒有一個官方的解決方案。直到去年官方終於開始有行動了,推出了 module,相對來講仍是一個很不錯的方案。

3. 泛型

Golang 沒有支持泛型的很大一個緣由是泛型太複雜。儘管不少人說 interface 也能實現泛型功能,可是這個泛型仍是有一些本質的區別的。沒有泛型確實是一個減分項。

最後,咱們從下一篇文章開始瞭解 Golang 的一些重要特性和底層原理。

參考

  1. blog.golang.org/versioning-…
  2. blog.golang.org/modules2019

最後歡迎感興趣的同窗關注微信公衆號。

相關文章
相關標籤/搜索