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

螺旋矩阵

要点:模拟,上下左右变换

java 复制代码
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int top = 0;
        int dibu = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;
        List<Integer> ans = new ArrayList<>();
        while(top <= dibu && left <= right){
            for(int i = left ; i <= right; i++){
                ans.add(matrix[top][i]);
            }
            top++;

            if(top <= dibu){
                for(int i = top; i <= dibu; i++){

                    //ans.add(matrix[right][i]);注意写法,行列是那个在动
                    ans.add(matrix[i][right]);
                }
                right--;
            }




            if(top <= dibu){
                for(int i = right; i >= left; i-- ){
                    ans.add(matrix[dibu][i]);
                }
                dibu--;
            }

            if(left <= right){
                for(int i = dibu; i>= top; i--){
                    ans.add(matrix[i][left]);
                }
                left++;
            }

        }

        return ans;
        
    }
}

旋转图像

要点:先转置,然后反转

java 复制代码
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        //第一步转置
        for(int i = 0; i < n; i++){
            for(int j = 0; j < i; j++){//对角线下方的元素
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = tmp;
            }
        }


        //第二部行反转

        for(int[] row : matrix){
            for(int j = 0; j < n/2; j++){
                int tmep = row[j];
                row[j] = row[n-1-j];
                row[n-1-j] = tmep;
            }
        }

        
        
    }
}

矩阵置零

要点: 模拟

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;

        boolean[] hang = new boolean[n];
        boolean[] lie = new boolean[m];

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(matrix[i][j] == 0){
                    hang[i] = lie[j] = true;
                }else{
                    continue;
                }
            }
        }

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(hang[i] || lie[j]){
                   matrix[i][j] = 0;
                }
            }
        }

    


        
    }
}

随机知识

Q1:happens-before 举例说明 volatile 规则和传递性

你的回答:基本正确但缺少举例。

标准答案(面试官想要的):

"happens-before 是 JMM 的核心,例如 volatile 变量规则 :对一个 volatile 变量的写 happens-before 后续对该变量的读。传递性 :若 A happens-before B,B happens-before C,则 A happens-before C。

举例 :线程1执行 a=1(普通写);flag=true(volatile 写)。线程2执行 if(flag) 读到 true,则 a=1 对线程2可见。推导:a=1 happens-before flag=true(程序次序),flag=true happens-before flag 读(volatile 规则),flag 读 happens-before a 读(程序次序),传递得 a=1 happens-before a 读。"

改进点 :一定要把传递性链条说出来,并且提到"普通变量 a 也能被看见"。


Q2:DCL 不加 volatile 的问题,以及不用 volatile 的替代方案

你的回答:"会造线程创建这个对象是对其他线程不可见的,加上指令重排,导致其他线程指向对象失败,加其他关键字" ------ 表述不清。

标准答案:

"不加 volatile 时,instance = new Singleton() 的三步(分配内存、初始化、赋值)可能重排序为 1→3→2。线程A执行到步骤3(赋值)但未初始化,线程B判断 instance != null 直接返回,使用未初始化的对象导致空指针或属性默认值错误。

不用 volatile 的替代方案:

  1. 静态内部类 Holder :private static class Holder { static final Singleton INSTANCE = new Singleton(); },利用类加载的初始化锁保证线程安全。

  2. 枚举单例 :enum Singleton { INSTANCE; },最简洁,防反射防序列化。"

改进点:不要只说"加其他关键字",要给出具体替代方案名称。


Q3:复杂任务选择 ReAct 还是 Plan-and-Execute?

你的回答:"plan,因为先计划在执行会更好的结果" ------ 太简略,没有对比分析。

标准答案:

"我选择 Plan-and-Execute。原因:

  1. 复杂任务步骤多,ReAct 每步都需调用 LLM,成本高且容易在长序列中偏离目标。

  2. Plan-and-Execute 先做全局规划,可并行执行无依赖步骤(如查机票和查酒店同时进行),效率更高。

  3. 规划可被缓存或复审,便于调试。

    但 ReAct 在环境动态变化、需要实时反馈的场景更优(如游戏操作)。本题是固定流程的行程规划,Plan-and-Execute 更合适。"

改进点:要展示你权衡过两种模式的优劣,而非简单下结论。


Q4:同一用户并发请求同一 Agent 的状态冲突避免(Redis 乐观锁细节)

你的回答:"前端限制,后端去重,版本号用时间戳" ------ 过于简化,且时间戳在高并发下会重复(同一毫秒),不可靠。

标准答案:

"前端限制按钮防抖是辅助手段,后端必须处理。方案:

  1. 请求去重 :使用 Redis 的 SETNX 对 userId+requestId 加短时锁,相同请求直接返回已有结果。

  2. 乐观锁(版本号) :在 Redis 中存储状态 key = agent:session:{userId},value 包含 plan、currentStep、version(自增整数)。更新时用 Lua 脚本或 WATCH + MULTI/EXEC,检查 version 是否匹配,不匹配则重试或拒绝。

  3. 时间戳不可靠 :同一毫秒内可能重复,必须用原子自增(如 INCR)生成版本号。"

改进点 :版本号必须原子自增,不能用时间戳;要提到 Lua 脚本保证原子性。


Q5:LLM 响应慢时的线程模型和超时控制

你的回答:"用 SSE 流式回复" ------ 答非所问。SSE 是客户端接收方式,不解决服务端线程阻塞。

标准答案:

"LLM 响应 5 秒会导致 Tomcat 线程池被占满。解决方案:

  1. 异步化 :使用 CompletableFuture 或 WebFlux 非阻塞 I/O,将 LLM 调用提交到独立线程池,主线程快速返回 Future。

  2. 超时控制 :future.get(3, TimeUnit.SECONDS) 或 @Async 配合 TimeoutTask,超时后取消任务并返回降级结果(如"服务繁忙,稍后重试")。

  3. 线程隔离 :为 LLM 调用单独配置线程池(如 ThreadPoolTaskExecutor),设置队列和拒绝策略,避免拖垮整个服务。

  4. 熔断降级:使用 Resilience4j 或 Sentinel,当 LLM 调用失败率超过阈值时直接返回兜底回复。

  5. SSE 流式:适合客户端边生成边展示,但服务端仍需异步处理,不能代替超时控制。"

改进点:要区分"超时控制"和"流式传输",前者是服务端健壮性,后者是交互体验。

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

总结:要掌控好自己的时间

1.算法面试150 【早中晚】1h

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

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

3.科研要跑一下,

4.检测项目,准备数据集【30min】

6.背八股,【30min】

7.锻炼身体,

今天杂活干了7h

反思:少刷短视频,该休息就休息

相关推荐
其实防守也摸鱼1 分钟前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
IT规划师2 分钟前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
SL_staff36 分钟前
打破风控迭代死循环:用决策编排重构业务与技术协作链路
java·产品·全栈
Mikko71 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
.Bryce.1 小时前
从零到一开发技术名词大全:从需求分析到 AI Agent 工程
java·网络·人工智能·agent·需求分析·agent评测
小超人诞生日记1 小时前
C++ 智能指针的使用及其原理详解
c++·算法
SL_staff1 小时前
JVS-APS的7个刚性约束设计:从无限产能幻觉到可执行排产的工程实践
java·spring cloud·全栈
代码山河3 小时前
基本类型转换:自动类型转换与强制类型转换
java·学习·架构·教程·面向对象·项目
Escalating_xu4 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络