[Go八股文]Map之Map的底层结构

Go中的map是一个指针,占用8个字节,指向hmap结构体

源码中src/runtime/map.go定义了Hmap的数据结构

在这里插入图片描述

  1. hmap结构体

    type hmap struct {
        count     int
        flags     uint8
        B         uint8
        noverflow uint16
        hash0     uint32
    
        buckets    unsafe.Pointer
        oldbuckets unsafe.Pointer
        nevacuate  uintptr
    
        extra *mapextra
    }
    
    • 字段包括:
      • count:表示当前map中元素的个数。
      • B:表示buckets数组的长度是2的B次方个。
      • noverflow:表示溢出桶的数量。
      • buckets:指向一个数组,数组的每个元素都是一个bucket(桶)。
      • oldbuckets:在发生扩容时,记录扩容前的buckets数组指针。
      • extra:一个指向mapextra结构体的指针,用于保存溢出桶的地址等信息。
  2. bucket(桶)

    • buckets数组中的每个元素都是一个bucket,它实际上是一个指向bmap结构体的指针。
    • 每个bmap结构体存储8个键值对。
  3. bmap结构体

    • 这是实际存储键值对的数据结构。
    • 字段包括:
      • tophash:一个长度为8的数组,存储哈希值的高8位,用于快速比较和查找。如果Key所在的tophash值在tophash中,则代表了Key在这个桶中。
      • keys:一个数组,用于存储键。
      • values:一个数组,用于存储值。
      • overflow:当bucket中的键值对超过8个时,使用此指针指向下一个bmap,形成链表结构来处理溢出。

    插入/删除/查找

    插入

    插入一个新的键值对时,map首先会检查当前的负载因子。如果负载因子超过了阈值,map会先进行扩容操作。然后,map会计算键的哈希值,并使用这个哈希值来决定应该将键值对存储在哪个桶中。具体的策略是,根据计算得到的哈希值的低B位,决定在buckets数组中的哪个bmap中,然后根据它哈希值的高8位,决定它在桶中的哪个位置(一共8个位置)。

    删除

    删除一个键时,map会计算键的哈希值,并使用这个哈希值来定位桶。然后,map会在这个桶中查找并删除键值对。

    查找一个键时,map会计算键的哈希值,并使用这个哈希值来定位桶。然后,map会在这个桶中查找键值对。

    溢出处理

    • 当一个bucket中的键值对数量超过8个时,Go语言会使用overflow指针将新的键值对存储在下一个bmap中,形成链表结构。
    • 这种链表结构允许map在保持哈希表高效查找特性的同时,也能够动态地处理大量键值对的情况。

    扩容操作

    • 当map中的元素数量达到某个阈值时(通常是buckets数组长度的某个比例),Go语言会触发扩容操作。
    • 扩容操作会创建一个新的、更大的buckets数组,并将旧的键值对重新哈希并分布到新的buckets数组中。
    • 为了减少扩容操作对性能的影响,Go语言采用了渐进式扩容的策略,即在扩容过程中仍然允许对map进行读写操作。
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang八股文是指在面试或考试中常被问到的一些基础知识和常见问题。下面是一份简单的整理: 1. Golang的特点:静态类型、垃圾回收、并发模型、内存安全、编译型语言等。 2. Golang中的基本数据类型:整型、浮点型、布尔型、字符串、数组、切片、映射、结构体等。 3. Golang中的控制流程:条件语句(if-else)、循环语句(for、range)、选择语句(switch)、跳转语句(break、continue)等。 4. Golang中的函数:函数定义、函数调用、参数传递(值传递和引用传递)、多返回值、匿名函数、闭包等。 5. Golang中的并发编程:goroutine的创建与调度、通道(channel)的使用、并发安全、锁机制(互斥锁、读写锁)等。 6. Golang中的错误处理:错误类型(error)、错误处理机制(defer、panic、recover)、错误码设计等。 7. Golang中的面向接口编程:接口的定义与实现、接口的多态性、空接口(interface{})、类型断言等。 8. Golang中的包管理:go mod的使用、依赖管理、版本管理等。 9. Golang中的测试与性能优化:单元测试(testing包)、性能剖析(pprof包)、内存分析、代码优化等。 10. Golang中的常用标准库:fmt、os、io、net、http、json等。 以上是一些常见的Golang八股文内容,希望对你有所帮助。当然,实际应用中还有很多其他方面的知识和技巧需要掌握。如果你有具体的问题,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值