面试题答案
一键面试package main
import (
"fmt"
"sync"
"time"
)
// 定义任务类型
type Task func(int) int
// 工作池结构体
type WorkerPool struct {
Workers int
TaskQueue chan Task
WaitGroup sync.WaitGroup
StopSignal chan struct{}
}
// 创建新的工作池
func NewWorkerPool(workers int, taskQueueSize int) *WorkerPool {
return &WorkerPool{
Workers: workers,
TaskQueue: make(chan Task, taskQueueSize),
StopSignal: make(chan struct{}),
}
}
// 启动工作池
func (wp *WorkerPool) Start() {
for i := 0; i < wp.Workers; i++ {
wp.WaitGroup.Add(1)
go func() {
defer wp.WaitGroup.Done()
for {
select {
case task, ok := <-wp.TaskQueue:
if!ok {
return
}
result := task(1) // 这里简单传入1作为参数示例
fmt.Printf("Worker processed task, result: %d\n", result)
case <-wp.StopSignal:
return
}
}
}()
}
}
// 停止工作池
func (wp *WorkerPool) Stop() {
close(wp.StopSignal)
close(wp.TaskQueue)
wp.WaitGroup.Wait()
}
func main() {
// 创建工作池,2个worker,任务队列大小为10
pool := NewWorkerPool(2, 10)
// 启动工作池
pool.Start()
// 添加任务
task1 := func(task int) int {
return task * 2
}
pool.TaskQueue <- task1
task2 := func(task int) int {
return task + 3
}
pool.TaskQueue <- task2
// 等待一段时间,确保任务处理完成
time.Sleep(2 * time.Second)
// 停止工作池
pool.Stop()
}
上述代码实现了一个固定worker数量的工作池:
- 定义任务类型:
Task
是一个函数类型,接受一个int
参数并返回一个int
。 - 工作池结构体:
WorkerPool
包含了worker数量、任务队列、等待组和停止信号通道。 - 创建工作池:
NewWorkerPool
函数初始化工作池。 - 启动工作池:
Start
方法启动指定数量的worker,每个worker从任务队列中取出任务并执行。 - 停止工作池:
Stop
方法发送停止信号并等待所有worker完成任务。 - 主函数:在
main
函数中,创建工作池,启动它,添加任务,等待一段时间后停止工作池。