欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

go語言中uintptr,Go語言中文

golang傳遞接口類型參數(shù)時(shí),什么時(shí)候用指針

因?yàn)?interface 類型本質(zhì)上就是 2 個(gè) uintptr(一個(gè)表示 type 一個(gè)表示 value)。當(dāng)你連 2 個(gè) uintptr 都不想拷貝的時(shí)候,你就會(huì)用到指向 interface 的指針了。

天峨ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

當(dāng)然,你用一個(gè)新的 uintptr 指向另一個(gè) 2 個(gè) uintptr 長度的對(duì)象,也沒省多少事兒

Go語言使用 map 時(shí)盡量不要在 big map 中保存指針

不知道你有沒有聽過這么一句:在使用 map 時(shí)盡量不要在 big map 中保存指針。好吧,你現(xiàn)在已經(jīng)聽過了:)為什么呢?原因在于 Go 語言的垃圾回收器會(huì)掃描標(biāo)記 map 中的所有元素,GC 開銷相當(dāng)大,直接GG。

這兩天在《Mastering Go》中看到 GC 這一章節(jié)里面對(duì)比 map 和 slice 在垃圾回收中的效率對(duì)比,書中只給出結(jié)論沒有說明理由,這我是不能忍的,于是有了這篇學(xué)習(xí)筆記。扯那么多,Show Your Code

這是一個(gè)簡單的測試程序,保存字符串的 map 和 保存整形的 map GC 的效率相差幾十倍,是不是有同學(xué)會(huì)說明明保存的是 string 哪有指針?這個(gè)要說到 Go 語言中 string 的底層實(shí)現(xiàn)了,源碼在 src/runtime/string.go里,可以看到 string 其實(shí)包含一個(gè)指向數(shù)據(jù)的指針和一個(gè)長度字段。注意這里的是否包含指針,包括底層的實(shí)現(xiàn)。

Go 語言的 GC 會(huì)遞歸遍歷并標(biāo)記所有可觸達(dá)的對(duì)象,標(biāo)記完成之后將所有沒有引用的對(duì)象進(jìn)行清理。掃描到指針就會(huì)往下接著尋找,一直到結(jié)束。

Go 語言中 map 是基于 數(shù)組和鏈表 的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,通過 優(yōu)化的拉鏈法 解決哈希沖突,每個(gè) bucket 可以保存 8 對(duì)鍵值,在 8 個(gè)鍵值對(duì)數(shù)據(jù)后面有一個(gè) overflow 指針,因?yàn)橥爸凶疃嘀荒苎b 8 個(gè)鍵值對(duì),如果有多余的鍵值對(duì)落到了當(dāng)前桶,那么就需要再構(gòu)建一個(gè)桶(稱為溢出桶),通過 overflow 指針鏈接起來。

因?yàn)?overflow 指針的緣故,所以無論 map 保存的是什么,GC 的時(shí)候就會(huì)把所有的 bmap 掃描一遍,帶來巨大的 GC 開銷。官方 issues 就有關(guān)于這個(gè)問題的討論, runtime: Large maps cause significant GC pauses #9477

無腦機(jī)翻如下:

如果我們有一個(gè)map [k] v,其中k和v都不包含指針,并且我們想提高掃描性能,則可以執(zhí)行以下操作。

將“ allOverflow [] unsafe.Pointer”添加到 hmap 并將所有溢出存儲(chǔ)桶存儲(chǔ)在其中。 然后將 bmap 標(biāo)記為noScan。 這將使掃描非???,因?yàn)槲覀儾粫?huì)掃描任何用戶數(shù)據(jù)。

實(shí)際上,它將有些復(fù)雜,因?yàn)槲覀冃枰獜腶llOverflow中刪除舊的溢出桶。 而且它還會(huì)增加 hmap 的大小,因此也可能需要重新整理數(shù)據(jù)。

最終官方在 hmap 中增加了 overflow 相關(guān)字段完成了上面的優(yōu)化,這是具體的 commit 地址。

下面看下具體是如何實(shí)現(xiàn)的,源碼基于 go1.15,src/cmd/compile/internal/gc/reflect.go 中

