【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 之间的操作等。

相关推荐
Re_zero几秒前
以为用了 try-with-resources 就稳了?这三个底层漏洞让TCP双向通讯直接卡死
java·后端
前端Hardy14 分钟前
Bun 1.0 正式发布:JavaScript 运行时的新王者?启动快 5 倍,打包小 90%!
前端·javascript·面试
SimonKing14 分钟前
Fiddler抓包完全指南:从安装配置到抓包,一文讲透
java·后端·程序员
IT_陈寒25 分钟前
Python 性能提升50%的5个魔法技巧,90%的人还不知道!
前端·人工智能·后端
前端Hardy25 分钟前
别再乱写正则了!一行 regex 可能让你的网站瘫痪 10 分钟
前端·javascript·面试
前端Hardy26 分钟前
Tauri 1.0 正式发布:用 Rust 写前端,体积比 Electron 小 90%!
面试
CodeSheep1 小时前
“渐渐能理解为何不愿意雇佣35岁以上程序猿。去年换了份工作,组里4位组员其中3位40+,发现其实最大的问题并不是说精力不济卷不动”
前端·后端·程序员
摸鱼的春哥1 小时前
【实战】吃透龙虾🦞,你写的Agent也能支持Skills渐进式披露
前端·javascript·后端
明月_清风2 小时前
从“能用”到“专业”:构建生产级装饰器与三层逻辑拆解
后端·python
万少9 小时前
小龙虾(openclaw),轻松玩转自动发帖
前端·人工智能·后端