面试题答案
一键面试误区阐述
- 忽略错误处理:在并发环境下,开发者可能会忽略
goroutine
中返回的错误,因为没有直接的机制像同步函数那样立刻捕获错误。例如,简单地启动一个goroutine
而不检查其返回值:
go func() {
result, err := someFunction()
if err != nil {
// 这里没有处理错误,错误被忽略
}
}()
- 同步问题导致错误丢失:当多个
goroutine
向同一个通道发送错误时,如果处理不当,可能会丢失错误。例如,没有使用缓冲通道或者没有正确处理通道的接收逻辑,导致部分错误没有被接收到。 - 没有正确的错误传播:在复杂的并发程序中,
goroutine
之间可能存在多层调用关系,没有正确地将底层goroutine
的错误向上传播,使得错误无法在合适的层次进行处理。
示例代码
package main
import (
"fmt"
"sync"
)
// someFunction 模拟一个可能返回错误的函数
func someFunction(id int) (string, error) {
if id%2 == 0 {
return fmt.Sprintf("Success for %d", id), nil
}
return "", fmt.Errorf("Error for %d", id)
}
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
errors := []error{}
results := []string{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
result, err := someFunction(id)
if err != nil {
mu.Lock()
errors = append(errors, err)
mu.Unlock()
return
}
mu.Lock()
results = append(results, result)
mu.Unlock()
}(i)
}
wg.Wait()
if len(errors) > 0 {
for _, err := range errors {
fmt.Println(err)
}
} else {
for _, result := range results {
fmt.Println(result)
}
}
}
在这个示例中:
- 避免忽略错误处理:每个
goroutine
都检查someFunction
返回的错误,并将错误收集到errors
切片中。 - 解决同步问题:使用
sync.Mutex
来确保在并发环境下对errors
和results
切片的安全访问,避免错误丢失。 - 正确的错误传播:错误在
goroutine
内部被捕获并收集,然后在主函数中统一处理。