【腾讯Bugly干货分享】揭秘:微信是怎么样用libco支撑8亿用户的澳门美高梅手机网站

  1. 【强制】定义 GAV 坚守以下规则: 1) GroupID 格式:com.{集团/BU
    }.业务线.[子业务线],最多 4 级。
    证实:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress 等 BU
    一流;子业务线可选。
    正例:com.taobao.tddl 或 com.alibaba.sourcing.multilang
    2) ArtifactID
    格式:产品线名-模块名。语义不重复不遗漏,先到库房中心去调研一下。
    正例:tc-client / uic-api / tair-tool
    3) Version:详细规定参考下方。
  2. 【强制】二方库版本号命名形式:主版本号.次版本号.修订号
    1) 主版本号:当做了不匹配的 API
    修改,或然扩大了能改变产品趋势的新功用。
    2) 次版本号:当做了向下包容的效能性新增(新增类、接口等)。
    3) 修订号:修复 bug,没有改动章程签名的作用增强,保持 API 包容性。
  3. 【强制】线上采纳不要借助 SNAPSHOT
    版本(安全包除外);正式公告的类库必须使用 RELEASE 版本号升级+1
    的法门,且版本号不容许覆盖升级,必须去中心仓库举行调研。
    声明:不依赖 SNAPSHOT
    版本是保险应用发表的幂等性。此外,也得以加快编译时的打包打造。
  4. 【强制】二方库的骤增或升级,保持除作用点之外的任何 jar
    包仲裁结果不变。即便有改变, 必须通晓评估和验证,指出开展
    dependency:resolve 前后信息比对,如若决策结果完全不一
    致,那么通过 dependency:tree 命令,找出差别点,举行<excludes>排除
    jar 包。
    5.
    【强制】二方Curry可以定义枚举类型,参数可以运用枚举类型,但是接口重返值不容许利用枚
    举类型恐怕隐含枚举类型的 POJO 对象。
    6.
    【强制】看重于三个二方库群时,必须定义七个联合版本变量,防止版本号差别。
    证实:着重springframework-core,-context,-beans,它们都是同一个本子,可以定义三个
    变量来保存版本:${spring.version},定义正视的时候,引用该版本。
  5. 【强制】禁止在子项目标 pom 看重中冒出雷同的 GroupId,相同的
    ArtifactId,可是不一样的 Version。
    表明:在地头调试时会使用各子项目指定的本子号,可是合并成一个war,只好有贰个版本号
    并发在最终的 lib
    目录中。曾经出现过线下调试是天经地义的,发布到线上出故障的先例。
  6. 【推荐】工具类二方库已经提供的,尽量不要在本利用中编程已毕。
     json 操作: fastjson
    阿里Baba(Alibaba) JAVA 开发手册
    29 / 32

— 非语言级其余lambda完成,结合协程原地编写并实施后台异步职分 (New);

依照epoll/kqueue已毕的小而轻的网络框架,基于时间轮盘完结的高品质定时器;

(二) 二方库规约

异步化改造的选拔

为了进步微信后台的产出能力,一般的做法是把现网的兼具服务改成异步模型。那种做法工程量巨大,从框架到事情逻辑代码均必要做三次彻底的改建,耗时耗力而且风险巨大。于是大家开端考虑动用协程。

但利用协程会见临以下挑衅:

  1. 业界协程在c/c++环境下并未广泛利用的阅历;
  2. 如何决定协程调度;
  3. 如何处理一起风格的API调用,如Socket、mysqlclient等;
  4. 哪些处理已有全局变量、线程私有变量的使用;

最后我们透过libco消除了上述的具备难点,已毕了对事情逻辑非侵入的异步化改造。大家利用libco对微信后台上百个模块举行了协程异步化改造,改造进度中工作逻辑代码基本无修改。于今,微信后台绝大多数劳务都已是多进度或二十四线程协程模型,并发能力相比较从前有了质的晋级,而libco也变为了微信后台框架的水源。

  1. 【强制】对 trace/debug/info
    级其余日记输出,必须使用规范输出格局仍然应用占位符的方 式。
    说明:logger.debug(“Processing trade with id: ” + id + ” symbol: ” +
    symbol); 如果
    日记级别是 warn,上述日志不会打印,可是会实施字符串拼接操作,假设 symbol
    是目的,会
    履行
    toString()方法,浪费了系统能源,执行了上述操作,最后日志却未曾打印。
    正例:(条件)
    if (logger.isDebugEnabled()) { logger.debug(“Processing trade with id: “

共同风格API的拍卖

对此联合风格的API,重如若共同的网络调用,libco的主要职分是破除那一个等待对能源的挤占,升高系统的现身质量。1个例行的网络后台服务,大家只怕会经历connect、write、read等步骤,已毕一次完整的互联网互动。当贰头的调用那几个API的时候,整个线程会因为等待网络互动而挂起。

尽管如此联合编程风格的产出品质并不佳,不过它有着代码逻辑清晰、易于编写的优点,并可援助工作快速迭代敏捷开发。为了持续保证同步编程的亮点,并且不需修改线上已部分事情逻辑代码,libco立异地接管了互连网调用接口(Hook),把协程的让出与回复作为异步网络IO中的一次事件注册与回调。当工作处理蒙受同步网络请求的时候,libco层会把这次互连网请求注册为异步事件,本协程让出CPU占用,CPU交给其他协程执行。libco会在互联网事件暴发或然逾期的时候,自动的复原协程执行。

大部协办风格的API我们都因而Hook的章程来接管了,libco会在方便的机会调度协程复苏执行。

阿里Baba(Alibaba) JAVA 开发手册
8 / 32

本文来源于腾讯bugly开发者社区,未经我同意,请勿转载,原文地址:http://dev.qq.com/topic/58203cfcd149ba305c5ccf85

接纳字符集 gb2312;若是还拾贰分,执行命令:set
termencoding=gbk,并且间接运用中文来
展开检索。
三、MYSQL 规约
(一) 建表规约

协程信号量

在十六线程环境下,大家会有线程间同步的须求,比如一个线程的进行要求等待另多个线程的信号,对于那种须要,大家一般是利用pthread_signal
来解决的。在libco中,大家定义了协程信号量co_signal用于拍卖协程间的出现需要,2个协程可以通过co_cond_signal与co_cond_broadcast来决定通告多个等待的协程只怕指示全部等待协程。

Alibaba JAVA 开发手册
28 / 32

总结

libco是多个很快的c/c++协程库,提供了到家的协程编程接口、常用的Socket族函数Hook等,使得业务可用一块编程模型快捷迭代开发。随着几年来的平静运转,libco作为微信后台框架的基石发挥了重大的效用。


越来越多美观内容欢迎关怀bugly的微信公众账号:

澳门美高梅手机网站 1

腾讯
Bugly
是一款专为移动开发者营造的品质监督工具,帮助开发者连忙,便捷的定位线上应用崩溃的处境以及缓解方案。智能合并功效帮忙开发同学把每日上报的数千条
Crash
依照根因合并分类,天天晚报会列出影响用户数最多的垮台,精准定位功能协理开发同学定位到出难题的代码行,实时报告可以在揭晓后高速的垂询应用的质感处境,适配最新的
iOS, Android 官方操作系统,鹅厂的工程师都在动用,快来加入大家吧!

  1. 【强制】全体的同一类其他包装类对象之间值的可比,全体应用 equals
    方法相比。
    讲明:对于 Integer var=?在-128 至 127 之间的赋值,Integer 对象是在
    IntegerCache.cache
    发出,会复用已有对象,那些间隔内的 Integer
    值可以直接接纳==举行判定,然而这么些距离之
    外的保有数据,都会在堆上发生,并不会复用已有对象,那是一个大坑,推荐应用
    equals 方
    法进行判断。
  2. 【强制】关于基本数据类型与包装数据类型的使用规范如下: 1) 全体的
    POJO 类属性必须运用包装数据类型。
    2) LANDPC 方法的重返值和参数必须采取包装数据类型。
    3) 全数的部分变量推荐应用基本数据类型。
    证实:POJO
    类属性没有初值是指示使用者在急需运用时,必须协调显式地进行赋值,任何
    NPE 难题,只怕入库检查,都由使用者来保管。
    正例:数据库的询问结果或者是 null,因为电动拆箱,用为重数据类型接收有
    NPE 风险。
    反例:某工作的贸易报表上显得成交总额涨跌处境,即正负 x%,x
    为基本数据类型,调用的
    LANDPC
    服务,调用不成功时,重返的是默许值,页面显示:0%,那是不客观的,应该突显成中划
    线-。所以包装数据类型的 null
    值,可以代表额外的新闻,如:远程调用退步,万分退出。
  3. 【强制】定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性暗中同意值。
    反例:某工作的 DO 的 gmtCreate 默许值为 new
    Date();不过那一个性情在数量提取时并不曾置
    入具体值,在更新任何字段时又顺手更新了此字段,导致创制时间被修改成当下时刻。
    10.【强制】体系化类新增属性时,请不要涂改 serialVersionUID
    字段,防止反连串战败;假设
    统统不包容升级,防止反连串化混乱,那么请修改 serialVersionUID 值。
    证实:注意 serialVersionUID 差距会抛出种类化运营时至极。
    11.【强制】构造方法里面禁止参加此外业务逻辑,尽管有初叶化逻辑,请放在
    init 方法中。
    12.【强制】POJO 类必须写 toString 方法。使用工具类 source> generate
    toString 时,若是继
    承了另壹个 POJO 类,注意在前面加一下 super.toString。
    注脚:在措施执行抛出卓殊时,可以直接调用 POJO 的
    toString()方法打印其属性值,便于排
    查问题。
  4. 【推荐】使用索引访问用 String 的 split
    方法取得的数组时,需做最后贰个相间符后有无内 容的反省,否则会有抛
    IndexOutOfBoundsException 的风险。

gethostbyname的Hook方法

