【编写高质量代码:改善Java程序的151个建议】第10章:性能和效率,第11章:开源世界,第12章:思想为源___建议132~151

第10章:性能和效率

建议132:提升Java性能的基本方法

Java性能优化的35个细节(珍藏版)

建议133:若非必要,不要克隆对象

JVM对new进行了大量的性能优化,而clone方式只是一个冷僻的生成对象方式,并不是主流,它主要用于构造函数比较复杂,对象属性比较多,通过new关键字创建一个对象比较耗时间的时候。

建议134:推荐使用“望闻问切”的方式诊断性能

1、望

性能问题从表象上可以分为两类:

① 较难重现的偶发性问题

② 可重现的性能问题

2、闻

在性能优化上的“闻”则是关注项目被动产生的信息,其中包括:项目组的技术能力(主要取决于技术经理的技术能力)、文化氛围、群体的习惯和习性,以及他们专注和擅长的领域等。
@如果项目组的技术能力很强,有资深的数据库专家,有顶尖的架构师,也有首席程序员,那性能问题产生的根源就应该定位在无意识的代码缺陷上。
@如果项目组的文化氛围很糟糕,组员不交流,没有固定的代码规范,缺乏整体的架构等,那性能问题的根源就可能存在于某个配置上,或者相互的接口调用上。
@如果项目组已经习惯了某一个框架,而且也习惯了框架的种种约束,那性能的根源就可能是有人越过了框架的协约。

3、问

与技术人员和业务人员一起探讨问题,了解性能问题的历史状况。

4、切

看设计,看代码,看日志,看系统环境,然后是思考分析,最后给出结论。

建议135:必须定义性能衡量标准

出现性能问题不可怕,可怕的是没有目标。

1、核心业务的响应时间

2、重要业务的响应时间

性能衡量标准必须在一定的环境下,比如网络、操作系统、硬件设备等确定的情况下才会有意义,并且还需要限定并发数、资源数(如10万数据和1000万的数据响应时间肯定不同)等。

建议136:枪打出头鸟--解决首要系统性能问题

解决性能问题时,不要把所有的问题都摆在眼前,这只会“扰乱”你的思维,集中精力,找到那个“出头鸟”,解决它,在大部分情况下,一批性能问题都会迎刃而解,而且我们的用户关注最多的可能就是系统20%的功能,可能我们解决了这一部分,已经达到了用户的预期目标,也就标志着我们的优化工作可以结束了。

建议137:调整JVM参数以提高性能

1、调整堆内存大小

2、调整堆内存中各分区的比例

3、变更GC的垃圾回收策略

4、更换JVM

da9ed2381bcdb5e3986cf442ec9cae0a87f.jpg

注意点:
metaSpace在jdk1.7之前被称为Permanent Space
而且严格意义上讲metaSpace不属于堆空间
见下图:

0306ec0dddd86673944bc333488cf0ee263.jpg

关于部分调优项的介绍

b9afd69c1be56897a0702fd4a0e87264088.jpg

建议138:性能是个大“咕咚”

1、没有慢的系统,只有不满足业务的系统
2、没有慢的系统,只有架构不良的系统
3、没有慢的系统,只有懒惰的技术人员
4、没有慢的系统,只有不愿意投入的系统

第11章:开源世界

建议139:大胆采用开源工具

在选择开源工具和框架时要遵循一定的原则:

1、普适性原则

确保大部分项目成员对工具都比较熟悉

2、唯一性原则

相同的工具只选择一个或一种,不要让多种相同或相似职能的工具共存。
例如集合工具可以在Apache Commons的collections包和Google Guava的Collections工具包中二选其一。

3、用比较有名的开源工具

4、精而专原则

比如虽然Spring框架提供了Utils工具包,但在一般情况下不要使用它,因为它不专,Utils工具包只是Spring框架中的一个附加功能而已,要用就用Apache Commons的BeanUtils、Lang等工具包。

5、高热度原则

一个开源项目的热度越高,更新得就越频繁,使用的人群就越广,Bug的曝光率就越快,修复效率也就越高。

建议140:推荐使用Guava扩展工具包

建议141:Apache工具包

建议142:推荐使用Joda日期扩展包

1、本地格式的日期时间

2、日期计算

3、时区时间

4、可以与JDK的日期库方便地进行转换

建议143:可以选择多种Collection扩展

三个比较有个性的Collections扩展工具包:

1、fastutil

主要提供了两种功能:一种是限定键值类型(Type Specific)的Map、List、Set等,另一种是大容量的集合。

2、Trove

