MST

星途 面试题库

面试题:Go中固定worker工作池代码复用技巧之基础理解

在Go语言的固定worker工作池场景下,简述如何复用已有的worker goroutine来处理不同类型但类似的任务,比如同时处理文件读取和数据计算任务,假设这两个任务的输入输出类型已经定义好。
38.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 定义任务接口
    • 首先定义一个通用的任务接口,该接口包含一个执行方法,用于执行具体的任务逻辑。例如:
    type Task interface {
        Execute()
    }
    
  2. 定义文件读取任务和数据计算任务结构体并实现接口
    • 文件读取任务
    type FileReadTask struct {
        // 假设这里有文件路径等相关输入参数
        filePath string
        // 输出结果
        result []byte
    }
    func (f *FileReadTask) Execute() {
        // 实现文件读取逻辑,将结果存入f.result
        // 示例代码(这里省略实际文件读取的完整逻辑,使用ioutil.ReadFile为例)
        data, err := ioutil.ReadFile(f.filePath)
        if err == nil {
            f.result = data
        }
    }
    
    • 数据计算任务
    type DataCalcTask struct {
        // 假设这里有输入数据参数
        inputData []int
        // 输出结果
        result int
    }
    func (d *DataCalcTask) Execute() {
        // 实现数据计算逻辑,将结果存入d.result
        sum := 0
        for _, num := range d.inputData {
            sum += num
        }
        d.result = sum
    }
    
  3. 创建工作池
    • 创建固定数量的worker goroutine,并通过通道接收任务。
    func worker(workerID int, taskChan chan Task) {
        for task := range taskChan {
            task.Execute()
        }
    }
    func createWorkerPool(numWorkers int) chan Task {
        taskChan := make(chan Task)
        for i := 0; i < numWorkers; i++ {
            go worker(i, taskChan)
        }
        return taskChan
    }
    
  4. 提交任务到工作池
    • 可以在需要的时候创建不同类型的任务实例,并提交到工作池的任务通道中。
    func main() {
        taskChan := createWorkerPool(5)
        // 提交文件读取任务
        fileTask := &FileReadTask{filePath: "test.txt"}
        taskChan <- fileTask
        // 提交数据计算任务
        calcTask := &DataCalcTask{inputData: []int{1, 2, 3, 4, 5}}
        taskChan <- calcTask
        close(taskChan)
        // 可以在这里等待所有任务完成(例如通过sync.WaitGroup等方式)
    }
    

通过以上步骤,在Go语言的固定worker工作池场景下,就可以复用已有的worker goroutine来处理不同类型但类似的任务。每个worker goroutine通过统一的任务接口来执行不同类型任务的具体逻辑。