专业的编程技术博客社区

网站首页 > 博客文章 正文

Deepseek整理高级java开发面经,来看看是否是你需要的

baijin 2025-06-24 11:39:17 博客文章 2 ℃ 0 评论

Java高级开发工程师面试题详解答案

一、JVM相关

1. JVM内存结构及版本变化

答案:

JDK8内存结构:

1. 程序计数器:线程私有,记录执行位置

2. Java虚拟机栈:线程私有,存储栈帧

3. 本地方法栈:Native方法调用

4. 堆:所有对象实例和数组

5. 方法区(元空间):类信息、常量、静态变量(JDK8用本地内存实现)

JDK8 vs JDK7主要变化:

- 永久代(PermGen)被元空间(Metaspace)取代

- 字符串常量池移至堆中

- 方法区实现改为使用本地内存

JDK11+新增特性:

- ZGC/Shenandoah垃圾收集器

- 类数据共享(CDS)优化

- Epsilon无操作垃圾收集器

2. Full GC诊断与解决案例

答案:

诊断步骤:

1. 开启GC日志:-XX:+PrintGCDetails -XX:+PrintGCDateStamps

2. 使用jstat -gcutil监控实时GC情况

3. 内存溢出时生成dump文件:-XX:+
HeapDumpOnOutOfMemoryError

常见原因及解决方案:

案例:电商系统促销期间频繁Full GC

- 现象:每分钟2-3次Full GC,STW达3秒

- 分析:

a. MAT分析发现HashMap缓存未限制大小

b. 年轻代太小导致过早晋升(-Xmn调整)

c. 存在内存泄漏:未关闭的数据库连接

- 解决方案:

a. 引入Caffeine缓存替换HashMap

b. 调整新生代与老年代比例1:2

c. 添加连接池监控

效果:Full GC降为每天1次,STW<500ms


二、并发编程

3. ConcurrentHashMap优化

答案:

JDK8优化点:

1. 数据结构:数组+链表+红黑树

2. 锁粒度:从分段锁改为CAS+synchronized锁单个桶

3. size计算:基于CounterCell的分段计数

4. 扩容协助:多线程协同扩容


size()实现原理:

final long sumCount() {

CounterCell[] as = counterCells;

long sum = baseCount;

if (as != null) {

for (CounterCell a : as) {

if (a != null)

sum += a.value;

}

}

return sum;

}

通过baseCount+CounterCell数组的方式减少竞争,最终一致性而非绝对准确


4. 高并发秒杀系统设计

答案:

分层设计:

1. 接入层:

- 限流:Guava RateLimiter+分布式限流

- 防刷:IP/用户行为分析

2. 服务层:

- 缓存预热:Redis提前加载库存

- 库存扣减:Lua脚本保证原子性

- 队列削峰:RocketMQ异步下单

3. 数据层:

- 分库分表:按活动ID分片

- 乐观锁:update inventory set count=count-1 where id=? and count>=1

关键代码:

// Redis库存扣减Lua脚本

String script = "if redis.call('get', KEYS[1]) >= ARGV[1] then " +

"return redis.call('decrby', KEYS[1], ARGV[1]) " +

"else return -1 end"

三、分布式系统

5. CAP理论权衡案例

答案

支付系统(CP选择):

- 需求:资金数据必须强一致

- 实现:

a. 分布式事务(Seata)

b. 同步复制(Raft协议)

c. 牺牲可用性:事务期间拒绝服务

社交系统(AP选择):

- 需求:高可用比强一致更重要

- 实现:

a. 最终一致性(CQRS)

b. 冲突解决(时间戳/向量时钟)

c. 客户端合并策略

折中方案:

- 本地优先:客户端缓存+后台同步

- 可调一致性:Dynamo风格的N/R/W配置

6. 分布式事务最终一致性方案

答案:

可靠消息方案设计:

1. 本地事务表:

- 业务表与消息表同库,事务保证原子性

2. 定时任务:

- 扫描待发送消息

- 幂等投递(消息ID去重)

3. 补偿机制:

- 状态确认回调

- 死信队列处理

伪代码:

// 1. 业务处理与消息存储

@Transactional

public void createOrder(Order order) {

orderDao.insert(order);

messageDao.save(new Message("order_created", order.getId()));

}

// 2. 消息投递(定时任务)

List<Message> messages = messageDao.findPending();

messages.forEach(msg -> {

try {

mqProducer.send(msg);

messageDao.updateStatus(msg.id, "SENT");

} catch(Exception e) {

// 重试机制

}

});

四、框架原理

7. Spring Bean生命周期

答案:

完整生命周期:

1. 实例化:BeanDefinition→构造函数

2. 属性填充:@Autowired注入

3. Aware回调:BeanNameAware等

4. 初始化前:
BeanPostProcessor.postProcessBeforeInitialization

5. 初始化:@PostConstruct、InitializingBean

6. 初始化后:
BeanPostProcessor.postProcessAfterInitialization

7. 销毁:@PreDestroy、DisposableBean

性能优化扩展点:

1.
SmartInitializingSingleton:所有单例初始化完成后回调

2. ImportSelector:动态加载配置类

3. BeanFactoryPostProcessor:修改BeanDefinition

4. Scope("prototype"):避免无状态Bean的单例竞争

8. MyBatis插件实现分页

答案:

实现原理:

1. 拦截目标:StatementHandler.prepare

2. 改写SQL:根据方言添加LIMIT/OFFSET

3. 线程局部变量:PageHelper.startPage()

核心代码:

@Intercepts(@Signature(type=StatementHandler.class,

method="prepare",

args={Connection.class,Integer.class}))

public class PageInterceptor implements Interceptor {


@Override

public Object intercept(Invocation invocation) {

StatementHandler sh = (StatementHandler)invocation.getTarget();

BoundSql boundSql = sh.getBoundSql();


// 获取分页参数

Page page = PageHelper.getPage();

if(page != null) {

String newSql = boundSql.getSql() +

" LIMIT " + page.getStartRow() + "," + page.getPageSize();

resetSql(sh, boundSql, newSql);

}

return invocation.proceed();

}


private void resetSql(...){...}

}


五、系统设计

9. 分布式配置中心设计

答案:

架构设计:

1. 存储层:

- 多版本配置的KV存储(MySQL+本地缓存)

- 配置变更日志(用于回滚)

2. 服务层:

- 长轮询+增量推送

- 配置加密(APOLLO的Namespace设计)

3. 客户端:

- 多级缓存(内存→本地文件→远程)

- 熔断降级(本地缓存兜底)

高可用保障:

1. 数据同步:基于Raft协议的多副本

2. 灰度发布:按IP/应用分批推送

3. 性能优化:

- 配置分片(zookeeper节点设计)

- 批量拉取(HTTP/2多路复用)

10. 千万级用户分库分表方案

答案:

分片策略:

1. 基因法:user_id后N位作为分片键

- 优点:避免跨分片查询

- 实现:订单表包含user_id后缀


跨分片查询方案:

1. 全局索引表:

- 维护非分片键到分片位置的映射

- 如:通过手机号查user_id再路由

2. 广播表:

- 基础数据全分片冗余存储

3. 分布式查询:

- 合并各分片结果(MyCAT中间件)

典型配置:

# 分16库64表

sharding-column: user_id

algorithm-expression: ds_${user_id % 16}.t_order_${user_id % 64}

以上答案可根据实际项目经验补充具体案例数据。建议准备时:

1. 对每个知识点准备1-2个实战案例

2. 重要的源码片段能手写关键部分

3. 系统设计题多使用架构图辅助说明

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表