Go进阶原理杂记

切片原理

Pointer 是指向一个数组的指针,len 代表当前切片的长度,cap 是当前切片的容量。(cap 总是大于等于 len 的)
在这里插入图片描述
在这里插入图片描述

map原理

  • hmap(a header for a go map)结构:
    最重要的是:buckets散列表指针!
    其中B:2^B就是[]bmap长度

在这里插入图片描述

  • bmap(a bucket for a Go map通常叫其bucket)结构:
  1. buckets指针指向一个一维数组,也就是bucket集合([]bmap)
    在这里插入图片描述

  2. 集合槽点数据结构为bmap
    每个bucket最多存放8个key-value
    在这里插入图片描述

key-value是分开存的:可以消除padding(内存对齐)带来的空间浪费。
在这里插入图片描述

  1. 数据存储过程:
    key得到hash值 ===> hash值的低位算出槽点 ===> hash高位算出bucket链中哪个bucket
    在这里插入图片描述

在这里插入图片描述

map扩容(懒迁移)

扩容因子公式是:map元素个数 / []bmap数组长度,阈值是6.5。
当达到扩容要求,将产生一个新的二倍bucket数组

注意:并不是立刻把旧的数组中的元素转义到新的bucket当中,而是,只有当访问到具体的某个bucket的时候,会把bucket中的数据转移到新的bucket中。

在这里插入图片描述

channel原理

环形队列+互斥锁

在这里插入图片描述

回想:上面三种是特殊数据类型,常使用make()函数创建!


sync.Map

互斥锁 + 原子类

// 封装的线程安全的map
type Map struct {
	// lock
	mu Mutex

	// 实际是readOnly这个结构
	// 一个只读的数据结构,因为只读,所以不会有读写冲突。
	read atomic.Value // readOnly

	dirty map[interface{}]*entry

	// 当从Map中读取entry的时候,如果read中不包含这个entry,会尝试从dirty中读取,这个时候会将misses加一
	misses int
}

defer原理

品:无论defer多少,最终defer的变量值都是按照执行顺序最新的值

func main() {
	fmt.Println(f(1,2)) #102
}

func f(x, y int) int {
	defer func() {
		y = 200
		fmt.Println(x,y) #100 200
	}()
	x = 100
	return x+y
}

本质原因是return xxx语句并不是一条原子指令,defer被插入到了赋值(方法将值返回) 与 ret(方法弹出栈)之间。

goroutine的控制结构中,有一张表记录defer,调用runtime.deferproc时会将需要defer的表达式记录在表中,而在调用runtime.deferreturn的时候,则会依次从defer表中出栈并执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值