《Effective JAVA》完结篇
最后一篇
第八章,通用程序设计
1. 将局部变量的作用域最小化;
2. for_each循环优先于传统的for循环
使用传统for循环更容易出错,特别是在嵌套循环中:
一般来说,只能用for而无法用for-each的情况有3种:
a. 具有破坏性的过滤:在循环过程中如果会改变容器大小size,那么for-each就会失效
b. 替换:由于for-each仅仅是引用的拷贝,因此修改这个引用对于容器中原本的值是无效的,所以这个使用只能使用iterator进行传统遍历修改
c. 并行迭代:如果需要通过所迭代的下标控制另外的容器的迭代下标,这个时候需要使用传统for循环
3. 有需要的情况下,区分double和float
不要将float或double用于需要精确结果的计算。
4. 基本类型优先于装箱类型
基本类型和装箱的基本类型主要有3个区别:
a.基本类型只有值,而装箱类型是一个引用,使用=所对比的是引用的地址
b.基本数据类型只有功能完备的值,而装箱类型有可能为null
c.基本类型比装箱类型更加节省时间和空间
5. 优先使用接口而非类来引用对象
6. 谨慎地进行优化,
必须在设计时考虑性能问题;使用性能剖析工具探测性能瓶颈
第九章:异常
1. 只针对异常的情况才使用异常
例外是为特殊情况而设计的。不要用它们来进行普通的控制流,不要写那些强迫别人这样做的api。
2. 对可恢复的情况使用受检情况,对编程错误使用运行时异常
3.避免不必要地使用受检的异常
4.优先使用标准的异常
易学易用,它与已熟悉的习惯用法一致
可读性好,不会出现不熟悉的异常
异常类越少,意味着内存印迹就越少,装载这些类的时间开销也越少。
5.抛出与抽象相对应的异常
6每个方法抛出的异常都要有文档
7. 在细节消息中包含能捕获失败的信息
8. 努力使失败保持原子性
9.不要忽略异常
如果忽略了现在的异常,又可能在新加入的代码中产生了同样的但是不能忽略的异常,程序则很可能在和该方法毫不相关的地方发生异常,这样的异常十分难以排查
第十章:并发
1.同步访问共享的可变数据
2.避免过度同步
为了避免死锁和数据破坏,千万不要从同步区域内调用外来的方法。更为一般的将,要尽量限制同步区域内部的工作量。当你设计一个可变的类的时候,要考虑一下他们是否应该自己完成同步操作。在现在这个多核的时代,这比永远不要多度同步来的更重要,只有当你有足够的理由一定要在内部同步类的时候,才可以这样做,同时还应该将这个决定清楚的写在文档中
3. executor和task优先于线程
a.当作为一个轻载服务器的时候,可以使用Executors.newCachedThreadPool
b.如果在一个大型负载产品中,最好使用executors.newFixedThreadPool,因为它带有排队机制
c.更加灵活的线程池:ThreadPoolExecutor
d.不仅应该避免编写自己的工作队列,而且通常应该避免直接使用线程
4. 并发工具优先于wait和notify
总是使用while循环模式来调用wait方法,永远不要在循环的外面调用wait
5.线程安全性的文档化
6.慎用延迟初始化
7.不要依赖于线程调度器
a.任何依赖于线程调度程序进行正确性或性能的程序都可能是不可移植的。
b.编写一个健壮的、响应性的、可移植的程序的最好方法是确保可运行线程的平均数量不会比处理器的数量大得多。这就使得线程调度程序几乎没有选择:它只是运行可运行的线程,直到它们不再运行。
c.保持可运行线程数量尽可能少的主要方法是,让每个线程做些有意义的工作,然后等待更多有意义工作,如果线程没有在做有意义的工作,就不应该运行
d.线程不应该一直处于忙等的状态,即反复地检查一个共享对象,以等待某些事情的发生。忙等会极大地增加处理器的负担,降低了同一机器上其他进行可以完成的工作量。
8.避免使用线程组
第十一章 序列化
1.谨慎地实现Serializable接口
2.考虑使用自定义的序列化形式
3.保护性地编写readObject方法
4.对于实例控制,枚举类型优先于readResolve
5.考虑用序列化***代替序列化实例
《Effective JAVA》已经更完,说实话,这本书的难度是有的,但是好书绝对是一本好书,是一本关于JAVA的高级编程规范与技巧的书。
感谢牛客给此次机会!
#Java#
查看6道真题和解析