校招面试--集合

说说常见的集合有哪些?

Set:HashSet、TreeSet、LinkedHashSet等
List:ArrayList、LinkedList、Stack以及Vector等
Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap

说说List,Set,Map三者区别?
  • List:有序、可重复。
  • Set:无序、不可重复。
  • Map: 使用键值对存储,key 是无序、不可重复的,value 是无序、可重复的,每个键最多映射到一个值。
HashMap与其他集合的区别

数组的特点是:查找容易,插入和删除困难
链表的特点是:查找困难,插入和删除容易
综合以上优点:查找插入删除操作取了中间值

HashMap与HashTable的区别?

HashMap:线程不安全,允许K/V都为null,初始化大小为 16,每次扩充变为原来的 2 倍

Hashtable:线程安全,K/V都不允许为null,Hashtable 默认的初始大小为 11,每次扩充变为原来的 2n+1

HashMap和HashSet区别
HashMapHashSet
实现了 Map 接口实现 Set 接口
存储键值对仅存储对象
调用 put()向 map 中添加元素调用 add()方法向 Set 中添加元素
HashMap 使用键(Key)计算 hashcodeHashSet 使用成员对象来计算 hashcode 值,对于两个对象来说 hashcode 可能相同,所以equals()方法用来判断对象的相等性
Arraylist与LinkedList区别

Arraylist:底层是数组,适合查找,实现了RandomAccess接口(支持快速随机访问),实现了Cloneable接口(支持克隆操作),实现了Serializable 接口(支持序列化),扩容机制是懒汉式的,当加载第一个数据时才会默认初始化的值10,之后扩容为原来的1.5倍
LinkedList :底层是双向链表,适合删除和插入操作

  • 内存空间占用: ArrayList:list 列表的结尾会预留一定的容量空间,LinkedList:每一个元素都要放指针和数据
Arraylist和Vector的区别

都实现了 List 接口,都是有序集合

  • ArrayList :线程不安全 ,扩容1.5倍
  • Vector :线程安全的,扩容2倍
HashSet、LinkedHashSet和TreeSet三者的异同
  • HashSet:底层是HashMap,线程不安全的,可以存储null值
  • LinkedHashSet:能够按照添加的顺序遍历
  • TreeSet:底层使用红黑树,能够按照添加元素的顺序进行遍历,排序的方式有自然排序和定制排序
==与 equals 的区别

==

  • 基本类型:== 比较的是值是否相等

  • 引用类型:== 引用是否指向同一个对象地址

equals

  • 比较的是值是否相等
HashMap在JDK1.7和JDK1.8中有哪些不同?(HashMap的底层实现)

JDK1.8 之前 HashMap 由 数组+链表组成的,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)

JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)

ConcurrentHashMapHashtable的区别

Hashtable:采用数组+链表的形式,使用 synchronized 来保证线程安全,效率非常低下。

ConcurrentHashMap:JDK1.7 采用分段的数组+链表实现,对整个桶数组进行了分割分段(Segment)
JDK1.8 采用Node 数组+链表+红黑树的数据结构来实现,摒弃了 Segment 的概念,并发控制使用 synchronized 和 CAS 来操作

哈希

Hash(散列):把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值)

哈希冲突是什么?怎么解决?

两个不同的输入值,根据同一散列函数计算出相同的哈希值

拉链法
两次扰动(哈希值高低位进行异或运算、数组长度 - 1进行与运算(&))
红黑树(时间复杂度O(n)->O(logn))

为什么数组长度要保证为2的幂次方呢?怎么实现的?

h&(length-1)才等价于h%length,但比取余操作更加有效率,还可以减少冲突次数
容量cap先减一,再分别与向右移1,2,4,8,16位进行按位或操作(只要有1就为1),目的是将最高位的1后面补齐1,得到的数大于等于原来的数

默认负载因子 loadFactor 为什么是0.75?阈值 threshold?

loadFactor大,扩容频率低,但浪费的空间比较小,不过发生hash冲突的几率就比较大
loadFactor小,扩容频率高,会占用更多的空间,但是元素的存储就比较稀疏,发生哈希冲突的可能性就比较小
所以取了一个0.75的中间值作为加载因子

threshold = 数组容量* 负载因子,当Size>=threshold的时候,那么就要考虑对数组的扩增了

给出n个键值对,如何合理的存入hashmap中

threshold = 数组容量* 负载因子(12=16*0.75)
16个数时存12个最好
n/0.75

HashMap为什么是线程不安全的?怎样线程安全的使用hashmap

在并发执行put操作时会发生数据覆盖的情况
例如一个hashmap的长度为8,已经存入了1和9两个值,当线程一准备存入17,线程二存入了25时,17会覆盖25

使用ConcurrentHashMap

源码分析
HashMap的put方法的具体流程?(put方法)

img

HashMap的扩容操作是怎么实现的?(resize底层原理)
TreeMap底层原理
实践
并发容器用过哪些?在什么场景?

ConcurrentHashMap:并发版 HashMap
最常见的并发容器之一,可以用作并发场景下的缓存。

并发情况下hashmap什么时候会修改失败
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值