创建型模式高频

共 18 题
#

1. 单例模式五种实现(饿汉/懒汉/双检锁/静态内部类/枚举)的线程安全性对比?反射与反序列化如何破坏单例、如何防御?

A 双检锁需要 volatile 但可省略,不省略也正确
B 枚举实现天然线程安全、防反射与反序列化 ✓ 正确答案
C 饿汉模式是懒加载,首次调用才创建
D 反序列化不会破坏单例
#

2. 简单工厂、工厂方法、抽象工厂的本质区别与演进关系?各自违反/满足开闭原则的边界?

A 三种工厂都完全满足开闭原则
B 工厂方法新增产品需修改已有工厂类
C 抽象工厂新增产品族需修改已有工厂接口
D 简单工厂新增产品需修改工厂判断,违反开闭原则 ✓ 正确答案
#

3. 原型模式与深/浅拷贝中 Cloneable 的坑与序列化深拷贝的取舍?

A 默认 clone() 是深拷贝,自动复制所有内部对象
B 浅拷贝只复制引用,新旧对象共享内部可变对象 ✓ 正确答案
C 序列化深拷贝性能好,适合所有类型
D 原型模式通过 new 创建新对象
#

4. 项目中你用过哪些创建型模式?结合框架举例,Spring 的 BeanFactory/ApplicationContext 工厂、默认单例 Bean、原型 Bean、Builder 构建配置对象

A Spring 所有 Bean 都是原型作用域
B Spring 容器是工厂,默认 Bean 是单例,prototype 每次新建 ✓ 正确答案
C Builder 用于构建只能继承的类
D FactoryBean 用于创建单例但无法自定义
#

5. Prototype 模式深拷贝的工程难题中循环引用的检测与处理(visited map)、不可变对象的安全共享、序列化/反序列化实现 clone 的性能代价与替代方案(copy constructor)

A copy constructor 必须通过序列化实现
B 不可变对象必须深拷贝,不能共享引用
C 序列化深拷贝性能最好,适合所有类型
D 循环引用需用 visited map 记录已拷贝对象,避免无限递归 ✓ 正确答案
#

6. Builder vs Abstract Factory 的选型标准中产品族一致性用 Abstract Factory、复杂对象分步构建用 Builder、两者组合使用(Director 持有 Abstract Factory)的场景

A Abstract Factory 保证产品族一致性,Builder 负责复杂对象分步构建 ✓ 正确答案
B Builder 用于创建一组相关产品
C Abstract Factory 用于分步构建单个复杂对象
D 两者不可组合使用
#

7. 对象池模式与单例、工厂的关系中池化能降低高频对象的分配开销,池的回收与泄漏检测如何设计?

A 对象池复用对象,降低高频创建与 GC 开销,但需重置与防泄漏 ✓ 正确答案
B 对象池与单例相同,只保留一个实例
C 对象归还无需重置状态
D 池化不会减少对象分配次数
#

8. 建造者模式与重叠构造器、JavaBeans 模式的对比中什么参数规模下引入 Builder 才划算?

A 参数越少越应该用 Builder
B 重叠构造器适合参数极多的场景,可读性好
C JavaBeans 模式生成的对象是完整的不可变对象
D 参数多且可选参数多、需要不可变对象时,用 Builder 才划算 ✓ 正确答案
#

9. 依赖注入(DI)对工厂模式的替代中 Spring/Guice 的 IoC 容器如何消除手动工厂代码、何时仍需显式工厂(运行时动态类型、跨进程创建)、DI 框架的隐式依赖与测试困难

A DI 容器消除手动工厂,但运行时动态类型仍需显式工厂 ✓ 正确答案
B DI 完全替代所有工厂,无需显式创建
C DI 依赖是显式可见的,无隐式问题
D DI 让测试无需 mock 依赖
#

10. Java 枚举单例的优势与边界中天然防反射与序列化攻击、不能继承的局限、带状态的枚举单例(如线程安全的计数器)实现、与 Kotlin object 声明的对比

A 枚举单例可以被反射创建新实例
B 枚举单例天然防反射与序列化攻击,但无法继承 ✓ 正确答案
C 枚举单例支持懒加载
D Kotlin object 与 Java 枚举在反序列化上完全相同
#

11. 创建型模式的目标是解耦创建与使用中简单工厂仍违反开闭原则,工厂方法如何把变化点延迟到子类?

A 简单工厂新增产品需修改 switch,违反开闭原则 ✓ 正确答案
B 工厂方法的创建逻辑固定写在父类,无法扩展
C 简单工厂对扩展开放,对修改关闭
D 工厂方法把变化点延迟到父类
#

12. 单例模式在框架中的实现中 Spring 默认单例 Bean 的线程安全性,为什么“有状态单例”是隐患,如何用 ThreadLocal/无状态化解?

A 单例 Bean 并发安全的前提是无状态,有状态单例是隐患 ✓ 正确答案
B 单例 Bean 天然线程安全,与状态无关
C 有状态单例用 ThreadLocal 反而更不安全
D 所有 Bean 都必须是单例
#

13. 建造者模式与不可变对象的配合中为什么 Builder 常用于构建不可变 DTO/配置对象,与 Lombok @Builder 的实现差异?

A Builder 常用于构建不可变 DTO/配置对象,构造清晰且对象不可变 ✓ 正确答案
B Lombok @Builder 完全等同手写 Builder,无任何差异
C 不可变对象必须用 setter 修改
D DTO 对象应该是可变的,便于各处修改
#

14. 工厂的注册表实现中 JDBC DriverManager 与 Spring FactoryBean 如何用注册表按标识创建对象,与简单工厂的差异

A 注册表工厂与简单工厂完全相同
B 简单工厂用注册表 Map 查找,扩展无需修改
C DriverManager 用 if/switch 判断驱动类型
D 注册表工厂用 Map 按标识查找创建,扩展时注册新项即可,符合开闭 ✓ 正确答案
#

15. 原型模式在什么场景比 Builder/工厂更合适(对象初始化成本高、属性差异小),原型池的并发安全如何保证?

A 原型池无需并发保护,clone 一定安全
B 原型模式每创建一次都重新走完整初始化流程
C 对象初始化成本高且属性差异小时,原型模式复制比重新初始化更高效 ✓ 正确答案
D 原型对象可变也没关系,clone 后共享状态
#

16. 抽象工厂在跨平台 UI/主题系统中的实践中新增产品族时如何违反开闭原则,与工厂方法的组合使用?

A 抽象工厂只能创建单个产品
B 新增产品族必须修改已有工厂接口
C 新增产品族加工厂类满足开闭,但新增同族产品需改接口违反开闭 ✓ 正确答案
D 跨平台 UI 中新增平台需要修改所有既有工厂
#

17. ServiceLoader/SPI 中如何用 Java 的 ServiceLoader 实现可插拔工厂,与反射直接 newInstance 的取舍

A 反射 newInstance 无需知道类名,天然可插拔
B ServiceLoader 从配置文件加载实现,实现可插拔扩展,无需改代码 ✓ 正确答案
C SPI 只能加载一个实现,无法扩展
D ServiceLoader 与反射 newInstance 完全没有区别
#

18. 对象作用域管理中 Spring 的 prototype/request/session scope 如何影响创建时机与线程安全,与默认单例的差异

A 所有 scope 的线程安全保证完全相同
B 单例 Bean 每次 getBean 都返回新实例
C request scope 的实例在应用启动时创建并永久存活
D prototype 每次获取创建新实例,适合有状态对象;单例共享实例需无状态 ✓ 正确答案