不少人面试都挂在这道题了!你挂了吗?

能看到这篇文章一定是特殊的缘分,请务必珍惜,请详细看看吧,哈哈。

图片图片

不止上图,最近 Go就业训练营 中不少小伙伴说,面试中碰到了好几次让手撕协程池的公司。

解题思路:

  • 定义协程池结构体:首先,我们需要定义一个协程池的结构体,包含协程池的属性和方法。结构体中需要包含一个任务队列、协程池的大小、当前运行的协程数量等属性。
  • 初始化协程池:在初始化函数中,我们需要创建一个指定大小的任务队列,并初始化协程池的属性。
  • 添加任务到协程池:当有任务需要执行时,我们将任务添加到任务队列中。
  • 启动协程池:在启动函数中,我们需要根据协程池的大小创建对应数量的协程,并从任务队列中获取任务进行执行。每个协程会不断从任务队列中获取任务并执行,直到任务队列为空。
  • 控制协程数量:在协程池中,我们需要控制同时运行的协程数量,以防止过多的协程导致资源浪费。可以使用信号量或者计数器来控制协程的数量。
  • 通过以上的解题思路,我们可以实现一个基本的协程池。

    在实际应用中,可能还需要考虑一些其他的因素,如任务优先级、任务超时处理等。根据具体的需求,可以对协程池进行进一步的扩展和优化。

    说完了解题思路,再给大家一个可参考,可运行的示例代码:

    示例代码:

    package main
    
    import (
            "fmt"
            "sync"
    )
    
    type Job struct {
            ID int
    }
    
    type Worker struct {
            ID         int
            JobChannel chan Job
            Quit       chan bool
    }
    
    type Pool struct {
            WorkerNum   int
            JobChannel  chan Job
            WorkerQueue chan chan Job
            Quit        chan bool
            wg          sync.WaitGroup
    }
    
    // NewWorker 创建一个新的工作者
    func NewWorker(id int, workerQueue chan chan Job) Worker {
            return Worker{
                    ID:         id,
                    JobChannel: make(chan Job),
                    Quit:       make(chan bool),
            }
    }
    
    // Start 启动工作者
    func (w Worker) Start(workerQueue chan chan Job) {
            go func() {
                    for {
                            workerQueue