Skip to content

Commit b5cf766

Browse files
committed
更正网友评论区指出的错误字与表述问题
1 parent d245c88 commit b5cf766

File tree

12 files changed

+40
-34
lines changed

12 files changed

+40
-34
lines changed

source/c01/c01_04.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ cannot use "A" (type string) as type byte in assignment
9191

9292

9393

94-
上面我说了,byte 和 uint8 没有区别,rune 和 uint32 没有区别,那为什么还要多出一个 byte 和 rune 类型呢?
94+
上面我说了,byte 和 uint8 没有区别,rune 和 int32 没有区别,那为什么还要多出一个 byte 和 rune 类型呢?
9595

96-
理由很简单,因为uint8 和 uint32 ,直观上让人以为这是一个数值,但是实际上,它也可以表示一个字符,所以为了消除这种直观错觉,就诞生了 byte 和 rune 这两个别名类型。
96+
理由很简单,因为uint8 和 int32 ,直观上让人以为这是一个数值,但是实际上,它也可以表示一个字符,所以为了消除这种直观错觉,就诞生了 byte 和 rune 这两个别名类型。
9797

9898

9999

@@ -239,4 +239,3 @@ func main() {
239239

240240

241241

242-

source/c01/c01_04.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ Unicode字符(Unicode是一个可以表示世界范围内的绝大部分字符
9696
9797
cannot use "A" (type string) as type byte in assignment
9898
99-
上面我说了,byte 和 uint8 没有区别,rune 和 uint32
99+
上面我说了,byte 和 uint8 没有区别,rune 和 int32
100100
没有区别,那为什么还要多出一个 byte 和 rune 类型呢?
101101

102-
理由很简单,因为uint8 和 uint32
102+
理由很简单,因为uint8 和 int32
103103
,直观上让人以为这是一个数值,但是实际上,它也可以表示一个字符,所以为了消除这种直观错觉,就诞生了
104104
byte 和 rune 这两个别名类型。
105105

source/c01/c01_12.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ func main() {
100100
}
101101
```
102102

103-
非常抱歉,目前以我的水平,暂时还无法解释这种现象,我建议是单独记忆一下这种特殊场景。
103+
这种现象对于新手来说,确实是个难点,不过这是面试的热点话题,感兴趣的朋友,可以去我的个人博客,查看下面这两篇文章:
104+
105+
- [Go 语言面试题 100 讲之 014篇:说说 Go 中闭包的底层原理?](https://iswbm.com/534.html)
106+
- [Go 语言面试题 100 讲之 015篇:defer 的变量快照什么情况会失效?](https://iswbm.com/535.html)
104107

105108
## 3. 多个defer 反序调用
106109

source/c01/c01_12.rst

+6-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,12 @@ defer 的用法很简单,只要在后面跟一个函数的调用,就能实
106106
fmt.Println(name) // 输出: python
107107
}
108108
109-
非常抱歉,目前以我的水平,暂时还无法解释这种现象,我建议是单独记忆一下这种特殊场景。
109+
这种现象对于新手来说,确实是个难点,不过这是面试的热点话题,感兴趣的朋友,可以去我的个人博客,查看下面这两篇文章:
110+
111+
- `Go 语言面试题 100 讲之 014篇:说说 Go
112+
中闭包的底层原理? <https://iswbm.com/534.html>`__
113+
- `Go 语言面试题 100 讲之 015篇:defer
114+
的变量快照什么情况会失效? <https://iswbm.com/535.html>`__
110115

111116
3. 多个defer 反序调用
112117
---------------------

source/c02/c02_06.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ func main() {
5050
./demo.go:30:10: phone.send_wechat undefined (type Phone has no field or method send_wechat)
5151
```
5252

53-
原因也很明显,因为我们的phone对象显示声明为 Phone 接口类型,因此 phone调用的方法会受到此接口的限制。
53+
原因也很明显,因为我们的phone对象显式声明为 Phone 接口类型,因此 phone调用的方法会受到此接口的限制。
5454

5555
**那么如何让 phone 可以调用 send_wechat 方法呢?**
5656

57-
答案是可以不显示的声明为 Phone接口类型 ,但要清楚 phone 对象实际上是隐式的实现了 Phone 接口,如此一来,方法的调用就不会受到接口类型的约束。
57+
答案是可以不显式的声明为 Phone接口类型 ,但要清楚 phone 对象实际上是隐式的实现了 Phone 接口,如此一来,方法的调用就不会受到接口类型的约束。
5858

5959
修改 main 方法成如下
6060

@@ -144,7 +144,7 @@ func main() {
144144

145145
当你使用这种写法时,Go 会默默地为我们做一件事,就是把传入函数的参数值(注意:Go 语言中的函数调用都是值传递的)的类型隐式的转换成 interface{} 类型。
146146

147-
### 如何进行接口类型的显示转换
147+
### 如何进行接口类型的显式转换
148148

149149
上面了解了函数中 接口类型的隐式转换后,你的心里可能开始有了疑问了,难道我使用类型断言,只能通过一个接收空接口类型的函数才能实现吗?
150150

source/c02/c02_06.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ call 函数),一个是发微信(send_wechat 函数)。
5757
# command-line-arguments
5858
./demo.go:30:10: phone.send_wechat undefined (type Phone has no field or method send_wechat)
5959
60-
原因也很明显,因为我们的phone对象显示声明为 Phone 接口类型,因此
60+
原因也很明显,因为我们的phone对象显式声明为 Phone 接口类型,因此
6161
phone调用的方法会受到此接口的限制。
6262

6363
**那么如何让 phone 可以调用 send_wechat 方法呢?**
6464

65-
答案是可以不显示的声明为 Phone接口类型 ,但要清楚 phone
65+
答案是可以不显式的声明为 Phone接口类型 ,但要清楚 phone
6666
对象实际上是隐式的实现了 Phone
6767
接口,如此一来,方法的调用就不会受到接口类型的约束。
6868

@@ -156,7 +156,7 @@ Go 语言中的函数调用都是值传递的,变量会在方法调用前进
156156
会默默地为我们做一件事,就是把传入函数的参数值(注意:Go
157157
语言中的函数调用都是值传递的)的类型隐式的转换成 interface{} 类型。
158158

159-
如何进行接口类型的显示转换
159+
如何进行接口类型的显式转换
160160
~~~~~~~~~~~~~~~~~~~~~~~~~~
161161

162162
上面了解了函数中

source/c04/c04_11.md

+7-8
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,18 @@ select 和 pool ,除了解决了连接数的限制 ,其他似乎没有本质
8080

8181
epoll 解决了前期 select 和 poll 出现的一系列的尴尬问题,比如:
8282

83-
- select 和 poll 无差别轮循fd,浪费资源,epool 使用通知回调机制,有流发生 IO事件时就会主动触发回调函数
84-
- select 和 poll 线程不安全,epool 线程安全
85-
- select 请求连接数的限制,epool 能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
83+
- select 和 poll 无差别轮循fd,浪费资源,epoll 使用通知回调机制,有流发生 IO事件时就会主动触发回调函数
84+
- select 和 poll 线程不安全,epoll 线程安全
85+
- select 请求连接数的限制,epoll 能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
8686
- select 和 pool 需要频繁地将fd复制到内核空间,开销大,epoll通过内核和用户空间共享一块内存来减少这方面的开销。
8787

88-
虽然 I/O 多路复用经历了三种实现:select -> pool -> epool,这也不是就说 epool 出现了, select 就会被淘汰掉。
88+
虽然 I/O 多路复用经历了三种实现:select -> pool -> epoll,这也不是就说 epoll 出现了, select 就会被淘汰掉。
8989

90-
epool 关注的是活跃的连接数,当连接数非常多但活跃连接少的情况下(比如长连接数较多),epool 的性能最好。
90+
epoll 关注的是活跃的连接数,当连接数非常多但活跃连接少的情况下(比如长连接数较多),epoll 的性能最好。
9191

92-
而 select 关注的是连接总数,当连接数多而且大部分的连接都很活跃的情况下,选择 select 会更好,因为 epool 的通知回调机制需要很多的函数回调。
92+
而 select 关注的是连接总数,当连接数多而且大部分的连接都很活跃的情况下,选择 select 会更好,因为 epoll 的通知回调机制需要很多的函数回调。
9393

94-
另外还有一点是,select 是 POSIX 规定的,一般操作系统均有实现,而 epool 是 Linux 所有的,其他平台上没有。
94+
另外还有一点是,select 是 POSIX 规定的,一般操作系统均有实现,而 epoll 是 Linux 所有的,其他平台上没有。
9595

9696
IO多路复用除了以上三种不同的具体实现的区别外,还可以根据线程数的多少来分类
9797

@@ -159,4 +159,3 @@ https://studygolang.com/articles/13344
159159

160160

161161

162-

source/c04/c04_11.rst

+9-9
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,26 @@ descriptor),而你要处理一个请求,却要遍历几万个fd,这样
9898

9999
epoll 解决了前期 select 和 poll 出现的一系列的尴尬问题,比如:
100100

101-
- select 和 poll 无差别轮循fd,浪费资源,epool
101+
- select 和 poll 无差别轮循fd,浪费资源,epoll
102102
使用通知回调机制,有流发生 IO事件时就会主动触发回调函数
103-
- select 和 poll 线程不安全,epool 线程安全
104-
- select 请求连接数的限制,epool
103+
- select 和 poll 线程不安全,epoll 线程安全
104+
- select 请求连接数的限制,epoll
105105
能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
106106
- select 和 pool
107107
需要频繁地将fd复制到内核空间,开销大,epoll通过内核和用户空间共享一块内存来减少这方面的开销。
108108

109-
虽然 I/O 多路复用经历了三种实现:select -> pool -> epool,这也不是就说
110-
epool 出现了, select 就会被淘汰掉。
109+
虽然 I/O 多路复用经历了三种实现:select -> pool -> epoll,这也不是就说
110+
epoll 出现了, select 就会被淘汰掉。
111111

112-
epool
113-
关注的是活跃的连接数,当连接数非常多但活跃连接少的情况下(比如长连接数较多),epool
112+
epoll
113+
关注的是活跃的连接数,当连接数非常多但活跃连接少的情况下(比如长连接数较多),epoll
114114
的性能最好。
115115

116116
而 select
117117
关注的是连接总数,当连接数多而且大部分的连接都很活跃的情况下,选择
118-
select 会更好,因为 epool 的通知回调机制需要很多的函数回调。
118+
select 会更好,因为 epoll 的通知回调机制需要很多的函数回调。
119119

120-
另外还有一点是,select 是 POSIX 规定的,一般操作系统均有实现,而 epool
120+
另外还有一点是,select 是 POSIX 规定的,一般操作系统均有实现,而 epoll
121121
是 Linux 所有的,其他平台上没有。
122122

123123
IO多路复用除了以上三种不同的具体实现的区别外,还可以根据线程数的多少来分类

source/c05/c05_04.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ func main() {
291291
wg.Add(2)
292292
dataChan := make(chan []byte)
293293
go func() {
294-
wg.Done()
294+
defer wg.Done()
295295
for {
296296
data := make([]byte, 100)
297297
n, _ := syscall.Read(fd, data)

source/c05/c05_04.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ os 库本质上也是调用 syscall 库,但由于 syscall
309309
wg.Add(2)
310310
dataChan := make(chan []byte)
311311
go func() {
312-
wg.Done()
312+
defer wg.Done()
313313
for {
314314
data := make([]byte, 100)
315315
n, _ := syscall.Read(fd, data)

source/c06/c06_05.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ http://0.0.0.0:9999
116116
- 本地电脑,就访问:http://localhost:9999
117117
- 服务器,就访问:http://host-ip:9999
118118

119-
然后就可以看到像下面这样的可视化界面,一下子就可能牛二以 main.concat 的区域最大
119+
然后就可以看到像下面这样的可视化界面,一下子就可以看出 main.concat 的区域最大
120120

121121
![](http://image.iswbm.com/20220119150344.png)
122122

source/c06/c06_05.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pprof <https://darjun.github.io/2021/06/09/youdontknowgo/pprof/>`__\ ,写得
127127
- 本地电脑,就访问:http://localhost:9999
128128
- 服务器,就访问:http://host-ip:9999
129129

130-
然后就可以看到像下面这样的可视化界面,一下子就可能牛二以 main.concat
130+
然后就可以看到像下面这样的可视化界面,一下子就可以看出 main.concat
131131
的区域最大
132132

133133
.. image:: http://image.iswbm.com/20220119150344.png

0 commit comments

Comments
 (0)