Java两年工作经验面试

Java两年工作经验面试题目和心得

  • 一、ArrayList和LinkedList的区别?
  • 二、ArrayList的底层扩容机制是如何实现的?
  • 三、spring的aop底层实现方式有哪些?
  • 四、HashMap的底层实现原理?
    • 4.1 HashMap的几个重要知识点
    • 4.2 JDK7与JDK8的HashMap区别
    • 4.3 HashMap的容量与扩容机制
  • 五、MySQL的事务隔离级别有哪些?


一、ArrayList和LinkedList的区别?

ArrayList是基于动态数组的数据结构实现的,LinkedList是基于链表的数据结构实现的,对于随机访问,ArrayList的get和set查询效率要高一些,因为是通过索引去定位进行访问的,而LinkedList是通过指针一步一步的移动(遍历)来实现,而对于新增和删除,LinkedList效率要高,只需要对指针进行修改即可,而ArrayList需要西东数据来填补被删除的元素。

两者空间复杂度对比:
ArrayList 是线性表(数组)
get() 直接读取第几个下标,复杂度 O(1)
add(E) 添加元素,直接在后面添加,复杂度O(1)
add(index, E) 添加元素,在第几个元素后面插入,后面的元素需要向后移动,复杂度O(n)
remove()删除元素,后面的元素需要逐个移动,复杂度O(n)

LinkedList 是链表的操作
get() 获取第几个元素,依次遍历,复杂度O(n)
add(E) 添加到末尾,复杂度O(1)
add(index, E) 添加第几个元素后,需要先查找到第几个元素,直接指针指向操作,复杂度O(n)
remove()删除元素,直接指针指向操作,复杂度O(1)

二、ArrayList的底层扩容机制是如何实现的?

首先初始化一个ArrayList数组,长度个数为0,当往里添加一个元素时,默认扩容的容量大小为10,接着做一个if的判断,判断数组的长度和默认容量的大小,如果比10要小,则容量为10;如果比10要大,则进行1.5倍的扩容。

为什么是1.5倍呢?
k=1.5时,就能充分利用前面已经释放的空间。

为什么是1.5,而不是1.2,1.25,1.8或者1.75?
因为1.5 可以充分利用移位操作,减少浮点数或者运算时间和运算次数。

三、spring的aop底层实现方式有哪些?

1.xml配置文件中配置aop相关的标签
2.通过注解方式来配置aop的功能,@Aspect

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

四、HashMap的底层实现原理?

4.1 HashMap的几个重要知识点

HashMap是无序且不安全的哈希数据结构。
HashMap 是以key–value对的形式存储的,key值是唯一的(可以为null),一个key只能对应着一个value,但是value是可以重复的。
HashMap 如果再次添加相同的key值,它会覆盖key值所对应的内容,这也是与HashSet不同的一点,Set通过add添加相同的对象,不会再添加到Set中去。
HashMap 提供了get方法,通过key值取对应的value值,但是HashSet只能通过迭代器Iterator来遍历数据,找对象。

4.2 JDK7与JDK8的HashMap区别

既然讲HashMap,那就不得不说一下JDK7与JDK8(及jdk8以后)的HashMap有什么区别:

jdk8中添加了红黑树,当链表长度大于等于8的时候链表会变成红黑树
链表新节点插入链表的顺序不同(jdk7是插入头结点,jdk8因为要把链表变为红 黑树所以采用插入尾节点)
hash算法简化 ( jdk8 )
resize的逻辑修改(jdk7会出现死循环,jdk8不会)

4.3 HashMap的容量与扩容机制

1.HashMap的默认负载因子
Java两年工作经验面试_第1张图片

面试的时候,面试官经常会问道一个问题:为什么HashMap的默认负载因子是0.75,而不是0.5或者是整数1呢?答案有两种:

阈值(threshold) = 负载因子(loadFactor) x 容量(capacity) 根据HashMap的扩容机制,他会保证容量(capacity)的值永远都是2的幂 为了保证负载因子x容量的结果是一个整数,这个值是0.75(4/3)比较合理,因为这个数和任何2的次幂乘积结果都是整数。
理论上来讲,负载因子越大,导致哈希冲突的概率也就越大,负载因子越小,费的空间也就越大,这是一个无法避免的利弊关系,所以通过一个简单的数学推理,可以测算出这个数值在0.75左右是比较合理的
2.HashMap的扩容机制

写数据之后会可能触发扩容,HashMap结构内,我记得有一个记录当前数据量的字段,这个数据量字段到达扩容阈值的话,它就会触发扩容的操作

问题又来了,为什么计算扩容后容量要采用位移运算呢,怎么不直接乘以2呢?这个问题就比较简单了,因为cpu毕竟它不支持乘法运算,所有的乘法运算它最终都是再指令层面转化为了加法实现的,这样效率很低,如果用位运算的话对cpu来说就非常的简洁高效。

3.HashMap中散列表数组初始长度

老问题又来了,为啥HashMap中初始化大小为什么是16呢?
二进制的按位运算,那为什么不是8,4呢? 因为是8或者4的话很容易导致map扩容影响性能,如果分配的太大的话又会浪费资源,所以就使用16作为初始大小。

五、MySQL的事务隔离级别有哪些?

读未提交、读提交、可重复度、串行化,性能依次往下越来越差


你可能感兴趣的:(JAVA面试题,后端java,面试,java)