第4章 面向对象与设计模式面试题:类、继承、多态、单例、工厂、观察者
本章聚焦 Python 面试中高频考察的 面向对象三大特性(封装、继承、多态)以及 经典设计模式(单例、工厂、观察者)。面试官常通过这些问题判断候选人的抽象能力、代码复用意识与系统设计思维。理解核心概念并掌握结构化回答框架,是拿到高分的的关键。
面试问答卡片
📌 面试问题:请解释 Python 中的继承和多态,并举例说明。
面试官考察点:是否理解继承的机制(MRO、super)、方法重写、多态的动态分发以及 Python 特有的鸭子类型。
回答框架:① 先定义继承与多态的概念 → ② 说明 Python 的多继承与 C3 线性化 → ③ 举例展示父类方法和子类重写 → ④ 解释多态如何通过同一接口调用不同实现(鸭子类型)→ ⑤ 总结应用场景(如框架基类)。
简短示例回答:“继承允许子类复用父类属性和方法,Python 通过 MRO 解决多继承冲突。多态意味着不同对象可以响应相同方法,Python 的鸭子类型使得只要对象有该方法即可调用。例如:Animal 父类定义 speak(),Dog 和 Cat 重写,循环中统一调用 speak()。” (98字)
可能追问:super() 的调用顺序?MRO 如何计算?钻石继承会出现哪些问题?
📌 面试问题:请实现一个线程安全的单例模式。
面试官考察点:是否掌握多线程下的竞态条件、锁的使用,以及 Python 中实现单例的多种方式(__new__、装饰器、模块导入)。
回答框架:① 说明单例模式意图:确保一个类只有一个实例 → ② 对比三种实现方式(模块天然单例、__new__ + 锁、装饰器 + 锁)→ ③ 重点给出线程安全的 __new__ 实现(加 threading.Lock)→ ④ 验证双重检查锁定(DCL)可提高性能。
简短示例回答:“使用 __new__ 加锁:_instance = None; _lock = threading.Lock(),在 __new__ 中先检查 _instance is None,若为真则加锁再次检查并创建实例,返回 _instance。模块导入方式则由 Python 解释器保证线程安全。” (99字)
可能追问:为什么需要双重检查?用 classmethod 或 metaclass 实现有何区别?
__new__ 实现;也不要用 @synchronized 这种 Java 思维,要强调 Python 的 threading.Lock。
📌 面试问题:请描述工厂模式在什么场景下使用,并给出一个简单实现。
面试官考察点:是否理解工厂模式解耦对象创建与使用的好处,能否区分简单工厂、工厂方法、抽象工厂。
回答框架:① 指出工厂模式适用于“创建对象逻辑复杂或需要根据条件动态选择类”的场景 → ② 对比直接 new 的弊端 → ③ 给出简单工厂的类图/代码 → ④ 延伸至工厂方法(将创建延迟到子类)→ ⑤ 总结:提高了代码扩展性和维护性。
简短示例回答:“假设有一个日志系统,需要根据配置创建 FileLogger 或 DatabaseLogger。简单工厂:定义一个 LoggerFactory.create(type) 方法,内部用 if-elif 返回相应实例。客户端只需调用工厂,无需知道具体类名,符合开闭原则。” (96字)
可能追问:简单工厂是否违反开闭原则?如何用工厂方法改进?抽象工厂与工厂方法的区别?
项目案例:电商订单通知系统(观察者模式实战)
| 项目名称 | OrderNotify - 订单状态事件驱动系统 |
| 业务背景 | 电商平台订单从“创建→支付→发货→完成”需同步通知库存、物流、短信/邮件等多个子系统,使用观察者模式实现松耦合。 |
| 规模指标 | 日均订单50万+,订阅者10+个(库存服务、物流接口、推送服务、用户通知等),事件峰值QPS 2000+。 |
| 技术栈 | Python 3.9 + Flask + Redis Pub/Sub + Celery(异步通知) + threading(本地观察者池) |
| 核心难点 | ① 观察者注册/注销的线程安全 ② 事件投递失败的重试与幂等 ③ 避免观察者之间相互阻塞(异步化) ④ 支持动态添加新观察者无需修改核心逻辑。 |
| 面试高频追问 | 观察者模式与发布-订阅模式的区别?项目中为什么没有直接用消息队列而自己实现?如何处理观察者异常不阻塞其他观察者?如果通知顺序有要求如何保证? |
| 可迁移回答话术 | “我在项目中采用观察者模式将订单状态变更作为事件,各子系统作为观察者订阅。主要用 Redis Pub/Sub 实现跨进程通知,本地则用线程池异步分发。这样新增通知渠道时只需添加观察者类并注册,符合开闭原则。同时通过异常隔离和重试队列保证可靠性。” (99字) |
本章核心记忆口诀:“继承多态看 MRO,单例加锁防竞争;工厂解耦创建事,观察者里存回调。” 面试时先亮框架,再带代码,最后讲场景,稳稳拿捏 OOP 与设计模式。