MST

星途 面试题库

面试题:Go并发编程中,如何根据业务场景选择合适的并发模型以避免资源竞争

假设你正在开发一个微服务,该服务需要频繁读取和更新共享资源,在Go语言环境下,描述你会如何利用并发特性来提高性能,同时通过合理的并发模型(如使用sync包中的工具等)避免资源竞争问题,给出具体的思路和关键代码片段。
13.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 思路
    • 使用goroutine实现并发:利用Go语言的goroutine来并发执行读取和更新操作,以充分利用多核CPU资源,提高性能。
    • 使用互斥锁(Mutex)避免资源竞争:当多个goroutine需要访问共享资源时,通过sync.Mutex来保证同一时间只有一个goroutine可以访问共享资源,从而避免资源竞争。
    • 读写锁(RWMutex)优化读操作:由于读取操作频繁,可以使用sync.RWMutex,允许多个读操作同时进行,而写操作时则独占资源,这样在读多写少的场景下能进一步提高性能。
  2. 关键代码片段
package main

import (
    "fmt"
    "sync"
)

// 定义共享资源
var sharedResource int

// 定义读写锁
var rwMutex sync.RWMutex

// 读操作函数
func readResource(wg *sync.WaitGroup) {
    defer wg.Done()
    // 读锁,允许多个读操作同时进行
    rwMutex.RLock()
    defer rwMutex.RUnlock()
    fmt.Printf("Read resource: %d\n", sharedResource)
}

// 写操作函数
func writeResource(wg *sync.WaitGroup, value int) {
    defer wg.Done()
    // 写锁,独占资源
    rwMutex.Lock()
    defer rwMutex.Unlock()
    sharedResource = value
    fmt.Printf("Write resource: %d\n", sharedResource)
}

func main() {
    var wg sync.WaitGroup

    // 模拟多个读操作
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go readResource(&wg)
    }

    // 模拟多个写操作
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go writeResource(&wg, i*10)
    }

    wg.Wait()
}

在上述代码中:

  • sharedResource是共享资源。
  • rwMutexsync.RWMutex类型的读写锁。
  • readResource函数使用读锁RLock来读取共享资源,允许多个读操作并发执行。
  • writeResource函数使用写锁Lock来更新共享资源,保证写操作的原子性,避免资源竞争。
  • main函数中,通过WaitGroup来等待所有goroutine执行完毕,模拟了多个读操作和写操作的并发执行场景。