AI出题人给出的Java后端面经(十七)(日更)
文章摘要 本文系统梳理了Java后端开发的核心技术要点,涵盖七大模块:1)Java基础聚焦Record序列化性能优化;2)MySQL提出虚拟列+函数索引20倍性能提升方案;3)中间件详解Redis会话迁移与Kafka延迟监控实现;4)JVM给出32GB堆G1调优参数与元空间泄漏排查方案;5)并发编程分析线程池OOM场景及CompletableFuture结构化编排;6)SpringCloud实现动
链接双端链表
目录
🔵 一、Java基础(Java 17)
题目:
-
Record类序列化陷阱
当Jackson序列化Record类时,为何会出现JsonMappingException: No serializer found for record错误?给出三种解决方案并对比性能
答案:
// 解决方案1:注册ParameterNamesModule(性能最优) ObjectMapper mapper = new ObjectMapper() .registerModule(new ParameterNamesModule()); // 解决方案2:添加@JsonProperty注解(兼容性好) public record User(@JsonProperty("id") int id, @JsonProperty("name") String name) {} // 解决方案3:自定义序列化器(灵活控制) mapper.registerModule(new SimpleModule() .addSerializer(User.class, new RecordSerializer()));性能对比(万次序列化):
方案 耗时 ParameterNamesModule 42ms @JsonProperty 48ms 自定义序列化器 65ms
🗃️ 二、持久化层(MySQL 8.0)
题目:
-
索引优化实战
针对SELECT * FROM orders WHERE YEAR(create_time)=2025 AND status='PAID'全表扫描问题,如何通过虚拟列+函数索引实现性能提升20倍? -
死锁自动处理
如何配置innodb_deadlock_detect和innodb_lock_wait_timeout实现死锁自动回退?给出金融系统的推荐参数值
答案:
题目1:索引优化实战
-- 1. 创建虚拟列 ALTER TABLE orders ADD COLUMN create_year YEAR AS (YEAR(create_time)) VIRTUAL; -- 2. 创建联合索引 CREATE INDEX idx_status_year ON orders(status, create_year); -- 3. 优化查询 SELECT * FROM orders WHERE status='PAID' AND create_year=2025;性能提升:
执行时间从 1.8s → 0.09s(提升20倍)
Extra:
Using index condition题目2:死锁自动处理
# my.cnf金融系统推荐配置 innodb_deadlock_detect = ON # 开启死锁检测 innodb_lock_wait_timeout = 20 # 超时20秒回退(支付系统) innodb_print_all_deadlocks = ON # 记录死锁日志 监控命令:SHOW ENGINE INNODB STATUS; # 查看死锁详情
⚙️ 三、中间件
a) Redis 6.2
题目:
设计分布式会话集群:如何用 Redis Hash + Redisson 实现会话无缝迁移?给出集群扩容时的数据迁移方案
b) Kafka 3.5
题目:
如何通过 ProducerInterceptor 实现消息发送的 P99延迟监控?设计滑动窗口统计并暴露Prometheus指标
答案:
a) Redis会话迁移
// 1. 会话存储结构 RMap<String, SessionData> sessionMap = redisson.getMap("sessions"); // 2. 集群扩容迁移方案 Map<String, SessionData> sessions = sessionMap.readAllMap(); redisNewCluster.getMap("sessions").putAll(sessions); // 3. 客户端重定向(双写过渡期) sessionMap.addListener(new MapPutListener() { public void onPut(String key) { redisNewCluster.getMap("sessions").fastPut(key, sessionMap.get(key)); } });b) Kafka延迟监控
public class LatencyInterceptor implements ProducerInterceptor<String, String> { private final SlidingWindowReservoir reservoir = new SlidingWindowReservoir(1000); // 滑动窗口 @Override public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) { record.headers().add("start-ts", String.valueOf(System.currentTimeMillis()).getBytes()); return record; } @Override public void onAcknowledgement(RecordMetadata metadata, Exception e) { long duration = System.currentTimeMillis() - Long.parseLong(new String(metadata.headers().lastHeader("start-ts").value())); reservoir.update(duration); // 暴露Prometheus指标 Metrics.gauge("kafka.producer.latency.p99", reservoir.getSnapshot().get99thPercentile()); } }
🧠 四、JVM(JDK 11 G1 GC)
题目:
-
G1调优实战
针对32GB堆的订单系统,如何设置-XX:G1HeapRegionSize和-XX:MaxGCPauseMillis平衡吞吐量(>92%)与延迟(<200ms)? -
元空间泄漏急救
给出MetaspaceOOM时快速定位类加载器泄漏的jcmd命令组合及MAT分析路径。
答案:
题目1:G1调优实战
# 32GB堆订单系统配置: -XX:+UseG1GC -XX:G1HeapRegionSize=16M # 匹配大对象 -XX:MaxGCPauseMillis=200 # 目标暂停时间 -XX:InitiatingHeapOccupancyPercent=40 # 提前标记 -XX:G1ReservePercent=15 # 预留空间防晋升失败 -XX:ParallelGCThreads=8 # 并行线程数效果验证:
Young GC: 120-180ms
Mixed GC: <200ms
吞吐量: 93.7%
题目2:元空间泄漏急救
# 1. 查看类加载器统计 jcmd <pid> VM.classloader_stats -verbose # 2. 定位未卸载代理类 jcmd <pid> GC.class_histogram | grep 'Proxy\|Generated' # 3. MAT分析路径 OQL: select * from java.lang.ClassLoader where objects(Class) > 100
⚡ 五、Java并发(Java 8)
题目:
-
线程池资源耗尽
分析ThreadPoolExecutor在queueCapacity=Integer.MAX_VALUE时导致OOM的四种场景,给出饱和策略最优选型 -
CompletableFuture陷阱
当使用thenApplyAsync()链式调用时,如何避免 回调地狱?给出结构化编排方案。
答案:
题目1:线程池OOM预防
四种OOM场景:
任务队列无限堆积
线程泄漏(未回收异常线程)
任务对象持有大内存
最大线程数设置过高
饱和策略选型:
new ThreadPoolExecutor( 10, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), // 限制队列 new ThreadPoolExecutor.CallerRunsPolicy() // 调用者执行防OOM );题目2:CompletableFuture陷阱
// 结构化编排方案 CompletableFuture.supplyAsync(() -> fetchOrder()) .thenApplyAsync(order -> enrichOrder(order)) .thenCombineAsync(fetchUser(), (order, user) -> attachUser(order, user)) .exceptionally(ex -> fallbackOrder()) // 统一异常处理 .thenAccept(this::saveOrder);优势:
链式调用替代嵌套回调
统一异常处理
清晰的数据流传递
🌱 六、Spring Cloud微服务
题目:
-
网关动态路由
如何通过Spring Cloud Gateway+Nacos实现实时路由更新?设计灰度发布的权重分流方案 -
零信任安全架构
设计OAuth2.1资源服务器:如何用JwtAuthenticationConverter将scope声明转换为GrantedAuthority? -
配置热更新失效
当@RefreshScope无法刷新@Value时,如何通过ContextRefresher实现批量热更新?
答案:
题目1:网关动态路由
# Nacos配置 dataId: gateway-routes [ { "id": "product-service", "predicates": ["Path=/product/**"], "filters": ["GrayFilter=30"] # 30%流量 "uri": "lb://product-service-v2" } ]@Bean public RouteLocator dynamicRouteLocator(RouteLocatorBuilder builder, NacosConfigManager config) { return builder.routes() .route(r -> r.path("/order/**") .uri(config.getConfig("gateway.routes.order-service")) .build(); }题目2:安全权限转换
@Bean public JwtAuthenticationConverter jwtConverter() { JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter(); converter.setAuthorityPrefix("ROLE_"); converter.setAuthoritiesClaimName("scope"); // 解析scope字段 return jwt -> new JwtAuthenticationToken( jwt, converter.convert(jwt), jwt.getSubject()); }题目3:配置热更新
@Autowired private ContextRefresher refresher; @PostMapping("/refresh") public void refreshConfig() { // 批量刷新所有@RefreshScope Bean refresher.refresh(); // 强制更新@Value Environment env = applicationContext.getEnvironment(); ((ConfigurableEnvironment) env).getPropertySources().addFirst( new MapPropertySource("manual-refresh", Collections.singletonMap("app.threshold", 100)) ); }
🤖 七、大模型与AI整合(选)
题目:
-
流式响应优化
如何用Spring WebFlux的SseEmitter实现大模型生成结果的实时流式传输?设计背压处理机制 -
语义缓存设计
基于Caffeine+Redis实现大模型响应的语义相似度缓存,给出Sentence-BERT的相似度计算方案 -
成本熔断系统
如何通过Bucket4j+Micrometer监控Token消耗量?实现日预算$100自动熔断
答案:
题目1:流式响应优化
@GetMapping("/ai/stream") public SseEmitter streamResponse(@RequestParam String prompt) { SseEmitter emitter = new SseEmitter(60_000L); aiClient.generateStream(prompt, new ResponseHandler() { @Override public void onChunk(String chunk) { emitter.send(chunk); // 流式发送 } @Override public void onComplete() { emitter.complete(); } }); return emitter; }背压处理:
通过
SseEmitter超时(60s)断开慢客户端使用
EmitterProcessor实现响应式背压题目2:语义缓存设计
public class SemanticCache { private final Cache<String, String> localCache = Caffeine.newBuilder() .maximumSize(10_000) .build(); private final RedisTemplate<String, String> redisTemplate; public String getCachedResponse(String prompt) { return localCache.get(prompt, p -> { String cached = redisTemplate.opsForValue().get(p); if (cached != null) return cached; String response = aiClient.generate(p); redisTemplate.opsForValue().set(p, response, 1, TimeUnit.HOURS); return response; }); } // 语义相似度计算 private boolean isSimilar(String text1, String text2) { float[] emb1 = sentenceBERT.encode(text1); float[] emb2 = sentenceBERT.encode(text2); return cosineSimilarity(emb1, emb2) > 0.92; } }题目3:成本熔断系统
// 1. Token计量器 Counter tokenCounter = Metrics.counter("openai.token.cost"); // 2. 预算熔断器 CircuitBreaker circuitBreaker = CircuitBreaker.of("openai", CircuitBreakerConfig.custom() .failureRateThreshold(80) // 80%失败熔断 .waitDurationInOpenState(Duration.ofMinutes(30)) .build()); // 3. 调用封装 String response = circuitBreaker.executeSupplier(() -> { int tokens = estimateTokens(prompt); if (tokenCounter.count() + tokens > 100_000) { // $100预算 throw new BudgetExceededException(); } tokenCounter.increment(tokens); return aiClient.generate(prompt); });
📌 今日知识地图
| 模块 | 核心考点 |
|---|---|
| Java基础 | Record序列化+并发集合原理 |
| MySQL | 函数索引优化+死锁自动处理 |
| Redis/Kafka | 会话迁移+P99延迟监控 |
| JVM | G1容器调优+元空间急救 |
| 并发 | 线程池OOM预防+异步编排 |
| Spring Cloud | 动态路由+安全转换+配置热更 |
| 大模型 | 流式传输+语义缓存+成本控制 |
更多推荐

所有评论(0)