Skip to content

Commit 48fc0bf

Browse files
committed
Update Java Notes
1 parent 3d7aa43 commit 48fc0bf

File tree

4 files changed

+107
-92
lines changed

4 files changed

+107
-92
lines changed

Frame.md

Lines changed: 58 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -8237,9 +8237,12 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
82378237
82388238
**开始创建**:`doCreateBean(beanName, RootBeanDefinition, Object[] args)`
82398239
8240+
* 清除缓存:如果bean是单例,就先清除缓存中的bean信息
8241+
82408242
* **创建实例**:`createBeanInstance(beanName, RootBeanDefinition, Object[] args)`
8241-
* 优先级从高到低:工厂方法、有参**构造函数**、默认构造函数
8242-
* 将 BeanDifinition 转化成 BeanWrapper,Spring给所有创建的Bean实例包装成BeanWrapper,BeanWrapper是对反射相关API的简单封装,使得上层使用反射完成相关的业务逻辑大大简化
8243+
8244+
* 优先级从高到低:工厂方法、有参**构造函数**、无参构造函数
8245+
* Spring给所有创建的Bean实例包装成BeanWrapper,BeanWrapper是对反射相关API的简单封装,使得上层使用反射完成相关的业务逻辑大大简化
82438246
82448247
* 后置处理:`applyMergedBeanDefinitionPostProcessors()`
82458248
* 将所有的后置处理器拿出来,并且把名字叫beanName的类中的变量都封装到InjectionMetadata的injectedElements集合里面,目的是以后从中获取,创建实例,通过反射注入到相应类
@@ -8296,8 +8299,6 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
82968299
82978300
* 根据不同的scope进行disposableBean的注册,在销毁对象时调用destory()
82988301
8299-
总结:Bean的初始化过程:共仓
8300-
83018302
83028303
83038304
****
@@ -9830,7 +9831,7 @@ ModelAndView 是SpringMVC提供的一个对象,该对象可以用作控制器
98309831

98319832
注解:@ResponseBody
98329833

9833-
作用:将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到Response的body区。如果返回值是字符串,那么直接将字符串返回客户端;如果是一个对象,会将对象转化为Json,然后返回客户端。
9834+
作用:将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到Response的body区。如果返回值是字符串,那么直接将字符串返回客户端;如果是一个对象,会**将对象转化为Json**,返回客户端
98349835

98359836
注意:当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。
98369837

@@ -10128,7 +10129,7 @@ ModelAndView 是SpringMVC提供的一个对象,该对象可以用作控制器
1012810129
名称:@RequestBody
1012910130
类型:形参注解
1013010131
位置:处理器类中的方法形参前方
10131-
作用:将异步提交数据组织成标准请求参数格式,并赋值给形参
10132+
作用:将异步提交数据**转换**成标准请求参数格式,并赋值给形参
1013210133
范例:
1013310134

