面试题答案
一键面试- 使用
context
和defer
释放资源的原理:context
用于在多个goroutine
之间传递取消信号。它提供了一种机制,允许父goroutine
取消子goroutine
,子goroutine
可以监听这个取消信号。defer
语句用于延迟执行函数调用。在goroutine
结束时,defer
语句会按照后进先出(LIFO)的顺序执行,这非常适合用于资源清理工作。
- 示例代码:
package main
import (
"context"
"fmt"
"time"
)
// 模拟数据库连接结构体
type DatabaseConnection struct {
// 这里可以添加数据库连接相关的字段
}
// 模拟关闭数据库连接的方法
func (db *DatabaseConnection) Close() {
fmt.Println("Closing database connection")
}
func worker(ctx context.Context) {
// 模拟获取数据库连接
db := &DatabaseConnection{}
// 使用defer在函数结束时关闭数据库连接
defer db.Close()
for {
select {
case <-ctx.Done():
// 当收到取消信号时,退出循环
fmt.Println("Received cancel signal, cleaning up")
return
default:
// 模拟工作
fmt.Println("Working...")
time.Sleep(1 * time.Second)
}
}
}
你可以使用以下方式调用这个函数:
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
go worker(ctx)
// 主goroutine等待一段时间
time.Sleep(5 * time.Second)
}
在这个示例中:
worker
函数使用context.Context
来监听取消信号。- 通过
defer
语句确保在worker
函数结束时,无论正常结束还是因为取消而结束,数据库连接都会被关闭。 - 在
main
函数中,通过context.WithTimeout
创建一个带有超时的context
,并在defer
中调用cancel
函数,确保资源能够被及时释放。