面试题答案
一键面试扇入模式实现原理
在Go语言中,扇入(Fan - In)模式是指将多个输入通道(input channels)的数据合并到一个输出通道(output channel)。它通常通过select
语句来实现。多个select
的case
语句分别监听不同的输入通道,当任意一个输入通道有数据可读时,对应的case
分支就会被执行,将数据发送到输出通道。这样就实现了从多个通道收集数据并合并到一个通道的功能。
应用场景
- 日志收集:假设有多个不同的服务产生日志,每个服务将日志写入自己的通道。通过扇入模式,可以将这些不同服务的日志通道数据合并到一个总的日志处理通道,方便统一处理日志,例如存储到文件或发送到日志分析系统。
- 并发数据处理结果汇总:当需要并发执行多个任务,并收集这些任务的结果时,可以使用扇入模式。比如在一个爬虫程序中,有多个并发的爬虫任务,每个任务将抓取到的数据写入各自的通道,通过扇入模式可以将这些数据合并到一个通道进行后续的统一处理,如数据清洗、存储等。
代码示例
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)
}
}
在上述代码中:
generateNumbers1
和generateNumbers2
函数分别向各自的通道ch1
和ch2
发送数据。fanIn
函数使用select
语句监听ch1
和ch2
,将数据发送到out
通道。当ch1
和ch2
都关闭时,out
通道也关闭。- 在
main
函数中,启动generateNumbers1
和generateNumbers2
协程,调用fanIn
函数,并从out
通道接收数据并打印。