Java高频考点场景题24

订单超时取消的设计方案差异能直接反映程序员的实战经验层级。

暴力轮询方案:新手常用 Quartz 或 Spring Schedule 定时扫全表检查未支付订单,高并发下会导致数据库 CPU 飙升、时效性差、锁竞争激烈。

延迟消息方案:下单时发 30 分钟延迟消息,消费者收到后检查订单状态执行取消;进阶用阶梯式检查(如 30 秒→1 分钟→5 分钟),尽早释放已支付订单,但会增加 MQ 消息量。

事务消息方案:下单发送事务消息,本地创建订单后返回 unknown,MQ 定期调用 checkLocalTransaction 回查;回查时若订单已支付则 rollback,未支付且未超时则继续返回 unknown,超时未支付则 commit 触发取消。

第三方确认环节:取消订单前需主动查询微信、支付宝等第三方支付平台的订单状态,避免回调延迟或丢失导致的支付成功但订单被取消的事故。

视频通过方案演进映射程序员从硬刚实现到全局视野的成长路径。

秒杀系统设计需通过多层拦截分散高并发压力,而非仅依赖 Redis 扣库存。

流量削峰:前端页面静态化并推至 CDN,活动前预加载;秒杀按钮置灰防止提前点击;Nginx 层设置连接数和 QPS 上限做兜底保护。

Redis 预扣库存:秒杀前将库存预加载到 Redis,用户请求通过 Lua 脚本原子性判断并扣减库存,扣减成功才进入后续流程。

异步下单:Redis 扣库存成功后,将请求发送至消息队列异步消费,完成订单创建和数据库库存扣减,用户端轮询订单状态。

数据库兜底:数据库写库存时加乐观锁,若更新函数为 0 则回滚,防止超卖。

防刷限流:同一用户 ID 仅允许成功一次,对同一 IP 进行限流,引入人机验证拦截高风险请求。

活动后清理:秒杀结束后 Redis 库存与数据库对账,未完成 MQ 消息设置超时处理机制。这套设计的核心是用多层拦截减少请求量,用缓存承担并发,用 MQ 异步化写操作,用乐观锁保证一致性。

蚂蚁金服二面中,仅会用 jstack 排查死锁但无法给出预防方案的候选人会直接被淘汰。

事故现场:支付系统转账时,用户 A 转 B 与用户 B 转 A 的请求同时触发,系统先锁转出账户再锁转入账户,导致两个请求互相等待对方持有的锁,程序卡死。

排查方法:使用 jstack 命令打印线程堆栈,通过 Deadlock 关键字定位死锁线程及锁持有关系。

死锁条件:需满足互斥、占有并等待、不可抢占、循环等待四个必要条件,破坏任一条件即可预防死锁。

预防方案:固定加锁顺序(按账户 ID 从小到大加锁)、使用 tryLock 超时机制、减少锁的持有时间。

生产建议:转账前检测账户状态、缩小加锁范围、设置超时机制、配置线程等待监控告警。

视频强调,死锁问题的核心考察点是系统设计思维,而非仅工具使用能力。

视频通过三个面试场景,呈现了不同数据类型下 TopK 问题的最优解法选择逻辑。

核心考点:视频以 "10 亿个数字找最大 100 个""10 亿个 URL 找访问频率最高 100 个""10 亿个手机号找重复最多 100 个" 三个场景,展示了分治、堆排序、位图法、桶排序等算法的应用边界。

关键细节:面试官重点考察数据倾斜处理(二次哈希、一致性哈希)、算法时间复杂度(小顶堆 O (NlogK))、内存优化方案(位图法仅需 512MB 处理 32 位整数)。

面试技巧:视频强调需根据数据特征(整数 / 字符串 / 重复率)选择算法,而非仅背诵 "小顶堆" 标准答案。

视频最后总结了不同场景下的 TopK 解决方案,包括内存足够时用堆排序、内存不足时分治归并、整数场景用位图法等。

synchronized和reentrantlock区别? 仅回答关键字与类、隐式与显式锁的区别会暴露知识浅薄、缺乏深度思考等问题,导致面试失败。

相同点:两者核心功能一致,都实现互斥锁,支持可重入性,保证内存可见性。

实现层面:synchronized 是 JVM 层面的内置锁,由底层机制保障;ReentrantLock 是 API 层面的工具类锁,功能强大且可定制性高。

灵活性:synchronized 功能固定,ReentrantLock 支持可中断获取、超时获取、非阻塞获取、公平锁和多个条件变量。

性能:JDK1.6 前 synchronized 性能差,之后 JVM 引入偏向锁、轻量级锁等优化,竞争不激烈时性能更优,性能不再是选择的决定性因素。

选择原则:优先使用 synchronized,因其简单安全;仅在需要高级功能时考虑 ReentrantLock。

视频最后提出问题,询问 ReentrantLock 的可重入性实现方式,以及它与 synchronized 的可重入性实现原理的不同。

实战中 Redis 与 MySQL 数据一致性问题的核心是追求最终一致性而非强一致性。

核心结论:分布式环境下强一致性代价过高,需将数据不一致的时间窗口缩至最短。

常用方案:先更新数据库再删除缓存,通过重试机制或消息队列解决删除失败问题。

兜底方案:延迟双删,先删缓存再更新数据库,异步延迟后再次删除缓存,解决并发导致的脏数据问题。

最稳方案:订阅 binlog 异步删缓存,通过 Canal 等工具监听 MySQL 的 binlog,数据变化时异步删除缓存,与业务代码解耦。

根据业务能容忍的时间窗口选择方案,避开脏数据即可应对面试问题。

相关推荐
兔小盈1 小时前
多线程-(五)线程安全之内存可见性
java·开发语言·多线程
CeshirenTester2 小时前
LangChain的工具调用 vs 原生Skill API:性能差在哪儿?
java·人工智能·langchain
yaoxin5211232 小时前
400. Java 文件操作基础 - 使用 Buffered Stream I/O 读取文本文件
java·开发语言·python
Fox爱分享2 小时前
字节二面:10亿数据毫秒级查手机尾号后4位,答不出“异构索引”直接挂?
java·后端·面试
WaywardOne2 小时前
Flutter面试事件队列,微任务队列以及事件循环相关问题及回答
flutter·面试
6190083362 小时前
win idea 控制台中文乱码
java·ide·intellij-idea
折哥的程序人生 · 物流技术专研2 小时前
《Java面试85题图解版(二)》进阶深化上篇:并发编程 + JVM
java·开发语言·后端·面试
Mahir082 小时前
MySQL 数据一致性的基石:三大日志( redo log/undo log/binlog)与两阶段提交(Prepare 阶段和Commit 阶段)深度解密
数据库·后端·mysql·面试
abcnull2 小时前
用ASM做精准测试(Java)
java·jar·asm·字节码·精准测试