1. 程式人生 > >我為什麽選擇go語言

我為什麽選擇go語言

pro slice 高質量 流行 shee 道理 多人 異常機制 約束

這裏。我並不打算引起語言爭論的口水仗,我並非什麽大牛,對語言的造詣也不深。僅僅是想通過自己實際的經歷,來說說為什麽我在項目中選擇go。

其它語言的經歷

C++

在接觸go之前,我已經有多年的c++開發經驗。

主要用在遊戲服務端引擎開發以及P2P上面,那可是一段痛並快樂的時期,以至於我看到不論什麽的程序釘子問題都認為能夠用c++這把錘子給敲定。

可是對於互聯網項目開發來說。除非你的團隊總體的c++技術水平nb,並且有非常強的代碼規範,不然真可能是一場災難,更別說我們現有團隊差點兒沒其它人會這玩意了。

本來,我打算在現有項目中的推送系統中使用c++,並用業余時間寫好了一個網絡底層庫libtnet,但後來還是決定打住,由於沒有人能夠協助我開發。令我比較欣慰的是,libtnet有一個遊戲公司在使用,現處於內部測試階段。即將放出去,我倒是非常期待他們的好消息。

Lua

在做遊戲的過程中。我也學會了lua這門語言,並且還有幸接觸並完好了雲風在Lua 不是 C++中提到的那個恐怖的lua,c++粘合層。

lua真的是一門非常好的語言,性能高,開發高速。不光遊戲公司大量使用。在互聯網領域,由於openresty的流行,一些公司(包含我們)也開始在web端使用lua進行開發。

(頗為自豪的是還給openresty反饋過幾個bug)

可是。lua由於太短小精悍,功能庫並不多。非常多須要自己去實現,並且,寫出高性能。高質量lua代碼也並非非常easy的事情。

另外,由於其動態語言的特性,我們也栽了不少坑,這個興許在詳說。

Python

在我來現有的團隊之前。他們就已經使用python進行整個系統的開發,甚至包含clientGUI(這對client童鞋當時就是一個災難,後來換成Qt就舒爽了)。

python的優點不必說,從數不清的公司用它進行開發就知道。庫非常豐富,代碼簡潔,開發迅速。

可是,在項目中經過兩年多python開發之後,我們漸漸出現了非常多問題:

  • 性能。python的性能是比較偏低的。對於非常多性能熱點代碼,通常都會採用其它的方式實現。在我們的項目中,須要對不論什麽API調用進行簽名認證。認證服務我們開始使用的是tornado實現,但非常不幸運的是。放到外網並沒有頂住壓力。所以我們引入openresty,將非常多高頻操作實現放到openresty實現。最終頂住了。
  • 部署,python的庫由於太豐富了。所以我們的童鞋引入了非常多的庫。個人感覺我們的童鞋可沒有造輪子的興趣。有時候發版本號的時候,我們會由於忘記安裝一個庫導致程序無法執行。這可能跟我們團隊沒有成熟運維經驗有關,興許通過salt。puppet這種公布工具應該能解決。
  • 質量,通常我們都認為,由於python代碼的簡潔。我們非常easy的能寫出高質量的代碼,可是假設沒有好的代碼控制手段。用python也仍然能寫出渣的代碼,我甚至認為由於其靈活性,可能會更easy寫出爛的代碼。這能夠說是我們團隊的教訓。

這裏,我並沒有噴python的意思,它真的是一門好語言。我能夠通過它高速的構建原型,驗證我的想法。並且還一直在使用。僅僅是在項目中,我們的一些疏忽,導致代碼不可控了,到了不得不重構的地步了。

Why GO?

