一、Java基础核心考点
1.1 数据类型与内存分配
Java中8种基本数据类型(byte/short/int/long/float/double/char/boolean)的存储空间差异显著:int占4字节,long占8字节,boolean类型在JVM中可能用1位或1字节实现。引用类型存储在堆内存,栈中保存对象地址。典型面试题:
Integer a = 127;Integer b = 127;System.out.println(a == b); // true(缓存机制)Integer c = 128;Integer d = 128;System.out.println(c == d); // false(超出缓存范围)
此现象源于IntegerCache机制,自动装箱时对-128~127的值进行缓存复用。
1.2 面向对象三大特性
封装性通过private修饰符实现,如:
public class Account {private double balance;public void deposit(double amount) {if(amount > 0) balance += amount;}}
继承需注意方法重写规则:子类方法访问权限不能比父类更严格。多态实现依赖动态绑定机制,编译时类型检查与运行时对象实际类型决定调用方法。
二、JVM体系深度解析
2.1 内存模型与GC机制
JVM内存划分为:
- 堆:对象实例存储区,新生代(Eden:Survivor=8
1)和老年代 - 方法区:存储类元数据,JDK8后移至元空间(直接内存)
- 栈:方法调用帧,每个线程私有
GC算法对比:
| 算法 | 优点 | 缺点 |
|——————|———————————-|—————————————-|
| 标记清除 | 实现简单 | 产生内存碎片 |
| 复制算法 | 无碎片,效率高 | 空间利用率低(50%) |
| 标记整理 | 无碎片,适合老年代 | 移动对象开销大 |
2.2 类加载机制
双亲委派模型工作流程:
- 检查类是否已加载
- 父加载器委托检查
- 父加载器无法加载时自行加载
破坏双亲委派的典型场景:SPI机制中JDBC驱动加载,通过线程上下文类加载器实现。
三、并发编程实战要点
3.1 线程安全实现方案
同步方式对比:
// synchronized锁方法public synchronized void update() {...}// ReentrantLock示例Lock lock = new ReentrantLock();lock.lock();try {// 临界区代码} finally {lock.unlock();}
CAS操作实现原子更新:
AtomicInteger counter = new AtomicInteger(0);counter.incrementAndGet(); // 原子操作
3.2 线程池配置艺术
核心参数配置公式:
核心线程数 = (IO密集型? 2*CPU核心数 : CPU核心数+1)最大线程数 = 核心线程数 * (1 + 阻塞系数)
典型配置示例:
ExecutorService executor = new ThreadPoolExecutor(5, // 核心线程数20, // 最大线程数60, // 空闲线程存活时间TimeUnit.SECONDS,new LinkedBlockingQueue<>(1000), // 任务队列new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略);
四、Spring生态高频考点
4.1 IoC容器初始化流程
- 资源定位:通过ResourceLoader定位配置文件
- 载入解析:BeanDefinitionReader解析XML/注解
- 注册到容器:BeanDefinitionRegistry注册Bean定义
- 依赖注入:通过AutowiredAnnotationBeanPostProcessor处理注解
4.2 AOP实现原理
JDK动态代理示例:
public class LoggingProxy implements InvocationHandler {private Object target;public Object bind(Object target) {this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) {System.out.println("Before method: " + method.getName());return method.invoke(target, args);}}
五、分布式系统设计题解
5.1 分布式锁实现方案
Redis实现示例:
public boolean tryLock(String key, String value, long expire) {Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, expire, TimeUnit.SECONDS);return Boolean.TRUE.equals(success);}public void unlock(String key, String value) {String current = redisTemplate.opsForValue().get(key);if(value.equals(current)) {redisTemplate.delete(key);}}
需注意锁续期和误删问题,可采用Redisson的WatchDog机制。
5.2 分布式事务解决方案
TCC模式实现示例:
public interface OrderService {// 尝试阶段boolean tryOrder(Order order);// 确认阶段boolean confirmOrder(String orderId);// 取消阶段boolean cancelOrder(String orderId);}
六、面试策略与避坑指南
- 项目经验阐述:采用STAR法则(Situation-Task-Action-Result)
- 算法题解题思路:先明确边界条件,再考虑时间复杂度
- 薪资谈判技巧:提前调研市场水平,给出合理区间
- 避坑提醒:
- 慎用”绝对”类表述
- 遇到不会的问题可请求思路提示
- 注意代码规范(命名、缩进、异常处理)
建议开发者建立知识图谱,将零散知识点系统化。可通过LeetCode刷题提升算法能力,阅读《Effective Java》深化设计理念,参与开源项目积累实战经验。面试前针对目标企业技术栈做专项准备,如金融行业侧重高并发、分布式事务,互联网企业关注中间件使用和性能优化。