vault backup: 2026-06-07 12:14:39

This commit is contained in:
2026-06-07 12:14:39 +08:00
parent 1a72bc4d82
commit 7ce9b83218
61 changed files with 8409 additions and 14429 deletions
+105 -35
View File
@@ -1,68 +1,138 @@
---
tags:
- Go
- golang
- context
- 面试题
- context面试题
tags: [go, golang, interview, context-questions]
create time: 2026-06-07 14:30
---
# Context面试题
# Context 面试题 🌐
## 1. Go语言里的Context是什么?
## 概述
go语言里的context实际上是一个接口,提供了Deadline(),Done(),Err()以及Value()四种方法。它在Go 1.7 标准库被引入。
本文件涵盖 Go Context 的 4 道高频面试题,涉及接口定义、作用机制、Value 查找和取消传播。Context 是 Go 1.7 引入的标准库接口,是并发编程中控制请求生命周期的核心工具。
它本质上是一个**信号传递和范围控制的工具**。它的核心作用是在一个请求处理链路中(跨越多个函数和goroutine),优雅地传递**取消信号(cancellation)、超时(timeout)和截止日期(deadline)**,并能携带一些范围内的键值对数据。
## 关联笔记
**分析**
- [[hzh/GolangStar/Go语言进阶/Context]] — Context 详细讲解
- [[hzh/GolangStar/Go语言原理/context原理]] — cancel chain / value chain 源码分析
- [[hzh/GolangStar/Go面试题库/代码面试题]] — Context + Channel 实战
## 正文
### Q1:Go 语言里的 Context 是什么? 🟡中等
> [!question] ❓ 思考一下
> 如果一个 HTTP 请求处理函数调用了 5 个下游服务,每个下游又调了更多服务,你怎么保证当请求超时或取消时所有调用链都能及时退出?
## 参考答案
Context 是一个**信号传递和范围控制的工具**,本质是一个接口:
```go
type Context interface {
Deadline() (deadline time.Time, ok bool) // Deadline方法的第一个返回值表示还有多久到 期, 第二个返回值代表是否被超时时间控制
Done() <-chan struct{} // Done() 返回一个 只读channel,当这个channel被关闭时,说明这个 context被取消
Err() error // Err() 返回一个错误,表示channel被关闭的原因,例如是被取消,还是超时关闭
Value(key interface{}) interface{}) // value方法返回指定key对应的value,这是context携带 的值
Deadline() (time.Time, bool) // 返回截止时间
Done() <-chan struct{} // 返回关闭 channel 作为取消信号
Err() error // 返回取消原因
Value(key interface{}) interface{} // 携带请求级键值对数据
}
```
这个接口定义了四个核心方法,它们共同构成了一套关于**截止时间、取消信号和请求范围值**的协定:
四个方法构成的协定:
* `Deadline()` - 返回一个时间点,告知任务何时应该被取消。
| 方法 | 作用 |
|------|------|
| `Deadline()` | 告知任务何时应该被取消 |
| `Done()` | 关闭后通知所有监听者收到取消信号 |
| `Err()` | 解释取消原因(Canceled / DeadlineExceeded) |
| `Value()` | 在调用链中传递请求范围的键值对 |
* `Done()` - 返回一个channel,当`Context`被取消或超时,这个channel会被关闭。这是goroutine监听取消信号的核心。
> [!note] 📝 核心考点
> Context 的核心作用是三件事:**超时控制**、**取消信号传播**、**请求级数据传递**。面试时可以按这个顺序展开。
* `Err()` - 在`Done()`的channel关闭后,它会解释关闭的原因,是主动取消(`Canceled`)还是超时(`DeadlineExceeded`)。
> [!warning] ⚠️ 高频陷阱
> Context 应该作为函数的**第一个参数**传递,**不要存储在结构体中**,传递的数据应该是**请求级别**的(如 request ID),不要滥用。
* `Value()` - 允许`Context`在调用链中携带请求范围的键值对数据。
---
## 2. Go语言的Context有什么作用?
### Q2:Context 有什么作用? 🟢简单
Go的Context主要解决三个核心问题:**超时控制、取消信号传播和请求级数据传递**
## 参考答案
在实际项目中,我们最常用的是超时控制。比如一个HTTP请求需要调用多个下游服务,我们通过`context.WithTimeout`设置整体超时时间,当超时发生时,所有子操作都会收到取消信号并立即退出,避免资源浪费。取消信号的传播是通过Context的层级结构实现的,父Context取消时,所有子Context都会自动取消。
三大核心作用:
另外Context还能传递请求级的元数据,比如用户ID、请求ID等,这在分布式链路追踪中特别有用。需要注意的是,Context应该作为函数的第一个参数传递,不要存储在结构体中,并且传递的数据应该是请求级别的,不要滥用。
| 作用 | 场景 | 示例 |
|------|------|------|
| **超时控制** | HTTP 请求调用多个下游服务 | `WithTimeout` |
| **取消信号传播** | 父请求取消时子操作自动退出 | `WithCancel` |
| **请求级数据传递** | 分布式链路追踪中的 request ID | `WithValue` |
![](https://golangstar.cn/assets/img/go语言系列/go面试题库/Context面试题/image-1.png)
```go
// 典型用法:HTTP handler 中
func handler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
// 将 ctx 传递给所有下游调用
result := fetchFromDownstream(ctx)
}
```
## 3. Context.Value的查找过程是怎样的
> [!tip] 💡 面试技巧
> "Context 就像一条传送带上的标签——它从请求入口开始,沿着调用链一路传递,任何环节都可以读取上面的信息,也可以随时发出'停止'信号让整条线停下来。"
Context.Value的查找过程是一个**链式递归查找的过程**,从当前Context开始,沿着父Context链一直向上查找直到找到对应的key或者到达根Context。
---
具体流程是:当调用`ctx.Value(key)`时,首先检查当前Context是否包含这个key,如果当前层没有,就会调用`parent.Value(key)`继续向上查找。这个过程会一直递归下去,直到找到匹配的key返回对应的value,或者查找到根Context返回nil。
### Q3:Context.Value 的查找过程是怎样的? 🟡中等
![](https://golangstar.cn/assets/img/go语言系列/go面试题库/Context面试题/image.png)
## 参考答案
## 4. Context如何被取消
**链式递归查找**,从当前 Context 沿父链向上直到找到 key 或到达根 Context。
Context的取消是通过**channel关闭信号**实现的,主要有三种取消方式。
```mermaid
graph TD
A[ctx.Value key] --> B{当前层有?}
B -->|是| C[返回 value]
B -->|否| D[parent.Value key]
D --> E{有?}
E -->|是| C
E -->|否| F[root.Value key]
F --> G{有?}
G -->|是| C
G -->|否| H[返回 nil]
```
首先是**主动取消**,通过`context.WithCancel`创建的Context会返回一个cancel函数,调用这个函数就会关闭内部的done channel,所有监听这个Context的goroutine都能通过`ctx.Done()`收到取消信号。
> [!info] 🔗 延伸阅读
> - [[hzh/GolangStar/Go语言原理/context原理]] — value chain 的实现细节
其次是**超时取消**,`context.WithTimeout`和`context.WithDeadline`会启动一个定时器,到达指定时间后自动调用cancel函数触发取消。
---
最后是**级联取消**,当父Context被取消时,所有子Context会自动被取消,这是通过Context树的结构实现的。
### Q4:Context 如何被取消? 🟡中等
![](https://golangstar.cn/assets/img/go语言系列/go面试题库/Context面试题/image-2.png)
## 参考答案
通过 **channel 关闭信号**实现,三种取消方式:
| 方式 | 创建函数 | 触发条件 |
|------|---------|---------|
| **主动取消** | `WithCancel` | 手动调用 cancel 函数 |
| **超时取消** | `WithTimeout` / `WithDeadline` | 到达指定时间自动 cancel |
| **级联取消** | 自动传播 | 父 Context 取消时子 Context 自动取消 |
```mermaid
graph LR
A[Root Context] --> B[WithCancel → child1]
A --> C[WithTimeout → child2]
B --> D[WithCancel → grandchild]
C --> E[WithCancel → grandchild2]
style A fill:#F44336,color:#fff
style B fill:#FF9800,color:#fff
style C fill:#2196F3,color:#fff
```
> [!tip] 💡 面试技巧
> 回答时可以强调:"Context 是一棵树的结构,父节点取消时,整棵子树都会取消。Done() 返回的 channel 会在任意一层被 cancel 时关闭。"
## 关联笔记
- [[hzh/GolangStar/Go语言进阶/Context]]
- [[hzh/GolangStar/Go语言原理/context原理]]
- [[hzh/GolangStar/Go面试题库/代码面试题]]