# 前言:面试要求
我们的技术面试会涉及到算法、数据结构和系统设计,面试前需要你做的准备具体如下:
- 结合实际项目经验回顾软件工程的知识,例如:如何从需求推导出系统设计,如何衡量两个不同设计的优劣,如何在各种限制下(人员、时间、资源等)选择其中更合适的设计,以及提升该设计的可拓展性等。
- 在白板上练习算法题目,写出清晰、简洁、bug free 的代码,并衡量时间和空间复杂度以及可能存在的副作用。
- 尝试用不同的方法,思路或数据结构去解决同一个问题,并且衡量不同解法之间的优劣。
- 我们需要你掌握面试岗位对应的技术领域相关知识,还需要对简历上所罗列的知识有深入的理解。
# 如何从需求推导出系统设计
就我个人而言,我在大学学习的过程中,也学习到了很多方便快捷好用的工具,包括但不限于 webpack、jenkins、腾讯的 TAPD 平台等,还有简单清晰明了的思维导图软件 xmind 和 ithoughts 等。所以通常来说,在实现一个完整的项目时,我的工作流程一般是:
- 需求采集,并绘制思维导图
- 将需求细分,从用户故事中拆分出 Task(使用 TAPD 平台)
- 使用敏捷开发进行迭代
- 使用 github 和 jenkins 进行持续集成、持续部署等。
对于系统设计来说,我认为比较重要的就是你要用什么模式去设计。比如我之前学习过的 MVC 模式,还有 MVVM 模式。好的设计模式不光可以降低组件之间的耦合程度,而且也易于后期的扩展。
以 MVC 模式来说,视图层、逻辑层、数据层,每一层之间都可以进行独立的单元测试
- 数据层:从数据库中获取数据等
- 视图层:控制 UI 的显示、交互、动画等
- 逻辑层:解决逻辑问题,响应用户的操作
所以基本的设计流程就是
- 实现视图层
- 设计后端数据库(如果是分工合作的话,可以与视图层同步进行)
- 实现数据层
- 实现逻辑层
- 检查逻辑层是否完整
检查逻辑层是否完整,我个人的理解就是检查是否实现了所有的功能。因为通常一个功能对应了一个逻辑操作。比如用户搜索功能,后端就需要有一个 Controller 处理用户的搜索。所以,检查逻辑层是否完整,就是看是否实现了系统的所有功能,这也可以借助自动化功能测试软件 Selenium 来实现。
# 如何衡量两个不同设计的优劣
应该综合多种因素去考虑,时间成本、资金成本、实现的难度等因素。是否问题,是否易于后期扩展。
# 用不同方法解决同一个问题,并衡量利弊
- 代码可读性
- 时间复杂度和空间复杂度
首先代码的可读性要好,因为我们都可能会去看别人的代码,而我们的代码也很可能会被别人看。所以平时要注重一些编码规范,多些注释。
综合考虑时间复杂度和空间复杂度。有时候,我们可能会用空间换取时间。在对时间没有过多要求的时候,为了降低空间成本,也会用时间换取空间。
# 参考
面试前的准备...... 一些编程外的软技能