面试必备!TCP协议经典十五连问!,2024年最新java高级程序员面试

本文介绍了如何帮助Java程序员提升技能,通过提供一份全面的学习资料,涵盖基础知识到高级进阶,包括TCP协议的可靠性机制,如三次握手、快速重传、滑动窗口和拥塞控制。同时鼓励加入技术交流社群,共同学习成长。
摘要由CSDN通过智能技术生成

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。

8. TCP 是如何保证可靠性的

  • 首先,TCP的连接是基于三次握手,而断开则是四次挥手。确保连接和断开的可靠性。

  • 其次,TCP的可靠性,还体现在有状态;TCP会记录哪些数据发送了,哪些数据被接受了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。

  • 再次,TCP的可靠性,还体现在可控制。它有报文校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。

9. TCP 重传机制

超时重传

TCP 为了实现可靠传输,实现了重传机制。最基本的重传机制,就是超时重传,即在发送数据报文时,设定一个定时器,每间隔一段时间,没有收到对方的ACK确认应答报文,就会重发该报文。

这个间隔时间,一般设置为多少呢?我们先来看下什么叫RTT(Round-Trip Time,往返时间)

RTT就是,一个数据包从发出去到回来的时间,即数据包的一次往返时间。超时重传时间,就是Retransmission Timeout ,简称RTO

RTO设置多久呢?

  • 如果RTO比较小,那很可能数据都没有丢失,就重发了,这会导致网络阻塞,会导致更多的超时出现。

  • 如果RTO比较大,等到花儿都谢了还是没有重发,那效果就不好了。

一般情况下,RTO略大于RTT,效果是最好的。一些小伙伴会问,超时时间有没有计算公式呢?有的!有个标准方法算RTO的公式,也叫Jacobson / Karels 算法。我们一起来看下计算RTO的公式

1. 先计算SRTT(计算平滑的RTT)

SRTT = (1 - α) * SRTT + α * RTT  //求 SRTT 的加权平均

2. 再计算RTTVAR (round-trip time variation)

RTTVAR = (1 - β) * RTTVAR + β * (|RTT - SRTT|) //计算 SRTT 与真实值的差距

3. 最终的RTO

RTO = µ * SRTT + ∂ * RTTVAR  =  SRTT + 4·RTTVAR

其中,α = 0.125,β = 0.25, μ = 1,∂ = 4,这些参数都是大量结果得出的最优参数。

但是,超时重传会有这些缺点:

  • 当一个报文段丢失时,会等待一定的超时周期然后才重传分组,增加了端到端的时延。
  • 当一个报文段丢失时,在其等待超时的过程中,可能会出现这种情况:其后的报文段已经被接收端接收但却迟迟得不到确认,发送端会认为也丢失了,从而引起不必要的重传,既浪费资源也浪费时间。

并且,TCP有个策略,就是超时时间间隔会加倍。超时重传需要等待很长时间。因此,还可以使用快速重传机制。

快速重传

快速重传机制,它不以时间驱动,而是以数据驱动。它基于接收端的反馈信息来引发重传。

一起来看下快速重传流程:

快速重传流程

发送端发送了 1,2,3,4,5,6 份数据:

  • 第一份 Seq=1 先送到了,于是就 Ack 回 2;

  • 第二份 Seq=2 也送到了,假设也正常,于是ACK 回 3;

  • 第三份 Seq=3 由于网络等其他原因,没送到;

  • 第四份 Seq=4 也送到了,但是因为Seq3没收到。所以ACK回3;

  • 后面的 Seq=4,5的也送到了,但是ACK还是回复3,因为Seq=3没收到。

  • 发送端连着收到三个重复冗余ACK=3的确认(实际上是4个,但是前面一个是正常的ACK,后面三个才是重复冗余的),便知道哪个报文段在传输过程中丢失了,于是在定时器过期之前,重传该报文段。

  • 最后,接收到收到了 Seq3,此时因为 Seq=4,5,6都收到了,于是ACK回7.

快速重传还可能会有个问题:ACK只向发送端告知最大的有序报文段,到底是哪个报文丢失了呢?并不确定!那到底该重传多少个包呢?

是重传 Seq3 呢?还是重传 Seq3、Seq4、Seq5、Seq6 呢?因为发送端并不清楚这三个连续的 ACK3 是谁传回来的。

带选择确认的重传(SACK)

为了解决快速重传的问题:应该重传多少个包? TCP提供了SACK方法(带选择确认的重传,Selective Acknowledgment)。

SACK机制就是,在快速重传的基础上,接收端返回最近收到的报文段的序列号范围,这样发送端就知道接收端哪些数据包没收到,酱紫就很清楚该重传哪些数据包啦。SACK标记是加在TCP头部选项字段里面的。

SACK机制

如上图中,发送端收到了三次同样的ACK=30的确认报文,于是就会触发快速重发机制,通过SACK信息发现只有30~39这段数据丢失,于是重发时就只选择了这个30~39的TCP报文段进行重发。