提供了一个快速、高效、低内存消耗的Collections集合,并且还提供了过滤和拦截的功能,同时还提供了基本类型的集合。

Trove的最大优势在于高性能上,在进行一般的增加、修改、删除操作时,Trove的响应时间比JDK的集合少了一个数量级,比fastutil也会高很多,因此在高性能项目中药考虑使用Trove。

3、lambdaj

lambdaj是一个纯净的集合操作工具,他不会提供任何的集合扩展,只会提供集合的操作,比如查询、过滤、统一初始化等,特别是它的查询操作,会提供求和、求平均值的方法:

List<Integer>ints=new ArrayList<Integer>();
//计算平均值
Lambda.avg(ints);
//统计每个元素出现的次数,返回的是一个Map
Lambda.count(ints);
//按照年龄排序
List<Person>persons=new ArrayList<Person>();
Lambda.sort(persons, Lambda.on(Person.class).getAge()));
//串联所有元素的指定属性,输出为:张三,李四,王五
Lambda.joinFrom(persons).getName();
//过滤出年龄大于20岁的所用元素,输出为一个子列表
Lambda.select(persons, new BaseMatcher<Person>(){
@Override
public boolean matches(Object_person){
Person p=(Person)_person;
return p.getAge()>20;
}
public void describeTo(Description desc){
}
});
//查找出最大年龄
Lambda.maxFrom(persons).getAge();
//抽取出所有姓名形成一个数组
Lambda.extract(persons, Lambda.on(Person.class).getName()));

第十二章:思想为源

建议144:提倡良好的代码风格

1、整洁

2、统一

3、流行

4、便捷

建议145:不要完全依靠单元测试来发现问题

1、单元测试不可能测试所有的场景(路径)
单元测试必须测试的三种数据场景是:正常场景、边界场景、异常场景。如果要进行完整的测试就必须建立三个不同的测试场景:正常数据场景,用来测试代码的主逻辑;边界数据场景,用来测试代码(或数据)在边界的情况下逻辑是否正确;异常数据场景,用来测试出现异常非故障时能否按照预期运行。
通常在项目中,单元测试覆盖率很难达到60%,因为不能100%覆盖,这就导致了代码测试的不完整性,隐藏的缺陷也就必然存在了。
2、代码整合错误是不可避免的

3、部分代码无法测试

4、单元测试验证的是编码人员的假设

建议146:让注释正确、清晰、简洁

提倡好的注释:
1、法律版权信息
2、解释意图的注释
说明为什么要这样做,而不是怎么做的,比如解决了哪个Bug,方法过时的原因是什么。
3、警示性注释
4、TODO注释

建议147:让接口的职责保持单一

单一职责有以下三个优点:
1、类的复杂性降低
2、可读性和可维护性提高
3、降低变更风险

建议148:增强类的可替换性

里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象。

建议149:依赖抽象而不是实现

依赖倒置原则(Dependence Inversion Principle,简称DIP):
高层模块不应该依赖低层模块,两者都应该依赖其抽象。
抽象不应该依赖细节。
细节应该依赖抽象。

要做到遵循此原则要做到以下几点:
(1)尽量抽象
接口和抽象类都是属于抽象的,有了抽象才可能依赖倒置。
(2)表面类型必须是抽象的
比如定义集合,尽量使用:
List<String>list=new ArrayList<String>();
(3)任何类都不应该从具体类派生
开发阶段要做到这一点,但不是绝对的,尤其是在维护时。
(4)尽量不要覆写基类的方法
(5)抽象不关注细节

建议150:抛弃七条不良的编码习惯

1、自由格式的代码

2、不使用抽象的代码

3、彰显个性的代码

4、死代码

5、冗余的代码

6、拒绝变化的代码

7、自以为是的代码

建议151:以技术员自律而不是工人

1、熟悉工具

2、使用IDE

3、坚持编码

4、编码前思考

5、坚持重构

6、多写文档

7、保持程序版本的简单性

8、做好备份

9、做单元测试

10、不要重复发明轮子

11、不要拷贝

12、让代码充满灵性

13、测试自动化

14、做压力测试

15、“剽窃”不可耻

多看开源代码

16、坚持向敏捷学习

17、分享

18、刨根问底

19、横向扩展

Java要运行在JVM、操作系统上,同时还要与硬件、网络、存储交互,另外要遵循诸如FTP、SMTP、HTTP等协议,还要实现Web Service、RMI、XML-RPC等接口,所以我们必须熟悉相关的知识—扩展知识面,这些都是必须去学习的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值