2026-7-16-cnblog
准备面式:
- 看Java八股文;
- 看简历上写的内容,要能够说的出来;
- 看职位要求的内容;
static关键字:静态变量,和类挂钩,和实例无关。
final关键字:定义的常量,或者类不能再被继承。
深拷贝和浅拷贝:浅拷贝实现Cloneable 接口,重写clone方法,会返回一个当前类的新对象,但是对象中的引用数据类型是复制引用;深拷贝会递归调用引用数据类型的clone方法,每次new一个对象,递归边界是到达基础数据类型(包括String)。
泛型
-
类型安全:编译时校验集合元素类型,避免运行时类型转换异常;
-
省去强制类型转换,代码更简洁;
-
提高代码复用性,一套模板适用于多种引用类型;
-
泛型是编译期语法糖,运行时发生类型擦除。
编译:编译器根据泛型约束做类型校验
class 字节码中,
<T>会被擦除- 无边界
<T>→ 擦除为Object - 有边界
<T extends Number>→ 擦除为Number
- 无边界
PECS:producter extend customer super,前者只能读,后者只能写。
对象:可以通过5种方法得到
- new关键字;
- 使用反射,用Class.forName(全类名);
- 使用克隆;
- 使用反序列化得到对象,需要实现Serializable接口;
- 工厂模式,比如ValueOf,封装了创建逻辑;
垃圾回收机制GC
开始有引用计数法,如果被引用一次,那么计数加1,否则计数-1,如果是0,那么就回收,但是无法解决循环引用。a->b,b->a,a=null,b=null。
可达性分析算法HotSpot JVM:会有很多GC Roots,只要GC Roots无法通过链到达的对象,那么就回收。
反射
动态获取信息以及调用对象的方法的功能称为Java语言的反射机制。
反射常用地方:
- 加载数据库驱动,可以使用Class.forName,注册不同的驱动;
- 用在配置类,Spring IOC容器管理正是用到这个机制;
反射,动态代理,AOP,Spring IOC,DI
动态代理就是在反射基础上实现的,可以做到方法增强,实现无侵入扩展功能:日志、事务、权限校验、耗时统计,这正是 AOP 的底层。
public class MyHandler implements InvocationHandler {
private Object target; // 真实目标对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("方法执行前");
// 反射调用目标方法
Object res = method.invoke(target, args);
// 后置增强
System.out.println("方法执行后");
return res;
}
}
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new MyHandler(target)
);
AOP 面向切面:横向抽取通用重复代码(日志、事务、异常处理),解耦业务与通用功能
核心专业术语
切面 Aspect:封装通用逻辑的类(@Aspect)
通知 Advice:切面里的增强逻辑,5 种类型
- @Before 前置:方法执行前
- @AfterReturning 正常返回后
- @AfterThrowing 异常抛出时
- @After 最终通知(无论成功失败都执行)
- @Around 环绕通知(包裹目标方法,最强)
切入点 Pointcut:匹配哪些类 / 方法需要拦截(execution 表达式)
连接点 JoinPoint:满足切入点的每一个方法(可拿到方法参数、类名)
目标对象 Target:被代理的原始业务 Bean
代理对象 Proxy:动态生成的代理对象
织入 Weaving:把切面逻辑嵌入目标对象的过程(Spring 运行时织入)
典型应用场景
- 统一日志记录
- 声明式事务 @Transactional(Spring 事务底层 AOP)
- 接口权限校验
- 接口耗时监控、统一异常处理
IOC:反向管理,把对象交给Spring来管理;
DI:依赖注入;
注解:注解介绍
异常
Object类:Object方法解析
Java8特性,Java21特性
序列化
设计模式
策略模式和责任链模式
策略模式定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。从而让算法可独立于使用它的客户而变化。
假设你正在开发一个电商网站的支付模块。用户可以选择支付宝、微信支付或者银行卡支付。每种支付方式的底层逻辑(比如调用的API、加密方式、参数构造)都完全不同,但对于调用支付功能的上层业务逻辑来说,它只需要调用一个统一的“支付”方法即可,无需关心具体是哪种支付。
这就是策略模式的用武之地。我们把每种支付方式(支付宝、微信)都封装成一个独立的“策略”类,它们都遵循一个共同的接口。上层业务代码通过这个共同的接口来调用支付功能,并可以在运行时根据用户的选择,动态地切换不同的策略。
所以,策略模式适用场景如下:
- 当一个系统需要动态地在几种算法中选择一种时。
- 当一个对象有很多行为,不想使用大量的
if-else或switch-case语句来选择时。 - 当你希望算法的变化不会影响到使用它的客户端时。
责任链模式
// 抽象处理者
abstract class Handler {
protected Handler next;
// 设置下一个处理节点
public void setNext(Handler next) {
this.next = next;
}
// 抽象处理方法
public abstract boolean handle(Request request);
}
然后每个校验逻辑都继承这个类,比如登录校验:
// 登录态校验节点
class LoginHandler extends Handler {
@Override
public boolean handle(Request request) {
if (request.isLogin()) {
System.out.println("登录态校验通过,交给下一个节点");
// 校验通过,交给下一个处理者
return next != null ? next.handle(request) : true;
} else {
System.out.println("未登录,直接返回失败");
// 校验不通过,终止链路
return false;
}
}
}
再写个权限校验节点、频率限制节点,最后在使用的时候,根据接口需求动态组装链路:
// 组装链路:登录校验 -> 权限校验 -> 频率限制
Handler loginHandler = new LoginHandler();
Handler authHandler = new AuthHandler();
Handler rateLimitHandler = new RateLimitHandler();
loginHandler.setNext(authHandler);
authHandler.setNext(rateLimitHandler);
// 发起请求
Request request = new Request(true, "admin", 1); // 已登录、管理员权限、第1次请求
boolean result = loginHandler.handle(request);

浙公网安备 33010602011771号