前面說了我的語言經歷,以及項目到了重構地步的原因,可是為什麽會是go呢?我們能夠有非常多其它的選擇,譬如java,erlang,或者仍然採用python。我認為有非常多因素考量:

  • 靜態,go是一門靜態語言。有著強類型約束。所以我們不太可能出如今python中變量在執行時類型不匹配(譬如int + string)這種runtime error。 在編譯階段就能夠幫我們發現非常多問題。不用等到執行時。(當然。這個靜態語言都能做到)

  • 代碼規範。非常多人都比較反感go強制的編碼規範。譬如花括號的位置。

    但我認為,就由於強制約定,所以大家寫出來的go代碼樣子都幾乎相同,不用費心再去深究代碼樣式問題。

    並且我發現,由於規範統一。我非常easy就能理解別人寫的代碼。

  • 庫支持,go的庫非常豐富,並且能通過go get非常方便的獲取github,google code上面的第三方庫(質量你自己得擔著了)。再不行,用go自己造輪子也是非常方便的,並且造的輪子通常都比較穩定。

  • 開發迅速,不得不說。當你習慣用go開發之後。用go開發功能非常的快。相對於靜態語言c++,開發的效率快的沒話說,我認為比python都不差。並且質量有保證。我們花了不到一個星期進行推送服務核心功能開發,到如今都沒怎麽變動,穩定執行。

  • 部署方便,由於是靜態的。僅僅須要build成一個可執行程序就能夠了。部署的時候直接扔一個文件過去,不須要像python那樣安裝太多的依賴庫。

GO特性

go如今的這個樣子,有些人喜歡。有些人不喜歡,我無法知道為啥google那幫人把go設計成這樣,可是我認為,既然存在,就有道理,我僅僅須要知道什麽該用,什麽不該用就能夠了。

gc

GO提供了gc,這對於c++的童鞋來說,極大的降低了在內存上面犯錯的機會,僅僅是go的gc這個效率還真的不好恭維。比起java來說。還有非常大的提升空間。

所以有時候寫代碼,我們還得依據tuning來提升gc的效率,譬如採用內存池的方式來管理大塊的slice分配,採用no copy的方式來進行string,slice的互轉。

只是go1.3貌似gc性能有了非常大的改善,這點讓我比較期待。

defer

go的defer事實上是一個讓人又愛又恨的東西,對於防止資源泄露,defer可是一個非常不錯的東西,可是濫用defer可是會讓你面臨非常嚴重的內存問題,尤其是像以下的代碼:

for {
    defer func(){
        //do somthing
    }
}

別以為go會在調用完畢defer之後就好好的進行gc回收defer裏面的東西,在我們進行內存profile的時候,發現大量的內存占用都是defer引起的。所以使用起來須要特別慎重。

但我認為,這個go應該會略微改善,在go1.3裏面。也有了對defer的優化。

error

或許error是一個讓人爭議非常大的東西。現代方式的exception那裏去呢?可是我認為error能夠非常明白的告訴使用者該函數會有錯誤返回,假設使用exception,除非文檔足夠具體。我還真不知道哪裏就會蹦出一個異常了。

僅僅是,go又提供了相似exception的defer,panic,recover,這是要鬧哪出。

事實上這篇文章我認為已經解釋的非常好了,go程序的慣例是對外的API使用error,而內部錯誤處理能夠用defer,recover和panic來簡化流程。

事實上這倒跟我一貫的編程準則相應。在團隊在用python進行開發的時候。我們都明白要求庫對外提供的API須要使用返回值來表示錯誤,而在內部能夠使用try,catch異常機制。

interface

go提供了interface來進行抽象編程。何謂接口。最通常的樣例就是鴨子的故事,“當看到一僅僅鳥走起來像鴨子、遊泳起來像鴨子、叫起來也像鴨子,那麽這僅僅鳥就能夠被稱為鴨子“。

在go裏面。interface就是一堆方法的集合,假設某個對象實現了這些方法,那麽該對象能夠就算是該interface。

使用interface,我們能夠非常方便的實現非侵入式編程,進行模塊功能的替換。

對於長時間沈浸c++和python的童鞋來說,一下子要用interface來解決抽象問題,可能會非常不適應。但當習慣之後,你會發現,事實上interface非常的靈活方便。

寫到後面

在使用的時候。我們須要知道go究竟適用在什麽地方,譬如我們如今也就將API服務使用go重構。我們可沒傻到用go去替換openresty。

總之,go是一門非常新的語言。國內也已經有非常多公司開始吃這個螃蟹,也有成功的樣例了,而我們也正開始了這段旅程。

最後在附上曾經給公司同事寫的一個ppt:https://qing.wps.cn/l/b76667b40bdb4b7c91f2b3920a7f4780

我為什麽選擇go語言