最近逛 Hacknews 发现的一篇文章,读完感觉很有启发,翻译分享出来~ (瞎翻译的,建议有条件食用原文)

原文是 Things they didn’t teach you about Software Engineering (vadimkravcenko.com)


免责声明:本文的各种观点是非常主观的,但无论你是拥有丰富经验的从业人员,还是刚进入这个领域的新手,我都希望你能有所收获。

虽然从 2022 年中期开始,我就一直想写这篇文章,但我当时并没有准备好。因此在过去的一年里,我一直在收集记录想法。终于,我有了足够多的观点想与你分享。

你几乎不会从头开始实现什么

在上大学时,学校会教你如何写一个 400 行的程序来从头到尾解决一个问题,比如用你那天才大脑里的花哨算法去生成一个迷宫。对于遇到的任何问题,你似乎总能找到很好的方案解决掉,对吗?

很遗憾,事实并非如此。在现实工作中,你的工作往往是:从一个有着几十万行代码量的仓库中,想办法弄懂你的同事在写某一块代码时,脑袋里到底进了什么水。你在文档和更懂代码的大佬之间来回跳跃,终于,你熬到了周末,写下了几十行代码,修复了一些 bug。这个流程会重复进行下去,直到有一天,你成为了那个更懂代码的大佬。

img

职业程序开发者不过是效力于公司某个组的螺丝钉,只负责代码中很小的一块。并且更多的情况下,他们的工作是去修复 bug 而不是从头创建什么东西。因此程序员工作并没有如 HR 小姐姐描绘的那般迷人,编码只是其中很小一部分。

业务知识比编程能力更重要

当你精通了业务的底层原理和逻辑时,编码会变得水到渠成。比如当你想做一个银行 APP 时,你最好了解交易、资金结算、账簿等等东西是如何运作的;当你做一个餐厅销售系统的时候,你最好弄清楚服务员是如何服务的,食物库存是如何管理的,以及信用卡认证是如何工作的。简单来说,你要搞懂你软件所跑的业务知识,包括不限于医学、物流、记账等等。

如果没有这些业务知识,你很难做出有意义的贡献,也不能向雇主体现你的价值。反之,你所掌握的业务知识能让你更轻松的找到另一份相同领域的工作。

写文档!写文档!写文档!

大学教育教会你从事软件开发所需的基本技能,比如算法和数据结构。然而,“编写干净的、有良好文档的、可维护的代码”的教育却总是遗漏了。

img

那一天,当研究别人的代码并试图理解和修改的时候,开发者 回想起来了被支配的恐惧, 意识到了代码可维护性的重要性。兄弟,你知道当一份良好的文档摆在我面前时,我有多泪目吗?!而这些在课堂上很难学到,需要被现实毒打后才能最终意识到:写出好的文档和易于理解的代码可以节约大量的时间和精力。

商业价值比代码本身重要

没有人会拍拍你的肩膀说,“哇,老哥,你第 42 行代码写的太棒棒了,什么样的脑子才能想出这样的实现啊!”。他们只会说,“客户对你写得功能很满意。”,或者,“你写得什么东西啊,特么让整个网站崩溃了!”(取决于你的运气怎么样。)

可能比较毁三观,但事实如此,软件工程师的意义不在于编写代码,而是通过编写的软件创造价值。代码只是实现这一终极目标的工具罢了,代码 -> 软件 -> 价值。

你写的东西要给世界带来一些不同 – 可以是一些用户依赖的工具,或者一些降低成本的自动化产品,或者任何用户愿意掏腰包的东西。我说得直白一点,如果你用屎一样的代码做出了伟大的产品,恭喜你,你可以骄傲得说自己是一名软件工程师!但如果你用伟大的技术做出了屎一样的产品,…,洗洗睡吧。

注意!优雅的代码、最佳实践、聪明的解决方案、设计模式 – 这些东西是为了让你能和其他工程师更好的合作,而不能帮你实现价值。(当然,伟大的产品代码往往也不能写得太烂)。

你需要和呆子共事

你工作中总会遇到一些 傻逼 不称职的人,他们可能是你的主管,你的合作伙伴或者客户。

和他们打交道是非常心累的。他们污染了工作环境,决定做得又慢又臭,拖累了整个团队和项目。甚至凭一己之力,带来了不断的延期和返工,浪费了宝贵的时间和资源。

学会如何在不打人的情况下和他们有效合作花费了我很长时间。以至于我总是在想,这应该作为一门大学课程里所教授的技能。

img

我发现一个有效的方法是保持自己的生产力,而不要太在乎别人的问题。比如尝试默默寻找更有效的解决方案而不让那些麻瓜参与进来。另外保存记录也很有帮助,可以证明失职的是他们而不是你。

归根结底,处理无能者的最好方法是 – 打不过就跑,具体来说:

  1. 寻找额外的资源或支持。
  2. 想办法把任务委托给更有能力的人。
  3. 做一些故障防御工作让你负责的那部分不会出问题。
  4. 私下和那些家伙聊一聊,让他们意识到自己拖累了进程。
  5. 再强调一下,不要打人!

你的工作总是充满了不确定性

和人打交道很难,和不确定性打交道也很难,和充满不确定性的人打交道更难!然而,作为一个软件工程师,这是你必须要做的工作。

人们往往不知道他们想要什么,并且有时候,他们不知道一个看似简单的变化可能带来巨大的复杂性。“什么,你说我们不能从微信支付直接换成支付宝,他们不都是扫码支付吗?”