对此现网服务,有只怕要求通过系统的gethostbyname
API接口去查询DNS获取真实地址。大家在协程化改造的时候,发现我们hook的socket族函数对gethostbyname不适用,当三个协程调用了gethostbyname时会同步等待结果,那就导致了同线程内的其余协程被延时执行。我们对glibc的gethostbyname源码进行了商讨,发现hook不奏效紧借使出于glibc内部是概念了__poll方法来等待事件,而不是通用的poll方法;同时glibc还定义了三个线程私有变量,差距协程的切换或者会重入导致数据不纯粹。最后gethostbyname协程异步化是透过Hook
__poll方法以及定义协程私有变量化解的。

gethostbyname是glibc提供的一起查询dns接口,业界还有许多美丽的gethostbyname的异步化化解方案,不过那一个完结都亟需引入一个第壹方库并且必要底层提供异步回调公告机制。libco通过hook方法,在不修改glibc源码的前提下促成了的gethostbyname的异步化。

阐明:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray
方法内部将重新分配
内存空间,并回到新数组地址;假如数组成分大于实际所需,下标为[
list.size() ]的数组
要素将被置为
null,其它数组成分保持原值,由此最好将艺术入参数组大小定义与集合成分
个数一致。
5.
【强制】使用工具类Arrays.asList()把数组转换来集合时,不可能应用其修改集合相关的措施,
它的 add/remove/clear 方法会抛出 UnsupportedOperationException 至极。
声明:asList 的归来对象是三个 Arrays
内部类,并不曾落实集合的改动章程。Arrays.asList
呈现的是适配器情势,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { “a”, “b” };
List list = Arrays.asList(str);
第叁种情况:list.add(“c”); 运转时特别。
其次种情景:str[0]= “gujin”; 那么 list.get(0)也会随着修改。

libco框架

libco在框架分为三层,分别是接口层、系统函数Hook层以及事件驱动层。

澳门美高梅手机网站 2

  1. 【强制】防止用 Apache Beanutils 举行性能的 copy。 表达:Apache
    BeanUtils 品质较差,能够动用此外方案比如 Spring BeanUtils, Cglib
    BeanCopier。
  2. 【强制】velocity 调用 POJO
    类的个性时,提议直接行使属性名取值即可,模板引擎会自行按 规范调用 POJO
    的 getXxx(),倘使是 boolean 基本数据类型变量(注意,boolean 命名不须求
    加 is 前缀),会活动调用 isXxx()方法。
    证实:注意如若是 Boolean 包装类对象,优先调用 getXxx()的格局。
  3. 【强制】后台输送给页面的变量必须加$!{var}——中间的惊讶号。 说明:尽管var=null 大概不存在,那么${var}会向来呈未来页面上。
  4. 【强制】注意 Math.random() 那一个主意再次来到是 double 类型,注意取值范围
    0≤x<1(可以取
    到零值,注意除零充裕),假使想取得整数档次的自由数,不要将 x 放大 10
    的若干倍然后取
    整,直接动用 Random 对象的 nextInt 可能 nextLong 方法。
  5. 【强制】获取当前阿秒数:System.currentTimeMillis(); 而不是 new
    Date().getTime(); 表达:倘诺想拿到特别精确的皮秒级时间值,用
    System.nanoTime。在 JDK8 中,针对计算时
    间等情景,推荐应用 Instant 类。
  6. 【推荐】尽量不要在 vm 中投入变量注脚、逻辑运算符,更毫不在 vm
    模板中插足其余扑朔迷离的逻 辑。
  7. 【推荐】任何数据结构的应用都应限量大小。
    表达:那一点很难完全形成,但很频仍的故障都以因为数据结构自拉长,结果导致内存被吃光。

导语

libco是微信后台大规模利用的c/c++协程库,二〇一一年于今稳定运维在微信后台的数万台机械上。libco在二〇一三年的时候作为腾讯六大开源项目首次开源,我们如今做了三次较大的翻新,同步更新在https://github.com/tencent/libco
上。libco辅助后台敏捷的同步风格编程情势,同时提供系统的高并发能力。

正例: “test”.equals(object);
Alibaba JAVA 开发手册
7 / 32

纯属级协程匡助

libco暗中同意是每多个协程独享3个运维栈,在协程创立的时候,从堆内存分配一个定位大小的内存作为该协程的运转栈。如若大家用一个协程处理前端的3个接入连接,这对于1个海量接入服务来说,我们的劳动的并发上限就很不难受限于内存。为此,libco也提供了stackless的协程共享栈方式,可以设置若干个协程共享同三个运维栈。同2个共享栈下的协程间切换的时候,需求把当下的运作栈内容拷贝到协程的个体内存中。为了减小那种内存拷贝次数,共享栈的内存拷贝只暴发在不一样协程间的切换。当共享栈的占用者一向尚未改动的时候,则不需求拷贝运转栈。

澳门美高梅手机网站 3

libco协程的共享协程栈情势使得单机很简单接通千万连接,只需创制丰硕多的协程即可。我们通过libco共享栈格局创造1千万的协程(E5-2670
v3 @ 2.30GHz * 2,
128G内存),每10万个协程共享的利用128k内存,整个稳定echo服务的时候总内存消耗差不离为66G。

正例:在 sqlmap.xml 中引入 #start#, #size#
Map<String, Object> map = new HashMap<String, Object>();
map.put(“start”, start); map.put(“size”, size); 6. 【强制】不允许直接拿
HashMap 与 HashTable 作为查询结果集的输出。
反例:某同学为避免写1个<resultMap>,直接行使 HashTable
来选择数据库再次回到结果,结果
并发常常是把 bigint 转成 Long 值,而线上由于数据库版本不平等,解析成
BigInteger,导
致线上难题。

协程私有变量

多进度程序改造为四线程程序时候,大家得以用__thread来对全局变量举行迅速修改,而在协程环境下,大家创制了协程变量ROUTINE_VA途锐,极大简化了协程的改建工作量。

因为协程实质上是线程内串行执行的,所以当大家定义了1个线程私有变量的时候,可能会有重入的标题。比如大家定义了三个__thread的线程私有变量,原本是梦想每三个实践逻辑独享这么些变量的。但当我们的实施环境迁移到协程驾驭后,同二个线程私有变量,大概会有五个协程会操作它,那就导致了变量冲入的题材。为此,我们在做libco异步化改造的时候,把半数以上的线程私有变量改成了协程级私有变量。协程私有变量具有那样的性状:当代码运维在二十四线程非协程环境下时,该变量是线程私有的;当代码运营在协程环境的时候,此变量是协程私有的。底层的协程私有变量会活动已毕运转环境的论断并科学重返所需的值。

协程私有变量对于现有条件同步到异步化改造起了重大的职能,同时我们定义了多少个万分简单方便的法门定义协程私有变量,简单到只需一行声西夏码即可。

(九) 其它
1.
【强制】在选用正则表达式时,利用好其预编译功用,可以使得加快正则匹配速度。
表达:不要在方式体内定义:Pattern pattern = Pattern.compile(规则);

libco帮衬的表征

  • 毋庸侵入业务逻辑,把多进度、二十四线程服务改造成协程服务,并发能力得到那贰个升高;

  • 支撑CGI框架,轻松创设web服务(New);

  • 支持gethostbyname、mysqlclient、ssl等常用第贰库(New);

  • 可选的共享栈情势,单机轻松接入千万连接(New);

  • 一应俱全简洁的协程编程接口


类pthread接口设计,通过co_create、co_resume等简单清晰接口即可已毕协程的创办与回复;
— 类__thread的协程私有变量、协程间通讯的协程信号量co_signal (New);

  1. 【强制】在多个 switch 块内,各个 case 要么通过 break/return
    来终止,要么注释表达程序 将继续执行到哪3个 case 截止;在3个 switch
    块内,都无法不含有1个 default 语句并且位居
    最终,即便它怎样代码也尚无。
  2. 【强制】在 if/else/for/while/do
    语句中必须使用大括号,即便唯有一行代码,幸免拔取下 面的花样:if
    (condition) statements;
  3. 【推荐】推荐尽量少用 else, if-else 的法门可以改写成:
    if(condition){ … return obj; } // 接着写 else 的事情逻辑代码;
    表达:如若使用要 if-else if-else 方式发挥逻辑,【强制】请勿超过 3
    层,超越请使用状态
    设计情势。
  4. 【推荐】除常用方法(如
    getXxx/isXxx)等外,不要在标准判断中进行复杂的言语,以抓好 可读性。
    正例:
    //伪代码如下 InputStream stream = file.open(fileName, “w”);
    Alibaba JAVA 开发手册
    15 / 32

libco爆发的背景

最初微信后台因为工作须求复杂多变、产品须求飞速迭代等要求,超过半数模块都使用了半一块半异步模型。接入层为异步模型,业务逻辑层则是同步的多进度或十二线程模型,业务逻辑的出现能力唯有几十到几百。随着微信工作的增加,系统规模变得更为粗大,各个模块很不难蒙受后端服务/互连网抖动的影响。

  1. 【推荐】若是变量值仅在3个限制内变化用 Enum
    类。如果还包涵名称之外的延伸属性,必须 使用 Enum
    类,上面正例中的数字就是延长新闻,表示星期几。
    正例:public Enum{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4),
    FRIDAY(5),
    SATURDAY(6), SUNDAY(7);}
    (三) 格式规约
    1.
    【强制】大括号的选择约定。假设是大括号内为空,则简洁地写成{}即可,不须要换行;若是是非空代码块则:
    1) 左大括号前不换行。
    2) 左大括号后换行。
    3) 右大括号前换行。
    4) 右大括号后还有 else 等代码则不换行;表示终止右大括号后务必换行。
  2. 【强制】
    左括号和后三个字符之间不出现空格;同样,右括号和前一个字符之间也不出新空
    格。详见第 5 条下方正例提醒。
  3. 【强制】if/for/while/switch/do 等保留字与左右括号之间都必须加空格。
  4. 【强制】任何运算符左右必须加二个空格。
    表达:运算符包含赋值运算符=、逻辑运算符&&、加减乘除符号、三目运转符等。
  5. 【强制】代码块缩进 4 个空格,如若应用 tab 缩进,请设置成 1 个 tab 为
    4 个空格。 正例: (涉及 1-5 点)
    阿里Baba(Alibaba) JAVA 开发手册
    5 / 32

