go test 介绍

https://geektutu.com/post/quick-go-test.html https://pkg.go.dev/testing

go modules

依赖管理

https://blog.golang.org/using-go-modules

slice

go中数组的赋值和函数传参都是值传递。

切片是对数组的一个连续片段的引用。

1
2
3
4
5
type slice struct {
  len int
  cap int              // cap >= len
  array unsafe.Pointer //指向数组的指针
}
  • 扩容
    • 首先判断,如果新申请容量(cap)大于2倍的旧容量(old.cap),最终容量(newcap)就是新申请的容量(cap)
    • 否则判断,如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap)
    • 否则判断,如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的 1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
    • 如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)

数组容量cap超过最大值时,才会创建新的底层数组。

slice range value为值拷贝

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
func main() {
	slice := []int{10, 20, 30, 40}
	for index, value := range slice {
		fmt.Printf("value = %d , value-addr = %x , slice-addr = %x\n", value, &value, &slice[index])
	}
}

/***
value = 10 , value-addr = c4200aedf8 , slice-addr = c4200b0320
value = 20 , value-addr = c4200aedf8 , slice-addr = c4200b0328
value = 30 , value-addr = c4200aedf8 , slice-addr = c4200b0330
value = 40 , value-addr = c4200aedf8 , slice-addr = c4200b0338
*/
由于 Value 是值拷贝的并非引用传递所以直接改 Value 是达不到更改原切片值的目的的需要通过 &slice[index] 获取真实的地址

map

map的key只能为可以进行比较的类型;float类型也可以,但是map在进行比较float类型时会先转换为int64再进行比较,会有意想不到的效果,有坑。

map的数据结构:hash table和search tree

哈希查找表用一个哈希函数将 key 分配到不同的桶(bucket,也就是数组的不同 index)。这样,开销主要在哈希函数的计算以及数组的常数访问时间。在很多场景下,哈希查找表的性能很高。

哈希查找表一般会存在“碰撞”的问题,就是说不同的 key 被哈希到了同一个 bucket。一般有两种应对方法:链表法开放地址法链表法将一个 bucket 实现成一个链表,落在同一个 bucket 中的 key 都会插入这个链表。开放地址法则是碰撞发生后,通过一定的规律,在数组的后面挑选“空位”,用来放置新的 key。

interface

channel

调度

gc

/Users/anpuqiang/Documents/hugoblog/blog/content/post/golang_gc.md

并发