浅谈研发实践的技术债与效能提升

在软件研发过程中,往往随着为了快速满足业务要求的压力,用户需求的变更,软件代码的增多,以及版本的迭代,团队成员的变化等等因素,导致一个软件项目随着时间推移,欠的技术债会越积越多,用户使用容易出错,部署流程也变得复杂。

技术债务不及时还掉,就会产生“利息”,进而导致软件复杂度呈指数级增长。代码行越多,逻辑越复杂,技术债务就会欠的越来越多,最终到了某个临界点的特定时刻,软件代码就会变得失控,没人知道里面改动会带来什么后果。每一次的需求修改调整,引发即使很小的代码修改,可能由于软件复杂度变高,都会带来新的问题,轻则导致软件无法正常使用,重则导致出现严重的问题,甚至系统崩溃无法正常使用等问题。随着时间的累积,导致问题处理和修复耗费大量时间。

而这种失控,在实际软件开发过程中,是一个普遍的现象。熵增定律告诉我们,孤立系统总是趋向于熵增,最终达到熵的最大状态,也就是系统的最混乱无序状态。熵是无序的混乱程度,也就是说世界上一切事物发展的自然倾向都是从井然有序走向混乱无序。软件也不例外,如果不进行适度控制和优化,也必然朝着混乱的方向行进。

在实践中,团队技术人员通过多种办法来提高软件研发效能,调整软件研发模式,以流程、方法等方式持续提高软件质量,最终提升软件可用性,以及用户体验。从笔者的过往实践来看,比较常见的有:

1.从需求分析与输入端控制

2.从软件架构与设计方面提升

3. 从团队协作与组织方面提升

4. 从软件代码质量与测试方面提升

5.从研发模式与工作流程方面

6.软件项目管理与部署发布

这篇文章,下面就以个人粗浅的理解,概要式的进行一些初步的分析,后续我们针对具体的每个方向的主题,逐步再进行详细的探讨。

需求分析与输入端控制

需求输入端的重要性毋庸置疑。软件要解决用户的什么痛点,用户会在什么场景下使用,做什么样的操作,来达到什么样的效果,解决了什么样的问题,这些要做一款软件需要考虑的首要问题。

而对用户真实需求的分析,做出符合产品定位并满足用户使用的解决方案,其中需要有很多的思考和分析,如何以高效且低成本方式做好,是值得长期研究和实践的话题。

ToC类软件和toB类软件的用户属性不同,需求侧重点不同,在做需求分析时候,做好需求分析,需求挖掘,以及需求的验证等也都不同。

在实践中,往往也会存在很多的伪需求,以及被忽略的隐含需求。功能性需求只是一方面,但决定软件成败的,往往是隐含的非功能性需求。

在进行软件需求分析时候,需要对于功能的完整性、功能前后一致性,以及逻辑合理性等进行论证,也需要考虑到需求是否可落地实施等。

需求分析和输入端的分析和控制,对软件的研发时间方向起着至关重要的作用。往往多一个需求,或者一个功能流程的变化,就足以使得后续的一系列软件流程随之改变。在软件需求阶段,做好需求分析,需求确认,以及需求评审,是很重要的一个环节。

软件架构与设计方面

当需求确定之后,就需要进行软件设计了。软件规模的大小,用户的使用场景差异,就决定着软件的设计方式,就一般的普通软件系统而言,采用单体软件、前后端分离、分布式云架构方式,采取公有云、混合云、或者私有云模式部署,都对整体软件设计影响很大。

软件整体架构的选择,不仅仅需要考虑功能方面,也需要对系统的可用性、性能、可扩展性、文件存储、消息处理、接口协议、通信方式等进行考虑,从基础模式上做好设计。

一般而言,常见的软件系统由前端UI展示层、服务应用层、业务逻辑层、数据持久化层组成。不论是单体应用,还是分布式应用,以及微服务架构,乃至一些大的云厂商设计的Serverless架构,都在解决给用户界面呈现,业务逻辑处理,与数据持久化的问题。只是在每一层里面,有更详细的架构设计;以及由于业务属性或者项目某方面的特点需要,导致做了一些特殊型的架构设计。如何巧妙地让前后端协调起来,通过完整、准确、高质量的代码实现,从而输出一个稳定高效的软件,是在设计方面值得下功夫去做的事情,并且值得持续演进和更新。架构设计是一个不断演进的过程,也是一个产品长期演进和迭代过程中绕不开的必由之路。

实践工作中,我们做的业务软件系统,也需要随着用户需求的驱动,不断进行技术选型的修改,软件架构设计的优化,持续不断地优化和调整。我们学习一些业界开源的经典软件架构设计,会有一定帮助。比如下面这几个:

Linux系统架构:

