用GC的策略,管理团队的技术债务
在数字化时代,每一个组织的经营都是建立在数字化的系统之上的,而数字化系统的构建,必然就会带来技术债务,这是每一个数字化团队都要面临的一个问题,如何有效的管控技术债务。
技术债务的产生,是技术团队不断迭代构建系统过程中,无法一次性预设所有的需求,而随之产生了系统设计上的扭曲失真。
在了解了技术债务产生的原因后,就可以将技术债务和团队的作为或不作为联系起来,使用一些有效的策略和方法,来最大限度的减少技术债务的积累,保持系统的持续健康。
垃圾回收模型
有效控制技术债务最小化的方法,可以从现代性的软件设计模式中去借鉴思路:垃圾回收算法。
相信熟悉JAVA和Golang等现代开发语言的人,对内存垃圾回收的概念,是非常熟悉的。其实,一个项目的技术债务的产生和积累,也就如同一个程序的内存分配和管理是一样的。
对内存垃圾收集的描述为:
运行程序会创建垃圾(garbage),即已分配但未使用的内存。垃圾的产生是不可避免的,因此我们必须偶尔停下来收集垃圾。如果停顿是可预测的,而且很短,那就更好了。有各种各样的垃圾收集算法,它们具有不同的属性。
对团队技术债务的描述,也可以如此:
运行有时间限制的迭代会产生技术债务,即使用过时的设计编写代码。创造技术债务是不可避免的,所以我们必须偶尔停下来重构代码。如果这些停顿是可预测的、短的,那就更好了。存在各种具有不同属性的迭代软件开发过程。
一个团队的软件开发过程是一个由团队自己运行的算法,它产生并清理了一种我们称之为技术债务的垃圾。
那依次延伸,软件开发过程,就可以使用两种方法来控制技术债务:
- 第一种方法是清理现有的技术债务。大多数团队已经通过重构来做到这一点。
- 第二是避免技术债务的产生。这种情况不太常见,但更有趣。
清理法
团队可以在技术债务存在后,通过清理的方式来处理债务。
通常情况下,一个团队在不考虑现有设计的情况下“仓促”完成一个功能,确定技术债务,然后才进行重构以清除债务。有时清理工作会立即进行,但也可能要很晚才得以开展。
小问题可以在几分钟内重构,但大问题可能就需要几天、几周,甚至几个月的投入。当开发人员在编写功能时停下来解决技术债务时,这就像垃圾收集器停下来清理垃圾一样,把时间花在重构上意味着花在新特性上的时间更少,同时当问题越大时,重构所需的时间也就越长。
因为清理债务需要从新功能的构建中去挤占时间,团队会发现自己面临着减少重构的压力,特别是大型系统重构。导致的后果就是,他们只清理了小问题,却延迟了大问题的清理,比如系统的架构。推迟一个小的清理会把它变成一个大的清理,因为随着时间的推移,代码会围绕这个问题构建起来,它也必须被重构。
预防法
团队也可以通过减少技术债务的产生来控制技术债务,也就是说,尽可能的预防技术债务。
譬如,团队通过考虑设计方案,并选择产生最少技术债务的方案来做到这一点。当被要求添加一个新功能时,团队会考虑当前的设计能在多大程度上适应该功能。如果设计已经是合适的,他们就添加功能。但如果设计不合适,他们会先更新设计,然后再添加功能。
对许多开发人员来说,避免问题听起来要比解决问题更好。然而,遗憾的是,一些技术债务是不可避免的,迟早,新的功能需求会成为令人不快的惊喜。
同时,团队也会担心,技术债务规避是一个变相的瀑布式流程,或者更糟,是一个预先设计好的大项目。其实不然,因为瀑布式流程会让团队查看所有的需求,并交付一个系统来完成所有需求。技术债务避免意味着团队迭代地处理需求,在每次迭代中交付一个工作系统。
另外,团队也会担心,技术债务规避会导致分析瘫痪。大部分的时候,团队依然会在每一次的迭代中持续交付新功能。
可选4类清理策略
在基本的2个策略的基础上,我们可以进一步延伸,扩展出一个四象限的策略组合:放任自流,被动清理,主动预防,双管齐下。具体如下图所示:
技术债务是一个不可完全驯服的怪物。,我们无法彻底的根除,只能选择合适的策略与之共存。
所以,所有最好的算法,任何团队,都要根据自身具体的情况,譬如团队的结构,系统的规模、业务领域的复杂度、团队能力和经验,以及进度的压力等,综合来选择适合的策略。
放任自流
在一些场景下,团队可以对技术债务采取放任自流的策略。
譬如,你为自己编写了一个快速处理数据的脚本,并且也不打算重用它,为什么要担心技术债呢?
同样,这个策略也可以适用于大一点项目,譬如,大型的电脑游戏,开发者知道他们将为下一款游戏开始新的系统,所以在游戏发行之前,只需忍受技术债务的困扰就可以了。
类似的一次性的系统,放任自流,也是一种可选的策略。
被动清理
被动清理,就是团队只使用技术债务的清理策略。
这是现在大多数团队所采取的策略。团队的重点始终在构建新功能之上,只是抽空来清理一些细小的技术债务。
因此,更大的清理工作就变的有挑战了,所以早期的错误会一直存在,导致的就是以后重构的代价会更大,这是一个潜在的隐患。
当然,识别问题比规避问题要容易的多,所以在开发人员的设计能力有限时,被动的清理依然是有意义的。
主动预防
这种只使用技术债务提前规避的主动策略,在今天大部分团队内是并不常见的。
其实,如果你能通过一些事先的思考,来避免技术债务的产生,这要比陷入明显的问题要有效得多。
另一方面,如果你对正在使用的技术没有充足的经验,你可能会因为错误的假设而浪费了时间。尽管努力避免技术债务,但它还是会发生,所以使用主动预防策略的团队,可能会切换到双管齐下的策略之上去。
双管齐下
当团队希望自身技术债务更低更可控的时候,大部分时候都是采取双管齐下的策略,将清理和预防都使用起来。
譬如,在每次迭代的开始,团队讨论新的功能需求将如何影响当前的设计,这样可以保持迭代设计的重点,并让每个人都对设计有理解和掌握度。
团队可能对系统未来的新功能有一定的前瞻的预期假设,即使他们现在没有在做这些需求,但是因为知道未来会发生什么,可能有助于他们更好的思考今天的设计和决策。
有的时候,一个新功能很难添加到现在的设计中,因为它可能与当前领域的假设是相矛盾,或者很难在当前架构中来构建的。
如果开发人员可以重做设计,并在当前迭代中添加功能,那就太好了,如果不能,他们还可以和产品负责人沟通。在做出决定之前,他们会权衡干系人诉求,进度压力和工程风险等。
最终的答案,可能是先推出该功能,然后再清理技术债务,或者完全推迟交付该功能,或者介于两者之间等。
有限和无限游戏
其实,决定那中策略适合当前团队的关键因素,是在于团队是在玩什么模式的游戏:有限游戏 or 无限游戏。
有限游戏有输也有赢,无限游戏可能会失败,但胜利只意味着你可以继续玩下去。技术债务有点像一场无限游戏:如果你能控制它,你就能继续玩下去。否则,你输了,并宣布技术债务破产。
有严格Deadline的团队是在玩有限的游戏。团队需要按时的完成任务,那就会积累了大量的技术债务。
初创企业也是一系列有限游戏。为了达到下一个里程碑,团队采取了孤注一掷的模式,因为失败意味着公司的终结。
团队缺乏经验,也会迫使你玩一个有限的游戏。如果开发人员不了解问题领域或实现技术,他们就会陷入有限的游戏中,直到他们能够构建一些可行的东西。
当然,从有限游戏,转换到无限游戏时,也会导致技术债务的破产。如果你接受破产,并重启新的游戏时,就需要重新评估你的策略的选择了。
不能试图一直使用一种针对有限游戏的策略,来希望玩转一个无限游戏。
无限游戏更适合双管齐下的平衡策略,既可以通过良好的设计实践避免技术债务,又可以通过重构清理不可避免的债务。
写在最后
避免技术债务破产的核心:就是最小化技术债务。
在迭代构建软件时,就无法避免到技术债务的产生,因为我们永远也无法预期所有的功能需求,系统是在生长演进之中,那我们的设计和代码,就会存在设计上局限性和扭曲。
管理技术债务就如同程序内存分配和管理一样,通过优化和改进团队的开发过程,来控制技术债务的产生和积累,将团队的技术债务最小化,以提升数字化团队的效能和交付价值。
最后的最后,技术债务不能完全消灭,只能合理管控。
以上为学习:https://ieeexplore.ieee.org/document/9520328/ 论文的一些笔记,具体内容可参见原文。
用GC的策略,管理团队的技术债务的更多相关文章
- 技术债务(Technical debt)的产生原因及衡量解决
第一次发布代码,就好比借了一笔钱.只要通过不断重写来偿还债务,小额负债可以加速开发.但久未偿还债务会引发危险.复用马马虎虎的代码,类似于负债的利息.整个部门有可能因为松散的实现,不完全的面向对象的设计 ...
- 聊聊两个Go即将过时的GC优化策略
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 这篇文章本来是要讲 Go Memory Ballast 以及 Go GC Tuner 来 ...
- .NET面试题解析(06)-GC与内存管理
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 GC作为.NET的重要核心基础,是必须要了解的.本文主要侧重于GC内存管理中的一些关键点,如要要全面深入了 ...
- 技术债务管理以及Firefox/Chromium的债务评价
如今的软件开发是在遍地敏捷,人人讲唯快不破的时代,哪有人有时间思考代码质量,设计的质量? 哪个又不是从一堆代码中杀出血路来实现还有一个功能?一个产品都存活不了几年,何必考虑什么可维护性? 我们追求进度 ...
- 2.Magicodes.NET框架之路——策略管理
闲话策略 策略,有很多解释.但鄙人个人比较看重这点: 策略,是为了实现某个目标或者针对某些问题而制定的应对方案,以最终实现目标.比如为实现生娃而XXOO. 因此在本框架中,策略(Strategy),则 ...
- 品味性能之道<四>:管理重于技术
一.性能优化中的角色分工 (1).老外的角色分工 在oracle性能优化方法论中,将IT系统中不同角色需要承担的性能优化工作罗列如下. 各司其职的角色分工 业务分析人员 1.业务需 ...
- <p>在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性。由于编程实际上是和机器打交道,而和机器打交道,仅仅要你符合机器预定的逻辑,</p>
在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性. 由于编程实际上是和机器打交道.而和机器打交道,仅仅要你符合机器预定的逻辑, 一步步迈向解决这个问题的道路上一点都不 ...
- 利用高级组策略管理AGPM复制组策略GPO
有时候管理多个林,在一个林中配置了GPO之后,想复制出来用到其它林里.默认系统的组策略管理里没有这个功能.但是微软在微软企业桌面优化套件Microsoft Desktop Optimization P ...
- 在win2008 r2主域控制域上打开“组策略管理”报错“未打开组策略对对象。你可能没有合适的权限”
在win2008 r2主域控制域上打开“组策略管理”报错“未打开组策略对对象.你可能没有合适的权限” 打开组策略管理其它选项提示:找不到指定路径.之前做过的操作:取消域控主机上的共享目录sysvol和 ...
- 使用WiX Toolset创建.NET程序发布Bootstrapper(安装策略管理)(二)——自定义安装
原文:使用WiX Toolset创建.NET程序发布Bootstrapper(安装策略管理)(二)--自定义安装 自定义产品卸载方式 继续从上一次的基础上前进,现在我们已经知道了最简单的bootstr ...
随机推荐
- ABAP 调用HTTP上传附件
1.需求说明 在SAP中调用第三方文件服务器的HTTP请求,将文件保存在文件服务器上,并返回保存的文件地址.SAP保存返回的文件地址,通过浏览器进行访问. 2.需求实现 2.1.POSTMAN测试 通 ...
- Java安全之动态加载字节码
Java字节码 简单说,Java字节码就是.class后缀的文件,里面存放Java虚拟机执行的指令. 由于Java是一门跨平台的编译型语言,所以可以适用于不同平台,不同CPU的计算机,开发者只需要将自 ...
- 【笔记】区间DP
记录一些基础的区间 \(\text{DP}\) 题. 0x00 AT_dp_n N - Slimes 最板的区间 \(\text{DP}\) . 记 \(f[i][j]\) 表示合并 \(i\sim ...
- 解决Halcon转C#时,图像显示的问题
不知道大家在使用Halcon进行图像处理,由于要连续处理多张图片,转为C#代码的时候,使用了Halcon控件显示图像,但是运行的时候,中间的其他图片没有显示在控件上,之前我一直以为是运行速度快导致看不 ...
- fuzor2020安装教程
fuzor下载安装包fuzor2020安装教程Fuzor2020 WIN10 64位安装步骤:1.先使用"百度网盘客户端"下载Fur20_CN_x64安装包到电脑磁盘里,并鼠标右击 ...
- PEP8语法规范解释说明
PEP8规范解析 内容概要: 1.PEP8规范是什么? 2.PEP8相关内容 1.PEP8规范是什么 PEP是Python Enhancement Proposal的缩写,翻译为:"Pyth ...
- Sql Server日期转汉字字符串
以下脚本转至互联网,增加了自己需要的功能并改成了函数的方式 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ================== ...
- nuxt作为主应用接入qiankun的实践(附代码)
上半年一直在倒腾qiankun,在使用nuxtjs接入qiankun时遇到了一些坑,记录并分享出来,希望能帮助到大家. 代码地址:nuxtjs-qiankun-demo Nuxtjs接入qiankun ...
- .NET 6使用ImageSharp给图片添加水印
.NET 6 中,使用System.Drawing操作图片,生成解决方案或打包的时候,会有警告,意思是System.Drawing仅在 'windows' 上受支持.微软官方的解释是: Syste ...
- MISC图片批量处理jio本
此处以ctfshow中MISC入门题目作为切入点 感兴趣的同学可以一边做题一边参照 批量修改PNG图片的宽 import zlib import struct filename = "fla ...