1、HashMap的源码,实现原理,JDK8中对HashMap做了怎样的优化。
1) HashMap实现Map接口,元素以键值对的方式存储,并且允许使用null 作为key和value,因为HashMap的key不允许重复,所以只能有一个键是 null,并不推荐使用,因为容易出问题并且很难排查。
2)HashMap不能保证放入元素的顺序,所以是无序的,HashMap初始长度16,每次扩充翻倍。
JDK1.7的HashMap是使用数组加链表进行存储,每一个键值对用一个Entry来存储,Entry中还有hash和next属性,hash是key的hash值,next则是指向下一个Entry的指针。HashMap的初始容量是16,即有一个长度为16的数组,用来存储每个Entry链表的头结点。每一个Entry存储的位置是由key.hashCode()%len获得,假设有A,B,C三个键值对并且每个key的hash值对16取模都是1,A先进来就存储在Entry[1],再进来B则B.next=A、Entry[1]=B。C相同。也就是说数组中存储的是最后插入的元素。所以说放入元素是无序的。
JDK1.8的HashMap加入了红黑树,当每个单链表的长度大于阈值(8)时,则将链表转化为红黑树。并且1.8之后,新插入的元素都放在了链表的尾部。
3) HashMap是线程不安全的,可以使用Collections.synchronizedMap()获 取一个线程安全的集合,Collections.synchronizedMap()实际上是定义一个synchronizedMap的内部类,这个内部类实现了Map接口并在方法上加上synchronized关键字。就是操作的HashMap的时候自动添synchronized。
2、HaspMap扩容是怎样扩容的,为什么都是2的N次幂的大小。
1) 如果超过阈值,会自动扩充两倍,然后重新计算HashMap中各个Entry的位置。
2) 都是2的N次幂是因为在新插入操作的时候,位置计算是由(n-1)&hash决定的,(n-1)&hash实际上相当于hash%(n-1),只不过&运算更快速。HashMap中的hash=((h = key.hashCode()) ^ (h >>> 16),hashCode是9位十进制也就是36位二进制。右位移16位,正好是32bit的一半,自己的高半区和低半区做异或,就是为了混合原始哈希码的高位和低位,以此来加大低位的随机性。而且混合后的低位掺杂了高位的部分特征,这样高位的信息也被变相保留下来。这样大多数的hashCode的分布已经很不错了。
3、HashMap,HashTable,ConcurrentHashMap的区别。
HashMap的key和value都可以为空,线程不安全,初始size16,每次扩容翻倍,先插入后扩容,插入后长度达到总数的75%则扩容,计算index(n-1)&hash,迭代器是fail-fast的(在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception)
HashTable的key和value都不能为空,线程不安全,初始size11,每次扩容size=oldSize*2+1,计算index方法 (hash & 0x7FFFFFFF) % tab.length,迭代器不是fail-fast
ConcurrentHashMap线程安全,分段加锁,段内扩容。需锁定整个map时按顺序锁定各个分段,然后按顺序释放锁。
4、极高并发下HashTable和ConcurrentHashMap哪个性能更好,为什么,如何实现的。
ConcurrentHashMap更好,分段锁,HashTable锁整个table。
5、HashMap在高并发下如果没有处理线程安全会有怎样的安全隐患,具体表现是什么。
1)put是会见检查Map容量是否足够,不够则扩充,扩充后会把数组从老的hash表移到新的hash表,多个线程同时同时操作可能会形成循环链表,所以get()时会出现无限循环
2)造成迭代的fail-fast
6、java中四种修饰符的限制范围。
7、Object类中的方法。
hash,finalize,notify,notifyAll,wait....
8、接口和抽象类的区别,注意JDK8的接口可以有实现。
(1)抽象类可以有构造方法,接口中不能有构造方法。
(2)抽象类中可以有普通成员变量,接口中没有普通成员变量
(3)抽象类中可以包含静态方法,接口中不能包含静态方法
(4) 一个类可以实现多个接口,但只能继承一个抽象类。
(5)接口可以被多重实现,抽象类只能被单一继承
(6)如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
9、动态代理的两种方式,以及区别。
10、Java序列化的方式。
11、传值和传引用的区别,Java是怎么样的,有没有传值引用。
12、一个ArrayList在循环过程中删除,会不会出问题,为什么。
会遗漏元素,例如删除了a[2],删除后a[3]就到了a[2]的位置上,继续遍历是从a[3]开始,那么如果之前的a[3]符合删除条件也不会被删除。反向遍历删除是可以的,用迭代器删除单线程可以多线程有可能触发fail-fast。
2JVM
1、JVM的内存结构。
2、JVM方法栈的工作过程,方法栈和本地方法栈有什么区别。
3、JVM的栈中引用如何和堆中的对象产生关联。
4、可以了解一下逃逸分析技术。
5、GC的常见算法,CMS以及G1的垃圾回收过程,CMS的各个阶段哪两个是Stop the world的,CMS会不会产生碎片,G1的优势。
6、标记清除和标记整理算法的理解以及优缺点。
7、eden survivor区的比例,为什么是这个比例,eden survivor的工作过程。
8、JVM如何判断一个对象是否该被GC,可以视为root的都有哪几种类型。
9、强软弱虚引用的区别以及GC对他们执行怎样的操作。
10、Java是否可以GC直接内存。
11、Java类加载的过程。
12、双亲委派模型的过程以及优势。
13、常用的JVM调优参数。
14、dump文件的分析。
15、Java有没有主动触发GC的方式(没有)。
3数据结构与算法
1、B+树
2、快速排序,堆排序,插入排序(八大排序算法)
3、一致性Hash算法,一致性Hash算法的应用
4多线程
1、Java实现多线程有哪几种方式。
2、Callable和Future的了解。
3、线程池的参数有哪些,在线程池创建一个线程的过程。
4、volitile关键字的作用,原理。
5、synchronized关键字的用法,优缺点。
6、Lock接口有哪些实现类,使用场景是什么。
7、可重入锁的用处及实现原理,写时复制的过程,读写锁,分段锁(ConcurrentHashMap中的segment)。
8、悲观锁,乐观锁,优缺点,CAS有什么缺陷,该如何解决。
9、ABC三个线程如何保证顺序执行。
10、线程的状态都有哪些。
11、sleep和wait的区别。
12、notify和notifyall的区别。
13、ThreadLocal的了解,实现原理。
5分布式
1、分布式事务的控制。分布式锁如何设计。
2、分布式session如何设计。
3、dubbo的组件有哪些,各有什么作用。
4、zookeeper的负载均衡算法有哪些。
5、dubbo是如何利用接口就可以通信的。
6框架相关
1、SpringMVC的Controller是如何将参数和前端传来的数据一一对应的。
2、Mybatis如何找到指定的Mapper的,如何完成查询的。
3、Quartz是如何完成定时任务的。自定义注解的实现。
4、Spring使用了哪些设计模式。Spring的IOC有什么优势。
5、Spring如何维护它拥有的bean。
6、一些较新的东西JDK8的新特性,流的概念及优势,为什么有这种优势。
7、区块链了解如何设计双11交易总额面板,要做到高并发高可用
原文:https://www.cnblogs.com/ryan304/p/11578691.html