通過注釋可以看出,如果 map 中保存的鍵值都不包含指針(通過 Haspointers 判斷),就使用一個(gè) uintptr 類型代替 bucket 的指針用于溢出桶 overflow 字段,uintptr 類型在 GO 語言中就是個(gè)大小可以保存得下指針的整數(shù),不是指針,就相當(dāng)于實(shí)現(xiàn)了 將 bmap 標(biāo)記為 noScan, GC 的時(shí)候就不會(huì)遍歷完整個(gè) map 了。隨著不斷的學(xué)習(xí),愈發(fā)感慨 GO 語言中很多模塊設(shè)計(jì)得太精妙了。

差不多說清楚了,能力有限,有不對(duì)的地方歡迎留言討論,源碼位置還是問的群里大佬 _

golang 獲取時(shí)間精確能到納秒嗎

這樣。不過只是個(gè)精確到納秒的計(jì)時(shí)器,不是精確到納秒的當(dāng)前時(shí)間。windows好像只能拿到ms精度的當(dāng)前時(shí)間吧,不是很清楚。

package main

import (

"syscall"

"time"

"unsafe"

)

func NewStopWatch() func() time.Duration {

var QPCTimer func() func() time.Duration

QPCTimer = func() func() time.Duration {

lib, _ := syscall.LoadLibrary("kernel32.dll")

qpc, _ := syscall.GetProcAddress(lib, "QueryPerformanceCounter")

qpf, _ := syscall.GetProcAddress(lib, "QueryPerformanceFrequency")

if qpc == 0 || qpf == 0 {

return nil

}

var freq, start uint64

syscall.Syscall(qpf, 1, uintptr(unsafe.Pointer(freq)), 0, 0)

syscall.Syscall(qpc, 1, uintptr(unsafe.Pointer(start)), 0, 0)

if freq = 0 {

return nil

}

freqns := float64(freq) / 1e9

return func() time.Duration {

var now uint64

syscall.Syscall(qpc, 1, uintptr(unsafe.Pointer(now)), 0, 0)

return time.Duration(float64(now-start) / freqns)

}

}

var StopWatch func() time.Duration

if StopWatch = QPCTimer(); StopWatch == nil {

// Fallback implementation

start := time.Now()

StopWatch = func() time.Duration { return time.Since(start) }

}

return StopWatch

}

func main() {

// Call a new stop watch to create one from this moment on.

watch := NewStopWatch()

// Do some stuff that takes time.

time.Sleep(1)

// Call the stop watch itself and it will return a time.Duration

dur := watch()

}

這和語言沒關(guān)系,操作系統(tǒng)要提供這樣的原語。linux和windows都是可以的。

進(jìn)大廠系列02

想進(jìn)大廠,但不知道該如何入手,不妨從先過八股文的題量開始,比如先過個(gè)50題,然后一邊面,一邊學(xué),進(jìn)大廠就只不過是時(shí)間問題了,加油打工人!

本篇一共10題,大概花20分鐘閱讀。

1.golang的switch語句有什么特點(diǎn)?

switch關(guān)鍵字是通過對(duì)比key和case后面的value來選擇需要執(zhí)行的語句,與其他語言比如php和java不同的是,golang的switch默認(rèn)不會(huì)去執(zhí)行下一個(gè)case的語句,除非你顯示的添加了一行fallthough關(guān)鍵字。

2.golang的select當(dāng)有多個(gè)goroutine準(zhǔn)備就緒,它是如何選擇的?

select語句是用來處理與channel IO相關(guān)的邏輯,當(dāng)有多個(gè)channel準(zhǔn)備就緒的時(shí)候,其是偽隨機(jī)選擇一個(gè)goroutine來接收,然后執(zhí)行相關(guān)的語句塊。

Note: select關(guān)鍵字常用于和goroutine超時(shí)相關(guān)的邏輯設(shè)計(jì)。

3.golang什么時(shí)候會(huì)panic?

這里總結(jié)了8種,應(yīng)付面試官應(yīng)該是夠了

