大厂面试解析

ArryaList和 LinkedList

ArrayList 是数组结构  内存在一块  遍历查找很容易,但是删除添加效率低,添加删除需要在添加的index后面arraycpoy  

LinkedList  是节点结构 node , node内部是有pre next和item    添加删除效率高  但是查找效率不高 需要遍历

提高ArrayList的效率 可以用标记,比如删除的时候。。不arraycpoy  只把元素删除 。标记为null

HashMap<key, value>  数据结构 table数组+链表 (Java8是 table数组+链表 /红黑树

hashmap初始长度是16   并且长度只可能是2的幂  大小  因为key的hashcode求模的时候是用与运算的   这样每一位都是1    hashcode|(length-1)    

key-> 其实用到的是key的 hashcode  能快速定位到下标

key->hashcode 求模运算计算得到   int   的值是0-(length-1)  length 是table数组的长度   即把key转成了数组的下标

元素用头插法 不是从尾部添加

第一层根据key的hashcode  直接找到数组的index,无需遍历

第二层根据index  再遍历对应的链表 就找到了

大厂面试解析

 但是可能所有的元素都在一个链表上。那效率就很低了

但是java8为了解决hash碰撞  也就是很多元素都在一个链表上  效率低   不用链表保存相同的index元素 而用了效率更高的红黑树treenode  (每个节点左边的数据都小于这个节点,右边都大于这个节点)

大厂面试解析

 但是红黑树创建相对浮在需要排序旋转

所以java中hashmap中的数组中并不是每一个数据结构都是红黑树,而是index这个链表的长度超过8个的时候才转成红黑树

大厂面试解析

HashMap线程不安全 所以有HashTable线程安全

HashTable比HashMap结构差不多,但是就是方法加了同步锁  sychronized

put和get不能同时进行会阻塞,效率低

ConcurrentHashMap 是基于 hashmap或者hashtable的优化

可能get和put不是同一个链表 ,那就不需要所有的方法都上锁

是在方法内部上锁,锁一段代码,锁住链表。。另外的链表你照样可以访问

强引用:不手动释放,不会回收

软引用:gc扫描到时不一定回收,只有内存不足时才回收

弱引用:gc扫描到的时候才回收

虚引用:取不到对象,取的时候为空,但是gc的时候可以拿到,能打印hashcode 作用就是gc的时候能收到一个通知

//强引用 不手动释放不会回收
MyUserInfo userInfo = new MyUserInfo();

//强引用 内存不足才会释放
SoftReference<MyUserInfo> myUserInfoSoftReference = new SoftReference<MyUserInfo>(userInfo);
MyUserInfo userInfo1 = myUserInfoSoftReference.get();//软引用

//弱引用 gc扫描到的时候就是释放
WeakReference<MyUserInfo> myUserInfoSoftReference1 = new  WeakReference<MyUserInfo>(userInfo);
MyUserInfo userInfo2 = myUserInfoSoftReference.get();//弱引用

//虚引用 使用的时候引用不到,gc的时候能引用到,也就是gc的时候能通知程序员
ReferenceQueue<MyUserInfo> referenceQueue = new ReferenceQueue<>();
PhantomReference<MyUserInfo> myUserInfoSoftReference2 = new  PhantomReference<MyUserInfo>(userInfo, referenceQueue);//必须联合referenceQueue一起用
userInfo = null;
System.out.print("userInfo:" + userInfo);//打印为:myUserInfoSoftReference2:null
System.out.print("myUserInfoSoftReference2:" + referenceQueue.poll());//打印为:myUserInfoSoftReference2:null
System.gc();
try {
    Thread.sleep(2000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.print("myUserInfoSoftReference2:" + referenceQueue.poll());//打印为:myUserInfoSoftReference2:myUserInfoSoftReference2的hash地址
//也就是gc的时候能获取这个对象

参考:https://www.bilibili.com/video/BV18f4y1L772?p=9&spm_id_from=pageDriver

上一篇:【uni app】坑


下一篇:shiro在前后分离的权限管理