- 博主簡介:努力學(xué)習(xí)的大一在校計算機專業(yè)學(xué)生,熱愛學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:數(shù)據(jù)結(jié)構(gòu)、Go,Java等相關(guān)知識。
- 博主主頁: @是瑤瑤子啦
- 所屬專欄: Go語言核心編程
- 近期目標:寫好專欄的每一篇文章
一、Go語言的誕生
Go 語言從 2009 年 9 月 21 日開始作為谷歌公司 20% 兼職項目,即相關(guān)員工利用 20% 的空余時間來參與 Go 語言的研發(fā)工作。
谷歌的“20%時間”工作方式,允許工程師拿出20%的時間來研究自己喜歡的項目。語音服務(wù)Google Now、谷歌新聞Google News、谷歌地圖Google Map上的交通信息等,全都是20%時間的產(chǎn)物。
該項目的三位領(lǐng)導(dǎo)者均是著名的 IT 工程師:
- Robert Griesemer,參與開發(fā) Java HotSpot 虛擬機;
- Rob Pike,Go 語言項目總負責(zé)人,貝爾實驗室 Unix 團隊成員,參與的項目包括 Plan 9,Inferno 操作系統(tǒng)和 Limbo 編程語言;
- Ken Thompson,貝爾實驗室 Unix 團隊成員,C 語言、Unix 和 Plan 9 的創(chuàng)始人之一,與 Rob Pike 共同開發(fā)了 UTF-8 字符集規(guī)范。
二、Why?——為什么需要Go
存在即合理,新事物的產(chǎn)生有它的道理
在了解為什么我們需要Go之前,我們先了解現(xiàn)有語言可以大致分為兩大類:
2.1:靜態(tài)類型語言、動態(tài)類型語言
首先,語言根據(jù)靜態(tài)和動態(tài)類型分為以下兩類分為以下兩類:
-
靜態(tài)類型語言(Statically Typed Language(強類型語言,編譯語言)
- ??簡介 :在程序編譯時變量的數(shù)據(jù)類型就被確定。且大多數(shù)靜態(tài)語言在編寫代碼時,都要求聲明變量的數(shù)據(jù)類型
- ??特性 :將所有代碼編譯(compile)完成,生成可執(zhí)行文件,再執(zhí)行。
- ??優(yōu)點 :高效: 運行速度快,便于調(diào)試,類型安全,結(jié)構(gòu)規(guī)范
- ??缺點 :每次改動都需要重新編譯,開發(fā)和學(xué)習(xí)效率低
- ??代表語言 :C,C++,Java(半編譯,半解釋),Pascal
???????總結(jié):靜態(tài)類型語言,如C++,執(zhí)行效率高,但編譯、學(xué)習(xí)、開發(fā)效率低
-
動態(tài)語言(弱類型語言
- ??簡介 :程序在運行的時候可以改變其結(jié)構(gòu):新的函數(shù)可以被引進,已有的函數(shù)可以被刪除等在結(jié)構(gòu)上的變化,判斷變量的類型是在程序運行的時候完成的
- ??特性: 變量聲明時無需指定類型,會在該變量第一次將數(shù)據(jù)賦給該變量時,在內(nèi)部記下該數(shù)據(jù)類型。將代碼按行解釋(launch)并允許。
- ??優(yōu)點: 代碼簡潔(不需要寫非常多的類型相關(guān)的代碼)、可以把更多精力放在業(yè)務(wù)邏輯的處理上(完成相同邏輯的程序,使用ruby或者Python類動態(tài)語言所需要的代碼量只有Java實現(xiàn)版本的1/10,相比C/C++差距更大)、更加靈活、易于開發(fā)、學(xué)習(xí)、當有改動時無需重新編譯,直接解釋運行
- ??缺點 :不方便調(diào)試,命名不規(guī)范導(dǎo)致可讀性差、運行速度慢
- ??代表語言 :PHP、Python、JavaScript
???????總結(jié):學(xué)習(xí)、開發(fā)效率高,執(zhí)行效率低
補充:之前學(xué)習(xí)Java的時候,有一個概念是多態(tài),其實本質(zhì)就是一個變量的不同形態(tài)(類型),像靜態(tài)語言,不能給變量賦予不同類型的值,需要采?。豪^承、接口等方式實現(xiàn)多態(tài)。而動態(tài)語言采用dynamic typing,就是說變量在運行期間是可變的,意味著對象的多態(tài)性是與生俱來的
2.2:Go——平衡語言差別
根據(jù)上面分析,
- 傳統(tǒng)語言如靜態(tài)語言C++,學(xué)習(xí)和開發(fā)效率低(命名規(guī)范等等,需要花很多時間取學(xué)習(xí),才能上手一個程序來寫個程序?qū)崿F(xiàn)某個功能),同時編譯花費時間長,編譯效率低(編寫——>編譯——>運行這個完成這個鏈條的周期較長)
- 動態(tài)語言,比如Python,沒有強類型的約束,很多問題在程序運行起來才發(fā)現(xiàn),雖然編寫——>運行,節(jié)省了靜態(tài)語言編譯效率低的問題,但是這種類型相關(guān)的低級錯誤,應(yīng)該交給編譯器來發(fā)現(xiàn)
總之,簡單來說,在Go之前,沒有語言可以兼顧執(zhí)行效率、開發(fā)效率
當然,這只是Go誕生的其中一點
下面列舉Goggle公司創(chuàng)造Go語言的原因:
2.3:為什么Google創(chuàng)造了Go
- 硬件技術(shù)更新快,機器性能大幅提高。目前主流的編程語言落后與硬件,不能合理利用多核多CPU的優(yōu)勢提高軟件性能
- 現(xiàn)有編程語言:風(fēng)格不統(tǒng)一、技術(shù)能力不夠、處理大并發(fā)不夠好。且軟件系統(tǒng)復(fù)雜度高,數(shù)以萬計的代碼,維護成本高,需要足夠簡潔高效的編程語言,提高開發(fā)效率,降低運維成本
- c/c++項目,雖然運行速度快,但編譯速度慢,且存在內(nèi)存泄漏的問題。
- 部署平臺各式各樣,交叉編譯難
- 在執(zhí)行效率、開發(fā)效率上達到平衡
?????♀?為了解決以上問題,Goggle公司就自己造了個輪子——GO
三、Go的優(yōu)點
??Go的主要優(yōu)點
- 編譯速度快
- 執(zhí)行速度快
- 內(nèi)存管理
- 并發(fā)編程(多核CPU
3.1:Go編譯快的原因
??Go的編譯器:
最初設(shè)計團隊的想法是實現(xiàn)Go語言編譯的前端,是基于C的gcc的編譯器來編譯成機器代碼。這個前端編譯器是目前Go的編譯器之一:gccGo
- 上面一行是“編譯器前端”組成部分
- 下面一行是“優(yōu)化”+“編譯器后端”組成部分
在Go的1.5中,Go團隊使用Go編寫了Go的編譯器(叫作自舉),對比與gccgo:1,提高了編譯速度,雖然執(zhí)行速度略有下降;3,增加可編譯平臺
???????C++為什么慢?
C++是也可以用gcc編譯器編譯的,所以從編譯器角度來說,應(yīng)該不是編譯器使Go更快。很大程度是是Go語言的設(shè)計本身
?注意:這里我們比較編譯速度都是比較的靜態(tài)編譯速度
?? Go語言·默認·編譯方式是·靜態(tài)編譯·不依賴任何動態(tài)鏈接庫,可以避免各種動態(tài)鏈接庫依賴的問題;編譯好后,只要平臺是一致的(linux amd64),就可以任意部署,完全不用考慮鏈接庫依賴問題;
?????♂?靜態(tài)編譯&動態(tài)編譯:
-
??靜態(tài)編譯
-
簡介: 編譯器在編譯可執(zhí)行文件時,會把該文件中使用到的鏈接庫提取出來,鏈接打包進可執(zhí)行文件中。編譯之后的結(jié)果只生成一個可執(zhí)行文件。
-
優(yōu)點:不需要管理不同版本庫的兼容問題
-
-
??動態(tài)編譯
- 簡介: 可執(zhí)行文件需要附帶獨立的庫文件,不打包庫到可執(zhí)行文件中,減少可執(zhí)行文件體積,編譯完成,程序執(zhí)行時,執(zhí)行到了,再從庫里面調(diào)用。
- 優(yōu)點:減少內(nèi)存和存儲占用(不同程序共享一個庫)
將外部代碼嵌入到當前生成的可執(zhí)行文件中的就是靜態(tài)編譯,以跳轉(zhuǎn)的方式引用外部代碼的就是動態(tài)編譯
在說回C++為什么慢?
- include頭文件
- 模板編譯
關(guān)于模板編譯:首先,C++的模板使用,是為了支持泛型編程(這篇文章說的很清楚,這里就不重復(fù)造輪子了)??梢钥吹?。編寫不同類型的泛型函數(shù),對于編碼者來說,確實很方便,但是從那篇文章中,也有可能給編譯器增加不必要的編譯負擔(dān):1,代碼膨脹,導(dǎo)致編譯時間變長,2,容易出現(xiàn)模板編譯錯誤,且錯誤信息不易定位
?????♂?優(yōu)化:
-
基于C/C++慢的第一個引入頭文件的問題,后生的語言大部分采用
import module
代替include 頭文件
的方式——Go采用的也是import module
方式(下面是基于C的幾種引入頭文件的對比)-
#include
: include做的事情其實就是簡單的復(fù)制粘貼,將目標.h文件中的內(nèi)容一字不落地拷貝到當前文件中,并替換掉這句include。 -
#import:
實質(zhì)上做的事情和#include是一樣的,只不過OC為了避免重復(fù)引用可能帶來的編譯錯誤(這種情況在引用關(guān)系復(fù)雜的時候很可能發(fā)生,比如B和C都引用了A,D又同時引用了B和C,這樣A中定義的東西就在D中被定義了兩次,重復(fù)了),而加入了#import,從而保證每個頭文件只會被引用一次。
如果想深究,import的實現(xiàn)是通過#ifndef一個標志進行判斷,然后在引入后#define這個標志,來避免重復(fù)引用的 -
PCH(PreCompiled Header):
實質(zhì)上import也還是拷貝粘貼,這樣就帶來一個問題:當引用關(guān)系很復(fù)雜,或者一個頭文件被非常多的實現(xiàn)文件引用時,編譯時引用所占的代碼量就會大幅上升(因為被引用的頭文件在各個地方都被copy了一遍)。
為了解決這個問題,C系語言引入了預(yù)編譯頭文件(PreCompiled Header),將公用的頭文件放入預(yù)編譯頭文件中預(yù)先進行編譯,然后在真正編譯工程時再將預(yù)先編譯好的產(chǎn)物加入到所有待編譯的Source中去,來加快編譯速度。 -
import Modules:
理論上說,想要提高編譯速度,可以把所有頭文件引用都放到pch中。但是這樣面臨的問題是在工程中隨處可用本來不應(yīng)該能訪問的東西,而編譯器也無法準確給出錯誤或者警告,無形中增加了出錯的可能性。Modules相當于將框架進行了封裝,然后加入在實際編譯之時加入了一個用來存放已編譯添加過的Modules列表。如果在編譯的文件中引用到某個Modules的話,將首先在這個列表內(nèi)查找,找到的話說明已經(jīng)被加載過則直接使用已有的,如果沒有找到,則把引用的頭文件編譯后加入到這個表中。這樣被引用到的Modules只會被編譯一次,但是在開發(fā)時又不會被意外使用到,從而同時解決了編譯時間和引用泛濫兩方面的問題。
-
-
基于第二個問題,Go根本沒有將泛型編程納入設(shè)計框架,根本不存在模板編譯帶來的開銷。(不過Go1.18中已經(jīng)支持泛型了)
3.1.2?????總結(jié)
Go編譯速度快的幾個原因
- 使用
import
引用管理方式 - 沒有模板編譯負擔(dān)
- 1.5版本后編譯器的優(yōu)化
- 語言本身關(guān)鍵字很少
3.2:Go的性能
Go的執(zhí)行速度,可以參考一個語言性能測試數(shù)據(jù)網(wǎng)站?? he Computer Language Benchmarks Game。
- Go的性能接近C++
- 算法時間花銷和Java接近,但內(nèi)存花銷遠低于Java
- 和python 對比,時間和內(nèi)存開銷都優(yōu)秀
3.3:并發(fā)編程
上面我們提到,硬件技術(shù)更新快,機器性能大幅提高(eg:多核CPU)。Go語言設(shè)計其實初衷也是為了追平編程語言和硬件之間的差距。Go很多特性都是為了并發(fā)而生(一些語言也支持并發(fā),但是是一些后期庫支持并發(fā)和第三方庫支持并發(fā),這和Go天生并發(fā)的設(shè)計是不同的)
-
Go的并發(fā)量可以比大部分語言里普通的線程實現(xiàn)要
這受益于輕量級的Goroutine,輕量化主要是它所占用的空間要小得多,例如64位環(huán)境下的JVM,它會默認固定為每個線程分配1MB的線程??臻g,而Goroutines大概只有4-8KB,之后再按需分配。足夠輕量化的線程在相同的內(nèi)存下也就可以有更高并發(fā)量(服務(wù)器CPU還沒有飽和的情況下),同時也可以減少很多上下文切換的時間開銷。但是如果你的每個線程占用空間都非常大時(比如10MB,當然這是非常規(guī)需求的情況下),Go的輕量化優(yōu)勢就沒有那么明顯了。
-
語言設(shè)計上支持了并發(fā)
3.3:垃圾回收(GC)
垃圾回收(英語:Garbage Collection,縮寫為GC),在計算機科學(xué)中是一種自動的存儲器管理機制。當一個計算機上的動態(tài)存儲器不再需要時,就應(yīng)該予以釋放,以讓出存儲器,這種存儲器資源管理,稱為垃圾回收。垃圾回收器可以讓程序員減輕許多負擔(dān),也減少程序員犯錯的機會
在使用Go或者其他有垃圾回收機制的語言(如Java),無需像C/C++一樣進行手動釋放內(nèi)存空間(free()/delete
)
- 優(yōu)點:方便
- 限制:
- 暗箱操作的不透明性
- GC處理的性能開銷
- 對于性能要求高的場景,需要進行主動釋放和優(yōu)化(eg:自定義內(nèi)存池)
如果對你有幫助還請:點贊+關(guān)注+收藏
如果文中有不足還請多多指出文章來源:http://www.zghlxwxcb.cn/news/detail-420063.html
關(guān)注我,一起學(xué)習(xí)Golang!文章來源地址http://www.zghlxwxcb.cn/news/detail-420063.html
到了這里,關(guān)于【Golang】三分鐘讓你快速了解Go語言&為什么我們需要Go語言?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!