MST
星途 面试题库

面试题:Go语言中闭包在并发编程面临哪些常见的安全性问题

请阐述在Go语言并发编程场景下,闭包可能出现的安全性相关问题,并举例说明如何产生这些问题。
21.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

闭包在Go语言并发编程场景下安全性相关问题

  1. 数据竞争问题
    • 问题阐述:当多个goroutine通过闭包访问和修改共享变量时,可能会出现数据竞争。由于Go语言的并发执行特性,多个goroutine可能同时访问和修改同一变量,导致结果不可预测。
    • 示例
package main

import (
    "fmt"
    "sync"
)

func main() {
    var num int
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            num++
        }()
    }
    wg.Wait()
    fmt.Println("Final value of num:", num)
}
  • 分析:在上述代码中,多个goroutine通过闭包访问和修改num变量。由于没有同步机制,不同goroutine对num的操作可能会相互干扰,导致最终num的值不一定是10。
  1. 闭包变量捕获延迟问题
    • 问题阐述:在循环中创建闭包时,如果闭包捕获了循环变量,可能会出现变量值并非如预期那样在闭包创建时被固定,而是在闭包执行时获取循环变量的当前值。在并发场景下,这种延迟捕获可能导致意外结果。
    • 示例
package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    var results []func()
    for i := 0; i < 3; i++ {
        wg.Add(1)
        results = append(results, func() {
            defer wg.Done()
            fmt.Println(i)
        })
    }
    for _, f := range results {
        f()
    }
    wg.Wait()
}
  • 分析:这里闭包捕获了循环变量i。预期输出是0、1、2,但实际输出可能是3、3、3。因为闭包捕获的是i的引用,当闭包执行时,i已经变成了循环结束后的最终值3。