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

相关推荐
进阶的DW8 分钟前
Wiki + Graph + RAG 知识库建设笔记2
笔记
AOwhisky9 分钟前
Linux(CentOS)系统管理入门笔记(第四期)——文件系统(下篇):文件与目录操作实战——cpmvmkdirrmln
linux·运维·笔记·centos·云计算·文件系统
nianniannnn10 分钟前
c++复习自存--标准模板库STL
开发语言·c++·windows
努力努力再努力wz19 分钟前
【高性能网络库与HTTP Server系列】:基于主从 Reactor 模型实现高性能 C++ 网络库与 HTTP Server
开发语言·网络·数据结构·数据库·c++·网络协议·http
bmy-happy21 分钟前
网安专业课程笔记sale
笔记
什巳27 分钟前
JAVA练习275-乘积最大子数组
java·开发语言·数据结构·算法
lang2015092831 分钟前
Apache POI Word(docx) 实战教程:从入门到精通表格合并、图片插入与文档合并
java·开发语言·word
树獭叔叔33 分钟前
从 Search 到 Extract:AI Agent 网页工具架构拆解
后端·agent·ai编程
Robot_Nav34 分钟前
C++ 面试常问问题汇总:基础语法、面向对象、STL、多线程与设计模式
c++·设计模式·面试
wear工程师35 分钟前
腾讯天美一面:从 HashMap 到 Spring 事务,面试官这套连环问到底在考什么
java·面试