「如何实现流动式软件发布」线上课堂开课啦,快来报名参与课堂抽奖吧~ 了解详情
写点什么

《阿里巴巴 Java 开发手册》背后的故事

2017 年 9 月 27 日

互联网的世界,风云变幻,经历着雷厉风行的洗牌,在这个快速迭代升级的风口上,创新成了几乎所有互联网企业的核心理念。而规范是需要一定的匠心去打造的,迁就规范,似乎就碍了创新,在技术日新月异、业务风口变换的今天,如何才能权衡好创新和匠心呢?

最近,阿里巴巴对外正式公开《阿里巴巴 Java 开发手册》终极版。回望这些年,国内的代码规范良莠不齐,通常都是各公司程序员基于个人开发过程中的经验总结出来的,验证不够充分,涉猎不够全面,描述不够准确。行业代码,可谓鱼龙混杂,各有千秋,没有统一的标准。《阿里巴巴 Java 开发手册》对中小企业,乃至对行业都有着很强的借鉴作用。

Java 工程师或许都经历过这样的场景:接手别人的代码时,因为没有注释,变量名五花八门,模块之间逻辑关系如麻,弄得满头雾水,一脸茫然,痛定思痛之后不得不推倒重来,这些都是不注重编程规范造成的,事倍功半。那如何权衡时间成本与代码规范?如何引领一名普通程序员走向优秀,进而迈向卓越?为此,InfoQ 采访了《阿里巴巴 Java 开发手册》作者杨冠宝。另外,杨冠宝也将会在 10 月 17 日举行的 QCon 全球软件开发大会上分享相关话题,欢迎关注。

宜未雨而绸缪,毋临渴而掘井

在阿里正式发布代码规范之前,孤尽回忆,那些牵一发而动全身的坏代码例子:如表达删除状态的字段名,非常多,像:delete/delete_flag/is_deleted,在数据分析时,总要小心翼翼,象文字游戏。而 0/1 还是 y/n 来表示已删除和未删除,更是神坑,极易造成线上问题。再如,批量接口定义时,没有接口保护很容易造成服务器方内存耗尽,产生 OOM 等等。

孤尽认为,国内的开发者大多重技能,轻规范。此前有这么一个段子,程序员 A 和 B,A 每天只写 100 行代码,字里行间规范清晰,其余大部分时间都在整理文档,备注的非常详细,B 每天写 50000 行代码,却很少写注释,天马行空,为此还嘲笑 A 不够高效。随着业务越来越复杂,客户需求随时可变,两个人都开始组建团队,这个时候,功夫不负苦心人,A 之前的努力都派上了用场,B 只能佩服加惭愧。

可见,编程规范,对于程序员而言,不是要靠强制约束,更关键的还是要让其从认知,思想觉悟上提高,骨子里意识到规范也是一种生产力。

原始社会的争端,更多的是讲究个人的蛮力,而三国时代的群雄并起,开始讲究士兵的配合与团队,而现代战争,海陆空、信息兵、工程兵,无不需要紧密配合。现在软件发展到现在,只是造一句 hello world 走天下的时代,已经过去了,需要团队紧密协作。

编程风格的不一致,明显影响了团队研发效能。有时候,团队可以为没有营养的接口定义方式,能够吵上一天。公说公有理,婆说婆有理,重点是:最后没有达成一致。编程规范就是极大的减少没有营养的争论,真正把时间放在需要解决的核心问题上。

程序员都是天生幻想创造个性化作品的艺术家,变着法子想着要如何与众不同,最好代码只有自己能够看懂,只有自己能够维护。但是个性化应尽量表现在代码质量和算法效率的提升上,而不是对于合作规范上纠缠不休的争论。再者,公司是请程序员来产出实际价值的,而不是经常消耗时间为 TAB 还是空格的事情争得脸红脖子粗的。有时候,就是一个规定,就像交规靠左行,还是右行一样,大家这么做了,协作效率自然就提升了,正所谓无规矩不成方圆,无规范难以协作。

简单,适用的代码规约背后,所传递的是技术上的追求卓越,协同合作的精神,是每个技术团队不可缺失的重要利器。

领先半步,是基于行业背后的思考

以前阿里巴巴对外开放的是一些纵向领域的中间件产品,如 dubbo/fastjson/jstorm 等,这次《阿里巴巴 Java 开发手册》的发布,也是第一次公开横向标准类的技术成果。

