Skip to content

Commit

Permalink
Merge branch 'master' of github.com:wolverinn/Waking-Up
Browse files Browse the repository at this point in the history
  • Loading branch information
wolverinn committed Mar 14, 2022
2 parents 82cc1c3 + c1f3e9c commit c74233a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 10 deletions.
33 changes: 30 additions & 3 deletions Computer Network.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* [什么是四次挥手?](#什么是四次挥手)
* [TCP如何实现流量控制?](#TCP如何实现流量控制)
* [TCP的拥塞控制是怎么实现的?](#TCP的拥塞控制是怎么实现的)
* [TCP如何最大利用带宽?](#TCP如何最大利用带宽)
* [TCP与UDP的区别](#TCP与UDP的区别)
* [TCP如何保证传输的可靠性](#TCP如何保证传输的可靠性)
* [~~什么是TCP粘包?~~](#什么是TCP粘包)
Expand Down Expand Up @@ -127,6 +128,8 @@ MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间

发送窗口的上限为接受窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。

![滑动窗口](_v_images/1615897397.gif)

##### 什么是零窗口(接收窗口为0时会怎样)?

<details>
Expand Down Expand Up @@ -155,6 +158,30 @@ MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间
4. 快恢复:当发送方连续收到三个重复确认时,就把慢开始门限减半,然后执行拥塞避免算法。不执行慢开始算法的原因:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方认为现在网络可能没有出现拥塞。
也有的快重传是把开始时的拥塞窗口cwnd值再增大一点,即等于 ssthresh + 3*MSS 。这样做的理由是:既然发送方收到三个重复的确认,就表明有三个分组已经离开了网络。这三个分组不再消耗网络的资源而是停留在接收方的缓存中。可见现在网络中减少了三个分组。因此可以适当把拥塞窗口扩大些。

### TCP如何最大利用带宽?

TCP速率受到三个因素影响

- 窗口:即滑动窗口大小,见[TCP如何实现流量控制?](#TCP如何实现流量控制)
- 带宽:这里带宽是指单位时间内从发送端到接收端所能通过的“最高数据率”,是一种硬件限制。TCP发送端和接收端的数据传输数不可能超过两点间的带宽限制。发送端和接收端之间带宽取所通过线路的带宽最小值(如通过互联网连接)。
- RTT:即Round Trip Time,表示从发送端到接收端的一去一回需要的时间,TCP在数据传输过程中会对RTT进行采样(即对发送的数据包及其ACK的时间差进行测量,并根据测量值更新RTT值),TCP根据得到的RTT值更新RTO值,即Retransmission TimeOut,就是重传间隔,发送端对每个发出的数据包进行计时,如果在RTO时间内没有收到所发出的数据包的对应ACK,则任务数据包丢失,将重传数据。一般RTO值都比采样得到的RTT值要大。

<details>
<summary>带宽时延乘积</summary>

带宽时延乘积=带宽*RTT,实际上等于发送端到接收端单向通道的数据容积的两倍,这里单向通道的数据容积可以这样来理解,单向通道看成是一条单行道马路,带宽就是马路的车道数,路上跑的汽车就是数据(不过这里所有汽车的速率都是一样的,且不会有人想超车,大家齐头并进),那么单向通道的数据容积就是这条单行道上摆满车,一共可以摆多少辆。带宽就是马路的车道数,带宽数乘以单向通道的数据容积就是路面上所能容纳的全部数据量。当路面上已经摆满的时候,就不能再往里面放了。
</details>

设滑动窗口大小为![](https://latex.codecogs.com/svg.latex?W), 发送端和接收端的带宽为![](https://latex.codecogs.com/svg.latex?B), RTT为![](https://latex.codecogs.com/svg.latex?T_r)

前面已经说过了,TCP发送数据时受滑动窗口的限制,当TCP将滑动窗口中的数据都发出后,在收到第一个ACK之前,滑动窗口大小是0,不能再发送数据了,必须等待ACK包使滑动窗口移动。那么在理想情况下,ACK包应该在什么时候到达呢?显然,就是在数据发出后的RTT时间后,ACK包到达。这也就是说,现在在不考虑丢包和拥塞情况下,TCP在一个RTT时间内能发出的最大数据量为 ![](http://latex.codecogs.com/gif.latex?W) ,所以不考虑带宽限制下,TCP能一个时刻能达到的最大速度是 ![](https://latex.codecogs.com/svg.latex?V=\frac{W}{T_r})

现在再考虑带宽限制,前面说过当马路上摆满车的时候,就无法再往里放车了,同理,TCP发送端在 ![](https://latex.codecogs.com/svg.latex?\frac{T_r}{2}) 时间内,能往通道上放的最大数据量为 ![](https://latex.codecogs.com/svg.latex?\frac{V*T_r}{2}) ,通过带宽时延乘积得到的容积限制为 ![](https://latex.codecogs.com/svg.latex?\frac{B*T_r}{2})。当 ![](https://latex.codecogs.com/svg.latex?\frac{B*T_r}{2}%20\geq%20\frac{V*T_r}{2}) 时,单向通道容积不构成瓶颈,速率的限制主要来源于窗口大小限制。而当 ![](https://latex.codecogs.com/svg.latex?\frac{V*T_r}{2}%20\geq%20\frac{B*T_r}{2}) 时,则就受到容积限制,即此时速率限制来源于带宽限制。

因此,TCP的最大速率为 ![](https://latex.codecogs.com/svg.latex?V%20=%20\min{(\frac{W}{T_r},%20B)})

在我们平时生活中使用的宽带网络,ADSL等环境下,因为带宽都比较小,从而 ![](https://latex.codecogs.com/svg.latex?B*T_r) 也比较小,再加上网络情况比较复杂,拥塞情况比较常见,所以这些网络环境下,TCP速率的主要限制因素在于带宽,丢包率等。长肥管道一般不太常见,多见于一些单位使用的专线网络,在这些网络中速率的主要限制因素就是窗口大小了,这也是传统TCP在这些网络环境中不能充分利用带宽的原因所在(因为传统TCP的窗口大小是用2字节表示的,所以最大只有65535(不考虑窗口扩大选项)),除了专线网络外,随着网络硬件技术的发展,万兆交换机的出现,局域网中也可能会出现带宽时延乘积较大的情况。

### TCP与UDP的区别

1. TCP是面向连接的,UDP是无连接的;
Expand Down Expand Up @@ -196,6 +223,8 @@ UDP接收方收到报文后,不需要给出任何确认
<summary>展开</summary>
HTTP不可以使用UDP,HTTP需要基于可靠的传输协议,而UDP不可靠

注:**http 3.0 使用udp实现**
https://zh.wikipedia.org/wiki/HTTP/3
</details>

##### 面向连接和无连接的区别
Expand Down Expand Up @@ -369,6 +398,4 @@ Cookie保存在客户端本地,客户端请求服务器时会将Cookie一起
### 参考
- [面试/笔试第一弹 —— 计算机网络面试问题集锦](https://blog.csdn.net/justloveyou_/article/details/78303617)
- [什么时候选TCP、UDP?](https://blog.csdn.net/yjxsdzx/article/details/71937886)

### 待完成
- [ ] 发送窗口的大小,如何最大利用带宽,假设延迟100ms,发送端10Mb/s,接收端100Mb/s. [reference](https://blog.csdn.net/bad_sheep/article/details/6158676)
- [TCP速率与窗口,带宽,RTT之间的关系](https://blog.csdn.net/bad_sheep/article/details/6158676)
4 changes: 3 additions & 1 deletion Database.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
- **丢失修改**:一个事务对数据进行了修改,在事务提交之前,另一个事务对同一个数据进行了修改,覆盖了之前的修改;
- **脏读**(Dirty Read):一个事务读取了被另一个事务修改、但未提交(进行了回滚)的数据,造成两个事务得到的数据不一致;
- **不可重复读**(Nonrepeatable Read):在同一个事务中,某查询操作在一个时间读取某一行数据和之后一个时间读取该行数据,发现数据已经发生修改(针对**update**操作);
- **幻读**(Phantom Read):当同一查询多次执行时,由于其它事务在这个数据范围内执行了插入操作,会导致每次返回不同的结果集(和不可重复读的区别:针对的是一个数据整体/范围;并且针对**insert/delete**操作)
- **幻读**(Phantom Read):当同一查询多次执行时,由于其它事务在这个数据范围内执行了插入操作,会导致每次返回不同的结果集(和不可重复读的区别:针对的是一个数据整体/范围;并且针对**insert**操作)

### 数据库的四种隔离级别?

Expand Down Expand Up @@ -291,6 +291,8 @@ InnoDB的索引使用的是B+树实现,B+树对比B树的好处:
- 冷备份:数据库正常关闭后,将关键性文件复制到另一位置的备份方式。优点:操作简单快速,恢复简单
</details>

更详细的可以参考:[MySQL 数据库的存储引擎与适用场景 - Images](https://imageslr.github.io/2020/db-engine.html)

### 如何优化数据库?
<details>
<summary>SQL 语句的优化</summary>
Expand Down
1 change: 1 addition & 0 deletions Git-ComdLine-REST.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ REST指Representational State Transfer,可以翻译为“表现层状态转化
## Linux 常用命令

### 参考
- [Learn Git Branching - 可视化的学习 Git 操作](https://learngitbranching.js.org/?demo=&locale=zh_CN)
- [Git教程 - 廖雪峰的官方网站](https://www.liaoxuefeng.com/wiki/896043488029600)
- [RESTful API 最佳实践 - 阮一峰的网络日志](http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html)
- [GitHub - jlevy/the-art-of-command-line: Master the command line, in one page](https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh.md)
37 changes: 36 additions & 1 deletion Operating Systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [什么是僵尸进程?](#什么是僵尸进程)
* [线程同步有哪些方式?](#线程同步有哪些方式)
* [什么是协程?](#什么是协程)
* [进程的异常控制流:陷阱、中断、异常和信号](#进程的异常控制流:陷阱、中断、异常和信号)
* [什么是IO多路复用?怎么实现?](#什么是IO多路复用怎么实现)
* [什么是用户态和内核态?](#什么是用户态和内核态)
* 死锁
Expand All @@ -19,6 +20,7 @@
* [分页和分段有什么区别?](#分页和分段有什么区别)
* [什么是虚拟内存?](#什么是虚拟内存)
* [有哪些页面置换算法?](#有哪些页面置换算法)
* [缓冲区溢出问题](#缓冲区溢出问题)
* [磁盘调度](#磁盘调度)
* [参考](#参考)

Expand Down Expand Up @@ -293,7 +295,7 @@ void test_forks(int i) {
<details>
<summary>展开</summary>
高优先级的进程等待被一个低优先级进程占用的资源时,就会出现优先级反转,即优先级较低的进程比优先级较高的进程先执行。
高优先级的进程等待被一个低优先级进程占用的资源时,就会出现优先级反转,即优先级较低的进程比优先级较高的进程先执行。此处详细解释优先级反转带来的问题:如果有一个中等优先级的进程将低优先级的进程抢占,那么此时低优先级的进程无法正常进行并在后续释放被占用的资源,导致高优先级的任务一直被挂起,直到中等优先级的进程完成后,低优先级的进程才可以继续并在后续释放占用的资源,最后高优先级的进程才可以执行。导致的问题就是高优先级的进程在中等优先级的进程调度之后。
解决方法:
- 优先级天花板(priority ceiling):当任务申请某资源时,把该任务的优先级提升到可访问这个资源的所有任务中的最高优先级,这个优先级称为该资源的优先级天花板。简单易行。
Expand Down Expand Up @@ -349,6 +351,18 @@ void test_forks(int i) {
3. 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态
</details>
### 进程的异常控制流:陷阱、中断、异常和信号
陷阱是**有意**造成的“异常”,是执行一条指令的结果。陷阱是同步的。陷阱的主要作用是实现**系统调用**。比如,进程可以执行 `syscall n` 指令向内核请求服务。当进程执行这条指令后,会中断当前的控制流,**陷入**到内核态,执行相应的系统调用。内核的处理程序在执行结束后,会将结果返回给进程,同时退回到用户态。进程此时继续执行**下一条指令**。
中断由处理器**外部**的**硬件**产生,不是执行某条指令的结果,也无法预测发生时机。由于中断独立于当前执行的程序,因此中断是异步事件。中断包括 I/O 设备发出的 I/O 中断、各种定时器引起的时钟中断、调试程序中设置的断点等引起的调试中断等。
异常是一种错误情况,是执行当前指令的结果,可能被错误处理程序修正,也可能直接终止应用程序。异常是同步的。这里特指因为执行当前指令而产生的**错误情况**,比如除法异常、缺页异常等。有些书上为了区分,也将这类“异常”称为**“故障”**。
信号是一种**更高层的**软件形式的异常,同样会中断进程的控制流,可以由进程进行处理。一个信号代表了一个消息。信号的作用是用来**通知进程**发生了某种系统事件。
更详细的可以参考:https://imageslr.github.io/2020/07/09/trap-interrupt-exception.html
### 什么是IO多路复用?怎么实现?
IO多路复用(IO Multiplexing)是指单个进程/线程就可以同时处理多个IO请求。
Expand Down Expand Up @@ -497,6 +511,8 @@ IO多路复用(IO Multiplexing)是指单个进程/线程就可以同时处
虚拟内存的优点是让程序可以获得更多的可用内存。
虚拟内存的实现方式、页表/多级页表、缺页中断、不同的页面淘汰算法:[答案](https://imageslr.github.io/2020/07/08/tech-interview.html#virtual-memory)。
##### 如何进行地址空间到物理内存的映射?
<details>
<summary>展开</summary>
Expand Down Expand Up @@ -532,6 +548,25 @@ IO多路复用(IO Multiplexing)是指单个进程/线程就可以同时处
- 终止该进程或增加物理内存容量。
</details>
### 缓冲区溢出问题
<details>
<summary>什么是缓冲区溢出?</summary>
C 语言使用运行时栈来存储过程信息。每个函数的信息存储在一个栈帧中,包括寄存器、局部变量、参数、返回地址等。C 对于数组引用不进行任何边界检查,因此**对越界的数组元素的写操作会破坏存储在栈中的状态信息**,这种现象称为缓冲区溢出。缓冲区溢出会破坏程序运行,也可以被用来进行攻击计算机,如使用一个指向攻击代码的指针覆盖返回地址。
</details>
<details>
<summary>缓冲区溢出的防范方式</summary>
防范缓冲区溢出攻击的机制有三种:随机化、栈保护和限制可执行代码区域。
- 随机化:包括栈随机化(程序开始时在栈上分配一段随机大小的空间)和地址空间布局随机化(Address-Space Layout Randomization,ASLR,即每次运行时程序的不同部分,包括代码段、数据段、栈、堆等都会被加载到内存空间的不同区域),但只能增加攻击一个系统的难度,不能完全保证安全。
- 栈保护:在每个函数的栈帧的局部变量和栈状态之间存储一个**随机产生的**特殊的值,称为金丝雀值(canary)。在恢复寄存器状态和函数返回之前,程序检测这个金丝雀值是否被改变了,如果是,那么程序异常终止。
- 限制可执行代码区域:内存页的访问形式有三种:可读、可写、可执行,只有编译器产生的那部分代码所处的内存才是可执行的,其他页限制为只允许读和写。
</details>
更详细的可以参考:https://imageslr.github.io/2020/07/08/tech-interview.html#stackoverflow
### 磁盘调度
过程:磁头(找到对应的盘面);磁道(一个盘面上的同心圆环,寻道时间);扇区(旋转时间)。为减小寻道时间的调度算法:
Expand Down
Loading

0 comments on commit c74233a

Please sign in to comment.