簡介
GO 語言是谷歌在2009年發布的第二款開源編程語言。它專門針對多處理器系統應用程序的編程進行了優化,使用Go編譯的程序可以媲美C或C++代碼的速度,而且更加安全、支持並行執行。
Go 的目標是希望提升現有編程語言對程序庫的依賴性(dependency)的管理,這些軟體元素會被應用程序反覆調用。由於支持並行編程模式,因此這一語言也被設計用來解決需要多處理器完成的任務。
特點
- 簡潔 快速 安全
- 並行 有趣 開源,
- 內存管理,數組安全,編譯迅速
Go 適合用來做什麼
- 伺服器編程,以前你如果使用 C 或者 C++ 做的那些事情,用 Go 來做很合適,例如處理日誌、數據打包、虛擬機處理、文件系統等。
- 分散式系統,資料庫代理器等。
- 網路編程,這一塊目前應用最廣,包括 Web 應用、API 應用。
- 雲平台,目前國外很多雲平台在採用 Go 開發。
如何編寫 Go 代碼
編寫 Go 代碼前,首先有一個概覽:
- Go 程序員通常將他們所有的 Go 代碼保存在一個工作區中。
- 工作區包含許多版本控制存儲庫 (例如,由 Git 管理)。
- 每個存儲庫都包含一個或多個包。
- 每個軟體包由一個目錄中的一個或多個 Go 源文件組成。
- 包的目錄的路徑決定了它的導入路徑。
但注意,這與其他編程環境不同,在這些編程環境中,每個項目都有一個單獨的工作區,工作區與版本控制存儲庫緊密相關。
關於 Go 的工作區:
工作區是一個目錄層次結構,其根目錄包含三個目錄:
- src 包含 Go 源文件,
- pkg 包含包對象
- bin 包含可執行命令。
該 go 工具構建源包並將生成的二進位文件安裝到 pkg 和 bin 目錄。
該 src 子目錄通常包含多個版本控制存儲庫(例如 Git 或 Mercurial),用於跟蹤一個或多個源包的開發。
導入路徑:
一個導入路徑是唯一標識一個包的字元串。程序包的導入路徑對應於其在工作區內或遠程存儲庫中的位置。來自標準庫的軟體包被賦予諸如"fmt"和的短導入路徑 "net/http"。對於你自己的軟體包,你必須選擇一個基本路徑,這個基本路徑不可能與未來添加到標準庫或其他外部庫中相衝突。
第一個 Go 程序:
要編譯並運行一個簡單的程序,首先選擇一個包路徑(我們將使用 github.com/user/hello)並在工作區內創建一個相應的包目錄:
$ mkdir $ GOPATH / src / github.com / user / hello
接下來,創建一個名為hello.go該目錄內的文件,其中包含以下Go代碼。
package main import "fmt" func main() { fmt.Printf("Hello, world.\n") }
現在,您可以使用該go工具構建和安裝該程序:
$ go install github.com/user/hello
請注意,您可以從系統上的任何位置運行此命令。該 go工具通過查找github.com/user/hello指定的工作區內的程序包 來查找源代碼 GOPATH。
Go語音程序例子:
用Go寫成的「hello world」例子:
package main import "fmt" func main() { fmt.Println("Hello, World") }
通過 Go 語言僅需幾行程序碼就完成 HTTP 網頁伺服器的實現:
package main import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello world!") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8000", nil) }
Go 語言的垃圾回收
Go 的垃圾回收在1.5版本之前是採用了標記-清理的方法,即先標記出需要清理的內存,然後清理掉。實際上,標記清除法是一種常見垃圾回收演算法。下面就介紹一下常見的垃圾回收演算法。
常見的垃圾回收(GC)演算法
引用計數法
在每個對象內加入一個整數值,這個對象被引用時加一,從被引用的狀態中解除時減一,然後清理掉引用計數為0的對象。
這種方法的缺陷在於無法處理循環引用,當對象A與B互相持有對方的引用時,無法回收它們。
標記清除法
顧名思義,這個方法分為標記和清除兩步。
標記:從程序的根節點開始,遞歸地遍歷所有的對象以確定所有還在使用的對象,然後標記他們
清除:沒被標記的就全部回收就好了
當然了這個演算法也會有應該缺陷,在發動時必須暫停整個程序,不然發動時一些對象的狀態如果被其他的代碼改變,就可能把這些對象中不該回收的回收掉。而且當對象很多時,會消耗很多時間,讓整個程序暫停的時間太長對用戶體驗會造成極其不好的影響。GO 語言1.5之前使用的是這個演算法。
三色標記法
這種方法是對標記清理法的一種改進,最大的好處就是不再需要暫停程序了。
- 首先建立三個集合:白,灰,黑,之後把所有的對象放入白集合中。
- 從根節點遍歷所有對象,不需要遞歸,遍歷到的對象放入灰集合
- 遍歷灰色集合,被灰集合引用的對象從白集合中移到灰集合中,直到灰集合中沒有任何對象
- 通過 write-barrier 檢測這個過程中對象的變化,有變化時重複上面幾步,當對象沒有變化時,把灰集合中的對象移入黑集合
- 回收白集合中的對象
這個演算法的缺陷就在於,如果程序中垃圾產生的速度大於清理的速度,就會讓垃圾無法被清理,這個演算法應用於 GO 1.5和 GO 1.6
分代收集法
這個方法也是對標記清理法的一種改進,因為絕大多數對象的生命周期都很短,所以按照它們的生命周期來分代,一般來說是分為三代的:第0代,第1代,第2代
原理如下:
- 新對象視為第0代
- 當內存用量超過一定程度時(通常很低),對第0代進行標記清理
- 沒被清理掉的第0代對象歸入第1代
- 當內存用量超過一定程度時(通常較高),對第1代進行標記清理
- 以此類推
因為新對象的數量比較少,所以收集時會很快,當內存消耗過大時才觸發1代和2代收集,目前在使用這種演算法的語言(平台)有 jvm , .NET