D-SACK

D-SACK,即Duplicate SACK(重复SACK),在SACK的基础上做了一些扩展,,主要用来告诉发送方,有哪些数据包自己重复接受了。DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传。让TCP可以更好的做网络流控。来看个图吧:

D-SACK简要流程

10. 聊聊TCP的滑动窗口

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

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

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

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

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

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

  • 已发送且已收到ACK确认

  • 已发送但未收到ACK确认

  • 未发送但可以发送

  • 未发送也不可以发送

  • 虚线矩形框,就是发送窗口。

  • SND.WND: 表示发送窗口的大小,上图虚线框的格子数就是14个。

  • SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。

  • SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。

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

  • 已成功接收并确认

  • 未收到数据但可以接收

  • 未收到数据并不可以接收的数据

  • 虚线矩形框,就是接收窗口。

  • REV.WND: 表示接收窗口的大小,上图虚线框的格子就是9个。

  • REV.NXT:下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。

11. 聊聊TCP的流量控制

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

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

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

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

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

TCP的流量控制

  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,才继续开始发送。

12. TCP的拥塞控制

拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。它跟流量控制又有什么区别呢?流量控制是作用于接收者的,根据接收端的实际接收能力控制发送速度,防止分组丢失的。

我们可以把网络链路比喻成一根水管,如果我们想最大化利用网络来传输数据,那就是尽快让水管达到最佳充满状态。

发送方维护一个拥塞窗口cwnd(congestion window) 的变量,用来估算在一段时间内这条链路(水管)可以承载和运输的数据(水)的数量。它大小代表着网络的拥塞程度,并且是动态变化的,但是为了达到最大的传输效率,我们该如何知道这条水管的运送效率是多少呢?

一个比较简单的方法就是不断增加传输的水量,直到水管快要爆裂为止(对应到网络上就是发生丢包),用 TCP 的描述就是:

只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入到网络中的数据包数。

实际上,拥塞控制主要有这几种常用算法

  • 慢启动

  • 拥塞避免

  • 拥塞发生

  • 快速恢复

慢启动算法

慢启动算法,表面意思就是,别急慢慢来。它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。

  • TCP连接完成,初始化cwnd = 1,表明可以传一个MSS单位大小的数据。

  • 每当收到一个ACK,cwnd就加一;

  • 每当过了一个RTT,cwnd就增加一倍; 呈指数让升

为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slow start threshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwnd >ssthresh时,进入了拥塞避免算法。

拥塞避免算法

一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值

  • 每收到一个ACK时,cwnd = cwnd + 1/cwnd

  • 当每过一个RTT时,cwnd = cwnd + 1

显然这是一个线性上升的算法,避免过快导致网络拥塞问题。

拥塞发生

当网络拥塞发生丢包时,会有两种情况:

  • RTO超时重传

  • 快速重传

如果是发生了RTO超时重传,就会使用拥塞发生算法

  • 慢启动阀值sshthresh =  cwnd /2

  • cwnd 重置为 1

  • 进入新的慢启动过程

这真的是辛辛苦苦几十年,一朝回到解放前。其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。

image.png

慢启动阀值ssthresh 和 cwnd 变化如下:

  • 拥塞窗口大小 cwnd = cwnd/2

  • 慢启动阀值 ssthresh = cwnd

  • 进入快速恢复算法

快速恢复

快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。

正如前面所说,进入快速恢复之前,cwnd 和 sshthresh已被更新:

- cwnd = cwnd /2

- sshthresh = cwnd

然后,真正的快速算法如下:

  • cwnd = sshthresh  + 3

  • 重传重复的那几个ACK(即丢失的那几个数据包)

  • 如果再收到重复的 ACK,那么 cwnd = cwnd +1

  • 如果收到新数据的 ACK 后, cwnd = sshthresh。因为收到新数据的 ACK,表明恢复过程已经结束,可以再次进入了拥塞避免的算法了。

线程、数据库、算法、JVM、分布式、微服务、框架、Spring相关知识

一线互联网P7面试集锦+各种大厂面试集锦

学习笔记以及面试真题解析

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 如果再收到重复的 ACK,那么 cwnd = cwnd +1

  • 如果收到新数据的 ACK 后, cwnd = sshthresh。因为收到新数据的 ACK,表明恢复过程已经结束,可以再次进入了拥塞避免的算法了。

线程、数据库、算法、JVM、分布式、微服务、框架、Spring相关知识

[外链图片转存中…(img-gRypHF3Y-1713561607351)]

一线互联网P7面试集锦+各种大厂面试集锦

[外链图片转存中…(img-t70SAwaH-1713561607352)]

学习笔记以及面试真题解析

[外链图片转存中…(img-hyTRKTCk-1713561607352)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-KBn5macN-1713561607353)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值