⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://dwz.cn/dqgOrbQo 「徐宏伟」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

本文来源华为人:徐宏伟,转给大家观摩下。

一天晚上,我和老婆聊天,说部门要我写个“大咖谈软件”的文章,老婆斜了我一眼,淡淡地说:“Linus大神21岁就写出了Linux内核的雏形,缔造了一个自由主义的开源世界;张小龙28岁写出了foxmail,在2000年就卖出了1200万的价格。大咖,认识您这么久了,还不太了解您有什么杰出的成就?”我讪讪地咽了口水:“好吧,我重新组织下语言,我需要写个谈软件的文章……”

回首过去这半年,软件总工、软件专家的任命,让我们这些写了十多年代码的软件工程师激动不已。我2006年进入公司,几乎参与了华为3G控制器产品的完整生命周期,见证了华为3G从起步、上升、灵魂深处的改进、巅峰、回落的波澜壮阔历程,并在35岁“高龄”有幸加入到5G开发部的大家庭。

十几年来,我一直坚持在编码岗位,经历了普通开发人员、TL、MDE、MDEL、SDM(云化团队)、Committer、软件专家等各种岗位。然而我却深知,不算大牛的我,从事编码这个“高危”职业十几年而没有被拿去“祭天”,依靠的是一个程序员的自我修养——扎实的基础软件能力、如履薄冰的工作态度、对技术孜孜不倦的追求。

幽默的“祭天”说明

好代码长什么模样

记得几年前部门第一次评选优秀代码,我成为“金码奖”获得者之一。是因为代码很炫吗?并不是。我参与评选的代码,遵循着简单的原则:简洁、逻辑清晰、函数职责单一、合理的数据结构设计。并没有使用高深的编码技巧,也没有应用某某设计模式。正如公司最新的C/C++语言编程规范,也是将编写简洁的程序放在首位。简洁、逻辑清晰的代码,易于阅读和维护,这段代码后面也因需求变化而被修改,但却从来没有引入过网上问题。

当然,简单不代表没有思考,恰恰相反,更需要我们在写代码之前谋定而后动、三思而后行。有一次项目组安排我做性能优化,通过反复分析热点函数、反复测试比对不同话务模型下的性能差异,前前后后花了3个星期的时间,我找到了引起性能恶化的最关键因素。最终我决定采用修改备份机制、减小备份数据的优化措施。这些方案代码改动都很小、很简单,但实际优化效果却很好,满足了未来几年业务发展的需求。

再来看另一个例子,某局点升级新版本后出现CPU负载上升的问题。经过近两周的攻关,我最终定位是新版本在业务处理流程中新增了直接读取DB内核的操作。直接读取DB内核,代码处理简单,也能正常实现业务功能,但是性能却非常差。如果开发过程中能多想一步,采用缓存的方案,性能会有天壤之别,也是更好的代码。

人们常说唯一不变的就是变化,客户需求一直在变化,我们的代码也会被动或者主动地在变化。设计出可扩展、自动适应客户需求变化的软件架构,是软件工程师永恒的追求。这说说容易,做起来却很难。需要我们不停积累业务知识,扩展知识面,勤于思考,识别技术未来演进趋势。我们无法从一开始就做一个无所不能的架构,来包含未来的千变万化,即使能,交付节奏也不一定允许。满足当前及未来一定时间内业务需要的设计,或许就是最合适的。

练好扎实的基本功

能写出好代码,更要能持续地写出好代码,需要我们深刻理解技术原理和业务逻辑。前提是具备扎实的编程基础,即基础软件能力,如基础的数据结构和算法、编译原理等。

去年底,我跟部门几个软件高手一起,去外部参加了一次互联网架构大会。AI、区块链、物联网、云、中间件等时尚、热点、风口相关的议题非常多。但是我没想到,最火爆的却是一些基础软件设计、架构设计和演进之类的专题。就像武侠小说写的一样,练好基本功、练好内功,后续无论什么精妙招式,都会信手拈来。

另外,一些编程习惯,如果坚持下去,对于编程修养提升也是非常有用的。比如快捷键的使用、有效的代码注释、命名规则、代码风格等。每次写代码除了追求好代码之外,我都会时刻去思考软件上的优化,能否能使用更少的内存,能否有更好的性能。重视数据结构中的每一个字段,重视每一处小的代码优化,都有可能给我们带来意想不到的收获。比如去年做性能优化,我们仅仅是将流程中的一处动态内存申请修改为静态内存池,却意外获得了30 CAPS(每秒呼叫次数)的性能提升。

团队合影

一行代码引发的惨案

有人问,道理我都懂,为什么却依然写不出好代码?

很多开发人员,因为个人习惯、赶工期、外部要求不高等多种原因,在编程时特别随意,直接Copy-Paste。我觉得程序员应当像追求生活品质一样,养成不将就的编程习惯、严谨的编程态度。

对于代码上库,我一直都是战战兢兢,如履薄冰。上库前我会反复看自己修改的代码,看修改代码的上下文,并进行修改前后代码比对。代码上库后再看几遍,确保都已按预期合入。进入公司这么多年,自己从来没有多合、漏合、错合过任何一行代码。

大家可能会觉得我这是小题大做,但事实上,这都是历史上曾经发生过的惨痛教训。我们在某国升级新版本后发现用户接入成功率恶化,最后定位是由于一行代码被误删除导致的。事后回溯,开发人员自己都不记得这一行代码为什么会被删除。还有一次,一行代码被误删除,导致一个关键KPI指标:软切换统计次数有变更。部门把这两起事件总结为“一行代码引发的惨案”,无论是对产品品牌、客户印象、还是对于个人,都造成了恶劣的影响。

