MST

星途 面试题库

面试题:Go函数式编程与并发编程的结合优化

Go语言在并发编程方面有出色的表现,结合函数式编程思想,设计一个高并发的任务处理系统。该系统需要处理大量的任务,每个任务可以用函数表示,使用函数式编程的方式实现任务的分发、执行和结果收集。同时,要考虑系统的性能优化,例如避免资源竞争、合理利用goroutine和channel等并发原语。请详细说明设计思路,并给出核心代码片段。
42.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 任务分发:将任务封装成函数,并通过一个任务队列(可以使用channel实现)来接收这些任务。
  2. 任务执行:启动多个goroutine来从任务队列中取出任务并执行。每个goroutine作为一个工作者(worker),负责处理单个任务。
  3. 结果收集:每个任务执行完成后,将结果发送到另一个channel,主程序从这个结果channel中收集所有任务的执行结果。
  4. 性能优化
    • 避免资源竞争:使用channel作为通信机制,因为channel本身是线程安全的,通过它来传递任务和结果可以有效避免资源竞争。
    • 合理利用goroutine:根据系统的CPU核心数和可用内存,合理设置goroutine的数量。过多的goroutine可能导致上下文切换开销增大,过少则无法充分利用系统资源。
    • 缓冲channel:在任务队列和结果收集channel上使用适当的缓冲区,可以减少阻塞,提高并发性能。

核心代码片段

package main

import (
    "fmt"
)

// Task 定义任务类型,是一个返回结果的函数
type Task func() interface{}

// Worker 定义工作者函数,从任务队列中取任务并执行,将结果发送到结果队列
func Worker(taskQueue <-chan Task, resultQueue chan<- interface{}) {
    for task := range taskQueue {
        result := task()
        resultQueue <- result
    }
}

// RunTasks 启动任务处理系统,分发任务并收集结果
func RunTasks(tasks []Task, workerCount int) []interface{} {
    taskQueue := make(chan Task, len(tasks))
    resultQueue := make(chan interface{}, len(tasks))

    // 启动工作者
    for i := 0; i < workerCount; i++ {
        go Worker(taskQueue, resultQueue)
    }

    // 分发任务
    for _, task := range tasks {
        taskQueue <- task
    }
    close(taskQueue)

    // 收集结果
    var results []interface{}
    for i := 0; i < len(tasks); i++ {
        results = append(results, <-resultQueue)
    }
    close(resultQueue)

    return results
}

func main() {
    // 示例任务
    tasks := []Task{
        func() interface{} { return "Task 1 result" },
        func() interface{} { return "Task 2 result" },
        func() interface{} { return "Task 3 result" },
    }

    // 运行任务
    results := RunTasks(tasks, 2)
    fmt.Println(results)
}

在上述代码中:

  1. Task是一个函数类型,代表单个任务。
  2. Worker函数是一个goroutine,从taskQueue中取出任务并执行,将结果发送到resultQueue
  3. RunTasks函数负责初始化任务队列、结果队列,启动工作者goroutine,分发任务并收集结果。
  4. main函数中,创建了一些示例任务并调用RunTasks函数执行任务并获取结果。