2022年8月24日星期三

求助于别人的正确姿势

什么情况下应该求助于别人?求助于别人是否就是伸手党,就会被人鄙视?我在做 career coaching 的过程中发现这是个常见问题,决定拿出来专门写一篇文章。Facebook 的 Bootcamp 在这方面对新人做了很多意识方面的训练,非常值得参考。

在 Bootcamp,专门有一个区域是给 mentor 提供 office hour 的,目标类似于学校里的 office hour(课后问答),如果作为新人的 bootcamper 在工作过程中遇到了问题,可以去这个区域进行提问。新人当然会问:那我该什么时候去提问?标准答案是:如果你自己捣腾了一个小时还是毫无进展,你就该去提问了。

跟学校作业不太一样的是,Facebook 布置给 bootcamper 的任务并不是标准答案已知的练习题,而是实际项目中不紧急也不重要的任务,每一个任务都不一样,mentor 不会提前知道问题,也不一定总能找到正确答案。新人在 office hour 提出问题后,mentor 都会问「那你都尝试了哪些办法?」如果有人说不出来,那 mentor 都会说「你先回去自己捣腾一下,如果一个小时了都毫无进展再回来提问」。

在新人解释完自己尝试过的办法后,如果 mentor 知道答案,可能会直接告诉他答案,把相关文档的链接发给他;如果 mentor 也不知道答案,他会亲自动手,把新人写了一半的代码拿过来 debug,试着解决问题;如果 mentor 解决不了,但知道谁可能提供有效帮助,他会把新人介绍过去。

就这样简单地一个过程,它强调了几种在 Facebook 成功必要的意识:

  1. mentor 必须授人以渔,bootcamper 必须求学捕鱼,不可以伸手要鱼。之所以问你尝试过什么办法但不成功,是因为接下来 mentor 必须要告诉你或者示范给你看什么办法能成功。你不能说「我捕不到鱼,请给我一条鱼」,正确的提问方式是「我用这样的方式捕鱼,我试过了但什么鱼也捕不到,请教我正确的捕鱼方式」。
  2. 即使面对你完全不懂毫无经验的问题,动手开干是最好的学习方式。动手开干不一定是写代码,动手开干也可以是搜索和研究。这跟在学校课程遇到问题存在一个本质的区别:学校课程能遇到的问题,都有已知答案,已知答案都属于一个清晰明了的知识体系,教材总能站在一个对该领域无所不知的角度帮你讲清楚一切。实际工作上的问题,往往你只能获取到碎片化的相关信息,然后再加上你自己的捣腾,产出一个可用的结果。你必须拥抱「真相在一定程度上不可知」然后冲上去捣腾。
  3. 你能直接接触到的人不一定有你需要的信息,你需要学会找到正确的人来获取正确的信息。这也是跟学校成体系的知识和课程结构很不一样的。在学校,你可以假设教这一课程的人对课程知识范围无所不知,你去 office hour 提问肯定能得到答案。在工作上需要获取的信息,有可能需要经过多个节点才能获取到,这个人建议你问那个人,那个人建议你问另一个人。你虽然不确定要经过多少个节点才能获取到你需要的信息,但你最好有一套方法能够收敛你和目标的距离。

修炼好这几种意识,即使不在 Facebook 工作也能让你更好地在需要时求助别人。即使你做不好后面两点,你至少要把第一点做好。


我在 career coaching 时有时候会遇到客户这样的顾虑:我向比我资深这么多的人求助,会不会是很浪费他们的时间?面对这种自我怀疑,你必须调整心态,把自己放在一个能够双赢的角度来思考你们的处境。

首先,你要确定你想要求助的事情确实重要。如果是工作上遇到的问题,你要确定解决这类问题是符合公司利益的,站在公司的立场来看这类问题确实值得解决。这时候无论是你解决还是别人解决,这类问题都是要解决的,这奠定了双赢的基础。

接着,你求助的态度必须是「请教会我捕鱼。我也不想总是找你要鱼,所以教会我捕鱼是符合双方利益的双赢选择。」对于公司来说,这是个三赢的选择,公司解决了符合公司利益的问题,你学会了可以重复使用的技能,帮助你的人将来不需要反复地帮助你。

最后你当然要把这实践执行到底,不能在别人教你捕鱼时捕到一条鱼就走人。尽管这一条鱼满足你此时此刻的需求,但很可能你还没有扎实的学会捕鱼,下次又要劳烦别人。你表明了你想学,你就必须比教你的人更投入地学。


「求助于别人的正确姿势」应该有一个镜像话题「帮助别人的正确姿势」。这是新手 mentor 时常会遇到的问题:我觉得帮助我的 bootcamper 非常消耗时间,但我不帮他又不行,怎样把握这个度呢?我可以下次写一写这个话题。这个话题不仅仅对 mentor 有用,对 mentee 也有用,因为在知道 mentor 如何才能更高效地帮助你之后,你也能更高效地利用 mentor 的时间。

这篇文章首发于我的 Patreon,对同类文章感兴趣的话可以考虑在 Patreon 上支持我,付费订户可以提前至少一周阅读到我的最新文章。同时也欢迎大家通过邮件RSS/Atom 免费订阅我的博客。

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 问题的意识。