作者:Leiffy

 开放接口层:可径直封装 Service 接口揭穿成 OdysseyPC 接口;通过 Web 封装成
http 接口;网关控
制层等。
 终端彰显层:种种端的模板渲染并执行突显层。当前重即使 velocity 渲染,JS
渲染,JSP 渲
染,移动端浮现层等。
 Web
层:紧假如对访问控制举行转向,各个基本参数校验,大概不复用的作业简单处理等。
 Service 层:相对具体的事情逻辑服务层。
 Manager 层:通用业务处理层,它有如下特征:
1) 对第2方平台封装的层,预处理回来结果及转会分外新闻;
2) 对 Service 层通用能力的下浮,如缓存方案、中间件通用处理;
3) 与 DAO 层交互,对 DAO 的事体通用能力的包裹。
 DAO 层:数据访问层,与底层 Mysql、Oracle、Hbase、OB 进行数量交互。
 外部接口或第①方平台:包涵其余单位 MuranoPC 开放接口,基础平台,其余公司的
HTTP 接口。

一 、编程规约
(一) 命名规约
1.
【强制】全数编程相关命名均无法以下划线或新币符号早先,也无法以下划线或法郎符号为止。
反例: _name / __name / $Object / name_ / name$ / Object$
2.
【强制】全数编程相关的命名严禁动用拼音与英文混合的方法,更不允许直接使用中文的办法。
证实:正确的英文拼写和语法可以让阅读者易于领悟,防止歧义。注意,尽管纯拼音命名形式
也要防止使用。
反例: DaZhePromotion [打折] / getPingfenByName() [评分] / int 变量
= 3;
正例: ali / alibaba / taobao / cainiao / aliyun / youku / hangzhou
等国际通用的
名称,可说是英文。

  1. 【强制】表明是与否概念的字段,必须运用 is_xxx 的方法命名,数据类型是
    unsigned tinyint ( 1 表示是,0 表示否),此规则平等适用于 odps 建表。
    证实:任何字段即使为非负数,必须是 unsigned。
    2.
    【强制】表名、字段名必须采用小写字母或数字;禁止出现数字发轫,禁止多少个下划线中间只
    出现数字。数据库字段名的改动代价很大,因为不能举行预表露,所以字段名称必要从长计议。
    正例:getter_admin,task_config,level3_name
    反例:GetterAdmin,taskConfig,level_3_name
  2. 【强制】表名不利用复数名词。
    表明:表名应该一味表示表里面的实体内容,不该代表实体数量,对应于 DO
    类名也是单数
    花样,符合表明习惯。
  3. 【强制】禁用保留字,如 desc、range、match、delayed
    等,参考官方保留字。
  4. 【强制】唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
    说明:uk_ 即 unique key;idx_ 即 index 的简称。
  5. 【强制】小数类型为 decimal,禁止接纳 float 和 double。
    表达:float 和 double
    在存储的时候,存在精度损失的题目,很只怕在值的比较时,得到不
    没错的结果。假如存储的多寡范围超越 decimal
    的限定,提议将数据拆成整数和小数分开储存。

  6. 【强制】即便存储的字符串长度大约也等于,使用 CHAPRADO 定长字符串类型。

  7. 【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要跨越
    四千,借使存储长度
    当先此值,定义字段类型为
    TEXT,独立出来一张表,用主键来对号入座,幸免影响其它字段索引
    效率。
  8. 【强制】表必备三字段:id, gmt_create, gmt_modified。 表明:其中 id
    必为主键,类型为 unsigned bigint、单表时自增、步长为 1;分表时改为从
    TDDL Sequence 取值,确保分表之间的全局唯一。gmt_create, gmt_modified
    的类型均为
    date_time 类型。
    阿里Baba(Alibaba) JAVA 开发手册
    22 / 32

阿里Baba(Alibaba) JAVA 开发手册
26 / 32

  1. 【强制】页面搜索严禁左模糊或许全模糊,如若急需请走搜索引擎来缓解。
    证实:索引文件具有 B-Tree
    的最左前缀匹配天性,如果右边的值未规定,那么不能运用此索
    引。
  2. 【推荐】假使有 order by 的现象,请小心拔取索引的有序性。order by
    最终的字段是结合索 引的一部分,并且位居索引组合顺序的最后,防止出现file_sort 的情景,影响查询质量。
    正例:where a=? and b=? order by c; 索引:a_b_c
    反例:索引中有限量查找,那么索引有序性不可以使用,如:WHERE a>10 O翼虎DER
    BY b; 索引 a_b
    胸中无数排序。
  3. 【推荐】利用覆盖索引来举行查询操作,来避免回表操作。
    讲明:假设一本书需求通晓第 11 章是何许标题,会翻动第 11
    章对应的那一页吗?目录浏览一
    下就好,这一个目录就是起到覆盖索引的意义。
    正例:IDB
    可以创设目录的门类:主键索引、唯一索引、普通索引,而覆盖索引是一种查询的
    一种功用,用 explain 的结果,extra 列会并发:using index.
  4. 【推荐】利用延迟关联可能子查询优化超多分页场景。 表达:MySQL
    并不是跳过 offset 行,而是取 offset+N 行,然后回来放弃前 offset 行,返回N
    行,那当 offset
    特别大的时候,作用就充足的放下,要么控制重返的总页数,要么对超越特
    定阈值的页数举行 SQL 改写。
    正例:先快捷稳定需求得到的 id 段,然后再涉及: SELECT a.* FROM 表 1 a,
    (select id from 表 1 where 条件 LIMIT 100000,20 ) b where a.id=b.id
  5. 【推荐】 SQL 品质优化的目的:至少要高达 range 级别,要求是 ref
    级别,若是可以是 consts 最好。
    说明:
    1)consts
    单表中最几只有2个匹配行(主键恐怕唯一索引),在优化阶段即可读取到数据。
    2)ref 指的是接纳普通的目录。(normal index)
    3)range 对索引进范围检索。
    反例:explain 表的结果,type=index,索引物理文件全扫描,速度格外慢,那么些index 级别
    正如 range 还低,与全表扫描是小巫见大巫。
  6. 【推荐】建组合索引的时候,区分度最高的在最左侧。 正例:借使 where a=?
    and b=? ,a 列的大概接近于唯一值,那么只须求单建 idx_a 索引即可。
    阿里Baba JAVA 开发手册
    24 / 32
  1. 【推荐】接口入参爱惜,那种现象常见的是用于做批量操作的接口。
  2. 【参考】方法中须要开展参数校验的情景:
    1) 调用频次低的艺术。
    2)
    执行时间支出很大的法子,参数校验时间大致可以忽略不计,但假如因为参数错误导致
    中级执行回退,只怕不当,那轻重颠倒。
    3) 须要极高稳定和可用性的不二法门。
    4) 对外提供的绽开接口,不管是 ENVISIONPC/API/HTTP 接口。
  3. 【参考】方法中不须要参数校验的场所:
    1)
    极有恐怕被循环调用的不二法门,不指出对参数进行校验。但在章程求证里总得评释外部参
    数检查。
    2)
    底层的点子调用频度都比较高,一般不校验。终究是像纯净水过滤的末尾一道,参数错
    误不太恐怕到底层才会揭露难题。一般 DAO 层与 Service层都在同1个行使中,布署在同一台
    服务器中,所以 DAO 的参数校验,可以归纳。
    3) 被声称成 private
    只会被自个儿代码所调用的艺术,如果可以鲜明调用方法的代码传入参
    数已经做过检查或许自然不会有标题,此时能够不校验参数。
    (八) 注释规约
  4. 【强制】类、类性质、类措施的注明必须拔取 javadoc
    规范,使用/**内容*/格式,不得接纳 //xxx 格局。
    表明:在 IDE 编辑窗口中,javadoc 方式会唤起相关切释,生成 javadoc
    可以正确输出相应注
    释;在 IDE
    中,工程调用方法时,不进入情势即可上浮提醒方法、参数、再次回到值的意思,升高
    开卷功能。
  5. 【强制】全体的说梅止渴方法(包蕴接口中的方法)必须要用 javadoc
    注释、除了重返值、参数、
    尤其说明外,还必须提出该格局做什么样工作,达成怎么样效益。
    阐明:如有完成和调用注意事项,请一并表达。
    阿里Baba(Alibaba) JAVA 开发手册
    16 / 32

  6. 【强制】全数的类都必须抬高创设者新闻。
    4.
    【强制】方法内部单行注释,在被诠释语句上方另起一行,使用//注释。方法内部多行注释使
    用/* */注释,注意与代码对齐。

  7. 【强制】全数的枚举类型字段必要求有注释,表明每种数据项的用途。
    6.
    【推荐】与其“半吊子”英文来诠释,不如用中文注释把标题说驾驭。专有名词、关键字,保
    持英文原稿即可。
    反例:“TCP 连接超时”解释成“传输控制协议连接超时”,精晓反而费脑筋。
    7.
    【推荐】代码修改的同时,注释也要拓展对应的修改,尤其是参数、重临值、很是、宗旨逻辑
    等的改动。
    证实:代码与注释更新不一致台,就像是路网与导航软件更新不一起一样,如若导航软件严重退化,
    就失去了领航的意思。
  8. 【参考】注释掉的代码尽量要合营表明,而不是大概的注脚掉。
    表达:代码被诠释掉有三种大概:1)后续会过来此段代码逻辑。2)永久不用。前者借使没
    有备注音讯,难以领悟注释动机。后者提议间接删掉(代码仓库保存了历史代码)。
    9.
    【参考】对于注释的需求:第三 、可以规范反应设计思想和代码逻辑;第壹 、可以描述业务含
    义,使其他程序员可以高效了解到代码背后的音讯。完全没有注释的大段代码对于阅读者形同
    天书,注释是给自身看的,就算隔十分短日子,也能清楚精晓当下的思路;注释也是给后者看
    的,使其可以高效接替自个儿的做事。
    10.
    【参考】好的命名、代码结构是自解释的,注释力求切中要害准确、表达到位。防止出现注释的一
    个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是一对一大的担当。
    反例:
    // put elephant into fridge put(elephant, fridge); 方法名
    put,加上三个有意义的变量名 elephant 和
    fridge,已经认证了那是在干什么,
    语义清晰的代码不需求格外的笺注。
    11.【参考】特殊注释标记,请评释标记人与标记时间。注意及时处理这个标记,通过标记扫描,
    不时清理此类标记。线上故障有时候尽管来源于那几个标记处的代码。
    1) 待办事宜(TODO):( 标记人,标记时间,[展望处理时间])
    表示要求贯彻,但目前还未兑现的成效。那其实是一个 javadoc
    的竹签,如今的
    javadoc
    还没有兑现,但曾经被大面积采用。只好选用于类,接口和方法(因为它是一个javadoc
    标签)。
    阿里Baba(Alibaba) JAVA 开发手册
    17 / 32
  1. 【强制】更新数据表记录时,必须同时更新记录对应的 gmt_modified
    字段值为当下光阴。
  2. 【推荐】不要写壹个大而全的数量更新接口,传入为 POJO
    类,不管是或不是友好的目的更新字 段,都开展 update table set
    c1=value1,c2=value2,c3=value3; 那是很是的。执行 SQL 时,
    尽心尽力不要更新无更改的字段,一是易出错;二是功用低;三是 binlog
    增加存储。
  3. 【参考】@Transactional 事务不要滥用。事务会潜移默化数据库的
    QPS,此外利用工作的地方需要考虑各地方的回滚方案,包涵缓存回滚、搜索引擎回滚、新闻补偿、计算修正等。
    10.【参考】<isEqual>中的 compareValue
    是与属性值相比的常量,一般是数字,表示十二分时带上
    此条件;<isNotEmpty>表示不为空且不为 null
    时进行;<isNotNull>表示不为 null 值时实施。
    四 、工程规约
    (一) 应用分层
    1.
    【推荐】图中暗中同意上层看重于下层,箭头关系表示可径直正视,如:开放接口层可以借助于
    Web 层,也足以一贯依赖于 瑟维斯 层,依此类推:
  1. 【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为 static
    变量,假如定义为 static,必须加锁,或许拔取 DateUtils 工具类。
    正例:注意线程安全,使用 DateUtils。亦推荐如下处理:
    private static final ThreadLocal<DateFormat> df = new
    ThreadLocal<DateFormat>() { @Override protected DateFormat
    initialValue() { return new SimpleDateFormat(“yyyy-MM-dd”); } };
    表达:尽管是 JDK8 的使用,可以应用 instant 代替 Date,Localdatetime 代替
    Calendar,
    Datetimeformatter 代替 Simpledateformatter,官方给出的演说:simple
    beautiful strong
    immutable thread-safe。
    4.
    【强制】高并发时,同步调用应该去考量锁的个性损耗。能用无锁数据结构,就绝不用锁;能
    锁区块,就不要锁整个方法体;能用对象锁,就不用用类锁。
    5.
    【强制】对多少个能源、数据库表、对象同时加锁时,须求保持一致的加锁顺序,否则可能会造
    成死锁。
    注脚:线程一要求对表 A、B、C
    依次全体加锁后才得以开展革新操作,那么线程二的加锁顺序
    也必须是 A、B、C,否则只怕出现死锁。
    6.
    【强制】并发修改同一记录时,防止更新丢失,要么在应用层加锁,要么在缓存加锁,要么在
    多少库层使用乐观锁,使用 version 作为创新依据。
    Alibaba JAVA 开发手册
    13 / 32

