微職位Golang開發工程師學習分享韓曉東

來源:互聯網
上載者:User
18年5月份接觸了51CTO推出的微職位Go課程,對Golang十分喜愛。通過張長志老師的視頻講解,前後4個月的學習時間。也用Golang寫了些簡單的代碼和例子,其中包括業餘時間的,也有項目中的。今天寫點Golang相關的總結,僅供各位同學參考。

特性少,文法簡單。GO是崇尚極簡主義的,提倡少即是多。這點在它的Spec上尤其凸顯,一下午的時間絕對可以看完。GO的特性很少,很多GO的使用者都反饋,GO的關鍵字至少完全可以記在大腦裡。同時它的文法極為簡單,而且語義清晰。

部署方便。GO是一個強型別靜態語言,可以把代碼編譯為本地機器指令。它的RUNTIME是會在編譯時間一起連結到執行檔案中,這也就意味著我們不需要像JAVA那樣裝一個JVM。而且編譯出的執行檔案本身不依賴於其他動態庫,完全可以做到輕鬆的發布。當然,如果你用GO編寫了調用一些動態庫介面的代碼,那麼還是需要根據實際情況來部署這個動態庫的。這點在很多從python/java轉到go的朋友來說,非常喜歡。

有較完善的標準庫並且較為健壯。GO自身帶的標準庫是比較全面的,從檔案歸檔、壓縮、加密、資料庫到資料序列化,字元格式設定化、校正和以及網路程式庫、同步庫等應有盡有。基本上能夠滿足很多基本的需求了。更好的是,這些標準庫的品質都非常高,都很健壯。介面也較為簡單,有清晰的文檔說明。同時隨著這兩年的發展,GO的第三方庫也多了起來,雖然可能沒有像python那麼多,但是較其發展時間來說,還是非常不錯的。

整合測架構。在之前用C++寫代碼時,寫單元測試不是個容易的工作。需要一些技巧和努力才可以做起來。但是在GO中整合了單元測試架構,只要源碼檔案以_test.go結尾,就可以直接通過go test執行單元測試。同時還提供了代碼測試覆蓋率工具,可以很容易實施自動化測試。除此之外,還整合了基準測試架構功能,可以很容易的測量自己寫的函數的運行效率。另外,還有效能剖析器,可以在運行時,測試時剖析程式的瓶頸點,進而可以進行最佳化。

健全的代碼風格與檢查工具。當初學GO的時候,很多文章和書都會提到go fmt這個命令,統一了代碼風格。我覺著這點實在是解決了風格之爭了。帶來的影響就是別人寫的代碼感覺也是自己寫的一樣。還有golint,可以按照go team的風格和要求來寫代碼。還有go vet可以用來檢查一些在GO中很隱形坑。

簡單卻強大的包管理。GO的包管理可能在很多其他語言的包管理看來太弱了,但是在我看來,它解決了我需要的兩個問題,一個是循環相依性問題,GO是拒絕有循環相依性關係的包;二是包的初始化,每個包的檔案都可以實現一個init函數,用來在匯入時執行。這點在分工合作時非常有用。

容易編寫跨平台代碼。如果你用純GO,不牽扯到CGO的話,你可以非常容易的做到跨平台。只需要在檔案尾碼.go前,引入_linux,_windows,_x86,_x64等字元為檔案名稱首碼的結尾就可以做到只在對應的平台中編譯。GO還有build constraints控制碼在什麼條件下編譯。如果你用到了CGO,就牽扯到了C的跨平台問題,所以稍微麻煩那麼一些,但是問題也不是太大。

記憶體回收。GC的存在極大的降低了並發代碼的編寫,而且還提供了程式的健壯性。做為一個從C/C++做起,有過驅動開發經驗的程式員來說,GC這個東西是我一直沒有涉獵過的。對我來說GC就等於噩夢。但是當我開始試著接受GC時發現,GC真的是解決了程式員的生產力,極大的提高了效率。雖然目前來說GO已經1.4版本了,但是GC還算不得上優秀,按照GO的路線圖,後面會有更優秀的GC實現添加進來。

