Java高级面试题
Spring框架
1. Spring循环依赖
问题:Spring如何解决循环依赖问题?三级缓存的作用是什么?
分析要点:
-
循环依赖场景
@Service public class A { @Autowired private B b; } @Service public class B { @Autowired private A a; } -
三级缓存的作用
- singletonObjects:一级缓存,存放完全初始化好的bean
- earlySingletonObjects:二级缓存,存放原始的bean对象
- singletonFactories:三级缓存,存放bean的工厂对象
-
解决流程
// Spring创建Bean的关键代码 protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 先从一级缓存查找 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 从二级缓存查找 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 从三级缓存查找 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } return singletonObject; }
2. Spring事务
问题:Spring事务的传播行为和隔离级别有哪些?如何处理分布式事务?
分析要点:
-
事务传播行为
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 如果当前没有事务,就新建一个事务 // 如果已经存在一个事务,就加入到这个事务中 } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { // 无论是否存在事务,都会新建事务 } -
分布式事务解决方案
- 2PC/3PC协议
- TCC补偿机制
- 可靠消息最终一致性
- SAGA模式
微服务架构
1. 服务治理
问题:在微服务架构中,如何实现服务的优雅降级和熔断?设计一个动态线程池方案。
实现思路:
-
熔断器实现
public class CustomCircuitBreaker { private final int failureThreshold; private final long resetTimeout; private int failureCount; private long lastFailureTime; private State state; public enum State { CLOSED, OPEN, HALF_OPEN } public CustomCircuitBreaker(int failureThreshold, long resetTimeout) { this.failureThreshold = failureThreshold; this.resetTimeout = resetTimeout; this.state = State.CLOSED; } public synchronized boolean allowRequest() { if (state == State.OPEN) { if (System.currentTimeMillis() - lastFailureTime >= resetTimeout) { state = State.HALF_OPEN; return true; } return false; } return true; } public synchronized void recordSuccess() { failureCount = 0; state = State.CLOSED; } public synchronized void recordFailure() { failureCount++; lastFailureTime = System.currentTimeMillis(); if (failureCount >= failureThreshold) { state = State.OPEN; } } } -
动态线程池方案
public class DynamicThreadPool { private ThreadPoolExecutor executor; private final int minPoolSize; private final int maxPoolSize; private final LoadMonitor loadMonitor; public DynamicThreadPool(int minPoolSize, int maxPoolSize) { this.minPoolSize = minPoolSize; this.maxPoolSize = maxPoolSize; this.executor = new ThreadPoolExecutor( minPoolSize, minPoolSize, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000) ); this.loadMonitor = new LoadMonitor(); startMonitoring(); } private void startMonitoring() { new Thread(() -> { while (true) { int currentLoad = loadMonitor.getCurrentLoad(); adjustPoolSize(currentLoad); try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }).start(); } private void adjustPoolSize(int load) { int currentPoolSize = executor.getCorePoolSize(); if (load > 80 && currentPoolSize < maxPoolSize) { executor.setCorePoolSize(currentPoolSize + 1); } else if (load < 30 && currentPoolSize > minPoolSize) { executor.setCorePoolSize(currentPoolSize - 1); } } }
2. 分布式缓存
问题:如何设计一个大规模分布式缓存系统?需要考虑哪些技术难点?
设计要点:
-
缓存架构
- 多级缓存策略
- 一致性Hash分片
- 主从复制机制
-
关键问题解决
public class ConsistentHash<T> { private final int numberOfReplicas; // 虚拟节点数量 private final SortedMap<Integer, T> circle = new TreeMap<>(); public ConsistentHash(int numberOfReplicas, Collection<T> nodes) { this.numberOfReplicas = numberOfReplicas; for (T node : nodes) { add(node); } } public void add(T node) { for (int i = 0; i < numberOfReplicas; i++) { circle.put(hash(node.toString() + i), node); } } public void remove(T node) { for (int i = 0; i < numberOfReplicas; i++) { circle.remove(hash(node.toString() + i)); } } public T get(Object key) { if (circle.isEmpty()) { return null; } int hash = hash(key.toString()); if (!circle.containsKey(hash)) { SortedMap<Integer, T> tailMap = circle.tailMap(hash); hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey(); } return circle.get(hash); } private int hash(String key) { return MurmurHash.hash32(key); } }
性能优化
1. JVM调优实战
问题:一个Spring Boot应用在生产环境频繁发生Full GC,如何进行问题诊断和优化?
解决方案:
-
问题诊断
# 收集GC日志 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log # 使用JMX监控 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -
优化措施
- 内存分配优化
- 垃圾收集器选择
- 代码层面优化
2. 数据库优化
问题:如何优化一个慢SQL查询?设计一个分库分表方案。
优化思路:
-
SQL优化
-- 优化前 SELECT * FROM orders o LEFT JOIN users u ON o.user_id = u.id WHERE o.create_time >= '2023-01-01' -- 优化后 SELECT o.id, o.order_no, u.name FROM orders o FORCE INDEX(idx_create_time) INNER JOIN users u ON o.user_id = u.id WHERE o.create_time >= '2023-01-01' -
分库分表设计
public class ShardingStrategy { private final int dbCount; // 库数量 private final int tableCount; // 表数量 public ShardingStrategy(int dbCount, int tableCount) { this.dbCount = dbCount; this.tableCount = tableCount; } public int getDbIndex(String shardingKey) { long hash = MurmurHash.hash64(shardingKey); return (int) (hash % dbCount); } public int getTableIndex(String shardingKey) { long hash = MurmurHash.hash64(shardingKey); return (int) ((hash / dbCount) % tableCount); } }
面试重点
- Spring框架核心原理
- 微服务架构设计
- 分布式系统问题处理
- 性能优化最佳实践
- 高并发系统设计
- 分布式事务解决方案
- 缓存架构设计
- 数据库优化技术
- 服务治理策略
- 线程池动态调优