Wednesday, December 2, 2015

如何做系统设计的面试题



如何做系统设计的面试题
系统设计是一类开放型的面试题,没有绝对正确的答案,更多时候是一些取舍。可以比较全面地考查面试者的综合素质,包括知识面,经验,理解和分析能力,抽象能力。这类题目一般是针对有一定工作经验的面试者。事实上,并没有要求在短暂的面试的时间,面试者给出一个完美的答案。世界上没有完美的系统,只有更好的系统。以下面这个例子,说一下这类题应该怎么做。
可穿戴设备会收集用户数据,这些数据会被上传到服务器。设计一下这个业务的存储系统。

理解使用场景和限制

面试官给出的问题描述都会比较简单。
所以要做的第一件事情就是:沟通,理解需求。要了解使用的场景和特定的限制。在确认自己理解清楚之前,不要埋头开始做题。

就上面的描述,我们大致能明白了是个什么样的问题,但是还有很多细节。
用户量有多少?收集的是哪些数据?这些数据收集后是否要用于分析和查询?每条记录的大小大概是多少?读和写的频率怎么样?还有没有一些特定的业务自身的特征?
假设场景是这样子的,这个业务当前有200w用户。智能设备是为了防止小孩走丢的鞋子,为了简化问题先假设只需要记录位置信息。每条记录大概200字节。需要查询用户当前位置,并且可以查询历史记录,比如当天该用户到过哪些地方,或者曾经到过哪些地方。请求的分布主要还是当前位置信息。每隔10分钟,设备会记录一次位置信息并上传服务器。假设历史数据需要保留五年。这个业务还有个特点是,用户与用户之间,并没有任何联系。

抽象问题

尽管这道题只是问存储相关的一块,但一个系统还是会有分层的设计,我们将功能提取出来。
服务层:
  • 查询当前位置和查询历史信息
  • 接收记录信息
数据存储层:
  • 近乎简单key-value的形式,但是涉及到历史信息查询
这一层的功能数据库那里可能直接提供了,服务层到底需不需要?在抽象问题的时候,这个思考过程肯定要有。

抽象出来的优点:数据存储层可能使用多种异构的数据库,那么在这一层可以提供统一的API。比如对当前位置做缓存,而历史数据直接查数据库;又或者写请求量很大,同步写操作转化为异步的批量写操作等这一层抽象可以让内部实现对外部透明。需要让面试官知道,你是在做设计,在思考。
接着看数据存储层。该使用什么样的数据库作为这个业务的存储呢?mongo?redis?hbase?或是传统数据库mysql?这里有时间属性和大量历史数据,是否可以考虑一下时序数据库,比如influxdb?告诉面试官你是怎么选择数据库的,它们在这个场景各自的优缺点是什么。
假设面试者对mysql比较熟习,不妨先考虑传统的mysql能否满足需求。
那么接下来就是表结构怎么设计?字段有哪些?假设记录位置数据用的是Location表。Location表中的字段要包括,用户ID,坐标,时间。那么给定当前时间和用户ID可以查询当前位置,给定一个时间区间可以查询到历史记录。如果查询速度有要求,是否需要做次级索引,涉及到这些具体细节,如果面试官感兴趣,都可以深入讨论。

瓶颈

抽象问题之后,该思考一些性能指标,来判断选型的方案是否满足。如果不满足,要继续思考其它的方案。估算是很重要的一项能力,对数据要敏感。
200w用户,10分钟一次写入,如果是按无规律的计时,整个系统的tps大概每秒只有3000多,单个mysql都能hold住的。但如果统一在每10分钟整点写入,则会有3w的峰值,压力比较大。

至于读的平均请求,可能还低于写。仍然需要考虑进去的是峰值。注意这里缓存似乎是无帮助的场景--用户只会去查询自己的位置信息,不会查他人,所以没有"热点用户"查询。
200w用户,10分钟一次写入,记录大小200字节。每天会生成大概50G数据的样子。保存5年,那么会有100T的量级。
通过这些分析,可以知道,这里面临的主要不是高并发请求的问题,而是数据存储量比较大的问题。另外,这么多记录条数对于mysql那边的性能影响也要考虑进去。

扩展

如果200w用户变成了2000w用户,甚至2亿用户会怎么样?当前设计的系统能不能扛住?扛不往该怎么样扩展?这个时候应该能立刻想到很多"常识",负载均衡、缓存、异步等等。
用户之间没有相互联系,这个特点很方便我们按用户去划分。即使数据再涨,都可以加机器应对。
mysql可能会挂,7*24的高可用怎么做?立刻应该想到主备,还有读写分离这些。
这里面任何一个点都可以继续讨论下去,因为都是一些通用的东西。

Read full article from 如何做系统设计的面试题

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts