转载自: 技术人核心竞争力:超越代码的思考
👉目录
1 超越需求:敬畏用户、理解用户、成为用户
2 超越流程:关注个体胜过流程工具
3 超越协作:边际效益的最大化
4 超越管理:催化剂与情感支持
5 超越代码:前灯范围内的设计与实现
6 写在最后
在团队日益注重流程与工具的当下,个体的因素反而容易被忽视。本文尝试从一名研发的视角,探讨在研发流程中,一些编码及编码以外的思考和原则,希望能为开发同学提供一些参考。
关注腾讯云开发者,一手技术干货提前解锁👇
对于软件开发人员而言,编码无疑是核心技能,自然也是投入时间和精力最多的领域。然而,在实际的业务研发过程中,需求的多变性、团队的紧密协作、用户的即时反馈、现网的故障排查、频繁的会议沟通以及历史负债的累积等因素,往往使得开发工作变得复杂而充满挑战。在这种背景下,开发人员可能会在“夹缝中开发,焦虑中编码”,尤其是在团队和业务规模不断扩大的时候。
当团队致力于优化流程和工具时,开发自身也可以通过积极了解一些编码之外的观念和原则,合理分配时间和优先级,更好地参与到研发流程中。
01
超越需求:敬畏用户、理解用户、成为用户
1.1 敬畏用户:反馈的冰山一角
记得之前负责某款作业类应用期间的一个深夜收到的一条告警:“同一用户反复提交作业失败”。这种个别用户的告警,也许很容易选择忽视。然而想象一下对方的情形呢,可能是一个孩子做完了作业却始终无法提交,焦虑地一次又一次尝试。这个问题后来被快速解决了,尽管这个故事似乎没有更多的后续,看起来也只是一次微不足道的故障排除。
一条告警很可能只是冰山一角,一次用户反馈的背后可能是成百上千用户的沉默。对用户保持敬畏,关注每一个细节,以确保用户体验的顺畅与满意。
1.2 理解用户:产品需求与目标的统一
需求评审前,需求的形成更多是产品经理的内部讨论,研发、运营、测试同学没有参与度,同时也没有把关键点和相关设计和研发同学进行深入的沟通和调研,导致评审时产生较大冲突,以及相关同学的参与感和主人翁意识不强,没有形成对产品的统一目标。再者,由于前期需求局部模糊性,随着需求开发的进行,产品在不断获得新的信息反馈后,免不了频繁对产品需求做出修改,进一步导致研发排期的不稳定和发版风险。
需求的提出者有理由让项目的参与者了解需求的来龙去脉,既是对参与者的负责,也是对最终的产品功能负责,同时也让开发更容易接受和理解需求的变化。产品需求与目标统一,也是产品经理与开发相互建立信任的重要渠道。
1.3 成为用户:用心体验产品
一个从不品尝菜肴的人,或许可以公式化的完成一道烹饪,但他很难成为一个出色的大厨。
你有多久没有认真体验过你的产品了,有多久没有和产品功能的真实用户有过沟通了解了,有多久没有给你的产品功能提出优化建议或者 debug 了,是产品已趋近于完美,还是没有那个闲心呢。你的团队,对于那些用心体验并时常给出好建议或者发现关键漏洞的成员,有没有鼓励呢?
产品功能是团队的集中智慧与辛劳的聚集,对于产品漠不关心,对于同事在做什么没有兴趣,如何形成责任心和主人翁意识,又如何对产品形成认同感,团队又如何产生归属感和凝聚力。回到用户中,重新成为用户,用心体验你的产品功能。
“为什么不玩玩咱们自己的游戏?”挨个去问你的同事这个问题。大部分人可能会嘲笑你,不屑于回答;也可能有人老实一点告诉你:“有什么好玩的,天天工作就是干这个,还不腻么?”如果这话是出自程序和美术之口,你可以无视,他们即使不怎么爱玩自己的游戏,也一样可以把本职工作做好,只是不够卓越而已。但如果类似的回答来自项目的策划,创意总监,策划主管之类的人,那么很不幸,也许最糟糕的情况发生了:项目的策划,尤其是主策划不热衷玩自己的游戏,是游戏研发中极端危险的征兆。这个说法有老生常谈之嫌,很像“你做的游戏自己都不喜欢,更不用指望别人”的翻版,不过对于策划而言,我认为这个经验值得被经常提起。 ——冯骥
作为开发人员,积极主动地去理解用户需求的深层含义、了解所有合作方的角色定位,并与产品目标统一,建立信任。特别是对于自己负责的模块,将自己置于用户的角度,用心体验、优化并主动沟通、反馈,不断提升自己的 debug 能力,增强对产品的认同感,深化自身的主人翁精神。
对待现网用户反馈时,更应保持一颗敬畏之心。看似平常的一条反馈,背后可能隐藏着许多严重的问题。时刻保持这种警觉,有助于我们更早发现并解决这些潜在的问题,维护产品的稳定性和用户的满意度。
02
超越流程:关注个体胜过流程工具
所有的流程和工具最终还是要落实到人,服务于人,解决开发者的痛点。既要让状态最好的人上场,同时也要让上场的人维持更好的状态。
2.1 并行过多,状态起伏大
在程序开发中,我们经常通过并行处理来加速完成任务。然而,在日常工作中,串行任务处理往往能带来更高的效率。
注意力点数
编程需要集中大量精力和注意力。然而注意力是一种稀缺资源。我们可能会设定闹钟提醒自己的待办事项,然后因为太忙又忘记设置闹钟… …你是否有过忘记提代码就打包了?你是否发版本发了一半被打断后就忘了继续?
并行处理太多任务会迅速耗尽我们的注意力,注意力耗尽后,继续进行需要高度集中注意力的活动变得不再适宜。这个时候,我们需要通过一些不需太多专注的活动来恢复,比如休息、喝咖啡或听音乐,这类似于游戏中的行动点系统。番茄工作法?它可以提供了一个专注工作的理由,给自己勇气在一段时间内不接受打扰。
WIP 追踪(Work In Progress,进行中的任务)
个人的 WIP 上限值不尽相同,就像每个人的注意力点数不同,一旦超载,效率会迅速下降。当新任务来临,而我们的并行处理能力已达上限,我们只能在任务之间不断切换,影响效率。就如下图中,背包要去承载大小不一、形状各异的任务,超出任务要并行就只能不断地拿出来装进去,来回腾挪… …
为自己或团队设置 WIP 限制,通过开发视角的看板实时追踪 WIP,以便及时调整。
优先级混乱
无论什么原因,我们总能找到办法逃避真正的工作,就像写“暑假作业”,总能找到调整优先级的借口,而把真正紧急的工作滞后。并行过多时,合理评估优先级,排除个人喜好和需求,按照真实的紧急程度来执行。
2.2 工时评估的差异
正如上面提到的,实际开发工作中是并行着诸多流程和琐事的,所以开发不要以100%的完全时间来评估工时,可以尝试一下计划评审方法。
计划评审(PERT,program evaluation and review technology):
O:乐观预估,这是个非常乐观的数字,一切顺利则可以在这个时间完成,事实上这个概率应当尽可能的小。预估因素:* 考虑历史上类似任务的最快完成时间。
- 考虑如果一切顺利(无延误、无问题)的情况下完成任务所需的时间。
- 可以询问有经验的团队成员或专家他们认为的最佳情况时间。
N:标准预估,也是概率最大的数字。预估因素:* 分析任务的常规流程和常见问题
- 参考过去类似任务的平均完成时间。
- 与项目团队成员讨论并达成共识,考虑正常的工作效率和可能的小延误。
P:悲观预估,这是最糟糕的时候,应当考虑到各种意外,比如第三方依赖的延期、个人事务处理等等,通常这个概率也应该尽可能小。根据以上可以得出一个预估的分布以及期望的时间,将这个结果反馈给项目管理人员,是一个避免了过度预估的合理方法。预估因素:* 考虑所有可能导致重大延误的因素,如资源短缺、技术难题、外部依赖等。
- 查看历史记录中类似任务遇到的最长延误情况。
- 咨询专家或团队成员预测在最坏情况下完成任务需要多久。
在实践中,开发人员经常需要提供精确的时间评估。因此我们应从多角度综合考虑,将各个预估的权重汇总,给出最切合实际的预期。同时把大任务尽可能拆小,然后再加总,会比单独预估大任务的准确度高很多。
通常我们不必对评估时间过度焦虑,在项目进行过程中,保持进度的透明度也极为关键。真正不能接受的是,表面上每日报告一切正常,而直到最后一天,突然宣布进度延迟。
估算精度
对于有些旷日持久的大项目时,当我们被要求给到工时评估的时候,通常出入也会比较大。这个时候要考虑提供多高的精度,大约125天、25周、6个月,你会发现这个单位会对结果的可信度产生影响。125天看上去很准确,是经过非常详尽的分解得到的,给人更可信的感觉。所以在做估算的时候,当你的数子足够大,不妨调整一下估算单位:
| 持续时间 | 估算单位 | | --- | --- | | 1-15天 | 天 | | 3-6周 | 周 | | 8-20周 | 月 |
2.3 说“不”
不要说试试看
不要轻易作出承诺,除非你确信能在某个确定时间点完成任务。面对要求你承诺不确定事项的情况,应立即表明立场拒绝。作为专业人士,学会说“不”,实际上是一种负责任的表现。如果完成某项任务的前提是需要连续加班牺牲休息,这种情况下应谨慎考虑并作出决策。
警惕排期陷阱
- 需求方的误解:“这个需求很简单,开发应该很快完成。”这种先入为主的观念可能会导致开发人员在评估时若给出较长的预估时间就被认为是“能力不足”。
- 模棱两可的需求评审:在需求评审阶段不明确需求,然后在开发过程中不断添加新的需求,这种做法将严重影响开发的进度和质量。
- 不断变动的截止日期:刻意压缩截止日期,然后再不断推迟,使开发工作长时间超负荷运转,这不仅会影响项目质量,还会严重损害开发团队的士气。
03
超越协作:边际效益的最大化
3.1 团队人数的边际效益
为了呈现一段绝美的乐章,不仅需要将各种技巧和不同乐器巧妙地结合起来,还需要在统一的指挥和节奏下协同演奏。然而,如果分配不当或者参与的乐手过多,不管每个人的天赋有多高或多么努力配合,最终的表演效果都可能受到影响。
1+1=3,两人良好的合作效率可以得到很大的提高,两人更能看到对方疏忽的地方,并且他们可以借助对方的能力,相互问责相互提升,达到更多的标准。
一定人数的精明强干且善于思考的人以开放心态讨论,通常能找到问题的最佳答案。更多人的团队人数看起来挺好,但合作的效果可能适得其反。给团队增加成员的共生效果是逐步递增的,直至到达一个顶点,过了顶点后将不再产生增效,反面带来效率递减。因为(1)边际效益随团队人数增多而减少,(2)团队人数过多时,互动效率低于小团队的互动效率。
“团队是小而稳定的实体,如果团队的成员经常被分配到其他地方,相互之间缺乏了解,那么这也不是一个团队,他们只是暂时同在一个公交车站躲雨的陌生人。务实的团队很小,充其量也就 10-12人左右。成员很少进出。每个人都很了解彼此相互信任,互相依赖。”———《程序员修炼之道》
3.2 会议与沟通
拒绝参加无效会议
会议是必需的,但同时又会消费大量注意力和时间。邀请参会的人不负责管理你的时间,为时间负责的人只有开发自己。确认你不需要参加的会议,可以礼貌的拒绝,不要勉强自己。
会议时间的建议,除了一些固定的宣讲日外,平时的会议尽可能不要打扰开发的黄金时间,别人可能刚刚进入深度开发状态,比如10-11点,14-16点等。
不要当快嘴王
经常在做业务分享、需求评审等会议中,都能遇到快嘴王,要知道听众可能没有你那么熟悉你所讲的内容。
快言快语的人表达问题时滔滔不绝、态度坚定且语速飞快,强行推进议程,使别人来不及评估检视或反对。快言快语在压制那些讲话慢且担心出丑的人时,显得尤为有效,但千万不要做这样的人。要认识到,你的责任是讲清楚事情,有一点没讲清楚都不要接着往下讲。
如果你对“快嘴王”感到有压力可以说一句“抱歉我比较迟钝,但是我希望你慢点说,好让我明白你的意思”,然后,该问问题就问问题,不要遗漏任何一点。
两分钟法则:你至少让人在两分钟内不受打扰的解释他的观点,不要急于插话表达自己的意见。
专心聆听
在每日站会或是周会上,很多人都不理会其他人,只是简单的等着汇报自己的更新情况,而且发言时能少说就少说,这让人觉得无聊。又或者有些人会在会上滔滔不绝,这需要明确杜绝,并在会下单独讨论。
目标明确、结论清晰
会议有明确的主持人,明确的目标,明确的议程,谨防跑题。所有会议讨论,都应该产出总结来结束讨论,如果达成一致应当明确指出,如果没有也应当说明。会议后的进一步行动、待办清单、任务分派、截止日期都应该清晰的进行记录和同步。
3.3 信息辐射与沉淀
杜绝个人英雄主义
长期忽略文档建设和技术沉淀,导致很多业务过于依赖某些员工,个人英雄主义。这对于业务本身来说也会产生巨大的风险,而对于员工来讲也会容易出现自扫门前雪的现象,同时无法对产品技术更好的掌握。而文档的缺失对于员工之间信息分享、新员工接替以及业务本身的交接都会产生巨大的成本。核心技术、核心能力没有得到沉淀,这些智力资产任由其留在个别人的脑海中、少数人的硬盘里或者被淹没于无序的文档中。
扩大业务视野
随着业务的发展,业务信息也会大爆炸,每一个模块的改动都会有很多关联模块的影响,扩大业务视野,理解上下游链路,才能更好的进行方案设计、排查问题。像迷雾模式一样去探索业务边界,扩大覆盖面,警惕黑盒功能,不要排斥获得更多信息,当没有足够的渠道去了解时,请主动反馈。
互相分享、知识沉淀,模块互备都是很好的扩大业务面的好方法。
在合理范围内尽可能扩大信息辐射
信息通道狭窄,未辐射到所有团队成员。需求阶段产品内部讨论,不与研发测试等同学阐明需求来源,研发过程中各个需求负责的同学只关注自己的模块,不参与也不关注其它同学的功能,长期以往会造成业务模块的壁垒。发布上线后的真实数据往往产品同学会单独讨论,也不会反馈给相应的研发同学,导致后者参与度不高,缺少产品统一目标意识,长此以往形成习惯,往往只停留在完成自己相应模块功能,流水线般机械生产,缺乏思考。
实际上,功能的研发和上线之后,获得实际的现网反馈是非常重要的,这可以极大地激发员工对产品的投入感和责任意识。
04
超越管理:催化剂与情感支持
4.1 石头汤
石头汤的故事,描述的是饥肠辘辘又没有粮食的士兵来到一个村庄,但村民们并不愿分享他们所剩不多的食物。于是士兵用石头煮了一锅汤,利用村民的好奇心,诱导村民主动将各种食物放入锅中。最终,他们煮了一大锅热气腾腾的汤。然后士兵将汤里的石头扔掉,和整个村子的村民一起分享了一顿美餐。
很多时候管理工作就像故事中的士兵一样,充当催化剂,把村民们团结起来,完成他们本不可能做到的事情,协作的成果。
4.2 团队成长阶段
每一个团队都有自己的成长过程,而成长的不同阶段,团队需要提供的帮助或者说领导风格也应该发生相应的变化。* 形成期,在这个阶段,人们还在努力明确他们的团队角色,他们想独立工作,但是也在努力合作,这个阶段的团队需要大量指导来熟悉他们需要完成的特定任务;
- 震荡期,随着团队对项目有了更多的了解,成员会对要如何去完成工作形成一些自己的看法。在开始时会带来一些争执,人们对于如何完成项目存在分歧,这个阶段团队需要大量的指导以及情感支持;
- 规范期,团队成员熟悉彼此后,开始不断调整自己的工作习惯,来相互帮助,大家开始学着相互信任,这个阶段团队不需要太多指导,更需要提供高层次的情感支持;
- 成熟期,一旦每个人都了解了问题以及其他人在做什么,他们开始形成一个有凝聚力的整体,并且高效的工作,这个阶段团队运行平稳,不需要太多指导和支持,只需要在出现特定情况时加以决策和处理即可。
4.3 既看过程,也看结果
“多看挥杆姿势,少看击中与否”,虽然很多时候结果很重要,但评价一个人或是一种制度,都需要留出一定的容错空间,当然重复犯同样的错是不能接受的。了解是什么样的人、什么样的习惯,可以更好的预知他未来能如何承担责任。评估一个人绩效,最好是既看过程,也看最终结果,毕竟扑克牌高手也可能在有限的时间内输给新手。
05
超越代码:前灯范围内的设计与实现
5.1 耦合与柔性策略
耦合是修改之敌,它将模块紧密联系在一起,要改就得一起改,这让修改起来非常困难。要么花上很多时间,弄清楚各个模块要修改的地方,要么就会因为修改不到位,把时间花在不断地问题排查过程中。
业务膨胀不可避免,每一个模块的增加都会增加耦合性,关联度越高,复杂度和迭代成本也越高。而且耦合有传递性,A 与 B 耦合,B 与 M/N 耦合,那么实际上A与 B/M/N 都存在耦合。当耦合发生,一个简单的修改会传播到其它不相关模块,开发害怕更改代码,因为不确定会造成什么影响。开会不知道拉谁,索性全部拉上,因为不确定会有多少关联模块。
当我们确保刚性,比如一座桥,就需要将组件耦合在一起,让结构得到刚性,不易变形。
当设计不断变化的应用时,我们希望他更灵活,更容易变化,就如下面这样。这样的结构没有了刚性,连接个体可以灵活变动,其它部分总能很快的适应。
5.2 ETC 设计(easy to change)
设计和编码的时候,考虑一下它是否易于变更,所谓的解耦、单一职责等原则,都只是为了让代码更易于变更。无论未来发生什么,这块代码都不会成为路障。ETC 只是一个观念,帮助思考和决策,当你保存文件时问一下自己,当你写测试的时候问一下自己,当你修复 BUG 的时候问一下自己。
很多时候与其在一开始浪费精力为不确定的未来做过度设计,不如把你的代码设计成最小成本可替换的,当有一天想要丢弃或更换时,可以非常容易和平滑进行。
5.3 不要超过前灯范围
小步前进
开车的时候,前灯只能照射一定范围,并且只在直线投射。在软件开发者,我们无法看到很远的未来,越远越黑暗,保持小步前进,不要过度设计,步子迈得过大。比如:估计未来几个月后的完成时间,猜测未来有的技术,猜测未来不着边际的需求。每一次调整,都在得到足够的反馈后继续前进,好比给小孩喂辅食一样,每一种辅食单独添加并观察足够天数后再添加下一样,才能让孩子更好的接受和排敏。
上面石头汤的故事也给带来了一种思考方式,即通过先展示简单的原型或演示,吸引他人的兴趣和参与,从而验证和改进我们的想法或方案。这种方法可以帮助我们快速获得反馈和意见,并获得更多的资源和支持。同时,它也可以帮助我们避免过度设计或过早优化的问题。在软件开发中,我们可以借鉴这种思考方式,以更高效和有效的方式推动项目的进展。
多好才算好
你所开发的软件要好到什么程度呢?如果你正在编写起搏器、航天飞机或广泛使用的底层库代码,那么需求质量会非常苛刻。但如果你正在开发一个全新产品,市场、用户、KPI 等待都会成为新的要求。无视来自用户的需求,一味的堆砌功能,这是心浮气躁的表现。许多用户宁愿三天内用上一个毛糙的版本,也不愿意等一年去用上一个打磨光亮、功能齐备的版本,但实际上一年后需求可能又完全不同了。
轻量开发
敏捷开发作为一种“轻量型”开发方式,其简单要求体现在整个项目的各个方面,只要是当前不必需的就不必考虑。如果我们可以用图片表示当前设计方案,就没有必要把他总结为一定格式的文档;如果当前功能是不需要的,我们就不用把它更新到功能图中;当前完成的功能只需按照当前的要求来做,不需要过分考虑可能要增加的需求;无需大量的前期设计,重视最后的可用产品。
5.4 不要跳出框框,尝试找到框框
我们总说跳出框框看问题,但是在做设计的时候,尤其是中台设计、通用库等功能的时候,如果不能确定好应用的边界,找到约束条件,功能和设计会变得啥都想做,越做越多,慢慢就脱离了轨道。等到项目上线,虽然功能丰富,却变成了一个杂拼的产物,使用起来一言难尽。
5.5 与代码同在
为代码署名
正如每块城墙的砖石都承载着工匠自豪的签名,编码亦应如此。避免匿名编程可防止粗心、错误、懒惰乃至劣质代码的产生。因此,请自信地在你的代码、文档和功能中留下签名(注意 GIT 提交记录可能并不准确),“这是我完成的作品,与代码共存。”你的签名代表了质量的承诺,体现了专业工作由专业人士完成的理念。
让复用变的容易
完成代码后发现早有相似实现,可能源于信息共享不足、团队交流缺失、不充分的调研,或认为既存代码是一坨,难以重用而倾向于重新编写。有效的团队沟通和紧密联系通常能够预防这类问题。鼓励开发人员经常性地进行交流,共享知识(包括专题分享和轻分享)、代码审核,建设团队论坛也是促进这种文化的好方式。
交流和分享是互惠的活动,认真研读他人的知识沉淀,是对他人的尊重。这不是偷窥别人的工作,而是在向他们学习,不要想太多。事实上,在系统内每一处知识和策略都应当是集中、单一、清晰并权威地表达,避免不必要的重复。
良好的代码命名
这是一组颜色和文字组成的图,但是名字和颜色不一定匹配。尝试说出每种颜色名字?再尝试说出字的颜色?是不是读出文字容易,识别颜色就难多了。
请在代码里使用尽可能准确、无歧义的命名,能用 buyer 就不要宽泛的用 user,并且保持命名统一,既是团队内统一,最好也与合作方保持统一。
破窗与亡羊补牢
"破窗效应"在程序开发中非常常见,任何一种不良现象都将传递一种信息,这种信息会导致不良现象的无限扩展。如果有破窗的存在,及时亡羊补牢,那便为时未晚;若一味放任,则将造成更大后果,后悔莫及。
5.6 重构与松弛
何时重构
- 发现了大量重复的功能和代码;
- 过时的逻辑和知识点,需求已经偏移;
- 上线后发现大量冗余功能和设计的存在;
- 性能不足,急需提高。
松弛一下
重构实际上是一种疼痛治疗,发起重构需要考虑它的收益、成本以及不去重构的隐患。没有时间重构么?
尝试为每个迭代增加一个叫做松弛的简单实践,团队使用松弛为每个迭代增加额外的工作量。松弛也就是加入少量可选和不太重要的项,如果将来进度落后,可以先去掉这些工作项。反之,团队可以利用这段时间进行代码重构,避免历史债务的累积。
06
写在最后
本文旨在为开发同学提供一些在实际工作中超越编码本身的思考和原则。通过敬畏用户、优化流程、强化协作、提升管理和精炼代码,我们能够更好地应对复杂多变的业务需求,提高团队的整体效率和产品质量。希望这些观点和建议能对你有所帮助。
参考资料
- 《代码整洁之道-程序员的职业素养》
- 《程序员修炼之道:通向务实的最高境界(第2版)》
- 《原则》
- 《精益产品和流程开发》
- 《Head First敏捷开发》
- 《研发困境突围》
- 《优化之道:生活中的运筹学思维》
-End- 原创作者|范云阳
除了开发技术,你觉得程序员应该还具备哪些能力?欢迎评论留言。我们将选取1则优质的评论,送出腾讯云定制文件袋套装1个(见下图)。2月6日中午12点开奖。
📢📢欢迎加入腾讯云开发者社群,享前沿资讯、大咖干货,找兴趣搭子,交同城好友,更有鹅厂招聘机会、限量周边好礼等你来~
(长按图片立即扫码)