MindMap

JMM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
mindmap
root((JMM<br/>Java Memory Model))
本质
并发访问共享变量的规则
不是JVM物理内存分区
解决线程间可见性与有序性问题
核心目标
原子性
可见性
有序性
抽象模型
主内存
存共享变量
工作内存
每个线程私有副本
线程先读副本再写回主内存
问题来源
缓存不一致
指令重排
并发交错执行
关键机制
volatile
保证可见性
禁止部分指令重排
不能保证复合操作原子性
synchronized
保证原子性
保证可见性
保证有序性
final
构造完成后安全发布
对final字段有特殊可见性保障
Happens-Before
程序次序规则
锁规则
volatile规则
start规则
join规则
传递性
重排序
编译器优化
CPU乱序执行
单线程遵守as-if-serial
多线程可能出问题
经典场景
volatile标志位
DCL单例
i++线程不安全

JUC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
mindmap
root((JUC<br/>Java Util Concurrent))
本质
Java并发编程工具箱
高层并发组件
覆盖任务执行 锁 容器 协作 异步
包结构
java.util.concurrent
java.util.concurrent.locks
java.util.concurrent.atomic
任务执行
Executor
ExecutorService
ScheduledExecutorService
ThreadPoolExecutor
Future
锁体系
Lock
ReentrantLock
ReadWriteLock
ReentrantReadWriteLock
Condition
底层支撑
AQS
LockSupport
CAS
volatile
原子类
AtomicInteger
AtomicLong
AtomicReference
AtomicStampedReference
LongAdder
并发容器
ConcurrentHashMap
ConcurrentLinkedQueue
CopyOnWriteArrayList
ConcurrentSkipListMap
ConcurrentSkipListSet
阻塞队列
BlockingQueue
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue
同步器
CountDownLatch
Semaphore
CyclicBarrier
Phaser
异步与并行
ForkJoinPool
ForkJoinTask
CompletableFuture
CompletionStage
面试主线
线程池参数与拒绝策略
AQS原理
CAS与ABA
ConcurrentHashMap
BlockingQueue生产者消费者
CountDownLatch与CyclicBarrier区别
CompletableFuture链式编排

设计模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
mindmap
root((设计模式 Design Patterns))
设计目标
提高可维护性
提高可复用性
提高可扩展性
降低耦合
提升沟通效率

