读-秦小波-编写高质量代码:改善java程序的151个建议
2016-12-21 10:06
507 查看
有些建议不太用到,但是用到的时候如果不注意就会进坑,所以书名改成java的151个坑更合适。
不要在常量和变量中出现易混淆的字母
包名全小写,类名首字母全大写,常量全大写下划线分割,变量驼峰;
字母l作为长整形标志大写L;
莫让常量蜕变成变量
常量final staic,一般不会,主要是值常量的值不要通过计算获取值,值应该在编译期确认,不要在运行期更改;
三元操作符的类型务必一致
– 不一致会做转换,不管怎么转换,保持一致就行;
避免带有变长参数的方法重载
重载的话,调用时不一定是你想要那个方法;
别让null值和空值威胁到变长方法
直接传递null或空值会让编译器区分不了调用的是哪个变长方法;
覆写变长方法也循规蹈矩
覆写满足的条件:
不能缩小访问权限;
参数列表与重写方法相同(类型、数量、显示形式);
返回类型相同或是其子类;
不能抛出新的异常或超出父类范围的异常,可以缩小或者不抛;
覆写变长方法参数列表必须完全一致;
警惕自增的陷阱
java中count = count++等价于mockAdd(int count){int temp=count; count=count+1;return temp;};
c++中count=count++会自增;
不要让旧语法困扰你
主要是java保有的一些关键字,如goto;
抛弃不用;
少用静态导入
不使用*通配符导入;
方法名是否具有明确清晰的意义;
感觉就是导入的常量类和常量一定要具有含义清晰,不能混淆;
不要在本类中覆盖静态导入的变量和方法
养成良好习惯,显示声明UID
实现Serializable接口的类,serialVersionUID要生成;
避免用序列化类在构造函数中为不变量赋值
序列化类中,不使用构造函数为final变量赋值;
基本类型,数组或简单对象(不通过new);
避免为final变量复杂赋值
反序列化时final变量在以下情况下不会被重新赋值:
通过构造函数赋值;
通过方法返回值赋值;
final修饰的属性不是基本类型;
使用序列化类的私有方法巧妙解决部分属性持久化问题
defaultWriteObject(),defaultReadObject(),writeXX和readXX屏蔽某些字段的序列化;
不要这个,基本不会用到;
break万万不可忘
易变业务使用脚本语言编写
之前工作中有个这样的需求,10几种类型根据公式计算不同生失效时间,公式易变,当时想用js,找了好久都没找到好用的,后来放弃了;
如果能找到适合的脚本engine,那就用吧;
慎用动态编译
避免instanceof非预期结果
instanceof只能用于对象的判断,基本类型不行;
左操作数为null,直接返回false;
断言绝对不是鸡肋
在spring源码中n多使用断言的地方,感觉只是辅助注释的作用;
想用就用,不想用就算;
不要只替换一个类
如果你用ide的话,基本不会有这个问题;
发布时,禁止类文件替换,整体发布。常量类不要私自替换,因为常量会被预编译到引用的类中,会导致私自替换的不起作用;
用偶判断,不用奇判断
奇数判断,负数有问题
用整数类型处理货币
用什么整形,直接BigDecimal;
不要让类型默默转换
基本类型向包裹类型转换时,使用主动声明方式;
long想Long转换:1L*X;
边界
单元测试时,边界测试要认真
四舍五入
第一次听说看见四舍五入还有这么多说法,服了,不过如果真有用到的地方一定要跟业务确认清楚;
RoundingMode;
提防包装类型的null值
包装类型参入运算时,做null值校验;
谨慎包装类型的大小比较
==比较对象引用,>或<使用响应的value()方法;
使用相应的compareTo;
优先使用整形池
valueOf生成的包装实例可以显著提供空间和时间性能;
Integer和Long的会缓存-128到127之间的对象,范围外会new,Double和Float会new;
优先选择基本类型
基本类型可以先加宽,再转变成对应的包装类型,但是不能直接转变成宽的包装类型;
不要随机设置随机种子
随机数和种子的关系:
种子不同,产生不同的随机数;
种子相同,即使实例不同也产生相同的随机数;
非必要,不要设置种子;
接口中不要存在实现代码
静态变量一定要先声明后赋值
变量赋值分2步:先分配空间后赋值,如果先赋值后声明的话,就可能后声明的赋值覆盖之前的赋值;
不要覆写静态方法
实例对象有2个类型:
表面类型:声明时的类型
和实际类型,对象产生时的类型
非静态方法根据实际类型来执行;
静态方法一般是通过类名访问,也可以通过对象访问,当通过对象调用静态方法时,会通过对象的表面类型查找入口执行,又是一个第一次听说的东西;
构造函数尽量简化
避免在构造函数中初始化其他类
跟34对应,构造函数简化,然后提供其他初始化方法,spring中学会的;
使用构造代码块精炼程序
直接{}括起来的代码片段,会在每个构造函数中调用;
建议不要用;
构造代码块会想你所想
构造代码库在super,this调用的情况下也只会调用一次;
了解就行,非必要使用
使用静态内部类提供封装性
使用匿名类的构造函数
匿名类的构造函数很特殊
让多重继承称为现实
外部类继承一个,内部类再继承另一个;
让工具类不可实例化
private 构造函数,阻止不了反射,实在不行就构造抛异常;
避免对象的浅拷贝
推荐使用序列化实现对象的拷贝
覆写equals方法时不要识别不出自己
对String做trim
这个要注意,好多接收外部数据什么的,都需要做trim处理;
equals应该考虑null值情景
判断null值情况
在equals中使用getClass进行类型判断
使用getClass进行类型判断,不要使用Instanceof,主要是防止继承情况下的判断;
这个还真没注意,下次要小心了;
覆写equals方法必须覆盖hashCode方法
推荐覆写toString方法
使用package-info类为包服务
很少用到,spring源码中看到,用这个给包做注释用的情况
作用:
声明友好类和保内访问常量;
为在包上标注注解提供便利;
包注释说明;
不要主动进行垃圾回收
推荐使用String直接量赋值
常量池;
注意方法传递的参数要求
replaceAll传递的第一参数是正则,我去,真没在意这个,下次小心;
正确使用String,StringBuffer、StringBuilder
一般情况String,频繁操作后面2个,单线程StringBuilder,线程安全StringBuffer;
注意字符串的位置
加号表达式中,String字符串具有最高优先级;
对于运算符优先级有疑问的,直接括号省事;
自由选择字符串拼接方法
加号,concat或append,耗时依次减少;
推荐在复杂字符串操作中使用正则表达式
强烈建议使用UTF编码
编码是开发永远的噩梦;
对字符串排序持一种宽容的心态
Collator中文排序,gb2312差不多可以解决,复杂的就找开源的或自己实现吧;
性能考虑,数组是首选
性能要求高的场景中使用数组替代集合;
若有必要,使用变长数组
主要是初始定长,后期校验扩容
警惕数组的浅拷贝
Arrays.copyOf产生的是一个浅拷贝,基本类型拷贝值,其他拷贝引用地址;
场景明确下,为集合指定初始容量
多种最值算法,适时选择
自己实现;
先排序,后取值:Arrays.sort();
避开基本类型数组转换list陷阱
基本类型不能泛型话;
Arrays.asList()参数不能使用原始类型;
asList产生的list对象不可更改
产生的list是一个静态内部类;
不能的列表选择不同的遍历方法
ArrayList实现RandomAcess随机存取接口,使用for循环更好,而不是foreach;
频繁插入和删除使用LinkedList
对比ArrayList,想想数据结构就明白了;
列表相等只需关心元素数据
在AbstractList中实现元素和长度比较
子列表只是原列表的一个视图
subList返回子列表;
所有对subList产生对象的操作作用于原list;
推荐使用subList处理局部列表
生成子列表后不要再操作原列表
会异常;
使用Comparator排序
不推荐使用binarySerach对列表进行检索
二分查找建立在基本有序的情况才行;
实现RandomAccess或数据量小于5K进行二分查找,否则顺序查找;
集合中元素必须做到compareTo和equals方法
集合运算时使用更优雅的方式
并集addAll
交集retainAll
差集removeAll
使用suffle打乱列表
collections.shuffle();
减少hashmap中元素的数量
主要是扩容的时候,可能会内部不够用;
集合中hash码不要重复
不重复最好,重复也无所谓,不用关心;
多线程使用Vector或hashTable
非稳定排序推荐使用List
treeset适用于不变量的数据集合排序;
在处理过程中可能会重新排序的,可以使用list自行排序;
集合家族
list
set
map
queue
数组
工具类:Arrays和反射类Array,collections
扩展类:commons和google的collections
推荐使用枚举定义常量
不太喜欢这种;
使用构造函数协助描述枚举项
使用枚举常量时,小心switch带来的空值异常
在switch的default代码块中增加AssertionError错误
如果使用枚举做switch就不应该走到default;
枚举使用valueOf前必须进行校验
枚举实现工厂模式
枚举项的数量限制在64个以内
小心注解继承
Inherit
枚举和注解结合使用威力更大
注解的值可以使用枚举来定义;
注意@Override不同版本的区别
1.5版本的接口实现,不需要override,1.6以上没问题,注意下就可以;
java的泛型是类型擦除的
泛型参数编译后会被清除;
不能初始化泛型参数和数组
类型擦除,无法获取具体参数
强制声明泛型的实际类型
不同场景使用不同的泛型通配符
读操作? extend限定泛型上界;
写操作? super限定泛型下界;
警惕泛型是不能协变和逆变的
协变:窄类型替换宽类型;
逆变:宽类型替换窄类型;
建议采用的顺序是List\List
使用forName加载类文件
有个参数设置static方法是否调用,默认加载static代码块;
动态加载不适合数组
数组用的反射跟普通的不一样;
动态代码可以使代理模式更灵活
反射增加装饰模式的普适性
反射让模板方法模式更强大
不需要太多关注反射效率
如果有需求要用,就不要过分关注;
提倡异常封装
我们项目很少用,都是用封装errorcode,下次最起码保证自己的代码部分用到;
采用异常链传递异常
异常需要封装和传递,不同视角展示不同提示;
受检异常尽可能转为非受检异常
不要在finally块中处理返回值return
finally返回会覆盖try块中的return值;
屏蔽异常;
只做收尾;
不要在构造函数中抛出异常
这个还真没见过这样处理的;
使用Throwable获得栈信息
异常只为异常服务
还真这么干过,正常业务有问题,为了省事直接抛出异常处理;
多使用异常,性能问题放一边
不推荐覆写start方法
不覆写Thread类的start方法
启动线程前stop方法是不可靠的
不适用stop方法停止线程
线程优先级只是用3个等级
差距大,才有体现;
使用线程异常处理器提升系统可靠性
123.volatile不能保证数据同步
异步运算考虑使用callable接口
有返回值和异常处理;
优先选择线程池
选择不同的线程池
Lock和synchronized是不一样的
预防死锁
适当设置队列长度
阻塞队列的长度是固定的;
countDownLatch协调子线程
- CountDownLatch、CyclicBarrier和Semaphore区别;
CyclicBarrier让多线程齐步走
让多线程同时做某些事;
提升Java性能的基本方法
不要在循环条件中计算;
尽可能把变量、方法声明为final static类型;
缩小变量的作用范围;
频繁字符串操作使用StringBuffer或StringBuilder;
使用非线性检索;
覆写Exception的fillInStackTrace方法,耗时,看情况,没太多必要;
不建立冗余对象;
若非必要,不要克隆对象
new做了优化;
推荐使用”望闻问切”的方式诊断性能
望:观察现象;
闻:团队的技术能力、氛围,习惯、擅长;
问:讨论;
切:分析问题;
定义性能衡量标准
解决首要系统性能问题
调整jvm参数提升性能
JVM调优总结 -Xms -Xmx -Xmn -Xss;
性能是个大“咕咚”
没有慢的系统,只有不满足业务的系统;
没有慢的系统,只有架构不良的系统;
没有慢的系统,只有懒惰的技术人员;
没有慢的系统,只有不愿意投入的系统;
怀疑精神;
大胆采用开源工具
推荐使用Guava扩展工具包
看情况吧,有需要,可以用,没有需求,就拉倒吧;
Apache扩展包
推荐使用Joda日期时间扩展包
可以选择多种Collections扩展
提倡良好的代码风格
见过几百行代码的方法,看的疯了;
不要完全依靠单元测试来发现问题
单元测试不可能测试所有场景:
正常场景;
边界场景;
异常场景;
单元测试没问题,可能全流程测试会出问题;
部分代码无测试,尤其是多线程环境的测试;
单元测试验证的是开发的想法,万一要是错的了,那不就挂了;
这个标题感觉改成不要相信测试最好,真实环境让你想吐;
让注释正确、清晰、简洁
让接口的职责保持单一
增强类的可替换性
依赖抽象而不是实现
抛弃7条不良的编码习惯
自由风格的代码;
不适用抽象的代码;
彰显个性的代码;
死代码;
冗余代码;
自以为是的代码;
见过最差的,日志居然用sysout打印,想骂人的感觉;
以技术员自律而不是工人
不为工作,爱你的工作;
总结:
1. 刚开始看,不像是国人写的,老外倒是喜欢写这种类型的书,感谢作者;
2. 泛型和注解部分写的不错;
3. 书中的坑,好多都是你用到时一不小心就进去了,所以用你不常用东西时,一定要先了解下,这是看这本书最重要的体会了;
不要在常量和变量中出现易混淆的字母
包名全小写,类名首字母全大写,常量全大写下划线分割,变量驼峰;
字母l作为长整形标志大写L;
莫让常量蜕变成变量
常量final staic,一般不会,主要是值常量的值不要通过计算获取值,值应该在编译期确认,不要在运行期更改;
三元操作符的类型务必一致
– 不一致会做转换,不管怎么转换,保持一致就行;
避免带有变长参数的方法重载
重载的话,调用时不一定是你想要那个方法;
别让null值和空值威胁到变长方法
直接传递null或空值会让编译器区分不了调用的是哪个变长方法;
覆写变长方法也循规蹈矩
覆写满足的条件:
不能缩小访问权限;
参数列表与重写方法相同(类型、数量、显示形式);
返回类型相同或是其子类;
不能抛出新的异常或超出父类范围的异常,可以缩小或者不抛;
覆写变长方法参数列表必须完全一致;
警惕自增的陷阱
java中count = count++等价于mockAdd(int count){int temp=count; count=count+1;return temp;};
c++中count=count++会自增;
不要让旧语法困扰你
主要是java保有的一些关键字,如goto;
抛弃不用;
少用静态导入
不使用*通配符导入;
方法名是否具有明确清晰的意义;
感觉就是导入的常量类和常量一定要具有含义清晰,不能混淆;
不要在本类中覆盖静态导入的变量和方法
养成良好习惯,显示声明UID
实现Serializable接口的类,serialVersionUID要生成;
避免用序列化类在构造函数中为不变量赋值
序列化类中,不使用构造函数为final变量赋值;
基本类型,数组或简单对象(不通过new);
避免为final变量复杂赋值
反序列化时final变量在以下情况下不会被重新赋值:
通过构造函数赋值;
通过方法返回值赋值;
final修饰的属性不是基本类型;
使用序列化类的私有方法巧妙解决部分属性持久化问题
defaultWriteObject(),defaultReadObject(),writeXX和readXX屏蔽某些字段的序列化;
不要这个,基本不会用到;
break万万不可忘
易变业务使用脚本语言编写
之前工作中有个这样的需求,10几种类型根据公式计算不同生失效时间,公式易变,当时想用js,找了好久都没找到好用的,后来放弃了;
如果能找到适合的脚本engine,那就用吧;
慎用动态编译
避免instanceof非预期结果
instanceof只能用于对象的判断,基本类型不行;
左操作数为null,直接返回false;
断言绝对不是鸡肋
在spring源码中n多使用断言的地方,感觉只是辅助注释的作用;
想用就用,不想用就算;
不要只替换一个类
如果你用ide的话,基本不会有这个问题;
发布时,禁止类文件替换,整体发布。常量类不要私自替换,因为常量会被预编译到引用的类中,会导致私自替换的不起作用;
用偶判断,不用奇判断
奇数判断,负数有问题
用整数类型处理货币
用什么整形,直接BigDecimal;
不要让类型默默转换
基本类型向包裹类型转换时,使用主动声明方式;
long想Long转换:1L*X;
边界
单元测试时,边界测试要认真
四舍五入
第一次听说看见四舍五入还有这么多说法,服了,不过如果真有用到的地方一定要跟业务确认清楚;
RoundingMode;
提防包装类型的null值
包装类型参入运算时,做null值校验;
谨慎包装类型的大小比较
==比较对象引用,>或<使用响应的value()方法;
使用相应的compareTo;
优先使用整形池
valueOf生成的包装实例可以显著提供空间和时间性能;
Integer和Long的会缓存-128到127之间的对象,范围外会new,Double和Float会new;
优先选择基本类型
基本类型可以先加宽,再转变成对应的包装类型,但是不能直接转变成宽的包装类型;
不要随机设置随机种子
随机数和种子的关系:
种子不同,产生不同的随机数;
种子相同,即使实例不同也产生相同的随机数;
非必要,不要设置种子;
接口中不要存在实现代码
静态变量一定要先声明后赋值
变量赋值分2步:先分配空间后赋值,如果先赋值后声明的话,就可能后声明的赋值覆盖之前的赋值;
不要覆写静态方法
实例对象有2个类型:
表面类型:声明时的类型
和实际类型,对象产生时的类型
非静态方法根据实际类型来执行;
静态方法一般是通过类名访问,也可以通过对象访问,当通过对象调用静态方法时,会通过对象的表面类型查找入口执行,又是一个第一次听说的东西;
构造函数尽量简化
避免在构造函数中初始化其他类
跟34对应,构造函数简化,然后提供其他初始化方法,spring中学会的;
使用构造代码块精炼程序
直接{}括起来的代码片段,会在每个构造函数中调用;
建议不要用;
构造代码块会想你所想
构造代码库在super,this调用的情况下也只会调用一次;
了解就行,非必要使用
使用静态内部类提供封装性
使用匿名类的构造函数
匿名类的构造函数很特殊
让多重继承称为现实
外部类继承一个,内部类再继承另一个;
让工具类不可实例化
private 构造函数,阻止不了反射,实在不行就构造抛异常;
避免对象的浅拷贝
推荐使用序列化实现对象的拷贝
覆写equals方法时不要识别不出自己
对String做trim
这个要注意,好多接收外部数据什么的,都需要做trim处理;
equals应该考虑null值情景
判断null值情况
在equals中使用getClass进行类型判断
使用getClass进行类型判断,不要使用Instanceof,主要是防止继承情况下的判断;
这个还真没注意,下次要小心了;
覆写equals方法必须覆盖hashCode方法
推荐覆写toString方法
使用package-info类为包服务
很少用到,spring源码中看到,用这个给包做注释用的情况
作用:
声明友好类和保内访问常量;
为在包上标注注解提供便利;
包注释说明;
不要主动进行垃圾回收
推荐使用String直接量赋值
常量池;
注意方法传递的参数要求
replaceAll传递的第一参数是正则,我去,真没在意这个,下次小心;
正确使用String,StringBuffer、StringBuilder
一般情况String,频繁操作后面2个,单线程StringBuilder,线程安全StringBuffer;
注意字符串的位置
加号表达式中,String字符串具有最高优先级;
对于运算符优先级有疑问的,直接括号省事;
自由选择字符串拼接方法
加号,concat或append,耗时依次减少;
推荐在复杂字符串操作中使用正则表达式
强烈建议使用UTF编码
编码是开发永远的噩梦;
对字符串排序持一种宽容的心态
Collator中文排序,gb2312差不多可以解决,复杂的就找开源的或自己实现吧;
性能考虑,数组是首选
性能要求高的场景中使用数组替代集合;
若有必要,使用变长数组
主要是初始定长,后期校验扩容
警惕数组的浅拷贝
Arrays.copyOf产生的是一个浅拷贝,基本类型拷贝值,其他拷贝引用地址;
场景明确下,为集合指定初始容量
多种最值算法,适时选择
自己实现;
先排序,后取值:Arrays.sort();
避开基本类型数组转换list陷阱
基本类型不能泛型话;
Arrays.asList()参数不能使用原始类型;
asList产生的list对象不可更改
产生的list是一个静态内部类;
不能的列表选择不同的遍历方法
ArrayList实现RandomAcess随机存取接口,使用for循环更好,而不是foreach;
频繁插入和删除使用LinkedList
对比ArrayList,想想数据结构就明白了;
列表相等只需关心元素数据
在AbstractList中实现元素和长度比较
子列表只是原列表的一个视图
subList返回子列表;
所有对subList产生对象的操作作用于原list;
推荐使用subList处理局部列表
生成子列表后不要再操作原列表
会异常;
使用Comparator排序
不推荐使用binarySerach对列表进行检索
二分查找建立在基本有序的情况才行;
实现RandomAccess或数据量小于5K进行二分查找,否则顺序查找;
集合中元素必须做到compareTo和equals方法
集合运算时使用更优雅的方式
并集addAll
交集retainAll
差集removeAll
使用suffle打乱列表
collections.shuffle();
减少hashmap中元素的数量
主要是扩容的时候,可能会内部不够用;
集合中hash码不要重复
不重复最好,重复也无所谓,不用关心;
多线程使用Vector或hashTable
非稳定排序推荐使用List
treeset适用于不变量的数据集合排序;
在处理过程中可能会重新排序的,可以使用list自行排序;
集合家族
list
set
map
queue
数组
工具类:Arrays和反射类Array,collections
扩展类:commons和google的collections
推荐使用枚举定义常量
不太喜欢这种;
使用构造函数协助描述枚举项
使用枚举常量时,小心switch带来的空值异常
在switch的default代码块中增加AssertionError错误
如果使用枚举做switch就不应该走到default;
枚举使用valueOf前必须进行校验
枚举实现工厂模式
枚举项的数量限制在64个以内
小心注解继承
Inherit
枚举和注解结合使用威力更大
注解的值可以使用枚举来定义;
注意@Override不同版本的区别
1.5版本的接口实现,不需要override,1.6以上没问题,注意下就可以;
java的泛型是类型擦除的
泛型参数编译后会被清除;
不能初始化泛型参数和数组
类型擦除,无法获取具体参数
强制声明泛型的实际类型
不同场景使用不同的泛型通配符
读操作? extend限定泛型上界;
写操作? super限定泛型下界;
警惕泛型是不能协变和逆变的
协变:窄类型替换宽类型;
逆变:宽类型替换窄类型;
建议采用的顺序是List\List
if(!method.isAccessible()){ method.setAccessible(true); } method.invoke(obj, args);
使用forName加载类文件
有个参数设置static方法是否调用,默认加载static代码块;
动态加载不适合数组
数组用的反射跟普通的不一样;
动态代码可以使代理模式更灵活
反射增加装饰模式的普适性
反射让模板方法模式更强大
不需要太多关注反射效率
如果有需求要用,就不要过分关注;
提倡异常封装
我们项目很少用,都是用封装errorcode,下次最起码保证自己的代码部分用到;
/** spring 中看到这种处理方式,感觉适合流程无关联性的业务*/ Class MyException extends Exception{ private List<Throwable> causes = new ArrayList<Throwable>(); public MyException(){ } ...get set ... }
采用异常链传递异常
异常需要封装和传递,不同视角展示不同提示;
受检异常尽可能转为非受检异常
不要在finally块中处理返回值return
finally返回会覆盖try块中的return值;
屏蔽异常;
只做收尾;
不要在构造函数中抛出异常
这个还真没见过这样处理的;
使用Throwable获得栈信息
异常只为异常服务
还真这么干过,正常业务有问题,为了省事直接抛出异常处理;
多使用异常,性能问题放一边
不推荐覆写start方法
不覆写Thread类的start方法
启动线程前stop方法是不可靠的
不适用stop方法停止线程
线程优先级只是用3个等级
差距大,才有体现;
使用线程异常处理器提升系统可靠性
123.volatile不能保证数据同步
异步运算考虑使用callable接口
有返回值和异常处理;
优先选择线程池
选择不同的线程池
Lock和synchronized是不一样的
预防死锁
适当设置队列长度
阻塞队列的长度是固定的;
countDownLatch协调子线程
- CountDownLatch、CyclicBarrier和Semaphore区别;
CyclicBarrier让多线程齐步走
让多线程同时做某些事;
提升Java性能的基本方法
不要在循环条件中计算;
尽可能把变量、方法声明为final static类型;
缩小变量的作用范围;
频繁字符串操作使用StringBuffer或StringBuilder;
使用非线性检索;
覆写Exception的fillInStackTrace方法,耗时,看情况,没太多必要;
不建立冗余对象;
若非必要,不要克隆对象
new做了优化;
推荐使用”望闻问切”的方式诊断性能
望:观察现象;
闻:团队的技术能力、氛围,习惯、擅长;
问:讨论;
切:分析问题;
定义性能衡量标准
解决首要系统性能问题
调整jvm参数提升性能
JVM调优总结 -Xms -Xmx -Xmn -Xss;
性能是个大“咕咚”
没有慢的系统,只有不满足业务的系统;
没有慢的系统,只有架构不良的系统;
没有慢的系统,只有懒惰的技术人员;
没有慢的系统,只有不愿意投入的系统;
怀疑精神;
大胆采用开源工具
推荐使用Guava扩展工具包
看情况吧,有需要,可以用,没有需求,就拉倒吧;
Apache扩展包
推荐使用Joda日期时间扩展包
可以选择多种Collections扩展
提倡良好的代码风格
见过几百行代码的方法,看的疯了;
不要完全依靠单元测试来发现问题
单元测试不可能测试所有场景:
正常场景;
边界场景;
异常场景;
单元测试没问题,可能全流程测试会出问题;
部分代码无测试,尤其是多线程环境的测试;
单元测试验证的是开发的想法,万一要是错的了,那不就挂了;
这个标题感觉改成不要相信测试最好,真实环境让你想吐;
让注释正确、清晰、简洁
让接口的职责保持单一
增强类的可替换性
依赖抽象而不是实现
抛弃7条不良的编码习惯
自由风格的代码;
不适用抽象的代码;
彰显个性的代码;
死代码;
冗余代码;
自以为是的代码;
见过最差的,日志居然用sysout打印,想骂人的感觉;
以技术员自律而不是工人
不为工作,爱你的工作;
总结:
1. 刚开始看,不像是国人写的,老外倒是喜欢写这种类型的书,感谢作者;
2. 泛型和注解部分写的不错;
3. 书中的坑,好多都是你用到时一不小心就进去了,所以用你不常用东西时,一定要先了解下,这是看这本书最重要的体会了;
相关文章推荐
- 读-秦小波-编写高质量代码:改善java程序的151个建议
- 《编写高质量代码改善Java程序的151个建议》学习笔记 第6章 枚举和注解
- [编写高质量代码:改善java程序的151个建议]建议38-41
- [编写高质量代码:改善java程序的151个建议]建议55:注意字符串的位置
- [编写高质量代码:改善java程序的151个建议]建议67 不同的列表选择不同的遍历方法
- 编写高质量代码:改善Java程序的151个建议 勘误 [不断更新]
- 编写高质量代码:改善Java程序的151个建议
- [编写高质量代码:改善java程序的151个建议]建议64 多种最值算法
- [编写高质量代码:改善java程序的151个建议]建议58 强烈建议使用UTF-8编码
- [编写高质量代码:改善java程序的151个建议]建议62 警惕数组的浅拷贝
- [编写高质量代码:改善java程序的151个建议]建议33:不要覆写静态方法
- [编写高质量代码:改善java程序的151个建议]建议36,37:构造代码块
- [编写高质量代码:改善java程序的151个建议]建议53 注意方法中传递的参数要求
- [编写高质量代码:改善java程序的151个建议]建议35:不要在类中初始化其他类
- 编写高质量代码++改善Java程序的151个建议
- 编写高质量代码:改善Java程序的151个建议 (第3章 类、对象及方法)
- [编写高质量代码:改善java程序的151个建议]建议63 在明确的场景下,为集合指定初始容量
- [编写高质量代码:改善java程序的151个建议]建议31-在接口中不要存在实现代码