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

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/UWz06

📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~

❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

61. 如何实现 Map 线程安全

如果想实现 map 线程安全,有两种方式:

  1. 使用读写锁 map + sync.RWMutex
go 复制代码
package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var lock sync.RWMutex
    s := make(map[int]int)
    for i := 0; i < 100; i++ {
        go func(i int) {
            lock.Lock()
            s[i] = i
            lock.Unlock()
        }(i)
    }
    for i := 0; i < 100; i++ {
        go func(i int) {
            lock.RLock()
            fmt.Printf("map第%d个元素值是%d
", i, s[i])
            lock.RUnlock()
        }(i)
    }
    time.Sleep(1 * time.Second)
}
  1. 使用 Go 提供的 sync.Map
go 复制代码
package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var m sync.Map
    for i := 0; i < 100; i++ {
        go func(i int) {
            m.Store(i, i)
        }(i)
    }
    for i := 0; i < 100; i++ {
        go func(i int) {
            v, ok := m.Load(i)
            fmt.Printf("Load: %v, %v
", v, ok)
        }(i)
    }
    time.Sleep(1 * time.Second)
}

62. Go map 和 sync.Map 谁的性能好,为什么?

Go 语言的 sync.Map 支持并发读写,采取 "空间换时间" 的机制,冗余了两个数据结构,分别是:read 和 dirty。

go 复制代码
type Map struct {
   mu Mutex
   read atomic.Value // readOnly
   dirty map[interface{}]*entry
   misses int
}

对比原始 map:

和原始 map + RWLock 的实现并发的方式相比,减少了加锁对性能的影响。它做了一些优化:可以无锁访问 read map,而且会优先操作 read map,倘若只操作 read map 就可以满足要求,那就不用去操作 write map (dirty),所以在某些特定场景中它发生锁竞争的频率会远远小于 map + RWLock 的实现方式。

优点:

适合读多写少的场景。

缺点:

写多的场景,会导致 read map 缓存失效,需要加锁,冲突变多,性能急剧下降。

63. 介绍一下 Channel

在 Go 语言中,Channel(通道)是用于多个 Goroutine 之间进行通信的一种机制,通过它们可以安全地传递数据。

Channel 是一种类型,可以使用内置的 make() 函数来创建它们。创建 Channel 时,需要指定它们可以传输的数据类型。

使用 Channel 时,可以在 Goroutine 之间传递数据,通过它们可以进行同步和异步的操作。在使用 Channel 时,需要注意以下几点:

  1. Channel 是引用类型,可以像 Slice 和 Map 一样传递给函数。
  2. 默认情况下,Channel 是无缓冲的,只有当有 Goroutine 准备好接收数据时,发送操作才会成功。如果发送操作没有被接收,发送的 Goroutine 将会阻塞。
  3. 通过 make() 函数创建带缓冲的 Channel 时,可以指定缓冲区的大小。在缓冲区没有被填满之前,发送操作不会阻塞。
  4. Channel 支持多路复用,可以使用 select 语句在多个 Channel 上进行选择和等待。
  5. Channel 可以用于控制 Goroutine 的执行,例如通过关闭 Channel 来通知 Goroutine 退出。

使用 Channel 可以帮助解决并发编程中的一些常见问题,例如避免竞态条件、协调不同 Goroutine 之间的操作等。

相关推荐
RPGMZ12 分钟前
RPGMZ游戏引擎 一个窗口 文本居中显示
开发语言·javascript·游戏引擎·rpgmz
爱看大明王朝15667 小时前
磁件学习-磁性元器件的极限计算
笔记·学习
问心无愧05137 小时前
ctf show web入门 40
笔记
庞轩px8 小时前
第七篇:Spring扩展点——如何优雅地介入Bean的创建流程
java·后端·spring·bean·aware·扩展点
ltl8 小时前
Q/K/V 三件套:把 Bahdanau 抽象成一个公式
后端
代钦塔拉8 小时前
Qt4 vs Qt5 带参数信号槽的连接方式详解
开发语言·数据库·qt
@蓝莓果粒茶9 小时前
【Unity笔记】保姆级AssetBundle详解(含代码+避坑指南)
笔记·游戏·unity
kobesdu9 小时前
【ROS2实战笔记-20】ROS2 bag 录播与时间模拟:从基础操作到高级调试技巧
笔记·机器人·ros·ros2
千叶风行10 小时前
Text-to-SQL 技术设计与注意事项
前端·人工智能·后端
InfinteJustice10 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft