太好了!是技术债务治理指南,我们年底有救了

滴滴技术 2025-01-19 10:19:00

一、前言

 

在现代软件开发中,技术债务(Technical Debt)已成为一个不可忽视的重要概念。它指的是在软件开发过程中,为了追求短期目标而做出的妥协,导致未来需要付出额外成本来修复这些妥协所带来的问题。技术债务的管理不仅影响项目的质量和可维护性,还直接关系到团队的工作效率和公司的长期发展。

 

 

1、什么是技术债务?

 

技术债务的定义可以追溯到Ward Cunningham,他将其比喻为“借款”,即在软件开发中选择了一个较为简单的解决方案,而非最佳实践。这种选择虽然在短期内能加快开发进度,但却可能在未来导致更高的维护成本和更复杂的技术问题。

 

 

为了提升需求开发速度,我们有时会在应当采纳最佳方案时作出妥协,转而选择那些短期内能迅速推进项目进程的方案。然而,这种做法往往会导致未来的错误问题增多,并给自己带来额外的开发负担。这种技术层面的抉择,犹如背负了一笔债务。

 

 

2、技术债务的分类

 

同样,技术债务也有其层次之分,通常根据其影响程度和解决的紧迫性,我们可以将其划分为四个象限,即技术债务的四象限模型。

 

 

技术债务可以根据不同的标准进行分类:

 

有意和无意两种:

 

  • 有意技术债务:团队明确意识到当前的解决方案并非最佳选择,且计划在未来进行改进。

  • 无意技术债务:团队在缺乏足够信息或经验的情况下做出的选择,往往潜伏较久,难以察觉。

 

鲁莽型和谨慎型:

 

  • 鲁莽技术债务:由于缺乏规划和规范而产生的债务,通常会导致严重的后果。

  • 谨慎技术债务:在项目进度中做出的合理妥协,虽然存在风险,但在可控范围内。

 

 

3、技术债务全景图

 

根据卡内基-梅龙大学软件工程研究所(SEI)的Robert Nord在《The Future of Managing Technical Debt》中提出的“技术债务全景图”,技术债务可以从多个维度进行分析:

 

 

这张全景图清晰地展现了技术债务的多个层面,包括那些通常与架构相关联的债务、因环境变化而产生的技术差距型债务,以及主要由内部代码质量低下引起的小粒度技术债务。

 

此外,通过这张图,我们还可以洞察到两个重要的方向。

 

可演进性

 

本质上,架构的元特征描述的是软件架构在演进过程中趋于目标的能力。这种演进目标并不仅限于支撑功能快速迭代的灵活性,同样可以涵盖其他重要的架构属性,如高可用性和可扩展性。

 

可维护性

 

狭义上的代码问题主要涉及代码的易理解性、问题的易修复性,以及在现有基础上的易扩展性。这些因素共同影响着代码的质量和可维护性。

 

二、背景

 

当技术债务已经严重影响了公司的运作、工作的效率时,才会着手去处理这些方面的问题,可要付出的代价就太大了。

 

 

随着滴滴国际化业务的快速发展,技术栈的多样化使得技术债务的管理变得愈发复杂。当前,研发所需的语言已不仅局限于平台原生语言,跨平台技术(如Flutter及其Dart语言)逐渐成为主流。这一转变带来了新的技术债务挑战,尤其是在代码质量和架构设计方面。

 

 

1、演绎过程

 

在项目的初期阶段,我们面临着快速上线和快速迭代的压力,因此问题的积累是不可避免的。然而,随着我们的不断发展,我们意识到如果继续这种状态,将会对项目的质量和成本带来双重风险。同时,随着业务逐渐融入Flutter跨平台能力,我们在学习和研发Flutter的过程中,也遇到了诸多挑战。特别是随着Flutter SDK的不断升级,我们在这个过程中也积累了大量的技术债务,例如空安全适配问题。目前,我们的SDK版本支持2.12.0,这是一个允许空安全和非空安全混合的版本,因此存在很大的隐患。

 

 

2、影响分析

 

1)对开发的影响

 

也许某一天我们接收了一个陌生的模块,也许是自己曾经的代码,发现如同屎山一样,如下图,自己都看不懂了,为了应付快速迭代的需求,只能不停的往这上面堆,这个屎山也会愈发庞大和混乱,如果这样继续下去,知道某一天因为一个小小的Bug,你需要花半天的时间来排查问题出在哪里,最后当你觉得问题终于改好了的时候,却不料碰了不该碰的地方,结果就是 fixing 1 bug will create 10 new bugs,甚至程序的崩溃。

 

(图片由AI生成)

 

我们需要正确面对、积极面对这个事情,它不是没有技术含量,他能给我们带来更多的技术和业务上的挑战。

 

2)对效率的影响

 

