为什么做app开发岗位的面试官时我很少面算法题?

9,536 阅读9分钟

为什么我不在app开发面试中面试算法?

新年来到, 找工作的人也开始慢慢动作起来了. 今天也借此聊聊面试的问题. 在我主导的多场Android或React Native面试中, 我鲜少有问到具体算法的, 特别是leetcode题的. 原因是不太实用. 这里我想解释下具体原因, 也探讨下我们面试官在面试时到底想考察什么才最有性价比.

一. 实用性

考察算法的第一个好处, 据说是"应对复杂的编程难题". 算法学好了, 就能解决各种难题了.

首先是这个说法不算错. 比如说我做过一个电子书reader的工作, 里面就要求得到目录信息(toc, table of content). 但麻烦地在于每个大章节下, 不知道有多少个小章节, 小章节还有更小章节. 如:

chap 1. xxx
  1.1 xxx1
    1.1.1 xxxx11
    1.1.2 xxxx12
  1.2 xxxx2
    1.2.1 xxxx21
      1.2.1.a xxxx21a
    1.2.2 xxxx22

常规思路就是几个for循环一遍历就得到. 但因为问题在于, 到底是"几个"for循环呢?
不同的电子书有不同的toc层级, 根本就不能写死到底有多少层for循环.

熟悉的同学肯定也发现了, 这种排列组合问题, 其实和leetcode的第17题, 即电话号码的字母组合相似. 也与leetcode第46题, 全排列, 很像. 只要会解上面这两题中任意一个, 那这个toc遍历的问题也能得到解决. 所以说, 算法是有用的.

但我不太赞同在app开发中面试算法的, 原因之一就是岗位问题. 若open的职位是算法工程师, 那肯定要过算法了, 最好是贴近于日常工作中要用的算法. 同理, 对于app开发来说, 我们日常中要用的算法真的不多, 所以那些复杂的"滑动窗口, 动态规划, 二叉平衡树, ..."在我十多年的app开发过程中一次都没有用过. 在我们app开发中, 用得更多的是:

  • 复杂的UI效果
  • 新出的各种库 (如jetpack的近百种包)
  • 新出的Android版本 (Google逼着我们每年升级一次targetSDK)
  • 设计架构的迭代 (如一个设计在版本1中可行; 但版本2新加了与新改了不少需求, 原来的架构不行了, 我们要如何做到让新架构兼容老新两种需求)
  • 性能的调优 (如启动时间, 打包时间, 编译时间的优化; 如页面响应时间的优化; 如电量消耗)
  • 内存的调优 (如内存抖动, 泄露)
  • 项目的质量保证 (如静态代码检测, 单元测试的覆盖, 自动化执行编译与测试)

而这些东西, 都与高深的算法没有直接关系的.

当然你可以说像启动时间, 我们可能就要用上拓扑排序, 这就牵扯上算法了. 有道理, 所以我的原则就是: "在面试里, 只考察与开发相关的算法问题", 比如这里讲到的拓扑排序, 如图片管理中的LRU.

另外, 我就是要考察个别我要用到的算法, 我也不会让人家手写出算法, 我多是讲人家讲下思路就行. 这就是要讲的第二点了: "性价比".

二. 性价比

这里要先说明的就是, 面试是有代价的. 是的, 无论是你打猎头花的钱, 还是花的HR + 你tech leader + CTO(复查)的时间, 这些都影响了大家的时间, 从而减少了日常工作的时间. 所以面试是有代价的, 我们也应该要追求一个性价比, 即"尽量以最小的时间, 得到我们想要的人才".

耗时长问题

我也面试过各种公司, 目前我见过的几种面试方式之一, 就是专门有个一两小时的"白板写算法". 我在面试snapchat时, 总耗时5小时的面试时间里有近2小时是在写算法. 这也是无奈, 因为面试中问算法, 确实是耗时的操作.
1). 你首先要讲解题目. candidate可能还有需求的疑问, 还要问你一些细节. 10分钟左右过去了
2). candidate动笔之前要花了十分钟左右思考下
3). candidate要开始写代码
4). 写完后, 你要提醒是否有些边界情况没考虑到, 是否有什么use case没有覆盖到, 哪里写得不对; 然后candidate自己再去修改,
5). 然后你再审核, 可能要重复这个"写->提醒->再写"的过程好多次

最后一处算法题下来, 可能半小时到40分钟就没了. 而你考察到了:

  • candidate是否细心
  • candidate是否了解这个算法

然后, 没了. 你得到就只是这两点.

再来看另一场面试形式, 我们问java与kotlin的掌握程度 + Android的基础知识 + 新UI(RecyclerView, MotionLayout,..) + 性能的调优 + 内存的调优 + 并发开发知识(RxJava/RxJS/RxDart, kotlin协程, JUC, ...).

