Files
interview/questions/design-patterns.md
yasinshaw fe2e6dc2f2 feat: add 50 backend interview questions and answers
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>
2026-03-01 00:09:50 +08:00

21 KiB
Raw Blame History

设计模式

问题

  1. 什么是设计模式?设计模式的六大原则是什么?
  2. 单例模式的实现方式有哪些?如何保证线程安全?
  3. 工厂模式和抽象工厂模式的区别是什么?
  4. 观察者模式的应用场景有哪些Spring 中哪些地方用到了观察者模式?
  5. 策略模式如何解决 if-else 过多的问题?
  6. 装饰器模式和代理模式的区别是什么?
  7. 在实际项目中如何使用设计模式?

标准答案

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 中的设计模式

  1. 工厂模式BeanFactoryApplicationContext
  2. 单例模式Spring Bean默认单例
  3. 代理模式AOP、事务管理
  4. 观察者模式ApplicationEvent、ApplicationListener
  5. 策略模式Resource(不同资源加载策略)
  6. 模板方法模式JdbcTemplateRestTemplate
  7. 适配器模式HandlerAdapter
  8. 责任链模式Filter Chain、Interceptor Chain

8. 阿里 P7 加分项

深度理解

  • 理解设计模式的适用场景和权衡
  • 理解设计模式与重构的关系
  • 理解设计模式在开源框架中的应用

实战经验

  • 有使用设计模式重构代码的经验
  • 有设计模式误用的经验和教训
  • 能根据业务特点选择合适的设计模式

架构能力

  • 能设计可扩展、可维护的架构
  • 能识别代码中的坏味道并重构
  • 能在团队中推广设计模式最佳实践