iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >golang map 实现原理
  • 367
分享到

golang map 实现原理

2023-05-15 11:05:22 367人浏览 薄情痞子
摘要

在学习 golang 的过程中,map 是我们经常使用的一种数据结构,可以用来存储 key-value 对。但是,你是否想过 map 的实现原理是什么呢?在本文中,我们将探究 Golang 中 map 的实现原理。map 实现原理简介map

学习 golang 的过程中,map 是我们经常使用的一种数据结构,可以用来存储 key-value 对。但是,你是否想过 map 的实现原理是什么呢?在本文中,我们将探究 Golang 中 map 的实现原理。

map 实现原理简介

map 实际上是一个哈希表,它的实现原理就是哈希算法。哈希表是一种根据关键字直接访问内存存储位置的数据结构,也就是说,它提供了一种将关键字映射到内存地址的方法。在哈希表中,关键字被称为“键”,通过哈希函数计算得到的内存地址被称为“桶”,桶存储了键值对。

在 Golang 中,map 是通过在桶内存区域存储键值对实现的,每个桶都有一个头部结构体,用于描述桶的状态,这个头部结构体称为“bucket”。

bucket 数据结构

先来看一下 bucket 的数据结构:

type bmap struct {
    tophash [bucketCnt]uint8
    // data 的类型在 map 被分配空间的时候由 map 的 key 和 value 类型决定
    // 如果 key 类型和 value 类型都是未知类型,那么 data 的类型是 byte
    // 因为 byte 可以用于存储任何类型,也就是说 data 可以存储任何类型的 key 和 value
    // 在存储 key 和 value 的时候,需要将 key 和 value 转换成 uintptr,然后再转换成 byte 存储到 data 中
    // 读取 key 和 value 的时候反向操作即可
    // 因此,map 中的 key 和 value 一般都是需要转换成 uintptr 类型的
    // 这里我们可以简单地理解为 data 存储了键值对的二进制数据
    // 第一个 bucket 中如果存不下某个 key-value,还需要在第二个 bucket 中存储
    // 所以,data 的长度可以为 1 或 2
    // 当 data 的长度为 1 或 2 时,存储的键值对的个数分别为 1 或 2
    // 因此,bucket 中最多只能存储 8 个键值对
    // 否则,就需要将键值对存储在 overflow 中
    // overflow 是一个指向单链表头部的指针数组
    // 如果某个桶存储的键值对数量超过了 8,那么就将多余的键值对存储到 overflow 中
    // overflow 中的第一个 bucket 中也是能够存储 8 个键值对的,如果第一个 bucket 中存不下的话
    // 那么还需要在第二个 bucket 中继续存储
    // 所以,overflow 数组的长度也可以为 1 或 2
    // 当 overflow 数组长度为 1 或 2 时,最多存储 8 个键值对的 overflow
    // 当 overflow 数组长度为 3 时,最多存储 24 个键值对的 overflow
    // 也就是说,如果 map 中存储的键值对数量很多的话,那么可能会有很多个 overflow 桶
    // 而 overflow 数组是动态分配的,因此它的长度是不定的,只有在运行时才能确定
    data unsafe.Pointer
    // overflow 是一个指针数组,用于存储除当前桶以外的其它桶
    // 如果某个桶的键值对数量超过了 8,那么它会将多余的键值对存储到 overflow 中
    // overflow 数组中的每个元素都是一个 bucket 指针
    // 这些 bucket 指针构成了一个链表,也就是所谓的 overflow 链表
    overflow *[]*bmap
    // 这里存储的是这个 bucket 当前存储的键值对的个数
    count int16
    // flags 存储了 bucket 的标志
    // 一个 bucket 可能会有如下三种状态:
    // 1. empty,表示这个 bucket 没有存储任何键值对
    // 2. iterator,表示这个 bucket 正在被访问,不能再被其它操作使用
    // 3. deleted,表示这个 bucket 存储的键值对已经被删除了
    // 注意,该标志位只有在 GC 达到一定阈值后才会被置为 true,而且并不是立即删除键值对,而是在下一次 GC 的时候才会内存回收
    flags uint8
    // Bmap 的类型标记
    // Bmap 用来标识存储于上文中 data 指针中的数据类型
    // 如果 data 中存储的是 int,那么 Bmap 的值为 hmap.Bmapint
    // 如果 data 中存储的是 string,那么 Bmap 的值为 hmap.BmapString
    // 如果 data 中存储的是 interface{},那么 Bmap 的值为 hmap.BmapInterface
    // 如果 data 中存储其他类型,那么 Bmap 的值为 hmap.BmapOther
    BmapType uint16
    // 与该 bucket 相关联的 key 的类型
    tophash0 uint8
}