4.子協(xié)程出現(xiàn)panic能在父協(xié)程使用recover()捕獲嗎?

不能,只能在子協(xié)程內(nèi)部使用recover()捕獲panic,協(xié)程只能捕獲自己的panic。

5.什么樣的panic不可恢復(fù)

6.defer函數(shù)的執(zhí)行順序是怎么樣的?

7.unsafe.Pointer和uintptr是用來干什么的呢?

在golang中,為了安全性,是不允許指針像C++那樣進(jìn)行類型轉(zhuǎn)換以及計(jì)算的,但是有些場景又必須要這么做怎么辦呢?于是出現(xiàn)了unsafe.Pointer用于指針類型轉(zhuǎn)換,比如*int64可以轉(zhuǎn)換為*int64,出現(xiàn)了uintptr用于指針運(yùn)算。

對(duì)于unsafe.Point有以下幾點(diǎn)性質(zhì):

uintptr官方的定義是

其是用來做指針運(yùn)算的

Note:

第三行的目的是為了獲取age屬性,age屬性在stuct中處于第二列,首先是把student轉(zhuǎn)換成unsafe.Point,獲取指向student的指針,然后再轉(zhuǎn)換成uintptr進(jìn)行指針運(yùn)算,然后通過unsafe.offset獲取student.age相對(duì)于student的偏移量加上student的起始地址就能獲得student.age的起始地址,然后轉(zhuǎn)換成*int類型,就可以讀取age屬性了。

8.常用unsafe.Point和uintptr做什么呢,這么做有什么好處呢?

unsafe.Point常用于操作結(jié)構(gòu)體的私有變量,以及類型轉(zhuǎn)換。

好處就是golang中只有unsafe.Point能做到這個(gè)事,其他方法都做不到,反射的底層也是用unsafe.Point做的。

9.unsafe.Point和unintptr有什么坑呢?

千萬要小心,不要為uintptr起一個(gè)中間變量 ,例如這樣:

這是因?yàn)楫?dāng)發(fā)生gc的時(shí)候,可能會(huì)修改變量的內(nèi)存地址,同時(shí)也會(huì)修改指向該變量的指針指向新的地址。但是uintptr是一個(gè)整數(shù),其不是一個(gè)指針,因此在gc修改變量的時(shí)候,可不會(huì)修改它的值,他還指向原來的地址,然后轉(zhuǎn)化成unsafe.Point進(jìn)行操作,當(dāng)然會(huì)報(bào)錯(cuò)。

10. string轉(zhuǎn)byte的零拷貝技術(shù)

string在golang中的的存儲(chǔ)結(jié)構(gòu)為:

我們可以定義一個(gè)一樣的結(jié)構(gòu)體,然后用unsafe.Point把其轉(zhuǎn)化成我們定義結(jié)構(gòu)體,這樣就可以把其私有屬性,映射成共有屬性了。

這個(gè)結(jié)構(gòu)體golang已經(jīng)幫我們定義好了,如下:

同理,slice的存儲(chǔ)結(jié)構(gòu)可以映射成,如下結(jié)構(gòu)體,golang也已經(jīng)幫我們定義好了

接來下就是具體的代碼:

其實(shí)就是修改了一下byte切片data所指向的地址空間以及l(fā)en就行了。

參考資料:

unsafe.Point

Golang|切片原理

在Golang語言開發(fā)過程中,我們經(jīng)常會(huì)用到數(shù)組和切片數(shù)據(jù)結(jié)構(gòu),數(shù)組是固定長度的,而切片是可以擴(kuò)張的數(shù)組,那么切片底層到底有什么不同?接下來我們來詳細(xì)分析一下內(nèi)部實(shí)現(xiàn)。

首先我們來看一下數(shù)據(jù)結(jié)構(gòu)

這里的array其實(shí)是指向切片管理的內(nèi)存塊首地址,而len就是切片的實(shí)際使用大小,cap就是切片的容量。

我們可以通過下面的代碼輸出slice:

這么分析下來,我們可以了解如下內(nèi)容:

