Eli's Blog

1. 反射

反射:在运行时,动态获取对象的类型信息和内存结构

反射操作所需要的全部信息都源自接口变量,接口变量除了存储自身类型外,还会保存实际对象的类型数据

将任何传入的对象转换为接口类型:

1
2
func TypeOf(o interface{}) Type
func ValueOf(o interface{}) Value

1. goroutine

协程,比线程更小,十几个goroutine可能体现在底层就五六个线程。Go语言内部实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(4~5KB),比线程更易用,更高效和更轻便。

goroutine调度模型:

  • M: 线程
  • P: 上下文
  • G: Goroutine

并发concurrency:

  • goroutine只是官方实现的超级“线程池”。每个实例4-5KB的栈内存占用,和大幅减少的创建和销毁开销,是制造Go号称高并发的根本原因
  • 并发不是并行(Concurrency is Not Parallelism): 并发是通过切换CPU时间来实现“同时”运行;而并行则是直接利用多核实现多线程同时运行。Go可设置使用的CPU核心数,以发挥多核计算机的能力
  • goroutine奉行通过通信来共享内存,而不是共享内存来通信。

1. 结构体

将多个不同类型命名字段(field)序列打包成一个复合类型。

结构体特点:

  • 值类型
  • 做参数,值传递
  • 相同类型,可使用==或!=比较

Go语言中实现封装、继承和多态:

  • 封装:通过方法实现
  • 继承:通过匿名字段实现
  • 多态:通过接口实现

1. 函数

  • 不支持嵌套、重载和默认参数
  • 无需声明原型、不定长度变参、多返回值、命名返回参数、匿名函数、闭包
  • 本身就是一种类型

函数调用底层分析:

  • 栈区:基本数据类型一般分配到栈区。编译器存在一个逃逸分析。每个函数有独立的栈,函数执行完毕,自动销毁
  • 堆区:引用数据类型一般分配在堆区
  • 代码区:存放代码指令

1. 指针

指针不是内存地址。

内存地址是内存中每个字节单元的唯一编号,而指针则是一个实体。

指针会分配内存空间,相当于一个专门用来保存地址的整型变量。

GO指针,不支持加减运算和类型转换

可通过unsafe.Pointer将指针转换为uintptr后进行加减法运算,但可能会造成非法访问。

Pointer类似C语言中的void*万能指针,可用来转换指针类型。它能安全持有对象或对象成员,但uintptr不行。后者仅是一种特殊整型,并不引用目标对象,无法阻止垃圾回收器回收对象内存。

1. 数据类型

1.1 Go数据类型

类型 长度 默认值 说明
bool 1 false
byte 1 0 uint8的别名,相互不需要转换
int, uint 4, 8 0 默认整型,长度依平台而定,32或64
int8, uint8 1 0 -128 ~ 127, 0 ~ 255
int16, uint16 2 0
int32, uint32 4 0
int64, uint64 8 0
float32 4 0.0
float64 8 0.0 默认
complex64 8
complex128 16
rune 4 0 Unicode Code Point, int32的别名
uintptr 4, 8 0 存储指针的uint
string “” 默认值空字符串,而非nil
array 数组
struct 结构体
function nil
interface nil
map nil 字典,引用类型
slice nil 切片,引用类型
channel nil 通道,引用类型 |