Go語言迎來全迸發時代,未來全面覆蓋程序開發領域丨解讀2015

2021-02-23 InfoQ

2015年,整個IT技術領域發生了許多深刻而又複雜的變化,InfoQ策劃了「解讀2015」年終技術盤點系列文章,希望能夠給讀者清晰地梳理出技術領域在這一年的發展變化,回顧過去,繼續前行。讀者可參照專欄去深入Go語言,也可參照國內Go項目匯總和Go命令教程學習Go語言。

現今,21世紀的第2個十年已經過半,網際網路也真正進入了極速發展的階段。在國內, 大家已經對「雲計算」和「大數據」等名詞耳熟能詳了。在網際網路軟體開發領域,最主流或火爆的技術也無不與之有關。就拿Golang(也可稱為Go語言)來說,它就號稱「雲計算時代的C語言」。Go語言在軟體開發效率和運行效率之間做出了絕佳的權衡。這使得它既適應於網際網路應用的快速開發,又能在高並發、高性能的開發場景中如魚得水。

在2015年,Go語言在服務端程序開發和Web開發領域大放光彩的同時也成功介入到了移動端開發領域。也正因為此,越來越多的創業公司(尤其是網際網路應用和雲計算領域的創業公司)選擇Go語言作為其技術棧的重要組成部分。在國內,據不完全統計,已在生產環境中使用Go語言程序的知名網際網路公司已有百度、美團、360、京東、搜狐、豌豆莢、宜信、微影時代等等,更不用說國內日漸增多的雲計算創業公司了。由此可見,對於廣大的網際網路軟體開發者而言,關注和學習Go語言已經是已經很有必要的事情了。

2016年已經到來,距Google在2012年3月發布的Go 1.0已將近4年。在2015年,Go語言發生了不小的變化。從該年初發布的1.4版本到該年8月下旬發布的1.5版本,Go語言終於完成了自舉的過程,即:幾乎完全用Go語言程序重寫了自己,僅留有少許彙編程序。

Go語言的自舉非常徹底,包括了最核心的編譯器、連結器、運行時系統等。顯然,這是一個很有意義的過程,代表著能力和自信。與此同時,Go語言的運行時性能得到了大幅提升,尤其是在1.5版本完成的並發GC使得Go語言程序在響應時間方面有了質的飛躍。另外,Go語言所支持的作業系統和計算架構越來越多,幾乎涵蓋了現今主流甚至非主流的所有選項。

當然,改變不止如此。下面,我們就列舉幾個比較驚豔的改變,並稍加剖析。

並發的GC

GC,一般認為是garbage collector的縮寫形式,通常被譯為垃圾回收器。不過,它有時候也被看做是garbage collection的縮寫形式,中文譯為垃圾回收。在下文中,當GC被當做動詞用時,指的是垃圾回收。但當GC被當做名詞用時,指的是垃圾回收器。

在1.4以及之前版本的Go語言中,每次GC都會導致完全的「stop the world」(也可稱之為STW)。這意味著在GC期間,Go語言的運行時系統會讓調度器暫停對已啟用的Goroutine的一切調度。也就是說,任何未處於運行狀態的Goroutine都不會被遞交至內核線程和運行,直到當次GC完成。如此暫停的代價不容忽視,對於有高並發需求的程序來說有時會顯得非常棘手。在1.5版本出來之前,Go語言的GC也常常因此被開發者們詬病。

Go 1.5的GC是一個非分代、無轉移的採用標記-清掃算法和三色標記法的並發垃圾回收器。它大刀闊斧地利用各種手段大大縮減了STW的時間。Go語言官方保證,在50毫秒的Go程序運行時間中因GC導致的調度停頓至多只有10毫秒。有了這一保證,相當於為Go程序設定了一個響應時間的上限。對於對響應時間敏感的程序(許多網際網路程序都是如此),這絕對是一個重大利好。當然,如此質的飛躍並不是一蹴而就的。實際上,Go 1.4也為此做了很多鋪墊,比如對Goroutine棧的改造以完全保證GC的標記操作的準確無誤。圖1展示了在最近幾個版本的Go語言中GC的STW時間與內存堆大小的對應關係。

