面试题答案
一键面试package main
import (
"fmt"
)
func sum1(nums []int) int {
sum := 0
for _, num := range nums {
sum += num
}
return sum
}
func sum2(nums []int) int {
sum := 0
length := len(nums)
for i := 0; i < length; i++ {
sum += nums[i]
}
return sum
}
func sum3(nums []int) int {
const numWorkers = 4
var sum int
chunkSize := (len(nums) + numWorkers - 1) / numWorkers
var results = make([]int, numWorkers)
var workerFinished = make(chan bool, numWorkers)
for i := 0; i < numWorkers; i++ {
start := i * chunkSize
end := (i + 1) * chunkSize
if i == numWorkers - 1 {
end = len(nums)
}
go func(workerIndex int) {
for j := start; j < end; j++ {
results[workerIndex] += nums[j]
}
workerFinished <- true
}(i)
}
for i := 0; i < numWorkers; i++ {
<-workerFinished
}
close(workerFinished)
for _, res := range results {
sum += res
}
return sum
}
优化方式一:避免每次循环获取切片长度
- 优化前:
for _, num := range nums {
sum += num
}
在使用 range
遍历切片时,每次迭代都可能隐式地获取切片的长度。虽然Go编译器会对此进行一定的优化,但显式获取长度并在循环外部保存可以减少这种开销。
2. 优化后:
length := len(nums)
for i := 0; i < length; i++ {
sum += nums[i]
}
原理:减少了每次循环时获取切片长度的开销,因为 len
函数在每次循环中不再重复调用,提高了循环执行效率。
优化方式二:并行计算
- 优化实现:
上述代码中的
sum3
函数将切片分成多个部分,使用多个goroutine并行计算每个部分的和,最后将各个部分的和累加起来。 - 原理:利用多核CPU的并行计算能力,提高计算效率。通过将大切片分成小的块,每个goroutine独立计算一块的和,最后合并结果,减少了总的计算时间。但需要注意的是,并行计算会引入额外的调度和通信开销,所以切片数据量较小时,并行计算可能反而会降低效率。