技术债务的治理本质上是提升效率的过程。

 

治理不当将导致开发周期延长、资源浪费和团队士气下降。因此,及时识别和解决技术债务是确保项目成功的关键。

 

 

 

3、现状梳理

 

业务发展至今,通过整理存量问题和结合监控报警沉淀的问题,可以看出目前工程存在的问题方向。(非最全)

 

 

1)代码复杂

 

在快速迭代过程中,往往忽视了良好的代码组织与模块化设计,导致组件间出现高度耦合的现象。此外,类文件行数过长也是一个需要关注的问题。这些问题可能会影响代码的可读性和可维护性,进而降低开发效率。因此,我们需要重视代码结构的优化和模块化设计,以降低组件间的耦合度,并合理控制类文件行数,从而提高代码质量。

 

2)架构混乱

 

业务架构在从初期到后期的迭代过程中,经历了逐步分化和尝试等阶段,尚未形成统一的结构走势。

 

目前存在新旧架构混合使用的情况。

 

3)代码风格

 

在Flutter跨平台代码中,代码结构和规范风格的不统一是一个常见问题。这主要是由于不同IDE的使用,很容易引发代码风格上的冲突,进而带来潜在的风险。为了提高代码的可读性和可维护性,降低风险,我们需要确保在整个代码库中保持一致的代码结构和规范风格。

 

4)基建混乱

 

在业务组件基建和服务基建方面,由于缺乏统一的最佳实践范式,导致使用层的代码出现混乱。这一问题亟待解决,以确保代码的整洁性和可维护性。

 

5)工程效率

 

管理缺乏统一性,功能分散,导致功能可用性低下。

 

6)性能债务

 

  • 解决由持续SDK升级触发的报警问题

  • 优化内存管理

  • 清理未使用的资源和已下架的代码

  • 实施lint代码质量检查与治理

  • 进行空安全适配(针对Flutter框架)

 

三、目标

 

 

1、产物目标

 

1)一套简易可视化运营平台

 

结合Lean平台,对Lean平台录入信息,通过脚本产出自定义报告。

 

增加巡检能力,周频次跟进问题状态。

 

 

2、稳定性目标

 

1)沉淀问题,整合债务

 

通过深入剖析问题和细致整合债务,将技术债务治理提升为确保系统稳定性的关键环节。

 

3、质量目标

 

1)提高代码质量

 

提高代码质量,确保代码符合Lint标准。

 

完成Flutter的空安全适配。

 

四、面对挑战

 

 

1、业务挑战

 

稳定性的设计需要针对老业务流程进行二次梳理,如何保证线上稳定性是关键。

 

在需求中不断植入Fix的问题,确保技术债务的及时解决。

 

 

2、技术挑战

 

优化思路和设计需要更全面的考虑。

 

如何通过架构设计更完美地落地修改和重构。

 

对技术的深入理解是实现更好方案的基础。

 

五、治理方案

 

 

1、债务整体架构

 

 

1)方向:通过对当前问题的归纳,合理划分技术债务的治理方向

 

  • 业务架构:主要以业务代码实现为主,最佳范式等;

  • 基建:对接底层基建能力,使用上不合理不舒服的点。

  • 代码:实施代码规范、Lint治理和代码格式化。

  • 效能:所有辅助程序运行的脚本能力。

 

2)治理运营:一套可持续运行的方案

 

任何人不管问题的大小,都可以畅快的提出问题(不是谁提出谁修改,你只管提),把痛点问题进行描述,通过Lean平台记录,并会有专门的人(提出人)标记方向(分类),负责的同学或者感兴趣的同学都可以进行认领,并做出合理的方案和同步进度。

 

3)沉淀:通过这些点沉淀能力,不断的下沉能力,解耦业务。

 

4)建设:

 

  • 非开源:可以按照产物进行成果分享。

  • 开源:是最好的状态,开源我们一些厉害的能力,无论是什么方向的结果。

 

 

2、债务治理机制

 

为了解决这些问题,我们决定采取一系列措施来优化我们的项目和技术栈,并最终沉淀出一套我们可执行可长期运营的方案。

 

 

1)识别

 

技术的持续改进离不开团队中每个人的努力,因此需要每个成员都积极参与。在日常交付中,团队成员应该持续识别和记录需要改进的问题并将其放入Lean平台中,以便在技术改进会议中与团队同步。

 

此外,团队还可以定期组织头脑风暴,以收集技术痛点和改进建议。

 

2)可视化平台

 

通过一个共享平台,我们可以高效地录入和展示信息,从而更清晰地一览所有问题的分布情况和各类问题的占比。这样的设计不仅提升了工作效率,还使得数据分析更加直观、便捷。

 

3)优先级

 

我们时常会遇到的问题是,需要改进的地方太多,尤其是对于遗留系统。怎么办?先排优先级。我们可以基于价值/成本矩阵来评估改进任务的价值和成本。

 

 