圖1 GC Pause vs. Heap Size

總之,Go 1.5為Go程序開啟了全並發的時代。雖然Go語言官方說當前的GC還可以被進一步優化,但是筆者認為它已不再會成為Go程序性能的瓶頸。

Go語言的亮點之一就是自帶了很多標準工具以幫助開發人員方便地進行Go程序的檢查、格式化、編譯、測試、部署,甚至升級。這些工具已經涵蓋了一個軟體的生命周期的方方面面,極大的方便了Go程序的開發者們。在1.4版本中,Go語言的標準工具集中加入了go generate。顧名思義,這是一個用於生成Go語言代碼的命令。有意思的是,這源於一個幾乎所有的電腦程式研發者們都有過的夢想——讓電腦程式自己編寫程序。go generate命令可以利用YACC(Yet Another Compiler Compiler,一種編譯器的生成器)並根據某種描述文件來生成Go語言代碼。

不過,千萬不要被這句話嚇到。即使我們不懂YACC,甚至對Go語言的AST(Abstract Syntax Tree,譯作抽象語法樹)一無所知,也可以使用go generate命令。比如,我們可以利用go generate命令把一些HTML(Hypertext Markup Language,譯作超文本標記語言)頁面模板文件內置到生成的Go程序代碼文件中(順便說一句,Go語言有自己的HTML頁面模板語法,可用於編寫HTML頁面模板)。這樣就無需在部署用於Web站點的Go程序時攜帶那些額外的文件了。下面展示一小段用於實現此功能的代碼:

程式設計師們應該可以猜到最後一行代碼實際上是一行注釋。實際上,只要有了這行注釋(其中的tpl_loader是筆者寫的一個小工具,也非常的簡單易懂),再在當前代碼包目錄下運行go generate命令,就可以實現上述功能了。在Go語言官方博客中可看到更詳細的說明。

在2015年裡,Go語言在標準工具方面的增進還不止於此。一個更加令人興奮的標準工具——go tool trace——隨著1.5版本的發布而到來。Go程序開發者們可以利用這一工具來圖形化的展示出Go程序的追蹤文件。當然,在展示之前,我們先要通過某種方式生成這樣的文件。Go語言為我們提供了三種用於生成Go程序追蹤文件的方法:通過顯式調用指定的標準庫函數以手動生成、導入指定的標準庫代碼包以使其自動生成,以及在運行程序測試時添加指定標記來生成。此後,當我們運行go tool trace命令並把相應的可執行的Go程序文件和Go程序追蹤文件作為參數以後,就可以在你的默認Web瀏覽器中看到類似下圖的圖形化展示了。

圖2 Go程序追蹤文件的圖形化展示

如圖所示,Go程序追蹤文件可以呈現出對應Go程序的內存使用、Goroutine和內核線程狀態、調度過程等信息。為我們調試Go並發程序提供了非常有力的輔助。

除了上述兩個新增的標準工具之外,Go語言官方也對一些已有的標準工具做了改進,比如:為go build命令和go test命令新增了可用標記以使其更加靈活、增強了go tool vet命令和go doc命令的功能,等等。

Go語言對代碼包的訪問控制的進一步增強始於1.4版本。在1.4版本之前,Go語言對程序實體(包括變量、常量、類型聲明、函數等)採取的是兩級訪問控制策略。程序實體的名稱的第一個字母的大小寫決定了它的可訪問範圍。若為大寫,則該程序實體可以被存在於任何位置的代碼訪問到。我們稱這樣的程序實體是公開的。若為小寫,則該程序實體僅能被存在於當前代碼包的代碼訪問到。我們稱這樣的程序實體是包級私有的。這樣簡明扼要的規則非常容易被記住。

