真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

豆瓣用go語言重構(gòu)了嗎,豆瓣用go語言重構(gòu)了嗎知乎

為什么許多原本的 Java 項目都試圖用 go 進行重寫開源?

項目推倒重構(gòu)是項目開發(fā)大忌,一方面我們要盡量避免做項目推倒重構(gòu),盡量在前期就規(guī)劃好,另一方面,我們又希望項目能常做小重構(gòu),這對項目可持續(xù)性開發(fā)是很有幫助的。而語言的重構(gòu),把Java項目用Go語言重寫一遍,無疑是一次重大的推倒重來。

10年的瑯琊網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整瑯琊建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)公司從事“瑯琊網(wǎng)站設(shè)計”,“瑯琊網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

一、Go語言的優(yōu)勢在哪里

Go語言領(lǐng)先于Java的最大優(yōu)勢,就在于快。Go語言會被編譯成機器代碼,直接執(zhí)行;Java語言則使用JVM運行其代碼,這比Go語言要慢了很多。另外,Java語言的內(nèi)存管理,相比于Go語言,也復(fù)雜得多,而內(nèi)存管理,不管對于程序運行,還是對程序員的開發(fā),都極為重要。最后,Go語言沒有引用只有指針,這比Java語言處處引用,又領(lǐng)先了一個身位。

二、Go語言為什么更適合開源

開源,也就是開放源代碼,最大的好處在于,可以利用全世界的程序員資源,來幫助你完善你的產(chǎn)品,開發(fā)新需求,或者修復(fù)產(chǎn)品BUG。這對產(chǎn)品的可持續(xù)發(fā)展,是非常有幫助的,很多企業(yè)紛紛將自己的產(chǎn)品開源,其實就是這個道理。而Go語言更易學(xué),更易避錯,更易閱讀等特點,就決定了它更適合用來做開源項目。

三、Java語言的優(yōu)勢

Java語言是目前軟件開發(fā)中使用率最廣泛,也是最重要的程序之一,它的地位,絕對不是目前Go語言可以比擬的。Java在WEB應(yīng)用的開發(fā)中,有著很重要的地位。但是,Java語言相對復(fù)雜的并發(fā)設(shè)計,相當(dāng)龐大的項目體系,使其在開發(fā)、測試階段都略為復(fù)雜,在某些方面已經(jīng)逐步落后于其他語言。

講講go語言的結(jié)構(gòu)體

作為C語言家族的一員,go和c一樣也支持結(jié)構(gòu)體??梢灶惐扔趈ava的一個POJO。

在學(xué)習(xí)定義結(jié)構(gòu)體之前,先學(xué)習(xí)下定義一個新類型。

新類型 T1 是基于 Go 原生類型 int 定義的新自定義類型,而新類型 T2 則是 基于剛剛定義的類型 T1,定義的新類型。

這里要引入一個底層類型的概念。

如果一個新類型是基于某個 Go 原生類型定義的, 那么我們就叫 Go 原生類型為新類型的底層類型

在上面的例子中,int就是T1的底層類型。

但是T1不是T2的底層類型,只有原生類型才可以作為底層類型,所以T2的底層類型還是int

底層類型是很重要的,因為對兩個變量進行顯式的類型轉(zhuǎn)換,只有底層類型相同的變量間才能相互轉(zhuǎn)換。底層類型是判斷兩個類型本質(zhì)上是否相同的根本。

這種類型定義方式通常用在 項目的漸進式重構(gòu),還有對已有包的二次封裝方面

類型別名表示新類型和原類型完全等價,實際上就是同一種類型。只不過名字不同而已。

一般我們都是定義一個有名的結(jié)構(gòu)體。

字段名的大小寫決定了字段是否包外可用。只有大寫的字段可以被包外引用。

還有一個點提一下

如果換行來寫

Age: 66,后面這個都好不能省略

還有一個點,觀察e3的賦值

new返回的是一個指針。然后指針可以直接點號賦值。這說明go默認進行了取值操作

e3.Age 等價于 (*e3).Age

