真希望你也明白runtime.Map和sync.Map

本文深入探讨了哈希表的重要性和Go语言中的Map实现。讲解了Hash冲突的两种常见解决方案——开放寻址法和拉链法,并详细分析了Go语言Map的源代码,包括Map的扩容过程和并发安全性问题。通过源码阅读,揭示了Map的内部工作机制,如bucket和overflow桶的设计,以及Map在并发环境下的潜在风险。
摘要由CSDN通过智能技术生成

Map 官方介绍

One of the most useful data structures in computer science is the hash table. Many hash table implementations exist with varying properties, but in general they offer fast lookups, adds, and deletes. Go provides a built-in map type that implements a hash table.
哈希表是计算机中最有用的数据结构之一。提供快速查找、添加和删除。 Go 提供了一个实现哈希表的内置Map类型。

Hash冲突

那对于Hash的一个最重要的问题,就是hash冲突。下面我们看一下常用的解决方案。

开放寻址法

开放寻址法想象成一个停车问题。若当前车位已经有车,则继续往前开,直到找到一个空停车位。
go-32-001

上图,每个方格子,就是一个车位,当一辆车来的时候,会依次查询是否有空位,如果没有,则继续向后面找,如果发现空位置,就会停到空位置中。

go-32-002

下面看一下,我们的代码是如何实现的?

go-32-003

go-32-004

  1. m[“面向加薪学习”]=“从0到Go语言微服务架构师-训练营”
  2. 要对键-“面向加薪学习”,进行hash
  3. 拿到全体格子的总数,然后取模
  4. 如果取模发现是位子1,但是发现1已经被别人占了,那么就向后走,直到有空位,再把自己放进去。

看了上面的步骤是不是和停车,是一个道理?

那我们再看,如果想读取数据的时候:

  1. 同样对J键进行hash
  2. 拿到全体格子的总数,然后取模
  3. 找到位置是1,但是发现key不一样,它可能在后面,就一直向后查找。

拉链法

go-32-005

go-32-006

  1. m[“面向加薪学习”]=“从0到Go语言微服务架构师-训练营”
  2. 要对键-“面向加薪学习”,进行hash
  3. 找到对应到槽位,每个槽位并不存储具体数据,只是一个指针,它指向下面的链表
  4. 当新增数据的时候,会把数据添加到链表头部(上图中黄色小球为例)

Go语言的Map

runtime/map.go,看到hmap这个结构体,它就go语言的map

type hmap struct {
   
    count     int
    flags     uint8
    B         uint8 
    noverflow uint16
    hash0     uint32
    buckets    unsafe.Pointer 
    oldbuckets unsafe.Pointer 
    nevacuate  uintptr
    extra *mapextra
}
  1. count 键值对的数量
  2. B 是以2为底,桶个数的对数
  3. hash0 hash的种子
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值