golang map的底层结构

news/2024/11/28 22:46:54/文章来源:https://www.cnblogs.com/zhanchenjin/p/18575399

1. Map 的主要结构

map 的底层数据结构定义在 Go 源码的 runtime 包中,其核心结构体是 hmap。Go 的 map 使用 哈希表 存储键值对,并结合了**桶(bucket)**机制来优化存储和查找。

hmap 的主要字段

  • count:存储的键值对数量。
  • buckets:哈希桶的数组,存储键值对的实际数据。
  • hash0:哈希种子,用于随机化哈希函数,防止哈希冲突攻击。
  • Bbuckets 的对数大小(2^B 表示桶的数量)。
  • overflow:溢出桶,用于解决哈希冲突导致的桶空间不足。

bucket 的结构

每个桶中包含:

  • 一个定长数组用于存储键。
  • 一个定长数组用于存储值。
  • 一个附加的链表指针(溢出桶),用于存储冲突过多时溢出的数据。

2. Map 的底层操作

插入(Set)

  1. 计算哈希值:对键调用哈希函数,结合 hash0 生成哈希值。
  2. 定位桶:根据哈希值计算目标桶的位置。
  3. 存储键值对
    • 如果目标桶有空闲空间,直接插入。
    • 如果目标桶已满,则创建溢出桶,将新键值对存入溢出桶。

查找(Get)

  1. 计算哈希值:与插入操作相同。
  2. 定位桶:找到目标桶后,逐个检查桶内的键是否与目标键匹配。
  3. 返回值:如果找到匹配的键,则返回值;否则,继续查找溢出桶,直到找到或确定不存在。

删除(Delete)

  1. 计算哈希值:定位目标桶。
  2. 查找键:遍历桶及其溢出桶,找到匹配的键。
  3. 移除键值对:将键值对标记为空位,或者重组桶内数据。

3. 解决哈希冲突

Go 的 map 使用链地址法(chaining with linked lists)来解决哈希冲突:

  • 当多个键映射到同一个桶时,这些键值对会存储在溢出桶中。
  • 溢出桶以链表的形式连接在主桶之后。

4. 扩容机制

当 map 的键值对数量增长到一定程度时,Go 会触发扩容

  • 触发条件:当存储负载超过一定阈值(通常是 6.5)时。
  • 扩容过程
    1. 分配新的桶数组,其大小是原来的两倍。
    2. 重新哈希所有键,分配到新的桶中。
    3. 新桶可以减少冲突,提高访问效率。

5. Map 的特点

  • 无序:由于键值对的存储位置依赖哈希值,map 的迭代顺序是不确定的。
  • 高效:平均情况下,map 的查找、插入、删除操作的时间复杂度为 O(1)
  • 自动扩容:Go 的 map 会根据键值对数量动态扩容,用户无需手动调整。

6. Map 的优势与限制

优势

  1. 快速访问:哈希表的结构使得查找、插入、删除操作非常高效。
  2. 动态扩容:能适应不断变化的数据规模。
  3. 简单易用:提供友好的语法,用户无需关心底层细节。

限制

  1. 键必须可比较:键类型必须支持 == 和 != 操作(如 slice 不可用作键)。
  2. 无序性:无法保证键值对的迭代顺序。
  3. 高负载下性能可能下降:如果哈希冲突严重或扩容频繁,性能会受影响。

7. 简单示例

package mainimport "fmt"func main() {myMap := make(map[string]int)myMap["Alice"] = 25myMap["Bob"] = 30fmt.Println("Alice's age:", myMap["Alice"])delete(myMap, "Bob")fmt.Println("After deletion:", myMap)
}

总结

Go 的 map 是基于哈希表实现的,结合了桶(bucket)和溢出链表来处理哈希冲突,并通过动态扩容保持性能的稳定。它是 Go 程序中处理键值对的高效工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/843127.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【架构】统一认证中心的架构设计与实现(一)

一、背景二、认证授权概念2.1 认证2.2 授权三、一些名词四、常见的认证方案4.1 JWT4.2 OAuth2五、SSO协议5.1 OpenID Connect5.2 SAML 2.05.3 CAS六、RBAC一、背景 一般在一个公司内部可能有多个系统,比如OA,财务系统,CMS,ERP,营销系统,客服中心,项目管理系统,代码管理…

