MST

星途 面试题库

面试题:Go语言中扇入模式的实现原理及应用场景

请详细阐述Go语言中扇入模式的实现原理,并举例说明至少两个适合使用扇入模式的应用场景,同时给出简单的代码示例。
43.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

扇入模式实现原理

在Go语言中,扇入(Fan - In)模式是指将多个输入通道(input channels)的数据合并到一个输出通道(output channel)。它通常通过select语句来实现。多个selectcase语句分别监听不同的输入通道,当任意一个输入通道有数据可读时,对应的case分支就会被执行,将数据发送到输出通道。这样就实现了从多个通道收集数据并合并到一个通道的功能。

应用场景

  1. 日志收集:假设有多个不同的服务产生日志,每个服务将日志写入自己的通道。通过扇入模式,可以将这些不同服务的日志通道数据合并到一个总的日志处理通道,方便统一处理日志,例如存储到文件或发送到日志分析系统。
  2. 并发数据处理结果汇总:当需要并发执行多个任务,并收集这些任务的结果时,可以使用扇入模式。比如在一个爬虫程序中,有多个并发的爬虫任务,每个任务将抓取到的数据写入各自的通道,通过扇入模式可以将这些数据合并到一个通道进行后续的统一处理,如数据清洗、存储等。

代码示例

package main

import (
    "fmt"
)

func generateNumbers1(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i * 2
        // 这里简单模拟一些工作
    }
    close(ch)
}

func generateNumbers2(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i * 3
        // 这里简单模拟一些工作
    }
    close(ch)
}

func fanIn(ch1, ch2 chan int, out chan int) {
    go func() {
        for {
            select {
            case val, ok := <-ch1:
                if!ok {
                    ch1 = nil
                } else {
                    out <- val
                }
            case val, ok := <-ch2:
                if!ok {
                    ch2 = nil
                } else {
                    out <- val
                }
            }
            if ch1 == nil && ch2 == nil {
                close(out)
                return
            }
        }
    }()
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    out := make(chan int)

    go generateNumbers1(ch1)
    go generateNumbers2(ch2)

    fanIn(ch1, ch2, out)

    for val := range out {
        fmt.Println(val)
    }
}

在上述代码中:

  1. generateNumbers1generateNumbers2函数分别向各自的通道ch1ch2发送数据。
  2. fanIn函数使用select语句监听ch1ch2,将数据发送到out通道。当ch1ch2都关闭时,out通道也关闭。
  3. main函数中,启动generateNumbers1generateNumbers2协程,调用fanIn函数,并从out通道接收数据并打印。