Go學習筆記 -- Go簡介
- 簡介
-
- Go語言創始人
- Go 是編譯型語言
- Go語言吉祥物
- 語言特性
- 文法簡單
- 并發模型
- 記憶體配置設定
- 垃圾回收
- 靜态連結
- 标準庫
簡介
起源于2007年,2009年對外正式釋出。Go的主要目标是“相容Python等動态語言的開發速度和C/C++等編譯型語言的性能與安全性”。
它能讓你通路底層作業系統,還提供了強大的網絡程式設計和并發程式設計支援。Go語言的用途衆多,可以進行網絡程式設計、系統程式設計、**并發程式設計、分布式程式設計**。
Go語言沒有類和繼承的概念,是以它和 Java 或 C++ 看起來并不相同。但是它通過接口(interface)的概念來實作多态性。Go語言有一個清晰易懂的輕量級類型系統,在類型之間也沒有層級之說。是以可以說Go語言是一門混合型的語言
此外,很多重要的開源項目都是使用Go語言開發的,其中包括 Docker、Go-Ethereum、Thrraform 和 Kubernetes。
Go語言創始人
對語言進行評估時,明白設計者的動機以及語言要解決的問題很重要。Go語言出自 Ken Thompson 和 Rob Pike、Robert Griesemer 之手,他們都是計算機科學領域的重量級人物。
Go 是編譯型語言
Go 使用編譯器來編譯代碼。編譯器将源代碼編譯成二進制(或位元組碼)格式;在編譯代碼時,編譯器檢查錯誤、優化性能并輸出可在不同平台上運作的二進制檔案。要建立并運作 Go 程式,程式員必須執行如下步驟。
1.使用文本編輯器建立 Go 程式;
2.儲存檔案;
3.編譯程式;
4.運作編譯得到的可執行檔案。
這不同于 Python、Ruby 和 JavaScript 等語言,它們不包含編譯步驟。Go 自帶了編譯器,是以無須單獨安裝編譯器。
Go語言吉祥物
Go語言有一個吉祥物,在會議、文檔頁面和博文中,大多會包含下圖所示的 Go Gopher,這是才華橫溢的插畫家 Renee French 設計的,她也是 Go 設計者之一 Rob Pike 的妻子。

