00-面试题杂项整理(新)
(持续维护…)
Java
1 |
|
集合
1 |
|
线程
1 |
|
锁&原子类
1 |
|
JVM
1 |
|
MySQL
1 |
|
事务
1 |
|
Redis
1 |
|
Spring
1 |
|
SpringMVC
1 |
|
SpringBoot
1 |
|
SpringCloud(微服务)
1 |
|
中间件
Nacos
1 |
|
MyBatis&MyBatisPlus
1 |
|
ElasticSearch
1 |
|
Netty
1 |
|
MQ消息队列
1 |
|
RPC&Feign
1 |
|
Dubbo
1 |
|
OAuth2.0
1 |
|
源码分析
1 |
|
设计模式
1 |
|
程序设计
1 |
|
其他概念
1 |
|
具体场景
1 |
|
技能描述(旧)
熟练 Java
面向对象
编程(OOP),常用数据集合
和IO
,熟悉 python/shell 编程写过工具一直在用;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【面向对象】
1.什么是面向对象 / 什么是OOP?
面向对象的方法主要是把事物给对象化,包括其属性和行为。贴近实际生活,万物皆对象。
2.面向对象的四大特征五大原则
4大特征:封装、继承、多态、抽象。
5大原则:
单一职能:每个模块、每个类、每个方法都只负责一件事情。
开放关闭:对功能扩展开放,对修改源码关闭。Java世界里最基础的设计原则。
里式替换:任何父类可以出现的地方,子类一定可以出现。子类可以无障碍地替换父类 - 多态
接口隔离:多个专门的接口比使用单一的总接口要好。
依赖倒置:面向抽象进行编程,高层不依赖底层,抽象不依赖细节实现。
3.接口回调
类A调用类B的方法b(),类B再回调类A的方法a(),其中方法a()是定义在接口中的,由类A来实现。这是一个双向调用的过程。
【数据集合】
1.List、Set、Map、Queue的各种集合和特点?
>>>List<<<
ArrayList:数组,线程不安全,查询快,增删慢,jdk1.2。jdk1.7无参默认长度为10,jdk1.8懒加载add才有10,扩容因子1.5倍,懒加载
Vector:数组,线程安全。方法与ArrayList相同,synchronized修饰所有操作方法。
LinkedList:链表,增删快,查询慢。无需开辟连续空间。
>>>Set<<<
HashSet:不重复+无序,hashCode -> == -> equals 实现不重复
LinkedHashSet:记录保留元素插入顺序,不重复
TreeSet:不重复+自动排序
>>>Map<<<
HashMap:效率快,线程不安全,value允许null值,初识容量16,负载因子0.75。jdk1.7数组+链表,jdk1.8数组+链表+红黑树(链表>8,此时时间复杂度为O(logN))
LinkedHashMap:HashMap子类,记录插入顺序
Hashtable:效率慢,线程安全,value不允许null值,所有方法synchronized修饰
TreeMap:实现SortedMap接口,对key自动排序
>>>Queue<<<
BlockingQueue:阻塞队列,空时读取等待,满时插入等待 -> 生产者消费者问题
ArrayBlockingQueue:数组,有界阻塞队列,可构造设置上限
LinkedBlockingQueue:链表,无界阻塞队列,默认上限Integer最大值
LinkedTransferQueue:链表,无界阻塞队列
PriorityBlockingQueue:优先级,无界阻塞队列,直到系统资源耗尽
SynchronousQueue:无缓冲的等待队列,无界
>>> 线程安全的集合 <<<
Collections工具类:synchronizedXXX静态方法,性能没有提升
CopyOnWriteArrayList:写有锁,读无锁,读写不阻塞
CopyOnWriteArraySet:底层为CopyOnWriteArrayList,add时查重元素,会遍历数组
ConcurrentHashMap:分段锁×16,每个Segment加锁,jdk1.7分段锁,jdk1.8为CAS比较交换算法+同步锁(锁表头)
ConcurrentLinkedQueue:无锁设计,CAS比较交换算法
静态cache缓冲区存储了256个地址值,类加载时就会被JVM生成:
int a = 128;
Integer b = 128;
a == b 结果:true
b.equals(a) 结果:true
Integer a = 127;
Integer b = 127;
a == b 结果:true
Integer a = 128;
Integer b = 128;
a == b 结果:false // 缓存cache的 -128~127
Integer i = new Integer(100);
Integer j = new Integer(100);
int k = 100;
i == j 结果:false //构造方法没有使用缓存cache的 -128~127
i == k 结果:true
【IO流】
1.IO分类
输入/输出,字节(8bit)/字符(16bit),节点/处理
InputStream/Reader: 所有的输入流的基类,InputStream字节输入流,Reader字符输入流
OutputStream/Writer: 所有输出流的基类,OutputStream字节输出流,Writer字符输出流
2.IO / NIO
NIO比IO效率高,IO单向会阻塞(面向流),NIO双向非阻塞(面向缓冲)
NIO:Channel(通道) <=> Buffer(缓冲), Selector(事件监听-连接/读/写)
● NIO 比原生 socket 性能要高,但代码比 Netty 框架要臃肿
3.BIO / NIO / AIO
BIO 同步阻塞,TCP/UDP,同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成
NIO 同步非阻塞-多路复用,适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器
AIO 异步非阻塞,即NIO2,适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器
【序列化&反序列化】
1.实现Serializable接口
2.Transient 关键字阻止该变量被序列化到文件中
3.序列化:Java对象 转换为 字节序列
反序列化:字节序列 恢复为 Java对象
【注解】
1.四种元注解(自定义注解@interface):
@Target 修饰的对象范围
@Retention 被保留的时间长短
@Documented 描述javadoc
@Inherited 标注类是被继承的
【多线程】
1.创建:继承Thread类,实现Runnable接口,实现Callable接口,线程池(线程状态:新建-就绪-运行-阻塞-死亡)
多文件上传:Callable判断 call 方法的返回值
2.线程B知道线程A修改了变量:volatile修饰变量 -> synchronized修饰方法 -> wait/notify -> while轮询
3.终止线程:正常运行结束,退出标志,interrupt方法结束,stop方法终止(线程不安全)
4.线程池:降低资源消耗、提高响应速度、提高线程的可管理性
5.线程池工作原理和参数:线程池主要避免了线程的频繁创建和销毁,消耗系统资源和导致系统不稳定
ThreadPoolExecutor(7个参数)
①corePoolSize:最小线程数(核心线程数量)
②maximumPoolSize:最大线程数(≥核心线程数)
③keepAliveTime:空闲线程存活时间
④unit:存活时间单位,比如秒:TimeUnit.SECONDS
⑤workQueue:一个阻塞队列,提交的任务将会被放到这个队列里
⑥threadFactory:线程工厂,用来创建线程,主要是为了给线程起名字,默认名:pool-1-thread-3
⑦handler:拒绝策略,当线程池里线程被耗尽,且队列也满了的时候会调用。
1>丢弃并抛异常 2>丢弃任务 3>丢弃前面的提交新的 4>调用线程来处理
6.线程池类型:缓冲线程池、固定大小线程池、单线程线程池、默认线程池
7.java线程调度算法:时间片轮转
8.多线程上下文切换:轮转竞争CPU的时间片,不同的线程切换使用CPU发生的切换数据就是上下文切换
9.线程池工作过程:
线程任务队列通过参数传入,执行execute添加任务方法会判断队列的情况,一个线程完成就进入下一个线程,
总数不会超过参数传入的最大线程数。
【线程锁】
0.并发包 java.util.concurrent 简称 juc
1.synchronized
悲观锁,抢占式,阻塞(同步代码块-锁对象 / 同步方法-锁类实例 / 同步静态方法-锁类对象Class)
实现原理:Java对象头 + Monitor(存储线程的数据结构)
2.volatile:多线程共享变量可见性,有序性,单次读写原子性 - 状态标记量和单例模式的双检锁
3.锁的分类:
1>乐观锁:乐观认为不会发生线程安全,读多写少,先判断再上锁
2>悲观锁:悲观认为总会有线程安全,写多读少,直接上锁
3>可重入锁:递归锁,同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁,
不会因为之前已经获取过还没释放而阻塞。不仅判断锁有没有被锁上,还会判断锁是谁锁上的,
当就是自己锁上时,那么他依旧可以再次访问临界资源,并把加锁次数state+1(优点:一定程度避免死锁),
如 synchronized和ReentrantLock
4>不可重入锁:若当前线程执行某个方法获取了该锁,那么在方法中尝试再次获取锁时,就会因获取不到而阻塞。
5>公平锁:按顺序分配给请求的线程需要的锁
6>非公平锁:JVM 按随机,就近原则分配锁的机制,抢占,直接尝试加锁,则称为不公平锁(效率高于公平锁)
● ReentrantLock构造中 boolean fair 可以指定是否为公平锁(FairSync)或非公平锁(NonFairSync-默认)
● ReentrantLock主要利用 CAS+AQS 队列来实现。
● AQS:AbstractQueuedsynchronizer 构建锁和同步容器的框架,使用一个FIFO的队列表示排队等待锁的线程,
队列头节点称作“哨兵节点”或者“哑节点”,它不与任何线程关联。其他的节点与等待线程关联,
每个节点维护一个等待状态 waitStatus.
7>共享锁:允许多个线程同时获取锁,并发访问共享资源,一种乐观锁,如 ReentrantReadWriteLock中的ReadLock
8>独占锁:(独享锁=排它锁=同步锁=互斥锁)只允许一个线程获取/持有锁,如 synchronized和ReentrantLock
9>自旋锁:先让当前线程自旋等待,不是阻塞,是为了减少线程切换
10>适应性自旋锁:jdk1.6新增,默认开启自旋锁,自旋时间不固定,JVM决定 - JVM参数可设
如 AtomicInteger 中的 TicketLock/CLHlock/MCSlock
● 锁的状态 4 种:无锁、偏向锁、轻量级锁、重量级锁(从左到右也是 synchronized锁升级过程)
11>无锁:不使用锁实现线程安全,如CAS
12>偏向锁:如果一个线程多次获取锁,就会引起偏向锁,不再参与竞争,直接获取锁(提高性能)-JVM参数可设
13>轻量级锁:偏向锁被另外的线程访问则升级到轻量级锁
14>重量级锁:轻量级锁进一步升级为重量级锁,直接阻塞访问该锁的其他线程
4.锁优化:
jdk1.6之后对 synchronized 优化:自旋锁,适应性自旋锁,锁消除,锁粗化,偏向锁,轻量级锁等技术减少锁操作的开销
5.synchronized和ReentrantLock的区别:
synchronized 锁方法和代码块,JVM底层实现,不够灵活,不可中断,低并发时效率高;
ReentrantLock 锁指定区域,比较灵活,可以通过interrupt()方法中断,封装有线程高级方法,高并发时效率高
6.jdk1.5之后对 synchronized 锁的优化:
1>减少锁持有时间,只在有线程安全要求的程序上加锁
2>减小锁粒度,降低锁的竞争,触发偏向锁,轻量级锁成功率才高
3>锁分离,根据功能进行分离成读锁和写锁
4>锁粗化,锁持有的时间尽量短,使用完后立即释放
5>锁消除,编译器级别的工作,编译时发现不能被共享的对象,则消除对象的锁操作
7.CAS算法:
3个核心值 当前内存值V、旧的预期值A、即将更新的值B。
当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。
原子类,如 AtomicInteger, AtomicLong... AtomicReference(操作多个值)
关键字 volatile 来保证当前单次读写操作的原子性不可分割和打断,以及线程可见性
类 Unsafe 用来获取当前原子操作的内存数据
● ABA问题和解决:
当第一个线程执行CAS操作,尚未修改为新值之前,内存中的值已经被其他线程连续修改,使得变量值经历 A -> B -> A的过程。
解决方案:添加版本号作为标识,每次修改变量值时,对应增加版本号; 做CAS操作前需要校验版本号。JDK1.5之后,新增 AtomicStampedReference 类来处理这种情况。
8.ThreadLocal
ThreadLocal是用来维护线程中的变量不被其他线程干扰而出现的一个结构。
内部是1个 ThreadLocalMap 类,它的 key 为 ThreadLocal 对象自身,value 为要存储的对象
这样在不同线程中,持有的都是当前线程的变量副本,与其他线程完全隔离,以此来保证线程执行过程中不受其他线程的影响。
【网络编程】
1.OSI网络七层模型:物理层 - 数据链路层 - 网络层 - 传输层 - 会话+应用+表示层
2.TCP和UDP区别:
TCP面向连接,可靠,字节流,点对点传输,头部开销20字节,保证正确性和顺序;
● ServerSocket - 服务端, Socket - 客户端
UDP面向报文,无连接的,连接方式多样化,头部开销8个字节,不保证正确性且可能丢包。
● DatagramPacket - 数据报包(接收/发送), DatagramSocket - 数据报套接字
3.TCP三次握手&四次挥手:
3握手:客户端 -> SYN -> 服务器 -> SYN+ACK -> 客户端(Established) -> ACK -> 服务器(Established)
4挥手:客户端 -> FIN -> 服务器 -> ACK、FIN 按顺序发 -> 客户端 -> ACK
4.HTTP工作流程:
域名解析 -> TCP3次握手 -> 发起HTTP请求 -> 服务器响应HTTP请求 -> 解析响应的HTML代码 -> 渲染代码
5.HTTPS工作流程:
浏览器 -> 443端口发起请求 -> 服务器
浏览器 <- 发送公钥证书 <- 服务器
浏览器:①验证公钥证书 ②伪随机数生成会话密钥 ③公钥加密会话密钥
浏览器 -> 发送加密后的密文 -> 服务器
服务器:①私钥解密接收的密文出会话密钥 ②通过会话密钥加密要发送的明文内容
浏览器 <- 发送加密明文后的密文 <- 服务器
后续就以该 会话密钥 进行信息请求和响应
6.SSL协议特性:私密性、确认性、可靠性
7.HTTP请求报文:请求行、请求头、请求体
8.GET与POST:
GET:参数拼在链接地址上,最大1024字节,主要用于获取/查询
POST:请求正文中,更安全,可传大数据,主要用于更新数据/上传文件
9.Nettry:
提供一个易于使用的 API 的客户端/服务器 Java 网络编程框架。
依赖 Jar 包:netty-all
Netty封装。
【JDK8新特性】
1.接口:支持 default 方法,static 静态方法 均可以有方法体
2.Lambda:函数做为方法的参数,使用->简写方式简化代码
3.函数式接口:@FunctionalInterface注解修饰的单个方法的接口
Predicate断言,返回真假;Consumer消费,有去无回;Supplier创造,无中生有;Function传递,返回数据
4.Stream:聚合操作,查找、过滤、映射,包含基本操作、中间操作、终止操作熟练 JavaWeb 编程 Servlet/JSP 以及 Java 常用框架 Spring、SpringMVC、SpringBoot、Mybatis、Mybatis-Plus、Dubbo、WebMagic等;
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【中文乱码】
1.GET请求中文乱码:服务器IOS-8859-1,浏览器UTF-8 ①编解码 ②String方法编解码 ③server.xml配置编码方式
2.POST请求中文乱码:request.setCharacterEncoding("UTF-8")来解决
3.响应中文乱码:
①响应头 response.setHeader("Context-Type", "text/html;charset=utf-8");
②响应内容类型 response.setContentType("text/html;charset=utf-8");
4.数据库中文乱码:url追加?useUnicode=true&characterEncoding=utf8&useSSL=false
【JavaWeb】
1.session和cookie:
session:存储在服务器,生命周期跟随服务器周期,或过期(默认30min)
cookie:存储在客户端,浏览器关闭则销毁,会话cookie存在浏览器内存,持久化cookie存储在客户端磁盘
2.servlet是什么?生命周期?:
servlet是一个可以处理客户端浏览器传来的HTTP请求并返回响应的对象。
生命周期:加载、实例化、初始化、服务、销毁
3.转发和重定向:
转发:服务器,1次请求,地址不变,跳转后信息不丢失,只能转发同一个web项目内的资源
重定向:客户端,2次请求,地址改变,跳转后信息会丢失,可以重定向到任何web资源
4.JSP 9大内置对象和作用:
page,pageContext, request,response, session, application,out,config,exception
5.JSP 四大作用域:
pageContext(当前页面),request(1次请求),session(1次会话),application(整个项目)
6.JSP 防止表单重复提交:
①点击后按钮失效 ②重定向到指定页面 ③自定义重复提交过滤器
7.过滤器与拦截器:
过滤器:实现Filter接口,java反射,不依赖servlet,只对action请求有效,只能被调用一次
拦截器:实现HandlerInterceptor接口,函数调用,依赖servlet,所有请求有效,spring容器的,可被多次调用
8.监听器:对象创建/销毁,对象属性改变,对象绑定情况(事件源、监听器、绑定、事件)
9.启动顺序:Listener 理 Filter 发 Servlet 师 (不会因为标签在配置文件中的先后顺序而改变)
【Spring】
1.Spring工作原理:
IOC将创建对象和管理对象交给Spring容器来管理,动态注入,原理是反射实现
AOP面向切面编程,对某一类对象或方法来进行监督和控制,来扩充模块的功能
Spring目的就是让对象与对象之间不通过代码来关联,通过配置来管理。
【SpringMVC】
1.SpringMVC工作流程(回顾那张图即可)
请求 → 前端控制器 DispatcherServlet → 处理器映射器 → 适配器 → 匹配处理器 → 返回modelAndView → 前端控制器转给视图解析器 → 解析视图 → 将视图返回响应给用户
2.Spring中IOC容器:BeanFactory与ApplicationContext
BeanFactory:Spring原始的Factory,无法支持AOP,web应用等
AppliationContext:具备资源访问、事件传播、国际化消息访问等...
3.IOC方式:构造、set、注解 (IOC控制反转,DI依赖注入,依赖注入实现了控制反转)
4.IOC:Spring创建/管理/装配/配置对象,并管理对象的生命周期
5.AOP:静态代理、动态代理(JDK动态代理-实现接口,CGLIB动态代理-继承)
6.Bean生命周期:实例化 → 属性赋值 → 初始化init方法 → 销毁destory方法
7.Bean作用范围:Singleton,Prototype,Request,Session,Globalsession
8.Spring用到的设计模式:代理/单例/工厂/模板方法...
9.Spring自动装配:xml bean标签 autowire="byType", byName, autodetect
10.Spring事务:编程式事务,声明式事务(事务管理与业务代码分离,使用注解或xml配置来管理)
11.AOP原理和通知类型:
面向切面编程的思想。一系列方法和通知的组合。
针对业务处理过程进行横向切面提取,优化重复代码。
如日志、事务、权限等...形成日志切面、事务切面、权限切面...
场景:缓存、权限、内容传递、错误、懒加载、日志记录、优化、同步管理、事务...
● 通知类型:方法执行的之前、之后、之后未出现异常、之后出现异常、之前和之后 5种。
12.SpringMVC和Struts2的区别:
拦截机制:SpringMVC是方法级别拦截,Struts2是类级别拦截
底层框架:SpringMVC底层是Servlet实现,Struts2底层是Filter实现
性能方面:SpringMVC效率高于Struts2
配置方面:SpringMVC和Spring是无缝集成的,项目管理和安全上比Struts2高
13.@Autowire和@Resource:@Autowire按照类型装配,@Resource按照名称装配
14.spring事务传播行为:7种。①不存在事务就新建 ②不存在事务就不使用 ③不存在事务就抛异常 ④存在事务则挂起创建新的 ⑤存在事务挂起当前事务 ⑥存在事务则抛异常 ⑦存在事务则嵌套事务
15.spring事务隔离级别:5种。①默认数据库的隔离级别 ②读未提交 ③读已提交 ④可重复读 ⑤序列化
MySQL 默认 可重复读,生产中使用的是读已提交,原因:死锁/锁表概率低以及update并发高;Oracle 默认 读已提交
16.脏读:1个事务读到另1个事务未提交的数据
不可重复读:1个事务读到另1个事务已经提交的数据,导致事务多次查询不一致
幻读/虚读:select 某记录是否存在,结果是不存在,准备插入此记录,但执行 insert 时发现此记录已存在(因刚好被另一个事务 insert),无法插入,此时 select 过程发生幻读。
17.spring启用注解自动装配:<context:annotation-config />
18.@Required 修饰实体类的 setter 方法,xml中必须提供注入该方法的配置,否则会抛异常
19.@Autowaire & @Qualifie & @Resource
@Autowaire 自动按照类型注入
@Qualifie 自动按照类型注入并可以起别名,按照别名注入
@Resource 直接按照bean的id注入,等价于 @Autowaire + @Qualifie
【SpringBoot】
1.SpringBoot自动装配原理
启动类上的 @SpringBootApplication 注解:
● @EnableAutoConfiguration 中
@AutoConfigurationPackage 自动配置包,可以找到调用的 Registrar.class 然后在这个类里加断点,可以看到扫描的包的路径。
@Import 导入组件使用,该注解会在启动时将 META-INF/spring.factories 文件中指定的约定配置的值全部导入到容器中,自动配置类就能生效了。
● @SpringBootConfiguration 即 SpringBoot 的配置类,本质也只是一个 @Configuration 注解
● @ComponentScan 即 开启注解扫描。
2.SpringBoot运行流程
SpringApplication 的 run 方法 →
新建 SpringApplication 对象,并启动计时监控类 →
调用 createApplicationContext 方法创建应用上下文 → 刷新上下文 → 发布应用上下文 →
最后返回应用上下文
3.SpringBoot优点
独立运行、简化配置、自动配置、无代码生成和XML配置、应用监控
4.SpringBoot日志框架
默认日志框架:logback
支持日志框架:logging、log4j2、logback
5.SpringBoot打包war包:
① maven编译插件 ②packaging打包为war
【Mybatis】
0.Mybatis原理:
Mabatis使用XML或注解用于配置和原始映射,主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过 SqlSessionFactoryBuilder 获得。用xml文件构建SqlSessionFactory实例。
MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
1.Mybatis与Hibernate区别:
Mybatis:面向sql,半自动ORM,xml动态配置sql更灵活
Hibernate:面向对象,全自动ORM(根据对象关系模型直接映射字段),支持级联操作,完整的日志系统
2.Mybatis优点:基于SQL语句,消除JDBC冗余,数据库兼容,与Spring继承,提供灵活的映射标签
3.Mybatis缺点:依赖数据库,移植性差,sql语句工作量大
4.resultMap和resultType:
resultMap:标签映射sql查询结果字段到dto自定义的类,适用于连表查询
resultType:指定映射返回值的类的类型对应实体类,适用于单表查询
5.#{}和${}区别:#{}是预编译-可以防止SQL注入攻击,${}是字符串替换
6.Mybatis缓存:
一级缓存:sqlSession 默认开启
二级缓存:sqlSessionFactory 需要配置开启 <setting name="cacheEnabled" value="true"/>
7.Mybatis主键回填:
① xml usegeneratedkeys="true" keyproperty="id"
② @Option(usegeneratedkeys="true", keyproperty="id")
8.Mybatis主键生成:
@SelectKey(keyProperty = "userBase.id",resultType = String.class, before = true,
statement = "select replace(uuid(), '-', '')")
9.Mybatis对象映射:<association ...> 即1对1关系映射
Mybatis集合映射:<conllection ...> 即1对多关系映射
【Mybatis-Plus】
1.Mybatis-Plus是对Mybatis框架的一种增强,简化开发、提高效率。
2.核心注解:
@TableName @TableId @TableField
@Version-乐观锁标记 @EnumValue-枚举 @TableLogic-逻辑删除
【Dubbo】
1.什么是Dubbo?
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合。一款高性能、轻量级的开源Java RPC框架。
三大核心:面向接口的远程方法调用、智能容错和负载均衡、以及服务自动注册和发现。
2.Dubbo角色:
①Provider暴露服务
②Consumer调用远程服务的消费者
③Registry服务注册与发现
④Monitor监控中心
⑤Container服务运行容器
3.Dubbo负载均衡策略:随机(默认-按权重设置随机概率)、轮询、最少活跃调用、一致性hash
4.Dubbo默认通信框架:Netty
5.Dubbo服务调用是阻塞的吗?
Dubbo是基于NIO的同步非阻塞方式实现的,客户端不需要启动多线程即可并行调用多个远程服务。
6.Dubbo的核心配置有哪些?
服务、引用、协议、应用、模块、注册中心、监控中心、提供者、消费者、方法、参数 配置。
7.Dubbo流程协议:
提供者 → 注册到注册中心 → 注册中心通知消费者 → 消费者远程调用提供者 → 服务运行容器监控消费者和提供者
8.Dubbo遇到过的问题:
1.注册不上nacos,检查所有扫描路径的地方
2.消费者与服务者均需要打包为 war 包
3.所有传输的类对象,如 pojo,dto,R结果集 等都需要实现 序列化
4.公共模块 maven 编译插件
【WebScoket】
一种计算机通信协议,单个 tcp 连接提供前双攻通信信道。
双向+全双工,可以实现客户端与服务器的双向消息发送。
初始连接使用 HTTP 然后将此连接升级到基于套接字的连接,然后用于未来的通信。精通 Git、SVN、禅道等版本控制、敏捷开发服务的部署和使用;
熟练 MySql、Oracle 关系型数据库,具备常见 SQL 优化相关经验;
1
2
3
4
5
6
7
8
9
10
11Mysql 与 Oracle 区别:
MySQL是轻量型数据库,并且免费,没有服务恢复数据。分页 limit
Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。分页 rownum 嵌套查询
【SQL调优】
1.SQL优化方法
步骤:定位、启用慢查询日志(slow_query_log)、Druid SQL监控
mysql> set global slow_query_log='ON';
细节:不*、不子查询、不IN/NOT IN、不OR、不!=、不null判断、DISTINCT与ORDER BY结合、limit 1、explain要控制带range和以内
2.SQL优化工具
● SQL Tuning Expert for MySQL ● EverSQL熟练 Redis 非关系型数据库,包括 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【Redis】
1.Redis为什么快?C语言实现、单线程NIO、内存数据库、RESP客户端与服务器通信协议、string使用SDS更快
2.Reids持久化?RDB-快照一定时间多少次请求/AOF-每修改/每秒-容灾性好
3.Redis数据结构和应用场景?
str-token, list-消息队列/分页, hash-单点登录, set-去重, zset-排序, bitmap, geo...
4.Redis事务实现?mutil、exec、discard
5.Redis淘汰策略?过期时间:1.接近 2.次数最少 3.随机 没有过期时间:1.次数最少 2.随机 最严:禁止驱逐
6.Redis缓存穿透、击穿、雪崩、倾斜和解决方案?
● 穿透, 查不到————布隆过滤器/缓存空对象
● 击穿, 瞬时访问量大穿过缓存————热点永不过期/添加互斥锁
● 雪崩, 同一时间大面积失效————集群/限流降级/数据预热/过期时随机时间范围失效
● 倾斜, 某个服务器压力大导致宕机————集群
7.Redis如何实现高并发?高可用?
高并发:一主多从,主从复制,主写从读
高可用:集群、哨兵、主备切换
8.Redis的操作为什么是原子性的,怎么保证原子性?————单线程
9.Redis主从复制的过程?————sync同步命令、bgsave(非阻塞)、offset同步新增的数据不需全量同步
10.Redis哨兵机制和作用?————高可用,监控、通知、自动故障转移
11.Redis性能问题和解决方案?————主机不做持久化备份,从机做AOF备份每秒同步,主从在局域网内
12.Redis的String底层结构
SDS(simple dynamic string) buff+free+len
获取字符串复杂度为 O(1), 不会造成缓冲器溢出, 减少修改字符串的内存重新分配次数, 内存预分配机制
13.Redis的RESP协议
客户端与服务端的序列化通信协议,Redis Serialization Protocol (Redis序列化协议)熟练 Nginx、Linux、Docker 常用环境搭建,如集群搭建等;
1
2
3
4
5
6
7
8
9【Nginx】
1.Apache、Tomcat配置
2.Nginx负载均衡策略
轮询、权重、ip hash、最少连接、最小响应时间
3.Nginx的原理
● master 进程:
● worker 进程:
4.Nginx常用配置
压缩、统一错误处理、C10K问题(如何处理大量he护短连接<10000+>)熟练常用的开发工具和项目构建,如 IDEA、Eclipse、Maven 等,以及常见设计模式和JVM调优;
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【设计模式】
1.单例模式:
2.代理模式:
能够创建一个增强方法的类的对象,增强一些指定的方法逻辑功能。
3.工厂模式
● 简单工厂:传入不同的参数实现多态,实例化不同的对象。
● 抽象工厂:工厂模式的一层抽象,可以生产一系列产品(对象),灵活配置给各工厂。
【JVM调优】
0.JVM监视工具:jdk下自带的 jvisualvm.exe
1.JVM加载器多少种
● 加载过程:加载 → 链接(验证<文件格式,元数据,字节码,符号引用验证>) → 初始化
● 加载器:默认3个类加载器 BootstrapClass / ExtClassLoader / SystemClassLoader / 自定义加载器
URL[] urls = Launcher.getBootstrapClassPath().getURLs(); //获取根目录下所有的依赖jar路径
URL url = ClassLoader.getSystemClassLoader().getResource(pathName);
● 双亲委派模型:
类加载的时候,递归加载父类,当父类加载器无法完成这个请求时,子类才会尝试加载。保证不重复加载类
2.JVM的构成(五大区域)
PC程序计数器、堆、栈、本地方法栈、元空间
3.JVM堆:
● 年轻代(伊甸区=默认为堆大小的1/15,幸存者区=FromSpace + ToSpace)
● 老年代(幸存者区每熬过一次GC年龄+1,15岁时成为老年代)
● 永久代(jdk1.8遗弃,改为元空间)
新创建对象先存到年轻代 → 伊甸区:
1>如果伊甸区满了,会触发GC(Minor GC)会对伊甸区进行回收,如果存活下来,会转移到幸存者区,依次类推。
2>如果幸存者区满了,会触发GC(Minor GC)进入幸存者区的 ToSpace。
3>如果 ToSpace 满了触发GC(Minor GC),会将存活的对象转移到老年代。
4>老年代满了,触发GC(Major GC)清理。
5>Full GC,清理整个堆空间,包括年轻代+老年代。(如果触发了 Full GC 说明程序就出了问题)
a.调用System.gc() 建议但不一定执行
b.未指定老年代和新生代大小,堆伸缩时
c.老年代空间不足时
整体策略:尽量把对象在年轻代使用回收,减少晋升老年代的几率
4.JVM幸存者区为什么是2块? 内存有碎片化可以充分利用内存 + 便于管理年轻代的对象
5.强引用+软引用+弱引用+虚引用
强引用:Object o = new Object();
————只要引用还在就不会被GC回收
软引用:SoftReference<T> sr = new SoftReference<>(new Object()); Object o = sr.get();
————内存不足时,GC强制清理软引用
弱引用:WeakReference<T> wr = new WeakReference<>(new Object(), new ReferenceQueue()); Object o = wr.get();
————只要GC运行就清理弱引用对象
虚引用:PhantomReference<T> pr = new PhantomReference<>(new Object(), new ReferenceQueue()); Object o = pr.get();
————幽灵引用,幻影引用:最弱引用,无法获取对象实例。虚可达对象
————直接重写finalize方法,方法中记录时间,用于标记GC运行状态和次数,验证JVM调优
6.final, finally, finalize
final常量,finally配合try用于释放资源,finalize配合虚引用来触发GC回收对象
7.GC回收原则
1>引用计数法 - 简单,但如果对象相互引用,计数不准确,会导致内存泄露
2>可达性分析算法 - GC ROOT,根节点向下分析引用关系,找到没有引用的对象,不能包含本地方法栈
8.GC回收算法
● 标记-清除:标记并统一回收
● 复制:内存分为2块,存活的复制到另一块上,清理掉
● 标记-整理:存活的向一端移动,清理到边界以外的
● 分代收集:新生代使用复制、老年代使用标记-清除
9.GC垃圾回收器
● 串行 ● 并行 ● CMS ● G1
10.JVM调优参数
● -Xms 初始堆大小 ● -Xmx 最大堆大小 ● -Xmn 年轻代大小 ...
通过调整参数降低 Full GC 的触发。
11.为什么出现OOM?
1> 老年代存储不下幸存者区的内容
2> 永久代(元数据空间)内存不足
3> bug GC 无法回收内存 -XX:+HeapDumpOnOutOfMemoryError 堆栈快照 -XX:+PrintGCDetails GC日志熟悉 RabbitMQ、Quartz/SpringTask、WebMagic、EasyExcel、ECharts、Elasticsearch 的使用;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21【RabbitMQ】
1.virtual-host:
broker逻辑分组,虚拟的 Broker,独立:queue、exchange、binding 权限隔离
2.RabbitMQ 消息如何传输?
信道 channel 进行数据传输,没有使用TCP
是建立在真实 tcp 上的虚拟连接,每个 tcp 上的信道没有限制
3.RabbitMQ 如何保证消息不丢失?
生产者发送丢失、消费者接收丢失
● 消息确认机制
生产者发送:转发到队列,返回ACK+消息唯一ID,生产者收到ACK,消息发送成功,如果是NACK,则重新发送
消费者接收:1.自动确认-发送ACK给生产者 2.手动确认-手动ACK给生产者 3.不确认-ackXXX=none
● 事务,确保消息一致性
● 开启消息持久化
4.RabbitMQ 如何保证消息不重复消费?
● 消息唯一ID(内部生成/外部生成)
● Redis set(value不重复),保证消息的幂等性
5.RabbitMQ 死信队列和延迟
● 死信机制实现延迟消息处理:延迟队列 → 消息超时 → DLX死信交换器 → 路由Key → 死信队列1,2...
【Quartz】
两个注解:@EnableScheduling @Scheduled(cron = 定时器表达式)熟悉接口开发规范和测试经验,如 Swagger2、Jmeter 等。
熟悉微服务 Spring Cloud Alibaba 微服务框架各种组件和分布式中间件(缓存/锁/消息队列)的基本使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18【微服务】
1.微服务的认知
高扩展性,公司对并发和扩展性有要求(总用户数百万级,日增5W),所以最终选择了 SpringCloudAlibaba
2.SpringCloud的各种区别
dubbo、gRPC、SpringCloudNetflex、SpringCloudAlibaba主流-阿里双11验证、Servicecomb
3.SpringCloud的常用组件
Nacos服务注册与发现和配置中心、Ribbon负载均衡(+远程调用)、Feign远程调用、Sentinel服务容错、RocketMQ消息队列、GateWay网关、链路监控
● Nacos 服务注册中心+统一配置中心
● Ribbon和Fegin区别:都可以做远程服务调用,Ribbon可以做负载匀衡/限流降级,实现类与否
4.服务间通信
声明式 REST 调用服务。
5.最擅长/印象最深的两个模块
Nacos & Ribbon
Nacos 调试和测试必然会用到,而且统一配置中心也是它最强大的动能之一。
Ribbon 使用 RestTemplate 【模板方法】来进行远程服务调用。
6.微服务项目中遇到的问题:
● 服务注册不上————检查IP地址或者配置服务的Nacos IP 和 port
● 服务有注册但是请求发送不成功的问题————请求方式不对,HTTP头加入消息类型为JSON
00-面试题杂项整理(新)
https://janycode.github.io/2017/05/03/20_面试问题/01_技术问题/00-面试题杂项整理 (新)/