這是一套幫助初學者從0到1學習go語言的開源教程,致力於打造最完整、最強悍、最有深度的Go語言學習體系html
我但願這套課程可以涵蓋Go語言的全部體系、並致力於用大量的案例來詮釋其用法前端
鑑於做者水平有限,真誠地但願可以集全部人的智慧,完善此項目,連接附後python
Go(又稱Golang)是Google開發的一種靜態強類型、編譯型、併發型,並具備垃圾回收功能的編程語言git
Go的最初目標是消除Google軟件開發的緩慢性和笨拙性,從而使流程更具效率和可擴展性,更多的關注於軟件工程領域程序員
Go致力於解決當代大型工程項目面臨的多核處理,網絡系統,海量計算集羣、快速構建等問題,Go在語言級別考慮併發問題,提供簡單高效的併發編程github
羅伯特·格瑞史莫(Robert Griesemer),羅勃·派克(Rob Pike)及肯·湯普遜(Ken Thompson)於2007年9月開始設計Go,稍後Ian Lance Taylor、Russ Cox加入項目golang
Go是基於Inferno操做系統所開發的算法
Go於2009年11月正式宣佈推出,成爲開放源代碼項目,支持Linux、macOS、Windows等操做系統docker
在2016年,Go被軟件評價公司TIOBE 選爲「TIOBE 2016 年最佳語言」數據庫
不少重要的開源項目都是使用Go語言開發的,其中包括 Docker、Go-Ethereum、Thrraform、Kubernetes、etcd、hyperledger、tidb
1960年 Ken Thompson(肯.湯普森) 發明了B語言
1972年 Dennis Ritchie(丹尼斯·裏奇)發明了C語言
1982年 Bjarne Stroustrup(本賈尼)發明了C++語言
1989年 Guido von Rossum 發明了Python語言
1995年SUN公司發明了Java語言
2007年Go語言誕生
2009年的11月對外正式發佈
對語言進行評估時,明白設計者的動機以及語言要解決的問題很重要。Go語言出自 Ken Thompson 和 Rob Pike、Robert Griesemer 之手,他們都是計算機科學領域的重量級人物。
Ken Thompson
貝爾實驗室 Unix 團隊成員,C語言、Unix 和 Plan 9 的創始人之一,在 20 世紀 70 年代,設計並實現了最初的 UNIX 操做系統,僅從這一點說,他對計算機科學的貢獻怎麼強調都不過度。他還與 Rob Pike 合做設計了 UTF-8 編碼方案
Rob Pike
Go語言項目總負責人,貝爾實驗室 Unix 團隊成員,除幫助設計 UTF-8 外,還幫助開發了分佈式多用戶操做系統 Plan 九、Inferno 操做系統和 Limbo 編程語言,並與人合著了《The Unix Programming Environment》,對 UNIX 的設計理念作了正統的闡述
Robert Griesemer
就任於 Google,參與開發 Java HotSpot 虛擬機,對語言設計有深刻的認識,並負責 Chrome 瀏覽器和 Node.js 使用的 Google V8 JavaScript 引擎的代碼生成部分
Go語言有時候被描述爲「C相似語言」,或者是「21世紀的C語言」
Go從C語言繼承了類似的表達式語法、控制流結構、基礎數據類型、調用參數傳值、指針等思想
Go繼承了C語言一直所看中的編譯後機器碼的運行效率以及和現有操做系統的無縫適配
Go語言的家族樹中還有其它的祖先。其中一個有影響力的分支來自Niklaus Wirth所設計的Pascal語言
Modula-2語言激發了包的概念,而後Oberon語言摒棄了模塊接口文件和模塊實現文件之間的區別。第二代的Oberon-2語言直接影響了包的導入和聲明的語法,還有Oberon語言的面向對象特性所提供的方法的聲明語法等
Go語言的另外一支祖先,帶來了Go語言區別其餘語言的重要特性,靈感來自於貝爾實驗室的Tony Hoare於1978年發表的鮮爲外界所知的關於併發研究的基礎文獻順序通訊進程(communicating sequential processes,縮寫爲CSP)
在CSP中,程序是一組中間沒有共享狀態的平行運行的處理過程,它們之間使用管道進行通訊和控制同步。不過Tony Hoare的CSP只是一個用於描述併發性基本概念的描述語言,並非一個能夠編寫可執行程序的通用編程語言
Rob Pike和其餘人開始不斷嘗試將CSP引入實際的編程語言中。他們第一次嘗試引入CSP特性的編程語言叫Squeak,是一個提供鼠標和鍵盤事件處理的編程語言,它的管道是靜態建立的
而後是改進版的Newsqueak語言,提供了相似C語言語句和表達式的語法和相似Pascal語言的推導語法。Newsqueak是一個帶垃圾回收的純函數式語言,它再次針對鍵盤、鼠標和窗口事件管理。在Newsqueak語言中管道是動態建立的,屬於第一等公民,能夠保存到變量中
在Plan9操做系統中,這些優秀的想法被吸取到了一個叫Alef的編程語言中。Alef試圖將Newsqueak語言改造爲系統編程語言,可是由於缺乏垃圾回收機制而致使併發編程很痛苦
注:在Aelf以後還有一個叫Limbo的編程語言,Go語言從其中借鑑了不少特性。具體請參考Pike的講稿:http://talks.golang.org/2012/concurrency.slide#9
Go語言的其餘的一些特性零散地來自於其餘一些編程語言;好比iota語法是從APL語言借鑑,詞法做用域與嵌套函數來自於Scheme語言和其餘不少語言
Go中也有不少創新的設計,好比Go語言的切片爲動態數組提供了有效的隨機存取的性能,還有Go語言新發明的defer語句
全部的編程語言都反映了語言設計者對編程哲學的反思,一般包括以前的語言所暴露的一些不足地方的改進。
簡潔
Go項目是在Google公司維護超級複雜的幾個軟件系統遇到的一些問題的反思(可是這類問題毫不是Google公司所特有的)
正如Rob Pike所說,「軟件的複雜性是乘法級相關的」,經過增長一個部分的複雜性來修復問題一般將慢慢地增長其餘部分的複雜性
經過增長功能、選項、配置是修復問題的最快的途徑,可是這很容易讓人忘記簡潔的內涵,卽使從長遠來看,簡潔依然是好軟件的關鍵因素
簡潔的設計須要在工做開始的時候捨棄沒必要要的想法,而且在軟件的生命週期內嚴格區別好的改變或壞的改變。經過足夠的努力,一個好的改變能夠在不破壞原有完整概念的前提下保持自適應
而一個壞的改變則不能達到這個效果,它們僅僅是經過膚淺的和簡單的妥協來破壞原有設計的一致性。只有經過簡潔的設計,才能讓一個系統保持穩定、安全和持續的進化
附帶了相關的工具和標準庫
沒有隱式的數值轉換
沒有構造函數和析構函數
沒有運算符重載
沒有默認參數
沒有繼承
沒有泛型(go2中考慮加入)
沒有異常,即沒有與錯誤處理相關的控制結構
沒有宏
沒有函數修飾
沒有線程局部存儲。
沒有指針運算
沒有類型別名
數組邊界老是受到檢查
基本特性
自動垃圾回收
包管理
函數做爲一等公民
系統調用接口
只讀的UTF8字符串
函數多返回值
匿名函數和閉包
反射
靜態連接
嚴格的依賴規範
CSP併發編程
Goroutine協程
接口類型
向後兼容
Go語言自己是成熟和穩定的,並且承諾保證向後兼容:用以前的Go語言編寫程序能夠用新版本的Go語言編譯器和標準庫直接構建而不須要修改代碼
類型系統
相比較於js、python,Go語言的類型系統避免動態語言中那些粗心的類型錯誤。可是Go語言的類型系統相比傳統的強類型語言又要簡潔不少,雖然有時候這會致使一個「無類型」的抽象類型的概念
Go語言程序員並不須要像C++或Haskell程序員那樣糾結於具體類型的安全屬性。在實踐中Go語言簡潔的類型系統給了程序員帶來了更多的安全性和更好的運行時性能
Go語言遵循當代計算機系統設計的原則,特別是局部的重要性。Go的內置數據類型和大多數的標準數據結構都通過精心設計而避免顯式的初始化或隱式的構造函數,所以內存分配和內存初始化代碼被隱藏在庫代碼中了
Go語言的聚合類型(結構體和數組)能夠直接操做它們的元素,只須要更少的存儲空間、更少的內存分配,並且指針操做比其餘間接操做的語言也更有效率
併發支持
因爲現代計算機是一個並行的機器,Go語言提供了基於CSP的併發特性支持。Go語言的動態棧使得輕量級線程goroutine的初始棧能夠很小,所以建立一個goroutine的代價很小,建立百萬級的goroutine徹底是可行的。
Go併發的座右銘:不要經過共享內存進行通訊,而要經過通訊共享內存(Don't communicate by sharing memory, share memory by communicating)
自動垃圾回收機制
對於系統語言,垃圾回收多是一個有爭議的功能
Go沒有顯式的內存釋放操做:分配的內存返回池的惟一方法是經過垃圾回收器。
內存管理對語言在實踐中的工做方式具備深遠的影響。在C和C++中,太多的編程工做花費在內存分配和釋放上
因爲垃圾回收機制,語言更易於使用。
垃圾回收會帶來巨大的成本:常規開銷,延遲和實現的複雜性
知識淵博的程序員能夠限制收集器所承受的壓力,從而提升性能。(此外,Go安裝附帶了用於研究正在運行的程序的動態內存性能的良好工具)
自動垃圾回收算法是一個持續跟新的過程、活躍的開發領域
強大的標準庫與規範
Go語言的標準庫,提供了清晰的構建模塊和公共接口,包含I/O操做、文本處理、圖像、密碼學、網絡和分佈式應用程序等,並支持許多標準化的文件格式和編解碼協議
庫和工具使用了大量的約定來減小額外的配置和解釋,從而最終簡化程序的邏輯,並且每一個Go程序結構都是如此的類似,所以Go程序也很容易學習
Go語言自帶工具構建Go語言項目只須要使用文件名、標識符名稱以及少許的註釋肯定全部的庫、可執行文件、測試、基準測試、案例、以及特定於平臺的變量、項目的文檔等;Go語言源代碼自己就包含了構建規範
開源,活躍的社區
組成而不是繼承
Go採用一種不尋常的方法來進行面向對象的編程(接口),它容許有相同方法的任何類型繼承,而不只是類
Go沒有任何形式的基於類型的繼承,這意味着沒有類型層次結構
這是一個故意的設計選擇,儘管類型層次結構已用於構建許多成功的軟件,但Go認爲該模型已被過分使用
學習曲線容易,語法簡單清晰
單就類型和規則而言,Go 與 C9九、C11 類似之處頗多,這也是Go語言被冠以「NextC」名號的重要緣由。
Go語言的語法規則嚴謹,沒有歧義,更沒什麼黑魔法變異用法。
任何人寫出的代碼都基本一致,這使得Go語言簡單易學。放棄部分「靈活」和「自由」,換來更好的維護性
強大的標準庫和工具鏈
完整的工具鏈對於平常開發極爲重要。Go 在此作得至關不錯,不管是編譯、格式化、錯誤檢查、幫助文檔,仍是第三方包下載、更新都有對應的工具
內置完整測試框架,其中包括單元測試、性能測試、代碼覆蓋率、數據競爭,以及用來調優的 pprof,這些都是保障代碼能正確而穩定運行的必備利器
可經過環境變量輸出運行時監控信息,尤爲是垃圾回收和併發調度跟蹤,可進一步幫助咱們改進算法,得到更佳的運行期表現
自動垃圾回收機制
垃圾回收一直是個難題。早年間,Java 就因垃圾回收低效被嘲笑了許久,後來 Sun 連續收納了好多人和技術才發展到今天。可即使如此,在 Hadoop 等大內存應用場景下,垃圾回收依舊捉襟見肘、寸步難行
相比 Java,Go 面臨的困難要更多。因指針的存在,因此回收內存不能作收縮處理。幸虧,指針運算被阻止,不然要作到精確回收都難
每次升級,垃圾回收器必然是核心組件裏修改最多的部分。從併發清理,到下降 STW 時間,直到 Go 的 1.5 版本實現併發標記,逐步引入三色標記和寫屏障等等,都是爲了能讓垃圾回收在不影響用戶邏輯的狀況下更好地工做
靜態連接
運行時、依賴庫直接打包到可執行文件內部,簡化了部署和發佈操做,無須事先安裝運行環境和下載諸多第三方庫
編譯迅速
清晰的依賴關係
併發編程
在早期 CPU 都是以單核的形式順序執行機器指令。Go語言的祖先C語言正是這種順序編程語言的表明
隨着處理器技術的發展,單核時代以提高處理器頻率來提升運行效率的方式遇到了瓶頸,單核 CPU 發展的停滯,給多核 CPU 的發展帶來了機遇
現代計算機都擁有多個核,可是大部分編程語言都沒有有效的工具讓程序能夠輕易利用這些資源。編程時須要寫大量的線程同步代碼來利用多個核,很容易致使錯誤
Go語言正是在多核和網絡化的時代背景下誕生的原生支持併發的編程語言。Go語言從底層原生支持併發,無須第三方庫,開發人員能夠很輕鬆地在編寫程序時決定怎麼使用 CPU 資源
Goroutine 是 Go 最顯著的特徵
Go語言的併發是基於 goroutine 的,goroutine 相似於線程,但並不是線程。能夠將 goroutine 理解爲一種虛擬線程。Go語言運行時會參與調度 goroutine,並將 goroutine 合理地分配到每一個 CPU 中,最大限度地使用 CPU 性能
Go用類協程的方式來處理併發單元,卻又在運行時層面作了更深度的優化處理。這使得語法上的併發編程變得極爲容易
無須處理回調,無須關注線程切換,僅一個關鍵字,簡單而天然
搭配 channel,實現 CSP 模型。將併發單元間的數據耦合拆解開來,各司其職,這對全部糾結於內存共享、鎖粒度的開發人員都是一個可期盼的解脫
內存分配
Go 選擇了 tcmalloc,它本就是爲併發而設計的高性能內存分配組件
刨去因配合垃圾回收器而修改的內容,內存分配器完整保留了 tcmalloc 的原始架構。使用 cache 爲當前執行線程提供無鎖分配,多個 central 在不一樣線程間平衡內存單元複用
heap 則管理着大塊內存,用以切分紅不一樣等級的複用內存塊。快速分配和二級內存平衡機制,讓內存分配器能優秀地完成高壓力下的內存管理任務
Go語言主要用做服務器端開發,適合於多人週期較長的大型軟件和支持雲計算的網絡服務
在服務器編程方面,Go語言適合處理日誌、中間件、數據打包、虛擬機處理、文件系統、分佈式系統、數據庫代理等
網絡編程方面,Go語言普遍應用於 Web 應用、API 應用、下載應用等
此外,Go語言還可用於內存數據庫和雲平臺領域,目前國外不少雲平臺都是採用 Go 開發
因爲Go垃圾回收犧牲了一些性能,所以其不適合作操做系統編程以及對速度要求極致的程序,不適合直接處理數據分析與計算
做爲創造了Go語言的 google 公司,固然會力挺Go語言了。Google 有不少基於 Go 開發的開源項目,好比 kubernets,docker,你們能夠參考《哪些項目使用Go語言開發》一節瞭解更多的Go語言開源項目
Facebook 也在使用Go語言,爲此他們還專門在 Github 上創建了一個開源組織 facebookgo。你們能夠經過 https://github.com/facebookgo 訪問查看 facebook 開源的項目,其中最具表明性的就是著名平滑重啓工具 grace
騰訊
騰訊在 15 年就已經作了 Docker 萬臺規模的實踐。由於騰訊主要的開發語言是 C/C++ ,因此在使用Go語言方面會方便不少,也有不少優點,不過日積月累的 C/C++ 代碼很難改造,也不敢動,因此主要在新業務上嘗試使用 Go
百度
百度主要在運維方面使用到了Go語言,好比百度運維的一個 BFE 項目,主要負責前端流量的接入,其次就是百度消息通信系統的服務器端也使用到了Go語言
七牛雲
七牛雲算是國內第一家選Go語言作服務端的公司。早在 2011 年,當Go語言的語法還沒徹底穩定下來的狀況下,七牛雲就已經選擇將 Go 做爲存儲服務端的主體語言
京東
京東雲消息推送系統、雲存儲,以及京東商城的列表頁等都是使用Go語言開發的
小米
小米對Go語言的支持,在於運維監控系統的開源,它的官方網址是 http://open-falcon.org/。此外,小米互娛、小米商城、小米視頻、小米生態鏈等團隊都在使用Go語言
360
360 對Go語言的使用也很多,好比開源的日誌搜索系統 Poseidon,你們能夠經過 https://github.com/Qihoo360/poseidon 查看,還有 360 的推送團隊也在使用Go語言
除了上面提到的,還有不少公司開始嘗試使用Go語言,好比美團、滴滴、新浪等。
Go語言有一個吉祥物,在會議、文檔頁面和博文中,大多會包含下圖所示的 Go Gopher,這是才華橫溢的插畫家 Renee French 設計的,她也是 Go 設計者之一 Rob Pike 的妻子。