面试题答案
一键面试-
设计方案:
- 使用一个有缓冲的通道(buffer channel)来控制并发数量,通道的容量设置为10,这样同一时间最多只有10个任务可以在通道中,也就是最多10个任务同时执行。
- 使用
WaitGroup
来等待所有任务完成。WaitGroup
的计数器初始化为100,每个任务开始时调用wg.Add(1)
,任务结束时调用wg.Done()
。 - 在主函数中,使用一个循环来创建100个任务,每个任务尝试向通道中发送一个信号,获取执行许可,执行完任务后从通道中接收信号,释放执行许可。
-
核心代码实现:
package main
import (
"fmt"
"sync"
)
func task(id int, wg *sync.WaitGroup, sem chan struct{}) {
defer wg.Done()
sem <- struct{}{} // 获取执行许可
defer func() { <-sem }() // 释放执行许可
// 模拟任务执行时间不定
fmt.Printf("Task %d is running\n", id)
// 这里可以替换为实际的任务逻辑
}
func main() {
var wg sync.WaitGroup
sem := make(chan struct{}, 10)
for i := 0; i < 100; i++ {
wg.Add(1)
go task(i, &wg, sem)
}
wg.Wait()
fmt.Println("All tasks completed")
}
在上述代码中:
task
函数代表具体的任务,接收任务ID、WaitGroup
指针和信号通道。在函数开始时向通道发送信号获取执行许可,结束时从通道接收信号释放许可。main
函数中创建了一个容量为10的信号通道sem
和WaitGroup
。通过循环创建100个goroutine
来执行任务,每个任务开始前调用wg.Add(1)
,最后通过wg.Wait()
等待所有任务完成。