从上面的定义中,我们可以看到,bucket 存储了以下信息:

  • tophash:用于快速筛选出不匹配的 key;
  • data:存储键值对的数据;
  • overflow:存储 overflow 链表的指针数组;
  • count:存储了当前 bucket 中存储的键值对的个数,最多为 8;
  • flags:存储了 bucket 的一些状态信息;
  • BmapType:存储了 data 中存储数据的类型;
  • tophash0:与该 bucket 相关联的 key 的类型。

实现原理

由于 map 存储的数据是键值对,而且键值对的 key 值是不可重复的并且能够进行比较大小操作,我们可以采用哈希函数将 key 值转换为一个唯一的哈希值,然后将哈希值作为 key 值对应的索引,将 value 值存储在该索引上。

在 Golang 中,每一个 map 都有一个哈希表,这个哈希表实际上就是一段连续的存储空间,可以存储若干个桶(bucket),每个桶都是一个 bucket 类型的结构体。

那么哈希表的大小是如何确定的呢?它是在 map 创建时动态分配内存而来的,首次分配空间时候使用的默认大小为 8 个桶。如果第一次增加元素的时候,桶的数量不够,则哈希表的大小会扩容,并重新计算每个元素在哈希表中的索引位置。

在 Golang 中,哈希函数的作用主要是将 key 值散列化,使其更方便的定位到哈希表中的一个桶,从而加速查找 key 值对应的 value 值。在 Golang 中,哈希函数的实现采用了 MurmurHash3 算法。

由于哈希函数是将 key 映射到一个整数,因此不同的 key 值可能映射到相同的索引。这种情况被称为哈希冲突。当出现哈希冲突时,Golang 采用链表法来进行解决,将相同索引上的键值对存储在该索引的链表中,这些键值对就称为 overflow。

总结

Golang 的 map 实现原理主要依赖哈希表和哈希函数。哈希函数用于散列化 key 值,将其映射到哈希表中的一个桶,从而加速查找 value 值的操作。哈希表由若干个桶组成,每个桶由一个 bucket 类型的结构体表示,存储了键值对的信息。当哈希表中的同一索引位置上存在多个键值对时,采用链表法存储 overflow。Golang 中的 map 实际上就是一个动态哈希表,可以动态地调整哈希表的大小。在使用 map 时,需要注意避免哈希冲突和包含无法比较大小的类型作为 key。

以上就是golang map 实现原理的详细内容,更多请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: golang map 实现原理

