MST

星途 面试题库

面试题:Go中context取消机制对网络请求上下文携带数据的影响

当使用context取消机制来终止一个网络请求时,对于已经在上下文携带的数据(例如一些认证信息),在取消操作后这些数据的生命周期和状态会发生什么变化?如何确保在取消请求时,相关的上下文携带数据能被正确清理或处理?请结合代码示例说明。
22.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

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 秒后取消,进而执行清理操作。