4. 上海数慧面试复盘--电话面试

结果:

挂了

时间

2023.2.26

心得

紧张,说话不自信,吞吞吐吐

八股没背,回答的点不是很清晰,深挖一下就不行了

分布式锁相关问题回答得也不是很好

注: ----- 以下答案不再更新(考虑删除),统一在面试宝典中更新

索引的原理是什么?

通过数据结构进行高效查询,mysql默认为B+树,然后讲一下B+树的特点,和其他树的区别

你看了集合的源码,主要有哪些?

ArrayList、HashMap、ConcurrentHashMap这些(源码跟着b站或者咕泡再看看,一定要亲手点一点

我比较熟悉的是 HashMap 这一块

那你讲讲 HashMap 吧?

HashMap 是一种基于哈希表实现的 key-value键值对形式的数据结构。可以在 O(1) 的时间复杂度内对元素进行操作。

首先讲一下 hashMap 的底层数据结构:

底层采用数组+链表的形式去进行存储,在1.8的时候引入了红黑树,主要是对链表去做一个转化,进行效率的提升(引诱面试官提问链表和红黑树的转换

hashmap的初始容量是16,扩容方式是2的幂

隐藏点:链表和红黑树的转换

如果链表长度超过8,并且数组长度大于64,就转换为红黑树;

如果链表长度小于等于 6 ,红黑树重新转化为链表

然后讲一下 put 方法的过程:

hashmap对 key 求哈希值然后计算下标,如果没有 哈希碰撞 就直接插入, 如果碰撞了就以链表的形式链接到后面。(引诱面试官提问哈希值计算过程)如果节点已经存在就替换旧值。

如果元素总个数大于 阈值(threshold) (容量 * 加载因子0.75) 就 resize 扩容,扩容还发生在当链表长度大于 8 但是此时数组容量小于 64 ,主要是为了扩容后让节点分步更均匀一些。

然后讲一下 HashMap 的哈希函数怎么实现:

(h = key.hashCode())^ (h >>> 16),首先调用 hashCode() 方法对 key 求 hash值,然后将hash值得低 16 位bit和高 16 位 bit 做异或运算获得 新的 hash 值,然后 (n - 1) & hash 获得下标 (n 指数组的长度)

为什么要和高16位进行 ^ 运算?

由于和 (length -1) 运算,length 绝大多数情况小于 2 的 16 次方。 所以始终是 hashcode 的低 16 位(甚至更低) 参与运算。 但是这样高 16 位是用不到的,为了让得到的下标更加散列,需要让高16位也参与运算,所以就需要低16位和高16位进行 ^ 运算。

为什么 & 位必须是(length - 1)?

长度是2的幂次,length -1 的所有二进制都是1,相当于 取余数,但是比 % 运算更快, table[i = (n -1)& hash];

为什么用 ^ 而不是用 & 或 |

因为 & 和 | 都会使结果偏向 0 或者 1,并不是均匀的概念,所以用 ^。

然后讲一下 hashmap 线程并发安全问题

多个线程同时 put , 当 put 的 key 一样造成一个线程 put 的数据被覆盖

多个线程同时检测到元素个数超过数组大小 * loadFactor, 同时对Node 数组 进行扩容,都重新计算元素位置和复制数据,最终只有一个线程扩容后的数据会复制成功,其他线程丢失,并且 put 的数据也丢失。

链表和红黑树转换的时候会抛出类型转化异常:两个线程同时将红黑树转换成链表,一个线程转换成功,红黑树变成链表了,另一个线程开始转换就会发现红黑树变成了链表,就会抛出类型转化异常。

hashMap 是怎么扩容的?

HashMap 的扩容操作分为两个步骤:

  1. 创建一个新的数组,长度是当前数组长度的两倍。
  2. 将原数组中的元素重新映射到新数组中的位置。这个过程需要重新计算每个元素的哈希值,然后重新映射到新数组的位置中。如果新数组中的某个位置已经有了元素,则需要进行链表或红黑树的操作,以保证元素可以正确地插入到数组中。

concurrenthashmap 了解吗?

保证线程安全的方式有哪些?

保证线程安全主要是保证它的原子性、可见性和有序性

基于synchronized的同步代码块和同步方法,然后使用锁、使用并发集合、使用原子类

使用CAS:保证共享变量的线程安全

使用ThreadLocal: 线程本地变量

volatile 能保证线程安全吗?

不能,volatile 不具备原子性,当多个线程进行 i++ 操作,最后结果是不准确的

ReenTrantLock和Synchronized区别

首先都是可重入锁,然后他们的区别主要有几个方面,第一个是锁的实现不同,

synchronized是JVM实现的关键字

ReentrantLock是JDK实现的类

第二个是性能,

synchronized与ReentrantLock大致相同,但是新版本Java对synchronized进行了很多优化,如自旋锁

第三个是等待可中断

可中断:当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,处理其他事情

ReentrantLock可中断

synchronized不可中断

第四个是公平锁

synchronized的锁是非公平的

ReentranlLock默认非公平,也可以调为公平

第五个是可以实现选择性通知

一个ReentrantLock可以同时绑定多个Condition对象,可以指定线程信息去实现选择性通知

讲一下Spring Bean的生命周期

Spring 中的 bean 的生命周期是指bean从创建到销毁的一个过程,主要包含四个阶段:

  • 实例化 Bean
  • Bean 属性赋值
  • 初始化 Bean
  • 销毁 Bean

(面试官如果问初始化这块,就简单说一下 aware,前后置初始化,自定义初始化这些)

Spring学习了哪些内容?

复盘过,重新整理答案出来

动态代理在哪里有用到?

aop,rpc,事务管理,数据库连接池

项目上用到了哪些设计模式?

策略模式,讲一下自己写的比较方法的策略模式+简单工厂模式

文章访问量、博客PV、UV怎么做的?

通过redis去统计每天的访问量,通过定时任务将访问量同步到数据库。同时将pv、uv通过日志统计的形式同步到数据库。

面试官评价

简历写得还行,问起来就一般

全部评论
这hashmap还纠结到异或去了
1 回复 分享
发布于 2023-03-22 20:42 广东
初试吗 base哪里?
点赞 回复 分享
发布于 2023-04-18 19:00 广东
xd是投的哪里的岗位啊,是广州吗?
点赞 回复 分享
发布于 2023-04-19 13:47 广东

相关推荐

10-19 15:48
武汉大学 Java
oppo 应用开发岗 33w
点赞 评论 收藏
分享
评论
4
20
分享
牛客网
牛客企业服务