- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本规范的目的是提升代码质量,提升团队协作效率,规范中出现的强制,推荐,参考含义如下:
【强制】:必须严格遵守,如有特殊情况,需架构委员会评审报备.
【推荐】:没特殊情况必须遵守,在开发组长允许下可以不遵守.
【参考】:可以参考,不做严格要求.
【强制】驼峰式命名,其他不允许,常量除外.
【强制】拼音和英文混合不允许.
正例: alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文。
反例: DaZhePromotion [ 打折 ] / getPingfenByName() [ 评分 ]
【强制】常量命名大写,单词以下划线隔开,语义尽量表达完整,比如MAX就语义不明确.
正例: MAX _STOCK _COUNT
反例: MAX _COUNT
【强制】抽象类使用Abstract开头或者Base结尾,异常类以Exception结尾, 测试类命名以它要测试的类的名称开始,以 Test 结尾.
【强制】除非业界通用缩写,否则不允许单词缩写.
反例: AbstractClass “缩写”命名成 AbsClass;condition “缩写”命名成 condi ,此类随意缩写严重降低了代码的可阅读性。
【推荐】工具类以Utils结尾,帮助类以Helper结尾,帮助类跟工具类的区别在于帮助类是方便业务逻辑使用的,工具类是更通用的.
正例: 应用工具类包名为 com . yujiahui . common . util 、类名为 MessageUtils( 此规则参考spring 的框架结构 )
【推荐】枚举类使用Enum结尾.
【推荐】如果模块、接口、类、方法使用了设计模式,在命名时体现出具体模式.
说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。
正例: public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
【参考】分层命名规范 。
1. DTO命名规范,如果DTO是命令,则Cmd结尾,如果是查询,Query结尾,如果是view object,VO结尾,其他无法归类的DTO结尾。
2. Service层以Service结尾,Dao层以Dao结尾。方法获取单个对象以get开头,获取多个对象以list开头,获取数量已count开头。
插入以create开头,更新以update开头,删除以delete开头
3. 领域层工厂以Factory结尾,领域服务建议以DomainService结尾,实体和值对象不需要后缀,是什么名称就什么名称,比如订单实体就叫Order
4. 领域模型层命名尽量与数据表一致,比如表order_detail,命名为OrderDetail,如果表有统一前缀,前缀是否体现到模型对象名上在一个项目内统一。
【推荐】实体里面有些布尔方法如果用is开头容易被框架判断为属性,建议都用iz开头,比如izEasy.
【强制】魔鬼数字不允许.
【强制】long 或者 Long 初始赋值时,使用大写的 L ,不能是小写的 l ,小写容易跟数字 1 混淆,造成误解.
说明: Long a = 2 l; 写的是数字的 21,还是 Long 型的 2?。
【推荐】不要在一个类里面维护所有常量,比如领域模型的常量可以放到领域模型里面,也可以另外建立一个常量类,常量类以Constants结尾 。
正例:缓存相关常量放在类 CacheConstants 下 ; 系统配置相关常量放在类 ConfigConstants 下
【推荐】常量类共享应该按层次放置,层次分为:跨应用共享,应用内共享,模块内共享,类内共享。跨应用共享的常量类放置在一个jar的constant包下,应用内共享的常量类放置下通用模块下的constant包下,模块内共享的常量类放置在本模块的constant包下.
反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:
类 A 中: public static final String YES = " yes " ;
类 B 中: public static final String YES = " y " ;
A . YES . equals(B . YES) ,预期是 true ,但实际返回为 false ,导致线上问题。
【强制】所有覆写的方法都必须加上@Override.
【推荐】equals方法容易报空指针异常,常量放前面或者使用Objects.equals(jdk7引入).
正例:" test " .equals(object);
反例: object.equals( " test " );
【强制】包装类的相等比较用equals,不能用==.
【推荐】基本类型和包装类型的使用标准:
1. pojo类型的属性用包装类型
2. RPC方法的参数和返回值用包装类型
3. 局部变量使用基本类型
【强制】领域模型类必须实现toString方法 。
【推荐】类内方法定义的顺序是:公有方法》保护方法》私有方法》getter,setter.
【推荐】类的方法的访问控制从严。类的方法只在内部使用必须是private,只对继承类开放,必须是protected,变量跟方法类似.
【强制】不要在类里面使用静态变量存储数据,如果需要,使用线程安全的数据结构.
【强制】不能在foreach循环中删除集合元素,删除元素使用迭代器.
// 正面案例
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (删除元素的条件) {
iterator.remove();
}
}
// 反面案例
List<String> a = new ArrayList<String>();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}
【强制】SimpleDateFormat线程不安全不要定义为static变量.
// 正例:注意线程安全,使用 DateUtils 。亦推荐如下处理:
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@ Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
【推荐】高并发时,考虑锁的性能,尽量用无锁数据结构,能锁区块就不要锁整个方法,能锁对象及不要锁整个类.
【强制】有并发修改同一个对象的场景,需要加锁,并发修改的概率大于20%,使用悲观锁,否则使用乐观锁, 乐观锁根据业务场景考虑重试次数.
【推荐】有返回值的函数尽量不要修改入参.
【推荐】尽量少用else,使用卫语句。比如:if(condition) {return obj;} 其他逻辑; 如果实在if-else多,采用状态模式.
// 正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,
public void today() {
if (izBusy()) {
System.out.println(“change time.”);
return;
}
if (izFree()) {
System.out.println(“go to travel.”);
return;
}
return;
}
【强制】方法的参数不允许超过5个.
【推荐】参数和返回值不要用Map这种泛化参数.
【强制】方法的大括号层级不允许超过4层.
【推荐】一个方法只做一件事情,方法不超过30行.
【强制】方法不能有副作用,比如查询类方法,不允许改变入参的属性值.
【推荐】类不能超过500行.
【推荐】不允许大量重复代码.
【强制】批量操作必须分组,比如批量插入一千条数据,分为500一组.
正例:List groups = Lists.partition(list,500);
【强制】业务查询返回数据过多必须分页,比如不能超过5000条返回数据.
【推荐】工具类先看项目中是否有提供,不允许随意添加,如果碰到项目中和jar内有同名工具类,优先使用项目中的类,比如StringUtils在多个jar中有,先使用本项目的StringUtils,满足不了要求,再用其他jar的类或者移植方法到本项目的StringUtils.
【推荐】重要业务流程必须有业务日志,采用BizLog注解,记录新旧值.
【推荐】Service层提供的都是业务逻辑方法,不要放大量查询方法,有多种查询的业务模型抽取出Query类,比如OrderQueryService,也可以采用CQRS模式,命令和查询分离.
【强制】业务上存在并发操作的场景,考虑方法的幂等性,或者使用乐观锁.
【推荐】时刻进行代码重构,避免代码腐化,去掉下次再改的心态(潜台词:永不再改) 。
【强制】业务上涉及订单、用户信息、金额等安全敏感数据文件导出并上传阿里云OSS时,必须使用文件服务的/api/file/uploadPrivate接口上传到阿里云OSS.
【强制】业务逻辑尽量避免跨数据库事务操作,严禁事务中穿插执行不同数据库的sql语句,必要时要考虑失败场景补偿方案和告警机制.
反例:
执行A数据库更新逻辑X
执行B数据库更新逻辑Y
执行A数据库更新逻辑X
执行B数据库更新逻辑Y
【参考】类、类属性、类方法的注释使用 Javadoc 规范,使用/**内容*/格式,避免使用// xxx 方式.
【推荐】所有的抽象方法 ( 包括接口中的方法 ) 必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能.
说明:对子类的实现要求,或者调用注意事项,请一并说明。
【推荐】所有的枚举类型字段要有注释,说明每个数据项的用途.
【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改.
【参考】谨慎注释掉代码。在上方详细说明,而不是简单的注释掉。如果无用,则删除.
说明:代码被注释掉有两种可能性:
1. 后续会恢复此段代码逻辑。
2. 永久不用。前者如果没有备注信息,难以知晓注释动机。后者建议直接删掉 ( 代码仓库保存了历史代码 ) 。
【参考】对于注释的要求:第1、能够准确反应设计思想和代码逻辑 ; 第2、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路 ; 注释也是给继任者看的,使其能够快速接替自己的工作.
【参考】好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担.
// 反例 put elephant into fridge
put(elephant, fridge);
方法名 put ,加上两个有意义的变量名 elephant 和 fridge ,已经说明了这是在干什么,语义清晰的代码不需要额外的注释。
【推荐】及时清理不再使用的代码段或配置信息.
说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。
正例:对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三个斜杠(///)来说明注释掉代码的理由。
比如{code:”0”,msg:”操作成功”,data:{XX}}.
【推荐】Rest接口必须标明请求的content_type。比如content_type=applicaton/json 。
【强制】接口提供方必须考虑幂等性,防止重复调用导致严重的业务灾难.
【强制】查询接口如果数据量过多,需要分页返回.
【推荐】接口必须标明字段的类型,长度,是否必填,文字说明必须准确,反例:person:人员.
正例:person:人员编码.
【推荐】Rest接口返回值需要综合考虑实际功能、安全和性能需求,精细化按需返回业务数据.
比如,移动端接口需要考虑性能问题,要避免返回无效字段;对于中台服务移动端接口返回的多余字段场景,需要业务应用封装处理后再返回给移动端.
PC端接口返回值要求 | 移动端接口返回值要求 | |
---|---|---|
中台服务 | 满足实际功能、安全即可 | 满足实际功能、安全即可。性能要求需要业务应用封装处理。 |
业务应用 | 满足实际功能、安全即可 | 除了满足实际功能、安全需求之外,要考虑性能,避免返回无效字段 |
【推荐】Feign Api提供方禁止在给下游使用方的jar中引入AutoConfiguration等影响启动的配置类 。
要求有自增ID作为主键,不要使用随机性较强的 order_id 作为主键,会导致innodb内部page分裂和大量随机I/O,性能下降.
单表索引建议控制在5个以内,单索引字段数不超过5个。注意:已有idx(a, b)索引,又有idx(a)索引,可以把idx(a)删了,浪费空间,降低更新、写入性能。* 单个索引中,每个索引记录的长度不能超过64KB 。
利用覆盖索引来进行查询操作,避免回表。另外建组合索引的时候,区分度最高的在最左边.
select(count(distinct(字段)))/count(id) = 1 的区分度,更适合建索引。在一些低区分度的字段,例如type、status上建立独立索引几乎没意义,降低更新、写入性能.
防止因字段不同造成的隐式转换,导致索引失效.
更新频繁的字段,不要建索引.
单表数据量不超过500万行,ibc 文件大小不超过 2G 。
水平分表用取模,日志、报表类,可以用日期 。
单实例表数目小于 500 。
alter表之前,先判断表数据量,对于超过100W行记录的表进行alter table,必须在业务低峰期执行。因为alter table会产生表锁,期间阻塞对于该表的所有写入 。
SELECT语句必须指定具体字段名称,禁止写成 “*”select * 会将不需要读的数据也从MySQL里读出来,造成网卡压力,数据表字段一旦更新,但model层没有来得及更新的话,系统会报错 。
insert语句指定具体字段名称,不要写成 `insert into t1 values(…)`` 。
``insert into…values(XX),(XX),(XX)..` 这里XX的值不要超过5000个,值过多会引起主从同步延迟变大.
union all 和 union,不要超过5个子句,如果没有去重的需求,使用union all性能更好.
in 值列表限制在500以内,例如 select… where userid in(….500个以内…),可以减少底层扫描,减轻数据库压力.
除静态表或小表(100行以内),DML语句必须有where条件,且尽量使用索引查找 。
生产环境禁止使用 hint,如 sql_no_cache,force index,ignore key,straight join等。 要相信MySQL优化器。hint是用来强制SQL按照某个执行计划来执行,但随着数据量变化我们无法保证自己当初的预判是正确的.
where条件里,等号左右字段类型必须一致,否则会造成隐式的类型转化,可能导致无法使用索引 。
生产数据库中强烈不推荐在大表执行全表扫描,查询数据量不要超过表行数的25%,否则可能导致无法使用索引 。
where子句中禁止只使用全模糊的LIKE条件进行查找,如like ‘%abc%’,必须有其他等值或范围查询条件,否则可能导致无法使用索引 。
索引列不要使用函数或表达式,如 where length(name)=10 或 where user_id+2=1002,否则可能导致无法使用索引 。
减少使用or语句 or有可能被 mysq l优化为支持索引,但也要损耗 mysql 的 cpu 性能。可将or语句优化为union,然后在各个where条件上建立索引。如 where a=1 or b=2 优化为 where a=1… union …where b=2, key(a),key(b) 某些场景下,也可优化为 in 。
分页查询,当limit起点较高时,可先用过滤条件进行过滤。如 select a,b,c from t1 limit 10000,20; 优化为 select a,b,c from t1 where id>10000 limit 20,
同表的字段增删、索引增删等,合并成一条DDL语句执行,提高执行效率,减少与数据库的交互.
replace into 和 insert on duplicate key update 在并发环境下执行都可能产生死锁(后者在5.6版本可能不报错,但数据有可能产生问题),需要catch异常,做事务回滚,具体的锁冲突可以关注next key lock和insert intention lock 。
TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,但 TRUNCATE 无事务且不触发 trigger ,有可能造成事故,故不建议在开发代码中使用此语句。说明: TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同.
系统性能瓶颈很大一部分都是指向了数据库,而循环中查询数据库非常耗资源.
展示少量树结构数据时,循环内查询数据后进行数据组装。导致服务器在测试环境就频繁宕机.
使用java.util.Comparator#compare方法调用数据库查询接口,导致线上性能极低.
缓存无法完全符合事务特性ACID原则,数据存在不可使用的风险比较大.
会员数据直接存储到redis缓存中,数据量也比较大,经常会丢数据.
死循环中最好有休眠语句存在,另外还要退出机制.
订单同步应用请求第三方平台数据时,平台方没有翻页的结束标志,同时代码中没有退出机制直接导致该平台订单同步异常.
尽量避免使用共享变量,无法避免时必须考虑线程安全.
微信抽奖功能中,每次中奖都是同一个,原因是对共享变量进行了修改操作,后面的逻辑获取的是脏数据.
如果需要精确计算,非要用String来够造BigDecimal不可.
数据量大时须批量操作,而批量操作必须分组,避免一次操作耗时过久导致连锁反应.
订单历史迁移数据时,分组为5000,导致数据库删除操作没有走索引。建议分组数量在100~500之间.
增加一台服务器部署可以降低50%的服务不可用风险.
全表扫描已经很耗数据库资源了,频繁处理请求不加限流就更雪上加霜.
售后问题跟踪单的导出,时间索引没有控制范围,导致全表扫描。导出数据接口没有加限流加剧服务资源消耗.
读写分离在业务数据更新写入后再重现读取时会存在延迟问题,导致读到脏数据.
A. 双十一开启读写分离,主从同步有延迟,导致业务事件重复发送,原因是读取到历史 脏数据.
B. 会员积分服务创建数据后其他服务应用马上查询,结果是查询到空数据.
事务本身是很耗资源,极易产生超时的问题,要避免再引入外部不稳定因素.
个人中心服务,事务内远程查询美丽分享官的积分,导致性能极低。外部接口调用需要设置超时和最长等待时间.
根据墨菲定律,接口重复调用是会必现的线上问题.
订单付款接口,幂等逻辑不严谨导致重复付款问题。apollo报表中心由于xxljob一秒内重复调度任务,导致统计数据重复,严重影响管理层的决策判断.
使用事务注解或者编程式事务时,需要考虑默认的事务传播属性,根据需要决定是并入同一个事务还是开启新事务.
OMS异步操作任务,调用第三方接口时,修改状态为确认中状态,需要先提交事务更新,后面的逻辑操作成功则需要修改为已确认,失败则修改为待审核。当第三方接口没有返回明确的成功或失败时,状态应该保持确认中不变。如果调用接口前不开启新事务,会导致后面回滚的数据有误.
equals和hashCode方法是对象在hash容器内高效工作的基础,正确的覆写这两个方法才能保证在hash容器内查找对象的正确性,同时一个好的hashCode方法能大幅提升hash容器效率.
循环上层包含事务,使用synchronized锁,会导致MySQL事务锁和JVM同步锁互相等待死锁问题.
@Transactional(rollbackFor = Exception.class)
public void storeData(List<Order> orderList) {
/**
order_id = {1,2,3}
线程A更新order_id为1后进入下一轮循环,事务锁还未释放,同步锁需要重新获取。
同时线程B已获取同步锁,需要更新order_id=1的事务操作。结果就是线程A等待线程B持有的
JVM同步锁,线程B等待线程A持有的事务锁。
*/
for(Order order : orderList) {
synchronized (LOCK) {
updateOrderId(order);
}
}
}
不加限制的批量创建线程会抢占大量系统的资源,引发OOM等连锁异常,最终导致宕机 。
将new MapReduce<>(xxx)创建线程池的代码放在API接口实现方法中没有加其他限制,导致引发OOM宕机,中间触发了Redis连接超时、Kafka重复消费等异常 。
对多个系统项目都有依赖的公共代码进行修改时,需要考虑兼容历史逻辑,除非确认所有使用方都能够接受功能修改产生的影响 。
项目A的开发人员将公共jar包中逻辑进行了修改(该修改需要开启一个新配置才和原逻辑一致),同时deploy jar包进行测试,新配置只在测试环境进行了操作。依赖了公共jar包的项目B这时进行线上发版,但是没有进行配置(而且也不知道有这个配置),导致线上事故.
字符集和排序规则后期修改需要耗费巨大的资源,影响业务稳定性,为了保持schema-表-表字段三者的字符集和排序规则一致,禁止在新建表或者增加修改表字段时设置字符集和排序规则.
A项目的某一个表的字段设置了字符集和排序规则,导致与表-schema的排序规则不一致,在联合查询时这个表作为关联字段,报关联字段排序规则不一致的错误,无法进行关联查询,只能修改,如果是一张大表修改会非常耗时,占用大量的io会影响业务.
TEXT/BLOD的大字段会产生磁盘临时表,而且不能使用全文索引,各种操作的代价都非常高昂,在业务中最好不要使用,如果实在是要使用,也要独立出一张表专门用于存储,不得跟业务表中使用.
A项目前期的一张表中使用了一个TEXT存储json大字段,导致这张表占用了600多G的空间,其中那一个大字段就占用90%的表空间,后续的查询,迁移,碎片整理都非常的耗资源.
最后此篇关于JAVA开发规范的文章就讲到这里了,如果你想了解更多关于JAVA开发规范的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我们有一个 Java 项目,每天晚上使用 TeamCity 对 Java 类进行静态分析,以查找代码中容易出现的错误。我们想告诉 TeamCity 寻找开发人员可能引入的与 == 与 .equals
前言 🍊缘由 Git分支管理好,走到哪里都是宝 🏀事情起因: 最近翻看博客中小伙伴评论时,发现文章【规范】看看人家Git提交描述,那叫一个规矩一条回复: 本狗亲测在我司中使用规范
使用带有不存在的命名空间的命名空间限定关键字来定义规范是否被认为是不好的做法?我想在公共(public) domain 命名空间中定义实体映射...所以为了避免在合并规范时丢失数据,我使用约定 :en
有没有办法在调用 clojure.spec.test.alpha/check 时覆盖核心谓词函数的生成器? 可以通过 s/gen 中的路径覆盖谓词生成器: (gen/generate (s/gen
以内核 rpm 为例,它允许在一个系统上同时安装多个版本。规范文件中究竟是什么允许的? 我想打包一个已经存在的具有不同安装前缀的多个版本的项目。 最佳答案 百胜 找到了让 yum 安装而不是更新的方法
我正在尝试用 C# 编写 PDF 解析器,但我遇到了一个问题,我不确定如何解释规范。 除非另有说明,否则 PDF 文档中的用户空间为 1/72 英寸(即 1pt)。 Tf 运算符提供的比例将字体从标准
我正在编写一些代码,需要能够获取两个 pdf 并将它们附加到页面级别(例如,如果它们都是 2 页文档,则有一个 4 页文档,其中所有 4 页都与原始文档相同). 在不使用库的情况下,最好的方法是什么?
是否有序言语言语法,或接近它的通常用作引用的东西?我正在使用 SWI-prolog,所以有一个适合这种风格的会很好,否则一般的 prolog 语言语法/规范也能工作。 最佳答案 自 1995 年起,P
我需要一个函数来过滤参数和构建查询。我有 4 个参数,因此如果我尝试为每个条件实现查询,我将不得不写 16 (2^4)实现 - 这不是一个好主意。 我尝试使用界面改进我的代码 Specificatio
这个 ExtGState 对象对图像做了什么: > 我有 PDF 规范,但一点也不清楚。显然,这将身份函数(什么的身份?单位矩阵?)从 [0.0 1.0] 映射到 [0.0 1.0](相同),这是没有
只是想获得有关 ePub 规范的一些帮助。toc.ncx 是否必须具有 src(即 xhtml)。我观察到 .opf 文件中也提供了相同的内容 src。 最佳答案 是的,这是强制性的,这是一个设计问题
让我们看看莱宁根项目 map 的真实示例 :global-vars : ;; Sets the values of global vars within Clojure. This example
我正在开发一个 LOB 框架,它具有 SL 和 MVC 前端、WCF 后端以及在服务器上运行的几个服务模块。我一直在查看 Spec#,看它是否对我有任何帮助。不可空类型和检查异常本身非常好,但我还没有
Promises/A+规范是最小的规范之一。因此,实现它是理解它的最佳方法。福布斯·林德赛(Forbes Lindesay)的以下回答将引导我们完成实现Promises / A +规范Basic Ja
哪个文档指定了 MySQL definer 格式? 具体来说,definer admin@% 中的 % 是什么意思(以及为什么使用这个符号)? 最佳答案 这里MySQL使用的格式定义在the MySQ
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
在 css 规范中,什么会影响更多的 inline 样式或外部 !important 外部“style.css”: #di{color: green!important;} div 文本颜色是红色还
我正在努力思考 CSS 的一些细节,我从 W3 CSS Visual Formatting Spec 9.2.2 中找到了这部分摘录。特别迟钝: Inline-level boxes that are
这个问题在这里已经有了答案: Are (non-void) self-closing tags valid in HTML5? (8 个答案) 关闭 9 年前。 在 HTML5 中你应该使用 或
以下样式在规范方面有何不同? ul .active { background: #E7F3EF;} ul li.active { background: #E7F3EF;} Item 1
我是一名优秀的程序员,十分优秀!