原文链接:https://github.com/karanpratapsingh/system-design?tab=readme-ov-file#system-design-interviews

系统设计涉及广泛的主题,系统设计面试旨在评估您为抽象问题提供技术解决方案的能力,因此,它们不是为了寻求特定答案。系统设计面试的独特之处在于候选人和面试官之间的双向互动。

不同工程级别的期望也有很大差异。这是因为具有丰富实践经验的人与行业新手的处理方式完全不同。因此,很难想出一个单一的策略来帮助我们在面试过程中保持条理。

让我们来看看一些常见的系统设计面试策略:

需求澄清

系统设计面试问题本质上是模糊或抽象的。在面试初期就询问有关问题确切范围的问题,并澄清功能需求至关重要。通常,需求分为三个部分:

功能需求

这些是最终用户特别要求的基本功能,系统应提供这些功能。根据合同,所有这些功能都需要纳入系统。

例如:

  • “我们需要为这个系统设计哪些功能?”
  • “在我们的设计中,我们需要考虑哪些边缘情况(如果有的话)?”

非功能性需求

这些是系统根据项目合同必须满足的质量约束。这些因素的实施优先级或程度因项目而异。它们也被称为非行为需求。例如,可移植性、可维护性、可靠性、可扩展性、安全性等。

例如:

  • “每个请求都应以最低延迟处理”
  • “系统应具有高可用性”

扩展需求

这些基本上是“好有”的需求,可能超出了系统的范围。

例如:

  • “我们的系统应记录指标和分析数据”
  • “服务健康和性能监控?”

估算和约束

估计我们要设计的系统的规模。询问诸如以下问题很重要:

  • “这个系统需要处理的目标规模是多少?”
  • “我们的系统的读 / 写比例是多少?”
  • “每秒有多少请求?”
  • “需要多少存储空间?”

这些问题将有助于我们后期扩展设计。

数据模型设计

一旦我们有了估算,我们可以开始定义数据库模式。在面试的早期阶段这样做将有助于我们了解数据流,这是每个系统的核心。在这一步中,我们基本上定义了所有实体及其之间的关系。

  • “系统中有哪些不同的实体?”
  • “这些实体之间的关系是什么?”
  • “我们需要多少张表?”
  • “NoSQL 在这里是否更好?”

API 设计

接下来,我们可以开始为系统设计 API。这些 API 将帮助我们明确地定义系统的预期。我们不需要编写任何代码,只需简单地定义API需求,如参数、函数、类、类型、实体等。

例如:

createUser(name: string, email: string): User

建议尽可能简化接口,并在后续处理扩展需求时返回。

高级组件设计

现在我们已经建立了数据模型和 API 设计,是时候确定解决问题所需的系统组件(如负载均衡器、API 网关等),并绘制系统的初步设计。

  • “设计单体架构还是微服务架构更好?”
  • “我们应该使用什么类型的数据库?”

一旦我们有了一个基本的图表,我们可以开始与面试官讨论如何从客户端的角度使系统正常工作。

详细设计

现在是时候详细讨论我们设计的系统的主要组件。与面试官讨论哪个组件可能需要进一步改进。

这是一个很好的机会来展示您在专业领域的经验。提出不同的方法,优缺点。解释您的设计决策,并用实例支持。这也是讨论系统可能支持的其他功能的好时机,尽管这是可选的。

  • “我们应该如何划分数据?”
  • “关于负载分配?”
  • “我们是否应该使用缓存?”
  • “如何处理流量激增?”

此外,尽量不要对某些技术持有强烈意见,像“我认为 NoSQL 数据库更好,SQL 数据库不可扩展”这样的说法给人的印象不好。作为多年来面试过很多人的人,我在这里的建议是要谦虚地对待你所知道的和你不知道的。在面试的这个部分,用实例运用你现有的知识来引导。

识别和解决瓶颈

最后,讨论瓶颈及缓解方法。以下是一些重要的问题:

  • “我们是否有足够的数据库副本?”
  • “是否存在单点故障?”
  • “是否需要数据库分片?”
  • “我们如何使系统更加健壮?”
  • “如何提高缓存的可用性?”

确保阅读您面试公司的工程博客。这将帮助您了解他们使用的技术栈,以及对他们来说哪些问题很重要。