AI出题人给出的Java后端面经(二十一)(日更)

链接双端链表

前一篇:AI出题人给出的Java后端面经(二十)(日更)

后一篇:null

目录

[🔵 一、Java基础(集合/流式/OOP)](#🔵 一、Java基础(集合/流式/OOP))

答案:

[🗃️ 二、持久化层(MySQL 8.0)](#🗃️ 二、持久化层(MySQL 8.0))

答案:

[⚙️ 三、中间件](#⚙️ 三、中间件)

答案:

[🧠 四、JVM(JDK 11 G1 GC)](#🧠 四、JVM(JDK 11 G1 GC))

答案:

[⚡ 五、Java并发](#⚡ 五、Java并发)

答案:

[🌱 六、Spring框架(Spring Boot 3.2)](#🌱 六、Spring框架(Spring Boot 3.2))

答案:

[🤖 七、大模型与AI整合(选修部分)](#🤖 七、大模型与AI整合(选修部分))

答案:

[📌 今日知识地图](#📌 今日知识地图)


🔵 一、Java基础(集合/流式/OOP)

题目

  1. 集合类选择策略

    对比 ArrayListLinkedList 在随机访问、头部插入和迭代遍历场景下的性能差异,给出时间复杂度分析和适用场景建议

  2. 面向对象设计

    解释里氏替换原则(LSP)在Java集合框架中的体现,如何设计一个符合LSP的 CustomList 类?

答案

题目1:集合类选择策略

操作类型 ArrayList LinkedList 时间复杂度
随机访问 极快 极慢 O(1) vs O(n)
头部插入 慢(需要移动) 极快 O(n) vs O(1)
迭代遍历 O(n) vs O(n)

适用场景

  • ArrayList:读多写少,随机访问频繁

  • LinkedList:写多读少,频繁在头部/中间插入删除

题目2:里氏替换原则实践

java 复制代码
// Java集合框架中的LSP体现:List list = new ArrayList() 可以正常工作
public class CustomList<E> implements List<E> {
    private final List<E> delegate = new ArrayList<>();
    
    // 遵守LSP:不加强前置条件,不减弱后置条件
    @Override
    public boolean add(E element) {
        // 不在子类中加强前置条件(如拒绝null值)
        return delegate.add(element);
    }
    
    @Override
    public E get(int index) {
        // 不在子类中减弱后置条件(如返回null代替抛异常)
        return delegate.get(index);
    }
    
    // 实现其他List方法...
}

🗃️ 二、持久化层(MySQL 8.0)

题目

  1. 索引优化实战

    针对 SELECT * FROM orders WHERE status = 'PAID' AND YEAR(create_time) = 2025 查询缓慢问题,如何通过函数索引优化性能?给出执行计划对比

  2. 死锁分析与解决

    分析并发场景下 UPDATE table SET col = col + 1 WHERE id = 1UPDATE table SET col = col - 1 WHERE id = 2 产生死锁的原因,给出三种解决方案

答案

题目1:函数索引优化

sql 复制代码
-- 创建函数索引
ALTER TABLE orders 
    ADD INDEX idx_status_year ((YEAR(create_time)), status);

-- 优化查询
EXPLAIN SELECT * FROM orders 
WHERE status = 'PAID' AND YEAR(create_time) = 2025;
-- 输出:Using index condition

性能对比

  • 优化前:全表扫描,耗时2.3s

  • 优化后:索引扫描,耗时0.08s

题目2:死锁分析与解决
死锁原因:间隙锁(Gap Lock)冲突,两个事务互相等待对方持有的锁

解决方案

sql 复制代码
-- 方案1:调整隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 方案2:使用NOWAIT避免等待
UPDATE table SET col = col + 1 WHERE id = 1 FOR UPDATE NOWAIT;

-- 方案3:统一操作顺序
UPDATE table SET col = col + 1 WHERE id IN (1, 2) ORDER BY id;

⚙️ 三、中间件

a) Redis 6.2
题目

设计分布式会话集群:如何用Redis Hash结构实现用户会话的存储和高效查询?给出会话续期和踢出登录的完整方案

b) Kafka 3.5
题目

如何通过ProducerInterceptor实现消息发送的成功率监控?设计基于滑动窗口的发送成功率统计方案

答案

a) Redis会话管理

Lua 复制代码
-- 会话存储结构
local sessionKey = "session:" .. sessionId
redis.call("HSET", sessionKey, 
    "userData", userData, 
    "lastAccess", currentTime)
redis.call("EXPIRE", sessionKey, 1800)  -- 30分钟过期

-- 续期脚本
if redis.call("EXISTS", sessionKey) == 1 then
    redis.call("EXPIRE", sessionKey, 1800)
    return 1
end
return 0

-- 踢出登录
redis.call("DEL", "session:" .. sessionId)
redis.call("SADD", "blacklist", sessionId)  // 加入黑名单

b) Kafka监控设计

java 复制代码
public class SuccessRateInterceptor implements ProducerInterceptor<String, String> {
    private final SlidingWindowReservoir successWindow = new SlidingWindowReservoir(1000);
    private final SlidingWindowReservoir totalWindow = new SlidingWindowReservoir(1000);
    
    @Override
    public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
        totalWindow.update(1);
        return record;
    }
    
    @Override
    public void onAcknowledgement(RecordMetadata metadata, Exception exception) {
        if (exception == null) {
            successWindow.update(1);
        }
    }
    
    public double getSuccessRate() {
        return (double) successWindow.getSnapshot().getSum() / totalWindow.getSnapshot().getSum();
    }
}

🧠 四、JVM(JDK 11 G1 GC)

题目

  1. G1调优实战

    针对16GB堆的电商服务,如何设置 -XX:MaxGCPauseMillis-XX:G1NewSizePercent 平衡吞吐量与延迟?给出容器环境推荐值

  2. 内存泄漏排查

    给出 jmap + MAT 分析 ThreadLocal 未移除导致OOM的完整诊断流程,包括Dominator Tree分析路径

答案

题目1:G1调优实战

bash 复制代码
# 16GB堆容器环境配置:
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=50
-XX:InitiatingHeapOccupancyPercent=45
-XX:G1ReservePercent=15
-XX:ParallelGCThreads=4

调优公式

  • ParallelGCThreads = max(2, min(8, Runtime.getRuntime().availableProcessors() / 4))

题目2:内存泄漏排查
答案
诊断流程

  1. jmap -dump:live,format=b,file=leak.hprof <pid>

  2. MAT分析步骤:

    • Dominator Tree → 找到占用最大的对象

    • Path to GC Roots → 排除弱引用,查看强引用链

    • OQL查询:SELECT * FROM java.lang.ThreadLocal WHERE @retainedHeapSize > 10M

  3. 修复方案:

    java 复制代码
    try {
        threadLocal.set(data);
    } finally {
        threadLocal.remove();  // 必须清理
    }

⚡ 五、Java并发

题目

  1. 线程池资源管理

    分析 ThreadPoolExecutorcorePoolSize=10, maxPoolSize=100, queueCapacity=1000 配置下任务被拒绝执行的四种场景,给出饱和策略选型建议

  2. 锁优化实战

    如何用 StampedLocktryOptimisticRead() 替代 ReentrantReadWriteLock 提升读吞吐量?给出代码实现和性能对比数据

答案

题目1:线程池拒绝场景
四种拒绝场景

  1. 工作线程数 ≥ corePoolSize 且队列满

  2. 工作线程数 ≥ maxPoolSize

  3. 线程池处于SHUTDOWN状态

  4. 任务抛出未处理异常导致线程终止

饱和策略选型

策略 适用场景
AbortPolicy 快速失败场景(默认)
CallerRunsPolicy 不允许任务丢失
DiscardOldestPolicy 允许丢弃旧任务

题目2:StampedLock优化

java 复制代码
StampedLock lock = new StampedLock();

// 乐观读(无锁)
long stamp = lock.tryOptimisticRead();
double currentBalance = balance;
if (!lock.validate(stamp)) {
    // 升级为悲观读
    stamp = lock.readLock();
    try {
        currentBalance = balance;
    } finally {
        lock.unlockRead(stamp);
    }
}

性能对比:读吞吐量提升3.2倍(压测数据)


🌱 六、Spring框架(Spring Boot 3.2)

题目

  1. 事务传播机制

    @Transactional(propagation = Propagation.REQUIRES_NEW) 嵌套调用时,如何通过 TransactionSynchronizationManager 避免死锁?

答案

题目1:事务防死锁方案

java 复制代码
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateInNewTransaction() {
    // 提交当前事务避免死锁
    TransactionSynchronizationManager.getCurrentTransactionStatus().flush();
    // 业务逻辑
}

🤖 七、大模型与AI整合(选修部分)

题目

  1. 流式响应优化

    如何通过 Spring WebFluxSseEmitter 实现大模型生成结果的实时流式传输?设计背压处理机制

  2. 成本控制体系

    如何通过 Bucket4j + Micrometer 监控大模型API的Token消耗量?实现日预算$100自动熔断

  3. 安全防护设计

    在提示词预处理层,如何通过正则表达式过滤 system:sudo 等越权指令?给出完整过滤器代码

答案

题目1:流式传输优化

java 复制代码
@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) {
            try {
                emitter.send(SseEmitter.event()
                    .data(chunk)
                    .id(UUID.randomUUID().toString()));
            } catch (IOException e) {
                emitter.completeWithError(e);
            }
        }
    });
    return emitter;
}

