MST
星途 面试题库

面试题:Go语言Map在高并发场景下的处理及优化

在高并发环境中,Go语言的Map不是线程安全的。请描述至少两种在高并发场景下安全使用Map的方法,并说明每种方法的优缺点。同时,给出一个示例代码,展示如何使用其中一种方法在多个goroutine中安全地读写Map。
12.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

方法一:使用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.Mutexsync.RWMutex,特别是在高并发场景下。
  • 缺点:引入了第三方依赖,增加了项目复杂度和维护成本。