AI出题人给出的Java后端面经(十四)(日更)
链接双端链表
前一篇:AI出题人给出的Java后端面经(十三)(日更)
后一篇:null
目录
🔵 一、Java基础
答案:
🗃️ 二、持久化层(MySQL 8.0)
答案:
⚙️ 三、中间件
答案:
🧠 四、JVM
答案:
⚡ 五、Java并发
答案:
🌱 六、Spring框架(Spring Boot 3.x)
答案:
🤖 七、大模型与AI整合(选修部分)
答案:
📌 今日知识地图
🔵 一、Java基础
题目:函数式编程
Stream
操作中 .parallel()
引发线程安全问题,如何用 Collectors.toConcurrentMap
替代实现线程安全归约?给出代码示例。
答案:
Map<Integer, String> result = dataList.parallelStream().collect(Collectors.toConcurrentMap(User::getId, User::getName,(oldVal, newVal) -> oldVal // 解决key冲突));
🗃️ 二、持久化层(MySQL 8.0)
题目:
-
索引失效场景
解释WHERE status = 1 OR amount > 100
导致联合索引(status, amount)
失效的根本原因,给出两种优化方案 -
事务隔离实战
在REPEATABLE-READ
级别下,如何通过SELECT ... FOR UPDATE SKIP LOCKED
实现高并发库存扣减?对比悲观锁与乐观锁性能差异
答案:
题目1:索引失效优化
失效原因:OR条件导致索引无法同时使用
优化方案:
UNION分治:
SELECT * FROM orders WHERE status = 1 UNION ALL SELECT * FROM orders WHERE amount > 100 AND status != 1
生成列索引:
ALTER TABLE orders ADD COLUMN status_amount INT AS (IF(status=1 OR amount>100, 1, NULL)); CREATE INDEX idx_status_amount ON orders(status_amount);
题目2:高并发库存扣减
START TRANSACTION; SELECT stock FROM inventory WHERE product_id = 1001 FOR UPDATE SKIP LOCKED; -- 跳过被锁行 UPDATE inventory SET stock = stock - 1 WHERE product_id = 1001; COMMIT;
性能对比(QPS = 1000请求):
方案 平均耗时 死锁概率 悲观锁 35ms 0.1% 乐观锁 28ms 12%重试
⚙️ 三、中间件
a) Redis 6.2
题目:
设计分布式会话:如何用 Redis Hash
+ Redisson
实现会话续期和踢出登录功能?给出 Lua 脚本原子操作方案
b) Kafka 3.5
题目:
如何通过 ConsumerRebalanceListener
实现分区再平衡时的消费位移校准?解释 isolation.level=read_committed
防止脏读的底层机制
答案:
a) Redis会话管理
-- 续期Lua脚本 local key = KEYS[1] local newExpire = ARGV[1] if redis.call('EXISTS', key) == 1 thenredis.call('EXPIRE', key, newExpire)return 1 end return 0-- 踢出登录(Java代码) RMap<String, Session> sessionMap = redisson.getMap("sessions"); sessionMap.remove(sessionId); // 自动广播删除事件
b) Kafka位移校准
答案consumer.subscribe(topics, new ConsumerRebalanceListener() {public void onPartitionsRevoked(Collection<TopicPartition> partitions) {// 提交当前位移consumer.commitSync(); }public void onPartitionsAssigned(Collection<TopicPartition> partitions) {// 从DB加载历史位移long offset = loadOffsetFromDB(partitions);consumer.seek(partition, offset);} });
read_committed
防脏读:
只暴露已提交事务的消息
Broker通过
__transaction_state
内部Topic追踪事务状态
🧠 四、JVM
题目:
-
G1 调优实战
针对 16GB 堆内存的电商服务,如何设置-XX:MaxGCPauseMillis
和-XX:G1NewSizePercent
平衡吞吐量与延迟? -
内存泄漏排查
给出jmap
+MAT
分析ThreadLocal
未移除导致 OOM 的完整诊断流程
答案:
题目1:G1调优实战
# 16GB堆电商服务推荐配置: -XX:+UseG1GC -XX:MaxGCPauseMillis=200 # 目标暂停时间 -XX:G1NewSizePercent=30 # 新生代最小占比 -XX:G1MaxNewSizePercent=50 # 新生代最大占比 -XX:InitiatingHeapOccupancyPercent=45 # 并发回收阈值
平衡效果:
GC暂停 ≤ 200ms
吞吐量 > 95%
题目2:ThreadLocal泄漏排查
诊断流程:
jmap -dump:format=b,file=oom.hprof <pid>
MAT分析:
查找
ThreadLocal$Entry
对象查看GC Root路径→未移除的ThreadLocal引用
修复代码:
try {threadLocal.set(data);// ... } finally {threadLocal.remove(); // 必须清理 }
⚡ 五、Java并发
题目:
-
线程池陷阱
分析ThreadPoolExecutor
配置corePoolSize=10, maxPoolSize=100
时任务被拒绝执行的四种场景,给出饱和策略选型建议 -
锁优化
解释ReentrantReadWriteLock
锁降级的使用场景及代码实现,为何写锁降级读锁是安全的?
答案:
题目1:线程池陷阱
拒绝执行的四种场景:
工作线程数 ≥
corePoolSize
且队列满工作线程数 ≥
maxPoolSize
线程池处于
SHUTDOWN
状态任务抛出
RejectedExecutionException
饱和策略选型:
策略 适用场景 AbortPolicy
(默认)需快速失败 CallerRunsPolicy
避免任务丢失 DiscardOldestPolicy
允许丢弃旧任务 题目2:锁降级实现
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); rwl.writeLock().lock(); // 获取写锁 try {// 写操作...rwl.readLock().lock(); // 降级开始(在写锁内获取读锁) } finally {rwl.writeLock().unlock(); // 降级完成(写锁释放,仍持有读锁) }try {// 读操作(仍受读锁保护) } finally {rwl.readLock().unlock(); }
安全性:写锁释放前获取读锁,可防止其他写操作干扰
🌱 六、Spring框架(Spring Boot 3.x)
题目:
-
事务传播机制
当@Transactional(propagation = Propagation.REQUIRES_NEW)
嵌套调用时,如何通过TransactionSynchronizationManager
避免死锁? -
安全配置
设计Spring Security
的权限缓存方案:如何用RedisCacheManager
实现UserDetailsService
的权限信息10分钟刷新? -
云原生监控
集成Micrometer
+Prometheus
:如何通过@Timed
统计Controller方法的P99响应时间?
答案:
题目1:事务传播防死锁
答案:@Transactional(propagation = Propagation.REQUIRES_NEW) public void updateOrder(Order order) {// 检查事务状态if (TransactionSynchronizationManager.isActualTransactionActive()) {// 提交当前事务避免死锁TransactionAspectSupport.currentTransactionStatus().flush();}// 业务逻辑 }
题目2:权限缓存方案
@Bean public UserDetailsService userDetailsService() {return username -> {String cacheKey = "userDetails::" + username;return redisTemplate.opsForValue().get(cacheKey, () -> dbUserDetailsService.loadUserByUsername(username), 10, TimeUnit.MINUTES // 缓存10分钟);}; }
题目3:P99监控配置
@Configuration public class MetricsConfig {@Beanpublic TimedAspect timedAspect(MeterRegistry registry) {return new TimedAspect(registry);} }@RestController public class OrderController {@Timed(value = "order.query", percentiles = {0.5, 0.95, 0.99} // 统计P50/P95/P99)@GetMapping("/orders")public List<Order> query() { ... } }
PromQL检测慢查询:
histogram_quantile(0.99, sum(rate(order_query_seconds_bucket[5m])) by (le)) > 1
🤖 七、大模型与AI整合(选修部分)
题目:
-
限流容错设计
针对 OpenAI API 的429
错误,如何通过Resilience4j
的RateLimiter
+Retry
实现指数退避重试? -
向量检索落地
如何用Spring Data JPA
+pgvector
扩展实现商品语义搜索?给出@Query
调用<=>
余弦相似度算子的示例 -
提示工程安全
在@Service
层设计提示词过滤:如何通过OWASP ESAPI
防御大模型注入攻击?
答案:
题目1:限流容错设计
RateLimiter rateLimiter = RateLimiter.of("openai", RateLimiterConfig.custom().limitRefreshPeriod(Duration.ofSeconds(10)).limitForPeriod(5) // 10秒5次.timeoutDuration(Duration.ZERO) // 立即失败.build());Retry retry = Retry.of("openai", RetryConfig.custom().maxAttempts(3).intervalFunction(IntervalFunction.ofExponentialBackoff(500, 2)) // 指数退避.retryOnException(e -> ((OpenAIException)e).getCode() == 429).build());Supplier<Completion> supplier = () -> openAIService.complete(prompt); Completion result = Decorators.ofSupplier(supplier).withRetry(retry).withRateLimiter(rateLimiter).get();
题目2:向量检索实现
public interface ProductRepository extends JpaRepository<Product, Long> {@Query(value = "SELECT * FROM products ORDER BY embedding <=> :embedding LIMIT 10", nativeQuery = true)List<Product> findSimilarProducts(@Param("embedding") float[] embedding); }// 调用 float[] queryEmbedding = model.encode("防水运动鞋"); productRepository.findSimilarProducts(queryEmbedding);
题目3:提示词过滤
@Service public class PromptService {private static final Encoder esapiEncoder = ESAPI.encoder();public String sanitizePrompt(String input) {// 1. 过滤HTML/JSString safe = esapiEncoder.encodeForJavaScript(esapiEncoder.encodeForHTML(input));// 2. 移除敏感命令return safe.replaceAll("(?i)(delete|drop|system)", "");} }
📌 今日知识地图
模块 | 核心考点 |
---|---|
Java基础 | Stream线程安全 |
MySQL | 索引优化+高并发事务 |
Redis/Kafka | 会话管理+消费语义 |
JVM | G1调优+内存泄漏排查 |
并发 | 线程池+读写锁降级 |
Spring微服务 | 事务传播+安全缓存+监控埋点 |
大模型 | 限流设计+向量检索+安全防护 |