论我眼中的基本工程师素养

thumbnail

最近两个迭代,临近发版之前又是喜闻乐见的改 bug 时段。有些人的 bug 修复效率很高,两到三天就能修正几乎所有 bug,然而也有部分人只能用按下葫芦起了瓢来形容,修正一个 bug,可能会导致两个或者更多的潜在 bug。借这个案例,我希望谈谈我眼中的工程师基本素养。

前瞻性与规划能力

这一部分在我看来,是任何一个软件工程师需要具备的基本能力了。其中涉及到这么几个方面:

  1. 将产品的需求解读成与之对应的技术设计
  2. 补全产品在设计时未能考虑到的点,并与产品确认这些点的详细设计
  3. 在实现需求前书写一份功能蓝图,提前预算实现需要的时间
  4. 在正式开发开始前,指出项目中的实施难点,并在会上尽量提早说明

接下来,我会结合实际开发经验,说明为什么前瞻性与规划能力是开发的必备能力

解读需求

Lowcode 是一个重研发驱动的项目,很多的产品在规划需求的时候,往往会从以往面向客户的产品下手进行规划。但是对于 Lowcode 这种面向开发的产品来说完全不是如此,工具最重要的是其能提供给你的功能,而不是外在的样式、操作交互之类的东西。客户不会为了一个徒有其表的产品买单,工具真正具备价值的点从来都是效率。因此在规划需求的时候,就需要开发充分参与需求的规划,对产品的需求予以修正,最懂开发痛点的人往往是开发。

针对需求的技术设计同样是很重要的,首先需要将产品的需求拆分成合理的层级,然后根据目前的需求,以及未来可能会产生的需求进行项目的层级划分,尽量保证会频繁变动的需求被锁定在一个固定的层级中,且不会对业务场景中的其他代码产生影响。

如果事先没有好的设计的话,很容易导致代码难以维护。例如修改了其中的某一部分,然后对其他不可预知的层级同样产生了影响,最终导致 bug 越改越多,甚至最后只能将旧代码舍弃重新书写。隔离变化,正是为了避免这一情况的发生,让所有的变动都是可预期的。

需求补全

产品在进行功能设计的时候,经常会出现某些原型未能覆盖到的点。这需要技术具备一定的前瞻性,提前指出需求中缺失的功能点,避免未来验收测试的时候出现产品与技术之间的拉锯战。

很多技术都将自己当成了实施人员,拿到原型的瞬间,只考虑能够满足产品的需求,对于产品需求以外的部分从来不予考虑。这会导致产品与技术在回归测试中陷入不断的拉锯战,产品将设计原型时未仔细考虑,但实际使用中出现问题的部分都当成了 bug 统一汇报给了研发,从而导致研发在迭代末期,为了补全产品在设计原型时未能考虑到的点疲于奔命。因此,在设计之初,务必需要仔细斟酌需求本身,判断是否存在需要补全的点。迭代初期考虑充分的话,可以大大减少迭代末期的返工 / 拉锯时间。

估算实现时间

每个迭代初期,开发都需要对本个迭代需要开发的功能进行预先估算。这个估算的时间,一般是你自认为的实现时间 * 3。这个周期对于开发来说一般比较稳妥。

为什么要取自己估算的时间 * 3 呢?很简单,迭代初期在不了解需求的情况下,往往容易对需求真正的实现时间产生误判。我们往往会将一个自己不了解的需求想的很简单,从而导致判断的时间远小于开发时间。因此在规划之初,就需要为自己后续的开发留出充分的缓冲时间,以应对开发过程中各种不可控因素。

如果预估的时间比实际实现时间长的话如何?实际上也不会存在太大问题。技术经理与产品在你确定工期时,往往对整个迭代的实现效果都会有固定的心理预期。如果你能先于他们预设的心理预期实现需求,那当然是皆大欢喜,同时充裕的工期也为各种意外情况留出了充分的应对空间,当然还有个额外的好处就是可以摸鱼(逃)。

提前指出实现难点

