1. 协议

协议相关的考题,经常被问

1.1.1. tcp三次握手

add: 2019-12-28

点击显示

三次握手

开始客户端和服务器都处于CLOSED状态,然后服务端开始监听某个端口,进入LISTEN状态

  • 第一次握手(SYN=1, seq=x),发送完毕后,客户端进入 SYN_SEND 状态
  • 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1), 发送完毕后,服务器端进入 SYN_RCVD 状态。
  • 第三次握手(ACK=1,ACKnum=y+1),发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手,即可以开始数据传输。

1.1.2. TCP握手为什么是三次,不能是两次?不能是四次?

add: 2021-07-20

点击显示

不能是两次主要有三个原因:

  1. 防止已过期的连接请求报文突然又传送到服务器,因而产生错误和资源浪费。

    在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器,服务器接收不到请求报文段就不会返回确认报文段。

    客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,客户端在收到 确认报文后也进入 ESTABLISHED 状态,双方建立连接并传输数据,之后正常断开连接。

    此时姗姗来迟的 A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费。

  2. 三次握手才能让双方均确认自己和对方的发送和接收能力都正常。

    第一次握手:客户端只是发送处请求报文段,什么都无法确认,而服务器可以确认自己的接收能力和对方的发送能力正常;

    第二次握手:客户端可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;

    第三次握手:服务器可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;

    可见三次握手才能让双方都确认自己和对方的发送和接收能力全部正常,这样就可以愉快地进行通信了。

  3. 告知对方自己的初始序号值,并确认收到对方的初始序号值。

    TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段,通过这两个字段双方都可以知道在自己发出的数据中,哪些是已经被对方确认接收的。这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认。

不需要四次是因为三次握手已经可以确认双方的发送接收能力正常,双方都知道彼此已经准备好,而且也可以完成对双方初始序号值得确认,也就无需再第四次握手了。

  • 第一次握手:服务端确认“自己收、客户端发”报文功能正常。
  • 第二次握手:客户端确认“自己发、自己收、服务端收、客户端发”报文功能正常,客户端认为连接已建立。
  • 第三次握手:服务端确认“自己发、客户端收”报文功能正常,此时双方均建立连接,可以正常通信。

1.1.3. tcp四次挥手

add: 2021-07-20

点击显示

