当前位置:首页 > 后端开发 > 品阿里 Java 开发手册有感

品阿里 Java 开发手册有感

6个月前 (05-25)15

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢!

file

一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。
-- 毕玄

1. 命名风格

【书摘】类名用 UpperCamelCase 风格,比如 DO/BO/VO/PO

【书摘】方法用 lowerCamelCase 风格,尽量是动词

小思考:例如常用的
- 获取单个对象,getUserById
- 获取对象累不,listUserByGroupId
- 统计对象数量,countUserByClassId
- 新增、删除,insert,delete,update 等

2. 常量定义

【书摘】如果变量值仅在一个范围变化,则用 enum 类型

小思考:例如电商中订单状态,用手指也能列出来。所以一般定义个 OrderSatausEnum 搞定,伪代码如下:

public enum OrderSatausEnum {
    TO_PAY(1,"代付款"), PAID(2,"已付款") ...;

    private Integer orderStatus;
    private String orderSatausDes;

    OrderSatausEnum(Integer orderStatus,String orderSatausDes) {
        this.orderStatus = orderStatus;
        this.orderSatausDes = orderSatausDes;
    }

    // get set
}

进一步,如果订单某天要加个“待拼团”状态咋办?所以这些配置化的东西,可以上配置中心。比如携程出的 apollo 等

3. OOP 规则

【书摘】Object 的 equals 方法容易抛空指针异常,应使用常量或者确定优质的对象来调用 equals 。

比如:“TO_PAY”.equals(order.getOrderStatus())。反着写就不对了,因为 order.getOrderStatus() 可能为 null。

自然,更加推荐 java.util.Objects#equals 工具类。

【书摘】所有相同类型的包装类对象之间的值比较,全部使用 equals 方法。

小思考:别用 == 了。equals 也要注意些事情,比如 Byte 类型的 status 对象值,用 equals 要注意如下:

getStatus().equals(0) // 反例,false
getStatus().equals((byte)0) // 正例,true

还有, == 比如 Integer 在 -128 到 127 范围比较正常,超过就不正常。原因是 -128 到 127 范围的对象在 IntegerCache.cache 中产生,会复用对象。所以所以,切记切记,别用 == 了,用 equals 去比较。

4. 集合处理

【书摘】不要在 for 循环中进行元素的 remove/add 操作。remove 请使用 Iterator 方法,如果有并发操作,则对 Iterator 对象加锁。

具体 Iterator 怎么操作集合,百度下即可。这还是典型的 迭代器设计模式,可以深入源码看看人家的简单实现原理,又能学到一发高级知识。

5. 并发处理

【书摘】第一,线程必须通过线程池来提供,不允许显式创建线程。第二,线程池不允许用 Executors 创建,应使用 ThreadPoolExecutor 去创建。因为
Executors 创建的几种 ThreadPool 会有弊端:

  • FixedThreadPool 和 SingleThreadPool 允许请求队列长度为 Integer.MAX_VALUE ,大量请求,会导致 OOM
  • CachedThreadPool 和 ScheduledThreadPool 允许创建最大的线程数为 Integer.MAX_VALUE,大量创建线程,会导致 OOM

所以,使用 ThreadPoolExecutor 的原因是能更好地理解线程池的运行规则,规避资源耗尽,更好地贴合某个业务场景,去创建更适合的线程池。


【书摘】在高并发场景中,同步调用应该考虑锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。即,加锁的粒度越小,性能损耗越小。并且避免锁的代码块中调用了 RPC 方法。

另外,同时对多个资源加锁的时候,需要保持一致的加锁顺序。否则,一个线程加锁顺序为 ABC,另一个加锁顺序为 ACB 或 BAC 等,会造成死锁。如图:

file


【书摘】金融资金相关信息,使用悲观锁。比如更新某个用户的钱包余额字段。

小思考:我以前做 P2P 的时候,就很简单地使用了 MySQL 的行锁。

SELECT * FROM xx WHREER xx.id=888 FOR UPDATE

具体行锁,表锁大家可以自行百度了解。

6. 控制语句

【书摘】高并发场景,比如秒杀场景,商品扣库存,库存的判断不要用“等于”来判断商品库存已售罄的条件。应使用大于或者小于的条件来代替。

小思考:这是典型的超卖场景。有人会问也会存在超卖几件的问题吧?答案是是的。但如果用 等于 来判断,超卖的件数会很多很多,比如达到 1 万件。但超卖 1 万件和超卖 1 件是不一样等级的故障。或者是一个故障和一个不是故障的区别。

7.异常处理

【书摘】异常不要用来做流程控制,条件控制

小思考:昨天京东小哥问我,这个能这么搞降级吗?如下代码:

