当前位置: 首页 > news >正文

Map 那些事儿

1. map 的基本结构

Go 的 map 是一种哈希表,其核心思想是通过哈希函数将键映射到某个位置(桶)以存储对应的值。它主要包含以下关键部分:

•桶(bucket):存储键值对的容器,map 中的元素被分散到多个桶中。

•哈希函数:用于计算键的哈希值,从而确定键应存放在哪个桶中。

•键值对存储:每个桶可以存储多个键值对,并通过链表或其他结构处理哈希冲突。

2. map 的实现细节

(1) hmap 结构

在 Go 源码中,map 是通过一个名为 hmap 的结构体实现的(定义在 runtime/map.go 中)。主要字段包括:

• count: map 中存储的键值对总数。

• buckets: 指向桶的指针,每个桶存储多个键值对。

• hash0: 用于防止哈希冲突的种子(随机数),在程序启动时初始化。

• B: 桶的数量为 2^B,B 是桶数的对数。

(2) 桶的结构

每个桶是一个固定大小的数组,存储若干个键值对。此外,每个桶还有一个位图,用于快速定位某个槽位是否已被占用。

• 键值对数组:存储键和值。

• 溢出桶:当一个桶满时,会使用额外的溢出桶存储新插入的键值对。

(3) 哈希冲突处理

当两个键通过哈希函数映射到同一个桶时,就会发生哈希冲突。Go 使用以下方法处理冲突:

• 链式处理:如果一个桶已满,则创建溢出桶。

• 线性探测:在桶中通过位图快速找到空闲槽位。

3. 操作原理

(1) 插入操作

1. 计算键的哈希值。

2. 根据哈希值定位到一个桶。

3. 在桶中查找空闲槽位,存储键值对。

4. 如果桶满,则分配溢出桶并存储新数据。

(2) 查找操作

1. 计算键的哈希值。

2. 定位到桶后,在桶内逐一检查键是否存在。

3. 如果未找到,继续在溢出桶中查找。

(3) 删除操作

1. 定位到桶。

2. 在桶中找到对应的键值对,将其标记为空。

4. 动态扩容

当 map 的负载因子(存储的键值对数与桶数的比值)超过某个阈值时,map 会进行扩容(rehash):

1. 增加桶的数量(桶数翻倍)。

2. 将现有键值对重新分配到新的桶中。

3. 新的桶结构更加稀疏,减少冲突。

扩容是一项耗时操作,因此频繁的插入操作可能会导致性能抖动。

Map迁移执行过程

(1) 扩容时分配新桶

• 新的桶数量为旧桶数量的两倍。

• 新桶的内存被初始化,但数据尚未迁移。

(2) 增量迁移

迁移操作是增量完成的,而非一次性迁移:

• 当 map 被访问(插入、查找或删除)时,Go 运行时会在后台逐步迁移旧桶中的数据到新桶。

• 每次访问会触发部分桶的迁移。

(3) 数据重新分布

迁移过程中:

1. 计算新哈希值:对每个键重新计算哈希值。

2. 分配到新桶:新哈希值根据新的桶数决定键值对的位置。

哈希值的高位用来区分数据是留在旧桶还是移动到新桶:

• 如果 (hash >> B) & 1 == 0,则数据保留在旧桶。

• 如果 (hash >> B) & 1 == 1,则数据迁移到新桶。

http://www.lryc.cn/news/500724.html

相关文章:

  • GCP Case:MountKirk Games
  • [创业之路-187]:《华为战略管理法-DSTE实战体系》-1-从UTStarcom的发展历程,如何辩证的看企业初期发展太顺利中的危机
  • 高级数据结构-树状数组
  • LeetCode279. 完全平方数(2024冬季每日一题 27)
  • Scala 隐式转换
  • K8S命令部署后端(流水线全自动化部署)
  • Ubuntu中配置交叉编译工具的三条命令的详细研究
  • 【PyQt5教程 二】Qt Designer 信号与槽的使用方法及PyQt5基本小部件说明
  • 编程语言中接口(Interface)介绍
  • 算法学习之贪心算法
  • 【jvm】垃圾回收的优点和原理
  • YOLO系列发展历程:从YOLOv1到YOLO11,目标检测技术的革新与突破
  • 深入浅出:序列化与反序列化的全面解析
  • word实践:正文/标题/表图等的共用模板样式设置
  • Blender中使用BlenderGIS插件快速生成城市建筑模型
  • 【单元测试】单元测试的重要性
  • Codeforces Round 992 (Div. 2)
  • el-table一键选择全部行,切换分页后无法勾选
  • 负载均衡最佳实践及自定义负载均衡器
  • 大模型 LMDeploy 量化部署
  • 算法设计5_分支限界法
  • 2025年人工智能专业可以考哪些证书呢?
  • 仿真技术助力高尔夫球打破传统设计局限,实现球杆强大的功能
  • 微前端架构学习笔记
  • DApp开发:从合约到系统快速上线解决方案
  • react 中 useState 中的 set 方法异步解决
  • UAC2.0 speaker——带反馈端点的 USB speaker(16bit 单声道)
  • docker的简单使用
  • Selenium:强大的 Web 自动化测试工具
  • 设计模式 在PLM系统的应用场景介绍