2022年8月13日星期六

面试题:开发新功能和重构老代码之间怎么选?


最近面试的多家公司当中,有至少一家尝试在行为(Behavior Questions,或 BQ)面试中问我这样的问题。尽管可以去猜这家公司到底更重视迭代速度还是代码质量然后从对应的角度去回答,但正确的答案只有一个,那就是不要回答这个问题。


第一原理(英语:First principle),哲学与逻辑名词,是一个最基本的命题或假设,不能被省略或删除,也不能被违反。第一原理相当于是在数学中的公理。最早由亚里士多德提出。——Wikipedia

对于所有商业公司来说,第一原理永远是商业,不是产品也不是技术。(「商业」和「业务」在英文里都是 business,在这里不针对中文进行区分。)产品的存在是为了服务于商业,技术的运用是为了服务于产品和商业。脱离商业探讨技术上的取舍毫无意义,因此如果被问到先开发新功能还是先重构老代码,必须要从商业的角度进行回答。

开发新功能对产品和商业有什么影响?重构老代码又有什么影响?这是你必须和面试官探讨的问题。面试官可以会提供更多具体的场景信息,也可能让你陈述不同场景下不同的取舍。我可以提供一些不同场景的例子。


如果我们是一个创业公司,或者是大公司的内部创业,正在做一个探索新市场的新产品。大家对这个新市场不是特别有信心,希望尽快通过产品验证市场是否存在,不存在的话就换方向或者撤销团队。这时候重构代码的优先级就很低了。或许几个月后发现假象中的新市场并不存在,现在的代码写得再烂,几个月后都随着产品下线而全面删除,谁在乎它烂呢?

这背后是有真实的故事的。Facebook 曾经做过一个针对拉美的应用,叫做 Flash,跟 SnapChat 很类似但这是在 Facebook 主应用之外的一个独立应用。Flash 花了 3 个月就发布了第一个版本,我们团队跟 Flash 团队合作,基于他们的代码进行二次开发,有时候会因为代码质量踩坑,我们非常希望 Flash 团队维持很高的代码质量。但他们的目标就是快速验证拉美是否存在一个低端用户的 SnapChat 市场,所以他们就一直往前冲。又过去了三个月,他们团队进行了一次内部讨论,到底接下来应该继续往前冲,还是先重构一下代码以便将来跑得更快,最后他们选择了继续往前冲。

我们团队虽然不喜欢他们这个决定,但这是一个正确的决定。做决定之后的三个月,他们做了最后的冲锋,把值得做的事情都尝试了一遍,最后的结论就是这个市场不存在或者说不值得做。Flash 应用下线,代码全部删除,团队解散。重构并不会改变这个结果,之后稍微推迟这个结果。从商业的角度来说,重构导致了近期成本,但不会带来长期收益,所以不应该进行重构。


如果我们是一个做券商的金融创业公司,那取舍的方向就可能很不一样。我们的首要目标是评估代码出现逻辑错误导致的财务风险。如果我们做的只是现金业务,财务风险是有上限的,也就是所有用户存放在我们这里的现金总量。在最坏的情况下,我们可以把所有用户存放在我们这里的现金都归还给用户,然后可能再承担对应的监管机构罚款和诉讼赔偿,损失的总额是可以进行估算的。如果我们涉及到证券业务,财务风险可能就是不封顶的,因为证券交易可能涉及杠杆和做空。

在进行这种讨论时,需要注重两方面的思维能力:

第一,对商业运作涉及的风险有基本的认识。可以不是很懂面试这家公司的具体商业模式,但要有商业常识和词汇,能够跟面试官进行这方面的沟通,然后才能进行商业上的趋势。

第二,坚持第一原理思维。不要为了控制商业风险就进行重构,而要思考控制商业风险的最佳手段是什么,用这来判断重构是不是合适的技术手段。商业风险有很多非技术的控制手段,例如说买保险。就算是技术手段,也不一定需要是重构,可能提高测试覆盖比例的性价比更高。总之不要为了合理化重构而找一个商业上的理由,那如同拿着锤子找钉子,本末倒置。


从这一道面试题可以推导出来一个更加广泛适用的思维模式:不要别人问什么你就答什么。考试(包括 LeetCode 形式的上机考试)往往把人训练为问什么就答什么,因为问题是没有协商空间的。但在面试的时候,一个大活人随时准备好跟你对话,你必须先对问题进行协商。

这是我在做 career coaching 中时常会提醒客户的事情。尤其是面试 senior 或以上职位时,搞清楚面试题的第一原理很重要,你找到了第一原理然后才能围绕第一原理进行解题。至于引出问题的说辞,例如「开发新功能和重构代码之间怎么选」,这其实不是重点。有时候这个说辞可能是个「X-Y 问题」,但我们期望资深的程序员有侦测和解决 X-Y 问题的意识。

没有评论:

发表评论