通信安全性
http 传输数据是明文的,且是不安全的。整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求/响应报文,数据不具有可信性。对于网络购物、证券交易需要高度信任的应用场景是致命的
通常认为,如果通信过程具备了四个特性,就可以认为是安全的,四个特性是:机密性、完整性、身份认证和不可否认
- 机密性:对数据的保密,只能由可信的人访问,对其他人是不可见的秘密
- 完整性:也称为一致性,数据在传输过程中没有被篡改,保持原状
1 | func main() { |
如上,结果表明,循环只遍历了原始切片中的三个元素,在遍历切片时追加的元素不会增加循环的执行次数,因此循环最终还是会停下来。
原理:Go语言源码中,对于所有的 range 循环,Go 语言都会在编译期将原切片或者数组赋值给一个新变量,在赋值过程中就发生了复制,并且又使用 len 关键字预先获取了切片的长度,所以在循环中追加新元素不会改变循环执行的次数。
1 | func main() { |
首先明确go语言的设计模块:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。这样在我看来让 go 语言代码更加整洁。因此 go 语言中 Goroutine 之间会通过 Channel 传递数据。基于go 1.15 版本,Channel 的实现:
chan 的底层数据结构如下:
1 | type hchan struct { |
chan 使用 make 关键字创建,可以带缓冲区的异步 Channel 和不带缓冲区的同步 Channel。这里对创建过程不做赘述。基本上分为三种情况:
基于 Go 语言 1.15 版本
互斥锁有两种状态:正常状态和饥饿状态
在正常状态下,所有等待锁的 Goroutine 按照 FIFO(先进先出)的顺序等待。唤醒的 Goroutine 不会直接拥有锁,而是会和新请求锁的 Goroutine 竞争锁的拥有。新请求锁的 Goroutine 具有优势,他正在 CPU 上执行,而且可能有好几个,所以刚刚唤醒的 Goroutine 有很大可能在锁竞争中失败。在这种情况下,这个被唤醒的 Goroutine 会加入到等待队列的前面。如果一个等待的 Goroutine 超过 1ms 没有获取到锁,那么他将会把锁变为饥饿模式
在饥饿模式下,锁的所有权会直接交给等待队列最前面的 Goroutine。新来的 Goroutine 在该状态下将不会尝试去获取锁,即使锁看起来是 unlock 状态,也不会尝试自旋操作,而是放在等待队列的尾部
如果一个等待的 Goroutine 获取了锁,并且满足以下其中的任何一个条件,他会将锁的状态转换为正常状态