这种形式考察的就是更为全面的, 更贴近日常app开发的内容. 同样地花了半小时, 考察算法的就是问1到2个算法问题, 考察全面知识的则是问到了candidate的知识体系, 窃以为第二种全面考察的过程, 才能提供更多信息让我们面试官决定是否要录取这位candidate同学.

当然, 你可以搞多场面试, 一场面算法, 一场考察Android全面知识. 但这就是我说的性价比问题了, 如何在更少时间里达到审核candidate是否达标的目标. 面试官的时间也是时间啊, 也要计算在成本之内的.

八股文问题

另一个面试算法的问题就是八股文问题. 大清都亡了百多年了, 没想到八股文还在全世界的高科技公司里盛行. 各种算法比赛, 各种Leetcode刷题盛行. 当你问一个算法问题, 而你的candidate同学答得很完美, 又考虑了边界情况, 代码里又做了优化, 你很满意. 但这种满意是对结果的满意, 你其实并不知道是他才思这么敏捷且全面, 还是因为他来面试之前已经刷过leetcode题好几遍.

所以我说, 在app开发这个岗位上, 搞几个算法题来让人家白板写题, 得到的结果确很少, 耗时却很长, 性价比太低.

三. 考察candidate的能力

很多人喜欢用算法来面试, 主要是想看:

  • candidate是否思虑周详, 是否有考虑为空, 为0, 为负数等诸多边界条件
  • candidate的反应与沟通能力. 当面试官给出指导后, 他是否能快速理解, 并做出快速反应
  • candidate的算法深度, 是否能解决类似的问题.

个人觉得这无可厚非. 不过相对于考察临场能力, 我更看重于两点:

  • candidate日常写代码习惯
  • candidate的潜力

第一点就是看candidate的github仓库, 看他是如何写代码的. 如代码架构, 如他的测试代码.
当然一般人写库, 可能不太有测试代码. 另外就是一些人没有写github的习惯, 所以这一块参考可能不是总有.

那另一个方法就是我们会留一个简单作业给candidate, 就是去远端取个数据, 然后用list展示出来. 我们要求candidate不要多于4小时, 不是考察他写代码的速度, 而是不想他浪费太多时间在上面. 我们就是想看个大概, 看这人的代码习惯而已.

第二点是关于candidate的潜力. 我之所有问全面的Kotlin/Android, JS/TS/ReactNative问题, 就是想知道他大概了解哪些, 哪些是他强项. 然后我根据他的回答, 来匹配他的工作年限.

  • 若candidate工作了两年, 了解的东西却很多, 一些东西还了解得颇有深度, 那我觉得这人潜力很大. 说明他自己业务时间自己去琢磨东西, 去研磨自己的技艺了. 我喜欢这样自主性, 积极性的开发.
  • 若candidate工作了五年, 了解的东西却一般, 没什么深度. 但我就会觉得这人可能只是应付工作, 平时技术研究就偏于工作这一块, 没什么自己的技术热情. 我可能就会pass掉这同学.

答疑

有同学在评论区中说了, 算法要准备最久, 要持之以桓的决心, 要有思辩能力, 所以最能筛选出最合适的开发.

我个人其实并不赞同这种说法的:

1). 基本上干开发这一行的, 只要不是过于松懈, 都是有一定思考与辨认能力的. 通过算法来考察一个人的能力, 我个人觉得没多大必要

2). 算法是要准备最久, 但吐槽的最多是"准备最久, 还没什么用", 浪费了大家的时间. 在app开发中我们不太使用得到动态规划, 红黑树这些麻烦的东东的.

3). 仍是那个终极问题, "我们要招什么样的人, 才能适合app开发岗位". 我们不是想招什么桓心大, 思考能力强. 我觉得这些都太虚. 说实在的就是想招, 性格上不刺头, 工作上上手快(对app开发熟悉), 对技术有热情(能自我成长)的人.

所以综上所述, 我们app开发岗位才没有必要去问什么算法.

总结

我面试时喜欢考察

  • 编码习惯 --- 通过看他的代码来判断
  • 技术潜力, 技术热情 --- 通过问大量技术问题, 来匹配他的工作年限, 从而得知.

而面试算法, 都不能看到太多这两点目标里的东西, 而且耗时过长, 考察到的点又很片面, 所以我个人一般不喜欢就app开发岗位问算法. 希望我的这篇文章, 对一些刚刚做面试官的teach lead同学, 能起到一点点指引作用, 帮助他们知道如何用最小成本来达到面试目的, 也希望我们开发行业的面试八股文少一些, 多一些"基于candidate背景与技术经历"的问题, 多一些引导性的问题, 少一些可以背诵/强记得到答案的问题.