如上定義了一個空的結(jié)構(gòu)體Empty。打印了元素e的內(nèi)存大小是0。

有什么用呢?

基于空結(jié)構(gòu)體類型內(nèi)存零開銷這樣的特性,我們在日常 Go 開發(fā)中會經(jīng)常使用空 結(jié)構(gòu)體類型元素,作為一種“事件”信息進行 Goroutine 之間的通信

這種以空結(jié)構(gòu)體為元素類建立的 channel,是目前能實現(xiàn)的、內(nèi)存占用最小的 Goroutine 間通信方式。

這種形式需要說的是幾個語法糖。

語法糖1:

對于結(jié)構(gòu)體字段,可以省略字段名,只寫結(jié)構(gòu)體名。默認字段名就是結(jié)構(gòu)體名

這種方式稱為 嵌入字段

語法糖2:

如果是以嵌入字段形式寫的結(jié)構(gòu)體

可以省略嵌入的Reader字段,而直接訪問ReaderName

此時book是一個各個屬性全是對應(yīng)類型零值的一個實例。不是nil。這種情況在Go中稱為零值可用。不像java會導(dǎo)致npe

結(jié)構(gòu)體定義時可以在字段后面追加標(biāo)簽說明。

tag的格式為反單引號

tag的作用是可以使用[反射]來檢視字段的標(biāo)簽信息。

具體的作用還要看使用的場景。

比如這里的tag是為了幫助 encoding/json 標(biāo)準(zhǔn)包在解析對象時可以利用的規(guī)則。比如omitempty表示該字段沒有值就不打印出來。

說說這篇我為什么從python轉(zhuǎn)向go

恩看了這篇我為什么從python轉(zhuǎn)向go,

看來作者也是 KSO 輕辦公/企業(yè)快盤團隊的。作為快盤從無到有時期的工程師之一(總是被瀟灑哥說他們改我留下的 bug ),又恰好是

Python/Go 雙修(大霧其實我是 Rust 黨),其實一開始我是拒絕的,duang duang duang,那就隨手寫一點把。

一段段來吧,首先作者說 Python 是動態(tài)語言

python是一門動態(tài)語言,不是強類型系統(tǒng)。對于一個變量,我們有時候壓根不知道它是什么類型,然后就可能出現(xiàn)int + string這樣的運行時錯誤。

在python里面,可以允許同名函數(shù)的出現(xiàn),后一個函數(shù)會覆蓋前一個函數(shù),有一次我們系統(tǒng)一個很嚴重的錯誤就是因為這個導(dǎo)致的。

事實上,如果是靜態(tài)檢查,pylint 和 pyflakes 是可以做這件事的,雖然不能和 go

那種靜態(tài)編譯型語言比,但也足夠了。如果沒記錯的話,阿通當(dāng)年是要求全組都在提交前做靜態(tài)檢查的。我認為這種問題更多的應(yīng)該是人員素質(zhì)上來避免,畢竟蔥頭

也說過,代碼自己寫的就要多回頭看看,看能不能重構(gòu),能不能做更好。不是說偷懶不行,但是從中得出 Python

動態(tài)特性太靈活,Python:怪我咯看

另外,函數(shù)作為第一對象,在 Python 中是 feature,Go 要寫個 mock,簡直虐得不要不要的。

其實這個一直是很多人吐槽python的地方,不過想想,python最開始是為了解決啥問題而被開發(fā)出來的看我們硬是要將他用到高性能服務(wù)器開發(fā)上面,其實也是有點難為它。

如果沒記錯,無論是輕辦公還是快盤,是重 IO 不重 CPU,最大耗時是數(shù)據(jù)塊加密那塊,我在的時候是 Java 寫的。另外高性能服務(wù)器選 Go 也是虐得不要不要的,各種小心翼翼避免 GC。大多數(shù)極端情況下,pypy 的性能足矣勝任了,我認為這不算充分條件。

python的GIL導(dǎo)致導(dǎo)致無法真正的多線程,大家可能會說我用多進程不就完了。但如果一些計算需要涉及到多進程交互,進程之間的通訊開銷也是不得不考慮的。