孤尽坦言,在此之前,阿里内部的 Java 编程规范,各自为政,没有权威的官方标准,痛定思痛的抉择后,形成了内部称为《集团开发规约》的宝典,经过脱敏后,对外发布《阿里巴巴 Java 开发手册》。编程规范发布后,希望业界的代码能够规范化,提升业界整体沟通和研发效率。

据悉这本手册历时 3 年,融汇了近万名开发者的智慧,几乎 Java 日常开发中的方方面面都有所涉及。当谈及是如何逐步接受实战检验的?孤尽描述:阿里巴巴推动中台化战略,对于项目机动联合的要求越来越高。而规范不一的痛楚,使大家意识到统一规范的紧迫性与必要性。以集团平台技术事业群为核心,以国际事业部的规范为蓝本,进行大幅度修订,多轮讨论,投票,甚至是辩论,艰难地形成最后的统一规范。首先,意识形态上统一,结合丰富的正反例,以及历史数据分析,融合已有规范,取长补短,明确规范往前一步是生,退后一步是死的危机感;其次,成立集团专业委员会来负责内容的制定,成立宣传推广项目组定向推进宣传工作,在过去一年中,几乎是饱和式轰炸地宣传方式,让规范深入人心;最后,成立检测项目组,如果自动化检测,如果不符合,对不起,不能发布上线。

对外版本的更新上,从之前的周频度,到后来的月频度,现在以季度的时间维护来修订,阿里巴巴有一个专门项目组来长久地维护《阿里巴巴 Java 开发手册》的与时俱进。终极版,只是 PDF 版本的终结,而不是《阿里巴巴 Java 开发手册》的最后一版,未来会转为线上维护,大家可以在线提交 issue,允许企业和个人 fork 分支用以非商业化用途,提升团队及个人的研发效能。

可见,扎根内部,立足行业,着眼未来,行业编码规范化水平,可以帮助行业人员提高开发质量和效率、大大降低代码维护成本。

不是一番寒彻骨,怎得梅花扑鼻香?

大家看到的都是蝴蝶飞舞的风光,而只有自己才明白破茧成蝶的痛苦。孤尽回忆了当时对内和对外遇到的最大挑战:对内而言,程序员的天性是自由的,没有人愿意被束缚。这个过程的意识碰撞,甚至是火星碰地球一样,即使插件普及率接近八成,但是挑战依然还存在,尤其是新入职的有经验的社招开发同学。扫描自动化只是实现了 30% 的条目,有 70% 的条目是没有落在自动化上,所以需要在意识上非常清楚地知道背后的逻辑。对外,个别同学在论坛上表示了这是阿里巴巴 KPI 的产物,感觉阿里从 KPI 孵化出来,都是怪兽,其实不然,这是一种愿意和技术情怀驱动。开放给业界,首先想到的是帮助到大家,一起提升程序员的幸福感。最大化地让大家懂得规约背后的意义,及它的衍生价值。

健壮的代码是经得起重复的修改和重构的

Java 开发工程师都比较关心一个问题:代码出现之前如何排除掉不给 Bug 出现的机会?孤尽给出了建议:

首先,定位问题比解决问题更加重要。解决问题,在计算机的世界里,都是能够找出方案的。无非是解决问题姿势是否够优雅,解决问题的时间长短,解决问题能否解决的同时,解决掉隐含的其他问题。

所以需要时时有异常分支流程的概念,清晰地知道这个世界上最强大的测试同学是用户,他们的操作行为千奇古怪,尽可能把自己想成傻的不能再傻的用户。曾经有一个故障,就是一个好奇的用户签名使用了:–&@# 这种奇怪的字符,结果被 SQL 注入,导致数据库被批量更新。

聊聊《阿里巴巴 Java 开发手册》细节

据悉,《阿里巴巴 Java 开发手册》主要是面向 Java 开发群体,Java 做为面向对象语言,在业界的生命力还是非常强大的,技术生态丰富,框架结构成熟,经历了超高并发的“双十一”实战考验,阿里想把多年的 Java 技术积累回馈给 Java 开发者社区。在里面可以找到很多的技术规范、最佳实践,避坑指南等。

