Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 09632fe

Browse files
authored
Merge pull request #34 from shipengqi/feat/images
feat(images): Using Gitee as an image hosting platform
2 parents 2aa6d8e + b355d7e commit 09632fe

File tree

17 files changed

+41
-39
lines changed

17 files changed

+41
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# golang-learn
22

3-
Go language learning ...
3+
Go learning ...
44

55
## Usage
66

content/docs/basic/03_slice.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type SliceHeader struct {
2020

2121
注意 `Cap` 也是底层数组的长度。`Data` 是一块连续的内存,可以存储切片 `Cap` 大小的所有元素。
2222

23-
![slice-struct](https://raw.githubusercontent.com/shipengqi/illustrations/76c579125ad122d2f1a4d9e605139af61da3a7c5/go/slice-struct.png)
23+
![slice-struct](https://gitee.com/shipengqi/illustrations/raw/main/go/slice-struct.png)
2424

2525
如图,虽然 slice 的 `Len` 是 5,但是底层数组的长度是 10,也就是 `Cap`
2626

@@ -82,20 +82,20 @@ func main() {
8282
- `s1 := slice[2:5]` 得到的 `s1` 的容量为 8,因为没有传入 `max`,容量默认是到底层数组的结尾。
8383
- `s2 := s1[2:6:7]` 得到的 `s2` 的容量为 5(`max - low`)。`s2``s1``slice` 底层数组是同一个,所以 `s2` 中的元素是 `[4,5,6,7]`
8484

85-
![slice-cut](https://raw.githubusercontent.com/shipengqi/illustrations/d28ded522afae7c5fec7cd9a38d6ba3e4287c52d/go/slice-cut.png)
85+
![slice-cut](https://gitee.com/shipengqi/illustrations/raw/main/go/slice-cut.png)
8686

8787
下面的 `s2 = append(s2, 100)` 追加一个元素,容量够用,不需要扩容,但是这个修改会影响所有指向这个底层数组的切片。
8888

89-
![slice-cut-append](https://raw.githubusercontent.com/shipengqi/illustrations/d28ded522afae7c5fec7cd9a38d6ba3e4287c52d/go/slice-cut-append.png)
89+
![slice-cut-append](https://gitee.com/shipengqi/illustrations/raw/main/go/slice-cut-append.png)
9090

9191
再次追加一个元素 `s2 = append(s2, 200)``s2` 的容量不够了,需要扩容,于是 `s2` 申请一块新的连续内存,并将数据拷贝过去,扩容后的容量是原来的 2 倍。
9292
这时候 `s2``Data` 指向了新的底层数组,已经和 `s1` `slice` 没有关系了,对 `s2` 的修改不会再影响 `s1` `slice`
9393

94-
![slice-cut-append2](https://raw.githubusercontent.com/shipengqi/illustrations/d28ded522afae7c5fec7cd9a38d6ba3e4287c52d/go/slice-cut-append2.png)
94+
![slice-cut-append2](https://gitee.com/shipengqi/illustrations/raw/main/go/slice-cut-append2.png)
9595

9696
最后 `s1[2] = 20` 也不会再影响 `s2`
9797

98-
![slice-cut-append3](https://raw.githubusercontent.com/shipengqi/illustrations/d28ded522afae7c5fec7cd9a38d6ba3e4287c52d/go/slice-cut-append3.png)
98+
![slice-cut-append3](https://gitee.com/shipengqi/illustrations/raw/main/go/slice-cut-append3.png)
9999

100100
## 切片是如何扩容的?
101101

content/docs/basic/04_map.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ weight: 4
1414

1515
哈希表是通过**哈希函数**将 key 转化为数组的下标,然后将数据存储在数组下标对应的位置。查询时,也是同样的使用哈希函数计算出数组下标,从下标对应的位置取出数据。
1616

17-
![map-seek-addr](https://raw.githubusercontent.com/shipengqi/illustrations/c532a70c015ab877e64c7fec6382cf1791597cbc/go/hash-func.png)
17+
![map-seek-addr](https://gitee.com/shipengqi/illustrations/raw/main/go/hash-func.png)
1818

1919
哈希函数的基本要求:
2020

@@ -31,7 +31,7 @@ weight: 4
3131

3232
开放寻址法核心思想是,如果出现了哈希冲突,就重新探测一个空闲位置,将其插入。
3333

34-
![map-seek-addr](https://raw.githubusercontent.com/shipengqi/illustrations/1e5051b9e3f0f681565b1737802ae7e15e075fc5/go/map-seek-addr.png)
34+
![map-seek-addr](https://gitee.com/shipengqi/illustrations/raw/main/go/map-seek-addr.png)
3535

3636
上图蓝色表示已经插入的元素,`key9` 哈希后得到的数组下标为 6,但是已经有数据了,产生了冲突。那么就按顺序向后查找直到找到一个空闲的位置,如果到数组的尾部都没有找到空闲的位置,就从头开始继续找。
3737
上图最终找到位置 1 并插入元素。
@@ -50,7 +50,7 @@ weight: 4
5050

5151
链表法是最常见的哈希冲突的解决办法。在哈希表中,每个桶(bucket)会对应一条链表,所有哈希值相同的元素都放到相同桶对应的链表中。
5252

53-
![map-link](https://raw.githubusercontent.com/shipengqi/illustrations/c532a70c015ab877e64c7fec6382cf1791597cbc/go/map-link.png)
53+
![map-link](https://gitee.com/shipengqi/illustrations/raw/main/go/map-link.png)
5454

5555
插入时,哈希函数计算后得出存放在几号桶,然后遍历桶中的链表了:
5656

@@ -121,14 +121,14 @@ type bmap struct {
121121

122122
`bmap` 就是桶,一个桶里面会最多存储 8 个键值对。
123123

124-
![bmap-struct](https://raw.githubusercontent.com/shipengqi/illustrations/8e8c090d5a1de970d1d00bdf5f79917e74bfd63d/go/bmap-struct.png)
124+
![bmap-struct](https://gitee.com/shipengqi/illustrations/raw/main/go/bmap-struct.png)
125125

126126
1. 在桶内,会根据 key 计算出来的 hash 值的高 8 位来决定 key 存储在桶中的位置。
127127
2. key 和 value 是分别放在一块连续的内存,这样做的目的是为了节省内存。例如一个 `map[int64]int8` 类型的 map,如果按照 `key1/value1/key2/value2 ...` 这样的形式来存储,那么内存对齐每个 `key/value` 都需要 padding 7 个字节。
128128
分开连续存储的话,就只需要在最后 padding 一次。
129129
3. 每个桶只能存储 8 个 `key/value`,如果有更多的 key 放入当前桶,就需要一个溢出桶,通过 `overflow` 指针连接起来。
130130

131-
![hmap](https://raw.githubusercontent.com/shipengqi/illustrations/8e8c090d5a1de970d1d00bdf5f79917e74bfd63d/go/hmap.png)
131+
![hmap](https://gitee.com/shipengqi/illustrations/raw/main/go/hmap.png)
132132

133133
### 初始化
134134

@@ -194,7 +194,7 @@ v, ok := hash[key]
194194

195195
查询过程:
196196

197-
![map-get](https://raw.githubusercontent.com/shipengqi/illustrations/ae69f3fdb54032a8619d342edccbcdc95c7776a6/go/map-get.png)
197+
![map-get](https://gitee.com/shipengqi/illustrations/raw/main/go/map-get.png)
198198

199199
#### 1. 计算哈希值
200200

@@ -294,7 +294,7 @@ func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
294294

295295
例如,原来 `B=5`,根据出 key 的哈希值的后 5 位,就能决定它落在哪个 bucket。扩容后的 buckets 数量翻倍,B 变成了 6,因此变成哈希值的后 6 位才能决定 key 落在哪个 bucket。这叫做 `rehash`
296296

297-
![map-evacuate-bucket-num](https://raw.githubusercontent.com/shipengqi/illustrations/d6f049a373b8bc7134b2fd13014a4e02aa7b6248/go/map-evacuate-bucket-num.png)
297+
![map-evacuate-bucket-num](https://gitee.com/shipengqi/illustrations/raw/main/go/map-evacuate-bucket-num.png)
298298

299299
因此,某个 key 在迁移前后 bucket 序号可能会改变,取决于 `rehash` 之后的哈希值倒数第 6 位是 0 还是 1。
300300

content/docs/basic/09_pointer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func main() {
6363
- 任何类型的指针 `*T` 可以和 `unsafe.Pointer` 相互转换。
6464
- `uintptr` 可以和 `unsafe.Pointer` 相互转换。
6565

66-
![pointer](https://raw.githubusercontent.com/shipengqi/illustrations/61f9eba25ea2a7f36ba14a9f6c06e13f14378c5d/go/pointer.png)
66+
![pointer](https://gitee.com/shipengqi/illustrations/raw/main/go/pointer.png)
6767

6868
指针类型转换示例:
6969

content/docs/concurrency/01_mutex.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type Mutex struct {
102102

103103
`state` 是一个复合型的字段,包含多个意义:
104104

105-
![mutex-state](https://raw.githubusercontent.com/shipengqi/illustrations/132b0f97ec250e221f725cbeb2d5c323a35f1cfe/go/mutex-state.png)
105+
![mutex-state](https://gitee.com/shipengqi/illustrations/raw/main/go/mutex-state.png)
106106

107107
在默认状态下,互斥锁的所有状态位都是 0,`int32` 中的不同位分别表示了不同的状态:
108108

content/docs/concurrency/03_waitgroup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ $ go vet proc.go
8989

9090
`state1` 包含一个总共占用 12 字节的数组,这个数组会存储当前结构体的状态,在 64 位与 32 位的机器上表现也非常不同。
9191

92-
![waitgroup-state1](https://raw.githubusercontent.com/shipengqi/illustrations/3039de62b8205f48431e7568e30a26c2f16524d9/go/waitgroup-state1.png)
92+
![waitgroup-state1](https://gitee.com/shipengqi/illustrations/raw/main/go/waitgroup-state1.png)
9393

9494
`state` 方法用来从 `state1` 字段中取出它的状态和信号量。
9595

content/docs/concurrency/07_context.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ context 的最大作用就是在一组 goroutine 构成的树形结构中对信
6666
例如,Go 的 HTTP server,处理每一个请求,都是启动一个单独的 goroutine,处理过程中还会启动新的 goroutine 来访问数据库和其他服务。而 context 在不同 Goroutine 之间可以同步请求特定数据、取消信号以及处理
6767
请求的截止日期。
6868

69-
![context](https://raw.githubusercontent.com/shipengqi/illustrations/505be84aff62a8b94292bf3468f0d9a1c8c049cf/go/context.png)
69+
![context](https://gitee.com/shipengqi/illustrations/raw/main/go/context.png)
7070

7171
每一个 context 都会从 root goroutine 一层层传递到底层。context 可以在上层 goroutine 执行出现错误时,将信号及时同步给下层。
7272

content/docs/practice/04_pprof.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func main() {
6060

6161
打开 http://localhost:8080/debug/pprof 后会看到下面页面:
6262

63-
![pprof-home](https://raw.githubusercontent.com/shipengqi/illustrations/810cbdff82baab7279ec4504d20e5b7bd88b6b33/go/pprof-home.png)
63+
![pprof-home](https://gitee.com/shipengqi/illustrations/raw/main/go/pprof-home.png)
6464

6565
pprof 包括了几个子页面:
6666

@@ -99,13 +99,13 @@ $ (pprof) web
9999

100100
> 如果出现 `Could not execute dot; may need to install graphviz.`,那么需要安裝 Graphviz。
101101

102-
![profile-graph](https://raw.githubusercontent.com/shipengqi/illustrations/810cbdff82baab7279ec4504d20e5b7bd88b6b33/go/profile-graph.png)
102+
![profile-graph](https://gitee.com/shipengqi/illustrations/raw/main/go/profile-graph.png)
103103

104104
图中框越大,线越粗代表它占用 CPU 的时间越长。
105105

106106
点击 `View -> Flame Graph` 可以查看火焰图:
107107

108-
![profile-flame-graph](https://raw.githubusercontent.com/shipengqi/illustrations/810cbdff82baab7279ec4504d20e5b7bd88b6b33/go/profile-flame-graph.png)
108+
![profile-flame-graph](https://gitee.com/shipengqi/illustrations/raw/main/go/profile-flame-graph.png)
109109

110110
图中调用顺序由上到下,每一块代表一个函数,越大代表占用 CPU 的时间越长。
111111

content/docs/practice/05_trace.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ $ go tool trace trace.out
7070

7171
访问 http://127.0.0.1:59181,可以看到类似的界面:
7272

73-
![trace-home](https://raw.githubusercontent.com/shipengqi/illustrations/f700fde7450ccdb21c410611ff949769e301c364/go/trace-home.png)
73+
![trace-home](https://gitee.com/shipengqi/illustrations/raw/main/go/trace-home.png)
7474

7575
- `View trace`:查看所有 goroutines 的执行过程。
7676
- `Goroutine analysis`:goroutines 分析,查看具体的 goroutine 的信息。
@@ -88,7 +88,7 @@ $ go tool trace trace.out
8888

8989
进入 `View trace` 页面:
9090

91-
![view-trace](https://raw.githubusercontent.com/shipengqi/illustrations/f700fde7450ccdb21c410611ff949769e301c364/go/view-trace.png)
91+
![view-trace](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace.png)
9292

9393
1. 时间线:显示执行的时间。
9494
2. Goroutines/Heap/Threads 的详细信息。
@@ -103,32 +103,32 @@ $ go tool trace trace.out
103103
104104
#### 查看某个时间点 goroutines 情况
105105

106-
![view-trace-g-counter](https://raw.githubusercontent.com/shipengqi/illustrations/f700fde7450ccdb21c410611ff949769e301c364/go/view-trace-g-counter.png)
106+
![view-trace-g-counter](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace-g-counter.png)
107107

108108
图中正在运行的 goroutine 数量为 3,其他状态的 goroutine 数量都是 0。
109109

110110
#### 查看某个时间点堆的使用情况
111111

112-
![view-trace-heap](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/view-trace-heap.png)
112+
![view-trace-heap](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace-heap.png)
113113

114114
1. 红色部分表示已经占用的内存
115115
2. 绿色部分的上边沿表示下次 GC 的目标内存,也就是绿色部分用完之后,就会触发 GC。
116116

117117
#### 查看某个时间点的系统线程
118118

119-
![view-trace-threads](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/view-trace-threads.png)
119+
![view-trace-threads](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace-threads.png)
120120

121121
图中正在运行的线程数量为 3,正在调用 SysCall 的线程数量为 0。
122122

123123
#### 查看 GC
124124

125-
![view-trace-gc](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/view-trace-gc.png)
125+
![view-trace-gc](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace-gc.png)
126126

127127
可以选择多个查看统计信息。
128128

129129
#### 查看某个时间点的 goroutine 运行情况
130130

131-
![view-trace-folw-events](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/view-trace-folw-events.png)
131+
![view-trace-folw-events](https://gitee.com/shipengqi/illustrations/raw/main/go/view-trace-folw-events.png)
132132

133133
点击具体的 Goroutine 可以查看详细信息:
134134

@@ -149,11 +149,11 @@ $ go tool trace trace.out
149149

150150
进入 `Goroutine analysis` 可查看整个运行过程中,每个函数块有多少个 goroutine 在跑,并且观察每个的 goroutine 的运行开销都花费在哪个阶段。
151151

152-
![goroutines-analysis](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/goroutines-analysis.png)
152+
![goroutines-analysis](https://gitee.com/shipengqi/illustrations/raw/main/goroutines-analysis.png)
153153

154154
点击一个 goroutine 查看详细信息,例如 `main.main.func1`
155155

156-
![goroutines-analysis-n](https://raw.githubusercontent.com/shipengqi/illustrations/aa2cb61b817e520379277b90937ac21909b4abd5/go/goroutines-analysis-n.png)
156+
![goroutines-analysis-n](https://gitee.com/shipengqi/illustrations/raw/main/goroutines-analysis-n.png)
157157

158158
| 名称 | 含义 | 耗时 |
159159
|-----------------------|--------|-------|

content/docs/practice/06_performance.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ CPU 访问内存时,并不是逐个字节访问,而是以**字长**(word s
5454

5555
进行内存对齐,就是为了减少 CPU 访问内存的次数。
5656

57-
![mem-align](https://raw.githubusercontent.com/shipengqi/illustrations/0a6f953f0387c30638ae8b0e03dda230194d10ab/go/mem-align.png)
57+
![mem-align](https://gitee.com/shipengqi/illustrations/raw/main/go/mem-align.png)
5858

5959
上图中,假如 CPU 字长为 4 个字节。变量 a 和 b 的大小为 3 个字节,没有内存对齐之前,CPU 读取 b 时,需要访问两次内存:
6060

@@ -127,7 +127,7 @@ func main() {
127127

128128
`Part1` 只是对成员变量的字段顺序进行了调整,就减少了结构体占用大小。
129129

130-
![mem-align](https://raw.githubusercontent.com/shipengqi/illustrations/ca9f00e7c3f54f02935d6615da69123d09ee8c7c/go/struct-mem-align.png)
130+
![mem-align](https://gitee.com/shipengqi/illustrations/raw/main/go/struct-mem-align.png)
131131

132132
`part1`
133133

0 commit comments

Comments
 (0)