(上图参考:https://retrage.github.io/img/lkl-architecture.png)

Openstack架构设计:

(上图参考:https://object-storage-ca-ymq-1.vexxhost.net/swift/v1/6e4619c416ff4bd19e1c087f27a43eea/www-assets-prod/openstack-map/openstack-map-v20221001.jpg)

Kubernetes架构设计: 

(上图参考:https://raw.githubusercontent.com/kubernetes/kubernetes/release-1.2/docs/design/architecture.png)

一些开源的经典软件设计很巧妙,在实际的软件设计中,可以给我们很多启发,在实践中可以参考学习借鉴,以便少走很多弯路。

团队协作与组织模式

当需求与软件基本设计确定之后,团队的协同与组织模型就进行相关协作与工作开展,基于一些常用的协作工具,如Jira、Redmine、Tapd、Worktile、Teambition、禅道、飞书之类进行产品需求、工作事务、项目进度、task、bug与软件质量等的管理与跟踪。大部分的工具现在都提供了对于任务优先级设定,人员、时间等的。可以根据自己团队的时间选择取用。各种工具皆有自己的优劣势,选取一种作为团队的标准化工具,再逐步优化和改善,目标是能够实现信息共享与同步,方便团队协同,提高效率就可以。

软件代码质量与测试

在人月神话中提到,软件开发工作没有银弹,不为系统测试安排足够的时间简直就是一场灾难。由于软件工程在实际中的复杂性,需要做好合理的时间规划,并且需要注意风险。在实际的项目开活动中,前期未为测试分配足够的时间,就会导致大多数项目在后期长期维护修复,反复挣扎,导致实际上测试花费了进度中超过一半的时间。软件工程中进度计划方面,典型的经验是为1/3计划、1/6编码、1/4部件测试以及1/4系统测试。

在项目实践中,许多项目在系统测试之前还能保持进度。在进入系统测试之后,就会陷入泥潭,时间不可控。因为项目为测试预留时间较少,测试介入较晚,在项目快完成的时候才开始启动测试,直到项目的发布日期,人们才会发现进度上存在问题,还有很多复杂的问题没有处理完成。给测试预留的时间不足,就会在项目快完成接近发布日的时候面临延期的窘境。就软件而言,实际往往需要经过数轮测试,才能使得一个软件能够功能可用,而要达到好用,更是需要持续地精雕细琢,经历更漫长的测试,多轮的实践。所以业界也有说法,好的软件是不断测试之后才优化打磨出来的。所谓“不经一番寒彻骨,怎得梅花扑鼻香”,只有持续的深入细节测试和优化,不断打磨,才能使得软件能用,直到最终好用、易用。

研发模式与工作流程

所谓”工欲善其事必先利其器”,选择合适的开发工具与模式,会对实际的效率提升有很大帮助。首先建议团队之间采用相同的标准SDK版本,相同的IDE版本,相同的项目管理工具与构建工具,节省一些由于版本差异导致的转换等成本。其次,敏捷开发模式已经盛行多年,基于敏捷模式的快速迭代工作,采取小步快跑,小版本迭代,快速发布,循序渐进的模式,这种主流普遍的研发模式,团队之间快速协作,更早的验证软件小功能,每一个Sprint都有对应的输出,迭代式、增量交付,能够让团队整体实现更高效的协作,以及最高效的交付。

项目管理与部署交付

在实际项目运行中,即使采取敏捷方式,基本的需求分析,编码与单元测试,集成与系统验收测试等关键环节也是必不可少的。而项目管理方面,就需要做好内外部的资源与时间等各方面的协调工作,控制好风险,确保团队的进度满足,整体进展与原计划之间是匹配的。

软件的部署与交付,是整体相对靠后的一个重要环节。通过持续集成结合持续交付与持续部署的方式,让一切自动化起来,让开发、测试人员专注与业务的实现与测试,让代码构建到发布的过程自动运行。采取流水线式自动部署,让项目从代码提交,代码质量扫描、单元测试、build构建,自动化测试,自动化发布,并完成自动化部署,代码提交即可触发构建到发布的过程,实现全程无人值守即可完成。

把能固化的流程性工作交给工具,降低人工操作,可以减少错误,也可以提高效率。用程序测试程序,用程序调用程序,用程序管理程序,从而提升整个发布与研发的运转效率。

总体而言,软件的研发、交付,也是个系统性的工程,只有快速地响应变化,持续提高效率,才能实现更好的结果。一些GTD工具、好的项目管理工具,一个小脚本,也会带来效能方面的提升。培养好的习惯,养成良好的规范化标准对工程师而言很重要。

小结

本文很简要地从几个方面讨论了一些效能提升的要点,在软件研发实践中,效能提升也不止上面几点,而且以上提到的几个方面也有更深入的细节,后续我们继续分享交流。

posted @ 2023-01-03 17:07  西安衍舆航天  阅读(190)  评论(0编辑  收藏  举报