try {
    searchFromES()
}catch(){
    searchFromDB()
}

这不算降级,这也不能这么搞。第一,代码这也写就不对,异常不要用来做流程控制,条件控制。第二,这个只要实现 ES 读取有问题,读取不到就读 DB。可以考虑责任链设计模式去实现。伪代码如下:

ESHandle {
    void handle() {
        try {
            searchFromES()
        }catch(){
        }
    }
}

DBHandle {
    void handle() {
        try {
            searchFromES()
        }catch(){
        }
    }
}

// 两个 Handle 利用责任链去实现即可。

8. 建表规约 、SQL 语句

【书摘】当单表行数超过 500 万行或者单表容量超过 2 GB时,才推荐进行分库分表。

如果预计三年后的数量级无法达到这个级别,请不要在创建表时就分库分表。


【书摘】不要使用 count(列名) 或者 count(常量) 来替代 count(*)。 因为它是 SQL92 定义的标准统计行数的预发。它会统计 NULL 的行。


【书摘】where 条件下里面的 in 能避免就避免,要注意 in 里面的集合数量,控制在 1000 个之内。


【书摘】在代码中写分页查询,如果 count 为 0 ,直接返回 空列表。避免执行下面的分页语句。

9.服务器

【书摘】高并发服务器建议调小 TCP 协议的 time_wait 超时时间。Linux 修改 /etc/sysctl.conf 文件,代码如下:

net.ipv4.tcp_fin_timeout = 30

【书摘】JVM 设置参数 -XX:+HeapDumpOnOutOfMemoryError。让 JVM 碰到 OOM 的时候,输出 dump 信息。

小思考:这个很重要。二者得保留事故服务器现场。比如 OOM 了某个服务器,则在 VIP 或者啥摘到该机器,让该机器不再有请求进入。然后去查看 dump 信息,去排查 OOM 问题。

最后

感谢小册子《阿里巴巴 Java 开发手册》,感觉不错。至少其中有几点,有目共睹的。

 
(关注微信公众号,领取 Java 精选干货学习资料)

作者:程序员泥瓦匠
来源链接:https://bysocket.blog.csdn.net/article/details/88971121

“品阿里 Java 开发手册有感” 的相关文章

-1-6 java 异常简单介绍 java异常 异常体系 Throwable 分类 throws和throw 异常处理 自定义异常

java 异常简单介绍 java异常 异常体系 Throwable 分类 throws和throw 异常处理 自定义异常  ...

全文搜索引擎 ElasticSearch 还是 Solr?

全文搜索引擎 ElasticSearch 还是 Solr?

最近项目组安排了一个任务,项目中用到了全文搜索,基于全文搜索 Solr,但是该 Solr 搜索云项目不稳定,经常查询不出来数据,需要手动全量同步,而且是其他团队在维护,依赖性太强,导致...

微服务之间的调用

微服务之间的调用

第一步:导入依赖:implementation(“org.springframework.cloud:spring-cloud-starter-op...

netty(七)【主从 Reactor 多线程模型】

netty(七)【主从 Reactor 多线程模型】

文章目录 简介: 优缺点: Reactor 模型 生动解释:...

超详细的MySQL8.0安装教程

超详细的MySQL8.0安装教程

MySQL8.0安装教程 一、先去官网(https://dev.mysql.com/downloads/mysql/)下载mysql。 接下...

NLP基本工具之jieba详解

NLP基本工具之jieba详解

jieba的作用只有分词吗?   简介 jieba(结巴)是百度工程师Sun Junyi开发的一个开源库,在GitHub上很受欢迎,使用频率也很高...

Java高级篇-多线程

Java高级篇-多线程

多线程 基本概念 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一 段静态的代码,静态对象。...

c++每日八股文 函数指针和指针函数

c++每日八股文 函数指针和指针函数

一、指针函数 本质是一个函数,其返回值是一个指针 #include<iostream> using namespace std;...

【JAVA程序设计】(C00048)基于springboot酒店宾馆管理系统——(全套视频讲解)

【JAVA程序设计】(C00048)基于springboot酒店宾馆管理系统——(全套视频讲解)

基于springboot酒店宾馆管理系统 项目获取 文章结构 一、开发...

深入解析Jieba分词源码(包括Trie存储,正向匹配,HMM,viterbi)

深入解析Jieba分词源码(包括Trie存储,正向匹配,HMM,viterbi)

最近在做关于短文本的分词和自定义类别标示工作,通过调研分析Jieba源码,发现开源的分词库里融合了许多算法:Trie数对词典的存储,HMM、Viterbi对文本的序列分割和标注,正向最大...