计算机网络
OSI模型 tcp/ip四层 以及5层网络模型
各层模型分类如图:
五层模型
- 应用层:该层为用于通信的应用程序和用于消息传输的底层网络提供接口,应用层直接和应用程序接口并提供常见的网络应用服务,应用层定义的是应用进程间通信和交互的规则。(HTTP,FTP,DNS)
- 传输层:负责向两个主机中进程之间的通信提供通用数据服务。(TCP,UDP)
- 网络层:网络层的任务就是选择合适的网间路由和交换结点,负责对数据包进行路由选择和存储转发。(IP,ICMP(ping命令))
- 数据链路层:两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧,在两个相邻的链路上传送帧(frame)。每一帧包括数据和必要的控制信息[同步信息/地址信息/差错控制等]。
- 物理层:物理层所传数据单位是比特(bit)。物理层要考虑用多大的电压代表1 或 0 ,以及接受方如何识别发送方所发送的比特。
七层模型
- 物理层:主要定义物理设备标准。
- 数据链路层:主要将从物理层接收的数据进行 MAC 地址(网卡的地址)的封装与解封装。
- 网络层:主要将从下层接收到的数据进行 IP 地址(例 192.168.0.1)的封装与解封装。
- 传输层:定义了一些传输数据的协议和端口号(WWW 端口 80 等)。
- 会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。
- 表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等
- 应用层:主要是一些终端的应用
tcp协议
tcp协议:传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。
三次握手
建立连接时候的双方一般互相交换ISN 并等待对方回复ack为ISN+1后建立连接的过程称为三次握手。且建立连接时候无数据传输,所以将客户端对服务端的回复ACK 以及申请对客户端建立连接的FIN合并为一次握手。
- 第一次握手:建立连接时,客户端发送 位码SYN = 1 以及 syn包(seq=x 一般是个非零的随机数)到服务器,并进入SYN_SENT状态,等待服务器确认。
- 第二次握手:服务器确认客户端的SYN(ack=seq+1),同时自己也发送一个syn包(seq=k)位码 SYN ACK置为1,服务器进入SYN_RECV状态。
- 握手阶段没有数据传输 服务端把对SYN的确认和申请和客户端连接合并为一次握手。
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
注意:
- ACK=1 表示携带的数据包ack有效 SYN=1表示 携带的Seq数据包有效
- 初始的Seq 一般称为 ISN【Initial Sequence Number ISN】建立连接时候的双方一般互相交换ISN 并等待对方回复ack为ISN+1后建立连接。
四次挥手
结束连接时候客户端和服务端互相想对方发送FIN 并等待对方回复后结束连接的过程,称为四次挥手,因为TCP是双全工,在客户端申请结束时候,服务端可能还有数据正在传输,所以无法对客户端的确认以及己方的申请结束合并为一次挥手过程。
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。
- 服务器关闭客户端的连接,发送一个FIN给客户端。
- 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
为什么要4次挥手而不是三次
三次握手:建立连接时候无数据传输,所以将客户端对服务端的回复ACK 以及对客户端建立连接的FIN合并为一次握手.
四次挥手:TCP是双全工,在客户端申请结束时候,服务端可能还有数据正在传输,所以无法对客户端的确认以及己方的申请结束合并为一次挥手过程。
数据传输中的Seq和握手中的Seq分别代表什么
第一次的Seq 为ISN 是一个初始的随机数。后Seq是一个传输数据的标志位表示当前传输的数据起点为seq 而服务端反馈的ack表示在下次希望收到的数据的标志位。
TCP数据包
- 源端口号( 16 位):它(连同源主机 IP 地址)标识源主机的一个应用进程。
- 目的端口号( 16 位):它(连同目的主机 IP 地址)标识目的主机的一个应用进程。这两个值
加上 IP 报头中的源主机 IP 地址和目的主机 IP 地址唯一确定一个 TCP 连接。 - 顺序号 seq( 32 位):用来标识从 TCP 源端向 TCP 目的端发送的数据字节流,它表示在这个
报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动,则 TCP 用顺序号对每个字节进行计数。序号是 32bit 的无符号数,序号到达 2 的 32 次方 - 1 后 又从 0 开始。当建立一个新的连接时, SYN 标志变 1 ,顺序号字段包含由这个主机选择的该 连接的初始顺序号 ISN ( Initial Sequence Number )。 - 确认号 ack( 32 位):包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当 是上次已成功收到数据字节顺序号加 1 。只有 ACK 标志为 1 时确认序号字段才有效。 TCP 为 应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必 须保持每个方向上的传输数据顺序号。
- TCP 报头长度( 4 位):给出报头中 32bit 字的数目,它实际上指明数据从哪里开始。需要这 个值是因为任选字段的长度是可变的。这个字段占 4bit ,因此 TCP 最多有 60 字节的首部。然 而,没有任选字段,正常的长度是 20 字节。
- 保留位( 6 位):保留给将来使用,目前必须置为 0 。
- 控制位( control flags , 6 位):在 TCP 报头中有 6 个标志比特,它们中的多个可同时被设
置为 1 。依次为:- URG :为 1 表示紧急指针有效,为 0 则忽略紧急指针值。
- ACK :为 1 表示确认号有效,为 0 表示报文中不包含确认信息,忽略确认号字段。
- PSH :为 1 表示是带有 PUSH 标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
- RST :用于复位由于主机崩溃或其他原因而出现错误的连接。它还可以用于拒绝非法的报文段和拒绝连接请求。一般情况下,如果收到一个 RST 为 1 的报文,那么一定发生了某些问题。
- SYN :同步序号,为 1 表示连接请求,用于建立连接和使顺序号同步( synchronize )。
- FIN :用于释放连接,为 1 表示发送方已经没有数据发送了,即关闭本方数据流。
- 窗口大小( 16 位):数据字节数,表示从确认号开始,本报文的源方可以接收的字节数,即源 方接收窗口大小。窗口大小是一个 16bit 字段,因而窗口大小最大为 65535 字节。
- 校验和( 16 位):此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字 进行计算所得。这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
- 紧急指针(16位):只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另 一端发送紧急数据的一种方式。
- 选项:最常见的可选字段是最长报文大小,又称为MSS(MaximumSegmentSize)。每个连 接方通常都在通信的第一个报文段(为建立连接而设置 SYN 标志的那个段)中指明这个选项, 它指明本端所能接收的最大长度的报文段。选项长度不一定是 32 位字的整数倍,所以要加填充 位,使得报头长度成为整字数。
- 数据: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报 文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数 据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
TCP协议如何保障可靠性传输的
- 序列号,对接收到的TCP报文段进行排序以及检测重复的数据.
- 校验和, 用来检测报文段的错误,保障无错传输。
- 超时重传
- 基于计时器的重传
- 快速重传
- 带选择确认的重传
- 伪超时重传
- 包失序和重复
- 流量控制
- 拥塞控制
滑动窗口
属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。 该协议允许发送方在停止并等待确认前发送多个数据分组。 由于发送方不必每发一个分组就停下来等待确认。 因此该协议可以加速数据的传输,提高网络吞吐量。
前提:
- TCP滑动窗口可分为发送窗口和接收窗口
- ACK=1 时候ack=n 理解为接收端确认收到前n-1字节的数据,期望收到第n字节开始的数据。若是n+1字节的数据是不会回复ACK的。
- 传输过程中有个window 用来标识窗口大小
- 发送端的数据可以分为4类 其中3/4就是滑动窗口起到的调控作用
- 已发送已收到ACK的
- 已发送未收到ACK的
- 未发送但允许发送的 -------> 称为发送窗口
- 未发送不允许发送的
- 接收端的数据状态可以分为三类 由于回复是TCP协议栈回复ACK 可以认为无延迟所有不存在 以收到未回复ACK这种状态
- 已收到且回复ACK
- 未收到可以接收的 ---------->称为接收窗口
- 未收到不能接收的
- 发送端并不是一次发送的数据等于一个滑动窗口大小,而是根据滑动窗口大小和已发送未收到ack的情况,来决定接下来还能发送多少数据。可以不必每发送一次就停下来等待确认。
滑动窗口原理跟窗口大小以及回复的ack可以计算出来接下来可以发送多少数据。
- 计算方式:窗口大小-(已发送未收到ACK的部分) = 剩余可以发送的数据
假设发送方已发送x前的数据,窗口大小为m,接收端确认到n 那么发送端接下来可以发送的数据为m-(x-(n-1))
拥塞控制
是指发送方根据网络的承载情况控制分组的发送量,以免过多的数据注入到网络中,出现网络负载过大的情况。
常用的算法
- 慢开始:思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。
- 拥塞避免: 思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1
- 快速重传递
- 快速恢复
TCP和UDP差异
-
UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等
-
TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。
3 HTTP协议
- HTTP请求的完全过程
- HTTP 1.x & 2.0的区别
- HTTP和HTTPS的区别
- HTTPS的请求过程
- 什么是对称加密什么是非对称加密
- SSL协议在那一层
HTTP请求的完全过程
- 浏览器查找域名的IP地址[DNS查找过程:浏览器缓存->路由器缓存->DNS缓存]
- 浏览器和WEB服务器建立一个TCP连接
- 浏览器向WEB服务器发送HTTP请求
- 服务器处理HTTP请求并返回一个response响应
- 浏览器对收到的HTTP响应解析渲染
HTTPS请求的完全过程
HTTPS: 即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL
TLS (和 SSL) 协议位于应用程序协议层和 TCP/IP 层之间,可以在其中保护应用程序数据并将其发送到传输层。 由于协议在应用程序层和传输层之间工作,因此 TLS 和 SSL 可以支持多个应用程序层协议。
- 建立链接获取证书
- 客户端发起Https请求服务端的443端口
- 服务端返回证书
- 证书是->非对称加密的公钥
- 证书验证阶段
- 证书不合法,提示警告信息
- 合法,在本地生成随机(对称)秘钥
- 通过公钥对随机秘钥加密,并发送给服务端
- 建立链接数据传输
- 服务端通过私钥对收到的随机咪猫进行解密
- 服务端通过客户端传入的随机秘钥构造对称加密算法
- 对返回结果内容使用客户端提供的对称秘钥进行加密后传输
可见HTTPS中存在非对称加密和对称加密
- 传输客户端生成的对称秘钥 使用非对称加密。
- (数据传输时候,双方都使用的客户端生成的对称秘钥。
HTTPS数据加密方式
- 对称加密: 数据传输过程中使用的是对称加密 双方都使用的客户端生成的随机秘钥
- 非对称加密:在传输客户端秘钥过程中使用的非对称加密。客户端生成秘钥 使用服务端公钥加密,传递给服务端,服务端使用私钥解密。
数据传输过程中使用非对称是不可取的,非对称效率相对较低,但是在Https过程中存在大量数据交换,所以只在传递秘钥的过程中使用了非对称加密。
对称加密和非对称加密
对称加密: 密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;
非对称加密: 密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。
HTTP和HTTPS的区别
端口 :
HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。
安全性和资源消耗:
1. HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
2. HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。
3. HTTPS协议需要申请证书。
3.2 HTTP 1.x & 2.0的区别
-
新的二进制格式(Binary Format):HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
-
多路复用(MultiPlexing):即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
-
header压缩:如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
-
服务端推送(server push):同SPDY一样,HTTP2.0也具有server push功能。
3.3 HTTP 1.1和1.0的差异
-
缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
-
带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
-
错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
-
Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
-
长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
HTTP 1.1长连接和HTTP2.0多路复用差异
-
HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
-
HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
-
HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
4 其他
4.1 URL和URI的区别
URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
4.2 Cookie 和 Session区别
-
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。[客户端通过保存在cookie中的JsessionId来区分Session]
-
cookie在服务端创建,通过响应发送给客户端的键值对。客户端保存cookie并标注来源。
参考
操作系统
进程的组成部分
进程由进程控制块(PCB)、程序段、数据段三部分组成。
进程和线程
-
进程是操作系统资源分配的最小单位,线程是CPU任务调度的最小单位。一个进程可以包含多个线程,所以进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。
-
不同进程间数据很难共享,同一进程下不同线程间数据很易共享。
-
每个进程都有独立的代码和数据空间,进程要比线程消耗更多的计算机资源。线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
-
进程间不会相互影响,一个线程挂掉将导致整个进程挂掉。
-
系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。
进程的通信方式
进程间的通讯方式主要有:无名管道/FIFO命名管道/消息队列/信号量/共享内存
-
无名管道:半双工的,即数据只能在一个方向上流动,只能用于具有亲缘关系的进程之间的通信,可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
-
FIFO命名管道:FIFO是一种文件类型,可以在无关的进程之间交换数据,与无名管道不同,FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
-
消息队列:消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。
-
信号量:信号量是一个计数器,信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。
-
共享内存:共享内存指两个或多个进程共享一个给定的存储区,一般配合信号量使用。
进程间五种通信方式的比较
- 管道:速度慢,容量有限,只有父子进程能通讯。
- FIFO:任何进程间都能通讯,但速度慢。
- 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
- 信号量:不能传递复杂消息,只能用来同步。
- 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。
操作系统中进程调度策略有哪几种
先来先服务调度算法FCFS/最短作业优先调度算法SJF/优先级调度算法/时间片轮转调度算法
-
先来先服务调度算法FCFS:队列实现,非抢占,先请求CPU的进程先分配到CPU,可以作为作业调度算法也可以作为进程调度算法;按作业或者进程到达的先后顺序依次调度,对于长作业比较有利.
-
最短作业优先调度算法SJF:作业调度算法,算法从就绪队列中选择估计时间最短的作业进行处理,直到得出结果或者无法继续执行,平均等待时间最短,但难以知道下一个CPU区间长度;缺点:不利于长作业;未考虑作业的重要性;运行时间是预估的,并不靠谱.
-
优先级调度算法(可以是抢占的,也可以是非抢占的):优先级越高越先分配到CPU,相同优先级先到先服务,存在的主要问题是:低优先级进程无穷等待CPU,会导致无穷阻塞或饥饿.
-
时间片轮转调度算法(可抢占的):按到达的先后对进程放入队列中,然后给队首进程分配CPU时间片,时间片用完之后计时器发出中断,暂停当前进程并将其放到队列尾部,循环 ;队列中没有进程被分配超过一个时间片的CPU时间,除非它是唯一可运行的进程。如果进程的CPU区间超过了一个时间片,那么该进程就被抢占并放回就绪队列。
多线程和单线程
线程不是越多越好,假如你的业务逻辑全部是计算型的(CPU密集型),不涉及到IO,并且只有一个核心。那肯定一个线程最好,多一个线程就多一点线程切换的计算,CPU不能完完全全的把计算能力放在业务计算上面,线程越多就会造成CPU利用率(用在业务计算的时间/总的时间)下降。但是在WEB场景下,业务并不是CPU密集型任务,而是IO密集型的任务,一个线程是不合适,如果一个线程在等待数据时,把CPU的计算能力交给其他线程,这样也能充分的利用CPU资源。但是线程数量也要有个限度,一般线程数有一个公式:最佳启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]*CPU内核数超过这个数量,CPU要进行多余的线程切换从而浪费计算能力,低于这个数量,CPU要进行IO等待从而造成计算能力不饱和。总之就是要尽可能的榨取CPU的计算能力。如果你的CPU处于饱和状态,并且没有多余的线程切换浪费,那么此时就是你服务的完美状态,如果再加大并发量,势必会造成性能上的下降。
内存管理有哪几种方式
-
块式管理:把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程序片断load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但是易于管理。
-
页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高很多。
-
段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物理地址上。
-
段页式管理:结合了段式管理和页式管理的优点。将程序分成若干段,每个段分成若干页。段页式管理每取一数据,要访问3次内存。