1.你常用的JDK中的集合都有哪些?你在项目中都是怎么用的
===============================================================
2.你了解hashMap的底层原理么?你说一下
===============================================================
3.ConcurrentHashMap的底层原理是什么
===============================================================
4.hashMap、hashTable和ConcurrentHashMap的区别是什么
1》hashMap 初始化大小16、每次扩充2n、若给定初始化大小,实际创建2的幂次方大小、线程不安全
2》hashTable初始化大小11、每次扩充2n+1、若给定初始化大小,就创建给定大小、线程安全、相比hashMap,所有公开方法加了synchronized关键字,所以线程安全,但是效率低下,因为是给整体加锁
3》concurrentHashMap 初始化大小,也就是默认并发度16、若给定初始化大小,实际创建2的幂次方大小、线程安全、并且是分段锁,并发效率比HashTable高
===============================================================
5.HashMap在做put和get操作的时候,是怎么样的过程
1》put操作,根据key的hashCode值,做取模运算,计算出本次put在数组的下标,然后放入对应位置,如果已经有值,则存入LinkedList链表最后
2》get操作,根据key的hashCode值,计算出存储位置,然后在链表中,根据hashCode值进行equals查找。
===============================================================
6.如果一定要在多线程下使用hashMap的话会出现什么问题
可能会带来循环链表,导致死循环致使线程挂掉。
===============================================================
7.为什么多线程下要选择ConcurrentHashMap而不选择hashTable,或者为什么不用synchronized或者Lock?
并发环境下,建议使用Java.util.concurrent包中的ConcurrentHashMap以保证线程安全。
至于HashTable,它并未使用分段锁,而是锁住整个数组,高并发环境下效率非常的低,会导致大量线程等待。
同样的,Synchronized关键字、Lock性能都不如分段锁实现的ConcurrentHashMap。
===============================================================
8.List你都用过哪些?分别都是什么样的特点
1》ArrayList 用的最多,是基于数组的数据结构,因为存储的地址是连续的,所以在查询起来速度快。但是在插入和删除的时候,会因为移动其他的元素,所以速度要慢;
2》LinkedList是基于链表的数据结构,链表的存储地址是不连续的,是通过指针指向下一个元素的,所以在查找起来比较慢。在插入和删除操作,不需要移动其他元素,所以速度快。
3》Vector 和ArrayList基本一样,除了所有的公开方法是synchronized修饰的,所以他是同步的,是线程安全的;相对的在性能上要劣势于ArrayList。在扩容的时候,Vector是翻倍的,而ArrayList是扩容50%,所以更有利于节省空间。
===============================================================
9.HashSet你用过么?有什么特点?
1》底层就是HashMap,map的value给成一个final值,用key做hashSet使用。
2》因为hashMap中存入null值,会默认将值放在hash表的第0个位置,所以hashSet中允许有null,但有且最多只能存一个空值
3》不允许有重复值,因为add进去也就是执行的hashMap的put操作,根据hashCode计算了位置,存放,如果重复就替换,所以不会有重复值出现
4》再一个就是存储顺序和取出顺序不一致,因为根据hashCode计算位置存入,所以要取出值,需要进行迭代
===============================================================
10.对于栈、队列和树状结构、链表有什么了解?
1》栈 数组实现栈
package com.sxd.test; import java.util.Arrays; public class MyStack<E> { private Object[] stack; int top = -1; public MyStack(){ this.stack = new Object[10]; } //判空 public boolean isEmpty(){ return top == 0; } //压栈 public E push(E e){ ensureCapacity(top+1); stack[++top] = e; return e; } //扩容操作 public void ensureCapacity(int size){ int len = this.stack.length; if(size > len){ int newLen = len+10; stack = Arrays.copyOf(stack,newLen); } } //查看栈顶元素 public E peek(){ if(isEmpty()){ return null; } return (E)stack[top]; } //出栈 public E pop(){ E e = peek(); stack[top] = null; top--; return e; } }
View Code
2》
===============================================================
11.TreeMap使用过么?底层是什么样的?对于树的遍历算法你都清楚么?
底层原理: 红黑树
使用情况1:
在API调用之前的拦截器中,进行签名验证的时候,使用过TreeMap.
使用场景是:将request中除了sign之外的所有请求参数,按照字段名ASCII码字典序,从小到大排序,这里使用TreeMap存放所有参数,取出就是有序的