其中引入了数据库、安全、服务器等知识。现代软件行业的高速发展对于开发者的综合素质要求越来越高,因为不仅是编程知识,其它维度的知识结构也会影响到软件的最终交付质量。比如:数据库的表结构和索引设计缺陷可能带来软件上的架构缺陷或性能风险;工程结构混乱导致维护困难;没有鉴权的漏洞代码被黑客攻击等等。

《阿里巴巴 Java 开发手册》划分为编程规约、异常日志规约、单元测试、MySQL 规约、工程规约、安全规约六大块。那么衍生的问题是为什么我们提到的这些看似与编码毫无关系的内容?有人提问,仅安全规约如果扩展开来可以是上百页的资料,不知道写在其中的意义何在?其实,主要关注的是与开发紧密相关的知识点,试问一个不知道水平权限校验的 Java 开发者,会是一个合格的程序员吗?这本手册不是提倡大家深究所有的知识点而成为安全专家、运维专家,而是关注在编码相关的生态知识上。

约束力等级为何是三级?《阿里巴巴 Java 开发手册》根据约束力强弱及故障敏感性,规约依次分为强制、推荐、参考三大类。强制是一种指令型的,是协作的 Gap,或是故障的痛点;而推荐,希望这样做是一件好事,大家都这样做,结构更清晰,协作更高效,但是不这样做也不会死。而参考分成两种情况:第一种是无法用代码量化的描述,提倡什么什么样的做法,如索引的创建索引时,宁滥勿缺的错误做法;第二种是真心觉得或左或右都可以,只是有倾向于一种,这个自由度由开发者自己把握。

扩展的说明、正例、反例用来表达什么?如果只是冷冰冰的条目,对于阅读者理解成本和记忆成本都是很大的挑战,《阿里巴巴 Java 开发手册》希望阅读者能够非常舒心地看完整个文档,掩卷遐思,亦有所得。具体来说,“说明”是对内容做了引申和解释,为求知其然;“正例”提倡什么样的编码和实现方式,推荐做法的其中之一;“反例”说明需要提防的雷区,以及真实的错误案例,让人知其不然。

千淘万淘虽辛苦,吹尽狂沙始到金

每个人在未来的世界,最重要的不是做的多久,而是在于做的多好。其实久和好是两个不同的概念,要想做的久,做法是不一样的,要做的好,做法也不一样,有时候活的久,不一定活得好,又要活得久,又要活得好,那是非常难的。但就是这丁点大的差距在时间维度上日积月累,导致了程序员之间的巨大差距。

有人说,Java 程序员的日常是搬砖,那么砖在哪里,就是一个个键盘。除此之外,难免还要和产品汪、运营、无厘头的用户打交道。

都说普通程序员到优秀程序员的过程,无非就是量变到质变的过程。其实不然,代码多少行才会产生质变,很难量化,但是如果没有深度地思考,就是写再多的代码也是枉然。就像一个泥水工,如果没有胸怀,没有思考,永远只是垒砖头的。

而在这其中,一名普通的程序员和一名优秀的程序员就出现了,优秀是知道自己的差距在哪里。一些刚入行两三年的程序员,经常说这个我懂了,那个我懂了,感觉写代码很枯燥,我要转型,要么往产品方向,要么向架构师方向,要么向管理方向。其实这距离一位基本程序员的自我修养,还只是摸到边。如果静下来,抬头仰望星空,发现优秀离自己两万里,而卓越更是无边无际。

那一名优秀的程序员如何突破成为一名卓越的程序员呢?卓越是弥补了这些差距。

比如:
1) 融会贯通技术知识体系 ;
2) 品味编程语言的内在美,感悟语言哲学 ;
3) 勇立新技术潮头。

最后,突然发现,在计算机的世界里,所谓的全才是不存在的。真正的卓越,往往是某个语言方向,某个领域方向上,持之以恒的追求与实践,以及永不磨灭的热爱。

Java 开发中如何用工匠精神突破创新?

对于任何一个项目,从重要性上来说,分为核心业务、非核心业务。前者更重视产品文档、技术方案、规范化编程。从需求时效上来说,分为临时性需求、长远型需求。临时性需求,相对来说更加讲究快速实现、快速迭代。而长远型需求,一定要考虑到,可能由不同的人在不同的阶段进行开发,这个时候的效率和质量就会受到很大的挑战。

