go語言簡易存儲(chǔ)數(shù)據(jù)結(jié)構(gòu) go語言構(gòu)造函數(shù)

goland map底層原理

map 是Go語言中基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),在日常的使用中經(jīng)常被用到。但是它底層是如何實(shí)現(xiàn)的呢?

10年積累的成都網(wǎng)站建設(shè)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有永靖免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

總體來說golang的map是hashmap,是使用數(shù)組+鏈表的形式實(shí)現(xiàn)的,使用拉鏈法消除hash沖突。

golang的map由兩種重要的結(jié)構(gòu),hmap和bmap(下文中都有解釋),主要就是hmap中包含一個(gè)指向bmap數(shù)組的指針,key經(jīng)過hash函數(shù)之后得到一個(gè)數(shù),這個(gè)數(shù)低位用于選擇bmap(當(dāng)作bmap數(shù)組指針的下表),高位用于放在bmap的[8]uint8數(shù)組中,用于快速試錯(cuò)。然后一個(gè)bmap可以指向下一個(gè)bmap(拉鏈)。

Golang中map的底層實(shí)現(xiàn)是一個(gè)散列表,因此實(shí)現(xiàn)map的過程實(shí)際上就是實(shí)現(xiàn)散表的過程。在這個(gè)散列表中,主要出現(xiàn)的結(jié)構(gòu)體有兩個(gè),一個(gè)叫 hmap (a header for a go map),一個(gè)叫 bmap (a bucket for a Go map,通常叫其bucket)。這兩種結(jié)構(gòu)的樣子分別如下所示:

hmap :

圖中有很多字段,但是便于理解map的架構(gòu),你只需要關(guān)心的只有一個(gè),就是標(biāo)紅的字段: buckets數(shù)組 。Golang的map中用于存儲(chǔ)的結(jié)構(gòu)是bucket數(shù)組。而bucket(即bmap)的結(jié)構(gòu)是怎樣的呢?

bucket :

相比于hmap,bucket的結(jié)構(gòu)顯得簡單一些,標(biāo)紅的字段依然是“核心”,我們使用的map中的key和value就存儲(chǔ)在這里?!案呶还V怠睌?shù)組記錄的是當(dāng)前bucket中key相關(guān)的“索引”,稍后會(huì)詳細(xì)敘述。還有一個(gè)字段是一個(gè)指向擴(kuò)容后的bucket的指針,使得bucket會(huì)形成一個(gè)鏈表結(jié)構(gòu)。例如下圖:

由此看出hmap和bucket的關(guān)系是這樣的:

而bucket又是一個(gè)鏈表,所以,整體的結(jié)構(gòu)應(yīng)該是這樣的:

哈希表的特點(diǎn)是會(huì)有一個(gè)哈希函數(shù),對(duì)你傳來的key進(jìn)行哈希運(yùn)算,得到唯一的值,一般情況下都是一個(gè)數(shù)值。Golang的map中也有這么一個(gè)哈希函數(shù),也會(huì)算出唯一的值,對(duì)于這個(gè)值的使用,Golang也是很有意思。

Golang把求得的值按照用途一分為二:高位和低位。

如圖所示,藍(lán)色為高位,紅色為低位。 然后低位用于尋找當(dāng)前key屬于hmap中的哪個(gè)bucket,而高位用于尋找bucket中的哪個(gè)key。上文中提到:bucket中有個(gè)屬性字段是“高位哈希值”數(shù)組,這里存的就是藍(lán)色的高位值,用來聲明當(dāng)前bucket中有哪些“key”,便于搜索查找。 需要特別指出的一點(diǎn)是:我們map中的key/value值都是存到同一個(gè)數(shù)組中的。數(shù)組中的順序是這樣的:

并不是key0/value0/key1/value1的形式,這樣做的好處是:在key和value的長度不同的時(shí)候,可 以消除padding(內(nèi)存對(duì)齊)帶來的空間浪費(fèi) 。

現(xiàn)在,我們可以得到Go語言map的整個(gè)的結(jié)構(gòu)圖了:(hash結(jié)果的低位用于選擇把KV放在bmap數(shù)組中的哪一個(gè)bmap中,高位用于key的快速預(yù)覽,用于快速試錯(cuò))

map的擴(kuò)容

當(dāng)以上的哈希表增長的時(shí)候,Go語言會(huì)將bucket數(shù)組的數(shù)量擴(kuò)充一倍,產(chǎn)生一個(gè)新的bucket數(shù)組,并將舊數(shù)組的數(shù)據(jù)遷移至新數(shù)組。

加載因子

判斷擴(kuò)充的條件,就是哈希表中的加載因子(即loadFactor)。

加載因子是一個(gè)閾值,一般表示為:散列包含的元素?cái)?shù) 除以 位置總數(shù)。是一種“產(chǎn)生沖突機(jī)會(huì)”和“空間使用”的平衡與折中:加載因子越小,說明空間空置率高,空間使用率小,但是加載因子越大,說明空間利用率上去了,但是“產(chǎn)生沖突機(jī)會(huì)”高了。

