一面
- 算法题:在一个数组n中找出所有和为m的两个数
第一想法两个for循环嵌套暴力循环,但是时间复杂度就O(n²)了;正确方法是空间换时间,构造一个hashMap,然后只需要遍历一次数据。
总结:基础的算法还是需要了解
- 讲讲HashMap的实现
答到了:1.8以前是数组+链表实现,1.8是数组+链表+红黑树实现;通过hash函数计算出hash值,在计算出偏移量定位到数组的位置,如果发生了hash冲突,则在数组元素后加上链表,当链表长度达到一定值转换成红黑树。 - 转换成链表后的复杂度
O(n),感觉还是比较重视算法基础 - HashMap是线程安全的吗,线程安全应该用哪个
只答到了线程不安全,没有说线程不安全会造成哪些后果, - ConcurrentHashMap是如何保证线程安全的
使用分段锁,只答到了分段锁,没有拓展如何实现
总结:对HashMap的理解还停留在比较一般的阶段,缺乏底层
- 如何写一个单例模式
构造方法私有,使用双重检查锁防止重复创建对象,使用volatile解决老版本jdk指令重排的问题。 - volatile是什么原理
volatile是通过禁用缓存来实现线程可见性,对volatile变量的写操作会立即更新到主内存中
对volatile的使用可以去参照happens-before原则:
a. 在一个线程中前面的操作happens-before后面的操作
b. volatile变量的写happens-before后续对这个变量的读操作
c. happens-before具有传递性
d. 使用synchronized锁中的操作happens-before后续锁的操作
e. 线程start原则
f. 线程join原则 - 对锁升级的了解
从偏向锁->轻量级锁->重量级锁 - 使用cas与synchronized的区别
a. cas适用于并发度不是很高的场景,性能会很高,但是在并发度很高的情况下,一直自旋得不到锁会导致cpu占用飙高,相反synchronized因为有等待唤醒机制,线程在队列中等待唤醒并不会消耗资源。
b. synchronized用于保证代码块原子性,如果需要处理多个变量,使用synchronized合适。 - 机械磁盘顺序IO和随机IO的区别
没听说过。。。应该是问mysql,需要补一波。
https://blog.csdn.net/zhenghuishengq/article/details/129080088 - truncate截断表和delete删除数据的区别
truncate删除后无法恢复了,delete删除后数据还能回滚 - 场景题:redis中使用布隆过滤器,防止恶意请求
使用布隆过滤器可以判断哪些值服务一定没有,他想在布隆过滤器后面放一层本地缓存,想问本地缓存来着,这方面没了解过,后面可以了解下guavaCache。 - mysql中varchar,char,text,longtext存储的区别
不会,需要补 - 了解过零拷贝吗
应该是kafka中使用到的技术,没有了解过,后面学习到kafka的话在了解下。 - http三次握手
这个确实忘记了,以后面试前看一下。
二面
- 介绍下你比较熟悉的项目。
讲了下电商的项目,提到了搜索引擎es,聊了下es数据是如何同步,版本升级api的改动。 - spring-data-es底层是如何对es做访问的。
应该是想问es中的几种请求及请求方式。
这里坑了自己一小下,es的项目是好久之前的项目了,面试前并没有准备,导致被问到很尴尬。 - 项目中有什么挑战,站在当前的角度再看以前的项目有什么新的见解。
讲了下项目中对分布式事务的解决,已经以前项目中对openFeign组件的使用,并发场景下分布式锁的事务问题。
项目亮点这一块需要重点准备下,考虑包装库存业务,分库分表技术。 - 线上问题如何排查,如何出现问题的代码刚好没有打日志该如何排查。
讲了下通过日志定位线上问题,如果没有打日志确实不知道该如何处理说了找dba,感觉是想问athas。
总结
工作经验达到三年后的第一次面试,发现了很多不足,平时确实没有刷算法,缺少算法题积累,对juc部分准备的不是很充分,虽然都答上了,但是缺乏亮点。
后续:
- 技术栈重点关注Spring源码,突出一个重点
- 技术栈学习k8s,发现现在招聘都要求会
- 学习常用的算法
- 项目经验准备DDD
- 项目亮点准备分库分表
- 项目亮点准备本地缓存