本文链接: https://www.lsjlt.com/news/208875.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • golang map 实现原理
    在学习 Golang 的过程中,map 是我们经常使用的一种数据结构,可以用来存储 key-value 对。但是,你是否想过 map 的实现原理是什么呢?在本文中,我们将探究 Golang 中 map 的实现原理。map 实现原理简介map...
    99+
    2023-05-15
  • golang map实现原理是什么
    Golang中的map是一种哈希表数据结构,用于存储键值对。它的实现原理是使用哈希函数将键映射到哈希表中的一个桶(bucket),每...
    99+
    2023-08-15
    golang map
  • 浅析Golang中map的实现原理
    Golang是一门支持面向对象编程的编程语言,它拥有高效的内存管理机制和灵活的语法特性,被广泛用于服务器端开发、网络编程、云计算等领域。在Golang中,map是一种非常重要的数据结构,它可以存储键值对,并提供快速的查找和插入操作。本文将介...
    99+
    2023-05-14
    go语言 Golang map
  • Golang中map的实现原理是什么
    这篇“Golang中map的实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Golang中map的实现原理是什么...
    99+
    2023-07-05
  • golang map底层实现原理是什么
    Golang中的map是基于散列表(hash table)实现的。散列表是一种用于存储键值对的数据结构,它通过将键映射到数组的索引来...
    99+
    2023-10-21
    golang
  • Golang基础学习之map的实现原理是什么
    这篇文章主要讲解了“Golang基础学习之map的实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang基础学习之map的实现原理是什么”吧!0. 简介哈希表是常见的数据结...
    99+
    2023-07-05
  • golang如何实现map
    本文小编为大家详细介绍“golang如何实现map”,内容详细,步骤清晰,细节处理妥当,希望这篇“golang如何实现map”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。随着大数据时代的到来和云计算技术的普及,数...
    99+
    2023-07-05
  • golang map实现接口
    在Golang中,map是一种非常常用的数据结构。它可以存储一个无序的键值对集合,并且可以通过键快速地检索到对应的值,因此在开发的过程中经常会使用它来存储和管理数据。在某些情况下,我们可能会需要将map类型与接口结合使用,来实现一些特定的功...
    99+
    2023-05-14
  • golang map如何实现
    本文小编为大家详细介绍“golang map如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“golang map如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。哈希表的概念哈希表是一种以键值对存储数...
    99+
    2023-07-05
  • 深入刨析Golang-map底层原理
    目录map底层原理刨析1. Go map 的底层结构Go map 的查找Go map 的插入/更新Go map 的删除Go map 的扩容Go map 的遍历map底层原理刨析 Go...
    99+
    2023-05-19
    Golang map底层原理 Golang map底层 Golang map
  • golang map的实现讲解
    Golang是一门新兴的编程语言,它的map是基于哈希表实现的。在这篇文章中,我们将讨论Golang中map的实现方式。具体来说,我们将介绍哈希表的概念、Golang map的结构和性能优化。哈希表的概念哈希表是一种以键值对存储数据的数据结...
    99+
    2023-05-14
    Golang
  • golang反射实现原理
    Golang是一种简单、高效、并发安全的编程语言。它的反射机制使得程序员可以在运行时获取和修改程序对象的信息,实现动态编程。本文将介绍Golang反射的实现原理,帮助读者更好地理解反射的工作机制和使用方式。一、反射的基础概念反射是一种程序在...
    99+
    2023-05-15
  • golang map 删除如何实现
    Golang是一种快速、高效、跨平台的编程语言,作为目前较为流行的编程语言之一,它拥有丰富的特性和各种高级数据结构,比如map。Map是Golang中非常常用的内置数据结构,它可以轻松的在程序中存储键值对类型的数据。Map提供了便捷的操作方...
    99+
    2023-05-14
    Golang
  • Golang锁原理如何实现
    这篇文章主要介绍了Golang锁原理如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang锁原理如何实现文章都会有所收获,下面我们一起来看看吧。什么是锁锁的本质,就是一种资源,是由操作系统维护的一种...
    99+
    2023-07-05
  • golang select的实现原理是什么
    在Go语言中,`select`语句用于从多个通道中接收数据,并且只有当其中一个通道可以接收数据时,`select`语句才会执行相应的...
    99+
    2023-10-27
    golang
  • golang协程实现原理是什么
    Golang协程实现的原理是使用了一种称为"轻量级线程"或"用户态线程"的概念,即Goroutine(协程)。在Goroutine中...
    99+
    2023-08-31
    golang
  • golang锁的实现原理是什么
    golang锁的实现原理是通过互斥锁和读写锁来保护共享资源的访问。互斥锁是一种基本的锁机制,用于保护共享资源,使用一个标志位来表示资源是否被占用,当一个goroutine获取到互斥锁后,其他goroutine就会被阻塞,直到该gorouti...
    99+
    2023-12-12
    Golang
  • golang函数自定义实现原理
    在 go 语言中,可自定义函数的实现原理如下:定义函数签名:func () 赋予函数值:函数作为值类型,可赋值给变量、传递或返回。调用函数:使用圆括号括起来的函数名后跟参数列表。实战案例...
    99+
    2024-04-26
    函数 golang
  • 深入理解Golang接口的实现原理
    深入理解Golang接口的实现原理,需要具体代码示例 Golang(又称Go语言)作为一种快速、可靠的编程语言,广受开发者青睐。其中,接口(Interface)是Golang语言中非常...
    99+
    2024-03-07
    原理 接口 golang go语言
  • Golang中map扩容底层如何实现
    这篇文章主要讲解了“Golang中map扩容底层如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang中map扩容底层如何实现”吧!map底层结构主要包含两个核心结构体hmap和...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作