到了Go 1.4時代,第三種訪問控制規則出現。官方稱之為Internalpackages。其含義是,如果代碼包A直接包含了一個名為internal的子代碼包,那麼這個internal包中公開的程序實體僅能被存在於代碼包A及其子代碼包中的代碼訪問到。這相當於使Go程序代碼有了「模塊級」的訪問控制。

不過,在Go 1.4中,這個「模塊級」的訪問控制只是對Go語言源碼和標準庫中的(即<Go語言安裝目錄>/src中的)代碼包有效,而對於其它代碼包則是無效的。也就是說,這是一個過渡階段。為的是讓廣大Go程序開發者有個適應期。到了Go 1.5,由internal代碼包代表的「模塊級私有」訪問控制規則才對所有代碼包有了強制約束力。至此,Go語言擁有了一套完整的三層訪問控制策略。相比於之前的兩層訪問控制策略,它更加靈活和完善。

在1.5版本之前,我們要想實現Go語言程序的跨平臺編譯是相當困難的。雖然因此催生出了幾個開源的輔助工具,但其步驟也依然是相當繁瑣的。其最主要的原因是那時的Go語言編譯工具是由C語言編寫的,是平臺相關的。這裡的平臺相關,是指被編譯後的程序的運行必要條件包含了目標計算機(也就是用於運行該程序的那臺計算機)的作業系統和計算架構。

其中,作業系統的可選項有windows、linux、darwin等,而計算架構的可選項目前有386(即32位計算架構)、amd64(即64位計算架構)和arm(一種基於精簡指令集的計算架構,多用於便攜設備專用CPU)。例如,我們在32位的Windows作業系統下,使用平臺相關的Go語言編譯工具編譯的程序是不能在64位的Linux作業系統下運行的,反之亦然。

我們已經知道,Go 1.5的所有編譯工具和運行時系統都被用Go語言重寫了。這使得這些編譯工具被進行了一系列合併,並且跨越了平臺的界線。例如,之前針對不同計算架構的Go語言編輯器5g、6g和8g被合而為一併命名為compile。隨之而來的優勢就是,我們可以使用這些編譯工具輕而易舉的進行跨平臺的程序編譯操作。

我們只需在程序編譯操作之前設置一下目標計算的作業系統和計算架構。前者通過設置環境變量GOOS來實現,而後者通過設置環境變量GOARCH來實現。例如,當我在64位的Linux作業系統下通過執行如下命令來編譯一個Go源碼文件之後,就可以在32位的Windows作業系統下直接運行那個編譯後的結果文件了。

從Go 1.4開始,開發人員已經可以利用官方擴展庫中的mobile代碼包來編寫Android App了。到了Go 1.5,其對iOS App的支持也已可用。這無疑是一大裡程碑,使人振奮!它使得Go語言的適用領域大大拓展,並壘砌了其在移動網際網路時代甚至物聯網時代的根基。開發者們既可以使用Go語言來構建原生的Android App或iOS App,也可以用它來編寫可被App程序調用的基礎庫。

讀者可以通過官方文檔來了解相關步驟,也可以去看看Go語言的創始人之一Rob Pike為大家編寫的示例App。另外,大家也可以關注Go語言北京用戶組和北京GDG( Google Developer Group - Beijing)聯合主辦的Go語言技術聚會,其中會包括與此有關的Topic。此聚會的時間初定在2016年2月的下旬。

除上述比較突出的變化之外,Go語言在很多地方也做了調整。比如,Goroutine內存棧的增長方式的變更,Goroutine內存棧的初始大小由8K縮減為了2K、GOMAXPROCS的默認值由1變成與當前計算機的CPU核心數一致、Go代碼可以被用於生成動態連結庫了,等等。對於這些調整,筆者就不一一細說了。不過,它們對於Go語言在2015年的精進也都起到了一定的推動作用。

總之,Go語言在2015年的發展迅速且振奮人心。無論在其本身的功能、性能和適用領域上,還是在社區方面(尤其是在中國)都是如此。如果說筆者在著《Go並發編程實戰》這本書的時候還只是建議大家把Go語言作為自己的第一或第二程式語言並以此作為長線技術投資的話,那麼現在我強烈建議所有網際網路軟體開發者都去嘗試並使用Go語言構建他們的(個人或公司的)軟體系統,並真正將其作為手邊的常用工具。

