Files
cs-note/hzh/GolangStar/Go面试题库/Context面试题.md
T

139 lines
4.5 KiB
Markdown
Raw Normal View History

2026-06-07 11:08:10 +08:00
---
2026-06-07 12:14:39 +08:00
tags: [go, golang, interview, context-questions]
create time: 2026-06-07 14:30
2026-06-07 11:08:10 +08:00
---
2026-06-07 12:14:39 +08:00
# Context 面试题 🌐
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 概述
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
本文件涵盖 Go Context 的 4 道高频面试题,涉及接口定义、作用机制、Value 查找和取消传播。Context 是 Go 1.7 引入的标准库接口,是并发编程中控制请求生命周期的核心工具。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 关联笔记
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
- [[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 是一个**信号传递和范围控制的工具**,本质是一个接口:
2026-06-07 11:08:10 +08:00
```go
type Context interface {
2026-06-07 12:14:39 +08:00
Deadline() (time.Time, bool) // 返回截止时间
Done() <-chan struct{} // 返回关闭 channel 作为取消信号
Err() error // 返回取消原因
Value(key interface{}) interface{} // 携带请求级键值对数据
2026-06-07 11:08:10 +08:00
}
```
2026-06-07 12:14:39 +08:00
四个方法构成的协定:
| 方法 | 作用 |
|------|------|
| `Deadline()` | 告知任务何时应该被取消 |
| `Done()` | 关闭后通知所有监听者收到取消信号 |
| `Err()` | 解释取消原因(Canceled / DeadlineExceeded) |
| `Value()` | 在调用链中传递请求范围的键值对 |
> [!note] 📝 核心考点
> Context 的核心作用是三件事:**超时控制**、**取消信号传播**、**请求级数据传递**。面试时可以按这个顺序展开。
> [!warning] ⚠️ 高频陷阱
> Context 应该作为函数的**第一个参数**传递,**不要存储在结构体中**,传递的数据应该是**请求级别**的(如 request ID),不要滥用。
---
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
### Q2:Context 有什么作用? 🟢简单
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 参考答案
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
三大核心作用:
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
| 作用 | 场景 | 示例 |
|------|------|------|
| **超时控制** | HTTP 请求调用多个下游服务 | `WithTimeout` |
| **取消信号传播** | 父请求取消时子操作自动退出 | `WithCancel` |
| **请求级数据传递** | 分布式链路追踪中的 request ID | `WithValue` |
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
```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)
}
```
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
> [!tip] 💡 面试技巧
> "Context 就像一条传送带上的标签——它从请求入口开始,沿着调用链一路传递,任何环节都可以读取上面的信息,也可以随时发出'停止'信号让整条线停下来。"
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
---
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
### Q3:Context.Value 的查找过程是怎样的? 🟡中等
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 参考答案
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
**链式递归查找**,从当前 Context 沿父链向上直到找到 key 或到达根 Context。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
```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]
```
> [!info] 🔗 延伸阅读
> - [[hzh/GolangStar/Go语言原理/context原理]] — value chain 的实现细节
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
---
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
### Q4:Context 如何被取消? 🟡中等
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 参考答案
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
通过 **channel 关闭信号**实现,三种取消方式:
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
| 方式 | 创建函数 | 触发条件 |
|------|---------|---------|
| **主动取消** | `WithCancel` | 手动调用 cancel 函数 |
| **超时取消** | `WithTimeout` / `WithDeadline` | 到达指定时间自动 cancel |
| **级联取消** | 自动传播 | 父 Context 取消时子 Context 自动取消 |
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
```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
```
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
> [!tip] 💡 面试技巧
> 回答时可以强调:"Context 是一棵树的结构,父节点取消时,整棵子树都会取消。Done() 返回的 channel 会在任意一层被 cancel 时关闭。"
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 关联笔记
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
- [[hzh/GolangStar/Go语言进阶/Context]]
- [[hzh/GolangStar/Go语言原理/context原理]]
- [[hzh/GolangStar/Go面试题库/代码面试题]]