SDI学习——系统设计方法论:一般步骤

SDI即系统设计面试,许多软件工程师在系统设计面试 (SDI) 中苦苦挣扎主要是因为以下三个原因:

  • SDI的非结构化性质,单我们被要求解决一个没有标准答案的开放式设计问题。
  • 缺乏开发大型系统的经验。
  • 他们没有为 SDI 做准备。

就想coding面试一样,候选人并没有有意识地准备SDIs,大多数表现得不好,尤其是在面试一些顶级公司的时候,比如Google,Facebook, Amazon, Microsoft, 等等。在这些公司中,表现不超过平均水平的候选人,获得录用的机会有限。

在系列中,我们将遵循循序渐进的方法来解决多个设计问题。首先,让我们完成以下步骤:

Step1:需求说明

我们最好先询问有关我们正在解决的问题的确切范围。
因为设计问题大多是开放式的,没有一个正确答案,这就是为什么在面试早期澄清歧义变得至关重要。
花足够时间定义系统最终目标的候选人总是更容易通过面试。

此外,由于我们只有 35-40 分钟来设计一个(假定的)大型系统,我们应该明确系统的哪些部分是我们我们将要关注的部分。

让我们用一个设计类似Twitter的服务的实际例子来扩展这个问题。以下是一些设计 Twitter 的问题,在继续下一步之前应该回答这些问题:

  • 我们服务的用户能够发布推文并关注其他人吗
  • Tweet可能会包含图片和视频嘛?
  • 我们只关注后端嘛,还是也要开发前端?
  • 用户可以在用户上搜索嘛
  • 对于新的(重要的)推文会发送推送(push)消息嘛

所有这些问题都会决定我们最终设计是怎样。

Step2:系统接口定义

定义系统期望的 API接口。这不仅将确定系统预期的边界,还将确保如果我们没有弄错任何需求。

我们类似Twitter的服务的一些例子如下:

postTweet(user_id, tweet_data, tweet_location, usr_location, timestamp …)
generateTimeline(user_id, current_time, user_locatioin, …)
markTweetFavorite(user_id, tweet_id, timestamp, …)

发推特:需要带有用户id,tweet数据,用户地理位置,时间戳。
生成时间线:用户id,当前时间点,用户地理位置
喜欢推特:用户id,推特id,时间戳

Setp3:(粗略估计)Back-of-the-envelope estimation

最好要估计下我们要设计的系统的规模。有助于我们之后讨论的扩展性,分区,负载均衡以及缓存。

比如:

  • 系统的规模有多大(比如推文的数量,推特的浏览量,每秒产生的时间线数量)
  • 我们需要多大的存储?如果用户可以在他们的推文中包含照片和视频,需要的存储大小也不一样。
  • 我们希望有多大的网络带宽用量?
  • 这对于决定我们如何管理流量和平衡服务器之间的负载至关重要。

Setp4:定义数据模型(Defining data model)

尽早定义数据模型将阐明数据如何在系统的不同组件之间流动。
稍后,它将帮我们更好地管理和设计数据分区。
候选人应该能够识别系统的各种实体,实体它们将如何相互交互,以及数据管理的不同方面,如存储、传输、加密等。

以下是我们类似 Twitter 的服务的一些实体:

User: UserID, Name, Email, DoB, CreationData, LastLogin, etc.
Tweet: TweetID, Content, TweetLocation, NumberOfLikes, TimeStamp, etc
UserFollowo: UserdID1, UserID2
FavoriteTweets: UserID, TweetID, TimeStamp

我们应该使用哪个数据库系统?像Cassandra这样的NoSQL是否最适合我们的需求?或者我们应该使用像MySQL这样的解决方案?我们应该使用那种块存储系统来存储我们的照片和视频?在后端,我们需要一个高效的数据库来存储所有的推文,并且可以支持大量的读取。同时也需要一个分布式文件存储系统来存储图片和视频。

Step5:架构设计(High-level design)

我们将绘制一个框图,用5-6个方框代表我们系统的核心部件。我们应该确定从端到端解决实际问题所需的足够组件(中间件)。

对于Twitter来说,在架构层次上,我们将需要多个应用服务器来为所有的读/写请求提供服务,并在它们前面设置负载均衡器以分配流量。如果我们有更多的读流量(相对于写),我们可以将服务器进行划分读/写服务器。

Step6: 详细设计

选择其中两到三个组件进行深入设计,然后根据面试官的反馈来决定深入讨论系统的哪部分。
我们应该提供多种选择方案,包括他们的优点和缺点;然后解释我们所选择的方案的原因。

记住,没有唯一的答案,唯一重要的是考虑不同选择之间的权衡,同时牢记系统的约束,下面是需要考虑的一些细节:

  • 由于我们将存储大量的数据,我们应该如何对数据进行分区,将其分配到多个数据库中?我们应该把一个用户所有的数据都放到同一个数据库中嘛?这会有什么问题吗?
  • 我们将如何处理经常发推文或关注很多人的热门用户?
  • 由于用户的时间线将包含最新(和相关)推文,我们是否应该基于时间和相关性来存储他们,以便于我们可以快速找到最新推文?
  • 我们应该在什么程度上以及在哪一层引入缓存来提升系统性能?
  • 哪些组件需要更好的负载均衡?

Step7: 识别并解决瓶颈问题

尝试讨论尽可能多的瓶颈问题以及缓解这些问题的不同方法。

  • 我们系统中存在单点故障嘛?该如何解决?
  • 数据是否有足够的副本,当一些服务器宕机时,是否还能正常提供服务?
  • 同样,我们是否有足够多的不同服务的副本在运行,保证部分故障不会导致整个系统崩溃。
  • 如何监控我们服务的性能?当核心组件失败或者性能降低的时候,我们是否可能收到报警?

总结

总之,做好准备以及在面试中具有条理性是在系统设计面试中成功的关键。
上述步骤应能指导你在设计系统时保持正确的方向并涵盖所有不同的方面。

后续我们将应用上述准则来设计几个在SDI中常见的系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值