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

相关推荐
野生的编程萌新4 分钟前
从冒泡到快速排序:探索经典排序算法的奥秘(二)
c语言·开发语言·数据结构·c++·算法·排序算法
Full Stack Developme5 分钟前
Java后台生成多个Excel并用Zip打包下载
java·开发语言·excel
Brookty7 分钟前
【Java学习】锁、线程死锁、线程安全2
java·开发语言·学习·java-ee
小木话安全15 分钟前
ISO27001 高阶架构 之 支持 -2
网络·安全·职场和发展·学习方法
David爱编程19 分钟前
进程 vs 线程到底差在哪?一文吃透操作系统视角与 Java 视角的关键差异
后端
weixin_3077791328 分钟前
VS Code配置MinGW64编译backward库
开发语言·c++·vscode·算法
百锦再31 分钟前
.NET 的 WebApi 项目必要可配置项都有哪些?
java·开发语言·c#·.net·core·net
布朗克1683 小时前
Java 10 新特性及具体应用
java·开发语言·新特性·java10
ZZHow10246 小时前
JavaWeb开发_Day05
java·笔记·web
CHEN5_026 小时前
【Java虚拟机】垃圾回收机制
java·开发语言·jvm