- 集合
- List集合相关面试题
- ArrayList与LinkedList区别
- ArrayList 和 Vector 的区别是什么?
- Java 中的 LinkedList是单向链表还是双向链表?
- ArrayList集合加入1万条数据,应该怎么提高效率
- Array 和 ArrayList 有何区别?
- ArrayList的默认大小
- Java中怎么打印数组?
- 说一说ArrayList 的扩容机制吧
- Collections.sort和Arrays.sort的实现原理
- 迭代器 Iterator 是什么?怎么用,有什么特点?
- Iterator 和 ListIterator 有什么区别?
- 遍历 ArrayList 时移除一个元素
- 如何实现数组和 List之间的转换?
- 快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
- Set集合
- Map集合
- 队列
集合
哪些集合类是线程安全的?哪些不安全?
- 线程安全
- Vector:比Arraylist多了个同步化机制。
- Hashtable:比Hashmap多了个线程安全。
- ConcurrentHashMap:是一种高效但是线程安全的集合。
- Stack:栈,也是线程安全的,继承于Vector。
- 线程不安全
- collection是Java集合框架中的基本接口
-
怎么确保一个集合不能被修改?
Collections.unmodifiableMap
- Collections.unmodifiableList
- Collections.unmodifiableSet
Enumeration和Iterator接口的区别?
- Enumeration:速度快、内存小、无快速失败、无法remove元素
- Iterator:有快速失败、可以remove元素
List集合相关面试题
ArrayList与LinkedList区别
- ArrayList底层是数组、LinkedList底层是链表,因此两者的区别也就是数组和链表的区别
- 数组随机读取速度快,链表随机读取速度慢
- 数组插入删除速度慢,需要移动元素,链表插入、删除速度快
-
ArrayList 和 Vector 的区别是什么?
Vector的关键操作上添加synchronized关键字保证了线程安全,ArrayList是线程不安全的
- ArrayList底层扩容是0.5倍扩容,Vector默认是1倍扩容和capacityIncrement有关
Java 中的 LinkedList是单向链表还是双向链表?
ArrayList集合加入1万条数据,应该怎么提高效率
初始化ArrayList时指定1万大小,避免ArrayList的扩容
Array 和 ArrayList 有何区别?
- Array:定长的
-
ArrayList的默认大小
ArrayList的默认大小是:10,且是在首次add操作后为其分配
Java中怎么打印数组?
foreach打印
-
说一说ArrayList 的扩容机制吧
计算数组的最小容量minCap,若当前数组是默认空数组则minCap=10
- 若minCap>数组长度,则进行扩容
- 每次扩容的大小是oldCap的0.5倍
- 若扩容0.5倍满足不了minCap,则使用minCap。
若minCap超过MAX_VALUE则抛异常,否则newCap=MAX_VALUE或MAX_VALUE-8
Collections.sort和Arrays.sort的实现原理
Collections.sort:底层调用的是Arrays.sort
Arrays.sort:
- legacyMergeSort(a),归并排序
- ComparableTimSort.sort():Timsort排序,结合了归并排序(merge.sort)和插入排序(insertion sort)而得出的排序方法
迭代器 Iterator 是什么?怎么用,有什么特点?
作用:迭代器主要是用来遍历集合使用
怎么用:
- next():获取下一个元素
- hasNext():是否拥有下一个元素
- remove():remove当前元素
特点:当遍历过程中集合被修改,则抛出异常 ConcurrentModificationException
Iterator 和 ListIterator 有什么区别?
- ListIterator只能用于遍历List及其子类,Iterator可用来遍历所有集合,
ListIterator有更多的操作
倒序删除
-
如何实现数组和 List之间的转换?
List->Array:list.toArray(new T[0])
Array->List:new ArrayList(Arrays.asList());
快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
快速失败:普通ArrayList,在迭代器遍历时修改元素则直抛异常
- 安全失败:CopyOnWriteArrayList集合,是先复制原数组,在原数组上生成迭代器,即使中途添加元素也不抛异常
Set集合
HashSet的原理
HashSet和TreeSet有什么区别?
- HashSet底层HashMap,TreeSet底层是红黑树
- HashSet是无序的,TreeSet是有序的
HashSet的add(),remove(),contains()是O(1),TreeSet是O(logn)
Map集合
HashMap原理,java8做了什么改变
底层数据结构:数组链表、红黑树
- 默认初始长度16,每次扩容2倍
- 允许key或value为null
- 桶位置定位:对hashCode运用hash函数,然后映射到相应的桶号。遍历桶下的链表并插入
树化:当链表长度大于8且总桶数大于64时进行链表转化为红黑树
HashMap,HashTable,ConcurrentHashMap的共同点和区别
HashMap
- 线程不安全
- 初始容量16,加载因子0.75
- HashTable
- 线程安全,锁全部
- 初始容量11
ConcurrentHashMap
实现了SortedMap
-
LinkedHashMap的应用,底层,原理
底层使用了LinkedList
-
讲讲红黑树的特点?
每个节点非黑即红
- 根节点是黑色
- 叶子节点是黑null
- 不能出现连续的两个红色节点
- 一个节点到其最底层几点的所有路径上的黑节点树相等
为什么HashMap中String、Integer这样的包装类适合作为key?
- 内部重写了hashCode和equals并符合HashMap规范,减少hash碰撞
JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。
Java8使用synchronized+CAS方式替代了分段锁,提高性能
HashMap 的长度为什么是2的幂次方,以及其他常量定义的含义
在put操作中,有一步是key定位桶位置的操作,使用&位运算,这样定位桶位置会更快
-
HashMap在JDK1.7和JDK1.8中有哪些不同
插入节点方式:JDK7头插法(并发死循环),JDK8尾插法
- 底层结构:JDK7:数组链表,JDK8:数组链表+红黑树
- 扩容后key的移动:JDK7:全部重新hash,JDK8:有的还在原位置、有的是原位置+旧容量
-
1.8 中为什么要用红黑树?
单个桶中链表长度长的话,不好定为元素,引入红黑树后查找速率提高
HashMap 的扩容过程
数组大小扩容到原来长度的2倍
将旧数组的key-value,插入新的数组
-
谈谈线程池阻塞队列
- ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,按FIFO排序量
- LinkedBlockingQueue:基于链表结构的阻塞队列,按FIFO排序任务,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE
- DelayQueue:(延迟队列)是一个任务定时周期的延迟执行的队列。根据指定的执行时间从小到大排序,否则根据插入到队列的先后排序。
- PriorityBlockingQueue:优先级队列)是具有优先级的无界阻塞队列
- SynchronousQueue:(同步队列)一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,