go语法剖析
什么是go程序执行的入口?
runtime包里面的函数(rt0_windows)
是程序员的运行编译环境 JVM就是java的runtime
初始化g0协程栈 是go代码的第一个协程
go启动新的协程调用的是底层的new proc 创建一个新的协程去执行runtime.main 放入调度器等待调度
初始化一个M,用来调度主协程
go的启动像是一个框架 go允许oo编程 但是缺乏继承结构 go的继承只是组合
1 | package main |
go的接口是隐式的(把接口的全部方法都实现就会接口)
1 | package main |
go的高并发下的数据结构
空结构体
int的大小是跟随系统字长的
指针的大小也是跟随系统长度的
空结构体只有地址 没有长度(Zero Peace)为了节约内存 map channel
1 | m := map[string]struct{}{} |
字符串
字符串本身是结构体 Data指针指向底层的Byte数组
遍历字符串
1 | s = string([]rune(s)[:3]) |
map
go使用拉链法实现hashmap 每个桶中存储哈希的前八位
超出8个数据 就会存储到溢出桶里面
map的扩容
map的溢出桶太多时会导致严重的性能下降
runtime.mapassign()可能会触发扩容的情况 装载因子超过6.5
转载系数或者溢出桶的增加,会触发map的扩容 扩容并不是增加桶数,而是整理
map的并发问题
sync.Map使用了两个Map,分离了扩容的问题
不会引发扩容(查改)的操作使用read map
可能引发扩容(新增)的操作使用dirty map
GO隐式接口的特点
结构体实现接口 | 结构体指针实现接口 | |
---|---|---|
结构体初始化变量 | 通过 | 不通过 |
结构体指针初始化变量 | 通过 | 通过 |
go和java的区别:隐式接口,接口体实现接口,会帮着多实现一个结构体指针实现接口的方法
结构体实现接口,结构体和结构体指针初始化变量都是可以通过的;
结构体指针实现接口,结构体初始化变量不通过
空接口
空接口就是runtime.eface的结构体(数据类型 数据本身省略了很多信息)
nil和空接口 空结构体的区别和联系
nil 就是变量名 是空 有类型 是6种类型的“零值”
空结构体的指针不是nil 但是都相同是(zerobase)
空接口不一定是nil接口 只有两个属性都是nil才是nil接口