我原本是一个医学生,但出于很多考虑,我决定转行程序员。相信应该也有蛮多人和我一样,在为自己喜欢的事业奋斗着。突发奇想,想记录下每天一点自己在为Java面试所作的准备,记录下自己觉得值得记录的题目。这是一个系列,我会一直坚持下去。
1. 线程局部变量的理解
线程局部变量是局限于线程内部的变量,属于线程自身所有。使用ThreadLocal来支持。ThreadLocal是在线程里面维护了一个ThreadLocalMap将数据隔离,达到数据不共享的效果。
2. Thread.sleep(0)的作用是什么?
由于java采用的是抢占式的线程调度算法,有可能出现某个线程常常获得CPU控制权的情况。为了让那些线程优先级比较低的线程也能获得CPU的控制权,可以使用Thread.sleep(0)手动触发一次操作系统分配时间片的操作。
3. 简述CAS操作
即Compare And Swap;有三个操作数:内存值V、旧的预期值A,要修改的值B。当且仅当A和V相同,才会将内存值修改为B并返回true,否则只返回false。要和volatile变量结合使用,保证变量是主内存最新的那个值,否则不好成功。
4. volatile变量修饰符的作用
1)修饰long或者double变量,使其能按原子类型来读写。long和double变量是64位宽,因此对这类变量的读写第一次是32位,需要两次。这个过程不是原子的。而volatile修饰的话,可以使其按原子操作进行。
2)该修饰符还可以提供读写屏障。写一个 volatile 变量之前,Java 内存模型会插入一个写屏障(write barrier),读一个 volatile 变量之前,会插入一个读屏障。
5. ArrayList和LinkedList的区别?
最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。ArrayList优势在于查找快,但插入删除慢,LinkedList则相反。
6. HashMap的实现原理
HashMap在往其中添加值的时候,要重新计算hash值,如果没发生冲突,可直接加入。否则就要在冲突的地方形成一个链表。新加入的在链头。在JDK1.8之后,当冲突达到8个之后,使用红黑树。
7. Fail-fast和Fail-safe机制的区别
java.util包中的所有集合类都被设计为fail->fast的,而java.util.concurrent中的集合类都为fail-safe的。当检测到正在遍历的集合的结构被改变时,Fail-fast迭代器抛出ConcurrentModificationException,而fail-safe迭代器从不抛出ConcurrentModificationException。
8. throw和throws的区别?
throw用于主动抛出java.lang.Throwable 类的一个实例化对象,意思是说你可以通过关键字 throw 抛出一个 Error 或者 一个Exception,而throws 的作用是作为方法声明和签名的一部分,方法被抛出相应的异常以便调用者能处理。Java 中,任何未处理的受检查异常强制在 throws 子句中声明。
9. Java 中,Serializable与 Externalizable 的区别
Serializable接口是一个可以用来标记类序列化的标记接口,没有其他特殊的内容。但Externalizable 可以为类添加复杂的操作,更加具有实用性。
10. 简述堆和栈的区别
VM 中堆和栈属于不同的内存区域,使用目的也不同。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。