MST

星途 面试题库

面试题:Go 中函数与协程如何通过 channel 进行简单协作

请编写一段 Go 代码,展示一个函数启动若干个协程,这些协程通过 channel 与主函数进行数据交互,例如协程将计算结果发送给主函数,主函数接收并打印结果。解释代码中 channel 的作用及使用方式。
29.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

func worker(id int, resultChan chan int) {
    // 模拟计算
    res := id * id
    resultChan <- res
}

func main() {
    numWorkers := 3
    resultChan := make(chan int, numWorkers)

    for i := 1; i <= numWorkers; i++ {
        go worker(i, resultChan)
    }

    for i := 1; i <= numWorkers; i++ {
        result := <-resultChan
        fmt.Printf("Received result from worker: %d\n", result)
    }

    close(resultChan)
}

channel 的作用及使用方式

  1. 作用
    • 在 Go 语言中,channel 用于在不同的 goroutine 之间进行通信和同步。它提供了一种类型安全的方式来传递数据,确保数据的一致性和避免竞态条件。在这段代码中,channel resultChan 被用于从各个 worker 协程向主函数传递计算结果。
  2. 使用方式
    • 创建resultChan := make(chan int, numWorkers) 创建了一个带缓冲的 channel,类型为 int,缓冲大小为 numWorkers。如果不带缓冲大小参数,就是无缓冲 channel。
    • 发送数据:在 worker 函数中,resultChan <- res 将计算结果 res 发送到 resultChan 这个 channel 中。
    • 接收数据:在 main 函数中,result := <-resultChanresultChan 接收数据,并将其赋值给 result 变量。
    • 关闭 channelclose(resultChan) 用于关闭 channel,向已关闭的 channel 发送数据会导致运行时错误,但从已关闭的 channel 接收数据会返回零值(如果 channel 为空),直到 channel 完全关闭。在这段代码中,虽然主函数接收完所有数据后关闭 channel 不是必需的(因为程序即将结束),但在更复杂的场景下,显式关闭 channel 是良好的实践。