且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

求解质量熵

更新时间:2022-08-22 13:58:54

1回顾



在第一篇文章中,我们从黑天鹅事件谈到了蝴蝶效应、墨菲定律。一言以蔽之为,要把软件研发中的质量搞好并非易事。质量是一个综合的大命题,涉及到业务准确性、稳定性、可用性等方面。比如xx大促,某厂商几小时无法交易;收藏夹商品丢失;用户享受的优惠不符合预期,营销规则复杂难以解释等。

 

黑天鹅告诉我们要走出经验主义,不要把自己知道的东西太当回事了,而不知道的事比知道的事更有意义。蝴蝶效应告诉我们要及时感知问题,止损和熔断,避免问题范围扩大包括传染到其它相关领域。墨菲定律告诉我们,你知道的但是忽略的漏掉终会出问题,在黎明破晓前!

相关link:


在第二篇文章中,我们讨论了导致质量问题难以掌握把控的原因。

  • 业务高速发展带来的变化
  • 技术债问题
  • 人、流程、文档的博弈
  • 采用不能cover的工具和框架
  • 复杂的问题域
  • 质量意识


为了破解这个复杂的问题,我们打算从以下几个方面来思考这个问题。如同没有银弹一样,也没有万能解药。


 


2运用敏捷思想



什么是敏捷思想,徐毅大大等一帮教练、咨询师们必然懂得比我得多,有开山立派的,有翻译多本书籍的,有已服务万千客户的。他们同时还在理论界辛勤耕耘。接地气的申导来成都布道说,敏捷的三个层次。一是思想,二是组织,三是操作方法。

敏捷宣言如是说:

我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:

  个体和互动 高于 流程和工具

  工作的软件 高于 详尽的文档

  客户合作 高于 合同谈判

  响应变化 高于 遵循计划

  也就是说,尽管右项有其价值,我们更重视左项的价值。


敏捷建模(Agile Modeling,AM)的价值观包括了XP(Extreme Programming:极限编程)的四个价值观:沟通、简单、反馈、勇气,此外,还扩展了第五个价值观:谦逊。至少我们明白了快速反馈有什么好处,做错了做偏了,可以马上校正。如果瀑布模型式的开发反馈必然是慢的。此前有一位做医疗单机软件的朋友说,他们半年才发布一次,可见这里面提升的空间有多大。


申导提及的第二层组织,我理解有组织层的支持,比如PMO,项目团队是否按scrum等;第三层操作方法则是持续集成、单元测试、TDD这些具体的实践。


总结一下:基于敏捷的思想可以快速release,快速纠正和调整,满足用户的需求。


3运用系统化的思想


我理解系统化的思想就是体系、举一反三、通过类比、抽象、层次化等手段挖掘本质。往往出了一个bug,故障复盘会开了,action有了,但下次又出错了。究其本质,我觉得两点。一是复盘的内容focus在单个事件,对于更体系的影响洞察不够。二是未持续学习,对于问题是不情愿的承担。


谈到学习,想起大卫张引用的一张图。太多人对这种发生的改变持抵抗态度。如同萨提亚改变模型所示,当我们适应了老的状态,遭遇到改变时,我们会经历抵抗、混乱、改变主意、重新上路等过程,最后到达新的状态。此前我们团队通过深度复盘这一实践让鲜血直接喷洒出来,通过大约1年的持续联系终使我们对于问题的认知【包括对于故障】,以及担当力都上了一个台阶。


求解质量熵


from http://davidzhang33.blog.51cto.com/3095817/1129749/


4技术债偿还计划


技术债务是由Ward Cunningham在1992年的报告中创造的一个比喻,被定义为当我们有意或无意地做了错误的或不理想的技术决策所累积的债务。它和金融债务非常相似。一个人贷款了就会产生债务。如果他定期还款,那么所创建的债务是可以接受的,不会产生进一步的问题。但是,如果他不还款,就会以利息作为惩罚,并随着不还款次数的增加而增加。如果这个人很长一段时间不能支付任何款项,那么应计利息使得他更难以偿还债务。在极端情况下,该人不得不宣布自己破产。


前一段在一个讨论中,关于技术债务有4个有趣的观点。

  • 由于技术人员水平不行,意识不够,所以越写越烂。
  • developer都有一颗积极向上的红心,但是他们不知道如何做才是好的。
  • 上行下效,没有靠谱的Leader,架构师,大家都是懒惰的,不想去还债。
  • 华为的同学表示,永远的业务压力;其实所有公司都一样滴,赶着交付,那有时间去清偿。