其实,任何事情,都是一个度的哲学问题。如果只写文档,代码编写效率低,不行;如果天马行空,只写代码,不写任何文档和注释,更不行,表面上诗意盎然,事实上是暗流涌动。这就需要权衡好代码和文档,两者都要抓都要硬。

在 Java 开发过程中,代码和文档的完美结合,讲究的就是匠心和创新,这是一种态度,更专注细节,力求完美。匠心来自坚守,沉浸在一个行业打磨若干年,正是因为这种坚守才能洞察用户需求,比消费者自己更了解他们之后,创新才会针对消费者的变化主动触发,匠心恰恰是创新的前提和基础。企业需要匠心精神的沉淀,也需要创新方式的突破,匠心和创新是相辅相成,切莫对立地去思考。


受访人简介:杨冠宝,花名“孤尽”,取自:

1.)孤帆远影碧空尽的缩写。那样的场景很萧瑟,但也很安静,很怀念,很感恩。伫立山顶之巅,遥望小帆远远淡去,一种感恩。

2.)独孤九剑,破尽天下武学。

无论是前者,还是后者,一方面,说明内心笃定的自信。另一方面,学习有时候是孤独的,成功有时候也是孤独的。希望在孤独的道路上,左手温暖右手。有胸怀,有远见,程序员不要固步自封。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017 年 9 月 27 日 19:005456

评论

发布
暂无评论
发现更多内容

架构实战课-模块1作业

Nullrable

学习

架构实战营 - 模块1 - 微信架构及学生管理系统毕设架构

雪中亮

架构实战营 #架构实战营

Redisson 分布式锁源码 04:可重入锁释放

程序员小航

Java redis 分布式锁 redisson redisson 分布式锁

电脑误删文件如何恢复?两个方法解决你的困扰

淋雨

EasyRecovery 文件恢复 硬盘数据恢复

C++ for Financial Mathematics读书笔记

bobcatzoo

c++ 金融

Linux之find命令

入门小站

Linux

2021前端面试必备题+答案

it优课

Rust从0到1-Cargo-自定义命令

rust cargo 自定义命令 Custom Commands

在线HTTP请求/响应头转JSON工具

入门小站

工具

架构实战营 模块一 作业

一雄

架构实战营 模块一

5款最强且免费的Python IDE

Jackpop

sublime-text vscode #python

架构实战营 作业 模块一

脉醉

#架构实战营

太好用!教你几招Python魔法方法的妙用

Jackpop

Python 数据分析 后端

Google 宣布 Android APK 退位对鸿蒙意味着什么?|【话题讨论】

老猿Python

android 鸿蒙 Google AAB格式

模块1作业

gevin

架构实战营

开发小技巧之:unicode的排序和正则匹配

程序那些事

Unicode 排序 程序那些事

关于深度学习编译器,这些知识你需要了解一下

华为云开发者社区

深度学习 tensorflow 编译器 算子开发 深度学习编译器

写代码是意识流?

卢卡多多

代码规范 意识 7月日更

吴恩达Andrew Ng Coursera学习总结合集,编程作业技巧合集 John 易筋 ARTS 打卡 Week 54

John(易筋)

ARTS 打卡计划

网络攻防学习笔记 Day65

穿过生命散发芬芳

网络攻防 7月日更

从大厂不允许使用 SELECT * 说开去

喵叔

7月日更

炫酷!一款有颜又强大的Python工具包

Jackpop

Python 开发工具

【LeetCode】点菜展示表Java题解

HQ数字卡

算法 LeetCode 7月日更

徒步运动系统开发|徒步运动软件APP开发

开發I852946OIIO

斗宠大陆APP开发|斗宠大陆软件系统开发

开發I852946OIIO

浏览器历史难题解决了....

Jackpop

chrome chrome扩展

“无法运行Windows 11”?最靠谱的升级方案来了!

Jackpop

windows windows 11

程序员跳槽指南

孙叫兽

程序员 跳槽 攻略

Rust从0到1-Cargo-Workspaces

rust cargo workspaces

滴滴出行因违规收集个人信息被下架:必须整治鱼龙混杂的应用市场

石头IT视角

学习哪门编程语言好,我来回答

实力程序员

《阿里巴巴Java开发手册》背后的故事-InfoQ