go map 映射

 1、数据结构


// A header for a Go map.
type hmap struct {
	// Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
	// Make sure this stays in sync with the compiler's definition.
	count     int // # live cells == size of map.  Must be first (used by len() builtin)
	flags     uint8
	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	hash0     uint32 // hash seed

	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

	extra *mapextra // optional fields
}

// mapextra holds fields that are not present on all maps.
type mapextra struct {
	// If both key and elem do not contain pointers and are inline, then we mark bucket
	// type as containing no pointers. This avoids scanning such maps.
	// However, bmap.overflow is a pointer. In order to keep overflow buckets
	// alive, we store pointers to all overflow buckets in hmap.extra.overflow and hmap.extra.oldoverflow.
	// overflow and oldoverflow are only used if key and elem do not contain pointers.
	// overflow contains overflow buckets for hmap.buckets.
	// oldoverflow contains overflow buckets for hmap.oldbuckets.
	// The indirection allows to store a pointer to the slice in hiter.
	overflow    *[]*bmap
	oldoverflow *[]*bmap

	// nextOverflow holds a pointer to a free overflow bucket.
	nextOverflow *bmap
}

// A bucket for a Go map.
type bmap struct {
	// tophash generally contains the top byte of the hash value
	// for each key in this bucket. If tophash[0] < minTopHash,
	// tophash[0] is a bucket evacuation state instead.
	tophash [abi.MapBucketCount]uint8
	// Followed by bucketCnt keys and then bucketCnt elems.
	// NOTE: packing all the keys together and then all the elems together makes the
	// code a bit more complicated than alternating key/elem/key/elem/... but it allows
	// us to eliminate padding which would be needed for, e.g., map[int64]int8.
	// Followed by an overflow pointer.
}

map 的底层结构包含以下几个重要的元素:

  • hmaphmap 是 Go 中 map 类型的实际数据结构,它包含了哈希表的核心信息。例如,桶的指针、大小、负载因子、哈希函数等。
  • B:2^B 代表桶的数量,初始时B=3,即桶数量为8。

  • bucketsbuckets 数组存储了 map 中的哈希桶,每个桶内存储着一部分键值对。如果哈希冲突较多,桶会存储多个键值对。

  • oldbuckets:旧桶数组

  • noverflow:代表溢出桶的数量

  • nevacuate:扩容进度,指向旧桶中某个位置

  • overflow: 为了处理大量的哈希冲突,Go 中的哈希桶通常还会有一个 overflow 字段,表示某些冲突较严重的元素会被溢出到其他位置。

 2、底层实现

(1)哈希表和桶的结构

        Go 语言的 map 底层实现是一个哈希表,通过链地址法(数组加链表)来解决冲突,它的每个单元是一个桶。它的数组是由一组桶组成,每个桶是一个链式结构,可以存储8个键值对,当发生hash冲突时首先存在桶内,如果桶满了,就在桶后面连接溢出桶来存储键值对。

(2)哈希函数

        Go 使用一个高效的哈希函数将键映射到桶的位置。不同类型的键使用不同的哈希函数,例如字符串和整数会有不同的哈希计算方法。

(3)扩容和负载因子

        负载因子为6.5,代表键值对数量与桶数量比值的上限。如果达到负载因子值或溢出桶的数量超过正常桶的数量(或者超过上限值1<<15),就会发生扩容,新的桶数量是原来的2倍数。(负载因子的计算和桶的倍数不考虑溢出桶的数量)

        Go 的 map 底层哈希表设计采用了渐进式扩容的策略,当扩容时,并不是所有的键值对都会立刻重新哈希。Go 会 分批次地、渐进地将老桶中的元素迁移到新桶中,避免在扩容过程中产生性能瓶颈。

3、常用方法

(1)创建

var mp map[string]string // nil

mp := make(map[string]string) // empty map

(2)获取元素

v := m[key],key不存在时,获取的是零值

(3)判断key是否存在

v, ok := m[key]

(4)删除元素

delete(map[key])

func example() {
    var mp1 map[string]string                 // nil
    fmt.Println(mp1, mp1 == nil, len(mp1))    // map[] true 0
 
    var mp2 = make(map[string]string)         // empty map
    fmt.Println(mp2, mp2 == nil, len(mp2))    // map[] false 0
 
    mp2["1"] = "1"
    mp2["2"] = "2"
    fmt.Println(mp2, mp2 == nil, len(mp2))    // map[1:1 2:2] false 2
 
    delete(mp2, "1")
    fmt.Println(mp2, mp2 == nil, len(mp2))    // map[2:2] false 1
}

4、使用map的注意事项

