面试题答案
一键面试方法一:使用sync.Mutex
- 优点:实现简单,适用于大多数场景,对于读写操作频率较为均衡的场景性能表现良好。
- 缺点:当并发写操作频繁时,锁的竞争会导致性能瓶颈,因为同一时间只有一个goroutine能访问Map。
示例代码:
package main
import (
"fmt"
"sync"
)
var (
mu sync.Mutex
data = make(map[string]int)
)
func write(key string, value int, wg *sync.WaitGroup) {
defer wg.Done()
mu.Lock()
data[key] = value
mu.Unlock()
}
func read(key string, wg *sync.WaitGroup) {
defer wg.Done()
mu.Lock()
value := data[key]
mu.Unlock()
fmt.Printf("Read key %s, value %d\n", key, value)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
key := fmt.Sprintf("key%d", i)
wg.Add(1)
go write(key, i, &wg)
}
for i := 0; i < 5; i++ {
key := fmt.Sprintf("key%d", i)
wg.Add(1)
go read(key, &wg)
}
wg.Wait()
}
方法二:使用sync.RWMutex
- 优点:读操作可以并发执行,适合读多写少的场景,能有效提高并发性能。
- 缺点:实现比
sync.Mutex
复杂,写操作时仍需要独占锁,若写操作频繁,性能提升有限。
方法三:使用concurrent-map
库
- 优点:开箱即用,内部采用更细粒度的锁机制(如分段锁),性能优于
sync.Mutex
和sync.RWMutex
,特别是在高并发场景下。 - 缺点:引入了第三方依赖,增加了项目复杂度和维护成本。