1. 程式人生 > >Go真的有這麼好嗎

Go真的有這麼好嗎

為什麼要學習Go

Go是未來的服務端語言— Tobias Lütke, Shopify。在過去的幾年中,Golang逐步流行起來。 還有什麼能比一門新語言讓碼農們瘋狂呢? 因此,我開始學習了一段時間Golang,在這裡我將告訴你為什麼你也應該學習這種新語言。 在本文裡我不會告訴你怎麼寫hello world。 我要分析計算機硬體軟體的當前階段,以解釋為什麼我們需要像Go這樣的新語言?

硬體限制

摩爾定律正在失效 第一個具有3.0GHz時鐘速度的Pentium 4處理器是由英特爾於2004年推出的。 而今天,我的Mackbook Pro 2016的CPU時鐘速度為2.9GHz。 可以看到在過去的十年中,CPU處理能力沒有太大的進步。 您可以在下面的圖表中看到這一點。


從上面的圖表可以看出,單執行緒的效能和處理器的頻率在過去的十年內保持平穩。如果你認為新增更多的電晶體是解決方案,那麼你錯了。這是因為在較小的尺度上一些量子性質開始出現(如隧道,因為它實際上用掉更多的更多的電晶體(為什麼?)並且新增電晶體的價效比在下降。 所以製造商開始向處理器新增越來越多的核心。現在我們有四核和八核CPU可用。 同時我們還引入了超執行緒。還向處理器新增更多快取以提高效能。 但上述解決方案也有其侷限性。我們不能向處理器新增更多的快取以提高效能,因為快取具有物理限制:快取越大,快取越慢。向處理器新增更多核心也具有成本。此外,這都不能無限擴充套件。這些多核處理器可以同時執行多個執行緒,並在紙面上帶來併發性。我們稍後將討論這一問題。 所以,如果我們不能完全依靠硬體的改進來提升效能,更高效的軟體也是我們需要考慮的手段。但遺憾的是,現代程式語言並不高效。

Go has goroutines!!

如上所述,硬體製造商正在向處理器新增越來越多的核心以提高效能。使用這些處理器的所有資料中心,在未來幾年核心數量將會大大增加。更重要的是,今天的應用程式使用多個微服務來維護資料庫連線,訊息佇列和快取。因此,我們開發的軟體和程式語言應該輕鬆支援併發性,並且它們應該隨著核心數量的增加而輕鬆擴充套件。 但是,大多數現代程式語言(如Java,Python等)發明於90年代的單執行緒環境。當然這並不意味著他們不支援多執行緒(譯者的話Python確實不支援多執行緒)。大多數程式語言支援多執行緒。真正的問題來自併發執行和執行緒鎖,競爭條件和死鎖。這些東西使得在這些語言上建立多執行緒應用程式很困難。 例如,在Java中建立新執行緒會消耗大約1MB的記憶體堆大小。最終如果你建立了數千個執行緒,這將對堆記憶體造成巨大的壓力,並將由於記憶體不足而被作業系統殺死。此外,如果你想在兩個或多個執行緒之間進行通訊,也比較困難。 另一方面,Go在2009年釋出時,多核處理器已經流行起來。這就是為什麼GoLang以併發為第一要務。 Go使用goroutines而不是執行緒。新建goroutine只使用近2KB的記憶體,你可以建立數百萬goroutine。


當然還有其他的好處:

  • 具有可增長的分段堆。這意味著他們只在需要時才使用更多的記憶體。

  • Goroutines的啟動時間比執行緒快。

  • Goroutines帶有內建的原語,以便在它們之間(channel)安全地通訊。

  • Goroutines允許您避免在共享資料結構時使用互斥鎖。

  • 此外,goroutines和OS執行緒不是1:1對映。 單個goroutine可以在多個執行緒上執行。 Goroutine被複用到少量的OS執行緒中。

以上幾點,使Go非常強大,可以在處理併發(如Java、C和C++)的同時保持程式碼的優雅(像Earlang)。


Go直接執行在硬體上

使用C、C ++的一個最大的好處是它們的效能比其他現代高階語言(如Java / Python)更強。 因為C / C ++是編譯執行而不是解釋執行的。 當您使用Java或其他基於JVM的語言構建應用程式時,它將程式碼編譯為位元組碼,在執行時,JVM解釋位元組碼並將其轉換為處理器可以理解的二進位制程式碼。 


而C、C 不在VM上執行,從執行週期中刪除一個步驟,並提高了效能。 他們直接將程式碼編譯成二進位制程式碼。 


但是在C/C中釋放和分配記憶體太過痛苦。 即使大多數程式語言可以使用垃圾收集器或引用計數演算法處理物件分配和刪除。 Go同時擁有上面提到的好處。 Go是像C/C++這樣的低階語言並且是編譯型語言。 這意味著它的效能幾乎更接近低階語言。 並且Go還使用垃圾回收來分配和釋放記憶體。 所以不需要malloc和free!!!

Go程式碼容易維護

Go有著非常整潔和乾淨的語法。Go的設計者在建立語言時考慮到了這一點。 由於google有非常大的程式碼庫,成千上萬的開發人員正在使用同一個程式碼庫,程式碼應該易於其他開發人員理解。這將使程式碼易於維護和修改。 Go故意去掉了很多現代OOP語言具有的功能。

  • 沒有類。 Go只有結構體而不是類。

  • 不支援繼承。 這將使程式碼容易修改。 在其他語言(如Java / Python)中,如果ABC類繼承了類XYZ,並且在類XYZ中進行了一些更改,那麼這可能會在繼承XYZ的其他類中產生一些副作用。 通過刪除繼承,Go使得很容易理解程式碼(因為沒有超類)。

  • 沒有建構函式。

  • 無註解(annotation)。

  • 沒有泛型(generics)。

  • 沒有異常。

以上的差異使Go與其他語言非常不同。 當然你可能不喜歡上面的一些點。 但是,在沒有上述功能的情況下 你需要做的僅僅是多寫2-3行程式碼。 然而這樣會使你的程式碼更加簡潔易懂。


上圖顯示Go幾乎與C/C++一樣高效,同時保持程式碼語法簡單,如同Ruby,Python。 這是一個對人類和機器來說雙贏的局面! 與其他新語言(像Swift)不同,Go的語法非常穩定。 自從2012年首次公開發布1.0版以來,它保持不變。這使得它向下相容。

Go的背後是Google

  • 雖然這不是直接的技術優勢。 但Go是由Google設計和支援的。 Google擁有世界上最大的雲基礎架構之一,並且可以大規模擴充套件。Go是由Google設計的,以解決他們需要的可擴充套件性性問題。這些也是你在建立自己的服務時將面臨的問題。

  • Go也被一些大公司使用,如Adobe,BBC,IBM,英特爾等等。

結論

  • 即使Go和其他面向物件的語言非常不同,但它同時為您提供高效能(如C/C++),超級好用的併發處理(如Java)和簡潔的程式碼(如Python/Perl)。

  • 如果你沒有任何計劃學習Go,我還是會說軟體開發人員需要寫出超高效的程式碼。開發人員需要了解硬體並相應地優化程式。優化軟體以執行在更便宜和更慢的硬體(如IOT裝置)以提升終端使用者體驗。