MST

星途 面试题库

面试题:Go语言扇出扇入模式在复杂任务中的应用

假设你有一个需求,需要从多个API(比如三个不同的天气API)获取天气数据,每个API的请求和解析逻辑不同,但最终要将这些API返回的数据合并处理(例如,求平均温度等)。请使用Go语言的扇出扇入模式实现这个功能,说明整体设计思路并编写核心代码。
28.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 扇出:使用多个goroutine并发地调用不同的天气API,每个goroutine负责一个API的请求和解析。
  2. 扇入:通过多个channel接收每个goroutine返回的数据,然后在一个goroutine中从这些channel中收集数据并进行合并处理。

核心代码

package main

import (
    "fmt"
    "sync"
)

// WeatherData 定义天气数据结构
type WeatherData struct {
    Temperature float64
}

// FetchWeatherFromAPI1 模拟从API1获取天气数据
func FetchWeatherFromAPI1(resultChan chan<- WeatherData) {
    // 实际这里是调用API1并解析数据
    data := WeatherData{Temperature: 25.0}
    resultChan <- data
    close(resultChan)
}

// FetchWeatherFromAPI2 模拟从API2获取天气数据
func FetchWeatherFromAPI2(resultChan chan<- WeatherData) {
    // 实际这里是调用API2并解析数据
    data := WeatherData{Temperature: 23.0}
    resultChan <- data
    close(resultChan)
}

// FetchWeatherFromAPI3 模拟从API3获取天气数据
func FetchWeatherFromAPI3(resultChan chan<- WeatherData) {
    // 实际这里是调用API3并解析数据
    data := WeatherData{Temperature: 27.0}
    resultChan <- data
    close(resultChan)
}

// MergeWeatherData 合并天气数据
func MergeWeatherData(api1Chan, api2Chan, api3Chan <-chan WeatherData) WeatherData {
    var wg sync.WaitGroup
    wg.Add(3)

    var totalTemp float64
    var count int

    go func() {
        for data := range api1Chan {
            totalTemp += data.Temperature
            count++
        }
        wg.Done()
    }()

    go func() {
        for data := range api2Chan {
            totalTemp += data.Temperature
            count++
        }
        wg.Done()
    }()

    go func() {
        for data := range api3Chan {
            totalTemp += data.Temperature
            count++
        }
        wg.Done()
    }()

    go func() {
        wg.Wait()
        avgTemp := totalTemp / float64(count)
        mergedData := WeatherData{Temperature: avgTemp}
        fmt.Println("Merged Data:", mergedData)
    }()

    return WeatherData{}
}

func main() {
    api1Chan := make(chan WeatherData)
    api2Chan := make(chan WeatherData)
    api3Chan := make(chan WeatherData)

    go FetchWeatherFromAPI1(api1Chan)
    go FetchWeatherFromAPI2(api2Chan)
    go FetchWeatherFromAPI3(api3Chan)

    MergeWeatherData(api1Chan, api2Chan, api3Chan)
}