【Go学习】语言类库(二)timer&&reflection

77 阅读2分钟

timer

为什么timer的底层数据结构用小顶堆?

image.png 因为timer中有个到期时间,可以判断当前有哪些timer到期。

为什么要用四叉堆而不是二叉堆?

因为四叉堆的层数更低。

你还知道哪些数据结构也是被用来实现timer的吗?

  • nginx使用红黑树
  • linux kernel使用时间轮

Go是如何保证获取时间的准确性的?(或者说获取的时间是及时的)

由于获取时间是一种很频繁的操作,所以通过一种加速系统调用的机制,这里采用的是VDSO(virtual dynamic shared boject)。

reflection

什么是反射?

类比于照镜子。通过镜子可以看到自己,这就是一种反射。 所以反射指的是计算机程序在运行期间可以访问检测修改它本身状态的一种能力。

在Go中的反射机制中,编译时不知道变量的具体类型,而在运行时可以更新变量、检查值、调用方法。

需要使用反射的常见场景?

  • 不能明确接口调用哪个函数
  • 不能明确传入函数的参数类型

反射的应用

  • 深度拷贝
    • 原理:使用反射推断出原对象的类型和值,而后对其进行递归复制
  • 其他:IDE自动补全、对象序列化、fmt相关函数实现、ORM

Go如何实现反射?

借助接口,基于类型。

接口会存储所赋予的实体的类型信息,而反射就通过这些类型信息实现。

谈谈TypeOf

路径地址:$GOROOT/src/reflect/type.go image.png

image.png

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

image.png

image.png

type Value struct {
   typ *rtype

   ptr unsafe.Pointer

   flag
}
  • 总结上面的流程即:ValueOf()返回一个结构体变量,包含类型信息及实际值

听说过反射三大定律吗?你是如何理解的?

三大定律

(直译)

  • 反射是从接口值到反射对象
  • 反射是从反射对象到接口值
  • 要修改反射对象,对象值本身必须是可设置的

理解

上述几句话表明了反射对象和接口值之间的直接联系,它们可以相互转化。反射对象对应于代码中的reflect.Type和reflect.Value;对反射变量的操作会反映到原变量本身