四次挥手

  1. 第一次挥手(FIN=1,seq=u),发送完毕后,客户端进入FIN_WAIT_1 状态
  2. 第二次挥手(ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态
  3. 第三次挥手(FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入LAST_ACK 状态,等待来自客户端的最后一个ACK。
  4. 第四次挥手(ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。

1.1.4. TIME-WAIT 状态为什么需要等待 2MSL

add: 2021-07-20

点击显示

TIME-WAIT

2MSL,2 Maximum Segment Lifetime,即两个最大段生命周期

  • 1个 MSL 保证四次挥手中主动关闭方最后的 ACK 报文能最终到达对端
  • 1个 MSL 保证对端没有收到 ACK 那么进行重传的 FIN 报文能够到达

1.1.5. tcp 和 udp 的区别?

add: 2019-12-28

点击显示
  1. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前 不需要建立连接
  2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失, 不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
  3. TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向 报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低
  4. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的 交互通信
  5. TCP首部开销20字节;UDP的首部开销小,只有8个字节
  6. TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

1.1.6. TCP报文首部有哪些字段,说说其作用

add: 2021-07-20

点击显示

报文首部

  • 16位端口号:源端口号,主机该报文段是来自哪里;目标端口号,要传给哪个上层协议或应用程序
  • 32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
  • 32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到的TCP报文段的序号值加1。
  • 4位头部长度:表示tcp头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
  • 6位标志位:URG(紧急指针是否有效),ACk(表示确认号是否有效),PSH(缓冲区尚未填满),RST(表示要求对方重新建立连接),SYN(建立连接消息标志接),FIN(表示告知对方本端要关闭连接了)
  • 16位窗口大小:是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
  • 16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
  • 16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。

1.1.7. http,tcp,ip分别处于OSI哪一层?

add: 2019-12-28

点击显示
  • 传输层协议:TCP、UDP、SCTP
  • 网络层协议:IP、ARP、RARP、ICMP、IGMP、OSPF
  • 应用层协议:http,FTP、SMTP、RIP、DNS

1.1.8. OSI有哪几层,会画出来,知道主要几层的各自作用?

add: 2019-12-28

点击显示
  1. 应用层(数据): 确定进程之间通信的性质以满足用户需要以及提供网络与用户应用
  2. 表示层(数据): 主要解决拥护信息的语法表示问题,如加密解密
  3. 会话层(数据): 提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制,如服务器验证用户登录便是由会话层完成的
  4. 运输层(段): 实现网络不同主机上用户进程之间的数据通信,可靠与不可靠的传输,传输层的错误检测,流量控制等
  5. 网络层(包): 提供逻辑地址(IP)、选路,数据从源端到目的端的传输
  6. 数据链路层(帧): 将上层数据封装成帧,用MAC地址访问媒介,错误检测与修正
  7. 物理层(比特流):设备之间比特流的传输,物理接口,电气特性等

1.1.9. TCP/IP有哪几层,会画出来,知道所有层数的作用,会列举各层主要的协议名称?

add: 2019-12-28

点击显示
  1. 应用层(TELNET、FTP、SMTP)
  2. 运输层(TCP、UDP)
  3. 网际层(IP、ICMP)
  4. 网络接口层(PPP)

1.1.10. 知道各个层使用的是哪个数据交换设备。(交换机、路由器、网关)?

add: 2019-12-28

点击显示
  1. 网关:应用层、传输层(网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连)
  2. 路由器:网络层(路由选择、存储转发)
  3. 交换机:数据链路层、网络层(识别数据包中的MAC地址信息,根据MAC地址进行转发,并将这些MAC地址与对应的端口记录在自己内部的一个地址表中)
  4. 网桥:数据链路层(将两个LAN连起来,根据MAC地址来转发帧)
  5. 集线器(Hub):物理层(纯硬件设备,主要用来连接计算机等网络终端)
  6. 中继器:物理层(在比特级别对网络信号进行再生和重定时,从而使得它们能够在网络上传输更长的距离)

1.1.11. TCP通过哪些措施,保证传输可靠?

add: 2019-12-28

点击显示
  1. 流量控制
  2. 让发送方的发送速率不要太快,要让接收方来得及接收
  3. 窗口大小是一个可以改变的值,它由接收端主机控制,附加在 TCP 首部的“窗口大小”字段中
  4. 拥塞控制
  5. 防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载
  6. 拥塞控制方法:慢开始、拥塞避免、快重传和快恢复

或者回答

  1. 首先,TCP的连接是基于三次握手,而断开则是四次挥手。确保连接和断开的可靠性。
  2. 其次,TCP的可靠性,还体现在有状态;TCP会记录哪些数据发送了,哪些数据被接受了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。
  3. 再次,TCP的可靠性,还体现在可控制。它有报文校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。

1.1.12. 请求各个状态的意义如下

add: 2019-12-28

点击显示
  1. LISTEN - 侦听来自远方TCP端口的连接请求;
  2. SYN-SENT -在发送连接请求后等待匹配的连接请求;
  3. SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;
  4. ESTABLISHED- 代表一个打开的连接,数据可以传送给用户;
  5. FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
  6. FIN-WAIT-2 - 从远程TCP等待连接中断请求;
  7. CLOSE-WAIT - 等待从本地用户发来的连接中断请求;
  8. CLOSING -等待远程TCP对连接中断的确认;
  9. LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;
  10. TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认;
  11. CLOSED - 没有任何连接状态;

1.1.13. 为什么要3次握手,4次挥手

add: 2019-12-28

点击显示
  1. 握手:防止已过期的连接请求报文突然又传送到服务器,因而产生错误
  2. 挥手:确保数据能够完成传输,但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的

1.1.14. HTTP 、TCP、Socket区别

add: 2019-12-28

点击显示
  • TCP/IP代表传输控制协议/网际协议,指的是一系列协组
  • HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议
  • Socket是TCP/IP网络的API其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议
  • 综上所述:需要IP协议来连接网络;TCP是一种允许我们安全传输数据的机制,使用TCP协议来传输数据的HTTP是Web服务器和客户端使用的特殊协议。HTTP基于TCP协议,但是却可以使用socket去建立一个TCP连接

1.1.15. Cookies 和 Session的区别

add: 2019-12-28

点击显示
  • cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据
  • session其实指的就是访问者从到达某个特定主页到离开为止的那段时间。 Session其实是利用Cookie进行信息处理的,当用户首先进行了请求后,服务端就在用户浏览器上创建了一个Cookie,当这个Session结束时,其实就是意味着这个Cookie就过期了
  • cookie数据保存在客户端,session数据保存在服务器端

1.1.16. HTTP /1.1 与 /2.0版本的常见差异和特性

add: 2019-12-31

点击显示

HTTP 1.1

  • 默认使用长连接(connection:keep-alive)。解决了复用TCP的问题,可以减少TCP的三次握手开销。
    • 指的是用同一个TCP连接来发送和接受多个http请求/应答,而不是为了每一个新的请求/应答打开新的TCP连接的方法。
      • 另一个定义:一定时间内,同一域名多次请求数据,只建立一次HTTP请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题。这里面所说的一定时间是可以配置的,不管你用的是Apache还是nginx
      • 但是还是存在效率问题(HTTP2.0通过多路复用解决)
        • 串行的文件传输,只能顺序传输:当请求a文件时,b文件只能等待,等待a连接到服务器、服务器处理文件、服务器返回文件,这三个步骤。我们假设这三步用时都是1秒,那么a文件用时为3秒,b文件传输完成用时为6秒,依此类推。(注:此项计算有一个前提条件,就是浏览器和服务器是单通道传输)
        • 连接数上限:我们假设Apache设置了最大并发数为300,因为浏览器限制,浏览器发起的最大请求数为6,也就是服务器能承载的最高并发为50,当第51个人访问时,就需要等待前面某个请求处理完成。
  • 支持只发送header信息而不带任何body信息,如果客户端有权限,则返回100(代表继续),否则返回401(无权限)客户端如果接收到100,才把请求的Body发送到服务器。
    • 这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽
  • 1.1开始支持获取文件的部分内容,这支持了 并行下载 和 断点续传。通过在Header的两个参数实现
    • 客户端请求的时候发送Range参数, 指定第一个字节的位置和最后一个字节的位置
    • 服务端响应的参数是:Content-Range
    • 在实际场景中,会出现一种情况,即在终端发起续传请求时,URL 对应的文件内容在服务器端已经发生变化,此时续传的数据肯定是错误的。如何解决这个问题 ?
      • 用Last-modified / etag / if-range
      • If-Range 必须与 Range 配套使用。如果请求报文中没有 Range,那么 If-Range 就会被忽略。如果服务器不支持 If-Range,那么 Range 也会被忽略。
    • 工作原理:
      • 第一次请求,客户端发起一个get请求;服务器处理请求,返回文件内容以及相应的Header,包括Etag
      • 第二次请求(断点续传):客户端发起get请求,同时发送if-range,这个if-range的值就是第一次请求中服务器返回的etag;服务器判断etag是否匹配,是则返回206,否则返回200
  • HTTP/1.1 引入了更多的缓存控制策略,比如
    • if-unmodified-since,其实就是和if-modified-since差不多的,常用来做判断断点续传的文件是否被修改过了。如果没有被修改,返回200;否则返回412预处理错误。
    • if-match
    • if-none-match
  • 1.1开始有Host(域) 这个概念

HTTP 2.0

  • 最大的一个目标是在用户和网站间只用一个连接
  • 二进制分帧(Binary Framing)

    • 在 TCP 协议中,数据的传输单位是数据报。数据分成两大部分。头部(header) 和 实际数据部分(body)。
    • 在 HTTP 2.0 中,它把数据报的两大部分分成了 header frame 和 data frame。也就是头部帧和数据体帧。帧的传输最终在流中进行,流中的帧,头部(header)帧 和 data 帧可以分为多个片段帧,例如data帧即是可以 data = data_1 + data_2 + ... + data_n。
    • 此外地,如果基于二进制帧整体来划分,除了报文的帧分类。还有其它一些辅助帧类型,例如评论中提到的:SETTINGS、PING、GOWAY、WINDOW_UPDATE等控制帧。
  • http1.x诞生的时候是明文协议,其格式由三部分组成:start line(request line或者status line),header,body。要识别这3部分就要做协议解析,http1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑http2.0的协议解析决定采用二进制格式,实现方便且健壮

  • 几个概念:
    • frame 帧:http/2通信的最小单位,单个帧包含帧首部,其中标注了当前帧所属的stream
    • message 消息:由若干个frame组合而成,例如请求,响应
    • connection 连接:与http/1 相同,指的都是对应的tcp连接
    • stream 流,已建立的连接上的双向字节流。
    • 数据流以消息的形式发送,而消息由一个或多个帧组成,帧可以在数据流上乱序发送,然后再根据每个帧首部的流标识符重新组装。二进制分帧是HTTP/2的基石,其他优化都是在这一基础上来实现的。
  • 支持多路复用(Multiplexing),在数据链路层使用二进制分帧,可以允许同时通过单一的ht2连接发起多重的请求-响应消息,同个域名只需要占用一个 TCP 连接,解决了请求阻塞的问题。
    • 在HTTP1.1中,同一域名在同一时间的请求数量是有限制的,超过限制会阻塞请求。
    • Head-of-Line Blocking,在http1.x中,TCP的connection在同一时间只能允许一个请求经过,因为HTTP1.x需要每条请求都是可是识别,按顺序发送,否则server就无法判断该相应哪个具体的请求。
    • 多路复用指的是:在同一个域名下,开启一个TCP的connection,每个请求以stream的方式传输,每个stream有唯一标识,connection一旦建立,后续的请求都可以复用这个connection并且可以同时发送,server端可以根据stream的唯一标识来相应对应的请求。之所以可以复用,是因为每个stream高度独立,堵塞的stream不会影响其它stream的处理。一个连接上可以有多个stream,每个stream的frame可以随机的混杂在一起,接收方可以根据stream id将frame再归属到各自不同的request里面。
    • 而多路复用什么时候关闭呢?
      • 用户离开这个页面
      • server主动关闭connection
    • 那么在HTTP2.0下,我们就不需要做
      • JS文件的合并:在之前,我们会将上线若干个模块的代码进行压缩合并成一个文件,减少http请求数。但是这样就会导致缓存问题:如果有一个模块修改了,就会导致客户端重新下载整个大文件,难以缓存。现在用HTTP2.0就不需要做这件事情了
      • CDN资源放在不同域名下,绕开浏览器的通道上限。
    • 头部压缩:
      • http2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。
    • 服务端推送(server push):
      • 从HTTP/2开始,服务器除了相应客户端的请求之外,还可以向客户端额外推送资源,这些资源遵守同源协议,有自己独立的URL,可以被浏览器缓存,可以多页面共享;同时客户端还可以拒绝推送过来的资源
      • 有了server push,客户端可以通过额外的http头部,列出需要服务器push 哪些资源
      • 服务器可以提前向客户端推送需要的资源。
    • 流量控制(flow control):
      • 在TCP的流量控制中,是以单个tcp为单位的流量控制;可是在http2.0时代,传输已经以单个stream为单位,tcp的流量控制无法做到这么精细的粒度,因此就在应用层引入了flow control,从而对每一个stream都做了不同的限流
      • 而HTTP/2利用stream来实现flow-control,引入了stream对TCP连接的抢占,不加控制就会造成stream被阻塞。而http/2上的flow-control就是确保同一连接上的多个流之间不会造成破坏性的干扰
    • 流优先级(stream priority):
      • 在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。(其实我的理解还是为了解决TCP抢占的问题?)

从HTTP/1.x到HTTP/2的过程中,仍然适用的优化规则

  • 减少DNS查询。DNS查询需要时间,没有resolved的域名会阻塞请求。
  • 减少TCP连接。HTTP/2只使用一个TCP连接。
  • 使用CDN。使用CDN分发资源可以减少延迟。
  • 减少HTTP跳转。特别是非同一域名的跳转,需要DNS,TCP,HTTP三种开销。
  • 消除不必要的请求数据。HTTP/2压缩了Header。
  • 压缩传输的数据。gzip压缩很高效。
  • 客户端缓存资源。缓存是必要的。
  • 消除不必要的资源。激进的提前获取资源对客户端和服务端都开销巨大。

因为HTTP/2而不一样的优化规则

  • 域名分片:大概意思就是我们把资源放在不同域名下,绕过浏览器HTTP连接数的限制。HTTP2.0不用了
  • 文件合并:在HTTP2.0中,我们要使用更小的模块,优化缓存策略(因为大文件的某一部分更改了,整个大文件就无法缓存了)
  • 内联资源:在HTTP2.0中直接使用server push。

以上参考:

HTTP

HTTP

1.1.17. 聊聊TCP的滑动窗口?

add: 2021-07-20

点击显示

TCP 发送一个数据,需要收到确认应答,才会发送下一个数据。这样有个缺点,就是效率会比较低。

这就好像我们面对面聊天,你说完一句,我应答后,你才会说下一句。那么,如果我在忙其他事情,没有能够及时回复你。你说完一句后,要等到我忙完回复你,你才说下句,这显然很不现实。

为了解决这个问题,TCP引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。

TCP头部有个字段叫win,也即那个16位的窗口大小,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。

通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是win。

TCP 滑动窗口分为两种: 发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:

  • 已发送且已收到ACK确认
  • 已发送但未收到ACK确认
  • 未发送但可以发送
  • 未发送也不可以发送

滑动窗口

  • 虚线矩形框,就是发送窗口。
  • SND.WND: 表示发送窗口的大小,上图虚线框的格子数就是14个。
  • SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。
  • SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。

接收方的滑动窗口包含三大部分,如下:

  • 已成功接收并确认
  • 未收到数据但可以接收
  • 未收到数据并不可以接收的数据

滑动窗口

  • 虚线矩形框,就是接收窗口。
  • REV.WND: 表示接收窗口的大小,上图虚线框的格子就是9个。
  • REV.NXT:下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。

1.1.18. 聊聊TCP的流量控制?

add: 2021-07-20

点击显示

TCP三次握手,发送端和接收端进入到ESTABLISHED状态,它们即可以愉快地传输数据啦。

但是发送端不能疯狂地向接收端发送数据,因为接收端接收不过来的话,接收方只能把处理不过来的数据存在缓存区里。如果缓存区都满了,发送方还在疯狂发送数据的话,接收方只能把收到的数据包丢掉,这就浪费了网络资源啦。

TCP 提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制。

TCP通过滑动窗口来控制流量,我们看下流量控制的简要流程吧:

首先双方三次握手,初始化各自的窗口大小,均为 400 个字节。

流量控制

  1. 假如当前发送方给接收方发送了200个字节,那么,发送方的SND.NXT会右移200个字节,也就是说当前的可用窗口减少了200 个字节。
  2. 接受方收到后,放到缓冲队列里面,REV.WND =400-200=200字节,所以win=200字节返回给发送方。接收方会在 ACK 的报文首部带上缩小后的滑动窗口200字节
  3. 发送方又发送200字节过来,200字节到达,继续放到缓冲队列。不过这时候,由于大量负载的原因,接受方处理不了这么多字节,只能处理100字节,剩余的100字节继续放到缓冲队列。这时候,REV.WND = 400-200-100=100字节,即win=100返回发送方。
  4. 发送方继续干活,发送100字节过来,这时候,接受窗口win变为0。
  5. 发送方停止发送,开启一个定时任务,每隔一段时间,就去询问接受方,直到win大于0,才继续开始发送。

1.1.19. 半连接队列和 SYN Flood 攻击的关系

add: 2021-07-20

点击显示

TCP进入三次握手前,服务端会从CLOSED状态变为LISTEN状态,同时在内部创建了两个队列:半连接队列(SYN队列)和全连接队列(ACCEPT队列)。

什么是半连接队列(SYN队列) 呢? 什么是全连接队列(ACCEPT队列) 呢?回忆下TCP三次握手的图:

三次握手

  • TCP三次握手时,客户端发送SYN到服务端,服务端收到之后,便回复ACK和SYN,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,即半连接队列。
  • 当客户端回复ACK, 服务端接收后,三次握手就完成了。这时连接会等待被具体的应用取走,在被取走之前,它被推入ACCEPT队列,即全连接队列。

SYN Flood是一种典型的DoS (Denial of Service,拒绝服务) 攻击,它在短时间内,伪造不存在的IP地址,向服务器大量发起SYN报文。当服务器回复SYN+ACK报文后,不会收到ACK回应报文,导致服务器上建立大量的半连接半连接队列满了,这就无法处理正常的TCP请求啦。

主要有 syn cookie和SYN Proxy防火墙等方案应对。

  • syn cookie:在收到SYN包后,服务器根据一定的方法,以数据包的源地址、端口等信息为参数计算出一个cookie值作为自己的SYNACK包的序列号,回复SYN+ACK后,服务器并不立即分配资源进行处理,等收到发送方的ACK包后,重新根据数据包的源地址、端口计算该包中的确认序列号是否正确,如果正确则建立连接,否则丢弃该包。

  • SYN Proxy防火墙:服务器防火墙会对收到的每一个SYN报文进行代理和回应,并保持半连接。等发送方将ACK包返回后,再重新构造SYN包发到服务器,建立真正的TCP连接。

1.1.20. Nagle 算法与延迟确认

点击显示

add: 2021-07-20

Nagle算法

如果发送端疯狂地向接收端发送很小的包,比如就1个字节,那么亲爱的小伙伴,你们觉得会有什么问题呢?

TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

Nagle算法的基本定义是:任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

Nagle算法的实现规则:

  • 如果包长度达到MSS,则允许发送;
  • 如果该包含有FIN,则允许发送;
  • 设置了TCP_NODELAY选项,则允许发送;
  • 未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
  • 上述条件都未满足,但发生了超时(一般为200ms),则立即发送。

延迟确认

如果接受方刚接收到发送方的数据包,在很短很短的时间内,又接收到第二个包。那么请问接收方是一个一个地回复好点,还是合并一起回复好呢?

接收方收到数据包后,如果暂时没有数据要发给对端,它可以等一段时再确认(Linux上默认是40ms)。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,而不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免对端以为丢包。

但是有些场景不能延迟确认,比如发现了乱序包、接收到了大于一个 frame 的报文,且需要调整窗口大小等。

一般情况下,Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,酱紫就会造成更大的延迟,会产生性能问题。

1.1.21. TCP的粘包和拆包

add: 2021-07-20

点击显示

TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

粘包

为什么会产生粘包和拆包呢?
  • 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
  • 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
  • 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
  • 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
解决方案:
  • 发送端将每个数据包封装为固定长度
  • 在数据尾部增加特殊字符进行分割
  • 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。

1.1.22. 单工、半双工、全双工的区别

add: 2021-07-29

点击显示

单工

单工是指信道的全部带宽都用于发送方给接收方发送数据,也就是说信息只能往一个方向传送。发送方只能发送数据,不需要有接收数据的能力;接收方只能接收数据,不需要有发送数据的能力。比如无线电广播就属于单工通信,广播电台只负责发送数据,听众的收音机只负责接收数据。

半双工

半双工就是通信的双方都可以发送数据和接收数据,但不能同时发送和接收数据。比如A向B发送数据时,信道的全部带宽都用于A向B发送数据,此时B不能向A发送数据;当A向B发完数据后,B可以向A发送数据,此时信道的全部带宽都用于B向A发送数据,此时A不能向B发送数据。比如无线对讲机就属于半双工通信。

全双工

全双工和半双工一样通信的双方都可以发送数据和接收数据,不同的地方在于双方收发数据可以同时进行。比如现代的电话通信就属于全双工通信。

1.1.23. OSI 7层模型和TCP/IP 4层模型

add: 2021-08-30

点击显示
OSI七层网络模型 TCP/IP四层概念模型 对应网络协议
应用层(Application) 应用层 HTTP,TFTP,FTP,NFS,WAIS,SMTP
表示层(Presentation) Telnet,Rlogin,SNMP,Gopher
会话层(Session) SMTP,DNS
传输层(Transport) 传输层 TCP,UDP
网络层(Netword) 网络层 IP,ICMP,ARP,RARP,AKP,UUCP
数据链路层(Data Link) 数据链路层 FDDI,Ethernet,Arpanet,PDN,SLIP,PPP
物理层(Physical) IEEE 802.1A,IEEE 802.2 到 IEEE 802.11

1.1.24. 什么是 SYN洪泛攻击?如何防范?

add: 2021-10-26

点击显示

SYN洪泛攻击属于 DOS 攻击的一种,它利用 TCP 协议缺陷,通过发送大量的半连接请求,耗费 CPU 和内存资源。

原理

  • 在三次握手过程中,服务器发送 [SYN/ACK] 包(第二个包)之后、收到客户端的 [ACK] 包(第三个包)之前的 TCP 连接称为半连接(half-open connect),此时服务器处于 SYN_RECV(等待客户端响应)状态。如果接收到客户端的 [ACK],则 TCP 连接成功,如果未接受到,则会不断重发请求直至成功。
  • SYN 攻击的攻击者在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 [SYN] 包,服务器回复 [SYN/ACK] 包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时。
  • 这些伪造的 [SYN] 包将长时间占用未连接队列,影响了正常的 SYN,导致目标系统运行缓慢、网络堵塞甚至系统瘫痪。

检测:当在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。

防范

  • 通过防火墙、路由器等过滤网关防护。
  • 通过加固 TCP/IP 协议栈防范,如增加最大半连接数,缩短超时时间。
  • SYN cookies技术。SYN Cookies 是对 TCP 服务器端的三次握手做一些修改,专门用来防范 SYN 洪泛攻击的一种手段。

1.1.25. 三次握手连接阶段,最后一次ACK包丢失,会发生什么?

add: 2021-10-26

点击显示

服务端:

  • 第三次的ACK在网络中丢失,那么服务端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便客户端重新发送ACK包。
  • 如果重发指定次数之后,仍然未收到 客户端的ACK应答,那么一段时间后,服务端自动关闭这个连接。

客户端:

客户端认为这个连接已经建立,如果客户端向服务端发送数据,服务端将以RST包(Reset,标示复位,用于异常的关闭连接)响应。此时,客户端知道第三次握手失败。

1.1.26. 如果已经建立了连接,但是客户端出现故障了怎么办?

add: 2021-10-26

点击显示

或者说,如果三次握手阶段、四次挥手阶段的包丢失了怎么办?如“服务端重发 FIN丢失”的问题。

简而言之,通过定时器 + 超时重试机制,尝试获取确认,直到最后会自动断开连接。

具体而言,TCP 设有一个保活计时器。服务器每收到一次客户端的数据,都会重新复位这个计时器,时间通常是设置为 2 小时。若 2 小时还没有收到客户端的任何数据,服务器就开始重试:每隔 75 分钟发送一个探测报文段,若一连发送 10 个探测报文后客户端依然没有回应,那么服务器就认为连接已经断开了。

1.1.27. TIME-WAIT 状态过多会产生什么后果?怎样处理?

add: 2021-10-26

点击显示

从服务器来讲,短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,严重消耗着服务器的资源,此时部分客户端就会显示连接不上。

从客户端来讲,客户端TIME_WAIT过多,就会导致端口资源被占用,因为端口就65536个,被占满就会导致无法创建新的连接。

解决办法:

  • 服务器可以设置 SO_REUSEADDR 套接字选项来避免 TIME_WAIT状态,此套接字选项告诉内核,即使此端口正忙(处于 TIME_WAIT状态),也请继续并重用它。

  • 调整系统内核参数,修改/etc/sysctl.conf文件,即修改net.ipv4.tcp_tw_reuse 和 tcp_timestamps

    net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    
  • 强制关闭,发送 RST 包越过TIME_WAIT状态,直接进入CLOSED状态。

1.1.28. TIME_WAIT 是服务器端的状态?还是客户端的状态?

add: 2021-10-26

点击显示

TIME_WAIT 是主动断开连接的一方会进入的状态,一般情况下,都是客户端所处的状态;服务器端一般设置不主动关闭连接。

TIME_WAIT 需要等待 2MSL,在大量短连接的情况下,TIME_WAIT会太多,这也会消耗很多系统资源。对于服务器来说,在 HTTP 协议里指定 KeepAlive(浏览器重用一个 TCP 连接来处理多个 HTTP 请求),由浏览器来主动断开连接,可以一定程度上减少服务器的这个问题。

1.1.29. HTTP常见的状态码有哪些?

add: 2021-10-26

点击显示

常见状态码:

  • 200:服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
  • 301 : (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
  • 302:(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  • 400 :客户端请求有语法错误,不能被服务器所理解。
  • 403 :服务器收到请求,但是拒绝提供服务。
  • 404 :(未找到) 服务器找不到请求的网页。
  • 500: (服务器内部错误) 服务器遇到错误,无法完成请求。

1.1.30. 状态码301和302的区别是什么?

add: 2021-10-26

点击显示

共同点:301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)。 不同点:301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO中302好于301。

补充,重定向原因

  1. 网站调整(如改变网页目录结构);
  2. 网页被移到一个新地址;
  3. 网页扩展名改变(如应用需要把.php改成.Html或.shtml)。

1.1.31. HTTP 常用的请求方式?

add: 2021-10-26

点击显示
方法 作用
GET 获取资源
POST 传输实体主体
PUT 上传文件
DELETE 删除文件
HEAD 和GET方法类似,但只返回报文首部,不返回报文实体主体部分
PATCH 对资源进行部分修改
OPTIONS 查询指定的URL支持的方法
CONNECT 要求用隧道协议连接代理
TRACE 服务器会将通信路径返回给客户端

为了方便记忆,可以将PUT、DELETE、POST、GET理解为客户端对服务端的增删改查。

  • PUT:上传文件,向服务器添加数据,可以看作增
  • DELETE:删除文件
  • POST:传输数据,向服务器提交数据,对服务器数据进行更新。
  • GET:获取资源,查询服务器资源

1.1.32. GET请求和POST请求的区别?

add: 2021-10-26

点击显示

使用上的区别

  • GET使用URL或Cookie传参,而POST将数据放在BODY中”,这个是因为HTTP协议用法的约定。
  • GET方式提交的数据有长度限制,则POST的数据则可以非常大”,这个是因为它们使用的操作系统和浏览器设置的不同引起的区别。

  • POST比GET安全,因为数据在地址栏上不可见”,这个说法没毛病,但依然不是GET和POST本身的区别。

本质区别

GET和POST最大的区别主要是GET请求是幂等性的,POST请求不是。这个是它们本质区别。

幂等性是指一次和多次请求某一个资源应该具有同样的副作用。简单来说意味着对同一URL的多个请求应该返回同样的结果。

1.1.33. 解释一下HTTP长连接和短连接?

add: 2021-10-26

点击显示

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

1.1.34. HTTP请求报文和响应报文的格式?

add: 2021-10-26

点击显示

请求报文格式

  1. 请求行(请求方法+URI协议+版本)
  2. 请求头部
  3. 空行
  4. 请求主体
GET/sample.jspHTTP/1.1 请求行
Accept:image/gif.image/jpeg, 请求头部
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate

username=jinqiao&password=1234 请求主体

响应报文

  1. 状态行(版本+状态码+原因短语)
  2. 响应首部
  3. 空行
  4. 响应主体
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112

<html>
    <head>
        <title>HTTP响应示例<title>
    </head>
    <body>
        Hello HTTP!
    </body>
</html>

1.1.35. HTTP1.0和HTTP1.1的区别(跟上面的题差不多,感觉这个总结的好)

add: 2021-10-26

点击显示
  • 长连接:HTTP 1.1支持长连接(Persistent Connection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

  • 缓存处理:在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略,可供选择的缓存头来控制缓存策略。

  • 带宽优化及网络连接的使用: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)。

1.1.36. HTTP1.1和 HTTP2.0的区别?(跟上面的题差不多,感觉这个总结的好)

add: 2021-10-26

点击显示

HTTP2.0相比HTTP1.1支持的特性:

  • 新的二进制格式:HTTP1.1的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

  • 多路复用,即连接共享,即每一个request都是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。

  • 头部压缩,HTTP1.1的头部(header)带有大量信息,而且每次都要重复发送;HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。

  • 服务端推送:服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。

1.1.37. 在浏览器中输入www.baidu.com后执行的全部过程?

add: 2021-10-26

点击显示
  1. 域名解析(域名 www.baidu.com 变为 ip 地址)。

    浏览器搜索自己的DNS缓存(维护一张域名与IP的对应表);若没有,则搜索操作系统的DNS缓存(维护一张域名与IP的对应表);若没有,则搜索操作系统的hosts文件(维护一张域名与IP的对应表)。

    若都没有,则找 tcp/ip 参数中设置的首选 dns 服务器,即本地 dns 服务器(递归查询),本地域名服务器查询自己的dns缓存,如果没有,则进行迭代查询。将本地dns服务器将IP返回给操作系统,同时缓存IP。

  2. 发起 tcp 的三次握手,建立 tcp 连接。浏览器会以一个随机端口(1024-65535)向服务端的 web 程序 80 端口发起 tcp 的连接。

  3. 建立 tcp 连接后发起 http 请求。

  4. 服务器响应 http 请求,客户端得到 html 代码。服务器 web 应用程序收到 http 请求后,就开始处理请求,处理之后就返回给浏览器 html 文件。

  5. 浏览器解析 html 代码,并请求 html 中的资源。

  6. 浏览器对页面进行渲染,并呈现给用户。

附一张形象的图片:img

add: 2021-10-26

点击显示

什么是 Cookie

HTTP Cookie(也叫 Web Cookie或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

什么是 Session

Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

add: 2021-10-26

点击显示

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

1.1.40. Cookie和Session的区别?

add: 2021-10-26

点击显示
  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

1.1.41. 如何考虑分布式 Session 问题?

add: 2021-10-26

点击显示

在互联网公司为了可以支撑更大的流量,后端往往需要多台服务器共同来支撑前端用户请求,那如果用户在 A 服务器登录了,第二次请求跑到服务 B 就会出现登录失效问题。

分布式 Session 一般会有以下几种解决方案:

  • 客户端存储:直接将信息存储在cookie中,cookie是存储在客户端上的一小段数据,客户端通过http协议和服务器进行cookie交互,通常用来存储一些不敏感信息

  • Nginx ip_hash 策略:服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。

  • Session 复制:任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。
  • 共享 Session:服务端无状态话,将用户的 Session 等信息使用缓存中间件(如Redis)来统一管理,保障分发到每一个服务器的响应结果都一致。

建议采用共享 Session的方案。

1.1.42. 什么是DDos攻击?

add: 2021-10-26

点击显示

DDos全称Distributed Denial of Service,分布式拒绝服务攻击。最基本的DOS攻击过程如下:

  1. 客户端向服务端发送请求链接数据包。
  2. 服务端向客户端发送确认数据包。
  3. 客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认

DDoS则是采用分布式的方法,通过在网络上占领多台“肉鸡”,用多台计算机发起攻击。

DOS攻击现在基本没啥作用了,因为服务器的性能都很好,而且是多台服务器共同作用,1V1的模式黑客无法占上风。对于DDOS攻击,预防方法有:

  • 减少SYN timeout时间。在握手的第三步,服务器会等待30秒-120秒的时间,减少这个等待时间就能释放更多的资源。
  • 限制同时打开的SYN半连接数目。

1.1.43. 什么是XSS攻击?

add: 2021-10-26

点击显示

XSS也称 cross-site scripting,跨站脚本。这种攻击是由于服务器将攻击者存储的数据原原本本地显示给其他用户所致的。比如一个存在XSS漏洞的论坛,用户发帖时就可以引入带有<script>标签的代码,导致恶意代码的执行。

预防措施有:

  • 前端:过滤。
  • 后端:转义,比如go自带的处理器就具有转义功能。

1.1.44. SQL注入是什么,如何避免SQL注入?

add: 2021-10-26

点击显示

SQL 注入就是在用户输入的字符串中加入 SQL 语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的 SQL 语句就会被数据库服务器误认为是正常的 SQL 语句而运行,攻击者就可以执行计划外的命令或访问未被授权的数据。

SQL注入的原理主要有以下 4 点

  • 恶意拼接查询
  • 利用注释执行非法命令
  • 传入非法参数
  • 添加额外条件

避免SQL注入的一些方法

  • 限制数据库权限,给用户提供仅仅能够满足其工作的最低权限。
  • 对进入数据库的特殊字符(’”\尖括号&*;等)转义处理。
  • 提供参数化查询接口,不要直接使用原生SQL。

1.1.45. 负载均衡算法有哪些?

add: 2021-10-26

点击显示

多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,能互相分担负载。

  • 轮询法:将请求按照顺序轮流的分配到服务器上。大锅饭,不能发挥某些高性能服务器的优势。
  • 随机法:随机获取一台,和轮询类似。
  • 哈希法:通过ip地址哈希化来确定要选择的服务器编号。好处是,每次客户端访问的服务器都是同一个服务器,能很好地利用session或者cookie。
  • 加权轮询:根据服务器性能不同加权。


以上内容来自:

  1. 面试过程中遇到

  2. tcp协议

  3. Java-Interview

results matching ""

    No results matching ""