前言
目录
1.看到你的简历里说使用Redis缓存高频数据,说一下Redis的操作
3.你的项目中使用了ThreadLocal,那么当有两个请求同时发出时,会怎么处理,可以同时处理两个请求吗
6.maven对项目进行打包,生成jar包后,要怎么找出class包
26届大三,刚开始学习java开发不久,只做了黑马程序员的苍穹外卖项目(只做了系统管理后台部分),今早去第一次面试,所以总结并记录一下这次面试。
面试完的整体感觉就是自己差的太多,还需要学很多东西。
接下来说一下整个面试的过程:
1.自我介绍
2.开始问一些技术问题
技术问题:
1.看到你的简历里说使用Redis缓存高频数据,说一下Redis的操作
先启动Redis的服务,使用Redis的Java客户端Spring Data Redis操作Redis,用来简化 Redis 操作,Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为operation接口,可以通过创建RedisTemplate的对象,使用对象操作Redis。
Spring Data Redis的使用:
- 导入Spring Data Redis的maven坐标
- 配置Redis数据源
- 编写配置类,创建RedisTemplate对象
- 通过RedisTemplate对象操作Redis
2.说一下Redis的缓存击穿、缓存穿透、缓存雪崩
缓存穿透
大量高并发的请求到达Redis,但Redis上没有请求的资源,缓存失败,这些大量的高并发请求就会转向数据库,向数据库请求资源,数据库的压力突然变大,并且在数据库中也没有找到需要的数据,就会引发一系列问题。
客户端请求的数据在缓存中和数据库中都不存在
原因
业务误操作,导致缓存中的数据和数据库中的数据都被错误删除了,所以缓存和数据库中都没有数据;
黑客恶意攻击,故意大量访问某些不存在数据的业务
解决办法
限制非法请求
在API入口处判断请求参数是否合理,比如请求参数是否含有非法制、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库。缓存空值或者默认值
当发现缓存穿透的现象时,可以针对查询的该数据,在Redis缓存中设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。(但可能导致Redis内存不足的情况)
使用布隆过滤器
在写入数据库数据时,使用布隆过滤器做一个标记,然后在用户请求到来时,先通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过就拒绝查询
缓存雪崩
当大量缓存数据同时过期和Redis故障时,大量请求访问到数据库,引发问题
原因
大量缓存数据同时过期:为了保证缓存中的数据和数据库中的数据一致性,会给Redis里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,就会访问到达数据库
缓存服务Redis故障
解决办法
设置缓存数据的失效时间尽量分散
将失效时间加上随机数,尽量保证不再同一时间失效
互斥锁
当某个请求的数据在内存Redis中不存在时,加上互斥锁,其他请求等待这个请求访问数据库并将数据更新在Redis内存中之后才继续进行访问,互斥锁需要加上过期时间,防止请求数据在数据库中也不存在造成无响应的情况
后台更新缓存
缓存不设置有限期,让缓存永久有效,将更新缓存的工作交由后台线程定时更新。
服务熔断或请求限流机制
服务熔断机制:暂停业务应用对缓存服务的访问,直接返回错误。等到Redis恢复正常后,再允许业务应用访问缓存服务。请求限流机制:服务熔断会导致全部业务都无法正常工作,请求限流机制,就只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,等到Redis恢复正常并把缓存预热完后,在解除请求限流的机制。
构建Redis缓存高可靠集群
之前说的服务熔断或者请求限流机制是缓存雪崩发生后的应对方案,为了避免由于Redis故障宕机导致的缓存雪崩问题,最后通过主从节点的方式构建Redis缓存高可靠集群,如果Redis缓存的主节点故障宕机,从节点可以切换成为主节点,继续提供缓存服务。
缓存击穿
Redis中的某个热点key过期,但是此时有大量的用户访问该过期key。
缓存击穿可以看成缓存雪崩的一个子集。
如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮了。
解决办法
互斥锁
后台更新缓存
全网最权威!Redis缓存击穿、雪崩、穿透!刷新你的三观!!!_redis bitmap hash碰撞-CSDN博客
【Redis】缓存穿透、缓存击穿、缓存雪崩的原因及解决方案-CSDN博客
3.你的项目中使用了ThreadLocal,那么当有两个请求同时发出时,会怎么处理,可以同时处理两个请求吗
这个问题记不太清楚了,问的问题记不清楚是什么样的了,对这个问题一点不知道咋回答
4.使用的是哪个版本的git
gitee(跟着苍穹外卖用的gitee)
5.假如在git提交的有两份代码,该怎么将这两份代码合并
1. merge命令
这是最常见的合并分支的方式,将其他分支合并到当前分支:
# 切换到接受合并的分支
git checkout master
# 合并指定分支到当前分支
git merge feature
2. rebase命令
rebase可以将当前分支代码 rebase 到其他分支上,实现合并:
# 切换到需合并的分支
git checkout feature
# 将feature rebase到master上
git rebase master
3. cherry-pick命令
可以只picked某些提交应用到其他分支:
# 切换到目标分支
git checkout master
# 拣选feature中的某些提交
git cherry-pick <commitA-id>
git cherry-pick <commitB-id>
4. squash合并
将多次提交squash为一个提交然后合并:
git merge --squash feature
5. 临时合并(no-commit merge)
合并后不自动提交,可进行额外操作:
git merge --no-commit feature
# 对合并结果进行操作
git commit
IDEA中使用Git提交代码(包括合并分支)_idea提交git-CSDN博客
6.maven对项目进行打包,生成jar包后,要怎么找出class包
7.说一下优化数据库的方法,可以在哪看到数据库语言的优化
谈谈几种数据库优化方法和依据的指标_如何根据指标做优化-CSDN博客
8.说一下mysql中的单列索引和联合索引
9.#{}和${}的区别
在Mybatis中提供的参数占位符有两种:${...} 、#{...}
-
#{...}
-
执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值
-
使用时机:参数传递,都使用#{…}
-
${...}
-
拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
-
使用时机:如果对表名、列表进行动态设置时使用
-
预编译处理
性能更高:预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译。(只是输入的参数不同)
更安全(防止SQL注入):将敏感字进行转义,保障SQL的安全性。
10.怎么防止sql注入
使用#{},进行预编译处理,将敏感字进行转义,保障SQL的安全性
11.平时使用什么进行前端的编码,你可以修改前端的代码吗
vscode,能看懂前端代码,没试过修改前端代码
最后问了一下我的期望薪资
)我说2-3k
(本来想说薪资没有也行,毕竟第一段实习,收我就行,太抽象了,没敢说)
总结
只记得这些题目了,可能会有题目记错的情况,然后我在网上搜了一下相关的,把回答写了上去,不一定对,有些题目暂时不确定,等确定答案之后再回来改。
在这次面试中,我看到了我自己的好多问题,知识掌握的太过潦草,匆匆忙忙做了一半的项目就去投简历面试,准备的不够充分。但也给了我一些学习方向,苍穹外卖目前后台系统管理基本做完,增删改查都做过了,先暂停外卖,转方向Git、数据库优化和Redis,感觉面试官对Redis更感兴趣,数据库虽然学过了,但感觉学得并不深入,只要一问就傻眼,所以先把这几个部分补一下。
关于Git [Git] Git下载及使用 详解(附下载链接)-CSDN博客
数据库优化和Redis之后附上链接
不会就去学,反正还能学,做一件事最好的时间是十年前,其次是现在。