面试题答案
一键面试设计思路
- 任务定义:使用空接口
interface{}
来表示不同类型的任务数据,定义一个结构体来包装任务和对应的处理函数。 - 数据竞争与资源同步:使用
sync.Mutex
来保护共享资源,防止数据竞争。使用sync.WaitGroup
来等待所有 goroutine 完成任务。 - 性能优化:采用工作池(worker pool)模式,避免创建过多的 goroutine 导致资源耗尽,提高整体性能。
代码实现
package main
import (
"fmt"
"sync"
)
// Task 定义任务结构体
type Task struct {
Data interface{}
Handler func(interface{})
}
// WorkerPool 定义工作池结构体
type WorkerPool struct {
Workers int
TaskQueue chan Task
WaitGroup sync.WaitGroup
Mutex sync.Mutex
}
// NewWorkerPool 创建新的工作池
func NewWorkerPool(workers int, capacity int) *WorkerPool {
return &WorkerPool{
Workers: workers,
TaskQueue: make(chan Task, capacity),
}
}
// Start 启动工作池
func (wp *WorkerPool) Start() {
for i := 0; i < wp.Workers; i++ {
wp.WaitGroup.Add(1)
go func() {
defer wp.WaitGroup.Done()
for task := range wp.TaskQueue {
task.Handler(task.Data)
}
}()
}
}
// Stop 停止工作池
func (wp *WorkerPool) Stop() {
close(wp.TaskQueue)
wp.WaitGroup.Wait()
}
func main() {
wp := NewWorkerPool(3, 10)
wp.Start()
// 添加不同类型任务
wp.TaskQueue <- Task{
Data: "Hello, World!",
Handler: func(data interface{}) {
fmt.Println("处理字符串任务:", data)
},
}
wp.TaskQueue <- Task{
Data: 42,
Handler: func(data interface{}) {
fmt.Println("处理整数任务:", data)
},
}
wp.Stop()
}
性能测试方案
- 测试工具:使用 Go 自带的
testing
包进行性能测试。 - 测试场景:模拟大量不同类型的任务,测试工作池在不同任务数量和工作线程数下的性能表现。
- 测试指标:记录任务处理的总时间、平均处理时间等指标。
package main
import (
"testing"
)
func BenchmarkWorkerPool(b *testing.B) {
for n := 0; n < b.N; n++ {
wp := NewWorkerPool(3, 1000)
wp.Start()
for i := 0; i < 1000; i++ {
if i%2 == 0 {
wp.TaskQueue <- Task{
Data: fmt.Sprintf("任务 %d", i),
Handler: func(data interface{}) {
// 模拟处理任务
},
}
} else {
wp.TaskQueue <- Task{
Data: i,
Handler: func(data interface{}) {
// 模拟处理任务
},
}
}
}
wp.Stop()
}
}
在命令行中运行 go test -bench=.
即可进行性能测试。通过分析测试结果,可以进一步优化工作池的参数设置,如工作线程数、任务队列容量等,以提高并发处理性能。