其實,Python 有宏可以繞開這個 GIL,但是呢架構(gòu)設(shè)計得好其實可以避免的,到異步那塊我會說。

無狀態(tài)的分布式處理使用多進程很方便,譬如處理http請求,我們就是在nginx后面掛載了200多個django server來處理http的,但這么多個進程自然導(dǎo)致整體機器負載偏高。

但即使我們使用了多個django進程來處理http請求,對于一些超大量請求,python仍然處理不過來。所以我們使用openresty,將高頻次的http請求使用lua來實現(xiàn)??蛇@樣又導(dǎo)致使用兩種開發(fā)語言,而且一些邏輯還得寫兩份不同的代碼。

如果推測沒錯,你們現(xiàn)在還在用五年前寫的 Gateway看那個基于 django route

的流量分發(fā)層看四年前我離開的時候已經(jīng)小范圍的使用 Flask+Gevent Demo 測試過了,無論是性能還是負載都比同步模型的 django

有優(yōu)勢。如果還是 django

這套的話,我只能說比較遺憾,畢竟當(dāng)年金山新員工大賽頭牌就是我和幾個小伙伴寫的實時同步在線文檔編輯系統(tǒng),用的就是這套技術(shù)。

因此這是個工程問題,并非語言問題。 Python 提供給了你了這么多工具,硬要選一個傳統(tǒng)的,Old fashion 的,Python:怪我咯看

django的網(wǎng)絡(luò)是同步阻塞的,也就是說,如果我們需要訪問外部的一個服務(wù),在等待結(jié)果返回這段時間,django不能處理任何其他的邏輯(當(dāng)然,多線程的除外)。如果訪問外部服務(wù)需要很長時間,那就意味著我們的整個服務(wù)幾乎在很長一段時間完全不可用。

為了解決這個問題,我們只能不斷的多開django進程,同時需要保證所有服務(wù)都能快速的處理響應(yīng),但想想這其實是一件很不靠譜的事情。

同步模型并非不行,因為 overhead 足夠低,很多業(yè)務(wù)場景下用同步模型反而會取得更好的效果,比如豆瓣。同步模型最大的問題是對于 IO 密集型業(yè)務(wù)等待時間足夠長,這時候需要的不是換語言 ,而是提醒你是不是架構(gòu)要改一下了。

雖然tornado是異步的,但是python的mysql庫都不支持異步,這也就意味著如果我們在tornado里面訪問數(shù)據(jù)庫,我們?nèi)匀豢赡苊媾R因為數(shù)據(jù)庫問題造成的整個服務(wù)不可用。

tornado 是有這個問題,但是 gevent 已經(jīng)解決了。我在 node.js 的某問題下曾經(jīng)回答過,對于 node

而言,能選擇的異步模型只有一個,而 Python 就是太多選擇了。另外 pypy+tornado+redis

可以隨意虐各種長連接的場景,比如我給我廠寫過的一個 push service。

其實異步模型最大的問題在于代碼邏輯的割裂,因為是事件觸發(fā)的,所以我們都是通過callback進行相關(guān)處理,于是代碼里面就經(jīng)常出現(xiàn)干一件事情,傳一個callback,然后callback里面又傳callback的情況,這樣的結(jié)果就是整個代碼邏輯非?;靵y。

這個還真不是,如果說沒有 ES6 的 JavaScript,可能真有 Callback hell,但這是 Python ?。ython

早就實現(xiàn)了左值綁定唉,yield 那姿勢比某些天天吹的語言不知道高到哪里去了,當(dāng)然我說的是完整版的 Python3 yield。即便是不完整的

Python 2 yield 用于異步表達式求值也是完全足夠的,tornado 的 gen.coroutine 啊。

同步形態(tài)寫異步,在 Python 實力強的公司里面早普及了,這是個工程問題,并非語言問題。當(dāng)然把這種事怪在 Python 身上,Python:怪我咯看