表达:存在非等号和等号混合判断标准时,在建索引时,请把等号规则的列前置。如:where
a>?
and b=? 那么即便 a 的区分度更高,也务必把 b 放在索引的最前列。
10.【参考】创建索引时幸免有如下极端误解:
1)误认为一个询问就须求建2个目录。
2)误认为索引会消耗空间、严重拖慢更新和新增速度。
3)误认为唯一索引一律须求在应用层通过“先查后插”形式缓解。
(三) SQL 规约

public static void main(String args[]) { // 缩进 4 个空格 String say =
“hello”; // 运算符的左右务必有一个空格 int flag = 0; // 关键词 if
与括号之间必须有多少个空格,括号内 f 与左括号,1 与右括号不需求空格 if
(flag == 0) { System.out.println(say); } //
左大括号前加空格且不换行;左大括号后换行 if (flag == 1) {
System.out.println(“world”); // 右大括号前换行,右大括号后有
else,不用换行 } else { System.out.println(“ok”); //
右大括号做为截止,必须换行 } } 6. 【强制】单行字符数限制不当先 1拾7个,超出必要换行,换行时,遵从如下原则: 1) 换行时相对上一行缩进 肆个空格。
2) 运算符与下文一起换行。
3) 方法调用的点符号与下文一起换行。
4) 在三个参数超长,逗号后展开换行。
5) 在括号前不要换行,见反例。
正例:
StringBuffer sb = new StringBuffer(); //领先 1二十个字符的情景下,换行缩进 4 个空格,并且方法前的点符号一起换行
sb.append(“zi”).append(“xin”)… .append(“huang”);
反例:
StringBuffer sb = new StringBuffer(); //领先 1十几个字符的情事下,不要在括号前换行 sb.append(“zi”).append(“xin”)…append
(“huang”);

  • id + ” symbol: ” + symbol); } 正例:(占位符)
    logger.debug(“Processing trade with id: {} and symbol : {} “, id,
    symbol); 5. 【强制】幸免双重打印日志,浪费磁盘空间,务必在 log4j.xml
    中装置 additivity=false。 正例:<logger
    name=”com.taobao.ecrm.member.config” additivity=”false”> 6.
    【强制】非凡音讯应该包括两类音信:案发现场音信和越发堆栈消息。假使不处理,那么往上
    抛。
    正例:logger.error(各样参数只怕目的 toString + “_” + e.getMessage(),
    e);
  1. 【强制】不允许出现其他魔法值(即未经定义的常量)直接现身在代码中。
    反例: String key=”Id#taobao_”+tradeId;
    cache.put(key, value);
  2. 【强制】long 或然 Long 开首赋值时,必须利用大写的 L,无法是小写的
    l,小写不难跟数字 1 混淆,造成误会。
    表达:Long a = 2l; 写的是数字的 21,还是 Long 型的 2?
    3.
    【推荐】不要选拔1个常量类珍爱有着常量,应该按常量效用拓展分拣,分开维护。如:缓存
    相关的常量放在类:CacheConsts 下;系统布置相关的常量放在类:ConfigConsts
    下。
    证实:大而全的常量类,非得 ctrl+f
    才定位到修改的常量,不便民精通,也不便于维护。
    阿里Baba(Alibaba) JAVA 开发手册
    4 / 32

类型,什么目的,也惠及归类查找。
正例:mppserver 应用中独立监控时区转换十分,如:
mppserver_monitor_timeZoneConvert.log
表明:推荐对日记进行分类,错误日志和工作日志尽量分开存放,便于开发人员查看,也利于
通过日记对系统举行及时督查。

阿里巴巴(Alibaba) JAVA 开发手册
27 / 32

  1. 【强制】泛型通配符<? extends
    T>来收纳重回的数量,此写法的泛型集合不能使用 add 方法。
    证实:苹果装箱后归来二个<? extends
    Fruits>对象,此目的就不能够往里加别样水果,包含苹
    果。
  2. 【强制】不要在 foreach 循环里展开元素的 remove/add 操作。remove
    成分请使用 Iterator 格局,假若出现操作,须求对 Iterator 对象加锁。
    反例:
    List<String> a = new ArrayList<String>(); a.add(“1”);
    a.add(“2”); for (String temp : a) { if(“1”.equals(temp)){
    a.remove(temp); } }
    表明:那个事例的施行结果会压倒我们的预料,那么试一下把“1”换来“2”,会是均等的结
    果吗?
    正例:
    Iterator<String> it = a.iterator(); while(it.hasNext()){ String
    temp = it.next(); if(删除成分的基准){ it.remove(); } }
    阿里Baba(Alibaba) JAVA 开发手册
    11 / 32

  3. 【强制】在 JDK7 版本以上,Comparator
    要满意自反性,传递性,对称性,不然 Arrays.sort,
    Collections.sort 会报 IllegalArgumentException 异常。
    说明:
    1) 自反性:x,y 的可比结实和 y,x 的相比结实相反。
    2) 传递性:x>y,y>z,则 x>z。
    3) 对称性:x=y,则 x,z 相比较结实和 y,z 相比结实同样。
    反例:下例中并未拍卖相等的动静,实际应用中恐怕会出现非常:
    new Comparator<Student>() { @Override public int compare(Student
    o1, Student o2) { return o1.getId() > o2.getId() ? 1 : -1; } } 9.
    【推荐】集合初阶化时,尽量钦点集合发轫值大小。 表明:ArrayList 尽量使用
    ArrayList(int initialCapacity) 先导化。
    10.【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet
    形式进行遍历。
    注明:keySet 其实是遍历了 2 次,一回是转为 Iterator 对象,另三遍是从
    hashMap 中取出 key
    所对应的 value。而 entrySet 只是遍历了五遍就把 key 和 value 都放到了
    entry 中,功效更
    高。如果是 JDK8,使用 Map.foreach 方法。
    正例:values()重返的是 V 值集合,是多个 list 集合对象;keySet()重返的是
    K 值集合,是
    1个 Set 集合对象;entrySet()再次来到的是 K-V 值组合集合。
    11.【推荐】中度注意 Map 类集合 K/V 能不大概储存 null
    值的动静,如下表格:
    集合类 Key Value Super 说明
    Hashtable 不允许为 null 不允许为 null Dictionary 线程安全
    ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 线程局部安全
    TreeMap 不容许为 null 允许为 null AbstractMap 线程不安全
    HashMap 允许为 null 允许为 null AbstractMap 线程不安全
    反例:很多同室觉得 ConcurrentHashMap 是可以置入 null
    值。在批量翻译现象中,子线程分
    发时,出现置入 null 值的情形,但主线程没有捕获到此十分,导致排查困难。
    12.【参考】合理利用好集合的有序性(sort)和平稳(order),防止集合的无序性(unsort)和不
    安定(unorder)带来的负面影响。
    Alibaba JAVA 开发手册
    12 / 32

