1.异常1.1.代码应该仅在发生意料之外的事情时抛出异常1.1.1.防御性编程性能好1.2.异常的处理成本未必很高1.2.1.应该只在适当的时候使用1.2.2.栈越深,处理异常的成本就越高1.3.对于频繁创建的系统异常,JVM会优化获取栈轨迹的性能开销1.4.在异常中禁用栈轨迹有时可以提高性能,但会丢失一些关键信息2.日志2.1.一直开启GC日志2.2.基本原则2.2.1.在日志的数据和日志的级别之间找到平衡2.2.2.使用细粒度的日志记录器2.2.2.1.开启过多的日志通常会改变生产环境,使原来的问题无法显现2.2.3.即使没有开启日志,也很容易在无意间写出具有副作用的日志代码2.3.应该包含大量日志以帮助用户找出问题所在,但日志默认应该是关闭的2.3.1.如果日志记录器的参数需要调用方法或者分配对象,那么不要忘记在调用记录器之前检验日志级别3.Java集合API3.1.根据算法选择集合类是至关重要的3.2.LinkedList不适合搜索3.3.HashMap用于访问一段随机的数据3.4.TreeMap用于数据需要保持有序3.5.HashMap是根据键值查找条目的最快方法3.6.ArrayList用于数据通过索引访问3.6.1.不适用将数据插入到数组中3.7.集合的大小会对性能产生很大的影响3.7.1.太大,会拖慢垃圾回收器的速度3.7.2.太小,会需要大量的复制操作和大小调整操作3.8.使用同步集合,降低由此带来的性能影响3.8.1.是否值得花费时间和精力为了线程安全而面向未来编程4.Lambda和匿名类4.1.Lambda并不是通过匿名类实现的4.2.Lambda的代码会创建一个静态方法4.2.1.该方法通过一个特殊的帮助类来调用4.3.匿名类是真正的Java类4.3.1.它有单独的类文件,并会通过类加载器加载4.3.2.启动有很多匿名类(相对于有很多Lambda)的应用程序,可能会出现更大的差异4.4.性能几乎没有区别4.4.1.在类加载很重要的环境中,Lambda会稍快一些5.流和过滤器5.1.流最重要的性能优势5.1.1.它们被实现为延迟处理的数据结构5.1.2.延迟处理的过滤器实现可以在完成需要做的事情后结束处理,这样处理的数据更少5.2.过滤器比迭代器快得多的原因5.2.1.它们可以进行算法上的优化5.3.即使处理整个数据集,单个过滤器的性能也会略优于迭代器5.4.多个过滤器是有开销的,要确保编写性能良好的过滤器6.对象序列化6.1.一种将对象的二进制状态写出来,以便之后重新创建的方法6.2.数据的序列化可能是很大的性能瓶颈6.3.降低对象序列化成本的方法是序列化更少的数据6.3.1.将字段标记为transient来做到,标记后它们默认不会被序列化6.3.2.可以让序列化更快,并减少需要传输的数据量6.4.优化序列化往往就是对对象引用进行特殊处理6.4.1.做得正确,序列化代码的性能会大幅提高6.4.2.做得不正确,就会引入不易察觉的bug6.4.3.避免写出重复的对象引用6.5.压缩序列化数据,传输速度会更快6.5.1.压缩序列化数据然后延迟解压会非常有用,特别是当目标是节省CPU内存而不是节省CPU时间的时候6.5.2.在快速的网络上,压缩数据的时间很容易比传输更少的数据所节省的时间长,在较慢的网络上,情况可能正好相反6.6.实现Externalizable接口6.6.1.当writeObject()方法调用defaultWriteObject()方法时6.6.1.1.Serializable接口会写出非瞬时字段6.6.1.2.Externalizable接口不会写出非瞬时字段6.6.2.Externalizable类必须明确地写出它要传输的所有字段6.6.2.1.不管这些字段是不是瞬时的6.7.即使一个对象的所有字段都是瞬时的,最好还是实现Serializable接口并调用defaultWriteObject()方法6.7.1.会让代码更容易维护6.8.通过writeObject()方法和readObject()方法进行的其他优化可以大幅加快序列化的速度