大学老师在撒谎,他们告诉你:哎呀,项目经理很牛逼的,他们会给你一个准确的、简单的需求,告诉你需要做什么,你尽管写代码就好了。比如让你 “画一个曼德拉集合” ,或者 “用XXX做一个XXX”。经过一天的头脑风暴,你有了一个实现方案,开心的与你的项目经理击掌,微笑着回家。

然而实际发生的确是:你的业务负责人会带着一张 PPT 大纲告诉你,“我们需要一个东西,从 A 到 B,但目前还没有任何设计,第三方服务也在等我们的需求。老板甲希望它是红色,老板乙希望它是绿色… …”。而这,才是软件工程师“真正工作”的开端 – 收集需求,搞清楚需要做什么。

收集需求并不容易,它也不像写代码那样有趣,但需要花费你相当长的时间。因为收集需求需要与人而不是机器打交道 – 给第三方服务机构打电话,与他们的开发聊天,了解要做啥。还要和金主爸爸坐下来好好聊一聊,告诉他们想法中的不合理之处以及替代方案。

在你写下第一行代码之前,可能需要好几个星期的准备工作。你需要弄清楚需求是啥、如何实现、哪里可能出错等等,然后写下第一行代码。

相信 Bug 总会存在

开发者总是有一些不好的想法:

  1. 你不相信自己的代码,因为你知道你是个人类,会犯错误。
  2. 第三方库极少 bug,它们可是大佬写的啊,对吧?
  3. 操作系统的标准库不应该有错误,对吧?他们可是巨佬写的啊。
  4. CPU/硬件永远不会出错,对吧?人们花了那么多时间研发,不应该有问题。
  5. 肯定不会停电!2333

但事实却是 – 我们永远无法保证我们的代码、库、甚至硬件不会在某个时候出问题;相反,我们要假设它总会发生。纵是是天才也只是人类,也会犯错误。

img

如果你打开 Github 上任何一个流行的库(操作系统或者应用级别的),点开 issue,你会看到大量的 bug 等待着被修复。别的不说,我可怜的 Linux 电脑不知道因为 segment fault 崩溃了几次了,crazy!

通过假设 Bug 总会存在,我们可以采取措施来预防或减轻潜在的问题,最终确保我们系统的可靠性和稳定性。

这不是一个完美的工作

无论你的辅导员或者 HR 小姐姐怎么和你说的,什么“从事 IT 工作后,你将升职加薪、当上总经理、出任CEO、迎娶白富美、走上人生巅峰”,都是扯淡的。

img

事实是:

  • 这是一项艰苦的工作。你一天大部分时间都将坐在电脑前。
  • 很少能工作生活平衡(WLB)。在其他行业,你 6 点准时下班,忘记工作,享受生活。而在这里,你很可能要一直在线并检查代码,甚至在深夜。
  • 你很少会编写你喜欢的代码,更多的时候,你只是在完成乏味的工作。
  • 职业发展机会有限。即使你是一个表现出色的人,也可能没有空间让你在公司里升迁。
  • 压力很大。Deadline,Bug,以及客户的期望都会增加你的压力。
  • 孤独,特别是远程工作时。根据公司和团队结构的不同,软件工程师可能长期在孤独中工作(不包括视频通话),导致缺乏真正的社交活动。
  • 工作不稳定。随着技术的不断发展,软件工程师很可能被优化淘汰。

品味是不能速成的

学校教我们如何写代码,但无法培养我们对代码的品味。

品味是指对代码的整体看法和感觉。比如它有多容易阅读、理解和维护。味道好的代码是干净的,有组织的,并且有逻辑。好的品味让你在看到好代码时感觉良好,或者看到糟糕代码的时候感到害怕。

不幸的是,品位是无法在一个学期的课程中教会的。它是通过阅读大量的好代码以及维护坏代码而获得的。

预估很难、但很重要

主管们喜欢数字、估算,以及给你一张写满想法的卫生纸,并要求你估算。这就是现实世界的运作方式 – 企业有一些财务目标,但在开始之前,需要了解成本是多少。

但同样,学校无法教你这个,因为预估的准确性高度依赖于你过往做项目的经验。你过去所解决的问题越复杂多样,你就越容易预测未来的工作。

img

我不打算讨论做预估的最佳方法;有几十种方法可以做。但我想说的是,预估对于企业至关重要。如果你说 “我们有长期规划,但我不知道我们什么时候能完成”,那你的企业多半快凉了。

在我的公司里,我们通常会粗略估计整个项目,以衡量需要分配多少预算 – 这是长期目标。之后,我们基于敏捷开发,整个团队坐在一起讨论、制定计划,并优先去做一些短期目标,使得我们不断靠近长期目标。

不是所有的会议都是无意义的

软件工程师几乎没花多少时间写代码,那时间都去哪了?开会去了。

会议的目的是确保一切在按计划进行。它使得每个人围绕共同的目标,步入正轨。在会议中,市场部能知道你开发了什么,好为发布做准备;项目经理能摸清开发人员的方向,并可能需要适当修正线路;客户支持部能提供客户那边的新需求;质量保证部门能分享他们发现的问题;管理层能分享金主爸爸们的最新诉求。

img

所有这些都是相互关联的,而会议就是分享这些信息的地方。作为一名软件工程师,你要对会议的某些部分负责。你可能不喜欢它,但为了保持系统的效率,信息必须得被共享。

结论

如果你立志当一名软件工程师,请准备好直面这些事实,拥抱成长的机会。坦率的说,你很可能不会给世界带来什么改变,但归根到底,这只是一份工作,你完全可以通过其他的方式给世界带来有意义的贡献。

但最重要的是 – 玩得开心!