Generated comprehensive interview preparation materials covering: - Distributed systems (transactions, locks, ID generation, consistency) - Database (indexing, sharding, replication, transactions) - Caching (Redis, cache problems, distributed lock) - Message queues (RocketMQ, Kafka) - Concurrency (ThreadLocal, ConcurrentHashMap, thread pools) - JVM (GC, memory, tuning) - System design (seckill, short URL, IM, feed, LBS) - Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel) - Network (TCP/IP, HTTP/HTTPS) - Security (encryption, SQL injection, XSS) - Performance tuning - Design patterns - Microservices (Spring Boot, Gateway, Service Mesh) - Container orchestration (Kubernetes, Docker) - CI/CD, observability Each file includes: - Detailed questions - Comprehensive answers - Code examples - Real project experience - Alibaba P7 level requirements Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
21 KiB
21 KiB
设计模式
问题
- 什么是设计模式?设计模式的六大原则是什么?
- 单例模式的实现方式有哪些?如何保证线程安全?
- 工厂模式和抽象工厂模式的区别是什么?
- 观察者模式的应用场景有哪些?Spring 中哪些地方用到了观察者模式?
- 策略模式如何解决 if-else 过多的问题?
- 装饰器模式和代理模式的区别是什么?
- 在实际项目中如何使用设计模式?
标准答案
1. 设计模式的六大原则(SOLID + 1)
单一职责原则(Single Responsibility Principle)
定义:一个类只负责一个职责。
示例:
// ❌ 违反单一职责
class UserService {
public void saveUser(User user) { }
public void sendEmail(User user) { }
public void log(User user) { }
}
// ✅ 符合单一职责
class UserService {
public void saveUser(User user) { }
}
class EmailService {
public void sendEmail(User user) { }
}
class LogService {
public void log(User user) { }
}
开闭原则(Open-Closed Principle)
定义:对扩展开放,对修改关闭。
示例:
// ❌ 每次新增类型需要修改代码
class OrderService {
public double calculateDiscount(String type, double price) {
if (type.equals("VIP")) {
return price * 0.8;
} else if (type.equals("SVIP")) {
return price * 0.7;
}
// 新增类型需要修改这里
return price;
}
}
// ✅ 使用策略模式
interface DiscountStrategy {
double calculate(double price);
}
class VipDiscount implements DiscountStrategy {
@Override
public double calculate(double price) {
return price * 0.8;
}
}
class OrderService {
private Map<String, DiscountStrategy> strategyMap = new HashMap<>();
public void registerStrategy(String type, DiscountStrategy strategy) {
strategyMap.put(type, strategy);
}
public double calculateDiscount(String type, double price) {
DiscountStrategy strategy = strategyMap.get(type);
return strategy != null ? strategy.calculate(price) : price;
}
}
里氏替换原则(Liskov Substitution Principle)
定义:子类可以替换父类出现在父类能够出现的任何地方。
示例:
// ❌ 违反里氏替换
class Bird {
public void fly() {
System.out.println("Flying");
}
}
class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("企鹅不会飞");
}
}
// ✅ 符合里氏替换
class Bird { }
class FlyingBird extends Bird {
public void fly() {
System.out.println("Flying");
}
}
class Penguin extends Bird {
public void swim() {
System.out.println("Swimming");
}
}
接口隔离原则(Interface Segregation Principle)
定义:客户端不应该依赖它不需要的接口。
示例:
// ❌ 接口过于臃肿
interface Animal {
void fly();
void swim();
void run();
}
// ✅ 拆分接口
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
interface Runnable {
void run();
}
class Duck implements Flyable, Swimmable, Runnable {
@Override
public void fly() { }
@Override
public void swim() { }
@Override
public void run() { }
}
依赖倒置原则(Dependency Inversion Principle)
定义:高层模块不应该依赖低层模块,两者都应该依赖抽象。
示例:
// ❌ 高层依赖低层
class OrderService {
private MySQLDatabase database = new MySQLDatabase(); // 直接依赖具体实现
public void saveOrder(Order order) {
database.save(order);
}
}
// ✅ 依赖抽象
interface Database {
void save(Object obj);
}
class MySQLDatabase implements Database {
@Override
public void save(Object obj) {
// MySQL 实现
}
}
class OrderService {
private final Database database;
public OrderService(Database database) {
this.database = database; // 依赖注入
}
public void saveOrder(Order order) {
database.save(order);
}
}
迪米特法则(Law of Demeter / Least Knowledge Principle)
定义:一个对象应该对其他对象有最少的了解。
示例:
// ❌ 违反迪米特法则
class Customer {
private Order order;
public void printOrderDetails() {
System.out.println(order.getItem().getProduct().getName());
// Customer → Order → Item → Product(了解太多)
}
}
// ✅ 符合迪米特法则
class Customer {
private Order order;
public void printOrderDetails() {
System.out.println(order.getProductName());
}
}
class Order {
private Item item;
public String getProductName() {
return item.getProduct().getName();
}
}
2. 单例模式
实现方式
方式 1:饿汉式(线程安全)
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}
优点:简单、线程安全 缺点:类加载时初始化,可能浪费资源
方式 2:懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
问题:线程不安全
方式 3:懒汉式 + synchronized(线程安全但性能差)
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
问题:每次调用都需要加锁,性能差
方式 4:双重检查锁定(推荐)
public class Singleton {
// volatile 禁止指令重排序
private static volatile Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) { // 第一次检查(无锁)
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查(有锁)
instance = new Singleton();
}
}
}
return instance;
}
}
为什么需要 volatile?
instance = new Singleton();
// 分三步:
// 1. 分配内存
// 2. 初始化对象
// 3. 将 instance 指向内存
// 指令重排序后可能是:1 → 3 → 2
// 线程 A 执行了 1、3,线程 B 发现 instance 不为 null,但对象未初始化!
方式 5:静态内部类(推荐)
public class Singleton {
private Singleton() { }
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
优点:
- 延迟加载(调用 getInstance 时才初始化)
- 线程安全(类加载机制保证)
- 性能好(无锁)
方式 6:枚举(最佳实践)
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
// 使用
Singleton.INSTANCE.doSomething();
优点:
- 线程安全(JVM 保证)
- 防止反射攻击
- 防止序列化破坏
单例模式的问题
1. 反射破坏单例:
Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
Singleton instance1 = constructor.newInstance();
Singleton instance2 = constructor.newInstance();
// instance1 != instance2(单例被破坏)
解决:
private Singleton() {
if (Holder.INSTANCE != null) {
throw new RuntimeException("不允许创建多个实例");
}
}
2. 序列化破坏单例:
Singleton instance1 = Singleton.getInstance();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(instance1);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray())
);
Singleton instance2 = (Singleton) ois.readObject();
// instance1 != instance2(单例被破坏)
解决:
public class Singleton implements Serializable {
private Singleton() { }
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
// 反序列化时返回单例
private Object readResolve() {
return Holder.INSTANCE;
}
}
3. 工厂模式
简单工厂
// 产品接口
interface Payment {
void pay(int amount);
}
// 具体产品
class Alipay implements Payment {
@Override
public void pay(int amount) {
System.out.println("支付宝支付:" + amount);
}
}
class WechatPay implements Payment {
@Override
public void pay(int amount) {
System.out.println("微信支付:" + amount);
}
}
// 工厂类
class PaymentFactory {
public static Payment createPayment(String type) {
switch (type) {
case "alipay":
return new Alipay();
case "wechat":
return new WechatPay();
default:
throw new IllegalArgumentException("不支持支付方式");
}
}
}
// 使用
Payment payment = PaymentFactory.createPayment("alipay");
payment.pay(100);
问题:新增支付方式需要修改工厂类(违反开闭原则)
工厂方法
// 工厂接口
interface PaymentFactory {
Payment createPayment();
}
// 具体工厂
class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
}
class WechatPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new WechatPay();
}
}
// 使用
PaymentFactory factory = new AlipayFactory();
Payment payment = factory.createPayment();
payment.pay(100);
优点:符合开闭原则(新增支付方式无需修改代码)
抽象工厂
场景:跨平台 UI 工具包
// 抽象产品
interface Button {
void render();
}
interface Checkbox {
void render();
}
// 具体产品(Windows 风格)
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Windows 按钮");
}
}
class WindowsCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("Windows 复选框");
}
}
// 具体产品(Mac 风格)
class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac 按钮");
}
}
class MacCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("Mac 复选框");
}
}
// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// 使用
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();
button.render();
checkbox.render();
4. 观察者模式
原理
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都得到通知并自动更新。
Java 实现
// 观察者接口
interface Observer {
void update(String message);
}
// 被观察者(主题)
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// 具体主题
class MessageQueue implements Subject {
private List<Observer> observers = new ArrayList<>();
private String message;
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message);
}
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
}
// 具体观察者
class EmailNotifier implements Observer {
@Override
public void update(String message) {
System.out.println("发送邮件:" + message);
}
}
class SMSNotifier implements Observer {
@Override
public void update(String message) {
System.out.println("发送短信:" + message);
}
}
// 使用
MessageQueue queue = new MessageQueue();
queue.attach(new EmailNotifier());
queue.attach(new SMSNotifier());
queue.setMessage("新订单创建");
Spring 事件机制(观察者模式)
// 1. 定义事件
class OrderCreatedEvent extends ApplicationEvent {
private final Order order;
public OrderCreatedEvent(Object source, Order order) {
super(source);
this.order = order;
}
public Order getOrder() {
return order;
}
}
// 2. 定义监听器
@Component
class OrderEmailListener {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
System.out.println("发送邮件:" + event.getOrder());
}
}
@Component
class OrderSMSListener {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
System.out.println("发送短信:" + event.getOrder());
}
}
// 3. 发布事件
@Service
class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createOrder(Order order) {
// 保存订单
orderRepository.save(order);
// 发布事件
eventPublisher.publishEvent(new OrderCreatedEvent(this, order));
}
}
5. 策略模式
场景:计算不同类型的折扣
// 策略接口
interface DiscountStrategy {
double calculate(double price);
}
// 具体策略
class VipDiscount implements DiscountStrategy {
@Override
public double calculate(double price) {
return price * 0.8;
}
}
class SvipDiscount implements DiscountStrategy {
@Override
public double calculate(double price) {
return price * 0.7;
}
}
class NormalDiscount implements DiscountStrategy {
@Override
public double calculate(double price) {
return price;
}
}
// 上下文
class OrderService {
private Map<String, DiscountStrategy> strategyMap = new HashMap<>();
@PostConstruct
public void init() {
strategyMap.put("VIP", new VipDiscount());
strategyMap.put("SVIP", new SvipDiscount());
strategyMap.put("NORMAL", new NormalDiscount());
}
public double calculatePrice(String userType, double price) {
DiscountStrategy strategy = strategyMap.get(userType);
if (strategy == null) {
throw new IllegalArgumentException("不支持的用户类型");
}
return strategy.calculate(price);
}
}
// 使用
OrderService orderService = new OrderService();
double price = orderService.calculatePrice("VIP", 100);
Spring 实现策略模式
// 策略接口
public interface PaymentStrategy {
void pay(int amount);
// 获取策略类型
String getType();
}
// 具体策略(标注为 Spring Bean)
@Component
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("支付宝支付:" + amount);
}
@Override
public String getType() {
return "alipay";
}
}
@Component
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("微信支付:" + amount);
}
@Override
public String getType() {
return "wechat";
}
}
// 策略工厂
@Service
public class PaymentService {
private final Map<String, PaymentStrategy> strategyMap;
// 构造器注入所有策略
public PaymentService(List<PaymentStrategy> strategies) {
this.strategyMap = strategies.stream()
.collect(Collectors.toMap(
PaymentStrategy::getType,
Function.identity()
));
}
public void pay(String type, int amount) {
PaymentStrategy strategy = strategyMap.get(type);
if (strategy == null) {
throw new IllegalArgumentException("不支持的支付方式");
}
strategy.pay(amount);
}
}
6. 装饰器模式 vs 代理模式
装饰器模式
目的:动态地给对象添加功能
示例:
// 组件接口
interface Coffee {
double cost();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 10;
}
}
// 装饰器
class MilkDecorator implements Coffee {
private final Coffee coffee;
public MilkDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public double cost() {
return coffee.cost() + 2; // 加奶 2 元
}
}
class SugarDecorator implements Coffee {
private final Coffee coffee;
public SugarDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public double cost() {
return coffee.cost() + 1; // 加糖 1 元
}
}
// 使用
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee); // 加奶
coffee = new SugarDecorator(coffee); // 加糖
System.out.println(coffee.cost()); // 10 + 2 + 1 = 13
代理模式
目的:控制对对象的访问
静态代理:
// 接口
interface OrderService {
void createOrder(Order order);
}
// 真实对象
class OrderServiceImpl implements OrderService {
@Override
public void createOrder(Order order) {
System.out.println("创建订单:" + order);
}
}
// 代理对象
class OrderServiceProxy implements OrderService {
private final OrderService orderService;
public OrderServiceProxy(OrderService orderService) {
this.orderService = orderService;
}
@Override
public void createOrder(Order order) {
// 前置增强
System.out.println("权限检查");
// 调用真实对象
orderService.createOrder(order);
// 后置增强
System.out.println("日志记录");
}
}
// 使用
OrderService proxy = new OrderServiceProxy(new OrderServiceImpl());
proxy.createOrder(new Order());
动态代理(JDK):
class ProxyHandler implements InvocationHandler {
private final Object target;
public ProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("权限检查");
// 调用真实对象
Object result = method.invoke(target, args);
// 后置增强
System.out.println("日志记录");
return result;
}
}
// 使用
OrderService realService = new OrderServiceImpl();
OrderService proxyService = (OrderService) Proxy.newProxyInstance(
realService.getClass().getClassLoader(),
realService.getClass().getInterfaces(),
new ProxyHandler(realService)
);
proxyService.createOrder(new Order());
对比
| 特性 | 装饰器模式 | 代理模式 |
|---|---|---|
| 目的 | 增强功能 | 控制访问 |
| 关注点 | 功能扩展 | 访问控制 |
| 透明性 | 对客户端透明 | 客户端可能知道代理存在 |
| 示例 | Java I/O Streams | Spring AOP |
7. 实际项目应用
Spring 中的设计模式
- 工厂模式:
BeanFactory、ApplicationContext - 单例模式:Spring Bean(默认单例)
- 代理模式:AOP、事务管理
- 观察者模式:ApplicationEvent、ApplicationListener
- 策略模式:
Resource(不同资源加载策略) - 模板方法模式:
JdbcTemplate、RestTemplate - 适配器模式:
HandlerAdapter - 责任链模式:Filter Chain、Interceptor Chain
8. 阿里 P7 加分项
深度理解:
- 理解设计模式的适用场景和权衡
- 理解设计模式与重构的关系
- 理解设计模式在开源框架中的应用
实战经验:
- 有使用设计模式重构代码的经验
- 有设计模式误用的经验和教训
- 能根据业务特点选择合适的设计模式
架构能力:
- 能设计可扩展、可维护的架构
- 能识别代码中的坏味道并重构
- 能在团队中推广设计模式最佳实践