MST

星途 面试题库

面试题:Go中如何高效组合多个无序返回结果的Channel

有多个(假设有N个)Channel,每个Channel会异步返回不同类型的任务结果(例如有的返回计算结果,有的返回文件读取结果等)。请编写代码,实现一个接收端,能够高效地接收这些结果,无论哪个Channel先返回数据都能及时处理,并且当所有Channel都关闭后,程序能够正确结束。
41.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

// 假设不同类型的任务结果结构体
type ComputeResult struct {
    Value int
}

type FileReadResult struct {
    Data string
}

func main() {
    // 假设有N个Channel
    const N = 3
    channels := make([]interface{}, N)

    // 模拟不同类型的Channel
    channels[0] = make(chan ComputeResult)
    channels[1] = make(chan FileReadResult)
    channels[2] = make(chan ComputeResult)

    // 模拟异步任务填充Channel
    go func() {
        res := ComputeResult{Value: 42}
        chanResult := channels[0].(chan ComputeResult)
        chanResult <- res
        close(chanResult)
    }()

    go func() {
        res := FileReadResult{Data: "file content"}
        chanResult := channels[1].(chan FileReadResult)
        chanResult <- res
        close(chanResult)
    }()

    go func() {
        res := ComputeResult{Value: 100}
        chanResult := channels[2].(chan ComputeResult)
        chanResult <- res
        close(chanResult)
    }()

    // 接收端
    var countClosed int
    for {
        select {
        case res, ok := <-channels[0].(chan ComputeResult):
            if ok {
                fmt.Printf("Received ComputeResult: %d\n", res.Value)
            } else {
                countClosed++
            }
        case res, ok := <-channels[1].(chan FileReadResult):
            if ok {
                fmt.Printf("Received FileReadResult: %s\n", res.Data)
            } else {
                countClosed++
            }
        case res, ok := <-channels[2].(chan ComputeResult):
            if ok {
                fmt.Printf("Received ComputeResult: %d\n", res.Value)
            } else {
                countClosed++
            }
        }
        if countClosed == N {
            break
        }
    }
}

上述代码使用Go语言实现,通过select语句监听多个不同类型的Channel,无论哪个Channel先返回数据都能及时处理,并且通过记录关闭的Channel数量,当所有Channel都关闭后程序正确结束。不同类型的任务结果通过不同的结构体表示,Channel也相应地使用对应类型。实际应用中,任务的异步填充部分可以替换为真实的异步任务逻辑。