简单系统设计 —— 面试(结)

简单系统设计 —— 面试(结)

一、前言 Overview

简单系统设计, 共9篇,边学边写。在努力克服自己的惰性,终于能在2022年来临前完成系列。在整个过程中,遇到新的思想,新的问题,留着后面解开。

系列开篇的时候,学习系统设计的主要目的(面试),所以在总结篇,就整理下自己对系统设计整体知识点和面试思路。希望N年后,自己回头看的时候,能读出自己的幼稚与不足。

如果整个系列有帮助,记得请我☕~

二、系统设计面试的目的 Destination

IT公司中,都在构建和优化商业级系统(可拓展 & 高性能)。所以我认为,公司更需要具备合理设计技能的员工(工程师≠码猿)。

系统设计面试,是一道开放性题目。除了设计能力,还有对思考过程、算法知识、人与人沟通以及突发思维的考量。脑子要转得快,要灵光,要系统,要谨慎。这才配得上工程师的称号。

三、关键步骤 Steps

1. 澄清需求和问题

Rome was not built in a day.

不管是淘宝,支付宝还是微信,他们所包含的上千个功能,都不是在短短45~60分钟设计完成的。这是多年的功能迭代,实践后累积的。

对于我们,时间有限,我们只能把面试官的题目,缩小到关键功能上。需求可以分成功能性需求非功能性需求。然后开始在白板设计简单功能

例如: 在设计一套打车系统,可以列下如下要求:

高德打车

  1. 乘客可以预定和取消行程
  2. 系统必须匹配司机
  3. 司机可以取消行程
  4. 乘客和司机可以互相评分
  5. 支持支付渠道
  6. 乘客可以查看司机的实时定位

提出要求,是为后续的设计范围。同时需要对面试官提出明确的问题(提出一个好问题是一门学问,同时能展示自己的逻辑思维)。比如用户群体是什么样的?系统后续是在什么平台被使用的?这些都将协助自己识别,自己设计瓶颈和预留拓展性。

2. 容量估算

在明确系统设计需求后,下一步就是需要确定系统的受众。了解系统的用户量级,如果未给出,应主动询问面试官。这是一个极其重要的设计参考值,能帮助我们对系统设计瓶颈的预估。

通过活跃用户的预测,进而估算系统接受请求的量级,以及预估所需存储的数据空间。同时需要知道系统的请求重心是在读还是写,预估读请求和写请求的比例和量级,从而决定使用SQL或者NoSQL的数据库,以及缓存的迫切程度。

同样举例说明:

假设我们要设计一款类似Weibo的系统。在这种情况下,我们可以做出假设性估算:

  • 3亿活跃用户,每天发文6亿。
  • 热数据占20%。
  • 每个用户平均有1000关注量。
  • 一条发文至少被转发1000次。
  • 每条发文上至少带有一个额外的媒体资源(图片或者视频)。

从而我们可以估算出这个读写请求的量级,所需服务器的规格和数量。同时能估算出1年所需要的数据存储大小(发文大小 x 每日发文量 x 天数) 。

这些同时也是系统发布前,性能测试的标准~

3. 设计目标

系统设计的的部分主要要求:延迟 & 吞吐量。

  • 延迟 是指处理客户端的请求,并返回结果所需要的时间;
  • 吞吐量 是指在给定时间间隔内可以处理的请求数;

高性能系统,必须具有最小延迟和最大吞吐量。设计京东网站,如果加载时间很长,那客户早就跑光了。如果双11节日,网站就容易因此崩溃,然后因此亏本,老板跑路。

第二个设计目标是在可用性和一致性之间进行选择。根据CAP理论,可以使用 CP 或 AP 系统来容忍网络中的故障。可用性和一致性的选择由系统类型决定。

CAP理论

如果是金融项目,则会更注重一致性。然而,对于微博这类的系统,则更注重于可用性。

4. API定义 & 架构

确定完需求后,就需要完善后端系统暴露的API。设计请求参数,响应体,状态码,以及HTTP方法类型等。API设计是否使用REST、GraphQL或GRPC。

API设计 - Swagger

设计好API接口后,开始在白板中绘制系统所需要的组件。从客户端的组件开始,到API网关、负载均衡策略。

API网关 & 负载均衡

如果你被要求设计一个像爱奇艺平台时,你还可以谈论 CDN(内容交付网络),它有助于提供静态图像或视频文件。

对于每个API接口,对于非CRUD的API接口,还需要考虑是否需要补充高级算法。
例如,设计电商平台中:

  • 要获得首页商品列表,可以提出一个商品推荐算法。
  • 如果用户查看商品详情,这将是一个普通的 CRUD API接口。

5. 数据库 & 缓存

对于大部分系统,数据库是必不可少的组件。针对于系统的长期存储数据:

  • 应该清楚地了解数据建模中涉及的实体及其之间的关系。
  • 弄清楚数据是结构化的还是非结构化的,以及它是否需要架构灵活性。
    上述问题的答案将影响,系统选择使用 SQL 还是 NoSQL 数据库。

大多数系统都是重读系统。因此可以通过根据访问模式在列或一组列上创建索引来加速所有数据库读取查询。可以使用一个主从数据库的架构,在主设备上执行写入,而从从设备上完成读取。这会将读取与写入隔离开来,从而提高系统的性能。

从数据库读取会导致 IO 操作在计算上执行起来很昂贵。系统可以在应用程序和数据库之间添加一个缓存层以最小化磁盘 IO。这将进一步提高系统的性能。在添加缓存时,需要在缓存逐出策略以及缓存模式(例如直写、回写、缓存搁置等)之间进行选择

当系统是面对百万级用户时,单节点数据库不再承受其并发量,需要采用分布式数据库。因此需要在多个数据库服务器之间分发数据,这称为数据分区。面试官可能会询问有关可用于分发数据的不同数据分区策略并讨论使用每种策略的权衡。

四、总结 Summary

不足的地方还是很多,很多地方总是泛泛而谈,很多地方理解的不够透彻,很多地方自己讲解的不够透彻。路还很远,继续走下去了~

>- 系统设计完结撒花❀ -<
作者

MinRam

发布于

2022-01-31

更新于

2022-07-17

Licensed under

评论