基于矩阵:

 

优先解决高价值+低成本的技术债。

 

尝试将高价值+高成本的技术债拆分为高价值+低成本的技术债,“尽早、频繁、小批”地进行PDCA(Plan/Do/Check/Adjust)的迭代解决。

 

在没有高价值+高/低成本的技术债时,再来考虑低价值+低成本的技术债。

 

最后如果只剩下低价值+高成本的技术债,还是先拆分,再解决,或可考虑直接移除

 

4)执行

 

债务问题,是无法集中清理的,每个人每天都有自己的业务需求,所以我个人认为可以存在两个进度方式:

 

在版本跌在中,引入20%的工作量进行技术任务的改进。

 

在技术架构升级或者重构等方案中,评估债务任务的清理。

 

总结&公式

 

每周固定时间进行报告产出。

 

存在这个能力,就能更好的整体观测治理的大盘,有助于促进治理的节奏,不会石沉大海。

 

让债务问题成为一个话题榜,成为一个论坛贴。从枯燥变成一种可持续输出知识点的平台。

 

(热门标签贴)

 

 

我认为在技术债务管理中,这一步是很重要的,我们需要分享解决的思路和成果,它是具有价值的,分享的过程是信息同步也是团队认知的对齐。

 

 

(自定义报告生成平台)

 

总结

 

通过这套精心设计的治理机制,我们能够高效地对问题进行细致分类,并实现有条不紊的治理。结合先进的可视化平台Lean+报告产出平台,我们可以实时追踪问题的处理进度。这一机制不仅帮助我们成功解决了问题,还促进了宝贵知识的积累和共享,形成了丰富的知识库。

 

 

3、稳定性方向沉淀

 

公司层面一直在推进稳定性,通过事前、事中、事后三个阶段进行预防、监控、复盘总结,形成一个闭环流程。

 

 

在技术债务治理方面,我认为它扮演着事前过滤器的重要角色。通过运用技术债务治理的手段,我们可以有效地识别并处理许多潜在隐患,从而为系统的稳定性奠定坚实基础。

 

在整体稳定性的三个阶段中,事中和事后阶段能够持续揭露技术债务问题的多维面貌,并对其进行系统归纳与整理。这些宝贵的经验教训随后被转化为事前阶段的预防性过滤网,从而助力我们更加精准地预防和应对未来潜在的问题挑战。

 

总结

 

在事中、事后阶段,我们要能够及时发现并沉淀归纳债务问题,确保问题留痕、总结到位,并达成共识,以便更出色地完成事前规划的任务。

 

 

4、代码质量治理

 

1)lint治理

 

从此时此刻起:债务问题不再新增,趋势线逐步下降;

 

严格执行代码规范、CR机制、Dlinter统一规范,提交高质量代码。

 

 

工程配置规则、远程代码配置规则开启,自动reject。(Flutter 配置为主)

 

 

 

2)空安全适配(Flutter)

 

我们强烈建议你按顺序迁移代码,先迁移依赖关系中的处于最末端的依赖。例如,如果 C 依赖了 B,B 依赖了 A,那么应该按照 A -> B -> C 的顺序进行迁移。

 

 

 

3)迁移时序层

 

从底层服务类出发,逐层向上适配。

 

 

 

 

六、总结

 

技术债务是项目进程中难以避免的现象,然而,如何将其控制在可管理范围内,却是我们必须深思的问题。要想有效预防和化解技术债务,离不开优秀开发人员的贡献,而团队的协同合作更是至关重要。借助这套精心设计的治理机制,我们能够对各类问题进行科学分类和有序治理。同时,结合高效的可视化平台,我们可以实时追踪问题进展,不仅及时解决现有问题,还能在此过程中积累并提炼出大量宝贵的共享知识资源。

 

七、结论

 

技术债务在现代软件开发中屡见不鲜,然而,借助高效的治理策略与团队的协同合作,我们完全有能力将其潜在影响压缩至最小。不懈的学习与持续的改进乃是项目取得成功的基石,唯有如此,我们方能在日新月异的技术浪潮中稳立潮头,保持强劲的竞争力。

 

技术债务是一个普遍存在的问题,它不受平台或编程语言的限制。我们应该共同努力,不断学习和提升自己,以应对这一挑战,共同推动技术进步。

 
作者丨白奇龙
来源丨公众号:滴滴技术(ID:)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
最新评论
访客 2024年04月08日

如果字段的最大可能长度超过255字节,那么长度值可能…

访客 2024年03月04日

只能说作者太用心了,优秀

访客 2024年02月23日

感谢详解

访客 2024年02月20日

一般干个7-8年(即30岁左右),能做到年入40w-50w;有…

访客 2023年08月20日

230721

活动预告