語言特性
Go語言也稱為 Golang,是由 Google 公司開發的一種靜态強類型、編譯型、并發型、并具有垃圾回收功能的程式設計語言。
文法簡單
抛開文法樣式不談,單就類型和規則而言,Go 與 C99、C11 相似之處頗多,這也是Go語言被冠以“NextC”名号的重要原因。
Go語言的文法處于簡單和複雜的兩極。C語言簡單到你每寫下一行代碼,都能在腦中想象出編譯後的模樣,指令如何執行,記憶體如何配置設定,等等。而 C 的複雜在于,它有太多隐晦而不着邊際的規則,着實讓人頭疼。相比較而言,Go 從零開始,沒有曆史包袱,在汲取衆多經驗教訓後,可從頭規劃一個規則嚴謹、條理簡單的世界。
Go語言的文法規則嚴謹,沒有歧義,更沒什麼黑魔法變異用法。任何人寫出的代碼都基本一緻,這使得Go語言簡單易學。放棄部分“靈活”和“自由”,換來更好的維護性,我覺得是值得的。
将“++”、“–”從運算符降級為語句,保留指針,但預設阻止指針運算,帶來的好處是顯而易見的。還有,将切片和字典作為内置類型,從運作時的層面進行優化,這也算是一種“簡單”。
并發模型
時至今日,并發程式設計已成為程式員的基本技能,在各個技術社群都能看到諸多與之相關的讨論主題。在這種情況下Go語言卻一反常态做了件極大膽的事,從根本上将一切都并發化,運作時用 Goroutine 運作所有的一切,包括 main.main 入口函數。
可以說,Goroutine 是 Go 最顯著的特征。它用類協程的方式來處理并發單元,卻又在運作時層面做了更深度的優化處理。這使得文法上的并發程式設計變得極為容易,無須處理回調,無須關注線程切換,僅一個關鍵字,簡單而自然。
搭配 channel,實作 CSP 模型。将并發單元間的資料耦合拆解開來,各司其職,這對所有糾結于記憶體共享、鎖粒度的開發人員都是一個可期盼的解脫。若說有所不足,那就是應該有個更大的計劃,将通信從程序内拓展到程序外,實作真正意義上的分布式。
記憶體配置設定
将一切并發化固然是好,但帶來的問題同樣很多。如何實作高并發下的記憶體配置設定和管理就是個難題。好在 Go 選擇了 tcmalloc,它本就是為并發而設計的高性能記憶體配置設定元件。
可以說,記憶體配置設定器是運作時三大元件裡變化最少的部分。刨去因配合垃圾回收器而修改的内容,記憶體配置設定器完整保留了 tcmalloc 的原始架構。使用 cache 為目前執行線程提供無鎖配置設定,多個 central 在不同線程間平衡記憶體單元複用。在更高層次裡,heap 則管理着大塊記憶體,用以切分成不同等級的複用記憶體塊。快速配置設定和二級記憶體平衡機制,讓記憶體配置設定器能優秀地完成高壓力下的記憶體管理任務。
在最近幾個版本中,編譯器優化卓有成效。它會竭力将對象配置設定在棧上,以降低垃圾回收壓力,減少管理消耗,提升執行性能。可以說,除偶爾因性能問題而被迫采用對象池和自主記憶體管理外,我們基本無須參與記憶體管理操作。
垃圾回收
垃圾回收一直是個難題。早年間,Java 就因垃圾回收低效被嘲笑了許久,後來 Sun 連續收納了好多人和技術才發展到今天。可即便如此,在 Hadoop 等大記憶體應用場景下,垃圾回收依舊捉襟見肘、步履維艱。
相比 Java,Go 面臨的困難要更多。因指針的存在,是以回收記憶體不能做收縮處理。幸好,指針運算被阻止,否則要做到精确回收都難。
每次更新,垃圾回收器必然是核心元件裡修改最多的部分。從并發清理,到降低 STW 時間,直到 Go 的 1.5 版本實作并發标記,逐漸引入三色标記和寫屏障等等,都是為了能讓垃圾回收在不影響使用者邏輯的情況下更好地工作。盡管有了努力,目前版本的垃圾回收算法也隻能說堪用,離好用尚有不少距離。
靜态連結
Go 剛釋出時,靜态連結被當作優點宣傳。隻須編譯後的一個可執行檔案,無須附加任何東西就能部署。這似乎很不錯,隻是後來風氣變了。連着幾個版本,編譯器都在完善動态庫 buildmode 功能,場面一時變得有些尴尬。
暫不說未完工的 buildmode 模式,靜态編譯的好處顯而易見。将運作時、依賴庫直接打包到可執行檔案内部,簡化了部署和釋出操作,無須事先安裝運作環境和下載下傳諸多第三方庫。這種簡單方式對于編寫系統軟體有着極大好處,因為庫依賴一直都是個麻煩
标準庫
功能完善、品質可靠的标準庫為程式設計語言提供了充足動力。在不借助第三方擴充的情況下,就可完成大部分基礎功能開發,這大大降低了學習和使用成本。最關鍵的是,标準庫有更新和修複保障,還能從運作時獲得深層次優化的便利,這是第三方庫所不具備的。
Go 标準庫雖稱不得完全覆寫,但也算極為豐富。其中值得稱道的是 net/http,僅須簡單幾條語句就能實作一個高性能 Web Server,這從來都是宣傳的亮點。更何況大批基于此的優秀第三方 Framework 更是将 Go 推到 Web/Microservice 開發标準之一的位置。
當然,優秀第三方資源也是語言生态圈的重要組成部分。近年來崛起的幾門語言中,Go 算是獨樹一幟,大批優秀作品頻繁湧現,這也給我們學習 Go 提供了很好的參照。