基础知识这种东西,没注意到的永远比想象中多.大部分都是在面试中问到的...
1.static关键字
变量,方法修饰;静态代码块;静态内部类;
静态导入:import static ,静态方法省略类名,直接调用.
2.final关键字
修饰基础数据类型时,表示数值恒定不变,修饰引用类型时,表示指向的引用不变,但引用的具体值确实可以修改的
使用final方法,在一定程度上有可能提高程序效率,将一个方法设成final后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里,编译器会忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理),而是使用方法体内实际代码的副本作为实际调用,避免方法调用时的系统开销,但是,方法体积大时,方法内部的时间抵消了系统开销。通常,只有在代码量非常小或者明确方法不被覆盖时,才将其定义为final.
3.transient关键字
在新建entity时,通常我们会将其进行序列化,常规操作为 implements java.io.Serializable , 但是实体中某些字段属性可能并不需要传输,此时,可以用transient关键进行修饰,则此字段不进行序列化;
另,除开Serializable 接口,Externalizable接口也可实现序列化,通过writeExternal()和readExternal()方法,可以执行一些特殊操作.
4.sleep()与wait()方法
二者都用于线程调度,二者都会释放cpu资源,但是,sleep()不会释放掉cpu的所有权,也就是说对象的锁并没有释放,其他线程仍无法访问这个对象;而wait()会释放掉锁,允许其他线程的访问.
5.常量池
Byte,Short,Integer,Long,Character,Boolean 这五种包装类型,默认[-128,127]间使用常量池;而Float,Double并没有实现常量池;
String类型使用引号创建的对象才会被放进常量池(包括使用+),而使用new创建出来的对象并不会放入常量池中;
String intern()方法,查询当前常量池中是否含有与某字符串equals()的常量,如果有则返回其引用,没有则将自己添加进常量池.
6.volatile
并发时,原子性与可见性作为两个保证安全条件,volatile具有可见性,但不具有原子性;
volatile变量修饰的值被修改时,底层命令带lock前缀,将处理器内存回写到内存,然后根据缓存一致性机制使其他缓存失效,保证可见性.
7.ConcurrentHashMap
hashMap 线程不安全,多线程下使用put()会引起死循环;hashTable效率低下,并发下访问其对象必须竞争同一把锁;
ConcurrentHashMap由可重入锁Segment 与 键值对 HashEntry 组成.ConcurrentHashMap使用锁分段技术保护不同段的数据,避免像hashTable一样并发竞争同一把锁引起的效率问题.
ConcurrentHashMap通过两次hash将元素分布到不同的Segment 上,然后Segment 分段保护其段上数据.
hashTable 在get()数据时也需要加锁,而ConcurrentHashMap的get()并不需要加锁(空值时加锁重读),因为HashEntry 中的值被定义为volatile,能够保持可见性.
ConcurrentHashMap的put()操作需要加锁,先定位到对应的Segment ,然后在Segment 中进行插入.
ConcurrentHashMap的size()并不是单纯的等于所有Segment 的和,计算时,其先进行两次不加锁的计算进行比较,若存在变动,则加锁进行计算.
ConcurrentHashMap 弱一致性.
8.finally块中的语句一定会执行到么?
try之前就return,则并不会执行到;
exit()方式执行,不会被执行到;
finally块的语句在try或catch中的return语句执行之后返回之前执行,finally块中的修改语句不能影响到try或者catch中return已经确定的值,会发生覆盖.