初始Golang---為啥選用Go語言?

2020-10-06 11:00:20

如題,為啥選用Go語言?

本文將介紹該語言誕生的原因,核心特性以及應用場景等。


前言

Go語言為什麼一會叫Go,一會又叫Golang?

這是因為Go的全名為Go language,簡稱可以為Golang或者Go。而Go表示的意思有太多了,比如在英文裡表示很多意思,很難讓人們想到程式語言,所以一般在搜尋時可以以Golang作為關鍵字。但是在這篇文章裡,兩者等價的,所以有時可能稱為Go,有時是Golang。


Go誕生的原因

Google在創造Go的原因:

  • 計算機硬體的發展特別快速,效能提高的很快。目前主流的程式語言發展明顯落後與硬體的發展,不能夠合理地利用多核CPU以提升軟體效能。
  • 軟體系統的複雜度越來越高,維護成本也越來越高。目前缺乏一個足夠簡潔高效的程式語言
  • 企業執行維護很多C/C++專案,這兩個語言雖然執行速度很快,但是編譯速度很慢,同時還存在記憶體洩露的問題需要解決。這使得我們程式設計師再解決業務的同時,還要分出精力去處理業務之外的事情。

Go的編碼風格

這裡摘選一個GitHub倉庫

最近十年來,C/C++在計算領域沒有很好得到發展,並沒有新的系統程式語言出現。對開發程度和系統效率在很多情況下不能兼得。要麼執行效率高,但低效的開發和編譯,如C++;要麼執行低效,但擁有有效的編譯,如.NET、Java;所以需要一種擁有較高效的執行速度、編譯速度和開發速度的程式語言,Go就橫空出世了。

傳統的語言比如c++,大家花費太多時間來學習如何使用這門語言,而不是如何更好的表達寫作者的思想,
同時編譯花費的時間實在太長,對於編寫-編譯-執行這個鏈條來說週期太長。動態語言如Python,
由於沒有強型別的約束,很多問題需要在執行時發現,這種低階錯誤更應該交給編譯器來發現。
執行效率 execution speed:
 C/C++ > Java > PHP 開發效率 developing efficiency: PHP > Java > C/C++

簡單一句話,為了兼顧執行速度與開發效率。可以看成Go=C+python。

因為它本質上是個靜態語言,不過編譯器給了開發者許多「語法糖」,所以又兼備動態語言的特點。


Go的核心特性

  • 並行程式設計:這個我覺得是最重要的特點,人家天然就支援並行。誒,有朋友可能會講了,Java不也支援並行嗎?Java是支援,它還有個關鍵字synchronized可以解決並行中的共用變數問題呢!但是人家底層還要涉及到核心層面的開銷,所以一些鎖特別「重」。而Go和它相比開銷就小的多。

    不僅如此,還有個重要的點,人家是多執行緒。Go是多攜程程式設計。什麼是攜程。攜程可以理解為更加輕量的執行緒(gorountine),可以高效的處理並行,更加高效地利用多核。 一次可以在程式中啟動成千上萬個gorountine,從而高效地完成任務。

    而gorountine之間的通訊採用獨特的chanel機制,確保gorountine之間可以通訊。

  • 記憶體回收(gc):這個大家就比較熟悉了,學過Java的朋友不陌生。我們在開發程式時無須去考慮記憶體問題,因為有jvm會幫我們自動釋放記憶體。而Go也同理,它會幫我們自動回收。

    GC過程:先stop the world,掃描所有物件判活,把可回收物件在一段bitmap區中標記下來,接著立即start the world,恢復服務,同時啟動一個專門的goroutine,回收記憶體到空閒list中以備複用,不物理釋放,物理釋放由專門執行緒定期來執行。GC瓶頸在於每次都要掃描所有物件來判活。待收集的物件數目越多,速度越慢。GC效能可能會隨著版本不斷更新會不斷優化。只需要new分配記憶體,不需要釋放。

    這裡插播一下,關於Go的記憶體分配

    在初始化階段直接分配一塊大記憶體區域,大記憶體被切分成各個大小等級的塊,放入不同的空閒list中。物件分配空間時從空閒list中取出大小合適的記憶體塊。記憶體回收時,會把不用的記憶體重放回空閒list。空閒記憶體會按照一定策略合併,以減少碎片。

  • 網路程式設計:這裡說白了就是像其它語言一樣,也提供了豐富便捷的網路程式設計介面。Go語言還自帶了高效能的HttpServer,通過簡單的幾行程式碼呼叫,就可以得到一個基於協程的高效能Web服務,維護成本極低,沒有任何依賴。

    socket用net.Dial(基於tcp/udp,封裝了傳統的connect、listen、accept等介面);
    http用http.Get/Post();
    rpc用client.Call(‘class_name.method_name’, args, &reply);

  • 函數多返回值:不僅返回本來的值,還可以返回一個error物件,用來出現異常時使用。這也是Go推薦的程式設計風格。有時候會有這種需求。

  • 語言互動性:可以呼叫其它語言編譯之後的庫,比如C。

  • 例外處理:Go語言不支援try catch這樣的結構化的異常解決方式。Go語言提供的例外處理方式是:如果是普通異常,檢視被呼叫方返回的error物件;如果是嚴重異常,指的是中斷性panic(比如除0),使用defer…recover…panic機制來捕獲處理。嚴重異常一般由Go語言內部自動丟擲,不需要使用者主動丟擲,避免傳統try…catch寫得到處都是的情況。

    三個重要關鍵字defer、panic、recover;
    defer是函數結束後執行,呈先進後出;
    panic是程式出現無法修復的錯誤時使用,但會讓defer執行完;
    recover會修復錯誤,不至於程式終止。當不確定函數不會出錯時使用defer+recover。

  • 除此之外還有一些其它的特性了,比如上文也出現的defer機制,本質上是延遲執行。個人覺得有點像Java中的finally和守護執行緒。還有一些型別推導等特性,各位在具體學習中會感受到,這裡不多介紹了。


Go的應用場景

主流的應用場景有那麼幾個:

  1. 區塊鏈開發:這個怎麼講呢。區塊鏈本質上是一個分散式賬本技術,就是人人都可以參與記錄。而編碼實現所用到的技術棧就是Golang。目前來看,也算是未來的一個趨勢吧。
  2. 遊戲/web端開發:先說遊戲這塊。舉個例子,平時咱們打lol時,隊友上去打出了爆炸傷害,我們可以馬上看到。這裡就可以看成資料的實時同步了,有個專業的詞,叫資料通道。而Golang可以實現這個資料通道。而web開發,這個就不用多說了吧,人家也可以做web應用,甚至於當下主流的微服務應用也能駕馭。
  3. 雲端計算/雲服務後臺應用:這裡主要涉及到一些雲上的東西,如京東的訊息推播和分散式檔案系統,都是採用Golang來實現的。還有盛大的CDN(內容分發網路)等等。因為Golang的計算機能力比較強。

不僅如此,Golang還被用來開發一些中介軟體。比如大名鼎鼎的dockerk8s等。人家就是用Golang來做的。還有微服務註冊中心consul等等。


之前在網上看到一個總結,未來的軟體系統應用可能是C/C++負責底層實現,Java負責高層(即業務層)的編碼實現,而Go可以來負責中間層的實現。目前來看的確有這種趨勢。

但是和其它語言相比,個人還是覺得Go的特性雖然足夠誘人,但是國內的社群活躍度還是不夠,這裡也希望各位學習該語言的小夥伴可以一塊記錄下部落格或貢獻開原始碼,一起為這個社群貢獻出一份力。

文中有些內容摘選自網際網路。最後,感謝您的觀看🙏