集合

哪些集合类是线程安全的?哪些不安全?

  1. 线程安全
  • Vector:比Arraylist多了个同步化机制。
  • Hashtable:比Hashmap多了个线程安全。
  • ConcurrentHashMap:是一种高效但是线程安全的集合。
  • Stack:栈,也是线程安全的,继承于Vector。
  1. 线程不安全
  • Hashmap
  • Arraylist
  • LinkedList
  • HashSet
  • TreeSet
  • TreeMap

    Collection与Collections的区别是什么?

  1. collection是Java集合框架中的基本接口
  2. collections是Java集合框架提供的一个工具类

    怎么确保一个集合不能被修改?

  3. Collections.unmodifiableMap

  4. Collections.unmodifiableList
  5. Collections.unmodifiableSet

Enumeration和Iterator接口的区别?

  1. Enumeration:速度快、内存小、无快速失败、无法remove元素
  2. Iterator:有快速失败、可以remove元素

List集合相关面试题

ArrayList与LinkedList区别

  1. ArrayList底层是数组、LinkedList底层是链表,因此两者的区别也就是数组和链表的区别
  2. 数组随机读取速度快,链表随机读取速度慢
  3. 数组插入删除速度慢,需要移动元素,链表插入、删除速度快
  4. 链表开销略大,除数据外还要存储指针

    ArrayList 和 Vector 的区别是什么?

  5. Vector的关键操作上添加synchronized关键字保证了线程安全,ArrayList是线程不安全的

  6. ArrayList底层扩容是0.5倍扩容,Vector默认是1倍扩容和capacityIncrement有关

image.png
image.png

Java 中的 LinkedList是单向链表还是双向链表?

双向链表
image.png

ArrayList集合加入1万条数据,应该怎么提高效率

初始化ArrayList时指定1万大小,避免ArrayList的扩容

Array 和 ArrayList 有何区别?

  1. Array:定长的
  2. ArrayList:可以动态扩容

    ArrayList的默认大小

    ArrayList的默认大小是:10,且是在首次add操作后为其分配
    image.png

    Java中怎么打印数组?

  3. foreach打印

  4. Arrays.toString();

    说一说ArrayList 的扩容机制吧

  5. 计算数组的最小容量minCap,若当前数组是默认空数组则minCap=10

  6. 若minCap>数组长度,则进行扩容
  7. 每次扩容的大小是oldCap的0.5倍
  8. 若扩容0.5倍满足不了minCap,则使用minCap。
  9. 若minCap超过MAX_VALUE则抛异常,否则newCap=MAX_VALUE或MAX_VALUE-8

    Collections.sort和Arrays.sort的实现原理

  10. Collections.sort:底层调用的是Arrays.sort

  11. Arrays.sort:

    1. legacyMergeSort(a),归并排序
    2. ComparableTimSort.sort():Timsort排序,结合了归并排序(merge.sort)和插入排序(insertion sort)而得出的排序方法

      迭代器 Iterator 是什么?怎么用,有什么特点?

      作用:迭代器主要是用来遍历集合使用
      怎么用:
    • next():获取下一个元素
    • hasNext():是否拥有下一个元素
    • remove():remove当前元素

特点:当遍历过程中集合被修改,则抛出异常 ConcurrentModificationException

Iterator 和 ListIterator 有什么区别?

  1. ListIterator只能用于遍历List及其子类,Iterator可用来遍历所有集合,
  2. ListIterator有更多的操作

    1. previous()和hasPrevious():逆向遍历
    2. add()方法:可以添加元素
    3. nextIndex()和previousIndex():定位索引位置
    4. set()方法:可以修改元素

      遍历 ArrayList 时移除一个元素

  3. 倒序删除

  4. 迭代器删除

    如何实现数组和 List之间的转换?

  5. List->Array:list.toArray(new T[0])

  6. Array->List:new ArrayList(Arrays.asList());

    快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

  7. 快速失败:普通ArrayList,在迭代器遍历时修改元素则直抛异常

  8. 安全失败:CopyOnWriteArrayList集合,是先复制原数组,在原数组上生成迭代器,即使中途添加元素也不抛异常

Set集合

HashSet的原理

底层使用HashMap

HashSet和TreeSet有什么区别?

  1. HashSet底层HashMap,TreeSet底层是红黑树
  2. HashSet是无序的,TreeSet是有序的
  3. HashSet的add(),remove(),contains()是O(1),TreeSet是O(logn)

    Map集合

    HashMap原理,java8做了什么改变

  4. 底层数据结构:数组链表、红黑树

  5. 默认初始长度16,每次扩容2倍
  6. 允许key或value为null
  7. 桶位置定位:对hashCode运用hash函数,然后映射到相应的桶号。遍历桶下的链表并插入
  8. 树化:当链表长度大于8且总桶数大于64时进行链表转化为红黑树

    HashMap,HashTable,ConcurrentHashMap的共同点和区别

  9. HashMap

    1. 线程不安全
    2. 初始容量16,加载因子0.75
  10. HashTable
    1. 线程安全,锁全部
    2. 初始容量11
  11. ConcurrentHashMap

    1. 线程安全,分段锁
    2. 不能存储null的键和值

      TreeMap底层?

  12. 实现了SortedMap

  13. 底层是红黑树

    LinkedHashMap的应用,底层,原理

  14. 底层使用了LinkedList

  15. 迭代顺序就是插入顺序

    讲讲红黑树的特点?

  16. 每个节点非黑即红

  17. 根节点是黑色
  18. 叶子节点是黑null
  19. 不能出现连续的两个红色节点
  20. 一个节点到其最底层几点的所有路径上的黑节点树相等

为什么HashMap中String、Integer这样的包装类适合作为key?

  1. 内部重写了hashCode和equals并符合HashMap规范,减少hash碰撞

JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。

  1. Java8使用synchronized+CAS方式替代了分段锁,提高性能

    HashMap 的长度为什么是2的幂次方,以及其他常量定义的含义

  2. 在put操作中,有一步是key定位桶位置的操作,使用&位运算,这样定位桶位置会更快

  3. 因此,只有当长度是2的幂次方可以运用&位运算计算桶位置

    HashMap在JDK1.7和JDK1.8中有哪些不同

  4. 插入节点方式:JDK7头插法(并发死循环),JDK8尾插法

  5. 底层结构:JDK7:数组链表,JDK8:数组链表+红黑树
  6. 扩容后key的移动:JDK7:全部重新hash,JDK8:有的还在原位置、有的是原位置+旧容量
  7. 每次扩容都是2倍

    1.8 中为什么要用红黑树?

    单个桶中链表长度长的话,不好定为元素,引入红黑树后查找速率提高

    HashMap 的扩容过程

  8. 数组大小扩容到原来长度的2倍

  9. 将旧数组的key-value,插入新的数组

    1. JDK7:全部重新计算数组位置,再头插法插入数组的链表中
    2. JDK8:key可能落在新桶的原始位置或者原始位置+旧桶位置

      队列

      阻塞队列的实现,ArrayBlockingQueue的底层实现?

  10. 有界阻塞队列,底层是数组

    谈谈线程池阻塞队列

  • ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,按FIFO排序量
  • LinkedBlockingQueue:基于链表结构的阻塞队列,按FIFO排序任务,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE
  • DelayQueue:(延迟队列)是一个任务定时周期的延迟执行的队列。根据指定的执行时间从小到大排序,否则根据插入到队列的先后排序。
  • PriorityBlockingQueue:优先级队列)是具有优先级的无界阻塞队列
  • SynchronousQueue:(同步队列)一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,