面试题答案
一键面试可能出现的问题
- 数据竞争:匿名函数引用外部变量,多个并发的匿名函数同时读写这些变量时,会产生数据竞争。例如,多个goroutine同时对一个共享的计数器变量进行自增操作,可能导致最终结果与预期不符。
- 变量作用域与生命周期混淆:闭包会延长所引用变量的生命周期,如果在循环中创建闭包并引用循环变量,可能导致所有闭包引用的是同一个最终值,而不是每次循环的不同值。
正确示例
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
numbers := []int{1, 2, 3, 4, 5}
for _, num := range numbers {
wg.Add(1)
// 使用局部变量numCopy,避免闭包引用同一个循环变量
numCopy := num
go func() {
defer wg.Done()
// 这里可以进行一些并发任务处理,例如对numCopy进行操作
result := numCopy * numCopy
fmt.Printf("The square of %d is %d\n", numCopy, result)
}()
}
wg.Wait()
}
在上述示例中,通过在循环内部创建一个局部变量numCopy
,每个闭包引用的是不同的局部变量,避免了闭包引用同一个循环变量的问题。同时,通过sync.WaitGroup
来等待所有goroutine完成,确保程序在所有并发任务执行完毕后再退出。