设计原则
SOLID
SRP["单一职责原则 SRP
一个类只做一类事"]
OCP["开闭原则 OCP
对扩展开放 对修改关闭"]
LSP["里氏替换原则 LSP
子类可替换父类"]
ISP["接口隔离原则 ISP
接口要小而专"]
DIP["依赖倒置原则 DIP
面向抽象编程"]
其他原则
CARP["合成复用原则
多用组合 少用继承"]
LoD["迪米特法则
只和直接朋友通信"]

分类
创建型模式
核心["关注对象怎么创建"]
简单工厂
工厂方法
抽象工厂
单例
建造者
原型
结构型模式
核心["关注类和对象如何组合"]
适配器
代理
装饰器
外观
桥接
组合
享元
行为型模式
核心["关注对象如何协作和分配职责"]
观察者
责任链
策略
状态
模板方法
命令
迭代器
中介者
备忘录
访问者
解释器

创建型高频
工厂模式家族
简单工厂
优点["创建逻辑集中"]
缺点["新增产品要改工厂
违反开闭原则"]
工厂方法
优点["扩展新产品更方便
符合开闭原则"]
缺点["类数量增加"]
抽象工厂
核心["创建一整套产品族"]
优点["同一风格产品统一切换"]
缺点["新增产品等级结构困难"]
单例模式
核心["一个类只有一个实例"]
写法
饿汉式
懒汉式
同步方法懒汉式
DCL["双重检查锁 DCL"]
静态内部类["推荐"]
枚举单例["推荐"]
关注点
线程安全
懒加载
防反射破坏
防反序列化破坏

结构型高频
适配器模式
核心["接口不兼容时做转换"]
角色
Target["目标接口"]
Adaptee["被适配者"]
Adapter["适配器"]
实现
类适配器["继承实现"]
对象适配器["组合实现 更推荐"]
代理模式
核心["控制对目标对象的访问"]
作用
权限控制
日志
事务
延迟加载
远程调用
Java实现
静态代理
JDK动态代理
CGLIB代理
装饰器模式
核心["不改原类前提下动态增强功能"]
对比代理
装饰器更强调功能增强
代理更强调控制访问

行为型高频
观察者模式
核心["一对多通知机制"]
适用
事件发布订阅
消息通知
状态变化广播
责任链模式
核心["多个处理器串成链逐个处理"]
适用
过滤器链
拦截器链
审批流
策略模式
核心["封装可替换算法"]
优点
消除大量 if else
算法可自由切换
符合开闭原则
适用
支付方式
促销计算
负载均衡
状态模式
核心["状态不同 行为不同"]
适用
订单状态流转
工作流状态机
对比策略
策略["重点在算法替换"]
状态["重点在状态驱动行为变化"]

面试回答主线
第一步["先说属于哪一类模式"]
第二步["再说解决什么问题"]
第三步["讲核心角色和结构"]
第四步["补优缺点"]
第五步["结合框架或项目举例"]

框架里的影子
Spring
工厂["BeanFactory"]
代理["AOP 事务"]
观察者["事件机制"]
JDK
单例["Runtime"]
工厂["Calendar getInstance"]
迭代器["Iterator"]
Netty
责任链["Pipeline"]
Dubbo
代理
装饰器
策略
责任链

API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
mindmap
root((Java 刷题常用 API))
输入输出
BufferedReader
readLine
配合StringTokenizer快读
StringTokenizer
nextToken
hasMoreTokens
Scanner
nextInt
next
nextLine
写法简单
大数据较慢
System.out
println
print

基本常量与包装类
Integer
MAX_VALUE
MIN_VALUE
parseInt
valueOf
compare
bitCount
Long
MAX_VALUE
MIN_VALUE
parseLong
compare
Double
compare
Character
isDigit
isLetter
toLowerCase
toUpperCase
Boolean
parseBoolean

Math与数值
Math
max
min
abs
sqrt
pow
ceil
floor
round
random
BigInteger
超大整数
BigDecimal
少数题会用
精度控制
常见意识
初始化最大最小值
注意int溢出转long

数组 Arrays
常用操作
length
二维数组
clone
Arrays工具类
sort
binarySearch
fill
copyOf
equals
compare
toString
deepToString
高频场景
排序
二分
初始化
拷贝

字符串 String
基本操作
length
charAt
substring
indexOf
lastIndexOf
startsWith
endsWith
contains
转换
toCharArray
valueOf
split
替换与比较
replace
replaceAll
equals
compareTo
高频注意
不可变
拼接多时少用加号

可变字符串
StringBuilder
append
insert
delete
deleteCharAt
reverse
setCharAt
charAt
length
toString
StringBuffer
线程安全
刷题少用

List与动态数组
ArrayList
add
get
set
remove
size
isEmpty
contains
常见用法
存答案
邻接表
二维List
注意
remove重载
按下标与按对象区别

哈希结构
HashMap
put
get
getOrDefault
containsKey
remove
putIfAbsent
computeIfAbsent
merge
keySet
values
entrySet
HashSet
add
contains
remove
高频场景
计数
去重
前缀和
图与映射
易忘好用
getOrDefault
computeIfAbsent
merge

有序结构
TreeMap
put
get
floorKey
ceilingKey
lowerKey
higherKey
firstKey
lastKey
TreeSet
add
contains
floor
ceiling
lower
higher
适用
有序去重
最近值
区间问题

队列栈双端队列
ArrayDeque
addLast
pollLast
peekLast
addFirst
pollFirst
peekFirst
push
pop
Queue接口
offer
poll
peek
常见用途
单调栈
单调队列
BFS
普通栈
注意
Stack老旧
刷题优先ArrayDeque

优先队列堆
PriorityQueue
offer
poll
peek
size
isEmpty
默认
小根堆
自定义比较器
大根堆
按数组某列排序
高频场景
TopK
贪心
Dijkstra

链表与节点
LinkedList
addFirst
addLast
pollFirst
pollLast
刷题定位
能用
但队列栈更推荐ArrayDeque
自定义ListNode
next
val

排序与比较器
Arrays.sort
基本类型数组
二维数组加比较器
Collections.sort
List排序
Comparator
comparingInt
comparingLong
reversed
Comparable
自然排序
常见写法
lambda比较器
多关键字排序

位运算
运算符


异或
取反
左移
右移
无符号右移
Integer位工具
bitCount
highestOneBit
lowestOneBit
numberOfLeadingZeros
numberOfTrailingZeros
高频场景
状压
判奇偶
lowbit

其他常用
Collections
reverse
swap
max
min
frequency
Objects
equals
hash
System
arraycopy
currentTimeMillis
StringTokenizer加BufferedReader
ACM快读模板核心

数据结构总览
数组
int
long
char
字符串
String
StringBuilder
哈希
HashMap
HashSet
有序
TreeMap
TreeSet
线性表
ArrayList
栈队列
ArrayDeque

PriorityQueue

最该记住
Math.max min abs
Integer.MAX_VALUE MIN_VALUE
Long.MAX_VALUE MIN_VALUE
Arrays.sort fill binarySearch
HashMap.getOrDefault
HashMap.computeIfAbsent
HashMap.merge
ArrayDeque做栈和队列
PriorityQueue默认小根堆
StringBuilder处理拼接

Spring

SpringMVC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
mindmap
root((SpringMVC))
核心定位
Web层框架
基于Servlet
处理请求与响应
属于Spring生态

核心目标
请求分发
参数绑定
返回响应
视图解析
统一异常处理

核心组件
DispatcherServlet
前端控制器
统一接收请求
统一调度流程
HandlerMapping
查找处理器
根据请求路径匹配方法
HandlerAdapter
适配调用处理器
屏蔽不同Handler差异
Controller
编写业务入口
接收参数返回结果
ViewResolver
解析视图名
定位页面资源
View
页面渲染
输出响应
Interceptor
前后置拦截
登录校验
日志统计
ExceptionResolver
统一异常处理

请求处理流程
用户发送请求
DispatcherServlet接收
HandlerMapping找Controller方法
HandlerAdapter执行目标方法
Controller处理业务
返回结果
结果分流
返回视图名
ViewResolver解析
View渲染页面
返回数据
HttpMessageConverter转换
输出Json或Xml
响应给客户端

常用注解
Controller
返回视图
RestController
返回数据
等于Controller加ResponseBody
RequestMapping
通用映射
GetMapping
PostMapping
PutMapping
DeleteMapping
RequestParam
接收请求参数
PathVariable
接收路径参数
RequestBody
接收Json请求体
ResponseBody
返回Json数据
RequestHeader
取请求头
CookieValue
取Cookie

参数绑定
基本类型
包装类型
数组
集合
JavaBean
日期类型
Json对象
文件上传
常见来源
请求参数
路径变量
请求头
请求体

返回值处理
String
视图名
ModelAndView
模型加视图
对象
转Json
List
转Json数组
ResponseEntity
自定义状态码响应头响应体
void
直接操作response

域对象与数据传递
Model
ModelMap
Map
ModelAndView
作用域
request
session
application

视图体系
JSP
Thymeleaf
重定向
redirect
转发
forward
前后端分离
多数直接返回Json

拦截器
作用
登录校验
权限控制
日志埋点
性能统计
方法
preHandle
postHandle
afterCompletion
对比Filter
Filter属于Servlet规范
Interceptor属于SpringMVC

异常处理
ExceptionHandler
局部异常处理
ControllerAdvice
全局异常处理
HandlerExceptionResolver
底层异常解析机制

数据转换
HttpMessageConverter
Json转换
字符串转换
表单数据转换
类型转换器
Converter
Formatter

上传下载
MultipartFile
单文件上传
多文件上传
文件下载
设置响应头
输出文件流

高频面试点
DispatcherServlet作用
HandlerMapping和HandlerAdapter作用
Controller和RestController区别
RequestParam和RequestBody区别
转发和重定向区别
Filter和Interceptor区别
SpringMVC执行流程
Json返回底层是谁做转换

与SpringBoot关系
SpringBoot自动配置SpringMVC
内嵌Tomcat
默认消息转换器
默认静态资源映射
开发更省配置

注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
mindmap
root((SpringMVC 常用注解))
控制器
Controller
返回视图
RestController
返回Json
等于Controller加ResponseBody

请求映射
RequestMapping
类上做模块前缀
方法上做接口映射
GetMapping
PostMapping
PutMapping
DeleteMapping
PatchMapping

参数获取
RequestParam
接收查询参数
适合name=xx
PathVariable
接收路径参数
适合user或id这类路径值
RequestBody
接收Json请求体
RequestHeader
取请求头
CookieValue
取Cookie
ModelAttribute
表单对象绑定

返回响应
ResponseBody
返回Json
ResponseStatus
指定响应状态码

结果传递
RequestAttribute
取request域数据
SessionAttribute
取session域数据

异常处理
ExceptionHandler
当前类异常处理
ControllerAdvice
全局增强
RestControllerAdvice
全局异常加Json返回

数据绑定
InitBinder
自定义参数绑定
DateTimeFormat
时间格式转换
Valid
参数校验
Validated
分组校验

跨域与会话
CrossOrigin
允许跨域
SessionAttributes
往session存模型数据

高频组合
前后端分离
RestController
GetMapping
PostMapping
RequestBody
传统页面
Controller
RequestMapping
全局异常
RestControllerAdvice
ExceptionHandler

Spring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
mindmap
root((Spring 常用注解))
组件注册
Component
通用组件
Service
业务层
Repository
持久层
Controller
控制层
Scope
singleton
prototype
request
session
Lazy
懒加载

依赖注入
Autowired
按类型注入
Qualifier
指定Bean名称
Resource
先按名称再按类型
Value
注入普通值
读取配置

配置类
Configuration
配置类
Bean
注册第三方Bean
方法名默认Bean名
ComponentScan
扫描组件
PropertySource
加载配置文件
Import
导入配置类
导入组件
ImportResource
导入xml配置

生命周期
PostConstruct
初始化后执行
PreDestroy
销毁前执行
DependsOn
指定先初始化谁

AOP相关
Aspect
切面类
Pointcut
切点
Before
前置通知
After
后置通知
AfterReturning
返回后通知
AfterThrowing
异常后通知
Around
环绕通知
EnableAspectJAutoProxy
开启AOP

事务
Transactional
开启事务
作用在类
作用在方法
EnableTransactionManagement
开启事务管理

异步与定时
EnableAsync
开启异步
Async
异步方法
EnableScheduling
开启定时任务
Scheduled
fixedRate
fixedDelay
cron

缓存
EnableCaching
开启缓存
Cacheable
查缓存
CachePut
更新缓存
CacheEvict
删除缓存

环境与配置读取
ConfigurationProperties
批量绑定配置
EnableConfigurationProperties
开启配置绑定
Profile
环境切换
Primary
默认优先Bean

常见组合
注册Bean
Component
Configuration
Bean
注入Bean
Autowired
Resource
Qualifier
配置读取
Value
ConfigurationProperties
横切增强
Aspect
Transactional
Async
Cacheable

高频记忆
Component负责注册
Autowired负责注入
Bean负责第三方对象
Configuration负责配置类
Transactional负责事务
Aspect负责切面
Value负责单个配置
ConfigurationProperties负责批量配置

SpringBoot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
mindmap
root((SpringBoot 常用注解))
启动类
SpringBootApplication
启动入口
组合注解
包含SpringBootConfiguration
包含EnableAutoConfiguration
包含ComponentScan
SpringBootConfiguration
本质上是Configuration
EnableAutoConfiguration
开启自动配置

配置绑定
ConfigurationProperties
批量绑定配置
适合前缀式配置
EnableConfigurationProperties
开启配置类绑定
ConfigurationPropertiesScan
扫描配置属性类
Value
读取单个配置
PropertySource
导入额外配置文件

条件装配
ConditionalOnClass
类存在才生效
ConditionalOnMissingBean
容器里没有Bean才生效
ConditionalOnBean
有指定Bean才生效
ConditionalOnProperty
配置满足条件才生效
ConditionalOnMissingClass
类不存在才生效
ConditionalOnResource
资源存在才生效
ConditionalOnWebApplication
Web应用才生效
ConditionalOnNotWebApplication
非Web应用才生效

自动配置开发
AutoConfiguration
自定义自动配置类
AutoConfigureBefore
指定先于谁生效
AutoConfigureAfter
指定后于谁生效
ImportAutoConfiguration
导入自动配置

环境与装配
Profile
区分开发测试生产环境
Primary
多个Bean时优先注入
Lazy
懒加载
Import
导入配置类或组件
Bean
注册第三方Bean
Configuration
配置类

Web相关扩展
ServletComponentScan
扫描Servlet
扫描Filter
扫描Listener

测试常用
SpringBootTest
启动Boot测试环境
MockBean
用Mock对象替换Bean

最该记住
SpringBootApplication
EnableAutoConfiguration
ConfigurationProperties
ConfigurationPropertiesScan
EnableConfigurationProperties
ConditionalOnClass
ConditionalOnMissingBean
ConditionalOnProperty
SpringBootTest
Profile

Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
mindmap
root((Spring Bean))
Bean是什么
Spring容器管理的对象
负责创建
负责注入
负责销毁

Bean来源
Component
组件扫描注册
Service
业务层Bean
Repository
持久层Bean
Controller
控制层Bean
Configuration加Bean
手动注册第三方对象

Bean作用域
singleton
默认单例
容器中一份
prototype
每次获取新对象
request
一次请求一个
session
一个会话一个
application
整个应用一个

Bean创建流程
扫描或解析配置
BeanDefinition注册
实例化
属性注入
初始化
放入容器
后续获取使用

依赖注入
Autowired
按类型注入
Qualifier
指定Bean名字
Resource
先按名称再按类型
Value
注入普通值

生命周期
实例化
依赖注入
Aware回调
BeanPostProcessor前置
初始化方法
PostConstruct
afterPropertiesSet
initMethod
BeanPostProcessor后置
使用
销毁方法
PreDestroy
destroy
destroyMethod

重点机制
BeanDefinition
Bean的元数据
BeanFactory
最基础容器
ApplicationContext
更高级容器
单例池
singletonObjects
三级缓存
解决循环依赖
BeanPostProcessor
扩展点核心
FactoryBean
生产Bean的Bean

常见注解
Component
Bean
Scope
Lazy
Primary
DependsOn
PostConstruct
PreDestroy

高频问题
Bean和对象区别
Bean受Spring管理
Bean和Component关系
Component是注册方式
Bean和FactoryBean区别
一个是对象
一个是生产对象的工厂
单例Bean线程安全吗
看成员变量是否共享可变
为什么默认单例
节省资源
便于统一管理
多例Bean会不会注入单例
可以
生命周期管理不同
循环依赖怎么解决
单例加三级缓存
构造器循环依赖能解决吗
不能

最该记住
Bean就是交给Spring管理的对象
默认是singleton
注册方式主要是Component和Bean
注入常用Autowired和Resource
生命周期有初始化和销毁
扩展核心是BeanPostProcessor
循环依赖核心是三级缓存

Redis

总览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
mindmap
root((Redis 总览))
定义与定位
内存数据库
Key Value存储
高性能NoSQL
支持持久化
常作缓存中间件
也可作轻量消息与计数系统

核心特性
读写快
基于内存
命令执行路径短
数据结构丰富
不只是String
支持多种结构化操作
支持高并发
适合热点访问
支持原子操作
单命令天然原子性
支持过期时间
TTL
EXPIRE
支持持久化
RDB
AOF
支持高可用
主从复制
哨兵
支持分布式扩展
Cluster集群

为什么快
内存访问
少磁盘IO
单线程命令执行
避免线程切换
避免锁竞争
IO多路复用
高效处理大量连接
高效数据结构
哈希表
跳表
压缩结构
C语言实现
执行开销低

数据类型
五大基础类型
String
List
Hash
Set
ZSet
特殊类型
Bitmap
HyperLogLog
GEO
Stream
学习重点
使用场景
常用命令
底层结构
时间复杂度

核心机制
过期机制
惰性删除
定期删除
内存淘汰
LRU
LFU
random
noeviction
持久化
RDB快照
AOF追加日志
混合持久化
事务与脚本
MULTI EXEC
Lua
发布订阅
Pub Sub
Pipeline
减少网络往返

高可用与扩展
主从复制
读写分离
数据副本
Sentinel
故障发现
自动故障转移
Cluster
分片存储
槽位机制
横向扩展

常见应用场景
缓存
热点数据缓存
查询结果缓存
计数器
点赞
浏览量
库存计数
排行榜
ZSet
分布式锁
set nx ex
会话共享
session存储
消息队列
List
Stream
去重与签到
Set
Bitmap

典型缓存问题
缓存穿透
缓存击穿
缓存雪崩
热Key
大Key
双写一致性

优点
性能高
使用简单
数据结构丰富
扩展方案成熟
社区生态强

局限
基于内存
成本高
容量受限
不适合复杂查询
不适合强事务核心业务
持久化能力弱于关系型数据库
缓存与数据库存在一致性问题

与MySQL关系
MySQL
持久存储
复杂查询
强一致业务
Redis
高速访问
热点数据
临时状态
常见组合
MySQL做主存储
Redis做缓存层

面试主线
Redis是什么
Redis为什么快
Redis有哪些数据类型
Redis怎么做持久化
Redis怎么保证高可用
Redis常见缓存问题有哪些
Redis和MySQL如何配合

五大数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
mindmap
root((Redis 五大基础数据结构))
String
本质
字符串对象
最常用类型
可存字符串数字二进制
常用命令
set
get
mget
incr
decr
append
setnx
setex
底层
SDS
记录长度
减少重复计算长度
二进制安全
典型场景
缓存对象
计数器
分布式锁
共享标记位
面试点
为什么适合计数
为什么是二进制安全
setnx加expire为什么常一起说

List
本质
有序可重复
双端链式操作
常用命令
lpush
rpush
lpop
rpop
lrange
blpop
底层
quicklist
链表加压缩列表思想
典型场景
消息队列
最新消息列表

队列
面试点
为什么适合双端操作
为什么现在底层不是单纯双向链表
和Stream做消息队列区别

Hash
本质
键值对集合
适合存对象
常用命令
hset
hget
hmget
hgetall
hincrby
hexists
底层
hashtable
listpack
小对象更省内存
典型场景
用户信息
商品属性
配置项
面试点
和String存对象区别
为什么更适合存部分字段
什么时候会从紧凑结构转成哈希表

Set
本质
无序唯一集合
自动去重
常用命令
sadd
srem
smembers
sismember
scard
sinter
sunion
sdiff
底层
hashtable
intset
整数集合时更省空间
典型场景
去重
共同关注
标签系统
抽奖候选池
面试点
为什么能去重
交并差集怎么做
intset何时升级

ZSet
本质
有序唯一集合
元素带分数score
常用命令
zadd
zrem
zrange
zrevrange
zscore
zrank
zincrby
底层
skiplist
hashtable
典型场景
排行榜
延时队列
权重排序
范围查询
面试点
为什么用跳表
为什么还要配哈希表
和Set区别
和Heap区别

横向对比
String
最简单
最通用
List
强在双端操作
Hash
强在对象字段存储
Set
强在去重与集合运算
ZSet
强在排序与范围查询

选型思路
只存一个值
String
存对象多个字段
Hash
需要先进先出或双端操作
List
需要去重
Set
需要排行榜或按分数排序
ZSet

高频易错点
String不只是字符串
List允许重复
Set无序且唯一
ZSet唯一的是元素不是score
Hash适合局部字段修改

特殊数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
mindmap
root((Redis 特殊数据结构))
Bitmap
本质
位数组
按bit存0和1
底层依赖String
常用命令
setbit
getbit
bitcount
bitop
核心特点
极省空间
适合大规模状态标记
支持位运算
典型场景
用户签到
在线状态
活跃统计
布尔标记集合
面试点
为什么节省内存
底层为什么属于String
和Set做签到对比

HyperLogLog
本质
基数统计
统计去重数量
不是精确去重集合
常用命令
pfadd
pfcount
pfmerge
核心特点
占用空间极小
统计值有误差
适合海量去重计数
典型场景
UV统计
独立访客数
搜索词去重计数
面试点
为什么省内存
为什么有误差
为什么不能拿出具体元素

GEO
本质
地理位置集合
存经纬度
底层依赖ZSet
常用命令
geoadd
geopos
geodist
georadius
geosearch
核心特点
支持附近的人
支持距离计算
支持范围搜索
典型场景
附近门店
附近骑手
LBS位置服务
面试点
为什么底层是ZSet
如何支持距离范围查询
和普通经纬度表查询区别

Stream
本质
消息流
可持久化消息队列
支持消费组
常用命令
xadd
xrange
xread
xgroup
xreadgroup
xack
核心特点
消息可回溯
支持多消费者
支持消费确认
比List更像正式消息队列
典型场景
异步任务
消息分发
日志流处理
面试点
和List做队列区别
消费组有什么用
为什么能避免消息丢失一部分问题

特殊结构对比
Bitmap
强在状态压缩
HyperLogLog
强在海量去重计数
GEO
强在地理位置搜索
Stream
强在消息流与消费组

选型思路
只关心某状态是否存在
Bitmap
只关心去重后的数量
HyperLogLog
只关心附近位置与距离
GEO
需要可靠消息流
Stream

高频易错点
Bitmap底层不是独立新结构
HyperLogLog不能精确去重
GEO底层本质是ZSet能力扩展
Stream比List更适合消息队列

持久化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
mindmap
root((Redis 持久化))
作用
宕机后恢复数据
降低内存数据丢失风险
支撑主从复制与重启恢复

持久化方案
RDB
本质
某一时刻数据快照
触发方式
save
bgsave
save规则自动触发
优点
文件紧凑
恢复速度快
适合备份
缺点
有时间点丢数据风险
fork开销大
适用场景
容忍少量数据丢失
追求恢复速度
AOF
本质
记录写命令日志
写回策略
always
everysec
no
重写机制
bgrewriteaof
压缩冗余命令
优点
数据更完整
可读性更强
缺点
文件更大
恢复更慢
适用场景
更看重数据安全
混合持久化
本质
RDB快照加增量AOF命令
特点
兼顾恢复速度
兼顾数据完整性

RDB机制
执行流程
fork子进程
子进程生成快照文件
写入临时文件
替换旧RDB
核心点
主进程继续处理请求
借助写时复制
高频问题
为什么用bgsave
fork会带来什么开销
写时复制是什么

AOF机制
执行流程
写命令追加到AOF缓冲区
按策略刷盘
重启时重放命令恢复数据
重写流程
fork子进程
根据当前内存数据重写新AOF
合并重写期间增量命令
替换旧AOF
高频问题
AOF为什么会膨胀
重写和刷盘区别
everysec为什么常用

两者对比
数据安全
AOF更强
恢复速度
RDB更快
文件大小
RDB更小
可读性
AOF更好
性能影响
RDB适合低频快照
AOF取决于刷盘策略

恢复流程
只有RDB
加载RDB恢复
只有AOF
重放AOF恢复
同时开启
优先使用AOF
混合持久化
先加载RDB部分
再执行增量命令

选型建议
只要快速备份恢复
RDB
更关注数据少丢失
AOF everysec
线上常见
RDB加AOF
或混合持久化

高频面试点
RDB和AOF区别
bgsave原理
bgrewriteaof原理
为什么AOF更安全
为什么RDB恢复更快
AOF重写会阻塞吗
RDB和AOF如何选择

易错点
RDB不是实时持久化
AOF重写不是读取旧AOF简单压缩
AOF更安全也不是绝对不丢数据
Redis持久化不能替代数据库主存储