python沒有原生的協(xié)程支持,雖然可以通過gevent,greenlet這種的上patch方式來支持協(xié)程,但畢竟更改了python源碼。另外,python的yield也可以進行簡單的協(xié)程模擬,但畢竟不能跨堆棧,局限性很大,不知道3.x的版本有沒有改進。

無論是 Gevent 還是 Greenlet 均沒修改 Python 源碼,事實上這貨已經(jīng)成為了 Py2 coroutine 的標(biāo)準(zhǔn),加上豆瓣開源出來的greenify,基本上所有的庫都可以平滑的異步化,包括 MySQL 等 C 一級的 lib。自從用上這套技術(shù)后,豆瓣的 Python dev 各種爽得不要不要的。

當(dāng)我第一次使用python開發(fā)項目,我是沒成功安裝上項目需要的包的,光安裝成功mysql庫就弄了很久。后來,是一位同事將他整個python目錄打包給我用,我才能正常的將項目跑起來。話說,現(xiàn)在有了docker,是多么讓人幸福的一件事情。

而部署python服務(wù)的時候,我們需要在服務(wù)器上面安裝一堆的包,光是這一點就讓人很麻煩,雖然可以通過puppet,salt這些自動化工具解決部署問題,但相比而言,靜態(tài)編譯語言只用扔一個二進制文件,可就方便太多了。

恰好我又是在開發(fā)基于 docker 的平臺, docker 還真不是用來做部署這事的。首先, Python 是有 virtualenv

這個工具的,事實上對比包管理和包隔離,Python 比 Go 高得不知道哪里去了。Python 跟 Git 談笑風(fēng)生的時候, Go 的 dev

們還得考慮我怎樣才能使得 import 的包穩(wěn)定在一個版本上(當(dāng)然現(xiàn)在有很多第三方方案)。Virtualenv + Pip 完全可以實現(xiàn)

Python 部署自動化,所以這個問題我認為是,工具鏈選取問題。畢竟是個十幾年的老妖怪了,Python

啥情況沒見過啊,各種打包工具任君選擇,強行說 Python 部署不方便,Python:怪我咯看

python非常靈活簡單,寫c幾十行代碼才能搞定的功能,python一行代碼沒準(zhǔn)就能解決。但是太簡單,反而導(dǎo)致很多

同學(xué)無法對代碼進行深層次的思考,對整個架構(gòu)進行細致的考量。來了一個需求,啪啪啪,鍵盤敲完開速實現(xiàn),結(jié)果就是代碼越來越混亂,最終導(dǎo)致了整個項目代碼

失控。

曾經(jīng)知乎有個帖子問 Python 會不會降低程序員編程能力,

我只能說這真的很人有關(guān)。你不去思考深層次的東西怪語言不行是沒道理的,那好,Go 里面 goroutine 是怎么實現(xiàn)的,一個帶 socket 的

goroutine

最小能做到多少內(nèi)存,思考過看任何語言都有自己的優(yōu)勢和劣勢,都需要執(zhí)行者自己去判斷,一味的覺得簡單就不會深入思考這是有問題的。另外,代碼混亂我認為

還是工程上的控制力不夠,豆瓣有超過10W行的 Python 實現(xiàn),雖然不說很完美,大體上做到了不會混亂這么個目標(biāo)。

還有,C 寫幾十行搞定的 Python 一行解決這絕對是重大 feature,生產(chǎn)力啊,人員配置啊,招人培養(yǎng)的成本啊,從工程上來說,Python 在這一塊完全是加分項,不是每個項目都要求極致的并發(fā),極致的效率,做工程很多時候都是要取舍的。

雖然java和php都是最好的編程語言(大家都這么爭的),但我更傾向一門更簡單的語言。而openresty,雖然性

能強悍,但lua仍然是動態(tài)語言,也會碰到前面說的動態(tài)語言一些問題。最后,前金山許式偉用的go,前快盤架構(gòu)師蔥頭也用的go,所以我們很自然地選擇了

go。

Openresty 用 lua 如果按照動態(tài)語言的角度去看,還真算不上,頂多是個簡單點的 C。許式偉走的時候大多數(shù)都是

