面向对象与设计模式:封装继承多态、接口抽象类、单例工厂策略

本章聚焦 C# 服务端面试中面向对象与设计模式的核心考点。理解三大特性、接口抽象类的区别以及经典设计模式,是构建高内聚低耦合系统的基础。以下结构化内容帮你快速形成清晰回答路径,避免概念混淆。

面向对象与设计模式回答框架 听题定位 概念解释 代码对比 优缺点/场景 追问:变种/反例 追问:性能代价 追问:替代方案 遵循此框架:先定位 → 再解释 → 代码佐证 → 总结场景 → 准备追问

面试问题

请解释面向对象三大特性——封装、继承、多态,并说明它们在 C# 中的实现方式。

面试官考察点

  • 是否理解三大特性的本质与区别
  • 能否用 C# 语法(如访问修饰符、sealed、virtual/override 等)具体说明
  • 是否知道何时使用继承 vs 多态

回答框架

  1. 总述:封装隐藏细节、继承复用代码、多态统一接口
  2. 封装:通过 private/public/protected 控制访问,属性 get/set 封装字段
  3. 继承:单一继承 + 接口多实现,sealed 阻止继承
  4. 多态:编译时重载(overload)与运行时重写(override + virtual/abstract)
  5. 举例:基类 Animal,派生类 Dog/Cat,重写 Speak()

简短示例回答

“封装通过 private 字段 + 公开属性实现数据保护;继承让子类复用基类代码,C# 只允许单继承;多态分编译时(方法重载)和运行时(virtual/override)。例如 Animal 基类定义 virtual void Speak(),Dog 和 Cat 各自重写,调用时根据实际类型执行对应版本。”

可能追问

  • new 关键字在继承中的作用是什么?
  • sealed 和 static class 的区别?
  • 多态在性能上有哪些影响?
避坑提醒:不要回答“封装就是 get/set”,要强调信息隐藏和接口稳定。继承容易滥用,面试中主动提到“优先组合而非继承”会加分。

面试问题

接口(interface)和抽象类(abstract class)有什么区别?C# 8 之后接口有哪些新特性?

面试官考察点

  • 是否清楚语法层面和行为层面的核心差异
  • 能否结合实际场景给出选择依据
  • 是否关注语言版本演进

回答框架

  1. 定义:接口定义契约(不能有字段),抽象类可包含实现
  2. 关键差异:多继承(接口可多实现)、访问修饰符(抽象类成员可带访问控制)
  3. 选择规则:定义能力 / 行为用接口;定义公共基类逻辑用抽象类
  4. C# 8+:接口允许默认实现、私有方法、静态成员

简短示例回答

“接口只声明行为,如 IDisposable;抽象类可提供默认实现,如 DbConnection 基类。C# 8 后接口可添加 default 方法,解决了接口版本兼容问题。实践中,需要多合同继承时选接口,需要共享状态或逻辑时选抽象类。”

可能追问

  • 接口的默认实现如何处理钻石问题?
  • 抽象类中的构造函数可以做什么?
  • 什么时候应该把接口拆分为多个小接口(接口隔离)?
加分策略:主动提及“显式接口实现”和“接口的协变/逆变”可展示深度。

面试问题

请对比单例模式、工厂模式、策略模式,分别说明它们在 C# 中的典型实现与适用场景。

面试官考察点

  • 是否能清晰区分三种模式的核心目的
  • 是否写过线程安全的单例等真实代码
  • 能否结合服务端实际场景(如依赖注入、配置策略)说明

回答框架

  1. 单例:确保全局唯一实例,关注线程安全(双重检查锁)
  2. 工厂:解耦创建逻辑,减少 new 的硬编码(简单工厂/工厂方法/抽象工厂)
  3. 策略:定义算法族,运行时切换行为(如支付策略、排序策略)
  4. 服务端关联:单例常配合 DI 容器生命周期,工厂用于复杂对象创建,策略常用于业务规则引擎

简短示例回答

“单例用 Lazy<T> 或双重检查锁实现,如配置管理器;工厂模式把创建逻辑分离,如 DbProviderFactory;策略模式将算法封装,如 IShippingStrategy。在 ASP.NET Core 中,DI 容器接管了单例和工厂的职责,策略模式仍用于运行时多态选择。”

可能追问

  • 如何破坏单例模式?(反射、序列化)
  • 工厂模式和抽象工厂的区别?
  • 策略模式与 switch/if-else 的权衡点?
面试提示:提到 .NET Core DI 默认支持 Singleton/Scoped/Transient 生命周期,面试官会认为你有实战经验。

项目案例:高并发订单处理系统

维度内容
项目名称分布式订单履约中台
业务背景电商平台日均 500 万订单,峰值 QPS 2 万 +,需要统一订单状态流转、支付对接、库存扣减。
规模指标6 个微服务,30 + 数据库表,日处理 5TB 日志,99.99% 可用性目标。
技术栈.NET Core 3.1 / 6.0,EF Core、Redis、RabbitMQ、Docker + K8s、Polly 熔断降级。
核心难点订单状态机复杂(策略模式 + 状态模式);库存扣减并发(单例库存服务 + 分布式锁);支付通知多工厂(工厂模式对接微信/支付宝)。
面试高频追问
  • 订单状态机如何保证一致性?
  • 库存扣减为什么不用数据库行锁?
  • 支付通知工厂模式如何扩展新渠道?
  • 单例服务在高并发下如何抗压?
  • 如何监控和回滚状态机异常?
可迁移回答话术 “使用策略模式实现不同支付渠道的验签与回调处理,新增渠道只需实现 IPaymentStrategy 接口并注册到工厂;订单状态机采用状态模式 + 事件驱动,每个状态是一个单例对象,通过门面层控制流转,结合 Redis 实现幂等。” 此表述展示了面向对象设计模式在实际高并发系统中的落地,面试官会认为你有架构思维。
设计模式项目追问路径图 订单状态机如何实现? 用了哪些设计模式? 状态流转如何保证原子性? 并发下状态回滚怎么办? 策略模式 vs 状态模式? Redis Lua 脚本实现? 补偿机制设计?
面试策略:项目案例配合追问路径图练习,自己模拟被追问的场景,提前准备好每个分支的回答稿。面试时主动提及“我们的状态机使用了状态模式 + 事件溯源”,能大幅提升印象分。