每種哈希表的都會(huì)有一個(gè)加載因子,數(shù)值超過加載因子就會(huì)為哈希表擴(kuò)容。

Golang的map的加載因子的公式是:map長度 / 2^B(這是代表bmap數(shù)組的長度,B是取的低位的位數(shù))閾值是6.5。其中B可以理解為已擴(kuò)容的次數(shù)。

當(dāng)Go的map長度增長到大于加載因子所需的map長度時(shí),Go語言就會(huì)將產(chǎn)生一個(gè)新的bucket數(shù)組,然后把舊的bucket數(shù)組移到一個(gè)屬性字段oldbucket中。注意:并不是立刻把舊的數(shù)組中的元素轉(zhuǎn)義到新的bucket當(dāng)中,而是,只有當(dāng)訪問到具體的某個(gè)bucket的時(shí)候,會(huì)把bucket中的數(shù)據(jù)轉(zhuǎn)移到新的bucket中。

如下圖所示:當(dāng)擴(kuò)容的時(shí)候,Go的map結(jié)構(gòu)體中,會(huì)保存舊的數(shù)據(jù),和新生成的數(shù)組

上面部分代表舊的有數(shù)據(jù)的bucket,下面部分代表新生成的新的bucket。藍(lán)色代表存有數(shù)據(jù)的bucket,橘黃色代表空的bucket。

擴(kuò)容時(shí)map并不會(huì)立即把新數(shù)據(jù)做遷移,而是當(dāng)訪問原來舊bucket的數(shù)據(jù)的時(shí)候,才把舊數(shù)據(jù)做遷移,如下圖:

注意:這里并不會(huì)直接刪除舊的bucket,而是把原來的引用去掉,利用GC清除內(nèi)存。

map中數(shù)據(jù)的刪除

如果理解了map的整體結(jié)構(gòu),那么查找、更新、刪除的基本步驟應(yīng)該都很清楚了。這里不再贅述。

值得注意的是,找到了map中的數(shù)據(jù)之后,針對(duì)key和value分別做如下操作:

1

2

3

4

1、如果``key``是一個(gè)指針類型的,則直接將其置為空,等待GC清除;

2、如果是值類型的,則清除相關(guān)內(nèi)存。

3、同理,對(duì)``value``做相同的操作。

4、最后把key對(duì)應(yīng)的高位值對(duì)應(yīng)的數(shù)組index置為空。

Go語言基礎(chǔ)語法(一)

本文介紹一些Go語言的基礎(chǔ)語法。

先來看一個(gè)簡單的go語言代碼:

go語言的注釋方法:

代碼執(zhí)行結(jié)果:

下面來進(jìn)一步介紹go的基礎(chǔ)語法。

go語言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫,

常用方法:

示例代碼:

執(zhí)行結(jié)果:

更多格式化方法可以訪問中的fmt包。

log包實(shí)現(xiàn)了簡單的日志服務(wù),也提供了一些格式化輸出的方法。

執(zhí)行結(jié)果:

下面來介紹一下go的數(shù)據(jù)類型

下表列出了go語言的數(shù)據(jù)類型:

int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。

常量是在程序編譯時(shí)就確定下來的值,程序運(yùn)行時(shí)無法改變。

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

Go 語言的運(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語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯(lián)用,這里不做介紹。

if語法格式如下:

if ... else :

else if:

示例代碼:

語法格式:

另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。

示例代碼:

執(zhí)行結(jié)果:

下面介紹幾種循環(huán)語句:

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

也可以通過標(biāo)記退出循環(huán):

--THE END--

求 分布式對(duì)象存儲(chǔ) 原理 架構(gòu)及Go語言實(shí)現(xiàn) pdf

分布式存儲(chǔ)架構(gòu)由三個(gè)部分組成:客戶端、元數(shù)據(jù)服務(wù)器和數(shù)據(jù)服務(wù)器??蛻舳素?fù)責(zé)發(fā)送讀寫請(qǐng)求,緩存文件元數(shù)據(jù)和文件數(shù)據(jù)。元數(shù)據(jù)服務(wù)器負(fù)責(zé)管理元數(shù)據(jù)和處理客戶端的請(qǐng)求,是整個(gè)系統(tǒng)的核心組件。數(shù)據(jù)服務(wù)器負(fù)責(zé)存放文件數(shù)據(jù),保證數(shù)據(jù)的可用性和完整性。該架構(gòu)的好處是性能和容量能夠同時(shí)拓展,系統(tǒng)規(guī)模具有很強(qiáng)的伸縮性。

