...大约 2 分钟
一般情况下,go build 可以直接编译程序,无需额外的参数设定。
但在用于生产环境编译时 go build 的一些参数还是很有用的。
go build -gcflags '-N -l' \
-ldflags '-w -s -X "main.appVersion=v1.0.0"' \
-o myapp .
...大约 2 分钟
1. 死锁简短示例
// 这种情况很好理解, 出现死锁了
func main() {
ch := make(chan int, 1)
<-ch
}
原创...大约 3 分钟
常见数据结构
- 链表
- 栈和队列
- 列表
- 哈希表
- 树
- ...
参考:
GoDS: https://github.com/emirpasic/gods
go-datastructures: https://github.com/Workiva/go-datastructures
...大约 1 分钟
对不同状态的 channel 操作分别是什么结果
状态 \ 操作 | close | send | receive |
---|---|---|---|
nil | panic | block | block |
为空 | closed, 没有保留元素 | write value | block |
已满 | closed, 保留未读的元素 | block | read value |
非空且未满 | closed, 保留未读的元素 | write value | read value |
closed | panic | panic | 返回未读元素, 读完后返回零值 |
原创...大约 1 分钟
for-range 是 Golang 提供的一种迭代遍历手段,可操作的类型有 数组、切片、Map、channel。for-range 遍历 slice 前会先获取 slice 的长度 len_temp 来作为循环次数,并将待循环的 slice 赋值给临时变量 range_temp。循环体中,每次循环会先获取元素值,如果 for-range 中接收 index 和 value 的话,则会对 index 和 value 进行一次赋值。数组与数组指针的遍历过程与 slice 基本一致。
原创...大约 6 分钟
golang中的return语句不是原子操作,分为【返回值赋值】和【RET指令】两步,而defer语句在这两步之间执行(返回值赋值之后,RET指令之前)。
原创...大约 3 分钟
区别
看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型。
new(T)
为每个新的类型T
分配一片内存,初始化为0
并且返回类型为*T
的内存地址:这种方法 返回一个指向类型为T
,值为 T 类型零值
的地址的指针,它适用于值类型如数组和结构体,相当于&T{}
。make(T)
返回一个类型为 T 的初始值,它 只适用 于 3 种内建的引用类型:切片
、map
和channel
。
...大约 2 分钟
// 数组: new([len]Type)
arr := new([5]int)
arr := [5]int{1, 2} // [5]int{1, 2, 0, 0, 0}
arr := [5]{1, 2, 3, 4, 5}
arr := [...]{1, 2, 3, 4, 5} // [5]int{1, 2, 3, 4, 5}
arrKV := [...]int{1: 10, 6: 20, 30} // [8]int{0, 10, 0, 0, 0, 0, 20, 30}
// 切片: make([]Type, size[, cap])
slice := make([]int, 0) // []int{}
slice := make([]int, 5) // []int{0, 0, 0, 0, 0}
slice := make([]int, 5, 10) // []int{0, 0, 0, 0, 0}
// 在预先知道所需切片大小时可以预先分配好底层数组, 避免 append 时频繁扩容
slice := make([]int, 0, 100) // []int{}
// 从现有数组/切片中截取: arr[start:end:max]
// 其中: start <= end <= max <= len(arr)
arr := [20]int{}
slice := arr[1:5:10]
...大约 9 分钟