这一点同样是建立产品心理预期的一环,非技术很难意识到实施过程中可能存在的各种问题。而我们在迭代初期,如果能预先计算出实现难点,在会上提早指出的话,也同样是为后续的攻坚预留了时间。同时技术经理也能提早获知需求实现时可能会存在的阻塞点,在迭代中期难点久攻不下的时候,也可以寻找更合适的人选协助攻坚。

与之相对的反例,就是实现需求时才意识到难点。当你意识到难点,并投入时间攻坚且久攻不下的时候,往往都已经是迭代末期了。这个时候,能够留给技术经理的选择实际上少的可怜,这种情况同样也会严重影响自身的开发信誉,让其他产品产生 ‘这个研发不靠谱’ 的印象。

获取新知识的能力

产品需求实现时,难免会遇到一部分公司内从未有人做过的需求。这部分需求极度考验开发获取新知识的能力,亦或者也可以说,是在考验一个开发日常的积累。

前文中所提到的上班摸鱼,对我来说并不是上班刷小说、刷微博、闲聊天之类的事情,而是上班期间,抽空看各种各样的文章 / 项目,思考这些项目的交互设计、代码结构、采用的设计模式。这些知识对于一个开发来说,属于日常经验的积累。短期看来,这些经验对于你目前的项目没有任何帮助,但是未来的某一天,当你接到一个前人从未尝试过的新特性时,往往能从以往的各种经验中获得各种灵感,从而启发现当下的项目实现。

Lowcode 项目进行到现在,启发项目的源头,往往不是其他公司的 Lowcode 项目,而是软件工程实践、是各种设计模式、以及各种代码库的底层实现原理。而这些经验,都是来自这些日常看来对开发毫无用处的文章 / 项目。

处理 Lowcode 这个项目的时候,特性设计往往会伴随着极多的试错。市面上已有的方案,出于商业保密的考虑,不会像你透露详细的技术设计。因此对这类技术做解读,会是一个很漫长的试错 + 反复尝试的过程。市面上的技术方案所提供的是一个黑盒子,你需要把你日常积累的技术套到这个黑盒子上,如技术 A + 技术 B、技术 A + 技术 C 这样反复试错。而技术积累的越多,这个试错的过程就会越短,这也是开发经验的另一种体现。

丰富的基础知识

我只是个开滴滴的司机,为什么需要了解汽车发动机的构造呢?

很多人都对大公司注重底层知识的行为不屑一顾,诚然,开发基础业务逻辑的话,基本不需要涉及到基础知识的使用。然而当你需要去设计一个新功能,或者是设计一整套项目架构的时候,这个时候就十分考验你对基础知识 / 底层原理的运用和了解。

例如,Lowcode 项目的组件,实际上就是借用了 React 对组件抽象的模式,将组件分成 rendererpropschildren 这几个部分。而 Lowcode 的事件,又从 Mobx 的事件调度机制中获取了不少灵感。如果对底层原理了解的不够透彻的话,接到这几个需求的设计任务的时候,往往处于一种无从下手的状态。

同样的,其余领域的知识,有时候会启发你在前端领域的相关设计。举一个很简单的例子,Mobx 的事务和 atom 就是借用了数据库的原子事件机制。而 Mobx 内部的事件编排与数据库原子事件也存在一定的相似性。

诸如此类的示例,不断提醒我们:对技术不光要知其然,还要知其所以然。*

不局限于某个领域

上一部分提到的:其余领域的知识,会启发你在前端领域的相关设计。这一点如果从另一个角度解读的话, 就是不要将自己局限在某个技术,或某个特定领域中。React 开发就一定不需要了解 Vue 吗?前端开发不需要懂 Nginx、Docker、Kubernates 吗?前端开发就一定不需要了解后端 api 书写吗?答案当然都是否定的。一个优秀的 Web 前端,首先是一个优秀的软件开发工程师。而前端这个 Tag,并不是你拒绝了解其他领域的理由。

小结

本文所提到的工程师基本素养,是我在日常开发中总结出的几个点。以上总结并不保证完全正确。未来的某一天,当我在开发这个领域积累了更多的经验,我会进一步优化这篇文章,重新谈谈我眼中的工程师基本素养。

© 2020 — Douglas/rss
友情连接/卡拉搜索