成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

go語言接口布局圖 go語言 接口

Go語言中恰到好處的內(nèi)存對(duì)齊

在開始之前,希望你計(jì)算一下 Part1 共占用的大小是多少呢?

建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁設(shè)計(jì)師等,應(yīng)用各種網(wǎng)絡(luò)程序開發(fā)技術(shù)和網(wǎng)頁設(shè)計(jì)技術(shù)配合操作的協(xié)同工作。創(chuàng)新互聯(lián)專業(yè)提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁設(shè)計(jì),網(wǎng)站制作(企業(yè)站、自適應(yīng)網(wǎng)站建設(shè)、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗(yàn)的提升,我們力求做到極致!

輸出結(jié)果:

這么一算, Part1 這一個(gè)結(jié)構(gòu)體的占用內(nèi)存大小為 1+4+1+8+1 = 15 個(gè)字節(jié)。相信有的小伙伴是這么算的,看上去也沒什么毛病

真實(shí)情況是怎么樣的呢?我們實(shí)際調(diào)用看看,如下:

輸出結(jié)果:

最終輸出為占用 32 個(gè)字節(jié)。這與前面所預(yù)期的結(jié)果完全不一樣。這充分地說明了先前的計(jì)算方式是錯(cuò)誤的。為什么呢?

在這里要提到 “內(nèi)存對(duì)齊” 這一概念,才能夠用正確的姿勢去計(jì)算,接下來我們?cè)敿?xì)的講講它是什么

有的小伙伴可能會(huì)認(rèn)為內(nèi)存讀取,就是一個(gè)簡單的字節(jié)數(shù)組擺放

上圖表示一個(gè)坑一個(gè)蘿卜的內(nèi)存讀取方式。但實(shí)際上 CPU 并不會(huì)以一個(gè)一個(gè)字節(jié)去讀取和寫入內(nèi)存。相反 CPU 讀取內(nèi)存是 一塊一塊讀取 的,塊的大小可以為 2、4、6、8、16 字節(jié)等大小。塊大小我們稱其為 內(nèi)存訪問粒度 。如下圖:

在樣例中,假設(shè)訪問粒度為 4。 CPU 是以每 4 個(gè)字節(jié)大小的訪問粒度去讀取和寫入內(nèi)存的。這才是正確的姿勢

另外作為一個(gè)工程師,你也很有必要學(xué)習(xí)這塊知識(shí)點(diǎn)哦 :)

在上圖中,假設(shè)從 Index 1 開始讀取,將會(huì)出現(xiàn)很崩潰的問題。因?yàn)樗膬?nèi)存訪問邊界是不對(duì)齊的。因此 CPU 會(huì)做一些額外的處理工作。如下:

從上述流程可得出,不做 “內(nèi)存對(duì)齊” 是一件有點(diǎn) "麻煩" 的事。因?yàn)樗鼤?huì)增加許多耗費(fèi)時(shí)間的動(dòng)作

而假設(shè)做了內(nèi)存對(duì)齊,從 Index 0 開始讀取 4 個(gè)字節(jié),只需要讀取一次,也不需要額外的運(yùn)算。這顯然高效很多,是標(biāo)準(zhǔn)的 空間換時(shí)間 做法

在不同平臺(tái)上的編譯器都有自己默認(rèn)的 “對(duì)齊系數(shù)”,可通過預(yù)編譯命令 #pragma pack(n) 進(jìn)行變更,n 就是代指 “對(duì)齊系數(shù)”。一般來講,我們常用的平臺(tái)的系數(shù)如下:

另外要注意,不同硬件平臺(tái)占用的大小和對(duì)齊值都可能是不一樣的。因此本文的值不是唯一的,調(diào)試的時(shí)候需按本機(jī)的實(shí)際情況考慮

輸出結(jié)果:

在 Go 中可以調(diào)用 unsafe.Alignof 來返回相應(yīng)類型的對(duì)齊系數(shù)。通過觀察輸出結(jié)果,可得知基本都是 2^n ,最大也不會(huì)超過 8。這是因?yàn)槲沂痔幔?4 位)編譯器默認(rèn)對(duì)齊系數(shù)是 8,因此最大值不會(huì)超過這個(gè)數(shù)

在上小節(jié)中,提到了結(jié)構(gòu)體中的成員變量要做字節(jié)對(duì)齊。那么想當(dāng)然身為最終結(jié)果的結(jié)構(gòu)體,也是需要做字節(jié)對(duì)齊的

接下來我們一起分析一下,“它” 到底經(jīng)歷了些什么,影響了 “預(yù)期” 結(jié)果

在每個(gè)成員變量進(jìn)行對(duì)齊后,根據(jù)規(guī)則 2,整個(gè)結(jié)構(gòu)體本身也要進(jìn)行字節(jié)對(duì)齊,因?yàn)榭砂l(fā)現(xiàn)它可能并不是 2^n ,不是偶數(shù)倍。顯然不符合對(duì)齊的規(guī)則

根據(jù)規(guī)則 2,可得出對(duì)齊值為 8?,F(xiàn)在的偏移量為 25,不是 8 的整倍數(shù)。因此確定偏移量為 32。對(duì)結(jié)構(gòu)體進(jìn)行對(duì)齊

Part1 內(nèi)存布局:axxx|bbbb|cxxx|xxxx|dddd|dddd|exxx|xxxx

通過本節(jié)的分析,可得知先前的 “推算” 為什么錯(cuò)誤?

