MST

星途 面试题库

面试题:Go语言变量声明与初始化在并发编程中的注意事项

在Go语言的并发编程场景下,变量声明与初始化可能会遇到哪些问题,如竞态条件等。如何通过合适的变量声明和初始化方式,以及同步机制来避免这些问题?请举例说明,要求代码中至少包含两个goroutine对共享变量的操作。
24.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言并发编程中,变量声明与初始化可能遇到以下问题:

  1. 竞态条件:多个goroutine同时读写共享变量,导致数据竞争,结果不可预测。

可以通过以下方式避免这些问题:

  1. 使用sync.Mutex:通过互斥锁来保护共享变量,同一时间只有一个goroutine能访问共享变量。
  2. 使用sync.RWMutex:读多写少场景下,允许并发读,写操作加锁。
  3. 使用channel:通过通道在goroutine间传递数据,避免共享变量。

以下是使用sync.Mutex的示例代码:

package main

import (
    "fmt"
    "sync"
)

var (
    counter int
    mu      sync.Mutex
)

func increment(wg *sync.WaitGroup) {
    defer wg.Done()
    mu.Lock()
    counter++
    mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final counter:", counter)
}

在上述代码中,counter是共享变量,mu是互斥锁。在increment函数中,通过mu.Lock()mu.Unlock()来保护对counter的操作,避免竞态条件。

使用channel的示例代码如下:

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)
    var sum int

    go func() {
        for i := 1; i <= 10; i++ {
            ch <- i
        }
        close(ch)
    }()

    for num := range ch {
        sum += num
    }

    fmt.Println("Final sum:", sum)
}

在这个例子中,通过channel传递数据,避免了共享变量的竞态问题。goroutinechannel发送数据,主goroutinechannel接收数据并计算总和。