金服|小姐姐面试蚂蚁金服被虐经历,敖丙心疼...( 二 )


小哥哥:那怎么处理呢?
我: 首先保障热点 key 过期问题,给不同的热点key分配随机的过期时间,保证过期的平滑。然后可以通过在 Redis 中设置分布式锁,只有获取到锁的请求才能够穿透到数据库,保证同一时间只有一个请求可以穿透到数据库更新缓存。
小哥哥:不是,我不是这个意思,我是问这个热点key的访问要如何解决?
我:可以通过 hash 分 key,把一个 key 拆分成多个 key,分布到不同的节点,防止单点过热。比如一个 key 之前就分到一个节点上,我把 key 做了拆分,就像一致性 hash 的虚拟节点,分散访问。
小哥哥:你说到一致性 hash?那和普通hash有什么区别?
我:一致性hash把hash的空间虚拟成一个圆环,key做hash落在圆环上,按顺时针查找,遇到的第一个缓存节点就命中。通过虚拟节点避免缓存分布不均,并且使得某个节点挂了之后,下面的节点只需要承担一部分的流量而不会因为需要承担所有流量而挂了,然后发生雪崩
小哥哥:好,那我们说回刚才的问题,你刚说的是一种解决方案那还有什么别的方案么?
我:(还有??我真的没了,我思考了十秒钟,一片空白不知道了)不知道了。
其实还有本地缓存,简单点就一个HashMap就行,或者Guava cache或者Ehcache。用本地缓存来应对极热数据。
小哥哥:那好吧,来说说MQ吧
我:(小哥哥有点失望的样子,哎也是不应该但是脑子就是想不起来..)常见的有RocketMQ、KafKa等,RocketMQ更适合业务,注重时延的优化。Kafka因为存在攒一波的思想,吞吐更高,并且适合大数据场景,不适合业务。
小哥哥:攒一波是什么意思?
我:攒一波就是发消息默认不是一条一条发,是等一波再发(其实攒一波思想很常见,例如tcp的纳格算法,pageCache的批量刷盘等等)
小哥哥:那Kafka是哪种模式?
我:什么意思?什么模式?
小哥哥:就是消息不是有推和拉两种模式
我:额...(我不知道,我就知道RocketMQ的,是基于拉的,虽说有个pushConsumer,但是本质上也就是拉,只是broker先hold住了拉的request。我也知道拉模式和推模式的优缺点,只是我当时傻了,我当时脑子想我简历就没写Kafka,为啥问我Kafka不问我RocketMQ,其实我应该先说说推拉模式的优缺点然后说了RocketMQ是采用什么的,然后说下我对Kafka不太熟,只是我当时傻了...)我说推?应该是推吧?不对不对好像是拉....(我真的是神操作)
小哥哥:不知道就说不知道,不要乱说一通。
我:是是是,我不知道对不起。(是的不知道就直接说不知道,然后应该把自己知道的说出来,弥补下)
小哥哥:说说synchronize和lock区别
我:(来了来了,赶紧弥补下刚才的操作)synchronized是java内置锁,不需要手动的解锁,支持可重入,但是非公平,不可中断,条件单一,在1.6之前性能较差,经过1.6优化只有性能有显著的提升。lock,基于AQS,拿reentrant为例,需要手动解锁,可重入,支持中断,支持多条件,支持超时操作。(来快问我synchronized底层和1.6做了什么优化,我来从monitor对象开始说到字节码到monitorenter和monitorexit再到mutex,从偏向锁到轻量级锁到重量级锁,我再说个逃逸分析、锁消除、锁粗化。再引申出个JMM,来个cpu缓存L1、L2、L3到MESI,我还可以给你来个cpu缓存行伪共享问题。什么你问的是锁为什么重?那就来上下文切换,内核态用户态,系统调用,再给你引到上一个mq话题,搞个mmap、sendfile零拷贝,扯一波pageCache、内存预分配、文件预热、mlock等。来啊!!!)
小哥哥:说说AQS原理吧
我:(擦竟然不问我synchronized)AQS主要是采用state,通过对state的CAS判断来获取锁和解锁,并且存在等待队列和条件等待队列来park相关线程之后入队等待,有公平和非公平两者模式来唤醒等待的线程。
小哥哥:那为什么需要个AQS?
我:主要是为了封装和抽象,通过封装了公共的方法,减少重复代码。
小哥哥:说说GC调优把
我:GC调优一般具体是通过GC日志的情况来分析。基本上发现minor gc频繁,新生代空间太小了。如果发现晋升的年龄很小,老年代迅速被填满,导致频繁的major gc,并且回收比率又很大,那说明对象的生命周期确实很短也需要调整新生代。如果看full gc很频繁,但是每次回收的内存就一点点,那目测就是内存泄露了。总体上就是根据分代的根本,也就是新生代朝生夕死的事实调整GC,避免分配大对象。具体还是得分析GC日志。
小哥哥:好,那说下mysql like有什么注意点?
我:最左匹配,防止全表扫描而不走索引
小哥哥:那说说mysql查找过程
我:就拿命中索引的说吧,innodb主键是聚簇索引,采用b+树结构,非叶节点存的是主键和指向子节点的指针,叶子节点存的就是整体行数据,整体都是有序的,通过主键扫描根据树查找,最终落到叶子节点,命中然后返回。(其实更细的有mysql的一页有16kb,一页其实有多行记录,命中一页之后还要通过行记录索引通过二分找到行记录)
小哥哥:那知道LSM树么?
我:(LSM,其实我是知道的,而且我还做过笔记,不过当时就是好耳熟啊...然后就没然后了)我说听过,但是不太记得 小哥哥:那cassandra知道么?


推荐阅读