
操作系统知识点
进程与线程
上图进程与线程部分是一个非常重要的考察点。
首先需要掌握进程与线程的区别和联系:
- 进程是系统资源分配的最小单位,线程是程序执行的最小单位;
- 进程使用独立的数据空间,而线程共享进程的数据空间。
线程调度,简单了解线程的几种调度算法就可以了。比如时间片轮转调度、先来先服务调度、优先级调度、多级反馈队列调度以及高响应比优先调度。
线程切换的步骤,主要是了解线程的上下文切换,明白线程切换的代价。关于线程的知识在后面的多线程课程中还会有详细讲解,这里先略过。
在进程与线程部分还有一个比较常见的考察点,就是进程间通信,也就是IPC。这部分在面试中间件研发的相关职位时经常会考察。如上面知识点汇总图中所示,需要了解这6种进程通信方式的原理与适用场景。例如,进程间数据共享的场景可以使用共享内存;进程间数据交换的场景可以使用UnixSocket或者消息队列。
最后协程部分,简单了解协程更轻量化,是在用户态进行调度,切换的代价比线程上下文切换要低很多就可以了,也可以了解Java的第三方协程框架,例如Kilim、Quasar等。
Linux 常用命令
大部分互联网公司的服务都是在Linux系统上运行的,因此Linux命令也是面试时的常考点,这部分其实主要考察的是候选人是否有线上问题的排查经验,重点学习AWK、top、netstat、grep等高频使用的工具
还有一些知识点不常考,做适当了解,例如内存分页管理与Swap机制、任务队列与CPULoad等,这些知识在分析线上问题中十分有用。
扩展知识
最后是扩展知识点,例如内存屏障、指令乱序、分支预测、NUMA与CPU亲和性等,如果在面试时有机会谈到的话,会在知识深度上给面试官留下比较好的印象
计算机网络知识点
计算机网络也是非常重要的基础知识,服务之间通过不同的网络协议进行交互,例如HTTP协议、RPC协议等,在Java面试中网络知识被考到的几率非常大。网络知识点汇总如下图。
首先你应该深刻理解网络的4/7层模型,这是网络知识的基础。
另外两个非常重要的网络协议就是HTTP和TCP了,这两个协议也是服务交互中使用最多的协议。先来看TCP协议,TCP协议中的三次握手建连与四次挥手断连是一个高频考点,后面会详细介绍。
TCP的报文状态标志与链接状态,在排查网络问题时非常重要,必须要明白协议状态,才方便抓包分析。
另一个知识点是Nagel算法和ACK延迟,需要了解产生的背景,是要解决小包问题,提高数据载荷比。知道对于延迟比较敏感且发送数据频率较低的场景可以关闭Nagel算法
关于TCP的Keepalive,是一种长时间没有数据发送的场景下,TCP保持链接可用的机制,需要知道TCPKeepalive的开启和设置方式。
最后一点,需要明白TCP是如何通过滑动窗口机制来实现流量控制的。
HTTP协议部分
- 需要掌握HTTP协议的规范,知道协议中的Method、Header、Cookies,需要了解常见状态码的含义,例如404、503、302等。
- 另外还有HTTPS的交互流程。
- 协议的了解可以在一定程度上体现对新技术的关注程度。可以关注:HTTP2多路复用、Stream流式交互、流量控制、服务端推送、头部压缩等新特性。
除了HTTP和TCP外,UDP也是一个比较常见的传输层协议,UDP的特点是非链接、非可靠传输,但是效率非常高。
最后可以对QUIC协议进行一些了解,QUIC已经被标准化为HTTP3协议。QUIC是基于UDP协议,但QUIC提供了类似TCP的可靠性保证和流量控制。QUIC可以有效避免HTTP2协议的前序包阻塞问题,能实现零RTT建连,提供FEC前向纠错能力。
详解 TCP 协议特点
TCP是传输层协议,对应OSI网络模型的第四层传输层,特点如下。
- TCP协议是基于链接的,也就是传输数据前需要先建立好链接,然后再进行传输。
- TCP链接一旦建立,就可以在链接上进行双向的通信
- TCP的传输是基于字节流而不是报文,将数据按字节大小进行编号,接收端通过ACK来确认收到的数据编号,通过这种机制,TCP协议能够保证接收数据的有序性和完整性,因此TCP能够提供可靠性传输。
- TCP还能提供流量控制能力,通过滑动窗口来控制数据的发送速率。滑动窗口的本质是动态缓冲区,接收端根据自己的处理能力,在TCP的Header中动态调整窗口大小,通过ACK应答包通知给发送端,发送端根据窗口大小调整发送的的速度。
- 仅仅有了流量控制能力还不够,TCP协议还考虑到了网络问题可能会导致大量重传,进而导致网络情况进一步恶化,因此TCP协议还提供拥塞控制。TCP处理拥塞控制主要用到了慢启动、拥塞避免、拥塞发生、快速恢复四个算法,感兴趣的同学可以进一步了解。
除了TCP协议的特点,还可以进一步了解TCP协议的报文状态、滑动窗口的工作流程、Keepalive的参数设置和Nagel算法的规则等一些细节。
另外还有典型的TCP协议问题,例如特定场景下Nagel和ACK延迟机制配合使用可能会出现delay40ms超时后才回复ACK包的问题
详解三次握手建连
接下来看TCP建连的三次握手。TCP是基于链接的,所以在传输数据前需要先建立链接,TCP在传输上是双工传输,不区分Client端与Server端,为了便于理解,我们把主动发起建连请求的一端称作Client端,把被动建立链接的一端称作Server端。
如下图,建连的时序是从上到下,左右两边的绿色字分别代表Client端与Server端当时的链接状态。
首先建立链接前需要Server端先监听端口,因此Server端建立链接前的初始状态就是LISTEN状态,这时Client端准备建立链接,先发送一个SYN同步包,发送完同步包后,Client端的链接状态变成了SYN_SENT状态。Server端收到SYN后,同意建立链接,会向Client端回复一个ACK。
由于TCP是双工传输,Server端也会同时向Client端发送一个SYN,申请Server向Client方向建立链接。发送完ACK和SYN后,Server端的链接状态就变成了SYN_RCVD。
Client收到Server的ACK后,Client端的链接状态就变成了ESTABLISHED状态,同时,Client向Server端发送ACK,回复Server端的SYN请求
Server端收到Client端的ACK后,Server端的链接状态也就变成了的ESTABLISHED状态,此时建连完成,双方随时可以进行数据传输。
需要明白三次握手是为了建立双向的链接,需要记住Client端和Server端的链接状态变化。另外回答建连的问题时,可以提到SYN洪水攻击发生的原因,就是Server端收到Client端的SYN请求后,发送了ACK和SYN,但是Client端不进行回复,导致Server端大量的链接处在SYN_RCVD状态,进而影响其他正常请求的建连。可以设置tcp_synack_retries = 0加快半链接的回收速度,或者调大tcp_max_syn_backlog来应对少量的SYN洪水攻击
详解四次挥手断连
再来看看TCP的断连,如下图所示。
TCP链接的关闭,通信双方都可以先发起,我们暂且把先发起的一方看作Client,从图中看出,通信中Client和Server两端的链接都是ESTABLISHED状态,然后Client先主动发起了关闭链接请求,Client向Server发送了一个FIN包,表示Client端已经没有数据要发送了,然后Client进入了FIN_WAIT_1状态。
Server端收到FIN后,返回ACK,然后进入CLOSE_WAIT状态。此时Server属于半关闭状态,因为此时Client向Server方向已经不会发送数据了,可是Server向Client端可能还有数据要发送。
当Server端数据发送完毕后,Server端会向Client端发送FIN,表示Server端也没有数据要发送了,此时Server进入LAST_ACK状态,就等待Client的应答就可以关闭链接了。
Client端收到Server端的FIN后,回复ACK,然后进入TIME_WAIT状态。TIME_WAIT状态下需要等待2倍的最大报文段生存时间,来保证链接的可靠关闭,之后才会进入CLOSED关闭状态。而Server端收到ACK后直接就进入CLOSED状态。
这里可能会问为什么需要等待2倍最大报文段生存时间之后再关闭链接,原因有两个:
- 保证TCP协议的全双工连接能够可靠关闭;
- 保证这次连接的重复数据段从网络中消失,防止端口被重用时可能产生数据混淆。
从这个交互流程可以看出,无论是建连还是断链,都是需要在两个方向上进行,只不过建连时,Server端的SYN和ACK合并为一次发送,而断链时,两个方向上数据发送停止的时间可能不同,所以不能合并发送FIN和ACK。这就是建连三次握手而断链需要四次的原因。
另外回答断链的问题时,可以提到实际应用中有可能遇到大量Socket处在TIME_WAIT或者CLOSE_WAIT状态的问题。一般开启tcp_tw_reuse和tcp_tw_recycle能够加快TIME-WAIT的Sockets回收;而大量CLOSE_WAIT可能是被动关闭的一方存在代码bug,没有正确关闭链接导致的。
- 本文标题:操作系统与计算机网络总结
- 本文作者:形而上
- 创建时间:2021-10-16 09:15:23
- 本文链接:https://deepter.gitee.io/2021_10_16_os_net/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!