1. context 结构是什么样的?#
分析
关于context要清楚具体是什么,context其实是一个接口,提供了四种方法,而在官方go语言中对context接口提供了四种基本类型的实现,回答的时候,要答出接口以及几种实现结构
回答
go语言里的context实际上是一个接口,提供了四种方法:
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携带的值有emptyCtx、cancelCtx、timerCtx、valueCtx四种实现
a. emptyCtx: emptyCtx 虽然实现了context接口,但是不具备任何功能,因为实现很简单,基本都是直接返回空值
i. 我们一般调用context.Background()和context.TODO() 都是返回一个 *emptyCtx的动态类型(通过静态类型context.Context传递)
b. cancelCtx: cancelCtx同时实现Context和canceler接口,通过取消函数cancelFunc实现退出通知。注意其退出通知机制不但通知自己,同时也通知其children节点。
i. 我们一般调用context.WithCancel() 就会返回一个*cancelCtx 和cancelFunc
c. timerCtx: timerCtx是一个实现了Context接口的具体类型,其内部封装了cancelCtx类型实例,同时也有个deadline变量,用来实现定时退出通知
i. 我们一般调用context.WithTimeout() 就会返回一个*timerCtx和cancelFunc,不仅可以定时通知,也可以调用cancelFunc进行通知
ii. 调用context.WithDeadline()也可以,WithTimeout是多少秒后进行通知,WithDeadline是在某个时间点通知,本质上,WithTimeout会转而WithDeadline
d. valueCtx: valueCtx是一个实现了Context接口的具体类型,其内部封装了Context接口类型,同时也封装了一个k/v的存储变量,其是一个实现了数据传递
i. 我们一般context.WithValue()来得到一个*valueCtx,valueCtx可以继承它的parent valueCtx中的{key, value}
2. context 使用场景和用途?(基本必问)#
分析
这个问题其实可以可以上一个问题的补充提问,在明确了context是什么之后,即context接口提供了哪些哪些方法,以及有哪些实践之后,看似联想出这些实现是为了解决什么问题,主要突出两点:上下文信息传递和协程的取消控制
回答
context 主要用来在 goroutine 之间传递上下文信息,比如传递请求的trace_id,以便于追踪全局唯一请求
另一个用处是可以用来做取消控制,通过取消信号和超时时间来控制子goroutine的退出,防止goroutine泄漏
包括:取消信号、超时时间、截止时间、k-v 等。