总结
三个工作日收到了offer,头条面试体验还是很棒的,这次的头条面试好像每面技术都问了我算法,然后就是中间件、MySQL、Redis、Kafka、网络等等。
- 第一个是算法
关于算法,我觉得最好的是刷题,作死的刷的,多做多练习,加上自己的理解,还是比较容易拿下的。
而且,我貌似是将《算法刷题LeetCode中文版》、《算法的乐趣》大概都过了一遍,尤其是这本
《算法刷题LeetCode中文版》总共有15个章节:编程技巧、线性表、字符串、栈和队列、树、排序、查找、暴力枚举法、广度优先搜索、深度优先搜索、分治法、贪心法、动态规划、图、细节实现题
《算法的乐趣》共有23个章节:
- 第二个是Redis、MySQL、kafka(给大家看下我都有哪些复习笔记)
基本上都是面试真题解析、笔记和学习大纲图,感觉复习也就需要这些吧(个人意见)
- 第三个是网络(给大家看一本我之前得到的《JAVA核心知识整理》包括30个章节分类,这本283页的JAVA核心知识整理还是很不错的,一次性总结了30个分享的大知识点)
首先,我们知道项目启动后,SpringBoot会装配
对应的mapper接口文件和.xml文件到mybatis的configuration
的mappedStatements
中。里面有对应sql的全部内容,包括完整语句,拆分拼接语句等的内容
。
在开始之前,mybatis的sql执行流程中必然会涉及到代理设计模式
,具体的内容可以参考《代理模式》
我们调用selectCount()
方法,查询数据库的时候。
他会执行这个方法对应的代理对象。
他所对应的代理对象执行的类PageMapperProxy
因为他实现了InvocationHandler
,所以他需要重写了invoke()
方法
- 上来先判断他是否是Object类本身,如果是就不增强
- 判断缓存中是否有对应方法的缓存,如果缓存中没有,则创建一个,并添加到缓存中
- 调用
mapperMethod.execute
方法执行sql
判断对应的sql执行类型:
- 首先上来会判断此次执行的sql是什么类型的操作
- 这次我们执行的操作是
Select
操作,他细分了具体的内容,如是否有返回值/多个/map/标记等的具体划分
-
这次的查询都不符合,我们查询的是count数量,所以最后返回的是一个值,就执行
else
里面的convertArgsToSqlCommandParam
。 -
一看方法名都能猜的出来,就是把对应的sql和我们的传入的参数做整合在一起
command.getName()
:获取到需要执行方法的全限定名
param
:对应传入的参数
sqlSession.selectOne(command.getName(), param)
这个方法又被代理
- 执行的AOP前后额外内容的结构如下:↓
获取对应sqlSession会话:
- 他在前置执行
获取了对应的sqlSession
,在里面执行了对应的操作,并执行openSession()
,打开获取这次会话
- 注意,这里的
autoCommit
为false,不自动提交会话
- 根据对应的设置构造一个
DefaultSqlSession
对象返回
- 返回sqlSession
- 发现
method.invoke(sqlSession, args)
,它又又又被代理了 3次!!!
selectList:
- 最后,他执行
selectList()
-
我们会发现,上面我们是查询一个返回对象,但是最后还是执行的selectList()方法。
-
但是,他会在下面对个数进行判断,如果是一个拿到集合第一个返回,如果多个就报TooManyResultsException错误,不然就返回null
- 他封装了两层的selectList(),传入的statement就是方法的全限定名,parameter顾名思义就是这次查询的参数
- 最最最最最最最最最!!!!关键的一步骤。
-
MappedStatement你还熟悉吗???
configuration.getMappedStatement(statement)
-
他根据方法的全限定名来拿到已经拼接好的sql语句
- 拿到的这个ms,就是这个方法对应的sql语句
MappedStatement ms = configuration.getMappedStatement(statement);
- 然后用执行
executor
executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
- 但是发现,它又被代理了一层
Plugin:资料
-
这个叫
Plugin
的类是啥,我们看名字可以看出是插件 -
这个
Plugin
类的mybatis提供第三方进行拦截的插件类,加上插件就是通过这个类的wrap()方法
- 比如PageHelper分页插件,他就会有个
PageInterceptor
- 这里就是自定义的拦截器第三方插件了,他就循环遍历。
- 比如阿昌这里装了
PageHelpe
r,那这里就会执行PageHelper的拦截器PageInterceptor
的intercept
方法
- 因为这里,我们并没有使用PageHelper的分页方法,所以就不会执行,会被放行,他会根据对应参数个数,来生产对应的CacheKey
CacheKey:如下,根据各种信息拼接,最后成一个长字符串
-
肯定有老哥说,搞了半天怎么还没执行我们写的sql方法啊!!!!!
-
对于这里生成了对应的CacheKey后,他就会执行正式的方法了!!!。
executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql)
:↓
- 他先看看MappedStatement的
cache缓存
里面有没有,那这里,因为我们是第一次执行,必然没有缓存
-
查询的过程,一开始会判断Executor关了没。没关就去缓存中拿,有就处理下返回,没有就去从数据库查。
-
这里会涉及到一个
queryStack
,queryStack为0时就会清空本地的缓存clearLocalCache()
- 那我们看如果没有缓存,从数据库中查是什么逻辑
queryFromDatabase
-
他会给本地缓存先放一份这个内容,
-
Key:为我们之前生成的CacheKey
-
Value:
EXECUTION_PLACEHOLDER
占位符 -
localCache.putObject(key, EXECUTION_PLACEHOLDER);
- 然后他就去数据库查,他就怎么查呢,这里他会根据对应那种类型的Executor来有不同的逻辑,我们这里是用的
SimpleExecutor
- 根据ms获取到对应的mybatis的配置类信息,然后配置信息参数,sql语句等信息获取到对应的
StatementHandler
,他就是实际负责操作 Statement 对象与数据库进行交流
有人肯定会不知道
Statement
是什么,Statement 是Java 执行数据库操作的一个重要接口,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。Statement对象,用于执行不带参数的简单SQL语句。
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
,不要写无关能力;
2. 项目经历:只写明星项目,描述遵循 STAR 法则;
3. 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
[外链图片转存中…(img-nzRNKJJZ-1715683858524)]
[外链图片转存中…(img-Qm2vRt2h-1715683858524)]
[外链图片转存中…(img-VoQSS0bg-1715683858525)]