Java高频面试考点场景题22

生产环境中使用 InheritableThreadLocal(ITL)处理线程池场景的 userId 传递,不仅无法解决问题,还会引发脏读事故。

数据丢失根源:主线程与异步线程存在内存隔离,若未显式桥接,数据无法跨线程传递,导致子线程读取 userId 为空。

ITL 的致命缺陷:在线程池复用机制下,ITL 仅在新建线程时复制主线程数据,复用线程时不会触发复制逻辑,导致新任务读取到旧任务的残留数据,引发脏读。

TTL 解决方案:通过阿里开源的 TransmittableThreadLocal(TTL)的 CRR 模式(Capture 捕获、Replay 重放、Restore 恢复),在任务提交时捕获上下文,执行前重放覆盖脏数据,执行后恢复线程状态,避免污染后续任务。

无侵入落地:采用 Java Agent 字节码增强技术,自动将普通任务包装为 TtlRunnable,业务层无需修改代码即可实现上下文自动流转。

视频明确指出,解决线程池场景下 userId 传递问题的核心是使用 TTL 的 CRR 模式。

五年经验的后端求职者因对数据库连接池原理的理解不足,导致面试回答无法应对实际事故场景。

事故场景:某系统将数据库连接池最大连接数从 50 调至 200 后,数据库连接数爆满、CPU 使用率达 100%,系统瘫痪。

核心问题:连接池并非越大越好,每个连接会占用数据库资源,连接数过大会导致上下文切换频繁、锁冲突放大,反而降低性能。

优化四层设计:

连接池原理:核心是复用连接,最佳连接数需根据核心线程数、等待时间和处理时间计算(公式为核心线程数 × 等待时间 ÷ 处理时间)。

数据库并发能力:PostgreSQL 每个连接占用 10-20MB 内存,200 个连接需 4GB 内存;高连接数会放大行锁、表锁冲突,有效并发可能低于 50。

连接池配置:需调整最小空闲连接、连接超时、空闲连接回收、连接生命周期等参数,不能仅调最大连接数。

监控与告警:通过 Prometheus+Grafana 监控活跃连接数、等待线程数、连接获取时间等指标,提前发现异常。

视频强调连接池配置需结合业务模型、数据库能力和监控数据科学调整。

京东零售 T7 架构题中,直接用动态规划解决优惠券组合问题会因状态爆炸被面试官淘汰。

业务筛选:通过漏斗图过滤过期、类目不匹配、未到时间的无效券,将 100 张券压缩至 20 张左右有效券。

算法优化:放弃动态规划(状态维度爆炸),采用回溯法结合图论降维(拆分连通孤岛)和支配剪枝(去除劣质券),降低计算复杂度。

工程落地:通过零 GC(用 long 类型、索引遍历避免 Young GC)、BitMap 位运算(互斥判断)、线程策略(巨型任务用 ForkJoinPool)、动静分离(规则引擎前置)等手段保证 200ms 内响应。

视频指出该题核心考察架构师对业务、底层和工程落地的综合能力。

候选人对 MQ 消费失败的回答仅停留在表面,未覆盖真实系统设计的核心问题。

候选人回答:消费失败时通过抛异常重试,多次失败后记录日志人工排查;针对重复投递,提出通过订单判断是否已处理。

核心问题:真实系统需解决消息不丢失、避免重复消费导致业务错误两个核心问题。

完整设计:采用三层机制,包括设置最大重试次数的自动重试、兜底的死信队列、保证幂等的业务逻辑(如通过订单 ID 判断是否已处理)。

视频明确指出真实系统需结合重试、死信队列和业务幂等三层机制。

仅依赖组件名称无法真正解决微服务雪崩问题,系统防护需完整治理体系。

依赖治理:通过 SkyWalking、Zipkin 等工具绘制服务调用拓扑图,区分核心服务(订单、支付)与非核心服务(积分、推荐),实现依赖隔离。

熔断器机制:需理解关闭、打开、半开三态逻辑,配置失败率阈值触发熔断,通过休眠窗口尝试恢复服务。

隔离策略:根据调用场景选择线程池隔离(适合慢调用)或信号量隔离(适合高并发快调用),主流工具为 Resilience4j 或 Sentinel。

动态监控:通过 Grafana 可视化 QPS、RT、错误率等指标,结合 Nacos、Apollo 配置中心实时调整熔断参数。

服务治理需从依赖、熔断、隔离、监控四个维度构建完整防护体系。

MySQL 索引失效的核心原因可归纳为一个 "变" 字,即让原本有序的索引变得无序或需要先计算结果才能查找。

三大忌

对索引列做运算或加函数,导致数据库无法直接使用索引,需全表计算。

模糊查询用百分号开头,类似字典按首字排序却查尾字,只能全表扫描。

隐式类型转换,如字符串字段用数字查询,系统会转换索引列导致失效。

两个坑

联合索引不符合最左前缀原则,跳过首字段会使后续字段无序,无法使用索引。

乱用 or 连接条件,若其中一个字段无索引,数据库会放弃所有索引进行全表扫描。

视频最后提出思考题:如何判断查询是否走索引。

相关推荐
雨季mo浅忆1 小时前
第二项目重新梳理
前端·面试
枫叶丹41 小时前
【HarmonyOS 6.0】Core File Kit:端云文件版本管理能力解析与实践
开发语言·华为·harmonyos
小则又沐风a1 小时前
list模拟实现
java·服务器·list
初心未改HD1 小时前
Go 文件与 I/O 操作完全指南
开发语言·golang
上弦月-编程1 小时前
C语言链表详解,新手也能看懂! ——从入门到精通的完整教程
java·c语言·c++
szial2 小时前
uv 实战指南:用一个工具重塑 Python 开发工作流
开发语言·python·uv
拾光Ծ2 小时前
【Linux系统】进程信号(上)
linux·运维·服务器·面试·信号处理
ffqws_2 小时前
Spring Boot 配置读取全解析:从 application.yml 到 Java 对象的完整链路
java·数据库·spring boot
wjs20242 小时前
HTML 段落
开发语言