2024年6月15日发(作者:)
一、.在多线程并发读写的情况下,下列哪些处理方式能保证对象的线
程安全:
1、使用synchronized关键字给对象的读写操作加锁。
2、如果是基本类型,推荐使用包下面提供的线程安全的基本类
型包装类,例如AtomicInteger。
3、如果是集合,推荐使用rent提供的并发集合类,例如:ConcurrentHashMap。
4.关于ORM的规则,下列哪些说法符合《阿里巴巴Java开发手册》:
(错误)
A .数据库中,表达是与否概念的字段,必须使用is_xxx的方式命名。
B .推荐使用iBATIS自带的queryForList(String statementName,int start,int
size)进行分页查询。
C .为避免写resultMap,可以直接拿HashMap与HashTable作为查询结果集
的输出。
D .不要用resultClass当返回参数,即使所有类属性名与数据库字段一一对应,
也需要定义。
3.关于索引效率,下列哪些说法符合《阿里巴巴Java开发手册》:
A .使用索引的效率一定高于全表扫描的效率。
B .关于explain的结果,type=index的索引效率好于type=ref。
C .sql查询条件 where a like '%阿里%' ,不会走索引。
D .sql查询条件 where a like '阿里%' ,a列创建了索引,一般会使用索引进行
检索。
ble,HashMap, ConcurrentHashMap都是Map的实现类,它
们在处理null值的存储上有细微的区别,下列哪些说法是正确的:
A .Hashtable的KV都不可以为null。
B .HashMap的KV都可以为null。
C .HashMap的K不可以为null,V可以为null。
D .ConcurrentHashMap的KV都不可以为null。
1.关于领域模型命名,下列哪些说法符合《阿里巴巴Java开发手册》:
A .数据对象命名:xxxDO,xxx即为数据表名,例如:ResellerAccountDO。
B .数据传输对象:xxxDTO,xxx为业务领域相关的名称,例如ProductDTO。
C .展示层对象:xxxVO,xxx一般为网页名称,例如RecommendProductVO。
D .POJO是DO/DTO/BO/VO的统称,命名成xxxPOJO。
1.关于使用explain对数据库性能进行优化分析,下列哪些说法符合《阿
里巴巴Java开发手册》:
A .SQL性能优化的目标:至少要达到 range 级别,要求是ref级别,如果可
以是consts最好。
B .index级别走的是扫描索引,所以速度会比ref快。
C .range级别是指对表进行范围索引。
D .ref级别是指使用主键或者唯一索
2.关于代码注释,下列哪些说法符合《阿里巴巴Java开发手册》:
A .所有的抽象方法(包括接口中的方法)必须要用javadoc注释。
B .所有的方法,包括私有方法,最好都增加注释,有总比没有强。
C .过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
D .我的命名和代码结构非常好,可以减少注释的内容。
4.关于类命名,下列哪些说法符合《阿里巴巴Java开发手册》:
A .抽象类命名使用Abstract或Base开头。
B .异常类命名使用Exception结尾。
C .测试类命名以它要测试的类的名称开始,以Test结尾。
D .如果使用到了设计模式,建议在类名中体现出具体模式。例如代理模式的类
命名:LoginProxy;观察者模式命名:ResourceObserver。
5.关于加锁,下列哪些说法符合《阿里巴巴Java开发手册》:
A .可以只锁代码区块的情况下,就不要锁整个方法体。
B .高并发的业务场景下,要考虑加锁及同步处理带来的性能损耗,能用无锁数
据结构,就不要用锁。
C .能用对象锁的情况下,就不要用类锁。
D .加锁时需要保持一致的加锁顺序,否则可能会造成死锁。
1.好的单元测试必须遵守AIR原则,那么AIR原则具体是指:
A .单元测试应该是全自动执行的,并且非交互式的。
B .单元测试必须在线上环境能够全部被正确地编译。
C .为了保证单元测试稳定可靠且便于维护,单元测试用例之间决不能互相调用,
也不能依赖执行的先后次序。
D .单元测试是可以重复执行的。
2.关于表字段和索引,下列哪些说法符合《阿里巴巴Java开发手册》:
A .表字段注释,如果修改字段含义或对字段表示的状态追加时,需要及时更新。
B .合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是
提升检索速度。
C .针对表的每个字段都增加索引,加快查询速度。
D .字段的区分度越高,索引的查找速度越快。
3.关于并发处理,下列哪些说法符合《阿里巴巴Java开发手册》:
A .线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
B .同步处理时,能锁部分代码区块的情况下不要锁整个方法;高并发时,同步
调用应该考虑到性能损耗。
C .创建线程或线程池时,推荐给线程指定一个有意义的名称,方便出错时回溯。
D .推荐使用edThreadPool(int x)生成指定大小的线程池。
4.关于线程池管理线程的好处,下列哪些说法是正确的:
A .能够减少在创建和销毁线程上所花的时间以及系统资源的开销。
B .使用线程池一定能避免OOM问题。
C .线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
D .线程池能够根据资源等待情况,自动调整线程优先级并解决死锁问题。
1.对于索引的基本原理,下列哪些说法是正确的:
A .索引的数据结构主要有B-Tree、Hash、R-Tree、Full-Text等。
B .从物理存储来看,主要分为聚集(clustered)和非聚集(non-clustered)索引。
C .MySQL的表是聚集索引组织表(index of table)。
D .聚簇索引的叶子节点存放的是数据,非聚簇索引的叶子节点存放的是非聚集
索引的key和主键值。
2.关于系统安全,下列哪些说法符合《阿里巴巴Java开发手册》:
A .表单、AJAX提交不需要进行CSRF安全过滤。
B .表单、AJAX提交必须执行CSRF安全过滤。
C .URL外部重定向传入的目标地址必须执行白名单过滤。
D .用户输入的SQL参数严格使用参数绑定或者METADATA字段值限定,防
止SQL注入,禁止字符串拼接SQL访问数据库。
3.关于方法的返回值是否可以为null,下列哪些说法符合《阿里巴巴Java
开发手册》:
A .方法的返回值可以为null,如果是集合,必须返回空集合。
B .方法的返回值可以为null,不强制返回空集合,或者空对象等。
C .方法实现者必须添加注释,充分说明什么情况下会返回null值。
D .防止NPE是调用者的责任。
4.关于接口使用抛异常还是返回错误码,下列哪些说法符合《阿里巴巴
Java开发手册》:
A .向公司外部提供的http/api接口,推荐使用“错误码”方式返回异常或者错误
信息。
B .对于应用内部的方法调用,推荐使用“抛出异常”的方式处理异常或者错误信
息。
C .跨应用的RPC调用,推荐使用将“错误码”和“错误简短信息”封装成Result
的方式进行返回。
D .对外提供的接口,一定要保证逻辑健壮性:尽量避免空指针等技术类异常;
对于业务类异常要做好错误码或者异常信息的封装。
5.下列哪些说法符合《阿里巴巴Java开发手册》:
A .在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
B .在JDK8中,针对统计时间等场景,推荐使用Instant类。
C .尽量不要在vm中加入变量声明、逻辑运算符,更不要在vm模板中加入任
何复杂的逻辑。
D .后台输送给页面的变量必须加$!{var}——中间的感叹号。
2.使用CountDownLatch进行异步转同步操作时,下列哪些说法是正确
的:
A .每个线程退出前必须调用countDown()方法。
B .线程执行代码注意catch异常,确保 countDown()方法可以被执行。
C .子线程抛出异常堆栈,直接就可以在主线程catch到。
D .主线程必须在启动其他线程后调用await()方法,这样主线程的操作就会在
这个方法上阻塞,直到其他线程完成各自的任务。
3.关于控制语句,下列哪些说法符合《阿里巴巴Java开发手册》:
A .推荐 if-else的方式可以改写成卫语句的形式。
B .尽量减少try-catch 块内的逻辑,定义对象、变量、获取数据库连接等操作
可以移到try-catch块外处理
C .if ( condition) statements; 单行语句不需要使用大括号。
D .在一个switch块内,都必须包含一个default语句并且放在最后,即使它什
么代码也没有。
4.关于捕获异常和抛异常,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .如果需要捕获不同类型异常,为了方便处理,可以使用catch(Exception
e){...}。
B .不要捕获异常后不处理,丢弃异常信息。
C .捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
D .异常定义时区分unchecked / checked 异常,避免直接使用
RuntimeException抛出。
5.关于索引的设计,下列哪些说法符合《阿里巴巴Java开发手册》:
A .对varchar类型的字段建立索引,必须指定索引长度。
B .对varchar类型的字段建立索引,不需要指定索引长度,这样索引区分度最
好。
C .业务上具有唯一特性的字段(含组合字段),必须指定唯一索引。
D .建复合索引时,一般选择区分度高的字段放在最左列。
1.关于组合索引,下列哪些说法符合《阿里巴巴Java开发手册》:
A .查询条件 where a='0' and b='1',当组合索引为(b,a) 的时候能进行索引扫
描。
B .查询条件 where a='0' and b='1',当组合索引为(c,a,b) 的时候能进行索引扫
描。
C .查询 select b from table where a='0',当组合索引为(a,b) 的时候会进行索
引扫描。
D .查询条件 where a > '0' order by b,当组合索引为(a,b) 时会利用索引进行
排序。
2.关于捕获异常和抛异常,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .如果需要捕获不同类型异常,为了方便处理,可以使用catch(Exception
e){...}。
B .不要捕获异常后不处理,丢弃异常信息。
C .捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
D .异常定义时区分unchecked / checked 异常,避免直接使用
RuntimeException抛出。
3.关于数据库命名规则,下列哪些说法符合《阿里巴巴Java开发手册》:
A .数据库库名和表名没有规定,可任意取名,只要方便记忆即可。
B .库名应该尽量与应用名称保持一致,表的命名最好是业务名称_表名的方式。
C .无论是库名还是表名都禁用保留字,如desc、match、range等。
D .表名、字段名必须使用小写字母或数字。
4.关于explain执行计划,下列哪些说法是正确的:
A .type列显示了连接使用了何种类型,从最好到最差的连接类型为:const,
eq_ref, ref, range, index, ALL。
B .possible_keys显示可能在这张表中的索引,如果为空,表示没有可能的索
引。
C .key列表示实际使用的索引。
D .ref列显示索引的哪一列被使用了。
1.关于枚举类型,以下描述符合规范的是:
A .只要是常量,就使用枚举值。
B .如果变量值在一个范围内变化,而且还带有名称之外的延伸属性,必须
使用Enum类,如:public enum MonthEnum{ JANUARY(1),FEBRUARY(2),
MARCH(3), APRIL(4), ..., DECEMBER(12);}。
C .枚举名命名建议带上Enum,枚举成员名称需要全大写,单词用“_”分割。
D .定义星期一至星期日这种范围固定的信息,不推荐使用枚举类型。
2.关于二方库的依赖处理,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .依赖于一个二方库群时,必须定义一个统一版本变量,避免各子二方库版本
号不一致。
B .可以允许子项目的pom依赖中出现相同的GroupId,相同的ArtifactId,但
是不同的Version。
C .所有pom文件中的依赖声明放在
放在
D .线上应用不要依赖SNAPSHOT版本(安全包除外)。
3.关于join的描述,下列哪些说法符合《阿里巴巴Java开发手册》:
A .join的字段,数据类型须保持绝对一致。
B .join列必须有索引。
C .优先where过滤,其次再join关联。
D .只要满足业务需求和,join表的个数不受限制。
4.关于参数校验,下列哪些说法符合《阿里巴巴Java开发手册》:
A .批量处理接口必须做好接口入参保护。
B .需要极高稳定性和可用性的方法需要对参数进行校验。
C .底层的方法,在上层调用中参数多半已经被校验过,可以考虑不校验。
D .对外提供的开放接口,都要进行参数检验。
5.好的单元测试必须遵守AIR原则,那么AIR原则具体是指:
A .单元测试应该是全自动执行的,并且非交互式的。
B .单元测试必须在线上环境能够全部被正确地编译。
C .为了保证单元测试稳定可靠且便于维护,单元测试用例之间决不能互相调用,
也不能依赖执行的先后次序。
D .单元测试是可以重复执行的。
1.关于二方库升级,下列哪些说法是正确的:
A .升级二方库只是改个版本号,不需要关联功能的回归。
B .升级二方库需要比对仲裁结果的差异,谨慎评估。
C .升级二方库,绝对不会影响到其它二方库的版本号。
D .只要此二方库负责人保证说不会有任何影响,即可大胆升级,直接发布上线。
2.防止NPE,是程序员的基本修养,对于可能产生NPE的场景,下列
哪些说法符合《阿里巴巴Java开发手册》:
A .数据库的查询结果可能为null。
B .集合只需要判断isNotEmpty,对取出的数据元素不需要判断是否为null。
C .远程调用返回对象,一律要求进行NPE判断。
D .对于Session中获取的数据,建议NPE检查,避免空指针。
3.关于二方库的snapshot与release的区别,下列哪些说法是正确的:
A .snapshot在本地编译时,都会到中央仓库下载最新的二方库。
B .release在本地编译时,如果已经存在相同的版本号,即使中央仓库有最新
相同版本的二方库也不会拉取。
C .应用使用了A的release版本二方库,A依赖了B的snapshot二方库,应
用本地编译时,并不会拉取B最新的snapshot二方库。
D .应用发布尽量使用release版本的二方库,此举是为了保证发布的幂等性。
4.关于count相关的使用,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .不要使用count(列名)或count(常量)来替代count(*)。
B .count(列名)会统计值为NULL的行,而count(*)不会统计。
C .当某一列的值全是NULL时,count(列名)返回0。
D .在程序代码中写分页查询逻辑时,若count为0应直接返回,以避免执行后
面的分页语句。
5.关于数据库是与否概念的列的命名方式,下列哪些说法符合《阿里巴
巴Java开发手册》:
A .对于是与否概念的列名,必须使用can_abc 来表示。
B .对于是与否概念的列名,必须使用is_abc 来表示。
C .数据类型是varchar(1)( Y表示是,N表示否)。
D .数据类型是unsigned tiny int.( 1表示是,0表示否)。
1.关于类的序列化,下列说法哪些是正确的:
A .类的序列化与serialVersionUID毫无关系。
B .如果完全不兼容升级,不需要修改serialVersionUID值。
C .POJO类的serialVersionUID不一致会编译出错。
D .POJO类的serialVersionUID不一致会抛出序列化运行时异常。
2.关于二方库版本号的命名方式,下列哪些说法符合《阿里巴巴Java
开发手册》:
A .版本号命名格式:主版本号.次版本号.修订号。
B .主版本号:产品方向改变,或者大规模API不兼容,或者架构不兼容升级。
C .次版本号:保持相对兼容性,增加主要功能特性,影响范围极小的API不兼
容修改。
D .修订号:保持完全兼容性,修复BUG、新增次要功能特性等。
4.在《阿里巴巴Java开发手册》中,提到不要对单元测试存在哪些误
解?
A .那是测试同学干的事情。
B .单元测试代码是多余的。
C .单元测试代码不需要维护。
D .单元测试与线上故障没有辩证关系。
5.关于变量和常量定义,下列哪些符合《阿里巴巴Java开发手册》:
A .Long a=2L;//大写的L
B .Long a=2l; //小写的l
C .常量只定义一次,不再赋值,所以不需要命名规范。
D .不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。
结构的集合,在处理null值的存储上有细微的区别,下列哪些说
法是正确的:
A .TreeMap的key不可以为null
B .TreeMap的key可以为null
C .ConcurrentHashMap的key可以为null
D .ConcurrentHashMap的value可以为null
2.关于测试代码的覆盖率,下列哪些说法是正确的?
A .路径覆盖是最强覆盖,符合路径覆盖且测试全部通过,程序绝对没有问题。
B .语句覆盖度是最弱的覆盖度量方式。
C .分支覆盖与条件覆盖其实是一回事。
D .判定条件覆盖与路径覆盖其实是一回事。
3.关于使用iBATIS操作数据,下列哪些说法符合《阿里巴巴Java开发
手册》:
A .如果表中字段和DO中的字段名完全一致,可直接用DO作为resultClass。
B .iBATIS中自带了queryForList(String statementName,int start,int size)的分
页接口,可直接使用,无需再自行封装。
C .不要定义大而全的数据更新接口,对整个DO进行更新。必须按需更新。
D .sqlmap中写update语句时,必须包含对记录中gmt_modified字段的更新。
4.关于MySQL性能优化的描述,下列哪些说法是正确的:
A .主键查询优先于二级索引查询。
B .表连接有一定的代价,故表连接数量越少越好。
C .一般情况下,二级索引扫描优先于全表扫描。
D .可以使用通过索引避免排序代价。
5.关于用日志记录异常信息,下列哪些说法符合《阿里巴巴Java开发
手册》:
A .日志尽量记录案发现场信息和异常堆栈信息。
B .如果日志中输出POJO类,POJO类需要重写toString方法,避免只输出
hashCode。
C .不建议输出任何日志,因为日志记录消耗性能。
D .捕获异常后,一律抛给调用者去处理。
2.关于线程池的创建,下列哪些说法符合《阿里巴巴Java开发手册》:
A .线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方
式。
B .newFixedThreadPool和newSingleThreadExecutor的主要问题是堆积的请
求处理队列可能会耗费非常大的内存,甚至OOM。
C .newCachedThreadPool和newScheduledThreadPool的主要问题是线程数
最大数是_VALUE,可能会创建数量非常多的线程,甚至OOM。
D .我们的机器运算速度够快,所以线程池的创建并不需要特别的约定。
3.关于常量定义,下列哪些说法符合《阿里巴巴Java开发手册》:
A .跨应用共享常量:放置在二方库中,通常是中的const目录下。
B .应用内共享常量:通常放置在一方库的modules中的const目录下。
C .子工程内部共享常量:即在当前子工程的const目录下。
D .类内常量:直接在类内部private static final定义。
4.防止NPE,是程序员的基本修养,对于可能产生NPE的场景,下列
哪些说法符合《阿里巴巴Java开发手册》:
A .数据库的查询结果可能为null。
B .集合只需要判断isNotEmpty,对取出的数据元素不需要判断是否为null。
C .远程调用返回对象,一律要求进行NPE判断。
D .对于Session中获取的数据,建议NPE检查,避免空指针。
5.关于二方库依赖的解析命令,下列哪些说法是正确的:
A .mvn dependency:resolve 打印出已仲裁依赖的列表。
B .mvn dependency:tree 打印工程整个的依赖树结构。
C .mvn dependency:tree -Dverbose -Dincludes=commons-lang 打印出与
commons-lang相关的详细依赖。
D .mvn clean install 打印工程整个的依赖树结构,并部署到本地仓库中。
1.集合在遍历过程中,有时需要对符合一定条件的元素进行删除,下列
哪些说法是正确的:
A .在 foreach 循环里进行元素的 remove操作。
B .使用Iterator方式,如果有并发,需要对Iterator对象加锁。
C .Iterator进行元素的删除操作,绝对是线程安全的。
D .Java无法实现在遍历时,进行删除元素操作。
2.关于数据库中NULL的描述,下列哪些说法符合《阿里巴巴Java开
发手册》:
A .NULL=NULL的返回结果为true。
B .NULL与任何值的比较结果都为NULL。
C .NULL<>1的返回结果为true。
D .当某一列的值全是NULL时,sum(col)的返回结果为NULL。
ble,HashMap, ConcurrentHashMap都是Map的实现类,它
们在处理null值的存储上有细微的区别,下列哪些说法是正确的:
A .Hashtable的KV都不可以为null。
B .HashMap的KV都可以为null。
C .HashMap的K不可以为null,V可以为null。
D .ConcurrentHashMap的KV都不可以为null。
4.关于checked/unchecked exception,下列哪些说法是正确的:
A .继承的类属于checked exception。
B .checked异常继承ion类。
C .unchecked异常继承eException类。
D .NullPointerException , IllegalArgumentException属于unchecked
exception。
3.关于注释,下列哪些说法符合《阿里巴巴Java开发手册》:
A .方法头定义签名上的注释可以使用//(双划线)简单说明,不必要遵守javadoc
规范。
B .类定义开始部分,一般都用Javadoc注释 程序的总体描述以及作者信息。
C .方法头定义签名上的注释必须遵守javadoc规范,使用/**回车来生成,不得
在方法定义上方使用//(双划线)简单说明。
D .方法头定义签名上的注释,可以使用// xxx 的形式
4.关于用日志记录异常信息,下列哪些说法符合《阿里巴巴Java开发
手册》:
A .日志尽量记录案发现场信息和异常堆栈信息。
B .如果日志中输出POJO类,POJO类需要重写toString方法,避免只输出
hashCode。
C .不建议输出任何日志,因为日志记录消耗性能。
D .捕获异常后,一律抛给调用者去处理。
5.关于多线程并行处理定时任务的情况,下列哪些说法符合《阿里巴巴
Java开发手册》:
A .推荐使用Timer方式处理。
B .推荐使用ScheduledExecutorService方式处理。
C .Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任
务便会自动终止运行。
D .ScheduledExecutorService并发运行多个定时任务时,其中某线程抛出异
常,不会影响到其它线程的继续运行。
子类使用toArray方法实现集合向数组转换,下列哪些说法是正
确的:
A .Vector无法使用toArray转换成数组。
B .优先推荐:调用集合类的方法toArray(T[] a),传入的是类型完全一样的数组,
大小就是集合的size()。
C .集合的修改,会影响到数组元素的改变。
D .数组的修改,会影响到集合元素的改变。
2.下列哪些说法符合《阿里巴巴Java开发手册》:
A .在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
B .在JDK8中,针对统计时间等场景,推荐使用Instant类。
C .尽量不要在vm中加入变量声明、逻辑运算符,更不要在vm模板中加入任
何复杂的逻辑。
D .后台输送给页面的变量必须加$!{var}——中间的感叹号。
3.以下关于命名规约内容说明,正确的是:
A .包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词,并且
使用复数形式,例如:应用工具类包名为
B .类名使用UpperCamelCase,必须遵从驼峰形式,但以下情形例外:(领域
模型的相关命名)DO / DTO / VO / DAO等。
C .抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;
测试类命名以它要测试的类的名称开始,以Test结尾。
D .枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线
隔开。
5.关于代码书写格式,下列哪些说法符合《阿里巴巴
A .换行时相对上一行缩进2个空格。
B .运算符与下文一起换行,方法调用的点符号与下文一起换行。
C .在多个参数超长,逗号后进行换行。
D .在括号前不要换行。
Java开发手册》:
1.关于Map类型集合的遍历方式,下列哪些说法是正确的:
A .Map类型的实现类都同时实现了Iterator接口。
B .使用foreach进行遍历。
C .推荐使用keySet进行遍历。
D .推荐使用entrySet进行遍历。
2.在定义DO/DTO/VO/等POJO类时,对属性默认值的设定,下列哪些
说法符合《阿里巴巴Java开发手册》:
A .String类型的默认值设定为空字符串。
B .Date类型的默认值设定为new Date()。
C .集合类型的默认值设定为_LIST。
D .不要设定任何属性默认值。
3.在多线程并发读写的情况下,下列哪些处理方式能保证对象的线程安
全:
A .使用volatile关键字。
B .使用synchronized关键字给对象的读写操作加锁。
C .如果是基本类型,推荐使用包下面提供的线程安
全的基本类型包装类,例如AtomicInteger。
D .如果是集合,推荐使用rent提供的并发集合类,例如:
ConcurrentHashMap。
4.关于工具类二方库已经提供的,尽量不要在本应用中编程实现,下列
哪些说法符合《阿里巴巴Java开发手册》:
A .json操作使用fastjson。
B .md5操作使用commons-codec。
C .ArrayUtils、NumberUtils、DateFormatUtils、DateUtils等优先使用
包。
D .CollectionUtils优先使用tions4包。
5.关于二方库的依赖处理,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .依赖于一个二方库群时,必须定义一个统一版本变量,避免各子二方库版本
号不一致。
B .可以允许子项目的pom依赖中出现相同的GroupId,相同的ArtifactId,但
是不同的Version。
C .所有pom文件中的依赖声明放在
放在
D .线上应用不要依赖SNAPSHOT版本(安全包除外)。
1.关于常量的命名,下列哪些说法符合《阿里巴巴Java开发手册》:
A .常量命名应该全部大写,单词间用下划线隔开。
B .常量的定义要力求语义表达完整清楚,让别人能从常量名称上大致了解含义,
例如:MAX_STOCK_COUNT。
C .常量命名,可以使用拼音与英文的混合方式。
D .在使用缩写时要注意:杜绝不规范的缩写。
2.关于二方库的依赖处理,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .依赖于一个二方库群时,必须定义一个统一版本变量,避免各子二方库版本
号不一致。
B .可以允许子项目的pom依赖中出现相同的GroupId,相同的ArtifactId,但
是不同的Version。
C .所有pom文件中的依赖声明放在
放在
D .线上应用不要依赖SNAPSHOT版本(安全包除外)。
3.关于Integer值的比较,下列哪些说法是正确的:
A .Integer a = 3; Integer b = 3; 那么条件表达式(a == b) 返回的结果是 true。
B .Integer a = 3; Integer b = 3; 那么条件表达式(a == b) 返回的结果是 false。
C .Integer a = 273; Integer b = 273; 那么条件表达式(a == b) 返回的结果是
true。
D .Integer a = 273; Integer b = 273; 那么条件表达式(a == b) 返回的结果是
false。
4.关于多线程并行处理定时任务的情况,下列哪些说法符合《阿里巴巴
Java开发手册》:
A .推荐使用Timer方式处理。
B .推荐使用ScheduledExecutorService方式处理。
C .Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任
务便会自动终止运行。
D .ScheduledExecutorService并发运行多个定时任务时,其中某线程抛出异
常,不会影响到其它线程的继续运行。
5.针对tcp协议,下列哪些说法是正确的:
A .tcp链接主动关闭的一方,在完成四次挥手协议后,即会立即关闭并释放
socket。
B .处于time_wait状态的socket,其实是已经关闭状态,当需要新建连接时,
可以被马上复用。
C .当大量socket处于time_wait状态时,会导致可用socket资源稀缺,从而
导致服务器并发能力下降。
D .通过修改/etc/配置文件,减小time_wait的超时时间,可以降低
time_wait状态的socket数量,从而提升服务器并发能力。
3.数组使用转化为集合,下列说法哪些正确的:
A .数组元素的修改,会影响到转化过来的集合。
B .数组元素的修改,不会影响到转化过来的集合。
C .对于转换过来的集合,它的 add/remove/clear 方法会抛出:
UnsupportedOperationException。
D . 体现的是适配器模式,只是转换接口,后台的数据仍是数组。
5.对于索引(a, b, c),下列哪些说法是正确的:
A .查询语句 where a between 5 and 10 可以使用该索引。
B .查询语句 where a = 5 and b between 5 and 10 可以使用该索引。
C .查询语句 where a in (5, 6, 7, 8, 9) and b = 5 可以使用该索引。
D .查询语句 where b = 5 and c = 10 可以使用该索引。
1.关于变量、方法名、包的命名,下列哪些说法符合《阿里巴巴Java
开发手册》:
A .POJO类中的任何布尔类型的变量,都不要加is,因为部分框架解析时有可
能会出现序列化错误。
B .包名统一使用单数形式,如:。
C .中括号是数组类型的一部分,数组定义如下:String[] args; 不要误写为
String args[];
D .Service/DAO层方法命名可以参考规约,例如:删除的方法推荐使用remove
或delete做前缀。
5.关于日志的条件输出和占位符的方式,下列哪些说法是正确的:
A .对trace/debug/info级别的日志输出,必须使用条件输出形式或者使用占位
符的方式。
B .条件输出方式可以避免log参数中字符串拼接的开销。
C .占位符输出格式可以和条件输出一样避免参数中字符串拼接开销。
D .因为设置了日志输出级别,所以无需使用条件输出方式。
1.利用索引进行排序,下列哪些说法是正确的:
A .查询语句 WHERE a = 10 ORDER BY b,可以利用索引(a,b)来进行索引排
序。
B .查询语句 WHERE a > 10 ORDER BY b,不可以利用索引(a,b)来进行索引
排序。
C .查询语句 WHERE a IN (10, 11) ORDER BY b,可以利用索引(a,b)来进行
索引排序。
D .查询语句 WHERE a > 10 AND b = 20 ORDER BY a,可以利用索引(b,a)
来进行索引排序。
2.关于捕获异常和抛异常,下列哪些说法符合《阿里巴巴Java开发手
册》:
A .如果需要捕获不同类型异常,为了方便处理,可以使用catch(Exception e){...}。
B .不要捕获异常后不处理,丢弃异常信息。
C .捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
D .异常定义时区分unchecked / checked 异常,避免直接使用
RuntimeException抛出。
3.通过集合t()获取子集合B,下列说法哪些是正确的:
A .返回的集合B没有实现Serializable接口,不能被序列化,所以不能应用于
RPC场景。
B .在B集合中添加某个元素,那么A集合也会添加进去此元素。
C .集合A中元素的修改不会影响到集合B的任何操作。
D .对A元素个数的修改,会导致集合B的遍历产生
ConcurrentModificationException 异常。
1.下列哪些说法符合《阿里巴巴Java开发手册》:
A .对于“明确停止使用的代码和配置”,如方法、变量、类、配置文件、动态配
置属性等要坚决从程序中清理出去,避免造成过多垃圾。
B .永久弃用的代码段注释掉即可,即不用加任何注释。
C .对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一
规定使用三 个斜杠(///)来说明注释掉代码的理由。
D .不要在视图模板中加入任何复杂的逻辑。
2.关于方法的返回值是否可以为null,下列哪些说法符合《阿里巴巴Java
开发手册》:
A .方法的返回值可以为null,如果是集合,必须返回空集合。
B .方法的返回值可以为null,不强制返回空集合,或者空对象等。
C .方法实现者必须添加注释,充分说明什么情况下会返回null值。
D .防止NPE是调用者的责任。
3.关于常量定义,下列哪些说法符合《阿里巴巴Java开发手册》:
A .像“yes”,“no”,“success”,“Y”,“N”,这些简单的词,可以直接在代码中使用,不
必定义成常量形式。
B .即使是“yes”,“no”,“success”,“Y”,“N”,看似简单的词,也必须定义成常量形式。
C .不要在一个常量类中,维护本应用所有常量,按常量功能进行归类。
D .大而全的常量类,可以通过文本搜索(文本查找)功能定位到修改的常量,
没有增加理解和维护代价。
4.关于Java的接口描述,下列哪些说法符合《阿里巴巴Java开发手册》:
A .在接口类中的方法和属性使用public修饰符。
B .对于Service类,内部的实现类加Impl的后缀与接口区别。例如:
ProductServiceImpl实现ProductService接口。
C .对于Service类,基于SOA的理念,是以接口方式暴露服务。
D .尽量不在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,
而且是整个应用的基础常量。
5.关于注释,下列哪些说法符合《阿里巴巴Java开发手册》:
A .方法内部单行注释,在被注释语句上方另起一行,使用//注释。
B .所有的类都必须添加创建者信息。
C .相比较使用“半吊子”英文来注释,用中文注释把问题说清楚更合适。
D .所有的枚举类型字段必须要有注释,说明每个数据项的用途。
1.单元测试代码写在Java工程的哪个地方最为合适?
A .写在业务代码体里边,方便调试。
B .写在业务代码同一个包下,方便归类查找。
C .写在src/test/java目录下。
D .写在src/java目录下。
4.关于构造方法,下列哪些说法符合《阿里巴巴Java开发手册》:
A .构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法
中。
B .当一个类有多个构造方法,应该按顺序放置在一起,便于阅读。
C .如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
D .构造方法中可以有业务实现代码,如对成员变量的简单运算、业务判断等。
5.关于系统安全,下列哪些说法符合《阿里巴巴Java开发手册》:
A .非SEO URL必须配置为禁止爬虫访问。
B .用户生成内容的场景,如发帖评论等,必须实现防刷。
C .使用平台资源,比如短信、邮件等功能,避免被滥刷资损,同时防止对用户
造成骚扰。
D .文本内容必须进行违禁词过滤。
3.关于建表规约,下列哪些说法符合《阿里巴巴Java开发手册》:
A .字段为非负数,必须定义为unsigned。
B .存储的字符数几乎完全相等的字段,推荐定义为char类型存储。
C .varchar会预先分配存储空间。
D .不得使用级联与外键,一切外键概念必须在应用层解决。
5.关于二方库GroupID和ArtifactID格式,下列哪些说法符合《阿里巴
巴Java开发手册》:
A .GroupID格式为:com.{公司/子公司 }.业务线.[子业务线]。
B .GroupID格式为:com.{公司/子公司 }.业务线.子业务线.子模块。
C .ArtifactID格式为:产品线名_模块名或者产品线.模块名。
D .ArtifactID格式为:产品线名-模块名。
5.根据《阿里巴巴Java开发手册》,数据库的表设计允许适当冗余,
以提升SQL查询的性能,避免表的关联查询,下列哪些字段不允许冗
余:
A .text类型的字段。
B .基本固定不变的类目名称。
C .varchar(2500)的字段。
D .需要频繁修改的字段。
1.关于应用与数据库之间的操作,下列哪些说法符合《阿里巴巴Java
开发手册》:
A .对外提供一个大而全的接口进行POJO的update更新,这样比较省事,省
代码。
B .使用事务回滚的地方需要考虑各方面的回滚方案,包括缓存回滚、搜索引擎
回滚、消息补偿、统计修正等。
C .应用服务器与数据库之间是短连接。
D .应用服务器与数据库之间是长连接。
2.关于索引的使用,下列哪些说法是正确的:
A .查询语句 WHERE a+1 = 5 可以利用a索引。
B .查询语句WHERE date_format(gmt_create, '%Y-%m-%d') = '2016-11-11'
无法利用gmt_create索引。
C .当 c 列类型为 char 时,查询语句 WHERE c = 5 无法利用c索引。
D .索引字段使用时不能进行函数运算。
3.关于生产环境的日志文件,下列哪些说法符合《阿里巴巴Java开发
手册》:
A .应用的日志文件统一保存在:/home/admin/应用名/logs/ 路径下,便于统一
维护以及认知统一。
B .日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。
C .避免重复打印日志,浪费磁盘空间,务必在中设置additivity=false。
D .错误日志和业务日志尽量分开存放。
4.在多线程并发读写的情况下,下列哪些处理方式能保证对象的线程安
全:
A .使用volatile关键字。
B .使用synchronized关键字给对象的读写操作加锁。
C .如果是基本类型,推荐使用包下面提供的线程安
全的基本类型包装类,例如AtomicInteger。
D .如果是集合,推荐使用rent提供的并发集合类,例如:
ConcurrentHashMap。
5.关于异常的处理方式,下列哪些说法是正确的:
A .为防止obj对象本身空指针异常,书写代码时应该注意加异常捕获处理,例
如:try { () } catch(NullPointerException e){……} 。
B .方法签名中,抛给调用者的关键字为throws
C .方法内部,抛出异常实例对象为throws
D .自定义异常要做到“认知对等”,即:抛出者和接收者要保持对自定义异常的
认知统一,接收方需要知道这种异常的含义和对应的处理方案。
前言
《阿里巴巴Java开发手册》是阿里巴巴集团技术团队的集体智慧结晶
和经验总结,经历了多次大规模一线实战的检验及不断的完善,系统化地
整理成册,反馈给广大开发者。现代软件行业的高速发展对开发者的综合
素质要求越来越高,因为不仅是编程知识点,其它维度的知识点也会影响
到软件的最终交付质量。比如:数据库的表结构和索引设计缺陷可能带来
软件上的架构缺陷或性能风险;工程结构混乱导致后续维护艰难;没有鉴
权的漏洞代码易被黑客攻击等等。所以本手册以Java开发者为中心视角,
划分为编程规约、异常日志、单元测试、安全规约、工程结构、MySQL数
据库六个维度,再根据内容特征,细分成若干二级子目录。根据约束力强
弱及故障敏感性,规约依次分为强制、推荐、参考三大类。对于规约条目
的延伸信息中,“说明”对内容做了适当扩展和解释;“正例”提倡什么
样的编码和实现方式;“反例”说明需要提防的雷区,以及真实的错误案
例。
本手册的愿景是码出高效,码出质量。现代软件架构都需要协同开发
完成,高效协作即降低协同成本,提升沟通效率,所谓无规矩不成方圆,
无规范不能协作。众所周知,制订交通法规表面上是要限制行车权,实际
上是保障公众的人身安全。试想如果没有限速,没有红绿灯,谁还敢上路
行驶。对软件来说,适当的规范和标准绝不是消灭代码内容的创造性、优
雅性,而是限制过度个性化,以一种普遍认可的统一方式一起做事,提升
协作效率。代码的字里行间流淌的是软件生命中的血液,质量的提升是尽
可能少踩坑,杜绝踩重复的坑,切实提升质量意识。
考虑到可以零距离地与众多开发同学进行互动,决定在线维护《手册》
内容,此版本号为1.3.0的PDF版本,是对外释放的终极版;其次,我们
会在2017年10月14日杭州云栖大会上,进行阿里巴巴Java开发规约插
件全球首发,插件点此下载,阿里巴巴云效(一站式企业协同研发云)也
会集成代码规约扫描引擎。最后,《码出高效——阿里巴巴Java开发手
册详解》即将出版,敬请关注。
目录
前言
一、编程规约............................................1
(一)命名风格.........................................1
(二)常量定义.........................................3
(三)代码格式.........................................4
(四)OOP规约.........................................6
(五)集合处理.........................................9
(六)并发处理.........................................12
(七)控制语句.........................................14
(八)注释规约.........................................16
(九)其它.............................................17
二、异常日志............................................18
(一)异常处理.....................................18
(二)日志规约.....................................19
三、单元测试...........................................21
四、安全规约...........................................23
五、MySQL数据库.......................................24
(一)建表规约........................................24
(二)索引规约........................................25
(三)SQL语句........................................27
(四)ORM映射........................................28
六、工程结构...........................................30
(一)应用分层........................................30
(二)二方库依赖......................................31
(三)服务器..........................................32
附1:版本历史..........................................34
附2:本手册专有名词....................................35
一、编程规约
(一) 命名风格
1.【强制】代码中的命名均不能以下划线或美元符号开始,也不能以
下划线或美元符号结束。
反例:
_name/__name/$Object/name_/name$/Object$
2.【强制】代码中的命名严禁使用拼音与英文混合的方式,更不允许
直接使用中文的方式。
说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。
注意,即使纯拼音命名方式也要避免采用。
正例:
alibaba
/
taobao
/
youku
/
hangzhou
等国际通用的名称,
可视同英文。
反例:
DaZhePromotion[
打折
]
/
getPingfenByName()[
评分
]
/
int
某变量= 3
3.【强制】类名使用
UpperCamelCase
风格,必须遵从驼峰形式,但以
下情形例外:
DO
/
BO
/
DTO
/
VO
/
AO
正例:
MarcoPolo
/
UserDO
/
XmlService
/
TcpUdpDeal
/
TaPromotion
反例:
macroPolo
/
UserDo
/
XMLService
/
TCPUDPDeal
/
TAPromotion
4.【强制】方法名、参数名、成员变量、局部变量都统一使用
lowerCamelCase
风格,必须遵从驼峰形式。
正例:
localValue
/
getHttpMessage()
/
inputUserId
5.【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达
完整清楚,不要嫌名字长。
正例:
MAX
_
STOCK
_
COUNT
反例:
MAX
_
COUNT
6.【强制】抽象类命名使用
Abstract
或
Base
开头
;
异常类命名使用
Exception
结尾
;
测试类命名以它要测试的类的名称开始,以
Test
结尾。
7.【强制】中括号是数组类型的一部分,数组定义如下:
String[]
args;
反例:使用
String args[]
的方式来定义。
8.【强制】
POJO
类中布尔类型的变量,都不要加
is
,否则部分框架解
析会引起序列化错误。
反例:定义为基本数据类型
Boolean
isDeleted;
的属性,它的方
法也是
isDeleted()
,
RPC
框架在反向解析的时候,“以为”对应的
属性名称是
deleted
,导致属性获取不到,进而抛出异常。
9.【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义
的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可
以使用复数形式。
正例:应用工具类包名为
com
.
alibaba
.
open
.
util
、类名为
MessageUtils(
此规则参考
spring
的框架结构
)
10.【强制】杜绝完全不规范的缩写,避免望文不知义。
反例:
AbstractClass
“缩写”命名成
AbsClass; condition
“缩写
命名成
condi
,此类随意缩写严重降低了代码的可阅读性。
11.【推荐】为了达到代码自解释的目标,任何自定义编程元素在命名
时,使用尽量完整的单词组合来表达其意。
正例:从远程仓库拉取代码的类命名为
PullCodeFromRemoteRepository。
反例:变量int a; 的随意命名方式。
12.【推荐】如果模块、接口、类、方法使用了设计模式,在命名时体
现出具体模式。
说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计
理念。
正例:
public class OrderFactory;
Public class LoginProxy;
Public class ResourceObserver;
13.【推荐】接口类中的方法和属性不要加任何修饰符号
(public
也
不要加
)
,保持代码的简洁性,并加上有效的
Javadoc
注释。尽量不要在
接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是
整个应用的基础常量。
正例:接口方法签名:
void f();
接口基础常量表示:
String
COMPANY
= "
alibaba
"
;
反例:接口方法定义:
public
abstract
void
f();
说明:
JDK
8中接口允许有默认实现,那么这个
default
方法,是
对所有实现类都有价值的默认实现。
14.接口和实现类的命名有两套规则:
1
)
【强制】对于
Service
和
DAO
类,基于
SOA
的理念,暴露出来
的服务一定是接口,内部的实现类用
Impl
的后缀与接口区别。
正例:
CacheServiceImpl
实现
CacheService
接口。
2
)
【推荐】如果是形容能力的接口名称,取对应的形容词做接口
名
(
通常是–
able
的形式
)
。
正例:
AbstractTranslator
实现
Translatable
。
15.【参考】枚举类名建议带上
Enum
后缀,枚举成员名称需要全大写,
单词间用下划线隔开。说明:枚举其实就是特殊的常量类,且构造方法被
默认强制是私有。
正例:枚举名字为
ProcessStatusEnum的
成员名称:
SUCCESS
/
UNKOWN
_
REASON
。
16.【参考】各层命名规约:
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
。
(二) 常量定义
1.【强制】不允许任何魔法值
(
即未经定义的常量
)
直接出现在代码
中。
反例:
String
key
= "
Id
#
taobao
_" +
tradeId;
cache
.
put(key
,
value);
2.【强制】
long
或者
Long
初始赋值时,使用大写的
L
,不能是小写的
l
,小写容易跟数字1混淆,造成误解。
说明:
Long
a
= 2
l;
写的是数字的21,还是
Long
型的2?
3.【推荐】不要使用一个常量类维护所有常量,按常量功能进行归类,
分开维护。
说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,
不利于理解和维护。
正例:缓存相关常量放在类
CacheConsts
下
;
系统配置相关常量放
在类
ConfigConsts
下。
4.【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常
量、子工程内共享常量、包内共享常量、类内共享常量。
1
)
跨应用共享常量:放置在二方库中,通常是
client
.
jar
中的
constant
目录下。
2
)
应用内共享常量:放置在一方库中,通常是
modules
中的
constant
目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位攻城师
在两个类中分别定义了表示“是”的变量:
类
A
中:
public
static
final
String
YES
= "
yes
"
;
类
B
中:
public
static
final
String
YES
= "
y
"
;
A
.
YES
.
equals(B
.
YES)
,预期是
true
,但实际返回为
false
,导致线上问题。
3
)
子工程内部共享常量:即在当前子工程的
constant
目录下。
4
)
包内共享常量:即在当前包下单独的
constant
目录下。
5
)
类内共享常量:直接在类内部
private static final
定义。
5.【推荐】如果变量值仅在一个范围内变化,且带有名称之外的延伸
属性,定义为枚举类。下面正例中的数字就是延伸信息,表示星期几。
正例:
public Enum
{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4),
FRIDAY(5), SATURDAY(6), SUNDAY(7);}
(三) 代码格式
1.【强制】大括号的使用约定。如果是大括号内为空,则简洁地写成
{}即可,不需要换行
;
如果是非空代码块则:
1
)
左大括号前不换行。
2
)
左大括号后换行。
3
)
右大括号前换行。
4
)
右大括号后还有
else
等代码则不换行
;
表示终止的右大括号后必
须换行。
2.【强制】左小括号和字符之间不出现空格
;
同样,右小括号和字符
之间也不出现空格。详见第5条下方正例提示。
反例:
if (空格a == b空格)
3.【强制】
if
/
for
/
while
/
switch
/
do
等保留字与括号之间都必须加
空格。
4.【强制】任何二目、三目运算符的左右两边都需要加一个空格。
说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号等。
5.【强制】采用4个空格缩进,禁止使用
tab
字符。
说明:如果使用tab缩进,必须设置1个tab为4个空格。IDEA
设置tab为4个空格时,请勿勾选
Use tab character
;而在eclipse
中,必须勾选
insert spaces for tabs
。
正例:
(
涉及1-5点
)
public static void main(String[]
args) {
// 缩进4个空格
String say = "hello";
// 运算符的左右必须有一个空格
int flag = 0;
// 关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不
需要空格
if (flag == 0) {
n(say);
}
// 左大括号前加空格且不换行;左大括号后换行
if (flag == 1) {
n("world");
// 右大括号前换行,右大括号后有else,不用换行
} else {
n("ok");
// 在右大括号后直接结束,则必须换行
}
}
6.【强制】注释的双斜线与注释内容之间有且仅有一个空格。
正例:
//
注释内容,注意在
//
和注释内容之间有一个空格。
7.【强制】单行字符数限制不超过120个,超出需要换行,换行时
遵循如下原则:
1)第二行相对第一行缩进4个空格,从第三行开始,不再继续缩
进,参考示例。
2
)
运算符与下文一起换行。
3
)
方法调用的点符号与下文一起换行。
4
)
方法调用时,多个参数,需要换行时,在逗号后进行。
5
)
在括号前不要换行,见反例。
正例:
StringBuffer sb = new StringBuffer();
//超过120个字符的情况下,换行缩进4个空格,点号和方法名称一起换行
("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");
反例:
StringBuffer sb = new StringBuffer();
// 超过120个字符的情况下,不要在括号前换行
("zi").append("xin")...append
("huang");
// 参数很多的方法调用可能超过120个字符,不要在逗号前换行
method(args1, args2, args3, ...
, argsX);
8.【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
正例:下例中实参的"
a
",后边必须要有一个空格。
method("a", "b", "c");
9.【强制】
IDE
的
text
file encoding
设置为
UTF
-8
;IDE
中文件的
换行符使用
Unix
格式,不要使用
Windows
格式。
10.【推荐】没有必要增加若干空格来使某一行的字符与上一行对应位
置的字符对齐。
正例:
int a = 3;
long b = 4L;
float c = 5F;
StringBuffer sb = new
StringBuffer();
说明:增加
sb
这个变量,如果需要对齐,则给
a
、
b
、
c
都要增加
几个空格,在变量比较多的情况下,是一种累赘的事情。
11.【推荐】方法体内的执行语句组、变量的定义语句组、不同的业务
逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不
需要插入空行。
说明:没有必要插入多个空行进行隔开。
(四) OOP规约
1.【强制】避免通过一个类的对象引用访问此类的静态变量或静态方
法,无谓增加编译器解析成本,直接用类名来访问即可。
2.【强制】所有的覆写方法,必须加@
Override
注解。
说明:
getObject()
与
get
0
bject()
的问题。一个是字母的
O
,一
个是数字的0,加@
Override
可以准确判断是否覆盖成功。另外,如果
在抽象类中对方法签名进行修改,其实现类会马上编译报错。
3.【强制】相同参数类型,相同业务含义,才可以使用
Java
的可变参
数,避免使用
Object
。
说明:可变参数必须放置在参数列表的最后。
(
提倡同学们尽量不
用可变参数编程
)
正例:
public User getUsers(String type, ids){...}
4.【强制】外部正在调用或者二方库依赖的接口,不允许修改方法签
名,避免对接口调用方产生影响。接口过时必须加@
Deprecated
注解,并
清晰地说明采用的新接口或者新服务是什么。
5.【强制】不能使用过时的类或方法。说明:
java
.
net
.
URLDecoder
中的方法
decode(String
encodeStr)
这个方法已经过时,应该使用双参
数
decode(String
source, String
encode)
。接口提供方既然明确是过
时接口,那么有义务同时提供新的接口
;
作为调用方来说,有义务去考证
过时方法的新实现是什么。
6.【强制】
Object
的
equals
方法容易抛空指针异常,应使用常量或
确定有值的对象来调用
equals
。
正例:"
test
"
.equals(object);
反例:
(
"
test
"
);
说明:推荐使用
java
.
util
.
Objects
#
equals(JDK
7引入的工具类
)
7.【强制】所有的相同类型的包装类对象之间值的比较,全部使用
equals
方法比较。
说明:对于
Integer
var
= ? 在-128至127范围内的赋值,
Integer
对象是在
IntegerCache
.
cache
产生,会复用已有对象,
这个区间内的
Integer
值可以直接使用==进行判断,但是这个区
间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是
一个大坑,推荐使用
equals
方法进行判断。
8.关于基本数据类型与包装数据类型的使用标准如下:
1
)
【强制】所有的
POJO
类属性必须使用包装数据类型。
2
)
【强制】
RPC
方法的返回值和参数必须使用包装数据类型。
3
)
【推荐】所有的局部变量使用基本数据类型。
说明:
POJO
类属性没有初值是提醒使用者在需要使用时,必须
自己显式地进行赋值,任何
NPE
问题,或者入库检查,都由使用者
来保证。
正例:数据库的查询结果可能是
null
,因为自动拆箱,用基本
数据类型接收有
NPE
风险。
反例:比如显示成交总额涨跌情况,即正负
x
%,
x
为基本数据
类型,调用的
RPC
服务,调用不成功时,返回的是默认值,页面显
示为0%,这是不合理的,应该显示成中划线。所以包装数据类型
的
null
值,能够表示额外的信息,如:远程调用失败,异常退出。
9.【强制】定义
DO
/
DTO
/
VO
等
POJO
类时,不要设定任何属性默认值。
反例:
POJO
类的
gmtCreate
默认值为
new
Date();
但是这个属
性在数据提取时并没有置入具体值,在更新其它字段时又附带更新
了此字段,导致创建时间被修改成当前时间。
10.【强制】序列化类新增属性时,请不要修改
serialVersionUID
字
段,避免反序列失败
;
如果完全不兼容升级,避免反序列化混乱,那么请
修改
serialVersionUID
值。
说明:注意
serialVersionUID
不一致会抛出序列化运行时异常。
11.【强制】构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,
请放在
init
方法中。
12.【强制】
POJO
类必须写
toString
方法。使用IDE的中工具:
source
>
generatetoString
时,如果继承了另一个
POJO
类,注意在前面加一下
super
.
toString
。
说明:在方法执行抛出异常时,可以直接调用
POJO
的
toString()
方法打印其属性值,便于排查问题。
13.【推荐】使用索引访问用
String
的
split
方法得到的数组时,需
做最后一个分隔符后有无内容的检查,否则会有抛
IndexOutOfBoundsException
的风险。
说明:
String str = "a,b,c,,";
String[] ary = (",");
// 预期大于3,结果是3
n();
14.【推荐】当一个类有多个构造方法,或者多个同名方法,这些方法
应该按顺序放置在一起,便于阅读,此条规则优先于第15条规则。
15.【推荐】类内方法定义顺序依次是:公有方法或保护方法> 私有
方法>
getter
/
setter
方法。
说明:公有方法是类的调用者和维护者最关心的方法,首屏展示最
好
;
保护方法虽然只是子类关心,也可能是“模板设计模式”下的核
心方法
;
而私有方法外部一般不需要特别关心,是一个黑盒实现
;
因为承载的信息价值较低,所有
Service
和
DAO
的
getter
/
setter
方法放在类体最后。
16.【推荐】
setter
方法中,参数名称与类成员变量名称一致,
this
.
成员名=参数名。在
getter
/
setter
方法中,不要增加业务逻辑,增加排
查问题的难度。
反例:
public Integer getData(){
if (true) {
return + 100;
}else {
return -100;
}
}
17.【推荐】循环体内,字符串的连接方式,使用
StringBuilder
的
append
方法进行扩展。
说明:反编译出的字节码文件显示每次循环都会
new
出一个
StringBuilder
对象,然后进行
append
操作,最后通过
toString
方
法返回
String
对象,造成内存资源浪费。
反例:
String str = "start";
for(int i=0; i<100; i++){
str = str + "hello";
}
18.【推荐】
final
可以声明类、成员变量、方法、以及本地变量,下
列情况使用
final
关键字:
1)不允许被继承的类,如:
String
类。
2)不允许修改引用的域对象,如:
POJO
类的域变量。
3)不允许被重写的方法,如:
POJO
类的
setter
方法。
4)不允许运行过程中重新赋值的局部变量。
5)避免上下文重复使用一个变量,使用
final
描述可以强制重新
定义一个变量,方便更好地进行重构。
19.【推荐】慎用
Object
的
clone
方法来拷贝对象。
说明:对象的
clone
方法默认是浅拷贝,若想实现深拷贝需要重写
clone
方法实现属性对象的拷贝。
20.【推荐】类成员与方法访问控制从严:
1
)
如果不允许外部直接通过
new
来创建对象,那么构造方法必须
是
private
。
2
)
工具类不允许有
public
或
default
构造方法。
3
)
类非
static
成员变量并且与子类共享,必须是
protected
。
4
)
类非
static
成员变量并且仅在本类使用,必须是
private
。
5
)
类
static
成员变量如果仅在本类使用,必须是
private
。
6
)
若是
static
成员变量,必须考虑是否为
final
。
7
)
类成员方法只供类内部调用,必须是
private
。
8
)
类成员方法只对继承类公开,那么限制为
protected
。
说明:任何类、方法、参数、变量,严控访问范围。过于宽泛的访
问范围,不利于模块解耦。
思考:如果是一个
private
的方法,想删除就删除,可是一个
public
的
service
方法,或者一个
public
的成员变量,删除一下,不得手心
冒点汗吗?变量像自己的小孩,尽量在自己的视线内,变量作用域太
大,无限制的到处跑,那么你会担心的。
发布评论