面试汇总——JavaSE——集合(二)

根据牛客网的面试经验的题进行的汇总,里面的内容是看别人的博客或者其东西进行汇总的,将这些的知识总结一下,方便自己查看和复习用
牛客网

集合(二)

JAVA集合

请解释为什么集合类没有实现Cloneable和Serializable接口?

像这些接口只要专注于自己的抽象功能即可,具体的实现操作则是由各自的实现类去完成的

请说明Java集合类框架的基本接口有哪些?
  • Collection

    • List:有序的集合
    • Set:无序且不重复的集合
  • Map:键值对,键不能重复

JAVA内存模型

请你说明一下ConcurrentHashMap的原理?

ConcurrentHashMap是将HashMap由线程不安全变为线程安全

  • JDK1.7

    • 数组+Segment+分段锁

    • 在JDK1.7中ConcurrentHashMap主要是由Segment组成,又因为Segment继承于ReentrantLock,所以每个Segment都有一把锁(分段锁),当访问不同分段锁中的数据时,不会相互影响

    • static class Segment<K, V> extends ReentrantLock implements Serializable 
      
    • 定位一个元素要两次hash,第一次hash定位到Segment,第二次hash定位到元素所在链表的头部

  • JDK1.8

    • 数组+链表+红黑树(数组容量>64 && 链表长度>8)【红黑树的查找能力O(logn)】

    • class Node<K,V> implements Map.Entry<K,V> {
          final int hash;//key的hash值
          final K key;//key值
          volatile V val;//value(保证可见性)
          volatile Node<K,V> next;//下一个节点(保证可见性)
      }
      

ReentrantLock 与synchronized区别

  • ReentrantLock又叫可重入锁,同时还支持获取锁的公平和非公平性选择
    • 公平性:是指当线程a进行访问时,此时内部有个计数器num+1,如果此时来了线程b,c那么就是处在等在状态,(此时b处于待唤醒状态),当a再次请求资源,计数器变加1变为num=2,可以不用排队,直接使用,使用完后释放所有锁时num=0,此时唤醒b
    • 非公平性:当a使用资源时,b等待,a使用完资源释放后,此时c获取请求,竞争资源,c抢占成功,b继续等待。非公平锁根据每个线程对资源的强制能力来获取资源
  • synchronized:当a使用资源时,b等待,a使用完资源释放后,b才能使用
请解释一下TreeMap?

key不能为null

  • 是一个BST

  • 根结点和Null都是黑色的

  • 如果一个子结点是红色的,那么它的子结点一定是黑色的,其父结点也是黑色的

  • 结点要么是黑色的要么是红色的

public class TreeMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V>, Cloneable, Serializable 
private final Comparator<? super K> comparator;//私有比较器
private transient TreeMap.Entry<K, V> root;//根节点
private transient int size = 0;//长度
private transient int modCount = 0;
private transient TreeMap<K, V>.EntrySet entrySet;
private transient TreeMap.KeySet<K> navigableKeySet;
private transient NavigableMap<K, V> descendingMap;
private static final Object UNBOUNDED = new Object();
private static final boolean RED = false;
private static final boolean BLACK = true;
private static final long serialVersionUID = 919286545866124006L;
  • 其内部都是Entry

  • TreeMap.Entry

  • static final class Entry<K, V> implements java.util.Map.Entry<K, V> {
        K key;
        V value;
        TreeMap.Entry<K, V> left;//左结点
        TreeMap.Entry<K, V> right;//右结点
        TreeMap.Entry<K, V> parent;//父结点
        boolean color = true;//默认为黑色
    }
    
  • Map.Entry

  • public interface Entry<K, V> {
        K getKey();//获取key
    
        V getValue();//获取value
    
        V setValue(V var1);//设置value
    
        boolean equals(Object var1);
    
        int hashCode();
    }
    

TreeMap是对封装好的Entry进行操作

  • Map.Entry
    • getValue() setValue(V value) getKey() equals() hashCode()
  • TreeMap.Entry
    • isEmpty() Comparator() put()
      • put()是给TreeMap中添加元素
        • 首先判断root是否为空
          • 为空,直接添加新结点,size++
          • 不为空
            • 看比较器是否存在
              • 存在,调用比较,<0,指向左边
              • 否则,指向右边;<=0时,即key相同,setValue
              • 不存在
              • 创建Comparable;比较同理

集合

请说明ArrayList是否会越界?

在添加元素时会有下标越界

请你说明concurrenthashmap有什么优势以及1.7和1.8区别?

因为hashMap在并非情况下是不安全的,但是concurrenthashmap在并发状况下时安全的

  • 1.7
    • 数组+链表+分段锁
    • 当进入不同的Segment时,不会有影响,这就是分段锁
  • 1.8
    • 数组+链表+红黑树(容量>64&&长度>8)
    • 当链表的长度过长,性能会下降,所以此时采用红黑树
请你说明一下TreeMap的底层实现?
  • put()
    • 首先定义一个var3指向root
    • 先判断root是否存在,不存在,创建一个;存在—>判断比较器是否为空,不为空,比较,判断返回值大小,<0,var3=var3.left,否则var 3=var3.right,若相等,更新value—>比较器为空,先创建Comparable,后面同理
请你说明ConcurrentHashMap锁加在了哪些地方?

key和value都不能为null

  • JDK1.7中的Segment数组继承ReetrenLock,锁的是每一个Segment数组,当访问的数据不在同一个Segment中,则不会发生冲突
  • JDK1.8用CAS和synchronized保证线程并发
请你解释HashMap的容量为什么是2的n次幂?

通过tab[i = (n - 1) & hash]公式计算得出hash值,在进行&运算时,产生的冲突较少,可以用16和15来和0-10(hash值)进行&运算,看其hash值与原来的hash值发生冲突的概率

请你简单介绍一下ArrayList和LinkedList的区别,并说明如果一直在list的尾部添加元素,用哪种方式的效率高?
  • ArrayList
    • 是动态数组的数据结构
    • 对于查询元素更加高效
  • LinkedList
    • 是双向链表的数据结构
    • 对于插入和删除元素更加高效

如果一直在尾部添加元素,用LinkedList更加高效

如果hashMap的key是一个自定义的类,怎么办?

要重写hashcode()和equals()

请你解释一下hashMap具体如何实现的?
  1. 先计算key的hash值,如果没有一样的,直接将value插入
  2. 如果有一样的hash值,将其value以链表或红黑树的形式插入
请你说明一下Map和ConcurrentHashMap的区别?

hashMap和ConcurrentHashMap区别

  • hashMap在多线程的情况下是不安全的
  • ConcurrentHashMap在JDK1.8中用CAS和synchronized来保证线程并发下的安全,并且在1.8中是通过数组+链表+红黑树实现的

你可能感兴趣的:(面试)