一、面试问题
- 自我介绍
- 问到了开源社区的经历,有没有投入到开源社区的建设。
- 学习技术的初心是什么?
- 实习期间碰到的困难有哪些?
- 实习期间有什么难忘的事情?
以上部分聊了十分钟
- 对LRU的理解,使用LRU算法实现一个缓存,说下思路。
- 如何判断一个单链表中是否有环。
- 说下快速排序。快速排序的空间复杂度最优可以是多少?
- 说说一致性Hash算法。
- 说下HTTP的常用状态码。
- 为什么开始用Socket写,后面用Netty框架改进。
- 说一下Netty的NIO。
- Netty里如何处理粘包和拆包。
- 之前有做过Java Web的相关项目吗?
- 谈谈对cookie和session的理解。
- 在分布式集群情况下如何处理session会话?
- 但是如果前端的请求没有命中确定服务器,怎么处理session请求。
- 还有什么方案呢?(讲到分布式集群这块的时候通话不是很清晰)
- 说一下数据库事务的特性。
- 说一下脏读、不可重复读和幻读的区别。
- 说一下MySQL中的四种隔离级别。
- 说一下主键和唯一索引的区别。
- 说一下乐观锁和悲观锁,结合数据库方面。
- 数据库里实现乐观锁我们可以怎么做?用SQL实现下。
- Java的锁优化机制清楚吗?
- 谈谈你对JVM内存分区的了解。详细说下堆吧。
- 再说得详细些。
- JVM对象回收涉及到哪些算法?不同情况采用什么算法。
- 那再说一下Java的双亲委派机制。
- 对Java反射这块有了解吗?
- Spring经常用的注解有哪些?
- 我们聊一下设计模式吧,说一下策略模式,代理模式。
以上聊了40分钟
- 聊一下个人的优点和不足吧。
- 平时老师、同学,或者同事、主管对你是怎样的评价。
- 说一下个人往后规划的方向。
- 平时学习的话会从哪些地方获取知识。
- 好,我没有问题了,你有啥想问的。
以上聊了10分钟
二、薄弱环节复盘
大厂,尤其是阿里和腾讯,分布式的知识是一个重点考察方面,作为加分项存在。
本次面试中的session一致性问题以及一致性hash算法就是分布式中的知识点。
(一)session一致性
问题背景:分布式集群情况下,如何保证在反向代理情况时,可以在对应web服务器上找到正确的session。
单机情况
在单机情况下是不存在session一致性问题的,因为所有session都在一台服务器上,会话请求通过Nginx反向代理服务器肯定会命中服务器,找到对应的session。(如下图所示)
分布式情况
但在分布式情况下问题就变得复杂了起来,Nginx负责转发请求,但因为Tomcat集群有多台机器,假如我们需要请求的session在第一台机器上,但Nginx把我们的请求转发到第三台机器上,这样就命中失败。后果是Nginx返回一个错误信息,告知用户需要重新登录或者重新提交。
解决之道(两个主流方案)
一、后端集中统一存储
将所有的session都存储在web服务器的存储层,如redis缓存。
因为session的读取频率很高,redis能较好得满足高可用的需求。如果采用数据库的话可能压力比较大。
这样做的优点是
- web服务器重启或者扩容都不会造成session数据丢失。
- 方便维护和扩展。
- 没有安全隐患。(和将session保存在客户端相比)
缺点是增加了一次网络调用,同时因为涉及到架构调整,还要修改对应的代码。
二、反向代理hash一致性
目的:保证一个用户的所有请求都落到一台web服务器上。
有两种方案,分别是四层代理hash和七层代理hash。
- 四层代理hash:利用用户的IP地址做hash运算,以保证同一个IP的请求都落在一台服务器上。
- 七层代理hash:使用HTTP协议中的某些业务属性来做hash,例如sid,user_id等,能够更加灵活地实施hash策略,以保证同一个浏览器用户的请求落在同一个web服务器上。
这样的话,只要hash函数设置得好,使hash分布均匀,那么多台服务器就是负载均衡的。而且只需要修改nginx的配置即可,不需要修改功能代码。它也支持web服务器的水平扩展。
缺点的话,服务器重启时会丢失session数据,但这可以认为是session过期(session本身就有生命周期),让用户重新登录即可。还有,web服务器水平扩展时需要进行rehash,这可能导致部分用户的session无法正常找到。