系统设计问题比较棘手有很多原因。 其一在日常工作中你可能没有太多机会接触设计系统,尤其是对于junior engineer来说。其次,与算法问题不同,学习系统设计的资料在网上并不多,近几年网上出现了大量的资源,但是质量上参差不齐。当我第一次开始学习系统设计面试时(那是2019年了),我对系统设计没有任何经验。所以我不得不在网上找资源。我读的第一本系统设计书是Stanley Bellbrook和David L. White的《System Design Interview: A Strategic Guide for a Successful Interview》,我是在亚马逊上搜“系统设计面试”找到的这本书的。这本书没有太大帮助,因为它只是介绍了基本概念,没有实例。然后,我在educative.io上找到了一门名为“Grokking the System Design Interview”的系统设计课程(这个课程想必大家都知道了)。找到这个课程时我非常兴奋,因为这套课程有一系列的实例。我完成了这门课程,然后进行了几次面试,但结果仍然不理想。现在想想,我还是建议避免这门课程,因为它充斥着很多不必要的,有时甚至是误导性的内容,这些内容在真正的系统设计面试中很少涉及。尤其是它用了太多的篇幅去cover estimate那部分, 让人感觉就是拿来充字数的。如果他们近几年对这门课的内容有所改善,请留言告诉我。
后来我找到Artur Ejsmont的《Web Scalability for Startup Engineers》,情况开始发生变化。我忘了是如何找到它的。从书名上看,它似乎跟系统设计面试没有太多关系。但事实证明,它是一本非常适合系统设计面试的入门书。首先,在这本书中,你将学到系统设计面试中将要使用的所有components,包括web servers, caching, data replication, data partitioning, message queues, load balancer, DNS, CDN等。其次,在大多数系统设计面试中,你将被要求去scale a system。这本书介绍了三种scale的设计技巧。
. .и
1. Adding more clones
2. Functional partitioning
3. Data partitioning
. ----
这本书比较详细解释了各个components在scale a system中所扮演的角色和为什么要用到它们。正本书讲解了从一个只有一个server的小系统逐步到最后加入了上述所有components的一个大型的high avalability的系统。当我读完了这本书,我觉得我的对于how to scale a system有了更深的理解。
另一本很好的书是Martin Abbott和Michael Fisher的《The Art of Scalability, Scalable Web Architecture, Processes, and Organizations for the Modern Enterprise》。
在这本书中,你将读到在《Web Scalability for Startup Engineers》中看到的类似的观点。例如,它介绍了AKF Scale Cube,由x、y和z三个轴组成。每个轴描述了一种scale a system的方法。这三个轴大致对应于《Web Scalability for Startup Engineers》中的三种scale a system的设计技巧。这本书比较偏理论性,但仍然是一本很好的补充书。
. ----
最后还有一个经验分享。系统设计面试本质上是评估你在设计系统时如何做决策。不同的技术是为解决不同类型的现实世界问题而被开发出来的。所以接触不同的技术非常重要。我的建议是,你应该尽量熟悉每个类别中至少一种技术。例如,对于cache,你可以选择Redis。对于NoSQL数据库,你可以选择Cassandra。对于message queue,你可以选择Kafka。然后,你需要寻找练习的机会。当然,最好的练习地点是在工作中。我的建议是,在完成项目后,记下有关这个项目的详细信息。你试图解决什么问题,你有哪些技术选项,为什么选择了其中一个而不是其他的,你做出了什么权衡,你面临了什么挑战并克服了它们?如果你在工作中没有使用某项技术的机会,还有一种替代方法。你可以在互联网上找到人们分享的真实面试中的系统设计问题。你可以自己尝试自己解决这些问题。在练习时,尽量深入细节。例如,你可能想在设计中的某个地方添加cache。你会想应该用哪种cache technology, 应该选择Redis还是Memcached?如果你选择Redis,应该使用哪种数据结构?当你自己提出这些问题时,你就不得不更深入地了解Redis的特性,从而让自己更多地了解这项技术。
这是我学习系统设计的经历。我过去非常害怕系统设计面试,但现在我在大多数系统设计面试中表现的都不错。近年来出版了许多新的资源。有一本叫《System Design Interview — An Insider's Guide》的书,在亚马逊上评价很高。在udemy上也有很多system design课程。我会去看这些新资源然后分享我的学习经验。如果大家还有其他的资源,也可以在评论区分享。