timer
为什么timer的底层数据结构用小顶堆?
因为timer中有个到期时间,可以判断当前有哪些timer到期。
为什么要用四叉堆而不是二叉堆?
因为四叉堆的层数更低。
你还知道哪些数据结构也是被用来实现timer的吗?
- nginx使用红黑树
- linux kernel使用时间轮
Go是如何保证获取时间的准确性的?(或者说获取的时间是及时的)
由于获取时间是一种很频繁的操作,所以通过一种加速系统调用的机制,这里采用的是VDSO(virtual dynamic shared boject)。
reflection
什么是反射?
类比于照镜子。通过镜子可以看到自己,这就是一种反射。 所以反射指的是计算机程序在运行期间可以访问、检测、修改它本身状态的一种能力。
在Go中的反射机制中,编译时不知道变量的具体类型,而在运行时可以更新变量、检查值、调用方法。
需要使用反射的常见场景?
- 不能明确接口调用哪个函数
- 不能明确传入函数的参数类型
反射的应用
- 深度拷贝
- 原理:使用反射推断出原对象的类型和值,而后对其进行递归复制
- 其他:IDE自动补全、对象序列化、fmt相关函数实现、ORM
Go如何实现反射?
借助接口,基于类型。
接口会存储所赋予的实体的类型信息,而反射就通过这些类型信息实现。
谈谈TypeOf
路径地址:$GOROOT/src/reflect/type.go
type Type interface {
Align() int
FieldAlign() int
Method(int) Method
MethodByName(string) (Method, bool)
NumMethod() int
Name() string
PkgPath() string
Size() uintptr
String() string
Kind() Kind
Implements(u Type) bool
AssignableTo(u Type) bool
ConvertibleTo(u Type) bool
Comparable() bool
Bits() int
ChanDir() ChanDir
IsVariadic() bool
Elem() Type
Field(i int) StructField
FieldByIndex(index []int) StructField
FieldByName(name string) (StructField, bool)
FieldByNameFunc(match func(string) bool) (StructField, bool)
In(i int) Type
Key() Type
Len() int
NumField() int
NumIn() int
NumOut() int
Out(i int) Type
common() *rtype
uncommon() *uncommonType
}
- 总结上面的流程即:TypeOf()返回一个接口,这个接口定义了一系列可以获取类型相关信息的方法
谈谈valueOf?
路径地址:$GOROOT/src/reflect/value.go
type Value struct {
typ *rtype
ptr unsafe.Pointer
flag
}
- 总结上面的流程即:ValueOf()返回一个结构体变量,包含类型信息及实际值
听说过反射三大定律吗?你是如何理解的?
三大定律
(直译)
- 反射是从接口值到反射对象
- 反射是从反射对象到接口值
- 要修改反射对象,对象值本身必须是可设置的
理解
上述几句话表明了反射对象和接口值之间的直接联系,它们可以相互转化。反射对象对应于代码中的reflect.Type和reflect.Value;对反射变量的操作会反映到原变量本身