半岛体育在公司工作转眼二十年过去了,笔者一直在软件开发领域工作,很欣慰我们的软件开发成功地走向了敏捷模式,虽然敏捷岛之类实践最后又退回到了格子间,但迭代开发、持续集成这些实践的价值已经毋庸置疑,变成了我司主流的开发模式。然而,软件开发的诸多基本问题仍然横亘在那里,没有很好地得到回答,特别是对软件开发效率的拷问一刻也没有停止过。
软件工程技术领域得承认,在废除了用代码行来度量微观的开发效率之后,一直没有找到普适的工程方法。大家比较熟悉的功能点,实践起来的确难以在不同业务部门之间拉齐,所以代码行仍然是IPMT投资决策中进行工作量评估的依据。现在不断有声音质疑研发打埋伏,想做就把工作量估低点,不想做就估得高高的。然后安排各种讨论审视——这种不信任造成的管理层面的博弈,对效率的影响非常大。
客观来说,最早之前没有约束地牵引人均代码行产出,确实会引起代码堆砌,但是在持续集成中加上了对内存/CPU使用、架构腐化的度量约束之后,会实时触发代码的重构,这样产出的代码可以说都是“干货”,代码行用于工作量的评估是可信的。但依然不能用来做效率的度量,一个优秀的架构师用几百行奠定的代码框架,其价值远比几千行的特性代码高。软件开发是创造性的智力活动,难以用一个或几个数字,线性地进行微观开发效率的衡量。信任,是效率的最大前提。
从大跨度时间的宏观数字上来看,R版本工作量从几年前的五六十万行,到现在的近百万行,而开发人力几乎持平,我们的交付效率、交付能力的确在提升,但是感觉竞争力还是不够,没有装多少有价值的特性,我们的效率到底跑到哪里去了?笔者基于自己多年的软件开发经历,就这方面谈几点陋见,核心就是再次重复软件业界的老观点:软件没有银弹。
一、系统维度,软/硬/芯片垂直整合,既为我们构筑了性能、能效的竞争优势,也让我们对软件新技术的转化产生了“免疫力”。
某些新特性只有新的芯片支持,为了性能提升又对之前的加速器做了优化,这就从DNA上决定了为什么做块新单板,从下到上都那么大工作量,决定了无法做到理想的软硬件解耦、硬件即插即用PnP、新老单板兼容形成资源池等,也就无从做到真正的云化部署。但我们管理层总希望某个软件技术能一劳永逸地解决类似问题,特别是虚拟化、云化、微服务这些技术,一上来情怀都特别丰满,但到最后落地都很骨感。
实际上软件根本不可能有某个万能技术,来消化硬件不断变化的问题,这就造成年年谈解耦,年年解不开的局面。跨硬件平台移植对IT界也是最头疼的问题,INTEL在手机上的故事就说明了这一点,抛开其终端芯片是否有竞争力不说,软件开发生态是其无法跨越的障碍跨越。在过去二十年中,我们的硬件平台单看CPU,就从PowerPC,到MIPS,到ARM,再到自研ARM,操作系统从VxWORKS,到厂家LINUX,到自研LINUX,其他还有诸多代的DSP/FPGA等,现在都在网上运行着,我们的软件产品要保证所有这些产品的稳定、高效运行,既影响效率,安全也是大问题。
这其实是NFV的缘起,试图学习IT,把硬件归一,甚至白牌化,软硬件彻底解耦。我们当然不能去迎合邯郸学步,丢掉自己的既有优势,去搞硬件通用化。但在努力跑得更快,保持优势的前提下,我们也确实需要积极向IT学习。
学IT、云化,不能简单照搬,描猫画虎,把一些功能搬到云上去就叫云化了,更要内化IT、云化的技术本质。改变软件以前只是把硬件跑起来的定位,软件要对硬件的开发形成约束力,在软件/硬件/芯片之间形成相对稳定的接口划分,不要把性能追求到极致,在性能与效率之间做好权衡。软件自身更要充分借鉴云化、微服务化,在不同细分场景之间提炼最大公约数,通过把平台化、组件化的工作做精做细,不断地提高效率。
这样不只是我们的开发效率,客户界面的部署效率也会得到根本性提高。华为自身的硬件足够归一,跨代之间能够相互兼容,软件能够灵活升级。也就是说,除了硬件白牌化,客户希望通过NFV得到的,我们都能够提供给他们。这样我们也就不需要畏惧所谓IT的进攻了。
二、时间维度,我们的软件产品是不断地甚至快速地进行特性积累,这与业界很多软件公司是本质的不同,这决定了产品架构的腐化是一种必然,为克服腐化所付出的成本也随着时间越来越大。
硬件虽然多代并存,但还有生命周期,而我司的软件特性根本没有特性生命周期一说,即使某个特性上线后最终没有一个客户使用,也不能在后面的版本中去除掉。为此,多年来我们一直在为一个朴素的目标奋斗——升级特性不丢失,升级性能不下降。
这个目标的达成,或者说防止架构的腐化,一方面得益于敏捷带来的软件工程,如迭代开发、持续集成、全量自动化测试能力的建设。另一方面更为关键的是,需要一支长期稳定的基层软件架构队伍,有人长期看着某个模块,看得懂,吃得透。他们在基层多年如一日,持之以恒地重构,坚持软件存量的控制,努力做到增加新特性,不增加静态代码,不增加消耗内存/CPU,是让我们的软件保持高质量、高效率的“笨”办法,并没有什么一劳永逸的软件技术。这次公司把基层编码骨干的职级提升上来,签发任命软件总工,是对他们压舱石般贡献的肯定与认可。
事实上,有了这个追求,他们自然会主动不断寻找业界新的编程技术、工具乃至理念。我们管理者,诸多不写代码的人,不要老替他们操心应该如何写好代码。不要像计划经济那样,总操心农民种什么,怎么种。
近几年,我们也不断引入尝试新的软件开发模式,比如按特性开发,服务/微服务,全功能团队,确实有效果,但没有普适性,这就是由我们软件产品的本质决定的。如果没有人守着那个模块责任田,几个版本下来,解决一个网上问题,需要一屋子人的局面就必然会出现。我们只需要保持开放的心态就好了,让新语言新技术新模式作为货架放那里,不要搞运动,不要搞一刀切。
为开发队伍如何多做些减法,这才是我们管理者该去努力做好的事情。过旧硬件如何加快收敛?软件只增不减,增加一个新特性,需要扰动的代码、考虑的特性关联,也就越来越多。我们该如何建立起对产品特性做减法的机制?特别是在当下,针对细分场景的特性越来越多的情况下。
三、流程维度,基于不信任的管理理念,下游对上游的卡位,决定了流程管控措施日趋增加的内在必然性,要做瘦身熵减,只能通过系统外力给予额外的做功驱动。
公司践行日落法,研发体系也在大规模地进行流程精简。但一个问题单七八个环节,一个TR点几十人参与,一篇文档评审上百人,怎么就没人主动提出精简?怎么就慢慢复杂到这个程度了?历史上,大规模地进行流程精简也已有若干次了。为什么流程系统自身没有精简的内驱力?
“过点”在公司是具有丰富内涵的一个词语,与“拉通”可以媲美。流程是环环相扣,段段相连的,我们一直倡导不让污水流入下一个环节,因为质量理论说,上个环节的污水,流到下个环节,会产生10倍的PONC(质量成本),所以“过点”设卡应运而生。原本“不让污水流入下一个环节”是每个环节的自我要求和追求,渐渐演变成每个下游环节对上游环节的零容忍,出现一个问题,就增加相应的检查项。
以SE的系统设计为例,让一个SE在3个月内再努力,即使给他更多时间,让他写到伪码的程度,到了编码阶段,还是会发现设计的缺陷,文档的不足。笔者曾解剖一个文档检视案例,项目组为了把SE的问题堵在前面,各派一些骨干去参加文档检视,这样若干项目组相加起来就是近百人;流程还要求SE必须对每个意见是否采纳给予明确的回复,哪怕是学习咨询、疑惑澄清类的意见,这样他基本上就是疲于应付,反而没有时间思考设计本身。
但这种检视,是否就把所有的设计缺陷消除了?可能未必。产品开发是创造性的劳动,其基本要义就是产品开发是渐进明细的过程,上个环节的“不合理之处”,必然需要在下个环节的细化过程中才能被检验、被发现。
“不能把污水流入下游”,“零缺陷”,这是一种原则性的要求,但不能成为在流程设计中,必须收敛到零的具体实际操作。如果这样,必然会不断强化下游对上游的围追堵截,增加各种烦琐的CHECK操作。我们还是要相信人的主观能动性,下游在工作开展中,对上游不合理的反馈,肯定会促进相关人员不断提高自己的工作水平和质量。流程每个环节的设计目标,不应该是让某个残留缺陷数字无限去收敛到零,而是让人的主观能动性得到最大的发挥。
类似问题总是历史循环往复,管理者总希望用几个数字半岛体育,并且还是线性可比的数字,就能把人、把团队区分开来。这种牵引下,才有现在几乎所有项目都能精准无误地做到零偏差的奇观景象;而且提前交付也不一定是好的,无法区分是前面估计不准确,还是团队努力达成的。五星评定已不足以区分,只有再加指标,搞六星、七星来评比。从业务本质上,在没有影响客户交付的前提下,偏差5天的一定就比3天差吗,这些数字是线性可比的吗?把这些数字搞成线性的,就会牵引队伍为了遗留缺陷率,过点之前停止测试,问题单暂缓提交的现象。
综上所述,软件没有银弹,没有某个技术,或者某个开发模式、某套流程能够一劳永逸地解决效率问题。但我们的管理者又总在试图寻找银弹,希望用几个线性数字就能衡量软件开发效率,区分考核,希望某些技术、某个模式能让我们效率倍增,而且还要年年增加。即使当下轰轰烈烈的效率运动,又有减法做成加法的迹象,各种访谈、研讨、汇报,比着看各种“减”掉的数字……这些做法其实反而损害了效率,导致各方面都在不断地做加法,不断地折腾基层开发队伍。
因此,我们需要回归业务本质,聚焦在宏观经营层面上审视投资效率,收旧约新,多做减法,微观上则要放开放活,无为而治,不搞规定动作,团队、个体的活力也就自然激发出来了。