面试题答案
一键面试1. context把控资源释放时机原理
在Go语言中,context
通过携带截止时间、取消信号等信息,在多个goroutine之间传递。当父context
被取消或超时时,所有基于该父context
衍生的子context
也会被取消,从而通知相关的goroutine及时停止工作并释放资源。
2. HTTP服务函数中利用context控制数据库连接资源释放示例
假设我们使用database/sql
包连接MySQL数据库,示例代码如下:
package main
import (
"context"
"database/sql"
"fmt"
"net/http"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test")
if err != nil {
panic(err.Error())
}
defer db.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// 创建一个带有取消功能的子context
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
var result string
err := db.QueryRowContext(ctx, "SELECT column_name FROM table_name WHERE some_condition").Scan(&result)
if err != nil {
if err == context.DeadlineExceeded {
http.Error(w, "Database operation timed out", http.StatusGatewayTimeout)
} else {
http.Error(w, "Database query error", http.StatusInternalServerError)
}
return
}
fmt.Fprintf(w, "Result: %s", result)
})
http.ListenAndServe(":8080", nil)
}
在上述代码中:
- 通过
r.Context()
获取HTTP请求的context
。 - 使用
context.WithTimeout
创建一个带有超时的子context
,并在函数结束时调用cancel
函数,确保在函数返回前释放相关资源。 - 在执行数据库查询时,使用
db.QueryRowContext
方法并传入context
。如果context
超时(例如数据库操作超过500毫秒),数据库操作会被取消,函数会返回错误,从而避免长时间占用数据库连接资源。