关于债务清偿,总结了务实接地气的几个思路。

  • 构建质量保障体系,让我有勇气动手动刀。比如接口测试、单元测试,通过CI持续反馈,这样我有50%的勇气来做重构。
  • 对于遗留系统,没出问题的地方,你不要动它。出问题的,修复并补充测试代码。如果更进一步,对于高危的功能和模块可以做定向增强。
  • 招募优秀的工程师,好的作风和习惯可以影响整个团队。
  • 抓住痛得不行的时候大作文章。平常说持续集成,可能团队成员没有感受到好处,出bug了,再回顾看看;copy-paste代码总有一天不能满足更复杂的需求,这样从心理认同上,大家觉得必须重写了。抓住这样的机会,构建品质高一些的代码和质量防线。改变一个人是非常难的,抓住这样的机会很重要!

求解质量熵



5
内建质量


前文谈技术债务,谈反馈都提及到了持续集成。那么整体来讲,内建质量就是更短构建,更快反馈。 


求解质量熵


同时,除了正确的做事,还要思辨【做正确的事】。通过ATDD/引流对比/串讲反串讲/评审/录制回放验证/接口回归测试 等手段可以保证需求到设计、实现是否发生了变形。


内建质量=正确的做事*做正确的事



6不唯新、不唯上、实践是检验真理的标准 


就技术选型而言,不迷信、不唯新、不唯上,建议尽早做小范围的可行性论证。比如好久前流行的OSGI,上这个东西,获得了什么,风险是什么。引入一个新的技术栈就带来一层复杂度,而复杂度有一条天性。复杂度只能增加,不能减少,就像宇宙中的熵一样。就如同一个接口一旦开放使用,就很难把这个接口停用。一旦以一个高耦合的方式引入到一种技术,要调整或者去除,带来的成本是几何级数一样的。

总结,对于技术选型请看看成熟度、团队人员的掌握程度、收益和风险评估,一旦陷入泥潭则无异于梦魇之旅。要活得好好的,可以采取可行性论证,基于风险的架构设计。


7复杂的问题域:专项突破


在第二篇文章中提到过,问题域的复杂度会导致出bug的风险增加。


随着业务的发展,对于可用性的诉求也越来越高。比如你曾经是单机房部署、然后演变成同城异机房、最后又发展到异地机房。因为有异地机房,对于RPC的路由复杂度就增加了,我得知道是路由到那个机房的;同样的,在开发环境、线下测试环境要模拟几种部署的情况亦是有复杂度的。

 

再举一个例子,有一个系统作支付链路的规则决策,起初可能就4万行代码;后来增加到8万,现在又增加到10万。代码行增加了,该应用的职责增加了,也可能调用逻辑的运算复杂度。那么如何保持对外API的TPS不降低,RT不降低?

每次release不仅要完成功能用例的构建,亦要完成性能的测试。

 

那么要如何破呢?对于第二个例子而言,除了构建功能回归测试环境,还需要有性能回归测试环境,以保障每次release的产品性能是没有降低的。对于多机房这个case而言,技术架构要关注可测试性、易用性。不仅仅考虑复杂度带来诸多依赖产品的修改成本,还要考虑易用性,如何测试,甚至是如何方便的,低侵入的测试。因为一旦从单机房到多机房了,问题的外延就翻倍了。比如一个定时任务会不会同时在2个机房运行导致数据重复;机房切换时是否有缓存切换的问题导致业务不可用;数据复制延迟带来的不一致性对业务的影响;对于就得有数据复制的监控、缓存的监控、数据在全局的唯一性管理策略,业务兼容性方案等等。

 


8Leader的意识 


 一个公司的文化由创始人决定,而一个团队的品质追求往往由其Leader决定。Leader不自觉的保护主义,报喜不报忧等做法会让这个问题变得严重。见微知著,一叶而知秋。


如果有足够的意识,依靠体力至少也能拿过80分。团队成员都是看Leader。Leader是看重质量,大家就看重;Leader是欺瞒,他们就欺瞒,Leader熟视无睹,这个团队就坏透了。:)


 

9创新解决方案


perl设计者在著作programming perl中提到:优秀的程序员具有三大美德:

懒惰 急躁 和傲慢 ( laziness,Impatience.and Hubris)

为了减少总能量支出而不遗余力地努力的素质,就是懒惰.

忍受不了程序执行的低效就是急躁.

容不得对错误不管不顾就是傲慢.

要发扬程序员的美德,比如对于规则系统如果不能构建上游上千种场景,就可能思考新的解法;有人说做业务系统没啥追求和挑战,但是又有满目苍夷的bug,小事不想做,大事做不来。其实【小事不小】!