面试题答案
一键面试package main
import (
"fmt"
"sync"
"time"
)
// 并发计算函数
func concurrentCalculation(n int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < n; i++ {
_ = i * i
}
}
// 并行计算函数
func parallelCalculation(n int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < n; i++ {
_ = i * i
}
}
func main() {
numTasks := 1000000
var wg sync.WaitGroup
// 并发执行
startConcurrent := time.Now()
for i := 0; i < 4; i++ {
wg.Add(1)
go concurrentCalculation(numTasks, &wg)
}
wg.Wait()
elapsedConcurrent := time.Since(startConcurrent)
// 并行执行(这里简单模拟,实际并行依赖于多核CPU调度)
startParallel := time.Now()
for i := 0; i < 4; i++ {
wg.Add(1)
parallelCalculation(numTasks, &wg)
}
wg.Wait()
elapsedParallel := time.Since(startParallel)
fmt.Printf("并发执行时间: %s\n", elapsedConcurrent)
fmt.Printf("并行执行时间: %s\n", elapsedParallel)
if elapsedConcurrent < elapsedParallel {
fmt.Println("并发执行更快")
} else if elapsedConcurrent > elapsedParallel {
fmt.Println("并行执行更快")
} else {
fmt.Println("两者执行时间相同")
}
}
代码思路
- 并发计算:使用
go
关键字开启多个协程来执行相同的计算任务,通过sync.WaitGroup
来等待所有协程完成。 - 并行计算:这里简单地通过顺序调用函数来模拟并行(实际并行需要多核CPU支持,且调度由操作系统完成)。
- 性能对比:使用
time.Now()
记录任务开始和结束时间,通过time.Since()
计算时间差,从而对比并发和并行执行相同数量计算任务的性能。
观察结果
在多核CPU环境下,通常并发执行会比并行执行(这里简单模拟的顺序执行)更快,因为并发利用了协程的轻量级特性和Go语言的调度器,可以在同一时间片内切换执行不同任务,而并行如果只是简单顺序执行,不能充分利用多核优势。但如果计算任务非常简单且CPU核数有限,可能性能差异不明显,甚至并行执行时间更短(因为协程切换也有开销)。