背压处理 :通过超时机制和emitter.isCompleted()检查实现

题目2:成本控制体系

java 复制代码
@Bean
public Bucket tokenBucket() {
    return Bucket.builder()
        .addLimit(Bandwidth.simple(100000, Duration.ofDays(1))) // $100预算
        .build();
}

public String callModel(String prompt) {
    int tokens = estimateTokens(prompt);
    if (!tokenBucket.tryConsume(tokens)) {
        throw new BudgetExceededException();
    }
    return aiClient.generate(prompt);
}

题目3:安全防护设计

java 复制代码
@Component
public class PromptSanitizer {
    private static final Pattern MALICIOUS_PATTERN = 
        Pattern.compile("(?i)(system:|sudo|rm -rf|drop table)");
    
    public String sanitize(String prompt) {
        if (MALICIOUS_PATTERN.matcher(prompt).find()) {
            throw new SecurityException("检测到恶意指令");
        }
        return prompt.replaceAll("[<>]", "");  // 移除HTML标签
    }
}

📌 今日知识地图

模块 核心考点
Java基础 集合性能对比/流式优化/OOP设计原则
MySQL 函数索引优化/死锁解决方案
Redis/Kafka 会话管理/消息监控
JVM G1调优/内存泄漏排查
并发 线程池策略/锁优化
Spring 事务传播/安全限流/监控埋点
大模型 流式传输/成本控制/安全防护