對(duì)象存儲(chǔ)最常用的方案,就是多臺(tái)服務(wù)器內(nèi)置大容量硬盤,再裝上對(duì)象存儲(chǔ)軟件,然后再額外搞幾臺(tái)服務(wù)作為管理節(jié)點(diǎn),安裝上對(duì)象存儲(chǔ)管理軟件。管理節(jié)點(diǎn)可以管理其他服務(wù)器對(duì)外提供讀寫訪問功能。

之所以出現(xiàn)了對(duì)象存儲(chǔ)這種東西,是為了克服塊存儲(chǔ)與文件存儲(chǔ)各自的缺點(diǎn),發(fā)揚(yáng)它倆各自的優(yōu)點(diǎn)。簡單來說塊存儲(chǔ)讀寫快,不利于共享,文件存儲(chǔ)讀寫慢,利于共享。能否弄一個(gè)讀寫快,利 于共享的出來呢。于是就有了對(duì)象存儲(chǔ)。

Go lang制作一個(gè)簡單的區(qū)塊鏈

區(qū)塊鏈?zhǔn)且环N數(shù)據(jù)存儲(chǔ)的結(jié)構(gòu),通過GO語言可以方便的創(chuàng)建一個(gè)區(qū)塊鏈

直接上代碼

1:區(qū)塊接口和方法

2:創(chuàng)建區(qū)塊鏈類和方法

最后測試方法:

測試結(jié)果:

PS F:goblock go run main.go

index: 0

times: 1640488480

PrevHash:

Hash: a91a1da064bd40523be90634584c7c6a23bef44390f855ce8ff671d48b8d9e06

data: 創(chuàng)世區(qū)塊

-----------------------------------

index: 1

times: 1640488481

PrevHash: a91a1da064bd40523be90634584c7c6a23bef44390f855ce8ff671d48b8d9e06

Hash: 28b659f29d8c8564adc23861e2fa2291dd23d14d672f080fa80ab70dcde7c059

data: 交易記錄:1

-----------------------------------

index: 2

times: 1640488482

PrevHash: 28b659f29d8c8564adc23861e2fa2291dd23d14d672f080fa80ab70dcde7c059

Hash: 12b668c4d98cade9d12d651598d302663bcf64435a4e6ed1987cd1d730f324ea

data: 交易記錄:2

-----------------------------------

index: 3

times: 1640488483

PrevHash: 12b668c4d98cade9d12d651598d302663bcf64435a4e6ed1987cd1d730f324ea

Hash: c420f63c9a8f73672f23b353f5fd752dee644e0f764740d090319dacccfa7be6

data: 交易記錄:3

-----------------------------------

index: 4

times: 1640488484

PrevHash: c420f63c9a8f73672f23b353f5fd752dee644e0f764740d090319dacccfa7be6

Hash: ff37f186a13a4871c398869a259f288e4f504c7adcb613172fc7fbfba6488a45

data: 交易記錄:4

-----------------------------------

index: 5

times: 1640488485

PrevHash: ff37f186a13a4871c398869a259f288e4f504c7adcb613172fc7fbfba6488a45

Hash: 0911b845ed602ab4f9c726b3d5dacea6c388c9e0c28db60a4aad62d94720f860

data: 交易記錄:5

-----------------------------------

index: 6

times: 1640488486

PrevHash: 0911b845ed602ab4f9c726b3d5dacea6c388c9e0c28db60a4aad62d94720f860

Hash: 8f0f744d190bf204b4441900df2412d99d613bc030ab607b736c99bf1da451b5

data: 交易記錄:6

-----------------------------------

index: 7

times: 1640488487

PrevHash: 8f0f744d190bf204b4441900df2412d99d613bc030ab607b736c99bf1da451b5

Hash: 3f8181b0570d615bfd0cae38f38813a46413d2ef8f40fc0bd312b7ff93fa57c5

data: 交易記錄:7

-----------------------------------

index: 8

times: 1640488488

PrevHash: 3f8181b0570d615bfd0cae38f38813a46413d2ef8f40fc0bd312b7ff93fa57c5

Hash: 17ca30a31359c73ecd9b7e43319e0736d0d3043f94e541e7b9e19914f192b8ea

data: 交易記錄:8

-----------------------------------

index: 9

times: 1640488489

PrevHash: 17ca30a31359c73ecd9b7e43319e0736d0d3043f94e541e7b9e19914f192b8ea

Hash: becffe7bb98f299739f6205bf16996e73315b5b752765d36ba7fc050de4abe1c

data: 交易記錄:9

-----------------------------------

標(biāo)題名稱:go語言簡易存儲(chǔ)數(shù)據(jù)結(jié)構(gòu) go語言構(gòu)造函數(shù)
網(wǎng)站地址:http://muchs.cn/article34/hheese.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)定制網(wǎng)站、全網(wǎng)營銷推廣、做網(wǎng)站、網(wǎng)站營銷、品牌網(wǎng)站制作

廣告

聲明:本網(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)

網(wǎng)站優(yōu)化排名