因为 fd 不足而出现“open too many files”错误,导致新的接连不可以树立。
提议将 linux
服务器所支撑的最大句柄数调高数倍(与服务器的内存数量相关)。 3.
【推荐】给 JVM 设置-XX:+HeapDumpOnOutOfMemoryError 参数,让 JVM 遇到 OOM
场景时输出 dump 音讯。
表达:OOM
的爆发是有几率的,甚至有规律地相隔数月才面世一例,出现时的现场音信对查错
卓殊有价值。

  1. 【强制】可被用户一向访问的功力亟须开展权力决定校验。
    表达:幸免没有做权限控制就可随便走访、操作旁人的多少,比如查看、修改旁人的订单。
  2. 【强制】用户敏感数据禁止直接显示,必须对体现数据脱敏。
    表明:支付宝中查看个人手机号码会来得成:158****9119,隐藏中间 二人,防止隐衷败露。
  3. 【强制】用户输入的 SQL 参数严苛使用参数绑定或许 METADATA
    字段值限定,幸免 SQL 注入, 禁止字符串拼接 SQL 访问数据库。
  4. 【强制】用户请求传入的其他参数必须做有效验证。
    表明:忽略参数校验大概导致:
     page size 过大导致内存溢出
     恶意 order by 导致数据库慢查询
     正则输入源串拒绝服务 ReDOS
     任意重定向
     SQL 注入
     Shell 注入
     反种类化注入
  5. 【强制】禁止向 HTML 页面输出未经安全过滤或未正确转义的用户数据。
  6. 【强制】表单、AJAX 提交必须实施 CSLX570F 安全过滤。 表达:CS途观F(Cross-site
    request forgery)跨站请求伪造是一类常见编程漏洞。对于存在 CS帕杰罗F
    漏洞的应用/网站,攻击者可以先行构造好
    UKugaL,只要受害者用户一拜访,后台便在用户不知
    情意况下对数据库中用户参数进行对应修改。
  7. 【强制】UPRADOL 外部重定向传入的对象地方必须实施白名单过滤。
    正例:
    try { if (com.alibaba.fasttext.sec.url.CheckSafeUrl
    .getDefaultInstance().inWhiteList(targetUrl)){
    response.sendRedirect(targetUrl); } } catch (IOException e) {
    logger.error(“Check returnURL error! targetURL=” + targetURL, e); throw
    e;
    阿里Baba JAVA 开发手册
    32 / 32

  8. 【强制】Web 应用必须正确配置 Robots 文件,非 SEO U中华VL
    必须安插为禁止爬虫访问。
    User-agent: * Disallow: / 9.
    【强制】在接纳平台财富,譬如短信、邮件、电话、下单、支付,必须贯彻科学的防回看范围,
    如数量限制、疲劳度控制、验证码校验,防止被滥刷、资损。
    表明:如注册时发送验证码到手机,假如没有界定次数和频率,那么可以应用此功能干扰到其
    它用户,并造成短信平台能源浪费。
    10.【推荐】发贴、评论、发送即时音讯等用户生成内容的情况必须兑现防刷、文本内容违禁词过
    滤等风控策略。

注明:借使每趟访问争论几率小于
二成,推荐应用乐观锁,否则使用悲观锁。乐观锁的重试次
数不得小于 3 次。

  1. 【强制】不要捕获 Java 类库中定义的存续自 RuntimeException
    的运作时相当类,如:
    IndexOutOfBoundsException /
    NullPointerException,那类非凡由程序员预检查来规避,保
    证程序健壮性。
    正例:if(obj != null) {…}
    反例:try { obj.method() } catch(NullPointerException e){…}
    2.
    【强制】卓殊不要用来做流程控制,条件决定,因为这一个的处理功能比标准分支低。
  2. 【强制】对大段代码进行 try-catch,那是不负义务的表现。catch
    时请分清稳定代码和非稳
    定代码,稳定代码指的是无论怎么着不会出错的代码。对于非稳定代码的 catch
    尽只怕举办区分
    十二分类型,再做相应的卓殊处理。
    4.
    【强制】捕获至极是为了处理它,不要捕获了却什么都不处理而丢掉之,若是不想处理它,请
    将该尤其抛给它的调用者。最外层的政工使用者,必须处理非常,将其转化为用户可以领悟的
    内容。
  3. 【强制】有 try 块放到了事情代码中,catch
    非凡后,假诺须要回滚事务,一定要注意手动回 滚事务。
  4. 【强制】finally 块必须对能源对象、流对象开展倒闭,有那些也要做
    try-catch。 表明:借使 JDK7,可以采用 try-with-resources 方法。
  5. 【强制】不或然在 finally 块中采取 return,finally 块中的 return
    再次回到后措施停止执行,不 会再举行 try 块中的 return 语句。
    8.
    【强制】捕获分外与抛分外,必须是一点一滴匹配,只怕捕获万分是抛非凡的父类。
    表达:假使预想抛的是绣球,实际吸收的是铅球,就会发出意想不到意况。
  6. 【推荐】方法的再次回到值可以为
    null,不强制重回空集合,只怕空对象等,必须添加注释丰裕表达怎么着状态下会回去 null 值。调用方须要展开 null 判断防止 NPE 难点。
    表明:本规约鲜明避免 NPE
    是调用者的义务。尽管被调用方法再次来到空集合可能空对象,对调用
    者来说,也不要高枕无忧,必须考虑到长途调用退步,运转时特别等现象再次回到null 的状态。
    10.【推荐】幸免 NPE,是程序员的骨干修养,注意 NPE 爆发的面貌:
    1) 重返类型为包装数据类型,有可能是 null,重返 int 值时留意判空。
    Alibaba JAVA 开发手册
    19 / 32
  1. 【强制】不要采纳 count(列名)或 count(常量)来取代
    count(*),count(*)就是 SQL92 定义的
    标准总括行数的语法,跟数据库毫不相关,跟 NULL 和非 NULL 毫无干系。
    说明:count(*)会统计值为 NULL 的行,而 count(列名)不会总结此列为 NULL
    值的行。
  2. 【强制】count(distinct col) 计算该列除 NULL 之外的不重复数量。注意
    count(distinct col1, col2) 假如中间一列全为
    NULL,那么即使另一列有差距的值,也回到为 0。
  3. 【强制】当某一列的值全是 NULL 时,count(col)的回来结果为 0,但
    sum(col)的回到结果为 NULL,由此使用 sum()时需注意 NPE 难点。
    正例:可以采取如下方式来幸免 sum 的 NPE 难题:SELECT
    IF(ISNULL(SUM(g)),0,SUM(g)) FROM
    table;
  4. 【强制】使用 ISNULL()来判定是还是不是为 NULL 值。注意:NULL
    与任何值的第壹手相比都为 NULL。
    说明:
    1) NULL<>NULL 的归来结果是 NULL,不是 false。
    2) NULL=NULL 的回到结果是 NULL,不是 true。
    3) NULL<>1 的归来结果是 NULL,而不是 true。
  5. 【强制】在代码中写分页查询逻辑时,若 count 为 0
    应直接回到,防止执行后边的分页语句。

  6. 【强制】不得利用外键与级联,一切外键概念必须在应用层化解。
    表达:(概念解释)学生表中的 student_id 是主键,那么成绩表中的
    student_id 则为外键。
    比方更新学生表中的 student_id,同时触发成绩表中的 student_id
    更新,则为级联更新。外
    键与级联更新适用于单机低并发,不吻合分布式、高并发集群;级联更新是强阻塞,存在数量
    库更新沙暴的高风险;外键影响数据库的插入速度。

  7. 【强制】禁止利用存储进程,存储进度难以调试和增添,更从未移植性。
    Alibaba JAVA 开发手册
    25 / 32

  8. 【强制】IDB 数据纠正时,删除和修改记录时,要先
    select,幸免出现误删除,确认无误才能 提交实施。

  9. 【推荐】in 操作能幸免则防止,若实在防止不了,须求精心评估 in
    前边的集合成分数量,控 制在 一千 个以内。
    10.【参考】因Alibaba举世化必要,全体的字符存储与代表,均以 utf-8
    编码,那么字符计数方
    法注意:
    说明:
    SELECT LENGTH(“Alibaba”); 重临为 12
    SELECT CHARACTER_LENGTH(“Alibaba”); 重返为 4
    借使要运用表情,那么使用 utfmb4 来展开仓储,注意它与 utf-8 编码。
    11.【参考】TRUNCATE TABLE 比 DELETE
    速度快,且使用的体系和事务日志财富少,但 TRUNCATE
    无工作且不触发
    trigger,有可能引致事故,故不提议在开发代码中接纳此语句。
    申明:TRUNCATE TABLE 在作用上与不带 WHERE 子句的 DELETE 语句相同。
    (四) ORM 规约
  10. 【强制】在表查询中,一律不要拔取 *
    作为查询的字段列表,需要怎么样字段必须了解写明。
    表达:1)伸张查询分析器解析开支。2)增减字段简单与 resultMap
    配置不一致等。
  11. 【强制】POJO 类的 boolean 属性不可以加 is,而数据库字段必须加
    is_,要求在 resultMap 中
    进行字段与本性之间的照射。
    阐明:参见定义 POJO 类以及数据库字段定义规定,在 sql.xml
    扩充映射,是必须的。
  12. 【强制】不要用 resultClass
    当重返参数,尽管拥有类属性名与数据库字段一一对应,也亟需
    定义;反过来,每1个表也一定有一个与之相应。
    表达:配置映射关系,使字段与 DO 类解耦,方便维护。
  13. 【强制】xml 配置中参数注意采纳:#{},#param# 不要采纳${}
    此种格局简单并发 SQL 注入。
  14. 【强制】iBATIS 自带的 queryForList(String statementName,int start,int
    size)不推荐使 用。
    表明:其促成形式是在数据库取到 statementName 对应的 SQL
    语句的保有记录,再经过 subList
    取 start,size 的子集合,线上因为那一个原因已经出现过 OOM。

