Golang学习笔记-map

2020-09-06  本文已影响0人  LegendGo

之前在面试今日头条时被问到了map的实现原理,当时答的不是很好。现在从网上找了些资料记录下map的实现原理。

什么是map

map 是一种通过key来获取value的数据结构,其底层存储方式为数组,在存储时 key不能重复,当key重复的时候,value进行覆盖,我们通过key进行hash计算,然后对数组的长度取余,得到key存储在数组的哪个下标位置,最后将key和value转化为一个结构体,放到数组的下标中。

hash冲突

在key进行hash的时候,会出现hash冲突的问题,主要有下面几个解决办法

开放定址法

在存储key-value的时候发现hashkey(key)的下标已经被别key占用,那我们在这个数组中空间中重新找一个没被占用的存储这个冲突的key,那么没被占用的有很多,找哪个好呢?常见的有线性探测法,线性补偿探测法,随机探测法,这里我们主要说一下线性探测法。

Golang中map的实现原理

在go中,map是用来进行数据存储的,每个数组下标处存储的是一个bucket,这个bucket的类型如下

type bmap {
    tophash [bucketCnt]uint8
}

tophash 用来快速查找key值是否在在bucket中,不是每次都是通过真值进行比较,至于kv的存放,不是k1v1,k2v2,而是k1k2,v1v2,主要是因为map[int64]int8,key是int64(8字节),value是int8(一个字节), key和value的长度不同,如果按照kv格式来存数据,则会占用较多的内存。
最后分析下go的整体内存结构,当向map中写入数据的时候,通过k获取hash值,hash值的低八位和bucket数组长度取余,定位到在数组中的那个下标,hash值的高八位存储在bucket中的tophash中,用来快速判断key是否存在,key和value的具体值则通过指针运算存储,当一个bucket满时,通过overfolw指针链接到下一个bucket。

上一篇下一篇

猜你喜欢

热点阅读