面试题答案
一键面试- recover 和 defer 的协同工作原理:
- defer:在Go语言中,
defer
语句用于延迟函数的执行。当包含defer
语句的函数执行到结束时(正常结束或者因为panic
异常结束),defer
语句后面指定的函数会按照后进先出(LIFO)的顺序依次执行。 - recover:
recover
是一个内置函数,用于终止panic
造成的程序崩溃。它只能在defer
修饰的函数中有效。当panic
发生时,程序会立即停止当前函数的执行,开始执行defer
函数,若在defer
函数中调用recover
,它会捕获到panic
时传入的参数,从而使程序从panic
状态中恢复,继续执行后续代码。
- defer:在Go语言中,
- 为什么将recover放在defer函数中使用:
panic
会立即终止当前函数的正常执行流程,直接执行defer
函数。如果recover
不放在defer
函数中,panic
发生时会跳过recover
,导致程序崩溃。而在defer
函数中,recover
可以捕获到panic
,并处理它,从而使程序恢复正常执行。
- Web服务处理HTTP请求利用recover和defer记录错误日志并返回友好响应的代码实现:
package main
import (
"fmt"
"log"
"net/http"
)
func handleRequest(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
// 记录错误日志
log.Printf("Panic occurred: %v", err)
// 返回友好的错误响应
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}()
// 模拟可能发生panic的代码
panic("Simulated panic")
}
func main() {
http.HandleFunc("/", handleRequest)
log.Println("Server is running on http://localhost:8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("Server failed to start: ", err)
}
}
在上述代码中:
defer
函数在handleRequest
函数结束时(无论是正常结束还是panic
结束)都会执行。recover
在defer
函数中捕获panic
,记录错误日志并向客户端返回一个HTTP 500错误响应。这样可以确保即使在处理HTTP请求时发生panic
,程序也不会崩溃,而是能正确处理错误并向客户端返回友好的错误信息。