(1)键必须是可比较的类型
  • 可比较类型:键必须是可比较的类型,即支持 == 和 != 运算符。常见的可比较类型包括基本类型(如 intstringbool)、指针类型、接口类型、固定长度的数组类型以及所有字段都是可比较的结构体类型。
  • 不可比较类型:切片、映射、函数和通道类型是不可比较的,因此不能作为 map 的键。
(2)键的性能
  • 散列函数map 内部使用散列表实现,键的散列函数对性能有影响。选择合适的键类型可以提高查找和插入的效率。
  • 复杂键:如果键是复杂的结构体或大对象,计算散列值可能会比较慢,影响性能。在这种情况下,可以考虑使用更简单的键类型或优化散列函数。
(3)并发安全

  map不是并发安全的。如果多个 goroutine 同时读写同一个 map,会导致运行时错误。可以使用互斥锁(sync.Mutex 或 sync.RWMutex)来保护 map,或者使用 sync.Map 提供的并发安全版本的 map

(4)初始化和容量
  • 初始化:可以使用 make 函数初始化 map,并指定初始容量
  • 容量:初始容量可以提高性能,特别是在已知 map 大小的情况下
(5)键的默认值
  • 零值:访问 map 中不存在的键时,会返回该类型的零值。例如,对于 map[string]int,访问不存在的键会返回 0
  • 存在性检查:使用多值赋值来检查键是否存在
(6)键的内存管理
  • 指针键:使用指针作为键时,要特别注意指针的生命周期。如果指针指向的对象在 map 的生命周期内被修改或释放,可能会导致未定义行为。
  • 垃圾回收map 中的键和值都会被垃圾回收器管理。如果键或值不再被引用,垃圾回收器会自动回收它们占用的内存

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子应用产品设计方案-4:基于物联网和人工智能的温度控制器设计方案

一、概述 本温度控制器旨在提供高精度、智能化、远程可控的温度调节解决方案&#xff0c;适用于各种工业和民用场景。 二、系统组成 1. 传感器模块 - 采用高精度的数字式温度传感器&#xff0c;如 TMP117&#xff0c;能够提供精确到 0.01C 的温度测量。 - 配置多个传感器分布在…

5G的发展演进