Go語言號稱是雲計算時代的C語言。它也正在持續、快速地向著這一目標前進。如果你也打算跟上後雲計算時代、物聯網時代以及不久就會出現的人工智慧時代的話,那麼就很有必要玩兒轉Go語言了。我相信,它一定不會讓你失望。

在2016年,我們目前可見的Go語言進展就是預計在2月份發布的1.6版本了。在這個版本中,Go語言官方準備重點發展UI庫。這也是Go語言當前的一大短板。在官方的UI庫完全就緒之前,筆者希望大家去關注一下七葉(優秀的國產Go語言IDE——LiteIDE——的作者)的新項目GoQt。此項目就是一個基於QT的Go語言UI庫。鑑於LiteIDE的優秀,我非常看好這個項目。

另外,Go語言在程序測試支持、程序運行分析以及程序調試方面都會有所改進,尤其是後者。實際上,許多不適應使用Go語言開發程序的程式設計師的最大抱怨就是Go語言程序不易調試(不過大家可以去了解下真正的Go語言愛好者是怎樣調試Go程序的)。Go語言官方也在2015年的重大版本升級中對這一方面做出了很多改進。隨之而來的就是Go語言在於各大主流IDE的集成方面所作出的不斷努力。在Go 1.6,這種努力還會繼續。

程序的開發效率與運行效率同樣重要。甚至在某些時候,前者比後者更加重要。這也是許多腳本語言得以生存並繁榮發展的重要原因之一。Go語言的創造者們更是深諳此道。最後,Go語言還會在移動App開發方面進行一步的增強。筆者相信Go語言在這一開發領域一定會有長足的進步的。

在奇點臨近的當下,由於各種智能行動裝置的先天優勢,移動開發需求持續暴漲。我想,大多數網際網路軟體開發團隊(尤其是創業團隊)都會想用儘量精簡的技術棧去支持多方產品的需求。如果能用一種既可快速上手又能高效運維的技術那該有多好。如果你通讀本篇並有所思考,就很可能有與我相同的感受——Go語言就是這樣的一門技術。如果你覺得理由並不充分或想深入了解Go語言,那麼就加入到Go語言社區並切實的感受一下吧。筆者發起的Go語言北京用戶組(微信公眾號:golang-beijing)也歡迎你的加入。

在不久的將來,Go語言一定會實現在程序開發領域的全面覆蓋。到那時,Go程式設計師的含金量也就毋庸置疑了。那麼,我們為什麼不現在就去做如此重要的技術投資或去積極的在內部培養Go開發工程師呢?

作者簡介:郝林,Go語言北京用戶組的發起人,著有圖靈原創圖書《Go並發編程實戰》,同時也是在線免費教程《Go命令教程》和《Go語言第一課》的作者。現在微賽時代擔任平臺研發負責人。


