搞定面试中的系统设计题

一般来说,社招多少都会考察系统设计题,尤其是针对有了1年以上工作经验的工程师,这更是面试流程中的家常菜, 除了面试之外,学会系统设计对我们的日常工作也是大有裨益的。

每当我说起“设计”,就会联想到“战略”这个词语,战略的意思就是,选择一方面,而放弃另一方面。而软件设计也是这样, 我们在多个需求、现实资源中进行权衡,从而给出一套符合当前,以及短期未来中最优的方案。下面这张图画出了后端中常见的 一些结构,此外,还可以参考我的 《Web开发简介》

system design

系统设计题想要考察什么?

首先我们要搞清楚,面试官为什么要问这一类题目。这一类题目的特点是题目非常开放,涉及到的知识点特别多,每一个地方都可以进行 深挖,而且,往往一个条件进行改变,相对较好的方案就会完全不同。通常来说,面试官使用系统设计题,主要就是考察:

  • 思维是否开阔、灵活
  • 知识广度
  • 知识深度
  • 架构能力是否足够,是否能设计出可扩展的系统
  • 是否能熟练使用常见工具并且知晓特性,能够因地制宜选择合适的方案和工具

因此,此时我们已经知道面试官到底想要通过系统设计题考察我们什么,我们也就知道在大的方面,该要怎么应对面试:

  • 加强知识深度:知识深度不仅仅在系统设计题中体现,包括此前的技术面试题都会考察
  • 加强知识广度:了解常见工具的特性和什么场景适合,例如MySQL/PG、Redis。了解常见的业务场景特点,例如:论坛一般来说都是读多写少,而日志服务则是写多读少。
  • 了解常见的软件架构模式,参考 这里

如何解决系统设计题

那么,当我们拿到一个具体的系统设计题时,我们应该怎么着手解决它呢?

注意陷阱⚠️

千万不要张口就来 。我们上面的分析已经表明,遇到问题,我们必须先明确问题,然后才能给出有效的解决方案,系统设计题也是如此。 而往往面试官会在这里面挖坑,就是,给出一个条件相当模糊的系统设计题。例如:请设计一个短链接系统、请设计一个压测工具。

如果我们张口就来,那么就中了面试官的套路。在工作中也是如此,如果你碰到了一个产品经理,产品经理还没有想清楚,就叫你写代码, 那么后面一定是反复修改需求,作为工程师的你一定是痛不欲生。因此,我们需要做的第一步就是 明确问题,不要张口就来

千万不要自己一个人闷头想,记得一边想一边把你的思路说出来 由于别人是不知道你咋想什么的,如果你一个人皱着眉头思考,面试官 也很着急,他也不知道你是想不出还是怎么的。所以,一边把你的思路描述出来一边想,这是最好的方式。

明确问题

拿到了问题之后,我们只有一个大概的方向,即我们要做一个什么。但是并不清楚具体条件,而不同的的业务场景所需要的架构也是不一样的。 例如,每天只有10000次访问的短链接系统和每秒钟有10000次访问的短链接系统在技术要求上是不一样的。

因此,第一个我们需要问面试官的问题:

  • 这个系统一天的请求量是多少?面试官回答,一天2万。

虽然现在我们有了更加明确的条件,但是还是不够具体,我们需要进一步确定:

  • 这个短链接系统的峰值是多少?面试官回答:峰值1万/s。

此刻,我们得到的条件已经清晰很多,我们知道,QPS位10k,相对来说,已经算是高并发了,但是我们还需要继续确定。

  • 这个短链系统的短链接是永久保存的吗?面试官回答:是。
  • 生成的锻炼字符长度有要求吗?越短越好。
  • 录入的长链接大概是多少个字符呢?有长有短。
  • 那么,平均是多少个字符呢?假设是50个字节。

通过这些我们可以了解到,我们需要对短链接进行持久化。而到目前为止,我们可以得出一些计算:

  • 峰值QPS为10k
  • 一天的请求量为20k,因此,我们的系统需要为并发考虑,所以我们很可能需要用到缓存
  • 一天为20k,那么一年就是 20k * 365 = 7300k
  • 如果短链接生成的链接长度为 6个字符,那么一年下来,需要的磁盘大小至少是:7300k * (6 + 50) / 1024 = 399.21875M

然后我们需要了解一些常见的性能指标,这是我们需要记在脑子里的:

这些数据是不准确的,因为:

  • 和怎么用关系很大
  • 和硬件配置关系很大

但是我们心里还是要有个大概印象。

现在我们就可以知道了,这个短链系统,并发是10k/s,但是我们还漏掉了一个问题,就是没有明确是读的QPS是10k还是写,还是读+写。 这个时候我们仍然可以向面试官提问。但是,不论读还是写,QPS为10k,只要硬件配置过得去,不加缓存也ok。但是通常来说,我们还是会 选择加上,原因很简单:此刻都有QPS都有10k,保不准半年之后更高了。

到此为止,我们已经知晓了解决系统设计题的一个大概思路流程,但是这远远不够,因为系统设计题对知识的广度要求也很高,因此这里 我还会提供一些常见的知识,希望能够对大家有所帮助。

常见知识

此外欢迎读者提供更多常见知识我收录到此处。

练习题

  • 设计一个短链接系统
  • 设计一个压测工具
  • 设计一个分布式ID生成器
  • 设计一个论坛
  • 设计一个微博


更多文章
  • 使用Redis的Stream模块实现群聊功能
  • 价值编程与职业发展
  • 解决k8s cron无法读取环境变量的问题
  • 应用内购的坑
  • 两种常见的访问控制模型
  • gunicorn max-requests 选项的作用
  • Redis使用中的几点注意事项
  • 给你的代码跑个分?pylint使用教程
  • 一个Gunicorn worker数量引发的血案
  • MySQL Boolean类型的坑
  • pip freeze是魔鬼
  • 一个feed流系统的演进
  • Android 使用view binding
  • 系统调用的过程
  • MySQL charset不同导致无法使用索引的坑