Java基础 & 集合
2022-10-17 18:09:52   2  举报             
     
         
 AI智能生成
  Java基础 & 集合 八股文
    作者其他创作
 大纲/内容
  String    
     String    
     String特点  
     StringBuffer  
     StringBuilder  
     重载和重写  
     接口和抽象类  
     异常处理  
     面向对象  
     泛型    
     什么是泛型  
     泛型的优点  
     泛型原理  
     反射    
     什么是反射  
     反射优缺点  
     反射使用场景  
     反射使用  
     序列化    
     为什么需要序列化  
     序列化方式  
     Vector/ArrayList/LinkedList    
     Vector  
     ArrayList    
     自动扩容流程    
     当我们试图在ArrayList中添加一个元素的时候,首先会检查数组容量,源码中是调用的ensureCapacity 方法,容量不够才会进行扩容  
     扩容的时候会创建一一个新的数组,大小是原数组大小的1.5倍,也就是size + size》> 1.之后将原数组中的所有元素都copy到新创建的数组中  
     最后,将引用指向新数组,完成扩容  
     ArrayList的拷贝    
     浅拷贝  
     深拷贝  
     LinkedList  
     HashMap/HashTable    
     哈希碰撞产生的原因  
     hashcode是如何计算的           
     为什么hashmap数组的长度为2的幂次方    
     计算hash值,通过取余操作,得到 index
  
     降低Hash冲突怎么做    
     在计算哈希值的 hash()方法中,得到 Object的hashcode之后,高16位和低16位做异或运算  
     HashMap避免内存泄露    
     HashMap如果使用自定义的对象作为key,那么- -定要重写equals和hashCode方法。
否则,假如我们new大量的对象给相同的参数,本意在map中这些对象key是会覆盖的,但是没有重写equals和hashCode的话,会无限死循环往里存,
又因为是强引用,垃圾回收不会处理。因此,造成了内存泄漏。
    否则,假如我们new大量的对象给相同的参数,本意在map中这些对象key是会覆盖的,但是没有重写equals和hashCode的话,会无限死循环往里存,
又因为是强引用,垃圾回收不会处理。因此,造成了内存泄漏。
 HashMap底层实现    
     jdk 1.7 数组+链表  
     jdk 1.8 数组+链表+红黑树    
     数组长度 > 64 且 链表长度>8会转换为红黑树    
     为什么是8, 12*0.75 柏松分布因子得到的  
     红黑树结点个数 < 6 时,会转回链表  
     为什么需要转换    
     红黑树保存较多信息,节点的值、指针、颜色  
     链表相对简单  
     HashMap查询的时间复杂度    
     数组+链表    
     没有Hash冲突,O(1)  
     有hash冲突 o1+ O(n)  
     数组、链表、红黑树    
     没Hash冲突 O(1)  
     有Hash冲突 O(1)+O(logn)  
     HashMap扩容    
     一些变量    
     capactiy,16    
     默认16,但初始容量是32  
     loadFactor,负载因子,0.75  
     threshold,阀值 = 容量 * 负载因子 ,超过阀值会扩容  
     什么时候触发扩容    
     当元素数量超过阀值会扩容,容量是扩容前的两倍  
     JDK 7     
     扩容机制    
     如果是空参,那么用默认的容量、负载因子和阈值,初始化数组,内部是空数组
如果不是空参,使用传入的参数
第一次put会初始化数组,容量变为不小于指定容量的2的幂,然后根据负载因子确定阈值
如果不是第一次扩容,则新容量=旧容量* 2
    如果不是空参,使用传入的参数
第一次put会初始化数组,容量变为不小于指定容量的2的幂,然后根据负载因子确定阈值
如果不是第一次扩容,则新容量=旧容量* 2
 元素迁移    
     遍历每个桶,然后遍历每个元素,重新计算hash值,找到新数组的对应位置,头插法插入新的链表
因为是头插法,因此新旧链表元素位置会倒置
并且,多线程下,可能会出现死循环
    因为是头插法,因此新旧链表元素位置会倒置
并且,多线程下,可能会出现死循环
 JDK 8    
     扩容机制    
     如果是空参构造函数,默认内部数组是null,也就是没有实例化!
在第一次put的时候,会开始第一次初始化扩容
如果是有参构造函数。会指定不小于容量的2的幕数。
如果不是第一次扩容,则容量变为原来的2倍
    在第一次put的时候,会开始第一次初始化扩容
如果是有参构造函数。会指定不小于容量的2的幕数。
如果不是第一次扩容,则容量变为原来的2倍
 元素迁移    
     扩容的时候,不需要重新计算hash,只需要判断最高位是1还是0
迁移元素的时候是正序的,不会出现链表专置
    迁移元素的时候是正序的,不会出现链表专置
 HashMap 和 HashTable 区别  
     concurrentHashMap  
     为什么重写 equals 还要重写 hashcode方法    
     HashCode方法,native 方法,底层采用c语言编写。作用是根据对象的内存地址,转换为整数类型
  
     equals方法,默认情况下继承Object类,使用==判断对象的内存地址是否相等
  
     两个对象相等,equal- 定相等 ,hashCode也- 定相等。因此重写equals方法之后还需要重写hashCode方法
  
     阿里巴巴手册页规定了,只要使用自定义的对象作为Map的键,那么必须重写equals和hashCode  
     内存泄漏的问题    
     如果HashMap使用自定义的对象作为key,举个极端的例子,new多个不同的对象给相同的参数,但是对象内存地址不同。我们没有重写equals和HashCode,就可能发生这样一个问题: 无限死循环往HashMap中存,导致内存溢出。涉及到强引用的问题,垃圾回收不会处理  
    
 
 
 
 
  0 条评论
 下一页
  
   
   
   
  
  
  
  
  
  
  
  
  
  
 