面试题答案
一键面试- 执行逻辑:
- 当
select
语句中有多个通道操作(接收或发送)同时准备好时,Go会随机选择其中一个分支执行。这是为了防止某个通道操作总是优先于其他操作执行,从而保证公平性。
- 当
- 避免潜在竞争条件:
- 竞争条件通常发生在多个goroutine同时访问和修改共享资源时。为了避免在
select
语句相关场景中的竞争条件,可以使用互斥锁(sync.Mutex
)来保护共享资源,或者使用无锁数据结构(如sync.Map
)。
- 竞争条件通常发生在多个goroutine同时访问和修改共享资源时。为了避免在
- 代码示例:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
sharedData := 0
ch1 := make(chan int)
ch2 := make(chan int)
// 模拟向通道发送数据
go func() {
defer wg.Done()
ch1 <- 10
}()
go func() {
defer wg.Done()
ch2 <- 20
}()
wg.Add(2)
select {
case data := <-ch1:
mu.Lock()
sharedData += data
mu.Unlock()
fmt.Printf("Received from ch1: %d, Shared data: %d\n", data, sharedData)
case data := <-ch2:
mu.Lock()
sharedData += data
mu.Unlock()
fmt.Printf("Received from ch2: %d, Shared data: %d\n", data, sharedData)
}
}
在上述代码中:
- 定义了两个通道
ch1
和ch2
,并在两个不同的goroutine中向通道发送数据。 - 使用
select
语句从两个通道中接收数据。 - 由于
sharedData
是共享资源,使用sync.Mutex
来保护对sharedData
的修改,从而避免竞争条件。无论select
语句随机选择哪个分支,都能保证sharedData
的安全修改。