1. 反射和序列化如何破坏单例?怎么防?

readResolve 防序列化
class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}

    // 反序列化时被调用,返回已有实例(防止新对象)
    private Object readResolve() { return INSTANCE; }
}

🎯 面试要点

  • 能背出"枚举的三个防护点"(构造、序列化、反射)就是完整答案
  • 克隆(clone)也会绕过构造器——单例类不要实现 Cloneable

2. 面向对象设计六大原则(SOLID + 迪米特)?

  1. 单一职责(S):一个类只做一件事,变化只影响一处
  2. 开闭原则(O):对扩展开放、对修改关闭(核心原则)——用策略/模板/装饰器实现
  3. 里氏替换(L):子类必须能替换父类且行为不破坏(重写不能削弱父类能力)
  4. 接口隔离(I):接口小而专,别搞万能接口(对比:接口大而全违反)
  5. 依赖倒置(D):依赖抽象不依赖具体(高层不依赖低层,都依赖抽象)——IoC 的理论基础
  6. 迪米特法则:最少知道原则——只和朋友通信,降低耦合

🎯 面试要点

  • 必考组合:依赖倒置 ↔ Spring IoC;开闭 ↔ 策略/装饰器/工厂
  • 里氏替换举例:父类方法抛 1 个异常,子类不能抛更宽泛的(Java 重写规则就体现它)

3. 易混模式对比速查?

对比组 一句话区分
代理 vs 装饰器代理管"调不调/何时调"(控制访问);装饰器管"调的过程加什么"(增强功能)
适配器 vs 外观适配器转换接口(让不兼容变兼容);外观提供统一简化入口(隐藏复杂度)
策略 vs 状态策略:外部选算法,对象行为不自动变;状态:内部状态驱动行为自动迁移
策略 vs 模板方法策略整体算法互换(组合);模板方法固定骨架细节可改(继承)
工厂方法 vs 抽象工厂工厂方法:一个工厂生产一种产品;抽象工厂:一个工厂生产一族产品
责任链 vs 装饰器责任链横向传递(请求依次经过);装饰器纵向包裹(调用嵌套)

🎯 面试要点

  • 对比题的答题公式:"相同点(结构相似)+ 不同点(意图/控制权)+ 各自场景"

4. 场景设计题:该用哪个模式?

场景 推荐模式
多支付方式(微信/支付宝/银联)策略 + 工厂 + 注册表
下单后发短信/通知/记账观察者(事件驱动),异步化
日志框架切换实现外观 + 适配器(slf4j 门面)
请求校验链(登录→权限→限流→业务)责任链(可中断)
订单状态流转(待支付→已支付…)状态模式 + 状态机表
DB 操作统一模板(连接/事务/异常)模板方法(JdbcTemplate)
对象创建开销大且频繁复用享元(池化)

🎯 面试要点

  • 场景题答题套路:识别"变化点" → 选择隔离变化的原则 → 给出模式结构 → 说明收益(解耦/扩展)

🎤 常见面试追问

  1. SOLID 原则具体指什么?(背下来)——单一职责(一个类一件事)、开闭(对扩展开放对修改关闭)、里氏替换(子类可替换父类)、接口隔离(接口小而专)、依赖倒置(依赖抽象不依赖具体)。
  2. 场景题答题套路?——识别变化点 → 选隔离变化的原则/模式 → 给结构 → 说收益。如"多支付方式":策略 + 工厂 + 注册表;"下单后通知多个系统":观察者。
  3. 什么时候不该用设计模式?——简单场景(2 个分支的 if)用模式是过度设计;模式增加类和间接层,可读性下降——"简单代码最宝贵"。
  4. 枚举单例为什么是最优解?——JVM 保证枚举实例唯一(构造器天然私有且受保护),反射 newInstance 对枚举抛异常,序列化由 JVM 特殊处理返回同一实例——三个破坏点全免疫。
  5. 代码里怎么发现"该用模式了"的信号?——if-else 越来越多(策略)、到处 new 同类对象(工厂)、重复的样板代码(模板方法)、一个变化要改很多地方(开闭被违反)。

📖 名词解释(本页术语)

术语 大白话解释
SOLID面向对象五大设计原则的缩写:单一职责/开闭/里氏替换/接口隔离/依赖倒置。
开闭原则(OCP)对扩展开放、对修改关闭:加新功能靠"加代码"不靠"改旧代码"——模式设计的核心目标。
依赖倒置(DIP)高层不依赖低层,都依赖抽象——IoC 的理论基础(Spring 就是为它而生)。
里氏替换(LSP)子类必须能替换父类且不破坏行为(重写不能削弱能力)——Java 重写规则体现它。
迪米特法则最少知道原则:只和"朋友"通信,降低耦合。
过度设计为不存在的需求引入复杂抽象——模式的滥用,比不用更糟。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。