Alibaba JAVA 开发手册

4.
【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包
内共享常量、类内共享常量。
1) 跨应用共享常量:放置在二方库中,平常是 client.jar 中的 const
目录下。
2) 应用内共享常量:放置在一方库的 modules 中的 const 目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在三个类中分别定义了象征
“是”的变量:
类 A 中:public static final String YES = “yes”;
类 B 中:public static final String YES = “y”;
A.YES.equals(B.YES),预期是 true,但事实上重回为
false,导致暴发线上难点。
3) 子工程内部共享常量:即在当前子工程的 const 目录下。
4) 包内共享常量:即在此时此刻包下单独的 const 目录下。
5) 类内共享常量:直接在类内部 private static final 定义。

  1. 【推荐】setter
    方法中,参数名称与类成员变量名称一致,this.成员名=参数名。在
    getter/setter 方法中,尽量不要扩充工作逻辑,增加排查难题难度。
    反例:
    public Integer getData(){ if(true) { return data + 100; } else { return
    data – 100; } } 17. 【推荐】循环体内,字符串的连接格局,使用
    StringBuilder 的 append 方法开展扩展。 反例:
    String str = “start”; for(int i=0; i<100; i++){ str = str + “hello”;
    } 表明:反编译出的字节码文件突显每一次循环都会 new 出二个 StringBuilder
    对象,然后开展
    append 操作,最后经过 toString 方法重回 String
    对象,造成内存财富浪费。
    18.【推荐】final 可做实程序响应效能,注解成 final 的情景:
    1) 不须要再度赋值的变量,包罗类属性、局地变量。
    2) 对象参数前加 final,表示不容许修改引用的对准。
    3) 类方法分明不容许被重写。
    19.【推荐】慎用 Object 的 clone 方法来拷贝对象。
    注脚:对象的 clone 方法暗许是浅拷贝,若想完成深拷贝需求重写 clone
    方法完毕属性对象的
    拷贝。
    阿里Baba(Alibaba) JAVA 开发手册
    9 / 32

五 、安全规则

反例: object.equals(“test”);
声明:推荐应用 java.util.Objects#equals (JDK7 引入的工具类)

//参数很多的办法调用也领先 120 个字符,逗号后才是换行处 method(args1,
args2, args3, … , argsX); 7.
【强制】方法参数在概念和传播时,四个参数逗号后面必须加空格。
正例:下例中实参的”a”,前面必须求有二个空格。
method(“a”, “b”, “c”);
Alibaba JAVA 开发手册
6 / 32

  1. 【强制】类名使用 UpperCamelCase
    风格,必须听从驼峰格局,但以下情况分化:(领域模型 的相关命名)DO / DTO
    / VO / DAO 等。
    正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
    反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
  2. 【强制】方法名、参数名、成员变量、局地变量都统一行使 lowerCamelCase
    风格,必须听从
    驼峰方式。
    正例: localValue / getHttpMessage() / inputUserId
    5.
    【强制】常量命名全体大写,单词间用下划线隔开,力求语义表明完整清楚,不要嫌名字长。
    正例: MAX_STOCK_COUNT
    反例: MAX_COUNT
  3. 【强制】抽象类命名使用 Abstract 或 Base 初始;非凡类命名使用
    Exception 结尾;测试类命 名以它要测试的类的名称先河,以 Test 结尾。
    阿里Baba(Alibaba) JAVA 开发手册
    2 / 32

  4. 【强制】中括号是数组类型的一部分,数组定义如下:String[] args;
    反例:请勿使用 String args[]的法子来定义

  5. 【强制】POJO 类中的任何布尔类型的变量,都不用加
    is,否则部分框架解析会滋生系列化错
    误。
    反例:定义为骨干数据类型 boolean isSuccess;的性子,它的方式也是
    isSuccess(),PAJEROPC
    框架在反向解析的时候,“以为”对应的天性名称是
    success,导致属性获取不到,进而抛出
    异常。
    9.
    【强制】包名统一使用小写,点分隔符之间有且仅有壹个自然语义的罗马尼亚语单词。包名统一运用
    单数形式,但是类名若是有复数含义,类名可以采用复数方式。
    正例: 应用工具类包名为 com.alibaba.mpp.util、类名为
    MessageUtils(此规则参考 spring
    的框架结构)
    10.【强制】杜绝完全不专业的缩写,防止望文不知义。
    反例:<某工作代码>AbstractClass“缩写”命名成
    AbsClass;condition“缩写”命名成
    condi,此类随意缩写严重下跌了代码的可阅读性。
    11.【推荐】如果拔取到了设计方式,提议在类名中呈现出实际方式。
    申明:将设计格局突显在名字中,有利于阅读者飞速精晓架构设计思想。
    正例:public class OrderFactory;
    public class LoginProxy;
    public class ResourceObserver;
    12.【推荐】接口类中的方法和总体性不要加其他修饰符号(public
    也休想加),保持代码的简单
    性,并累加有效的 javadoc
    注释。尽量不要在接口里定义变量,假使一定要定义变量,肯定是
    与接口方法有关,并且是全部应用的根基常量。
    正例:接口方法签名:void f();
    接口基础常量表示:String COMPANY = “alibaba”;
    反例:接口方法定义:public abstract void f();
    表明:JDK8 中接口允许有暗许完毕,那么那个 default
    方法,是对全部达成类都有价值的默
    认实现。
    13.接口和落到实处类的命名有两套规则:
    1)【强制】对于 Service 和 DAO 类,基于 SOA
    的意见,揭揭发来的服务一定是接口,内部
    的兑现类用 Impl 的后缀与接口差异。
    正例:CacheServiceImpl 实现 CacheService 接口。
    Alibaba JAVA 开发手册
    3 / 32

9.
【推荐】对于“显然为止使用的代码和配备”,如方法、变量、类、配置文件、动态配置属性
等要坚定从程序中清理出去,避免造成过多垃圾。清理那类垃圾代码是技巧气场,不要有那样
的古板:“不做科学,多做多错”。

  1. 【强制】三十六线程并行处理定时职分时,Timer 运维两个 TimeTask
    时,只要其中之一没有捕获 抛出的要命,别的职分便会自动终止运营,使用
    ScheduledExecutorService 则没有那些标题。
  2. 【强制】线程池分歧意利用 Executors 去成立,而是经过
    ThreadPoolExecutor 的方法,那样
    的处理格局让写的同学越来越扎眼线程池的运作规则,规避财富耗尽的高危机。
    阐明:Executors 各种艺术的弊端:
    1)newFixedThreadPool 和 newSingleThreadExecutor:
    主要难题是堆积的央求处理队列大概会消耗非凡大的内存,甚至 OOM。
    2)newCachedThreadPool 和 newScheduledThreadPool:
    重点难题是线程数最大数是
    Integer.MAX_VALUE,只怕会成立数量拾叁分多的线程,甚至 OOM。

  3. 【强制】创设线程或线程池时请内定有意义的线程名称,方便出错时回看。
    正例:
    public class TimerTaskThread extends Thread { public TimerTaskThread(){
    super.setName(“TimerTaskThread”); … } 10.【推荐】使用 CountDownLatch
    举行异步转同步操作,每一种线程退出前务必调用 countDown 方
    法,线程执行代码注意 catch 至极,确保 countDown
    方法可以执行,防止主线程无法实施至
    countDown 方法,直到超时才回来结果。
    证实:注意,子线程抛出分外堆栈,不恐怕在主线程 try-catch 到。
    11.【推荐】幸免 Random
    实例被十二线程使用,纵然共享该实例是线程安全的,但会因竞争同一 seed
    导致的质量下降。
    声明:Random 实例包蕴 java.util.Random 的实例可能 Math.random()实例。
    正例:在 JDK7 随后,可以一向利用 API ThreadLocalRandom,在 JDK7
    从前,能够完毕每一种线
    程二个实例。

  4. 【推荐】通过重新检查锁(double-checked
    locking)(在出现场景)达成延迟初阶化的优化 难点隐患(可参照 The
    “Double-Checked Locking is Broken” Declaration),推荐难点化解方
    案中较为不难一种(适用于 jdk5 及以上版本),将目的属性注解为 volatile
    型(比如反例
    中修改 helper 的质量注解为 private volatile Helper helper = null;);
    反例:
    class Foo { private Helper helper = null; public Helper getHelper() {
    阿里Baba JAVA 开发手册
    14 / 32
  1. 【强制】超过多少个表禁止 join。须要 join
    的字段,数据类型保持相对相同;多表关联查询时,
    保险被提到的字段必要有目录。
    注脚:尽管双表 join 也要留意表索引、SQL 品质。
  2. 【强制】在 varchar
    字段上建立目录时,必须指定索引长度,没须求对全字段建立目录,依据
    其实文本区分度决定索引长度。
    表明:索引的长度与区分度是一对争辨体,一般对字符串类型数据,长度为 20
    的目录,区分
    Alibaba JAVA 开发手册
    23 / 32

度会高达 十分之九之上,可以动用 count(distinct left(列名,
索引长度))/count(*)的区分度来
确定。

阿里Baba(Alibaba) JAVA 开发手册
18 / 32

说明:稳定性指集合每一次遍历的因素次序是早晚的。有序性是指遍历的结果是按某种对比规则
次第排列的。如:ArrayList 是 order/unsort;HashMap 是
unorder/unsort;TreeSet 是
order/sort。
13.【参考】利用 Set
元素唯一的表征,可以连忙对另三个会面举办去重操作,防止接纳 List 的
contains 方法进行遍历去重操作。
(六) 并发处理
1.
【强制】获取单例对象要线程安全。在单例对象里面做操作也要保管线程安全。
表达:财富驱动类、工具类、单例工厂类都急需小心。
2.
【强制】线程能源必须通过线程池提供,不容许在利用中活动显式创立线程。
证实:使用线程池的补益是压缩在创制和销毁线程上所花的年华以及系统能源的开发,化解资
源不足的题材。借使不使用线程池,有只怕引致系统创设大气同类线程而导致消耗完内存依然
“过度切换”的难题。

 md5 操作:commons-codec
 工具集合:Guava 包
 数组操作:ArrayUtils(org.apache.commons.lang3.ArrayUtils)

集合操作:CollectionUtils(org.apache.commons.collections4.CollectionUtils)
 除上面以外还有 NumberUtils、DateFormatUtils、DateUtils 等优先采用
org.apache.commons.lang3 那几个包下的,不要拔取 org.apache.commons.lang
包下面
的。原因是 commons.lang 那几个包是从 JDK1.2 起初援助的所以众多 1.5/1.6
的特色是不
支持的,例如:泛型。

2)【推荐】
假若是描写能力的接口名称,取对应的形容词做接口名(经常是–able 的形
式)。
正例:AbstractTranslator 实现 Translatable。
14.【参考】枚举类名提出带上 Enum
后缀,枚举成员名称要求全大写,单词间用下划线隔开。
表达:枚举其实就是破例的常量类,且构造方法被专擅认同强制是私有。
正例:枚举名字:DealStatusEnum;成员名称:SUCCESS / UNKOWN_REASON。
15.【参考】各层命名规则:
A) Service/DAO 层方法命名规则
1) 获取单个对象的法子用 get 做前缀。
2) 获取多个对象的法门用 list 做前缀。
3) 获取统计值的艺术用 count 做前缀。
4) 插入的方式用 save(推荐)或 insert 做前缀。
5) 删除的点子用 remove(推荐)或 delete 做前缀。
6) 修改的措施用 update 做前缀。
B) 领域模型命名规则
1) 数据对象:xxxDO,xxx 即为数据表名。
2) 数据传输对象:xxxDTO,xxx 为作业领域有关的称谓。
3) 突显对象:xxxVO,xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
(二) 常量定义

