大话java面试-java基础-2

1、AtomicLong和LongAdder的区别,Atomic解决ABA问题

LongAdder更高效并发高的情况下性能更好,内部采用cell分段cas。参考

AtomicStampedReference内部维护一个版本号来解决ABA问题。

2、synchronized修饰方法块和修饰静态方法,synchronized和volatile区别

synchronized修饰非静态方法或者方法块时,锁定的是当前的对象。synchronized修饰静态方法时,锁定的类的Class对象、即类锁。synchronized可以保证原子性和内存可见性,volatile保证的是内存可见性,防止cpu的内存指令重排。可见性是指读取cpu的内存缓存的值的时候都从主内存用load命令重新读,每次写都写到缓存后立即用store命令写到主内存。

3、final修饰的类不可被继承,修饰的方法不能重写,修饰的变量不能修改。引用类型如map list用final修改后不能重新初始化但是可以修改值,如果想使用不可变的map可以用Collections.unmodifiableMap().方法传过来的值不想在方法中被修改,可以用public void printx(final int x)。

4、ThreadLocal原理以及应用场景

ThreadLocal内部实现了ThreadLocalMap,线程有一个threadLocals属性引用当前ThreadLocalMap,key为当前ThreadLocal,value为要存放的对象。

内存泄漏:内部使用的是弱引用,当调用set get remove方法的时候会被动的清除value为null的,如果不在调用了方法就会回收不了就会造成内存泄漏,所以最好用完后自己remove删除。

应用场景:在http请求中,如果需要多次使用HttpRequest里的东西原来都是逐层传递,考虑在Filter里把HttpRequest放到ThreadLocal,这样可以在任何地方使用而不用传到其他层,在filter使用完毕后remove即可。

详细说明

5、同步集合

ArrayList->Vector->CopyOnWriteArrayList

HashMap->HashTable->ConcurrentHashMap

HashSet->CopyOnWriteArraySet

TreeSet->ConcurrentSkipListSet

TreeMap->ConcurrentSkipListMap

6、CountDownLatch、CyclicBarrier和Semaphore区别联系使用场景

CountDownLatch一个主线程等待其它线程,countDown方法不会阻塞而逝统一阻塞到await方法,只能使用一次。CyclicBarrier是多个线程统一在调用await方法后阻塞,barrier满足条件后统一放行,可以复用。Semaphore类似于钥匙,acquire方法申请,release方法释放。

场景:一群人在操场上分跑道测试成绩,Semaphore就是限制每一波的人数不能大于跑道数,一个学生开始跑就申请一个跑道,结束就释放一个跑道。CyclicBarrier就是让大家都阻塞到开始的位置,当跑道满了统一开始跑。CountDownLatch就是等一波学生都跑完了,老师才能组织下一个活动。

7、HashMap1.8的优化点

链表长度大于8使用红黑树,查询时间复杂度为O(logN)

Node结点会保存key的hashcode高位运算以后的值,扩容时不用重新计算,直接取hash然后进行位运算

扩容时链表从尾部插入,1.7从头插入导致链表反转多线程引发死循环,1.8不会死循环但是会丢失数据

8、ConcurrentHashMap1.71.8区别

1.7采用Segment数组和HashEntry数组和链表,Segment继承自ReentrantLock,tryLock获取锁,获取不到就循环一个与处理器核数有关系的次数执行tryLock。

先采用不加锁的方式,连续计算元素的个数,最多计算3次:1、如果前后两次计算结果相同,则说明计算出来的元素个数是准确的;2、如果前后两次计算结果都不同,则给每个Segment进行加锁,再计算一次元素的个数;

1.8采用Node数组、链表、红黑树,使用synchronized锁锁定Node。当链表长度超过8需要转换为红黑树时才会判断当前是否需要扩容。扩容时用CAS修改每个Node的标示来实现多线程复制,链表或红黑树都需要组装好两个链表,然后复制到对应的位置。

baseCount记录元素的个数,如果CAS修改baseCount失败,使用CAS记录到CounterCell数组中,累加baseCount和CounterCell数组中的数量,即可得到元素的总个数

你可能感兴趣的:(大话java面试-java基础-2)