MST

星途 面试题库

面试题:Go匿名函数在并发编程中的复杂应用

在Go的并发编程场景下,有多个协程需要执行一些任务,这些任务的执行结果需要汇总并做进一步处理。请使用匿名函数结合通道(channel)实现一个功能,该功能能够并发执行多个任务,每个任务模拟一个网络请求(通过time.Sleep模拟延迟),并最终将所有任务的结果汇总输出。说明匿名函数在这个过程中起到的作用以及如何避免可能出现的死锁情况。
19.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "time"
)

func main() {
    numTasks := 5
    resultsChan := make(chan int, numTasks)
    defer close(resultsChan)

    for i := 0; i < numTasks; i++ {
        go func(taskID int) {
            // 模拟网络请求延迟
            time.Sleep(time.Duration(taskID+1) * time.Second)
            result := taskID * 10
            resultsChan <- result
        }(i)
    }

    var allResults []int
    for i := 0; i < numTasks; i++ {
        allResults = append(allResults, <-resultsChan)
    }

    fmt.Println("汇总结果:", allResults)
}

匿名函数的作用

  1. 封装任务逻辑:每个匿名函数封装了一个独立的任务逻辑,这里是模拟网络请求延迟并生成结果,使得代码逻辑更加清晰,易于维护和管理。
  2. 并发执行:通过go关键字启动匿名函数作为协程,实现了多个任务的并发执行,提高了程序的执行效率。

避免死锁的方法

  1. 合理使用通道
    • 缓冲通道:创建resultsChan时使用了带缓冲的通道make(chan int, numTasks),这样在向通道发送数据时,不会立刻阻塞,直到缓冲区满。
    • 及时关闭通道:在main函数开始处使用defer close(resultsChan),确保在main函数结束前关闭通道,避免接收端因通道未关闭而一直阻塞。
  2. 确保接收和发送的平衡:在main函数中,通过for循环接收numTasks次数据,保证了接收数据的次数与发送数据的次数一致,避免因接收端接收次数不足导致发送端一直阻塞。