介面與struct。在第一次學習GO的interface的時候,我第一反應是這就是我想要的。雖然很多人也在說GO的這個interface的不好,而且說的很有道理,比如老趙的《為什麼我不喜歡GO語言式的介面》。interface可以通過組合擴充為新的interface,struct也可以通過組合擴充為新的struct。沒有繼承,只有組合。可以通過匿名組合達到類似繼承的效果。可以對interface進行查詢,有點類似COM的味道,但是文法層面上更為簡單。struct到interface的映射是隱式的,不需要聲明某個struct實現了某個interface。雖然可能會出現名字上的衝突,但是可以通過wrapper進行解決。這種interface的另外一個好處是單元測試時很容易實現MOCK,這點非常喜歡。也可以看這篇文章《Go interfaces make test stubbing easy》

統一的工作布局。GO定義了項目的目錄結構,比如bin目錄,pkg目錄以及src目錄。這個和我日常的項目布局是一致的。之前用C++開發時我們也是如此安排布局,所以就這點來說,我覺著容易過渡。

內建的並發原語。提到GO就不得不提到goroutine和channel。廉價的goroutine可以讓我們歡快的處理非同步任務,channel可以用來交換資料。藉助goroutine,可以很容易的實現高效能的服務端。goroutine及其調度器可以很容易和EPOLL,IOCP等系統機制結合起來,再通過Half Sync/Half Async模式,很容易在文法層面上達到同步形式,卻不失效能。

GO標準庫中還提供了sync包,其中有基本的mutex說,還有RMutex這樣的讀寫鎖,還有Once,WaiterGroup等東西。基本滿足日常中對鎖的需求了。

GO為了協助程式員解決在並發時經常遇到的race condition問題,還提供了相應的race condition工具。還有相應的死結偵查工具。

雖然GO社區有個slogan:"do not communicate by sharing memory; instead, share memory by communicating.",但是每個goroutine之間並不是完全獨立的,一樣可以做到通過記憶體共用資料。這個時候只能依靠程式員自己去遵守了。而且因為goroutine不是完全獨立,panic這種東西就可能會導致整個程式掛掉。這點和Erlang比起來確實不是很好。

蛋疼的defer。用習慣了C++的RAII後,十分反感GO的defer機制,但是有的時候又不得不用。原因就是這個defer不是block層級的,而是函數層級的,需要在函數返回前才得到執行。所以這就會導致在處理一些類似於檔案開啟,操作再關閉的邏輯時非常蛋疼,回到了C的年代,必須手動去Close。

蛋疼的panic。雖然我在C++下不怎麼用異常,但是對於panic這個設計我表示非常的不滿意啊。因為它會影響全域。而要捕捉panic就需要用defer。如果panic只是讓當前goroutine掛掉我覺著就嗨皮壞了。

沒有泛型。GO沒有泛型帶來的蛋疼地方是,要麼就用interface{}來做運行時泛型,要麼就自己手動寫代碼產生器。比如我自己為了產生網路通訊協定序列化代碼就擼了一個產生器。而且因為沒有泛型,想實作類別似C++ STL的容器與演算法基本沒太可能,當然方法還是有的,繼續使用代碼產生器。而且GO1.4乾脆引入了一個叫go generate的命令。

總結
GO裡面其他一些內建的資料結構,比如slice,map等,但這些也是詬病,因為它又沒給予程式員可以享用range關鍵字的福利。

在GO的所有特性裡,最喜歡就是GC,goroutine,channel以及interface。而其餘的特性(比如上面我列舉的很多特性)我覺著都不是太重要,其中很多都可以在工程中實踐,和語言本身沒有太大關係。

總結下來,這東西就是一個工程工具,各種好用,但是從設計角度講各種粗糙,沒必要過度高估。它算的上工程實踐中的好朋友。在寫服務端時,它是把利器,至少在寫服務端程式時,我自己感覺如此。

有朋友說一個語言好不好就看它有沒有開拓你的眼界,給予你新的思想,我想至少GO在這點上滿足了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.