10.【推荐】表的命名最好是加上“业务名称_表的意义”,防止上云梯后,再与任何业务表关联
时有混淆。
正例:tiger_task / tiger_reader / mpp_config
11.【推荐】库名与利用名称尽量一致。
12.【推荐】倘诺改动字段含义或对字段表示的情况追加时,须求立时更新字段注释。
13.【推荐】字段允许适当冗余,以提升品质,可是必须考虑数据同步的景观。冗余字段应根据:

二 、分外日志
(一) 非常处理

  1. 【推荐】全体 pom
    文件中的尊敬表明放在<dependencies>语句块中,全部版本仲裁放在
    <dependencyManagement>语句块中。
    表达:<dependencyManagement>里只是宣称版本,并不兑现引入,由此子项目须求显式的注明
    正视,version和scope都读取自父pom。而
    <dependencies>全数宣称在主pom的<dependencies >
    里的依赖都会活动引入,并暗许被抱有的子项目继承。
    10.【推荐】二方库尽量不要有布置项,最低限度不要再充实计划项。
    11.【参考】为防止选取二方库的重视争论难点,二方库发表者应当根据以下条件:
    1)精简可控条件。移除一切不要求的 API 和凭借,只含有 瑟维斯API、要求的圈子模型对
    象、Utils 类、常量、枚举等。如果借助别的二方库,尽量是 provided
    引入,让二方库使用
    者去倚重具体版本号;无 log 具体完毕,只依靠日志框架。
    2)稳定可追溯原则。每一个版本的成形应该被记录,二方库由何人爱慕,源码在哪里,都急需能
    福利查到。除非用户积极提高版本,否则公共二方库的一举一动不应有发生变化。
    (三) 服务器规约
  2. 【推荐】高并发服务器提出调小 TCP 协议的 time_wait 超时时间。
    说明:操作系统暗中同意 240 秒后,才会关闭处于 time_wait
    状态的总是,在高并发访问下,服务
    器端会因为处于 time_wait
    的连接数太多,只怕无法建立新的连年,所以必要在服务器上调小
    此等待值。
    正例:在 linux 服务器上请通过变更/etc/sysctl.conf
    文件去修改该缺省值(秒):
    net.ipv4.tcp_fin_timeout = 30
  3. 【推荐】调大服务器所接济的最大文件句柄数(File Descriptor,简写为
    fd)。
    说明:主流操作系统的安排性是将 TCP/UDP
    连接使用与公事一律的艺术去管理,即三个接连对应
    于壹个 fd。主流的 linux 服务器暗中同意所支撑最大 fd 数量为
    1024,当并发连接数很大时很简单
    阿里Baba(Alibaba) JAVA 开发手册
    30 / 32
  1. 【参考】服务器内部重定向必须利用 forward;外部重定向地址必须利用 U逍客L
    Broker 生成,
    要不因线上应用 HTTPS 协议而致使浏览器提醒“不安全”。其它,还会带来 U奥迪Q5L
    维护不等同的
    问题。
  1. 【参考】(分层万分处理规约)在 DAO
    层,爆发的那一个类型有为数不少,不可以用细粒度非凡举办 catch,使用
    catch(Exception e)格局,并 throw new DaoException(e),不要求打印日志,
    因为日志在 Manager/Service层一定必要捕获并打到日志文件中去,如若同台服务器再打日志,
    荒废品质和仓储。在 Service层出现至极时,必须记录日志消息到磁盘,尽只怕带上参数音信,
    也等于爱护案发现场。如若 Manager 层与 Service 同机布置,日志方式与 DAO
    层处理一致,如
    果是单独布置,则运用与 Service 一致的处理情势。Web
    层绝不应该继承往上抛很是,因为已
    经处于顶层,无再三再各处理非凡的主意,借使发现到那个尤其将促成页面无法不奇怪渲染,那么就
    有道是一向跳转到友好错误页面,尽量加上自身的荒唐提醒音信。开放接口层要将不胜处理成错
    误码和错误新闻情势赶回。
  2. 【参考】分层领域模型规约:
     DO(Data Object):与数量库表结构一一对应,通过 DAO
    层向上传输数据源对象。
     DTO(Data Transfer Object):数据传输对象,Service 和 Manager
    向外传输的对象。
     BO(Business Object):业务对象。可以由 Service层输出的包装业务逻辑的目标。
     QUE奥德赛Y:数据查询对象,各层接收上层的询问请求。注:当先 一个参数的询问封装,禁止使
    用 Map 类来传输。
     VO(View Object):显示层对象,平时是 Web
    向模板渲染引擎层传输的靶子。

if (helper == null) synchronized(this) { if (helper == null) helper =
new Helper(); } return helper; } // other functions and members…
} 13.【参考】volatile
化解二十四线程内存不可知难点。对于一写多读,是可以缓解变量同步难点,
不过借使多写,同样无法解决线程安全题材。要是想取回
count++数据,使用如下类达成:
AtomicInteger count = new AtomicInteger(); count.addAndGet(1);
count++操作如若是
JDK8,推荐使用 LongAdder 对象,比 AtomicLong
品质更好(裁减乐观锁的重试次数)。
14.【参考】注意 HashMap 的扩容死链,导致 CPU 飙升的标题。
15.【参考】ThreadLocal无法消除共享对象的换代难点,ThreadLocal对象提议使用static修饰。
那一个变量是针对三个线程内全体操作共有的,所以设置为静态变量,全部此类实例共享此静态
变量
,约等于说在类第两次被采纳衣服载,只分红一块存储空间,全体此类的对象(只即使那
个线程内定义的)都得以操控这一个变量。
(七) 控制语句

