面试题答案
一键面试设计思路
- 使用defer和recover:在每个goroutine内部使用
defer
关键字注册一个函数,在这个函数中使用recover
来捕获panic
。这样即使某个goroutine发生panic
,也能被捕获并处理,避免整个程序崩溃。 - 资源管理:对于共享资源,使用
sync
包中的工具,如sync.Mutex
来保证在多个goroutine访问时的数据一致性。同时,在defer
中确保释放任何已获取的资源,如文件描述符等。
关键代码示例
package main
import (
"fmt"
"sync"
)
// 模拟一个可能会panic的函数
func riskyFunction(id int) {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Goroutine %d panicked: %v\n", id, r)
}
}()
// 模拟可能会导致panic的操作
if id == 3 {
panic("Simulated panic in goroutine 3")
}
fmt.Printf("Goroutine %d is working normally\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
riskyFunction(id)
}(i)
}
wg.Wait()
fmt.Println("All goroutines have finished")
}
在上述代码中:
riskyFunction
函数模拟了可能会发生panic
的操作。通过defer
和recover
,当panic
发生时,能捕获并打印出相关信息,而不会影响其他goroutine。- 在
main
函数中,启动了5个goroutine,每个goroutine都调用riskyFunction
,并使用sync.WaitGroup
来等待所有goroutine完成。这样确保了所有goroutine都执行完毕后main
函数才结束。