5G发展的驱动力 什么是5G [远程会议&#xff0c;2020年7月10日] 在来自世界各地的政府主管部门、电信制造及运营企业、研究机构约200多名会议代表和专家们的共同见证下&#xff0c;ITU-R WP 5D#35e远程会议宣布3GPP 5G技术&#xff08;含NB-IoT&#xff09;满足IMT-2020 5G技…

人工智能--自然语言处理简介

上一篇&#xff1a;《人工智能模型训练中的数据之美——探索TFRecord》 序言&#xff1a;自然语言处理&#xff08;NLP&#xff09;是人工智能中的一种技术&#xff0c;专注于理解基于人类语言的内容。它包含了编程技术&#xff0c;用于创建可以理解语言、分类内容&#xff0c…

第8章 利用CSS制作导航菜单

8.1 水平顶部导航栏 水平莱单导航栏是网站设计中应用范围最广的导航设计&#xff0c;一般放置在页面的顶部。水平 导航适用性强&#xff0c;几乎所有类型的网站都可以使用&#xff0c;设计难度较低。 如果导航过于普通&#xff0c;无法容纳复杂的信息结构&#xff0c;就需要在…

企望制造ERP系统 drawGrid.action SQL注入致RCE漏洞复现

0x01 产品简介 企望制造ERP系统是一款专为制造企业设计的企业资源计划(ERP)软件,旨在优化企业的资源配置,提高运营效率,并增强企业的竞争力。系统集成了财务管理、生产管理、供应链管理、客户关系管理(CRM)、人力资源管理(HRM)等多个核心功能模块,能够全面覆盖企业的…

基于JDBC的书库系统(MySQL)

一、创建数据库中的表 1、需求 有一张表叫javabook【创建表要求使用sql语句进行】 表中列 bookid 整数自增类型 表中列 bprice 小数类型 表中列 bookname 字符串类型 长度不能小于50 工程和包要求&#xff1a; domain dao …

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪BD311R 发布时间: 2024-10-23 11:28:42 一、 产品图片&#xff1a; 二、 产品特性&#xff1a; 4G性能&#xff1a;支持2K超高清图传&#xff0c;数据传输不掉帧&#xff0c;更稳定。 独立北…

腾讯音乐2024Q3财报:“稳”是核心,再进一步

11月12日&#xff0c;腾讯音乐娱乐集团&#xff08;以下简称“腾讯音乐”&#xff09;发布了截至2024年9月30日止的第三季度未经审计财务报告&#xff0c;各项核心财务指标均符合市场预期。本季度总收入为70.2亿元&#xff0c;同比增长6.8%&#xff1b;调整后净利润为19.4亿元&…

地宫取宝(摘花生+最长上升子序列)C++

1212. 地宫取宝 - AcWing题库 #include <iostream>using namespace std;const int N 55; const int MOD 1000000007;int w[N][N],f[N][N][13][14]; int n,m,k;int main() {cin >> n >> m >> k;for (int i 1;i < n;i) {for (int j 1;j < m;j)…

2024 年 8 个最佳 API 设计工具图文介绍

8 个最佳 API 设计工具推荐&#xff0c;包括 Apifox、Postman、Swagger、Insomnia、Stoplight、Hoppscotch、RapidAPI和Paw。 详细介绍&#xff1a;2024 年 8 个最佳 API 设计工具推荐

minio 分布式

方案设计 需要5台服务器&#xff0c;一台nginx用作分发请求&#xff0c;4台minio服务器&#xff0c;每个minio服务器上至少2个盘。在这个方法中&#xff0c;我使用了lvm的缓存&#xff0c;在同种固态盘的情况下&#xff0c;可以使读性能提高数倍到十倍&#xff0c;使写性能提高…

kettle开发-Day43-数据对比

前言&#xff1a; 随着数字化的深入&#xff0c;各种系统及烟囱的建立&#xff0c;各系统之间的架构和数据存储方式不同&#xff0c;导致做数据仓库或数据湖时发现&#xff0c;因自建的系统或者非标准化的系统经常存在物理删除而不是软删除。这就延伸出一个问题&#xff0c;经常…

vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-

1.前提&#xff1a; VScode中的git组件执行任何合并动作的时候需要提交远程合并的commit信息&#xff0c;然后编辑器自动打开的是nano文本编辑器 2.nano编辑器说明&#xff1a; 1.保存文件&#xff1a;按 Ctrl O&#xff0c;然后按 Enter 来保存文件。 2.退出编辑器&#xf…

Android音视频直播低延迟探究之:WLAN低延迟模式

Android WLAN低延迟模式 Android WLAN低延迟模式是 Android 10 引入的一种功能&#xff0c;允许对延迟敏感的应用将 Wi-Fi 配置为低延迟模式&#xff0c;以减少网络延迟&#xff0c;启动条件如下&#xff1a; Wi-Fi 已启用且设备可以访问互联网。应用已创建并获得 Wi-Fi 锁&a…

如何详细查询全球药品研发的进度信息?

药品的研发进展对于医药研发人员来说&#xff0c;不仅是知识和技能的积累&#xff0c;更是职业精神和价值观的塑造。通过了解药品的研发进展&#xff0c;研发人员可以更好地提高自己的专业知识和技能&#xff0c;激发创新思维&#xff0c;保持专业竞争力&#xff0c;提高研发效…

摄像机视频分析软件下载LiteAIServer视频智能分析软件抖动检测的技术实现

在现代社会中&#xff0c;视频监控系统扮演着至关重要的角色&#xff0c;其可靠性和有效性在很大程度上取决于视频质量。然而&#xff0c;由于多种因素&#xff0c;如摄像机安装不当、外部环境振动或视频信号传输的不稳定&#xff0c;视频画面常常出现抖动问题&#xff0c;这不…

Jmeter中的监听器(一)

监听器 1--查看结果树 用途 调试测试计划&#xff1a;查看每个请求的详细信息&#xff0c;帮助调试和修正测试计划。分析响应数据&#xff1a;查看服务器返回的响应数据&#xff0c;验证请求是否成功。检查错误&#xff1a;识别和分析请求失败的原因。 配置步骤 添加查看结果…

PaaS云原生:分布式集群中如何构建自动化压测工具

场景 测试环境中&#xff0c;压测常常依赖环境中的各种工具获取基础信息&#xff0c;而这些工具可能集中在某个中控机上&#xff0c;此时想打造的自动化工具的运行模式是&#xff1a; 通过中控机工具获取压测所需的基本信息在中控机部署压测工具&#xff0c;实际压测任务分发…

数据结构-递归函数的调用栈过程

这道题考察的是递归函数的调用栈过程。 逐步分析程序的执行过程&#xff1a; main() 函数首先被调用&#xff0c;此时栈底是 main() 的信息。main() 函数调用 S(1)&#xff0c;此时 S(1) 的信息被压入栈中&#xff0c;位于 main() 之上。S(1) 函数内部调用 S(0)&#xff0c;因…

华为OD机试 - 芯片资源限制(Python/JS/C/C++ 2024 C卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…