leecodecode【面试150】【2026.6.13打卡-java版本】

轮转数组

要点:三次反转

java 复制代码
class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k = k%n;

        reverse(0,n-k-1,nums);
        reverse(n-k,n-1,nums);
        reverse(0,n-1,nums);
        
    }

    public void reverse(int left, int right, int[] nums){

        while(left < right){
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }

}

跳跃游戏

要点:维护最大能达到的位置

java 复制代码
class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        int zuiyuan = 0;
        //记录最远的可以的位置就行

        for(int i = 0; i < n; i++){
            //先判断这个点能不能到
            if(i > zuiyuan){
                return false;
            }

            //更新
            int temp = i+nums[i];
            zuiyuan = Math.max(zuiyuan,temp);


            //剪枝
            if(zuiyuan >= n-1){
                return true;
            }

        }

        return true;

        
        
    }
}

跳跃游戏 II

要点:

方法1:dp

java 复制代码
class Solution {
    public int jump(int[] nums) {
        //dp
        int n = nums.length;
        int[] dp = new int[n];

        for(int i = 0 ; i < n ; i++){
            dp[i] = Integer.MAX_VALUE;
        }
        dp[0] = 0;
        for(int i = 0; i < n; i++){
            int maxl = i+nums[i];
            if(nums[i] == 0){
                continue;
            }
            for(int j = i+1 ; j <=maxl && j < n; j++){
                dp[j] = Math.min(dp[j], dp[i]+1);
            }

        }

        return dp[n-1];
        
    }
}

方法2:灵神的造桥法

java 复制代码
class Solution {
    public int jump(int[] nums) {
        int ans = 0;
        int curEnd =0;
        int nextEnd = 0;

        for(int i = 0; i < nums.length-1; i++){
            nextEnd = Math.max(nextEnd, i+nums[i]);
            if(i == curEnd){
                curEnd = nextEnd;
                ans++;
            }
        }

        return ans;
        
    }
}

核心题:TCP 怎么保证可靠传输?

面试官为什么这么问?

这是一道可以让你把课本知识系统输出的题。我要看你能不能有条理地说出确认应答、超时重传、滑动窗口、流量控制、拥塞控制这几个核心机制,最好还能简要解释每一点。

希望听到怎样的回答:

  • 确认应答与序列号:每个字节有编号,接收方回复 ACK 告知期望的下一个字节号,确保数据按序无损到达。
  • 超时重传:发送方等待 ACK 超时,会自动重传数据包。
  • 滑动窗口:不一一确认,发送方可连续发送窗口内的多个包,提高吞吐;接收方返回窗口大小,控制发送速率(流量控制)。
  • 流量控制 :接收方在 ACK 中携带 rwnd 窗口大小,防止发送太快撑爆接收方缓存。
  • 拥塞控制:慢启动、拥塞避免、快重传、快恢复,防止网络拥塞。
  • 最好能举一个例子:比如你下载文件时网络抖了一下,TCP 就靠重传机制保证了文件完整。

候选人

好的,TCP 的可靠性是通过一系列机制协同工作来实现的。我按从基础到进阶的顺序,把这些机制串起来讲清楚。

第一,确认应答与序列号------可靠性的基石。

TCP 把要发送的数据看成一个个字节,给每个字节都分配一个唯一的序列号。接收方每收到一批数据,就会回复一个 ACK 报文,里面带着确认号,意思是"我期待的下一个字节的序列号"。比如接收方收到序列号 1-1000 的数据,就回复 ACK,确认号为 1001,告诉发送方"1001 之前的数据我都收到了,你从 1001 开始发"。

这个机制看似简单,但它是 TCP 可靠性最根本的保障。通过序列号和确认号的持续握手,发送方能够精确知道哪些数据已经安全到达,哪些还没有。

第二,超时重传------兜底手段。

网络是不稳定的,数据包可能在传输过程中丢失,ACK 也可能丢失。发送方每发一个数据包,都会启动一个重传定时器。如果在定时器超时之前没有收到对应的 ACK,发送方就认为这个包丢了,自动重传这段数据。

超时时间 RTO 并不是一个固定值,而是根据网络状况动态计算出来的。TCP 会持续统计 RTT(往返时间)的加权平均值和偏差,当网络抖动变大时,RTO 相应变大;网络平稳时,RTO 变小。这种自适应重传策略既能在网络差时保证可靠,又不会在网络好时浪费等待时间。

重传的触发方式其实有两种。 除了超时重传,TCP 还有快速重传机制。发送方不需要傻等定时器超时,如果连续收到三个相同的 ACK(比如接收方反复说"我期待 1001"),说明序号 1001 之后的数据已经到达了接收方,但 1001 这个包丢了。这时发送方不等定时器到期,立刻重传丢失的那个包。两种重传互补,一个为绝对兜底而设,一个为快速响应连续丢包而设。

