之前由于公司资金问题,不得己进行大规模裁员,本来想年后再找,赶上疫情,已经失业快3个月了,面试从最开始紧张的要死,到现在快麻木了,希望自己整理一下知识点,继续加油。大家也可为我指点一下啦。
- 首先进行自我介绍,因为我是19年毕业的,算上实习也就1年左右,所以我在进行自我介绍时,会说我在学校的一些情况,包括实习时候做了哪些东西,然后说项目的情况和我所负责的模块。我之前大概准备了差不多800字包括项目的介绍,但是有时候听得出面试官在对面会有些不耐烦,我现在已经缩短了一些,变得更加总结性的陈述。
- 首先集合连连问
- 了解哪些集合?
- Map接口和Collection接口是所有集合框架的父接口:
- Collection接口的子接口包括:Set接口和List接口
- Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
- Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
- List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
- Map接口和Collection接口是所有集合框架的父接口:
- ArrayList和LinkedList的区别?
- LinkedList 实现了 List 和 Deque(双端队列) 接口,一般称为双向链表;ArrayList 实现了 List 接口,动态数组;
- LinkedList 在插入和删除数据时效率更高,ArrayList 在查找某个 index 的数据时效率更高;
- LinkedList 比 ArrayList 需要更多的内存;
- HashMap的实现原理
- JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)且数组长度>64时,将链表转换为红黑树
- 首先有一个每个元素都是链表(在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,(利用位运算求出一个和取模相近的值,h & (length - 1)位运算效率高(数组容量2的幂原因,不是2的幂有可能下标越界))确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面。而当链表长度>8时,(判断数组是否<64,优先扩容)链表就转换为红黑树,这样大大提高了查找的效率。当链表数组的容量超过加载因子时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中.(1.8中利用位运算将原来链表上的数据分为两块,原索引位置和原索引+原数组容量的和索引位置)。
- 怎么解决哈希冲突?
- put 方法中有putVal(), putVal()方法中又执行了hash()->{return (key == null ) ?0 :(h = key.hashCode())^(h >>> 16)}
- 首先 h = key.hashCode() :获取key的hash值(其中包括如果是自己创建的对象会涉及到重写hashCode)
- 然后 h >>> 16 : 把h 无符号右移 16 位
- 最后将两个结果进行 ^ : 相当于进行无符号异或。让高位也参与hash值的计算。
- HashMap线程安全吗?
- 不安全,因为在多线程情况下扩容会造成死循环,在扩容时链表转移会形成环
- 怎样实现线程安全?
- Hashtable 和 ConcurrentHashMap。(然后说区别)
- Hashtable 是每个方法都用synchronized 关键字修饰的,所以效率比较低
- 而 ConcurrentHashMap 是把每个索引位置进行加锁,锁的粒度减小
- synchronized实现原理了解吗?
- 进入synchronized块的语义是:把synchronized块内使用到的变量从线程的工作内存中清除,直接从主内存中获取
- 退出的语义是:把synchronized块对变量的修改刷新到主内存。
- 会造成上下文切换的开销,独占锁,降低并发性
- 扩展:CAS自旋锁、unsafe(相当于是线程安全的原子性的i++)
- volatile 的实现原理了解吗 ?
- 保证可见性(确保一个变量的更新对其他线程马上可见)和有序性(lock解决CPU的指令重排序问题),但不保证原子性,原子性需要synchronized这样的锁机制
- 缓存可见性实现原理:底层通过汇编Lock前缀指令,会锁定这块内存区域的缓存并写回到主内存。
- Lock指令解释:会将当前处理器的缓存行的数据立即写回到系统内存,这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效(MESI协议)。
- 什么情况会造成死锁?
- 产生死锁的四个必要条件:
- 互斥条件:一个资源在同一时刻只能被一个线程操作。
- 占有且等待:线程因为请求资源而阻塞时不会释放已经获取到的资源。
- 不可强行占有:线程已经获取到的资源,在未释放前不允许被其他线程强行剥夺
- 循环等待:线程存在循环等待资源的关系(线程 T1 依次占有资源 A,B;线程 T2 依次占有资源 B,A;这就构成了循环等待资源关系)。
- 产生死锁的四个必要条件:
3. 然后是数据库连连问
- 了解MySQL索引吗?
- 知道MySQL索引的数据结构实现是用B+树,是对B 树的升级
有点累了,明天再写。。。