使用一個(gè)切片通常有兩種方法:

另一種是slice = make([]int, len, cap)這種方法,稱為分配內(nèi)存。

創(chuàng)建一個(gè)slice,實(shí)質(zhì)上是在分配內(nèi)存。

這里跟一下細(xì)節(jié),math.MulUintptr是基于底層的指針計(jì)算乘法的,這樣計(jì)算不會(huì)導(dǎo)致超出int大小,這個(gè)方法在后面會(huì)經(jīng)常用到。

同樣,對(duì)于int64的長度,也有對(duì)應(yīng)的方法

而實(shí)際分配內(nèi)存的操作調(diào)用mallocgc這個(gè)分配內(nèi)存的函數(shù),這個(gè)函數(shù)以后再分析。

我們了解切片和數(shù)組最大的不同就是切片能夠自動(dòng)擴(kuò)容,接下來看看切片是如何擴(kuò)容的

這里可以看到,growslice是返回了一個(gè)新的slice,也就是說如果發(fā)生了擴(kuò)容,會(huì)發(fā)生拷貝。

所以我們?cè)谑褂眠^程中,如果預(yù)先知道容量,可以預(yù)先分配好容量再使用,能提高運(yùn)行效率。

copy這個(gè)函數(shù)在內(nèi)部實(shí)現(xiàn)為slicecopy

還有關(guān)于字符串的拷貝

這里顯示了可以把string拷貝成[]byte,不能把[]byte拷貝成string。

1、切片的數(shù)據(jù)結(jié)構(gòu)是 array內(nèi)存地址,len長度,cap容量

2、make的時(shí)候需要注意 容量 * 長度 分配的內(nèi)存大小要小于264,并且要小于可分配的內(nèi)存量,同時(shí)長度不能大于容量。

3、內(nèi)存增長的過程:

4、當(dāng)發(fā)生內(nèi)存擴(kuò)容時(shí),會(huì)發(fā)生拷貝數(shù)據(jù)的現(xiàn)象,影響程序運(yùn)行的效率,如果可以,要先分配好指定的容量

5、關(guān)于拷貝,可以把string拷貝成[]byte,不能把[]byte拷貝成string。

網(wǎng)站標(biāo)題:go語言中uintptr,Go語言中文
URL網(wǎng)址:http://aaarwkj.com/article14/dssjode.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、關(guān)鍵詞優(yōu)化云服務(wù)器、網(wǎng)站策劃、外貿(mào)網(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)

成都網(wǎng)站建設(shè)公司
亚洲青涩精品一区二区三区| 国产精品一区二区久久| 欧美成人精品资源在线观看| 青青草国产成人自拍视频在线观看| 丰满人妻被猛烈进入中文版| 国产丝袜肉丝在线播放| 中文字幕的国产在线播放| 青青草原在线视频伊人| 亚洲视频欧美视频自拍偷拍| 熟女另类视频在线观看| 国产欧美日本综合一区| 国产精品老熟女一区二区| 亚洲国产视频中文字幕| 国产欧美日本一区二区| 日韩看片一区二区三区高清| 久久人妻一区二区三区免费| 亚洲毛片在线免费播放| 免费在线av一区二区| 精品偷拍污视频一区二区| 亚洲欧美精品福利在线| 日韩欧美一区二区中文字幕视频| 国产亚洲av麻豆精品推荐| 亚洲国产成人91精品| 偷拍盗摄一区二区三区| 成人在线观看av毛片| 精品人妻一区两区三区| 亚洲日本乱码一区二区三| 国产日韩精品一区二区三区在线| 国产成人综合在线观看网站| 黄片欧美精品在线观看| 日本一区二区三在线观看| 青草草草草草在线观看| 免费看真人性生活视频| 蜜桃精品国产一区二区三区 | 国产亚洲精品视频免费| 久久99精品久久久国产| 免费黄色福利网址大片| 国产精品久久久亚洲不卡| 大香蕉欧美日韩在线视频| 国产欧美日韩一区二区三区四区| 亚洲国内精品一区二区在线|