面试题答案
一键面试代码示例
package main
import (
"fmt"
"sync"
)
func main() {
var mu sync.Mutex
data := 0
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
data++
fmt.Println("Data value:", data)
mu.Unlock()
}()
}
wg.Wait()
}
防止数据竞争
在上述代码中,使用sync.Mutex
来防止数据竞争。在访问和修改共享变量data
之前,调用mu.Lock()
锁定互斥锁,操作完成后调用mu.Unlock()
解锁互斥锁。这样,同一时间只有一个goroutine能够访问和修改data
,从而避免数据竞争。
闭包的优势
- 封装性:闭包可以将共享数据和操作数据的逻辑封装在一起,使代码结构更清晰,提高代码的可维护性。例如,在上述代码中,闭包内部封装了对
data
的操作,外部无法直接访问和修改data
,只能通过闭包提供的逻辑来操作。 - 灵活性:闭包可以在不同的上下文中使用,方便在不同的地方创建和启动goroutine,而不需要额外传递共享数据。
潜在风险
- 内存泄漏:如果闭包持有对大型对象的引用,并且这些闭包在不需要时没有被释放,可能会导致内存泄漏。例如,如果闭包引用了一个很大的数组,即使不再需要这个闭包,由于闭包持有数组的引用,数组占用的内存不会被垃圾回收器回收。
- 数据竞争风险:如果在闭包中没有正确使用同步机制(如上述代码中的
sync.Mutex
),仍然可能出现数据竞争问题,导致程序出现不可预测的行为。