尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java面试场景题实战:从并发扣库存到OOM排查

Java面试场景题实战:从并发扣库存到OOM排查 Java 面试场景题在面试中的占比越来越高这是一个明显的趋势。很多开发者能把 HashMap 扩容流程、ConcurrentHashMap 锁粒度、JVM 内存区域背得很熟但面试官接着问一句“你们的接口在并发扣库存时会怎么设计订单超时未支付系统如何关闭”很多人立刻就卡住。差距不在背诵量而在能否把知识点变成项目里的决策。场景题考察的不是“你知道什么”而是“你在真实系统里会怎么选、怎么做、怎么善后”。这篇文章以 Java 面试场景题为线索把常见面试题和项目实战结合起来梳理一套从刷题、答题到复盘的方法。正文会包含一周刷题计划、五个高频场景题的完整思路和示例代码、面试追问的防御方法以及刷题过程中最容易遇到的环境坑和排查路径。停车场项目里用 MQTT 协议对接海康、大华等车牌识别相机的部分也会作为项目实战案例单独展开。如果你正在准备 Java 面试或者已经工作但想系统回顾一下核心知识可以按这份材料安排一周的复习节奏。代码尽量落地到能跑通的最小示例不要只读不动手。1. 为什么 Java 面试开始考场景题而不是只背八股文1.1 八股文能过笔试却过不了项目追问八股文在笔试和机试阶段仍然重要它用来快速筛选基础是否扎实。但进入现场面试后面试官更关心的是你有没有真正写过可运行的系统而不是只见过别人分享的博客。典型场景是这样的候选人能说出HashMap在 Java 8 之后为什么从链表转红黑树也能说出ConcurrentHashMap的锁粒度是桶节点。可当面试官把问题包装成一条业务场景比如“你们系统的用户数据存在 HashMap 里并发读写时会出现什么问题”候选人反而不知道怎么回答。这是因为背答案只需要记忆答场景题需要调用多种知识做判断。项目追问本质上是在验证候选人有没有形成“问题 - 方案 - 验证 - 复盘”的思考习惯。1.2 场景题考察的是工程判断力场景题的题干通常很短但边界条件很多。典型的问法有你们的订单超时未支付是怎么关闭的并发秒杀下库存怎么防止超卖支付回调重复推送你们怎么保证幂等服务偶发 Full GC怎么排查如果让你接入一批车牌识别相机事件上报走什么协议这些问题没有标准答案只有相对合理的答案。面试官想听的不是“定时任务扫描数据库”而是你能说出这个方案的延迟、数据库压力、补偿方式以及为什么不用延迟消息中间件。所以准备场景题的正确方式是先理解业务约束再比较多个方案最后用代码验证。只背一个答案一旦被追问“换一种方案行不行”就会暴露。1.3 八股题与场景题的本质区别维度八股题场景题典型问题HashMap 为什么用红黑树并发扣库存怎么防止超卖考察点记忆准确性和理解深度方案比较、落地能力和边界意识答案形态单个知识点多个知识点组合包含取舍准备方式反复背诵和默写写 Demo、跑测试、复盘追问面试评判答错扣分方案是否自洽、是否能自曝缺陷从表格可以看出场景题对能力的要求更高。准备场景题时不要追求“标准答案”而是要训练自己像做技术方案评审一样去思考。2. 一周刷题计划怎么设计才能覆盖面试高频场景2.1 按模块切分而不是按题号硬刷很多人准备面试时按题目数量刷今天刷 20 道明天刷 20 道结果知识是散的。真正有效的做法是按模块切分每天集中解决一个主题这样同一个主题下的知识点会自然形成体系。结合 Java 面试场景题的高频区间建议覆盖这几个模块Java 基础与集合、并发与线程池、MySQL、Redis、消息与设备接入、JVM 与 OOM、综合项目复盘。每个模块不需要贪多但要保证每个知识点都能写出代码、能讲清为什么。比如学线程池不能只知道参数要能说出“核心线程数设为多少、队列长度怎么定、拒绝策略选哪种”以及背后的估算依据。2.2 每天刷题闭环题干 - 方案 - 代码 - 追问 - 复盘刷题不能只看答案。每天遇到一道场景题按下面五步处理记录题干找出业务背景和约束条件。先不看答案自己写一版方案哪怕是粗糙的。把方案落到代码里运行并验证。主动追问自己这个方案的缺点是什么极端情况下会怎样把答案和复盘记录成笔记面试前反复看。这套闭环最花时间的是第三步和第四步。很多候选人只做第一步和第二步导致面试时只能说思路写不出代码或者被追问边界条件后答不上来。2.3 一周计划表示例时间主题核心覆盖点产出物第 1 天Java 基础与集合异常处理、泛型擦除、HashMap、ConcurrentHashMap集合对比 Demo第 2 天并发与线程池synchronized、ReentrantLock、CAS、AQS、线程池参数线程池压测小脚本第 3 天MySQL 场景索引失效、SQL 优化、事务隔离、乐观锁慢 SQL 分析笔记第 4 天Redis 场景缓存穿透、缓存击穿、缓存雪崩、分布式锁缓存方案 Demo第 5 天MQTT 与设备接入协议流程、消息 QoS、断线重连、车牌相机对接相机对接 Demo第 6 天JVM 与 OOM内存区域、GC 类型、堆转储分析、Full GC 排查一次 OOM 复盘记录第 7 天模拟面试综合场景题 项目追问录音或书面复盘学习环境和生产环境的重点不一样。学习环境追求快速跑通生产环境还要考虑日志、监控、权限、回滚和异常处理。刷题时至少把“生产环境还会补充什么”这个问题想一遍。3. 五个高频场景题精讲从答题思路到可运行代码3.1 订单超时自动关闭定时任务、Redis ZSET、延迟消息怎么选业务场景很常见用户下单后 30 分钟内未支付系统自动将订单改为已取消并回补库存。第一个直观方案是定时任务扫描数据库。这个方案实现简单但问题明显扫描周期决定关闭延迟比如每分钟扫描一次订单实际超时时间可能被延迟 0 到 60 秒而且订单表变大后全表扫描对数据库压力很大。第二个方案是使用 Redis ZSET。把订单 ID 作为成员把“当前时间 超时时间”作为 score 写入 ZSET然后由一个定时任务每秒取出 score 小于当前时间戳的订单执行关单操作。public class OrderDelayScanner { private static final String DELAY_QUEUE_KEY order:delay:queue; private final StringRedisTemplate redisTemplate; public OrderDelayScanner(StringRedisTemplate redisTemplate) { this.redisTemplate redisTemplate; } public void addDelayOrder(String orderId, long timeoutSeconds) { long expireScore System.currentTimeMillis() timeoutSeconds * 1000; redisTemplate.opsForZSet().add(DELAY_QUEUE_KEY, orderId, expireScore); } public void scanExpiredOrders() { long now System.currentTimeMillis(); SetString expiredOrders redisTemplate.opsForZSet() .rangeByScore(DELAY_QUEUE_KEY, 0, now); if (expiredOrders null || expiredOrders.isEmpty()) { return; } for (String orderId : expiredOrders) { Long removed redisTemplate.opsForZSet().remove(DELAY_QUEUE_KEY, orderId); if (removed ! null removed 0) { closeOrder(orderId); } } } private void closeOrder(String orderId) { // 修改订单状态为已取消并回补库存 // 这里要保证幂等避免重复关单 } }关键点是先移除成员再执行关单逻辑。如果先执行业务再移除万一业务处理超时或抛出异常同一个订单可能被下一个扫描周期再次取出。先移除虽然可能在业务失败时丢失延迟任务但可以通过一个兜底任务扫描数据库未支付订单来解决。第三个方案是使用 RocketMQ 或 RabbitMQ 的延迟消息。延迟消息实时性更好适合对关闭时间敏感的场景但增加了中间件依赖也要考虑消息重复投递的幂等问题。这个场景里面试官最常追问的是Redis 中延迟任务丢失怎么办正确的回答思路是把 Redis ZSET 作为主路径同时保留一个定时任务扫描数据库里“未支付且已超时”的订单作为兜底。两个路径都走到业务层后通过数据库更新条件保证幂等。3.2 库存防超卖数据库乐观锁和 Redis Lua 怎么配合库存防超卖是面试里出现频率最高的场景题之一。直接写成先查询库存再 UPDATE会出现并发问题int stock selectStock(skuId); if (stock 0) { updateStock(skuId, stock - 1); }两个线程同时查到库存为 1都认为可以扣减结果库存变成 -1这就是超卖。解决办法是在 UPDATE 语句里带上库存条件。UPDATE sku_stock SET stock stock - 1 WHERE sku_id #{skuId} AND stock 1;affectedRows 等于 1 说明扣减成功等于 0 说明库存不足或商品不存在。这种方式利用数据库行锁保证同一时刻只有一个线程能扣减成功。在高并发场景下数据库行锁会成为瓶颈所以很多项目把库存预加载到 Redis再用 Lua 脚本保证扣减的原子性。local stock tonumber(redis.call(GET, KEYS[1])) if stock nil then return -1 end if stock 0 then return 0 end redis.call(DECRBY, KEYS[1], ARGV[1]) return 1Java 端通过DefaultRedisScriptLong调用脚本private static final String STOCK_LUA local stock tonumber(redis.call(GET, KEYS[1])) if stock nil then return -1 end if stock 0 then return 0 end redis.call(DECRBY, KEYS[1], ARGV[1]) return 1; DefaultRedisScriptLong script new DefaultRedisScript(STOCK_LUA, Long.class); Long result stringRedisTemplate.execute( script, List.of(stock:sku: skuId), String.valueOf(count) );注意Redis 扣减成功并不代表数据库库存已经更新因此还要由一个异步任务把 Redis 中的扣减结果同步到数据库保证最终一致性。这个场景的追问点通常集中在扣减成功后用户取消订单库存怎么回补回补时要防止重复回补可以用一个业务单号加唯一索引控制。不要把回补逻辑写成“查到订单已取消就无条件加库存”否则重复回调会导致库存越加越多。3.3 接口幂等性重复请求和重复回调怎么处理幂等性在很多业务里都会出现用户疯狂点击提交按钮、支付网关重复推送回调、MQ 重复投递消息。面试官通常会让候选人设计一个通用幂等方案。最稳妥的做法是数据库唯一索引。业务表设计时预留一个幂等键字段并建立唯一索引CREATE TABLE idempotent_record ( idempotent_key VARCHAR(128) PRIMARY KEY, biz_type VARCHAR(32) NOT NULL, payload TEXT, created_time DATETIME NOT NULL, KEY idx_biz_type (biz_type) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;处理请求时先尝试插入幂等记录。如果插入成功说明是第一次请求继续执行业务如果插入时主键冲突说明是重复请求直接返回之前的处理结果或提示重复提交。Redis 版本可以更轻量Boolean success stringRedisTemplate.opsForValue() .setIfAbsent(idempotent: idempotentKey, 1, Duration.ofMinutes(10)); if (Boolean.FALSE.equals(success)) { throw new BusinessException(重复请求请勿重复提交); } try { doBiz(); } finally { // 注意不建议无脑删除幂等 key // 需要结合业务状态决定何时删除 }这里有几个细节要说明。第一setIfAbsent是原子操作不会出现两个线程同时判断不存在然后同时写进去的问题。第二Redis 幂等 key 的过期时间必须大于业务处理时间。如果请求处理了 5 分钟key 却只有 3 分钟过期同一请求后面部分就拦不住了。第三不要在finally里无脑删除 key。正确做法是业务处理完成后根据业务状态决定是否删除或者保留 key 到业务周期结束让数据库唯一索引兜底。纯靠 Redis 做幂等一旦 key 丢失重复请求还是会进来。回答这个题时建议主动说出“最终推荐数据库唯一索引兜底 Redis 做前置过滤”的组合方案。这比只说一种方案更接近生产实际。3.4 停车场项目实战MQTT 怎么搞定海康、大华等车牌识别相机项目场景是停车场系统要接入多品牌车牌识别相机。当车辆进入或离开时相机识别车牌并把入场、出场事件上报给平台。不同品牌的相机能力不同有的提供厂商 SDK有的提供 MQTT 网关或 HTTP 回调。使用 MQTT 协议做统一接入是项目中比较常见的思路。选择 MQTT 的原因有三个车牌识别事件是小而频繁的消息适合 MQTT 这种轻量协议。MQTT 支持断线重连、遗嘱消息、QoS 级别适合停车场闸口网络不完全稳定的环境。发布订阅模型方便扩展。每台相机或相机网关作为一个客户端订阅指定主题平台侧统一订阅事件主题即可新增设备时不需要改平台代码。如果设备侧不是直接支持 MQTT项目里通常通过一个边缘网关或协议适配服务把厂商 SDK 的消息转成标准 MQTT 消息。平台侧只依赖 MQTT 主题和 JSON 结构不直接依赖厂商 SDK这样后续替换硬件品牌时影响最小。MQTT 连接配置示例mqtt: broker: tcp://192.168.10.20:1883 client-id: parking-platform-01 username: parking password: encrypted-value topics: - plate/event/# - camera/status/# qos: 1 connect-timeout: 10 keep-alive: 30Java 端接收事件的思路可以先用一个轻量客户端封装。以 Eclipse Paho 为例核心是MqttCallbackpublic class PlateEventCallback implements MqttCallback { private final PlateEventProcessor processor; public PlateEventCallback(PlateEventProcessor processor) { this.processor processor; } Override public void connectionLost(Throwable cause) { // 记录日志触发重连 // MQTT 客户端可以通过 reconnect() 恢复 } Override public void messageArrived(String topic, MqttMessage message) throws Exception { String json new String(message.getPayload(), StandardCharsets.UTF_8); String deviceId resolveDeviceId(topic); processor.process(deviceId, json); } Override public void deliveryComplete(IMqttDeliveryToken token) { // 发送完成回调一般用于消息发布侧 } }车牌识别事件的消息体字段各厂商有差异但通常会包含车牌号、事件类型、抓拍时间、图片地址和相机编号。标准化后的结构类似{ plateNo: 京A12345, eventType: ENTRY, deviceId: camera-001, passTime: 2026-02-18 08:30:00, imageUrl: http://storage.internal/plate/20260218/xxx.jpg, direction: IN }平台收到事件后根据deviceId判断入口还是出口然后调用停车记录服务创建入场记录或者触发计费和抬杆。在实际项目里这个对接过程最需要留意的不是 MQTT 本身而是设备厂商的字段差异和网络异常。不同相机的eventType可能叫EntryEvent、enter或1所以必须做一层协议适配。否则当项目从海康相机换成大华相机时平台要大面积改动。此外client ID 必须保证唯一。如果两个 MQTT 客户端使用相同的 client ID后者会把前者踢下线导致相机事件丢失。建议按设备编号生成 client ID例如parking-platform-01和camera-001分开使用不同 client ID。3.5 线上 OOM 排查从日志到堆转储的完整路径OOM 是 Java 开发绕不开的话题。面试中常见的考法不是问内存模型而是问“线上服务突然挂了日志里出现OutOfMemoryError: Java heap space你会怎么排查”。最怕的是没有留下现场。很多项目在启动脚本里没有配置堆转储参数进程一挂堆里的对象全部丢失排查只能靠猜。正确的启动参数应该提前加好java -Xms1g -Xmx1g \ -XX:HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath/var/log/app/oom.hprof \ -jar parking-service.jar启动参数中-Xms和-Xmx建议设置成相同值避免 JVM 运行期动态扩容带来的性能抖动。HeapDumpOnOutOfMemoryError让 JVM 在抛出 OOM 前生成堆转储文件HeapDumpPath指定文件路径。排查时按以下顺序进行# 1. 查看 Java 进程 jps -l # 2. 查看 GC 情况和内存变化 jstat -gcutil pid 1000 # 3. 查看堆对象分布 jmap -histo:live pid | head -30 # 4. 导出堆转储文件交给 MAT 或 JProfiler 分析 jmap -dump:live,formatb,file/tmp/app_dump.hprof pid在堆上直接执行jmap -dump时要注意大堆导出会阻塞应用。生产环境优先使用配置好的-XX:HeapDumpOnOutOfMemoryError自动转储手动导出放在服务半挂或低峰期做。拿到 hprof 文件后用 MAT 打开先看Dominator Tree通常能找到占内存最多的对象。常见根因有以下几类根因典型表现处理方向一次性加载超大集合某一个 List 占用数 GB改为分页查询或流式处理线程过多Thread 对象数量巨大检查线程池和连接池参数静态缓存无限增长静态 Map 不断 add使用带容量上限的缓存组件临时对象频繁创建GC 频繁但内存仍不够检查循环内创建对象和未关闭 IO元空间不足Metaspace OOM增加 Metaspace 或排查动态类生成排查 OOM 时不要只看堆大小还要结合 GC 日志和线程栈。如果 Full GC 非常频繁但每次回收后内存很快又满通常是有对象被持有无法释放而不是单纯堆太小。面试中追问“Full GC 频繁和 OOM 有什么区别”时可以这样回答Full GC 频繁说明内存回收压力大系统可能还活着但吞吐量下降OOM 说明对象分配已经无法满足进程即将退出。两者都可能由内存泄漏或超大对象引起但 OOM 是最终结果Full GC 频繁是前兆。4. 面试官追问时如何稳住答题框架和追问防御4.1 按三层结构答场景描述题场景题回答要有层次不建议一上来就写代码或报方案。推荐按“结论先行 - 方案比较 - 缺陷补偿”三层结构回答。比如订单超时问题第一层结论我会优先使用 Redis ZSET 做延迟扫描因为当前量级下实现成本低、延迟可控同时保留数据库定时任务兜底。第二层对比不用纯数据库定时任务是因为全表扫描压力大不用延迟消息是因为引入 MQ 增加运维成本。第三层缺陷Redis ZSET 方案存在任务丢失风险所以增加数据库兜底扫描并且关单逻辑要做幂等。这套结构的好处是即使面试官不认同你的选择他也能清楚看到你的判断依据讨论会围绕取舍展开而不是停留在“你答错了”。4.2 被追问到不会问题时怎么切换策略场景题的追问往往会超出准备范围。这时不要硬撑也不要马上说不会而是先做边界确认。可以这样回应“你说的这个场景我不太确定我先确认一下这里的并发量大概是多少对一致性的要求是强一致还是最终一致”这样有两个作用一是给自己争取思考时间二是在面试官眼里你是在按工程方法分析问题而不是在背书。快速决策清单可以按四步走判断量级单机几百 QPS 和分布式十几万 QPS方案完全不同。判断一致性强一致用数据库事务或分布式事务最终一致用消息队列加幂等。判断失败语义允许重试还是必须回滚。判断基础设施项目里已经有 Redis、MQ还是需要引新组件。如果确认后仍然无法准确回答可以说出思路“这个问题我虽然没直接做过但按模型看我会先考虑……然后通过压测验证。”4.3 主动暴露缺陷反而更像有经验没有方案是完美的。候选人主动说出方案的缺陷并给出补偿机制比把方案吹得十全十美更有说服力。例如回答幂等设计时“这个方案在 Redis key 提前过期时会有失效风险所以我会在关键业务表加唯一索引兜底。如果唯一索引也冲突说明请求确实重复了业务层直接返回成功不报错。”这句话体现了两个经验点知道 Redis 幂等有缺陷知道怎么用数据库兜底。这种表达方式在面试中很加分。5. 刷题过程中必踩的环境坑和排查路径5.1 Lombok 编译告警新版本 JDK 下为什么 Lombok 不工作刷题时很多人用最新版 JDK然后遇到一行很迷惑的编译告警java: You arent using a compiler supported by lombok, so lombok will not work with your project.现象是 IDE 里所有使用了Data、Slf4j的类都编译失败报找不到getXxx()方法或log变量。原因是 Lombok 通过注解处理器修改编译期 AST它对 JDK 内部 API 有版本依赖。JDK 版本太新而 Lombok 版本太旧时Lombok 无法工作了。处理方式确认 JDK 版本java -version。确认 Lombok 版本看pom.xml或build.gradle。把 Lombok 升级到支持当前 JDK 的版本。一般新项目优先使用较新的稳定版本同时查看 Lombok 发布说明。如果项目是 Gradle还要确认 annotationProcessor 的配置是否正确。在准备面试项目时建议不要为了尝鲜而用很不稳定的 JDK 版本。选一个主流 LTS 版本和配套稳定的框架版本能减少大量环境问题。5.2 源发行版 17 需要目标发行版 17另一个高频编译错误是java: 警告: 源发行版 17 需要目标发行版 17错误原因一般是 Maven 编译参数和 JDK 版本不一致。比如本机 JDK 是 17但pom.xml里的maven.compiler.source还是 8或者 IDEA 里 Project Structure 的 Language Level 与 Maven 设置不一致。排查路径检查pom.xml中的属性properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target /properties检查 IDEA 的 Project Structure把 SDK 和 Language Level 都设为 17。检查 Maven Runner 的 JRE 设置确保 Maven 使用同一个 JDK。检查 Maven Compiler Plugin 版本过旧版本插件对新 Java 版本支持不好。这属于环境配置问题不是业务逻辑问题但刷题时最容易卡住。碰到类似报错先查编译链路再查代码。5.3 OutOfMemoryError: Insufficient memory 不只是堆太小有一种 OOM 特别容易让人误解它的提示不是Java heap space而是java.lang.OutOfMemoryError: Insufficient memory看到这个报错时不要第一时间只调大-Xmx。常见原因有这么几类启动参数把-Xmx设置得比容器或物理机内存还大JVM 初始化失败。系统可用内存不足但不是堆的问题而是线程栈、直接内存、Metaspace 等 native memory 不够。创建了大量线程每个线程默认栈大小-Xss乘起来超过了系统限制。容器场景下内存 limit 小于 JVM 申请的内存。检查方式free -h docker stats cat /proc/meminfo jcmd pid VM.flags处理方向是结合容器内存设置-Xmx一般控制在容器内存的 70% 到 80%。同时检查线程数上限和直接内存使用量。生产环境要配合监控别等运行几天后在凌晨突然 OOM。问题现象常见原因检查方式处理建议日志出现 Insufficient memory-Xmx 超过物理内存free -h 查看内存调低 -Xmx容器启动后被 OOM Kill未设置容器 aware 参数docker stats 观察内存配置 JVM 识别容器限制线程大量创建后崩溃线程栈耗尽 native memoryjstack 查看线程数优化线程池降低 -Xss 或限制线程数堆未满但系统内存不足直接内存或元空间占用jcmd VM.native_memory排查 NIO 和动态类生成6. 项目实战复盘清单简历和面试表达怎么落地6.1 简历项目陈述公式背景 - 选型 - 实现 - 结果准备项目实战类问题时简历里的描述尽量按“业务背景、技术选型、实现细节、结果指标”四段写。以停车场相机对接项目为例业务背景停车场需要接入多品牌车牌识别相机实时处理车辆入场和离场事件并触发计费与放行。技术选型Spring Boot MQTT Redis MySQL。实现细节设计统一事件模型通过 MQTT 订阅车牌事件主题解析不同厂商的相机消息用 Redis 缓存设备状态和临时记录最终写入 MySQL。结果指标完成主流品牌相机的接入验证入场事件入库耗时在可接受范围内设备断线后能自动恢复。写项目经历时不要只写技术名词要把“为什么选它”和“遇到什么问题”写出来。面试官看到“MQTT”后会追问 Qos、断线重连、消息乱序、client ID 唯一性这些都要提前准备。6.2 面试前检查清单准备场景题至少要在面试前一天完成以下检查本机 JDK、Maven、Git 环境是否正常能否一键编译。每个 Demo 是否都能运行而不是只写了代码没跑过。每个方案能不能回答三个问题为什么选它、有什么缺点、怎么兜底。项目中的表和中间件结构是否画得出来比如订单表结构、缓存 key 设计、MQTT topic 划分。是否准备过日志和异常验证比如测试过 OOM 参数、看过程序崩溃后的日志。建议把上面内容整理成一个 checklist 文档面试前逐项打勾。6.3 答题可用句式场景题回答有一些可以复用的表达方式。以下句式不是套话而是强迫自己把话说完整“我会先确认这个接口的并发量级和一致性要求因为不同的量级对应完全不同的方案。”“这个方案有一个代价是……但在当前业务场景下可以接受。”“这里我不用分布式事务原因是这个流程允许最终一致状态机加幂等已经能解决问题。”“如果出现重复消息我用数据库唯一索引兜底。”“我建议先小流量验证再逐步放量同时监控 GC 和慢 SQL。”实际面试中语言可以不用那么正式但结构要保持。先把结论说出来再补理由最后说明边界条件。这样做的好处是即使面试官中途打断你也已经把核心观点表达出去了。准备 Java 面试场景题最关键的还是把代码写出来、把项目讲清楚、把边界条件想透。一周时间可以用来集中冲刺但工程能力的积累来自平时每一次方案设计、代码 review 和线上问题排查。刷完这些题目之后建议挑一个项目里的真实问题完整走一遍“现象 - 定位 - 修复 - 复盘”的过程这比再背一百道题更有价值。
返回列表