反例:public int f(){ return Integer 对象},若是为 null,自动解箱抛
NPE。
2) 数据库的询问结果可能为 null。
3) 集合里的成分就是 isNotEmpty,取出的数目成分也或然为 null。
4) 远程调用重回对象,一律须求举办 NPE 判断。
5) 对于 Session 中取得的数量,指出 NPE 检查,防止空指针。
6) 级联调用 obj.getA().getB().getC();三番五次串调用,易爆发 NPE。
11.【推荐】在代码中使用“抛十分”仍旧“再次回到错误码”,对于商家外的 http/api
开放接口必
须动用“错误码”;而采取内部推荐分外抛出;跨应用间 EvoquePC 调用优先考虑使用
Result 情势,
封装 isSuccess、“错误码”、“错误简短音讯”。
证实:关于 牧马人PC 方法重返格局采纳 Result 形式的说辞:
1)使用抛非常重临情势,调用方尽管没有捕获到就会爆发运维时不当。
2)借使不加栈音信,只是 new 自定义分外,参与自个儿的精通的 error
message,对于调用
端化解难题的扶助不会太多。即使加了栈音讯,在多次调用出错的情况下,数据系列化和传导
的属性损耗也是题材。
12.【推荐】定义时区分 unchecked / checked 十分,防止直接使用
RuntimeException 抛出,更
差异意抛出 Exception 可能Throwable,应使用有事情含义的自定义很是。推荐业界已定义过
的自定义极度,如:DaoException / ServiceException 等。
13.【参考】防止出现重复的代码(Don’t Repeat Yourself),即 D奔驰M级Y 原则。
证实:随意复制和粘贴代码,必然会促成代码的再一次,在今后要求修改时,要求修改全数的副
本,简单遗漏。必要时抽取共性方法,只怕抽象公共类,甚至是共用模块。
正例:贰个类中有三个 public
方法,都必要进行数行相同的参数校验操作,那个时候请抽取:
private boolean checkParam(DTO dto){…} (二) 日志规约

  1. 出口的 POJO 类必须重写 toString 方法,否则只输出此目的的 hashCode
    值(地址值),没啥 参考意义。
  2. 【推荐】可以使用 warn
    日志级别来记录用户输入参数错误的事态,防止用户投诉时,无所适
    从。注意日志输出的级别,error
    级别只记录系统逻辑出错、分外、只怕根本的错误音信。如
    非要求,请不要在此情景打出 error 级别,防止频仍报警。
  3. 【推荐】谨慎地记下日志。生产条件禁止出口 debug 日志;有选取地输出
    info 日志;若是使 用 warn
    来记录刚上线时的政工商银行为消息,一定要留意日志输出量的标题,防止把服务器磁盘
    撑爆,并记得及时删除那些观测日志。
    证实:多量地出口无效日志,不便民系统质量升高,也不便于神速稳定错误点。纪录日志时请
    沉凝:那几个日记真的有人看吗?看到那条日志你能做什么?能如故不能够给难点排查带来好处?
    10.【参考】若是日志用英文描述不明了,推荐使用普通话注释。对于华语 UTF-8
    的日记,在 secureC君越T
    中,set
    encoding=utf-8;假如中文字符还乱码,请设置:全局>暗许的对话设置>外观>字体>
    Alibaba JAVA 开发手册
    21 / 32

2) 错误,不可以办事(FIXME):(标记人,标记时间,[预测处理时间])
在诠释中用 FIXME
标记某代码是荒唐的,而且不可能工作,需求立时校订的情事。

if (stream != null) { … } 反例:
if (file.open(fileName, “w”) != null)) { … } 5.
【推荐】循环体中的语句要考量品质,以下操作尽量移至循环体外处理,如定义对象、变量、
获取数据库连接,进行不要求的 try-catch 操作(那一个 try-catch
是不是可以移至循环体外)。

说明:
String str = “a,b,c,,”; String[] ary = str.split(“,”); //预期大于
3,结果是 3 System.out.println(ary.length);
14.【推荐】当1个类有几个构造方法,或然五个同名方法,这个情势应该按梯次放置在一起,便
于阅读。
15.【推荐】 类内方法定义顺序依次是:公有方法或爱护办法 > 私有艺术
> getter/setter 方
法。
注脚:公有方法是类的调用者和支持者最关心的措施,首屏呈现最好;珍爱形式即使只是子类
爱护入微,也只怕是“模板设计方式”下的着力措施;而个人方法外部一般不必要专门关爱,是一
个黑盒落成;因为方法消息价值较低,全部 Service 和 DAO 的 getter/setter
方法放在类体最
后。

20.【推荐】类成员与艺术访问控制从严:
1) 假诺不容许外部间接通过 new 来创造对象,那么构造方法必须是
private。
2) 工具类分裂意有 public 或 default 构造方法。
3) 类非 static 成员变量并且与子类共享,必须是 protected。
4) 类非 static 成员变量并且仅在本类使用,必须是 private。
5) 类 static 成员变量要是仅在本类使用,必须是 private。
6) 若是 static 成员变量,必须考虑是还是不是为 final。
7) 类成员方法只供类内部调用,必须是 private。
8) 类成员方法只对继承类公开,那么限制为 protected。
表达:任何类、方法、参数、变量,严控访问范围。过广泛的造访范围,不便于模块解耦。思
考:如果是三个 private 的方法,想删除就删除,不过3个 public 的 Service方法,可能一
个 public
的分子变量,删除一下,不得手心冒点汗吗?变量像本人的小孩子,尽量在祥和的视
线内,变量作用域太大,倘使无界定的四处跑,那么您会担心的。
(五) 集合处理

  1. 【强制】IDE 的 text file encoding 设置为 UTF-8; IDE
    普通话件的换行符使用 Unix 格式,不 要使用 windows 格式。
    10.【推荐】方法体内的执行语句组、变量的概念语句组、差异的事情逻辑之间只怕不一致的语义之
    间插入三个空行。相同业务逻辑和语义之间不须求插入空行。
    声明:没有必要插入多行空格进行隔开。
    (四) OOP 规约
    1.
    【强制】幸免通过3个类的靶子引用访问此类的静态变量或静态方法,无谓增添编译器解析成本,直接用类名来访问即可。
  2. 【强制】全部的覆写方法,必须加@Override 注脚。 反例:getObject()与
    get0bject()的题目。七个是字母的 O,三个是数字的 0,加@Override
    可以规范判断是或不是覆盖成功。其它,假诺在抽象类中对艺术签名进行改动,其达成类会马上编
    译报错。
  3. 【强制】相同参数类型,相同业务含义,才方可选拔 Java
    的可变参数,防止采用 Object。
    表达:可变参数必须放置在参数列表的最后。(提倡同学们尽只怕不用可变参数编程)
    正例:public User getUsers(String type, Integer… ids); 4.
    【强制】对外暴露的接口签名,原则上不相同意修改章程签名,防止对接口调用方发生影响。接
    口过时必须加@Deprecated
    评释,并清晰地申明接纳的新接口恐怕新劳动是怎么样。
  4. 【强制】不或许运用老式的类或措施。 表达:java.net.U凯雷德LDecoder 中的方法
    decode(String encodeStr) 那些形式已经不合时宜,应该
    利用双参数 decode(String source, String
    encode)。接口提供方既然鲜明是不合时宜接口,那
    么有分文不取同时提供新的接口;作为调用方来说,有职分去考证过时方法的新落成是哪些。
    6.
    【强制】Object的equals方法简单抛空指针相当,应拔取常量或规定有值的对象来调用equals。

8.
【推荐】没有须求增添多少空格来使某一行的字符与上一行的附和字符对齐。
正例:
int a = 3; long b = 4L; float c = 5F; StringBuffer sb = new
StringBuffer(); 表明:增添 sb 这么些变量,若是必要对齐,则给 a、b、c
都要追加多少个空格,在变量相比多的
事态下,是一种累赘的事务。

  1. 【强制】应用中不得直接运用日志系统(Log4j、Logback)中的
    API,而应借助于使用日志框架 SLF4J 中的
    API,使用门面格局的日记框架,有利于保险和一一类的日志处理情势统一。
    import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static
    final Logger logger = LoggerFactory.getLogger(Abc.class); 2.
    【强制】日志文件推荐至御史存 15
    天,因为有些万分具备以“周”为频次暴发的表征。
  2. 【强制】应用中的增加日志(如打点、一时监控、访问日志等)命名格局:
    appName_logType_logName.log。logType:日志类型,推荐分类有
    stats/desc/monitor/visit
    等;logName:日志描述。那种命名的裨益:通过文件名就可领略日记文件属于怎么应用,什么
    Alibaba JAVA 开发手册
    20 / 32
  1. 【强制】Map/Set 的 key 为自定义对象时,必须重写 hashCode 和 equals。
    正例:String 重写了 hashCode 和 equals 方法,所以大家得以十二分喜欢地行使
    String 对象作
    为 key 来使用。
  2. 【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出
    ClassCastException 非常:java.util.RandomAccessSubList cannot be cast to
    java.util.ArrayList ;
    讲明:subList 再次来到的是 ArrayList 的里边类 SubList,并不是 ArrayList
    ,而是 ArrayList
    的多个视图,对于 SubList 子列表的全部操作最后会反映到原列表上。
  3. 【强制】在 subList
    场景中,高度注意对原集合成分个数的改动,会导致子列表的遍历、增加、
    删除均爆发 ConcurrentModificationException 万分。
  4. 【强制】使用集合转数组的法子,必须选用集合的 toArray(T[]
    array),传入的是系列完全 一样的数组,大小就是 list.size()。
    反例:直接采取 toArray 无参方法存在难题,此办法再次来到值只好是
    Object[]类,若强转其它
    系列数组将现出 ClassCastException 错误。
    正例:
    List<String> list = new ArrayList<String>(2);
    list.add(“guan”); list.add(“bao”); String[] array = new
    String[list.size()]; array = list.toArray(array);
    阿里Baba(Alibaba) JAVA 开发手册
    10 / 32

1)不是频仍修改的字段。
2)不是 varchar 超长字段,更不可以是 text 字段。
正例:各业务线日常冗余存储商品名称,幸免查询时须求调用 IC 服务拿到。
14.【推荐】单表行数领先 500 万行恐怕单表容积超越2GB,才推荐进行分库分表。
证实:假诺预测三年后的数据量根本达不到这几个级别,请不要在开创表时就分库分表。
反例:某工作三年总和据量才 2 万行,却分成 1024
张表,问:你干吗那样设计?答:分 1024
张表,不是标配吗?
15.【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更爱抚的是升格查找
速度。
正例:人的岁数用 unsigned tinyint(表示范围 0-255,人的寿命不会当先 25四虚岁);海龟就
总得是 smallint,但如借使阳光的年龄,就亟须是
int;如若是负有恒星的年纪都加起来,那
么就不可以不运用 bigint。
(二) 索引规约
1.
【强制】业务上富有唯一特点的字段,尽管是组成字段,也必须建成唯一索引。
表明:不要觉得唯一索引影响了 insert
速度,这么些速度损耗可以忽略,但进步查找速度是明
显的;别的,尽管在应用层做了要命完美的校验和决定,只要没有唯一索引,按照Murphy定律,
自然有脏数据暴发。

发表评论

电子邮件地址不会被公开。 必填项已用*标注