Skip to content

Commit f88d358

Browse files
author
zhenglin
committed
update: 面试解答
1 parent 79b08e4 commit f88d358

7 files changed

Lines changed: 244 additions & 48 deletions

File tree

Java-JVM/垃圾回收.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* [判断一个对象能否被回收](#判断一个对象能否被回收)
33
* [引用计数法](#引用计数法)
44
* [可达性算法](#可达性算法)
5+
* [哪些可以作为是根节点](#哪些可以作为是根节点)
56
* [方法区的回收](#方法区的回收)
67
* [finalize()](#finalize)
78
* [引用类型](#引用类型)
@@ -14,14 +15,14 @@
1415
* [整堆收集(Full GC)](#整堆收集full-gc)
1516
* [回收算法](#回收算法)
1617
* [标记-清除](#标记-清除)
17-
* [原理](#原理)
18-
* [优缺点](#优缺点)
18+
* [原理](#原理)
19+
* [优缺点](#优缺点)
1920
* [标记-复制](#标记-复制)
20-
* [原理](#原理-1)
21-
* [优缺点](#优缺点-1)
21+
* [原理](#原理-1)
22+
* [优缺点](#优缺点-1)
2223
* [标记-整理](#标记-整理)
23-
* [原理](#原理-2)
24-
* [优缺点](#优缺点-2)
24+
* [原理](#原理-2)
25+
* [优缺点](#优缺点-2)
2526
* [Hotspot算法实现细节](#hotspot算法实现细节)
2627
* [根节点枚举GC Roots](#根节点枚举gc-roots)
2728
* [安全点Safe Point](#安全点safe-point)
@@ -77,7 +78,14 @@
7778
## 可达性算法
7879
![](../img/jvm/gcRoot.png)
7980
以 GC Roots 为起始点进行搜索,可达的对象都是存活的,不可达的对象可被回收。
80-
哪些是根节点
81+
## 哪些可以作为是根节点
82+
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
83+
- 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象
84+
- 方法区中类静态属性引用的对象
85+
- 方法区中常量引用的对象
86+
- 正在运⾏的线程
87+
- 锁住的对象
88+
8189
## 方法区的回收
8290
## finalize()
8391
当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能在该方法中让对象重新被引用,从而实现自救。自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会再调用该方法。
@@ -188,7 +196,7 @@
188196
- 抢先式中断
189197
- GC时中断所有的用户线程
190198
- 如果发现该线程不在安全点则恢复,直到它跑到了安全点
191-
- 现在几乎没有虚 拟机实现采用抢先式中断来暂停线程响应GC事件
199+
- 现在几乎没有虚拟机实现采用抢先式中断来暂停线程响应GC事件
192200
- 主动式中断
193201
- 不主动中断线程,设置一个标志位,让线程自己主动轮询这个标志位,一旦发现标志位为真,就自己在最近的安全点主动中断挂起
194202
## 安全区域Safe Region

Java-JVM/类加载机制.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
* [1、依赖冲突](#1依赖冲突)
1919
* [2、热加载](#2热加载)
2020
* [3、加密保护](#3加密保护)
21-
21+
* [怎么打破双亲委派模型?](#怎么打破双亲委派模型)
22+
* [自定义类加载器,并使用自定义类加载器](#自定义类加载器并使用自定义类加载器)
23+
* [SPI也打破了双亲委派模型](#spi也打破了双亲委派模型)
24+
* [Tomcat 的类加载器](#tomcat-的类加载器)
25+
* [Tomcat 如何实现自己独特的类加载机制?](#tomcat-如何实现自己独特的类加载机制)
26+
* [如果tomcat 的 Common ClassLoader 想加载 WebApp ClassLoader 中的类,该怎么办?](#如果tomcat-的-common-classloader-想加载-webapp-classloader-中的类该怎么办)
27+
* [参考文章](#参考文章)
2228

2329
# 类加载机制
2430
### 有哪些类加载器
@@ -74,4 +80,30 @@
7480
- 打包时加密class文件
7581
- 加载时使用实现解密的classloader
7682

83+
## 怎么打破双亲委派模型?
84+
### 自定义类加载器,并使用自定义类加载器
85+
### SPI也打破了双亲委派模型
86+
### Tomcat 的类加载器
87+
- Tomcat是个web容器,如果部署的多个app,但是每个应用的使用包都不一致,所以要保持每个程序都能独立运行相互隔离
88+
- web容器也有自己依赖的类库,不能与应用混淆
89+
- 要支持jsp的热加载
90+
#### Tomcat 如何实现自己独特的类加载机制?
91+
tomcat有很多种类的加载器
92+
- commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
93+
- catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
94+
- sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
95+
- WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见
96+
97+
CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。
98+
99+
WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
100+
101+
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。
102+
103+
很显然,tomcat 不是这样实现,tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器。
104+
105+
#### 如果tomcat 的 Common ClassLoader 想加载 WebApp ClassLoader 中的类,该怎么办?
106+
可以使用线程上下文类加载器实现,使用线程上下文加载器,可以让父类加载器请求子类加载器去完成类加载的动作
77107

108+
# 参考文章
109+
- https://www.cnblogs.com/jay-wu/p/11590571.html

Java-多线程/线程池.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
* [没有固定的计算方式,需要以业务来衡量](#没有固定的计算方式需要以业务来衡量)
2424
* [市面上说的其实都不太准确](#市面上说的其实都不太准确)
2525
* [((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目](#线程等待时间线程cpu时间线程cpu时间--cpu数目)
26-
* [线程池被创建后里面有线程吗?如果没有的话,你知道有什么方法对线程池进行预热吗?](#线程池被创建后里面有线程吗如果没有的话你知道有什么方法对线程池进行预热吗)
27-
* [线上机器突然重启/宕机,线程池里的阻塞队列中任务怎么办?](#线上机器突然重启宕机线程池里的阻塞队列中任务怎么办)
26+
* [线程池被创建后里面有线程吗?如果没有的话,你知道有什么方法对线程池进行预热吗?](#线程池被创建后里面有线程吗如果没有的话你知道有什么方法对线程池进行预热吗)
27+
* [线上机器突然重启/宕机,线程池里的阻塞队列中任务怎么办?](#线上机器突然重启宕机线程池里的阻塞队列中任务怎么办)
28+
* [运行时能修改线程数么?](#运行时能修改线程数么)
2829
* [参考文章](#参考文章)
2930

30-
3131
# 创建线程池的方式
3232
### Executors
3333
#### newCachedThreadPool

Spring/Spring.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ AOP实际上就是OOP的补充,将代码横向抽取成一个独立的模块
148148
### AOP术语
149149
#### 连接点(Join point)
150150
能够被拦截的地方
151-
#### 切点(Poincut)
151+
#### 切点(Poincut)
152152
具体定位的连接点
153153
#### 增强/通知(Advice)
154154
表示添加到切点的一段逻辑代码,并定位连接点的方位信息

数据库/MySQL.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* [自适应哈希索引 (Adaptive Hash Index)](#自适应哈希索引-adaptive-hash-index)
2424
* [日志缓冲 (Log Buffer)](#日志缓冲-log-buffer)
2525
* [磁盘结构](#磁盘结构)
26-
* [支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、务的完整性要求比较高比如银行要求实现并发控制比如售票那选择innodb有很大的优势如果需要频繁的更新删除操作的数据库也可以选择innodb因为支持事务的提交commit和回滚rollback)
26+
* [特点总结](#特点总结)
2727
* [MyISAM](#myisam)
2828
* [索引](#索引)
2929
* [B树](#b树)
@@ -280,7 +280,9 @@ redo log,binlog都先写入到日志缓冲区,然后再追加写入到磁盘
280280
- `策略二`:强一致(`innodb_flush_log_at_trx_commit=1`) 每次事务提交,都将Log Buffer中的数据write入OS cache,同时MySQL主动fsync。 这种策略,是InnoDB的默认配置,为的是保证事务ACID特性。
281281
- `策略三`:折衷(`innodb_flush_log_at_trx_commit=2`) 每次事务提交,都将Log Buffer中的数据write入OS cache; 每隔一秒,MySQL主动将OS cache中的数据批量fsync。这种策略,如果操作系统奔溃,最多有一秒的数据丢失。
282282
##### 磁盘结构
283-
#### 支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)
283+
//TODO
284+
#### 特点总结
285+
支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)
284286
### MyISAM
285287
- 不支持事务
286288
- 不支持行级锁 表级锁
@@ -296,6 +298,19 @@ redo log,binlog都先写入到日志缓冲区,然后再追加写入到磁盘
296298
- 利用磁盘预读特性
297299
- 为了减少磁盘 I/O 操作,磁盘往往不是严格按需读取,而是每次都会预读。预读过程中,磁盘进行顺序读取,顺序读 取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。 操作系统一般将内存和磁盘分割成固定大小的块,每一块称为一页,内存与磁盘以页为单位交换数据。数据库系统将 索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点。并且可以利用预读特性,相邻的节点 也能够被预先载入。
298300
- 为什么数据库索引用B+树,而不用list、map、二叉树或红黑树
301+
- 为什么不用b树
302+
- b+树只有叶子节点存放数据,而b树每个索引节点都会存放数据,查询范围数据时io次数会大大增加
303+
- b+树叶子结点也是链表,在范围查找时也是非常高效
304+
- 为什么不使用hash
305+
- hash只能值匹配不能实现范围查询
306+
- 不能实现排序
307+
- 不能联合索引
308+
- 数据量大,hash冲突大
309+
- 为什么不是AVL
310+
- b+树的高度远低于AVL,查找效率更高
311+
- 为什么不是红黑树
312+
- 树高度
313+
- 红黑树的平衡
299314
- MySQL B+树一般几层,怎么算的
300315
#### b tree
301316
所有节点都会储存信息
@@ -394,7 +409,6 @@ InnoDB的主键索引与行记录是存储在一起的,故叫做聚集索引
394409
- 而避免幻读,则需要通过next-key lock。next-key lock是行锁的一种,实现相当于record lock(记录锁) + gap lock(间隙锁);其特点是不仅会锁住记录本身(record lock的功能),还会锁定一个范围(gap lock的功能)。因此,加锁读同样可以避免脏读、不可重复读和幻读,保证隔离性
395410
- `串行化:serializable` 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
396411
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发
397-
- MySQL隔离级别分别怎么实现的
398412
#### 持久性(Durability)
399413
定义 持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
400414
- 实现原理:redo log

计算机网络/TCP_IP.md

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11

22
* [<a href="#">UDP 和 TCP 的特点</a>](#udp-和-tcp-的特点)
3-
* [<a href="#">UDP</a>](#udp)
4-
* [<a href="#">TCP</a>](#tcp)
3+
* [<a href="#">UDP</a>](#udp)
4+
* [<a href="#">TCP</a>](#tcp)
55
* [<a href="#">三次握手</a>](#三次握手)
6-
* [<a href="#">流程</a>](#流程)
7-
* [<a href="#">为什么需要三次握手</a>](#为什么需要三次握手)
6+
* [<a href="#">流程</a>](#流程)
7+
* [<a href="#">为什么需要三次握手</a>](#为什么需要三次握手)
88
* [<a href="#">四次挥手</a>](#四次挥手)
9-
* [<a href="#">流程</a>](#流程-1)
9+
* [<a href="#">流程</a>](#流程-1)
1010
* [<a href="#">TCP怎么保障可靠传输</a>](#tcp怎么保障可靠传输)
11-
* [<a href="#">数据合理分片和排序</a>](#数据合理分片和排序)
12-
* [<a href="#">数据校验:校验和</a>](#数据校验校验和)
13-
* [<a href="#">TCP 的接收端会丢弃重复的数据</a>](#tcp-的接收端会丢弃重复的数据)
14-
* [<a href="#">超时重传</a>](#超时重传)
15-
* [<a href="#">流量控制</a>](#流量控制)
16-
* [<a href="#">拥塞控制</a>](#拥塞控制)
17-
* [<a href="#">ARQ协议</a>](#arq协议)
18-
11+
* [<a href="#">数据合理分片和排序</a>](#数据合理分片和排序)
12+
* [<a href="#">数据校验:校验和</a>](#数据校验校验和)
13+
* [<a href="#">TCP 的接收端会丢弃重复的数据</a>](#tcp-的接收端会丢弃重复的数据)
14+
* [<a href="#">超时重传</a>](#超时重传)
15+
* [<a href="#">流量控制</a>](#流量控制)
16+
* [<a href="#">拥塞控制</a>](#拥塞控制)
17+
* [<a href="#">ARQ协议</a>](#arq协议)
18+
* [HTTP长连接还是短连接?](#http长连接还是短连接)
19+
* [参考文章](#参考文章)
1920

2021
## [UDP 和 TCP 的特点](#)
21-
- ### [UDP](#)
22-
- 是无连接的,尽最大可能交付,没有拥塞控制,面向报文 (对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多
23-
的交互通信。
24-
- ### [TCP](#)
25-
- 是面向连接的,提供可靠交付,有流量控制,拥塞控 制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据
26-
块),每一条 TCP 连接只能是点对点的(一对一)。
27-
---
22+
### [UDP](#)
23+
是无连接的,尽最大可能交付,没有拥塞控制,面向报文 (对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多 的交互通信。
24+
### [TCP](#)
25+
是面向连接的,提供可靠交付,有流量控制,拥塞控 制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据 块),每一条 TCP 连接只能是点对点的(一对一)。
2826
## [三次握手](#)
29-
- ### [流程](#)
27+
### [流程](#)
3028
![](../img/计算机网络/tcp三次握手.png)
3129

3230
1. 客户端–发送带有 SYN 标志的数据包–一次握手–服务端
@@ -41,9 +39,8 @@
4139

4240
- 第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
4341

44-
---
4542
## [四次挥手](#)
46-
- ### [流程](#)
43+
### [流程](#)
4744
![](../img/计算机网络/tcp四次挥手.png)
4845

4946
1. 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送
@@ -57,8 +54,6 @@
5754
- 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
5855
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
5956

60-
---
61-
6257
## [TCP怎么保障可靠传输](#)
6358

6459
### [数据合理分片和排序](#)
@@ -145,6 +140,13 @@
145140
- 优点: 信道利用率高,容易实现,即使确认丢失,也不必重传。
146141
- 缺点: 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。
147142

143+
## HTTP长连接还是短连接?
144+
在HTTP/1.0中,默认使用的是短连接
145+
- 也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
148146

147+
HTTP/1.1起,默认使用长连接,用以保持连接特性
148+
- Connection:keep-alive
149+
- 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接
149150

150-
151+
# 参考文章
152+
- https://www.cnblogs.com/0201zcr/p/4694945.html

0 commit comments

Comments
 (0)