是因?yàn)閷?shí)際內(nèi)存管理并非 “一個(gè)蘿卜一個(gè)坑” 的思想。而是一塊一塊。通過空間換時(shí)間(效率)的思想來完成這塊讀取、寫入。另外也需要兼顧不同平臺(tái)的內(nèi)存操作情況

在上一小節(jié),可得知根據(jù)成員變量的類型不同,其結(jié)構(gòu)體的內(nèi)存會(huì)產(chǎn)生對(duì)齊等動(dòng)作。那假設(shè)字段順序不同,會(huì)不會(huì)有什么變化呢?我們一起來試試吧 :-)

輸出結(jié)果:

通過結(jié)果可以驚喜的發(fā)現(xiàn),只是 “簡單” 對(duì)成員變量的字段順序進(jìn)行改變,就改變了結(jié)構(gòu)體占用大小

接下來我們一起剖析一下 Part2 ,看看它的內(nèi)部到底和上一位之間有什么區(qū)別,才導(dǎo)致了這樣的結(jié)果?

符合規(guī)則 2,不需要額外對(duì)齊

Part2 內(nèi)存布局:ecax|bbbb|dddd|dddd

通過對(duì)比 Part1 和 Part2 的內(nèi)存布局,你會(huì)發(fā)現(xiàn)兩者有很大的不同。如下:

仔細(xì)一看, Part1 存在許多 Padding。顯然它占據(jù)了不少空間,那么 Padding 是怎么出現(xiàn)的呢?

通過本文的介紹,可得知是由于不同類型導(dǎo)致需要進(jìn)行字節(jié)對(duì)齊,以此保證內(nèi)存的訪問邊界

那么也不難理解,為什么 調(diào)整結(jié)構(gòu)體內(nèi)成員變量的字段順序 就能達(dá)到縮小結(jié)構(gòu)體占用大小的疑問了,是因?yàn)榍擅畹販p少了 Padding 的存在。讓它們更 “緊湊” 了。這一點(diǎn)對(duì)于加深 Go 的內(nèi)存布局印象和大對(duì)象的優(yōu)化非常有幫

【接口測試】Go語言進(jìn)行簡單的接口測試

在正常的測試中,當(dāng)我們需要進(jìn)行接口測試時(shí),通常使用接口調(diào)試工具,如postman進(jìn)行接口測試

目前我在嘗試使用Go語言進(jìn)行接口測試,使用的庫均為Go自帶的庫。

注:當(dāng)前采用的接口為時(shí)事新聞接口,每天可以請(qǐng)求100次,需要的同學(xué),可以自行使用。

go語言接口在一個(gè)包里,其他的包想實(shí)現(xiàn),怎么做啊?

在 Go 語言中,如果一個(gè)接口在一個(gè)包里,其他包要實(shí)現(xiàn)該接口,需要遵循下列步驟:

1. 定義接口:

假設(shè)接口定義在 `foo` 包中:

go

package foo

type MyInterface interface {

MyMethod() string

}

2. 實(shí)現(xiàn)接口:

定義一個(gè)新的類型 `Bar`,并為其實(shí)現(xiàn) `foo.MyInterface` 接口:

go

package bar

import "your-package/foo"

type Bar struct {

// ...

}

func (b Bar) MyMethod() string {

// implement method

return "bar"

}

在這里,需要導(dǎo)入 `foo` 包,并定義一個(gè) `Bar` 類型,為其實(shí)現(xiàn) `foo.MyInterface` 接口,這樣就完成了在不同包中實(shí)現(xiàn)接口的目標(biāo)。

如果在其他包中使用 `Bar`,需要先導(dǎo)入 `bar` 包,然后聲明 `Bar` 實(shí)例,并將其轉(zhuǎn)換為 `foo.MyInterface`,然后就可以調(diào)用 `MyMethod` 方法了:

go

import "your-package/bar"

func main() {

var myInterface foo.MyInterface = new(bar.Bar)

myInterface.MyMethod()

}

在這里,我們定義了一個(gè) `myInterface` 實(shí)例,將其類型聲明為 `foo.MyInterface`,并將其初始化為 `new(bar.Bar)`。這允許我們調(diào)用 `MyMethod` 方法,這個(gè)方法實(shí)際上是由 `bar.Bar` 類型實(shí)現(xiàn)的。

總結(jié)起來,在其他包中使用其它包的接口,需要實(shí)現(xiàn)接口的包定義一個(gè)新的類型,并完成接口的實(shí)現(xiàn),另一個(gè)使用接口的包需要導(dǎo)入實(shí)現(xiàn)包的路徑,并將接口轉(zhuǎn)換成實(shí)現(xiàn)類型。

標(biāo)題名稱:go語言接口布局圖 go語言 接口
網(wǎng)頁網(wǎng)址:http://jinyejixie.com/article14/ddcdhge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、定制網(wǎng)站、動(dòng)態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)
永春县| 卓尼县| 玛纳斯县| 洛浦县| 呼伦贝尔市| 丹凤县| 尉氏县| 新泰市| 县级市| 涞水县| 保康县| 资兴市| 汝州市| 巨鹿县| 江川县| 股票| 会泽县| 平潭县| 塔城市| 华安县| 安龙县| 孟连| 上虞市| 峨山| 三河市| 绥芬河市| 开阳县| 温宿县| 萨迦县| 盐源县| 甘泉县| 淳安县| 井冈山市| 定远县| 拉萨市| 开江县| 哈巴河县| 盘山县| 资溪县| 罗源县| 福海县|