技术面试记录
很久没面试了
一下理论都没回答上几个,反正也记录下,当是一个学习吧。有的是当时没想起来,或者没意识到是这么回事
1、Spring Boot 2特性
1.1、Jdk8+
1.2、Optional广泛应用(感觉源于swift语言,可选对象),1中也有用到,但是需要自己显示调用
** 我个人比较喜欢在dao中使用,真的不愿意再写if (entity != null)了,很烦
1.3、其他由于也是看别人写的内容就不记了,没有涉及到验证过的,写了可能是错误误导
对于使用的人来说,和1的版本没有太明显的差别
2、Redis缓存穿透
初时没太理解为什么要问这个问题,也以为自己没有遇到过,后面仔细想想,在接口访问这块实际上遇到过。
问题不复杂,解决方式也不难(并不是说所有解决的方式都不难,只是单纯解决不难,实际业务场景可能很难)
大概的原因就是数据库和Redis中都没有数据,而redis不缓存null。导致每一次请求,都会耗费大量资源(通常会做缓存的,也是每次执行时间较长的,或者访问频率很高的)
2.1、最简单的做法就是,一定不会返回null
2.2、还有一种做法是限定获取新数据的时间,比如十分钟内不会执行访问数据库(一般对于数据实时性要求不是很高的情况下,限制刷新缓存的时间会合适)
2.3、算法型:布隆过滤器-缺点是概率性,只能证明一定不存在,不能证明一定存在,所以算是一种概率性优化
衍生问题:
* 缓存击穿,通常指一个key过于热门,导致在失效的瞬间,有大并发访问
* 缓存雪崩,通常指很多key同时失效,同时访问持久层,与缓存击穿主要差别在于多个key失效
个人初步思路是:
* 一般认为手动提前触发可能失效的key
* 可以参考转发的方式,比如说一个网站的启动时间非常慢,我们可以在启动期间把域名指向另一个网站,比如说单页面网站:系统维护中。等到网站启动完成后,再把转向地址变更
最近重读了代理模式,感觉可以应用代理模式的访问控制特点:对数据库访问做一个拦截,保证同一时间只有一个进程在访问数据库;如果不是很在意数据的实时性,可以采用新数据替换后旧数据才过期的方式
3、Java线程池种类
五种:其中两种更像是衍生的 - 缓存线程池、固定线程池、单例固定线程池、定时计划线程池、单例定时计划线程池;还没有查询之前自己猜测是用来固定执行顺序用的,好像猜对了
其实之前爬虫用到过,也为了执行顺序的问题曾经采用了单例,当时傻傻的,用的是固定线程池,然后指定1
首先思考线程池存在的目的:并发,但每次并发都创建新的线程是一件更耗资源的事情,就好像自动开关的电灯如果几乎不关闭的情况下,肯定比一直开着的电灯更耗电
其次,不同线程池解决的问题:
* 缓存线程池:可增长,优点:按需创建,可回收空闲线程;缺点:也很明显对应优点,即可能存在太多线程,导致系统崩掉
* 固定线程池:优点:就是可控。。。。算吗 缺点:如果核心数量不合适,就有点尬
* 单例固定线程池:就是保证顺序执行
* 定时固定线程池:支持定时执行,个人理解是在固定线程池的基础上,在外面继续包一层定时触发的接口;优点:支持定时执行;缺点:估计就是如果执行时间比较长,可能池里面的任务会太多
* 单例定时固定线程池 :就是保证顺序执行
* 抢占线程池:也解释为任务窃取,大致的原理是(计算机也多是采用时间片的方式,即给每一个线程一定时间片执行,执行结束后换给另一个线程):本来线程池各自分配的任务,各自完成即可;现在如果我完成了自己的任务,我就去帮一下你。这边理解也不一定对,后面有深入再更新;这边理解的是计算机的并发本质上也是把执行切割成时间片,比如0.1毫秒一次,这样子,执行时间少的任务就能被执行完成,造成一种并发执行的感观;同时也适用于有些任务需要等待的场景(优化到位的话,性能就会有大的提升)
4、支付网络抖动
* 通过定时器去同步状态
* 通过异常检测去判断是否产生异常单,用于定时器也无法处理的场景
不太确定为什么问这个问题,难道还有更好的方式,这边没想到。
5、Java8特性
* lambda 表达式
* Optional 可选值(这个也是比较好用的特性)
* 接口默认方法
* Stream-链式调用、集合优化(这个用的比较多)、视图副本
* 上面提到的抢占线程池
* 算法优化,例如HashMap,超过一定数量之后就使用红黑树 大致的特性是插入会比较复杂,但是查询的复杂度会在log(n),比较高效
6、HashMap在Java8的差别
* 7中是数组,8中采用了红黑树;总结起来是算法的复杂度进行了优化2^n变成logN
* 红黑树的概念等了解之后再来补充
7、创建线程的方式(我没想到还真的是问这个,看来是被鄙视了,所以当时没反应过来)
7.1、实现Runable接口-通过线程、或线程池工具执行,如CompleteableFuture,或线程池服务类submit(runable)
7.2、继承Thread,调用start方法
8、Redis的持久化
8.1、RDB:快照;缺点:快照期间的数据可能丢失,丢失量比较大;相当于一次全量存储,所以按理执行速度会受到影响,存的时候比较慢,取的应该比较快
8.2、AOF:日志型,可能和mysql的binlog比较接近,通过日志记录产生的数据;恢复起来比较慢;相当于多次存,所以取起来比较麻烦