常见面试题
MySQL
存储引擎
mysql5.1之后默认的就是Innodb,之前时MyISAM。
InnoDB支持事务,外键,mysql能不做集群就不做,因为要考虑分布式事务,很麻烦。
事务
非常重要,尤其是隔离级别的。
要实现隔离性就要加锁
锁
MyISAM默认是表级锁,不支持行级锁,锁的粒度比较粗,Innodb默认是行级锁。
在给一个表加共享锁(S)之前要先加IS(意向共享锁)。在加排他锁(X)之前,先加意向排他锁(IX)。
间隙锁:例如我要查找id大于100的,但是表中的数据直到id为103的,那间隙锁就加在104,105不存在的.。。。。。为什么这样呢?防止我在读的时候,有人插入(幻读)。
执行DQL语句时,默认不加锁,想加锁在写sql语句时实现。
死锁
行级锁有可能会出现死锁(表级锁不存在),
场景:事务1先更新id1,再更新id2。同时事务2先更新id2,在更新id1.这时id1被事务1加了锁,id2被事务2加了锁,两者出现了互等。
数据库加得锁都是悲观锁,不用他的加锁机制,自己可以使用乐观锁。当更新操作多,使用悲观锁,当大部分都是查询数据使用乐观锁。
version是更新前查到的,如果我去更新之前读到的version是2,但是我去更新的时候version变成了3,说明有人改了数据,这时就会更新失败。
当内存值等于旧值时,才去用新的值更新它。
事务是为了保证数据的一致性,完整性,安全,索引是为了提高效率
索引
索引相当于书的目录。
Redis
数据类型
过期策略
淘汰策略
缓存穿透
缓存击穿
某个数据
缓存雪崩
大批量数据(大量key同时失效)
降级:返回空值或者是默认值。(五千个请求但是我只能处理两千个,两千个正常处理,剩余的三千返回默认值)
分布式锁
多个进程都能访问到的地方,那就不能放在内存里了。()
将锁存在数据库里(多个server存在数据库里,redis里,zookeeper里)
单个Redis实例实现分布式锁
为什么不使用redis命令来释放锁,而是用Lua脚本呢?
因为使用redis命令释放锁,可能会出现A客户端加锁,阻塞了,在阻塞过程中,锁过时了释放了,这时B客户端加锁,这时就把别人的锁给释放了。
多Redis实例实现分布式锁
Spring
Spring IoC
Bean的作用域
Spring AOP
Spring MVC
Handler Mapping:2:根据访问路径找到controller。
HandlerExecutionChain:4:里面有了能处理访问请求的controller和拦截器。
之后并不是直接去调controller,而是去调HandlerAdapter:里面封装了controller,在此之前先调用拦截器的preHandle方法。执行controller后得到ModelAndView返回给DispatcherServlet,它再将模板和数据给ViewReslover,ViewReslover将数据给View,View渲染显示页面给客户端,之后执行拦截器的afterCompletion方法。