CPP,蔥頭目前我還不知道他創(chuàng)業(yè)用的是什么寫的,不過他肯定沒語言傾向。當(dāng)年無論是 leo 還是 ufa,一個用 Python 一個用

Java, 他都是從工程實際來選擇使用什么樣的語言。

error,好吧,如果有語言潔癖的同學(xué)可能真的受不了go的語法,尤其是約定的最后一個返回值是error。

這其實是 Go style,無論是 go fmt 還是 error style,Go 其實是想抹平不同工程師之間的風(fēng)格問題。不再為了一個縮進和大括號位置什么的浪費時間。這種方法并不是不好,只是我個人覺得沒 rust 那種返回值處理友善。

GC,java的GC發(fā)展20年了,go才這么點時間,gc鐵定不完善。所以我們?nèi)匀徊荒茈S心所欲的寫代碼,不然在大請求量下面gc可能會卡頓整個服務(wù)。所以有時候,該用對象池,內(nèi)存池的一定要用,雖然代碼丑了點,但好歹性能上去了。

1.4 開始 go 就是 100% 精確 GC 了,另外說到卡頓啊,完全和你怎么用對象有關(guān),能內(nèi)聯(lián)絕不傳引用大部分場景是完全足夠的,這樣 gc 的影響程度會最低。實在想用池……只能說為啥不選 Java。

天生的并行支持,因為goroutine以及channel,用go寫分布式應(yīng)用,寫并發(fā)程序異常的容易。沒有了蛋疼的callback導(dǎo)致的代碼邏輯割裂,代碼邏輯都是順序的。

這是有代價的,goroutine 的內(nèi)存消耗計算(當(dāng)然1.3還是1.4開始得到了很大的改善,內(nèi)存最小值限制已經(jīng)沒了),channel

跨線程帶來的性能損耗(跨線程鎖),還有對 goroutine 的控制力幾乎為 0

等。總之這種嘛,算不上是殺手級特性,大家都有,是方便了一點,但也有自己的弊端。比如我們用 go 吧,經(jīng)常就比較蛋疼 spawn 出去的

goroutine 怎么優(yōu)美的 shutdown,反而有時候把事情做復(fù)雜化了。

性能,go的性能可能趕不上c,c++以及openresty,但真的也挺強悍的。在我們的項目中,現(xiàn)在單機就部署了一個go的進程,就完全能夠勝任以前200個python進程干的事情,而且CPU和MEM占用更低。

我不嚴謹?shù)膶崪y大概 gevent+py2 能達到同樣邏輯 go 實現(xiàn)的 30%~40%,pypy+tornado 能達到

80%~90%,混合了一些計算和連接處理什么的。主要還是看業(yè)務(wù)場景吧,純粹的 CPU bound 當(dāng)然是 go 好,純粹的 IO bound

你就是用 C 也沒用啊。

運維部署,直接編譯成二進制,扔到服務(wù)器上面就成,比python需要安裝一堆的環(huán)境那是簡單的太多了。當(dāng)然,如果有cgo,我們也需要將對應(yīng)的動態(tài)庫給扔過去。

我們現(xiàn)在根據(jù) glibc 所處的 host 版本不同有2套編譯環(huán)境,看上去是部署簡單了,編譯起來坑死你。另外雖然說 disk 便宜,這幾行代碼就幾M了,集群同步部署耗時在某些情況下還真會出簍子。

開發(fā)效率,雖然go是靜態(tài)語言,但我個人感覺開發(fā)效率真的挺高,直覺上面跟python不相上下。對于我個人來說,最好的

例子就是我用go快速開發(fā)了非常多的開源組件,譬如ledisdb,go-mysql等,而這些最開始的版本都是在很短的時間里面完成的。對于我們項目來

說,我們也是用go在一個月就重構(gòu)完成了第一個版本,并發(fā)布。


文章標(biāo)題:豆瓣用go語言重構(gòu)了嗎,豆瓣用go語言重構(gòu)了嗎知乎
URL地址:http://weahome.cn/article/dscpsec.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部