原文链接: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 数据库不可扩展”这样的说法给人的印象不好。作为多年来面试过很多人的人,我在这里的建议是要谦虚地对待你所知道的和你不知道的。在面试的这个部分,用实例运用你现有的知识来引导。
识别和解决瓶颈
最后,讨论瓶颈及缓解方法。以下是一些重要的问题:
- “我们是否有足够的数据库副本?”
- “是否存在单点故障?”
- “是否需要数据库分片?”
- “我们如何使系统更加健壮?”
- “如何提高缓存的可用性?”
确保阅读您面试公司的工程博客。这将帮助您了解他们使用的技术栈,以及对他们来说哪些问题很重要。