事后大家都在思考,我们有结对编程、代码检视、开发者自测试等非常完善的开发流程,还有MDE(模块设计师)检视作为代码上库前的“守门员”,为什么还会发生这么低级的错误?是流程没执行到位,还是MDE疏忽、没把好关?

在IPD 2.0变革中,公司借鉴开源组织的Committer运作,来加强我们的Committer机制和文化。5G开发部也选拔、任命了一批Committer,我有幸成为其中之一。刚开始履行Committer职责时,我有点疑惑:这不就是给MDE角色披上了新的外衣,把MDE原先“私下”做的事情,通过Committer统计数据给呈现出来嘛?

不过,经过几个月的摸索、实践后,我渐渐地明白,Committer机制应该是一种文化上的变革,牵引大家提升自己的软件能力。Committer的职责很多,作为代码提交前的最后一道关卡,这是在当前人员能力不足阶段有效果,但是最终应该被弱化的一项实践。参与编码前的软件设计、持续做好架构看护和技术债务清理,让大家都有更大的机会写出更好的代码,我认为这是Committer更大的价值。

随着个人和组织的软件工程能力提升,自动化测试防护网和变更防护墙建设完善之后,前面提到的“一行代码引起的惨案”,是可以避免的。

“变更防护墙”够不够可靠

对于大部分老员工,特别是无线2G/3G/4G等部门的老员工来说,一提到变更控制,都会如临大敌。版本升级后,KPI变差是绝对不允许的,严重时可能面临版本回退、客户投诉和上报事故。而KPI变好,除了要向客户解释,还有可能面临商务风险,客户会觉得之前吃亏了。现实世界对我们就是这么苛刻,谁让我们是影响世界的通信软件工程师呢,他们这是爱之深、责之切啊!

我们开发一个版本,动辄涉及几十万代码的新增、修改或重构。要想不引入变更问题,除了做好设计、结对编码、代码检视和测试之外,我认为最关键的就是完善的自动化防护网。在3G时,我带着两个同事将IT测试工程从只有几百个用例扩充到上万个用例。全方位的场景覆盖、严密的信元有效性检查、完善的用例失败判决机制、无死角的资源泄漏检查等手段,让变更错误无所遁形,给3G留下了一道变更防护墙。

开发过程中补充IT和PC-ST测试用例,不是为了提升代码覆盖率,而是为了自动化防护。而要能达成自动化防护的前提,是每个用例都具备完善的有效性检查,否则防护网就是形同虚设。几年前,我跟一个同事开玩笑:“我会故意将某行代码改错,看看你补充的用例是否能检查出来。”让我意外的是,在交付紧张的情况下,他仍然多花了半天时间完善用例有效性检查,并请我故意改错代码来做试验。当然,最终的结果是,他准备得很充分,我没能发现问题。多么有自我追求的一个程序员!

保持对于新兴技术的好奇心

说起程序员的追求,我还想起了2016年参与的一个产品云化项目,我负责弹性伸缩特性的方案设计。在此之前,我一直在投入嵌入式软件开发,虽然期间产品也换了好几代的硬件,经历了产品与平台解耦、制式间解耦、软件与硬件解耦等过程,但是对于服务化、微服务化、云化等概念,我却基本处于懵懂的状态。

不懂怎么办,只能是“站在巨人肩膀上,为我所用”。兄弟产品线不是已经做了吗,那就找他们做同行协助;友商不是有路标和规划了吗,那就在他们的有限材料中寻找可借鉴的地方;互联网的亚马逊云、阿里云不是有非常成熟的方案了吗,那就下载他们的产品手册和用户指南……那段时间感觉自己就像是入了魔一样,疯狂地学习分布式软件相关技术,疯狂地吸收各方面的能量为我所用,最终给出了一个令自己和项目满意的设计方案。

这也让我充分意识到自己之前把眼光局限于所在产品、系统、子系统的不足。

作为一个程序员,除了要提升自己的基础软件能力,我们也要始终保持对于新兴技术的好奇心,孜孜不倦的追求,不断拓宽自己的视野。而这方面的能力和诉求,在5G时代更是如此。

当前我们华为5G面临的网络安全问题,虽然有着很大的政治因素,但也从侧面反映了5G的战略意义。超高速率、超大连接数、超高可靠低时延,对我们在软件处理时延、可靠性、安全、韧性等方面的能力都提出了更高的要求。同时,5G承载的垂直行业应用、接口开放和硬件“白盒化”等趋势,也必将对我们当前的知识和技术体系,提出更大的挑战。

公司计划用五年的时间,全面提升软件工程能力,对我们是考验,也是机会。统一编程规范、整洁代码、整洁优雅的架构,不同的人有不同的追求,需要我们有持之以恒、水滴石穿的决心。五年或者十年后,当我们回首时,会发现自己曾经的付出是值得的。正如,清代著名学者王国维提出的读书三境界之第三境:“众里寻她千百度,蓦然回首,那人却在灯火阑珊处。”

也许我们绝大多数人终其一生也无法成为Linus、张小龙这样的大神。然而,我们能够做一个有修养的程序员,并参与到改变世界的华为5G产品开发中来,在人类的通信史中留下自己的优秀代码,幸哉。

文章目录
  1. 1. 好代码长什么模样
  2. 2. 练好扎实的基本功
  3. 3. 一行代码引发的惨案
  4. 4. “变更防护墙”够不够可靠
  5. 5. 保持对于新兴技术的好奇心