Listener内存马

概述 Listener是Java Web App中的一种事件监听机制,用于监听Web应用程序中产生的事件,例如,在ServletContext初始化完成后,会触发contextInitialized事件,实现了ServletContextListener接口的Listener就可以接收到事件通知,可以在内部做一些初始化工作,如加载配置文件,…

一种小资源情况下RDS数据实时同步StarRocks方案

使用一台4C8 G服务器轻松实现2个MySQL实例中通过负责分库分表规则之后的5000多张表的数据实时同步到StarRocks一、背景 目前需要将阿里云RDS数据库的数据同步到自建的StarRocks集群。之前使用DolphinScheduler通过定时调度Datax任务,将数据同步到StarRocks集群中,但是随着业务…

Elasticsearch常用查询及Kibana使用

Elasticsearch常用查询及Kibana使用 背景 搭建好Nginx => Filebeat => Logstash => Elasticsearch的日志获取通道后,通过jmeter配置产生10000条请求查看jmeter配置查看聚合报告Devtools工具进行查询查询reponseTime 90%,95%,99%分割线GET nginx-2024.11.28/_search…

Logstash安装及传输日志

Logstash安装及传输日志 Logstash安装按照官方文档安装启动logstash 方法1启动命令systemctl start logstash方法2 查看logstash启动配置先执行命令查看启动文件位置,可看出启动文件位置为/etc/systemd/system/logstash.servicesystemctl status logstash查看/etc/systemd/sys…

FileBeat安装及抽取Nginx日志

FileBeat安装及抽取Nginx日志 FileBeat安装按照官网指导安装,其他系统或版本可参考下载页面。此次测试FileBeat与nginx部署在同一台机器上。curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.25-linux-x86_64.tar.gz tar xzvf filebeat-7.17.…

jquery数字格式化分隔符插件

jquery-number-divider是一款jquery数字格式化分隔符插件。该数字格式化插件可以按指定格式对大数字进行分隔,可以指定分隔符,是一款简单实用的数字格式化插件。在线演示 下载 安装 可以通过bower来安装number-divider.js数字格式化插件。bower install number-divider …

MySQL底层概述—2.InnoDB磁盘结构

大纲 1.InnoDB磁盘结构 2.表空间(Tablespaces) 3.数据字典(Data Dictionary) 4.双写缓冲区(Double Write Buffer Files) 5.重做日志(redo log) 6.撤销日志(undo log) 7.二进制日志(binlog) 8.新版本结构演变1.InnoDB磁盘结构 (1)Tablespaces (2)Double Write Buffer (3)redo lo…

36. MySQL补充知识点

1. 视图 1.1 理论 [1] 什么是视图 视图是通过查询得到一张虚拟表,并保存下来,后续可以直接使用。 视图也是一张表。 在计算机科学中,视图(View)是一种虚拟表,其内容是一个或多个基本表的查询结果。 与基本表不同,视图不存储实际的数据,而是根据创建视图时的查询语句在…

车间工人违规行为智能识别方案

车间工人违规行为智能识别方案基于深度学习的视频分析系统,车间工人违规行为智能识别方案能够利用工业相机实时监测工人在生产线上的行为,系统不仅能够监测工人的操作行为,还能够监控整个生产流程。例如,它可以监测材料选择需要经过的环节数量,手动翻转的次数,以及上料动…

人员禁区闯入行为检测算法

人员禁区闯入行为检测算法通过现场监控相机捕捉监控区域内的实时图像,人员禁区闯入行为检测算法基于YOLOv7和CNN对图像进行分析,当检测到禁区闯入行为时,系统会立即触发告警。支持与第三方设备通信,发送开关量信号,以及将告警信息推送给后台值班人员。通过实时监控和快速响…

MySQL底层概述—1.InnoDB内存结构

大纲 1.InnoDB引擎架构 2.Buffer Pool 3.Page管理机制之Page页分类 4.Page管理机制之Page页管理 5.Change Buffer 6.Log Buffer1.InnoDB引擎架构 (1)InnoDB引擎架构图 (2)InnoDB内存结构(1)InnoDB引擎架构图 下面是InnoDB引擎架构图,主要分为内存结构和磁盘结构两大部分。(2)I…