相關焦點

  • Go語言的2017年終總結
    Go 語言的適用範圍一直在不斷地擴大。經過廣大開發者的共同努力,它已開始涉足在當前大熱的數據科學和機器學習領域。雖然還只是開始,但是就像我在《Go 並發編程實戰》第 2 版的扉頁中說的那樣,我「深信 Go 語言在人工智慧時代和機器人時代也能大放異彩」。更令人欣慰的是,中國的開發者對於 Go 語言的流行起著至關重要的作用。在過去的一年裡,我們的熱衷和貢獻依然領跑全世界!
  • Go語言無孔不入的2016:躋身主流程式語言、國內大熱、極速提升、尖端應用……
    2015,Go迎來了全迸發的一年。時隔一年,回頭再看,Go已躋身主流程式語言行列。在國內,Go的熱度更是不凡。2016,對於Go來說,又是怎樣的一年? Go語言已經7歲了!今年8月,Go 1.7如期發布。撰寫本稿時,Go 1.8的測試版也出來了。我們正在熱切盼望著明年2月的Go 1.8正式版。
  • 解讀 Go 語言的 2019:Go 語言不行了嗎?
    作為緊跟時代步伐的軟體開發者,我們還是應該務實一些,多做一些腳踏實地的事情,尤其是在構建底層的基礎設施方面。而 Go 語言正是我們做這類事情時所需要的強大工具。本文是 InfoQ 「解讀 2019 」年終技術盤點系列文章之一。從 TIOBE Index 來看,Go 語言最近在全球的熱度似乎有所下滑。
  • Go 語言基礎入門教程 —— 第一個 Go 程序
    開發工具選擇在本地安裝完 Go 環境之後,需要選擇一個趁手的開發工具來編寫 Go 語言代碼,目前比較流行的開發工具有集成開發環境 GoLand 以及微軟家開源的 Visual Studio Code,使用 VS
  • 為什麼很多公司轉型 Go 語言開發?Go 語言能做什麼
    鑑於Go語言的特點和設計的初衷,Go語言作為伺服器程式語言,很適合處理日誌、數據打包、虛擬機處理、文件系統、分布式系統、資料庫代理等;網絡編程方面,Go語言廣泛應用於Web 應用、API應用、下載應用等;除此之外,Go語言還適用於內存資料庫和雲平臺領域,目前國外很多雲平臺都是採用Go開發。
  • 2020年程式語言趨勢解讀:編程世界之未來握於誰手?
    在整個程序開發行業,程式語言歷經了從面向過程的C、到面向對象的C++、再到兩個改裝版Java和C#區塊鏈行業的程式語言也發生了很大的變化:2018年度,根據德勤報告,應用於以太坊和Hyperledger C++是最青睞的語言,谷歌開發的Go語言則是是第二大區塊鏈開發語言。在2019年程式語言的應用又有哪些趨勢呢?
  • 20 個好用的 Go 語言微服務開發框架
    谷歌決定開源 Go 語言是一個明智之舉。這門語言培育了數千個開源項目,這些項目為你的 Web 項目提供了開箱即用的構建塊。這裡列出了 20 個最有趣的開源項目,用於構建基於 Go 語言的微服務系統。從專注於消息傳遞、路由、錯誤處理或 API 的小工具包,到用於構建 MVC Web 應用程式的更全面的框架,你將發現,使用 Go 語言開發微服務有著非常豐富的選擇。
  • Go 語言實戰:命令行程序(1)
    這往往是因為我們對相應的領域了解不夠,只看到複雜的結果,對如何通向目的地毫無概念。如果了解如何分解任務,到最簡單的步驟為止,還有從最簡單能看到反饋的雛形開始,逐步改善,普通人也能做出複雜的作品,最多時間比有天賦的人多花一些。
  • Go語言簡介
    Go語言的主要開發者有:肯.湯姆遜(Ken Thompson)、羅布.派克(Rob Pike)和羅伯特.格裡澤默(Robert Griesemer)。這三個都是大神,稍介紹一下他們的貢獻: 肯.湯姆遜(Ken Thompson):圖靈獎得主,Uinx發明人,B語言作者(C語言前身),還做飛行員,後來被谷歌挖走。
  • Go VS Java:一位資深程式設計師對兩種語言的解讀
    現在我轉向到基於自然語言處理的開發方向,如Spring Boot、Redis、RabbitMQ、Open NLP還有UIMA等技術。因此說來,我選擇的語言是Java,這個語言一直有旺盛的生命力,寫起程序來也很有意思。開始測試Go!在2017年初,我接到了一個很有意思的項目。
  • 軟體開發大爆炸,被諾基亞錯過的開發工具Qt正迎來智能製造時代
    作為一個完整的、跨平臺的C++圖形用戶界面應用程式開發框架,Qt不僅有著悠久的歷史,也有著其獨特的價值。在當前軟體開發大爆炸時代,Qt最大優勢在於只需編寫一次代碼,就能編譯部署在任何作業系統和硬體上,以及擅長圖形界面開發,如今更擴展到移動及嵌入式設備開發。
  • 活力迸發,未來科技城捷報頻傳!
    未來科技城智慧財產權助力「5G領域高頻覆銅板」項目立項近日,國家知識產權局辦公室公布關於2020年度專利專項研究項目立項名單。未來科技城轄區內企業浙江華正新材料股份有限公司與浙江省科技信息研究院科技諮詢查新中心共同承擔的5G領域高頻覆銅板專利分析研究項目入選。
  • 盤點那些使用 Go 語言的國外公司
    他們使用 Go 的案例可以參考該文:https://go.dev/solutions/mercadolibre/。04 金融科技在金融科技領域,許多客戶對金融數據的需求是 24*7 無間斷。在處理交易和訪問財務數據方面,Go 是一個非常合適的語言。
  • 12張圖解讀2015年IT行業發展
    近日,InfoQ攜手拉勾網發布《2015 IT職業發展白皮書》,從行業招聘的角度深入解讀2015年中國IT行業發展,展望2016。本次報告基於拉勾網提供的10w+網際網路公司數據,以及400w+網際網路從業人員中近200w名程式設計師薪資數據。在IT技術的大舞臺,各個垂直細分的技術領域都能佔據一席之地,但不同的領域有不同的「供需關係」。
  • 5G產業鏈全面解讀!
    本文將圍繞5G的概況、國內外的發展現狀、及中國5G產業鏈市場等方面進行梳理與重點分析,並對未來發展重點領域進行了預測與解讀。來源:中創產業研究院一、5G概述5G,即第五代行動電話行動通信標準,也稱第五代移動通信技術。目前5G技術正在落地中,下載速度預計可達1.25GB/S。
  • Go語言入門教程(一)
    它具有C語言的語法特性,但功能上又具備內存安全,垃圾回收,結構形態和並行計算等特點。對於廣大的開發者的一個福音是go完全開源。在雲原生,雲計算的今天,Go語言又被稱之為雲計算時代的C語言,它誕生的目的是為了讓廣大程式設計師們具有快速的開發效率,因為它專門針對多處理器系統應用應用程式提供了優化。
  • 2015年移動資訊平臺盤點:眾媒時代,聚合成未來
    在眾媒時代,「多媒體共生」升級為「萬物皆媒體」的行業高級形態。這也意味著,每位網際網路用戶都將成為未來媒體在進化中的重要「細胞組織」。而在2015年,各個平臺必須在內容、渠道、產品上尋求突破,為新一輪的進化和蛻變做準備。
  • 安全程序設計語言 | CNCC2021
    程序設計語言作為軟體的表示載體和描述工具,對軟體的開發效率和開發質量起決定性作用。本論壇將討論如下問題:1)如何設計安全的程序設計語言?2)如何提供安全加強的軟體開發環境?3)如何進行安全的編程?其長期從事基於交互式定理證明的程序驗證工具開發,並研究有關程序邏輯特別是分離邏輯的理論問題。曹欽翔是Verified Software Toolchain(VST)工具的主要開發者之一,首次實現了從業務邏輯,到原始碼開發,再到編譯的全鏈條正確性驗證。
  • 【崗位解讀】(48)——網頁(WEB)前端開發工程師
    網頁(WEB)前端開發工程師導語我校2021屆畢業生預計5219人,為更好地讓我校學生充分就業和高質量就業,提高人崗匹配率,就創中心特推出崗位解讀專欄,讓同學們更好地了解崗位職責,所需技能和從業資格等信息,該板塊預計為畢業生推送上百餘個崗位信息解讀,為我校學生順利就業保駕護航。
  • 用Go語言編程的利與弊
    如果你有個名為 thing.go 的文件,請在另一個名為 thing_test.go 的文件中編寫測試,並運行「go test」。Go 就將快速執行這些測試。Go 語言的靜態分析工具眾多且強大。一種特別的工具是 gofmt,它根據 Go 的建議風格對代碼進行格式化。這可以規範項目的許多意見,讓團隊獎經理集中在代碼所做的工作上。