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

【Golang 面试题】每日 3 题(十四)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

40. Go slice 为什么不是线程安全的?

先看下线程安全的定义:

多个线程访问同一个对象时,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的。

若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

再看 Go 语言实现线程安全常用的几种方式:

  1. 互斥锁
  2. 读写锁
  3. 原子操作
  4. sync.once
  5. sync.atomic
  6. channel

slice 底层结构并没有使用加锁等方式,不支持并发读写,所以并不是线程安全的,使用多个 goroutine 对类型为 slice 的变量进行操作,每次输出的值大概率都不会一样,与预期值不一致;slice 在并发执行中不会报错,但是数据会丢失。

/**
* 切片非并发安全
* 多次执行,每次得到的结果都不一样
* 可以考虑使用 channel 本身的特性 (阻塞) 来实现安全的并发读写
 */
func TestSliceConcurrencySafe(t *testing.T) {
    a := make([]int, 0)
    var wg sync.WaitGroup
    for i := 0; i < 10000; i++ {
        wg.Add(1)
        go func(i int) {
            a = append(a, i)
            wg.Done()
        }(i)
    }
    wg.Wait()
    t.Log(len(a)) 
    // not equal 10000
}

41. Golang Map 底层实现

Go 语言中的 map 是一种无序的键值对的集合,底层实现使用了哈希表(hash table)。

具体来说,Go 语言中的 map 实际上是一个指向哈希表的指针。哈希表本身是由若干个桶(bucket)组成的,每个桶包含了若干个键值对,每个键值对由一个 key 和一个 value 组成。在对 map 进行读写操作时,Go 语言会根据 key 计算出它在哈希表中的位置,然后直接访问对应的桶,从而实现高效的访问。

具体而言,当我们往 map 中添加键值对时,Go 语言会首先计算出 key 的哈希值,然后根据哈希值计算出 key 在哈希表中的位置。如果该位置还没有被占用,Go 语言会在该位置上创建一个新的桶,并把键值对放入该桶中;如果该位置已经被占用,Go 语言会在该桶中查找是否已经有一个键值对的 key 与待添加的 key 相同。
如果找到了相同的 key,就替换该键值对的 value;如果没有找到相同的 key,就将新的键值对添加到该桶的末尾。

需要注意的是,Go 语言中的 map 不是线程安全的,因此在多线程并发访问时需要使用锁等机制来保证安全。

另外,由于哈希表的大小是固定的,因此当 map 中的元素数量达到一定程度时,需要对哈希表进行扩容。

42. Go Map 扩容时机是什么?

在向 map 插入新 key 的时候,会进行条件检测,符合下面这 2 个条件,就会触发扩容

if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
  hashGrow(t, h)
  goto again // Growing the table invalidates everything, so try again
}
// 判断是否在扩容
func (h *hmap) growing() bool {
    return h.oldbuckets != nil
}

http://www.kler.cn/a/464280.html

相关文章:

  • 基层医联体医院患者历史检验检查数据的快速Python编程分析
  • Elasticsearch: 高级搜索
  • Windows平台下如何手动安装MYSQL
  • TT100K数据集, YOLO格式, COCO格式
  • 数字孪生:物联+数据打造洞察世界新视角
  • epoll 水平ET跟边缘LT触发的区别是什么
  • IJCNN2025 投稿准备
  • python中的assert和if的区别
  • ‌新手小白TikTok美区无货源:适合与否?
  • python代做/tensorflow代做/pytorch代做/keras/图像/目标检测/
  • df.groupby(‘team‘).agg({...}) 是 Pandas 中一个非常常用的聚合操作
  • 前端CSS3学习
  • [创业之路-232]:《华为闭环战略管理》-5-组织架构、业务架构、产品架构、技术架构、项目架构各自设计的原则是什么?
  • SpringCloud源码分析-Lettue Redis
  • NeurIPS 2024 | 像素级LLM实现图像视频理解、生成、分割和编辑大统一(昆仑万维等)
  • 前端如何用 canvas 做电影院选票功能
  • 【人工智能数据科学与数据处理】——深入详解数据科学与数据处理之数据获取与清洗
  • Visual Studio 2022安装教程
  • Effective C++读书笔记——item2(const,enum,inlines取代#define)
  • Java实现下载excel模板,并实现自定义下拉框
  • 应用架构模式
  • Python 列表的高级索引技巧
  • axios 实现进度监控
  • 第3章 总线
  • 搭建开源版Ceph分布式存储
  • 跨域问题解决