针对项目用到的技术提问:
redis相关:
分布式锁怎么做的?
答:setnx加一段过期时间
问:假如过期时间到了会发生什么问题?怎么解决
答:过期时间到,锁消失,线程不安全;解决考虑用续命锁
问:续命锁具体怎么做的?
答:框架底层封装的,没有怎么看……
问:假如是你,你会怎么解决?
答:采用lua脚本
问:Lua脚本只解决原子性啊,这个过期时间问题还是没解决
答:采用一个工作线程监控任务的执行,任务执行完,工作线程才结束。
还是意犹未尽,但是跳过了……
持久化机制?
集群模式了解吗?
Kafak相关:
消费幂等性是怎么做的:
两个consume group会消费同一个生产者吗?
回答:多个group消费会隔离开
问:也就是多个group消费是一个全集吗?
回答:是
面试官:你可以回头再看看,不是这样
只用过消费者模式吗?是单线程还是多线程部署的?
答:只用过消费者模式升级旧数据,是单线程(其实我也不知道)
问:单线程的话,如果是你,可以怎么提升效率?
答:可以采用IO复用的机制
kafak的offset是怎么存储的?
答:磁盘存储
maxwell是什么?
答:监控mysql binlog,并将其写入到kafak
基础
mysql相关:
假如插入一行数据,索引的建立过程是怎样的?
索引的存储大小了解吗?
答:页分裂16kb
假如我有一千万行数据插入,你可以计算出来b+tree的高度吗?思路是什么?
答:按照主键存储,每16kb转到下一页……(其实不知道)
面试官补充:其实就是根据每一行索引的大小,计算出全部数据的大小,再除以每一页的大小就得出来了,这个行高是很低的。
了解mvcc吗?说下原理
mvcc是什么隔离级别?
间隙锁知道吗?
唯一索引会走间隙锁吗?
Mysql的逻辑是什么?(刚开始懵了,啥逻辑,也不说清楚,面试官都想跳过这个话题了)
答:server层,和存储引擎层,以及执行优化器
问:假如有个client和server,他们是全双工还是半双工?
答:全双工吧……
问:什么是全双工,什么是半双工?
答:全双工就是发送和接受是同时的,半双工不是这样……(以为和tcp client和server一样是全双工)
sql调优了解哪些?
锁相关:
jdk的锁有什么优化方案(不按套路出牌)
答:悲观锁可以拿乐观锁(CAS)实现
问:除了这个还有吗?
答:读写锁可以用共享锁优化
死锁怎么避免?
答:线程按照顺序有序执行,让线程并发访问同一个资源
问:并发访问同一个资源,那还是会死锁啊
答:那就最好线程有序执行……
问:怎么让线程有序执行
答:让多个线程锁开启和释放的时机并不一致
线程池相关:
线程池参数说一下?
线程池提交一个任务的执行流程?
场景题:
假如线程池有四个线程都在统计学校数量,要和主线程怎么搭配去实现?
答:主线程写一段awaitTermination等待一段时间关闭线程池
问:那你这是关闭线程池了啊,那应该是第一个线程执行完关闭还是最后一个线程执行完关闭
答:最后一个……等到所有都执行完才关闭
问:对啊,所有执行完成了自动就关了
答:可以写一个共享变量volatitle schoolNumber,每个线程都对其schoolNumber--
问:共享变量有线程安全问题啊
答:建一个runnable任务,里面加锁,通过notifyall和wait唤醒其他线程和释放锁搭配统计
GC相关:
有没有遇到过gc问题?
答:有遇到内存溢出问题
问:怎么定位和排查的
答:试用MAT定位堆栈中内存占用最大的变量
Juc相关:
平时有用过什么工具包吗?(引出Juc)
有用过juc
问:用过什么
答:synchronized和lock,AtomicInteger
问:有遇到过什么问题吗?(懵了不知道想问什么)
答:有看过Unfafe类,感觉这个有问题(瞎说的)
问:你知道ABA问题吗(晕,你直接说不就好了,绕来绕去)
答:知道,说了下ABA是什么
问:怎么解决
答:可以使用版本号机制,unsafe有提供通过object,加内存偏移量的方法实现cas
场景题:
假如多个线程同时访问同一个方法,这个方法里采用stringbuilder不停的append字符串,变量都是方法里的变量,没有成员变量,会遇到线程安全问题吗?
答:会,假如两个线程同时对空字符串append(a),则第一个线程append完了变为a,第二个线程也会变为a(也不知道答的对不对)
问:你这个空字符串是成员变量吗?
答:不是
查了下
StringBuilder的append()方法调用的父类AbstractStringBuilder的append()方法
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
count += len不是一个原子操作。假设这个时候count值为10,len值为1,两个线程同时执行到了第七行,拿到的count值都是10,执行完加法运算后将结果赋值给count,所以两个线程执行完后count值为11,而不是12。
有看过什么源码吗?(引出hashmap)
答:看过hashmap源码
问:那你说一下put和get的流程吧
答:回答了一通(罕见的没追问,此时已经要一个小时了,口干舌燥)
手撕算法:
一个ip地址的字符串,设计一种映射可以让其转为int类型,int又可以转回ip地址
(先说的思路)
答:ip地址分段各自异或操作
问:那这个边界问题你怎么考虑
答:和一个n与运算……(瞎说的)
问:那你能写一下吗
答:不会……
后续查了下可以参考这个blog
https://blog.csdn.net/paul342/article/details/48374237
换一道算法,写一下LRU实现,通过一个meeting会议网站,不是共享屏幕,也没开摄像头(谢天谢地)
最后总算写出来了
为什么跨专业找工作
反问
全部评论
(13) 回帖