MST
星途 面试题库

面试题:Go命名类型在并发场景下的应用

在Go语言的并发编程中,设计一个场景,利用命名类型来管理多个goroutine之间共享的数据,并通过通道进行安全的数据通信,防止数据竞争。请描述整体设计思路并给出核心代码片段。
34.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义命名类型:创建一个结构体来表示共享数据,将相关的数据和操作封装在一起,增强代码的可读性和维护性。
  2. 使用互斥锁:在命名类型的结构体中嵌入一个sync.Mutex来保护共享数据,防止多个goroutine同时访问造成数据竞争。
  3. 通道通信:利用通道来安全地在goroutine之间传递数据。通过通道发送和接收数据,避免直接对共享数据进行并发读写。

核心代码片段

package main

import (
    "fmt"
    "sync"
)

// 定义命名类型来管理共享数据
type SharedData struct {
    mu    sync.Mutex
    value int
}

// 定义一个函数来修改共享数据
func (sd *SharedData) updateValue(newValue int, wg *sync.WaitGroup) {
    defer wg.Done()
    sd.mu.Lock()
    sd.value = newValue
    sd.mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    sharedData := SharedData{}

    // 创建通道
    dataCh := make(chan int)

    // 启动多个goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(num int) {
            defer wg.Done()
            // 通过通道获取数据
            data := <-dataCh
            sharedData.updateValue(data, &wg)
        }(i)
    }

    // 向通道发送数据
    for i := 0; i < 5; i++ {
        dataCh <- i
    }
    close(dataCh)

    wg.Wait()
    fmt.Println("Final value:", sharedData.value)
}

在上述代码中:

  • SharedData结构体封装了共享数据value以及一个sync.Mutex来保护数据。
  • updateValue方法负责修改共享数据,在修改前加锁,修改后解锁。
  • main函数中,创建了一个通道dataCh用于在goroutine之间传递数据,启动多个goroutine从通道接收数据并更新共享数据。通过sync.WaitGroup来等待所有goroutine完成操作。