Java两年工作经验面试


一、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的默认负载因子
在这里插入图片描述

面试的时候,面试官经常会问道一个问题:为什么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的事务隔离级别有哪些?

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


  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的小青年~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值