第三,滑动窗口------从"一问一答"到"流水线"传输。

如果发送方每发一个包就等 ACK 再发下一个,这就是停等协议,效率极低。TCP 用滑动窗口机制解决了这个问题。

发送方维护一个发送窗口,窗口内的数据可以一次性连续发出,不需要等前面的确认。接收方也维护一个接收窗口,缓存乱序到达的数据。发送方收到 ACK 后,窗口向前滑动,继续发送新的数据。

滑动窗口把一问一答的串行模式,变成了连续发送的流水线模式,吞吐量得到了质的提升。窗口大小不是固定的,由流量控制和拥塞控制共同调节。

第四,流量控制------保护接收方。

接收方的处理能力是有限的,如果发送方发得太快,接收方的缓冲区会被塞满,新数据装不进去只能丢弃,这就失去了可靠传输的意义。

TCP 的做法是:接收方在每次 ACK 报文中,都会在头部携带一个窗口大小字段(rwnd),告诉发送方"我的接收缓冲区还剩多少空间"。发送方据此调整发送窗口,保证在途数据不会超过接收方的处理能力。如果接收方缓冲区快满了,rwnd 变小,发送方就减速;如果接收方处理得快,rwnd 变大,发送方就加速。

如果 rwnd 变成 0,发送方会停止发送数据,但会定期发送窗口探测报文,防止接收方后来清出空间后发的更新 rwnd 的报文丢失导致死锁。

第五,拥塞控制------保护网络。

流量控制是端到端的,保护的是接收方;拥塞控制则是发送方和网络之间的,保护的是整个网络的承载能力。

TCP 假设数据包丢失不仅仅是因为物理错误,更可能是因为网络中的某个路由器缓冲区满了,开始丢包。一旦出现拥塞还大量发包,只会雪上加霜。拥塞控制通过四种策略动态调整发送速率:

  • 慢启动:连接刚开始时,拥塞窗口 cwnd 设为很小的值,每收到一个 ACK 指数翻倍增长,快速探测网络的可用带宽。
  • 拥塞避免:当 cwnd 达到慢启动门限 ssthresh 后,改为线性增长,每经过一个 RTT 加一,温和逼近极限。
  • 快重传:收到三个重复 ACK 不等定时器,立刻重传。
  • 快恢复:发生快重传后,不降到零重新慢启动,而是把 cwnd 减半,然后从减半后的位置进入拥塞避免,快速恢复到合理区间。

最终发送窗口的大小,是流量控制的 rwnd 和拥塞控制的 cwnd 两者的最小值。既要考虑接收方能承受多少,也要考虑网络能承受多少。

第六,结合一个具体场景串起来。

比如你在下载一个文件时,网络突然抖了一下。

发送方连续发了一组包。其中 1001-2000 的包丢了,其余数据包陆续到达了接收方。接收方每收一个后续包,都回复 ACK,确认号都是 1001,意思是"1001 这块数据我还没收到,我一直期待它"。

发送方连续收到了三个相同确认号 1001 的 ACK,快速重传机制被触发,不等定时器超时,直接重传 1001-2000 这个包。接收方终于收到缺失的包,回复一个更大的确认号,滑动窗口继续前滚,文件完整下载完成。

如果重传的包还是丢了,超时重传会作为兜底机制接管,保证数据最终一定送达。

总结一句话:TCP 的可靠性靠的是五层机制协同------序列号与确认应答建立丢失感知、超时重传兜底补救、滑动窗口开启流水线传输、流量控制匹配收发速率、拥塞控制顺应网络状态。每个机制各司其职,共同构建了 TCP 可靠传输的完整体系。

碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第34天。努力连续更新100天!以后每天就按,秋招项目【java +agent】,科研,必做项目,算法,八股,锻炼身体来总结。

总结:得多动脑子

1.算法要系统过一遍晚上】1h

2.秋招项目,【java】开始实际看业务,1/6;无

【agent 】还在学,整理cc,无,

3.科研要跑一下,

4.检测项目也得总结文档,

6.背八股,无

7.锻炼身体,无

反思:睡到中午,然后下午加班,晚上玩手机,没学习,确实还是要保持学习习惯和健康作息

相关推荐
NE_STOP29 分钟前
Vide Coding--AI编程工具的选择
java
通信小呆呆43 分钟前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
码云数智-园园1 小时前
C++20 Modules 模块详解
java·开发语言·spring
程序员黑豆1 小时前
JDK 下载安装与配置详细教程
java·前端·ai编程
benben0441 小时前
强化学习之DQN算法族(基于gymnasium开发)
算法
小宇宙Zz1 小时前
Maven依赖冲突
java·服务器·maven
swordbob1 小时前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
咖啡八杯2 小时前
GoF设计模式——享元模式
java·spring·设计模式·享元模式
十五喵源码网2 小时前
基于springboot2+vue2的租房管理系统
java·毕业设计·springboot·论文笔记