面试题答案
一键面试1. 数据生命周期和状态变化
当使用 context
取消机制终止网络请求时,上下文携带的数据本身并不会因为 context
的取消而自动销毁。context
的取消主要用于通知相关的 goroutine 停止当前操作,但上下文携带的数据仍然存在于内存中,直到没有任何引用指向它们,被垃圾回收器回收。
2. 确保数据正确清理或处理
为了确保在取消请求时,相关的上下文携带数据能被正确清理或处理,可以在取消操作的回调函数中进行处理,或者在使用完数据后主动清理。
3. 代码示例
以下是一个简单的 Go 语言示例,展示如何在 context
取消时清理数据:
package main
import (
"context"
"fmt"
"time"
)
// 模拟一个携带认证信息的结构体
type AuthInfo struct {
Token string
}
func doRequest(ctx context.Context, auth AuthInfo) {
// 模拟一个需要长时间运行的网络请求
select {
case <-time.After(5 * time.Second):
fmt.Println("Request completed with auth:", auth.Token)
case <-ctx.Done():
// 当 context 取消时,清理认证信息
fmt.Println("Request cancelled, cleaning up auth info:", auth.Token)
auth.Token = "" // 清理 Token
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
auth := AuthInfo{Token: "example-token"}
go doRequest(ctx, auth)
time.Sleep(4 * time.Second)
}
在上述代码中:
AuthInfo
结构体模拟了携带认证信息的数据。doRequest
函数中使用select
语句监听ctx.Done()
通道,当context
取消时,会执行ctx.Done()
分支,在这个分支中清理了auth.Token
。- 在
main
函数中,通过context.WithTimeout
创建了一个带有超时的context
,并在defer
中调用cancel
函数确保资源正确释放。启动一个 goroutine 执行doRequest
,由于设置的超时时间为 3 秒,而模拟的网络请求需要 5 秒,所以context
会在 3 秒后取消,进而执行清理操作。