快手Java 二面 45min
这面感觉有点不对劲,时间太短了
一上来根据项目问了一道场景题:MySQL主从复制读写分离后,主从之间存在延迟,在一个操作内发成写后读,未读到正确数据怎么办?(我的个人博客中根本不涉及到写后读这种操作,一上来就把我问蒙了,所以答得感觉不是很好,说了一种思路是同一个事务下读同一个库,另一种思路是业务线程内等待但是会影响响应时间,感觉都不太对,有懂的老哥指点一下。。。)
第二道场景题:分库分表后如何读写分离?(没GET到,我认为分库分表后读写分离与单表的读写分离其实差别不大,懂的老哥指点一下。。。)
第三道场景题:按userid分库分表后,A部门的user可能分布在不同的库表中,想查询所有A部门的user只能全查吗?(懵,懵的不行,我答的:首先我会考虑如果有这个业务需求,是否当初分库分表的设计有问题。其次如果确实存在大量按userid分表的需求,同时又存在这个需求,我能想到的解决方案是借助Redis按部门存储数据,避免扫库。但是这样只适用于查询需求只需要查询user的部分信息,存缓存的开销可以接受。如果想全部信息都查的话,在我的理解里只能全表查或者借助分布式存储引擎去查,懂的老哥指点一下。。。)
项目提问:说一下用token鉴权的流程,主要就说的SpringSecurity的流程,以及在前端的localstorage存储Token
然后就做题了???做题了??? 到这才30分钟
算法题:三数之和,秒了。。。
做完题直接来了个毫无关联的八股,String是不是final的。。。我说是。。。然后就没然后了,
又来个八股,怎么解决HASH冲突,说了拉链法,开放寻址法(顺序寻,间隔寻)
然后就反问了,整体过程刨去反问只有40分钟不到。。。感觉不太对。。。唉,随缘了
----------------------------------两个小时后约三面了----------------------------补充一下场景题解答
首先第一个场景题其实应该很常见,我上网一查就查到很多博客(而且这个场景题与一面面到我的那个题是同源的。。。就这个没去查,结果二面又考了,惭愧):
首先会出现延时是由于MySQL默认基于binlog-pos的复制是异步复制,即当写操作执行完就直接返回客户端,后期异步去更新从库。那第一个很简单的解决方式就是将MySQL的异步复制改为半同步复制或全同步复制,半同步复制实质上就是部分同步的更新从库,必须有一个从库将数据存入relaylog后向主库发送一个ACK确认包,主库收到确认包后才会提交事务并返回客户端,需要安装半同步插件semisync_xxx.so 并启用。半同步复制更侧重于预防主节点挂掉之后数据丢失问题,无法解决时延问题,必须采用全同步复制(组复制)解决,组复制的要求就更加严格,当主节点事务执行时,必须全部节点事务执行完成才能返回(性能怕是会降低很多)。第二种方式就是我面试中回答的,对于特定操作比方说同一事务内强制访问主库,这个需要业务代码调整。第三种方式可以在每次写主库时记录一个key到Redis中,过期时间为主从复制的延时,在写操作之后轮询查询Redis中是否存在Key值,如果存在则代表当前有数据可能处于主从未同步的状态则等待,这个其实就是我说的写完等待的具体实现。
第二个场景题确实是个陷阱,分库分表后的读写分离实际与单表读写分离没有太大区别。
第三个场景题后来我理解,可能面试官想问的是分库分表后如何查询数据。这个直接使用ShardingJDBC即可,ShardingJDBC既提供了读写分离的功能也提供了分库分表查询的功能。具体原理就不写在这了,感兴趣的童鞋可以自行查阅。