1013410135
```java
@@ -10374,6 +10375,8 @@ public User cross(HttpServletRequest request){
1037410375

1037510376

1037610377

10378+
10379+
1037710380
***
1037810381

1037910382

@@ -10488,16 +10491,19 @@ public void afterCompletion(HttpServletRequest request,
1048810491

1048910492
### 拦截配置
1049010493

10494+
拦截路径:
10495+
10496+
* `/**`:表示拦截所有映射
10497+
* `/* `:表示拦截所有/开头的映射
10498+
* `/user/*`:表示拦截所有/user/开头的映射
10499+
* `/user/add*`:表示拦截所有/user/开头,且具体映射名称以add开头的映射
10500+
* `/user/*All`:表示拦截所有/user/开头,且具体映射名称以All结尾的映射
10501+
1049110502
```xml
1049210503
<mvc:interceptors>
1049310504
<!--开启具体的拦截器的使用,可以配置多个-->
1049410505
<mvc:interceptor>
10495-
<!--设置拦截器的拦截路径,支持*通配-->
10496-
<!--/** 表示拦截所有映射-->
10497-
<!--/* 表示拦截所有/开头的映射-->
10498-
<!--/user/* 表示拦截所有/user/开头的映射-->
10499-
<!--/user/add* 表示拦截所有/user/开头,且具体映射名称以add开头的映射-->
10500-
<!--/user/*All 表示拦截所有/user/开头,且具体映射名称以All结尾的映射-->
10506+
<!--设置拦截器的拦截路径,支持*通配-->
1050110507
<mvc:mapping path="/handleRun*"/>
1050210508
<!--设置拦截排除的路径,配置/**或/*,达到快速配置的目的-->
1050310509
<mvc:exclude-mapping path="/b*"/>
@@ -10886,20 +10892,14 @@ ExceptionHandler注解:
1088610892

1088710893
### Rest概述
1088810894

10889-
RestREpresentational State Transfer:一种网络资源的访问风格,定义了网络资源的访问方式
10895+
Rest (Representational State Transfer):一种网络资源的访问风格,定义了网络资源的访问方式
1089010896

10891-
* 传统风格访问路径
10892-
http://localhost/user/get?id=1
10893-
http://localhost/deleteUser?id=1
10894-
* Rest风格访问路径
10895-
http://localhost/user/1
10897+
* 传统风格访问路径:http://localhost/user/get?id=1
10898+
* Rest风格访问路径:http://localhost/user/1
1089610899

1089710900
Restful是按照Rest风格访问网络资源
1089810901

10899-
优点:
10900-
10901-
* 隐藏资源的访问行为,通过地址无法得知做的是何种操作
10902-
* 书写简化
10902+
优点:隐藏资源的访问行为,通过地址无法得知做的是何种操作,书写简化
1090310903

1090410904
Rest行为约定方式:
1090510905

@@ -10913,32 +10913,50 @@ Rest行为约定方式:
1091310913

1091410914
注意:上述行为是约定方式,约定不是规范,可以打破,所以称Rest风格,而不是Rest规范
1091510915

10916+
10917+
1091610918
***
1091710919

1091810920

1091910921

10920-
### Restful开发
10922+
### Restful
10923+
10924+
Restful请求路径简化配置方式:@RestController = @Controller + @ResponseBody
10925+
10926+
相关注解:
10927+
10928+
* `@GetMapping("/poll")` = `@RequestMapping(value = "/poll",method = RequestMethod.GET)`
10929+
10930+
* `@PostMapping("/push")` = `@RequestMapping(value = "/push",method = RequestMethod.POST)`
1092110931

10922-
Restful请求路径简化配置方式:**@RestController = @Controller + @ResponseBody**
10932+
* `@GetMapping("{id}")`:Restful开发
10933+
10934+
```java
10935+
public String getMessage(@PathVariable("id") Integer id){}
10936+
```
10937+
10938+
`@PathVariable`注解的参数一般在有多个参数的时候添加
10939+
10940+
过滤器:HiddenHttpMethodFilterSpringMVCRestful风格的访问支持的过滤器,
10941+
10942+
代码实现:
1092310943

1092410944
* restful.jsp
10925-
开启SpringMVCRestful风格的访问支持过滤器,即可**通过页面表单提交PUT**DELETE请求
1092610945
页面表单使用隐藏域提交请求类型,参数名称固定为_method,必须配合提交类型method=post使用
10927-
10928-
* GET请求通过地址栏可以发送,也可以通过设置form的请求方式提交
10946+
10947+
* GET请求通过地址栏可以发送,也可以通过设置form的请求方式提交
1092910948
* POST请求必须通过form的请求方式提交
10930-
10931-
```html
10949+
10950+
```html
1093210951
<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
1093310952
<h1>restful风格请求表单</h1>
1093410953
<%--切换请求路径为restful风格--%>
1093510954
<form action="/user/1" method="post">
1093610955
<%--当添加了name为_method的隐藏域时,可以通过设置该隐藏域的值,修改请求的提交方式,切换为PUT请求或DELETE请求,但是form表单的提交方式method属性必须填写post--%>
10937-
<%--该配置需要配合HiddenHttpMethodFilter过滤器使用,单独使用无效,请注意检查web.xml中是否配置了对应过滤器--%>
1093810956
<input type="text" name="_method" value="PUT"/>
1093910957
<input type="submit"/>
1094010958
</form>
10941-
```
10959+
```
1094210960

1094310961

1094410962
* java / controller / UserController
@@ -11008,49 +11026,17 @@ Restful请求路径简化配置方式:**@RestController = @Controller + @Respo
1100811026
* 配置拦截器 web.xml
1100911027

1101011028
```xml
11011-
<?xml version="1.0" encoding="UTF-8"?>
11012-
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
11013-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11014-
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
11015-
version="3.1">
11016-
<filter>
11017-
<filter-name>characterEncodingFilter</filter-name>
11018-
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
11019-
<init-param>
11020-
<param-name>encoding</param-name>
11021-
<param-value>UTF-8</param-value>
11022-
</init-param>
11023-
</filter>
11024-
<filter-mapping>
11025-
<filter-name>characterEncodingFilter</filter-name>
11026-
<url-pattern>/*</url-pattern>
11027-
</filter-mapping>
11028-
1102911029
<!--配置拦截器,解析请求中的参数_method,否则无法发起PUT请求与DELETE请求,配合页面表单使用-->
11030-
<filter>
11031-
<filter-name>HiddenHttpMethodFilter</filter-name>
11032-
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
11033-
</filter>
11034-
<filter-mapping>
11035-
<filter-name>HiddenHttpMethodFilter</filter-name>
11036-
<servlet-name>DispatcherServlet</servlet-name>
11037-
</filter-mapping>
11038-
11039-
<servlet>
11040-
<servlet-name>DispatcherServlet</servlet-name>
11041-
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
11042-
<init-param>
11043-
<param-name>contextConfigLocation</param-name>
11044-
<param-value>classpath*:spring-mvc.xml</param-value>
11045-
</init-param>
11046-
</servlet>
11047-
<servlet-mapping>
11048-
<servlet-name>DispatcherServlet</servlet-name>
11049-
<url-pattern>/</url-pattern>
11050-
</servlet-mapping>
11051-
</web-app>
11030+
<filter>
11031+
<filter-name>HiddenHttpMethodFilter</filter-name>
11032+
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
11033+
</filter>
11034+
<filter-mapping>
11035+
<filter-name>HiddenHttpMethodFilter</filter-name>
11036+
<servlet-name>DispatcherServlet</servlet-name>
11037+
</filter-mapping>
1105211038
```
11053-
11039+
1105411040

1105511041

1105611042

Interview.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,16 @@
206206
* 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序
207207
* 分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护
208208

209+
* 快表和多级页表
210+
211+
快表:虚拟地址到物理地址的转换要快
212+
213+
* CPU给出逻辑地址,地址转换后先去快表(高速缓存寄存器)中查询,如果有就直接读取物理地址
214+
* 如果没有就去访问主存中的页表,读出以后同时存入快表
215+
* 当快表填满,就按照淘汰策略淘汰旧的页表项
216+
217+
多级页表:为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中
218+
209219
* 什么是CPU寻址?
210220

211221
现代处理器使用的是一种称为虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU 将虚拟(逻辑)地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为内存管理单元(Memory Management Unit, MMU)的硬件

JavaSE.md

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ public class ScannerDemo {
454454

455455
二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器
456456

457-
初始化
457+
初始化
458458

459459
* 动态初始化:
460460
数据类型[][] 变量名 = new 数据类型[m] [n] : `int[][] arr = new int[3][3];`
@@ -465,8 +465,6 @@ public class ScannerDemo {
465465
* 数据类型[][] 变量名 = { {元素1, 元素2...} , {元素1, 元素2...} ...}
466466
* `int[][] arr = {{11,22,33}, {44,55,66}};`
467467

468-
469-
470468
遍历:
471469

472470
```java
@@ -597,6 +595,12 @@ public static void sum(int... nums){
597595
注意:方法必须先创建才可以使用,该过程成为方法定义
598596
方法创建后并不是直接可以运行的,需要手动使用后,才执行,该过程成为方法调用
599597

598+
在方法内部定义的叫局部变量,局部变量不能加static,包括protected, private, public这些也不能加
599+
600+
原因:局部变量是保存在栈中的,而静态变量保存于方法区,局部变量出了方法就被栈回收了,而静态变量不会,所以在局部变量前不能加static关键字,静态变量是定义在类中,又叫类变量
601+
602+
603+
600604

601605

602606
***
@@ -11171,7 +11175,7 @@ Heap 堆:是JVM内存中最大的一块,由所有线程共享,由垃圾回
1117111175

1117211176
存放哪些资源:
1117311177

11174-
* 对象实例:类初始化生成的对象,基本数据类型的数组也是对象实例,new 创建对象都使用堆内存
11178+
* 对象实例:类初始化生成的对象,**基本数据类型的数组也是对象实例**,new 创建对象都使用堆内存
1117511179
* 字符串常量池:
1117611180
* 字符串常量池原本存放于方法区,jdk7开始放置于堆中
1117711181
* 字符串常量池**存储的是string对象的直接引用,而不是直接存放的对象**,是一张string table
@@ -11227,7 +11231,7 @@ public static void main(String[] args) throws InterruptedException {
1122711231
类元信息:
1122811232

1122911233
* 类元信息在类编译期间放入方法区,里面放置了类的基本信息,包括类的方法、参数、接口以及常量池表
11230-
* 常量池表(Constant Pool Table)存储了类在编译期间生成的字面量、符号引用,这些信息在类加载完后会被解析到运行时常量池中
11234+
* 常量池表(Constant Pool Table)存储了类在编译期间生成的字面量、符号引用,这些信息在类加载完后会被解析到运行时常量池中,JVM为每个已加载的类维护一个常量池
1123111235

1123211236
**运行时常量池**是方法区的一部分
1123311237

@@ -11800,6 +11804,24 @@ Java语言提供了对象终止(finalization)机制来允许开发人员提
1180011804

1180111805

1180211806

11807+
#### 无用类
11808+
11809+
方法区主要回收的是无用的类,
11810+
11811+
判定一个类是否是无用的类,需要同时满足下面 3 个条件 :
11812+
11813+
- 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例
11814+
- 加载该类的`ClassLoader`已经被回收
11815+
- 该类对应的`java.lang.Class`对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
11816+
11817+
虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收
11818+
11819+
11820+
11821+
***
11822+
11823+
11824+
1180311825
### 回收算法
1180411826

1180511827
#### 标记清除
@@ -11810,14 +11832,11 @@ Java语言提供了对象终止(finalization)机制来允许开发人员提
1181011832
- 复制算法(copying)
1181111833
- 标记压缩算法(Mark-Compact)
1181211834

11813-
标记清除算法,是将垃圾回收分为2个阶段,分别是**标记和清除**
11835+
标记清除算法,是将垃圾回收分为2个阶段,分别是**标记和清除**
1181411836

1181511837
- **标记**:Collector从引用根节点开始遍历,**标记所有被引用的对象**,一般是在对象的Header中记录为可达对象,**标记的是引用的对象,不是垃圾**
11816-
- **清除**:Collector对堆内存从头到尾进行线性的遍历,如果发现某个对象在其Header中没有标记为可达对象,则将其回收,清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里
11817-
11818-
回收和分配:
11838+
- **清除**:Collector对堆内存从头到尾进行线性的遍历,如果发现某个对象在其Header中没有标记为可达对象,则将其回收,把分块连接到 “**空闲链表**” 的单向链表,判断回收后的分块与前一个空闲分块是否连续,若连续会合并这两个分块,之后进行分配时只需要遍历这个空闲链表,就可以找到分块
1181911839

11820-
- 回收阶段:判断回收后的分块与前一个空闲分块是否连续,若连续会合并这两个分块。回收对象就是把分块连接到 “**空闲链表**” 的单向链表,之后进行分配时只需要遍历这个空闲链表,就可以找到分块
1182111840
- 分配阶段:程序会搜索空闲链表寻找空间大于等于新对象大小 size 的块 block,如果找到的块等于 size,会直接返回这个分块;如果找到的块大于 size,会将块分割成大小为 size 与 (block - size) 的两部分,返回大小为 size 的分块,并把大小为 (block - size) 的块返回给空闲链表
1182211841

1182311842
缺点:
@@ -13449,7 +13468,9 @@ public class Candy11 {
1344913468

1345013469
#### 创建时机
1345113470

13452-
一个Java对象的创建过程往往包括 **类初始化** 和 **类实例化** 两个阶段
13471+
一个Java对象的创建过程往往包括**类初始化**和**类实例化**两个阶段
13472+
13473+
类在第一次实例化加载一次,后续实例化不再加载,引用第一次加载的类
1345313474

1345413475
Java对象创建时机:
1345513476

@@ -13487,7 +13508,7 @@ Java对象创建时机:
1348713508

1348813509
#### 创建过程
1348913510

13490-
当一个对象被创建时,虚拟机就会为其分配内存来存放对象的实例变量及其从父类继承过来的实例变量(即使这些从超类继承过来的实例变量有可能被隐藏也会被分配空间),同时这些实例变量也会被赋予默认值(零值),然后开始进行对象初始化: **实例变量初始化**、**实例代码块初始化** 、 **构造函数初始化**
13511+
当一个对象被创建时,虚拟机就会为其分配内存来存放对象的实例变量及其从父类继承过来的实例变量(即使这些从超类继承过来的实例变量有可能被隐藏也会被分配空间),同时这些实例变量也会被赋予默认值(零值),然后开始进行对象初始化:**实例变量初始化**、**实例代码块初始化** 、 **构造函数初始化**
1349113512

1349213513
1. 实例变量初始化与实例代码块初始化
1349313514

@@ -13515,8 +13536,8 @@ Java对象创建时机:
1351513536

1351613537
2. 类的初始化过程与类的实例化过程的异同?
1351713538

13518-
类的初始化是指类加载过程中的初始化阶段对类变量按照代码进行赋值的过程
13519-
而类的实例化是指在类完全加载到内存中后创建对象的过程
13539+
类的初始化是指类加载过程中的初始化阶段对类变量按照代码进行赋值的过程
13540+
类的实例化是指在类完全加载到内存中后创建对象的过程(类的实例化触发了类的初始化)
1352013541

1352113542
3. 假如一个类还未加载到内存中,那么在创建一个该类的实例时,具体过程是怎样的?(**经典案例**)
1352213543

@@ -13558,7 +13579,7 @@ Java对象创建时机:
1355813579

1355913580
`static StaticTest st = new StaticTest();`:
1356013581

13561-
* 实例初始化化不一定要在类初始化结束之后才开始
13582+
* 实例初始化不一定要在类初始化结束之后才开始
1356213583

1356313584
* 在同一个类加载器下,一个类型只会被初始化一次。所以一旦开始初始化一个类,无论是否完成后续都不会再重新触发该类型的初始化阶段了(只考虑在同一个类加载器下的情形)。因此,在实例化上述程序中的st变量时,**实际上是把实例初始化嵌入到了静态初始化流程中,并且在上面的程序中,嵌入到了静态初始化的起始位置**,这就导致了实例初始化完全发生在静态初始化之前,这也是导致a为110 b为0的原因
1356413585

@@ -13738,6 +13759,8 @@ class D {
1373813759

1373913760
类构造器<clinit>()与实例构造器<init>()不同,它不需要程序员进行显式调用。在一个类的生命周期中,类构造器<clinit>()最多会被虚拟机**调用一次**,而实例构造器<init>()则会被虚拟机调用多次,只要程序员创建对象
1374013761

13762+
类在第一次实例化加载一次,把class读入内存,后续实例化不再加载,引用第一次加载的类
13763+
1374113764

1374213765

1374313766
###### clinit
@@ -13805,7 +13828,7 @@ init指的是实例构造器,主要作用是在类实例化过程中执行,
1380513828

1380613829
实例化即调用 <init>()V ,虚拟机会保证这个类的构造方法的线程安全,先为实例变量分配内存空间,再执行赋默认值,然后根据源码中的顺序执行赋初值或代码块,没有成员变量初始化和代码块则不会执行
1380713830

13808-
创建对象的过程:**父类的类构造器<clinit>() -> 子类的类构造器<clinit>() -> 父类的成员变量和实例代码块 -> 父类的构造函数 -> 子类的成员变量和实例代码块 -> 子类的构造函数**
13831+
类实例化过程:**父类的类构造器<clinit>() -> 子类的类构造器<clinit>() -> 父类的成员变量和实例代码块 -> 父类的构造函数 -> 子类的成员变量和实例代码块 -> 子类的构造函数**
1380913832

1381013833

1381113834

JavaWeb.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,10 +2534,6 @@ Servlet的运行环境叫做Web容器或Servlet服务器,**Tomcat 是Web应用
25342534

25352535

25362536

2537-
2538-
2539-
2540-
25412537
***
25422538

25432539

0 commit comments

Comments
 (0)