十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
go可以在安卓運(yùn)行的,github.com/golang/mobile,這是用golang做移動(dòng)端開(kāi)發(fā)的庫(kù),
成都創(chuàng)新互聯(lián)基于成都重慶香港及美國(guó)等地區(qū)分布式IDC機(jī)房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動(dòng)大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)聯(lián)通機(jī)房服務(wù)器托管報(bào)價(jià),主機(jī)托管價(jià)格性價(jià)比高,為金融證券行業(yè)服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨(dú)享,G口帶寬及機(jī)柜租用的專業(yè)成都idc公司。
go是靜態(tài)編譯語(yǔ)言,不是腳本語(yǔ)言
在上一篇文章的golang代碼中,函數(shù)add的上一行,增加了一條注釋語(yǔ)句: //go:noinline 。在bpftrace追蹤時(shí),是否可以去掉?有什么作用?
為了說(shuō)明該問(wèn)題,設(shè)計(jì)一個(gè)例子。
golang代碼中,有兩個(gè)求和函數(shù)。其中,add1加上 //go:noinline ,另一個(gè)add2不加。代碼如下:
bpftrace程序分別對(duì)函數(shù)add1和add2的輸入?yún)?shù)、返回值進(jìn)行追蹤,代碼如下:
執(zhí)行程序后,可以看到bpftrace程序能夠正常追蹤到函數(shù)add1,但是無(wú)法追蹤到函數(shù)add2。
通過(guò)上文中的示例代碼,可以看到,沒(méi)有加 //go:noinline 的函數(shù)無(wú)法被bpftrace程序追蹤到。通過(guò)查閱golang相關(guān)文檔,可以知道, //go:noinline 表示該函數(shù)在編譯時(shí),不會(huì)被內(nèi)聯(lián)。
使用 objump -S 生成golang程序的匯編代碼如下:
通過(guò)匯編代碼,我們可以看到,主函數(shù)中,地址 0x498e52 處 callq 498e00 調(diào)用了add1函數(shù),地址 0x498ebb 處 movq $0x4,(%rsp) 直接計(jì)算求值。
因此,golang編譯器在編譯代碼時(shí),會(huì)對(duì)代碼進(jìn)行分析,并按照內(nèi)聯(lián)規(guī)則,將某些函數(shù)生成內(nèi)聯(lián)代碼。一旦函數(shù)被內(nèi)聯(lián),bpftrace將無(wú)法追蹤到對(duì)應(yīng)函數(shù)。也就是,上文中函數(shù) add2 無(wú)法被追蹤到。
針對(duì)golang程序中編譯器內(nèi)聯(lián)的問(wèn)題,可以通過(guò)禁止內(nèi)聯(lián)的方式來(lái)解決。禁止內(nèi)聯(lián)的方式有:
在實(shí)踐中,可以通過(guò) go build -gcflags="-m -m" 來(lái)查看,哪些函數(shù)會(huì)在編譯時(shí)執(zhí)行內(nèi)聯(lián),如:
從輸出中,可以看到:
關(guān)于golang編譯器進(jìn)行內(nèi)聯(lián)的場(chǎng)景,可以參考golang源碼:。
由于golang編譯器內(nèi)聯(lián)優(yōu)化,bpftrace可能無(wú)法正常追蹤golang程序。在編寫bpftrace腳本時(shí),可以先使用 nm 命令查看一下可執(zhí)行程序,是否存在需要追蹤的函數(shù)的符號(hào)信息。如果沒(méi)有則bpftrace將不能對(duì)其進(jìn)行追蹤。
前面的示例中,都是對(duì) int 類型的參數(shù)進(jìn)行追蹤,那對(duì)于 string 類型的參數(shù),是否也可以用同樣的方式進(jìn)行追蹤?將在下一篇中進(jìn)行討論。
本文介紹一些Go語(yǔ)言的基礎(chǔ)語(yǔ)法。
先來(lái)看一個(gè)簡(jiǎn)單的go語(yǔ)言代碼:
go語(yǔ)言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來(lái)進(jìn)一步介紹go的基礎(chǔ)語(yǔ)法。
go語(yǔ)言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問(wèn)中的fmt包。
log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來(lái)介紹一下go的數(shù)據(jù)類型
下表列出了go語(yǔ)言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。
常量是在程序編譯時(shí)就確定下來(lái)的值,程序運(yùn)行時(shí)無(wú)法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語(yǔ)言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。
算術(shù)運(yùn)算符:
關(guān)系運(yùn)算符:
邏輯運(yùn)算符:
位運(yùn)算符:
賦值運(yùn)算符:
指針相關(guān)運(yùn)算符:
下面介紹一下go語(yǔ)言中的if語(yǔ)句和switch語(yǔ)句。另外還有一種控制語(yǔ)句叫select語(yǔ)句,通常與通道聯(lián)用,這里不做介紹。
if語(yǔ)法格式如下:
if ... else :
else if:
示例代碼:
語(yǔ)法格式:
另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語(yǔ)句,不管下一條case語(yǔ)句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語(yǔ)句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過(guò)標(biāo)記退出循環(huán):
--THE END--
1.Docker項(xiàng)目
網(wǎng)址為 。
介紹:Docker是一種操作系統(tǒng)層面的虛擬化技術(shù),可以在操作系統(tǒng)和應(yīng)用程序之間進(jìn)行隔離,也可以稱之為容器。Docker可以在一臺(tái)物理服務(wù)器上快速運(yùn)行一個(gè)或多個(gè)實(shí)例。例如,啟動(dòng)一個(gè)Cent OS操作系統(tǒng),并在其內(nèi)部命令行執(zhí)行指令后結(jié)束,整個(gè)過(guò)程就像自己在操作系統(tǒng)一樣高效。
2.golang項(xiàng)目
網(wǎng)址為 。
介紹:Go語(yǔ)言的早期源碼使用C語(yǔ)言和匯編語(yǔ)言寫成。從Go 1.5版本自舉后,完全使用Go語(yǔ)言自身進(jìn)行編寫。Go語(yǔ)言的源碼對(duì)了解Go語(yǔ)言的底層調(diào)度有極大的參考意義,建議希望對(duì)Go語(yǔ)言有深入了解的讀者讀一讀。
3.Kubernetes項(xiàng)目
網(wǎng)址為 。
介紹:Google公司開(kāi)發(fā)的構(gòu)建于Docker之上的容器調(diào)度服務(wù),用戶可以通過(guò)Kubernetes集群進(jìn)行云端容器集群管理。
4.etcd項(xiàng)目
網(wǎng)址為 。
介紹:一款分布式、可靠的KV存儲(chǔ)系統(tǒng),可以快速進(jìn)行云配置。
5.beego項(xiàng)目
網(wǎng)址為 。
介紹:beego是一個(gè)類似Python的Tornado框架,采用了RESTFul的設(shè)計(jì)思路,使用Go語(yǔ)言編寫的一個(gè)極輕量級(jí)、高可伸縮性和高性能的Web應(yīng)用框架。
6.martini項(xiàng)目
網(wǎng)址為 。
介紹:一款快速構(gòu)建模塊化的Web應(yīng)用的Web框架。
7.codis項(xiàng)目
網(wǎng)址為 Labs/codis。
介紹:國(guó)產(chǎn)的優(yōu)秀分布式Redis解決方案。
8.delve項(xiàng)目
網(wǎng)址為 。
介紹:Go語(yǔ)言強(qiáng)大的調(diào)試器,被很多集成環(huán)境和編輯器整合。