快手二面
08.10 快手二面
自我介绍
介绍论文
说一说在项目里Redis的作用?怎么用的?
那详细说一说项目里短信验证登录的流程?
如果存验证码到Redis时,Redis没有返回存成功的结果,或者Redis直接超时,该怎么办?
这里我说可以重试解决,但是面试官又继续问:“那一直没有返回消息或者说一直超时,难道要一直重试吗?重试无数次?”
然后我以为他问的是验证码已经存进去了,只是没有返回结果,我又说了Redis会对数据进行持久化,说了说持久化机制。
但是面试官说我没有理解他的意思,不过确实没有明白他到底要问的是啥,然后他让我回去好好想想。
后面回去想了想,结合后面问的问题,这个问题可能他要的答案是用主从模式+哨兵来解决,因为主节点负责读写,而从节点只负责读,所以在存取验证码的时候,如果主节点长时间没有返回结果或者超时,那么说明这个主节点已经失联了,哨兵就会推举出一个新的主节点与用户相连,继续支持用户写数据,然后与其他从节点之间进行数据同步。
Redis集群了解过吗?怎么保证主节点和从节点数据一致?
如果主节点失联,那主节点和从节点数据还一致吗?
你提到了哨兵模式,那哨兵是怎么知道有多少主节点多少从节点的?
通过哨兵的自动发现机制实现的,一般情况下,哨兵节点每10秒向主从节点发送
INFO
命令,以此获取主从节点的信息。第一次执行的时候,哨兵仅知道我们给出的主节点信息,通过对主节点执行INFO
命令就可以获取其从节点列表。这样周期性的循环,就可以不断地发现新加入的节点。
那哨兵之间是如何保持连接呢的?它们之间是怎么发现对方的呢?
因为哨兵可以通过
INFO
命令发现主节点和从节点的信息,而Redis提供了一种发布订阅的消息通信模式,哨兵们就是通过一个约定好的频道发布/订阅信息进行通信:每隔2秒,每个哨兵就会通过它监控的主节点、从节点向频道发送一条hello消息;
每个哨兵会通过它监控的主节点、从节点订阅频道的消息,以此来接收其他哨兵发布的消息。
简单来说就有点类似于广播的方式,实现哨兵之间发现。
MySQL的原子性和持久性是怎么实现的?
那MySQL一致性的底层是怎么实现的呢?
这个我说了一致性是通过原子性、持久性、隔离性来实现的,然后又详细介绍了其他三个性质的底层实现,通过实现这三个性质来保证最后事务的一致性。
但是面试官又说:“没有理解我的意思,下去好好再想想”。
???这个我是真的不知道他想问我什么了???
难道是想问我主从模式之间实现的数据一致性?如果是的话也太逆天了,自己都没有说清楚问题。
说一说对象创建的过程吧
具体说说对象内存分配的过程
为什么大对象要直接移到老年代?
那具体介绍一下垃圾回收机制和垃圾回收器
为什么要Full GC?什么时候触发Full GC?
前面半个问题还算正常,后面半个问题是最逆天的。
我回答的是当新生代没有足够空间存放新对象,或老年代空间不足,或永久代空间不足等情况下才会触发Full GC。
然后面试官说:“我当然知道空间不足的时候会进行Full GC,我问的是什么时候触发Full GC?”
给我整蒙了,这我是真不知道该怎么回答了。
后面我详细查了一下,除了上面回答的空间不足会触发Full GC外,还有一种情况也会触发Full GC。
也就是Minor GC也会引发Full GC,这是因为JVM的空间担保机制引起的。
空间担保机制:在发生Minor GC之间,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间(是所有对象,并不仅仅是存活的对象,为什么?因为使用全部对象总和来判断,相对消耗的资源更小,速度更快,不用去判断哪些对象是存活的)。
- 当老年代剩余连续空间 > 新生代所有对象总空间 > 历次晋升到老年代的对象平均大小,这就是正常情况,会执行Minor GC;
- 当新生代所有对象总空间 > 老年代剩余连续空间 > 历次晋升到老年代的对象平均大小,这里又分为三种情况:
- Minor GC后,剩余的存活对象大小 < Survivor区大小,这个时候存活的对象进入Survivor区;
- Minor GC后,Survivor区大小 < 剩余的存活对象大小 < 老年代可用内存大小,这个时候存活的对象进入老年代;
- Minor GC后,剩余的存活对象大小 > 老年代可用内存大小,这时候连老年代都放不下,就会触发Full GC,如果Full GC之后仍然放不下,就会OOM;
- 当新生代所有对象总空间 > 历次晋升到老年代的对象平均大小 > 老年代剩余连续空间,就会直接触发Full GC。
最长回文子串