MST

星途 面试题库

面试题:Go语言Mutex锁与其他同步原语结合应对复杂业务逻辑场景

假设你正在开发一个复杂的金融交易系统,其中涉及多种业务逻辑,如账户余额更新、交易记录存储等,并且要求高并发处理。在这种场景下,如何将Mutex锁与其他Go语言同步原语(如Channel、WaitGroup等)巧妙结合,以实现高效、安全的并发控制,请给出详细的设计思路和核心代码片段。
12.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. Mutex锁:用于保护共享资源,如账户余额。在对账户余额进行更新等操作时,使用Mutex锁来确保同一时间只有一个goroutine可以访问和修改余额,防止竞态条件。
  2. Channel:用于在不同的goroutine之间传递数据和信号。例如,将交易请求通过Channel发送到专门处理交易的goroutine,避免直接在多个goroutine中同时操作共享资源。还可以利用Channel进行同步,比如一个goroutine完成某项任务后通过Channel通知其他goroutine。
  3. WaitGroup:用于等待一组goroutine完成。在系统启动多个goroutine处理交易等任务时,使用WaitGroup来阻塞主线程,直到所有相关的goroutine完成工作,确保系统在所有任务完成后再进行下一步操作,比如关闭资源等。

核心代码片段

package main

import (
    "fmt"
    "sync"
)

// 定义账户结构体
type Account struct {
    balance int
    mutex   sync.Mutex
}

// 更新账户余额
func (a *Account) updateBalance(amount int) {
    a.mutex.Lock()
    a.balance += amount
    a.mutex.Unlock()
}

// 获取账户余额
func (a *Account) getBalance() int {
    a.mutex.Lock()
    defer a.mutex.Unlock()
    return a.balance
}

func main() {
    var wg sync.WaitGroup
    account := Account{}
    // 模拟交易请求通道
    transactionCh := make(chan int)

    // 启动交易处理goroutine
    go func() {
        for amount := range transactionCh {
            account.updateBalance(amount)
        }
    }()

    // 模拟多个并发交易
    numTransactions := 10
    for i := 0; i < numTransactions; i++ {
        wg.Add(1)
        go func(amount int) {
            defer wg.Done()
            transactionCh <- amount
        }(i * 10)
    }

    // 等待所有交易处理完成
    go func() {
        wg.Wait()
        close(transactionCh)
    }()

    // 等待交易处理goroutine完成所有交易
    wg.Wait()

    // 获取最终账户余额
    balance := account.getBalance()
    fmt.Printf("Final balance: %d\n", balance)
}

在上述代码中:

  • Account结构体包含余额和一个Mutex锁,用于保护余额的更新操作。
  • updateBalance方法通过Mutex锁确保余额更新的原子性。
  • main函数中创建了一个交易请求的Channel,并启动一个goroutine来处理这些交易请求。
  • 使用WaitGroup来等待所有模拟的交易goroutine完成,完成后关闭Channel,最终获取并打印账户的最终余额。