From 470b56b35ad830e235d39c1f9f53286176ebceb8 Mon Sep 17 00:00:00 2001 From: jguo Date: Fri, 21 May 2021 11:39:41 -0700 Subject: [PATCH 001/257] =?UTF-8?q?Update=20=E5=8F=8D=E5=B0=84=E6=9C=BA?= =?UTF-8?q?=E5=88=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix typo --- docs/java/basis/反射机制.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/反射机制.md b/docs/java/basis/反射机制.md index 0e2389b5..d6fe4263 100644 --- a/docs/java/basis/反射机制.md +++ b/docs/java/basis/反射机制.md @@ -80,7 +80,7 @@ Class alunbarClass2 = o.getClass(); **4.通过类加载器`xxxClassLoader.loadClass()`传入类路径获取:** ```java -class clazz = ClassLoader.LoadClass("cn.javaguide.TargetObject"); +Class clazz = ClassLoader.loadClass("cn.javaguide.TargetObject"); ``` 通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一些列步骤,静态块和静态对象不会得到执行 @@ -173,4 +173,4 @@ value is JavaGuide ```java Class tagetClass = Class.forName("cn.javaguide.TargetObject"); -``` \ No newline at end of file +``` From ae531bf22c2d4a9118d77f8c72dfbc0357c04f3c Mon Sep 17 00:00:00 2001 From: guide Date: Sun, 23 May 2021 20:20:02 +0800 Subject: [PATCH 002/257] =?UTF-8?q?[fix]=20=E5=8A=A8=E6=80=81=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=B9=B4=E9=BE=84=E5=88=A4=E5=AE=9A=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E4=B8=8D=E5=87=86=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/JVM垃圾回收.md | 36 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index d657f3b8..d25667a5 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -176,26 +176,30 @@ public class GCTest { 大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。 -> 修正([issue552](https://github.com/Snailclimb/JavaGuide/issues/552)):“Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的一半时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。 +> 修正([issue552](https://github.com/Snailclimb/JavaGuide/issues/552)):“Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的 50% 时(默认值是 50%,可以通过 `-XX:TargetSurvivorRatio=percent` 来设置,参见 [issue1199](https://github.com/Snailclimb/JavaGuide/issues/1199) ),取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。 > -> **动态年龄计算的代码如下** +> jdk8官方文档引用 :https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html 。 +> +> ![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210523201742303.png) +> +> **动态年龄计算的代码如下:** > > ```c++ > uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { -> //survivor_capacity是survivor空间的大小 -> size_t desired_survivor_size = (size_t)((((double)survivor_capacity)*TargetSurvivorRatio)/100); -> size_t total = 0; -> uint age = 1; -> while (age < table_size) { -> //sizes数组是每个年龄段对象大小 -> total += sizes[age]; -> if (total > desired_survivor_size) { -> break; -> } -> age++; -> } -> uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold; -> ... +> //survivor_capacity是survivor空间的大小 +> size_t desired_survivor_size = (size_t)((((double)survivor_capacity)*TargetSurvivorRatio)/100); +> size_t total = 0; +> uint age = 1; +> while (age < table_size) { +> //sizes数组是每个年龄段对象大小 +> total += sizes[age]; +> if (total > desired_survivor_size) { +> break; +> } +> age++; +> } +> uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold; +> ... > } > > ``` From 2062c3e9c6fe5e489042cfa1e565b4961a64aeaa Mon Sep 17 00:00:00 2001 From: guide Date: Sun, 23 May 2021 20:56:00 +0800 Subject: [PATCH 003/257] =?UTF-8?q?[fix]=20=E6=95=B4=E5=9E=8B=E5=8C=85?= =?UTF-8?q?=E8=A3=85=E7=B1=BB=E5=80=BC=E7=9A=84=E6=AF=94=E8=BE=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识疑难点.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/java/basis/Java基础知识疑难点.md b/docs/java/basis/Java基础知识疑难点.md index 3688a0e6..b11de0c5 100644 --- a/docs/java/basis/Java基础知识疑难点.md +++ b/docs/java/basis/Java基础知识疑难点.md @@ -72,16 +72,16 @@ Reference:[Java中equals方法造成空指针异常的原因及解决方案](htt 先看下面这个例子: ```java -Integer x = 3; -Integer y = 3; -System.out.println(x == y);// true -Integer a = new Integer(3); -Integer b = new Integer(3); -System.out.println(a == b);//false -System.out.println(a.equals(b));//true +Integer i1 = 40; +Integer i2 = new Integer(40); +System.out.println(i1==i2);//false ``` -当使用自动装箱方式创建一个Integer对象时,当数值在-128 ~127时,会将创建的 Integer 对象缓存起来,当下次再出现该数值时,直接从缓存中取出对应的Integer对象。所以上述代码中,x和y引用的是相同的Integer对象。 +`Integer i1=40` 这一行代码会发生拆箱,也就是说这行代码等价于 `Integer i1=Integer.valueOf(40)` 。因此,`i1` 直接使用的是常量池中的对象。而`Integer i1 = new Integer(40)` 会直接创建新的对象。因此,输出 false 。 + +记住:**所有整型包装类对象之间值的比较,全部使用 `equals()` 方法比较**。 + +![](https://img-blog.csdnimg.cn/20210313164740893.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MzM3Mjcy,size_16,color_FFFFFF,t_70) **注意:** 如果你的IDE(IDEA/Eclipse)上安装了阿里巴巴的p3c插件,这个插件如果检测到你用 ==的话会报错提示,推荐安装一个这个插件,很不错。 From 2fbd08922c58680eefc4783675c28f74393888e8 Mon Sep 17 00:00:00 2001 From: guide Date: Sun, 23 May 2021 21:04:50 +0800 Subject: [PATCH 004/257] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/collection/Java集合框架常见面试题.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 9cc5b54f..63e67002 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -86,7 +86,7 @@ - `HashMap`: JDK1.8 之前 `HashMap` 由数组+链表组成的,数组是 `HashMap` 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间 - `LinkedHashMap`: `LinkedHashMap` 继承自 `HashMap`,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,`LinkedHashMap` 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。详细可以查看:[《LinkedHashMap 源码详细分析(JDK1.8)》](https://www.imooc.com/article/22931) -- `Hashtable`: 数组+链表组成的,数组是 `HashMap` 的主体,链表则是主要为了解决哈希冲突而存在的 +- `Hashtable`: 数组+链表组成的,数组是 `Hashtable` 的主体,链表则是主要为了解决哈希冲突而存在的 - `TreeMap`: 红黑树(自平衡的排序二叉树) ### 1.1.4. 如何选用集合? From 7c567657853e6ac3082d3362aeead1f126b6e895 Mon Sep 17 00:00:00 2001 From: guide Date: Sun, 23 May 2021 21:30:29 +0800 Subject: [PATCH 005/257] =?UTF-8?q?Update=20java=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E5=AD=A6=E4=B9=A0=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/multi-thread/java线程池学习总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/multi-thread/java线程池学习总结.md b/docs/java/multi-thread/java线程池学习总结.md index 18b12001..66d835fd 100644 --- a/docs/java/multi-thread/java线程池学习总结.md +++ b/docs/java/multi-thread/java线程池学习总结.md @@ -545,7 +545,7 @@ public interface Callable { 1. **`execute()`方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;** 2. **`submit()`方法用于提交需要返回值的任务。线程池会返回一个 `Future` 类型的对象,通过这个 `Future` 对象可以判断任务是否执行成功** ,并且可以通过 `Future` 的 `get()`方法来获取返回值,`get()`方法会阻塞当前线程直到任务完成,而使用 `get(long timeout,TimeUnit unit)`方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。 -我们以**`AbstractExecutorService`**接口中的一个 `submit` 方法为例子来看看源代码: +我们以 **`AbstractExecutorService`** 接口中的一个 `submit()` 方法为例子来看看源代码: ```java public Future submit(Runnable task) { From c27b54539a77d1682fb14c070d7908376d8ec942 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Mon, 24 May 2021 09:55:14 +0800 Subject: [PATCH 006/257] =?UTF-8?q?Object=E7=B1=BB=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=8E=92=E7=89=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 36 ++++++++++------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index f526cd0d..40c9e873 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -1118,30 +1118,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { Object 类是一个特殊的类,是所有类的父类。它主要提供了以下 11 个方法: -```java +- `public final native Class getClass()`:`native`方法,用于返回当前运行时对象的`Class`对象,使用了`final`关键字修饰,故不允许子类重写 +- `public native int hashCode()`:`native`方法,用于返回对象的哈希码,主要使用在哈希表中,比如`HashMap` +- `public boolean equals(Object obj)`:用于比较两个对象的内存地址是否相等,`String`类对该方法进行了重写,判断用户比较字符串的值是否相等 +- `protected native Object clone() throws CloneNotSupportedException`:`naitive`方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象`x`,表达式`x.clone() != x`为`true`,`x.clone().getClass() == x.getClass()`为`true`。`Object`本身没有实现`Cloneable`接口,所以不重写`clone`方法并且进行调用的话会发生`CloneNotSupportedException`异常 +- `public String toString()`:返回`类的名字@实例的哈希码`的16进制的字符串。建议`Object`所有的子类都重写这个方法 +- `public final native void notify()`:`native`方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念),如果有多个线程在等待只会任意唤醒一个 +- `public final native void notifyAll()`:`native`方法,并且不能重写。跟`notify`一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程 +- `public final native void wait(long timeout) throws InterruptedException`:`native`方法,并且不能重写。暂停线程的执行。注意:`sleep`方法没有释放锁,而`wait`方法释放了锁 ,`timeout`是等待时间 +- `public final void wait(long timeout, int nanos) throws InterruptedException`:多了`nanos`参数,这个参数表示额外时间(以毫微秒为单位,范围是`0-999999`), 所以超时的时间还需要加上`nanos`毫秒 +- `public final void wait() throws InterruptedException`:跟之前的2个`wait`方法一样,只不过该方法一直等待,没有超时时间这个概念 +- `protected void finalize() throws Throwable { }`:实例被垃圾回收器回收的时候触发的操作 -public final native Class getClass()//native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。 - -public native int hashCode() //native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。 -public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。 - -protected native Object clone() throws CloneNotSupportedException//naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。 - -public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。 - -public final native void notify()//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。 - -public final native void notifyAll()//native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。 - -public final native void wait(long timeout) throws InterruptedException//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。 - -public final void wait(long timeout, int nanos) throws InterruptedException//多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。 - -public final void wait() throws InterruptedException//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念 - -protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作 - -``` ## 反射 @@ -1400,4 +1388,4 @@ Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上 - https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre - https://www.educba.com/oracle-vs-openjdk/ -- https://stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdk?answertab=active#tab-top## 基础概念与常识 \ No newline at end of file +- https://stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdk?answertab=active#tab-top## 基础概念与常识 From 9cc9218c71de155d4e2d09897264a05d1da390ba Mon Sep 17 00:00:00 2001 From: tangj1992 <694756023@qq.com> Date: Mon, 24 May 2021 10:37:30 +0800 Subject: [PATCH 007/257] =?UTF-8?q?Update=20ConcurrentHashMap=E6=BA=90?= =?UTF-8?q?=E7=A0=81+=E5=BA=95=E5=B1=82=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=88=86=E6=9E=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- .../ConcurrentHashMap源码+底层数据结构分析.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/collection/ConcurrentHashMap源码+底层数据结构分析.md b/docs/java/collection/ConcurrentHashMap源码+底层数据结构分析.md index ebabf4a4..cb5ce818 100644 --- a/docs/java/collection/ConcurrentHashMap源码+底层数据结构分析.md +++ b/docs/java/collection/ConcurrentHashMap源码+底层数据结构分析.md @@ -91,7 +91,7 @@ public ConcurrentHashMap(int initialCapacity,float loadFactor, int concurrencyLe 总结一下在 Java 7 中 ConcurrnetHashMap 的初始化逻辑。 1. 必要参数校验。 -2. 校验并发级别 concurrencyLevel 大小,如果大于最大值,重置为最大值。无惨构造**默认值是 16.** +2. 校验并发级别 concurrencyLevel 大小,如果大于最大值,重置为最大值。无参构造**默认值是 16.** 3. 寻找并发级别 concurrencyLevel 之上最近的 **2 的幂次方**值,作为初始化容量大小,**默认是 16**。 4. 记录 segmentShift 偏移量,这个值为【容量 = 2 的N次方】中的 N,在后面 Put 时计算位置时会用到。**默认是 32 - sshift = 28**. 5. 记录 segmentMask,默认是 ssize - 1 = 16 -1 = 15. From 513258a7f44876d8f981e4d41dc7294a3ef6dd9f Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 25 May 2021 23:15:13 +0800 Subject: [PATCH 008/257] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 33 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index 40c9e873..4911d88f 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -1118,17 +1118,28 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { Object 类是一个特殊的类,是所有类的父类。它主要提供了以下 11 个方法: -- `public final native Class getClass()`:`native`方法,用于返回当前运行时对象的`Class`对象,使用了`final`关键字修饰,故不允许子类重写 -- `public native int hashCode()`:`native`方法,用于返回对象的哈希码,主要使用在哈希表中,比如`HashMap` -- `public boolean equals(Object obj)`:用于比较两个对象的内存地址是否相等,`String`类对该方法进行了重写,判断用户比较字符串的值是否相等 -- `protected native Object clone() throws CloneNotSupportedException`:`naitive`方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象`x`,表达式`x.clone() != x`为`true`,`x.clone().getClass() == x.getClass()`为`true`。`Object`本身没有实现`Cloneable`接口,所以不重写`clone`方法并且进行调用的话会发生`CloneNotSupportedException`异常 -- `public String toString()`:返回`类的名字@实例的哈希码`的16进制的字符串。建议`Object`所有的子类都重写这个方法 -- `public final native void notify()`:`native`方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念),如果有多个线程在等待只会任意唤醒一个 -- `public final native void notifyAll()`:`native`方法,并且不能重写。跟`notify`一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程 -- `public final native void wait(long timeout) throws InterruptedException`:`native`方法,并且不能重写。暂停线程的执行。注意:`sleep`方法没有释放锁,而`wait`方法释放了锁 ,`timeout`是等待时间 -- `public final void wait(long timeout, int nanos) throws InterruptedException`:多了`nanos`参数,这个参数表示额外时间(以毫微秒为单位,范围是`0-999999`), 所以超时的时间还需要加上`nanos`毫秒 -- `public final void wait() throws InterruptedException`:跟之前的2个`wait`方法一样,只不过该方法一直等待,没有超时时间这个概念 -- `protected void finalize() throws Throwable { }`:实例被垃圾回收器回收的时候触发的操作 +```java +public final native Class getClass()//native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。 + +public native int hashCode() //native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。 +public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。 + +protected native Object clone() throws CloneNotSupportedException//naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。 + +public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。 + +public final native void notify()//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。 + +public final native void notifyAll()//native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。 + +public final native void wait(long timeout) throws InterruptedException//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。 + +public final void wait(long timeout, int nanos) throws InterruptedException//多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。 + +public final void wait() throws InterruptedException//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念 + +protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作 +``` ## 反射 From 24a91cd7ac2e01e8affc51e310334a0b67d37c91 Mon Sep 17 00:00:00 2001 From: zhaoweiwei <1275013290@qq.com> Date: Wed, 26 May 2021 22:01:49 +0800 Subject: [PATCH 009/257] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6JDK?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E4=BB=A3=E7=90=86BY=E5=81=A5=E7=BE=8E?= =?UTF-8?q?=E7=8C=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/JDK动态代理-健美猪.md | 425 +++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 docs/java/basis/JDK动态代理-健美猪.md diff --git a/docs/java/basis/JDK动态代理-健美猪.md b/docs/java/basis/JDK动态代理-健美猪.md new file mode 100644 index 00000000..51503d62 --- /dev/null +++ b/docs/java/basis/JDK动态代理-健美猪.md @@ -0,0 +1,425 @@ +最近在整理关于AOP的资料,发现绕不开代理(Proxy)这个概念,所以还是先梳理下这块的知识点,为以后做做铺垫,全文很长,改了很多版才敢发出来,约7000字,概念也比较多,可以先收藏慢慢看,毕竟不管多难的文章,**收藏=我会了**: + + +**但如果真看懂了,就来个赞吧,创作不易就想来点鼓励**。 + +## 什么是代理Proxy +代理我理解是一种**代码增强**,即在原先的方法逻辑上加上额外操作,在方法执行之前和之后加点通用逻辑,方便实现和维护,代理粗略可以分为静态代理和动态代理,本文的重点是后者,至于为什么要这么写,恐怕大部分人都是一知半解,所以本文的重点是解析JDK动态代码写法背后的过程和实现逻辑,但纯文字谁要看,所以文章里画了不少流程图希望能帮助你看懂。** + +## 静态代理 +先说下静态代理,比较简单,我通过一个例子简单讲下,比如有一个业务:**炜哥要去银行存钱10000块钱**,那么可以这样做: +定义一个 `SaveMoney` 的接口,需要实现的方法是**存钱** +```java +/** + * 去银行存钱 + * + * @author 炜哥 + */ +public interface SaveMoney { + + /** + * 去银行存钱 + */ + public void saveMoney(); +} +``` +然后有个具体实现类 `SaveMoneyToBankImpl` :**谁存钱,存了多少钱** +```java +/** + * 存钱实现 + * 谁存钱,存了多少钱 + * + * @author + */ +public class SaveMoneyToBankImpl implements SaveMoney { + + private String peopleName; + + private int money; + + public SaveMoneyToBankImpl(String peopleName,int money) { + this.peopleName = peopleName; + this.money = money; + } + + /** + * 具体实现存钱 + */ + public void saveMoney() { + System.out.println(peopleName + "在银行存了" + money + "元"); + } +} +``` +平常代码(存钱)到这里就结束了,不过假设业务流程需要调整: + +- 需要加一个校验(即存的钱是不是真的) +- 实现类不能动(来存钱的人不会自己验钞) + +你肯定会想到在**实现类**的 `saveMoney()` 中前后增加一些操作: +```java +/** + * 具体实现存钱 + */ +public void saveMoney() { + System.out.println("工作人员开始验钞..."); + System.out.println("验钞通过..."); + System.out.println(peopleName + "在银行存了" + money + "元"); + System.out.println("存钱完毕..."); +} +``` +这样做可以吗?**当然可以**,逻辑都实现了有啥不可以,但这时候**普通程序员**和**架构师**的区别就体现出来了: +> **普通程序员**:什么?加点额外操作,加!直接在原逻辑上开搞 +> **架构师**:这个额外操作看着有点普遍,会不会其他地方也需要?如果其他代码也需要难道都一个个手动加么,能不能给原逻辑某个执行点前后自动加上所需操作,从而解放(拯救)我们码农的双手(头发)? + +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620378296918-b8eeb9fd-37f6-41be-aefc-5297cba56b57.png) +**能不能另外弄一个代理程序,包含原程序需要执行的方法和额外操作,到时候只要执行下这个对象的方法不就行了么**,先不管通用不通用了,看看能不能把有这种功能的代理程序弄出来,既然思路有了就开搞: +为存钱这个动作做一个代理(**有一个银行工作人员帮你验钞**),即定义一个银行工作人员的代理类 `SaveMoneyByWokerProxy` ,构造函数的入参是实际对象(也就是XX要存XX钱的一个对象) +```java +/** + * 存钱代理,银行柜员代理存钱 + * + * @author 炜哥 + * @since 2021-04-15 21:56:39 + */ +public class SaveMoneyByWokerProxy implements SaveMoney { + + //代理对象 + SaveMoney saveMoneyProxy; + + //通过构造器给代理对象赋值 + public SaveMoneyByWokerProxy(SaveMoney saveMoney) { + this.saveMoneyProxy = saveMoney; + } + + /** + * 用代理存钱(工作人员帮忙存钱) + * 在这里会有一些业务流程上的操作 + */ + public void saveMoney() { + System.out.println("工作人员开始验钞..."); + System.out.println("验钞通过..."); + saveMoneyProxy.saveMoney(); + System.out.println("存钱完毕..."); + } +} +``` +OK,接下来就是测试下了 +```java +/** + * 代理存钱测试类 + * + * @author 炜哥 + * @since 2021-04-15 22:01:53 + */ +public class SaveMoneyProxyTest { + + public static void main(String[] args) { + + //定义一个炜哥存钱10000元的实际对象,炜哥要去存10000元了 + //这边为什么不是实现类对象 = new 实现类(); + //1.可以统一化管理所有子类,只需要提供一个共有的方法 + //2.java设计原则之一:依赖于抽象编程,而不是实现 + SaveMoney weigeSaveMoney = new SaveMoneyToBankImpl("炜哥",10000); + + //炜哥把要存的一万元和身份信息交给银行工作人员(生成一个代理对象) + SaveMoneyByWokerProxy workerProxySaveMoney = new SaveMoneyByWokerProxy(weigeSaveMoney); + + //代理对象也就是银行工作人员开始存钱(实际由代理类完成实际对象的方法) + workerProxySaveMoney.saveMoney(); + } +} +``` +运行结果: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1618541115094-d43003f1-254b-4c72-8e3e-6673b7f7a270.png) +到这里可能就会有人说了,这代理跟接口实现有什么区别吗,都用了关键词 `implements` 来实现 +**有区别**,我们看下面用红框框起来的内容: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620373395192-6aa39252-6480-4881-92bd-c720afc303b3.png) +代理对象 `saveMoneyProxy` 不仅做了实际对象需要做的操作 `saveMoney()` ,而且在这个操作的前后做了一些额外操作(这个额外操作在实际项目里很多应用场景,比如计算方法执行时间、执行前的校验、执行后的统一输出等),也就是**方法增强概念。而且静态代理还实现了目标接口类和增强代码的解耦,**但静态代理有非常致命的缺陷,为什么这么说呢,先来回顾下上述例子实现静态代理的过程: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620379095140-028c2a5c-6f51-4d5b-bf91-ab3ff3d6c980.png) +显而易见,虽然原有程序(**目标类**)和增强代码解耦了,但是原有程序(**目标类**)跟代理程序(**代理类**)又纠缠不清了,为什么这么说呢,体现在两个方面: + +- 代理的对象每次只能设定一种,如果上面的实际对象 `saveMoney` 换成其他就需要新增代理类 +- 因为需要实现相同的方法,所以如果原有程序新增/修改方法,那么代理程序也都需要同步新增/修改 + + + +比较灵性的人看到这,会说,这两个问题有啥难的,我只要**用Object类和Method分别接收目标对象和目标对象需要增强的方法**不就行啦,至于需要实现接口的所有方法,那我**不实现接口**不行吗,为啥非要实现目标接口呢?多此一举,来,上**小爷的“动态代理类”**: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620824714014-b8bcbb60-3953-406f-befd-2cbfe8b8edad.png) +执行代码改一改,变成这样: +```java +//炜哥把要存的一万元和身份信息交给银行工作人员(生成一个代理对象) +SaveMoneyByWokerProxy workerProxySaveMoney = new SaveMoneyByWokerProxy(weigeSaveMoney, weigeSaveMoney.getClass().getMethod("saveMoney")); +``` +执行结果: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620824854980-769cc7b7-f30b-4958-b8bc-3a8c299bbf91.png) +程序实现确实没有问题,但是我们忽略了一个问题,代理的**初衷**是什么,或者说什么是代理: + + +代理类是为目标类而服务的,目标类更占主导地位,后者只关心自己需要执行的方法,通俗点讲就是:**“你讲你的开场白和结束语,别影响我的真功夫表演”,**而上面这个所谓的代理类虽然实现了一样的作用但总有种**被托管**的味道,有点就像是“**我把我的真功夫给你,你替我发扬光大**”的意思,因为此时的代理类跟目标类没有任何关系了。 + + +实际上,这种“代理类”被世人称之为**装饰器模式**,这两种模式在本文里的应用场景下根本体会不到它们之间的细微差别,因此继续讨论下去的意义不大,有兴趣去查下资料,**动态代理模式和装饰者模式之间的区别**,这里就不做展开,徒增你们的记忆负担了。 + + +好了,回到正题,如何解决上述这两个问题,既要实现接口来体现代理的含义,又要解决因此带来的棘手问题 + +## JDK动态代理 +**它的出现就是为了解决上述两大难,但如果是你,会如何去设计动态代理,不急,先分析下静态的过程** + +### 创建代理类的目的 + +1. 创建上述的代理类 `SaveMoneyByWokerProxy` 是为了做什么,是不是为了初始化时接收目标类实例从而生成一个代理对象 +1. 生成代理对象是为了干什么,是不是为了能够调用目标类实例的方法并同时执行代理对象中的增强代码 + +所以,重点来了,能不能通过不设计**完全没头绪的动态代理类**得到**代理对象**,从而调用**目标类实例方法**和**增强代码**,因为后面这两个才是我们最终想要的。 +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620880813876-8b72cdd8-a4a4-4ed6-a0a8-de0e4c4ebed7.png) +按照静态代理的思路,获得目标实例的代理对象**一我们需要目标类的实例化对象,二需要一个代理类去接收该对象,获得对象方法,重写方法时在目标对象方法前后加点料(方法增强)。    ** +第一步没有什么问题,虽然接口不能直接new一个对象,说到new,**可能有比较灵性的同学会想到,接口是有class对象的,能否通过class对象的 `newInstance` 方法反射创建对象呢?**很遗憾,反射没用**,因为它没有构造函数**,不信看下面代码: +```java +//获取接口的构造器 +Constructor[] constructors = SaveMoney.class.getConstructors(); +for (Constructor constructor : constructors) { + System.out.println(constructor); +} +``` +**输出的结果是空的,**那为什么这个代码看起来那么像是接口被实例化了,生成了“接口对象”: +```java +SaveMoney weigeSaveMoney = new SaveMoneyToBankImpl("炜哥",10000); +``` +NoNoNo,千万别搞错了,很多人喜欢把一个 `A a = new A()` 的这个a当成一个对象,这样你完全没有办法理解后面的多态是怎么一回事,所以我更喜欢把a当成是一个引用,就像C语言的指针一样,指向的是右边真正创建的对象,也就是栈内存和堆内存存放数据类型之间的关系。 + + +**所以,只要目标类被某个类实现了,目标对象不是什么问题(JDK动态代理的前提是接口至少被一个实现类实现,否则就无法生成代理对象)**,因此重点在于第二步。 + + +想一下,如果我们要设计一个**动态代理类**,是不是应该把代理类设计成**一个可以接收所有目标对象和实现所有目标对象中所有方法**的样子,怎么去弄,我擦嘞!完全没头绪啊。 + +### 贴心的JDK +好难,第二个条件好难,有没有什么办法直接通过一个**API方法**来获得**代理对象**啊 +**有!!!** +贴心的JDK中有一个 `java.lang.reflect` 包下的 `Proxy` 类,字面意思就是代理,我们看下它有哪些方法: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620437611840-381617a1-f880-4935-93a8-0892cb18bc1f.png) +红框框起来的字面意思看起来跟我们需要解决的问题有很大关系,先看下第一个方法_getProxyClass_ +_![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620437741640-7eff4536-c9b9-4cd9-823e-11a94e0aa056.png)_ +入参是类加载器和Class对象,返回了一个新的Class对象,想要更确切的信息看下源码中的英文注释: +> _Returns the {_**@code **_java.lang.Class} object for a proxy class given a class loader and an array of interfaces.  The proxy class will be defined by the specified class loader and will implement all of the supplied interfaces.  If any of the given interfaces is non-public, the proxy class will be non-public. If a proxy class for the same permutation of interfaces has already been defined by the class loader, then the existing proxy class will be returned; otherwise, a proxy class for those interfaces will be generated dynamically and defined by the class loader._ + +直接反手一个有道翻译: +> **返回代理类的{@code java.lang.Class}对象,给出类装入器和接口数组**。代理类将由指定的类装入器定义,并将实现提供的所有接口。如果任何给定接口是非公共的,则代理类是非公共的。如果类装入器已经定义了用于相同接口排列的代理类,那么将返回现有的代理类;否则,将动态生成这些接口的代理类,并由类装入器定义 + + + +我们只要关注第一句加粗的话,返回**代理类的Class对象**,等于说,我们上面绞尽脑汁想要的,这里只要一句话就搞定了!!! +```java +Class proxyClass = Proxy.getProxyClass(SaveMoney.class.getClassLoader(), SaveMoney.class.getInterfaces()); +``` +**既然代理类的Class对象拿到了,那得到代理对象不是分分钟的事情,不就要求传入类加载器和类信息么,开搞:** +```java +//获得代理类的Class对象 +Class proxyClass = Proxy.getProxyClass(SaveMoney.class.getClassLoader(), SaveMoney.class.getInterfaces()); +//通过Class反射获得代理类实例 +SaveMoneyToBankImpl saveMoneyToBankImpl = (SaveMoneyToBankImpl)proxyClass.newInstance(); +``` +很遗憾,第二句代码的 `newInstance` 不行,为什么: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620438625034-011d0fa1-b570-4c4e-9237-547eb150c8ad.png) +`Proxy` 的默认无参构造函数是private类型的(代理类继承了Proxy),而且注释上的_Prohibits instantiation._清清楚楚表达着:**别用这个,不允许** +** +其实你看上述代码应该也能想到,就算这样能创建出来的代理对象也是没软用的,为什么? +**因为目标对象 `saveMoney` 根本没用到呀,**`SaveMoney` 实现类那么多,但**我们只用了 **`**SaveMoney**` **接口,没用到目标对象的话怎么找到并执行目标对象的方法呢** +还有没有其他办法了,再往下看: + +### Proxy的有参构造函数 +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620438761618-b0ce91a2-1b8d-40cb-85a3-29822eeb4e12.png) +又发现了一个构造器,这个修饰词是protect,肯定能直接用,不过有个入参,类型是 `InvocationHandler` ,这个类做什么的? + + +在你不知道某个类干嘛用的,又找不到对应的api文档时,只能硬着头皮进源码看一眼了,但这次你会发现这个类出奇的简单: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620439092284-2b722a3a-2630-484a-b3fe-22b32681f644.png) +只有一个 `invoke` 方法,对反射有经验的看到`invoke`应该能想到,反射类Method中也有`invoke`,那么是不是意味着这个`InvocationHandler`跟方法有关系,也就是跟增强代码可能有点联系。 + + +而且你发现没有,`InvocationHandler`是一个接口,需要有实现类去实现,所以`invoke`方法得重写,问题又来了,invoke方法重写成什么样子,要想知道怎么重写首先得知道各个方法入参是什么意思: + +- **dynamic_proxy**:代理对象com.sun.dynamic_proxy.$Proxy0 +- **method**:代理对象的Method方法实例 +- **args**:指代代理对象方法传递的参数 + + + +看了中文注释是不是还是有点懵逼?没关系,一个个来: + +- 第一个com.sun.dynamic_proxy.$Proxy0是什么意思,其实是这样的,jvm会根据我们传入的参数生成代理类,被类加载加载后生成class字节码文件(也就是Class对象),类型名是**“$Proxy”+序号(据说使用后会被删除掉,所以你找不到这个class文件)**,这个类实现了所有传入接口的所有方法,也就是我们上面一心想要拿到的代理对象,但这个参数基本不会用到。 +- 第二个method你可以理解为代理对象中的方法反射,因为通过Proxy生成的代理Class对象已经传入了接口所有需要实现的方法,所以通过这个参数我们能反射执行所有接口方法,了解反射的同学肯定知道Class对象中有个反射Data,里面就有Method实例 +- 第三个比较好理解,就是一些参数之类的传递 +- 除此之外,还有个return的Object,**这个object你可以理解成是和被代理对象方法相同的返回值,即目标对象的该方法返回什么,那么Object就是什么** + +** +**先不管这么多了,我只要个代理对象,先随便重写下invoke方法试试看吧:** +**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879082496-217134bd-ca73-4a83-9728-021ecb04f241.png)** +报错了,无法创建目标类的代理对象,为啥啊,我都按照api要求传入需要的参数了呀: +还是上述说的那个问题,**不传入目标对象,Proxy怎么给你造一个可以执行目标对象方法的代理对象**啊,一句话总结就是:**获得代理Class对象可以只用接口,但生成代理对象则需要目标对象**,所以我们换一种写法: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879460015-6752ecc8-ba36-4f0b-aad9-fb495deb4102.png) +可能有人对**`InvocationHandler`**这个参数还是没概念,那只能使出我的**和稀泥大法**:**你只要理解成把`InvocationHandler`丢到代理类 `Proxy` 中,JDK底层在`Proxy`中一通鸡儿操作,最后向下转型生成的代理类对象执行目标对象方法时,会自动调用`InvocationHandler`中重写的 `invoke` 方法,这样说的话,那重写的invoke方法是不是可以大做文章了?** +**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879552715-b18fd367-5e8c-4b8c-a73d-187d7598607c.png)** +**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620881202389-bc475d83-0e2d-493b-ba95-ac0ea8f4a7bd.png)** +**所以 `Proxy` 类不光帮我们解决了如何获得代理对象,又允许我们通过`InvocationHandler`把目标对象和增强方法也放进去!!!** + + +说的有点深了,有些人已经忘记之前的思路是什么样子了,这里再回顾下: + +- 需要能够接受所有泛型类和实现所有泛型类方法的动态代理类-》动态代理类不知道怎么创建-》拿不到代理对象-》**这条路走不通了** +- ①JDK有个Proxy类可以通过传入不需要实例化的接口就能生成代理类的**Class对象**-》 +- ②**代理Class对象**有构造函数所以可以通过**反射**直接拿到代理对象,但**构造函数**需要传入`InvocationHandler`-》 +- ③`InvocationHandler` 入参需要重写invoke方法,此时可以传入目标对象,通过**方法反射**执行目标对象方法,增强代码此时也可以放入,而通过**该构造函数生成的代理对象**执行目标方法时会自动执行`InvocationHandler` 中的重写invoke方法,最终达到代码增强的效果 + +所以最终JDK动态代理的思路大概应该是: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620882373243-f00409ff-066e-4712-929f-b3e00ced291e.png) +ok,思路有了,Method实例有了,是不是可以通过 `method.invoke` 来执行目标类的方法,但invoke方法还需要传入目标对象,目标对象当然不是第一个参数_代理对象com.sun.dynamic_proxy.$Proxy0_ ,所以传入的目标对象**saveMoney**,上面的代码再改一改: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879727230-1f043b81-8bd6-4160-92dc-445c74f5c577.png) +执行输出: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620450709671-e195eb45-e1a4-4f36-9363-538f052992d5.png) +代码执行了,也达到预期效果了,但有些小萌新还是会有点疑惑: + +- 为什么要先反射获取代理Class对象的构造函数Constructor,然后通过Constructor的newInstance()方法创建代理对象,不能直接用代理Class对象的newInstance()方法创建代理对象吗? +- 为什么代理对象只能用接口`SaveMoney` 去接,不能使用它的实现类比如 `SaveMoneyToBankImpl` 去接收吗? + + + +第一个问题,其实这个看Class源码就能知道,Class对象的newInstance()方法实际上还是调用构造器Constructor的无参构造函数newInstance(),比较局限,如果Class对象没有无参构造器,那么直接调用newInstance()就会报错,Constructor里支持无参和有参构造,因为需传入`InvocationHandler` 的关系所以得通过Constructor获得有参构造函数对象: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620453535075-c5f48894-276d-488d-83f2-29356210b891.png) +至于第二个,我的解释非常简单,代理类已经实现了目标接口的所有方法,那么你可以把它看做就是个目标接口实现类,那么想用**另外一个目标接口实现类去接收代理对象**就相当于这样: +```java +public interface 接口 {...} +class 实现类1 implements 接口{...} +class 实现类2 implements 接口{...} //把代理类看做是实现类2 +class Test{ + public static void main(String[] args) { + //相当于这样 + 实现类1 实现类1对象 = (实现类1) new 实现类2(); + } +} +``` +这个操作肯定不允许啊,实现类1和实现类2之间又没有直接的联系,怎么能相互之间强转呢?_ + +### 直接拿代理对象_ +OK,其实我们的目的已经达到了,不过可以往回看一眼, `Proxy` 类中除了 `getProxyClass` 方法之外,还有另外一个方法 `newProxyInstance` ,即直接返回给你一个代理对象! +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620453873833-3fd5c3d4-5eff-4de8-9083-67089b941efe.png) +这就更简单了,不需要再自己弄一个有参构造函数对象,直接调用这个Api就可以拿到代理对象了,是上述方法的**简化版**: +```java +//初始化目标类对象 +SaveMoney saveMoney = new SaveMoneyToBankImpl("炜哥", 1000); + +//通过有参构造函数得到代理对象 +SaveMoney saveMoneyProxy = (SaveMoney) Proxy.newProxyInstance( + saveMoney.getClass().getClassLoader(), + saveMoney.getClass().getInterfaces(), + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + //为了实现功能,先这样写 + System.out.println("工作人员开始验钞..."); + System.out.println("验钞通过..."); + Object o = method.invoke(saveMoney, args); + System.out.println("存钱完毕..."); + return o; + } + }); + +//这个saveMoney方法其实已经包含了上面的增强代码 +saveMoneyProxy.saveMoney(); +``` +执行的结果和上面是一样的,同样需要先确定目标对象 + + +不过上面的代码有点小瑕疵,需要抽取 `new InvocationHandler` 这块对象,因为如果还有其他增强业务呢,总不能把增强业务写死吧,而且内部的目标对象也不能写死: +![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620459362534-47c3f17a-ab3f-48b3-87ca-317396676642.png) +把抽取出来的代码命名为`ProxyHandler` ,同时增加有参构造函数来接收像SaveMoney这样的变量 +```java +/** + * @author :炜哥 + * @description:TODO 代理类 + * @date :2021/4/15 14:20 + */ +public class ProxyHandler implements InvocationHandler { + + //代理对象 + private Object target; + + //真实对象赋值 + public ProxyHandler(Object target) { + this.target = target; + } + + /** + * dynamic_proxy:代理对象com.sun.dynamic_proxy.$Proxy0 + * method:代理对象的Method方法实例 + * args:指代代理对象方法传递的参数 + */ + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("工作人员开始验钞..."); + System.out.println("验钞通过..."); + Object o = method.invoke(target, args); + System.out.println("存钱完毕..."); + return o; + } +} +``` +这个代理类跟静态代理中的 `SaveMoneyByWokerProxy` 类起到相同的作用,但不同的是实现了 `InvocationHandler` 接口,重写了 `invoke()` 方法,构造器入参由之前的**特定类**变成了**Object** + + +最后用 `Proxy` 类生成代理对象测试下(**解释各个入参的含义我已经尽力了......**) +```java +/** + * 动态代理测试 + * + * @author :炜哥 + * @description:TODO + * @date :2021/4/14 16:36 + */ +public class SaveProxyTest { + + public static void main(String[] args) { + + //定义一个炜哥存钱10000元的实际对象,炜哥要去存10000元了 + SaveMoney saveMoney = new SaveMoneyToBankImpl("炜哥",10000); + + /** + * 代理对象的调用处理程序 + * 你可以把它想象成一个“传入真实对象生成代理对象”的程序,其内置的invoke()方法会最终调用真实对象的方法 + */ + InvocationHandler invocationHandler = new ProxyHandler(saveMoney); + + /** + * 炜哥把要存的一万元和身份信息交给银行工作人员(通过newProxyInstance创建一个代理对象) + * + * 第一个参数 the class loader to define the dynamic_proxy class + * 谁被代理就用谁的类加载器,是一种固定的写法,用来加载代理Class对象字节码 + * + * 第二个参数 the list of interfaces for the dynamic_proxy class to implement + * 让代理对象有跟被代理对象相同的方法,谁被代理就写谁的getInterfaces,也是一种固定写法 + * + * 第三个参数 invocationHandler的invoke方法the invocation handler to dispatch method invocations to + * 让我们可以把增强代码放入该handler中,从而实现代理 + * + * 返回参数 + * a dynamic_proxy instance with the specified invocation handler of a that is defined by the specified class loader + * and that implements the specified interfaces + * 返回一个代理对象,该对象是被指定的类加载器定义并且实现了指定接口 + * + */ + SaveMoney saveMoneyProxy = (SaveMoney) Proxy.newProxyInstance( + saveMoney.getClass().getClassLoader(), + saveMoney.getClass().getInterfaces(), + invocationHandler); + + //这个saveMoney方法其实已经包含了上面的增强代码 + saveMoneyProxy.saveMoney(); + } +} +``` +这样,增强代码放在了InvocationHandler中,并且可以通过反射执行目标类的所有方法,**实现了增强代码和目标类的解耦;**代理对象可以通过Proxy配合InvocationHandler获得,没有像静态代理一样与目标类纠缠不清的代理类,不管有多少个目标类,通过这两个类配合统统可以接收,**实现了目标类与代理对象的解耦**,这种通过接口获取代理对象的叫做**JDK动态代理(**不能用在非接口类的代理上面,因为newProxyInstance方法中第二个参数就是要求传入目标类对象的接口数组**)。** +** +在JDK动态代理中,为什么一定要基于接口实现?这个问题其实你可以通过代理类class反推,通过反编译得到一个结果:**代理类都继承了Proxy,因为java单继承的关系,只能通过实现关系来满足代理的意义**,那如果想基于没有被任何实现类实现的java类呢,能不能生成动态代理对象,答案当然是肯定的: + + +但是有空再说这种动态代理-cglib From 9873b1b08d3b7f84cb49c7455e352e33346d4773 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 27 May 2021 20:50:29 +0800 Subject: [PATCH 010/257] =?UTF-8?q?1.5=20Collections=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=201.5.2=20=E9=94=99=E5=88=AB=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/collection/Java集合框架常见面试题.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 63e67002..39bf90f7 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -594,10 +594,10 @@ void rotate(List list, int distance)//旋转。当distance为正数时,将list int binarySearch(List list, Object key)//对List进行二分查找,返回索引,注意List必须是有序的 int max(Collection coll)//根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll) int max(Collection coll, Comparator c)//根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c) -void fill(List list, Object obj)//用指定的元素代替指定list中的所有元素。 +void fill(List list, Object obj)//用指定的元素代替指定list中的所有元素 int frequency(Collection c, Object o)//统计元素出现次数 -int indexOfSubList(List list, List target)//统计target在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target). -boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替换旧元素 +int indexOfSubList(List list, List target)//统计target在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target) +boolean replaceAll(List list, Object oldVal, Object newVal)//用新元素替换旧元素 ``` ### 1.5.3. 同步控制 @@ -619,4 +619,4 @@ synchronizedSet(Set s) //返回指定 set 支持的同步(线程安全的 **《Java 面试突击》:** Java 程序员面试必备的《Java 面试突击》V3.0 PDF 版本扫码关注下面的公众号,在后台回复 **"面试突击"** 即可免费领取! -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/format,png.jpeg) \ No newline at end of file +![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/format,png.jpeg) From 966facaf8412b14f7d3e072e1e8a0d1af8801975 Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 28 May 2021 08:22:32 +0800 Subject: [PATCH 011/257] =?UTF-8?q?=E5=AE=8C=E5=96=84=20CAP=20=E7=90=86?= =?UTF-8?q?=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/system-design/distributed-system/CAP理论.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/system-design/distributed-system/CAP理论.md b/docs/system-design/distributed-system/CAP理论.md index 045581b9..d12ffaa1 100644 --- a/docs/system-design/distributed-system/CAP理论.md +++ b/docs/system-design/distributed-system/CAP理论.md @@ -46,13 +46,13 @@ CAP 理论的提出者布鲁尔在提出 CAP 猜想的时候,并没有详细 > > 简而言之就是:CAP 理论中分区容错性 P 是一定要满足的,在此基础上,只能满足可用性 A 或者一致性 C。 -因此,**分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。** +因此,**分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。** 比如 ZooKeeper、HBase 就是 CP 架构,Cassandra、Eureka 就是 AP 架构,Nacos 不仅支持 CP 架构也支持 AP 架构。 -**为啥无同时保证 CA 呢?** +**为啥不可能选择 CA 架构呢?** 举个例子:若系统出现“分区”,系统中的某个节点在进行写操作。为了保证 C, 必须要禁止其他节点的读写操作,这就和 A 发生冲突了。如果为了保证 A,其他节点的读写操作正常的话,那就和 C 发生冲突了。 -举个例子:若系统出现“分区”,系统中的某个节点在进行写操作。为了保证 C, 必须要禁止其他节点的读写操作,这就和 A 发生冲突了。如果为了保证 A,其他节点的读写操作正常的话,那就和 C 发生冲突了。 +**选择 CP 还是 AP 的关键在于当前的业务场景,没有定论,比如对于需要确保强一致性的场景如银行一般会选择保证 CP 。** -**选择的关键在于当前的业务场景,没有定论,比如对于需要确保强一致性的场景如银行一般会选择保证 CP 。** +另外,需要补充说明的一点是: **如果网络分区正常的话(系统在绝大部分时候所处的状态),也就说不需要保证 P 的时候,C 和 A 能够同时保证。** ### CAP 实际应用案例 From ae8a771476d3e35b9dffb83218ecfe65d9cd417a Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 28 May 2021 08:53:47 +0800 Subject: [PATCH 012/257] =?UTF-8?q?BASE=E7=90=86=E8=AE=BA=EF=BC=9A?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=9C=80=E7=BB=88=E4=B8=80=E8=87=B4=E6=80=A7?= =?UTF-8?q?=E7=9A=84=E5=85=B7=E4=BD=93=E6=96=B9=E5=BC=8F=E6=98=AF=E4=BB=80?= =?UTF-8?q?=E4=B9=88=E5=91=A2=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/system-design/distributed-system/BASE理论.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/system-design/distributed-system/BASE理论.md b/docs/system-design/distributed-system/BASE理论.md index 0a0bd06f..17c5789c 100644 --- a/docs/system-design/distributed-system/BASE理论.md +++ b/docs/system-design/distributed-system/BASE理论.md @@ -53,6 +53,14 @@ CAP 理论这节我们也说过了: > > **业界比较推崇是最终一致性级别,但是某些对数据一致要求十分严格的场景比如银行转账还是要保证强一致性。** +那实现最终一致性的具体方式是什么呢? [《分布式协议与算法实战》](http://gk.link/a/10rZM) 中是这样介绍: + +> - **读时修复** : 在读取数据时,检测数据的不一致,进行修复。比如 Cassandra 的 Read Repair 实现,具体来说,在向 Cassandra 系统查询数据的时候,如果检测到不同节点 的副本数据不一致,系统就自动修复数据。 +> - **写时修复** : 在写入数据,检测数据的不一致时,进行修复。比如 Cassandra 的 Hinted Handoff 实现。具体来说,Cassandra 集群的节点之间远程写数据的时候,如果写失败 就将数据缓存下来,然后定时重传,修复数据的不一致性。 +> - **异步修复** : 这个是最常用的方式,通过定时对账检测副本数据的一致性,并修复。 + +比较推荐 **写时修复**,这种方式对性能消耗比较低。 + ### 总结 **ACID 是数据库事务完整性的理论,CAP 是分布式系统设计理论,BASE 是 CAP 理论中 AP 方案的延伸。** From f40b2bdc6a328d06a12ee80f15689853926be77c Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 29 May 2021 10:17:18 +0800 Subject: [PATCH 013/257] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a79146c5..d0441665 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://www.zhihu.com/question/56110328/answer/869069586) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线! +👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://www.zhihu.com/question/56110328/answer/869069586) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线! -👍推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来) +👉 推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来) -👍推荐[2021最新实战项目源码下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100018862&idx=1&sn=858e00b60c6097e3ba061e79be472280&chksm=4ea1856579d60c73224e4d852af6b0188c3ab905069fc28f4b293963fd1ee55d2069fb229848#rd) - -书单已经被移动到[awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 +👉 书单已经被移动到[awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 > 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。[图解计算机基础 PDF 版](#优质原创PDF资源)。 From e01be437dce52463ef24fb39608559d520675c9e Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 29 May 2021 10:26:06 +0800 Subject: [PATCH 014/257] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E2=80=94>=E5=A0=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../pictures/堆/删除堆顶元素1.png | Bin 0 -> 38473 bytes .../pictures/堆/删除堆顶元素2.png | Bin 0 -> 38802 bytes .../pictures/堆/删除堆顶元素3.png | Bin 0 -> 38897 bytes .../pictures/堆/删除堆顶元素4.png | Bin 0 -> 38488 bytes .../pictures/堆/删除堆顶元素5.png | Bin 0 -> 38797 bytes .../pictures/堆/删除堆顶元素6.png | Bin 0 -> 38925 bytes .../pictures/堆/堆-插入元素1.png | Bin 0 -> 50796 bytes .../pictures/堆/堆-插入元素2.png | Bin 0 -> 59748 bytes .../pictures/堆/堆-插入元素3.png | Bin 0 -> 60384 bytes .../data-structure/pictures/堆/堆1.png | Bin 0 -> 67439 bytes .../data-structure/pictures/堆/堆2.png | Bin 0 -> 49381 bytes .../pictures/堆/堆排序1.png | Bin 0 -> 27193 bytes .../pictures/堆/堆排序2.png | Bin 0 -> 25701 bytes .../pictures/堆/堆排序3.png | Bin 0 -> 23249 bytes .../pictures/堆/堆排序4.png | Bin 0 -> 20274 bytes .../pictures/堆/堆排序5.png | Bin 0 -> 16267 bytes .../pictures/堆/堆排序6.png | Bin 0 -> 10387 bytes .../pictures/堆/堆的存储.png | Bin 0 -> 46189 bytes .../data-structure/pictures/堆/建堆1.png | Bin 0 -> 28519 bytes .../data-structure/pictures/堆/建堆2.png | Bin 0 -> 28603 bytes .../data-structure/pictures/堆/建堆3.png | Bin 0 -> 28570 bytes .../data-structure/pictures/堆/建堆4.png | Bin 0 -> 28575 bytes .../data-structure/堆.md | 189 ++++++++++++++++++ 24 files changed, 190 insertions(+) create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素3.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素5.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素6.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素2.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素3.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序1.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序2.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序5.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序6.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/堆的存储.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/建堆3.png create mode 100644 docs/dataStructures-algorithms/data-structure/pictures/堆/建堆4.png create mode 100644 docs/dataStructures-algorithms/data-structure/堆.md diff --git a/README.md b/README.md index d0441665..d7d421c0 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ - **图解数据结构:** 1. [线性数据结构 :数组、链表、栈、队列](docs/dataStructures-algorithms/data-structure/线性数据结构.md) 2. [图](docs/dataStructures-algorithms/data-structure/图.md) + 3. [堆](docs/dataStructures-algorithms/data-structure/堆.md) - [不了解布隆过滤器?一文给你整的明明白白!](docs/dataStructures-algorithms/data-structure/bloom-filter.md) ### 算法 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png new file mode 100644 index 0000000000000000000000000000000000000000..63381b522c160d3386a62e30fdd8f77fd2c56387 GIT binary patch literal 38473 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 LB~bKH`^*0YWg^#s literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png new file mode 100644 index 0000000000000000000000000000000000000000..c23bbfa8cda8ec5ccc9fee60dd0c777b07ed1810 GIT binary patch literal 38802 zcmbrmcRbbY|2Q5gRI(D;yQr*Vmd$Z+4hP2;vK_~<&anxZC7URF�_y8lsHsjEu-k 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png new file mode 100644 index 0000000000000000000000000000000000000000..a2e3a937acfe1abd4a5719e0863fe22e0e6fa133 GIT binary patch literal 38488 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μnuyvIT%il#3Gz2q}T47bAP) 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 XTgttzmpNKS3_#%N>gTe~DWM4fUXZCM literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png new file mode 100644 index 0000000000000000000000000000000000000000..424fe3d91c04e9824bb86342c7e4662d543a7d6f GIT binary patch literal 50796 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

=wsWkOTJ5$XqJ24Dnvv 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png new file mode 100644 index 0000000000000000000000000000000000000000..fa08e776ec081c3c54a7f47d8018b972c19e1df5 GIT binary patch literal 67439 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png new file mode 100644 index 0000000000000000000000000000000000000000..ec8a89d0943bffe3d4d2272ecb26a4ba7597cf51 GIT binary patch literal 49381 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%0A+vs#sOHg|(r(jssfK!qQUO6XU9efom8EWAt>0 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%0A@Wv@nz&sEf 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png new file mode 100644 index 0000000000000000000000000000000000000000..61633b1d3d9c828c9703c96ae034a13cc68177bb GIT binary patch literal 23249 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png new file mode 100644 index 0000000000000000000000000000000000000000..e502b808f20923d176ec5f0ac59e60941db5dba6 GIT binary patch literal 20274 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

qx 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 literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png new file mode 100644 index 0000000000000000000000000000000000000000..f69153d0c066bbe8eeabda69eb83e1dfa953cf66 GIT binary patch literal 28519 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

UfGlMr6W8|$JUqZ6Ag%!8w^v3?yjUOA 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 YdE>z5*fZSX4E3d>Vesgyn%&#~0#dFM-v9sr literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png b/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png new file mode 100644 index 0000000000000000000000000000000000000000..fcbf71ca5a9aa941716e3a543ef7eba433a535c3 GIT binary patch literal 28603 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�|k%8T+rLU6$L>Bj}Y5`ozwJwW6SC4KRGr@oh z9o~Ek7N}87^s1{N*f~3aiR6iGwRc4^Wz1P`nOS^;zlLeS?sA^D^s`ulBapP#Yj-n~ zb~Xhs9`o#^M*e6ISRVA_vs9qC+~4)@PBjh1tkQapH~alj?& zEH^^lGOTBFd!1a*nX6G5K~27GBKK>qvIbPeXkLa4$?-QaD7Cv~z!&yipsGdxI~MjW z&JDp_8DGL|&He_S`6)}ygFD2pcHxCjwJsxcnvgmI7&B=In%)u4s2LOy?&Pm(Idq;^ z{zwpWEI`v5X_6@yRN^uTwqXf-Y4V&^?Q+aSRM~)G%)=J4&Dgte>$6?lfug5Q(ewN{ zBLF*6(`zcrjPLpQjfG1>=m`t^2z?{Fr##qgs-K)JT(*$f<`JR?k% zqeF4Y0XVsYO17)h+mtJ4sdy!HAY-!qn6uM1Q}ZaNn=+K&VZ$axJSC3bW}q&DxB3e9 z;f0?Z!374#mHi&}U@^?`cO26?|H? zG!~BW{6U%FKIs8ersc6p)G-(%o7ki)D^4{+2p^D9Q*o6$V#2GE^y#|aAs_UbFbcj7 zhOvNEb%Do8sh-AsyQ;%C zR3Efea%IaKup!wvb8LI@2B^uH+L;<*ZSy=#c)&uyF&wn zsTbdD-;3fwvxSaMcd^>x*09{5P{-VKMpMYZD)k{JBUhvdp$APFY-hIO-DwRAT&kcG zxmZ^kq>^>8R^F@(QSqY}V!u||v-{#M%Q}};1$yAH5@E-fm{JbN(hqqXfkojn+z4T0Lb0gA&HBvcjDzOqOdge%CqhM2|Olb>&y@b5QOdfhjFM2r9Y_*>dD%(Kj0cpU8k$b~K}tSK3gh{6h;7OuU(FBHpfb}I#M=~Q z&+T)fw+w;;(|j~}vU}u&mBk-GXEqA0b+Fp(R`L9nHOd+5#8o4#`rdpYzuE7V#tCPi zxaUF_WkmX2Kv09d%l)_Z(#EF_%w|CY(!&*X5A~tjw5_DTD zN|ikr(7M`V9Hkbgq9nLu`Zhz~UQXWRRWdWferY}GedU9!Sa8PCvw~ykDk75Lm;khWvYyG1=fs$RWM<_pz?0CYr-23FYwB2=W z^HqhE-OL~*Vuu^+9@qDfbly4mPt2|B9Z}y(%tvlrTAhT7B?jrX2drqp8CYe7qdHi=~;4$5cdfOw8x)3?w)^0SPK2~mHA+dMgPj6QdG2}romu#Z<4jv zd50uxhfRvXeJ#`gR5LMXXi{RM*vS#745`E^uBPrnvd-ooxIaK;WXXvwcZ=Dx(#Oq% z4QyU}(A;2cB20fi;S|E!3i{#@6M(K%DUdS6R_<}D&gq-~B%IQHds8x8a9fQF=xbR@ U>dB-Xymv}h)8Jw01MA@b1>zn(dH?_b literal 0 HcmV?d00001 diff --git a/docs/dataStructures-algorithms/data-structure/堆.md b/docs/dataStructures-algorithms/data-structure/堆.md new file mode 100644 index 00000000..7e8f9811 --- /dev/null +++ b/docs/dataStructures-algorithms/data-structure/堆.md @@ -0,0 +1,189 @@ +## 什么是堆 +堆是一种满足以下条件的树: + +堆中的每一个节点值都大于等于(或小于等于)子树中所有节点的值。或者说,任意一个节点的值都大于等于(或小于等于)所有子节点的值。 + +> 大家可以把堆(最大堆)理解为一个公司,这个公司很公平,谁能力强谁就当老大,不存在弱的人当老大,老大手底下的人一定不会比他强。这样有助于理解后续堆的操作。 + +**!!!特别提示:** + +- 很多博客说堆是完全二叉树,其实并非如此,**堆不一定是完全二叉树**,只是为了方便存储和索引,我们通常用完全二叉树的形式来表示堆,事实上,广为人知的斐波那契堆和二项堆就不是完全二叉树,它们甚至都不是二叉树。 +- (**二叉**)堆是一个数组,它可以被看成是一个 **近似的完全二叉树**。——《算法导论》第三版 + +大家可以尝试判断下面给出的图是否是二叉树? + +![](pictures/堆/堆1.png) + +第1个和第2个是堆。第1个是最大堆,每个节点都比子树中所有节点大。第2个是最小堆,每个节点都比子树中所有节点小。 + +第3个不是,第三个中,根结点1比2和15小,而15却比3大,19比5大,不满足堆的性质。 + +## 堆的用途 +当我们只关心所有数据中的最大值或者最小值,存在多次获取最大值或者最小值,多次插入或删除数据时,就可以使用堆。 + +有小伙伴可能会想到用有序数组,初始化一个有序数组时间复杂度是 `O(nlog(n))`,查找最大值或者最小值时间复杂度都是 `O(1)`,但是,涉及到更新(插入或删除)数据时,时间复杂度为 `O(n)`,即使是使用复杂度为 `O(log(n))` 的二分法找到要插入或者删除的数据,在移动数据时也需要 `O(n)` 的时间复杂度。 + +**相对于有序数组而言,堆的主要优势在于更新数据效率较高。** 堆的初始化时间复杂度为 `O(nlog(n))`,堆可以做到`O(1)`时间复杂度取出最大值或者最小值,`O(log(n))`时间复杂度插入或者删除数据,具体操作在后续章节详细介绍。 + +## 堆的分类 + +堆分为 **最大堆** 和 **最小堆**。二者的区别在于节点的排序方式。 +- **最大堆** :堆中的每一个节点的值都大于等于子树中所有节点的值 +- **最小堆** :堆中的每一个节点的值都小于等于子树中所有节点的值 + +如下图所示,图1是最大堆,图2是最小堆 + +![](pictures/堆/堆2.png) + + +## 堆的存储 +之前介绍树的时候说过,由于完全二叉树的优秀性质,利用数组存储二叉树即节省空间,又方便索引(若根结点的序号为1,那么对于树中任意节点i,其左子节点序号为 `2\*i`,右子节点序号为 `2\*i+1`)。 + +为了方便存储和索引,(二叉)堆可以用完全二叉树的形式进行存储。存储的方式如下图所示: + +![堆的存储](pictures/堆/堆的存储.png) + +## 堆的操作 +堆的更新操作主要包括两种 : **插入元素** 和 **删除堆顶元素**。操作过程需要着重掌握和理解。 +> 在进入正题之前,再重申一遍,堆是一个公平的公司,有能力的人自然会走到与他能力所匹配的位置 +### 插入元素 +> 插入元素,作为一个新入职的员工,初来乍到,这个员工需要从基层做起 + +**1.将要插入的元素放到最后** + +![堆-插入元素-1](pictures/堆/堆-插入元素1.png) + +> 有能力的人会逐渐升职加薪,是金子总会发光的!!! + +**2.从底向上,如果父结点比该元素大,则该节点和父结点交换,直到无法交换** + +![堆-插入元素2](pictures/堆/堆-插入元素2.png) + +![堆-插入元素3](pictures/堆/堆-插入元素3.png) + +### 删除堆顶元素 + +根据堆的性质可知,最大堆的堆顶元素为所有元素中最大的,最小堆的堆顶元素是所有元素中最小的。当我们需要多次查找最大元素或者最小元素的时候,可以利用堆来实现。 + +删除堆顶元素后,为了保持堆的性质,需要对堆的结构进行调整,我们将这个过程称之为"**堆化**",堆化的方法分为两种: + +- 一种是自底向上的堆化,上述的插入元素所使用的就是自底向上的堆化,元素从最底部向上移动。 +- 另一种是自顶向下堆化,元素由最顶部向下移动。在讲解删除堆顶元素的方法时,我将阐述这两种操作的过程,大家可以体会一下二者的不同。 + +#### 自底向上堆化 + +> 在堆这个公司中,会出现老大离职的现象,老大离职之后,他的位置就空出来了 + +首先删除堆顶元素,使得数组中下标为1的位置空出。 + + + +![删除堆顶元素1](pictures/堆/删除堆顶元素1.png) + + +> 那么他的位置由谁来接替呢,当然是他的直接下属了,谁能力强就让谁上呗 + +比较根结点的左子节点和右子节点,也就是下标为2,3的数组元素,将较大的元素填充到根结点(下标为1)的位置。 + +![删除堆顶元素2](pictures/堆/删除堆顶元素2.png) + + +> 这个时候又空出一个位置了,老规矩,谁有能力谁上 + +一直循环比较空出位置的左右子节点,并将较大者移至空位,直到堆的最底部 + +![删除堆顶元素3](pictures/堆/删除堆顶元素3.png) + +这个时候已经完成了自底向上的堆化,没有元素可以填补空缺了,但是,我们可以看到数组中出现了“气泡”,这会导致存储空间的浪费。接下来我们试试自顶向下堆化。 + +#### 自顶向下堆化 +自顶向下的堆化用一个词形容就是“石沉大海”,那么第一件事情,就是把石头抬起来,从海面扔下去。这个石头就是堆的最后一个元素,我们将最后一个元素移动到堆顶。 + +![删除堆顶元素4](pictures/堆/删除堆顶元素4.png) + +然后开始将这个石头沉入海底,不停与左右子节点的值进行比较,和较大的子节点交换位置,直到无法交换位置。 + +![删除堆顶元素5](pictures/堆/删除堆顶元素5.png) + +![删除堆顶元素6](pictures/堆/删除堆顶元素6.png) + + + +### 堆的操作总结 + +- **插入元素** :先将元素放至数组末尾,再自底向上堆化,将末尾元素上浮 +- **删除堆顶元素** :删除堆顶元素,将末尾元素放至堆顶,再自顶向下堆化,将堆顶元素下沉。也可以自底向上堆化,只是会产生“气泡”,浪费存储空间。最好采用自顶向下堆化的方式。 + + +## 堆排序 + +堆排序的过程分为两步: + +- 第一步是建堆,将一个无序的数组建立为一个堆 +- 第二步是排序,将堆顶元素取出,然后对剩下的元素进行堆化,反复迭代,直到所有元素被取出为止。 + +### 建堆 + +如果你已经足够了解堆化的过程,那么建堆的过程掌握起来就比较容易了。建堆的过程就是一个对所有非叶节点的自顶向下堆化过程。 + +首先要了解哪些是非叶节点,最后一个节点的父结点及它之前的元素,都是非叶节点。也就是说,如果节点个数为n,那么我们需要对n/2到1的节点进行自顶向下(沉底)堆化。 + +具体过程如下图: + +![建堆1](pictures/堆/建堆1.png) + +将初始的无序数组抽象为一棵树,图中的节点个数为6,所以4,5,6节点为叶节点,1,2,3节点为非叶节点,所以要对1-3号节点进行自顶向下(沉底)堆化,注意,顺序是从后往前堆化,从3号节点开始,一直到1号节点。 +3号节点堆化结果: + +![建堆1](pictures/堆/建堆2.png) + +2号节点堆化结果: + +![建堆1](pictures/堆/建堆3.png) + +1号节点堆化结果: + +![建堆1](pictures/堆/建堆4.png) + +至此,数组所对应的树已经成为了一个最大堆,建堆完成! + +### 排序 + +由于堆顶元素是所有元素中最大的,所以我们重复取出堆顶元素,将这个最大的堆顶元素放至数组末尾,并对剩下的元素进行堆化即可。 + +现在思考两个问题: + +- 删除堆顶元素后需要执行自顶向下(沉底)堆化还是自底向上(上浮)堆化? +- 取出的堆顶元素存在哪,新建一个数组存? + +先回答第一个问题,我们需要执行自顶向下(沉底)堆化,这个堆化一开始要将末尾元素移动至堆顶,这个时候末尾的位置就空出来了,由于堆中元素已经减小,这个位置不会再被使用,所以我们可以将取出的元素放在末尾。 + +机智的小伙伴已经发现了,这其实是做了一次交换操作,将堆顶和末尾元素调换位置,从而将取出堆顶元素和堆化的第一步(将末尾元素放至根结点位置)进行合并。 + +详细过程如下图所示: + +取出第一个元素并堆化: + +![堆排序1](pictures/堆/堆排序1.png) + +取出第二个元素并堆化: + +![堆排序2](pictures/堆/堆排序2.png) + +取出第三个元素并堆化: + +![堆排序3](pictures/堆/堆排序3.png) + +取出第四个元素并堆化: + +![堆排序4](pictures/堆/堆排序4.png) + +取出第五个元素并堆化: + +![堆排序5](pictures/堆/堆排序5.png) + +取出第六个元素并堆化: + +![堆排序6](pictures/堆/堆排序6.png) + +堆排序完成! \ No newline at end of file From 86b2ddf14e29df2d110ec62adcd7dcbaadb2b839 Mon Sep 17 00:00:00 2001 From: ly <37680485+drlifeL@users.noreply.github.com> Date: Sat, 29 May 2021 15:16:32 +0800 Subject: [PATCH 015/257] =?UTF-8?q?Update=20ArrayList=E6=BA=90=E7=A0=81+?= =?UTF-8?q?=E6=89=A9=E5=AE=B9=E6=9C=BA=E5=88=B6=E5=88=86=E6=9E=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对 ArrayList 中的 System.arraycopy() 和 Arrays.copyOf() 添加说明 --- .../ArrayList源码+扩容机制分析.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/java/collection/ArrayList源码+扩容机制分析.md b/docs/java/collection/ArrayList源码+扩容机制分析.md index 1a04914f..cd717572 100644 --- a/docs/java/collection/ArrayList源码+扩容机制分析.md +++ b/docs/java/collection/ArrayList源码+扩容机制分析.md @@ -733,6 +733,24 @@ public class ArrayList extends AbstractList #### 3.3.1. `System.arraycopy()` 方法 +源码: + +```java + // 我们发现 arraycopy 是一个 native 方法,接下来我们解释一下各个参数的具体意义 + /** + * 复制数组 + * @param src 源数组 + * @param srcPos 源数组中的起始位置 + * @param dest 目标数组 + * @param destPos 目标数组中的起始位置 + * @param length 要复制的数组元素的数量 + */ + public static native void arraycopy(Object src, int srcPos, + Object dest, int destPos, + int length); +``` + +场景: ```java /** * 在此列表中的指定位置插入指定的元素。 @@ -781,6 +799,21 @@ public class ArraycopyTest { #### 3.3.2. `Arrays.copyOf()`方法 +源码: + +```java + public static int[] copyOf(int[] original, int newLength) { + // 申请一个新的数组 + int[] copy = new int[newLength]; + // 调用System.arraycopy,将源数组中的数据进行拷贝,并返回新的数组 + System.arraycopy(original, 0, copy, 0, + Math.min(original.length, newLength)); + return copy; + } +``` + +场景: + ```java /** 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型。 From 0f33faf3df8ac7f62428ad7e4aa05c1a1450b8dd Mon Sep 17 00:00:00 2001 From: ly <37680485+drlifeL@users.noreply.github.com> Date: Sun, 30 May 2021 15:10:36 +0800 Subject: [PATCH 016/257] =?UTF-8?q?Update=202020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JUC 中的 Atomic 原子类总结链接指向错误, 期望:JUC 中的 Atomic 原子类总结 实际:AQS 原理以及 AQS 同步组件总结 --- .../2020最新Java并发进阶常见面试题总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 3464fc34..1577abc0 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -907,7 +907,7 @@ AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方 CAS 的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址,返回值是 valueOffset。另外 value 是一个 volatile 变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。 -关于 Atomic 原子类这部分更多内容可以查看我的这篇文章:并发编程面试必备:[JUC 中的 Atomic 原子类总结](https://mp.weixin.qq.com/s/joa-yOiTrYF67bElj8xqvg) +关于 Atomic 原子类这部分更多内容可以查看我的这篇文章:并发编程面试必备:[JUC 中的 Atomic 原子类总结](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484834&idx=1&sn=7d3835091af8125c13fc6db765f4c5bd&source=41) ## 6. AQS From 4705093435f8484fbfd6113ff7b90a35e2bd5562 Mon Sep 17 00:00:00 2001 From: ly <37680485+drlifeL@users.noreply.github.com> Date: Sun, 30 May 2021 15:11:51 +0800 Subject: [PATCH 017/257] =?UTF-8?q?Update=202020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 1577abc0..8dccd950 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -907,7 +907,7 @@ AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方 CAS 的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址,返回值是 valueOffset。另外 value 是一个 volatile 变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。 -关于 Atomic 原子类这部分更多内容可以查看我的这篇文章:并发编程面试必备:[JUC 中的 Atomic 原子类总结](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484834&idx=1&sn=7d3835091af8125c13fc6db765f4c5bd&source=41) +关于 Atomic 原子类这部分更多内容可以查看我的这篇文章:并发编程面试必备:[JUC 中的 Atomic 原子类总结](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484834&idx=1&sn=7d3835091af8125c13fc6db765f4c5bd&source=41#wechat_redirect) ## 6. AQS From a9f96e48a7e77cc7dfc8bebbab00b1bad8472c7d Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 31 May 2021 21:20:30 +0800 Subject: [PATCH 018/257] =?UTF-8?q?Update=20=E7=B1=BB=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E8=BF=87=E7=A8=8B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/类加载过程.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/java/jvm/类加载过程.md b/docs/java/jvm/类加载过程.md index f186180a..18cdd0b1 100644 --- a/docs/java/jvm/类加载过程.md +++ b/docs/java/jvm/类加载过程.md @@ -79,15 +79,15 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚 对于初始化阶段,虚拟机严格规范了有且只有 5 种情况下,必须对类进行初始化(只有主动去使用类才会初始化类): 1. 当遇到 `new` 、 `getstatic`、`putstatic` 或 `invokestatic` 这 4 条直接码指令时,比如 `new` 一个类,读取一个静态字段(未被 final 修饰)、或调用一个类的静态方法时。 - - 当 jvm 执行 new 指令时会初始化类。即当程序创建一个类的实例对象。 - - 当 jvm 执行 getstatic 指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。 - - 当 jvm 执行 putstatic 指令时会初始化类。即程序给类的静态变量赋值。 - - 当 jvm 执行 invokestatic 指令时会初始化类。即程序调用类的静态方法。 -2. 使用 `java.lang.reflect` 包的方法对类进行反射调用时如 Class.forname("..."), newInstance()等等。如果类没初始化,需要触发其初始化。 + - 当 jvm 执行 `new` 指令时会初始化类。即当程序创建一个类的实例对象。 + - 当 jvm 执行 `getstatic` 指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。 + - 当 jvm 执行 `putstatic` 指令时会初始化类。即程序给类的静态变量赋值。 + - 当 jvm 执行 `invokestatic` 指令时会初始化类。即程序调用类的静态方法。 +2. 使用 `java.lang.reflect` 包的方法对类进行反射调用时如 `Class.forname("...")`, `newInstance()` 等等。如果类没初始化,需要触发其初始化。 3. 初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。 -4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。 -5. MethodHandle 和 VarHandle 可以看作是轻量级的反射调用机制,而要想使用这 2 个调用, - 就必须先使用 findStaticVarHandle 来初始化要调用的类。 +4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 `main` 方法的那个类),虚拟机会先初始化这个类。 +5. `MethodHandle` 和 `VarHandle` 可以看作是轻量级的反射调用机制,而要想使用这 2 个调用, + 就必须先使用 `findStaticVarHandle` 来初始化要调用的类。 6. **「补充,来自[issue745](https://github.com/Snailclimb/JavaGuide/issues/745)」** 当一个接口中定义了 JDK8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。 ## 卸载 From dcd82146bd590e4dfd0ddc9d46fc2d1834daaa5b Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 1 Jun 2021 16:08:53 +0800 Subject: [PATCH 019/257] Update README.md --- README.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d7d421c0..70a97473 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,10 @@ 👉 书单已经被移动到[awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 -> 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。[图解计算机基础 PDF 版](#优质原创PDF资源)。 -> 3. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。星球内部更新的[《Java面试进阶指北 打造个人的技术竞争力》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7)这个小册的质量很高,专为面试打造。 -> 4. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java 面试进阶指南》](https://xiaozhuanlan.com/javainterview?rel=javaguide) +> 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。 +> 3. **图解计算机基础** :[图解计算机基础 PDF 下载](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 +> 4. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。星球内部更新的[《Java面试进阶指北 打造个人的技术竞争力》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7)这个小册的质量很高,专为面试打造。 +> 5. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java 面试进阶指南》](https://xiaozhuanlan.com/javainterview?rel=javaguide) > 6. **转载须知** :以下所有文章如非文首说明皆为我(Guide哥)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️

http://www.cnblogs.com/chengxiao/p/6842045.html>

+

https://www.cnblogs.com/chengxiao/p/6842045.html>

**JDK1.7 的 ConcurrentHashMap:** ![JDK1.7的ConcurrentHashMap](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/ConcurrentHashMap分段锁.jpg) -

http://www.cnblogs.com/chengxiao/p/6842045.html>

+

https://www.cnblogs.com/chengxiao/p/6842045.html>

**JDK1.8 的 ConcurrentHashMap:** diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index d25667a5..13af4987 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -131,7 +131,7 @@ public class GCTest { 运行结果 (红色字体描述有误,应该是对应于 JDK1.7 的永久代): -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-26/28954286.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-26/28954286.jpg) 从上图我们可以看出 eden 区内存几乎已经被分配完全(即使程序什么也不做,新生代也会使用 2000 多 k 内存)。假如我们再为 allocation2 分配内存会出现什么情况呢? @@ -139,7 +139,7 @@ public class GCTest { allocation2 = new byte[900*1024]; ``` -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-26/28128785.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-26/28128785.jpg) **简单解释一下为什么会出现这种情况:** 因为给 allocation2 分配内存的时候 eden 区内存几乎已经被分配完了,我们刚刚讲了当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC.GC 期间虚拟机又发现 allocation1 无法存入 Survivor 空间,所以只好通过 **分配担保机制** 把新生代的对象提前转移到老年代中去,老年代上的空间足够存放 allocation1,所以不会出现 Full GC。执行 Minor GC 后,后面分配的对象如果能够存在 eden 区的话,还是会在 eden 区分配内存。可以执行如下代码验证: diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 699f434b..214f3814 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -1004,7 +1004,7 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true 推荐两篇 AQS 原理和相关源码分析的文章: -- http://www.cnblogs.com/waterystone/p/4920797.html +- https://www.cnblogs.com/waterystone/p/4920797.html - https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html ### 6.3. AQS 组件总结 @@ -1101,7 +1101,7 @@ CompletableFuture allFutures = CompletableFuture.allOf( - 《深入理解 Java 虚拟机》 - 《实战 Java 高并发程序设计》 - 《Java 并发编程的艺术》 -- http://www.cnblogs.com/waterystone/p/4920797.html +- https://www.cnblogs.com/waterystone/p/4920797.html - https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html - diff --git a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md index 832cbbc9..936809f5 100644 --- a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md +++ b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md @@ -233,7 +233,7 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true 推荐两篇 AQS 原理和相关源码分析的文章: -- http://www.cnblogs.com/waterystone/p/4920797.html +- https://www.cnblogs.com/waterystone/p/4920797.html - https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html ### 3 Semaphore(信号量)-允许多个线程同时访问 diff --git a/docs/java/multi-thread/并发容器总结.md b/docs/java/multi-thread/并发容器总结.md index ed606342..fcc900e6 100644 --- a/docs/java/multi-thread/并发容器总结.md +++ b/docs/java/multi-thread/并发容器总结.md @@ -129,7 +129,7 @@ ConcurrentLinkedQueue 适合在对性能要求相对较高,同时对队列的 BlockingQueue 是一个接口,继承自 Queue,所以其实现类也可以作为 Queue 的实现来使用,而 Queue 又继承自 Collection 接口。下面是 BlockingQueue 的相关实现类: -![BlockingQueue 的实现类](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/51622268.jpg) +![BlockingQueue 的实现类](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/51622268.jpg) **下面主要介绍一下:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,这三个 BlockingQueue 的实现类。** @@ -198,13 +198,13 @@ PriorityBlockingQueue 并发控制采用的是 **ReentrantLock**,队列为无 跳表的本质是同时维护了多个链表,并且链表是分层的, -![2级索引跳表](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/93666217.jpg) +![2级索引跳表](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/93666217.jpg) 最低层的链表维护了跳表内所有的元素,每上面一层链表都是下面一层的子集。 跳表内的所有链表的元素都是排序的。查找时,可以从顶级链表开始找。一旦发现被查找的元素大于当前链表中的取值,就会转入下一层链表继续找。这也就是说在查找过程中,搜索是跳跃式的。如上图所示,在跳表中查找元素 18。 -![在跳表中查找元素18](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/32005738.jpg) +![在跳表中查找元素18](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/32005738.jpg) 查找 18 的时候原来需要遍历 18 次,现在只需要 7 次即可。针对链表长度比较大的时候,构建索引查找效率的提升就会非常明显。 diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index 64d70b3a..bab66c01 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -52,7 +52,7 @@ Java 9 允许为 JDK 和应用配置同样的日志实现。新增了 `System.Lo ### 其它新特性 - **接口私有方法** :Java 9 允许在接口中使用私有方法 -- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 [http://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html](http://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)) +- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 [https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)) - **类 `CompletableFuture` 中增加了几个新的方法(`completeAsync` ,`orTimeout` 等)** - **Nashorn 引擎的增强** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性 - **I/O 流的新特性** :增加了新的方法来读取和复制 InputStream 中包含的数据 diff --git a/docs/operating-system/Shell.md b/docs/operating-system/Shell.md index c88ebdd6..53466d11 100644 --- a/docs/operating-system/Shell.md +++ b/docs/operating-system/Shell.md @@ -45,7 +45,7 @@ 另外,了解 shell 编程也是大部分互联网公司招聘后端开发人员的要求。下图是我截取的一些知名互联网公司对于 Shell 编程的要求。 -![大型互联网公司对于shell编程技能的要求](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-16/60190220.jpg) +![大型互联网公司对于shell编程技能的要求](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-16/60190220.jpg) ### 什么是 Shell? @@ -53,7 +53,7 @@ W3Cschool 上的一篇文章是这样介绍 Shell的,如下图所示。 -![什么是 Shell?](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-26/19456505.jpg) +![什么是 Shell?](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-26/19456505.jpg) ### Shell 编程的 Hello World @@ -80,7 +80,7 @@ shell中 # 符号表示注释。**shell 的第一行比较特殊,一般都会 (4) 运行脚本:`./helloworld.sh` 。(注意,一定要写成 `./helloworld.sh` ,而不是 `helloworld.sh` ,运行其它二进制的程序也一样,直接写 `helloworld.sh` ,linux 系统会去 PATH 里寻找有没有叫 helloworld.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 `helloworld.sh` 是会找不到命令的,要用`./helloworld.sh` 告诉系统说,就在当前目录找。) -![shell 编程Hello World](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-16/55296212.jpg) +![shell 编程Hello World](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-16/55296212.jpg) ## Shell 变量 @@ -118,7 +118,7 @@ hello="hello world" echo $hello echo "helloworld!" ``` -![使用自己定义的变量](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-17/19835037.jpg) +![使用自己定义的变量](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-17/19835037.jpg) **Shell 编程中的变量名的命名的注意事项:** @@ -183,7 +183,7 @@ echo $greeting_2 $greeting_3 输出结果: -![输出结果](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-17/51148933.jpg) +![输出结果](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-17/51148933.jpg) **获取字符串长度:** @@ -234,10 +234,10 @@ echo ${str:0:10} #输出:SnailClimb #!bin/bash #author:amau -var="http://www.runoob.com/linux/linux-shell-variable.html" +var="https://www.runoob.com/linux/linux-shell-variable.html" s1=${var%%t*}#h -s2=${var%t*}#http://www.runoob.com/linux/linux-shell-variable.h +s2=${var%t*}#https://www.runoob.com/linux/linux-shell-variable.h s3=${var%%.*}#http://www s4=${var#*/}#/www.runoob.com/linux/linux-shell-variable.html s5=${var##*/}#linux-shell-variable.html @@ -281,7 +281,7 @@ for i in ${array[@]};do echo $i ;done # 遍历数组,数组元素为空,没 ### 算数运算符 -![算数运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/4937342.jpg) +![算数运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/4937342.jpg) 我以加法运算符做一个简单的示例(注意:不是单引号,是反引号): @@ -298,7 +298,7 @@ echo "Total value : $val" 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。 -![shell关系运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/64391380.jpg) +![shell关系运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/64391380.jpg) 通过一个简单的示例演示关系运算符的使用,下面shell程序的作用是当score=100的时候输出A否则输出B。 @@ -322,7 +322,7 @@ B ### 逻辑运算符 -![逻辑运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/60545848.jpg) +![逻辑运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/60545848.jpg) 示例: @@ -336,13 +336,13 @@ echo $a; ### 布尔运算符 -![布尔运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/93961425.jpg) +![布尔运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/93961425.jpg) 这里就不做演示了,应该挺简单的。 ### 字符串运算符 -![ 字符串运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/309094.jpg) +![ 字符串运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/309094.jpg) 简单示例: @@ -366,7 +366,7 @@ a 不等于 b ### 文件相关运算符 -![文件相关运算符](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/60359774.jpg) +![文件相关运算符](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-22/60359774.jpg) 使用方式很简单,比如我们定义好了一个文件路径`file="/usr/learnshell/test.sh"` 如果我们想判断这个文件是否可读,可以这样`if [ -r $file ]` 如果想判断这个文件是否可写,可以这样`-w $file`,是不是很简单。 diff --git a/docs/system-design/authority-certification/SSO单点登录看这一篇就够了.md b/docs/system-design/authority-certification/SSO单点登录看这一篇就够了.md index a2042c61..7dab034e 100644 --- a/docs/system-design/authority-certification/SSO单点登录看这一篇就够了.md +++ b/docs/system-design/authority-certification/SSO单点登录看这一篇就够了.md @@ -10,12 +10,12 @@ SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。https://baike.baidu.com/item/SSO/3451380 -例如访问在网易账号中心(http://reg.163.com/ )登录之后 +例如访问在网易账号中心(https://reg.163.com/ )登录之后 访问以下站点都是登录状态 -- 网易直播 [http://v.163.com](http://v.163.com/) -- 网易博客 [http://blog.163.com](http://blog.163.com/) -- 网易花田 [http://love.163.com](http://love.163.com/) +- 网易直播 [https://v.163.com](https://v.163.com/) +- 网易博客 [https://blog.163.com](https://blog.163.com/) +- 网易花田 [https://love.163.com](https://love.163.com/) - 网易考拉 [https://www.kaola.com](https://www.kaola.com/) - 网易Lofter [http://www.lofter.com](http://www.lofter.com/) diff --git a/docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md b/docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md index 83a1ed80..fb6beae7 100644 --- a/docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md +++ b/docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md @@ -46,7 +46,7 @@ RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、 下面再来看看图1—— RabbitMQ 的整体模型架构。 -![图1-RabbitMQ 的整体模型架构](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/96388546.jpg) +![图1-RabbitMQ 的整体模型架构](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/96388546.jpg) 下面我会一一介绍上图中的一些概念。 @@ -67,7 +67,7 @@ RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、 Exchange(交换器) 示意图如下: -![Exchange(交换器) 示意图](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/24007899.jpg) +![Exchange(交换器) 示意图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/24007899.jpg) 生产者将消息发给交换器的时候,一般会指定一个 **RoutingKey(路由键)**,用来指定这个消息的路由规则,而这个 **RoutingKey 需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效**。 @@ -75,7 +75,7 @@ RabbitMQ 中通过 **Binding(绑定)** 将 **Exchange(交换器)** 与 **Queue( Binding(绑定) 示意图: -![Binding(绑定) 示意图](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/70553134.jpg) +![Binding(绑定) 示意图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/70553134.jpg) 生产者将消息发送给交换器时,需要一个RoutingKey,当 BindingKey 和 RoutingKey 相匹配时,消息会被路由到对应的队列中。在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的 BindingKey。BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型,比如fanout类型的交换器就会无视,而是将消息路由到所有绑定到该交换器的队列中。 @@ -95,7 +95,7 @@ Binding(绑定) 示意图: 下图展示了生产者将消息存入 RabbitMQ Broker,以及消费者从Broker中消费数据的整个流程。 -![消息队列的运转过程](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/67952922.jpg) +![消息队列的运转过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/67952922.jpg) 这样图1中的一些关于 RabbitMQ 的基本概念我们就介绍完毕了,下面再来介绍一下 **Exchange Types(交换器类型)** 。 @@ -111,7 +111,7 @@ fanout 类型的Exchange路由规则非常简单,它会把所有发送到该Ex direct 类型的Exchange路由规则也很简单,它会把消息路由到那些 Bindingkey 与 RoutingKey 完全匹配的 Queue 中。 -![direct 类型交换器](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/37008021.jpg) +![direct 类型交换器](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/37008021.jpg) 以上图为例,如果发送消息的时候设置路由键为“warning”,那么消息会路由到 Queue1 和 Queue2。如果在发送消息的时候设置路由键为"Info”或者"debug”,消息只会路由到Queue2。如果以其他的路由键发送消息,则消息不会路由到这两个队列中。 @@ -125,7 +125,7 @@ direct 类型常用在处理有优先级的任务,根据任务的优先级把 - BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串; - BindingKey 中可以存在两种特殊字符串“\*”和“#”,用于做模糊匹配,其中“\*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。 -![topic 类型交换器](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/73843.jpg) +![topic 类型交换器](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/73843.jpg) 以上图为例: @@ -156,10 +156,10 @@ headers 类型的交换器不依赖于路由键的匹配规则来路由消息, 在官网下载然后上传到 Linux 上或者直接使用下面的命令下载对应的版本。 ```shell -[root@SnailClimb local]#wget http://erlang.org/download/otp_src_19.3.tar.gz +[root@SnailClimb local]#wget https://erlang.org/download/otp_src_19.3.tar.gz ``` -erlang 官网下载:[http://www.erlang.org/downloads](http://www.erlang.org/downloads) +erlang 官网下载:[https://www.erlang.org/downloads](https://www.erlang.org/downloads) **2 解压 erlang 安装包** @@ -211,7 +211,7 @@ make && make install ```erlang io:format("hello world~n", []). ``` -![输出“hello world”](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/49570541.jpg) +![输出“hello world”](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/49570541.jpg) 大功告成,我们的 erlang 已经安装完成。 @@ -242,7 +242,7 @@ export ERL_HOME PATH [root@SnailClimb etc]# erl ``` -![输入 erl 查看 erlang 环境变量是否配置正确](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/62504246.jpg) +![输入 erl 查看 erlang 环境变量是否配置正确](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/62504246.jpg) ### 2.2 安装 RabbitMQ @@ -319,6 +319,6 @@ Setting permissions for user "root" in vhost "/" ... 再次访问:http://你的ip地址:15672/ ,输入用户名和密码:root root -![RabbitMQ控制台](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/45835332.jpg) +![RabbitMQ控制台](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-12/45835332.jpg) diff --git a/docs/system-design/distributed-system/rpc/Dubbo.md b/docs/system-design/distributed-system/rpc/Dubbo.md index 135ab53e..452c7f1b 100644 --- a/docs/system-design/distributed-system/rpc/Dubbo.md +++ b/docs/system-design/distributed-system/rpc/Dubbo.md @@ -30,7 +30,7 @@ 具体原理图如下,后面我会串起来将整个RPC的过程给大家说一下。 -![RPC原理图](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/37345851.jpg) +![RPC原理图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/37345851.jpg) 1. 服务消费端(client)以本地调用的方式调用远程服务; 1. 客户端 Stub(client stub) 接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体(序列化):`RpcRequest`; @@ -90,7 +90,7 @@ Dubbo 是由阿里开源,后来加入了 Apache 。正式由于 Dubbo 的出 3. **服务访问压力以及时长统计、资源调度和治理** :基于访问压力实时管理集群容量,提高集群利用率。 4. ...... -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-26/43050183.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-26/43050183.jpg) 另外,Dubbo 除了能够应用在分布式系统中,也可以应用在现在比较火的微服务系统中。不过,由于 Spring Cloud 在微服务中应用更加广泛,所以,我觉得一般我们提 Dubbo 的话,大部分是分布式系统的情况。 diff --git a/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md b/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md index 4a139911..73953f0a 100644 --- a/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md +++ b/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md @@ -10,7 +10,7 @@ RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络 http://www.importnew.com/22003.html -![RPC原理图](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/37345851.jpg) +![RPC原理图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/37345851.jpg) 1. 服务消费方(client)调用以本地调用方式调用服务; 2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体; @@ -24,7 +24,7 @@ http://www.importnew.com/22003.html 下面再贴一个网上的时序图: -![RPC原理时序图](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/32527396.jpg) +![RPC原理时序图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/32527396.jpg) ### RPC 解决了什么问题? diff --git a/docs/system-design/framework/spring/Spring.md b/docs/system-design/framework/spring/Spring.md index 18efadcc..82fe4ef7 100644 --- a/docs/system-design/framework/spring/Spring.md +++ b/docs/system-design/framework/spring/Spring.md @@ -17,7 +17,7 @@ ### 视频 -- [网易云课堂——58集精通java教程Spring框架开发](http://study.163.com/course/courseMain.htm?courseId=1004475015#/courseDetail?tab=1&35) +- [网易云课堂——58集精通java教程Spring框架开发](https://study.163.com/course/courseMain.htm?courseId=1004475015#/courseDetail?tab=1&35) - [慕课网相关视频](https://www.imooc.com/) - **黑马视频和尚硅谷视频(非常推荐):** 微信公众号:“**JavaGuide**”后台回复关键字 “**1**” 免费领取。 @@ -44,7 +44,7 @@ AOP思想的实现一般都是基于 **代理模式** ,在JAVA中一般采用J 推荐阅读: -- [静态代理、JDK动态代理、CGLIB动态代理讲解](http://www.cnblogs.com/puyangsky/p/6218925.html) :我们知道AOP思想的实现一般都是基于 **代理模式** ,所以在看下面的文章之前建议先了解一下静态代理以及JDK动态代理、CGLIB动态代理的实现方式。 +- [静态代理、JDK动态代理、CGLIB动态代理讲解](https://www.cnblogs.com/puyangsky/p/6218925.html) :我们知道AOP思想的实现一般都是基于 **代理模式** ,所以在看下面的文章之前建议先了解一下静态代理以及JDK动态代理、CGLIB动态代理的实现方式。 - [Spring AOP 入门](https://juejin.im/post/5aa7818af265da23844040c6) :带你入门的一篇文章。这篇文章主要介绍了AOP中的基本概念:5种类型的通知(Before,After,After-returning,After-throwing,Around);Spring中对AOP的支持:AOP思想的实现一般都是基于代理模式,在Java中一般采用JDK动态代理模式,Spring AOP 同时支持 CGLIB、ASPECTJ、JDK动态代理, - [Spring AOP 基于AspectJ注解如何实现AOP](https://juejin.im/post/5a55af9e518825734d14813f) : **AspectJ是一个AOP框架,它能够对java代码进行AOP编译(一般在编译期进行),让java代码具有AspectJ的AOP功能(当然需要特殊的编译器)**,可以这样说AspectJ是目前实现AOP框架中最成熟,功能最丰富的语言,更幸运的是,AspectJ与java程序完全兼容,几乎是无缝关联,因此对于有java编程基础的工程师,上手和使用都非常容易。Spring注意到AspectJ在AOP的实现方式上依赖于特殊编译器(ajc编译器),因此Spring很机智回避了这点,转向采用动态代理技术的实现原理来构建Spring AOP的内部机制(动态织入),这是与AspectJ(静态织入)最根本的区别。**Spring 只是使用了与 AspectJ 5 一样的注解,但仍然没有使用 AspectJ 的编译器,底层依是动态代理技术的实现,因此并不依赖于 AspectJ 的编译器**。 Spring AOP虽然是使用了那一套注解,其实实现AOP的底层是使用了动态代理(JDK或者CGLib)来动态植入。至于AspectJ的静态植入,不是本文重点,所以只提一提。 - [探秘Spring AOP(慕课网视频,很不错)](https://www.imooc.com/learn/869):慕课网视频,讲解的很不错,详细且深入 @@ -65,7 +65,7 @@ AOP思想的实现一般都是基于 **代理模式** ,在JAVA中一般采用J ### Spring单例与线程安全 -- [Spring框架中的单例模式(源码解读)](http://www.cnblogs.com/chengxuyuanzhilu/p/6404991.html):单例模式是一种常用的软件设计模式。通过单例模式可以保证系统中一个类只有一个实例。spring依赖注入时,使用了 多重判断加锁 的单例模式。 +- [Spring框架中的单例模式(源码解读)](https://www.cnblogs.com/chengxuyuanzhilu/p/6404991.html):单例模式是一种常用的软件设计模式。通过单例模式可以保证系统中一个类只有一个实例。spring依赖注入时,使用了 多重判断加锁 的单例模式。 ### Spring源码阅读 diff --git a/docs/system-design/framework/spring/Spring事务总结.md b/docs/system-design/framework/spring/Spring事务总结.md index db47ee4b..27f49ec7 100644 --- a/docs/system-design/framework/spring/Spring事务总结.md +++ b/docs/system-design/framework/spring/Spring事务总结.md @@ -430,7 +430,7 @@ Class B { - **`TransactionDefinition.PROPAGATION_NOT_SUPPORTED`**: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 - **`TransactionDefinition.PROPAGATION_NEVER`**: 以非事务方式运行,如果当前存在事务,则抛出异常。 -更多关于事务传播行为的内容请看这篇文章:[《太难了~面试官让我结合案例讲讲自己对 Spring 事务传播行为的理解。》](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486668&idx=2&sn=0381e8c836442f46bdc5367170234abb&chksm=cea24307f9d5ca11c96943b3ccfa1fc70dc97dd87d9c540388581f8fe6d805ff548dff5f6b5b&token=1776990505&lang=zh_CN#rd) +更多关于事务传播行为的内容请看这篇文章:[《太难了~面试官让我结合案例讲讲自己对 Spring 事务传播行为的理解。》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486668&idx=2&sn=0381e8c836442f46bdc5367170234abb&chksm=cea24307f9d5ca11c96943b3ccfa1fc70dc97dd87d9c540388581f8fe6d805ff548dff5f6b5b&token=1776990505&lang=zh_CN#rd) #### 3.3.2 事务隔离级别 diff --git a/docs/system-design/framework/spring/Spring常见问题总结.md b/docs/system-design/framework/spring/Spring常见问题总结.md index 870d3b3d..99b0d981 100644 --- a/docs/system-design/framework/spring/Spring常见问题总结.md +++ b/docs/system-design/framework/spring/Spring常见问题总结.md @@ -192,11 +192,11 @@ public OneService getService(status) { 图示: -![Spring Bean 生命周期](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/48376272.jpg) +![Spring Bean 生命周期](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/48376272.jpg) 与之比较类似的中文版本: -![Spring Bean 生命周期](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/5496407.jpg) +![Spring Bean 生命周期](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/5496407.jpg) ## 6. Spring MVC @@ -213,12 +213,12 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M **Spring MVC 的简单原理图如下:** -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/60679444.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/60679444.jpg) ### 6.2 SpringMVC 工作原理了解吗? **原理如下图所示:** -![SpringMVC运行原理](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/49790288.jpg) +![SpringMVC运行原理](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/49790288.jpg) 上图的一个笔误的小问题:Spring MVC 的入口函数也就是前端控制器 `DispatcherServlet` 的作用是接收请求,响应结果。 @@ -340,7 +340,7 @@ String transient4; // not persistent because of @Transient ## 参考 - 《Spring 技术内幕》 -- +- - - - https://www.cnblogs.com/clwydjgs/p/9317849.html diff --git a/docs/system-design/website-architecture/关于大型网站系统架构你不得不懂的10个问题.md b/docs/system-design/website-architecture/关于大型网站系统架构你不得不懂的10个问题.md index f1a1662e..194cc52b 100644 --- a/docs/system-design/website-architecture/关于大型网站系统架构你不得不懂的10个问题.md +++ b/docs/system-design/website-architecture/关于大型网站系统架构你不得不懂的10个问题.md @@ -164,7 +164,7 @@ CAP仅适用于原子读写的NOSQL场景中,并不适合数据库系统。现 **当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能2选1。也就是说当网络分区之后P是前提,决定了P之后才有C和A的选择。也就是说分区容错性(Partition tolerance)我们是必须要实现的。** -我在网上找了很多文章想看一下有没有文章提到这个不是所谓的3选2,用百度半天没找到了一篇,用谷歌搜索找到一篇比较不错的,如果想深入学习一下CAP就看这篇文章把,我这里就不多BB了:**《分布式系统之CAP理论》 :** [http://www.cnblogs.com/hxsyl/p/4381980.html](http://www.cnblogs.com/hxsyl/p/4381980.html) +我在网上找了很多文章想看一下有没有文章提到这个不是所谓的3选2,用百度半天没找到了一篇,用谷歌搜索找到一篇比较不错的,如果想深入学习一下CAP就看这篇文章把,我这里就不多BB了:**《分布式系统之CAP理论》 :** [https://www.cnblogs.com/hxsyl/p/4381980.html](https://www.cnblogs.com/hxsyl/p/4381980.html) #### BASE 理论 diff --git a/docs/tools/Git.md b/docs/tools/Git.md index 78ea2805..d2ac8f2d 100644 --- a/docs/tools/Git.md +++ b/docs/tools/Git.md @@ -268,8 +268,8 @@ git push origin **推荐阅读:** -- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html) -- [图解Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) +- [Git - 简明指南](https://rogerdudler.github.io/git-guide/index.zh.html) +- [图解Git](https://marklodato.github.io/visual-git-guide/index-zh-cn.html) - [猴子都能懂得Git入门](https://backlog.com/git-tutorial/cn/intro/intro1_1.html) - https://git-scm.com/book/en/v2 - [Generating a new SSH key and adding it to the ssh-agent](https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) diff --git a/docs/tools/Github技巧.md b/docs/tools/Github技巧.md index ba7dc824..5a334ae3 100644 --- a/docs/tools/Github技巧.md +++ b/docs/tools/Github技巧.md @@ -6,7 +6,7 @@ ## 1. 一键生成 Github 简历 -通过 [http://resume.github.io/](http://resume.github.io/) 这个网站你可以一键生成一个在线的 Github 简历。 +通过 [https://resume.github.io/](https://resume.github.io/) 这个网站你可以一键生成一个在线的 Github 简历。 当时我参加的校招的时候,个人信息那里就放了一个在线的 Github 简历。我觉得这样会让面试官感觉你是一个内行,会提高一些印象分。 diff --git a/docs/公众号历史文章汇总.md b/docs/公众号历史文章汇总.md index da66dbc9..5e698dba 100644 --- a/docs/公众号历史文章汇总.md +++ b/docs/公众号历史文章汇总.md @@ -186,12 +186,12 @@ ## 杂文闲记 -- [一只准准程序员的唠叨](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484932&idx=1&sn=a4f3057ecd4412cb8b18e92058b29680&chksm=cea249cff9d5c0d97580310f6666a4e0c42cfd1ba13dd759850e489c9386dce8c5c35b0a1a95&token=1082669959&lang=zh_CN#rd)(2018-06-09) +- [一只准准程序员的唠叨](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484932&idx=1&sn=a4f3057ecd4412cb8b18e92058b29680&chksm=cea249cff9d5c0d97580310f6666a4e0c42cfd1ba13dd759850e489c9386dce8c5c35b0a1a95&token=1082669959&lang=zh_CN#rd)(2018-06-09) - [说几件近期的小事](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484900&idx=1&sn=745e8f6027da369ef5f8e349cb5d6657&chksm=cea24a2ff9d5c339c925322ffacdc72dd37bda63238dfb3452540085c1695681e2e79070e2a7&token=1082669959&lang=zh_CN#rd)(2018-08-02) - [选择技术方向都要考虑哪些因素](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484898&idx=1&sn=fd2ebf9ffd37ab5de1de09cd3272ac0a&chksm=cea24a29f9d5c33fa48f5a57de864cd9382a730578fb18d78b7f06b45504aede18b235b9bc9e&token=1082669959&lang=zh_CN#rd)(2018-08-04) - [结束了我短暂的秋招,说点自己的感受](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484842&idx=1&sn=4489dfab0ef2479122b71407855afc71&chksm=cea24a61f9d5c3774a8ed67c5fcc3234cb0741fbe831152986e5d1c8fb4f36a003f4fb2f247e&token=1082669959&lang=zh_CN#rd)(2018-10-22) - [【周日闲谈】最近想说的几件小事](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484818&idx=1&sn=e14b0a08537456eb15ba49cf5e70ff74&chksm=cea24a59f9d5c34fe0a9e0567d867b85a81d1f19b0ea8e6a3c14161e436508de9adfeb2a5e6a&token=1082669959&lang=zh_CN#rd)(2018-11-18) -- [做公众号这一年的经历和一件“大事”](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484746&idx=1&sn=a519a9e3d638bff5c65008f7de167e4b&chksm=cea24a81f9d5c397ca9ac5668ba6cb18b38065e0e282a34ebc077a2dea98de3f1eb285ea5f09&token=1082669959&lang=zh_CN#rd)(2019-03-10) +- [做公众号这一年的经历和一件“大事”](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484746&idx=1&sn=a519a9e3d638bff5c65008f7de167e4b&chksm=cea24a81f9d5c397ca9ac5668ba6cb18b38065e0e282a34ebc077a2dea98de3f1eb285ea5f09&token=1082669959&lang=zh_CN#rd)(2019-03-10) - [几经周折,公众号终于留言功能啦!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485007&idx=1&sn=096a436cd6a9251c23b8effc3cfa5076&chksm=cea24984f9d5c092d1f7740d1c3e0ea347562ba0aa597507ce275c5bdf1c8bd608328ee756ba&token=1082669959&lang=zh_CN#rd)(2019-03-15) - [写在毕业季的大学总结!细数一下大学干过的“傻事”。](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485358&idx=1&sn=3aaf1163fe13351e06c76b70f2bd33bd&chksm=cea24865f9d5c1735b51c707c8f5ade16af7eca304540205ab0fb1284f99034d418b9858d7db&token=1667678311&lang=zh_CN#rd) (2019-06-11) - [入职一个月的职场小白,谈谈自己这段时间的感受](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485540&idx=1&sn=4492eece8f7738e99350118040e14a79&chksm=cea247aff9d5ceb9e7c67f418d8a8518c550fd7dd269bf2c9bdef83309502273b4b9f1e7021f&token=1333232257&lang=zh_CN&scene=21#wechat_redirect) From 4545a7f595446cbaf265588e6d0aa6a8094b8f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E4=B9=9D=E9=BC=8E?= <109224573@qq.com> Date: Wed, 2 Jun 2021 21:50:28 +0800 Subject: [PATCH 023/257] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index 4911d88f..ee3f483a 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -274,7 +274,7 @@ System.out.println(list); ```java //此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 //在实例化泛型类时,必须指定T的具体类型 -public class Generic{ +public class Generic { private T key; @@ -282,7 +282,7 @@ public class Generic{ this.key = key; } - public T getKey(){ + public T getKey() { return key; } } @@ -327,13 +327,12 @@ class GeneratorImpl implements Generator{ **3.泛型方法** : ```java - public static < E > void printArray( E[] inputArray ) - { - for ( E element : inputArray ){ - System.out.printf( "%s ", element ); - } - System.out.println(); +public static void printArray(E[] inputArray) { + for (E element : inputArray) { + System.out.printf("%s ", element); } + System.out.println(); +} ``` 使用: @@ -342,8 +341,8 @@ class GeneratorImpl implements Generator{ // 创建不同类型数组: Integer, Double 和 Character Integer[] intArray = { 1, 2, 3 }; String[] stringArray = { "Hello", "World" }; -printArray( intArray ); -printArray( stringArray ); +printArray(intArray); +printArray(stringArray); ``` **常用的通配符为: T,E,K,V,?** @@ -457,7 +456,7 @@ public native int hashCode(); 在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 -因为 `hashCode()` 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 `hashCode`。 +因为 `hashCode()` 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 `hashCode`。 我们刚刚也提到了 `HashSet`,如果 `HashSet` 在对比的时候,同样的 hashcode 有多个对象,它会使用 `equals()` 来判断是否真的相同。也就是说 `hashcode` 只是用来缩小查找成本。 @@ -750,7 +749,7 @@ public void f5(int a) { 首先,我们回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。 -**按值调用(call by value)** 表示方法接收的是调用者提供的值,**按引用调用(call by reference)** 表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。它用来描述各种程序设计语言(不只是 Java)中方法参数传递方式。 +**按值调用(call by value)** 表示方法接收的是调用者提供的值,**按引用调用(call by reference)** 表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。它用来描述各种程序设计语言(不只是 Java)中方法参数传递方式。 **Java 程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。** @@ -1324,7 +1323,7 @@ try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new F } ``` -## I\O 流 +## I/O 流 ### 什么是序列化?什么是反序列化? @@ -1349,7 +1348,7 @@ try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new F ### Java 序列化中如果有些字段不想进行序列化,怎么办? -`对于不想进行序列化的变量,使用`transient`关键字修饰。` +对于不想进行序列化的变量,使用`transient`关键字修饰。` `transient` 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 `transient` 修饰的变量值不会被持久化和恢复。`transient` 只能修饰变量,不能修饰类和方法。 @@ -1399,4 +1398,4 @@ Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上 - https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre - https://www.educba.com/oracle-vs-openjdk/ -- https://stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdk?answertab=active#tab-top## 基础概念与常识 +- https://stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdk 基础概念与常识 From 53e24b4fe84e1574b95494992e7c212a329b5e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E4=B9=9D=E9=BC=8E?= <109224573@qq.com> Date: Wed, 2 Jun 2021 22:12:52 +0800 Subject: [PATCH 024/257] =?UTF-8?q?=E6=B3=9B=E5=9E=8B=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index ee3f483a..d99d6b70 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -316,7 +316,7 @@ class GeneratorImpl implements Generator{ 实现泛型接口,指定类型: ```java -class GeneratorImpl implements Generator{ +class GeneratorImpl implements Generator{ @Override public String method() { return "hello"; From e646892384428fb53476886e03d5f81e586fb47c Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 10:38:09 +0800 Subject: [PATCH 025/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java并发进阶常见面试题总结.md | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 699f434b..190c47d4 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -478,7 +478,8 @@ ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { ### 4.2. 实现 Runnable 接口和 Callable 接口的区别 -`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口**不会返回结果或抛出检查异常,但是**`Callable` 接口**可以。所以,如果任务不需要返回结果或抛出异常推荐使用 **`Runnable` 接口**,这样代码看起来会更加简洁。 +`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 +中引入,目的就是为了来处理`Runnable`不支持的用例。`Runnable`**接口不会返回结果或抛出检查异常,但是**`Callable`**接口可以。所以,如果任务不需要返回结果或抛出异常推荐使用**`Runnable`**接口**,这样代码看起来会更加简洁。 工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 @@ -550,8 +551,11 @@ public interface Callable { > - **CachedThreadPool 和 ScheduledThreadPool** : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致 OOM。 **方式一:通过构造方法实现** + ![ThreadPoolExecutor构造方法](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/ThreadPoolExecutor构造方法.png) + **方式二:通过 Executor 框架的工具类 Executors 来实现** + 我们可以创建三种类型的 ThreadPoolExecutor: - **FixedThreadPool** : 该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。 @@ -559,6 +563,7 @@ public interface Callable { - **CachedThreadPool:** 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。 对应 Executors 工具类中的方法如图所示: + ![Executor框架的工具类](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/Executor框架的工具类.png) ### 4.5 ThreadPoolExecutor 类分析 @@ -566,30 +571,30 @@ public interface Callable { `ThreadPoolExecutor` 类中提供的四个构造方法。我们来看最长的那个,其余三个都是在这个构造方法的基础上产生(其他几个构造方法说白点都是给定某些默认参数的构造方法比如默认制定拒绝策略是什么),这里就不贴代码讲了,比较简单。 ```java - /** - * 用给定的初始参数创建一个新的ThreadPoolExecutor。 - */ - public ThreadPoolExecutor(int corePoolSize, - int maximumPoolSize, - long keepAliveTime, - TimeUnit unit, - BlockingQueue workQueue, - ThreadFactory threadFactory, - RejectedExecutionHandler handler) { - if (corePoolSize < 0 || - maximumPoolSize <= 0 || - maximumPoolSize < corePoolSize || - keepAliveTime < 0) +/** + * 用给定的初始参数创建一个新的ThreadPoolExecutor。 + */ +public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue workQueue, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) { + if (corePoolSize < 0 || + maximumPoolSize <= 0 || + maximumPoolSize < corePoolSize || + keepAliveTime < 0) throw new IllegalArgumentException(); - if (workQueue == null || threadFactory == null || handler == null) - throw new NullPointerException(); - this.corePoolSize = corePoolSize; - this.maximumPoolSize = maximumPoolSize; - this.workQueue = workQueue; - this.keepAliveTime = unit.toNanos(keepAliveTime); - this.threadFactory = threadFactory; - this.handler = handler; - } + if (workQueue == null || threadFactory == null || handler == null) + throw new NullPointerException(); + this.corePoolSize = corePoolSize; + this.maximumPoolSize = maximumPoolSize; + this.workQueue = workQueue; + this.keepAliveTime = unit.toNanos(keepAliveTime); + this.threadFactory = threadFactory; + this.handler = handler; +} ``` **下面这些对创建 非常重要,在后面使用线程池的过程中你一定会用到!所以,务必拿着小本本记清楚。** @@ -615,8 +620,8 @@ public interface Callable { 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任时,`ThreadPoolTaskExecutor` 定义一些策略: -- **`ThreadPoolExecutor.AbortPolicy`**:抛出 `RejectedExecutionException`来拒绝新任务的处理。 -- **`ThreadPoolExecutor.CallerRunsPolicy`**:调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 +- **`ThreadPoolExecutor.AbortPolicy`:**抛出 `RejectedExecutionException`来拒绝新任务的处理。 +- **`ThreadPoolExecutor.CallerRunsPolicy`:**调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 - **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。 - **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。 From 8d9d3942705dfe175e14248628ccfdc7889d4cd4 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 18:48:29 +0800 Subject: [PATCH 026/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java并发进阶常见面试题总结.md | 282 +++++++++--------- 1 file changed, 139 insertions(+), 143 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 190c47d4..4008126d 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -379,13 +379,12 @@ Thread Name= 9 formatter = yy-M-d ah:mm 上面有一段代码用到了创建 `ThreadLocal` 变量的那段代码用到了 Java8 的知识,它等于下面这段代码,如果你写了下面这段代码的话,IDEA 会提示你转换为 Java8 的格式(IDEA 真的不错!)。因为 ThreadLocal 类在 Java 8 中扩展,使用一个新的方法`withInitial()`,将 Supplier 功能接口作为参数。 ```java - private static final ThreadLocal formatter = new ThreadLocal(){ - @Override - protected SimpleDateFormat initialValue() - { - return new SimpleDateFormat("yyyyMMdd HHmm"); - } - }; +private static final ThreadLocal formatter = new ThreadLocal(){ + @Override + protected SimpleDateFormat initialValue(){ + return new SimpleDateFormat("yyyyMMdd HHmm"); + } +}; ``` ### 3.3. ThreadLocal 原理 @@ -394,13 +393,13 @@ Thread Name= 9 formatter = yy-M-d ah:mm ```java public class Thread implements Runnable { - ...... -//与此线程有关的ThreadLocal值。由ThreadLocal类维护 -ThreadLocal.ThreadLocalMap threadLocals = null; + //...... + //与此线程有关的ThreadLocal值。由ThreadLocal类维护 + ThreadLocal.ThreadLocalMap threadLocals = null; -//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护 -ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; - ...... + //与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护 + ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; + //...... } ``` @@ -409,17 +408,17 @@ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; `ThreadLocal`类的`set()`方法 ```java - public void set(T value) { - Thread t = Thread.currentThread(); - ThreadLocalMap map = getMap(t); - if (map != null) - map.set(this, value); - else - createMap(t, value); - } - ThreadLocalMap getMap(Thread t) { - return t.threadLocals; - } +public void set(T value) { + Thread t = Thread.currentThread(); + ThreadLocalMap map = getMap(t); + if (map != null) + map.set(this, value); + else + createMap(t, value); +} +ThreadLocalMap getMap(Thread t) { + return t.threadLocals; +} ``` 通过上面这些内容,我们足以通过猜测得出结论:**最终的变量是放在了当前线程的 `ThreadLocalMap` 中,并不是存在 `ThreadLocal` 上,`ThreadLocal` 可以理解为只是`ThreadLocalMap`的封装,传递了变量值。** `ThrealLocal` 类中可以通过`Thread.currentThread()`获取到当前线程对象后,直接通过`getMap(Thread t)`可以访问到该线程的`ThreadLocalMap`对象。 @@ -428,7 +427,7 @@ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; ```java ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { - ...... + //...... } ``` @@ -445,15 +444,15 @@ ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { `ThreadLocalMap` 中使用的 key 为 `ThreadLocal` 的弱引用,而 value 是强引用。所以,如果 `ThreadLocal` 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。这样一来,`ThreadLocalMap` 中就会出现 key 为 null 的 Entry。假如我们不做任何措施的话,value 永远无法被 GC 回收,这个时候就可能会产生内存泄露。ThreadLocalMap 实现中已经考虑了这种情况,在调用 `set()`、`get()`、`remove()` 方法的时候,会清理掉 key 为 null 的记录。使用完 `ThreadLocal`方法后 最好手动调用`remove()`方法 ```java - static class Entry extends WeakReference> { - /** The value associated with this ThreadLocal. */ - Object value; +static class Entry extends WeakReference> { + /** The value associated with this ThreadLocal. */ + Object value; - Entry(ThreadLocal k, Object v) { - super(k); - value = v; - } - } + Entry(ThreadLocal k, Object v) { + super(k); + value = v; + } +} ``` **弱引用介绍:** @@ -478,8 +477,7 @@ ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { ### 4.2. 实现 Runnable 接口和 Callable 接口的区别 -`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 -中引入,目的就是为了来处理`Runnable`不支持的用例。`Runnable`**接口不会返回结果或抛出检查异常,但是**`Callable`**接口可以。所以,如果任务不需要返回结果或抛出异常推荐使用**`Runnable`**接口**,这样代码看起来会更加简洁。 +`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。** `Runnable`接口 **不会返回结果或抛出检查异常,但是** `Callable`接口 **可以。所以,如果任务不需要返回结果或抛出异常推荐使用** `Runnable`接口 **,这样代码看起来会更加简洁。 工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 @@ -514,31 +512,31 @@ public interface Callable { 1. **`execute()`方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;** 2. **`submit()`方法用于提交需要返回值的任务。线程池会返回一个 `Future` 类型的对象,通过这个 `Future` 对象可以判断任务是否执行成功**,并且可以通过 `Future` 的 `get()`方法来获取返回值,`get()`方法会阻塞当前线程直到任务完成,而使用 `get(long timeout,TimeUnit unit)`方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。 -我们以**`AbstractExecutorService`**接口中的一个 `submit` 方法为例子来看看源代码: +我们以** `AbstractExecutorService` **接口中的一个 `submit` 方法为例子来看看源代码: ```java - public Future submit(Runnable task) { - if (task == null) throw new NullPointerException(); - RunnableFuture ftask = newTaskFor(task, null); - execute(ftask); - return ftask; - } +public Future submit(Runnable task) { + if (task == null) throw new NullPointerException(); + RunnableFuture ftask = newTaskFor(task, null); + execute(ftask); + return ftask; +} ``` 上面方法调用的 `newTaskFor` 方法返回了一个 `FutureTask` 对象。 ```java - protected RunnableFuture newTaskFor(Runnable runnable, T value) { - return new FutureTask(runnable, value); - } +protected RunnableFuture newTaskFor(Runnable runnable, T value) { + return new FutureTask(runnable, value); +} ``` 我们再来看看`execute()`方法: ```java - public void execute(Runnable command) { - ... - } +public void execute(Runnable command) { + ... +} ``` ### 4.4. 如何创建线程池 @@ -713,7 +711,6 @@ public class ThreadPoolExecutorDemo { System.out.println("Finished all threads"); } } - ``` 可以看到我们上面的代码指定了: @@ -760,46 +757,46 @@ pool-1-thread-1 End. Time = Tue Nov 12 20:59:54 CST 2019 **为了搞懂线程池的原理,我们需要首先分析一下 `execute`方法。**在 4.6 节中的 Demo 中我们使用 `executor.execute(worker)`来提交一个任务到线程池中去,这个方法非常重要,下面我们来看看它的源码: ```java - // 存放线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount) - private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); +// 存放线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount) +private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); - private static int workerCountOf(int c) { - return c & CAPACITY; +private static int workerCountOf(int c) { + return c & CAPACITY; +} + +private final BlockingQueue workQueue; + +public void execute(Runnable command) { + // 如果任务为null,则抛出异常。 + if (command == null) + throw new NullPointerException(); + // ctl 中保存的线程池当前的一些状态信息 + int c = ctl.get(); + + // 下面会涉及到 3 步 操作 + // 1.首先判断当前线程池中执行的任务数量是否小于 corePoolSize + // 如果小于的话,通过addWorker(command, true)新建一个线程,并将任务(command)添加到该线程中;然后,启动该线程从而执行任务。 + if (workerCountOf(c) < corePoolSize) { + if (addWorker(command, true)) + return; + c = ctl.get(); } - - private final BlockingQueue workQueue; - - public void execute(Runnable command) { - // 如果任务为null,则抛出异常。 - if (command == null) - throw new NullPointerException(); - // ctl 中保存的线程池当前的一些状态信息 - int c = ctl.get(); - - // 下面会涉及到 3 步 操作 - // 1.首先判断当前线程池中执行的任务数量是否小于 corePoolSize - // 如果小于的话,通过addWorker(command, true)新建一个线程,并将任务(command)添加到该线程中;然后,启动该线程从而执行任务。 - if (workerCountOf(c) < corePoolSize) { - if (addWorker(command, true)) - return; - c = ctl.get(); - } - // 2.如果当前执行的任务数量大于等于 corePoolSize 的时候就会走到这里 - // 通过 isRunning 方法判断线程池状态,线程池处于 RUNNING 状态才会被并且队列可以加入任务,该任务才会被加入进去 - if (isRunning(c) && workQueue.offer(command)) { - int recheck = ctl.get(); - // 再次获取线程池状态,如果线程池状态不是 RUNNING 状态就需要从任务队列中移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。 - if (!isRunning(recheck) && remove(command)) - reject(command); - // 如果当前线程池为空就新创建一个线程并执行。 - else if (workerCountOf(recheck) == 0) - addWorker(null, false); - } - //3. 通过addWorker(command, false)新建一个线程,并将任务(command)添加到该线程中;然后,启动该线程从而执行任务。 - //如果addWorker(command, false)执行失败,则通过reject()执行相应的拒绝策略的内容。 - else if (!addWorker(command, false)) + // 2.如果当前执行的任务数量大于等于 corePoolSize 的时候就会走到这里 + // 通过 isRunning 方法判断线程池状态,线程池处于 RUNNING 状态才会被并且队列可以加入任务,该任务才会被加入进去 + if (isRunning(c) && workQueue.offer(command)) { + int recheck = ctl.get(); + // 再次获取线程池状态,如果线程池状态不是 RUNNING 状态就需要从任务队列中移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。 + if (!isRunning(recheck) && remove(command)) reject(command); + // 如果当前线程池为空就新创建一个线程并执行。 + else if (workerCountOf(recheck) == 0) + addWorker(null, false); } + //3. 通过addWorker(command, false)新建一个线程,并将任务(command)添加到该线程中;然后,启动该线程从而执行任务。 + //如果addWorker(command, false)执行失败,则通过reject()执行相应的拒绝策略的内容。 + else if (!addWorker(command, false)) + reject(command); +} ``` 通过下图可以更好的对上面这 3 步做一个展示,下图是我为了省事直接从网上找到,原地址不明。 @@ -874,15 +871,15 @@ public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet ```java class AtomicIntegerTest { - private AtomicInteger count = new AtomicInteger(); - //使用AtomicInteger之后,不需要对该方法加锁,也可以实现线程安全。 - public void increment() { - count.incrementAndGet(); - } + private AtomicInteger count = new AtomicInteger(); + //使用AtomicInteger之后,不需要对该方法加锁,也可以实现线程安全。 + public void increment() { + count.incrementAndGet(); + } - public int getCount() { - return count.get(); - } + public int getCount() { + return count.get(); + } } ``` @@ -894,18 +891,18 @@ AtomicInteger 线程安全原理简单分析 AtomicInteger 类的部分源码: ```java - // setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用) - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; +// setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用) +private static final Unsafe unsafe = Unsafe.getUnsafe(); +private static final long valueOffset; - static { - try { - valueOffset = unsafe.objectFieldOffset - (AtomicInteger.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } - } +static { + try { + valueOffset = unsafe.objectFieldOffset + (AtomicInteger.class.getDeclaredField("value")); + } catch (Exception ex) { throw new Error(ex); } +} - private volatile int value; +private volatile int value; ``` AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。 @@ -954,15 +951,15 @@ private volatile int state;//共享变量,使用volatile修饰保证线程可 //返回同步状态的当前值 protected final int getState() { - return state; + return state; } // 设置同步状态的值 protected final void setState(int newState) { - state = newState; + state = newState; } //原子地(CAS操作)将同步状态值设置为给定值update如果当前同步状态的值等于expect(期望值) protected final boolean compareAndSetState(int expect, int update) { - return unsafe.compareAndSwapInt(this, stateOffset, expect, update); + return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } ``` @@ -1030,33 +1027,32 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true ```java public class CountDownLatchExample1 { - // 处理文件的数量 - private static final int threadCount = 6; + // 处理文件的数量 + private static final int threadCount = 6; - public static void main(String[] args) throws InterruptedException { - // 创建一个具有固定线程数量的线程池对象(推荐使用构造方法创建) - ExecutorService threadPool = Executors.newFixedThreadPool(10); - final CountDownLatch countDownLatch = new CountDownLatch(threadCount); - for (int i = 0; i < threadCount; i++) { - final int threadnum = i; - threadPool.execute(() -> { - try { - //处理文件的业务操作 - ...... - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - //表示一个文件已经被完成 - countDownLatch.countDown(); + public static void main(String[] args) throws InterruptedException { + // 创建一个具有固定线程数量的线程池对象(推荐使用构造方法创建) + ExecutorService threadPool = Executors.newFixedThreadPool(10); + final CountDownLatch countDownLatch = new CountDownLatch(threadCount); + for (int i = 0; i < threadCount; i++) { + final int threadnum = i; + threadPool.execute(() -> { + try { + //处理文件的业务操作 + //...... + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + //表示一个文件已经被完成 + countDownLatch.countDown(); + } + + }); } - - }); + countDownLatch.await(); + threadPool.shutdown(); + System.out.println("finish"); } - countDownLatch.await(); - threadPool.shutdown(); - System.out.println("finish"); - } - } ``` @@ -1066,22 +1062,22 @@ public class CountDownLatchExample1 { ```java CompletableFuture task1 = - CompletableFuture.supplyAsync(()->{ - //自定义业务操作 - }); + CompletableFuture.supplyAsync(()->{ + //自定义业务操作 + }); ...... CompletableFuture task6 = - CompletableFuture.supplyAsync(()->{ + CompletableFuture.supplyAsync(()->{ //自定义业务操作 - }); + }); ...... - CompletableFuture headerFuture=CompletableFuture.allOf(task1,.....,task6); +CompletableFuture headerFuture=CompletableFuture.allOf(task1,.....,task6); - try { +try { headerFuture.join(); - } catch (Exception ex) { - ...... - } +} catch (Exception ex) { + //...... +} System.out.println("all done. "); ``` @@ -1092,11 +1088,11 @@ System.out.println("all done. "); List filePaths = Arrays.asList(...) // 异步处理所有文件 List> fileFutures = filePaths.stream() - .map(filePath -> doSomeThing(filePath)) - .collect(Collectors.toList()); + .map(filePath -> doSomeThing(filePath)) + .collect(Collectors.toList()); // 将他们合并起来 CompletableFuture allFutures = CompletableFuture.allOf( - fileFutures.toArray(new CompletableFuture[fileFutures.size()]) + fileFutures.toArray(new CompletableFuture[fileFutures.size()]) ); ``` From 98bc2661895f5a5ef46618d87fd2b5738e137ee9 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 18:53:02 +0800 Subject: [PATCH 027/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 4008126d..f92eb246 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -477,7 +477,7 @@ static class Entry extends WeakReference> { ### 4.2. 实现 Runnable 接口和 Callable 接口的区别 -`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。** `Runnable`接口 **不会返回结果或抛出检查异常,但是** `Callable`接口 **可以。所以,如果任务不需要返回结果或抛出异常推荐使用** `Runnable`接口 **,这样代码看起来会更加简洁。 +`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口**不会返回结果或抛出检查异常,但是**`Callable` 接口**可以。所以,如果任务不需要返回结果或抛出异常推荐使用**`Runnable` 接口**,这样代码看起来会更加简洁。 工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 From 0607a18a1f3dc031652b378bc734fe1e5058a29a Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 18:54:21 +0800 Subject: [PATCH 028/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index f92eb246..6700fc3e 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -477,7 +477,7 @@ static class Entry extends WeakReference> { ### 4.2. 实现 Runnable 接口和 Callable 接口的区别 -`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口**不会返回结果或抛出检查异常,但是**`Callable` 接口**可以。所以,如果任务不需要返回结果或抛出异常推荐使用**`Runnable` 接口**,这样代码看起来会更加简洁。 +`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口** 不会返回结果或抛出检查异常,但是 **`Callable` 接口** 可以。所以,如果任务不需要返回结果或抛出异常推荐使用 **`Runnable` 接口** ,这样代码看起来会更加简洁。 工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 From 19b31d4e598d277d2afffac6f9a3b15742f560f9 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 19:01:13 +0800 Subject: [PATCH 029/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java并发进阶常见面试题总结.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 6700fc3e..5e0a40f7 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -12,7 +12,7 @@ - [1.3. 构造方法可以使用 synchronized 关键字修饰么?](#13-构造方法可以使用-synchronized-关键字修饰么) - [1.3. 讲一下 synchronized 关键字的底层原理](#13-讲一下-synchronized-关键字的底层原理) - [1.3.1. synchronized 同步语句块的情况](#131-synchronized-同步语句块的情况) - - [1.3.2. `synchronized` 修饰方法的的情况](#132-synchronized-修饰方法的的情况) + - [1.3.2. synchronized 修饰方法的的情况](#132-synchronized-修饰方法的的情况) - [1.3.3.总结](#133总结) - [1.4. 说说 JDK1.6 之后的 synchronized 关键字底层做了哪些优化,可以详细介绍一下这些优化吗](#14-说说-jdk16-之后的-synchronized-关键字底层做了哪些优化可以详细介绍一下这些优化吗) - [1.5. 谈谈 synchronized 和 ReentrantLock 的区别](#15-谈谈-synchronized-和-reentrantlock-的区别) @@ -167,11 +167,11 @@ public class Singleton { ```java public class SynchronizedDemo { - public void method() { - synchronized (this) { - System.out.println("synchronized 代码块"); - } - } + public void method() { + synchronized (this) { + System.out.println("synchronized 代码块"); + } + } } ``` @@ -194,13 +194,13 @@ public class SynchronizedDemo { 在执行 `monitorexit` 指令后,将锁计数器设为 0,表明锁被释放。如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止。 -#### 1.3.2. `synchronized` 修饰方法的的情况 +#### 1.3.2. synchronized 修饰方法的的情况 ```java public class SynchronizedDemo2 { - public synchronized void method() { - System.out.println("synchronized 方法"); - } + public synchronized void method() { + System.out.println("synchronized 方法"); + } } ``` @@ -277,7 +277,7 @@ JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、 ![JMM(Java内存模型)](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2020-8/0ac7e663-7db8-4b95-8d8e-7d2b179f67e8.png) -要解决这个问题,就需要把变量声明为**`volatile`**,这就指示 JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。 +要解决这个问题,就需要把变量声明为 **`volatile`** ,这就指示 JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。 所以,**`volatile` 关键字 除了防止 JVM 的指令重排 ,还有一个重要的作用就是保证变量的可见性。** @@ -293,7 +293,7 @@ JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、 `synchronized` 关键字和 `volatile` 关键字是两个互补的存在,而不是对立的存在! -- **`volatile` 关键字**是线程同步的**轻量级实现**,所以**`volatile `性能肯定比` synchronized `关键字要好**。但是**`volatile` 关键字只能用于变量而 `synchronized` 关键字可以修饰方法以及代码块**。 +- **`volatile` 关键字**是线程同步的**轻量级实现**,所以 **`volatile `性能肯定比` synchronized `关键字要好** 。但是 **`volatile` 关键字只能用于变量而 `synchronized` 关键字可以修饰方法以及代码块 **。 - **`volatile` 关键字能保证数据的可见性,但不能保证数据的原子性。`synchronized` 关键字两者都能保证。** - **`volatile`关键字主要用于解决变量在多个线程之间的可见性,而 `synchronized` 关键字解决的是多个线程之间访问资源的同步性。** From b98b5c6c22bffd4af97ca3bd89d052f97c79a773 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 19:05:32 +0800 Subject: [PATCH 030/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 5e0a40f7..c8b693c9 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -293,7 +293,7 @@ JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、 `synchronized` 关键字和 `volatile` 关键字是两个互补的存在,而不是对立的存在! -- **`volatile` 关键字**是线程同步的**轻量级实现**,所以 **`volatile `性能肯定比` synchronized `关键字要好** 。但是 **`volatile` 关键字只能用于变量而 `synchronized` 关键字可以修饰方法以及代码块 **。 +- **`volatile` 关键字**是线程同步的**轻量级实现**,所以 **`volatile `性能肯定比` synchronized `关键字要好** 。但是 **`volatile` 关键字只能用于变量而 `synchronized` 关键字可以修饰方法以及代码块** 。 - **`volatile` 关键字能保证数据的可见性,但不能保证数据的原子性。`synchronized` 关键字两者都能保证。** - **`volatile`关键字主要用于解决变量在多个线程之间的可见性,而 `synchronized` 关键字解决的是多个线程之间访问资源的同步性。** @@ -618,8 +618,9 @@ public ThreadPoolExecutor(int corePoolSize, 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任时,`ThreadPoolTaskExecutor` 定义一些策略: -- **`ThreadPoolExecutor.AbortPolicy`:**抛出 `RejectedExecutionException`来拒绝新任务的处理。 -- **`ThreadPoolExecutor.CallerRunsPolicy`:**调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 +- **`ThreadPoolExecutor.AbortPolicy`:** 抛出 `RejectedExecutionException`来拒绝新任务的处理。 +- **`ThreadPoolExecutor.CallerRunsPolicy`:** +调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 - **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。 - **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。 @@ -953,7 +954,7 @@ private volatile int state;//共享变量,使用volatile修饰保证线程可 protected final int getState() { return state; } - // 设置同步状态的值 +//设置同步状态的值 protected final void setState(int newState) { state = newState; } From c32c0527ecc0f507c83752bf7e5e9e4b664fb6c9 Mon Sep 17 00:00:00 2001 From: 2293736867 <2293736867@qq.com> Date: Thu, 3 Jun 2021 19:07:37 +0800 Subject: [PATCH 031/257] =?UTF-8?q?multi-thread/2020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93=20=E6=8E=92=E7=89=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index c8b693c9..857f8173 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -86,7 +86,7 @@ ```java synchronized void method() { - //业务代码 + //业务代码 } ``` @@ -94,7 +94,7 @@ synchronized void method() { ```java synchronized static void method() { -//业务代码 + //业务代码 } ``` @@ -102,7 +102,7 @@ synchronized static void method() { ```java synchronized(this) { - //业务代码 + //业务代码 } ``` @@ -755,7 +755,7 @@ pool-1-thread-1 End. Time = Tue Nov 12 20:59:54 CST 2019 现在,我们就分析上面的输出内容来简单分析一下线程池原理。 -**为了搞懂线程池的原理,我们需要首先分析一下 `execute`方法。**在 4.6 节中的 Demo 中我们使用 `executor.execute(worker)`来提交一个任务到线程池中去,这个方法非常重要,下面我们来看看它的源码: + **为了搞懂线程池的原理,我们需要首先分析一下 `execute`方法。** 在 4.6 节中的 Demo 中我们使用 `executor.execute(worker)`来提交一个任务到线程池中去,这个方法非常重要,下面我们来看看它的源码: ```java // 存放线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount) From 851c44e978c1acf9bf18c4e1b6ec17c00d656289 Mon Sep 17 00:00:00 2001 From: guide Date: Thu, 3 Jun 2021 20:29:09 +0800 Subject: [PATCH 032/257] =?UTF-8?q?[feat]jdk=20=E7=89=88=E6=9C=AC=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java版本发布.png | Bin 57942 -> 0 bytes ...带你看遍JDK9到14的重要新特性.md | 8 ++++---- docs/贡献指南.md | 0 3 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 docs/java/new-features/images/一文带你看遍JDK9~14 的重要新特性/java版本发布.png create mode 100644 docs/贡献指南.md diff --git a/docs/java/new-features/images/一文带你看遍JDK9~14 的重要新特性/java版本发布.png b/docs/java/new-features/images/一文带你看遍JDK9~14 的重要新特性/java版本发布.png deleted file mode 100644 index 7529c73fb982a063d3da2ff1e36ca71eff0b5ca9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57942 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�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 ra4>(qtRrz9BBme&ba=qd@ diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index bab66c01..2d56e512 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -109,7 +109,7 @@ Java 10 在现有的 CDS 功能基础上再次拓展,以允许应用类放置 Java11 于 2018 年 9 月 25 日正式发布,这是很重要的一个版本!Java 11 和 2017 年 9 月份发布的 Java 9 以及 2018 年 3 月份发布的 Java 10 相比,其最大的区别就是:在长期支持(Long-Term-Support)方面,**Oracle 表示会对 Java 11 提供大力支持,这一支持将会持续至 2026 年 9 月。这是据 Java 8 以后支持的首个长期版本。** -![](images/一文带你看遍JDK9~14 的重要新特性/java版本发布.png) +![](https://img-blog.csdnimg.cn/20210603202746605.png) ### 字符串加强 @@ -280,7 +280,7 @@ client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) ``` ```java - + String json = """ { "name":"mkyong", @@ -323,12 +323,12 @@ client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) final class Rectangle implements Shape { final double length; final double width; - + public Rectangle(double length, double width) { this.length = length; this.width = width; } - + double length() { return length; } double width() { return width; } } diff --git a/docs/贡献指南.md b/docs/贡献指南.md new file mode 100644 index 00000000..e69de29b From b51b8269f57f60b4a1cb86c1abc0b4dec48c8a8f Mon Sep 17 00:00:00 2001 From: VinterHe <37563054+VinterHe@users.noreply.github.com> Date: Fri, 4 Jun 2021 17:17:03 +0800 Subject: [PATCH 033/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E4=B8=AD=E8=A3=85=E7=AE=B1=E5=86=99=E6=88=90=E6=8B=86=E7=AE=B1?= =?UTF-8?q?=E7=9A=84=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识疑难点.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/Java基础知识疑难点.md b/docs/java/basis/Java基础知识疑难点.md index b11de0c5..09fb3269 100644 --- a/docs/java/basis/Java基础知识疑难点.md +++ b/docs/java/basis/Java基础知识疑难点.md @@ -77,7 +77,7 @@ Integer i2 = new Integer(40); System.out.println(i1==i2);//false ``` -`Integer i1=40` 这一行代码会发生拆箱,也就是说这行代码等价于 `Integer i1=Integer.valueOf(40)` 。因此,`i1` 直接使用的是常量池中的对象。而`Integer i1 = new Integer(40)` 会直接创建新的对象。因此,输出 false 。 +`Integer i1=40` 这一行代码会发生装箱,也就是说这行代码等价于 `Integer i1=Integer.valueOf(40)` 。因此,`i1` 直接使用的是常量池中的对象。而`Integer i1 = new Integer(40)` 会直接创建新的对象。因此,输出 false 。 记住:**所有整型包装类对象之间值的比较,全部使用 `equals()` 方法比较**。 From e450f524158e841c8ce278eca9e82085ff7df275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 15:25:16 +0800 Subject: [PATCH 034/257] fix typo --- docs/java/jvm/Java内存区域.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/jvm/Java内存区域.md b/docs/java/jvm/Java内存区域.md index 977ee296..5881c817 100644 --- a/docs/java/jvm/Java内存区域.md +++ b/docs/java/jvm/Java内存区域.md @@ -103,7 +103,7 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成 **Java 虚拟机栈会出现两种错误:`StackOverFlowError` 和 `OutOfMemoryError`。** - **`StackOverFlowError`:** 若 Java 虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。 -- **`OutOfMemoryError`:** Java 虚拟机栈的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出`OutOfMemoryError`异常异常。 +- **`OutOfMemoryError`:** Java 虚拟机栈的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出`OutOfMemoryError`异常。 ![](./pictures/java内存区域/《深入理解虚拟机》第三版的第2章-虚拟机栈.png) @@ -498,4 +498,4 @@ i4=i5+i6 true - - - -- 深入解析 String#intern \ No newline at end of file +- 深入解析 String#intern From 2546860ada8cca66b44e250abed1697b40c0dcaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 17:54:00 +0800 Subject: [PATCH 035/257] fix typo --- docs/java/jvm/类加载过程.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/jvm/类加载过程.md b/docs/java/jvm/类加载过程.md index 18cdd0b1..c79de7df 100644 --- a/docs/java/jvm/类加载过程.md +++ b/docs/java/jvm/类加载过程.md @@ -102,7 +102,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚 2. 该类没有在其他任何地方被引用 3. 该类的类加载器的实例已被 GC -所以,在 JVM 生命周期类,由 jvm 自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。 +所以,在 JVM 生命周期内,由 jvm 自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。 只要想通一点就好了,jdk 自带的 `BootstrapClassLoader`, `ExtClassLoader`, `AppClassLoader` 负责加载 jdk 提供的类,所以它们(类加载器的实例)肯定不会被回收。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。 @@ -120,4 +120,4 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚 **Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) \ No newline at end of file +![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) From 1aa12ac44eb1acec138b0bb5e2834965aec9719b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 18:46:15 +0800 Subject: [PATCH 036/257] fix typo --- docs/java/jvm/[加餐]大白话带你认识JVM.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/jvm/[加餐]大白话带你认识JVM.md b/docs/java/jvm/[加餐]大白话带你认识JVM.md index b80b34c7..6b7d48ab 100644 --- a/docs/java/jvm/[加餐]大白话带你认识JVM.md +++ b/docs/java/jvm/[加餐]大白话带你认识JVM.md @@ -2,7 +2,7 @@ ## 前言 -如果在文中用词或者理解方面出现问题,欢迎指出。此文旨在提及和而不深究,但会尽量效率地把知识点都抛出来 +如果在文中用词或者理解方面出现问题,欢迎指出。此文旨在提及而不深究,但会尽量效率地把知识点都抛出来 ## 一、JVM的基本介绍 From 889493fd933476b90d453a90124591ed344bbdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 23:14:51 +0800 Subject: [PATCH 037/257] =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/new-features/java8-common-new-features.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index 022a3bc9..9b5a8384 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -798,6 +798,7 @@ public void newFormat(){ //format yyyy-MM-dd HH:mm:ss LocalDateTime dateTime = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String dateTimeStr = dateTime.format(dateTimeFormatter); System.out.println(String.format("dateTime format : %s", dateTimeStr)); } ``` @@ -1016,4 +1017,4 @@ System.out.println("本地时区时间: " + localZoned); - Optional - Date time-api -这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 \ No newline at end of file +这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 From cdceff2cc34f910d9bd29651d8c6daad3bea6b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 23:24:15 +0800 Subject: [PATCH 038/257] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 觉得这行没什么用 --- docs/java/new-features/java8-common-new-features.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index 022a3bc9..b914e543 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -898,7 +898,6 @@ public void getDay() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //获取当前月第一天: Calendar c = Calendar.getInstance(); - c.add(Calendar.MONTH, 0); c.set(Calendar.DAY_OF_MONTH, 1); String first = format.format(c.getTime()); System.out.println("first day:" + first); @@ -1016,4 +1015,4 @@ System.out.println("本地时区时间: " + localZoned); - Optional - Date time-api -这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 \ No newline at end of file +这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 From c8a676100d0a9fdb2271e703f7c55fca8bec301d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=82=87=E6=98=8E?= Date: Sun, 6 Jun 2021 23:31:23 +0800 Subject: [PATCH 039/257] trim --- docs/java/new-features/java8-common-new-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index 022a3bc9..7102e7d5 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -934,7 +934,7 @@ public void getDayNew() { //当年最后一天 LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear()); //2021年最后一个周日,如果用Calendar是不得烦死。 - LocalDate lastMondayOf2021 = LocalDate.parse("2021-12- 31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY)); + LocalDate lastMondayOf2021 = LocalDate.parse("2021-12-31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY)); } ``` @@ -1016,4 +1016,4 @@ System.out.println("本地时区时间: " + localZoned); - Optional - Date time-api -这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 \ No newline at end of file +这些都是开发当中比较常用的特征。梳理下来发现它们真香,而我却没有更早的应用。总觉得学习 java 8 新特性比较麻烦,一致使用老的实现方式。其实这些新特性几天就可以掌握,一但掌握,效率会有很大的提高。其实我们涨工资也是涨的学习的钱,不学习终究会被淘汰,35 岁危机会提前来临。 From e2e340c7cb46199a345154353fbe8b7344e6cd42 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 7 Jun 2021 10:46:10 +0800 Subject: [PATCH 040/257] [docs]jvm --- README.md | 2 + docs/java/jvm/类加载过程.md | 4 + .../basis-of-authority-certification.md | 202 +++++++++++------- 3 files changed, 132 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index e8db97f4..067cabfa 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ ### JVM (必看 :+1:) +JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle.com/javase/specs/jvms/se8/html/index.html) 和周志明老师的[《深入理解Java虚拟机(第3版)》](https://book.douban.com/subject/34907497/) (强烈建议阅读多遍!)。 + 1. **[Java 内存区域](docs/java/jvm/Java内存区域.md)** 2. **[JVM 垃圾回收](docs/java/jvm/JVM垃圾回收.md)** 3. [JDK 监控和故障处理工具](docs/java/jvm/JDK监控和故障处理工具总结.md) diff --git a/docs/java/jvm/类加载过程.md b/docs/java/jvm/类加载过程.md index c79de7df..bf2811eb 100644 --- a/docs/java/jvm/类加载过程.md +++ b/docs/java/jvm/类加载过程.md @@ -26,6 +26,10 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚 ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png) +详见:[jvm规范5.4](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4) 。 + +![](https://img-blog.csdnimg.cn/20210607102244508.png) + ### 加载 类加载过程的第一步,主要完成下面 3 件事情: diff --git a/docs/system-design/authority-certification/basis-of-authority-certification.md b/docs/system-design/authority-certification/basis-of-authority-certification.md index 22055861..9a8a09f0 100644 --- a/docs/system-design/authority-certification/basis-of-authority-certification.md +++ b/docs/system-design/authority-certification/basis-of-authority-certification.md @@ -1,45 +1,75 @@ -## 1. 认证 (Authentication) 和授权 (Authorization)的区别是什么? +## 认证 (Authentication) 和授权 (Authorization)的区别是什么? 这是一个绝大多数人都会混淆的问题。首先先从读音上来认识这两个名词,很多人都会把它俩的读音搞混,所以我建议你先先去查一查这两个单词到底该怎么读,他们的具体含义是什么。 说简单点就是: -**认证 (Authentication):** 你是谁。 +- **认证 (Authentication):** 你是谁。 +- **授权 (Authorization):** 你有权限干什么。 -![](./images/basis-of-authority-certification/authentication.png) +稍微正式点(啰嗦点)的说法就是 : -**授权 (Authorization):** 你有权限干什么。 +- **Authentication(认证)** 是验证您的身份的凭据(例如用户名/用户 ID 和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。 +- **Authorization(授权)** 发生在 **Authentication(认证)** 之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如 admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。 -![](./images/basis-of-authority-certification/authorization.png) +认证 : -稍微正式点(啰嗦点)的说法就是: +![](https://img-blog.csdnimg.cn/20210604160908352.png) -- **Authentication(认证)** 是验证您的身份的凭据(例如用户名/用户ID和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。 -- **Authorization(授权)** 发生在 **Authentication(认证)** 之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。 +授权: + +![](https://img-blog.csdnimg.cn/20210604161032412.png) 这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。 -## 2. 什么是Cookie ? Cookie的作用是什么?如何在服务端使用 Cookie ? +## RBAC 模型介绍一下? -![](./images/basis-of-authority-certification/cookie-sessionId.png) +系统权限控制最常采用的访问控制模型就是 **RBAC 模型** 。 -### 2.1 什么是Cookie ? Cookie的作用是什么? +**什么是 RBAC 呢?** -Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 +RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这是一种通过角色关联权限,角色同时又关联用户的授权的方式。 -维基百科是这样定义 Cookie 的:Cookies是某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。简单来说: **Cookie 存放在客户端,一般用来保存用户信息**。 +简单地说:一个用户可以拥有若干角色,每一个角色有可以被分配若干权限这样,就构造成“用户-角色-权限” 的授权模型。在这种模型中,用户与角色、角色与权限之间构成了多对多的关系,如下图 -下面是 Cookie 的一些应用案例: +![RBAC](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-9/RBAC.png) -1. 我们在 Cookie 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了。除此之外,Cookie 还能保存用户首选项,主题和其他设置信息。 -2. 使用Cookie 保存 session 或者 token ,向后端发送请求的时候带上 Cookie,这样后端就能取到session或者token了。这样就能记录用户当前的状态了,因为 HTTP 协议是无状态的。 -3. Cookie 还可以用来记录和分析用户行为。举个简单的例子你在网上购物的时候,因为HTTP协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常用的实现方式就是将这些信息存放在Cookie +**在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。** -### 2.2 如何在服务端使用 Cookie 呢? +本系统的权限设计相关的表如下(一共 5 张表,2 张用户建立表之间的联系): -这部分内容参考:https://attacomsian.com/blog/cookies-spring-boot, 更多如何在Spring Boot中使用Cookie 的内容可以查看这篇文章。 +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2020-11/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1-%E6%9D%83%E9%99%90.png) -**1)设置cookie返回给客户端** +通过这个权限模型,我们可以创建不同的角色并为不同的角色分配不同的权限范围(菜单)。 + +![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-7/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%E6%A8%A1%E5%9D%97.png) + +通常来说,如果系统对于权限控制要求比较严格的话,一般都会选择使用 RBAC 模型来做权限控制。 + +## 什么是 Cookie ? Cookie 的作用是什么? + +![](./images/basis-of-authority-certification/cookie-SessionId.png) + +`Cookie` 和 `Session` 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 + +维基百科是这样定义 `Cookie` 的: + +> `Cookies` 是某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。 + +简单来说: **`Cookie` 存放在客户端,一般用来保存用户信息**。 + +下面是 `Cookie` 的一些应用案例: + +1. 我们在 `Cookie` 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了。除此之外,`Cookie` 还能保存用户首选项,主题和其他设置信息。 +2. 使用 `Cookie` 保存 `Session` 或者 `Token` ,向后端发送请求的时候带上 `Cookie`,这样后端就能取到 `Session` 或者 `Token` 了。这样就能记录用户当前的状态了,因为 HTTP 协议是无状态的。 +3. `Cookie` 还可以用来记录和分析用户行为。举个简单的例子你在网上购物的时候,因为 HTTP 协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常用的实现方式就是将这些信息存放在 `Cookie` +4. ...... + +## 如何在项目中使用 Cookie 呢? + +我这里以 Spring Boot 项目为例。 + +**1)设置 `Cookie` 返回给客户端** ```java @GetMapping("/change-username") @@ -55,7 +85,7 @@ public String setCookie(HttpServletResponse response) { } ``` -**2) 使用Spring框架提供的`@CookieValue`注解获取特定的 cookie的值** +**2) 使用 Spring 框架提供的 `@CookieValue` 注解获取特定的 cookie 的值** ```java @GetMapping("/") @@ -64,7 +94,7 @@ public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") } ``` -**3) 读取所有的 Cookie 值** +**3) 读取所有的 `Cookie` 值** ```java @GetMapping("/all-cookies") @@ -80,115 +110,139 @@ public String readAllCookies(HttpServletRequest request) { } ``` -## 3. Cookie 和 Session 有什么区别?如何使用Session进行身份验证? +更多关于如何在 Spring Boot 中使用 `Cookie` 的内容可以查看这篇文章:[How to use cookies in Spring Boot](https://attacomsian.com/blog/cookies-spring-boot。) 。 -**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 +## Cookie 和 Session 有什么区别? -**Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。** +**`Session` 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 `Session` 之后就可以标识这个用户并且跟踪这个用户了。 -**那么,如何使用Session进行身份验证?** +`Cookie` 数据保存在客户端(浏览器端),`Session` 数据保存在服务器端。相对来说 `Session` 安全性更高。如果使用 `Cookie` 的一些敏感信息不要写入 `Cookie` 中,最好能将 `Cookie` 信息加密然后使用到的时候再去服务器端解密。 -很多时候我们都是通过 SessionID 来实现特定的用户,SessionID 一般会选择存放在 Redis 中。举个例子:用户成功登陆系统,然后返回给客户端具有 SessionID 的 Cookie,当用户向后端发起请求的时候会把 SessionID 带上,这样后端就知道你的身份状态了。关于这种认证方式更详细的过程如下: +**那么,如何使用 `Session` 进行身份验证?** + +## 如何使用 Session-Cookie 方案进行身份验证? + +很多时候我们都是通过 `SessionID` 来实现特定的用户,`SessionID` 一般会选择存放在 Redis 中。举个例子: + +1. 用户成功登陆系统,然后返回给客户端具有 `SessionID` 的 `Cookie` +2. 当用户向后端发起请求的时候会把 `SessionID` 带上,这样后端就知道你的身份状态了。 + +关于这种认证方式更详细的过程如下: ![Session Based Authentication flow](./images/basis-of-authority-certification/Session-Based-Authentication-flow.png) 1. 用户向服务器发送用户名和密码用于登陆系统。 -2. 服务器验证通过后,服务器为用户创建一个 Session,并将 Session信息存储 起来。 -3. 服务器向用户返回一个 SessionID,写入用户的 Cookie。 -4. 当用户保持登录状态时,Cookie 将与每个后续请求一起被发送出去。 -5. 服务器可以将存储在 Cookie 上的 Session ID 与存储在内存中或者数据库中的 Session 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。 +2. 服务器验证通过后,服务器为用户创建一个 `Session`,并将 `Session` 信息存储 起来。 +3. 服务器向用户返回一个 `SessionID`,写入用户的 `Cookie`。 +4. 当用户保持登录状态时,`Cookie` 将与每个后续请求一起被发送出去。 +5. 服务器可以将存储在 `Cookie` 上的 `SessionID` 与存储在内存中或者数据库中的 `Session` 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。 -使用 Session 的时候需要注意下面几个点: +使用 `Session` 的时候需要注意下面几个点: -1. 依赖Session的关键业务一定要确保客户端开启了Cookie。 -2. 注意Session的过期时间 +1. 依赖 `Session` 的关键业务一定要确保客户端开启了 `Cookie`。 +2. 注意 `Session` 的过期时间 -花了个图简单总结了一下Session认证涉及的一些东西。 +画了个图简单总结了一下 `Session` 认证涉及的一些东西。 -![](./images/basis-of-authority-certification/session-cookie-intro.jpeg) +![](./images/basis-of-authority-certification/Session-cookie-intro.jpeg) -另外,Spring Session提供了一种跨多个应用程序或实例管理用户会话信息的机制。如果想详细了解可以查看下面几篇很不错的文章: +另外,Spring Session 提供了一种跨多个应用程序或实例管理用户会话信息的机制。如果想详细了解可以查看下面几篇很不错的文章: -- [Getting Started with Spring Session](https://codeboje.de/spring-session-tutorial/) -- [Guide to Spring Session](https://www.baeldung.com/spring-session) -- [Sticky Sessions with Spring Session & Redis](https://medium.com/@gvnix/sticky-sessions-with-spring-session-redis-bdc6f7438cc3) +- [Getting Started with Spring Session](https://codeboje.de/spring-Session-tutorial/) +- [Guide to Spring Session](https://www.baeldung.com/spring-Session) +- [Sticky Sessions with Spring Session & Redis](https://medium.com/@gvnix/sticky-Sessions-with-spring-Session-redis-bdc6f7438cc3) -## 4.如果没有Cookie的话Session还能用吗? +## 多服务器节点下 Session-Cookie 方案如何做? + +Session-Cookie 方案在单体环境是一个非常好的身份认证方案。但是,当服务器水平拓展成多节点时,Session-Cookie 方案就要面临挑战了。 + +举个例子:假如我们部署了两份相同的服务 A,B,用户第一次登陆的时候 ,Nginx 通过负载均衡机制将用户请求转发到 A 服务器,此时用户的 Session 信息保存在 A 服务器。结果,用户第二次访问的时候 Nginx 将请求路由到 B 服务器,由于 B 服务器没有保存 用户的 Session 信息,导致用户需要重新进行登陆。 + +**我们应该如何避免上面这种情况的出现呢?** + +有几个方案可供大家参考: + +1. 某个用户的所有请求都通过特性的哈希策略分配给同一个服务器处理。这样的话,每个服务器都保存了一部分用户的 Session 信息。服务器宕机,其保存的所有 Session 信息就完全丢失了。 +2. 每一个服务器保存的 Session 信息都是互相同步的,也就是说每一个服务器都保存了全量的 Session 信息。每当一个服务器的 Session 信息发生变化,我们就将其同步到其他服务器。这种方案成本太大,并且,节点越多时,同步成本也越高。 +3. 单独使用一个所有服务器都能访问到的数据节点(比如缓存)来存放 Session 信息。为了保证高可用,数据节点尽量要避免是单点。 + +## 如果没有 Cookie 的话 Session 还能用吗? 这是一道经典的面试题! -一般是通过 Cookie 来保存 SessionID ,假如你使用了 Cookie 保存 SessionID的方案的话, 如果客户端禁用了Cookie,那么Session就无法正常工作。 +一般是通过 `Cookie` 来保存 `SessionID` ,假如你使用了 `Cookie` 保存 `SessionID` 的方案的话, 如果客户端禁用了 `Cookie`,那么 `Session` 就无法正常工作。 -但是,并不是没有 Cookie 之后就不能用 Session 了,比如你可以将SessionID放在请求的 url 里面`https://javaguide.cn/?session_id=xxx` 。这种方案的话可行,但是安全性和用户体验感降低。当然,为了你也可以对 SessionID 进行一次加密之后再传入后端。 +但是,并不是没有 `Cookie` 之后就不能用 `Session` 了,比如你可以将 `SessionID` 放在请求的 `url` 里面`https://javaguide.cn/?Session_id=xxx` 。这种方案的话可行,但是安全性和用户体验感降低。当然,为了你也可以对 `SessionID` 进行一次加密之后再传入后端。 -## 5.为什么Cookie 无法防止CSRF攻击,而token可以? +## 为什么 Cookie 无法防止 CSRF 攻击,而 Token 可以? **CSRF(Cross Site Request Forgery)**一般被翻译为 **跨站请求伪造** 。那么什么是 **跨站请求伪造** 呢?说简单用你的身份去发送一些对你不友好的请求。举个简单的例子: -小壮登录了某网上银行,他来到了网上银行的帖子区,看到一个帖子下面有一个链接写着“科学理财,年盈利率过万”,小壮好奇的点开了这个链接,结果发现自己的账户少了10000元。这是这么回事呢?原来黑客在链接中藏了一个请求,这个请求直接利用小壮的身份给银行发送了一个转账请求,也就是通过你的 Cookie 向银行发出请求。 +小壮登录了某网上银行,他来到了网上银行的帖子区,看到一个帖子下面有一个链接写着“科学理财,年盈利率过万”,小壮好奇的点开了这个链接,结果发现自己的账户少了 10000 元。这是这么回事呢?原来黑客在链接中藏了一个请求,这个请求直接利用小壮的身份给银行发送了一个转账请求,也就是通过你的 Cookie 向银行发出请求。 -``` +```html 科学理财,年盈利率过万 ``` -上面也提到过,进行Session 认证的时候,我们一般使用 Cookie 来存储 SessionId,当我们登陆后后端生成一个SessionId放在Cookie中返回给客户端,服务端通过Redis或者其他存储工具记录保存着这个Sessionid,客户端登录以后每次请求都会带上这个SessionId,服务端通过这个SessionId来标示你这个人。如果别人通过 cookie拿到了 SessionId 后就可以代替你的身份访问系统了。 +上面也提到过,进行 `Session` 认证的时候,我们一般使用 `Cookie` 来存储 `SessionId`,当我们登陆后后端生成一个 `SessionId` 放在 Cookie 中返回给客户端,服务端通过 Redis 或者其他存储工具记录保存着这个 `SessionId`,客户端登录以后每次请求都会带上这个 `SessionId`,服务端通过这个 `SessionId` 来标示你这个人。如果别人通过 `Cookie` 拿到了 `SessionId` 后就可以代替你的身份访问系统了。 - Session 认证中 Cookie 中的 SessionId是由浏览器发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。 +`Session` 认证中 `Cookie` 中的 `SessionId` 是由浏览器发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。 -但是,我们使用 token 的话就不会存在这个问题,在我们登录成功获得 token 之后,一般会选择存放在 local storage 中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 token,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 token 的,所以这个请求将是非法的。 +但是,我们使用 `Token` 的话就不会存在这个问题,在我们登录成功获得 `Token` 之后,一般会选择存放在 local storage 中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 `Token`,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 `Token` 的,所以这个请求将是非法的。 -需要注意的是不论是 Cookie 还是 token 都无法避免跨站脚本攻击(Cross Site Scripting)XSS。 +需要注意的是不论是 Cookie 还是 Token 都无法避免 **跨站脚本攻击(Cross Site Scripting)XSS** 。 -> 跨站脚本攻击(Cross Site Scripting)缩写为 CSS 但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。 +> 跨站脚本攻击(Cross Site Scripting)缩写为 CSS 但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为 XSS。 -XSS中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如cookie。 +XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 cookie。 -推荐阅读:[如何防止CSRF攻击?—美团技术团队](https://tech.meituan.com/2018/10/11/fe-security-csrf.html) +推荐阅读:[如何防止 CSRF 攻击?—美团技术团队](https://tech.meituan.com/2018/10/11/fe-security-csrf.html) -## 6. 什么是 Token?什么是 JWT?如何基于Token进行身份验证? +## 什么是 Token?什么是 JWT? -我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 Session 信息服务器的可用性、不适合移动端(依赖Cookie)等等。 +我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 Session 信息服务器的可用性、不适合移动端(依赖 Cookie)等等。 -有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。 +有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。 **JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。** 下面是 [RFC 7519](https://tools.ietf.org/html/rfc7519) 对 JWT 做的较为正式的定义。 -> JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. ——[JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) +> JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. ——[JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) JWT 由 3 部分构成: -1. Header :描述 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。 -2. Payload(负载):用来存放实际需要传递的数据 -3. Signature(签名):服务器通过`Payload`、`Header`和一个密钥(`secret`)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。 +1. **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。 +2. **Payload** : 用来存放实际需要传递的数据 +3. **Signature(签名)** :服务器通过`Payload`、`Header`和一个密钥(`secret`)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。 -在基于 Token 进行身份验证的的应用程序中,服务器通过`Payload`、`Header`和一个密钥(`secret`)创建令牌(`Token`)并将 `Token` 发送给客户端,客户端将 `Token` 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization字段中:` Authorization: Bearer Token`。 +## 如何基于 Token 进行身份验证? + +在基于 Token 进行身份验证的的应用程序中,服务器通过`Payload`、`Header`和一个密钥(`secret`)创建令牌(`Token`)并将 `Token` 发送给客户端,客户端将 `Token` 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization 字段中:`Authorization: Bearer Token`。 ![Token Based Authentication flow](./images/basis-of-authority-certification/Token-Based-Authentication.png) 1. 用户向服务器发送用户名和密码用于登陆系统。 2. 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。 -3. 用户以后每次向后端发请求都在Header中带上 JWT。 +3. 用户以后每次向后端发请求都在 Header 中带上 JWT。 4. 服务端检查 JWT 并从中获取用户相关信息。 - 推荐阅读: -- [JWT (JSON Web Tokens) Are Better Than Session Cookies](https://dzone.com/articles/jwtjson-web-tokens-are-better-than-session-cookies) +- [JWT (JSON Web Tokens) Are Better Than Session Cookies](https://dzone.com/articles/jwtjson-web-Tokens-are-better-than-Session-cookies) - [JSON Web Tokens (JWT) 与 Sessions](https://juejin.im/entry/577b7b56a3413100618c2938) -- [JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html) -- [彻底理解Cookie,Session,Token](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485603&idx=1&sn=c8d324f44d6102e7b44554733da10bb7&chksm=cea24768f9d5ce7efe7291ddabce02b68db34073c7e7d9a7dc9a7f01c5a80cebe33ac75248df&token=844918801&lang=zh_CN#rd) +- [JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_Token-tutorial.html) +- [彻底理解 Cookie,Session,Token](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485603&idx=1&sn=c8d324f44d6102e7b44554733da10bb7&chksm=cea24768f9d5ce7efe7291ddabce02b68db34073c7e7d9a7dc9a7f01c5a80cebe33ac75248df&Token=844918801&lang=zh_CN#rd) -## 7 什么是OAuth 2.0? +## 什么是 OAuth 2.0? -OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。而 OAuth 2.0是对 OAuth 1.0 的完全重新设计,OAuth 2.0更快,更容易实现,OAuth 1.0 已经被废弃。详情请见:[rfc6749](https://tools.ietf.org/html/rfc6749)。 +OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。而 OAuth 2.0 是对 OAuth 1.0 的完全重新设计,OAuth 2.0 更快,更容易实现,OAuth 1.0 已经被废弃。详情请见:[rfc6749](https://tools.ietf.org/html/rfc6749)。 -实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 token,使得第三方应用能够通过该令牌获取相关的资源。 +实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 Token,使得第三方应用能够通过该令牌获取相关的资源。 OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了第三方登录的时候一般就是使用的 OAuth 2.0 协议。 -另外,现在OAuth 2.0也常见于支付场景(微信支付、支付宝支付)和开发平台(微信开放平台、阿里开放平台等等)。 +另外,现在 OAuth 2.0 也常见于支付场景(微信支付、支付宝支付)和开发平台(微信开放平台、阿里开放平台等等)。 微信支付账户相关参数: @@ -201,16 +255,12 @@ OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了 - [OAuth 2.0 的四种方式](http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html) - [GitHub OAuth 第三方登录示例教程](http://www.ruanyifeng.com/blog/2019/04/github-oauth.html) -## 8 什么是 SSO? +## 什么是 SSO? SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。 -## 9.SSO与OAuth2.0的区别 - -OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。SSO解决的是一个公司的多个相关的自系统的之间的登陆问题比如京东旗下相关子系统京东金融、京东超市、京东家电等等。 - ## 参考 -- https://medium.com/@sherryhsu/session-vs-token-based-authentication-11a6c5ac45e4 +- https://medium.com/@sherryhsu/Session-vs-Token-based-authentication-11a6c5ac45e4 - https://www.varonis.com/blog/what-is-oauth/ - https://tools.ietf.org/html/rfc6749 From e4098a6bb2046899f4b952a8b6856fa895ff759a Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 7 Jun 2021 14:49:20 +0800 Subject: [PATCH 041/257] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 067cabfa..eaf962f3 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 > 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。 > 3. **图解计算机基础** :[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 -> 4. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。星球内部更新的[《Java面试进阶指北 打造个人的技术竞争力》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7)这个小册的质量很高,专为面试打造。 -> 5. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java 面试进阶指南》](https://xiaozhuanlan.com/javainterview?rel=javaguide) +> 4. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。 +> 5. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java面试进阶指北 》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7) (质量很高,专为面试打造) > 6. **转载须知** :以下所有文章如非文首说明皆为我(Guide哥)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️

From d1277e81713720d93d88de0c24b90e3728feee31 Mon Sep 17 00:00:00 2001 From: YGQ Date: Mon, 7 Jun 2021 15:58:00 +0800 Subject: [PATCH 042/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=B3=BB=E7=BB=9F3.6=E8=8A=82=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=BE=AE=E8=BD=AF=E5=AE=98=E7=BD=91=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=EF=BC=8C=E7=8E=B0=E5=9C=A8=E5=BE=AE=E8=BD=AF=E5=AE=98=E7=BD=91?= =?UTF-8?q?=E8=AF=A5=E6=96=87=E5=B7=B2=E6=9C=89=E4=B8=AD=E6=96=87=E7=89=88?= =?UTF-8?q?=EF=BC=8C=E4=B8=94=E5=8F=AF=E5=88=87=E6=8D=A2=E4=B8=AD=E8=8B=B1?= =?UTF-8?q?=E6=96=87=E9=98=85=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/operating-system/basis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operating-system/basis.md b/docs/operating-system/basis.md index b1cb59b5..9276f040 100644 --- a/docs/operating-system/basis.md +++ b/docs/operating-system/basis.md @@ -233,7 +233,7 @@ 于是面试完之后我默默去查阅了相关文档!留下了没有技术的泪水。。。 -> 这部分内容参考了 Microsoft 官网的介绍,地址: +> 这部分内容参考了 Microsoft 官网的介绍,地址: 现代处理器使用的是一种称为 **虚拟寻址(Virtual Addressing)** 的寻址方式。**使用虚拟寻址,CPU 需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。** 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 **内存管理单元(Memory Management Unit, MMU)** 的硬件。如下图所示: From 50b170b0d5325b8e65e665623d82a6074bcb88f3 Mon Sep 17 00:00:00 2001 From: Holdonbei <54311580+Holdonbei@users.noreply.github.com> Date: Tue, 8 Jun 2021 10:13:48 +0800 Subject: [PATCH 043/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=89=E6=AC=A1?= =?UTF-8?q?=E6=8F=A1=E6=89=8B=E7=9A=84=E5=8E=9F=E5=9B=A0=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?SYNDDoS=E6=94=BB=E5=87=BB=E7=9A=84=E5=8E=9F=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络.md | 643 +++++++++++++++++--------------- 1 file changed, 349 insertions(+), 294 deletions(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 10fc157f..35245120 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -1,294 +1,349 @@ -## 一 OSI与TCP/IP各层的结构与功能,都有哪些协议? - -学习计算机网络时我们一般采用折中的办法,也就是中和 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。 - -![五层体系结构](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/五层体系结构.png) - -结合互联网的情况,自上而下地,非常简要的介绍一下各层的作用。 - -### 1.1 应用层 - -**应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。**应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如**域名系统DNS**,支持万维网应用的 **HTTP协议**,支持电子邮件的 **SMTP协议**等等。我们把应用层交互的数据单元称为报文。 - -**域名系统** - -> 域名系统(Domain Name System缩写 DNS,Domain Name被译为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。(百度百科)例如:一个公司的 Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有:IBM 公司的域名是 www.ibm.com、Oracle 公司的域名是 www.oracle.com、Cisco公司的域名是 www.cisco.com 等。 - -**HTTP协议** - -> 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。(百度百科) - -### 1.2 运输层 - -**运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务**。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。 - -**运输层主要使用以下两种协议:** - -1. **传输控制协议 TCP**(Transmission Control Protocol)--提供**面向连接**的,**可靠的**数据传输服务。 -2. **用户数据协议 UDP**(User Datagram Protocol)--提供**无连接**的,尽最大努力的数据传输服务(**不保证数据传输的可靠性**)。 - -**TCP 与 UDP 的对比见问题三。** - - -### 1.3 网络层 - -**在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。** 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 **IP 协议**,因此分组也叫 **IP 数据报** ,简称 **数据报**。 - -这里要注意:**不要把运输层的“用户数据报 UDP ”和网络层的“ IP 数据报”弄混**。另外,无论是哪一层的数据单元,都可笼统地用“分组”来表示。 - -这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系结构模型中第三层的名称. - -互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Internet Protocol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP层**。 - -### 1.4 数据链路层 -**数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。** 在两个相邻节点之间传送数据时,**数据链路层将网络层交下来的 IP 数据报组装成帧**,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 - -在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 -控制信息还使接收端能够检测到所收到的帧中有无差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。 - -### 1.5 物理层 -在物理层上所传送的数据单位是比特。 - - **物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,** 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。 - -在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。 - -### 1.6 总结一下 - -上面我们对计算机网络的五层体系结构有了初步的了解,下面附送一张七层体系结构图总结一下(图片来源于网络)。 - -![七层体系结构图](images/七层体系结构图.png) - -## 二 TCP 三次握手和四次挥手(面试常客) - -为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。 - -### 2.1 TCP 三次握手漫画图解 - -如下图所示,下面的两个机器人通过3次握手确定了对方能正确接收和发送消息(图片来源:《图解HTTP》)。 -![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手.png) - -**简单示意图:** -![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手2.png) - -- 客户端–发送带有 SYN 标志的数据包–一次握手–服务端 -- 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端 -- 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端 - -### 2.2 为什么要三次握手 - -**三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。** - -第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常 - -第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常 - -第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常 - -所以三次握手就能确认双发收发功能都正常,缺一不可。 - -### 2.3 第2次握手传回了ACK,为什么还要传回SYN? - -接收端传回发送端所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传SYN则是为了建立并确认从服务端到客户端的通信。” - -> SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。 - -### 2.5 为什么要四次挥手 - -![TCP四次挥手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/TCP四次挥手.png) - -断开一个 TCP 连接则需要“四次挥手”: - -- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送 -- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号 -- 服务器-关闭与客户端的连接,发送一个FIN给客户端 -- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1 - -任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 - -举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 - -上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891) - -## 三 TCP,UDP 协议的区别 -![TCP、UDP协议的区别](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp-vs-udp.jpg) - -UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等 - -TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 - -## 四 TCP 协议如何保证可靠传输 - -1. 应用数据被分割成 TCP 认为最适合发送的数据块。 -2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。 -3. **校验和:** TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。 -4. TCP 的接收端会丢弃重复的数据。 -5. **流量控制:** TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) -6. **拥塞控制:** 当网络拥塞时,减少数据的发送。 -7. **ARQ协议:** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 -8. **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 - -### 4.1 ARQ协议 - -**自动重传请求**(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。 - -#### 停止等待ARQ协议 -停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。 - -在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。 - -**优缺点:** - -- **优点:** 简单 -- **缺点:** 信道利用率低,等待时间长 - -**1) 无差错情况:** - -发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。 - -**2) 出现差错情况(超时重传):** - -停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为 **自动重传请求 ARQ** 。另外在停止等待协议中若收到重复分组,就丢弃该分组,但同时还要发送确认。**连续 ARQ 协议** 可提高信道利用率。发送维持一个发送窗口,凡位于发送窗口内的分组可连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组位置的所有分组都已经正确收到了。 - -**3) 确认丢失和确认迟到** - -- **确认丢失** :确认消息在传输过程丢失。当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:1. 丢弃这个重复的M1消息,不向上层交付。 2. 向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。 -- **确认迟到** :确认消息在传输过程中迟到。A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:1. A收到重复的确认后,直接丢弃。2. B收到重复的M1后,也直接丢弃重复的M1。 - -#### 连续ARQ协议 - -连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。 - -**优缺点:** - -- **优点:** 信道利用率高,容易实现,即使确认丢失,也不必重传。 -- **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。 - -### 4.2 滑动窗口和流量控制 - -**TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。** 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。 - -### 4.3 拥塞控制 - -在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。 - -为了进行拥塞控制,TCP 发送方要维持一个 **拥塞窗口(cwnd)** 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。 - -TCP的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免** 、**快重传** 和 **快恢复**。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。 - -- **慢开始:** 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。 -- **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1. -- **快重传与快恢复:** - 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。 - - -## 五 在浏览器中输入url地址 ->> 显示主页的过程(面试常客) - -百度好像最喜欢问这个问题。 - -> 打开一个网页,整个过程会使用哪些协议? - -图解(图片来源:《图解HTTP》): - - - -> 上图有一个错误,请注意,是OSPF不是OPSF。 OSPF(Open Shortest Path First,ospf)开放最短路径优先协议,是由Internet工程任务组开发的路由选择协议 - -总体来说分为以下几个过程: - -1. DNS解析 -2. TCP连接 -3. 发送HTTP请求 -4. 服务器处理请求并返回HTTP报文 -5. 浏览器解析渲染页面 -6. 连接结束 - -具体可以参考下面这篇文章: - -- [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700) - -## 六 状态码 - -![状态码](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/状态码.png) - - -## 七 各种协议与HTTP协议之间的关系 -一般面试官会通过这样的问题来考察你对计算机网络知识体系的理解。 - -图片来源:《图解HTTP》 - -![各种协议与HTTP协议之间的关系](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/各种协议与HTTP协议之间的关系.png) - -## 八 HTTP长连接,短连接 - -在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。 - -而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码: - -``` -Connection:keep-alive -``` - -在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 - -**HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。** - -—— [《HTTP长连接、短连接究竟是什么?》](https://www.cnblogs.com/gotodsp/p/6366163.html) - -## 九 HTTP是不保存状态的协议,如何保存用户状态? - -HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。 - -在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。 - -**Cookie 被禁用怎么办?** - -最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。 - -![HTTP是无状态协议](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HTTP是无状态的.png) - -## 十 Cookie的作用是什么?和Session有什么区别? - -Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 - - **Cookie 一般用来保存用户信息** 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 - -Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 - -Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 - -## 十一 HTTP 1.0和HTTP 1.1的主要区别是什么? - -> 这部分回答引用这篇文章 的一些内容。 - -HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在: - -1. **长连接** : **在HTTP/1.0中,默认使用的是短连接**,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。**HTTP 1.1起,默认使用长连接** ,默认开启Connection: keep-alive。 **HTTP/1.1的持续连接有非流水线方式和流水线方式** 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 -1. **错误状态响应码** :在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 -1. **缓存处理** :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。 -1. **带宽优化及网络连接的使用** :HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。 - -## 十二 URI和URL的区别是什么? - -- URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。 -- URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。 - -URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。 - -## 十三 HTTP 和 HTTPS 的区别? - -1. **端口** :HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。 -2. **安全性和资源消耗:** HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。 - - 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等; - - 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。 - -## 建议 - -非常推荐大家看一下 《图解HTTP》 这本书,这本书页数不多,但是内容很是充实,不管是用来系统的掌握网络方面的一些知识还是说纯粹为了应付面试都有很大帮助。下面的一些文章只是参考。大二学习这门课程的时候,我们使用的教材是 《计算机网络第七版》(谢希仁编著),不推荐大家看这本教材,书非常厚而且知识偏理论,不确定大家能不能心平气和的读完。 - -## 参考 - -- [https://blog.csdn.net/qq_16209077/article/details/52718250](https://blog.csdn.net/qq_16209077/article/details/52718250) -- [https://blog.csdn.net/zixiaomuwu/article/details/60965466](https://blog.csdn.net/zixiaomuwu/article/details/60965466) -- [https://blog.csdn.net/turn__back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641) -- +## 一 OSI与TCP/IP各层的结构与功能,都有哪些协议? + +学习计算机网络时我们一般采用折中的办法,也就是中和 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。 + +![五层体系结构](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/五层体系结构.png) + +结合互联网的情况,自上而下地,非常简要的介绍一下各层的作用。 + +### 1.1 应用层 + +**应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。**应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如**域名系统DNS**,支持万维网应用的 **HTTP协议**,支持电子邮件的 **SMTP协议**等等。我们把应用层交互的数据单元称为报文。 + +**域名系统** + +> 域名系统(Domain Name System缩写 DNS,Domain Name被译为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。(百度百科)例如:一个公司的 Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有:IBM 公司的域名是 www.ibm.com、Oracle 公司的域名是 www.oracle.com、Cisco公司的域名是 www.cisco.com 等。 + +**HTTP协议** + +> 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。(百度百科) + +### 1.2 运输层 + +**运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务**。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。 + +**运输层主要使用以下两种协议:** + +1. **传输控制协议 TCP**(Transmission Control Protocol)--提供**面向连接**的,**可靠的**数据传输服务。 +2. **用户数据协议 UDP**(User Datagram Protocol)--提供**无连接**的,尽最大努力的数据传输服务(**不保证数据传输的可靠性**)。 + +**TCP 与 UDP 的对比见问题三。** + + +### 1.3 网络层 + +**在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。** 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 **IP 协议**,因此分组也叫 **IP 数据报** ,简称 **数据报**。 + +这里要注意:**不要把运输层的“用户数据报 UDP ”和网络层的“ IP 数据报”弄混**。另外,无论是哪一层的数据单元,都可笼统地用“分组”来表示。 + +这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系结构模型中第三层的名称. + +互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Internet Protocol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP层**。 + +### 1.4 数据链路层 +**数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。** 在两个相邻节点之间传送数据时,**数据链路层将网络层交下来的 IP 数据报组装成帧**,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 + +在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 +控制信息还使接收端能够检测到所收到的帧中有无差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。 + +### 1.5 物理层 +在物理层上所传送的数据单位是比特。 + + **物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,** 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。 + +在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。 + +### 1.6 总结一下 + +上面我们对计算机网络的五层体系结构有了初步的了解,下面附送一张七层体系结构图总结一下(图片来源于网络)。 + +![七层体系结构图](images/七层体系结构图.png) + +## 二 TCP 三次握手和四次挥手(面试常客) + +为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。 + +### 2.1 TCP 三次握手漫画图解 + +如下图所示,下面的两个机器人通过3次握手确定了对方能正确接收和发送消息(图片来源:《图解HTTP》)。 +![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手.png) + +**简单示意图:** +![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手2.png) + +- 客户端–发送带有 SYN 标志的数据包–一次握手–服务端 +- 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端 +- 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端 + +### 2.2 为什么要三次握手 + +**三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。** + +第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常 + +第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常 + +第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常 + +所以三次握手就能确认双发收发功能都正常,缺一不可。 + +### 2.3 第2次握手传回了ACK,为什么还要传回SYN? + +接收端传回发送端所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传SYN则是为了建立并确认从服务端到客户端的通信。” + +> SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。 + +#### 2.3.1 三次握手的原因? + +一般来说,这种问题我们可以使用反证法来说明 TCP 为什么要进行三次握手。 + +* 如果只有两次握手,我们来看看会发生什么事情。 + +正常情况下,TCP 连接建立之后,默认保持长连接。如果只有两次握手,情况就是: + +第一次握手:Client 发送 SYN 请求连接。Client 进入SYN-SENT 状态 + +第二次握手:Server 回发 ACK、SYN 报文。确认连接。**Server 由 LISTEN 状态进入 ESTABLISHED 状态** + +到这里,我们看到,Server 只要接收到 SYN 报文 且回发 ACK、SYN 报文后,就建立了连接。 + +正常情况下我们这么考虑是没有问题的,但网络环境十分复杂,Client 第一次发送的连接请求报文段可能会在这次连接已经释放(结束)后才到达 Server。显然这是一个已经失效的连接,但由于两次握手机制,Server 认可这个连接请求,所以 Server 会再一次建立连接。 + +连接建立之后,由于 Client 已经结束了之前的连接,因此 Server 后面发过来的连接请求,Client是不管的,最终 Server 只能白白维持这次连接(多次重传无效后才发送 RST 报文,断开连接),造成资源的浪费。 + +* 有没有必要四次握手呢? + +结论是,没有必要进行四次握手。原因如下: + +1. 有过抓包经验的小伙伴应该直到,**TCP 握手的前两次,TCP 头部的长度一般都是32字节(固定头部:20字节,选项部分:12字节),且数据部分的长度都为0**,这个阶段。TCP 涉及的拥塞控制、流量控制等需要的信息,比如序号(Seq)、窗口信息等都会在前两次握手中交换。 +2. 使用第三次握手的主要原因就是为了避免 Server 一直等待,浪费资源。 + +综上,我们没有必要再添加多一次握手,增加建立连接的成本。 + +#### 2.3.2 什么是 SYN 攻击? + +我们重新看一下三次握手的过程: + +第一次握手: Client 向 Server 发送连接请求。 + +第二次握手:Server 接收到 Client 的连接请求,向 Client 发送 SYN + ACK 报文。同时 Server 进入 SYN_RCVD 状态。 + +第三次握手:Client 返回 ACK 报文以确认收到 Server 的报文,确认通信。 + +第二次握手与第三次握手之间, Server 此时开启了新的端口等待 Client 的响应,这个 Server 在等待 Client 响应的状态被称为**半开连接状态**。 + +攻击者可以利用半开连接状态对服务器进行攻击,这种攻击称为 SYN 攻击。 + +#### 2.3.3 什么是 DDoS 攻击? + +首先,**拒绝服务攻击**(denial-of-service attack,DoS 攻击)也被称为**洪水攻击**,原理就是上面提到的 SYN 攻击。其目的就像它的名字一样,通过 SYN 攻击使目标服务器资源耗尽,让服务器无法正常提供服务,导致用户无法正常访问。 + +**分布式拒绝服务攻击**(distributed denial-of-service attack,DDoS 攻击),其概念为攻击者控制两台包括两台以上的电脑向目标发起 DoS攻击。 + +网上有一个关于 DDoS 的比喻十分生动: + +我们可以想象大城市堵车的情景,当公路的交通状况很差时,你需要在路上耗费很长的时间,此时公路的交通情况就妨碍了你到达目的地。 + +与此相对应,我们把公路看作用户通往服务器的网络通道,公路上的车看作攻击者攻击的服务器的工具,用户此时就是公路上的一辆车。 + +如果道路很少车(网络通畅),我们就可以迅速通过这段路(网站快速反应);如果道路很多车,变得很拥挤(网络拥塞),那么我们需要花费比平常更多得时间通过这段路(网站响应时间边长);如果有人制造交通事故导致大塞车(DDoS攻击),那么我们可能无法通过这段路(网站几乎瘫痪)。 + +### 2.4 为什么要四次挥手 + +![TCP四次挥手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/TCP四次挥手.png) + +断开一个 TCP 连接则需要“四次挥手”: + +- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送 +- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号 +- 服务器-关闭与客户端的连接,发送一个FIN给客户端 +- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1 + +任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 + +举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 + +上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891) + +## 三 TCP,UDP 协议的区别 +![TCP、UDP协议的区别](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp-vs-udp.jpg) + +UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等 + +TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 + +## 四 TCP 协议如何保证可靠传输 + +1. 应用数据被分割成 TCP 认为最适合发送的数据块。 +2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。 +3. **校验和:** TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。 +4. TCP 的接收端会丢弃重复的数据。 +5. **流量控制:** TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) +6. **拥塞控制:** 当网络拥塞时,减少数据的发送。 +7. **ARQ协议:** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 +8. **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 + +### 4.1 ARQ协议 + +**自动重传请求**(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。 + +#### 停止等待ARQ协议 +停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。 + +在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。 + +**优缺点:** + +- **优点:** 简单 +- **缺点:** 信道利用率低,等待时间长 + +**1) 无差错情况:** + +发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。 + +**2) 出现差错情况(超时重传):** + +停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为 **自动重传请求 ARQ** 。另外在停止等待协议中若收到重复分组,就丢弃该分组,但同时还要发送确认。**连续 ARQ 协议** 可提高信道利用率。发送维持一个发送窗口,凡位于发送窗口内的分组可连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组位置的所有分组都已经正确收到了。 + +**3) 确认丢失和确认迟到** + +- **确认丢失** :确认消息在传输过程丢失。当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:1. 丢弃这个重复的M1消息,不向上层交付。 2. 向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。 +- **确认迟到** :确认消息在传输过程中迟到。A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:1. A收到重复的确认后,直接丢弃。2. B收到重复的M1后,也直接丢弃重复的M1。 + +#### 连续ARQ协议 + +连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。 + +**优缺点:** + +- **优点:** 信道利用率高,容易实现,即使确认丢失,也不必重传。 +- **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。 + +### 4.2 滑动窗口和流量控制 + +**TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。** 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。 + +### 4.3 拥塞控制 + +在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。 + +为了进行拥塞控制,TCP 发送方要维持一个 **拥塞窗口(cwnd)** 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。 + +TCP的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免** 、**快重传** 和 **快恢复**。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。 + +- **慢开始:** 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。 +- **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1. +- **快重传与快恢复:** + 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。 + + +## 五 在浏览器中输入url地址 ->> 显示主页的过程(面试常客) + +百度好像最喜欢问这个问题。 + +> 打开一个网页,整个过程会使用哪些协议? + +图解(图片来源:《图解HTTP》): + + + +> 上图有一个错误,请注意,是OSPF不是OPSF。 OSPF(Open Shortest Path First,ospf)开放最短路径优先协议,是由Internet工程任务组开发的路由选择协议 + +总体来说分为以下几个过程: + +1. DNS解析 +2. TCP连接 +3. 发送HTTP请求 +4. 服务器处理请求并返回HTTP报文 +5. 浏览器解析渲染页面 +6. 连接结束 + +具体可以参考下面这篇文章: + +- [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700) + +## 六 状态码 + +![状态码](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/状态码.png) + + +## 七 各种协议与HTTP协议之间的关系 +一般面试官会通过这样的问题来考察你对计算机网络知识体系的理解。 + +图片来源:《图解HTTP》 + +![各种协议与HTTP协议之间的关系](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/各种协议与HTTP协议之间的关系.png) + +## 八 HTTP长连接,短连接 + +在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。 + +而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码: + +``` +Connection:keep-alive +``` + +在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 + +**HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。** + +—— [《HTTP长连接、短连接究竟是什么?》](https://www.cnblogs.com/gotodsp/p/6366163.html) + +## 九 HTTP是不保存状态的协议,如何保存用户状态? + +HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。 + +在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。 + +**Cookie 被禁用怎么办?** + +最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。 + +![HTTP是无状态协议](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HTTP是无状态的.png) + +## 十 Cookie的作用是什么?和Session有什么区别? + +Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 + + **Cookie 一般用来保存用户信息** 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 + +Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 + +Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 + +## 十一 HTTP 1.0和HTTP 1.1的主要区别是什么? + +> 这部分回答引用这篇文章 的一些内容。 + +HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在: + +1. **长连接** : **在HTTP/1.0中,默认使用的是短连接**,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。**HTTP 1.1起,默认使用长连接** ,默认开启Connection: keep-alive。 **HTTP/1.1的持续连接有非流水线方式和流水线方式** 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 +1. **错误状态响应码** :在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 +1. **缓存处理** :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。 +1. **带宽优化及网络连接的使用** :HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。 + +## 十二 URI和URL的区别是什么? + +- URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。 +- URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。 + +URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。 + +## 十三 HTTP 和 HTTPS 的区别? + +1. **端口** :HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。 +2. **安全性和资源消耗:** HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。 + - 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等; + - 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。 + +## 建议 + +非常推荐大家看一下 《图解HTTP》 这本书,这本书页数不多,但是内容很是充实,不管是用来系统的掌握网络方面的一些知识还是说纯粹为了应付面试都有很大帮助。下面的一些文章只是参考。大二学习这门课程的时候,我们使用的教材是 《计算机网络第七版》(谢希仁编著),不推荐大家看这本教材,书非常厚而且知识偏理论,不确定大家能不能心平气和的读完。 + +## 参考 + +- [https://blog.csdn.net/qq_16209077/article/details/52718250](https://blog.csdn.net/qq_16209077/article/details/52718250) +- [https://blog.csdn.net/zixiaomuwu/article/details/60965466](https://blog.csdn.net/zixiaomuwu/article/details/60965466) +- [https://blog.csdn.net/turn__back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641) +- From 4b404d812ba390ecf89c62e0cf668835db0ea97e Mon Sep 17 00:00:00 2001 From: karezachen Date: Tue, 8 Jun 2021 11:01:55 +0800 Subject: [PATCH 044/257] =?UTF-8?q?=E6=B8=85=E9=99=A4=E6=97=A0=E6=95=88?= =?UTF-8?q?=E9=93=BE=E6=8E=A5=E3=80=81=E6=9B=B4=E6=96=B0=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E6=8F=8F=E8=BF=B0=E3=80=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AD=A6=E4=B9=A0=E6=9D=90=E6=96=99=E5=B0=8F=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...调用为啥不直接用HTTP而用RPC.md | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md b/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md index 73953f0a..532e2cde 100644 --- a/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md +++ b/docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md @@ -6,23 +6,17 @@ RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络 ### **RPC原理是什么?** -我这里这是简单的提一下,详细内容可以查看下面这篇文章: - -http://www.importnew.com/22003.html - ![RPC原理图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/37345851.jpg) -1. 服务消费方(client)调用以本地调用方式调用服务; -2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体; -3. client stub找到服务地址,并将消息发送到服务端; -4. server stub收到消息后进行解码; -5. server stub根据解码结果调用本地的服务; -6. 本地服务执行并将结果返回给server stub; -7. server stub将返回结果打包成消息并发送至消费方; -8. client stub接收到消息,并进行解码; -9. 服务消费方得到最终结果。 +1. 服务消费端(client)以本地调用的方式调用远程服务; +2. 客户端 Stub(client stub) 接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体(序列化):`RpcRequest`; +3. 客户端 Stub(client stub) 找到远程服务的地址,并将消息发送到服务提供端; +4. 服务端 Stub(桩)收到消息将消息反序列化为Java对象: `RpcRequest`; +5. 服务端 Stub(桩)根据`RpcRequest`中的类、方法、方法参数等信息调用本地的方法; +6. 服务端 Stub(桩)得到方法执行结果并将组装成能够进行网络传输的消息体:`RpcResponse`(序列化)发送至消费方; +7. 客户端 Stub(client stub)接收到消息并将消息反序列化为Java对象:`RpcResponse` ,这样也就得到了最终结果。 -下面再贴一个网上的时序图: +下面再贴一个网上的时序图,辅助理解: ![RPC原理时序图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-6/32527396.jpg) @@ -35,10 +29,13 @@ http://www.importnew.com/22003.html - **RMI(JDK自带):** JDK自带的RPC,有很多局限性,不推荐使用。 - **Dubbo:** Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。目前 Dubbo 已经成为 Spring Cloud Alibaba 中的官方组件。 - **gRPC** :gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。 - - **Hessian:** Hessian是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。 - **Thrift:** Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于thrift研发一套分布式服务框架,增加诸如服务注册、服务发现等功能。 +### RPC学习材料 + +- [跟着 Guide 哥造轮子](https://github.com/Snailclimb/guide-rpc-framework) + ## 既有 HTTP ,为啥用 RPC 进行服务调用? ### RPC 只是一种设计而已 From e4d3671e2cc51908bc5a47ed01c583d3bedc15bf Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 8 Jun 2021 13:01:26 +0800 Subject: [PATCH 045/257] =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E6=8C=87=E5=8D=97~?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ docs/贡献指南.md | 0 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 docs/贡献指南.md diff --git a/README.md b/README.md index eaf962f3..cc022988 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,12 @@ 👉 书单已经被移动到[awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 -> 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。 -> 3. **图解计算机基础** :[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 -> 4. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。 -> 5. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java面试进阶指北 》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7) (质量很高,专为面试打造) -> 6. **转载须知** :以下所有文章如非文首说明皆为我(Guide哥)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️ +> 2. **贡献指南** :欢迎参与 [JavaGuide的维护工作](https://github.com/Snailclimb/JavaGuide/issues/1235),这是一件非常有意义的事情。 +> 3. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。 +> 4. **图解计算机基础** :[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 +> 5. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。 +> 6. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java面试进阶指北 》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7) (质量很高,专为面试打造) +> 7. **转载须知** :以下所有文章如非文首说明皆为我(Guide哥)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️

@@ -393,4 +394,3 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: **《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V4.0 PDF 版本[公众号](#公众号)后台回复 **"面试突击"** 即可领取! ![我的公众号](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-08/167598cd2e17b8ec.png) - diff --git a/docs/贡献指南.md b/docs/贡献指南.md deleted file mode 100644 index e69de29b..00000000 From f25cdaddfa114cf23c9cab501b717a973cb95490 Mon Sep 17 00:00:00 2001 From: HuYe Date: Tue, 8 Jun 2021 17:29:29 +0800 Subject: [PATCH 046/257] Update java8-common-new-features.md fix typo --- docs/java/new-features/java8-common-new-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index d736ffba..540ccf02 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -510,7 +510,7 @@ ForkJoinPool.commonPool-worker-9>>2 > > 正例:使用 JDK8 的 Optional 类来防止 NPE 问题。 -他建议使用 `Optional` 解决 NPE(`java.lang.NumberFormatException`)问题,它就是为 NPE 而生的,其中可以包含空值或非空值。下面我们通过源码逐步揭开 `Optional` 的红盖头。 +他建议使用 `Optional` 解决 NPE(`java.lang.NullPointerException`)问题,它就是为 NPE 而生的,其中可以包含空值或非空值。下面我们通过源码逐步揭开 `Optional` 的红盖头。 假设有一个 `Zoo` 类,里面有个属性 `Dog`,需求要获取 `Dog` 的 `age`。 From 9e6bfac997d201a7a935ca9db037d20f863e8a17 Mon Sep 17 00:00:00 2001 From: HuYe Date: Tue, 8 Jun 2021 21:39:04 +0800 Subject: [PATCH 047/257] fix typo --- docs/java/new-features/java8-common-new-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index 540ccf02..69a9b7f7 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -537,7 +537,7 @@ if(zoo != null){ } ``` -层层判断对象分空,有人说这种方式很丑陋不优雅,我并不这么认为。反而觉得很整洁,易读,易懂。你们觉得呢? +层层判断对象非空,有人说这种方式很丑陋不优雅,我并不这么认为。反而觉得很整洁,易读,易懂。你们觉得呢? `Optional` 是这样的实现的: From 9de9b145fb33049f0ed0641e8fdca3ef82e375f4 Mon Sep 17 00:00:00 2001 From: HuYe Date: Wed, 9 Jun 2021 10:39:00 +0800 Subject: [PATCH 048/257] =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-structure/线性数据结构.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dataStructures-algorithms/data-structure/线性数据结构.md b/docs/dataStructures-algorithms/data-structure/线性数据结构.md index c592a9ea..f00264aa 100644 --- a/docs/dataStructures-algorithms/data-structure/线性数据结构.md +++ b/docs/dataStructures-algorithms/data-structure/线性数据结构.md @@ -78,9 +78,9 @@ ### 2.4. 数组 vs 链表 -- 数据支持随机访问,而链表不支持。 +- 数组支持随机访问,而链表不支持。 - 数组使用的是连续内存空间对 CPU 的缓存机制友好,链表则相反。 -- 数据的大小固定,而链表则天然支持动态扩容。如果声明的数组过小,需要另外申请一个更大的内存空间存放数组元素,然后将原数组拷贝进去,这个操作是比较耗时的! +- 数组的大小固定,而链表则天然支持动态扩容。如果声明的数组过小,需要另外申请一个更大的内存空间存放数组元素,然后将原数组拷贝进去,这个操作是比较耗时的! ## 3. 栈 From d1a5762574d46a240b812445fcea33f1aa81f983 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 9 Jun 2021 10:50:12 +0800 Subject: [PATCH 049/257] Update README.md --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cc022988..0cf26022 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://www.zhihu.com/question/56110328/answer/869069586) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线! +👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://zhuanlan.zhihu.com/p/379041500) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线!另外,我整理了一份各个技术的学习路线,需要的小伙伴[加我微信](#联系我)备注“**Github-学习路线**”即可! 👉 推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来) -👉 书单已经被移动到[awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 +👉 书单已经被移动到 [awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。 > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 > 2. **贡献指南** :欢迎参与 [JavaGuide的维护工作](https://github.com/Snailclimb/JavaGuide/issues/1235),这是一件非常有意义的事情。 @@ -385,7 +385,11 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ### 联系我 - +![各种技术的学习路线](https://img-blog.csdnimg.cn/20210609102613344.png) + +整理了一份各个技术的学习路线,需要的小伙伴加我微信备注“**Github-学习路线**”即可! + +![](https://img-blog.csdnimg.cn/20210609084555810.jpg) ### 公众号 From ee15fc31afd1fae55d5886dbd29c25e3863ae9c0 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 9 Jun 2021 11:13:55 +0800 Subject: [PATCH 050/257] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf26022..a8609952 100644 --- a/README.md +++ b/README.md @@ -387,7 +387,7 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ![各种技术的学习路线](https://img-blog.csdnimg.cn/20210609102613344.png) -整理了一份各个技术的学习路线,需要的小伙伴加我微信备注“**Github-学习路线**”即可! +整理了一份各个技术的学习路线,需要的小伙伴加我微信:“**JavaGuide1996**”备注“**Github-学习路线**”即可! ![](https://img-blog.csdnimg.cn/20210609084555810.jpg) From 4f0a9123706e7e72e1e519b010c746913590ad0a Mon Sep 17 00:00:00 2001 From: HuYe Date: Wed, 9 Jun 2021 11:30:12 +0800 Subject: [PATCH 051/257] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20Linux=20=E4=B9=8B?= =?UTF-8?q?=E7=88=B6=E5=A7=93=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/operating-system/linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operating-system/linux.md b/docs/operating-system/linux.md index 7f318ccc..8b0b98ec 100644 --- a/docs/operating-system/linux.md +++ b/docs/operating-system/linux.md @@ -163,7 +163,7 @@ _玩玩电脑游戏还是必须要有 Windows 的,所以我现在是一台 Win - **类 Unix 系统** : Linux 是一种自由、开放源码的类似 Unix 的操作系统 - **Linux 本质是指 Linux 内核** : 严格来讲,Linux 这个词本身只表示 Linux 内核,单独的 Linux 内核并不能成为一个可以正常工作的操作系统。所以,就有了各种 Linux 发行版。 -- **Linux 之父** : 一个编程领域的传奇式人物,真大佬!我辈崇拜敬仰之楷模。他是 **Linux 内核** 的最早作者,随后发起了这个开源项目,担任 Linux 内核的首要架构师。他还发起了 Git 这个开源项目,并为主要的开发者。 +- **Linux 之父(林纳斯·本纳第克特·托瓦兹 Linus Benedict Torvalds)** : 一个编程领域的传奇式人物,真大佬!我辈崇拜敬仰之楷模。他是 **Linux 内核** 的最早作者,随后发起了这个开源项目,担任 Linux 内核的首要架构师。他还发起了 Git 这个开源项目,并为主要的开发者。 ![Linux](images/Linux之父.png) From 095daa72310d46e16865614b3fa8ba79e620c83f Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 15:30:33 +0800 Subject: [PATCH 052/257] fix typo --- docs/operating-system/linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operating-system/linux.md b/docs/operating-system/linux.md index 8b0b98ec..80b52fba 100644 --- a/docs/operating-system/linux.md +++ b/docs/operating-system/linux.md @@ -303,7 +303,7 @@ Linux 中的打包文件一般是以.tar 结尾的,压缩的命令一般是以 **2)解压压缩包:** -命令:`tar [-xvf] 压缩文件`` +命令:`tar [-xvf] 压缩文件` 其中:x:代表解压 From f53f4efde11cd5511eb29bf3659a4c9a0215c322 Mon Sep 17 00:00:00 2001 From: wulnm Date: Wed, 9 Jun 2021 15:56:46 +0800 Subject: [PATCH 053/257] =?UTF-8?q?=E7=BA=A0=E6=AD=A3=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/Redis/redis-all.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/Redis/redis-all.md b/docs/database/Redis/redis-all.md index 16264dc1..8bfda557 100644 --- a/docs/database/Redis/redis-all.md +++ b/docs/database/Redis/redis-all.md @@ -127,7 +127,7 @@ _简单,来说使用缓存主要是为了提升用户体验以及应对更多 #### 6.1. string 1. **介绍** :string 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种 **简单动态字符串**(simple dynamic string,**SDS**)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串为 O(N)),除此之外,Redis 的 SDS API 是安全的,不会造成缓冲区溢出。 -2. **常用命令:** `set,get,strlen,exists,dect,incr,setex` 等等。 +2. **常用命令:** `set,get,strlen,exists,decr,incr,setex` 等等。 3. **应用场景** :一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等。 下面我们简单看看它的使用! From cc594c976ec14b994d3a9b2e578f5e864c041071 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 15:59:32 +0800 Subject: [PATCH 054/257] fix typo --- docs/operating-system/basis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operating-system/basis.md b/docs/operating-system/basis.md index 9276f040..49048648 100644 --- a/docs/operating-system/basis.md +++ b/docs/operating-system/basis.md @@ -8,7 +8,7 @@ 开始本文的内容之前,我们先聊聊为什么要学习操作系统。 -- **从对个人能力方面提升来说** :操作系统中的很多思想、很多经典的算法,你都可以在我们日常开发使用的各种工具或者框架中找到它们的影子。比如说我们开发的系统使用的缓存(比如 Redis)和操作系统的高速缓存就很像。CPU 中的高速缓存有很多种,不过大部分都是为了解决 CPU 处理速度和内存处理速度不对等的问题。我们还可以把内存可以看作外存的高速缓存,程序运行的时候我们把外存的数据复制到内存,由于内存的处理速度远远高于外存,这样提高了处理速度。同样地,我们使用的 Redis 缓存就是为了解决程序处理速度和访问常规关系型数据库速度不对等的问题。高速缓存一般会按照局部性原理(2-8 原则)根据相应的淘汰算法保证缓存中的数据是经常会被访问的。我们平常使用的 Redis 缓存很多时候也会按照 2-8 原则去做,很多淘汰算法都和操作系统中的类似。既说了 2-8 原则,那就不得不提命中率了,这是所有缓存概念都通用的。简单来说也就是你要访问的数据有多少能直接在缓存中直接找到。命中率高的话,一般表明你的缓存设计比较合理,系统处理速度也相对较快。 +- **从对个人能力方面提升来说** :操作系统中的很多思想、很多经典的算法,你都可以在我们日常开发使用的各种工具或者框架中找到它们的影子。比如说我们开发的系统使用的缓存(比如 Redis)和操作系统的高速缓存就很像。CPU 中的高速缓存有很多种,不过大部分都是为了解决 CPU 处理速度和内存处理速度不对等的问题。我们还可以把内存看作外存的高速缓存,程序运行的时候我们把外存的数据复制到内存,由于内存的处理速度远远高于外存,这样提高了处理速度。同样地,我们使用的 Redis 缓存就是为了解决程序处理速度和访问常规关系型数据库速度不对等的问题。高速缓存一般会按照局部性原理(2-8 原则)根据相应的淘汰算法保证缓存中的数据是经常会被访问的。我们平常使用的 Redis 缓存很多时候也会按照 2-8 原则去做,很多淘汰算法都和操作系统中的类似。既说了 2-8 原则,那就不得不提命中率了,这是所有缓存概念都通用的。简单来说也就是你要访问的数据有多少能直接在缓存中直接找到。命中率高的话,一般表明你的缓存设计比较合理,系统处理速度也相对较快。 - **从面试角度来说** :尤其是校招,对于操作系统方面知识的考察是非常非常多的。 **简单来说,学习操作系统能够提高自己思考的深度以及对技术的理解力,并且,操作系统方面的知识也是面试必备。** From d290240bc147274fd261de8eae632f5b2173b721 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 16:40:49 +0800 Subject: [PATCH 055/257] fix typo --- docs/operating-system/Shell.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/operating-system/Shell.md b/docs/operating-system/Shell.md index 53466d11..cd65827f 100644 --- a/docs/operating-system/Shell.md +++ b/docs/operating-system/Shell.md @@ -51,7 +51,6 @@ 简单来说“Shell编程就是对一堆Linux命令的逻辑化处理”。 - W3Cschool 上的一篇文章是这样介绍 Shell的,如下图所示。 ![什么是 Shell?](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-26/19456505.jpg) @@ -91,7 +90,7 @@ shell中 # 符号表示注释。**shell 的第一行比较特殊,一般都会 **Shell编程中一般分为三种变量:** 1. **我们自己定义的变量(自定义变量):** 仅在当前 Shell 实例中有效,其他 Shell 启动的程序不能访问局部变量。 -2. **Linux已定义的环境变量**(环境变量, 例如:$PATH, $HOME 等..., 这类变量我们可以直接使用),使用 `env` 命令可以查看所有的环境变量,而set命令既可以查看环境变量也可以查看自定义变量。 +2. **Linux已定义的环境变量**(环境变量, 例如:`PATH`, ​`HOME` 等..., 这类变量我们可以直接使用),使用 `env` 命令可以查看所有的环境变量,而set命令既可以查看环境变量也可以查看自定义变量。 3. **Shell变量** :Shell变量是由 Shell 程序设置的特殊变量。Shell 变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了 Shell 的正常运行 **常用的环境变量:** @@ -347,7 +346,6 @@ echo $a; 简单示例: ```shell - #!/bin/bash a="abc"; b="efg"; @@ -530,8 +528,6 @@ echo "输入的两个数字之和为 $?" ### 带参数的函数 - - ```shell #!/bin/bash funWithParam(){ @@ -544,7 +540,6 @@ funWithParam(){ echo "作为一个字符串输出所有参数 $* !" } funWithParam 1 2 3 4 5 6 7 8 9 34 73 - ``` 输出结果: @@ -557,5 +552,4 @@ funWithParam 1 2 3 4 5 6 7 8 9 34 73 第十一个参数为 73 ! 参数总数有 11 个! 作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 ! - ``` From 52fb411bc0d18fcdf2b4cc6c40be60302b6f5cc7 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 17:18:24 +0800 Subject: [PATCH 056/257] fix typo --- docs/network/计算机网络.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 10fc157f..d89e1e9e 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -32,7 +32,7 @@ ### 1.3 网络层 -**在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。** 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 **IP 协议**,因此分组也叫 **IP 数据报** ,简称 **数据报**。 +**在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。** 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 **IP 协议**,因此分组也叫 **IP 数据报** ,简称 **数据报**。 这里要注意:**不要把运输层的“用户数据报 UDP ”和网络层的“ IP 数据报”弄混**。另外,无论是哪一层的数据单元,都可笼统地用“分组”来表示。 @@ -44,6 +44,7 @@ **数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。** 在两个相邻节点之间传送数据时,**数据链路层将网络层交下来的 IP 数据报组装成帧**,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 + 控制信息还使接收端能够检测到所收到的帧中有无差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。 ### 1.5 物理层 From 075488375d39fde69765b3f52548654061ef44e8 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 21:29:02 +0800 Subject: [PATCH 057/257] fix typo --- .../framework/spring/Spring常见问题总结.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/system-design/framework/spring/Spring常见问题总结.md b/docs/system-design/framework/spring/Spring常见问题总结.md index 99b0d981..774d4eb0 100644 --- a/docs/system-design/framework/spring/Spring常见问题总结.md +++ b/docs/system-design/framework/spring/Spring常见问题总结.md @@ -83,11 +83,11 @@ IoC源码阅读 AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,**却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来**,便于**减少系统的重复代码**,**降低模块间的耦合度**,并**有利于未来的可拓展性和可维护性**。 -**Spring AOP就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么Spring AOP会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用**Cglib** ,这时候Spring AOP会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: +**Spring AOP就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么Spring AOP会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用**Cglib**生成一个被代理对象的子类来作为代理,如下图所示: ![SpringAOPProcess](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/SpringAOPProcess.jpg) -当然你也可以使用 AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 +当然你也可以使用 AspectJ,Spring AOP 已经集成了AspectJ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 使用 AOP 之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样大大简化了代码量。我们需要增加新功能时也方便,这样也提高了系统扩展性。日志功能、事务管理等等场景都用到了 AOP 。 @@ -117,7 +117,7 @@ AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无 常见的有 2 种解决办法: -2. 在类中定义一个 `ThreadLocal` 成员变量,将需要的可变成员变量保存在 `ThreadLocal` 中(推荐的一种方式)。 +1. 在类中定义一个 `ThreadLocal` 成员变量,将需要的可变成员变量保存在 `ThreadLocal` 中(推荐的一种方式)。 2. 改变 Bean 的作用域为 “prototype”:每次请求都会创建一个新的 bean 实例,自然不会存在线程安全问题。 From 55af506dbd645ea519b0cf599c50751020d071da Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 9 Jun 2021 22:29:46 +0800 Subject: [PATCH 058/257] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=20spring-boot-starter-web=20?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E4=B8=AD=E4=B8=8D=E5=86=8D=E6=9C=89=20hibern?= =?UTF-8?q?ate-validator=20=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/spring/SpringBoot+Spring常用注解总结.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/system-design/framework/spring/SpringBoot+Spring常用注解总结.md b/docs/system-design/framework/spring/SpringBoot+Spring常用注解总结.md index e60eeef2..1e741e75 100644 --- a/docs/system-design/framework/spring/SpringBoot+Spring常用注解总结.md +++ b/docs/system-design/framework/spring/SpringBoot+Spring常用注解总结.md @@ -409,6 +409,8 @@ class WebSite { SpringBoot 项目的 spring-boot-starter-web 依赖中已经有 hibernate-validator 包,不需要引用相关依赖。如下图所示(通过 idea 插件—Maven Helper 生成): +**注**:更新版本的 spring-boot-starter-web 依赖中不再有 hibernate-validator 包(如2.3.11.RELEASE),需要自己引入 `spring-boot-starter-validation` 依赖。 + ![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2021/03/c7bacd12-1c1a-4e41-aaaf-4cad840fc073.png) 非 SpringBoot 项目需要自行引入相关依赖包,这里不多做讲解,具体可以查看我的这篇文章:《[如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485783&idx=1&sn=a407f3b75efa17c643407daa7fb2acd6&chksm=cea2469cf9d5cf8afbcd0a8a1c9cc4294d6805b8e01bee6f76bb2884c5bc15478e91459def49&token=292197051&lang=zh_CN#rd)》。 From d5888b51e2728deec6cb74e38648fc2fff7f1f7c Mon Sep 17 00:00:00 2001 From: Churchillhua-wangfei <1531258563@qq.com> Date: Thu, 10 Jun 2021 11:18:31 +0800 Subject: [PATCH 059/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Java=E5=AD=97?= =?UTF-8?q?=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/公众号历史文章汇总.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/公众号历史文章汇总.md b/docs/公众号历史文章汇总.md index 5e698dba..5f8f45f1 100644 --- a/docs/公众号历史文章汇总.md +++ b/docs/公众号历史文章汇总.md @@ -11,6 +11,8 @@ - [技术面试复习大纲](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485505&idx=1&sn=f7d916334c078bc3fdc2933f889b5016&chksm=cea2478af9d5ce9cafcfe9a053e49e84296d8b1929f79844bba59c8c3d8b56753f34a2c2f6a9&token=1701499214&lang=zh_CN&scene=21#wechat_redirect) ## Java +java +java ### 必看书籍 From 99d941e72f8280d8e9ed630afa0df391deeb8a1a Mon Sep 17 00:00:00 2001 From: Churchillhua-wangfei <1531258563@qq.com> Date: Thu, 10 Jun 2021 11:27:10 +0800 Subject: [PATCH 060/257] =?UTF-8?q?=E5=A4=8D=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/公众号历史文章汇总.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/公众号历史文章汇总.md b/docs/公众号历史文章汇总.md index 5f8f45f1..5741f714 100644 --- a/docs/公众号历史文章汇总.md +++ b/docs/公众号历史文章汇总.md @@ -11,8 +11,7 @@ - [技术面试复习大纲](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485505&idx=1&sn=f7d916334c078bc3fdc2933f889b5016&chksm=cea2478af9d5ce9cafcfe9a053e49e84296d8b1929f79844bba59c8c3d8b56753f34a2c2f6a9&token=1701499214&lang=zh_CN&scene=21#wechat_redirect) ## Java -java -java + ### 必看书籍 From d99b432235385e0b280fd315bd17ea1c46efd528 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Thu, 10 Jun 2021 21:38:02 +0800 Subject: [PATCH 061/257] fix typo --- .../authority-certification/basis-of-authority-certification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/authority-certification/basis-of-authority-certification.md b/docs/system-design/authority-certification/basis-of-authority-certification.md index 9a8a09f0..e554ef8a 100644 --- a/docs/system-design/authority-certification/basis-of-authority-certification.md +++ b/docs/system-design/authority-certification/basis-of-authority-certification.md @@ -30,7 +30,7 @@ RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这是一种通过角色关联权限,角色同时又关联用户的授权的方式。 -简单地说:一个用户可以拥有若干角色,每一个角色有可以被分配若干权限这样,就构造成“用户-角色-权限” 的授权模型。在这种模型中,用户与角色、角色与权限之间构成了多对多的关系,如下图 +简单地说:一个用户可以拥有若干角色,每一个角色又可以被分配若干权限,这样就构造成“用户-角色-权限” 的授权模型。在这种模型中,用户与角色、角色与权限之间构成了多对多的关系,如下图 ![RBAC](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-9/RBAC.png) From d533a76f4fc6ef7fca2f51be9b97f308ee95e152 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 11 Jun 2021 11:04:08 +0800 Subject: [PATCH 062/257] fix typo --- .../message-queue/message-queue.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/system-design/distributed-system/message-queue/message-queue.md b/docs/system-design/distributed-system/message-queue/message-queue.md index c5f30fbc..1a79514e 100644 --- a/docs/system-design/distributed-system/message-queue/message-queue.md +++ b/docs/system-design/distributed-system/message-queue/message-queue.md @@ -46,7 +46,7 @@ ![解耦](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/消息队列-解耦.png) -生产者(客户端)发送消息到消息队列中去,接受者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合, 这显然也提高了系统的扩展性。 +生产者(客户端)发送消息到消息队列中去,接受者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合,这显然也提高了系统的扩展性。 **消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。** 从上图可以看到**消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合**,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。**对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计**。 @@ -98,19 +98,19 @@ JMS 定义了五种不同的消息正文格式,以及调用的消息类型, ### 4.2 AMQP -AMQP,即 Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 **高级消息队列协议**(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。 +AMQP,即 Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 **高级消息队列协议**(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。 **RabbitMQ 就是基于 AMQP 协议实现的。** ### 4.3 JMS vs AMQP -| 对比方向 | JMS | AMQP | -| :----------- | --------------------------------------: | :----------------------------------------------------------: | -| 定义 | Java API | 协议 | -| 跨语言 | 否 | 是 | -| 跨平台 | 否 | 是 | +| 对比方向 | JMS | AMQP | +| :----------- | :-------------------------------------- | :----------------------------------------------------------- | +| 定义 | Java API | 协议 | +| 跨语言 | 否 | 是 | +| 跨平台 | 否 | 是 | | 支持消息类型 | 提供两种消息模型:①Peer-2-Peer;②Pub/sub | 提供了五种消息模型:①direct exchange;②fanout exchange;③topic change;④headers exchange;⑤system exchange。本质来讲,后四种和 JMS 的 pub/sub 模型没有太大差别,仅是在路由机制上做了更详细的划分; | -| 支持消息类型 | 支持多种消息类型 ,我们在上面提到过 | byte[](二进制) | +| 支持消息类型 | 支持多种消息类型 ,我们在上面提到过 | byte[](二进制) | **总结:** From cd6d4ee78c27dd763755957728f93b7b61276d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BD=90?= <48374300+wulnm@users.noreply.github.com> Date: Fri, 11 Jun 2021 23:53:11 +0800 Subject: [PATCH 063/257] fix format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正表格格式以及去除一个多余字符` --- .../framework/mybatis/mybatis-interview.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/system-design/framework/mybatis/mybatis-interview.md b/docs/system-design/framework/mybatis/mybatis-interview.md index 9b68d75e..e1195390 100644 --- a/docs/system-design/framework/mybatis/mybatis-interview.md +++ b/docs/system-design/framework/mybatis/mybatis-interview.md @@ -197,14 +197,14 @@ public V get(Object key) { 举例:下面 join 查询出来 6 条记录,一、二列是 Teacher 对象列,第三列为 Student 对象列,MyBatis 去重复处理后,结果为 1 个老师 6 个学生,而不是 6 个老师 6 个学生。 - t_id t_name s_id - -| 1 | teacher | 38 | -| 1 | teacher | 39 | -| 1 | teacher | 40 | -| 1 | teacher | 41 | -| 1 | teacher | 42 | -| 1 | teacher | 43 | +| t_id | t_name | s_id | +| ---- | ------- | ---- | +| 1 | teacher | 38 | +| 1 | teacher | 39 | +| 1 | teacher | 40 | +| 1 | teacher | 41 | +| 1 | teacher | 42 | +| 1 | teacher | 43 | #### 10、MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么? @@ -238,7 +238,7 @@ public V get(Object key) { **`SimpleExecutor`:**每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。 -**``ReuseExecutor`:**执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map内,供下一次使用。简言之,就是重复使用 Statement 对象。 +**`ReuseExecutor`:**执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map内,供下一次使用。简言之,就是重复使用 Statement 对象。 **`BatchExecutor`:**执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。 From 96048c4fd067f5b8b034b8fbc0566c4422f7c2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BD=90?= <48374300+wulnm@users.noreply.github.com> Date: Sun, 13 Jun 2021 20:14:14 +0800 Subject: [PATCH 064/257] add string expression explanation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加了一些表达式说明以及对齐注释 --- docs/operating-system/Shell.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/operating-system/Shell.md b/docs/operating-system/Shell.md index 53466d11..c4d4d43a 100644 --- a/docs/operating-system/Shell.md +++ b/docs/operating-system/Shell.md @@ -235,12 +235,16 @@ echo ${str:0:10} #输出:SnailClimb #author:amau var="https://www.runoob.com/linux/linux-shell-variable.html" - -s1=${var%%t*}#h -s2=${var%t*}#https://www.runoob.com/linux/linux-shell-variable.h -s3=${var%%.*}#http://www -s4=${var#*/}#/www.runoob.com/linux/linux-shell-variable.html -s5=${var##*/}#linux-shell-variable.html +# %表示删除从后匹配, 最短结果 +# %%表示删除从后匹配, 最长匹配结果 +# #表示删除从头匹配, 最短结果 +# ##表示删除从头匹配, 最长匹配结果 +# 注: *为通配符, 意为匹配任意数量的任意字符 +s1=${var%%t*} #h +s2=${var%t*} #https://www.runoob.com/linux/linux-shell-variable.h +s3=${var%%.*} #http://www +s4=${var#*/} #/www.runoob.com/linux/linux-shell-variable.html +s5=${var##*/} #linux-shell-variable.html ``` ### Shell 数组 From 6516e2183e3a8e944c9c953075f99637d75a9cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BD=90?= <48374300+wulnm@users.noreply.github.com> Date: Mon, 14 Jun 2021 15:41:55 +0800 Subject: [PATCH 065/257] fix typo --- docs/java/basis/Java基础知识疑难点.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/Java基础知识疑难点.md b/docs/java/basis/Java基础知识疑难点.md index 09fb3269..eb5c17b2 100644 --- a/docs/java/basis/Java基础知识疑难点.md +++ b/docs/java/basis/Java基础知识疑难点.md @@ -376,7 +376,7 @@ s=list.toArray(new String[0]);//没有指定类型的话会报错 如果要进行`remove`操作,可以调用迭代器的 `remove `方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身`remove/add`方法,迭代器都将抛出一个`ConcurrentModificationException`,这就是单线程状态下产生的 **fail-fast 机制**。 -> **fail-fast 机制** :多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。 +> **fail-fast 机制** :多个线程对 fail-fast 集合进行修改的时候,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。 Java8开始,可以使用`Collection#removeIf()`方法删除满足特定条件的元素,如 ``` java From 758a16cb16b151d5bcf7b0f1f3935a3778eaa394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BD=90?= <48374300+wulnm@users.noreply.github.com> Date: Mon, 14 Jun 2021 16:44:48 +0800 Subject: [PATCH 066/257] fix typo --- docs/java/basis/Java常见关键字总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/Java常见关键字总结.md b/docs/java/basis/Java常见关键字总结.md index a37ef4b6..f46c5245 100644 --- a/docs/java/basis/Java常见关键字总结.md +++ b/docs/java/basis/Java常见关键字总结.md @@ -88,7 +88,7 @@ public class Sub extends Super { } ``` -在上面的例子中,Sub 类访问父类成员变量 number 并调用其其父类 Super 的 `showNumber()` 方法。 +在上面的例子中,Sub 类访问父类成员变量 number 并调用其父类 Super 的 `showNumber()` 方法。 **使用 this 和 super 要注意的问题:** From 014823195a30a6e1b7675bf0fa99e7403ce89f30 Mon Sep 17 00:00:00 2001 From: hacryq Date: Mon, 14 Jun 2021 16:51:44 +0800 Subject: [PATCH 067/257] =?UTF-8?q?fix(java=E5=AE=B9=E5=99=A8):=20jdk1.8?= =?UTF-8?q?=EF=BC=8CHashMap=E6=BA=90=E7=A0=81=EF=BC=8CHashMap=E6=89=A9?= =?UTF-8?q?=E5=AE=B9=E6=9D=A1=E4=BB=B6=E6=8F=8F=E8=BF=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原文:链表长度大于阈值(默认为 8),HashMap 数组长度超过 64。但是其实不是大于和超过,等于这个阈值也会扩容 --- .../HashMap(JDK1.8)源码+底层数据结构分析.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md index 977fdf78..303dfa5b 100644 --- a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md +++ b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md @@ -27,8 +27,8 @@ JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体 JDK1.8 之后 HashMap 的组成多了红黑树,在满足下面两个条件之后,会执行链表转红黑树操作,以此来加快搜索速度。 -- 链表长度大于阈值(默认为 8) -- HashMap 数组长度超过 64 +- 链表长度大于或等于阈值(默认为 8) +- HashMap 数组长度大于或等于 64 ## 底层数据结构分析 From 79d7098e0799b1b7fbf92e55d49ce87573f51432 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 14 Jun 2021 22:42:03 +0800 Subject: [PATCH 068/257] =?UTF-8?q?Update=20Java=E5=B8=B8=E8=A7=81?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=AD=97=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java常见关键字总结.md | 100 +++++++++---------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/docs/java/basis/Java常见关键字总结.md b/docs/java/basis/Java常见关键字总结.md index a37ef4b6..e99cb8c8 100644 --- a/docs/java/basis/Java常见关键字总结.md +++ b/docs/java/basis/Java常见关键字总结.md @@ -23,63 +23,63 @@ ## final 关键字 -**final关键字,意思是最终的、不可修改的,最见不得变化 ,用来修饰类、方法和变量,具有以下特点:** +**final 关键字,意思是最终的、不可修改的,最见不得变化 ,用来修饰类、方法和变量,具有以下特点:** -1. **final修饰的类不能被继承,final类中的所有成员方法都会被隐式的指定为final方法;** +1. **final 修饰的类不能被继承,final 类中的所有成员方法都会被隐式的指定为 final 方法;** -2. **final修饰的方法不能被重写;** +2. **final 修饰的方法不能被重写;** -3. **final修饰的变量是常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。** +3. **final 修饰的变量是常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。** -说明:使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的Java版本已经不需要使用final方法进行这些优化了)。类中所有的private方法都隐式地指定为final。 +说明:使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的 Java 实现版本中,会将 final 方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的 Java 版本已经不需要使用 final 方法进行这些优化了)。类中所有的 private 方法都隐式地指定为 final。 ## static 关键字 **static 关键字主要有以下四种使用场景:** -1. **修饰成员变量和成员方法:** 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:`类名.静态变量名` `类名.静态方法名()` +1. **修饰成员变量和成员方法:** 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被 static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:`类名.静态变量名` `类名.静态方法名()` 2. **静态代码块:** 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次. -3. **静态内部类(static修饰类的话只能修饰内部类):** 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非static成员变量和方法。 -4. **静态导包(用来导入类中的静态资源,1.5之后的新特性):** 格式为:`import static` 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。 +3. **静态内部类(static 修饰类的话只能修饰内部类):** 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非 static 成员变量和方法。 +4. **静态导包(用来导入类中的静态资源,1.5 之后的新特性):** 格式为:`import static` 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。 ## this 关键字 -this关键字用于引用类的当前实例。 例如: +this 关键字用于引用类的当前实例。 例如: ```java class Manager { Employees[] employees; - + void manageEmployees() { int totalEmp = this.employees.length; System.out.println("Total employees: " + totalEmp); this.report(); } - + void report() { } } ``` -在上面的示例中,this关键字用于两个地方: +在上面的示例中,this 关键字用于两个地方: -- this.employees.length:访问类Manager的当前实例的变量。 -- this.report():调用类Manager的当前实例的方法。 +- this.employees.length:访问类 Manager 的当前实例的变量。 +- this.report():调用类 Manager 的当前实例的方法。 此关键字是可选的,这意味着如果上面的示例在不使用此关键字的情况下表现相同。 但是,使用此关键字可能会使代码更易读或易懂。 ## super 关键字 -super关键字用于从子类访问父类的变量和方法。 例如: +super 关键字用于从子类访问父类的变量和方法。 例如: ```java public class Super { protected int number; - + protected showNumber() { System.out.println("number = " + number); } } - + public class Sub extends Super { void bar() { super.number = 10; @@ -93,11 +93,11 @@ public class Sub extends Super { **使用 this 和 super 要注意的问题:** - 在构造器中使用 `super()` 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。 -- this、super不能用在static方法中。 +- this、super 不能用在 static 方法中。 **简单解释一下:** -被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象;所以, **this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西**。 +被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象;所以, **this 和 super 是属于对象范畴的东西,而静态方法是属于类范畴的东西**。 ## 参考 @@ -111,15 +111,15 @@ public class Sub extends Super { 1. 修饰成员变量和成员方法 2. 静态代码块 3. 修饰类(只能修饰内部类) -4. 静态导包(用来导入类中的静态资源,1.5之后的新特性) +4. 静态导包(用来导入类中的静态资源,1.5 之后的新特性) ### 修饰成员变量和成员方法(常用) -被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。 +被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被 static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。 -方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。 +方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。 - HotSpot 虚拟机中方法区也常被称为 “永久代”,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。 +HotSpot 虚拟机中方法区也常被称为 “永久代”,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。 调用格式: @@ -170,44 +170,40 @@ public class StaticDemo { } ``` - ### 静态代码块 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块 —> 非静态代码块 —> 构造方法)。 该类不管创建多少对象,静态代码块只执行一次. -静态代码块的格式是 +静态代码块的格式是 ``` -static { -语句体; +static { +语句体; } ``` - -一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 +一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM 加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM 将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/88531075.jpg) 静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问. - ### 静态内部类 静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着: 1. 它的创建是不需要依赖外围类的创建。 -2. 它不能使用任何外围类的非static成员变量和方法。 - +2. 它不能使用任何外围类的非 static 成员变量和方法。 Example(静态内部类实现单例模式) ```java public class Singleton { - + //声明为 private 避免调用默认构造方法创建对象 private Singleton() { } - + // 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问 private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); @@ -219,13 +215,13 @@ public class Singleton { } ``` -当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 `getUniqueInstance() `方法从而触发 `SingletonHolder.INSTANCE` 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。 +当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 `getUniqueInstance()`方法从而触发 `SingletonHolder.INSTANCE` 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。 这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。 ### 静态导包 -格式为:import static +格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法 @@ -234,12 +230,12 @@ public class Singleton { //将Math中的所有静态资源导入,这时候可以直接使用里面的静态方法,而不用通过类名进行调用 //如果只想导入单一某个静态方法,只需要将*换成对应的方法名即可 - + import static java.lang.Math.*;//换成import static java.lang.Math.max;具有一样的效果 - + public class Demo { public static void main(String[] args) { - + int max = max(1,2); System.out.println(max); } @@ -247,8 +243,7 @@ public class Demo { ``` - -## 补充内容 +## 补充内容 ### 静态方法与非静态方法 @@ -259,13 +254,13 @@ Example ```java class Foo { int i; - public Foo(int i) { + public Foo(int i) { this.i = i; } public static String method1() { return "An example string that doesn't depend on i (an instance variable)"; - + } public int method2() { @@ -274,26 +269,28 @@ class Foo { } ``` + 你可以像这样调用静态方法:`Foo.method1()`。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行 -``` java + +```java Foo bar = new Foo(1); bar.method2(); ``` 总结: -- 在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。 -- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 +- 在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。 +- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 ### `static{}`静态代码块与`{}`非静态代码块(构造代码块) -相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。 +相同点: 都是在 JVM 加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些 static 变量进行赋值。 -不同点: 静态代码块在非静态代码块之前执行(静态代码块 -> 非静态代码块 -> 构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。 +不同点: 静态代码块在非静态代码块之前执行(静态代码块 -> 非静态代码块 -> 构造方法)。静态代码块只在第一次 new 执行一次,之后不再执行,而非静态代码块在每 new 一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。 -> **🐛 修正(参见: [issue #677](https://github.com/Snailclimb/JavaGuide/issues/677))** :静态代码块可能在第一次new的时候执行,但不一定只在第一次new的时候执行。比如通过 `Class.forName("ClassDemo")`创建 Class 对象的时候也会执行。 +> **🐛 修正(参见: [issue #677](https://github.com/Snailclimb/JavaGuide/issues/677))** :静态代码块可能在第一次 new 对象的时候执行,但不一定只在第一次 new 的时候执行。比如通过 `Class.forName("ClassDemo")`创建 Class 对象的时候也会执行,即 new 或者 `Class.forName("ClassDemo")` 都会执行静态代码块。 -一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:Arrays类,Character类,String类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的. +一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:`Arrays` 类,`Character` 类,`String` 类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的. Example: @@ -346,8 +343,7 @@ public class Test { 静态代码块!--非静态代码块!--默认构造方法!-- ``` - -非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。 +非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。 ### 参考 From 98c9396565f2d2b406d0889ccfb969ddc2bb77cd Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 14 Jun 2021 22:55:15 +0800 Subject: [PATCH 069/257] =?UTF-8?q?Update=20HashMap(JDK1.8)=E6=BA=90?= =?UTF-8?q?=E7=A0=81+=E5=BA=95=E5=B1=82=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=88=86=E6=9E=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HashMap(JDK1.8)源码+底层数据结构分析.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md index 303dfa5b..3b60d6aa 100644 --- a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md +++ b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md @@ -1,4 +1,3 @@ - @@ -21,14 +20,13 @@ ## HashMap 简介 -HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一。 +HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。 -JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。 + `HashMap` 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个 -JDK1.8 之后 HashMap 的组成多了红黑树,在满足下面两个条件之后,会执行链表转红黑树操作,以此来加快搜索速度。 +JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。 JDK1.8 以后的 `HashMap` 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。 -- 链表长度大于或等于阈值(默认为 8) -- HashMap 数组长度大于或等于 64 +`HashMap` 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, `HashMap` 总是使用 2 的幂作为哈希表的大小 ## 底层数据结构分析 @@ -574,5 +572,4 @@ public class HashMapDemo { } } - ``` \ No newline at end of file From 7e46563e86354d8794a495da92543a7d4a636c3f Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 15 Jun 2021 10:48:32 +0800 Subject: [PATCH 070/257] fix typo --- docs/tools/Git.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/Git.md b/docs/tools/Git.md index d2ac8f2d..20c857d3 100644 --- a/docs/tools/Git.md +++ b/docs/tools/Git.md @@ -82,7 +82,7 @@ Linux 内核项目组当时使用分布式版本控制系统 BitKeeper 来管理 大部分版本控制系统(CVS、Subversion、Perforce、Bazaar 等等)都是以文件变更列表的方式存储信息,这类系统**将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。** -具体原理如下图所示,理解起来其实很简单,每个我们对提交更新一个文件之后,系统记录都会记录这个文件做了哪些更新,以增量符号Δ(Delta)表示。 +具体原理如下图所示,理解起来其实很简单,每个我们对提交更新一个文件之后,系统都会记录这个文件做了哪些更新,以增量符号Δ(Delta)表示。

From f1119178c6d15903ae15bdd0d030c7af392364cc Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 15 Jun 2021 11:01:52 +0800 Subject: [PATCH 071/257] fix typo --- docs/tools/Git.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/tools/Git.md b/docs/tools/Git.md index 20c857d3..a7376e04 100644 --- a/docs/tools/Git.md +++ b/docs/tools/Git.md @@ -154,7 +154,7 @@ Git 有三种状态,你的文件可能处于其中之一: 主体部分当然也可以有几段,但是一定要注意换行和句子不要太长。因为这样在使用 "git log" 的时候会有缩进比较好看。 提交的标题行描述应该尽量的清晰和尽量的一句话概括。这样就方便相关的 Git 日志查看工具显示和其他人的阅读。 - + ### 推送改动到远程仓库 - 如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:·`git remote add origin ` ,比如我们要让本地的一个仓库和 Github 上创建的一个仓库关联可以这样`git remote add origin https://github.com/Snailclimb/test.git` @@ -164,7 +164,7 @@ Git 有三种状态,你的文件可能处于其中之一: ### 远程仓库的移除与重命名 -- 将 test 重命名位 test1:`git remote rename test test1` +- 将 test 重命名为 test1:`git remote rename test test1` - 移除远程仓库 test1:`git remote rm test1` ### 查看提交历史 @@ -183,31 +183,30 @@ git log --author=bob 有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 `--amend` 选项的提交命令尝试重新提交: -```console +```shell git commit --amend ``` 取消暂存的文件 -```console +```shell git reset filename ``` 撤消对文件的修改: -``` +```shell git checkout -- filename ``` 假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它: -``` +```shell git fetch origin git reset --hard origin/master ``` - ### 分支 分支是用来将特性开发绝缘开来的。在你创建仓库的时候,*master* 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。 @@ -216,13 +215,13 @@ git reset --hard origin/master 创建一个名字叫做 test 的分支 -```console +```shell git branch test ``` 切换当前分支到 test(当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样) -```console +```shell git checkout test ``` @@ -232,39 +231,39 @@ git checkout test 你也可以直接这样创建分支并切换过去(上面两条命令的合写) -```console +```shell git checkout -b feature_x ``` 切换到主分支 -``` +```shell git checkout master ``` 合并分支(可能会有冲突) -```java +```shell git merge test ``` 把新建的分支删掉 -``` +```shell git branch -d feature_x ``` 将分支推送到远端仓库(推送成功后其他人可见): -``` -git push origin +```shell +git push origin ``` ## 推荐 **在线演示学习工具:** -「补充,来自[issue729](https://github.com/Snailclimb/JavaGuide/issues/729)」Learn Git Branching https://oschina.gitee.io/learn-git-branching/ 。该网站可以方便的演示基本的git操作,讲解得明明白白。每一个基本命令的作用和结果。 +「补充,来自[issue729](https://github.com/Snailclimb/JavaGuide/issues/729)」Learn Git Branching https://oschina.gitee.io/learn-git-branching/。该网站可以方便的演示基本的git操作,讲解得明明白白。每一个基本命令的作用和结果。 **推荐阅读:** From 1bf506b23f36811c4c1a4d9b4443347e7b9137a6 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 15 Jun 2021 16:18:03 +0800 Subject: [PATCH 072/257] =?UTF-8?q?=E8=AE=A4=E8=AF=81=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...(JDK1.8)源码+底层数据结构分析.md | 2 +- .../basis-of-authority-certification.md | 57 ++++++++---------- .../Token-Based-Authentication.png | Bin 39122 -> 0 bytes .../authentication.png | Bin 4645 -> 0 bytes .../authorization.png | Bin 5885 -> 0 bytes .../jwt.drawio | 1 + .../basis-of-authority-certification/jwt.png | Bin 0 -> 172561 bytes .../session-cookie-intro.jpeg | Bin 27529 -> 0 bytes .../session-cookie.drawio | 1 + .../session-cookie.png | Bin 0 -> 171104 bytes .../sso.drawio | 1 + .../basis-of-authority-certification/sso.png | Bin 0 -> 52153 bytes 12 files changed, 28 insertions(+), 34 deletions(-) delete mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/Token-Based-Authentication.png delete mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/authentication.png delete mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/authorization.png create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/jwt.drawio create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/jwt.png delete mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie-intro.jpeg create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.drawio create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.png create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/sso.drawio create mode 100644 docs/system-design/authority-certification/images/basis-of-authority-certification/sso.png diff --git a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md index 3b60d6aa..e78ba116 100644 --- a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md +++ b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md @@ -26,7 +26,7 @@ HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现, JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。 JDK1.8 以后的 `HashMap` 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。 -`HashMap` 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, `HashMap` 总是使用 2 的幂作为哈希表的大小 +`HashMap` 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, `HashMap` 总是使用 2 的幂作为哈希表的大小。 ## 底层数据结构分析 diff --git a/docs/system-design/authority-certification/basis-of-authority-certification.md b/docs/system-design/authority-certification/basis-of-authority-certification.md index 9a8a09f0..88faf082 100644 --- a/docs/system-design/authority-certification/basis-of-authority-certification.md +++ b/docs/system-design/authority-certification/basis-of-authority-certification.md @@ -22,7 +22,7 @@ 这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。 -## RBAC 模型介绍一下? +## RBAC 模型了解吗? 系统权限控制最常采用的访问控制模型就是 **RBAC 模型** 。 @@ -129,10 +129,10 @@ public String readAllCookies(HttpServletRequest request) { 关于这种认证方式更详细的过程如下: -![Session Based Authentication flow](./images/basis-of-authority-certification/Session-Based-Authentication-flow.png) +![](./images/basis-of-authority-certification/session-cookie.png) -1. 用户向服务器发送用户名和密码用于登陆系统。 -2. 服务器验证通过后,服务器为用户创建一个 `Session`,并将 `Session` 信息存储 起来。 +1. 用户向服务器发送用户名、密码、验证码用于登陆系统。 +2. 服务器验证通过后,服务器为用户创建一个 `Session`,并将 `Session` 信息存储起来。 3. 服务器向用户返回一个 `SessionID`,写入用户的 `Cookie`。 4. 当用户保持登录状态时,`Cookie` 将与每个后续请求一起被发送出去。 5. 服务器可以将存储在 `Cookie` 上的 `SessionID` 与存储在内存中或者数据库中的 `Session` 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。 @@ -140,11 +140,7 @@ public String readAllCookies(HttpServletRequest request) { 使用 `Session` 的时候需要注意下面几个点: 1. 依赖 `Session` 的关键业务一定要确保客户端开启了 `Cookie`。 -2. 注意 `Session` 的过期时间 - -画了个图简单总结了一下 `Session` 认证涉及的一些东西。 - -![](./images/basis-of-authority-certification/Session-cookie-intro.jpeg) +2. 注意 `Session` 的过期时间。 另外,Spring Session 提供了一种跨多个应用程序或实例管理用户会话信息的机制。如果想详细了解可以查看下面几篇很不错的文章: @@ -188,21 +184,23 @@ Session-Cookie 方案在单体环境是一个非常好的身份认证方案。 `Session` 认证中 `Cookie` 中的 `SessionId` 是由浏览器发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。 -但是,我们使用 `Token` 的话就不会存在这个问题,在我们登录成功获得 `Token` 之后,一般会选择存放在 local storage 中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 `Token`,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 `Token` 的,所以这个请求将是非法的。 +但是,我们使用 `Token` 的话就不会存在这个问题,在我们登录成功获得 `Token` 之后,一般会选择存放在 `localStorage` (浏览器本地存储)中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 `Token`,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 `Token` 的,所以这个请求将是非法的。 -需要注意的是不论是 Cookie 还是 Token 都无法避免 **跨站脚本攻击(Cross Site Scripting)XSS** 。 +![](https://img-blog.csdnimg.cn/20210615161108272.png) + +需要注意的是不论是 `Cookie` 还是 `Token` 都无法避免 **跨站脚本攻击(Cross Site Scripting)XSS** 。 > 跨站脚本攻击(Cross Site Scripting)缩写为 CSS 但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为 XSS。 -XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 cookie。 +XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 `Cookie` 。 推荐阅读:[如何防止 CSRF 攻击?—美团技术团队](https://tech.meituan.com/2018/10/11/fe-security-csrf.html) ## 什么是 Token?什么是 JWT? -我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 Session 信息服务器的可用性、不适合移动端(依赖 Cookie)等等。 +我们在前面的问题中探讨了使用 `Session` 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 `Session` 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 `Session` 信息服务器的可用性、不适合移动端(依赖 `Cookie`)等等。 -有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。 +有没有一种不需要自己存放 `Session` 信息就能实现身份验证的方式呢?使用 `Token` 即可!**JWT** (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 `Session` 数据了,只用在客户端保存服务端返回给客户的 `Token` 就可以了,扩展性得到提升。 **JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。** @@ -212,27 +210,26 @@ XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面 JWT 由 3 部分构成: -1. **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。 +1. **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。 2. **Payload** : 用来存放实际需要传递的数据 -3. **Signature(签名)** :服务器通过`Payload`、`Header`和一个密钥(`secret`)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。 +3. **Signature(签名)** :服务器通过`Payload`、`Header`和一个密钥(`secret`)使用 `Header` 里面指定的签名算法(默认是 HMAC SHA256)生成。 ## 如何基于 Token 进行身份验证? 在基于 Token 进行身份验证的的应用程序中,服务器通过`Payload`、`Header`和一个密钥(`secret`)创建令牌(`Token`)并将 `Token` 发送给客户端,客户端将 `Token` 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization 字段中:`Authorization: Bearer Token`。 -![Token Based Authentication flow](./images/basis-of-authority-certification/Token-Based-Authentication.png) +![jwt](./images/basis-of-authority-certification/jwt.png) 1. 用户向服务器发送用户名和密码用于登陆系统。 2. 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。 -3. 用户以后每次向后端发请求都在 Header 中带上 JWT。 +3. 用户以后每次向后端发请求都在 `Header` 中带上 JWT。 4. 服务端检查 JWT 并从中获取用户相关信息。 -推荐阅读: +## 什么是 SSO? -- [JWT (JSON Web Tokens) Are Better Than Session Cookies](https://dzone.com/articles/jwtjson-web-Tokens-are-better-than-Session-cookies) -- [JSON Web Tokens (JWT) 与 Sessions](https://juejin.im/entry/577b7b56a3413100618c2938) -- [JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_Token-tutorial.html) -- [彻底理解 Cookie,Session,Token](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485603&idx=1&sn=c8d324f44d6102e7b44554733da10bb7&chksm=cea24768f9d5ce7efe7291ddabce02b68db34073c7e7d9a7dc9a7f01c5a80cebe33ac75248df&Token=844918801&lang=zh_CN#rd) +SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东国际、京东生鲜等子系统。 + +![sso](./images/basis-of-authority-certification/sso.png) ## 什么是 OAuth 2.0? @@ -248,19 +245,13 @@ OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了 ![](./images/basis-of-authority-certification/微信支付-fnglfdlgdfj.png) +下图是 [Slack OAuth 2.0 第三方登录](https://api.slack.com/legacy/oauth)的示意图: + +![](https://img-blog.csdnimg.cn/20210615151716340.png) + **推荐阅读:** - [OAuth 2.0 的一个简单解释](http://www.ruanyifeng.com/blog/2019/04/oauth_design.html) - [10 分钟理解什么是 OAuth 2.0 协议](https://deepzz.com/post/what-is-oauth2-protocol.html) - [OAuth 2.0 的四种方式](http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html) - [GitHub OAuth 第三方登录示例教程](http://www.ruanyifeng.com/blog/2019/04/github-oauth.html) - -## 什么是 SSO? - -SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。 - -## 参考 - -- https://medium.com/@sherryhsu/Session-vs-Token-based-authentication-11a6c5ac45e4 -- https://www.varonis.com/blog/what-is-oauth/ -- https://tools.ietf.org/html/rfc6749 diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/Token-Based-Authentication.png b/docs/system-design/authority-certification/images/basis-of-authority-certification/Token-Based-Authentication.png deleted file mode 100644 index ad30fd375f59fa48c0391a9ee2fd2c857237f59a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39122 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 Ujtp+|;Ohlsg0O&B8s3WeH`MiSy#N3J diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/authorization.png b/docs/system-design/authority-certification/images/basis-of-authority-certification/authorization.png deleted file mode 100644 index 9f3afc0fbdf7618835bcfe8ac69cda46056c92e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5885 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 \ No newline at end of file diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/jwt.png b/docs/system-design/authority-certification/images/basis-of-authority-certification/jwt.png new file mode 100644 index 0000000000000000000000000000000000000000..53a6a98f33629f422079b2aa77882da4bcdf51d1 GIT binary patch literal 172561 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 Date: Tue, 15 Jun 2021 17:27:26 +0800 Subject: [PATCH 073/257] Update basis-of-authority-certification.md --- .../authority-certification/basis-of-authority-certification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/authority-certification/basis-of-authority-certification.md b/docs/system-design/authority-certification/basis-of-authority-certification.md index 88faf082..974d67fe 100644 --- a/docs/system-design/authority-certification/basis-of-authority-certification.md +++ b/docs/system-design/authority-certification/basis-of-authority-certification.md @@ -48,7 +48,7 @@ RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这 ## 什么是 Cookie ? Cookie 的作用是什么? -![](./images/basis-of-authority-certification/cookie-SessionId.png) +![](https://img-blog.csdnimg.cn/20210615162505880.png) `Cookie` 和 `Session` 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 From 2cba4f0f55dc84423a0eae58186dee60a470cbba Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 15 Jun 2021 19:27:10 +0800 Subject: [PATCH 074/257] fix typo --- docs/java/jvm/Java内存区域.md | 2 +- docs/tools/Docker.md | 16 ++++++++-------- docs/tools/Docker从入门到实战.md | 8 +++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/java/jvm/Java内存区域.md b/docs/java/jvm/Java内存区域.md index 5881c817..beed7526 100644 --- a/docs/java/jvm/Java内存区域.md +++ b/docs/java/jvm/Java内存区域.md @@ -57,7 +57,7 @@ ## 二 运行时数据区域 -Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK. 1.8 和之前的版本略有不同,下面会介绍到。 +Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK 1.8 和之前的版本略有不同,下面会介绍到。 **JDK 1.8 之前:** diff --git a/docs/tools/Docker.md b/docs/tools/Docker.md index f3ced448..8f40ee75 100644 --- a/docs/tools/Docker.md +++ b/docs/tools/Docker.md @@ -12,11 +12,11 @@ - **容器镜像是轻量的、可执行的独立软件包** ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。 - **容器化软件适用于基于 Linux 和 Windows 的应用,在任何环境中都能够始终如一地运行。** -- **容器赋予了软件独立性** ,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。 +- **容器赋予了软件独立性**,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。 #### 再来看看容器较为通俗的解释 -**如果需要通俗的描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。** +**如果需要通俗地描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。** ![认识容器](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/container.png) @@ -26,7 +26,7 @@ 关于虚拟机与容器的对比在后面会详细介绍到,这里只是通过网上的图片加深大家对于物理机、虚拟机与容器这三者的理解(下面的图片来源与网络)。 -**物理机** +**物理机:** ![物理机](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/物理机图解.png) @@ -38,7 +38,7 @@ ![容器](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/容器图解.png) -通过上面这三张抽象图,我们可以大概可以通过类比概括出: **容器虚拟化的是操作系统而不是硬件,容器之间是共享同一套操作系统资源的。虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统。因此容器的隔离级别会稍低一些。** +通过上面这三张抽象图,我们可以大概通过类比概括出: **容器虚拟化的是操作系统而不是硬件,容器之间是共享同一套操作系统资源的。虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统。因此容器的隔离级别会稍低一些。** --- @@ -90,7 +90,7 @@ ### 3.1 两者对比图 -传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便. +传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。 ![容器 VS 虚拟机](https://user-gold-cdn.xitu.io/2018/6/17/1640cb4abec9e902?w=1086&h=406&f=png&s=70264) @@ -130,9 +130,9 @@ **Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。** 镜像不包含任何动态数据,其内容在构建之后也不会被改变。 -Docker 设计时,就充分利用 **Union FS**的技术,将其设计为 **分层存储的架构** 。 镜像实际是由多层文件系统联合组成。 +Docker 设计时,就充分利用 **Union FS** 的技术,将其设计为**分层存储的架构** 。镜像实际是由多层文件系统联合组成。 -**镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。** 比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。 +**镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。**比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。 分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。 @@ -182,7 +182,7 @@ mariadb MariaDB is a community-developed fork of MyS mysql/mysql-server Optimized MySQL Server Docker images. Create… 650 [OK] ``` -在国内访问**Docker Hub** 可能会比较慢国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像库](https://hub.tenxcloud.com/ "时速云镜像库")、[网易云镜像服务](https://www.163yun.com/product/repo "网易云镜像服务")、[DaoCloud 镜像市场](https://www.daocloud.io/ "DaoCloud 镜像市场")、[阿里云镜像库](https://www.aliyun.com/product/containerservice?utm_content=se_1292836 "阿里云镜像库")等。 +在国内访问**Docker Hub** 可能会比较慢国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像库](https://www.tenxcloud.com/ "时速云镜像库")、[网易云镜像服务](https://www.163yun.com/product/repo "网易云镜像服务")、[DaoCloud 镜像市场](https://www.daocloud.io/ "DaoCloud 镜像市场")、[阿里云镜像库](https://www.aliyun.com/product/containerservice?utm_content=se_1292836 "阿里云镜像库")等。 除了使用公开服务外,用户还可以在 **本地搭建私有 Docker Registry** 。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。 diff --git a/docs/tools/Docker从入门到实战.md b/docs/tools/Docker从入门到实战.md index 7fa33d3b..c083e690 100644 --- a/docs/tools/Docker从入门到实战.md +++ b/docs/tools/Docker从入门到实战.md @@ -4,22 +4,20 @@ 说实话关于 Docker 是什么并太好说,下面我通过四点向你说明 Docker 到底是个什么东西。 -- Docker 是世界领先的软件容器平台,基于 **Go 语言** 进行开发实现。 +- Docker 是世界领先的软件容器平台,基于 **Go 语言** 进行开发实现。 - Docker 能够自动执行重复性任务,例如搭建和配置开发环境,从而解放开发人员。 - 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。 -- Docker可以**对进程进行封装隔离,属于操作系统层面的虚拟化技术。** 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 +- Docker 可以**对进程进行封装隔离,属于操作系统层面的虚拟化技术。** 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 官网地址:https://www.docker.com/ 。 ![什么是Docker](https://user-gold-cdn.xitu.io/2018/6/18/16411c3946dda762?w=971&h=629&f=jpeg&s=56655) - - ### 为什么要用 Docker? Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 -容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 +容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 传统的开发流程中,我们的项目通常需要使用 MySQL、Redis、FastDFS 等等环境,这些环境都是需要我们手动去进行下载并配置的,安装配置流程极其复杂,而且不同系统下的操作也不一样。 From 9b605b4981b2eb8fffa0d9787963ce5344a93ee6 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 15 Jun 2021 22:06:58 +0800 Subject: [PATCH 075/257] fix typo --- docs/java/jvm/Java内存区域.md | 92 +++++++++++++++---------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/docs/java/jvm/Java内存区域.md b/docs/java/jvm/Java内存区域.md index beed7526..00020544 100644 --- a/docs/java/jvm/Java内存区域.md +++ b/docs/java/jvm/Java内存区域.md @@ -96,7 +96,7 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成 **与程序计数器一样,Java 虚拟机栈也是线程私有的,它的生命周期和线程相同,描述的是 Java 方法执行的内存模型,每次方法调用的数据都是通过栈传递的。** -**Java 内存可以粗糙的区分为堆内存(Heap)和栈内存 (Stack),其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。** (实际上,Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。) +**Java 内存可以粗糙的区分为堆内存(Heap)和栈内存 (Stack),其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。** (实际上,Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。) **局部变量表主要存放了编译期可知的各种数据类型**(boolean、byte、char、short、int、float、long、double)、**对象引用**(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。 @@ -111,7 +111,7 @@ Java 虚拟机栈也是线程私有的,每个线程都有各自的 Java 虚拟 **扩展:那么方法/函数如何调用?** -Java 栈可用类比数据结构中栈,Java 栈中保存的主要内容是栈帧,每一次函数调用都会有一个对应的栈帧被压入 Java 栈,每一个函数调用结束后,都会有一个栈帧被弹出。 +Java 栈可以类比数据结构中栈,Java 栈中保存的主要内容是栈帧,每一次函数调用都会有一个对应的栈帧被压入 Java 栈,每一个函数调用结束后,都会有一个栈帧被弹出。 Java 方法有两种返回方式: @@ -132,11 +132,11 @@ Java 方法有两种返回方式: Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。**此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。** -Java 世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT 编译期的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。 +Java 世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT 编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。 -Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(Garbage Collected Heap)**.从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。**进一步划分的目的是更好地回收内存,或者更快地分配内存。** +Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(Garbage Collected Heap)**。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代;再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。**进一步划分的目的是更好地回收内存,或者更快地分配内存。** -在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常被分为下面三部分: +在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常分为下面三部分: 1. 新生代内存(Young Generation) 2. 老生代(Old Generation) @@ -170,7 +170,6 @@ JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 > uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold; > ... > } -> > ``` 堆这里最容易出现的就是 OutOfMemoryError 错误,并且出现这种错误之后的表现形式还会有几种,比如: @@ -247,7 +246,7 @@ JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1 **直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 错误出现。** -JDK1.4 中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通道(Channel)** 与**缓存区(Buffer)** 的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为**避免了在 Java 堆和 Native 堆之间来回复制数据**。 +JDK1.4 中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通道(Channel)**与**缓存区(Buffer)**的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为**避免了在 Java 堆和 Native 堆之间来回复制数据**。 本机直接内存的分配不会受到 Java 堆的限制,但是,既然是内存就会受到本机总内存大小以及处理器寻址空间的限制。 @@ -383,10 +382,10 @@ System.out.println(str4 == str5);//false **验证:** ```java - String s1 = new String("abc");// 堆内存的地址值 - String s2 = "abc"; - System.out.println(s1 == s2);// 输出 false,因为一个是堆内存,一个是常量池的内存,故两者是不同的。 - System.out.println(s1.equals(s2));// 输出 true +String s1 = new String("abc");// 堆内存的地址值 +String s2 = "abc"; +System.out.println(s1 == s2);// 输出 false,因为一个是堆内存,一个是常量池的内存,故两者是不同的。 +System.out.println(s1.equals(s2));// 输出 true ``` **结果:** @@ -421,15 +420,15 @@ private static class CharacterCache { 两种浮点数类型的包装类 Float,Double 并没有实现常量池技术。 ```java - Integer i1 = 33; - Integer i2 = 33; - System.out.println(i1 == i2);// 输出 true - Integer i11 = 333; - Integer i22 = 333; - System.out.println(i11 == i22);// 输出 false - Double i3 = 1.2; - Double i4 = 1.2; - System.out.println(i3 == i4);// 输出 false +Integer i1 = 33; +Integer i2 = 33; +System.out.println(i1 == i2);// 输出 true +Integer i11 = 333; +Integer i22 = 333; +System.out.println(i11 == i22);// 输出 false +Double i3 = 1.2; +Double i4 = 1.2; +System.out.println(i3 == i4);// 输出 false ``` **Integer 缓存源代码:** @@ -438,12 +437,11 @@ private static class CharacterCache { /** *此方法将始终缓存-128 到 127(包括端点)范围内的值,并可以缓存此范围之外的其他值。 */ - public static Integer valueOf(int i) { - if (i >= IntegerCache.low && i <= IntegerCache.high) - return IntegerCache.cache[i + (-IntegerCache.low)]; - return new Integer(i); - } - +public static Integer valueOf(int i) { + if (i >= IntegerCache.low && i <= IntegerCache.high) + return IntegerCache.cache[i + (-IntegerCache.low)]; + return new Integer(i); +} ``` **应用场景:** @@ -452,38 +450,38 @@ private static class CharacterCache { 2. Integer i1 = new Integer(40);这种情况下会创建新的对象。 ```java - Integer i1 = 40; - Integer i2 = new Integer(40); - System.out.println(i1==i2);//输出 false +Integer i1 = 40; +Integer i2 = new Integer(40); +System.out.println(i1==i2);//输出 false ``` **Integer 比较更丰富的一个例子:** ```java - Integer i1 = 40; - Integer i2 = 40; - Integer i3 = 0; - Integer i4 = new Integer(40); - Integer i5 = new Integer(40); - Integer i6 = new Integer(0); +Integer i1 = 40; +Integer i2 = 40; +Integer i3 = 0; +Integer i4 = new Integer(40); +Integer i5 = new Integer(40); +Integer i6 = new Integer(0); - System.out.println("i1=i2 " + (i1 == i2)); - System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); - System.out.println("i1=i4 " + (i1 == i4)); - System.out.println("i4=i5 " + (i4 == i5)); - System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); - System.out.println("40=i5+i6 " + (40 == i5 + i6)); +System.out.println("i1=i2 " + (i1 == i2)); +System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); +System.out.println("i1=i4 " + (i1 == i4)); +System.out.println("i4=i5 " + (i4 == i5)); +System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); +System.out.println("40=i5+i6 " + (40 == i5 + i6)); ``` 结果: ``` -i1=i2 true -i1=i2+i3 true -i1=i4 false -i4=i5 false -i4=i5+i6 true -40=i5+i6 true +i1=i2 true +i1=i2+i3 true +i1=i4 false +i4=i5 false +i4=i5+i6 true +40=i5+i6 true ``` 解释: From 0c61be453df014a1119cdebc4a5f6155d895a7da Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 16 Jun 2021 17:14:31 +0800 Subject: [PATCH 076/257] fix typo --- docs/java/jvm/最重要的JVM参数指南.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/java/jvm/最重要的JVM参数指南.md b/docs/java/jvm/最重要的JVM参数指南.md index 319c9d3a..90987dd7 100644 --- a/docs/java/jvm/最重要的JVM参数指南.md +++ b/docs/java/jvm/最重要的JVM参数指南.md @@ -1,4 +1,4 @@ -> 本文由 JavaGuide 翻译自 https://www.baeldung.com/jvm-parameters,并对文章进行了大量的完善补充。翻译不易,如需转载请注明出处为: 作者: 。 +> 本文由 JavaGuide 翻译自 [https://www.baeldung.com/jvm-parameters](https://www.baeldung.com/jvm-parameters),并对文章进行了大量的完善补充。翻译不易,如需转载请注明出处,作者:[baeldung](https://www.baeldung.com/author/baeldung/) 。 ## 1.概述 @@ -7,7 +7,6 @@ ## 2.堆内存相关 >Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。**此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。** -> ### 2.1.显式指定堆内存`–Xms`和`-Xmx` From 4a255c9aa3d8bba6cf61d379321a9d83f7317ce7 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Wed, 16 Jun 2021 20:16:13 +0800 Subject: [PATCH 077/257] fix typo --- .../剑指offer部分编程题.md | 238 +++++++++--------- 1 file changed, 116 insertions(+), 122 deletions(-) diff --git a/docs/dataStructures-algorithms/剑指offer部分编程题.md b/docs/dataStructures-algorithms/剑指offer部分编程题.md index 84a21a5f..9b73888b 100644 --- a/docs/dataStructures-algorithms/剑指offer部分编程题.md +++ b/docs/dataStructures-algorithms/剑指offer部分编程题.md @@ -14,38 +14,36 @@ n<=39 **采用迭代法:** ```java - int Fibonacci(int number) { - if (number <= 0) { - return 0; - } - if (number == 1 || number == 2) { - return 1; - } - int first = 1, second = 1, third = 0; - for (int i = 3; i <= number; i++) { - third = first + second; - first = second; - second = third; - } - return third; - } +int Fibonacci(int number) { + if (number <= 0) { + return 0; + } + if (number == 1 || number == 2) { + return 1; + } + int first = 1, second = 1, third = 0; + for (int i = 3; i <= number; i++) { + third = first + second; + first = second; + second = third; + } + return third; +} ``` **采用递归:** ```java - public int Fibonacci(int n) { - - if (n <= 0) { - return 0; - } - if (n == 1||n==2) { - return 1; - } +public int Fibonacci(int n) { + if (n <= 0) { + return 0; + } + if (n == 1||n==2) { + return 1; + } - return Fibonacci(n - 2) + Fibonacci(n - 1); - - } + return Fibonacci(n - 2) + Fibonacci(n - 1); +} ``` ### 二 跳台阶问题 @@ -71,24 +69,24 @@ f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5, 可以总结出f(n) = f(n-1) + f(n-2) #### **示例代码:** ```java - int jumpFloor(int number) { - if (number <= 0) { - return 0; - } - if (number == 1) { - return 1; - } - if (number == 2) { - return 2; - } - int first = 1, second = 2, third = 0; - for (int i = 3; i <= number; i++) { - third = first + second; - first = second; - second = third; - } - return third; - } +int jumpFloor(int number) { + if (number <= 0) { + return 0; + } + if (number == 1) { + return 1; + } + if (number == 2) { + return 2; + } + int first = 1, second = 2, third = 0; + for (int i = 3; i <= number; i++) { + third = first + second; + first = second; + second = third; + } + return third; +} ``` ### 三 变态跳台阶问题 @@ -113,9 +111,9 @@ f(n)=f(n-1)+f(n-2)+...+f(1) #### **示例代码:** ```java - int JumpFloorII(int number) { - return 1 << --number;//2^(number-1)用位移操作进行,更快 - } +int JumpFloorII(int number) { + return 1 << --number;//2^(number-1)用位移操作进行,更快 +} ``` #### **补充:** @@ -124,7 +122,7 @@ f(n)=f(n-1)+f(n-2)+...+f(1) 1. “<<” : **左移运算符**,等同于乘2的n次方 2. “>>”: **右移运算符**,等同于除2的n次方 -3. “>>>” **无符号右移运算符**,不管移动前最高位是0还是1,右移后左侧产生的空位部分都以0来填充。与>>类似。 +3. “>>>” : **无符号右移运算符**,不管移动前最高位是0还是1,右移后左侧产生的空位部分都以0来填充。与>>类似。 例: int a = 16; int b = a << 2;//左移2,等同于16 * 2的2次方,也就是16 * 4 @@ -147,22 +145,22 @@ f(n)=f(n-1)+f(n-2)+...+f(1) #### **示例代码:** ```java - public boolean Find(int target, int [][] array) { - //基本思路从左下角开始找,这样速度最快 - int row = array.length-1;//行 - int column = 0;//列 - //当行数大于0,当前列数小于总列数时循环条件成立 - while((row >= 0)&& (column< array[0].length)){ - if(array[row][column] > target){ - row--; - }else if(array[row][column] < target){ - column++; - }else{ - return true; - } +public boolean Find(int target, int [][] array) { + //基本思路从左下角开始找,这样速度最快 + int row = array.length-1;//行 + int column = 0;//列 + //当行数大于0,当前列数小于总列数时循环条件成立 + while((row >= 0)&& (column< array[0].length)){ + if(array[row][column] > target){ + row--; + }else if(array[row][column] < target){ + column++; + }else{ + return true; } - return false; } + return false; +} ``` ### 五 替换空格 @@ -175,38 +173,37 @@ f(n)=f(n-1)+f(n-2)+...+f(1) 这道题不难,我们可以通过循环判断字符串的字符是否为空格,是的话就利用append()方法添加追加“%20”,否则还是追加原字符。 -或者最简单的方法就是利用: replaceAll(String regex,String replacement)方法了,一行代码就可以解决。 +或者最简单的方法就是利用:replaceAll(String regex,String replacement)方法了,一行代码就可以解决。 #### **示例代码:** **常规做法:** ```java - public String replaceSpace(StringBuffer str) { - StringBuffer out=new StringBuffer(); - for (int i = 0; i < str.toString().length(); i++) { - char b=str.charAt(i); - if(String.valueOf(b).equals(" ")){ - out.append("%20"); - }else{ - out.append(b); - } +public String replaceSpace(StringBuffer str) { + StringBuffer out = new StringBuffer(); + for (int i = 0; i < str.toString().length(); i++) { + char b = str.charAt(i); + if(String.valueOf(b).equals(" ")){ + out.append("%20"); + }else{ + out.append(b); } - return out.toString(); } + return out.toString(); +} ``` **一行代码解决:** ```java - public String replaceSpace(StringBuffer str) { - //return str.toString().replaceAll(" ", "%20"); - //public String replaceAll(String regex,String replacement) - //用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串。 - //\ 转义字符. 如果你要使用 "\" 本身, 则应该使用 "\\". String类型中的空格用“\s”表示,所以我这里猜测"\\s"就是代表空格的意思 - return str.toString().replaceAll("\\s", "%20"); - } - +public String replaceSpace(StringBuffer str) { + //return str.toString().replaceAll(" ", "%20"); + //public String replaceAll(String regex,String replacement) + //用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串。 + //\ 转义字符. 如果你要使用 "\" 本身, 则应该使用 "\\". String类型中的空格用“\s”表示,所以我这里猜测"\\s"就是代表空格的意思 + return str.toString().replaceAll("\\s", "%20"); +} ``` ### 六 数值的整数次方 @@ -279,17 +276,17 @@ public class Solution { 当然这一题也可以采用笨方法:累乘。不过这种方法的时间复杂度为O(n),这样没有前一种方法效率高。 ```java - // 使用累乘 - public double powerAnother(double base, int exponent) { - double result = 1.0; - for (int i = 0; i < Math.abs(exponent); i++) { - result *= base; - } - if (exponent >= 0) - return result; - else - return 1 / result; +// 使用累乘 +public double powerAnother(double base, int exponent) { + double result = 1.0; + for (int i = 0; i < Math.abs(exponent); i++) { + result *= base; } + if (exponent >= 0) + return result; + else + return 1 / result; +} ``` ### 七 调整数组顺序使奇数位于偶数前面 @@ -434,22 +431,21 @@ public class ListNode { } }*/ public class Solution { -public ListNode ReverseList(ListNode head) { - ListNode next = null; - ListNode pre = null; - while (head != null) { - //保存要反转到头来的那个节点 - next = head.next; - //要反转的那个节点指向已经反转的上一个节点 - head.next = pre; - //上一个已经反转到头部的节点 - pre = head; - //一直向链表尾走 - head = next; + public ListNode ReverseList(ListNode head) { + ListNode next = null; + ListNode pre = null; + while (head != null) { + //保存要反转到头来的那个节点 + next = head.next; + //要反转的那个节点指向已经反转的上一个节点 + head.next = pre; + //上一个已经反转到头部的节点 + pre = head; + //一直向链表尾走 + head = next; + } + return pre; } - return pre; -} - } ``` @@ -538,20 +534,20 @@ public class Solution { ```java public ListNode Merge(ListNode list1,ListNode list2) { - if(list1 == null){ - return list2; - } - if(list2 == null){ - return list1; - } - if(list1.val <= list2.val){ - list1.next = Merge(list1.next, list2); - return list1; - }else{ - list2.next = Merge(list1, list2.next); - return list2; - } - } + if(list1 == null){ + return list2; + } + if(list2 == null){ + return list1; + } + if(list1.val <= list2.val){ + list1.next = Merge(list1.next, list2); + return list1; + }else{ + list2.next = Merge(list1, list2.next); + return list2; + } +} ``` ### 十一 用两个栈实现队列 @@ -642,8 +638,6 @@ https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106 …. 依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。 - - #### **考察内容:** 栈 From 32fe5941ea91afed5cebd96dcffc075ee6ce551e Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 16 Jun 2021 22:13:33 +0800 Subject: [PATCH 078/257] =?UTF-8?q?Update=20Github=E6=8A=80=E5=B7=A7.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tools/Github技巧.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tools/Github技巧.md b/docs/tools/Github技巧.md index 5a334ae3..512bf7af 100644 --- a/docs/tools/Github技巧.md +++ b/docs/tools/Github技巧.md @@ -18,17 +18,17 @@ Github 目前支持在个人主页自定义展示一些内容。展示效果如下图所示。 -![个性化首页展示效果](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2020-11/1.png) +![个性化首页展示效果](/Users/guide/Library/Application Support/typora-user-images/image-20210616221212259.png) 想要做到这样非常简单,你只需要创建一个和你的 Github 账户同名的仓库,然后自定义`README.md`的内容即可。 展示在你主页的自定义内容就是`README.md`的内容(_不会 Markdown 语法的小伙伴自行面壁 5 分钟_)。 -![创建一个和你的Github账户同名的仓库](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2020-11/image-20201107110309341.png) +![创建一个和你的Github账户同名的仓库](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20201107110309341.png) 这个也是可以玩出花来的!比如说:通过 [github-readme-stats](https://hellogithub.com/periodical/statistics/click/?target=https://github.com/anuraghazra/github-readme-stats) 这个开源项目,你可以 README 中展示动态生成的 GitHub 统计信息。展示效果如下图所示。 -![通过github-readme-stats动态生成GitHub统计信息 ](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/2020-11/2.png) +![通过github-readme-stats动态生成GitHub统计信息 ](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210616221312426.png) 关于个性化首页这个就不多提了,感兴趣的小伙伴自行研究一下。 From 56e33d7242070fa37ff6034831d71255a8bd8902 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Thu, 17 Jun 2021 16:05:39 +0800 Subject: [PATCH 079/257] fix typo --- docs/database/MySQL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index afac2396..36bd8f6c 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -4,7 +4,7 @@ 顾名思义,关系型数据库就是一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系(一对一、一对多、多对多)。 -关系型数据库中,我们的数据都被存放在了各种表中(比如用户表),表中的每一列就存放着一条数据(比如一个用户的信息)。 +关系型数据库中,我们的数据都被存放在了各种表中(比如用户表),表中的每一行就存放着一条数据(比如一个用户的信息)。 ![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/5e3c1a71724a38245aa43b02_99bf70d46cc247be878de9d3a88f0c44.png) @@ -34,7 +34,7 @@ mysql> show engines; ![查看MySQL提供的所有存储引擎](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/mysql-engines.png) -从上图我们可以查看出 MySQL 当前默认的存储引擎是 InnoDB,并且在 5.7 版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。 +从上图我们可以查看出 MySQL 当前默认的存储引擎是 InnoDB,并且在 5.7 版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。 **查看 MySQL 当前默认的存储引擎** From 3b44d9e093a0a18f77adcdfa87b5c5d397d1aab0 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Thu, 17 Jun 2021 16:05:39 +0800 Subject: [PATCH 080/257] fix typo --- docs/database/MySQL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index afac2396..5edb178d 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -4,7 +4,7 @@ 顾名思义,关系型数据库就是一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系(一对一、一对多、多对多)。 -关系型数据库中,我们的数据都被存放在了各种表中(比如用户表),表中的每一列就存放着一条数据(比如一个用户的信息)。 +关系型数据库中,我们的数据都被存放在了各种表中(比如用户表),表中的每一行就存放着一条数据(比如一个用户的信息)。 ![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/5e3c1a71724a38245aa43b02_99bf70d46cc247be878de9d3a88f0c44.png) @@ -34,7 +34,7 @@ mysql> show engines; ![查看MySQL提供的所有存储引擎](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/mysql-engines.png) -从上图我们可以查看出 MySQL 当前默认的存储引擎是 InnoDB,并且在 5.7 版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。 +从上图我们可以查看出 MySQL 当前默认的存储引擎是 InnoDB,并且在 5.7 版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。 **查看 MySQL 当前默认的存储引擎** @@ -227,7 +227,7 @@ MySQL InnoDB 引擎通过 **锁机制**、**MVCC** 等手段来保证事务的 - **脏读(Dirty read):** 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。 - **丢失修改(Lost to modify):** 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 修改 A=A-1,事务 2 也修改 A=A-1,最终结果 A=19,事务 1 的修改被丢失。 -- **不可重复读(Unrepeatableread):** 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。 +- **不可重复读(Unrepeatable read):** 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。 - **幻读(Phantom read):** 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。 **不可重复读和幻读区别:** @@ -269,7 +269,7 @@ mysql> SELECT @@tx_isolation; 🐛 问题更正:**MySQL InnoDB 的 REPEATABLE-READ(可重读)并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是 Next-Key Locks。** -因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 **READ-COMMITTED(读取提交内容)** ,但是你要知道的是 InnoDB 存储引擎默认使用 **REPEAaTABLE-READ(可重读)** 并不会有任何性能损失。 +因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 **READ-COMMITTED(读取提交内容)** ,但是你要知道的是 InnoDB 存储引擎默认使用 **REPEATABLE-READ(可重读)** 并不会有任何性能损失。 InnoDB 存储引擎在 **分布式事务** 的情况下一般会用到 **SERIALIZABLE(可串行化)** 隔离级别。 From b26f3777cda526b48cc2337b9ec5538fe31e986b Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 18 Jun 2021 11:16:47 +0800 Subject: [PATCH 081/257] fix typo --- docs/database/MySQL Index.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/database/MySQL Index.md b/docs/database/MySQL Index.md index ea683c15..32d88388 100644 --- a/docs/database/MySQL Index.md +++ b/docs/database/MySQL Index.md @@ -28,11 +28,9 @@ select username , age from user where username = 'Java' and age = 22 ## 选择索引和编写利用这些索引的查询的3个原则 -1. 单行访问是很慢的。特别是在机械硬盘存储中(SSD的随机I/O要快很多,不过这一点仍然成立)。如果服务器从存储中读取一个数据块只是为了获取其中一行,那么就浪费了很多工作。最好读取的块中能包含尽可能多所需要的行。使用索引可以创建位置引,用以提升效率。 +1. 单行访问是很慢的。特别是在机械硬盘存储中(SSD的随机I/O要快很多,不过这一点仍然成立)。如果服务器从存储中读取一个数据块只是为了获取其中一行,那么就浪费了很多工作。最好读取的块中能包含尽可能多所需要的行。使用索引可以创建位置引,用以提升效率。 2. 按顺序访问范围数据是很快的,这有两个原因。第一,顺序 I/O 不需要多次磁盘寻道,所以比随机I/O要快很多(特别是对机械硬盘)。第二,如果服务器能够按需要顺序读取数据,那么就不再需要额外的排序操作,并且GROUPBY查询也无须再做排序和将行按组进行聚合计算了。 -3. 索引覆盖查询是很快的。如果一个索引包含了查询需要的所有列,那么存储引擎就 - 不需要再回表查找行。这避免了大量的单行访问,而上面的第1点已经写明单行访 - 问是很慢的。 +3. 索引覆盖查询是很快的。如果一个索引包含了查询需要的所有列,那么存储引擎就不需要再回表查找行。这避免了大量的单行访问,而上面的第1点已经写明单行访问是很慢的。 ## 为什么索引能提高查询速度 @@ -58,7 +56,7 @@ MySQL的基本存储结构是页(记录都存在页里边): 1. **定位到记录所在的页:需要遍历双向链表,找到所在的页** 2. **从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了** -很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。 +很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。 ### 使用索引之后 @@ -95,7 +93,7 @@ select * from user where city=xx ; // 无法命中索引 ### 注意避免冗余索引 -冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city )和(name )这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。 +冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city)和(name)这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者。在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。 -MySQL 5.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引 +MySQL 5.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引。 From 8b3f852fe17a9324b30bcd0a57e33b8ea858725b Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 18 Jun 2021 11:16:47 +0800 Subject: [PATCH 082/257] fix typo --- docs/database/MySQL Index.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/database/MySQL Index.md b/docs/database/MySQL Index.md index ea683c15..32d88388 100644 --- a/docs/database/MySQL Index.md +++ b/docs/database/MySQL Index.md @@ -28,11 +28,9 @@ select username , age from user where username = 'Java' and age = 22 ## 选择索引和编写利用这些索引的查询的3个原则 -1. 单行访问是很慢的。特别是在机械硬盘存储中(SSD的随机I/O要快很多,不过这一点仍然成立)。如果服务器从存储中读取一个数据块只是为了获取其中一行,那么就浪费了很多工作。最好读取的块中能包含尽可能多所需要的行。使用索引可以创建位置引,用以提升效率。 +1. 单行访问是很慢的。特别是在机械硬盘存储中(SSD的随机I/O要快很多,不过这一点仍然成立)。如果服务器从存储中读取一个数据块只是为了获取其中一行,那么就浪费了很多工作。最好读取的块中能包含尽可能多所需要的行。使用索引可以创建位置引,用以提升效率。 2. 按顺序访问范围数据是很快的,这有两个原因。第一,顺序 I/O 不需要多次磁盘寻道,所以比随机I/O要快很多(特别是对机械硬盘)。第二,如果服务器能够按需要顺序读取数据,那么就不再需要额外的排序操作,并且GROUPBY查询也无须再做排序和将行按组进行聚合计算了。 -3. 索引覆盖查询是很快的。如果一个索引包含了查询需要的所有列,那么存储引擎就 - 不需要再回表查找行。这避免了大量的单行访问,而上面的第1点已经写明单行访 - 问是很慢的。 +3. 索引覆盖查询是很快的。如果一个索引包含了查询需要的所有列,那么存储引擎就不需要再回表查找行。这避免了大量的单行访问,而上面的第1点已经写明单行访问是很慢的。 ## 为什么索引能提高查询速度 @@ -58,7 +56,7 @@ MySQL的基本存储结构是页(记录都存在页里边): 1. **定位到记录所在的页:需要遍历双向链表,找到所在的页** 2. **从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了** -很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。 +很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。 ### 使用索引之后 @@ -95,7 +93,7 @@ select * from user where city=xx ; // 无法命中索引 ### 注意避免冗余索引 -冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city )和(name )这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。 +冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。如(name,city)和(name)这两个索引就是冗余索引,能够命中前者的查询肯定是能够命中后者。在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。 -MySQL 5.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引 +MySQL 5.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引。 From c0bdcfaee8120d992640b8153c7c8ee578fa6ea3 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 18 Jun 2021 16:48:47 +0800 Subject: [PATCH 083/257] fix typo --- docs/database/MySQL数据库索引.md | 2 +- docs/database/MySQL高性能优化规范建议.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/database/MySQL数据库索引.md b/docs/database/MySQL数据库索引.md index 31ed9a66..d797144e 100644 --- a/docs/database/MySQL数据库索引.md +++ b/docs/database/MySQL数据库索引.md @@ -8,7 +8,7 @@ **优点** : -- 使用索引可以大大加快 数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因。 +- 使用索引可以大大加快 数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因。 - 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 **缺点** : diff --git a/docs/database/MySQL高性能优化规范建议.md b/docs/database/MySQL高性能优化规范建议.md index 1e380508..240a1dd9 100644 --- a/docs/database/MySQL高性能优化规范建议.md +++ b/docs/database/MySQL高性能优化规范建议.md @@ -266,7 +266,7 @@ Innodb 是按照主键索引的顺序来组织表的 ### 7. 对于频繁的查询优先考虑使用覆盖索引 -> 覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引 +> 覆盖索引:就是包含了所有查询字段 (where,select,order by,group by 包含的字段) 的索引 **覆盖索引的好处:** From eae908533efb54046c493ab0b42f635163fc01ab Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 18 Jun 2021 17:18:13 +0800 Subject: [PATCH 084/257] fix typo --- .../关于数据库存储时间的一点思考.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/database/关于数据库存储时间的一点思考.md b/docs/database/关于数据库存储时间的一点思考.md index ab4e62c6..8eccaff2 100644 --- a/docs/database/关于数据库存储时间的一点思考.md +++ b/docs/database/关于数据库存储时间的一点思考.md @@ -1,4 +1,4 @@ -我们平时开发中不可避免的就是要存储时间,比如我们要记录操作表中这条记录的时间、记录转账的交易时间、记录出发时间等等。你会发现这个时间这个东西与我们开发的联系还是非常紧密的,用的好与不好会给我们的业务甚至功能带来很大的影响。所以,我们有必要重新出发,好好认识一下这个东西。 +我们平时开发中不可避免的就是要存储时间,比如我们要记录操作表中这条记录的时间、记录转账的交易时间、记录出发时间等等。你会发现时间这个东西与我们开发的联系还是非常紧密的,用的好与不好会给我们的业务甚至功能带来很大的影响。所以,我们有必要重新出发,好好认识一下这个东西。 这是一篇短小精悍的文章,仔细阅读一定能学到不少东西! @@ -9,7 +9,7 @@ 但是,这是不正确的做法,主要会有下面两个问题: 1. 字符串占用的空间更大! -2. 字符串存储的日期比较效率比较低(逐个字符进行比对),无法用日期相关的 API 进行计算和比较。 +2. 字符串存储的日期效率比较低(逐个字符进行比对),无法用日期相关的 API 进行计算和比较。 ### 2.Datetime 和 Timestamp 之间抉择 @@ -17,7 +17,7 @@ Datetime 和 Timestamp 是 MySQL 提供的两种比较相似的保存时间的 **通常我们都会首选 Timestamp。** 下面说一下为什么这样做! -#### 2.1 DateTime 类型没有时区信息的 +#### 2.1 DateTime 类型没有时区信息 **DateTime 类型是没有时区信息的(时区无关)** ,DateTime 类型保存的时间都是当前会话所设置的时区对应的时间。这样就会有什么问题呢?当你的时区更换之后,比如你的服务器更换地址或者更换客户端连接时区设置的话,就会导致你从数据库中读出的时间错误。不要小看这个问题,很多系统就是因为这个问题闹出了很多笑话。 @@ -106,7 +106,7 @@ Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗 ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/FhRGUVHFK0ujRPNA75f6CuOXQHTE.jpeg) -可以看出 5.6.4 之后的 MySQL 多出了一个需要 0 ~ 3 字节的小数位。Datatime 和 Timestamp 会有几种不同的存储空间占用。 +可以看出 5.6.4 之后的 MySQL 多出了一个需要 0 ~ 3 字节的小数位。DateTime 和 Timestamp 会有几种不同的存储空间占用。 为了方便,本文我们还是默认 Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗费 8 个字节的存储空间。 From 79f6bfc18d77296b2b706582dbfa6fc27b3b84d7 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Fri, 18 Jun 2021 20:44:32 +0800 Subject: [PATCH 085/257] fix typo --- ...条sql语句在mysql中如何执行的.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/database/一条sql语句在mysql中如何执行的.md b/docs/database/一条sql语句在mysql中如何执行的.md index 261a0c0b..9798df73 100644 --- a/docs/database/一条sql语句在mysql中如何执行的.md +++ b/docs/database/一条sql语句在mysql中如何执行的.md @@ -20,7 +20,7 @@ 本篇文章会分析下一个 sql 语句在 MySQL 中的执行流程,包括 sql 的查询在 MySQL 内部会怎么流转,sql 语句的更新是怎么完成的。 -在分析之前我会先带着你看看 MySQL 的基础架构,知道了 MySQL 由那些组件组成已经这些组件的作用是什么,可以帮助我们理解和解决这些问题。 +在分析之前我会先带着你看看 MySQL 的基础架构,知道了 MySQL 由那些组件组成以及这些组件的作用是什么,可以帮助我们理解和解决这些问题。 ## 一 MySQL 基础架构分析 @@ -30,11 +30,11 @@ 先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图,在 1.2 节中会详细介绍到这些组件的作用。 -- **连接器:** 身份认证和权限相关(登录 MySQL 的时候)。 -- **查询缓存:** 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。 -- **分析器:** 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。 -- **优化器:** 按照 MySQL 认为最优的方案去执行。 -- **执行器:** 执行语句,然后从存储引擎返回数据。 +- **连接器:**身份认证和权限相关(登录 MySQL 的时候)。 +- **查询缓存:**执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。 +- **分析器:** 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。 +- **优化器:**按照 MySQL 认为最优的方案去执行。 +- **执行器:**执行语句,然后从存储引擎返回数据。 ![](https://user-gold-cdn.xitu.io/2019/3/23/169a8bc60a083849?w=950&h=1062&f=jpeg&s=38189) @@ -96,7 +96,7 @@ select * from tb_student A where A.age='18' and A.name=' 张三 '; 结合上面的说明,我们分析下这个语句的执行流程: * 先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL8.0 版本以前,会先查询缓存,以这条 sql 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。 -* 通过分析器进行词法分析,提取 sql 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id='1'。然后判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。 +* 通过分析器进行词法分析,提取 sql 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id='1'。然后判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。 * 接下来就是优化器进行确定执行方案,上面的 sql 语句,可以有两种执行方案: a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。 @@ -112,7 +112,7 @@ select * from tb_student A where A.age='18' and A.name=' 张三 '; ``` update tb_student A set A.age='19' where A.name=' 张三 '; ``` -我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,MySQL 自带的日志模块式 **binlog(归档日志)** ,所有的存储引擎都可以使用,我们常用的 InnoDB 引擎还自带了一个日志模块 **redo log(重做日志)**,我们就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下: +我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实这条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,MySQL 自带的日志模块是 **binlog(归档日志)** ,所有的存储引擎都可以使用,我们常用的 InnoDB 引擎还自带了一个日志模块 **redo log(重做日志)**,我们就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下: * 先查询到张三这一条数据,如果有缓存,也是会用到缓存。 * 然后拿到查询的语句,把 age 改为 19,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。 @@ -121,7 +121,7 @@ update tb_student A set A.age='19' where A.name=' 张三 '; **这里肯定有同学会问,为什么要用两个日志模块,用一个日志模块不行吗?** -这是因为最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。 +这是因为最开始 MySQL 并没有 InnoDB 引擎(InnoDB 引擎是其他公司以插件形式插入 MySQL 的),MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。 并不是说只用一个日志模块不可以,只是 InnoDB 引擎就是通过 redo log 来支持事务的。那么,又会有同学问,我用两个日志模块,但是不要这么复杂行不行,为什么 redo log 要引入 prepare 预提交状态?这里我们用反证法来说明下为什么要这么做? @@ -138,10 +138,10 @@ update tb_student A set A.age='19' where A.name=' 张三 '; ## 三 总结 -* MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。 +* MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。 * 引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。 -* 查询语句的执行流程如下:权限校验(如果命中缓存)---》查询缓存---》分析器---》优化器---》权限校验---》执行器---》引擎 -* 更新语句执行流程如下:分析器----》权限校验----》执行器---》引擎---redo log(prepare 状态---》binlog---》redo log(commit状态) +* 查询语句的执行流程如下:权限校验(如果命中缓存)--->查询缓存--->分析器--->优化器--->权限校验--->执行器--->引擎 +* 更新语句执行流程如下:分析器---->权限校验---->执行器--->引擎---redo log(prepare 状态)--->binlog--->redo log(commit状态) ## 四 参考 From 35adb487536569f8ef51a9cd29ae952f98624c3c Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Sat, 19 Jun 2021 11:09:40 +0800 Subject: [PATCH 086/257] =?UTF-8?q?fix=20typo=20=E5=A2=9E=E5=8A=A0=20redis?= =?UTF-8?q?=20=E9=BB=98=E8=AE=A4=E8=BF=87=E6=9C=9F=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/Redis/redis-all.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/database/Redis/redis-all.md b/docs/database/Redis/redis-all.md index 8bfda557..bfceaf13 100644 --- a/docs/database/Redis/redis-all.md +++ b/docs/database/Redis/redis-all.md @@ -44,7 +44,7 @@ 简单来说 **Redis 就是一个使用 C 语言开发的数据库**,不过与传统数据库不同的是 **Redis 的数据是存在内存中的** ,也就是它是内存数据库,所以读写速度非常快,因此 Redis 被广泛应用于缓存方向。 -另外,**Redis 除了做缓存之外,Redis 也经常用来做分布式锁,甚至是消息队列。** +另外,**Redis 除了做缓存之外,也经常用来做分布式锁,甚至是消息队列。** **Redis 提供了多种数据类型来支持不同的业务场景。Redis 还支持事务 、持久化、Lua 脚本、多种集群方案。** @@ -54,7 +54,7 @@ Memcached 是分布式缓存最开始兴起的那会,比较常用的。后来,随着 Redis 的发展,大家慢慢都转而使用更加强大的 Redis 了。 -分布式缓存主要解决的是单机缓存的容量受服务器限制并且无法保存通用的信息。因为,本地缓存只在当前服务里有效,比如如果你部署了两个相同的服务,他们两者之间的缓存数据是无法共同的。 +分布式缓存主要解决的是单机缓存的容量受服务器限制并且无法保存通用信息的问题。因为,本地缓存只在当前服务里有效,比如如果你部署了两个相同的服务,他们两者之间的缓存数据是无法共同的。 ### 3. 说一下 Redis 和 Memcached 的区别和共同点 @@ -72,7 +72,7 @@ Memcached 是分布式缓存最开始兴起的那会,比较常用的。后来 2. **Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memecache 把数据全部存在内存之中。** 3. **Redis 有灾难恢复机制。** 因为可以把缓存中的数据持久化到磁盘上。 4. **Redis 在服务器内存使用完之后,可以将不用的数据放到磁盘上。但是,Memcached 在服务器内存使用完之后,就会直接报异常。** -5. **Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 目前是原生支持 cluster 模式的.** +5. **Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 目前是原生支持 cluster 模式的。** 6. **Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程的多路 IO 复用模型。** (Redis 6.0 引入了多线程 IO ) 7. **Redis 支持发布订阅模型、Lua 脚本、事务等功能,而 Memcached 不支持。并且,Redis 支持更多的编程语言。** 8. **Memcached 过期数据的删除策略只用了惰性删除,而 Redis 同时使用了惰性删除与定期删除。** @@ -116,7 +116,7 @@ _简单,来说使用缓存主要是为了提升用户体验以及应对更多 > QPS(Query Per Second):服务器每秒可以执行的查询次数; -所以,直接操作缓存能够承受的数据库请求数量是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。进而,我们也就提高的系统整体的并发。 +由此可见,直接操作缓存能够承受的数据库请求数量是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。进而,我们也就提高了系统整体的并发。 ### 6. Redis 常见数据结构以及使用场景分析 @@ -126,9 +126,9 @@ _简单,来说使用缓存主要是为了提升用户体验以及应对更多 #### 6.1. string -1. **介绍** :string 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种 **简单动态字符串**(simple dynamic string,**SDS**)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串为 O(N)),除此之外,Redis 的 SDS API 是安全的,不会造成缓冲区溢出。 -2. **常用命令:** `set,get,strlen,exists,decr,incr,setex` 等等。 -3. **应用场景** :一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等。 +1. **介绍** :string 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种 **简单动态字符串**(simple dynamic string,**SDS**)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串为 O(N)),除此之外,Redis 的 SDS API 是安全的,不会造成缓冲区溢出。 +2. **常用命令:** `set,get,strlen,exists,decr,incr,setex` 等等。 +3. **应用场景:** 一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等。 下面我们简单看看它的使用! @@ -162,7 +162,6 @@ OK **计数器(字符串的内容为整数的时候可以使用):** ```bash - 127.0.0.1:6379> set number 1 OK 127.0.0.1:6379> incr number # 将 key 中储存的数字值增一 @@ -175,7 +174,7 @@ OK "1" ``` -**过期**: +**过期(默认为永不过期)**: ```bash 127.0.0.1:6379> expire key 60 # 数据在 60s 后过期 From 4685dd8a5ca4dd34a5774274b2502037a873b151 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Mon, 21 Jun 2021 16:53:08 +0800 Subject: [PATCH 087/257] fix typo --- docs/database/Redis/redis-all.md | 41 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/database/Redis/redis-all.md b/docs/database/Redis/redis-all.md index bfceaf13..3cd8ff62 100644 --- a/docs/database/Redis/redis-all.md +++ b/docs/database/Redis/redis-all.md @@ -1,6 +1,5 @@ 点击关注[公众号](#公众号)及时获取笔主最新更新文章,并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。 - @@ -187,8 +186,8 @@ OK #### 6.2. list -1. **介绍** :**list** 即是 **链表**。链表是一种非常常见的数据结构,特点是易于数据元素的插入和删除并且且可以灵活调整链表长度,但是链表的随机访问困难。许多高级编程语言都内置了链表的实现比如 Java 中的 **LinkedList**,但是 C 语言并没有实现链表,所以 Redis 实现了自己的链表数据结构。Redis 的 list 的实现为一个 **双向链表**,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。 -2. **常用命令:** `rpush,lpop,lpush,rpop,lrange、llen` 等。 +1. **介绍** :**list** 即是 **链表**。链表是一种非常常见的数据结构,特点是易于数据元素的插入和删除并且可以灵活调整链表长度,但是链表的随机访问困难。许多高级编程语言都内置了链表的实现比如 Java 中的 **LinkedList**,但是 C 语言并没有实现链表,所以 Redis 实现了自己的链表数据结构。Redis 的 list 的实现为一个 **双向链表**,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。 +2. **常用命令:** `rpush,lpop,lpush,rpop,lrange,llen` 等。 3. **应用场景:** 发布与订阅或者说消息队列、慢查询。 下面我们简单看看它的使用! @@ -340,9 +339,9 @@ OK #### 6.6 bitmap -1. **介绍 :** bitmap 存储的是连续的二进制数字(0 和 1),通过 bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 bitmap 本身会极大的节省储存空间。 +1. **介绍:** bitmap 存储的是连续的二进制数字(0 和 1),通过 bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 bitmap 本身会极大的节省储存空间。 2. **常用命令:** `setbit` 、`getbit` 、`bitcount`、`bitop` -3. **应用场景:** 适合需要保存状态信息(比如是否签到、是否登录...)并需要进一步对这些信息进行分析的场景。比如用户签到情况、活跃用户情况、用户行为统计(比如是否点赞过某个视频)。 +3. **应用场景:** 适合需要保存状态信息(比如是否签到、是否登录...)并需要进一步对这些信息进行分析的场景。比如用户签到情况、活跃用户情况、用户行为统计(比如是否点赞过某个视频)。 ```bash # SETBIT 会返回之前位的值(默认是 0)这里会生成 7 个位 @@ -375,7 +374,7 @@ OK 使用时间作为 key,然后用户 ID 为 offset,如果当日活跃过就设置为 1 -那么我该如果计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只有有一天在线就称为活跃),有请下一个 redis 的命令 +那么我该如何计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只要有一天在线就称为活跃),有请下一个 redis 的命令 ```bash # 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。 @@ -414,7 +413,7 @@ BITOP operation destkey key [key ...] **使用场景三:用户在线状态** -对于获取或者统计用户在线状态,使用 bitmap 是一个节约空间效率又高的一种方法。 +对于获取或者统计用户在线状态,使用 bitmap 是一个节约空间且效率又高的一种方法。 只需要一个 key,然后用户 ID 为 offset,如果在线就设置为 1,不在线就设置为 0。 @@ -424,17 +423,17 @@ BITOP operation destkey key [key ...] **既然是单线程,那怎么监听大量的客户端连接呢?** -Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接(或者说是监听多个 socket),它会将感兴趣的事件及类型(读、写)注册到内核中并监听每个事件是否发生。 +Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接(或者说是监听多个 socket),它会将感兴趣的事件及类型(读、写)注册到内核中并监听每个事件是否发生。 这样的好处非常明显: **I/O 多路复用技术的使用让 Redis 不需要额外创建多余的线程来监听客户端的大量连接,降低了资源的消耗**(和 NIO 中的 `Selector` 组件很像)。 -另外, Redis 服务器是一个事件驱动程序,服务器需要处理两类事件: 1. 文件事件; 2. 时间事件。 +另外, Redis 服务器是一个事件驱动程序,服务器需要处理两类事件:1. 文件事件; 2. 时间事件。 时间事件不需要多花时间了解,我们接触最多的还是 **文件事件**(客户端进行读取写入等操作,涉及一系列网络通信)。 《Redis 设计与实现》有一段话是如是介绍文件事件的,我觉得写得挺不错。 -> Redis 基于 Reactor 模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器(file event handler)。文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字,并根据 套接字目前执行的任务来为套接字关联不同的事件处理器。 +> Redis 基于 Reactor 模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器(file event handler)。文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。 > > 当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关 闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。 > @@ -453,7 +452,7 @@ Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接( ### 8. Redis 没有使用多线程?为什么不使用多线程? -虽然说 Redis 是单线程模型,但是, 实际上,**Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。** +虽然说 Redis 是单线程模型,但是,实际上,**Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。** ![redis4.0 more thread](images/redis-all/redis4.0-more-thread.png) @@ -466,14 +465,14 @@ Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接( 我觉得主要原因有下面 3 个: 1. 单线程编程容易并且更容易维护; -2. Redis 的性能瓶颈不再 CPU ,主要在内存和网络; +2. Redis 的性能瓶颈不在 CPU ,主要在内存和网络; 3. 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。 ### 9. Redis6.0 之后为何引入了多线程? **Redis6.0 引入多线程主要是为了提高网络 IO 读写性能**,因为这个算是 Redis 中的一个性能瓶颈(Redis 的瓶颈主要受限于内存和网络)。 -虽然,Redis6.0 引入了多线程,但是 Redis 的多线程只是在网络数据的读写这类耗时操作上使用了, 执行命令仍然是单线程顺序执行。因此,你也不需要担心线程安全问题。 +虽然,Redis6.0 引入了多线程,但是 Redis 的多线程只是在网络数据的读写这类耗时操作上使用了,执行命令仍然是单线程顺序执行。因此,你也不需要担心线程安全问题。 Redis6.0 的多线程默认是禁用的,只使用主线程。如需开启需要修改 redis 配置文件 `redis.conf` : @@ -501,7 +500,7 @@ io-threads 4 #官网建议4核的机器建议设置为2或3个线程,8核的 Redis 自带了给缓存数据设置过期时间的功能,比如: ```bash -127.0.0.1:6379> exp key 60 # 数据在 60s 后过期 +127.0.0.1:6379> exp key 60 # 数据在 60s 后过期 (integer) 1 127.0.0.1:6379> setex key 60 value # 数据在 60s 后过期 (setex:[set] + [ex]pire) OK @@ -509,7 +508,7 @@ OK (integer) 56 ``` -注意:**Redis 中除了字符串类型有自己独有设置过期时间的命令 `setex` 外,其他方法都需要依靠 `expire` 命令来设置过期时间 。另外, `persist` 命令可以移除一个键的过期时间: ** +注意:**Redis 中除了字符串类型有自己独有设置过期时间的命令 `setex` 外,其他方法都需要依靠 `expire` 命令来设置过期时间 。另外, `persist` 命令可以移除一个键的过期时间。 ** **过期时间除了有助于缓解内存的消耗,还有什么其他用么?** @@ -548,7 +547,7 @@ typedef struct redisDb { 但是,仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。这样就导致大量过期 key 堆积在内存里,然后就 Out of memory 了。 -怎么解决这个问题呢?答案就是: **Redis 内存淘汰机制。** +怎么解决这个问题呢?答案就是:**Redis 内存淘汰机制。** ### 13. Redis 内存淘汰机制了解么? @@ -565,7 +564,7 @@ Redis 提供 6 种数据淘汰策略: 4.0 版本后增加以下两种: -7. **volatile-lfu(least frequently used)**:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰 +7. **volatile-lfu(least frequently used)**:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰 8. **allkeys-lfu(least frequently used)**:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key ### 14. Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复) @@ -590,7 +589,7 @@ save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生 **AOF(append-only file)持久化** -与快照持久化相比,AOF 持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启: +与快照持久化相比,AOF 持久化的实时性更好,因此已成为主流的持久化方案。默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启: ```conf appendonly yes @@ -622,7 +621,7 @@ AOF 重写可以产生一个新的 AOF 文件,这个新的 AOF 文件和原有 AOF 重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有 AOF 文件进行任何读入、分析或者写入操作。 -在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧两个 AOF 文件所保存的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作 +在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧两个 AOF 文件所保存的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。 ### 15. Redis 事务 @@ -640,7 +639,7 @@ QUEUED 2) "Guide哥" ``` -使用 [`MULTI`](https://redis.io/commands/multi)命令后可以输入多个命令。Redis 不会立即执行这些命令,而是将它们放到队列,当调用了[`EXEC`](https://redis.io/commands/exec)命令将执行所有命令。 +使用 [`MULTI`](https://redis.io/commands/multi) 命令后可以输入多个命令。Redis 不会立即执行这些命令,而是将它们放到队列,当调用了 [`EXEC`](https://redis.io/commands/exec) 命令将执行所有命令。 这个过程是这样的: @@ -809,7 +808,7 @@ Cache Aside Pattern 中遇到写请求是这样的:更新 DB,然后直接删 如果更新数据库成功,而删除缓存这一步失败的情况的话,简单说两个解决方案: 1. **缓存失效时间变短(不推荐,治标不治本)** :我们让缓存数据的过期时间变短,这样的话缓存就会从数据库中加载数据。另外,这种解决办法对于先操作缓存后操作数据库的场景不适用。 -2. **增加 cache 更新重试机制(常用)**: 如果 cache 服务当前不可用导致缓存删除失败的话,我们就隔一段时间进行重试,重试次数可以自己定。如果多次重试还是失败的话,我们可以把当前更新失败的 key 存入队列中,等缓存服务可用之后,再将 缓存中对应的 key 删除即可。 +2. **增加 cache 更新重试机制(常用)**: 如果 cache 服务当前不可用导致缓存删除失败的话,我们就隔一段时间进行重试,重试次数可以自己定。如果多次重试还是失败的话,我们可以把当前更新失败的 key 存入队列中,等缓存服务可用之后,再将缓存中对应的 key 删除即可。 ### 19. 参考 From a7a2225f07f373d016d69719f3fc1a35953a2081 Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Mon, 21 Jun 2021 17:05:51 +0800 Subject: [PATCH 088/257] fix typo --- .../data-structure/bloom-filter.md | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/docs/dataStructures-algorithms/data-structure/bloom-filter.md b/docs/dataStructures-algorithms/data-structure/bloom-filter.md index b9d129d2..bfb7efe7 100644 --- a/docs/dataStructures-algorithms/data-structure/bloom-filter.md +++ b/docs/dataStructures-algorithms/data-structure/bloom-filter.md @@ -39,7 +39,7 @@ ![布隆过滤器hash计算](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/布隆过滤器-hash运算.png) -如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后在对应的位数组的下表的元素设置为 1(当位数组初始化时 ,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 +如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。 @@ -147,15 +147,15 @@ public class MyBloomFilter { 测试: ```java - String value1 = "https://javaguide.cn/"; - String value2 = "https://github.com/Snailclimb"; - MyBloomFilter filter = new MyBloomFilter(); - System.out.println(filter.contains(value1)); - System.out.println(filter.contains(value2)); - filter.add(value1); - filter.add(value2); - System.out.println(filter.contains(value1)); - System.out.println(filter.contains(value2)); +String value1 = "https://javaguide.cn/"; +String value2 = "https://github.com/Snailclimb"; +MyBloomFilter filter = new MyBloomFilter(); +System.out.println(filter.contains(value1)); +System.out.println(filter.contains(value2)); +filter.add(value1); +filter.add(value2); +System.out.println(filter.contains(value1)); +System.out.println(filter.contains(value2)); ``` Output: @@ -170,15 +170,15 @@ true 测试: ```java - Integer value1 = 13423; - Integer value2 = 22131; - MyBloomFilter filter = new MyBloomFilter(); - System.out.println(filter.contains(value1)); - System.out.println(filter.contains(value2)); - filter.add(value1); - filter.add(value2); - System.out.println(filter.contains(value1)); - System.out.println(filter.contains(value2)); +Integer value1 = 13423; +Integer value2 = 22131; +MyBloomFilter filter = new MyBloomFilter(); +System.out.println(filter.contains(value1)); +System.out.println(filter.contains(value2)); +filter.add(value1); +filter.add(value2); +System.out.println(filter.contains(value1)); +System.out.println(filter.contains(value2)); ``` Output: @@ -190,18 +190,18 @@ true true ``` -### 5.利用Google开源的 Guava中自带的布隆过滤器 +### 5.利用 Google 开源的 Guava 中自带的布隆过滤器 自己实现的目的主要是为了让自己搞懂布隆过滤器的原理,Guava 中布隆过滤器的实现算是比较权威的,所以实际项目中我们不需要手动实现一个布隆过滤器。 首先我们需要在项目中引入 Guava 的依赖: ```java - - com.google.guava - guava - 28.0-jre - + + com.google.guava + guava + 28.0-jre + ``` 实际使用如下: @@ -209,42 +209,42 @@ true 我们创建了一个最多存放 最多 1500个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) ```java - // 创建布隆过滤器对象 - BloomFilter filter = BloomFilter.create( - Funnels.integerFunnel(), - 1500, - 0.01); - // 判断指定元素是否存在 - System.out.println(filter.mightContain(1)); - System.out.println(filter.mightContain(2)); - // 将元素添加进布隆过滤器 - filter.put(1); - filter.put(2); - System.out.println(filter.mightContain(1)); - System.out.println(filter.mightContain(2)); +// 创建布隆过滤器对象 +BloomFilter filter = BloomFilter.create( + Funnels.integerFunnel(), + 1500, + 0.01); +// 判断指定元素是否存在 +System.out.println(filter.mightContain(1)); +System.out.println(filter.mightContain(2)); +// 将元素添加进布隆过滤器 +filter.put(1); +filter.put(2); +System.out.println(filter.mightContain(1)); +System.out.println(filter.mightContain(2)); ``` -在我们的示例中,当`mightContain()` 方法返回*true*时,我们可以99%确定该元素在过滤器中,当过滤器返回*false*时,我们可以100%确定该元素不存在于过滤器中。 +在我们的示例中,当`mightContain()` 方法返回 *true* 时,我们可以99%确定该元素在过滤器中,当过滤器返回 *false* 时,我们可以100%确定该元素不存在于过滤器中。 **Guava 提供的布隆过滤器的实现还是很不错的(想要详细了解的可以看一下它的源码实现),但是它有一个重大的缺陷就是只能单机使用(另外,容量扩展也不容易),而现在互联网一般都是分布式的场景。为了解决这个问题,我们就需要用到 Redis 中的布隆过滤器了。** ### 6.Redis 中的布隆过滤器 -#### 6.1介绍 +#### 6.1 介绍 Redis v4.0 之后有了 Module(模块/插件) 功能,Redis Modules 让 Redis 可以使用外部模块扩展其功能 。布隆过滤器就是其中的 Module。详情可以查看 Redis 官方对 Redis Modules 的介绍 :https://redis.io/modules -另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom. 其他还有: +另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom。其他还有: -- redis-lua-scaling-bloom-filter (lua 脚本实现):https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter +- redis-lua-scaling-bloom-filter(lua 脚本实现):https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter - pyreBloom(Python中的快速Redis 布隆过滤器) :https://github.com/seomoz/pyreBloom - ...... RedisBloom 提供了多种语言的客户端支持,包括:Python、Java、JavaScript 和 PHP。 -#### 6.2使用Docker安装 +#### 6.2 使用Docker安装 -如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索**docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 +如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 **具体操作如下:** @@ -257,7 +257,7 @@ root@21396d02c252:/data# redis-cli #### 6.3常用命令一览 -> 注意: key:布隆过滤器的名称,item : 添加的元素。 +> 注意: key : 布隆过滤器的名称,item : 添加的元素。 1. **`BF.ADD `**:将元素添加到布隆过滤器中,如果该过滤器尚不存在,则创建该过滤器。格式:`BF.ADD {key} {item}`。 2. **`BF.MADD `** : 将一个或多个元素添加到“布隆过滤器”中,并创建一个尚不存在的过滤器。该命令的操作方式`BF.ADD`与之相同,只不过它允许多个输入并返回多个值。格式:`BF.MADD {key} {item} [item ...]` 。 From 64cc847b61dcd0cf44a26a49f53f702b9872b524 Mon Sep 17 00:00:00 2001 From: VinterHe <37563054+VinterHe@users.noreply.github.com> Date: Tue, 22 Jun 2021 09:53:11 +0800 Subject: [PATCH 089/257] =?UTF-8?q?=E8=B7=9F=E6=96=B0=E4=BA=86=E5=8D=95?= =?UTF-8?q?=E6=A0=B8=E5=92=8C=E5=A4=9A=E6=A0=B8=E7=B3=BB=E7=BB=9F=E4=B8=AD?= =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=E7=9A=84=E4=B8=BB=E8=A6=81=E4=BD=9C?= =?UTF-8?q?=E7=94=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对系统中存在多个进程的情况进行了备注,防止读者迷惑 --- .../2020最新Java并发基础常见面试题总结.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md index 6ff3f381..eab717bb 100644 --- a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md @@ -126,8 +126,11 @@ public class MultiThread { 再深入到计算机底层来探讨: -- **单核时代:** 在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。 -- **多核时代:** 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个线程就可以让多个 CPU 核心被利用到,这样就提高了 CPU 的利用率。 +- **单核时代**: 在单核时代多线程主要是为了提高单进程利用CPU和IO系统的效率。 当我们请求IO的时候,如果java进程中只有一个线程,此线程被IO阻塞则整个进程被阻塞。CPU和IO设备只有一个在运行,那么可以简单地说系统整体效率只有50%。当使用多线程的时候,一个线程被IO阻塞,其他线程还可以继续使用CPU。从而提高了java进程利用系统资源的整体效率。 + +注意:此种情况是指的计算机只有一个CPU核心,并且假设只运行了一个java进程的情况,多进程的时候,操作系统会调度不同进程占用CPU,也不会存在浪费CPU的问题,只不过是因为大型项目中,作为服务器运行的机器中一般不会运行太多无关进程,所以才可作此假设。 + +- **多核时代**: 多核时代多线程主要是为了提高进程利用多核CPU的能力。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,不论系统有几个CPU核心,都只会有一个 CPU 核心被利用到。而创建多个线程,这些线程可以被映射到底层多个CPU上执行,在任务中的多个线程没有资源竞争的情况下,任务执行的效率会有显著性的提高,约等于(单核时执行时间/CPU核心数)。 ## 5. 使用多线程可能带来什么问题? From c50a6d2469b8747059b3c9c3856e806cb68367f7 Mon Sep 17 00:00:00 2001 From: VinterHe <37563054+VinterHe@users.noreply.github.com> Date: Tue, 22 Jun 2021 11:05:19 +0800 Subject: [PATCH 090/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=BB=80?= =?UTF-8?q?=E4=B9=88=E6=98=AF=E4=B8=8A=E4=B8=8B=E6=96=87=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E7=9A=84=E6=8F=8F=E8=BF=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...020最新Java并发基础常见面试题总结.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md index 6ff3f381..fc7beb79 100644 --- a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md @@ -155,13 +155,15 @@ Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种 ## 7. 什么是上下文切换? -多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。 +线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说到过的程序计数器,栈信息等。当出现如下情况的时候,线程会从占用CPU状态中退出。 +- 主动让出CPU,比如调用了sleep(),wait()等。 +- 时间片用完,因为操作系统要防止一个线程或者进程长时间占用CPU导致其他线程或者进程饿死。 +- 调用了阻塞类型的系统中断,比如请求IO,线程被阻塞。 +- 被终止或结束运行 -概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。**任务从保存到再加载的过程就是一次上下文切换**。 +这其中前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用CPU的时候恢复现场。并加载下一个将要占用CPU的线程上下文。这就是所谓的上下文切换。 -上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗最大的操作。 - -Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。 +上下文切换是现代操作系统的基本功能,因其每次需要保存信息恢复信息,这将会占用CPU,内存等系统资源进行处理,也就意味着效率会有一定损耗,如果频繁切换就会造成整体效率低下。 ## 8. 什么是线程死锁?如何避免死锁? From ae0f4f0c4c8e17183f7cd2cdf15cc4a47ee0f67a Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 22 Jun 2021 11:27:26 +0800 Subject: [PATCH 091/257] fix typo --- docs/database/Redis/Redis持久化.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/database/Redis/Redis持久化.md b/docs/database/Redis/Redis持久化.md index 0408c276..2da52eec 100644 --- a/docs/database/Redis/Redis持久化.md +++ b/docs/database/Redis/Redis持久化.md @@ -7,7 +7,7 @@ **很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后回复数据),或者是为了防止系统故障而将数据备份到一个远程位置。** -Redis不同于Memcached的很重一点就是,**Redis支持持久化**,而且支持两种不同的持久化操作。Redis的一种持久化方式叫**快照(snapshotting,RDB)**,另一种方式是**只追加文件(append-only file,AOF)**.这两种方法各有千秋,下面我会详细这两种持久化方法是什么,怎么用,如何选择适合自己的持久化方法。 +Redis不同于Memcached的很重要一点就是,**Redis支持持久化**,而且支持两种不同的持久化操作。Redis的一种持久化方式叫**快照(snapshotting,RDB)**,另一种方式是**只追加文件(append-only file,AOF)**。这两种方法各有千秋,下面我会详细这两种持久化方法是什么,怎么用,如何选择适合自己的持久化方法。 ## 快照(snapshotting)持久化 @@ -16,8 +16,8 @@ Redis可以通过创建快照来获得存储在内存里面的数据在某个时 ![春夏秋冬又一春](https://user-gold-cdn.xitu.io/2018/6/13/163f97568281782a?w=600&h=329&f=jpeg&s=88616) **快照持久化是Redis默认采用的持久化方式**,在redis.conf配置文件中默认有此下配置: -``` +``` save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。 save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。 @@ -39,8 +39,6 @@ save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生 如果系统真的发生崩溃,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化只适用于即使丢失一部分数据也不会造成一些大问题的应用程序。不能接受这个缺点的话,可以考虑AOF持久化。 - - ## **AOF(append-only file)持久化** 与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启: @@ -55,7 +53,6 @@ appendonly yes **在Redis的配置文件中存在三种同步方式,它们分别是:** ``` - appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度 appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘 appendfsync no #让操作系统决定何时进行同步 @@ -65,7 +62,6 @@ appendfsync no #让操作系统决定何时进行同步 为了兼顾数据和写入性能,用户可以考虑 **appendfsync everysec选项** ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。 - **appendfsync no** 选项一般不推荐,这种方案会使Redis丢失不定量的数据而且如果用户的硬盘处理写入操作的速度不够的话,那么当缓冲区被等待写入的数据填满时,Redis的写入操作将被阻塞,这会导致Redis的请求速度变慢。 **虽然AOF持久化非常灵活地提供了多种不同的选项来满足不同应用程序对数据安全的不同要求,但AOF持久化也有缺陷——AOF文件的体积太大。** @@ -100,7 +96,7 @@ auto-aof-rewrite-min-size 64mb 无论是AOF持久化还是快照持久化,将数据持久化到硬盘上都是非常有必要的,但除了进行持久化外,用户还必须对持久化得到的文件进行备份(最好是备份到不同的地方),这样才能尽量避免数据丢失事故发生。如果条件允许的话,最好能将快照文件和重新重写的AOF文件备份到不同的服务器上面。 -随着负载量的上升,或者数据的完整性变得 越来越重要时,用户可能需要使用到复制特性。 +随着负载量的上升,或者数据的完整性变得越来越重要时,用户可能需要使用到复制特性。 ## Redis 4.0 对于持久化机制的优化 Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 `aof-use-rdb-preamble` 开启)。 @@ -113,4 +109,3 @@ Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通 [深入学习Redis(2):持久化](https://www.cnblogs.com/kismetv/p/9137897.html) - From 09e88e476da46b7e4939c8b1c362c2ea4af4a28e Mon Sep 17 00:00:00 2001 From: TommyMerlin <786731256@qq.com> Date: Tue, 22 Jun 2021 15:02:11 +0800 Subject: [PATCH 092/257] fix typo --- docs/database/Redis/redis集群以及应用场景.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/database/Redis/redis集群以及应用场景.md b/docs/database/Redis/redis集群以及应用场景.md index dfa0d40e..cd54f067 100644 --- a/docs/database/Redis/redis集群以及应用场景.md +++ b/docs/database/Redis/redis集群以及应用场景.md @@ -77,7 +77,7 @@ - 优化参数不一致:内存不一致. - 避免全量复制 - 选择小主节点(分片)、低峰期间操作. - - 如果节点运行 id 不匹配(如主节点重启、运行 id 发送变化),此时要执行全量复制,应该配合哨兵和集群解决. + - 如果节点运行 id 不匹配(如主节点重启、运行 id 发生变化),此时要执行全量复制,应该配合哨兵和集群解决. - 主从复制挤压缓冲区不足产生的问题(网络中断,部分复制无法满足),可增大复制缓冲区( rel_backlog_size 参数). - 复制风暴 @@ -111,7 +111,7 @@ - 转移流程 1. Sentinel 选出一个合适的 Slave 作为新的 Master(slaveof no one 命令)。 2. 向其余 Slave 发出通知,让它们成为新 Master 的 Slave( parallel-syncs 参数)。 - 3. 等待旧 Master 复活,并使之称为新 Master 的 Slave。 + 3. 等待旧 Master 复活,并使之成为新 Master 的 Slave。 4. 向客户端通知 Master 变化。 - 从 Slave 中选择新 Master 节点的规则(slave 升级成 master 之后) 1. 选择 slave-priority 最高的节点。 @@ -138,7 +138,7 @@ ##### 集中式 -> 将集群元数据(节点信息、故障等等)几种存储在某个节点上。 +> 将集群元数据(节点信息、故障等等)集中存储在某个节点上。 - 优势 1. 元数据的更新读取具有很强的时效性,元数据修改立即更新 - 劣势 From 65926e5e549b923020f04bb515604d45cbd31c8f Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 23 Jun 2021 20:35:00 +0800 Subject: [PATCH 093/257] =?UTF-8?q?Update=202020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E5=9F=BA=E7=A1=80=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java并发基础常见面试题总结.md | 59 +++++++++---------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md index eab717bb..95e53699 100644 --- a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md @@ -1,25 +1,25 @@ -- [Java 并发基础常见面试题总结](#java-并发基础常见面试题总结) - - [1. 什么是线程和进程?](#1-什么是线程和进程) - - [1.1. 何为进程?](#11-何为进程) - - [1.2. 何为线程?](#12-何为线程) - - [2. 请简要描述线程与进程的关系,区别及优缺点?](#2-请简要描述线程与进程的关系区别及优缺点) - - [2.1. 图解进程和线程的关系](#21-图解进程和线程的关系) - - [2.2. 程序计数器为什么是私有的?](#22-程序计数器为什么是私有的) - - [2.3. 虚拟机栈和本地方法栈为什么是私有的?](#23-虚拟机栈和本地方法栈为什么是私有的) - - [2.4. 一句话简单了解堆和方法区](#24-一句话简单了解堆和方法区) - - [3. 说说并发与并行的区别?](#3-说说并发与并行的区别) - - [4. 为什么要使用多线程呢?](#4-为什么要使用多线程呢) - - [5. 使用多线程可能带来什么问题?](#5-使用多线程可能带来什么问题) - - [6. 说说线程的生命周期和状态?](#6-说说线程的生命周期和状态) - - [7. 什么是上下文切换?](#7-什么是上下文切换) - - [8. 什么是线程死锁?如何避免死锁?](#8-什么是线程死锁如何避免死锁) - - [8.1. 认识线程死锁](#81-认识线程死锁) - - [8.2. 如何避免线程死锁?](#82-如何避免线程死锁) - - [9. 说说 sleep() 方法和 wait() 方法区别和共同点?](#9-说说-sleep-方法和-wait-方法区别和共同点) - - [10. 为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?](#10-为什么我们调用-start-方法时会执行-run-方法为什么我们不能直接调用-run-方法) - - [公众号](#公众号) +- [Java 并发基础常见面试题总结](#Java-并发基础常见面试题总结) + - [1. 什么是线程和进程?](#1-什么是线程和进程) + - [1.1. 何为进程?](#11-何为进程) + - [1.2. 何为线程?](#12-何为线程) + - [2. 请简要描述线程与进程的关系,区别及优缺点?](#2-请简要描述线程与进程的关系区别及优缺点) + - [2.1. 图解进程和线程的关系](#21-图解进程和线程的关系) + - [2.2. 程序计数器为什么是私有的?](#22-程序计数器为什么是私有的) + - [2.3. 虚拟机栈和本地方法栈为什么是私有的?](#23-虚拟机栈和本地方法栈为什么是私有的) + - [2.4. 一句话简单了解堆和方法区](#24-一句话简单了解堆和方法区) + - [3. 说说并发与并行的区别?](#3-说说并发与并行的区别) + - [4. 为什么要使用多线程呢?](#4-为什么要使用多线程呢) + - [5. 使用多线程可能带来什么问题?](#5-使用多线程可能带来什么问题) + - [6. 说说线程的生命周期和状态?](#6-说说线程的生命周期和状态) + - [7. 什么是上下文切换?](#7-什么是上下文切换) + - [8. 什么是线程死锁?如何避免死锁?](#8-什么是线程死锁如何避免死锁) + - [8.1. 认识线程死锁](#81-认识线程死锁) + - [8.2. 如何避免线程死锁?](#82-如何避免线程死锁) + - [9. 说说 sleep() 方法和 wait() 方法区别和共同点?](#9-说说-sleep-方法和-wait-方法区别和共同点) + - [10. 为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?](#10-为什么我们调用-start-方法时会执行-run-方法为什么我们不能直接调用-run-方法) + - [公众号](#公众号) @@ -126,11 +126,8 @@ public class MultiThread { 再深入到计算机底层来探讨: -- **单核时代**: 在单核时代多线程主要是为了提高单进程利用CPU和IO系统的效率。 当我们请求IO的时候,如果java进程中只有一个线程,此线程被IO阻塞则整个进程被阻塞。CPU和IO设备只有一个在运行,那么可以简单地说系统整体效率只有50%。当使用多线程的时候,一个线程被IO阻塞,其他线程还可以继续使用CPU。从而提高了java进程利用系统资源的整体效率。 - -注意:此种情况是指的计算机只有一个CPU核心,并且假设只运行了一个java进程的情况,多进程的时候,操作系统会调度不同进程占用CPU,也不会存在浪费CPU的问题,只不过是因为大型项目中,作为服务器运行的机器中一般不会运行太多无关进程,所以才可作此假设。 - -- **多核时代**: 多核时代多线程主要是为了提高进程利用多核CPU的能力。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,不论系统有几个CPU核心,都只会有一个 CPU 核心被利用到。而创建多个线程,这些线程可以被映射到底层多个CPU上执行,在任务中的多个线程没有资源竞争的情况下,任务执行的效率会有显著性的提高,约等于(单核时执行时间/CPU核心数)。 +- **单核时代**: 在单核时代多线程主要是为了提高单进程利用 CPU 和 IO 系统的效率。 假设只运行了一个 Java 进程的情况,当我们请求 IO 的时候,如果 Java 进程中只有一个线程,此线程被 IO 阻塞则整个进程被阻塞。CPU 和 IO 设备只有一个在运行,那么可以简单地说系统整体效率只有 50%。当使用多线程的时候,一个线程被 IO 阻塞,其他线程还可以继续使用 CPU。从而提高了 Java 进程利用系统资源的整体效率。 +- **多核时代**: 多核时代多线程主要是为了提高进程利用多核 CPU 的能力。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,不论系统有几个 CPU 核心,都只会有一个 CPU 核心被利用到。而创建多个线程,这些线程可以被映射到底层多个 CPU 上执行,在任务中的多个线程没有资源竞争的情况下,任务执行的效率会有显著性的提高,约等于(单核时执行时间/CPU 核心数)。 ## 5. 使用多线程可能带来什么问题? @@ -146,11 +143,11 @@ Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种 ![Java 线程状态变迁 ](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java+%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81.png) -> 订正(来自[issue736](https://github.com/Snailclimb/JavaGuide/issues/736)):原图中 wait到 runnable状态的转换中,`join`实际上是`Thread`类的方法,但这里写成了`Object`。 +> 订正(来自[issue736](https://github.com/Snailclimb/JavaGuide/issues/736)):原图中 wait 到 runnable 状态的转换中,`join`实际上是`Thread`类的方法,但这里写成了`Object`。 由上图可以看出:线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。 -> 操作系统隐藏 Java 虚拟机(JVM)中的 READY 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinjava.com/ "HowToDoInJava"):[Java Thread Life Cycle and Thread States](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/ "Java Thread Life Cycle and Thread States")),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 +> 操作系统隐藏 Java 虚拟机(JVM)中的 READY 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinJava.com/ "HowToDoInJava"):[Java Thread Life Cycle and Thread States](https://howtodoinJava.com/Java/multi-threading/Java-thread-life-cycle-and-thread-states/ "Java Thread Life Cycle and Thread States")),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 ![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png) @@ -239,7 +236,7 @@ Thread[线程 2,5,main]waiting get resource1 **如何预防死锁?** 破坏死锁的产生的必要条件即可: -1. **破坏请求与保持条件** :一次性申请所有的资源。 +1. **破坏请求与保持条件** :一次性申请所有的资源。 2. **破坏不剥夺条件** :占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。 3. **破坏循环等待条件** :靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。 @@ -294,9 +291,9 @@ Process finished with exit code 0 ## 10. 为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法? -这是另一个非常经典的 java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! +这是另一个非常经典的 Java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! -new 一个 Thread,线程进入了新建状态。调用 `start()`方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 `start()` 会执行线程的相应准备工作,然后自动执行 ` run() ` 方法的内容,这是真正的多线程工作。 但是,直接执行 `run()` 方法,会把 `run()` 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。 +new 一个 Thread,线程进入了新建状态。调用 `start()`方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 `start()` 会执行线程的相应准备工作,然后自动执行 `run()` 方法的内容,这是真正的多线程工作。 但是,直接执行 `run()` 方法,会把 `run()` 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。 **总结: 调用 `start()` 方法方可启动线程并使线程进入就绪状态,直接执行 `run()` 方法的话不会以多线程的方式执行。** @@ -309,5 +306,3 @@ new 一个 Thread,线程进入了新建状态。调用 `start()`方法,会 **Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 ![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) - - From d342570fb709eeb710cbea1aecdc41708d66cc77 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 23 Jun 2021 20:39:36 +0800 Subject: [PATCH 094/257] =?UTF-8?q?Update=202020=E6=9C=80=E6=96=B0Java?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E5=9F=BA=E7=A1=80=E5=B8=B8=E8=A7=81=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发基础常见面试题总结.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md index d536dc0e..45a48544 100644 --- a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md @@ -155,15 +155,15 @@ Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种 ## 7. 什么是上下文切换? -线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说到过的程序计数器,栈信息等。当出现如下情况的时候,线程会从占用CPU状态中退出。 -- 主动让出CPU,比如调用了sleep(),wait()等。 +线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说到过的程序计数器,栈信息等。当出现如下情况的时候,线程会从占用 CPU 状态中退出。 +- 主动让出 CPU,比如调用了 `sleep()`, `wait()` 等。 - 时间片用完,因为操作系统要防止一个线程或者进程长时间占用CPU导致其他线程或者进程饿死。 -- 调用了阻塞类型的系统中断,比如请求IO,线程被阻塞。 +- 调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞。 - 被终止或结束运行 -这其中前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用CPU的时候恢复现场。并加载下一个将要占用CPU的线程上下文。这就是所谓的上下文切换。 +这其中前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用 CPU 的时候恢复现场。并加载下一个将要占用 CPU 的线程上下文。这就是所谓的 **上下文切换**。 -上下文切换是现代操作系统的基本功能,因其每次需要保存信息恢复信息,这将会占用CPU,内存等系统资源进行处理,也就意味着效率会有一定损耗,如果频繁切换就会造成整体效率低下。 +上下文切换是现代操作系统的基本功能,因其每次需要保存信息恢复信息,这将会占用 CPU,内存等系统资源进行处理,也就意味着效率会有一定损耗,如果频繁切换就会造成整体效率低下。 ## 8. 什么是线程死锁?如何避免死锁? From 0026f531af301dd9b515ae2f6555768e3f86c202 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 23 Jun 2021 21:06:49 +0800 Subject: [PATCH 095/257] =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=EF=BC=9A=20?= =?UTF-8?q?READY=20=E5=92=8C=20RUNNING=20=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发基础常见面试题总结.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md index 45a48544..b5f2e57d 100644 --- a/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发基础常见面试题总结.md @@ -147,12 +147,16 @@ Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种 由上图可以看出:线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。 -> 操作系统隐藏 Java 虚拟机(JVM)中的 READY 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinJava.com/ "HowToDoInJava"):[Java Thread Life Cycle and Thread States](https://howtodoinJava.com/Java/multi-threading/Java-thread-life-cycle-and-thread-states/ "Java Thread Life Cycle and Thread States")),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 +> 在操作系统中层面线程有 READY 和 RUNNING 状态,而在 JVM 层面只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinJava.com/ "HowToDoInJava"):[Java Thread Life Cycle and Thread States](https://howtodoinJava.com/Java/multi-threading/Java-thread-life-cycle-and-thread-states/ "Java Thread Life Cycle and Thread States")),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 +> +> **为什么 JVM 没有区分这两种状态呢?** (摘自:[java线程运行怎么有第六种状态? - Dawell的回答](https://www.zhihu.com/question/56494969/answer/154053599) ) 现在的时分(time-sharing)多任务(multi-task)操作系统架构通常都是用所谓的“时间分片(time quantum or time slice)”方式进行抢占式(preemptive)轮转调度(round-robin式)。这个时间分片通常是很小的,一个线程一次最多只能在 CPU 上运行比如 10-20ms 的时间(此时处于 running 状态),也即大概只有 0.01 秒这一量级,时间片用后就要被切换下来放入调度队列的末尾等待再次调度。(也即回到 ready 状态)。线程切换的如此之快,区分这两种状态就没什么意义了。 ![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png) 当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)** 状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的`run()`方法之后将会进入到 **TERMINATED(终止)** 状态。 +相关阅读:[挑错 |《Java 并发编程的艺术》中关于线程状态的三处错误](https://mp.weixin.qq.com/s/UOrXql_LhOD8dhTq_EPI0w) 。 + ## 7. 什么是上下文切换? 线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说到过的程序计数器,栈信息等。当出现如下情况的时候,线程会从占用 CPU 状态中退出。 From 06545375a2cf6421d8c290937137557e2cf2cc89 Mon Sep 17 00:00:00 2001 From: daniubi <804703017@qq.com> Date: Tue, 29 Jun 2021 19:05:05 +0800 Subject: [PATCH 096/257] =?UTF-8?q?2.1.7=20=E6=B6=88=E6=81=AF=E7=9A=84=20p?= =?UTF-8?q?ush=20=E5=AE=9E=E7=8E=B0--=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 感觉这样对初学者而言更直观一点。 --- .../distributed-system/message-queue/RocketMQ-Questions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md b/docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md index a41a4035..843d927a 100644 --- a/docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md +++ b/docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md @@ -172,6 +172,8 @@ class Broker { 1. 注意,RocketMQ 已经说了自己会有低延迟问题,其中就包括这个消息的 push 延迟问题 2. 因为这并不是真正的将消息主动的推送到消费者,而是 Broker 定时任务每5s将消息推送到消费者 +3. pull模式需要我们手动调用consumer拉消息,而push模式则只需要我们提供一个listener即可实现对消息的监听,而实际上,RocketMQ的push模式是基于pull模式实现的,它没有实现真正的push。 +4. push方式里,consumer把轮询过程封装了,并注册MessageListener监听器,取到消息后,唤醒MessageListener的consumeMessage()来消费,对用户而言,感觉消息是被推送过来的。 ### 2.1.8 消息重复发送的避免 From 86558e417d566c0f4c296eea8e22853634eeff5a Mon Sep 17 00:00:00 2001 From: daniubi <804703017@qq.com> Date: Wed, 30 Jun 2021 09:01:54 +0800 Subject: [PATCH 097/257] Update RocketMQ.md --- .../distributed-system/message-queue/RocketMQ.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/message-queue/RocketMQ.md b/docs/system-design/distributed-system/message-queue/RocketMQ.md index c74fab6f..9391d522 100644 --- a/docs/system-design/distributed-system/message-queue/RocketMQ.md +++ b/docs/system-design/distributed-system/message-queue/RocketMQ.md @@ -190,7 +190,7 @@ 你可以看到图中生产者组中的生产者会向主题发送消息,而 **主题中存在多个队列**,生产者每次生产消息之后是指定主题中的某个队列发送消息的。 -每个主题中都有多个队列(这里还不涉及到 `Broker`),集群消费模式下,一个消费者集群多台机器共同消费一个 `topic` 的多个队列,**一个队列只会被一个消费者消费**。如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。就像上图中 `Consumer1` 和 `Consumer2` 分别对应着两个队列,而 `Consuer3` 是没有队列对应的,所以一般来讲要控制 **消费者组中的消费者个数和主题中队列个数相同** 。 +每个主题中都有多个队列(分布在不同的 `Broker`中,如果是集群的话,`Broker`又分布在不同的服务器中),集群消费模式下,一个消费者集群多台机器共同消费一个 `topic` 的多个队列,**一个队列只会被一个消费者消费**。如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。就像上图中 `Consumer1` 和 `Consumer2` 分别对应着两个队列,而 `Consuer3` 是没有队列对应的,所以一般来讲要控制 **消费者组中的消费者个数和主题中队列个数相同** 。 当然也可以消费者个数小于队列个数,只不过不太建议。如下图。 @@ -451,4 +451,4 @@ emmm,是不是有一点复杂🤣,看英文图片和英文文档的时候就 等等。。。 -> 如果喜欢可以点赞哟👍👍👍。 \ No newline at end of file +> 如果喜欢可以点赞哟👍👍👍。 From 0cafebbdc32f4f930f7d73ae45c34b6825cd1788 Mon Sep 17 00:00:00 2001 From: daniubi <804703017@qq.com> Date: Wed, 30 Jun 2021 09:16:23 +0800 Subject: [PATCH 098/257] Update RocketMQ.md --- .../distributed-system/message-queue/RocketMQ.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/system-design/distributed-system/message-queue/RocketMQ.md b/docs/system-design/distributed-system/message-queue/RocketMQ.md index c74fab6f..cd45b3d3 100644 --- a/docs/system-design/distributed-system/message-queue/RocketMQ.md +++ b/docs/system-design/distributed-system/message-queue/RocketMQ.md @@ -200,6 +200,8 @@ 因为我们刚刚画的仅仅是一个消费者组,我们知道在发布订阅模式中一般会涉及到多个消费者组,而每个消费者组在每个队列中的消费位置都是不同的。如果此时有多个消费者组,那么消息被一个消费者组消费完之后是不会删除的(因为其它消费者组也需要呀),它仅仅是为每个消费者组维护一个 **消费位移(offset)** ,每次消费者组消费完会返回一个成功的响应,然后队列再把维护的消费位移加一,这样就不会出现刚刚消费过的消息再一次被消费了。 +这里我有一个疑问:上面说【一个队列只会被一个消费者消费】下面说说【那么消息被一个消费者组消费完之后是不会删除的(因为其它消费者组也需要呀)】,讲不通啊,消息在不同队列上是重复的吗? + ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/16ef3857fefaa079.jpg) 可能你还有一个问题,**为什么一个主题中需要维护多个队列** ? @@ -451,4 +453,4 @@ emmm,是不是有一点复杂🤣,看英文图片和英文文档的时候就 等等。。。 -> 如果喜欢可以点赞哟👍👍👍。 \ No newline at end of file +> 如果喜欢可以点赞哟👍👍👍。 From 9c185d3f350221f9aaa706bd1ddfe60edc50099c Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 30 Jun 2021 21:19:28 +0800 Subject: [PATCH 099/257] Update RocketMQ.md --- docs/system-design/distributed-system/message-queue/RocketMQ.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/system-design/distributed-system/message-queue/RocketMQ.md b/docs/system-design/distributed-system/message-queue/RocketMQ.md index 38fb6b1a..9391d522 100644 --- a/docs/system-design/distributed-system/message-queue/RocketMQ.md +++ b/docs/system-design/distributed-system/message-queue/RocketMQ.md @@ -200,8 +200,6 @@ 因为我们刚刚画的仅仅是一个消费者组,我们知道在发布订阅模式中一般会涉及到多个消费者组,而每个消费者组在每个队列中的消费位置都是不同的。如果此时有多个消费者组,那么消息被一个消费者组消费完之后是不会删除的(因为其它消费者组也需要呀),它仅仅是为每个消费者组维护一个 **消费位移(offset)** ,每次消费者组消费完会返回一个成功的响应,然后队列再把维护的消费位移加一,这样就不会出现刚刚消费过的消息再一次被消费了。 -这里我有一个疑问:上面说【一个队列只会被一个消费者消费】下面说说【那么消息被一个消费者组消费完之后是不会删除的(因为其它消费者组也需要呀)】,讲不通啊,消息在不同队列上是重复的吗? - ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/16ef3857fefaa079.jpg) 可能你还有一个问题,**为什么一个主题中需要维护多个队列** ? From 53e1ffdf21865e501b3e21123b720543d52b2493 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 30 Jun 2021 21:19:31 +0800 Subject: [PATCH 100/257] Update MySQL.md --- docs/database/MySQL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 5edb178d..0241d05e 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -132,7 +132,7 @@ MVCC 可以看作是行级锁的一个升级,可以有效减少加锁操作, - Record lock:记录锁,单个行记录上的锁 - Gap lock:间隙锁,锁定一个范围,不包括记录本身 -- Next-key lock:record+gap临键锁,锁定一个范围,包含记录本身 +- Next-key lock:record+gap 临键锁,锁定一个范围,包含记录本身 ## 查询缓存 From 1f2ca65961aefd1773e6d0b5d96e879bda6387f2 Mon Sep 17 00:00:00 2001 From: VinterHe Date: Thu, 1 Jul 2021 11:02:54 +0800 Subject: [PATCH 101/257] =?UTF-8?q?jvm=E5=9E=83=E5=9C=BE=E5=9B=9E=E6=94=B6?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=B5=8B=E8=AF=95=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E5=92=8C=E4=B8=80=E4=BA=9B=E6=96=87?= =?UTF-8?q?=E6=A1=88=E7=9A=84=E4=BF=AE=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/JVM垃圾回收.md | 86 +++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index 13af4987..534ca51d 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -74,7 +74,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G 上图所示的 Eden 区、From Survivor0("From") 区、To Survivor1("To") 区都属于新生代,Old Memory 区属于老年代。 -大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。 +大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为大于 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置默认值,这个值会在虚拟机运行过程中进行调整,可以通过`-XX:+PrintTenuringDistribution`来打印出当次GC后的Threshold。 > **🐛 修正(参见:[issue552](https://github.com/Snailclimb/JavaGuide/issues/552))**:“Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的一半时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。 > @@ -100,8 +100,90 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G > > ``` -经过这次 GC 后,Eden 区和"From"区已经被清空。这个时候,"From"和"To"会交换他们的角色,也就是新的"To"就是上次 GC 前的“From”,新的"From"就是上次 GC 前的"To"。不管怎样,都会保证名为 To 的 Survivor 区域是空的。Minor GC 会一直重复这样的过程,直到“To”区被填满,"To"区被填满之后,会将所有对象移动到老年代中。 +经过这次 GC 后,Eden 区和"From"区已经被清空。这个时候,"From"和"To"会交换他们的角色,也就是新的"To"就是上次 GC 前的“From”,新的"From"就是上次 GC 前的"To"。不管怎样,都会保证名为 To 的 Survivor 区域是空的。Minor GC 会一直重复这样的过程,在这个过程中,有可能当次Minor GC后,Survivor 的"From"区域空间不够用,有一些还达不到进入老年代条件的实例放不下,则放不下的部分会提前进入老年代。 +接下来我们提供一个调试脚本来测试这个过程。 + +**调试代码参数如下** +``` +-verbose:gc +-Xmx200M +-Xms200M +-Xmn50M +-XX:+PrintGCDetails +-XX:TargetSurvivorRatio=60 +-XX:+PrintTenuringDistribution +-XX:+PrintGCDetails +-XX:+PrintGCDateStamps +-XX:MaxTenuringThreshold=3 +-XX:+UseConcMarkSweepGC +-XX:+UseParNewGC +``` +**示例代码如下:** +``` +/* +* 本实例用于java GC以后,新生代survivor区域的变化,以及晋升到老年代的时间和方式的测试代码。需要自行分步注释不需要的代码进行反复测试对比 +* +* 由于java的main函数以及其他基础服务也会占用一些eden空间,所以要提前空跑一次main函数,来看看这部分占用。 +* +* 自定义的代码中,我们使用堆内分配数组和栈内分配数组的方式来分别模拟不可被GC的和可被GC的资源。 +* +* +* */ + +public class JavaGcTest { + + public static void main(String[] args) throws InterruptedException { + //空跑一次main函数来查看java服务本身占用的空间大小,我这里是占用了3M。所以40-3=37,下面分配三个1M的数组和一个34M的垃圾数组。 + + + // 为了达到TargetSurvivorRatio(期望占用的Survivor区域的大小)这个比例指定的值, 即5M*60%=3M(Desired survivor size), + // 这里用1M的数组的分配来达到Desired survivor size + //说明: 5M为S区的From或To的大小,60%为TargetSurvivorRatio参数指定,可以更改参数获取不同的效果。 + byte[] byte1m_1 = new byte[1 * 1024 * 1024]; + byte[] byte1m_2 = new byte[1 * 1024 * 1024]; + byte[] byte1m_3 = new byte[1 * 1024 * 1024]; + + //使用函数方式来申请空间,函数运行完毕以后,就会变成垃圾等待回收。此时应保证eden的区域占用达到100%。可以通过调整传入值来达到效果。 + makeGarbage(34); + + //再次申请一个数组,因为eden已经满了,所以这里会触发Minor GC + byte[] byteArr = new byte[10*1024*1024]; + // 这次Minor Gc时, 三个1M的数组因为尚有引用,所以进入From区域(因为是第一次GC)age为1 + // 且由于From区已经占用达到了60%(-XX:TargetSurvivorRatio=60), 所以会重新计算对象晋升的age。 + // 计算方法见上文,计算出age:min(age, MaxTenuringThreshold) = 1,输出中会有Desired survivor size 3145728 bytes, new threshold 1 (max 3)字样 + //新的数组byteArr进入eden区域。 + + + //再次触发垃圾回收,证明三个1M的数组会因为其第二次回收后age为2,大于上一次计算出的new threshold 1,所以进入老年代。 + //而byteArr因为超过survivor的单个区域,直接进入了老年代。 + makeGarbage(34); + } + private static void makeGarbage(int size){ + byte[] byteArrTemp = new byte[size * 1024 * 1024]; + } +} + +``` + +注意:如下输出结果中老年代的信息为concurrent mark-sweep generation和以前版本略有不同。age列出了某次GC后是否重新生成了threshold,还有各个年龄占用空间的大小。 +``` +2021-07-01T10:41:32.257+0800: [GC (Allocation Failure) 2021-07-01T10:41:32.257+0800: [ParNew +Desired survivor size 3145728 bytes, new threshold 1 (max 3) +- age 1: 3739264 bytes, 3739264 total +: 40345K->3674K(46080K), 0.0014584 secs] 40345K->3674K(199680K), 0.0015063 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] +2021-07-01T10:41:32.259+0800: [GC (Allocation Failure) 2021-07-01T10:41:32.259+0800: [ParNew +Desired survivor size 3145728 bytes, new threshold 3 (max 3) +: 13914K->0K(46080K), 0.0046596 secs] 13914K->13895K(199680K), 0.0046873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] +Heap + par new generation total 46080K, used 35225K [0x05000000, 0x08200000, 0x08200000) + eden space 40960K, 86% used [0x05000000, 0x072667f0, 0x07800000) + from space 5120K, 0% used [0x07800000, 0x07800000, 0x07d00000) + to space 5120K, 0% used [0x07d00000, 0x07d00000, 0x08200000) + concurrent mark-sweep generation total 153600K, used 13895K [0x08200000, 0x11800000, 0x11800000) + Metaspace used 153K, capacity 2280K, committed 2368K, reserved 4480K + +``` ![堆内存常见分配策略 ](./pictures/jvm垃圾回收/堆内存.png) ### 1.1 对象优先在 eden 区分配 From f3023884c9267e73d7f684fd343999b024f7ef37 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 5 Jul 2021 15:57:57 +0800 Subject: [PATCH 102/257] =?UTF-8?q?fix=20arraylist=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/MySQL.md | 1 - docs/java/collection/ArrayList源码+扩容机制分析.md | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 0241d05e..cf1e4833 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -280,5 +280,4 @@ InnoDB 存储引擎在 **分布式事务** 的情况下一般会用到 **SERIALI ## 参考 - 《高性能 MySQL》 - - https://www.omnisci.com/technical-glossary/relational-database diff --git a/docs/java/collection/ArrayList源码+扩容机制分析.md b/docs/java/collection/ArrayList源码+扩容机制分析.md index 8a8c5298..79ae722c 100644 --- a/docs/java/collection/ArrayList源码+扩容机制分析.md +++ b/docs/java/collection/ArrayList源码+扩容机制分析.md @@ -14,7 +14,7 @@ public class ArrayList extends AbstractList - `RandomAccess` 是一个标志接口,表明实现这个这个接口的 List 集合是支持**快速随机访问**的。在 `ArrayList` 中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。 - `ArrayList` 实现了 **`Cloneable` 接口** ,即覆盖了函数`clone()`,能被克隆。 -- `ArrayList` 实现了 `java.io.Serializable `接口,这意味着`ArrayList`支持序列化,能通过序列化去传输。 +- `ArrayList` 实现了 `java.io.Serializable`接口,这意味着`ArrayList`支持序列化,能通过序列化去传输。 ### 1.1. Arraylist 和 Vector 的区别? @@ -594,9 +594,9 @@ public class ArrayList extends AbstractList ``` -细心的同学一定会发现 :**以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。** 下面在我们分析 ArrayList 扩容时会讲到这一点内容! +细心的同学一定会发现 :**以无参数构造方法创建 `ArrayList` 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。** 下面在我们分析 ArrayList 扩容时会讲到这一点内容! -> 补充:JDK7 new无参构造的ArrayList对象时,直接创建了长度是10的Object[]数组elementData 。jdk7中的ArrayList的对象的创建**类似于单例的饿汉式**,而jdk8中的ArrayList的对象的创建**类似于单例的懒汉式**。JDK8的内存优化也值得我们在平时开发中学习。 +> 补充:JDK6 new 无参构造的 `ArrayList` 对象时,直接创建了长度是 10 的 `Object[]` 数组 elementData 。 ### 3.2. 一步一步分析 ArrayList 扩容机制 @@ -751,6 +751,7 @@ public class ArrayList extends AbstractList ``` 场景: + ```java /** * 在此列表中的指定位置插入指定的元素。 From 5473fe976b69ecefaa3ed10e27ccbd55e9596908 Mon Sep 17 00:00:00 2001 From: VinterHe Date: Tue, 6 Jul 2021 14:13:23 +0800 Subject: [PATCH 103/257] =?UTF-8?q?Update=20JVM=E5=9E=83=E5=9C=BE=E5=9B=9E?= =?UTF-8?q?=E6=94=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/JVM垃圾回收.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index 534ca51d..b95be0ba 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -166,7 +166,7 @@ public class JavaGcTest { ``` -注意:如下输出结果中老年代的信息为concurrent mark-sweep generation和以前版本略有不同。age列出了某次GC后是否重新生成了threshold,还有各个年龄占用空间的大小。 +注意:如下输出结果中老年代的信息为concurrent mark-sweep generation和以前版本略有不同。另外还列出了某次GC后是否重新生成了threshold,以及各个年龄占用空间的大小。 ``` 2021-07-01T10:41:32.257+0800: [GC (Allocation Failure) 2021-07-01T10:41:32.257+0800: [ParNew Desired survivor size 3145728 bytes, new threshold 1 (max 3) From 450df55ce018b4008d743c213adfb43154f06bf7 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 6 Jul 2021 17:37:54 +0800 Subject: [PATCH 104/257] =?UTF-8?q?Update=20Kafka=E5=B8=B8=E8=A7=81?= =?UTF-8?q?=E9=9D=A2=E8=AF=95=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message-queue/Kafka常见面试题总结.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md b/docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md index d62c19ec..8b4e6176 100644 --- a/docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md +++ b/docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md @@ -36,7 +36,7 @@ Kafka 主要有两大应用场景: #### 队列模型:早期的消息模型 -![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/队列模型23.png) +![队列模型](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/队列模型23.png) **使用队列(Queue)作为消息通信载体,满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。** 比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。) @@ -50,7 +50,7 @@ Kafka 主要有两大应用场景: 发布-订阅模型主要是为了解决队列模型存在的问题。 -![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/广播模型21312.png) +![发布订阅模型](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E6%A8%A1%E5%9E%8B.png) 发布订阅模型(Pub-Sub) 使用**主题(Topic)** 作为消息通信载体,类似于**广播模式**;发布者发布一条消息,该消息通过主题传递给所有的订阅者,**在一条消息广播之后才订阅的用户则是收不到该条消息的**。 From 4391099006a2a74e1d16dc03f4378c16c5849107 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 6 Jul 2021 22:21:50 +0800 Subject: [PATCH 105/257] =?UTF-8?q?Update=20JVM=E5=9E=83=E5=9C=BE=E5=9B=9E?= =?UTF-8?q?=E6=94=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/JVM垃圾回收.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index b95be0ba..3c4c9e45 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -120,7 +120,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G -XX:+UseParNewGC ``` **示例代码如下:** -``` +```java /* * 本实例用于java GC以后,新生代survivor区域的变化,以及晋升到老年代的时间和方式的测试代码。需要自行分步注释不需要的代码进行反复测试对比 * @@ -166,8 +166,8 @@ public class JavaGcTest { ``` -注意:如下输出结果中老年代的信息为concurrent mark-sweep generation和以前版本略有不同。另外还列出了某次GC后是否重新生成了threshold,以及各个年龄占用空间的大小。 -``` +注意:如下输出结果中老年代的信息为 `concurrent mark-sweep generation` 和以前版本略有不同。另外,还列出了某次GC后是否重新生成了threshold,以及各个年龄占用空间的大小。 +```bash 2021-07-01T10:41:32.257+0800: [GC (Allocation Failure) 2021-07-01T10:41:32.257+0800: [ParNew Desired survivor size 3145728 bytes, new threshold 1 (max 3) - age 1: 3739264 bytes, 3739264 total From ad786cd0704179e3b5b5620e031b65569c0dfc72 Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 9 Jul 2021 18:52:07 +0800 Subject: [PATCH 106/257] =?UTF-8?q?Update=20JVM=E5=9E=83=E5=9C=BE=E5=9B=9E?= =?UTF-8?q?=E6=94=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/JVM垃圾回收.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/java/jvm/JVM垃圾回收.md b/docs/java/jvm/JVM垃圾回收.md index 3c4c9e45..7d22468e 100644 --- a/docs/java/jvm/JVM垃圾回收.md +++ b/docs/java/jvm/JVM垃圾回收.md @@ -313,6 +313,16 @@ public class GCTest { 整堆收集 (Full GC):收集整个 Java 堆和方法区。 +### 1.6 空间分配担保 + +空间分配担保是为了确保在 Minor GC 之前老年代本身还有容纳新生代所有对象的剩余空间。 + +《深入理解Java虚拟机》第三章对于空间分配担保的描述如下: + +> JDK 6 Update 24 之前,在发生 Minor GC 之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那这一次 Minor GC 可以确保是安全的。如果不成立,则虚拟机会先查看 `-XX:HandlePromotionFailure` 参数的设置值是否允许担保失败(Handle Promotion Failure);如果允许,那会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次 Minor GC,尽管这次 Minor GC 是有风险的;如果小于,或者 `-XX: HandlePromotionFailure` 设置不允许冒险,那这时就要改为进行一次 Full GC。 +> +> JDK 6 Update 24之后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行 Minor GC,否则将进行 Full GC。 + ## 2 对象已经死亡? 堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)。 From 144736c68f28cbc4fcdfe38b5bc33b797fa9c199 Mon Sep 17 00:00:00 2001 From: LiuKay Date: Sun, 11 Jul 2021 16:25:59 +0800 Subject: [PATCH 107/257] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=93=BE=E8=B7=AF=E5=B1=82=E5=9B=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络知识总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/network/计算机网络知识总结.md b/docs/network/计算机网络知识总结.md index f64a61b1..8a830818 100644 --- a/docs/network/计算机网络知识总结.md +++ b/docs/network/计算机网络知识总结.md @@ -163,7 +163,7 @@ ## 3. 数据链路层(Data Link Layer) -![数据链路层](https://img-blog.csdnimg.cn/img_convert/8d24d1684552fa9cc824ce72b3087637.png) +![数据链路层](https://www.cloudflare.com/img/learning/ddos/glossary/open-systems-interconnection-model-osi/2-data-link-layer.svg) ### 3.1. 基本术语 From aefa2ccf249c87c40a5c407041268bb5c3f61a96 Mon Sep 17 00:00:00 2001 From: VinterHe Date: Mon, 12 Jul 2021 11:50:06 +0800 Subject: [PATCH 108/257] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8C=85=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E5=8F=8D=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/system-design/naming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/naming.md b/docs/system-design/naming.md index 1c16523c..33d0db49 100644 --- a/docs/system-design/naming.md +++ b/docs/system-design/naming.md @@ -123,7 +123,7 @@ void shouldGet200StatusCodoWhenRequestIsValid() { 正例: `org.apache.dubbo.common.threadlocal` -反例: ~~`org.apache.dubbo.common.threadLocal`~~ +反例: ~~`org.apache_dubbo.Common.threadLocals`~~ **5.抽象类命名使用 Abstract 开头**。 From 88afe4d8af5d7df0d3eaf5d90feb05e3d2ee841a Mon Sep 17 00:00:00 2001 From: ipofss <274694451@qq.com> Date: Tue, 13 Jul 2021 10:39:19 +0800 Subject: [PATCH 109/257] =?UTF-8?q?Update=20AQS=E5=8E=9F=E7=90=86=E4=BB=A5?= =?UTF-8?q?=E5=8F=8AAQS=E5=90=8C=E6=AD=A5=E7=BB=84=E4=BB=B6=E6=80=BB?= =?UTF-8?q?=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/multi-thread/AQS原理以及AQS同步组件总结.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md index 936809f5..86a4ece1 100644 --- a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md +++ b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md @@ -292,7 +292,7 @@ public class SemaphoreExample1 { ```java semaphore.acquire(5);// 获取5个许可,所以可运行线程数量为20/5=4 test(threadnum); -semaphore.release(5);// 获取5个许可,所以可运行线程数量为20/5=4 +semaphore.release(5);// 释放5个许可 ``` 除了 `acquire`方法之外,另一个比较常用的与之对应的方法是`tryAcquire`方法,该方法如果获取不到许可就立即返回 false。 @@ -725,4 +725,4 @@ threadnum:7is finish **Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) \ No newline at end of file +![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) From ab6a36b7aa4729f5d019c4944c3bbaa5426bd337 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 13 Jul 2021 23:18:41 +0800 Subject: [PATCH 110/257] Update basis.md --- docs/operating-system/basis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operating-system/basis.md b/docs/operating-system/basis.md index 49048648..f35bef6e 100644 --- a/docs/operating-system/basis.md +++ b/docs/operating-system/basis.md @@ -337,7 +337,7 @@ - **OPT 页面置换算法(最佳页面置换算法)** :最佳(Optimal, OPT)置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若千页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。一般作为衡量其他置换算法的方法。 - **FIFO(First In First Out) 页面置换算法(先进先出页面置换算法)** : 总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。 -- **LRU (Least Currently Used)页面置换算法(最近最久未使用页面置换算法)** :LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当须淘汰一个页面时,选择现有页面中其 T 值最大的,即最近最久未使用的页面予以淘汰。 +- **LRU (Least Recently Used)页面置换算法(最近最久未使用页面置换算法)** :LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当须淘汰一个页面时,选择现有页面中其 T 值最大的,即最近最久未使用的页面予以淘汰。 - **LFU (Least Frequently Used)页面置换算法(最少使用页面置换算法)** : 该置换算法选择在之前时期使用最少的页面作为淘汰页。 ## Reference From 874a58bcf302d7d4906bcf594bfa0cafd0a57f9c Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 13 Jul 2021 23:25:21 +0800 Subject: [PATCH 111/257] =?UTF-8?q?Update=20=E8=AE=A1=E7=AE=97=E6=9C=BA?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E7=9F=A5=E8=AF=86=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络知识总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/network/计算机网络知识总结.md b/docs/network/计算机网络知识总结.md index 8a830818..7d0db60a 100644 --- a/docs/network/计算机网络知识总结.md +++ b/docs/network/计算机网络知识总结.md @@ -163,7 +163,7 @@ ## 3. 数据链路层(Data Link Layer) -![数据链路层](https://www.cloudflare.com/img/learning/ddos/glossary/open-systems-interconnection-model-osi/2-data-link-layer.svg) +![数据链路层](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/2-data-link-layer.svg) ### 3.1. 基本术语 From 67395906eec2d73a438d99b99c9cce733b2f33ee Mon Sep 17 00:00:00 2001 From: VinterHe Date: Thu, 15 Jul 2021 16:47:24 +0800 Subject: [PATCH 112/257] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../distributed-system/zookeeper/zookeeper-intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md index 4978fb1a..190146d0 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md @@ -109,7 +109,7 @@ ZooKeeper 数据模型采用层次化的多叉树形结构,每个节点上都 强调一句:**ZooKeeper 主要是用来协调服务的,而不是用来存储业务数据的,所以不要放比较大的数据在 znode 上,ZooKeeper 给出的上限是每个结点的数据大小最大是 1M。** -从下图可以更直观地看出:ZooKeeper 节点路径标识方式和 Unix 文件系统路径非常相似,都是由一系列使用斜杠"/"进行分割的路径表示,开发人员可以向这个节点中写人数据,也可以在节点下面创建子节点。这些操作我们后面都会介绍到。 +从下图可以更直观地看出:ZooKeeper 节点路径标识方式和 Unix 文件系统路径非常相似,都是由一系列使用斜杠"/"进行分割的路径表示,开发人员可以向这个节点中写入数据,也可以在节点下面创建子节点。这些操作我们后面都会介绍到。 ![ZooKeeper 数据模型](images/znode-structure.png) @@ -296,4 +296,4 @@ ZAB 协议包括两种基本的模式,分别是 ## 7. 参考 -1. 《从 Paxos 到 ZooKeeper 分布式一致性原理与实践》 \ No newline at end of file +1. 《从 Paxos 到 ZooKeeper 分布式一致性原理与实践》 From bfd6faa26d08caecb6dfd15db58b77699a0a63bd Mon Sep 17 00:00:00 2001 From: VinterHe Date: Thu, 15 Jul 2021 17:17:07 +0800 Subject: [PATCH 113/257] =?UTF-8?q?=E5=A2=9E=E5=8A=A0zookeeper=E9=80=89?= =?UTF-8?q?=E4=B8=BE=E7=9A=84=E8=BF=87=E5=8D=8A=E6=9C=BA=E5=88=B6=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E8=84=91=E8=A3=82=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../distributed-system/zookeeper/zookeeper-intro.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md index 4978fb1a..8c6d9645 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md @@ -265,6 +265,11 @@ ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooK 综上,何必增加那一个不必要的 ZooKeeper 呢? +### 4.4. ZooKeeper 选举的过半机制防止脑裂 +另外过半机制也可以防止脑裂情况的发生。 + +脑裂:对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,比如现在有一个由6台服务器所组成的一个集群,部署在了两个机房,每个机房三台。正常情况下只有一个leader,但是当两个机房中间网络断开的时候,每个机房的三台服务器都会认为另一个机房的三台服务器下线,而选出自己的leader并对外提供服务。若没有过半机制,当网络恢复的时候会发现有两个leader。仿佛是一个大脑(leader)分散成了两个大脑,这就发生了脑裂现象。因为脑裂期间两个大脑都对外提供了服务,这将会带来数据一致性等问题。 + ## 5. ZAB 协议和Paxos 算法 Paxos 算法应该可以说是 ZooKeeper 的灵魂了。但是,ZooKeeper 并没有完全采用 Paxos算法 ,而是使用 ZAB 协议作为其保证数据一致性的核心算法。另外,在ZooKeeper的官方文档中也指出,ZAB协议并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特别为Zookeeper设计的崩溃可恢复的原子消息广播算法。 @@ -296,4 +301,4 @@ ZAB 协议包括两种基本的模式,分别是 ## 7. 参考 -1. 《从 Paxos 到 ZooKeeper 分布式一致性原理与实践》 \ No newline at end of file +1. 《从 Paxos 到 ZooKeeper 分布式一致性原理与实践》 From dd26b350bb91dd9cf15ed0b56ee93c9b445fc380 Mon Sep 17 00:00:00 2001 From: jiangrz <308119975@qq.com> Date: Thu, 15 Jul 2021 23:47:50 +0800 Subject: [PATCH 114/257] =?UTF-8?q?add=20InnoDB=E5=AF=B9MVCC=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + docs/database/InnoDB对MVCC的实现.md | 270 ++++++++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 docs/database/InnoDB对MVCC的实现.md diff --git a/README.md b/README.md index a8609952..6ba56ffb 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle 2. [事务隔离级别(图文详解)]() 3. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/一条sql语句在mysql中如何执行的.md) 4. [关于数据库中如何存储时间的一点思考](docs/database/关于数据库存储时间的一点思考.md) +5. [InnoDB存储引擎对MVCC的实现](docs/database/InnoDB对MVCC的实现.md) ### Redis diff --git a/docs/database/InnoDB对MVCC的实现.md b/docs/database/InnoDB对MVCC的实现.md new file mode 100644 index 00000000..bb2a70b0 --- /dev/null +++ b/docs/database/InnoDB对MVCC的实现.md @@ -0,0 +1,270 @@ + + +- [一致性非锁定读和锁定读](#一致性非锁定读和锁定读) + - [一致性非锁定读](#一致性非锁定读) + - [锁定读](#锁定读) +- [InnoDB对MVCC的实现](#InnoDB对MVCC的实现) + - [隐藏字段](#隐藏字段]) + - [ReadView](#ReadView) + - [undo-log](#undo-log) + - [数据可见性算法](#数据可见性算法) +- [RC、RR隔离级别下MVCC的差异](#RC、RR隔离级别下MVCC的差异) +- [MVCC解决不可重复读问题](#MVCC解决不可重复读问题) + - [在RC下ReadView生成情况](#在RC下ReadView生成情况) + - [在RR下ReadView生成情况](#在RR下ReadView生成情况) +- [MVCC+Next-key-Lock防止幻读](#MVCC➕Next-key-Lock防止幻读) + + + + + +## 一致性非锁定读和锁定读 + +#### 一致性非锁定读 + +对于 [**一致性非锁定读(Consistent Nonlocking Reads)** ](https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html)的实现,通常做法是加一个版本号或者时间戳字段,在更新数据的同时版本号 + 1或者更新时间戳。查询时,将当前可见的版本号与对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见 + +在 `InnoDB` 存储引擎中,[多版本控制 (multi versioning)](https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html) 就是对非锁定读的实现。如果读取的行正在执行 `DELETE` 或 `UPDATE` 操作,这时读取操作不会去等待行上锁的释放。相反地,`InnoDB` 存储引擎会去读取行的一个快照数据,对于这种读取历史数据的方式,我们叫它快照读 (snapshot read) + +在 `Repeatable Read` 和 `Read Committed` 两个隔离级别下,如果是执行普通的 `select` 语句(不包括 `select ... lock in share mode` ,` select ... for update`)则会使用 `一致性非锁定读(MVCC)`。并且在 `Repeatable Read` 下 `MVCC` 实现了可重复读和防止部分幻读 + + + +#### 锁定读 + +如果执行的是下列语句,就是 [**锁定读(Locking Reads)**](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html) + +- select ... lock in share mode +- select ... for update +- insert、update、delete 操作 + + + +在锁定读下,读取的是数据的最新版本,这种读也被称为 `当前读(current read)`。锁定读会对读取到的记录加锁: + +- `select ... lock in share mode`:对记录加 `S` 锁,其它事务也可以加`S`锁,如果加 `x` 锁则会被阻塞 + +- `select ... for update`、`insert`、`update`、`delete `:对记录加 `X` 锁,且其它事务不能加任何锁 + + + +在一致性非锁定读下,即使读取的记录已被其它事务加上 `X` 锁,这时记录也是可以被读取的,即读取的快照数据。上面说了在 `Repeatable Read` 下 `MVCC` 防止了部分幻读,这边的 “部分” 是指在 `一致性非锁定读` 情况下,只能读取到第一次查询之前所插入的数据(根据Read View判断数据可见性,Read View在第一次查询时生成),但如果是`当前读` ,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。**所以 `InnoDB` 在实现`Repeatable Read` 时,如果执行的是当前读,则会对读取的记录使用 `Next-key Lock` ,来防止其它事务在间隙间插入数据** + + + +## InnoDB对MVCC的实现 + +`MVCC` 的实现依赖于:**隐藏字段、Read View、undo log**。在内部实现中,`InnoDB` 通过数据行的 `DB_TRX_ID` 和 `Read View` 来判断数据的可见性,如不可见,则通过数据行的 `DB_ROLL_PTR` 找到 `undo log` 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 `Read View` 之前已经提交的修改和该事务本身做的修改 + + + +#### 隐藏字段 + +在内部,`InnoDB` 存储引擎为每行数据添加了三个 [隐藏字段](https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html): + +- `DB_TRX_ID(6字节)`:表示最后一次插入或更新该行的事务id。此外,`delete` 操作在内部被视为更新,只不过会在记录头 `Record header` 中的 `deleted_flag` 字段将其标记为已删除 +- `DB_ROLL_PTR(7字节)` 回滚指针,指向该行的 `undo log` 。如果该行未被更新,则为空 +- `DB_ROW_ID(6字节)`:如果没有设置主键且该表没有唯一非空索引时,`InnoDB` 会使用该id来生成聚簇索引 + + + +#### ReadView + +[`Read View`](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L298) 主要是用来做可见性判断,里面保存了 “当前对本事务不可见的其他活跃事务” + +主要有以下字段: + +- `m_low_limit_id`:目前出现过的最大的事务ID+1,即下一个将被分配的事务ID。大于这个ID的数据版本均不可见 +- `m_up_limit_id`:活跃事务列表 `m_ids` 中最小的事务ID,如果 `m_ids` 为空,则 `m_up_limit_id` 为 `m_low_limit_id`。小于这个ID的数据版本均可见 +- `m_ids`:`Read View` 创建时其他未提交的活跃事务ID列表。创建 `Read View `时,将当前未提交事务ID记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的。`m_ids` 不包括当前事务自己和已提交的事务(正在内存中) +- `m_creator_trx_id`:创建该 `Read View` 的事务ID + + + +#### undo-log + +`undo log` 主要有两个作用: + +- 当事务回滚时用于将数据恢复到修改前的样子 +- 另一个作用是 `MVCC` ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 `undo log` 读取之前的版本数据,以此实现非锁定读 + + + +**在 `InnoDB` 存储引擎中 `undo log` 分为两种: `insert undo log` 和 `update undo log`:** + + + +1. **`insert undo log`** :指在 `insert` 操作中产生的 `undo log`。因为 `insert` 操作的记录只对事务本身可见,对其他事务不可见,故该 `undo log` 可以在事务提交后直接删除。不需要进行 `purge` 操作 + + + +**`insert` 时的数据初始状态:** + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png) + +2. **`update undo log`** :`update` 或 `delete` 操作中产生的 `undo log`。该 `undo log`可能需要提供 `MVCC` 机制,因此不能在事务提交时就进行删除。提交时放入 `undo log` 链表,等待 `purge线程` 进行最后的删除 + + + +**数据第一次被修改时:** + + + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png) + +**数据第二次被修改时:** + + + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png) + +不同事务或者相同事务的对同一记录行的修改,会使该记录行的 `undo log` 成为一条链表,链首就是最新的记录,链尾就是最早的旧记录 + + + +#### 数据可见性算法 + +在 `InnoDB` 存储引擎中,创建一个新事务后,执行每个 `select` 语句前,都会创建一个快照(Read View),**快照中保存了当前数据库系统中正处于活跃(没有commit)的事务的ID号**。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务ID列表(即m_ids)。当用户在这个事务中要读取某个记录行的时候,`InnoDB` 会将该记录行的 `DB_TRX_ID` 与 `Read View` 中的一些变量及当前事务ID进行比较,判断是否满足可见性条件 + +[具体的比较算法](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L161)如下:[图源](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/#MVCC-1) + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/8778836b-34a8-480b-b8c7-654fe207a8c2.png) + +1. 如果记录 DB_TRX_ID < m_up_limit_id,那么表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照之前就提交了,所以该记录行的值对当前事务是可见的 + +2. 如果 DB_TRX_ID >= m_low_limit_id,那么表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照之后才修改该行,所以该记录行的值对当前事务不可见。跳到步骤5 + +3. m_ids 为空,则表明在当前事务创建快照之前,修改该行的事务就已经提交了,所以该记录行的值对当前事务是可见的 + +4. 如果 m_up_limit_id <= DB_TRX_ID < m_up_limit_id,表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照的时候可能处于“活动状态”或者“已提交状态”;所以就要对活跃事务列表 m_ids 进行查找(源码中是用的二分查找,因为是有序的) + + - 如果在活跃事务列表 m_ids 中能找到 DB_TRX_ID,表明:①在当前事务创建快照前,该记录行的值被事务ID为 DB_TRX_ID 的事务修改了,但没有提交;或者 ②在当前事务创建快照后,该记录行的值被事务ID为 DB_TRX_ID 的事务修改了。这些情况下,这个记录行的值对当前事务都是不可见的。跳到步骤5 + + - 在活跃事务列表中找不到,则表明“id为trx_id的事务”在修改“该记录行的值”后,在“当前事务”创建快照前就已经提交了,所以记录行对当前事务可见 + +5. 在该记录行的 DB_ROLL_PTR 指针所指向的 `undo log` 取出快照记录,用快照记录的 DB_TRX_ID 跳到步骤1重新开始判断,直到找到满足的快照版本或返回空 + + + +## RC和RR隔离级别下MVCC的差异 + +在事务隔离级别 `RC` 和 `RR` (InnoDB存储引擎的默认事务隔离级别)下,` InnoDB` 存储引擎使用 `MVCC`(非锁定一致性读),但它们生成 `Read View` 的时机却不同 + +- 在 RC 隔离级别下的 **`每次select`** 查询前都生成一个`Read View` (m_ids列表) +- 在 RR 隔离级别下只在事务开始后 **`第一次select`** 数据前生成一个`Read View`(m_ids列表) + + + +## MVCC解决不可重复读问题 + +虽然 RC 和 RR 都通过 `MVCC` 来读取快照数据,但由于 **生成 Read View 时机不同**,从而在 RR 级别下实现可重复读 + +举个例子: + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png) + + +#### **在RC下ReadView生成情况** + +1. **`假设时间线来到 T4 ,那么此时数据行 id = 1 的版本链为`:** + + ![markdown](https://ddmcc-1255635056.file.myqcloud.com/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png) + +由于 RC 级别下每次查询都会生成` Read View` ,并且事务101、102 并未提交,此时 `103` 事务生成的 `Read View` 中活跃的事务 **`m_ids` 为:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 + +- 此时最新记录的 `DB_TRX_ID` 为101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 +- 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` + + + +2. **`时间线来到 T6 ,数据的版本链为`:** + + ![markdown](https://ddmcc-1255635056.file.myqcloud.com/528559e9-dae8-4d14-b78d-a5b657c88391.png) + +因为在 RC 级别下,重新生成 `Read View`,这时事务101已经提交,102并未提交,所以此时 `Read View` 中活跃的事务 **`m_ids`:[102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:102,`m_creator_trx_id`为:103 + +- 此时最新记录的 `DB_TRX_ID` 为102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 + +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为101,满足 102 < m_up_limit_id,记录可见,所以在 `T6` 时间点查询到数据为 `name = 李四`,与时间 T4 查询到的结果不一致,不可重复读! + + + +3. **`时间线来到 T9 ,数据的版本链为`:** + + + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/6f82703c-36a1-4458-90fe-d7f4edbac71a.png) + +重新生成 `Read View`, 这时事务 101 和 102 都已经提交,所以 **m_ids** 为空,则 m_up_limit_id = m_low_limit_id = 104,最新版本事务ID为102,满足 102 < m_low_limit_id,可见,查询结果为 `name = 赵六` + + + +> **总结:** **在RC隔离级别下,事务在每次查询开始时都会生成并设置新的 Read View,所以导致不可重复读** + + +#### **在RR下ReadView生成情况** + +**在可重复读级别下,只会在事务开始后第一次读取数据时生成一个Read View(m_ids列表)** + +1. **`在 T4 情况下的版本链为`:** + + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/0e906b95-c916-4f30-beda-9cb3e49746bf.png) + +在当前执行 `select` 语句时生成一个 `Read View`,此时 **`m_ids`:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 + +此时和 RC 级别下一样: + +- 最新记录的 `DB_TRX_ID` 为101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 +- 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` + + +2. **`时间点 T6 情况下`:** + + ![markdown](https://ddmcc-1255635056.file.myqcloud.com/79ed6142-7664-4e0b-9023-cf546586aa39.png) + + 在 RR 级别下只会生成一次`Read View`,所以此时依然沿用 **`m_ids` :[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 + + + - 最新记录的 `DB_TRX_ID` 为102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 + + - 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为101,不可见 + + - 继续根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 + + - 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` + + + +3. **时间点 T9 情况下:** + +![markdown](https://ddmcc-1255635056.file.myqcloud.com/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png) + + + +此时情况跟 T6 完全一样,由于已经生成了 `Read View`,此时依然沿用 **`m_ids` :[101,102]** ,所以查询结果依然是 `name = 菜花` + + + +## MVCC➕Next-key-Lock防止幻读 + +`InnoDB`存储引擎在 RR 级别下通过 `MVCC`和 `Next-key Lock` 来解决幻读问题: + +1. **执行普通 `select`,此时会以 `MVCC` 快照读的方式读取数据** + +在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 `Read View` ,并使用至事务提交。所以在生成 `Read View` 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读” + +2. **执行select...for update/lock in share mode、insert、update、delete等当前读** + +在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!`InnoDB` 使用 [Next-key Lock](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-next-key-locks) 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读 + + + +## 参考 + +- **《MySQL技术内幕InnoDB存储引擎第2版》** + +- [Innodb中的事务隔离级别和锁的关系](https://tech.meituan.com/2014/08/20/innodb-lock.html) +- [MySQL事务与MVCC如何实现的隔离级别](https://blog.csdn.net/qq_35190492/article/details/109044141) \ No newline at end of file From c3b3f5cf589626f16307e114d7a414d18e528056 Mon Sep 17 00:00:00 2001 From: VinterHe Date: Fri, 16 Jul 2021 09:47:19 +0800 Subject: [PATCH 115/257] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../distributed-system/zookeeper/zookeeper-plus.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md b/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md index b70ab4c0..44b5abf6 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md @@ -373,7 +373,7 @@ 看到这里是不是觉得 `zookeeper` 实在是太强大了,它怎么能这么能干! -别急,它能干的事情还很多呢。可能我们会有这样的需求,我们需要了解整个集群中有多少机器在工作,我们想对及群众的每台机器的运行时状态进行数据采集,对集群中机器进行上下线操作等等。 +别急,它能干的事情还很多呢。可能我们会有这样的需求,我们需要了解整个集群中有多少机器在工作,我们想对集群中的每台机器的运行时状态进行数据采集,对集群中机器进行上下线操作等等。 而 `zookeeper` 天然支持的 `watcher` 和 临时节点能很好的实现这些需求。我们可以为每条机器创建临时节点,并监控其父节点,如果子节点列表有变动(我们可能创建删除了临时节点),那么我们可以使用在其父节点绑定的 `watcher` 进行状态监控和回调。 @@ -405,4 +405,4 @@ * `zookeeper` 的典型应用场景,比如选主,注册中心等等。 - 如果忘了可以回去看看再次理解一下,如果有疑问和建议欢迎提出🤝🤝🤝。 \ No newline at end of file + 如果忘了可以回去看看再次理解一下,如果有疑问和建议欢迎提出🤝🤝🤝。 From cf5193ca5e5e74d0cfe30f5931556d4c780371c9 Mon Sep 17 00:00:00 2001 From: fengxiao <1063371248@qq.com> Date: Sun, 18 Jul 2021 13:38:44 +0800 Subject: [PATCH 116/257] =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 07028ccf..5b593a72 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -113,7 +113,7 @@ ## 三 TCP,UDP 协议的区别 ![TCP、UDP协议的区别](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp-vs-udp.jpg) -UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等 +UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 却是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等 TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 From edecf8fdd41505752b39585d23fad5412ff97c2b Mon Sep 17 00:00:00 2001 From: VinterHe Date: Sun, 18 Jul 2021 14:53:55 +0800 Subject: [PATCH 117/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9ZooKeeper=20=E9=80=89?= =?UTF-8?q?=E4=B8=BE=E7=9A=84=E8=BF=87=E5=8D=8A=E6=9C=BA=E5=88=B6=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E8=84=91=E8=A3=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../distributed-system/zookeeper/zookeeper-intro.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md index 8c6d9645..9f52ec18 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md @@ -266,9 +266,12 @@ ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooK 综上,何必增加那一个不必要的 ZooKeeper 呢? ### 4.4. ZooKeeper 选举的过半机制防止脑裂 -另外过半机制也可以防止脑裂情况的发生。 -脑裂:对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,比如现在有一个由6台服务器所组成的一个集群,部署在了两个机房,每个机房三台。正常情况下只有一个leader,但是当两个机房中间网络断开的时候,每个机房的三台服务器都会认为另一个机房的三台服务器下线,而选出自己的leader并对外提供服务。若没有过半机制,当网络恢复的时候会发现有两个leader。仿佛是一个大脑(leader)分散成了两个大脑,这就发生了脑裂现象。因为脑裂期间两个大脑都对外提供了服务,这将会带来数据一致性等问题。 +集群脑裂:对于一个集群,通常多台机器会部署在不同机房,来提高这个集群的可用性。保证可用性的同时,会发生一种机房间网络线路故障,导致机房间网络不通,而集群被割裂成几个小集群。这时候子集群各自选主导致“脑裂”的情况。 + +举例说明:比如现在有一个由6台服务器所组成的一个集群,部署在了两个机房,每个机房三台。正常情况下只有一个leader,但是当两个机房中间网络断开的时候,每个机房的三台服务器都会认为另一个机房的三台服务器下线,而选出自己的leader并对外提供服务。若没有过半机制,当网络恢复的时候会发现有两个leader。仿佛是一个大脑(leader)分散成了两个大脑,这就发生了脑裂现象。因为脑裂期间两个大脑都可能对外提供了服务,这将会带来数据一致性等问题。 + +过半机制防止脑裂:ZooKeeper的过半机制导致不可能产生两个leader,因为少于等于一半是不可能产生leader的,这就使得不论机房的机器如何分配都不可能发生脑裂。 ## 5. ZAB 协议和Paxos 算法 From 473d7200a1ae6607296697ffedf833162eac8fc8 Mon Sep 17 00:00:00 2001 From: wulnm Date: Mon, 19 Jul 2021 13:25:02 +0800 Subject: [PATCH 118/257] =?UTF-8?q?=E5=A2=9E=E5=8A=A0HashSet=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=85=83=E7=B4=A0=E6=96=B9=E6=B3=95=E7=9A=84=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0&typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java集合框架常见面试题.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 2db5c4b1..5c0c5b38 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -432,10 +432,31 @@ TreeMap treeMap = new TreeMap<>((person1, person2) -> { ### 1.4.4. HashSet 如何检查重复 -以下内容摘自我的 Java 启蒙书《Head fist java》第二版: +以下内容摘自我的 Java 启蒙书《Head first java》第二版: 当你把对象加入`HashSet`时,`HashSet` 会先计算对象的`hashcode`值来判断对象加入的位置,同时也会与其他加入的对象的 `hashcode` 值作比较,如果没有相符的 `hashcode`,`HashSet` 会假设对象没有重复出现。但是如果发现有相同 `hashcode` 值的对象,这时会调用`equals()`方法来检查 `hashcode` 相等的对象是否真的相同。如果两者相同,`HashSet` 就不会让加入操作成功。 +在openjdk8中,`HashSet`的`add()`方法只是简单的调用了`HashMap`的`put()`方法,并且判断了一下返回值以确保是否有重复元素。直接看一下`HashSet`中的源码: +```java +// Returns: true if this set did not already contain the specified element +// 返回值:当set中没有包含add的元素时返回真 +public boolean add(E e) { + return map.put(e, PRESENT)==null; +} +``` + +而在`HashMap`的`putVal()`方法中也能看到如下说明: +```java +// Returns : previous value, or null if none +// 返回值:如果插入位置没有元素返回null,否则返回上一个元素 +final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { +... +} +``` + +也就是说,在openjdk8中,实际上无论`HashSet`中是否已经存在了某元素,`HashSet`都会直接插入,只是会在`add()`方法的返回值处告诉我们插入前是否存在相同元素。 + **`hashCode()`与 `equals()` 的相关规定:** 1. 如果两个对象相等,则 `hashcode` 一定也是相同的 From 66dd9aa1c2e7478067801ec5a336cdbd68477f58 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 21 Jul 2021 09:34:39 +0800 Subject: [PATCH 119/257] =?UTF-8?q?zookeeper=20=E8=84=91=E8=A3=82=E7=8E=B0?= =?UTF-8?q?=E8=B1=A1=E6=8F=8F=E8=BF=B0=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zookeeper/zookeeper-intro.md | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md index 715a870e..8178d303 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md @@ -1,4 +1,3 @@ - @@ -13,7 +12,7 @@ - [3. ZooKeeper 重要概念解读](#3-zookeeper-重要概念解读) - [3.1. Data model(数据模型)](#31-data-model数据模型) - [3.2. znode(数据节点)](#32-znode数据节点) - - [3.2.1. znode 4种类型](#321-znode-4种类型) + - [3.2.1. znode 4 种类型](#321-znode-4种类型) - [3.2.2. znode 数据结构](#322-znode-数据结构) - [3.3. 版本(version)](#33-版本version) - [3.4. ACL(权限控制)](#34-acl权限控制) @@ -23,7 +22,7 @@ - [4.1. ZooKeeper 集群角色](#41-zookeeper-集群角色) - [4.2. ZooKeeper 集群中的服务器状态](#42-zookeeper-集群中的服务器状态) - [4.3. ZooKeeper 集群为啥最好奇数台?](#43-zookeeper-集群为啥最好奇数台) -- [5. ZAB 协议和Paxos 算法](#5-zab-协议和paxos-算法) +- [5. ZAB 协议和 Paxos 算法](#5-zab-协议和paxos-算法) - [5.1. ZAB 协议介绍](#51-zab-协议介绍) - [5.2. ZAB 协议两种基本的模式:崩溃恢复和消息广播](#52-zab-协议两种基本的模式崩溃恢复和消息广播) - [6. 总结](#6-总结) @@ -31,7 +30,6 @@ - ## 1. 前言 相信大家对 ZooKeeper 应该不算陌生。但是你真的了解 ZooKeeper 到底有啥用不?如果别人/面试官让你给他讲讲对于 ZooKeeper 的认识,你能回答到什么地步呢? @@ -50,7 +48,7 @@ 另外,本文不光会涉及到 ZooKeeper 的一些概念,后面的文章会介绍到 ZooKeeper 常见命令的使用以及使用 Apache Curator 作为 ZooKeeper 的客户端。 -*如果文章有任何需要改善和完善的地方,欢迎在评论区指出,共同进步!* +_如果文章有任何需要改善和完善的地方,欢迎在评论区指出,共同进步!_ ## 2. ZooKeeper 介绍 @@ -117,7 +115,7 @@ ZooKeeper 数据模型采用层次化的多叉树形结构,每个节点上都 介绍了 ZooKeeper 树形数据模型之后,我们知道每个数据节点在 ZooKeeper 中被称为 **znode**,它是 ZooKeeper 中数据的最小单元。你要存放的数据就放在上面,是你使用 ZooKeeper 过程中经常需要接触到的一个概念。 -#### 3.2.1. znode 4种类型 +#### 3.2.1. znode 4 种类型 我们通常是将 znode 分为 4 大类: @@ -260,6 +258,7 @@ ZooKeeper 集群中的所有机器通过一个 **Leader 选举过程** 来选定 ### 4.3. ZooKeeper 集群为啥最好奇数台? ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才依然可用。假如我们的集群中有 n 台 ZooKeeper 服务器,那么也就是剩下的服务数必须大于 n/2。先说一下结论,2n 和 2n-1 的容忍度是一样的,都是 n-1,大家可以先自己仔细想一想,这应该是一个很简单的数学问题了。 + 比如假如我们有 3 台,那么最大允许宕掉 1 台 ZooKeeper 服务器,如果我们有 4 台的的时候也同样只允许宕掉 1 台。 假如我们有 5 台,那么最大允许宕掉 2 台 ZooKeeper 服务器,如果我们有 6 台的的时候也同样只允许宕掉 2 台。 @@ -267,15 +266,19 @@ ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooK ### 4.4. ZooKeeper 选举的过半机制防止脑裂 -集群脑裂:对于一个集群,通常多台机器会部署在不同机房,来提高这个集群的可用性。保证可用性的同时,会发生一种机房间网络线路故障,导致机房间网络不通,而集群被割裂成几个小集群。这时候子集群各自选主导致“脑裂”的情况。 +**何为集群脑裂?** -举例说明:比如现在有一个由6台服务器所组成的一个集群,部署在了两个机房,每个机房三台。正常情况下只有一个leader,但是当两个机房中间网络断开的时候,每个机房的三台服务器都会认为另一个机房的三台服务器下线,而选出自己的leader并对外提供服务。若没有过半机制,当网络恢复的时候会发现有两个leader。仿佛是一个大脑(leader)分散成了两个大脑,这就发生了脑裂现象。因为脑裂期间两个大脑都可能对外提供了服务,这将会带来数据一致性等问题。 +对于一个集群,通常多台机器会部署在不同机房,来提高这个集群的可用性。保证可用性的同时,会发生一种机房间网络线路故障,导致机房间网络不通,而集群被割裂成几个小集群。这时候子集群各自选主导致“脑裂”的情况。 -过半机制防止脑裂:ZooKeeper的过半机制导致不可能产生两个leader,因为少于等于一半是不可能产生leader的,这就使得不论机房的机器如何分配都不可能发生脑裂。 +举例说明:比如现在有一个由 6 台服务器所组成的一个集群,部署在了 2 个机房,每个机房 3 台。正常情况下只有 1 个 leader,但是当两个机房中间网络断开的时候,每个机房的 3 台服务器都会认为另一个机房的 3 台服务器下线,而选出自己的 leader 并对外提供服务。若没有过半机制,当网络恢复的时候会发现有 2 个 leader。仿佛是 1 个大脑(leader)分散成了 2 个大脑,这就发生了脑裂现象。脑裂期间 2 个大脑都可能对外提供了服务,这将会带来数据一致性等问题。 -## 5. ZAB 协议和Paxos 算法 +**过半机制是如何防止脑裂现象产生的?** -Paxos 算法应该可以说是 ZooKeeper 的灵魂了。但是,ZooKeeper 并没有完全采用 Paxos算法 ,而是使用 ZAB 协议作为其保证数据一致性的核心算法。另外,在ZooKeeper的官方文档中也指出,ZAB协议并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特别为Zookeeper设计的崩溃可恢复的原子消息广播算法。 +ZooKeeper 的过半机制导致不可能产生 2 个 leader,因为少于等于一半是不可能产生 leader 的,这就使得不论机房的机器如何分配都不可能发生脑裂。 + +## 5. ZAB 协议和 Paxos 算法 + +Paxos 算法应该可以说是 ZooKeeper 的灵魂了。但是,ZooKeeper 并没有完全采用 Paxos 算法 ,而是使用 ZAB 协议作为其保证数据一致性的核心算法。另外,在 ZooKeeper 的官方文档中也指出,ZAB 协议并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特别为 Zookeeper 设计的崩溃可恢复的原子消息广播算法。 ### 5.1. ZAB 协议介绍 @@ -283,15 +286,15 @@ ZAB(ZooKeeper Atomic Broadcast 原子广播) 协议是为分布式协调服 ### 5.2. ZAB 协议两种基本的模式:崩溃恢复和消息广播 -ZAB 协议包括两种基本的模式,分别是 +ZAB 协议包括两种基本的模式,分别是 -- **崩溃恢复** :当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的 Leader 服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,**所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader服务器的数据状态保持一致**。 -- **消息广播** :**当集群中已经有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。** 当一台同样遵守ZAB协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到Leader所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。 +- **崩溃恢复** :当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的 Leader 服务器,同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。其中,**所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和 Leader 服务器的数据状态保持一致**。 +- **消息广播** :**当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。** 当一台同样遵守 ZAB 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个 Leader 服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。 -关于 **ZAB 协议&Paxos算法** 需要讲和理解的东西太多了,具体可以看下面这两篇文章: +关于 **ZAB 协议&Paxos 算法** 需要讲和理解的东西太多了,具体可以看下面这两篇文章: -- [图解 Paxos 一致性协议](http://codemacro.com/2014/10/15/explain-poxos/) -- [Zookeeper ZAB 协议分析](https://dbaplus.cn/news-141-1875-1.html) +- [图解 Paxos 一致性协议](http://codemacro.com/2014/10/15/explain-poxos/) +- [Zookeeper ZAB 协议分析](https://dbaplus.cn/news-141-1875-1.html) ## 6. 总结 From 4c8d1a38e8dece567ee80702ef34b7633907d3ae Mon Sep 17 00:00:00 2001 From: callmePicacho <38685653+callmePicacho@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:51:23 +0800 Subject: [PATCH 120/257] =?UTF-8?q?Update=20CAP=E7=90=86=E8=AE=BA.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix typo --- docs/system-design/distributed-system/CAP理论.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/CAP理论.md b/docs/system-design/distributed-system/CAP理论.md index d12ffaa1..1a038357 100644 --- a/docs/system-design/distributed-system/CAP理论.md +++ b/docs/system-design/distributed-system/CAP理论.md @@ -26,7 +26,7 @@ CAP 理论的提出者布鲁尔在提出 CAP 猜想的时候,并没有详细 因此,对于 CAP 的民间解读有很多,一般比较被大家推荐的是下面 👇 这种版本的解。 -在理论计算机科学中,CAP 定理(CAP theorem)指出对于一个分布式系统来说,当设计读写操作时,只能能同时满足以下三点中的两个: +在理论计算机科学中,CAP 定理(CAP theorem)指出对于一个分布式系统来说,当设计读写操作时,只能同时满足以下三点中的两个: - **一致性(Consistence)** : 所有节点访问同一份最新的数据副本 - **可用性(Availability)**: 非故障的节点在合理的时间内返回合理的响应(不是错误或者超时的响应)。 @@ -84,4 +84,4 @@ CAP 理论的提出者布鲁尔在提出 CAP 猜想的时候,并没有详细 1. [CAP 定理简化](https://medium.com/@ravindraprasad/cap-theorem-simplified-28499a67eab4) (英文,有趣的案例) 2. [神一样的 CAP 理论被应用在何方](https://juejin.im/post/6844903936718012430) (中文,列举了很多实际的例子) -3. [请停止呼叫数据库 CP 或 AP ](https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html) (英文,带给你不一样的思考) \ No newline at end of file +3. [请停止呼叫数据库 CP 或 AP ](https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html) (英文,带给你不一样的思考) From 250c209ca76720cb11756293e985cff090bd4ee5 Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 23 Jul 2021 19:00:27 +0800 Subject: [PATCH 121/257] =?UTF-8?q?Update=20Github=E6=8A=80=E5=B7=A7.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tools/Github技巧.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tools/Github技巧.md b/docs/tools/Github技巧.md index 512bf7af..c77cc2cf 100644 --- a/docs/tools/Github技巧.md +++ b/docs/tools/Github技巧.md @@ -1,4 +1,4 @@ -我使用 Github 已经有 5 年多了,今天毫无保留地把自己觉得比较有用的 Gihub 小技巧送给关注 JavaGuide 的各位小伙伴。 +我使用 Github 已经有 5 年多了,今天毫无保留地把自己觉得比较有用的 Github 小技巧送给关注 JavaGuide 的各位小伙伴。 这篇文章肝了很久,就挺用心的,大家看内容就知道了。 @@ -18,7 +18,7 @@ Github 目前支持在个人主页自定义展示一些内容。展示效果如下图所示。 -![个性化首页展示效果](/Users/guide/Library/Application Support/typora-user-images/image-20210616221212259.png) +![个性化首页展示效果](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210616221212259.png) 想要做到这样非常简单,你只需要创建一个和你的 Github 账户同名的仓库,然后自定义`README.md`的内容即可。 @@ -56,7 +56,7 @@ Github 目前支持在个人主页自定义展示一些内容。展示效果如 ## 5. 高效阅读 Github 项目的源代码 -Github 前段时间推出的 Codespaces 可以提供类似 VS Code 的在线 IDE,不过目前还没还没完全开发使用。 +Github 前段时间推出的 Codespaces 可以提供类似 VS Code 的在线 IDE,不过目前还没有完全开发使用。 简单介绍几种我最常用的阅读 Github 项目源代码的方式。 From 387abcdd7fd736b71fd8ff13b551c2be6bc68bce Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sun, 25 Jul 2021 01:45:17 +0800 Subject: [PATCH 122/257] =?UTF-8?q?Update=20serialization=20part=20in=20Ja?= =?UTF-8?q?va=E5=9F=BA=E7=A1=80=E7=9F=A5=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index e624f6f1..6fbc5397 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -1348,9 +1348,14 @@ try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new F ### Java 序列化中如果有些字段不想进行序列化,怎么办? -对于不想进行序列化的变量,使用`transient`关键字修饰。` +对于不想进行序列化的变量,使用 `transient` 关键字修饰。 -`transient` 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 `transient` 修饰的变量值不会被持久化和恢复。`transient` 只能修饰变量,不能修饰类和方法。 +`transient` 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 `transient` 修饰的变量值不会被持久化和恢复。 + +关于 `transient` 还有几点注意: +- `transient` 只能修饰变量,不能修饰类和方法。 +- `transient` 修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰 `int` 类型,那么反序列后结果就是 `0`。 +- `static` 变量因为不属于任何对象(Object),所以无论有没有 `transient` 关键字修饰,均不会被序列化。 ### 获取用键盘输入常用的两种方法 From edf813ab70f5b551fa8213fd85ea6abf8bb4eea1 Mon Sep 17 00:00:00 2001 From: VinterHe Date: Mon, 26 Jul 2021 15:58:01 +0800 Subject: [PATCH 123/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=B9CountDownLat?= =?UTF-8?q?ch=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../multi-thread/AQS原理以及AQS同步组件总结.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md index 86a4ece1..e7d49d6a 100644 --- a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md +++ b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md @@ -227,7 +227,11 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true 以 `ReentrantLock` 为例,state 初始化为 0,表示未锁定状态。A 线程 `lock()` 时,会调用 `tryAcquire()`独占该锁并将 state+1。此后,其他线程再 `tryAcquire()` 时就会失败,直到 A 线程 unlock()到 state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A 线程自己是可以重复获取此锁的(state 会累加),这就是可重入的概念。但要注意,获取多少次就要释放多么次,这样才能保证 state 是能回到零态的。 -再以 `CountDownLatch` 以例,任务分为 N 个子线程去执行,state 也初始化为 N(注意 N 要与线程个数一致)。这 N 个子线程是并行执行的,每个子线程执行完后 `countDown()` 一次,state 会 CAS(Compare and Swap)减 1。等到所有子线程都执行完后(即 state=0),会 unpark()主调用线程,然后主调用线程就会从 `await()` 函数返回,继续后余动作。 +再以 `CountDownLatch` 以例,任务分为 N 个子线程去执行,state 也初始化为 N(也可以不初始化为N,不初始化为N,state减到0也会从await()返回)。这 N 个子线程是并行执行的,每个子线程执行完后 `countDown()` 一次,state 会 CAS(Compare and Swap)减 1。等到state=0,会 unpark()主调用线程,然后主调用线程就会从 `await()` 函数返回,继续后余动作。 + +所以CountDownLatch可以做倒计数器,减到0后唤醒的线程可以对线程池进行处理,比如关闭线程池。BOSS直聘面试官提过一个问题如下: + +现在有8个赛道进行比赛,而我只需要知道前三名就够了,可以怎么实现?大家可以自己思考这个问题了。 一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现`tryAcquire-tryRelease`、`tryAcquireShared-tryReleaseShared`中的一种即可。但 AQS 也支持自定义同步器同时实现独占和共享两种方式,如`ReentrantReadWriteLock`。 From c2a80902e70619033870ba8ce3ed2049e52e29b2 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 26 Jul 2021 21:50:07 +0800 Subject: [PATCH 124/257] =?UTF-8?q?Update=20=E5=9B=BE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/dataStructures-algorithms/data-structure/图.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dataStructures-algorithms/data-structure/图.md b/docs/dataStructures-algorithms/data-structure/图.md index 71a00d8f..32123a46 100644 --- a/docs/dataStructures-algorithms/data-structure/图.md +++ b/docs/dataStructures-algorithms/data-structure/图.md @@ -11,7 +11,7 @@ - 线性数据结构的元素满足唯一的线性关系,每个元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继。 - 树形数据结构的元素之间有着明显的层次关系。 -但是,树形结构的元素之间的关系是任意的。 +但是,图形结构的元素之间的关系是任意的。 **何为图呢?** 简单来说,图就是由顶点的有穷非空集合和顶点之间的边组成的集合。通常表示为:**G(V,E)**,其中,G表示一个图,V表示顶点的集合,E表示边的集合。 From 967cde4c80bc337aca8c04a8d7b4aa3514a6a391 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 27 Jul 2021 11:09:28 +0800 Subject: [PATCH 125/257] =?UTF-8?q?Update=20AQS=E5=8E=9F=E7=90=86=E4=BB=A5?= =?UTF-8?q?=E5=8F=8AAQS=E5=90=8C=E6=AD=A5=E7=BB=84=E4=BB=B6=E6=80=BB?= =?UTF-8?q?=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AQS原理以及AQS同步组件总结.md | 186 ++++++++---------- 1 file changed, 77 insertions(+), 109 deletions(-) diff --git a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md index e7d49d6a..4edc32d1 100644 --- a/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md +++ b/docs/java/multi-thread/AQS原理以及AQS同步组件总结.md @@ -1,48 +1,34 @@ -点击关注[公众号](#公众号 "公众号")及时获取笔主最新更新文章,并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。 +开始之前,先来看几道常见的面试题!建议你带着这些问题来看这篇文章: - +- 何为 AQS?AQS 原理了解吗? +- `CountDownLatch` 和 `CyclicBarrier` 了解吗?两者的区别是什么? +- 用过 `Semaphore` 吗?应用场景了解吗? +- ...... -- [1 AQS 简单介绍](#1-aqs-简单介绍) -- [2 AQS 原理](#2-aqs-原理) - - [2.1 AQS 原理概览](#21-aqs-原理概览) - - [2.2 AQS 对资源的共享方式](#22-aqs-对资源的共享方式) - - [2.3 AQS 底层使用了模板方法模式](#23-aqs-底层使用了模板方法模式) -- [3 Semaphore(信号量)-允许多个线程同时访问](#3-semaphore信号量-允许多个线程同时访问) -- [4 CountDownLatch (倒计时器)](#4-countdownlatch-倒计时器) - - [4.1 CountDownLatch 的三种典型用法](#41-countdownlatch-的三种典型用法) - - [4.2 CountDownLatch 的使用示例](#42-countdownlatch-的使用示例) - - [4.3 CountDownLatch 的不足](#43-countdownlatch-的不足) - - [4.4 CountDownLatch 常见面试题](#44-countdownlatch-相常见面试题) -- [5 CyclicBarrier(循环栅栏)](#5-cyclicbarrier循环栅栏) - - [5.1 CyclicBarrier 的应用场景](#51-cyclicbarrier-的应用场景) - - [5.2 CyclicBarrier 的使用示例](#52-cyclicbarrier-的使用示例) - - [5.3 `CyclicBarrier`源码分析](#53-cyclicbarrier源码分析) - - [5.4 CyclicBarrier 和 CountDownLatch 的区别](#54-cyclicbarrier-和-countdownlatch-的区别) -- [6 ReentrantLock 和 ReentrantReadWriteLock](#6-reentrantlock-和-reentrantreadwritelock) -- [参考](#参考) -- [公众号](#公众号) +## AQS 简单介绍 - - -> 常见问题:AQS 原理?;CountDownLatch 和 CyclicBarrier 了解吗,两者的区别是什么?用过 Semaphore 吗? - -### 1 AQS 简单介绍 - -AQS 的全称为(`AbstractQueuedSynchronizer`),这个类在 `java.util.concurrent.locks` 包下面。 +AQS 的全称为 `AbstractQueuedSynchronizer` ,翻译过来的意思就是抽象队列同步器。这个类在 `java.util.concurrent.locks` 包下面。 ![enter image description here](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/Java%20%E7%A8%8B%E5%BA%8F%E5%91%98%E5%BF%85%E5%A4%87%EF%BC%9A%E5%B9%B6%E5%8F%91%E7%9F%A5%E8%AF%86%E7%B3%BB%E7%BB%9F%E6%80%BB%E7%BB%93/AQS.png) -AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 `ReentrantLock`,`Semaphore`,其他的诸如 `ReentrantReadWriteLock`,`SynchronousQueue`,`FutureTask`(jdk1.7) 等等皆是基于 AQS 的。当然,我们自己也能利用 AQS 非常轻松容易地构造出符合我们自己需求的同步器。 +AQS 就是一个抽象类,主要用来构建锁和同步器。 -### 2 AQS 原理 +```java +public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable { +} +``` + +AQS 为构建锁和同步器提供了一些通用功能的是实现,因此,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 `ReentrantLock`,`Semaphore`,其他的诸如 `ReentrantReadWriteLock`,`SynchronousQueue`,`FutureTask`(jdk1.7) 等等皆是基于 AQS 的。 + +## AQS 原理 > 在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于 AQS 原理的理解”。下面给大家一个示例供大家参考,面试不是背题,大家一定要加入自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。 下面大部分内容其实在 AQS 类注释上已经给出了,不过是英语看着比较吃力一点,感兴趣的话可以看看源码。 -#### 2.1 AQS 原理概览 +### AQS 原理概览 -**AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。** +AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 **CLH 队列锁**实现的,即将暂时获取不到锁的线程加入到队列中。 > CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS 是将每条请求共享资源的线程封装成一个 CLH 锁队列的一个结点(Node)来实现锁的分配。 @@ -56,7 +42,7 @@ AQS 使用一个 int 成员变量来表示同步状态,通过内置的 FIFO private volatile int state;//共享变量,使用volatile修饰保证线程可见性 ``` -状态信息通过 protected 类型的`getState`,`setState`,`compareAndSetState`进行操作 +状态信息通过 `protected` 类型的`getState()`,`setState()`,`compareAndSetState()` 进行操作 ```java //返回同步状态的当前值 @@ -73,16 +59,16 @@ protected final boolean compareAndSetState(int expect, int update) { } ``` -#### 2.2 AQS 对资源的共享方式 +### AQS 对资源的共享方式 -**AQS 定义两种资源共享方式** +AQS 定义两种资源共享方式 **1)Exclusive**(独占) -只有一个线程能执行,如 `ReentrantLock`。又可分为公平锁和非公平锁,`ReentrantLock` 同时支持两种锁,下面以 `ReentrantLock` 对这两种锁的定义做介绍: +只有一个线程能执行,如 `ReentrantLock`。又可分为公平锁和非公平锁,`ReentrantLock` 同时支持两种锁,下面以 `ReentrantLock` 对这两种锁的定义做介绍: -- 公平锁:按照线程在队列中的排队顺序,先到者先拿到锁 -- 非公平锁:当线程要获取锁时,先通过两次 CAS 操作去抢锁,如果没抢到,当前线程再加入到队列中等待唤醒。 +- **公平锁** :按照线程在队列中的排队顺序,先到者先拿到锁 +- **非公平锁** :当线程要获取锁时,先通过两次 CAS 操作去抢锁,如果没抢到,当前线程再加入到队列中等待唤醒。 > 说明:下面这部分关于 `ReentrantLock` 源代码内容节选自:https://www.javadoop.com/post/AbstractQueuedSynchronizer-2 ,这是一篇很不错文章,推荐阅读。 @@ -138,7 +124,7 @@ static final class FairSync extends Sync { } ``` -非公平锁的 lock 方法: +非公平锁的 `lock` 方法: ```java static final class NonfairSync extends Sync { @@ -201,7 +187,7 @@ final boolean nonfairTryAcquire(int acquires) { 不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源 state 的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS 已经在上层已经帮我们实现好了。 -#### 2.3 AQS 底层使用了模板方法模式 +### AQS 底层使用了模板方法模式 同步器的设计是基于模板方法模式的,如果需要自定义同步器一般的方式是这样(模板方法模式很经典的一个应用): @@ -210,7 +196,9 @@ final boolean nonfairTryAcquire(int acquires) { 这和我们以往通过实现接口的方式有很大区别,这是模板方法模式很经典的一个运用,下面简单的给大家介绍一下模板方法模式,模板方法模式是一个很容易理解的设计模式之一。 -> 模板方法模式是基于”继承“的,主要是为了在不改变模板结构的前提下在子类中重新定义模板中的内容以实现复用代码。举个很简单的例子假如我们要去一个地方的步骤是:购票`buyTicket()`->安检`securityCheck()`->乘坐某某工具回家`ride()`->到达目的地`arrive()`。我们可能乘坐不同的交通工具回家比如飞机或者火车,所以除了`ride()`方法,其他方法的实现几乎相同。我们可以定义一个包含了这些方法的抽象类,然后用户根据自己的需要继承该抽象类然后修改 `ride()`方法。 +> 模板方法模式是基于”继承“的,主要是为了在不改变模板结构的前提下在子类中重新定义模板中的内容以实现复用代码。 +> +> 举个很简单的例子假如我们要去一个地方的步骤是:购票 `buyTicket()`->安检 `securityCheck()`->乘坐某某工具回家 `ride()` ->到达目的地 `arrive()`。我们可能乘坐不同的交通工具回家比如飞机或者火车,所以除了`ride()`方法,其他方法的实现几乎相同。我们可以定义一个包含了这些方法的抽象类,然后用户根据自己的需要继承该抽象类然后修改 `ride()`方法。 **AQS 使用了模板方法模式,自定义同步器时需要重写下面几个 AQS 提供的模板方法:** @@ -220,29 +208,26 @@ tryAcquire(int)//独占方式。尝试获取资源,成功则返回true,失 tryRelease(int)//独占方式。尝试释放资源,成功则返回true,失败则返回false。 tryAcquireShared(int)//共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。 tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true,失败则返回false。 - ``` 默认情况下,每个方法都抛出 `UnsupportedOperationException`。 这些方法的实现必须是内部线程安全的,并且通常应该简短而不是阻塞。AQS 类中的其他方法都是 final ,所以无法被其他类使用,只有这几个方法可以被其他类使用。 以 `ReentrantLock` 为例,state 初始化为 0,表示未锁定状态。A 线程 `lock()` 时,会调用 `tryAcquire()`独占该锁并将 state+1。此后,其他线程再 `tryAcquire()` 时就会失败,直到 A 线程 unlock()到 state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A 线程自己是可以重复获取此锁的(state 会累加),这就是可重入的概念。但要注意,获取多少次就要释放多么次,这样才能保证 state 是能回到零态的。 -再以 `CountDownLatch` 以例,任务分为 N 个子线程去执行,state 也初始化为 N(也可以不初始化为N,不初始化为N,state减到0也会从await()返回)。这 N 个子线程是并行执行的,每个子线程执行完后 `countDown()` 一次,state 会 CAS(Compare and Swap)减 1。等到state=0,会 unpark()主调用线程,然后主调用线程就会从 `await()` 函数返回,继续后余动作。 +再以 `CountDownLatch` 以例,任务分为 N 个子线程去执行,state 也初始化为 N(也可以不初始化为 N,不初始化为 N,state 减到 0 也会从 await()返回)。这 N 个子线程是并行执行的,每个子线程执行完后 `countDown()` 一次,state 会 CAS(Compare and Swap)减 1。等到 `state=0`,会 `unpark()` 主调用线程,然后主调用线程就会从 `await()` 函数返回,继续后余动作。 -所以CountDownLatch可以做倒计数器,减到0后唤醒的线程可以对线程池进行处理,比如关闭线程池。BOSS直聘面试官提过一个问题如下: - -现在有8个赛道进行比赛,而我只需要知道前三名就够了,可以怎么实现?大家可以自己思考这个问题了。 +所以 `CountDownLatch` 可以做倒计数器,减到 0 后唤醒的线程可以对线程池进行处理,比如关闭线程池。 一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现`tryAcquire-tryRelease`、`tryAcquireShared-tryReleaseShared`中的一种即可。但 AQS 也支持自定义同步器同时实现独占和共享两种方式,如`ReentrantReadWriteLock`。 推荐两篇 AQS 原理和相关源码分析的文章: -- https://www.cnblogs.com/waterystone/p/4920797.html -- https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html +- [Java 并发之 AQS 详解](https://www.cnblogs.com/waterystone/p/4920797.html) +- [Java 并发包基石-AQS 详解](https://www.cnblogs.com/chengxiao/p/7141160.html) -### 3 Semaphore(信号量)-允许多个线程同时访问 +## Semaphore(信号量) -**`synchronized` 和 `ReentrantLock` 都是一次只允许一个线程访问某个资源,`Semaphore`(信号量)可以指定多个线程同时访问某个资源。** +`synchronized` 和 `ReentrantLock` 都是一次只允许一个线程访问某个资源,`Semaphore`(信号量)可以指定多个线程同时访问某个资源。 示例代码如下: @@ -289,7 +274,7 @@ public class SemaphoreExample1 { } ``` -执行 `acquire` 方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个 `release` 方法增加一个许可证,这可能会释放一个阻塞的 acquire 方法。然而,其实并没有实际的许可证这个对象,`Semaphore` 只是维持了一个可获得许可证的数量。 `Semaphore` 经常用于限制获取某种资源的线程数量。 +执行 `acquire()` 方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个 `release` 方法增加一个许可证,这可能会释放一个阻塞的 `acquire()` 方法。然而,其实并没有实际的许可证这个对象,`Semaphore` 只是维持了一个可获得许可证的数量。 `Semaphore` 经常用于限制获取某种资源的线程数量。 当然一次也可以一次拿取和释放多个许可,不过一般没有必要这样做: @@ -299,14 +284,14 @@ test(threadnum); semaphore.release(5);// 释放5个许可 ``` -除了 `acquire`方法之外,另一个比较常用的与之对应的方法是`tryAcquire`方法,该方法如果获取不到许可就立即返回 false。 +除了 `acquire()` 方法之外,另一个比较常用的与之对应的方法是 `tryAcquire()` 方法,该方法如果获取不到许可就立即返回 false。 `Semaphore` 有两种模式,公平模式和非公平模式。 -- **公平模式:** 调用 acquire 的顺序就是获取许可证的顺序,遵循 FIFO; +- **公平模式:** 调用 `acquire()` 方法的顺序就是获取许可证的顺序,遵循 FIFO; - **非公平模式:** 抢占式的。 -**`Semaphore` 对应的两个构造方法如下:** +`Semaphore` 对应的两个构造方法如下: ```java public Semaphore(int permits) { @@ -323,20 +308,23 @@ semaphore.release(5);// 释放5个许可 [issue645 补充内容](https://github.com/Snailclimb/JavaGuide/issues/645) :`Semaphore` 与 `CountDownLatch` 一样,也是共享锁的一种实现。它默认构造 AQS 的 state 为 `permits`。当执行任务的线程数量超出 `permits`,那么多余的线程将会被放入阻塞队列 Park,并自旋判断 state 是否大于 0。只有当 state 大于 0 的时候,阻塞的线程才能继续执行,此时先前执行任务的线程继续执行 `release()` 方法,`release()` 方法使得 state 的变量会加 1,那么自旋的线程便会判断成功。 如此,每次只有最多不超过 `permits` 数量的线程能自旋成功,便限制了执行任务线程的数量。 -由于篇幅问题,如果对 `Semaphore` 源码感兴趣的朋友可以看下这篇文章:https://juejin.im/post/5ae755366fb9a07ab508adc6 - -### 4 CountDownLatch (倒计时器) +## CountDownLatch (倒计时器) `CountDownLatch` 允许 `count` 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。 `CountDownLatch` 是共享锁的一种实现,它默认构造 AQS 的 `state` 值为 `count`。当线程使用 `countDown()` 方法时,其实使用了`tryReleaseShared`方法以 CAS 的操作来减少 `state`,直至 `state` 为 0 。当调用 `await()` 方法的时候,如果 `state` 不为 0,那就证明任务还没有执行完毕,`await()` 方法就会一直阻塞,也就是说 `await()` 方法之后的语句不会被执行。然后,`CountDownLatch` 会自旋 CAS 判断 `state == 0`,如果 `state == 0` 的话,就会释放所有等待的线程,`await()` 方法之后的语句得到执行。 -#### 4.1 CountDownLatch 的两种典型用法 +### CountDownLatch 的两种典型用法 -1. 某一线程在开始运行前等待 n 个线程执行完毕。将 `CountDownLatch` 的计数器初始化为 n :`new CountDownLatch(n)`,每当一个任务线程执行完毕,就将计数器减 1 `countdownlatch.countDown()`,当计数器的值变为 0 时,在`CountDownLatch上 await()` 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。 -2. 实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的 `CountDownLatch` 对象,将其计数器初始化为 1 :`new CountDownLatch(1)`,多个线程在开始执行任务前首先 `coundownlatch.await()`,当主线程调用 `countDown()` 时,计数器变为 0,多个线程同时被唤醒。 +**1、某一线程在开始运行前等待 n 个线程执行完毕。** -#### 4.2 CountDownLatch 的使用示例 +将 `CountDownLatch` 的计数器初始化为 n (`new CountDownLatch(n)`),每当一个任务线程执行完毕,就将计数器减 1 (`countdownlatch.countDown()`),当计数器的值变为 0 时,在 `CountDownLatch 上 await()` 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。 + +**2、实现多个线程开始执行任务的最大并行性。** + +注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的 `CountDownLatch` 对象,将其计数器初始化为 1 (`new CountDownLatch(1)`),多个线程在开始执行任务前首先 `coundownlatch.await()`,当主线程调用 `countDown()` 时,计数器变为 0,多个线程同时被唤醒。 + +### CountDownLatch 的使用示例 ```java /** @@ -383,7 +371,7 @@ public class CountDownLatchExample1 { 上面的代码中,我们定义了请求的数量为 550,当这 550 个请求被处理完成之后,才会执行`System.out.println("finish");`。 -与 CountDownLatch 的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用 `CountDownLatch.await()` 方法。这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。 +与 `CountDownLatch` 的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用 `CountDownLatch.await()` 方法。这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。 其他 N 个线程必须引用闭锁对象,因为他们需要通知 `CountDownLatch` 对象,他们已经完成了各自的任务。这种通知机制是通过 `CountDownLatch.countDown()`方法来完成的;每调用一次这个方法,在构造函数中初始化的 count 值就减 1。所以当 N 个线程都调 用了这个方法,count 的值等于 0,然后主线程就能通过 `await()`方法,恢复执行自己的任务。 @@ -397,29 +385,25 @@ for (int i = 0; i < threadCount-1; i++) { 这样就导致 `count` 的值没办法等于 0,然后就会导致一直等待。 -如果对 `CountDownLatch` 源码感兴趣的朋友,可以查看: [【JUC】JDK1.8 源码分析之 CountDownLatch(五)](https://www.cnblogs.com/leesf456/p/5406191.html) - -#### 4.3 CountDownLatch 的不足 +### CountDownLatch 的不足 `CountDownLatch` 是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当 `CountDownLatch` 使用完毕后,它不能再次被使用。 -#### 4.4 CountDownLatch 相常见面试题 +### CountDownLatch 相常见面试题 -解释一下 `CountDownLatch` 概念? +- `CountDownLatch` 怎么用?应用场景是什么? +- `CountDownLatch` 和 `CyclicBarrier` 的不同之处? +- `CountDownLatch` 类中主要的方法? -`CountDownLatch` 和 `CyclicBarrier` 的不同之处? - -给出一些 `CountDownLatch` 使用的例子? - -`CountDownLatch` 类中主要的方法? - -### 5 CyclicBarrier(循环栅栏) +## CyclicBarrier(循环栅栏) `CyclicBarrier` 和 `CountDownLatch` 非常类似,它也可以实现线程间的技术等待,但是它的功能比 `CountDownLatch` 更加复杂和强大。主要应用场景和 `CountDownLatch` 类似。 -> `CountDownLatch` 的实现是基于 AQS 的,而 `CycliBarrier` 是基于 `ReentrantLock`(`ReentrantLock` 也属于 AQS 同步器)和 `Condition` 的. +> `CountDownLatch` 的实现是基于 AQS 的,而 `CycliBarrier` 是基于 `ReentrantLock`(`ReentrantLock` 也属于 AQS 同步器)和 `Condition` 的。 -CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 `CyclicBarrier(int parties)`,其参数表示屏障拦截的线程数量,每个线程调用`await`方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 +`CyclicBarrier` 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是:让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。 + +`CyclicBarrier` 默认的构造方法是 `CyclicBarrier(int parties)`,其参数表示屏障拦截的线程数量,每个线程调用 `await()` 方法告诉 `CyclicBarrier` 我已经到达了屏障,然后当前线程被阻塞。 再来看一下它的构造函数: @@ -438,11 +422,11 @@ public CyclicBarrier(int parties, Runnable barrierAction) { 其中,parties 就代表了有拦截的线程的数量,当拦截的线程数量达到这个值的时候就打开栅栏,让所有线程通过。 -#### 5.1 CyclicBarrier 的应用场景 +### CyclicBarrier 的应用场景 `CyclicBarrier` 可以用于多线程计算数据,最后合并计算结果的应用场景。比如我们用一个 Excel 保存了用户所有银行流水,每个 Sheet 保存一个帐户近一年的每笔银行流水,现在需要统计用户的日均银行流水,先用多线程处理每个 sheet 里的银行流水,都执行完之后,得到每个 sheet 的日均银行流水,最后,再用 barrierAction 用这些线程的计算结果,计算出整个 Excel 的日均银行流水。 -#### 5.2 CyclicBarrier 的使用示例 +### CyclicBarrier 的使用示例 示例 1: @@ -521,9 +505,9 @@ threadnum:6is finish ...... ``` -可以看到当线程数量也就是请求数量达到我们定义的 5 个的时候, `await`方法之后的方法才被执行。 +可以看到当线程数量也就是请求数量达到我们定义的 5 个的时候, `await()` 方法之后的方法才被执行。 -另外,`CyclicBarrier` 还提供一个更高级的构造函数`CyclicBarrier(int parties, Runnable barrierAction)`,用于在线程到达屏障时,优先执行`barrierAction`,方便处理更复杂的业务场景。示例代码如下: +另外,`CyclicBarrier` 还提供一个更高级的构造函数 `CyclicBarrier(int parties, Runnable barrierAction)`,用于在线程到达屏障时,优先执行 `barrierAction`,方便处理更复杂的业务场景。示例代码如下: ```java /** @@ -599,18 +583,18 @@ threadnum:7is finish ...... ``` -#### 5.3 `CyclicBarrier`源码分析 +### CyclicBarrier 源码分析 -当调用 `CyclicBarrier` 对象调用 `await()` 方法时,实际上调用的是`dowait(false, 0L)`方法。 `await()` 方法就像树立起一个栅栏的行为一样,将线程挡住了,当拦住的线程数量达到 `parties` 的值时,栅栏才会打开,线程才得以通过执行。 +当调用 `CyclicBarrier` 对象调用 `await()` 方法时,实际上调用的是 `dowait(false, 0L)`方法。 `await()` 方法就像树立起一个栅栏的行为一样,将线程挡住了,当拦住的线程数量达到 `parties` 的值时,栅栏才会打开,线程才得以通过执行。 ```java - public int await() throws InterruptedException, BrokenBarrierException { - try { - return dowait(false, 0L); - } catch (TimeoutException toe) { - throw new Error(toe); // cannot happen - } - } +public int await() throws InterruptedException, BrokenBarrierException { + try { + return dowait(false, 0L); + } catch (TimeoutException toe) { + throw new Error(toe); // cannot happen + } +} ``` `dowait(false, 0L)`: @@ -696,11 +680,11 @@ threadnum:7is finish ``` -总结:`CyclicBarrier` 内部通过一个 count 变量作为计数器,cout 的初始值为 parties 属性的初始化值,每当一个线程到了栅栏这里了,那么就将计数器减一。如果 count 值为 0 了,表示这是这一代最后一个线程到达栅栏,就尝试执行我们构造方法中输入的任务。 +总结:`CyclicBarrier` 内部通过一个 count 变量作为计数器,count 的初始值为 parties 属性的初始化值,每当一个线程到了栅栏这里了,那么就将计数器减一。如果 count 值为 0 了,表示这是这一代最后一个线程到达栅栏,就尝试执行我们构造方法中输入的任务。 -#### 5.4 CyclicBarrier 和 CountDownLatch 的区别 +### CyclicBarrier 和 CountDownLatch 的区别 -**下面这个是国外一个大佬的回答:** +下面这个是国外一个大佬的回答: `CountDownLatch` 是计数器,只能使用一次,而 `CyclicBarrier` 的计数器提供 `reset` 功能,可以多次使用。但是我不那么认为它们之间的区别仅仅就是这么简单的一点。我们来从 jdk 作者设计的目的来看,javadoc 是这么描述它们的: @@ -711,22 +695,6 @@ threadnum:7is finish `CountDownLatch` 是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而 `CyclicBarrier` 更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。 -### 6 ReentrantLock 和 ReentrantReadWriteLock +### ReentrantLock 和 ReentrantReadWriteLock `ReentrantLock` 和 `synchronized` 的区别在上面已经讲过了这里就不多做讲解。另外,需要注意的是:读写锁 `ReentrantReadWriteLock` 可以保证多个线程可以同时读,所以在读操作远大于写操作的时候,读写锁就非常有用了。 - -### 参考 - -- https://juejin.im/post/5ae755256fb9a07ac3634067 -- https://blog.csdn.net/u010185262/article/details/54692886 -- https://blog.csdn.net/tolcf/article/details/50925145?utm_source=blogxgwz0 - -### 公众号 - -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 - -**《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V2.0 PDF 版本[公众号](#公众号 "公众号")后台回复 **"面试突击"** 即可免费领取! - -**Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 - -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) From a9330d48e16b1e1f52d11918ee48148079424fa4 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 27 Jul 2021 16:19:41 +0800 Subject: [PATCH 126/257] Update MySQL.md --- docs/database/MySQL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index cf1e4833..58da9e6b 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -209,7 +209,7 @@ COMMIT; 1. **原子性**(`Atomicity`) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; 2. **一致性**(`Consistency`): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的; 3. **隔离性**(`Isolation`): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的; -4. **持久性**(`Durabilily`): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 +4. **持久性**(`Durability`): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 **数据事务的实现原理呢?** From 08e97e82af383dc90f68bdc4c44e3fb64fa53a14 Mon Sep 17 00:00:00 2001 From: haozhibei <837948266@qq.com> Date: Thu, 29 Jul 2021 10:29:07 +0800 Subject: [PATCH 127/257] Update zookeeper-intro.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 微调Follower和Observer的表述,使其描述更统一,对比更明显 --- .../distributed-system/zookeeper/zookeeper-intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md index 8178d303..f9b94eb2 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-intro.md @@ -235,8 +235,8 @@ ZooKeeper 集群中的所有机器通过一个 **Leader 选举过程** 来选定 | 角色 | 说明 | | -------- | ------------------------------------------------------------ | | Leader | 为客户端提供读和写的服务,负责投票的发起和决议,更新系统状态。 | -| Follower | 为客户端提供读服务,如果是写服务则转发给 Leader。在选举过程中参与投票。 | -| Observer | 为客户端提供读服务器,如果是写服务则转发给 Leader。不参与选举过程中的投票,也不参与“过半写成功”策略。在不影响写性能的情况下提升集群的读性能。此角色于 ZooKeeper3.3 系列新增的角色。 | +| Follower | 为客户端提供读服务,如果是写服务则转发给 Leader。参与选举过程中的投票。 | +| Observer | 为客户端提供读服务,如果是写服务则转发给 Leader。不参与选举过程中的投票,也不参与“过半写成功”策略。在不影响写性能的情况下提升集群的读性能。此角色于 ZooKeeper3.3 系列新增的角色。 | 当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,就会进入 Leader 选举过程,这个过程会选举产生新的 Leader 服务器。 From bfa4f7864f7a6c1716b8cccc2899fd5e57fc2435 Mon Sep 17 00:00:00 2001 From: xiaoshuguo <343905275@qq.com> Date: Thu, 29 Jul 2021 17:19:17 +0800 Subject: [PATCH 128/257] =?UTF-8?q?Java=208=20=E6=96=B0=E7=89=B9=E6=80=A7?= =?UTF-8?q?=20=E4=BE=8B=E5=AD=90=E5=B0=8F=E9=94=99=E8=AF=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/new-features/java8-common-new-features.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/java/new-features/java8-common-new-features.md b/docs/java/new-features/java8-common-new-features.md index 69a9b7f7..f0630eff 100644 --- a/docs/java/new-features/java8-common-new-features.md +++ b/docs/java/new-features/java8-common-new-features.md @@ -176,7 +176,7 @@ public interface Runnable{} ```java @FunctionalInterface -public interface LambdaFunctionalInterface { +public interface LambdaInterface { void f(); } //使用 @@ -221,7 +221,7 @@ public class LambdaClassSuper { } } -public class LambdaClass { +public class LambdaClass extends LambdaClassSuper { public static LambdaInterface staticF() { return null; } @@ -243,6 +243,7 @@ public class LambdaClass { //4. 构造方法调用 LambdaInterface tt = LambdaClassSuper::new; + } } ``` From 021b1f3038fa208be30f6aa82c970063d76bde8a Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sun, 1 Aug 2021 21:28:56 +0800 Subject: [PATCH 129/257] =?UTF-8?q?Update=20Java=E5=86=85=E5=AD=98?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/Java内存区域.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/jvm/Java内存区域.md b/docs/java/jvm/Java内存区域.md index 00020544..11210af1 100644 --- a/docs/java/jvm/Java内存区域.md +++ b/docs/java/jvm/Java内存区域.md @@ -174,8 +174,8 @@ JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 堆这里最容易出现的就是 OutOfMemoryError 错误,并且出现这种错误之后的表现形式还会有几种,比如: -1. **`OutOfMemoryError: GC Overhead Limit Exceeded`** : 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。 -2. **`java.lang.OutOfMemoryError: Java heap space`** :假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发`java.lang.OutOfMemoryError: Java heap space` 错误。(和本机物理内存无关,和你配置的内存大小有关!) +1. **`java.lang.OutOfMemoryError: GC Overhead Limit Exceeded`** : 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。 +2. **`java.lang.OutOfMemoryError: Java heap space`** :假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。(和配置的最大堆内存有关,且受制于物理内存大小。最大堆内存可通过`-Xmx`参数配置,若没有特别配置,将会使用默认值,详见:[Default Java 8 max heap size](https://stackoverflow.com/questions/28272923/default-xmxsize-in-java-8-max-heap-size)) 3. ...... ### 2.5 方法区 From 64b247e63451d71eeb4f5683ab55bfb18537280a Mon Sep 17 00:00:00 2001 From: yamonc Date: Wed, 4 Aug 2021 15:07:32 +0800 Subject: [PATCH 130/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E6=9C=BA=E7=BD=91=E7=BB=9C=E4=B8=AD=E4=B8=89=E6=AC=A1=E6=8F=A1?= =?UTF-8?q?=E6=89=8B=E8=AF=A6=E6=83=85=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 8ea49e02..d67084c2 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -110,6 +110,10 @@ - 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端 - 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端 +**详细示意图(图片来源不详)** + +![](https://user-images.githubusercontent.com/52881289/128109410-b3619cfa-ce64-4f69-86ac-ececa4e014e4.png) + ### 2.2 为什么要三次握手 **三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。** From 9876181f43ba143b9e0fa7226a8afc81105be679 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 4 Aug 2021 20:49:42 +0800 Subject: [PATCH 131/257] =?UTF-8?q?Update=20=E8=AE=A1=E7=AE=97=E6=9C=BA?= =?UTF-8?q?=E7=BD=91=E7=BB=9C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 8c13cb7e..69ed4084 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -77,7 +77,7 @@ **详细示意图(图片来源不详)** -![](https://user-images.githubusercontent.com/52881289/128109410-b3619cfa-ce64-4f69-86ac-ececa4e014e4.png) +![](https://img-blog.csdnimg.cn/img_convert/0c9f470819684156cfdc27c682db4def.png) ### 2.2 为什么要三次握手 From d8784d1c50c5821189731396611ce1666f606b1c Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Wed, 4 Aug 2021 23:00:16 +0800 Subject: [PATCH 132/257] =?UTF-8?q?Update=20Java=E5=B9=B6=E5=8F=91?= =?UTF-8?q?=E8=BF=9B=E9=98=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020最新Java并发进阶常见面试题总结.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index a817d041..92b007db 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -479,7 +479,7 @@ static class Entry extends WeakReference> { `Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口** 不会返回结果或抛出检查异常,但是 **`Callable` 接口** 可以。所以,如果任务不需要返回结果或抛出异常推荐使用 **`Runnable` 接口** ,这样代码看起来会更加简洁。 -工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 +工具类 `Executors` 可以实现将 `Runnable` 对象转换成 `Callable` 对象。(`Executors.callable(Runnable task)` 或 `Executors.callable(Runnable task, Object result)`)。 `Runnable.java` @@ -510,9 +510,9 @@ public interface Callable { ### 4.3. 执行 execute()方法和 submit()方法的区别是什么呢? 1. **`execute()`方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;** -2. **`submit()`方法用于提交需要返回值的任务。线程池会返回一个 `Future` 类型的对象,通过这个 `Future` 对象可以判断任务是否执行成功**,并且可以通过 `Future` 的 `get()`方法来获取返回值,`get()`方法会阻塞当前线程直到任务完成,而使用 `get(long timeout,TimeUnit unit)`方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。 +2. **`submit()`方法用于提交需要返回值的任务。线程池会返回一个 `Future` 类型的对象,通过这个 `Future` 对象可以判断任务是否执行成功**,并且可以通过 `Future` 的 `get()`方法来获取返回值,`get()`方法会阻塞当前线程直到任务完成,而使用 `get(long timeout,TimeUnit unit)`方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。 -我们以** `AbstractExecutorService` **接口中的一个 `submit` 方法为例子来看看源代码: +我们以 **`AbstractExecutorService` 接口** 中的一个 `submit` 方法为例子来看看源代码: ```java public Future submit(Runnable task) { From e8d1e143929c824ee2d08a263bc43595fe1c11b9 Mon Sep 17 00:00:00 2001 From: guide Date: Thu, 5 Aug 2021 16:12:45 +0800 Subject: [PATCH 133/257] =?UTF-8?q?Update=20=E8=AE=A1=E7=AE=97=E6=9C=BA?= =?UTF-8?q?=E7=BD=91=E7=BB=9C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/network/计算机网络.md | 159 ++++++++++++++++---------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 69ed4084..5a10b739 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -1,4 +1,4 @@ -## 一 OSI与TCP/IP各层的结构与功能,都有哪些协议? +## 一 OSI 与 TCP/IP 各层的结构与功能,都有哪些协议? 学习计算机网络时我们一般采用折中的办法,也就是中和 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。 @@ -8,13 +8,13 @@ ### 1.1 应用层 -**应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。**应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如**域名系统DNS**,支持万维网应用的 **HTTP协议**,支持电子邮件的 **SMTP协议**等等。我们把应用层交互的数据单元称为报文。 +**应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。**应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如**域名系统 DNS**,支持万维网应用的 **HTTP 协议**,支持电子邮件的 **SMTP 协议**等等。我们把应用层交互的数据单元称为报文。 **域名系统** -> 域名系统(Domain Name System缩写 DNS,Domain Name被译为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。(百度百科)例如:一个公司的 Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有:IBM 公司的域名是 www.ibm.com、Oracle 公司的域名是 www.oracle.com、Cisco公司的域名是 www.cisco.com 等。 +> 域名系统(Domain Name System 缩写 DNS,Domain Name 被译为域名)是因特网的一项核心服务,它作为可以将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。(百度百科)例如:一个公司的 Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有:IBM 公司的域名是 www.ibm.com、Oracle 公司的域名是 www.oracle.com、Cisco 公司的域名是 www.cisco.com 等。 -**HTTP协议** +**HTTP 协议** > 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。(百度百科) @@ -29,7 +29,6 @@ **TCP 与 UDP 的对比见问题三。** - ### 1.3 网络层 **在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。** 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 **IP 协议**,因此分组也叫 **IP 数据报** ,简称 **数据报**。 @@ -38,20 +37,22 @@ 这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系结构模型中第三层的名称. -互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Internet Protocol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP层**。 +互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Internet Protocol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP 层**。 ### 1.4 数据链路层 + **数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。** 在两个相邻节点之间传送数据时,**数据链路层将网络层交下来的 IP 数据报组装成帧**,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 控制信息还使接收端能够检测到所收到的帧中有无差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。 ### 1.5 物理层 + 在物理层上所传送的数据单位是比特。 - **物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,** 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。 +**物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,** 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。 -在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。 +在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的 TCP/IP 并不一定单指 TCP 和 IP 这两个具体的协议,而往往表示互联网所使用的整个 TCP/IP 协议族。 ### 1.6 总结一下 @@ -61,11 +62,11 @@ ## 二 TCP 三次握手和四次挥手(面试常客) -为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。 +为了准确无误地把数据送达目标处,TCP 协议采用了三次握手策略。 ### 2.1 TCP 三次握手漫画图解 -如下图所示,下面的两个机器人通过3次握手确定了对方能正确接收和发送消息(图片来源:《图解HTTP》)。 +如下图所示,下面的两个机器人通过 3 次握手确定了对方能正确接收和发送消息(图片来源:《图解 HTTP》)。 ![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手.png) **简单示意图:** @@ -91,53 +92,55 @@ 所以三次握手就能确认双发收发功能都正常,缺一不可。 -### 2.3 第2次握手传回了ACK,为什么还要传回SYN? +### 2.3 第 2 次握手传回了 ACK,为什么还要传回 SYN? -接收端传回发送端所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传SYN则是为了建立并确认从服务端到客户端的通信。” +接收端传回发送端所发送的 ACK 是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传 SYN 则是为了建立并确认从服务端到客户端的通信。” -> SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。 +> SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。 -### 2.5 为什么要四次挥手 +### 2.5 为什么要四次挥手 ![TCP四次挥手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/TCP四次挥手.png) 断开一个 TCP 连接则需要“四次挥手”: - 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送 -- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号 -- 服务器-关闭与客户端的连接,发送一个FIN给客户端 -- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1 +- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号 +- 服务器-关闭与客户端的连接,发送一个 FIN 给客户端 +- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加 1 -任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 +任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。 -举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 +举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891) ## 三 TCP,UDP 协议的区别 + ![TCP、UDP协议的区别](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp-vs-udp.jpg) UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 却是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等 -TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 +TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 ## 四 TCP 协议如何保证可靠传输 -1. 应用数据被分割成 TCP 认为最适合发送的数据块。 -2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。 -3. **校验和:** TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。 -4. TCP 的接收端会丢弃重复的数据。 -5. **流量控制:** TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) +1. 应用数据被分割成 TCP 认为最适合发送的数据块。 +2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。 +3. **校验和:** TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。 +4. TCP 的接收端会丢弃重复的数据。 +5. **流量控制:** TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) 6. **拥塞控制:** 当网络拥塞时,减少数据的发送。 -7. **ARQ协议:** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 -8. **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 +7. **ARQ 协议:** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 +8. **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 -### 4.1 ARQ协议 +### 4.1 ARQ 协议 -**自动重传请求**(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。 +**自动重传请求**(Automatic Repeat-reQuest,ARQ)是 OSI 模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ 包括停止等待 ARQ 协议和连续 ARQ 协议。 -#### 停止等待ARQ协议 -停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。 +#### 停止等待 ARQ 协议 + +停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。 在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。 @@ -156,17 +159,17 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接, **3) 确认丢失和确认迟到** -- **确认丢失** :确认消息在传输过程丢失。当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:1. 丢弃这个重复的M1消息,不向上层交付。 2. 向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。 -- **确认迟到** :确认消息在传输过程中迟到。A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:1. A收到重复的确认后,直接丢弃。2. B收到重复的M1后,也直接丢弃重复的M1。 +- **确认丢失** :确认消息在传输过程丢失。当 A 发送 M1 消息,B 收到后,B 向 A 发送了一个 M1 确认消息,但却在传输过程中丢失。而 A 并不知道,在超时计时过后,A 重传 M1 消息,B 再次收到该消息后采取以下两点措施:1. 丢弃这个重复的 M1 消息,不向上层交付。 2. 向 A 发送确认消息。(不会认为已经发送过了,就不再发送。A 能重传,就证明 B 的确认消息丢失)。 +- **确认迟到** :确认消息在传输过程中迟到。A 发送 M1 消息,B 收到并发送确认。在超时时间内没有收到确认消息,A 重传 M1 消息,B 仍然收到并继续发送确认消息(B 收到了 2 份 M1)。此时 A 收到了 B 第二次发送的确认消息。接着发送其他数据。过了一会,A 收到了 B 第一次发送的对 M1 的确认消息(A 也收到了 2 份确认消息)。处理如下:1. A 收到重复的确认后,直接丢弃。2. B 收到重复的 M1 后,也直接丢弃重复的 M1。 -#### 连续ARQ协议 +#### 连续 ARQ 协议 连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。 **优缺点:** - **优点:** 信道利用率高,容易实现,即使确认丢失,也不必重传。 -- **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。 +- **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5 条 消息,中间第三条丢失(3 号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。 ### 4.2 滑动窗口和流量控制 @@ -178,32 +181,31 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接, 为了进行拥塞控制,TCP 发送方要维持一个 **拥塞窗口(cwnd)** 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。 -TCP的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免** 、**快重传** 和 **快恢复**。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。 +TCP 的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免** 、**快重传** 和 **快恢复**。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。 -- **慢开始:** 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。 -- **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1. -- **快重传与快恢复:** - 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。 +- **慢开始:** 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。 +- **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送放的 cwnd 加 1. +- **快重传与快恢复:** + 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。 - -## 五 在浏览器中输入url地址 ->> 显示主页的过程(面试常客) +## 五 在浏览器中输入 url 地址 ->> 显示主页的过程(面试常客) 百度好像最喜欢问这个问题。 > 打开一个网页,整个过程会使用哪些协议? -图解(图片来源:《图解HTTP》): +图解(图片来源:《图解 HTTP》): -> 上图有一个错误,请注意,是OSPF不是OPSF。 OSPF(Open Shortest Path First,ospf)开放最短路径优先协议,是由Internet工程任务组开发的路由选择协议 +> 上图有一个错误,请注意,是 OSPF 不是 OPSF。 OSPF(Open Shortest Path First,ospf)开放最短路径优先协议,是由 Internet 工程任务组开发的路由选择协议 总体来说分为以下几个过程: -1. DNS解析 -2. TCP连接 -3. 发送HTTP请求 -4. 服务器处理请求并返回HTTP报文 +1. DNS 解析 +2. TCP 连接 +3. 发送 HTTP 请求 +4. 服务器处理请求并返回 HTTP 报文 5. 浏览器解析渲染页面 6. 连接结束 @@ -215,85 +217,84 @@ TCP的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免** ![状态码](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/状态码.png) +## 七 各种协议与 HTTP 协议之间的关系 -## 七 各种协议与HTTP协议之间的关系 一般面试官会通过这样的问题来考察你对计算机网络知识体系的理解。 -图片来源:《图解HTTP》 +图片来源:《图解 HTTP》 ![各种协议与HTTP协议之间的关系](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/各种协议与HTTP协议之间的关系.png) -## 八 HTTP长连接,短连接 +## 八 HTTP 长连接,短连接 -在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。 +在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源(如 JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。 -而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码: +而从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头加入这行代码: ``` Connection:keep-alive ``` -在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 +在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 -**HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。** +**HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接。** -—— [《HTTP长连接、短连接究竟是什么?》](https://www.cnblogs.com/gotodsp/p/6366163.html) +—— [《HTTP 长连接、短连接究竟是什么?》](https://www.cnblogs.com/gotodsp/p/6366163.html) -## 九 HTTP是不保存状态的协议,如何保存用户状态? +## 九 HTTP 是不保存状态的协议,如何保存用户状态? -HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。 +HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个 Session)。 -在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。 +在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库 redis 保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。 **Cookie 被禁用怎么办?** -最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。 +最常用的就是利用 URL 重写把 Session ID 直接附加在 URL 路径的后面。 ![HTTP是无状态协议](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HTTP是无状态的.png) -## 十 Cookie的作用是什么?和Session有什么区别? +## 十 Cookie 的作用是什么?和 Session 有什么区别? -Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 +Cookie 和 Session 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 - **Cookie 一般用来保存用户信息** 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 +**Cookie 一般用来保存用户信息** 比如 ① 我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;② 一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③ 登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 -Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 +Cookie 存储在客户端中,而 Session 存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 -## 十一 HTTP 1.0和HTTP 1.1的主要区别是什么? +## 十一 HTTP 1.0 和 HTTP 1.1 的主要区别是什么? > 这部分回答引用这篇文章 的一些内容。 -HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在: +HTTP1.0 最早在网页中使用是在 1996 年,那个时候只是使用一些较为简单的网页上和网络请求上,而 HTTP1.1 则在 1999 年才开始广泛应用于现在的各大浏览器网络请求中,同时 HTTP1.1 也是当前使用最为广泛的 HTTP 协议。 主要区别主要体现在: -1. **长连接** : **在HTTP/1.0中,默认使用的是短连接**,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。**HTTP 1.1起,默认使用长连接** ,默认开启Connection: keep-alive。 **HTTP/1.1的持续连接有非流水线方式和流水线方式** 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 -1. **错误状态响应码** :在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 -1. **缓存处理** :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。 -1. **带宽优化及网络连接的使用** :HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。 +1. **长连接** : **在 HTTP/1.0 中,默认使用的是短连接**,也就是说每次请求都要重新建立一次连接。HTTP 是基于 TCP/IP 协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。**HTTP 1.1 起,默认使用长连接** ,默认开启 Connection: keep-alive。 **HTTP/1.1 的持续连接有非流水线方式和流水线方式** 。流水线方式是客户在收到 HTTP 的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 +1. **错误状态响应码** :在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 +1. **缓存处理** :在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。 +1. **带宽优化及网络连接的使用** :HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。 -## 十二 URI和URL的区别是什么? +## 十二 URI 和 URL 的区别是什么? - URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。 - URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。 -URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。 +URI 的作用像身份证号一样,URL 的作用更像家庭住址一样。URL 是一种具体的 URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。 ## 十三 HTTP 和 HTTPS 的区别? -1. **端口** :HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。 -2. **安全性和资源消耗:** HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。 - - 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等; - - 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。 +1. **端口** :HTTP 的 URL 由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。 +2. **安全性和资源消耗:** HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。 + - 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有 DES、AES 等; + - 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有 RSA、DSA 等。 ## 建议 -非常推荐大家看一下 《图解HTTP》 这本书,这本书页数不多,但是内容很是充实,不管是用来系统的掌握网络方面的一些知识还是说纯粹为了应付面试都有很大帮助。下面的一些文章只是参考。大二学习这门课程的时候,我们使用的教材是 《计算机网络第七版》(谢希仁编著),不推荐大家看这本教材,书非常厚而且知识偏理论,不确定大家能不能心平气和的读完。 +非常推荐大家看一下 《图解 HTTP》 这本书,这本书页数不多,但是内容很是充实,不管是用来系统的掌握网络方面的一些知识还是说纯粹为了应付面试都有很大帮助。下面的一些文章只是参考。大二学习这门课程的时候,我们使用的教材是 《计算机网络第七版》(谢希仁编著),不推荐大家看这本教材,书非常厚而且知识偏理论,不确定大家能不能心平气和的读完。 ## 参考 - [https://blog.csdn.net/qq_16209077/article/details/52718250](https://blog.csdn.net/qq_16209077/article/details/52718250) - [https://blog.csdn.net/zixiaomuwu/article/details/60965466](https://blog.csdn.net/zixiaomuwu/article/details/60965466) -- [https://blog.csdn.net/turn__back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641) +- [https://blog.csdn.net/turn\_\_back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641) - - From fb8eef291aae3f9acd055a1a7be8b3124934d97b Mon Sep 17 00:00:00 2001 From: guide Date: Thu, 5 Aug 2021 16:34:08 +0800 Subject: [PATCH 134/257] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/Java基础知识.md | 32 +++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index 6fbc5397..7c03a111 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -741,9 +741,37 @@ public void f5(int a) { ### 静态方法和实例方法有何不同? -1. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,**调用静态方法可以无需创建对象。** +**1、调用方式** -2. 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。 +在外部调用静态方法时,可以使用 `类名.方法名` 的方式,也可以使用 `对象.方法名` 的方式,而实例方法只有后面这种方式。也就是说,**调用静态方法可以无需创建对象** 。 + +不过,需要注意的是一般不建议使用 `对象.方法名` 的方式来调用静态方法。这种方式非常容易造成混淆,静态方法不属于类的某个对象而是属于这个类。 + +因此,一般建议使用 `类名.方法名` 的方式来调用静态方法。 + +```java + +public class Person { + public void method() { + //...... + } + + public static void staicMethod(){ + //...... + } + public static void main(String[] args) { + Person person = new Person(); + // 调用实例方法 + person.method(); + // 调用静态方法 + Person.staicMethod() + } +} +``` + +**2、访问类成员是否存在限制** + +静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),不允许访问实例成员(即实例成员变量和实例方法),而实例方法不存在这个限制。 ### 为什么 Java 中只有值传递? From 62bef0f750e0209099ff87eae4111c6a8cbdabe1 Mon Sep 17 00:00:00 2001 From: guide Date: Thu, 5 Aug 2021 16:55:48 +0800 Subject: [PATCH 135/257] =?UTF-8?q?Update=20=E4=BA=8B=E5=8A=A1=E9=9A=94?= =?UTF-8?q?=E7=A6=BB=E7=BA=A7=E5=88=AB(=E5=9B=BE=E6=96=87=E8=AF=A6?= =?UTF-8?q?=E8=A7=A3).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/事务隔离级别(图文详解).md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/database/事务隔离级别(图文详解).md b/docs/database/事务隔离级别(图文详解).md index 95da8be9..19cbd71e 100644 --- a/docs/database/事务隔离级别(图文详解).md +++ b/docs/database/事务隔离级别(图文详解).md @@ -69,7 +69,7 @@ | REPEATABLE-READ | × | × | √ | | SERIALIZABLE | × | × | × | -MySQL InnoDB 存储引擎的默认支持的隔离级别是 **REPEATABLE-READ(可重读)**。我们可以通过`SELECT @@tx_isolation;`命令来查看,MySQL 8.0 该命令改为`SELECT @@transaction_isolation;` +MySQL InnoDB 存储引擎的默认支持的隔离级别是 **REPEATABLE-READ(可重读)**。我们可以通过`SELECT @@tx_isolation;`命令来查看,MySQL 8.0 该命令改为`SELECT @@transaction_isolation;` ```sql mysql> SELECT @@tx_isolation; @@ -80,11 +80,17 @@ mysql> SELECT @@tx_isolation; +-----------------+ ``` -这里需要注意的是:与 SQL 标准不同的地方在于InnoDB 存储引擎在 **REPEATABLE-READ(可重读)** 事务隔离级别下,允许应用使用 Next-Key Lock 锁算法来避免幻读的产生。这与其他数据库系统(如 SQL Server)是不同的。所以说虽然 InnoDB 存储引擎的默认支持的隔离级别是 **REPEATABLE-READ(可重读)** ,但是可以通过应用加锁读(例如 `select * from table for update` 语句)来保证不会产生幻读,而这个加锁度使用到的机制就是 Next-Key Lock 锁算法。从而达到了 SQL 标准的 **SERIALIZABLE(可串行化)** 隔离级别。 +~~这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在 **REPEATABLE-READ(可重读)** 事务隔离级别下使用的是 Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说 InnoDB 存储引擎的默认支持的隔离级别是 **REPEATABLE-READ(可重读)** 已经可以完全保证事务的隔离性要求,即达到了 SQL 标准的 **SERIALIZABLE(可串行化)** 隔离级别。~~ -因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是**READ-COMMITTED(读取提交内容):**,但是你要知道的是InnoDB 存储引擎默认使用 **REPEATABLE-READ(可重读)** 并不会有任何性能损失。 +🐛 问题更正:**MySQL InnoDB 的 REPEATABLE-READ(可重读)并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是 Next-Key Locks。** -InnoDB 存储引擎在 **分布式事务** 的情况下一般会用到**SERIALIZABLE(可串行化)** 隔离级别。 +因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 **READ-COMMITTED(读取提交内容)** ,但是你要知道的是 InnoDB 存储引擎默认使用 **REPEATABLE-READ(可重读)** 并不会有任何性能损失。 + +InnoDB 存储引擎在 **分布式事务** 的情况下一般会用到 **SERIALIZABLE(可串行化)** 隔离级别。 + +🌈 拓展一下(以下内容摘自《MySQL 技术内幕:InnoDB 存储引擎(第 2 版)》7.7 章): + +> InnoDB 存储引擎提供了对 XA 事务的支持,并通过 XA 事务来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源(transactional resources)参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对于事务原有的 ACID 要求又有了提高。另外,在使用分布式事务时,InnoDB 存储引擎的事务隔离级别必须设置为 SERIALIZABLE。 ### 实际情况演示 From 203fa5d16577ad7742489bb7689fe21521eab6f8 Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Thu, 5 Aug 2021 23:37:32 +0800 Subject: [PATCH 136/257] =?UTF-8?q?Update=20java=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E5=AD=A6=E4=B9=A0=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/multi-thread/java线程池学习总结.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/java/multi-thread/java线程池学习总结.md b/docs/java/multi-thread/java线程池学习总结.md index 66d835fd..eb266f3a 100644 --- a/docs/java/multi-thread/java线程池学习总结.md +++ b/docs/java/multi-thread/java线程池学习总结.md @@ -337,7 +337,7 @@ pool-1-thread-2 End. Time = Sun Apr 12 11:14:47 CST 2020 ### 4.2 线程池原理分析 -承接 4.1 节,我们通过代码输出结果可以看出:**线程首先会先执行 5 个任务,然后这些任务有任务被执行完的话,就会去拿新的任务执行。** 大家可以先通过上面讲解的内容,分析一下到底是咋回事?(自己独立思考一会) +承接 4.1 节,我们通过代码输出结果可以看出:**线程池首先会先执行 5 个任务,然后这些任务有任务被执行完的话,就会去拿新的任务执行。** 大家可以先通过上面讲解的内容,分析一下到底是咋回事?(自己独立思考一会) 现在,我们就分析上面的输出内容来简单分析一下线程池原理。 @@ -509,9 +509,9 @@ pool-1-thread-2 End. Time = Sun Apr 12 11:14:47 CST 2020 #### 4.3.1 `Runnable` vs `Callable` -`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口**不会返回结果或抛出检查异常,但是**`Callable` 接口**可以。所以,如果任务不需要返回结果或抛出异常推荐使用 **`Runnable` 接口**,这样代码看起来会更加简洁。 +`Runnable`自 Java 1.0 以来一直存在,但`Callable`仅在 Java 1.5 中引入,目的就是为了来处理`Runnable`不支持的用例。**`Runnable` 接口**不会返回结果或抛出检查异常,但是 **`Callable` 接口**可以。所以,如果任务不需要返回结果或抛出异常推荐使用 **`Runnable` 接口**,这样代码看起来会更加简洁。 -工具类 `Executors` 可以实现 `Runnable` 对象和 `Callable` 对象之间的相互转换。(`Executors.callable(Runnable task`)或 `Executors.callable(Runnable task,Object resule)`)。 +工具类 `Executors` 可以实现将 `Runnable` 对象转换成 `Callable` 对象。(`Executors.callable(Runnable task)` 或 `Executors.callable(Runnable task, Object result)`)。 `Runnable.java` From 4fa8a50dba133aed3b14a2299f7a6275b6181ebd Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Thu, 5 Aug 2021 23:40:24 +0800 Subject: [PATCH 137/257] =?UTF-8?q?fix:=20=E5=90=8C=E6=AD=A5=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E6=B1=A0=E5=8E=9F=E7=90=86=E5=88=86=E6=9E=90=20from?= =?UTF-8?q?=20java=E7=BA=BF=E7=A8=8B=E5=AD=A6=E4=B9=A0=E6=80=BB=E7=BB=93.m?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java并发进阶常见面试题总结.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 92b007db..8b92632d 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -726,36 +726,36 @@ public class ThreadPoolExecutorDemo { **Output:** ``` -pool-1-thread-2 Start. Time = Tue Nov 12 20:59:44 CST 2019 -pool-1-thread-5 Start. Time = Tue Nov 12 20:59:44 CST 2019 -pool-1-thread-4 Start. Time = Tue Nov 12 20:59:44 CST 2019 -pool-1-thread-1 Start. Time = Tue Nov 12 20:59:44 CST 2019 -pool-1-thread-3 Start. Time = Tue Nov 12 20:59:44 CST 2019 -pool-1-thread-5 End. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-3 End. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-2 End. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-4 End. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-1 End. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-2 Start. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-1 Start. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-4 Start. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-3 Start. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-5 Start. Time = Tue Nov 12 20:59:49 CST 2019 -pool-1-thread-2 End. Time = Tue Nov 12 20:59:54 CST 2019 -pool-1-thread-3 End. Time = Tue Nov 12 20:59:54 CST 2019 -pool-1-thread-4 End. Time = Tue Nov 12 20:59:54 CST 2019 -pool-1-thread-5 End. Time = Tue Nov 12 20:59:54 CST 2019 -pool-1-thread-1 End. Time = Tue Nov 12 20:59:54 CST 2019 +pool-1-thread-3 Start. Time = Sun Apr 12 11:14:37 CST 2020 +pool-1-thread-5 Start. Time = Sun Apr 12 11:14:37 CST 2020 +pool-1-thread-2 Start. Time = Sun Apr 12 11:14:37 CST 2020 +pool-1-thread-1 Start. Time = Sun Apr 12 11:14:37 CST 2020 +pool-1-thread-4 Start. Time = Sun Apr 12 11:14:37 CST 2020 +pool-1-thread-3 End. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-4 End. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-1 End. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-5 End. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-1 Start. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-2 End. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-5 Start. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-4 Start. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-3 Start. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-2 Start. Time = Sun Apr 12 11:14:42 CST 2020 +pool-1-thread-1 End. Time = Sun Apr 12 11:14:47 CST 2020 +pool-1-thread-4 End. Time = Sun Apr 12 11:14:47 CST 2020 +pool-1-thread-5 End. Time = Sun Apr 12 11:14:47 CST 2020 +pool-1-thread-3 End. Time = Sun Apr 12 11:14:47 CST 2020 +pool-1-thread-2 End. Time = Sun Apr 12 11:14:47 CST 2020 ``` ### 4.7 线程池原理分析 -承接 4.6 节,我们通过代码输出结果可以看出:**线程池每次会同时执行 5 个任务,这 5 个任务执行完之后,剩余的 5 个任务才会被执行。** 大家可以先通过上面讲解的内容,分析一下到底是咋回事?(自己独立思考一会) +承接 4.6 节,我们通过代码输出结果可以看出:**线程池首先会先执行 5 个任务,然后这些任务有任务被执行完的话,就会去拿新的任务执行。** 大家可以先通过上面讲解的内容,分析一下到底是咋回事?(自己独立思考一会) 现在,我们就分析上面的输出内容来简单分析一下线程池原理。 - **为了搞懂线程池的原理,我们需要首先分析一下 `execute`方法。** 在 4.6 节中的 Demo 中我们使用 `executor.execute(worker)`来提交一个任务到线程池中去,这个方法非常重要,下面我们来看看它的源码: +**为了搞懂线程池的原理,我们需要首先分析一下 `execute`方法。** 在 4.6 节中的 Demo 中我们使用 `executor.execute(worker)`来提交一个任务到线程池中去,这个方法非常重要,下面我们来看看它的源码: ```java // 存放线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount) @@ -802,13 +802,13 @@ public void execute(Runnable command) { 通过下图可以更好的对上面这 3 步做一个展示,下图是我为了省事直接从网上找到,原地址不明。 -![图解线程池实现原理](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/图解线程池实现原理.png) +![图解线程池实现原理](images/java线程池学习总结/图解线程池实现原理.png) 现在,让我们在回到 4.6 节我们写的 Demo, 现在应该是不是很容易就可以搞懂它的原理了呢? 没搞懂的话,也没关系,可以看看我的分析: -> 我们在代码中模拟了 10 个任务,我们配置的核心线程数为 5 、等待队列容量为 100 ,所以每次只可能存在 5 个任务同时执行,剩下的 5 个任务会被放到等待队列中去。当前的 5 个任务执行完成后,才会执行剩下的 5 个任务。 +> 我们在代码中模拟了 10 个任务,我们配置的核心线程数为 5 、等待队列容量为 100 ,所以每次只可能存在 5 个任务同时执行,剩下的 5 个任务会被放到等待队列中去。当前的5个任务中如果有任务被执行完了,线程池就会去拿新的任务执行。 ## 5. Atomic 原子类 From 30f8fad19afe4b4224e71d676188f1ef07cd8a0f Mon Sep 17 00:00:00 2001 From: yamonc Date: Fri, 6 Aug 2021 10:19:55 +0800 Subject: [PATCH 138/257] =?UTF-8?q?=E8=A1=A5=E5=85=85MySQL=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=BC=93=E5=AD=98=E5=86=85=E5=AE=B9=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=83=A8=E5=88=86=E9=94=99=E5=88=AB=E5=AD=97=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/MySQL.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 64dfad2f..0190605a 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -144,11 +144,14 @@ MySQL执行以下命令也可以开启查询缓存 set global query_cache_type=1; set global query_cache_size=600000; ``` -如上,**开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果**。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL库中的系统表,其查询结果也不会被缓存。 +如上,**开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果**。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。(**查询缓存不命中的情况:(1)**)因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,(**查询缓存不命中的情况(2)**)如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL库中的系统表,其查询结果也不会被缓存。 -缓存建立之后,MySQL的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。 +(**查询缓存不命中的情况(3)**)缓存建立之后,MySQL的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。 + +**使用查询缓存的缺点/为什么MySQL8.0要移除这查询缓存?** **缓存虽然能够提升数据库的查询性能,但是缓存同时也带来了额外的开销,每次查询后都要做一次缓存操作,失效后还要销毁。** 因此,开启缓存查询要谨慎,尤其对于写密集的应用来说更是如此。如果开启,要注意合理控制缓存空间大小,一般来说其大小设置为几十MB比较合适。此外,**还可以通过sql_cache和sql_no_cache来控制某个查询语句是否需要缓存:** + ```sql select sql_no_cache count(*) from usr; ``` @@ -159,7 +162,7 @@ select sql_no_cache count(*) from usr; 事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。 -### 事物的四大特性(ACID) +### 事务的四大特性(ACID) ![事物的特性](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/事务特性.png) From 485242c7947d5b73b25203768a3b921e9fb66e9d Mon Sep 17 00:00:00 2001 From: yamonc Date: Fri, 6 Aug 2021 15:30:32 +0800 Subject: [PATCH 139/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0mysql.md=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E8=8C=83=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/MySQL.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 0190605a..d5ab04da 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -55,6 +55,26 @@ ## 常见问题总结 +### 关系型数据库的设计范式? + +**范式**是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”,可以粗略的理解为**一张数据表的表结构所符合的某种设计标准的级别**。 + +- **第一范式**(1NF):符合1NF的关系中的每个属性不可再分。另外第一范式是所有关系型数据库的最基本要求。 + + 第一范式的存在的问题:数据冗余过大、插入异常、删除异常、修改异常等问题。 + +- **第二范式(2NF)**:在符合1NF的基础上,消除了非主属性对于码的部分函数依赖。 + + 第二范式存在的问题: 有可能会出现非主属性对码的传递依赖。 + +- **第三范式(3NF):** 在符合2NF的基础上,消除了非主属性对码的传递函数依赖。也就是说,如果存在非主属性对于码的传递函数依赖,则不符合第三范式的要求。 + + 第三范式存在的问题:存在着**主属性**对于码的部分函数依赖与传递函数依赖。 + +- **BC范式(BCNF)**: 在符合3NF 的基础上消除了主属性对码的部分函数依赖和传递函数依赖。 + +摘自这篇文章[《如何理解关系型数据库的常见设计范式?》](https://www.zhihu.com/question/24696366/answer/29189700) + ### 什么是MySQL? MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。阿里巴巴数据库系统也大量用到了 MySQL,因此它的稳定性是有保障的。MySQL是开放源代码的,因此任何人都可以在 GPL(General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL的默认端口号是**3306**。 From c6d832cf37b00933d042caee2f15ff0606cba30f Mon Sep 17 00:00:00 2001 From: yamonc Date: Sat, 7 Aug 2021 10:10:30 +0800 Subject: [PATCH 140/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=9Adoc/system-design/frameword/spring/SpringInterviewQues?= =?UTF-8?q?tions.md=20=EF=BC=9Aspring=20AOP=E5=92=8CAspectJ=20AOP=E6=9C=89?= =?UTF-8?q?=E4=BB=80=E4=B9=88=E5=8C=BA=E5=88=AB=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BA=8F=E5=8F=B7=EF=BC=8C=E6=96=B9=E4=BE=BF=E8=AE=B0=E5=BF=86?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/spring/SpringInterviewQuestions.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/system-design/framework/spring/SpringInterviewQuestions.md b/docs/system-design/framework/spring/SpringInterviewQuestions.md index a0064f6d..ca99b875 100644 --- a/docs/system-design/framework/spring/SpringInterviewQuestions.md +++ b/docs/system-design/framework/spring/SpringInterviewQuestions.md @@ -93,9 +93,10 @@ AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无 ### 4.2 Spring AOP 和 AspectJ AOP 有什么区别? -**Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。 +1. **Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** +2. **Spring AOP** 基于**代理(Proxying)**,而 **AspectJ** 基于**字节码操作(Bytecode Manipulation)**。 - Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单, +3. **Spring AOP** 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单, 如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。 From cb33610c5dc7a56995f9b73d737b2de0661f2a9a Mon Sep 17 00:00:00 2001 From: yamonc Date: Sat, 7 Aug 2021 10:24:43 +0800 Subject: [PATCH 141/257] =?UTF-8?q?=E6=9B=B4=E6=96=B0spring=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=EF=BC=9A=E6=B7=BB=E5=8A=A0=E7=AE=A1=E7=90=86=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E7=9A=84=E6=96=B9=E5=BC=8F=E3=80=81=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E4=BC=A0=E6=92=AD=E6=96=B9=E5=BC=8F=E6=80=9D=E7=BB=B4=E5=AF=BC?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/spring/SpringInterviewQuestions.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/system-design/framework/spring/SpringInterviewQuestions.md b/docs/system-design/framework/spring/SpringInterviewQuestions.md index ca99b875..9d637143 100644 --- a/docs/system-design/framework/spring/SpringInterviewQuestions.md +++ b/docs/system-design/framework/spring/SpringInterviewQuestions.md @@ -258,6 +258,10 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M 1. 基于XML的声明式事务 2. 基于注解的声明式事务 +**思维导图**: + +![image-20210807101442105](https://gitee.com/yamonc/blogImage/raw/master//img/blogImage/image-20210807101442105.png) + ### 8.2 Spring 事务中的隔离级别有哪几种? **TransactionDefinition 接口中定义了五个表示隔离级别的常量:** @@ -286,6 +290,10 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M - **TransactionDefinition.PROPAGATION_NESTED:** 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。 +**思维导图:** + +![image-20210807102320870](https://gitee.com/yamonc/blogImage/raw/master//img/blogImage/image-20210807102320870.png) + ### 8.4 @Transactional(rollbackFor = Exception.class)注解了解吗? 我们知道:Exception分为运行时异常RuntimeException和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 From 3e91372140caa1349bd44f8795c508d7249d0caf Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 7 Aug 2021 15:14:04 +0800 Subject: [PATCH 142/257] =?UTF-8?q?aop=20=E6=8C=81=E4=B9=85=E5=8C=96?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/Redis/redis-all.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/database/Redis/redis-all.md b/docs/database/Redis/redis-all.md index 3cd8ff62..64ea49d5 100644 --- a/docs/database/Redis/redis-all.md +++ b/docs/database/Redis/redis-all.md @@ -595,7 +595,9 @@ save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生 appendonly yes ``` -开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入硬盘中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都是通过 dir 参数设置的,默认的文件名是 appendonly.aof。 +开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入到内存缓存 `server.aof_buf` 中,然后再根据 `appendfsync` 配置来决定何时将其同步到硬盘中的 AOF 文件。 + +AOF 文件的保存位置和 RDB 文件的位置相同,都是通过 dir 参数设置的,默认的文件名是 `appendonly.aof`。 在 Redis 的配置文件中存在三种不同的 AOF 持久化方式,它们分别是: @@ -605,7 +607,7 @@ appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步 appendfsync no #让操作系统决定何时进行同步 ``` -为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步一次 AOF 文件,Redis 性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis 还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。 +为了兼顾数据和写入性能,用户可以考虑 `appendfsync everysec` 选项 ,让 Redis 每秒同步一次 AOF 文件,Redis 性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis 还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。 **相关 issue** :[783:Redis 的 AOF 方式](https://github.com/Snailclimb/JavaGuide/issues/783) @@ -615,6 +617,10 @@ Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通 如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。 +官方文档地址:https://redis.io/topics/persistence + +![](https://cdn.jsdelivr.net/gh/javaguide-tech/image-host-github-stars-01@main/webfunny_monitor/image-20210807145107290.png) + **补充内容:AOF 重写** AOF 重写可以产生一个新的 AOF 文件,这个新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小。 From ab0874f0db32935fa56755f9bc54beee7b6210d1 Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 7 Aug 2021 15:18:25 +0800 Subject: [PATCH 143/257] =?UTF-8?q?Update=20=E7=B1=BB=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=99=A8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/类加载器.md | 43 ++++++++++------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/docs/java/jvm/类加载器.md b/docs/java/jvm/类加载器.md index 3cd31cdc..01339701 100644 --- a/docs/java/jvm/类加载器.md +++ b/docs/java/jvm/类加载器.md @@ -1,42 +1,26 @@ - - -- [回顾一下类加载过程](#回顾一下类加载过程) -- [类加载器总结](#类加载器总结) -- [双亲委派模型](#双亲委派模型) - - [双亲委派模型介绍](#双亲委派模型介绍) - - [双亲委派模型实现源码分析](#双亲委派模型实现源码分析) - - [双亲委派模型的好处](#双亲委派模型的好处) - - [如果我们不想要双亲委派模型怎么办?](#如果我们不想要双亲委派模型怎么办) -- [自定义类加载器](#自定义类加载器) -- [推荐](#推荐) - - - -> 公众号JavaGuide 后台回复关键字“1”,免费获取JavaGuide配套的Java工程师必备学习资源(文末有公众号二维码)。 - ## 回顾一下类加载过程 类加载过程:**加载->连接->初始化**。连接过程又可分为三步:**验证->准备->解析**。 ![类加载过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png) -一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 `loadClass()` 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。 +一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去自定义类加载器去控制字节流的获取方式(重写一个类加载器的 `loadClass()` 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。 -所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。 +所有的类都由类加载器加载,加载的作用就是将 `.class`文件加载到内存。 ## 类加载器总结 JVM 中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自`java.lang.ClassLoader`: -1. **BootstrapClassLoader(启动类加载器)** :最顶层的加载类,由C++实现,负责加载 `%JAVA_HOME%/lib`目录下的jar包和类或者或被 `-Xbootclasspath`参数指定的路径中的所有类。 -2. **ExtensionClassLoader(扩展类加载器)** :主要负责加载目录 `%JRE_HOME%/lib/ext` 目录下的jar包和类,或被 `java.ext.dirs` 系统变量所指定的路径下的jar包。 -3. **AppClassLoader(应用程序类加载器)** :面向我们用户的加载器,负责加载当前应用classpath下的所有jar包和类。 +1. **BootstrapClassLoader(启动类加载器)** :最顶层的加载类,由 C++实现,负责加载 `%JAVA_HOME%/lib`目录下的 jar 包和类或者被 `-Xbootclasspath`参数指定的路径中的所有类。 +2. **ExtensionClassLoader(扩展类加载器)** :主要负责加载 `%JRE_HOME%/lib/ext` 目录下的 jar 包和类,或被 `java.ext.dirs` 系统变量所指定的路径下的 jar 包。 +3. **AppClassLoader(应用程序类加载器)** :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。 ## 双亲委派模型 ### 双亲委派模型介绍 -每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用 **双亲委派模型** 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派该父类加载器的 `loadClass()` 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 `BootstrapClassLoader` 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为null时,会使用启动类加载器 `BootstrapClassLoader` 作为父类加载器。 +每一个类都有一个对应它的类加载器。系统中的 ClassLoader 在协同工作的时候会默认使用 **双亲委派模型** 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派给父类加载器的 `loadClass()` 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 `BootstrapClassLoader` 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 `BootstrapClassLoader` 作为父类加载器。 ![ClassLoader](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/classloader_WPS图片.png) @@ -61,18 +45,18 @@ The GrandParent of ClassLodarDemo's ClassLoader is null ``` `AppClassLoader`的父类加载器为`ExtClassLoader`, -`ExtClassLoader`的父类加载器为null,**null并不代表`ExtClassLoader`没有父类加载器,而是 `BootstrapClassLoader`** 。 +`ExtClassLoader`的父类加载器为 null,**null 并不代表`ExtClassLoader`没有父类加载器,而是 `BootstrapClassLoader`** 。 -其实这个双亲翻译的容易让别人误解,我们一般理解的双亲都是父母,这里的双亲更多地表达的是“父母这一辈”的人而已,并不是说真的有一个 Mother ClassLoader 和一个 Father ClassLoader 。另外,类加载器之间的“父子”关系也不是通过继承来体现的,是由“优先级”来决定。官方API文档对这部分的描述如下: +其实这个双亲翻译的容易让别人误解,我们一般理解的双亲都是父母,这里的双亲更多地表达的是“父母这一辈”的人而已,并不是说真的有一个 Mother ClassLoader 和一个 Father ClassLoader 。另外,类加载器之间的“父子”关系也不是通过继承来体现的,是由“优先级”来决定。官方 API 文档对这部分的描述如下: ->The Java platform uses a delegation model for loading classes. **The basic idea is that every class loader has a "parent" class loader.** When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself. +> The Java platform uses a delegation model for loading classes. **The basic idea is that every class loader has a "parent" class loader.** When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself. ### 双亲委派模型实现源码分析 双亲委派模型的实现代码非常简单,逻辑非常清晰,都集中在 `java.lang.ClassLoader` 的 `loadClass()` 中,相关代码如下所示。 ```java -private final ClassLoader parent; +private final ClassLoader parent; protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { @@ -90,7 +74,7 @@ protected Class loadClass(String name, boolean resolve) } catch (ClassNotFoundException e) { //抛出异常说明父类加载器无法完成加载请求 } - + if (c == null) { long t1 = System.nanoTime(); //自己尝试加载 @@ -112,7 +96,7 @@ protected Class loadClass(String name, boolean resolve) ### 双亲委派模型的好处 -双亲委派模型保证了Java程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 `java.lang.Object` 类的话,那么程序运行的时候,系统就会出现多个不同的 `Object` 类。 +双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 `java.lang.Object` 类的话,那么程序运行的时候,系统就会出现多个不同的 `Object` 类。 ### 如果我们不想用双亲委派模型怎么办? @@ -129,6 +113,3 @@ protected Class loadClass(String name, boolean resolve) - - - - - - From 95d5aee9729ca687f6f4c12db6d792d75d8b5272 Mon Sep 17 00:00:00 2001 From: yamonc Date: Sat, 7 Aug 2021 15:27:54 +0800 Subject: [PATCH 144/257] =?UTF-8?q?=E4=BF=AE=E6=94=B9MySQL=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=BC=93=E5=AD=98=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/MySQL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 13e08377..81e637b8 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -174,9 +174,9 @@ set global query_cache_type=1; set global query_cache_size=600000; ``` -如上,**开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果**。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果也不会被缓存。 +如上,**开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果**。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。(**查询缓存不命中的情况:(1)**)因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,(**查询缓存不命中的情况:(2)**)如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果也不会被缓存。 -缓存建立之后,MySQL 的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。 +(**查询缓存不命中的情况:(3)**)**缓存建立之后**,MySQL 的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。 **缓存虽然能够提升数据库的查询性能,但是缓存同时也带来了额外的开销,每次查询后都要做一次缓存操作,失效后还要销毁。** 因此,开启查询缓存要谨慎,尤其对于写密集的应用来说更是如此。如果开启,要注意合理控制缓存空间大小,一般来说其大小设置为几十 MB 比较合适。此外,**还可以通过 sql_cache 和 sql_no_cache 来控制某个查询语句是否需要缓存:** From 013b8a0a505f384ef3efaddf79ea3efb3e1766e8 Mon Sep 17 00:00:00 2001 From: yamonc Date: Sun, 8 Aug 2021 09:44:41 +0800 Subject: [PATCH 145/257] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BA=8F=E5=8F=B7?= =?UTF-8?q?=EF=BC=8C=E9=98=85=E8=AF=BB=E8=AE=B0=E5=BF=86=E6=9B=B4=E6=96=B9?= =?UTF-8?q?=E4=BE=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/system-design/framework/mybatis/mybatis-interview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/framework/mybatis/mybatis-interview.md b/docs/system-design/framework/mybatis/mybatis-interview.md index e1195390..db84dee3 100644 --- a/docs/system-design/framework/mybatis/mybatis-interview.md +++ b/docs/system-design/framework/mybatis/mybatis-interview.md @@ -147,7 +147,7 @@ public V get(Object key) { 注:我出的。 -答:MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页,可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。 +答:**(1)** MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页;**(2)** 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,**(3)** 也可以使用分页插件来完成物理分页。 分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。 From c1705c32d23bd231948d8b45632b8362bd317363 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 9 Aug 2021 00:21:28 +0800 Subject: [PATCH 146/257] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=9F=BA=E7=A1=80=E7=9F=A5=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 +- .../{ => mysql}/InnoDB对MVCC的实现.md | 169 ++++++------------ .../{MySQL.md => mysql/MySQL总结.md} | 20 --- .../{ => mysql}/MySQL数据库索引.md | 0 .../MySQL高性能优化规范建议.md | 0 .../一千行MySQL学习笔记.md} | 0 ...条sql语句在mysql中如何执行的.md | 0 .../事务隔离级别(图文详解).md | 0 ...于数据库存储时间的一点思考.md | 0 ...册数据库部分的一些最佳实践.md | 0 docs/database/数据库基础知识.md | 118 ++++++++++++ 11 files changed, 185 insertions(+), 141 deletions(-) rename docs/database/{ => mysql}/InnoDB对MVCC的实现.md (58%) rename docs/database/{MySQL.md => mysql/MySQL总结.md} (92%) rename docs/database/{ => mysql}/MySQL数据库索引.md (100%) rename docs/database/{ => mysql}/MySQL高性能优化规范建议.md (100%) rename docs/database/{一千行MySQL命令.md => mysql/一千行MySQL学习笔记.md} (100%) rename docs/database/{ => mysql}/一条sql语句在mysql中如何执行的.md (100%) rename docs/database/{ => mysql}/事务隔离级别(图文详解).md (100%) rename docs/database/{ => mysql}/关于数据库存储时间的一点思考.md (100%) rename docs/database/{ => mysql}/阿里巴巴开发手册数据库部分的一些最佳实践.md (100%) create mode 100644 docs/database/数据库基础知识.md diff --git a/README.md b/README.md index 6ba56ffb..54eeb07e 100644 --- a/README.md +++ b/README.md @@ -137,18 +137,19 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle **总结:** -1. **[MySQL知识点总结](docs/database/MySQL.md)** (必看 :+1:) -2. [阿里巴巴开发手册数据库部分的一些最佳实践](docs/database/阿里巴巴开发手册数据库部分的一些最佳实践.md) -3. [一千行 MySQL 学习笔记](docs/database/一千行MySQL命令.md) -4. [MySQL 高性能优化规范建议](docs/database/MySQL高性能优化规范建议.md) +1. [数据库基础知识总结](docs/database/数据库基础知识.md) +2. **[MySQL知识点总结](docs/database/mysql/MySQL总结.md)** (必看 :+1:) +3. [阿里巴巴开发手册数据库部分的一些最佳实践](docs/database/mysql/阿里巴巴开发手册数据库部分的一些最佳实践.md) +4. [一千行 MySQL 学习笔记](docs/database/mysql/一千行MySQL学习笔记.md) +5. [MySQL 高性能优化规范建议](docs/database/mysql/MySQL高性能优化规范建议.md) **重要知识点:** -1. [MySQL数据库索引总结](docs/database/MySQL数据库索引.md) -2. [事务隔离级别(图文详解)]() -3. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/一条sql语句在mysql中如何执行的.md) -4. [关于数据库中如何存储时间的一点思考](docs/database/关于数据库存储时间的一点思考.md) -5. [InnoDB存储引擎对MVCC的实现](docs/database/InnoDB对MVCC的实现.md) +1. [MySQL数据库索引总结](docs/database/mysql/MySQL数据库索引.md) +2. [事务隔离级别(图文详解)](docs/database/mysql/事务隔离级别(图文详解).md) +3. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/mysql/一条sql语句在mysql中如何执行的.md) +4. [关于数据库中如何存储时间的一点思考](docs/database/mysql/关于数据库存储时间的一点思考.md) +5. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/InnoDB对MVCC的实现.md) ### Redis diff --git a/docs/database/InnoDB对MVCC的实现.md b/docs/database/mysql/InnoDB对MVCC的实现.md similarity index 58% rename from docs/database/InnoDB对MVCC的实现.md rename to docs/database/mysql/InnoDB对MVCC的实现.md index bb2a70b0..9f3ed51d 100644 --- a/docs/database/InnoDB对MVCC的实现.md +++ b/docs/database/mysql/InnoDB对MVCC的实现.md @@ -1,34 +1,30 @@ - [一致性非锁定读和锁定读](#一致性非锁定读和锁定读) - - [一致性非锁定读](#一致性非锁定读) - - [锁定读](#锁定读) -- [InnoDB对MVCC的实现](#InnoDB对MVCC的实现) - - [隐藏字段](#隐藏字段]) - - [ReadView](#ReadView) - - [undo-log](#undo-log) - - [数据可见性算法](#数据可见性算法) -- [RC、RR隔离级别下MVCC的差异](#RC、RR隔离级别下MVCC的差异) -- [MVCC解决不可重复读问题](#MVCC解决不可重复读问题) - - [在RC下ReadView生成情况](#在RC下ReadView生成情况) - - [在RR下ReadView生成情况](#在RR下ReadView生成情况) -- [MVCC+Next-key-Lock防止幻读](#MVCC➕Next-key-Lock防止幻读) + - [一致性非锁定读](#一致性非锁定读) + - [锁定读](#锁定读) +- [InnoDB 对 MVCC 的实现](#InnoDB对MVCC的实现) + - [隐藏字段](#隐藏字段]) + - [ReadView](#ReadView) + - [undo-log](#undo-log) + - [数据可见性算法](#数据可见性算法) +- [RC、RR 隔离级别下 MVCC 的差异](#RC、RR隔离级别下MVCC的差异) +- [MVCC 解决不可重复读问题](#MVCC解决不可重复读问题) + - [在 RC 下 ReadView 生成情况](#在RC下ReadView生成情况) + - [在 RR 下 ReadView 生成情况](#在RR下ReadView生成情况) +- [MVCC+Next-key-Lock 防止幻读](#MVCC➕Next-key-Lock防止幻读) - - ## 一致性非锁定读和锁定读 #### 一致性非锁定读 -对于 [**一致性非锁定读(Consistent Nonlocking Reads)** ](https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html)的实现,通常做法是加一个版本号或者时间戳字段,在更新数据的同时版本号 + 1或者更新时间戳。查询时,将当前可见的版本号与对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见 +对于 [**一致性非锁定读(Consistent Nonlocking Reads)** ](https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html)的实现,通常做法是加一个版本号或者时间戳字段,在更新数据的同时版本号 + 1 或者更新时间戳。查询时,将当前可见的版本号与对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见 在 `InnoDB` 存储引擎中,[多版本控制 (multi versioning)](https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html) 就是对非锁定读的实现。如果读取的行正在执行 `DELETE` 或 `UPDATE` 操作,这时读取操作不会去等待行上锁的释放。相反地,`InnoDB` 存储引擎会去读取行的一个快照数据,对于这种读取历史数据的方式,我们叫它快照读 (snapshot read) -在 `Repeatable Read` 和 `Read Committed` 两个隔离级别下,如果是执行普通的 `select` 语句(不包括 `select ... lock in share mode` ,` select ... for update`)则会使用 `一致性非锁定读(MVCC)`。并且在 `Repeatable Read` 下 `MVCC` 实现了可重复读和防止部分幻读 - - +在 `Repeatable Read` 和 `Read Committed` 两个隔离级别下,如果是执行普通的 `select` 语句(不包括 `select ... lock in share mode` ,`select ... for update`)则会使用 `一致性非锁定读(MVCC)`。并且在 `Repeatable Read` 下 `MVCC` 实现了可重复读和防止部分幻读 #### 锁定读 @@ -38,35 +34,25 @@ - select ... for update - insert、update、delete 操作 - - 在锁定读下,读取的是数据的最新版本,这种读也被称为 `当前读(current read)`。锁定读会对读取到的记录加锁: - `select ... lock in share mode`:对记录加 `S` 锁,其它事务也可以加`S`锁,如果加 `x` 锁则会被阻塞 -- `select ... for update`、`insert`、`update`、`delete `:对记录加 `X` 锁,且其它事务不能加任何锁 +- `select ... for update`、`insert`、`update`、`delete`:对记录加 `X` 锁,且其它事务不能加任何锁 +在一致性非锁定读下,即使读取的记录已被其它事务加上 `X` 锁,这时记录也是可以被读取的,即读取的快照数据。上面说了在 `Repeatable Read` 下 `MVCC` 防止了部分幻读,这边的 “部分” 是指在 `一致性非锁定读` 情况下,只能读取到第一次查询之前所插入的数据(根据 Read View 判断数据可见性,Read View 在第一次查询时生成),但如果是`当前读` ,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。**所以 `InnoDB` 在实现`Repeatable Read` 时,如果执行的是当前读,则会对读取的记录使用 `Next-key Lock` ,来防止其它事务在间隙间插入数据** - -在一致性非锁定读下,即使读取的记录已被其它事务加上 `X` 锁,这时记录也是可以被读取的,即读取的快照数据。上面说了在 `Repeatable Read` 下 `MVCC` 防止了部分幻读,这边的 “部分” 是指在 `一致性非锁定读` 情况下,只能读取到第一次查询之前所插入的数据(根据Read View判断数据可见性,Read View在第一次查询时生成),但如果是`当前读` ,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。**所以 `InnoDB` 在实现`Repeatable Read` 时,如果执行的是当前读,则会对读取的记录使用 `Next-key Lock` ,来防止其它事务在间隙间插入数据** - - - -## InnoDB对MVCC的实现 +## InnoDB 对 MVCC 的实现 `MVCC` 的实现依赖于:**隐藏字段、Read View、undo log**。在内部实现中,`InnoDB` 通过数据行的 `DB_TRX_ID` 和 `Read View` 来判断数据的可见性,如不可见,则通过数据行的 `DB_ROLL_PTR` 找到 `undo log` 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 `Read View` 之前已经提交的修改和该事务本身做的修改 - - #### 隐藏字段 在内部,`InnoDB` 存储引擎为每行数据添加了三个 [隐藏字段](https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html): -- `DB_TRX_ID(6字节)`:表示最后一次插入或更新该行的事务id。此外,`delete` 操作在内部被视为更新,只不过会在记录头 `Record header` 中的 `deleted_flag` 字段将其标记为已删除 +- `DB_TRX_ID(6字节)`:表示最后一次插入或更新该行的事务 id。此外,`delete` 操作在内部被视为更新,只不过会在记录头 `Record header` 中的 `deleted_flag` 字段将其标记为已删除 - `DB_ROLL_PTR(7字节)` 回滚指针,指向该行的 `undo log` 。如果该行未被更新,则为空 -- `DB_ROW_ID(6字节)`:如果没有设置主键且该表没有唯一非空索引时,`InnoDB` 会使用该id来生成聚簇索引 - - +- `DB_ROW_ID(6字节)`:如果没有设置主键且该表没有唯一非空索引时,`InnoDB` 会使用该 id 来生成聚簇索引 #### ReadView @@ -74,12 +60,10 @@ 主要有以下字段: -- `m_low_limit_id`:目前出现过的最大的事务ID+1,即下一个将被分配的事务ID。大于这个ID的数据版本均不可见 -- `m_up_limit_id`:活跃事务列表 `m_ids` 中最小的事务ID,如果 `m_ids` 为空,则 `m_up_limit_id` 为 `m_low_limit_id`。小于这个ID的数据版本均可见 -- `m_ids`:`Read View` 创建时其他未提交的活跃事务ID列表。创建 `Read View `时,将当前未提交事务ID记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的。`m_ids` 不包括当前事务自己和已提交的事务(正在内存中) -- `m_creator_trx_id`:创建该 `Read View` 的事务ID - - +- `m_low_limit_id`:目前出现过的最大的事务 ID+1,即下一个将被分配的事务 ID。大于这个 ID 的数据版本均不可见 +- `m_up_limit_id`:活跃事务列表 `m_ids` 中最小的事务 ID,如果 `m_ids` 为空,则 `m_up_limit_id` 为 `m_low_limit_id`。小于这个 ID 的数据版本均可见 +- `m_ids`:`Read View` 创建时其他未提交的活跃事务 ID 列表。创建 `Read View`时,将当前未提交事务 ID 记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的。`m_ids` 不包括当前事务自己和已提交的事务(正在内存中) +- `m_creator_trx_id`:创建该 `Read View` 的事务 ID #### undo-log @@ -88,43 +72,29 @@ - 当事务回滚时用于将数据恢复到修改前的样子 - 另一个作用是 `MVCC` ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 `undo log` 读取之前的版本数据,以此实现非锁定读 - - **在 `InnoDB` 存储引擎中 `undo log` 分为两种: `insert undo log` 和 `update undo log`:** - - 1. **`insert undo log`** :指在 `insert` 操作中产生的 `undo log`。因为 `insert` 操作的记录只对事务本身可见,对其他事务不可见,故该 `undo log` 可以在事务提交后直接删除。不需要进行 `purge` 操作 - - **`insert` 时的数据初始状态:** ![markdown](https://ddmcc-1255635056.file.myqcloud.com/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png) 2. **`update undo log`** :`update` 或 `delete` 操作中产生的 `undo log`。该 `undo log`可能需要提供 `MVCC` 机制,因此不能在事务提交时就进行删除。提交时放入 `undo log` 链表,等待 `purge线程` 进行最后的删除 - - **数据第一次被修改时:** - - ![markdown](https://ddmcc-1255635056.file.myqcloud.com/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png) **数据第二次被修改时:** - - ![markdown](https://ddmcc-1255635056.file.myqcloud.com/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png) 不同事务或者相同事务的对同一记录行的修改,会使该记录行的 `undo log` 成为一条链表,链首就是最新的记录,链尾就是最早的旧记录 - - #### 数据可见性算法 -在 `InnoDB` 存储引擎中,创建一个新事务后,执行每个 `select` 语句前,都会创建一个快照(Read View),**快照中保存了当前数据库系统中正处于活跃(没有commit)的事务的ID号**。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务ID列表(即m_ids)。当用户在这个事务中要读取某个记录行的时候,`InnoDB` 会将该记录行的 `DB_TRX_ID` 与 `Read View` 中的一些变量及当前事务ID进行比较,判断是否满足可见性条件 +在 `InnoDB` 存储引擎中,创建一个新事务后,执行每个 `select` 语句前,都会创建一个快照(Read View),**快照中保存了当前数据库系统中正处于活跃(没有 commit)的事务的 ID 号**。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务 ID 列表(即 m_ids)。当用户在这个事务中要读取某个记录行的时候,`InnoDB` 会将该记录行的 `DB_TRX_ID` 与 `Read View` 中的一些变量及当前事务 ID 进行比较,判断是否满足可见性条件 [具体的比较算法](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L161)如下:[图源](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/#MVCC-1) @@ -132,30 +102,26 @@ 1. 如果记录 DB_TRX_ID < m_up_limit_id,那么表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照之前就提交了,所以该记录行的值对当前事务是可见的 -2. 如果 DB_TRX_ID >= m_low_limit_id,那么表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照之后才修改该行,所以该记录行的值对当前事务不可见。跳到步骤5 +2. 如果 DB_TRX_ID >= m_low_limit_id,那么表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照之后才修改该行,所以该记录行的值对当前事务不可见。跳到步骤 5 3. m_ids 为空,则表明在当前事务创建快照之前,修改该行的事务就已经提交了,所以该记录行的值对当前事务是可见的 4. 如果 m_up_limit_id <= DB_TRX_ID < m_up_limit_id,表明最新修改该行的事务(DB_TRX_ID)在当前事务创建快照的时候可能处于“活动状态”或者“已提交状态”;所以就要对活跃事务列表 m_ids 进行查找(源码中是用的二分查找,因为是有序的) - - 如果在活跃事务列表 m_ids 中能找到 DB_TRX_ID,表明:①在当前事务创建快照前,该记录行的值被事务ID为 DB_TRX_ID 的事务修改了,但没有提交;或者 ②在当前事务创建快照后,该记录行的值被事务ID为 DB_TRX_ID 的事务修改了。这些情况下,这个记录行的值对当前事务都是不可见的。跳到步骤5 + - 如果在活跃事务列表 m_ids 中能找到 DB_TRX_ID,表明:① 在当前事务创建快照前,该记录行的值被事务 ID 为 DB_TRX_ID 的事务修改了,但没有提交;或者 ② 在当前事务创建快照后,该记录行的值被事务 ID 为 DB_TRX_ID 的事务修改了。这些情况下,这个记录行的值对当前事务都是不可见的。跳到步骤 5 - - 在活跃事务列表中找不到,则表明“id为trx_id的事务”在修改“该记录行的值”后,在“当前事务”创建快照前就已经提交了,所以记录行对当前事务可见 + - 在活跃事务列表中找不到,则表明“id 为 trx_id 的事务”在修改“该记录行的值”后,在“当前事务”创建快照前就已经提交了,所以记录行对当前事务可见 -5. 在该记录行的 DB_ROLL_PTR 指针所指向的 `undo log` 取出快照记录,用快照记录的 DB_TRX_ID 跳到步骤1重新开始判断,直到找到满足的快照版本或返回空 +5. 在该记录行的 DB_ROLL_PTR 指针所指向的 `undo log` 取出快照记录,用快照记录的 DB_TRX_ID 跳到步骤 1 重新开始判断,直到找到满足的快照版本或返回空 +## RC 和 RR 隔离级别下 MVCC 的差异 +在事务隔离级别 `RC` 和 `RR` (InnoDB 存储引擎的默认事务隔离级别)下,`InnoDB` 存储引擎使用 `MVCC`(非锁定一致性读),但它们生成 `Read View` 的时机却不同 -## RC和RR隔离级别下MVCC的差异 +- 在 RC 隔离级别下的 **`每次select`** 查询前都生成一个`Read View` (m_ids 列表) +- 在 RR 隔离级别下只在事务开始后 **`第一次select`** 数据前生成一个`Read View`(m_ids 列表) -在事务隔离级别 `RC` 和 `RR` (InnoDB存储引擎的默认事务隔离级别)下,` InnoDB` 存储引擎使用 `MVCC`(非锁定一致性读),但它们生成 `Read View` 的时机却不同 - -- 在 RC 隔离级别下的 **`每次select`** 查询前都生成一个`Read View` (m_ids列表) -- 在 RR 隔离级别下只在事务开始后 **`第一次select`** 数据前生成一个`Read View`(m_ids列表) - - - -## MVCC解决不可重复读问题 +## MVCC 解决不可重复读问题 虽然 RC 和 RR 都通过 `MVCC` 来读取快照数据,但由于 **生成 Read View 时机不同**,从而在 RR 级别下实现可重复读 @@ -163,63 +129,51 @@ ![markdown](https://ddmcc-1255635056.file.myqcloud.com/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png) - -#### **在RC下ReadView生成情况** +#### **在 RC 下 ReadView 生成情况** 1. **`假设时间线来到 T4 ,那么此时数据行 id = 1 的版本链为`:** ![markdown](https://ddmcc-1255635056.file.myqcloud.com/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png) -由于 RC 级别下每次查询都会生成` Read View` ,并且事务101、102 并未提交,此时 `103` 事务生成的 `Read View` 中活跃的事务 **`m_ids` 为:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 - -- 此时最新记录的 `DB_TRX_ID` 为101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 -- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 -- 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` - +由于 RC 级别下每次查询都会生成`Read View` ,并且事务 101、102 并未提交,此时 `103` 事务生成的 `Read View` 中活跃的事务 **`m_ids` 为:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 +- 此时最新记录的 `DB_TRX_ID` 为 101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是 101,不可见 +- 继续找上一条 `DB_TRX_ID`为 1,满足 1 < m_up_limit_id,可见,所以事务 103 查询到数据为 `name = 菜花` 2. **`时间线来到 T6 ,数据的版本链为`:** ![markdown](https://ddmcc-1255635056.file.myqcloud.com/528559e9-dae8-4d14-b78d-a5b657c88391.png) -因为在 RC 级别下,重新生成 `Read View`,这时事务101已经提交,102并未提交,所以此时 `Read View` 中活跃的事务 **`m_ids`:[102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:102,`m_creator_trx_id`为:103 - -- 此时最新记录的 `DB_TRX_ID` 为102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 - -- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为101,满足 102 < m_up_limit_id,记录可见,所以在 `T6` 时间点查询到数据为 `name = 李四`,与时间 T4 查询到的结果不一致,不可重复读! +因为在 RC 级别下,重新生成 `Read View`,这时事务 101 已经提交,102 并未提交,所以此时 `Read View` 中活跃的事务 **`m_ids`:[102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:102,`m_creator_trx_id`为:103 +- 此时最新记录的 `DB_TRX_ID` 为 102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为 101,满足 102 < m_up_limit_id,记录可见,所以在 `T6` 时间点查询到数据为 `name = 李四`,与时间 T4 查询到的结果不一致,不可重复读! 3. **`时间线来到 T9 ,数据的版本链为`:** - - ![markdown](https://ddmcc-1255635056.file.myqcloud.com/6f82703c-36a1-4458-90fe-d7f4edbac71a.png) -重新生成 `Read View`, 这时事务 101 和 102 都已经提交,所以 **m_ids** 为空,则 m_up_limit_id = m_low_limit_id = 104,最新版本事务ID为102,满足 102 < m_low_limit_id,可见,查询结果为 `name = 赵六` +重新生成 `Read View`, 这时事务 101 和 102 都已经提交,所以 **m_ids** 为空,则 m_up_limit_id = m_low_limit_id = 104,最新版本事务 ID 为 102,满足 102 < m_low_limit_id,可见,查询结果为 `name = 赵六` +> **总结:** **在 RC 隔离级别下,事务在每次查询开始时都会生成并设置新的 Read View,所以导致不可重复读** +#### **在 RR 下 ReadView 生成情况** -> **总结:** **在RC隔离级别下,事务在每次查询开始时都会生成并设置新的 Read View,所以导致不可重复读** - - -#### **在RR下ReadView生成情况** - -**在可重复读级别下,只会在事务开始后第一次读取数据时生成一个Read View(m_ids列表)** +**在可重复读级别下,只会在事务开始后第一次读取数据时生成一个 Read View(m_ids 列表)** 1. **`在 T4 情况下的版本链为`:** - ![markdown](https://ddmcc-1255635056.file.myqcloud.com/0e906b95-c916-4f30-beda-9cb3e49746bf.png) 在当前执行 `select` 语句时生成一个 `Read View`,此时 **`m_ids`:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 此时和 RC 级别下一样: -- 最新记录的 `DB_TRX_ID` 为101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 -- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 -- 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` - +- 最新记录的 `DB_TRX_ID` 为 101,m_up_limit_id <= 101 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是 101,不可见 +- 继续找上一条 `DB_TRX_ID`为 1,满足 1 < m_up_limit_id,可见,所以事务 103 查询到数据为 `name = 菜花` 2. **`时间点 T6 情况下`:** @@ -227,28 +181,21 @@ 在 RR 级别下只会生成一次`Read View`,所以此时依然沿用 **`m_ids` :[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 +- 最新记录的 `DB_TRX_ID` 为 102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 - - 最新记录的 `DB_TRX_ID` 为102,m_up_limit_id <= 102 < m_low_limit_id,所以要在 `m_ids` 列表中查找,发现 `DB_TRX_ID` 存在列表中,那么这个记录不可见 - - - 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为101,不可见 - - - 继续根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是101,不可见 - - - 继续找上一条 `DB_TRX_ID`为1,满足 1 < m_up_limit_id,可见,所以事务103查询到数据为 `name = 菜花` +- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为 101,不可见 +- 继续根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是 101,不可见 +- 继续找上一条 `DB_TRX_ID`为 1,满足 1 < m_up_limit_id,可见,所以事务 103 查询到数据为 `name = 菜花` 3. **时间点 T9 情况下:** ![markdown](https://ddmcc-1255635056.file.myqcloud.com/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png) - - 此时情况跟 T6 完全一样,由于已经生成了 `Read View`,此时依然沿用 **`m_ids` :[101,102]** ,所以查询结果依然是 `name = 菜花` - - -## MVCC➕Next-key-Lock防止幻读 +## MVCC➕Next-key-Lock 防止幻读 `InnoDB`存储引擎在 RR 级别下通过 `MVCC`和 `Next-key Lock` 来解决幻读问题: @@ -256,15 +203,13 @@ 在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 `Read View` ,并使用至事务提交。所以在生成 `Read View` 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读” -2. **执行select...for update/lock in share mode、insert、update、delete等当前读** +2. **执行 select...for update/lock in share mode、insert、update、delete 等当前读** 在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!`InnoDB` 使用 [Next-key Lock](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-next-key-locks) 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读 - - ## 参考 -- **《MySQL技术内幕InnoDB存储引擎第2版》** +- **《MySQL 技术内幕 InnoDB 存储引擎第 2 版》** -- [Innodb中的事务隔离级别和锁的关系](https://tech.meituan.com/2014/08/20/innodb-lock.html) -- [MySQL事务与MVCC如何实现的隔离级别](https://blog.csdn.net/qq_35190492/article/details/109044141) \ No newline at end of file +- [Innodb 中的事务隔离级别和锁的关系](https://tech.meituan.com/2014/08/20/innodb-lock.html) +- [MySQL 事务与 MVCC 如何实现的隔离级别](https://blog.csdn.net/qq_35190492/article/details/109044141) \ No newline at end of file diff --git a/docs/database/MySQL.md b/docs/database/mysql/MySQL总结.md similarity index 92% rename from docs/database/MySQL.md rename to docs/database/mysql/MySQL总结.md index 81e637b8..242c487f 100644 --- a/docs/database/MySQL.md +++ b/docs/database/mysql/MySQL总结.md @@ -22,32 +22,12 @@ MySQL、PostgreSQL、Oracle、SQL Server、SQLite(微信本地的聊天记录 由于 MySQL 是开源免费并且比较成熟的数据库,因此,MySQL 被大量使用在各种系统中。任何人都可以在 GPL(General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL 的默认端口号是**3306**。 -### 关系型数据库的设计范式? -**范式**是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”,可以粗略的理解为**一张数据表的表结构所符合的某种设计标准的级别**。 - -- **第一范式**(1NF):符合1NF的关系中的每个属性不可再分。另外第一范式是所有关系型数据库的最基本要求。 - - 第一范式的存在的问题:数据冗余过大、插入异常、删除异常、修改异常等问题。 - -- **第二范式(2NF)**:在符合1NF的基础上,消除了非主属性对于码的部分函数依赖。 - - 第二范式存在的问题: 有可能会出现非主属性对码的传递依赖。 - -- **第三范式(3NF):** 在符合2NF的基础上,消除了非主属性对码的传递函数依赖。也就是说,如果存在非主属性对于码的传递函数依赖,则不符合第三范式的要求。 - - 第三范式存在的问题:存在着**主属性**对于码的部分函数依赖与传递函数依赖。 - -- **BC范式(BCNF)**: 在符合3NF 的基础上消除了主属性对码的部分函数依赖和传递函数依赖。 - -摘自这篇文章[《如何理解关系型数据库的常见设计范式?》](https://www.zhihu.com/question/24696366/answer/29189700) ## 存储引擎 ### 存储引擎相关的命令 -**查看MySQL提供的所有存储引擎** -======= **查看 MySQL 提供的所有存储引擎** ```sql diff --git a/docs/database/MySQL数据库索引.md b/docs/database/mysql/MySQL数据库索引.md similarity index 100% rename from docs/database/MySQL数据库索引.md rename to docs/database/mysql/MySQL数据库索引.md diff --git a/docs/database/MySQL高性能优化规范建议.md b/docs/database/mysql/MySQL高性能优化规范建议.md similarity index 100% rename from docs/database/MySQL高性能优化规范建议.md rename to docs/database/mysql/MySQL高性能优化规范建议.md diff --git a/docs/database/一千行MySQL命令.md b/docs/database/mysql/一千行MySQL学习笔记.md similarity index 100% rename from docs/database/一千行MySQL命令.md rename to docs/database/mysql/一千行MySQL学习笔记.md diff --git a/docs/database/一条sql语句在mysql中如何执行的.md b/docs/database/mysql/一条sql语句在mysql中如何执行的.md similarity index 100% rename from docs/database/一条sql语句在mysql中如何执行的.md rename to docs/database/mysql/一条sql语句在mysql中如何执行的.md diff --git a/docs/database/事务隔离级别(图文详解).md b/docs/database/mysql/事务隔离级别(图文详解).md similarity index 100% rename from docs/database/事务隔离级别(图文详解).md rename to docs/database/mysql/事务隔离级别(图文详解).md diff --git a/docs/database/关于数据库存储时间的一点思考.md b/docs/database/mysql/关于数据库存储时间的一点思考.md similarity index 100% rename from docs/database/关于数据库存储时间的一点思考.md rename to docs/database/mysql/关于数据库存储时间的一点思考.md diff --git a/docs/database/阿里巴巴开发手册数据库部分的一些最佳实践.md b/docs/database/mysql/阿里巴巴开发手册数据库部分的一些最佳实践.md similarity index 100% rename from docs/database/阿里巴巴开发手册数据库部分的一些最佳实践.md rename to docs/database/mysql/阿里巴巴开发手册数据库部分的一些最佳实践.md diff --git a/docs/database/数据库基础知识.md b/docs/database/数据库基础知识.md new file mode 100644 index 00000000..71af7f01 --- /dev/null +++ b/docs/database/数据库基础知识.md @@ -0,0 +1,118 @@ +数据库知识基础,这部分内容一定要理解记忆。虽然这部分内容只是理论知识,但是非常重要,这是后面学习 MySQL 数据库的基础。PS:这部分内容由于涉及太多概念性内容,所以参考了维基百科和百度百科相应的介绍。 + +## 什么是数据库,数据库管理系统,数据库系统,数据库管理员? + +- **数据库** :数据库(DataBase 简称 DB)就是信息的集合或者说数据库是由数据库管理系统管理的数据的集合。 +- **数据库管理系统** : 数据库管理系统(Database Management System 简称 DBMS)是一种操纵和管理数据库的大型软件,通常用语用于建立、使用和维护数据库。 +- **数据库系统** : 数据库系统(Data Base System,简称 DBS)通常由软件、数据库和数据管理员(DBA)组成。 +- **数据库管理员** : 数据库管理员(Database Administrator,简称 DBA)负责全面管理和控制数据库系统。 + +数据库系统基本构成如下图所示: + +![数据库系统基本构成](https://img-blog.csdnimg.cn/img_convert/e21120184e63406526a4e873cacd23f2.png) + +## 什么是元组,码,候选码,主码,外码,主属性,非主属性? + +- **元组** : 元组(tuple)是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性。 在二维表里,元组也称为行。 +- **码** :码就是能唯一标识实体的属性,对应表中的列。 +- **候选码** : 若关系中的某一属性或属性组的值能唯一的标识一个元组,而其任何、子集都不能再标识,则称该属性组为候选码。例如:在学生实体中,“学号”是能唯一的区分学生实体的,同时又假设“姓名”、“班级”的属性组合足以区分学生实体,那么{学号}和{姓名,班级}都是候选码。 +- **主码** : 主码也叫主键。主码是从候选码中选出来的。 一个实体集中只能有一个主码,但可以有多个候选码。 +- **外码** : 外码也叫外键。如果一个关系中的一个属性是另外一个关系中的主码则这个属性为外码。 +- **主属性** : 候选码中出现过的属性称为主属性。比如关系 工人(工号,身份证号,姓名,性别,部门).显然工号和身份证号都能够唯一标示这个关系,所以都是候选码。工号、身份证号这两个属性就是主属性。如果主码是一个属性组,那么属性组中的属性都是主属性。 +- **非主属性:** 不包含在任何一个候选码中的属性称为非主属性。比如在关系——学生(学号,姓名,年龄,性别,班级)中,主码是“学号”,那么其他的“姓名”、“年龄”、“性别”、“班级”就都可以称为非主属性。 + +## 主键和外键有什么区别? + +- **主键(主码)** :主键用于唯一标识一个元组,不能有重复,不允许为空。一个表只能有一个主键。 +- **外键(外码)** :外键用来和其他表建立联系用,外键是另一表的主键,外键是可以有重复的,可以是空值。一个表可以有多个外键。 + +## 什么是 ER 图? + +> 我们做一个项目的时候一定要试着花 ER 图来捋清数据库设计,这个也是面试官问你项目的时候经常会被问道的。 + +**E-R 图**也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 它是描述现实世界关系概念模型的有效方法。 是表示概念关系模型的一种方式。 + +下图是一个学生选课的 ER 图,每个学生可以选若干门课程,同一门课程也可以被若干人选择,所以它们之间的关系是多对多(M:N)。另外,还有其他两种关系是:1 对 1(1:1)、1 对多(1:N)。 + +![ER图示例](https://img-blog.csdnimg.cn/img_convert/4717673e36966e0e4b33fccfd753f6ea.png) + +我们试着将上面的 ER 图转换成数据库实际的关系模型(实际设计中,我们通常会将任课教师也作为一个实体来处理): + +![关系模型](https://img-blog.csdnimg.cn/img_convert/5897753dfb301dfa3a814ab06e718a5e.png) + +## 数据库范式了解吗? + +**1NF(第一范式)** + +属性(对应于表中的字段)不能再被分割,也就是这个字段只能是一个值,不能再分为多个其他的字段了。**1NF 是所有关系型数据库的最基本要求** ,也就是说关系型数据库中创建的表一定满足第一范式。 + +**2NF(第二范式)** + +2NF 在 1NF 的基础之上,消除了非主属性对于码的部分函数依赖。如下图所示,展示了第一范式到第二范式的过渡。第二范式在第一范式的基础上增加了一个列,这个列称为主键,非主属性都依赖于主键。 + +![第二范式](https://img-blog.csdnimg.cn/img_convert/bd1d31be3779342427fc9e462bf7f05c.png) + +一些重要的概念: + +- **函数依赖(functional dependency)** :若在一张表中,在属性(或属性组)X 的值确定的情况下,必定能确定属性 Y 的值,那么就可以说 Y 函数依赖于 X,写作 X → Y。 +- **部分函数依赖(partial functional dependency)** :如果 X→Y,并且存在 X 的一个真子集 X0,使得 X0→Y,则称 Y 对 X 部分函数依赖。比如学生基本信息表 R 中(学号,身份证号,姓名)当然学号属性取值是唯一的,在 R 关系中,(学号,身份证号)->(姓名),(学号)->(姓名),(身份证号)->(姓名);所以姓名部分函数依赖与(学号,身份证号); +- **完全函数依赖(Full functional dependency)** :在一个关系中,若某个非主属性数据项依赖于全部关键字称之为完全函数依赖。比如学生基本信息表 R(学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在 R 关系中,(学号,班级)->(姓名),但是(学号)->(姓名)不成立,(班级)->(姓名)不成立,所以姓名完全函数依赖与(学号,班级); +- **传递函数依赖** : 在关系模式 R(U)中,设 X,Y,Z 是 U 的不同的属性子集,如果 X 确定 Y、Y 确定 Z,且有 X 不包含 Y,Y 不确定 X,(X∪Y)∩Z=空集合,则称 Z 传递函数依赖(transitive functional dependency) 于 X。传递函数依赖会导致数据冗余和异常。传递函数依赖的 Y 和 Z 子集往往同属于某一个事物,因此可将其合并放到一个表中。比如在关系 R(学号 ,姓名, 系名,系主任)中,学号 → 系名,系名 → 系主任,所以存在非主属性系主任对于学号的传递函数依赖。。 + +**3NF(第三范式)** + +3NF 在 2NF 的基础之上,消除了非主属性对于码的传递函数依赖 。符合 3NF 要求的数据库设计,**基本**上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。比如在关系 R(学号 ,姓名, 系名,系主任)中,学号 → 系名,系名 → 系主任,所以存在非主属性系主任对于学号的传递函数依赖,所以该表的设计,不符合 3NF 的要求。 + +**总结** + +- 1NF:属性不可再分。 +- 2NF:1NF 的基础之上,消除了非主属性对于码的部分函数依赖。 +- 3NF:3NF 在 2NF 的基础之上,消除了非主属性对于码的传递函数依赖 。 + +## 什么是存储过程? + +我们可以把存储过程看成是一些 SQL 语句的集合,中间加了点逻辑控制语句。存储过程在业务比较复杂的时候是非常实用的,比如很多时候我们完成一个操作可能需要写一大串 SQL 语句,这时候我们就可以写有一个存储过程,这样也方便了我们下一次的调用。存储过程一旦调试完成通过后就能稳定运行,另外,使用存储过程比单纯 SQL 语句执行要快,因为存储过程是预编译过的。 + +存储过程在互联网公司应用不多,因为存储过程难以调试和扩展,而且没有移植性,还会消耗数据库资源。 + +阿里巴巴 Java 开发手册里要求禁止使用存储过程。 + +![阿里巴巴Java开发手册:禁止存储过程](https://img-blog.csdnimg.cn/img_convert/0fa082bc4d4f919065767476a41b2156.png) + +## drop、delete 与 truncate 区别? + +### 用法不同 + +- drop(丢弃数据): `drop table 表名` ,直接将表都删除掉,在删除表的时候使用。 +- truncate (清空数据) : `truncate table 表名` ,只删除表中的数据,再插入数据的时候自增长 id 又从 1 开始,在清空表中数据的时候使用。 +- delete(删除数据) : `delete from 表名 where 列名=值`,删除某一列的数据,如果不加 where 子句和`truncate table 表名`作用类似。 + +truncate 和不带 where 子句的 delete、以及 drop 都会删除表内的数据,但是 **truncate 和 delete 只删除数据不删除表的结构(定义),执行 drop 语句,此表的结构也会删除,也就是执行 drop 之后对应的表不复存在。** + +### 属于不同的数据库语言 + +truncate 和 drop 属于 DDL(数据定义语言)语句,操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。而 delete 语句是 DML (数据库操作语言)语句,这个操作会放到 rollback segement 中,事务提交之后才生效。 + +**DML 语句和 DDL 语句区别:** + +- DML 是数据库操作语言(Data Manipulation Language)的缩写,是指对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select),是开发人员日常使用最频繁的操作。 +- DDL (Data Definition Language)是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改的操作语言。它和 DML 语言的最大区别是 DML 只是对表内部数据的操作,而不涉及到表的定义、结构的修改,更不会涉及到其他对象。DDL 语句更多的被数据库管理员(DBA)所使用,一般的开发人员很少使用。 + +### 执行速度不同 + +一般来说:drop>truncate>delete(这个我没有设计测试过)。 + +## 数据库设计通常分为哪几步? + +1. **需求分析** : 分析用户的需求,包括数据、功能和性能需求。 +2. **概念结构设计** : 主要采用 E-R 模型进行设计,包括画 E-R 图。 +3. **逻辑结构设计** : 通过将 E-R 图转换成表,实现从 E-R 模型到关系模型的转换。 +4. **物理结构设计** : 主要是为所设计的数据库选择合适的存储结构和存取路径。 +5. **数据库实施** : 包括编程、测试和试运行 +6. **数据库的运行和维护** : 系统的运行与数据库的日常维护。 + +## 参考 + +- +- +- \ No newline at end of file From b24ab648911b9b0c8b64430107265ce2ef256100 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 9 Aug 2021 00:27:06 +0800 Subject: [PATCH 147/257] =?UTF-8?q?Update=20Spring=E5=B8=B8=E8=A7=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spring/Spring常见问题总结.md | 208 +++++++++--------- 1 file changed, 103 insertions(+), 105 deletions(-) diff --git a/docs/system-design/framework/spring/Spring常见问题总结.md b/docs/system-design/framework/spring/Spring常见问题总结.md index 30b35e2c..6c146272 100644 --- a/docs/system-design/framework/spring/Spring常见问题总结.md +++ b/docs/system-design/framework/spring/Spring常见问题总结.md @@ -1,60 +1,62 @@ 这篇文章主要是想通过一些问题,加深大家对于 Spring 的理解,所以不会涉及太多的代码!这篇文章整理了挺长时间,下面的很多问题我自己在使用 Spring 的过程中也并没有注意,自己也是临时查阅了很多资料和书籍补上的。网上也有一些很多关于 Spring 常见问题/面试题整理的文章,我感觉大部分都是互相 copy,而且很多问题也不是很好,有些回答也存在问题。所以,自己花了一周的业余时间整理了一下,希望对大家有帮助。 +# 剖析面试最常见问题之 Spring + ## 1. 什么是 Spring 框架? Spring 是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性。Spring 官网:。 -我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是:核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。比如:Core Container 中的 Core 组件是Spring 所有组件的核心,Beans 组件和 Context 组件是实现IOC和依赖注入的基础,AOP组件用来实现面向切面编程。 +我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是:核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。比如:Core Container 中的 Core 组件是 Spring 所有组件的核心,Beans 组件和 Context 组件是实现 IOC 和依赖注入的基础,AOP 组件用来实现面向切面编程。 Spring 官网列出的 Spring 的 6 个特征: - **核心技术** :依赖注入(DI),AOP,事件(events),资源,i18n,验证,数据绑定,类型转换,SpEL。 -- **测试** :模拟对象,TestContext框架,Spring MVC 测试,WebTestClient。 -- **数据访问** :事务,DAO支持,JDBC,ORM,编组XML。 -- **Web支持** : Spring MVC和Spring WebFlux Web框架。 +- **测试** :模拟对象,TestContext 框架,Spring MVC 测试,WebTestClient。 +- **数据访问** :事务,DAO 支持,JDBC,ORM,编组 XML。 +- **Web 支持** : Spring MVC 和 Spring WebFlux Web 框架。 - **集成** :远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。 - **语言** :Kotlin,Groovy,动态语言。 -## 2. 列举一些重要的Spring模块? +## 2. 列举一些重要的 Spring 模块? -下图对应的是 Spring4.x 版本。目前最新的5.x版本中 Web 模块的 Portlet 组件已经被废弃掉,同时增加了用于异步响应式处理的 WebFlux 组件。 +下图对应的是 Spring4.x 版本。目前最新的 5.x 版本中 Web 模块的 Portlet 组件已经被废弃掉,同时增加了用于异步响应式处理的 WebFlux 组件。 -![Spring主要模块](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/Spring主要模块.png) +![Spring主要模块](https://images.xiaozhuanlan.com/photo/2019/e0c60b4606711fc4a0b6faf03230247a.png) - **Spring Core:** 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。 -- **Spring Aspects** : 该模块为与AspectJ的集成提供支持。 +- **Spring Aspects** : 该模块为与 AspectJ 的集成提供支持。 - **Spring AOP** :提供了面向切面的编程实现。 -- **Spring JDBC** : Java数据库连接。 -- **Spring JMS** :Java消息服务。 -- **Spring ORM** : 用于支持Hibernate等ORM工具。 -- **Spring Web** : 为创建Web应用程序提供支持。 +- **Spring JDBC** : Java 数据库连接。 +- **Spring JMS** :Java 消息服务。 +- **Spring ORM** : 用于支持 Hibernate 等 ORM 工具。 +- **Spring Web** : 为创建 Web 应用程序提供支持。 - **Spring Test** : 提供了对 JUnit 和 TestNG 测试的支持。 ## 3. @RestController vs @Controller **`Controller` 返回一个页面** -单独使用 `@Controller` 不加 `@ResponseBody`的话一般使用在要返回一个视图的情况,这种情况属于比较传统的Spring MVC 的应用,对应于前后端不分离的情况。 +单独使用 `@Controller` 不加 `@ResponseBody`的话一般使用在要返回一个视图的情况,这种情况属于比较传统的 Spring MVC 的应用,对应于前后端不分离的情况。 -![SpringMVC 传统工作流程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/SpringMVC传统工作流程.png) +![SpringMVC 传统工作流程](https://images.xiaozhuanlan.com/photo/2019/b0f0310873a7dec2b7f433ff8094b919.png) -**`@RestController` 返回JSON 或 XML 形式数据** +**`@RestController` 返回 JSON 或 XML 形式数据** -但`@RestController`只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。 +但`@RestController`只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web 服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。 -![SpringMVC+RestController](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/SpringMVCRestController.png) +![SpringMVC+RestController](https://images.xiaozhuanlan.com/photo/2019/1f40a6f48f8338ea25963a6dd368fded.png) -**`@Controller +@ResponseBody` 返回JSON 或 XML 形式数据** +**`@Controller +@ResponseBody` 返回 JSON 或 XML 形式数据** -如果你需要在Spring4之前开发 RESTful Web服务的话,你需要使用`@Controller` 并结合`@ResponseBody`注解,也就是说`@Controller` +`@ResponseBody`= `@RestController`(Spring 4 之后新加的注解)。 +如果你需要在 Spring4 之前开发 RESTful Web 服务的话,你需要使用`@Controller` 并结合`@ResponseBody`注解,也就是说`@Controller` +`@ResponseBody`= `@RestController`(Spring 4 之后新加的注解)。 -> `@ResponseBody` 注解的作用是将 `Controller` 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。 +> `@ResponseBody` 注解的作用是将 `Controller` 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。 -![Spring3.xMVC RESTfulWeb服务工作流程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/Spring3.xMVCRESTfulWeb服务工作流程.png) +![Spring3.xMVC RESTfulWeb服务工作流程](https://images.xiaozhuanlan.com/photo/2019/88612da6b4798687e0312485f14a9737.png) Reference: -- https://dzone.com/articles/spring-framework-restcontroller-vs-controller (图片来源) +- https://dzone.com/articles/spring-framework-restcontroller-vs-controller(图片来源) - https://javarevisited.blogspot.com/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html?m=1 ## 4. Spring IOC & AOP @@ -63,19 +65,19 @@ Reference: #### IoC -IoC(Inverse of Control:控制反转)是一种**设计思想**,就是 **将原本在程序中手动创建对象的控制权,交由Spring框架来管理。** IoC 在其他语言中也有应用,并非 Spring 特有。 **IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。** +IoC(Inverse of Control:控制反转)是一种**设计思想**,就是 **将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。** IoC 在其他语言中也有应用,并非 Spirng 特有。 **IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。** -将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 **IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。** 在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。 +将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 **IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。** 在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。 Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。 推荐阅读:https://www.zhihu.com/question/23277575/answer/169698662 -**Spring IoC的初始化过程:** +**Spring IoC 的初始化过程:** -![Spring IoC的初始化过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/SpringIOC初始化过程.png) +![Spring IoC的初始化过程](https://images.xiaozhuanlan.com/photo/2019/57da0deca924d0e73dbb56501d2ec4be.png) -IoC源码阅读 +IoC 源码阅读 - https://javadoop.com/post/spring-ioc @@ -83,22 +85,21 @@ IoC源码阅读 AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,**却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来**,便于**减少系统的重复代码**,**降低模块间的耦合度**,并**有利于未来的可拓展性和可维护性**。 -**Spring AOP就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么Spring AOP会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用**Cglib**生成一个被代理对象的子类来作为代理,如下图所示: +**Spring AOP 就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用**Cglib** ,这时候 Spring AOP 会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: -![SpringAOPProcess](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/SpringAOPProcess.jpg) +![SpringAOPProcess](https://images.xiaozhuanlan.com/photo/2019/926dfc549b06d280a37397f9fd49bf9d.jpg) -当然你也可以使用 AspectJ,Spring AOP 已经集成了AspectJ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 +当然你也可以使用 AspectJ ,Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 使用 AOP 之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样大大简化了代码量。我们需要增加新功能时也方便,这样也提高了系统扩展性。日志功能、事务管理等等场景都用到了 AOP 。 ### 4.2 Spring AOP 和 AspectJ AOP 有什么区别? -1. **Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** -2. **Spring AOP** 基于**代理(Proxying)**,而 **AspectJ** 基于**字节码操作(Bytecode Manipulation)**。 +**Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。 -3. **Spring AOP** 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单, +Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单, -如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。 +如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。 ## 5. Spring bean @@ -106,27 +107,25 @@ AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无 - singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。 - prototype : 每次请求都会创建一个新的 bean 实例。 -- request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。 -- session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。 -- global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话 +- request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。 +- session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。 +- global-session: 全局 session 作用域,仅仅在基于 portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话 ### 5.2 Spring 中的单例 bean 的线程安全问题了解吗? -的确是存在安全问题的。因为,当多个线程操作同一个对象的时候,对这个对象的成员变量的写操作会存在线程安全问题。 +大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。 -但是,一般情况下,我们常用的 `Controller`、`Service`、`Dao` 这些 Bean 是无状态的。无状态的 Bean 不能保存数据,因此是线程安全的。 +常见的有两种解决办法: -常见的有 2 种解决办法: - -1. 在类中定义一个 `ThreadLocal` 成员变量,将需要的可变成员变量保存在 `ThreadLocal` 中(推荐的一种方式)。 -2. 改变 Bean 的作用域为 “prototype”:每次请求都会创建一个新的 bean 实例,自然不会存在线程安全问题。 +1. 在 Bean 对象中尽量避免定义可变的成员变量(不太现实)。 +2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。 ### 5.3 @Component 和 @Bean 的区别是什么? 1. 作用对象不同: `@Component` 注解作用于类,而`@Bean`注解作用于方法。 -2. `@Component`通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用 `@ComponentScan` 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。`@Bean` 注解通常是我们在标有该注解的方法中定义产生这个 bean,`@Bean`告诉了Spring这是某个类的示例,当我需要用它的时候还给我。 -3. `@Bean` 注解比 `Component` 注解的自定义性更强,而且很多地方我们只能通过 `@Bean` 注解来注册bean。比如当我们引用第三方库中的类需要装配到 `Spring`容器时,则只能通过 `@Bean`来实现。 +2. `@Component`通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 `@ComponentScan` 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。`@Bean` 注解通常是我们在标有该注解的方法中定义产生这个 bean,`@Bean`告诉了 Spring 这是某个类的示例,当我需要用它的时候还给我。 +3. `@Bean` 注解比 `Component` 注解的自定义性更强,而且很多地方我们只能通过 `@Bean` 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 `Spring`容器时,则只能通过 `@Bean`来实现。 `@Bean`注解使用示例: @@ -141,7 +140,7 @@ public class AppConfig { } ``` - 上面的代码相当于下面的 xml 配置 +上面的代码相当于下面的 xml 配置 ```xml @@ -165,39 +164,40 @@ public OneService getService(status) { } ``` -### 5.4 将一个类声明为Spring的 bean 的注解有哪些? +### 5.4 将一个类声明为 Spring 的 bean 的注解有哪些? 我们一般使用 `@Autowired` 注解自动装配 bean,要想把类标识成可用于 `@Autowired` 注解自动装配的 bean 的类,采用以下注解可实现: -- `@Component` :通用的注解,可标注任意类为 `Spring` 组件。如果一个Bean不知道属于哪个层,可以使用`@Component` 注解标注。 +- `@Component` :通用的注解,可标注任意类为 `Spring` 组件。如果一个 Bean 不知道属于哪个层,可以使用`@Component` 注解标注。 - `@Repository` : 对应持久层即 Dao 层,主要用于数据库相关操作。 -- `@Service` : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。 -- `@Controller` : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。 +- `@Service` : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。 +- `@Controller` : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。 ### 5.5 Spring 中的 bean 生命周期? -这部分网上有很多文章都讲到了,下面的内容整理自: ~~https://yemengying.com/2016/07/14/spring-bean-life-cycle/~~ (原作者可能不再维护这个博客,连接无法访问,可通过其 Github 仓库访问 ) ,除了这篇文章,再推荐一篇很不错的文章 : 。 +这部分网上有很多文章都讲到了,下面的内容整理自: ,除了这篇文章,再推荐一篇很不错的文章 : 。 - Bean 容器找到配置文件中 Spring Bean 的定义。 -- Bean 容器利用 Java Reflection API 创建一个Bean的实例。 +- Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。 - 如果涉及到一些属性值 利用 `set()`方法设置一些属性值。 -- 如果 Bean 实现了 `BeanNameAware` 接口,调用 `setBeanName()`方法,传入Bean的名字。 +- 如果 Bean 实现了 `BeanNameAware` 接口,调用 `setBeanName()`方法,传入 Bean 的名字。 - 如果 Bean 实现了 `BeanClassLoaderAware` 接口,调用 `setBeanClassLoader()`方法,传入 `ClassLoader`对象的实例。 +- 如果 Bean 实现了 `BeanFactoryAware` 接口,调用 `setBeanClassLoader()`方法,传入 `ClassLoade` r 对象的实例。 - 与上面的类似,如果实现了其他 `*.Aware`接口,就调用相应的方法。 - 如果有和加载这个 Bean 的 Spring 容器相关的 `BeanPostProcessor` 对象,执行`postProcessBeforeInitialization()` 方法 -- 如果Bean实现了`InitializingBean`接口,执行`afterPropertiesSet()`方法。 -- 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。 -- 如果有和加载这个 Bean的 Spring 容器相关的 `BeanPostProcessor` 对象,执行`postProcessAfterInitialization()` 方法 +- 如果 Bean 实现了`InitializingBean`接口,执行`afterPropertiesSet()`方法。 +- 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。 +- 如果有和加载这个 Bean 的 Spring 容器相关的 `BeanPostProcessor` 对象,执行`postProcessAfterInitialization()` 方法 - 当要销毁 Bean 的时候,如果 Bean 实现了 `DisposableBean` 接口,执行 `destroy()` 方法。 - 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。 图示: -![Spring Bean 生命周期](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/48376272.jpg) +![Spring Bean 生命周期](https://images.xiaozhuanlan.com/photo/2019/24bc2bad3ce28144d60d9e0a2edf6c7f.jpg) 与之比较类似的中文版本: -![Spring Bean 生命周期](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-17/5496407.jpg) +![Spring Bean 生命周期](https://images.xiaozhuanlan.com/photo/2019/b5d264565657a5395c2781081a7483e1.jpg) ## 6. Spring MVC @@ -205,21 +205,21 @@ public OneService getService(status) { 谈到这个问题,我们不得不提提之前 Model1 和 Model2 这两个没有 Spring MVC 的时代。 -- **Model1 时代** : 很多学 Java 后端比较晚的朋友可能并没有接触过 Model1 模式下的 JavaWeb 应用开发。在 Model1 模式下,整个 Web 应用几乎全部用 JSP 页面组成,只用少量的 JavaBean 来处理数据库连接、访问等操作。这个模式下 JSP 既是控制层又是表现层。显而易见,这种模式存在很多问题。比如①将控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;②前端和后端相互依赖,难以进行测试并且开发效率极低; -- **Model2 时代** :学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View,)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。Model:系统涉及的数据,也就是 dao 和 bean。View:展示模型中的数据,只是用来展示。Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。 +- **Model1 时代** : 很多学 Java 后端比较晚的朋友可能并没有接触过 Model1 模式下的 JavaWeb 应用开发。在 Model1 模式下,整个 Web 应用几乎全部用 JSP 页面组成,只用少量的 JavaBean 来处理数据库连接、访问等操作。这个模式下 JSP 即是控制层又是表现层。显而易见,这种模式存在很多问题。比如 ① 将控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;② 前端和后端相互依赖,难以进行测试并且开发效率极低; +- **Model2 时代** :学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View,)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。Model:系统涉及的数据,也就是 dao 和 bean。View:展示模型中的数据,只是用来展示。Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。 -Model2 模式下还存在很多问题,Model2的抽象和封装程度还远远不够,使用Model2进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。于是很多JavaWeb开发相关的 MVC 框架应运而生比如Struts2,但是 Struts2 比较笨重。随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。 +Model2 模式下还存在很多问题,Model2 的抽象和封装程度还远远不够,使用 Model2 进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。于是很多 JavaWeb 开发相关的 MVC 框架应运而生比如 Struts2,但是 Struts2 比较笨重。随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。 -MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的Web层的开发,并且它天生与 Spring 框架集成。Spring MVC 下我们一般把后端项目分为 Service层(处理业务)、Dao层(数据库操作)、Entity层(实体类)、Controller层(控制层,返回数据给前台页面)。 +MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的 Web 层的开发,并且它天生与 Spring 框架集成。Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。 **Spring MVC 的简单原理图如下:** -![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/60679444.jpg) +![](https://images.xiaozhuanlan.com/photo/2019/2c3c2d5862db4b6dab3809183f64ab07.jpg) ### 6.2 SpringMVC 工作原理了解吗? **原理如下图所示:** -![SpringMVC运行原理](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-11/49790288.jpg) +![SpringMVC运行原理](https://images.xiaozhuanlan.com/photo/2019/093258b80bf44a737cdc3304ceea85d7.jpg) 上图的一个笔误的小问题:Spring MVC 的入口函数也就是前端控制器 `DispatcherServlet` 的作用是接收请求,响应结果。 @@ -228,7 +228,7 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M 1. 客户端(浏览器)发送请求,直接请求到 `DispatcherServlet`。 2. `DispatcherServlet` 根据请求信息调用 `HandlerMapping`,解析请求对应的 `Handler`。 3. 解析到对应的 `Handler`(也就是我们平常说的 `Controller` 控制器)后,开始由 `HandlerAdapter` 适配器处理。 -4. `HandlerAdapter` 会根据 `Handler `来调用真正的处理器来处理请求,并处理相应的业务逻辑。 +4. `HandlerAdapter` 会根据 `Handler`来调用真正的处理器开处理请求,并处理相应的业务逻辑。 5. 处理器处理完业务后,会返回一个 `ModelAndView` 对象,`Model` 是返回的数据对象,`View` 是个逻辑上的 `View`。 6. `ViewResolver` 会根据逻辑 `View` 查找实际的 `View`。 7. `DispaterServlet` 把返回的 `Model` 传给 `View`(视图渲染)。 @@ -236,9 +236,9 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M ## 7. Spring 框架中用到了哪些设计模式? -关于下面一些设计模式的详细介绍,可以看笔主前段时间的原创文章[《面试官:“谈谈Spring中都用到了那些设计模式?”。》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485303&idx=1&sn=9e4626a1e3f001f9b0d84a6fa0cff04a&chksm=cea248bcf9d5c1aaf48b67cc52bac74eb29d6037848d6cf213b0e5466f2d1fda970db700ba41&token=255050878&lang=zh_CN#rd) 。 +关于下面一些设计模式的详细介绍,可以看笔主前段时间的原创文章[《面试官:“谈谈 Spring 中都用到了那些设计模式?”。》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485303&idx=1&sn=9e4626a1e3f001f9b0d84a6fa0cff04a&chksm=cea248bcf9d5c1aaf48b67cc52bac74eb29d6037848d6cf213b0e5466f2d1fda970db700ba41&token=255050878&lang=zh_CN#rd) 。 -- **工厂设计模式** : Spring使用工厂模式通过 `BeanFactory`、`ApplicationContext` 创建 bean 对象。 +- **工厂设计模式** : Spring 使用工厂模式通过 `BeanFactory`、`ApplicationContext` 创建 bean 对象。 - **代理设计模式** : Spring AOP 功能的实现。 - **单例设计模式** : Spring 中的 Bean 默认都是单例的。 - **模板方法模式** : Spring 中 `jdbcTemplate`、`hibernateTemplate` 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 @@ -256,22 +256,18 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M **声明式事务又分为两种:** -1. 基于XML的声明式事务 +1. 基于 XML 的声明式事务 2. 基于注解的声明式事务 -**思维导图**: - -![image-20210807101442105](https://gitee.com/yamonc/blogImage/raw/master//img/blogImage/image-20210807101442105.png) - ### 8.2 Spring 事务中的隔离级别有哪几种? **TransactionDefinition 接口中定义了五个表示隔离级别的常量:** -- **TransactionDefinition.ISOLATION_DEFAULT:** 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别. +- **TransactionDefinition.ISOLATION_DEFAULT:** 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ 隔离级别 Oracle 默认采用的 READ_COMMITTED 隔离级别. - **TransactionDefinition.ISOLATION_READ_UNCOMMITTED:** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** -- **TransactionDefinition.ISOLATION_READ_COMMITTED:** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** -- **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** -- **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 +- **TransactionDefinition.ISOLATION_READ_COMMITTED:** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** +- **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** +- **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 ### 8.3 Spring 事务中哪几种事务传播行为? @@ -289,47 +285,39 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M **其他情况:** -- **TransactionDefinition.PROPAGATION_NESTED:** 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。 - -**思维导图:** - -![image-20210807102320870](https://gitee.com/yamonc/blogImage/raw/master//img/blogImage/image-20210807102320870.png) +- **TransactionDefinition.PROPAGATION_NESTED:** 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 TransactionDefinition.PROPAGATION_REQUIRED。 ### 8.4 @Transactional(rollbackFor = Exception.class)注解了解吗? -我们知道:Exception分为运行时异常RuntimeException和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 +我们知道:Exception 分为运行时异常 RuntimeException 和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 当`@Transactional`注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。 -在`@Transactional`注解中如果不配置`rollbackFor`属性,那么事务只会在遇到`RuntimeException`的时候才会回滚,加上`rollbackFor=Exception.class`,可以让事务在遇到非运行时异常时也回滚。 - -关于 `@Transactional ` 注解推荐阅读的文章: - -- [透彻的掌握 Spring 中@transactional 的使用](https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html) +在`@Transactional`注解中如果不配置`rollbackFor`属性,那么事物只会在遇到`RuntimeException`的时候才会回滚,加上`rollbackFor=Exception.class`,可以让事物在遇到非运行时异常时也回滚。 ## 9. JPA -### 9.1 如何使用JPA在数据库中非持久化一个字段? +### 9.1 如何使用 JPA 在数据库中非持久化一个字段? 假如我们有有下面一个类: ```java Entity(name="USER") public class User { - + @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ID") private Long id; - + @Column(name="USER_NAME") private String userName; - + @Column(name="PASSWORD") private String password; - + private String secrect; - + } ``` @@ -345,25 +333,35 @@ String transient4; // not persistent because of @Transient 一般使用后面两种方式比较多,我个人使用注解的方式比较多。 +## 10. Spring Security + +### 10.1 认证 (Authentication) 和授权 (Authorization) + +这是一个绝大多数人都会混淆的问题。首先先从读音上来认识这两个名词,很多人都会把它俩的读音搞混,所以我建议你先先去查一查这两个单词到底该怎么读,他们的具体含义是什么。 + +**Authentication(认证)** 是验证您的身份的凭据(例如用户名/用户 ID 和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。 + +**Authorization(授权)** 发生在 **Authentication(认证)**之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如 admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。 + +这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。 + +### 10.2 Cookie 的作用是什么?和 Session 有什么区别? + +Cookie 和 Session 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 + +**Cookie 一般用来保存用户信息** 比如 ① 我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;② 一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③ 登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 + +Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 + +Cookie 存储在客户端中,而 Session 存储在服务器上,相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 ## 参考 - 《Spring 技术内幕》 -- +- - - - https://www.cnblogs.com/clwydjgs/p/9317849.html - - - -- - -## 公众号 - -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 - -**《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! - -**Java工程师必备学习资源:** 一些Java工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 - -![公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/javaguide1.jpg) From 7cc919c0e8953ad5b0af6a35404a5cf0f377fac5 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 9 Aug 2021 00:27:09 +0800 Subject: [PATCH 148/257] =?UTF-8?q?Update=20MySQL=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/mysql/MySQL总结.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/database/mysql/MySQL总结.md b/docs/database/mysql/MySQL总结.md index 242c487f..37793525 100644 --- a/docs/database/mysql/MySQL总结.md +++ b/docs/database/mysql/MySQL总结.md @@ -22,8 +22,6 @@ MySQL、PostgreSQL、Oracle、SQL Server、SQLite(微信本地的聊天记录 由于 MySQL 是开源免费并且比较成熟的数据库,因此,MySQL 被大量使用在各种系统中。任何人都可以在 GPL(General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL 的默认端口号是**3306**。 - - ## 存储引擎 ### 存储引擎相关的命令 From 9b9123c5a96327175ff181b57f2d6c9a0d0765f8 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 9 Aug 2021 17:33:20 +0800 Subject: [PATCH 149/257] =?UTF-8?q?Spring=20=E5=B8=B8=E8=A7=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session-cookie.drawio | 2 +- .../spring/Spring常见问题总结.md | 356 +++++++++++------- 2 files changed, 219 insertions(+), 139 deletions(-) diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.drawio b/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.drawio index 6a1b06b5..c5d46f57 100644 --- a/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.drawio +++ b/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.drawio @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/docs/system-design/framework/spring/Spring常见问题总结.md b/docs/system-design/framework/spring/Spring常见问题总结.md index 6c146272..f6d40e1b 100644 --- a/docs/system-design/framework/spring/Spring常见问题总结.md +++ b/docs/system-design/framework/spring/Spring常见问题总结.md @@ -1,99 +1,108 @@ -这篇文章主要是想通过一些问题,加深大家对于 Spring 的理解,所以不会涉及太多的代码!这篇文章整理了挺长时间,下面的很多问题我自己在使用 Spring 的过程中也并没有注意,自己也是临时查阅了很多资料和书籍补上的。网上也有一些很多关于 Spring 常见问题/面试题整理的文章,我感觉大部分都是互相 copy,而且很多问题也不是很好,有些回答也存在问题。所以,自己花了一周的业余时间整理了一下,希望对大家有帮助。 +这篇文章主要是想通过一些问题,加深大家对于 Spring 的理解,所以不会涉及太多的代码! -# 剖析面试最常见问题之 Spring +下面的很多问题我自己在使用 Spring 的过程中也并没有注意,自己也是临时查阅了很多资料和书籍补上的。网上也有一些很多关于 Spring 常见问题/面试题整理的文章,我感觉大部分都是互相 copy,而且很多问题也不是很好,有些回答也存在问题。所以,自己花了一周的业余时间整理了一下,希望对大家有帮助。 -## 1. 什么是 Spring 框架? +## 什么是 Spring 框架? -Spring 是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性。Spring 官网:。 +Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。 -我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是:核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。比如:Core Container 中的 Core 组件是 Spring 所有组件的核心,Beans 组件和 Context 组件是实现 IOC 和依赖注入的基础,AOP 组件用来实现面向切面编程。 +Spring 翻译过来就是春天的意思,可见其目标和使命就是为 Java 程序员带来春天啊!感动! -Spring 官网列出的 Spring 的 6 个特征: +> 题外话 : 语言的流行通常需要一个杀手级的应用,Spring 就是 Java 生态的一个杀手级的应用框架。 -- **核心技术** :依赖注入(DI),AOP,事件(events),资源,i18n,验证,数据绑定,类型转换,SpEL。 -- **测试** :模拟对象,TestContext 框架,Spring MVC 测试,WebTestClient。 -- **数据访问** :事务,DAO 支持,JDBC,ORM,编组 XML。 -- **Web 支持** : Spring MVC 和 Spring WebFlux Web 框架。 -- **集成** :远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。 -- **语言** :Kotlin,Groovy,动态语言。 +我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。 -## 2. 列举一些重要的 Spring 模块? +比如说 Spring 自带 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、可以很方便地集成第三方组件(电子邮件,任务,调度,缓存等等)、对单元测试支持比较好、支持 RESTful Java 应用程序的开发。 + +![](https://img-blog.csdnimg.cn/38ef122122de4375abcd27c3de8f60b4.png) + +Spring 最核心的思想就是不重新造轮子,开箱即用! + +Spring 提供的核心功能主要是 IoC 和 AOP。学习 Spring ,一定要把 IoC 和 AOP 的核心思想搞懂! + +- Spring 官网: +- Github 地址: https://github.com/spring-projects/spring-framework + +## 列举一些重要的 Spring 模块? 下图对应的是 Spring4.x 版本。目前最新的 5.x 版本中 Web 模块的 Portlet 组件已经被废弃掉,同时增加了用于异步响应式处理的 WebFlux 组件。 ![Spring主要模块](https://images.xiaozhuanlan.com/photo/2019/e0c60b4606711fc4a0b6faf03230247a.png) -- **Spring Core:** 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。 -- **Spring Aspects** : 该模块为与 AspectJ 的集成提供支持。 -- **Spring AOP** :提供了面向切面的编程实现。 -- **Spring JDBC** : Java 数据库连接。 -- **Spring JMS** :Java 消息服务。 -- **Spring ORM** : 用于支持 Hibernate 等 ORM 工具。 -- **Spring Web** : 为创建 Web 应用程序提供支持。 -- **Spring Test** : 提供了对 JUnit 和 TestNG 测试的支持。 +**Spring Core** -## 3. @RestController vs @Controller +核心模块, Spring 其他所有的功能基本都需要依赖于该类库,主要提供 IoC 依赖注入功能的支持。 -**`Controller` 返回一个页面** +**Spring Aspects** -单独使用 `@Controller` 不加 `@ResponseBody`的话一般使用在要返回一个视图的情况,这种情况属于比较传统的 Spring MVC 的应用,对应于前后端不分离的情况。 +该模块为与 AspectJ 的集成提供支持。 -![SpringMVC 传统工作流程](https://images.xiaozhuanlan.com/photo/2019/b0f0310873a7dec2b7f433ff8094b919.png) +**Spring AOP** -**`@RestController` 返回 JSON 或 XML 形式数据** +提供了面向切面的编程实现。 -但`@RestController`只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web 服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。 +**Spring Data Access/Integration :** -![SpringMVC+RestController](https://images.xiaozhuanlan.com/photo/2019/1f40a6f48f8338ea25963a6dd368fded.png) +Spring Data Access/Integration 由 5 个模块组成: -**`@Controller +@ResponseBody` 返回 JSON 或 XML 形式数据** +- spring-jdbc : 提供了对数据库访问的抽象 JDBC。不同的数据库都有自己独立的 API 用于操作数据库,而 Java 程序只需要和 JDBC API 交互,这样就屏蔽了数据库的影响。 +- spring-tx : 提供对事务的支持。 +- spring-orm : 提供对 Hibernate 等 ORM 框架的支持。 +- spring-oxm : 提供对 Castor 等 OXM 框架的支持。 +- spring-jms : Java 消息服务。 -如果你需要在 Spring4 之前开发 RESTful Web 服务的话,你需要使用`@Controller` 并结合`@ResponseBody`注解,也就是说`@Controller` +`@ResponseBody`= `@RestController`(Spring 4 之后新加的注解)。 +**Spring Web** -> `@ResponseBody` 注解的作用是将 `Controller` 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。 +Spring Web 由 4 个模块组成: -![Spring3.xMVC RESTfulWeb服务工作流程](https://images.xiaozhuanlan.com/photo/2019/88612da6b4798687e0312485f14a9737.png) +- spring-web :对 Web 功能的实现提供一些最基础的支持。 +- spring-webmvc : 提供对 Spring MVC 的实现。 +- spring-websocket : 提供了对 WebSocket 的支持,WebSocket 可以让客户端和服务端进行双向通信。 +- spring-webflux :提供对 WebFlux 的支持。WebFlux 是 Spring Framework 5.0 中引入的新的响应式框架。与 Spring MVC 不同,它不需要 Servlet API,是完全异步. -Reference: +**Spring Test** -- https://dzone.com/articles/spring-framework-restcontroller-vs-controller(图片来源) -- https://javarevisited.blogspot.com/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html?m=1 +Spring 团队提倡测试驱动开发(TDD)。有了控制反转 (IoC)的帮助,单元测试和集成测试变得更简单。 -## 4. Spring IOC & AOP +Spring 的测试模块对 JUnit(单元测试框架)、TestNG(类似 JUnit)、Mockito(主要用来 Mock 对象)、PowerMock(解决 Mockito 的问题比如无法模拟 final, static, private 方法)等等常用的测试框架支持的都比较好。 -### 4.1 谈谈自己对于 Spring IoC 和 AOP 的理解 +## Spring IOC & AOP -#### IoC +### 谈谈自己对于 Spring IoC 的了解 -IoC(Inverse of Control:控制反转)是一种**设计思想**,就是 **将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。** IoC 在其他语言中也有应用,并非 Spirng 特有。 **IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。** +**IoC(Inverse of Control:控制反转)** 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spirng 特有,在其他语言中也有应用。 -将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 **IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。** 在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。 +**为什么叫控制反转?** + +- **控制** :指的是对象创建(实例化、管理)的权力 +- **反转** :控制权交给外部环境(Spring 框架、IoC 容器) + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/frc-365faceb5697f04f31399937c059c162.png) + +将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。 + +在实际项目中一个 Service 类可能依赖了很多其他的类,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。 + +在 Spring 中, IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。 Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。 -推荐阅读:https://www.zhihu.com/question/23277575/answer/169698662 +相关阅读: -**Spring IoC 的初始化过程:** +- [IoC 源码阅读](https://javadoop.com/post/spring-ioc) +- [面试被问了几百遍的 IoC 和 AOP ,还在傻傻搞不清楚?](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486938&idx=1&sn=c99ef0233f39a5ffc1b98c81e02dfcd4&chksm=cea24211f9d5cb07fa901183ba4d96187820713a72387788408040822ffb2ed575d28e953ce7&token=1736772241&lang=zh_CN#rd) -![Spring IoC的初始化过程](https://images.xiaozhuanlan.com/photo/2019/57da0deca924d0e73dbb56501d2ec4be.png) +### 谈谈自己对于 AOP 的了解 -IoC 源码阅读 +AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码**,**降低模块间的耦合度,并有利于未来的可拓展性和可维护性。 -- https://javadoop.com/post/spring-ioc - -#### AOP - -AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,**却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来**,便于**减少系统的重复代码**,**降低模块间的耦合度**,并**有利于未来的可拓展性和可维护性**。 - -**Spring AOP 就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用**Cglib** ,这时候 Spring AOP 会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: +Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 **JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 **Cglib** ,这时候 Spring AOP 会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: ![SpringAOPProcess](https://images.xiaozhuanlan.com/photo/2019/926dfc549b06d280a37397f9fd49bf9d.jpg) -当然你也可以使用 AspectJ ,Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 +当然你也可以使用 **AspectJ** !Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 -使用 AOP 之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样大大简化了代码量。我们需要增加新功能时也方便,这样也提高了系统扩展性。日志功能、事务管理等等场景都用到了 AOP 。 - -### 4.2 Spring AOP 和 AspectJ AOP 有什么区别? +### Spring AOP 和 AspectJ AOP 有什么区别? **Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。 @@ -101,29 +110,69 @@ Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系 如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。 -## 5. Spring bean +## Spring bean -### 5.1 Spring 中的 bean 的作用域有哪些? +### 什么是 bean? -- singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。 -- prototype : 每次请求都会创建一个新的 bean 实例。 -- request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。 -- session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。 -- global-session: 全局 session 作用域,仅仅在基于 portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话 +简单来说,bean 代指的就是那些被 IoC 容器所管理的对象。 -### 5.2 Spring 中的单例 bean 的线程安全问题了解吗? +我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据的定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。 -大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。 +```xml + + + + +``` + +下图简单地展示了 IoC 容器如何使用配置元数据来管理对象。 + +![](https://img-blog.csdnimg.cn/062b422bd7ac4d53afd28fb74b2bc94d.png) + +`org.springframework.beans`和 `org.springframework.context` 这两个包是 IoC 实现的基础,如果想要研究 IoC 相关的源码的话,可以去看看 + +### bean 的作用域有哪些? + +Spring 中 Bean 的作用域通常由下面几种: + +- **singleton** : 唯一 bean 实例,Spring 中的 bean 默认都是单例的,对单例设计模式的应用。 +- **prototype** : 每次请求都会创建一个新的 bean 实例。 +- **request** : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。 +- **session** : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。 +- **global-session** : 全局 session 作用域,仅仅在基于 portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。 + +**如何配置 bean 的作用域呢?** + +xml 方式: + +```xml + +``` + +注解方式: + +```java +@Bean +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public Person personPrototype() { + return new Person(); +} +``` + +### 单例 bean 的线程安全问题了解吗? + +大部分时候我们并没有在项目中使用多线程,所以很少有人会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候是存在资源竞争的。 常见的有两种解决办法: -1. 在 Bean 对象中尽量避免定义可变的成员变量(不太现实)。 +1. 在 bean 中尽量避免定义可变的成员变量。 +2. 在类中定义一个 `ThreadLocal` 成员变量,将需要的可变成员变量保存在 `ThreadLocal` 中(推荐的一种方式)。 -2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。 +不过,大部分 bean 实际都是无状态(没有实例变量)的(比如 Dao、Service),这种情况下, bean 是线程安全的。 -### 5.3 @Component 和 @Bean 的区别是什么? +### @Component 和 @Bean 的区别是什么? -1. 作用对象不同: `@Component` 注解作用于类,而`@Bean`注解作用于方法。 +1. `@Component` 注解作用于类,而`@Bean`注解作用于方法。 2. `@Component`通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 `@ComponentScan` 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。`@Bean` 注解通常是我们在标有该注解的方法中定义产生这个 bean,`@Bean`告诉了 Spring 这是某个类的示例,当我需要用它的时候还给我。 3. `@Bean` 注解比 `Component` 注解的自定义性更强,而且很多地方我们只能通过 `@Bean` 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 `Spring`容器时,则只能通过 `@Bean`来实现。 @@ -164,7 +213,7 @@ public OneService getService(status) { } ``` -### 5.4 将一个类声明为 Spring 的 bean 的注解有哪些? +### 将一个类声明为 bean 的注解有哪些? 我们一般使用 `@Autowired` 注解自动装配 bean,要想把类标识成可用于 `@Autowired` 注解自动装配的 bean 的类,采用以下注解可实现: @@ -173,9 +222,9 @@ public OneService getService(status) { - `@Service` : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。 - `@Controller` : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。 -### 5.5 Spring 中的 bean 生命周期? +### bean 的生命周期? -这部分网上有很多文章都讲到了,下面的内容整理自: ,除了这篇文章,再推荐一篇很不错的文章 : 。 +> 下面的内容整理自: ,除了这篇文章,再推荐一篇很不错的文章 : 。 - Bean 容器找到配置文件中 Spring Bean 的定义。 - Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。 @@ -199,29 +248,43 @@ public OneService getService(status) { ![Spring Bean 生命周期](https://images.xiaozhuanlan.com/photo/2019/b5d264565657a5395c2781081a7483e1.jpg) -## 6. Spring MVC +## Spring MVC -### 6.1 说说自己对于 Spring MVC 了解? +### 说说自己对于 Spring MVC 了解? 谈到这个问题,我们不得不提提之前 Model1 和 Model2 这两个没有 Spring MVC 的时代。 -- **Model1 时代** : 很多学 Java 后端比较晚的朋友可能并没有接触过 Model1 模式下的 JavaWeb 应用开发。在 Model1 模式下,整个 Web 应用几乎全部用 JSP 页面组成,只用少量的 JavaBean 来处理数据库连接、访问等操作。这个模式下 JSP 即是控制层又是表现层。显而易见,这种模式存在很多问题。比如 ① 将控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;② 前端和后端相互依赖,难以进行测试并且开发效率极低; -- **Model2 时代** :学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View,)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。Model:系统涉及的数据,也就是 dao 和 bean。View:展示模型中的数据,只是用来展示。Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。 +**Model 1 时代** -Model2 模式下还存在很多问题,Model2 的抽象和封装程度还远远不够,使用 Model2 进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。于是很多 JavaWeb 开发相关的 MVC 框架应运而生比如 Struts2,但是 Struts2 比较笨重。随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。 +很多学 Java 后端比较晚的朋友可能并没有接触过 Model 1 时代下的 JavaWeb 应用开发。在 Model1 模式下,整个 Web 应用几乎全部用 JSP 页面组成,只用少量的 JavaBean 来处理数据库连接、访问等操作。 + +这个模式下 JSP 即是控制层(Controller)又是表现层(View)。显而易见,这种模式存在很多问题。比如控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;再比如前端和后端相互依赖,难以进行测试维护并且开发效率极低。 + +**Model 2 时代** + +学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。 + +- Model:系统涉及的数据,也就是 dao 和 bean。 +- View:展示模型中的数据,只是用来展示。 +- Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。 + +Model2 模式下还存在很多问题,Model2 的抽象和封装程度还远远不够,使用 Model2 进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。 + +于是,很多 JavaWeb 开发相关的 MVC 框架应运而生比如 Struts2,但是 Struts2 比较笨重。 + +**Spring MVC 时代** + +随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。 MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的 Web 层的开发,并且它天生与 Spring 框架集成。Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。 -**Spring MVC 的简单原理图如下:** +### SpringMVC 工作原理了解吗? -![](https://images.xiaozhuanlan.com/photo/2019/2c3c2d5862db4b6dab3809183f64ab07.jpg) +**Spring MVC 原理如下图所示:** -### 6.2 SpringMVC 工作原理了解吗? +> SpringMVC 工作原理的图解我没有自己画,直接图省事在网上找了一个非常清晰直观的,原出处不明。 -**原理如下图所示:** -![SpringMVC运行原理](https://images.xiaozhuanlan.com/photo/2019/093258b80bf44a737cdc3304ceea85d7.jpg) - -上图的一个笔误的小问题:Spring MVC 的入口函数也就是前端控制器 `DispatcherServlet` 的作用是接收请求,响应结果。 +![](https://img-blog.csdnimg.cn/img_convert/de6d2b213f112297298f3e223bf08f28.png) **流程说明(重要):** @@ -234,7 +297,7 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M 7. `DispaterServlet` 把返回的 `Model` 传给 `View`(视图渲染)。 8. 把 `View` 返回给请求者(浏览器) -## 7. Spring 框架中用到了哪些设计模式? +## Spring 框架中用到了哪些设计模式? 关于下面一些设计模式的详细介绍,可以看笔主前段时间的原创文章[《面试官:“谈谈 Spring 中都用到了那些设计模式?”。》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485303&idx=1&sn=9e4626a1e3f001f9b0d84a6fa0cff04a&chksm=cea248bcf9d5c1aaf48b67cc52bac74eb29d6037848d6cf213b0e5466f2d1fda970db700ba41&token=255050878&lang=zh_CN#rd) 。 @@ -244,60 +307,99 @@ MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring M - **模板方法模式** : Spring 中 `jdbcTemplate`、`hibernateTemplate` 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 - **包装器设计模式** : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 - **观察者模式:** Spring 事件驱动模型就是观察者模式很经典的一个应用。 -- **适配器模式** :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配`Controller`。 +- **适配器模式** : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配`Controller`。 - ...... -## 8. Spring 事务 +## Spring 事务 -### 8.1 Spring 管理事务的方式有几种? +Spring/SpringBoot 模块下专门有一篇是讲 Spring 事务的,总结的非常详细,通俗易懂。 -1. 编程式事务,在代码中硬编码。(不推荐使用) -2. 声明式事务,在配置文件中配置(推荐使用) +### Spring 管理事务的方式有几种? -**声明式事务又分为两种:** +- **编程式事务** : 在代码中硬编码(不推荐使用) : 通过 `TransactionTemplate`或者 `TransactionManager` 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。 +- **声明式事务** : 在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于`@Transactional` 的全注解方式使用最多) -1. 基于 XML 的声明式事务 -2. 基于注解的声明式事务 +### Spring 事务中哪几种事务传播行为? -### 8.2 Spring 事务中的隔离级别有哪几种? +**事务传播行为是为了解决业务层方法之间互相调用的事务问题**。 -**TransactionDefinition 接口中定义了五个表示隔离级别的常量:** +当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。 -- **TransactionDefinition.ISOLATION_DEFAULT:** 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ 隔离级别 Oracle 默认采用的 READ_COMMITTED 隔离级别. -- **TransactionDefinition.ISOLATION_READ_UNCOMMITTED:** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** -- **TransactionDefinition.ISOLATION_READ_COMMITTED:** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** -- **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** -- **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 +正确的事务传播行为可能的值如下: -### 8.3 Spring 事务中哪几种事务传播行为? +**1.`TransactionDefinition.PROPAGATION_REQUIRED`** -**支持当前事务的情况:** +使用的最多的一个事务传播行为,我们平时经常使用的`@Transactional`注解默认使用就是这个事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 -- **TransactionDefinition.PROPAGATION_REQUIRED:** 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 -- **TransactionDefinition.PROPAGATION_SUPPORTS:** 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 -- **TransactionDefinition.PROPAGATION_MANDATORY:** 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性) +**`2.TransactionDefinition.PROPAGATION_REQUIRES_NEW`** -**不支持当前事务的情况:** +创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,`Propagation.REQUIRES_NEW`修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。 -- **TransactionDefinition.PROPAGATION_REQUIRES_NEW:** 创建一个新的事务,如果当前存在事务,则把当前事务挂起。 -- **TransactionDefinition.PROPAGATION_NOT_SUPPORTED:** 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 -- **TransactionDefinition.PROPAGATION_NEVER:** 以非事务方式运行,如果当前存在事务,则抛出异常。 +**3.`TransactionDefinition.PROPAGATION_NESTED`** -**其他情况:** +如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于`TransactionDefinition.PROPAGATION_REQUIRED`。 -- **TransactionDefinition.PROPAGATION_NESTED:** 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 TransactionDefinition.PROPAGATION_REQUIRED。 +**4.`TransactionDefinition.PROPAGATION_MANDATORY`** -### 8.4 @Transactional(rollbackFor = Exception.class)注解了解吗? +如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性) -我们知道:Exception 分为运行时异常 RuntimeException 和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 +这个使用的很少。 -当`@Transactional`注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。 +若是错误的配置以下 3 种事务传播行为,事务将不会发生回滚: -在`@Transactional`注解中如果不配置`rollbackFor`属性,那么事物只会在遇到`RuntimeException`的时候才会回滚,加上`rollbackFor=Exception.class`,可以让事物在遇到非运行时异常时也回滚。 +- **`TransactionDefinition.PROPAGATION_SUPPORTS`**: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 +- **`TransactionDefinition.PROPAGATION_NOT_SUPPORTED`**: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 +- **`TransactionDefinition.PROPAGATION_NEVER`**: 以非事务方式运行,如果当前存在事务,则抛出异常。 -## 9. JPA +### Spring 事务中的隔离级别有哪几种? -### 9.1 如何使用 JPA 在数据库中非持久化一个字段? +和事务传播行为这块一样,为了方便使用,Spring 也相应地定义了一个枚举类:`Isolation` + +```java +public enum Isolation { + + DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), + + READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), + + READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), + + REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), + + SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE); + + private final int value; + + Isolation(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + +} +``` + +下面我依次对每一种事务隔离级别进行介绍: + +- **`TransactionDefinition.ISOLATION_DEFAULT`** :使用后端数据库默认的隔离级别,MySQL 默认采用的 `REPEATABLE_READ` 隔离级别 Oracle 默认采用的 `READ_COMMITTED` 隔离级别. +- **`TransactionDefinition.ISOLATION_READ_UNCOMMITTED`** :最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** +- **`TransactionDefinition.ISOLATION_READ_COMMITTED`** : 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** +- **`TransactionDefinition.ISOLATION_REPEATABLE_READ`** : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** +- **`TransactionDefinition.ISOLATION_SERIALIZABLE`** : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 + +### @Transactional(rollbackFor = Exception.class)注解了解吗? + +`Exception` 分为运行时异常 `RuntimeException` 和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 + +当 `@Transactional` 注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。 + +在 `@Transactional` 注解中如果不配置`rollbackFor`属性,那么事物只会在遇到`RuntimeException`的时候才会回滚,加上 `rollbackFor=Exception.class`,可以让事物在遇到非运行时异常时也回滚。 + +## JPA + +### 如何使用 JPA 在数据库中非持久化一个字段? 假如我们有有下面一个类: @@ -333,28 +435,6 @@ String transient4; // not persistent because of @Transient 一般使用后面两种方式比较多,我个人使用注解的方式比较多。 -## 10. Spring Security - -### 10.1 认证 (Authentication) 和授权 (Authorization) - -这是一个绝大多数人都会混淆的问题。首先先从读音上来认识这两个名词,很多人都会把它俩的读音搞混,所以我建议你先先去查一查这两个单词到底该怎么读,他们的具体含义是什么。 - -**Authentication(认证)** 是验证您的身份的凭据(例如用户名/用户 ID 和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。 - -**Authorization(授权)** 发生在 **Authentication(认证)**之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如 admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。 - -这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。 - -### 10.2 Cookie 的作用是什么?和 Session 有什么区别? - -Cookie 和 Session 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 - -**Cookie 一般用来保存用户信息** 比如 ① 我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;② 一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③ 登录一次网站后访问网站其他页面不需要重新登录。**Session 的主要作用就是通过服务端记录用户的状态。** 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。 - -Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 - -Cookie 存储在客户端中,而 Session 存储在服务器上,相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。 - ## 参考 - 《Spring 技术内幕》 From 452fc49d6bb34f566e359c3c5d24e844912ab17d Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 9 Aug 2021 19:43:23 +0800 Subject: [PATCH 150/257] =?UTF-8?q?Update=20Spring=E5=B8=B8=E8=A7=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/spring/Spring常见问题总结.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/system-design/framework/spring/Spring常见问题总结.md b/docs/system-design/framework/spring/Spring常见问题总结.md index f6d40e1b..529406be 100644 --- a/docs/system-design/framework/spring/Spring常见问题总结.md +++ b/docs/system-design/framework/spring/Spring常见问题总结.md @@ -252,7 +252,15 @@ public OneService getService(status) { ### 说说自己对于 Spring MVC 了解? -谈到这个问题,我们不得不提提之前 Model1 和 Model2 这两个没有 Spring MVC 的时代。 +MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210809181452421.png) + +网上有很多人说 MVC 不是设计模式,只是软件设计规范,我个人更倾向于 MVC 同样是众多设计模式中的一种。**[java-design-patterns](https://github.com/iluwatar/java-design-patterns)** 项目中就有关于 MVC 的相关介绍。 + +![](https://img-blog.csdnimg.cn/159b3d3e70dd45e6afa81bf06d09264e.png) + +想要真正理解 Spring MVC,我们先来看看 Model 1 和 Model 2 这两个没有 Spring MVC 的时代。 **Model 1 时代** @@ -260,6 +268,8 @@ public OneService getService(status) { 这个模式下 JSP 即是控制层(Controller)又是表现层(View)。显而易见,这种模式存在很多问题。比如控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;再比如前端和后端相互依赖,难以进行测试维护并且开发效率极低。 +![mvc-mode1](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/mvc-mode1.png) + **Model 2 时代** 学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。 @@ -268,6 +278,8 @@ public OneService getService(status) { - View:展示模型中的数据,只是用来展示。 - Controller:处理用户请求都发送给 ,返回数据给 JSP 并展示给用户。 +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/mvc-model2.png) + Model2 模式下还存在很多问题,Model2 的抽象和封装程度还远远不够,使用 Model2 进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。 于是,很多 JavaWeb 开发相关的 MVC 框架应运而生比如 Struts2,但是 Struts2 比较笨重。 From ae936446377522c47179cc315e9741bb935660c0 Mon Sep 17 00:00:00 2001 From: coiggahou <1096119575@qq.com> Date: Tue, 10 Aug 2021 11:29:15 +0800 Subject: [PATCH 151/257] fix mistake: Location should be Locator --- docs/network/计算机网络.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/network/计算机网络.md b/docs/network/计算机网络.md index 07028ccf..95dc93f6 100644 --- a/docs/network/计算机网络.md +++ b/docs/network/计算机网络.md @@ -271,7 +271,7 @@ HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较 ## 十二 URI和URL的区别是什么? - URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。 -- URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。 +- URL(Uniform Resource Locator) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。 URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。 From 08fd4ac95bff782e319809a73e5f9f506e363f8c Mon Sep 17 00:00:00 2001 From: Silverados <295843706@qq.com> Date: Tue, 10 Aug 2021 12:29:59 +0800 Subject: [PATCH 152/257] =?UTF-8?q?Update=20=E5=88=86=E5=B8=83=E5=BC=8Fid?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=96=B9=E6=A1=88=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 减少人工成功---》减少人工成本 --- .../micro-service/分布式id生成方案总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/micro-service/分布式id生成方案总结.md b/docs/system-design/micro-service/分布式id生成方案总结.md index 48f962d6..5c5afd59 100644 --- a/docs/system-design/micro-service/分布式id生成方案总结.md +++ b/docs/system-design/micro-service/分布式id生成方案总结.md @@ -152,7 +152,7 @@ Leaf中的snowflake模式和原始snowflake算法的不同点,也主要在work ### 总结 -总得来说,上面两种都是自动生成workId,以让系统更加稳定以及减少人工成功。 +总得来说,上面两种都是自动生成workId,以让系统更加稳定以及减少人工成本。 ## Redis From 170e0afb1064ac0f8859bef543754c221ee823b9 Mon Sep 17 00:00:00 2001 From: Silverados <295843706@qq.com> Date: Tue, 10 Aug 2021 12:34:57 +0800 Subject: [PATCH 153/257] =?UTF-8?q?Update=20=E5=88=86=E5=B8=83=E5=BC=8Fid?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=96=B9=E6=A1=88=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 由于incr命令过得 --》 由于incr命令过多 --- .../micro-service/分布式id生成方案总结.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/micro-service/分布式id生成方案总结.md b/docs/system-design/micro-service/分布式id生成方案总结.md index 48f962d6..67b68b06 100644 --- a/docs/system-design/micro-service/分布式id生成方案总结.md +++ b/docs/system-design/micro-service/分布式id生成方案总结.md @@ -171,7 +171,7 @@ OK RDB持久化相当于定时打一个快照进行持久化,如果打完快照后,连续自增了几次,还没来得及做下一次快照持久化,这个时候Redis挂掉了,重启Redis后会出现ID重复。 -AOF持久化相当于对每条写命令进行持久化,如果Redis挂掉了,不会出现ID重复的现象,但是会由于incr命令过得,导致重启恢复数据时间过长。 +AOF持久化相当于对每条写命令进行持久化,如果Redis挂掉了,不会出现ID重复的现象,但是会由于incr命令过多,导致重启恢复数据时间过长。 ## 公众号 From d96ba4e872914fddddeeaae0184cfe3b177dd56b Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 10 Aug 2021 16:44:35 +0800 Subject: [PATCH 154/257] =?UTF-8?q?Update=20InnoDB=E5=AF=B9MVCC=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/mysql/InnoDB对MVCC的实现.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/database/mysql/InnoDB对MVCC的实现.md b/docs/database/mysql/InnoDB对MVCC的实现.md index 9f3ed51d..e846088d 100644 --- a/docs/database/mysql/InnoDB对MVCC的实现.md +++ b/docs/database/mysql/InnoDB对MVCC的实现.md @@ -18,7 +18,7 @@ ## 一致性非锁定读和锁定读 -#### 一致性非锁定读 +### 一致性非锁定读 对于 [**一致性非锁定读(Consistent Nonlocking Reads)** ](https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html)的实现,通常做法是加一个版本号或者时间戳字段,在更新数据的同时版本号 + 1 或者更新时间戳。查询时,将当前可见的版本号与对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见 @@ -26,13 +26,13 @@ 在 `Repeatable Read` 和 `Read Committed` 两个隔离级别下,如果是执行普通的 `select` 语句(不包括 `select ... lock in share mode` ,`select ... for update`)则会使用 `一致性非锁定读(MVCC)`。并且在 `Repeatable Read` 下 `MVCC` 实现了可重复读和防止部分幻读 -#### 锁定读 +### 锁定读 如果执行的是下列语句,就是 [**锁定读(Locking Reads)**](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html) -- select ... lock in share mode -- select ... for update -- insert、update、delete 操作 +- `select ... lock in share mode` +- `select ... for update` +- `insert`、`update`、`delete` 操作 在锁定读下,读取的是数据的最新版本,这种读也被称为 `当前读(current read)`。锁定读会对读取到的记录加锁: @@ -40,13 +40,13 @@ - `select ... for update`、`insert`、`update`、`delete`:对记录加 `X` 锁,且其它事务不能加任何锁 -在一致性非锁定读下,即使读取的记录已被其它事务加上 `X` 锁,这时记录也是可以被读取的,即读取的快照数据。上面说了在 `Repeatable Read` 下 `MVCC` 防止了部分幻读,这边的 “部分” 是指在 `一致性非锁定读` 情况下,只能读取到第一次查询之前所插入的数据(根据 Read View 判断数据可见性,Read View 在第一次查询时生成),但如果是`当前读` ,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。**所以 `InnoDB` 在实现`Repeatable Read` 时,如果执行的是当前读,则会对读取的记录使用 `Next-key Lock` ,来防止其它事务在间隙间插入数据** +在一致性非锁定读下,即使读取的记录已被其它事务加上 `X` 锁,这时记录也是可以被读取的,即读取的快照数据。上面说了,在 `Repeatable Read` 下 `MVCC` 防止了部分幻读,这边的 “部分” 是指在 `一致性非锁定读` 情况下,只能读取到第一次查询之前所插入的数据(根据 Read View 判断数据可见性,Read View 在第一次查询时生成)。但是!如果是 `当前读` ,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。所以, **`InnoDB` 在实现`Repeatable Read` 时,如果执行的是当前读,则会对读取的记录使用 `Next-key Lock` ,来防止其它事务在间隙间插入数据** ## InnoDB 对 MVCC 的实现 `MVCC` 的实现依赖于:**隐藏字段、Read View、undo log**。在内部实现中,`InnoDB` 通过数据行的 `DB_TRX_ID` 和 `Read View` 来判断数据的可见性,如不可见,则通过数据行的 `DB_ROLL_PTR` 找到 `undo log` 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 `Read View` 之前已经提交的修改和该事务本身做的修改 -#### 隐藏字段 +### 隐藏字段 在内部,`InnoDB` 存储引擎为每行数据添加了三个 [隐藏字段](https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html): @@ -54,7 +54,7 @@ - `DB_ROLL_PTR(7字节)` 回滚指针,指向该行的 `undo log` 。如果该行未被更新,则为空 - `DB_ROW_ID(6字节)`:如果没有设置主键且该表没有唯一非空索引时,`InnoDB` 会使用该 id 来生成聚簇索引 -#### ReadView +### ReadView [`Read View`](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L298) 主要是用来做可见性判断,里面保存了 “当前对本事务不可见的其他活跃事务” @@ -65,7 +65,7 @@ - `m_ids`:`Read View` 创建时其他未提交的活跃事务 ID 列表。创建 `Read View`时,将当前未提交事务 ID 记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的。`m_ids` 不包括当前事务自己和已提交的事务(正在内存中) - `m_creator_trx_id`:创建该 `Read View` 的事务 ID -#### undo-log +### undo-log `undo log` 主要有两个作用: @@ -78,21 +78,21 @@ **`insert` 时的数据初始状态:** -![markdown](https://ddmcc-1255635056.file.myqcloud.com/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png) +![](https://ddmcc-1255635056.file.myqcloud.com/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png) 2. **`update undo log`** :`update` 或 `delete` 操作中产生的 `undo log`。该 `undo log`可能需要提供 `MVCC` 机制,因此不能在事务提交时就进行删除。提交时放入 `undo log` 链表,等待 `purge线程` 进行最后的删除 **数据第一次被修改时:** -![markdown](https://ddmcc-1255635056.file.myqcloud.com/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png) +![](https://ddmcc-1255635056.file.myqcloud.com/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png) **数据第二次被修改时:** -![markdown](https://ddmcc-1255635056.file.myqcloud.com/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png) +![](https://ddmcc-1255635056.file.myqcloud.com/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png) 不同事务或者相同事务的对同一记录行的修改,会使该记录行的 `undo log` 成为一条链表,链首就是最新的记录,链尾就是最早的旧记录 -#### 数据可见性算法 +### 数据可见性算法 在 `InnoDB` 存储引擎中,创建一个新事务后,执行每个 `select` 语句前,都会创建一个快照(Read View),**快照中保存了当前数据库系统中正处于活跃(没有 commit)的事务的 ID 号**。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务 ID 列表(即 m_ids)。当用户在这个事务中要读取某个记录行的时候,`InnoDB` 会将该记录行的 `DB_TRX_ID` 与 `Read View` 中的一些变量及当前事务 ID 进行比较,判断是否满足可见性条件 @@ -127,13 +127,13 @@ 举个例子: -![markdown](https://ddmcc-1255635056.file.myqcloud.com/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png) +![](https://ddmcc-1255635056.file.myqcloud.com/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png) -#### **在 RC 下 ReadView 生成情况** +### 在 RC 下 ReadView 生成情况 1. **`假设时间线来到 T4 ,那么此时数据行 id = 1 的版本链为`:** - ![markdown](https://ddmcc-1255635056.file.myqcloud.com/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png) + ![](https://ddmcc-1255635056.file.myqcloud.com/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png) 由于 RC 级别下每次查询都会生成`Read View` ,并且事务 101、102 并未提交,此时 `103` 事务生成的 `Read View` 中活跃的事务 **`m_ids` 为:[101,102]** ,`m_low_limit_id`为:104,`m_up_limit_id`为:101,`m_creator_trx_id` 为:103 @@ -159,7 +159,7 @@ > **总结:** **在 RC 隔离级别下,事务在每次查询开始时都会生成并设置新的 Read View,所以导致不可重复读** -#### **在 RR 下 ReadView 生成情况** +### 在 RR 下 ReadView 生成情况 **在可重复读级别下,只会在事务开始后第一次读取数据时生成一个 Read View(m_ids 列表)** @@ -199,11 +199,11 @@ `InnoDB`存储引擎在 RR 级别下通过 `MVCC`和 `Next-key Lock` 来解决幻读问题: -1. **执行普通 `select`,此时会以 `MVCC` 快照读的方式读取数据** +**1、执行普通 `select`,此时会以 `MVCC` 快照读的方式读取数据** 在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 `Read View` ,并使用至事务提交。所以在生成 `Read View` 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读” -2. **执行 select...for update/lock in share mode、insert、update、delete 等当前读** +**2、执行 select...for update/lock in share mode、insert、update、delete 等当前读** 在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!`InnoDB` 使用 [Next-key Lock](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-next-key-locks) 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读 From c05b4be45f684bd2d0bf9c5989ac6bae3e4e969a Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 10 Aug 2021 16:44:37 +0800 Subject: [PATCH 155/257] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 54eeb07e..7cf58b25 100644 --- a/README.md +++ b/README.md @@ -147,9 +147,9 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle 1. [MySQL数据库索引总结](docs/database/mysql/MySQL数据库索引.md) 2. [事务隔离级别(图文详解)](docs/database/mysql/事务隔离级别(图文详解).md) -3. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/mysql/一条sql语句在mysql中如何执行的.md) -4. [关于数据库中如何存储时间的一点思考](docs/database/mysql/关于数据库存储时间的一点思考.md) -5. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/InnoDB对MVCC的实现.md) +3. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/InnoDB对MVCC的实现.md) +4. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/mysql/一条sql语句在mysql中如何执行的.md) +5. [关于数据库中如何存储时间的一点思考](docs/database/mysql/关于数据库存储时间的一点思考.md) ### Redis From 0c147b8b0e7d218b36746ddcc25bc925f4974d86 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 10 Aug 2021 20:04:36 +0800 Subject: [PATCH 156/257] Update limit-request.md --- .../system-design/high-availability/limit-request.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/system-design/high-availability/limit-request.md b/docs/system-design/high-availability/limit-request.md index e7e64acc..80511532 100644 --- a/docs/system-design/high-availability/limit-request.md +++ b/docs/system-design/high-availability/limit-request.md @@ -22,14 +22,20 @@ #### 漏桶算法 -我们可以把发请求的动作比作成注水到桶中,我们处理请求的过程可以比喻为漏桶漏水。我们往桶中以任意速率流入水,以一定速率流出水。当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。如果想要实现这个算法的话也很简单,准备一个队列用来保存请求,然后我们定期从队列中拿请求来执行就好了。 +我们可以把发请求的动作比作成注水到桶中,我们处理请求的过程可以比喻为 **漏桶漏水** 。我们往桶中以任意速率流入水,以一定速率流出水。当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。 + +如果想要实现这个算法的话也很简单,准备一个队列用来保存请求,然后我们定期从队列中拿请求来执行就好了。 ![漏桶算法](https://static001.infoq.cn/resource/image/75/03/75938d1010138ce66e38c6ed0392f103.png) #### 令牌桶算法 -令牌桶算法也比较简单。和漏桶算法算法一样,我们的主角还是桶(这限流算法和桶过不去啊)。不过现在桶里装的是令牌了,请求在被处理之前需要拿到一个令牌,请求处理完毕之后将这个令牌丢弃(删除)。我们根据限流大小,按照一定的速率往桶里添加令牌。 +令牌桶算法也比较简单。和漏桶算法算法一样,我们的主角还是桶(这限流算法和桶过不去啊)。不过现在桶里装的是令牌了,请求在被处理之前需要拿到一个令牌,请求处理完毕之后将这个令牌丢弃(删除)。 + +我们根据限流大小,按照一定的速率往桶里添加令牌即可! ![令牌桶算法](https://static001.infoq.cn/resource/image/ec/93/eca0e5eaa35dac938c673fecf2ec9a93.png) -### +**漏桶算法 vs 令牌桶算法** : + + From 1672da37b0892c92cd8736fbdf95719095884ea8 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 11 Aug 2021 10:56:02 +0800 Subject: [PATCH 157/257] typo --- .../2020最新Java并发进阶常见面试题总结.md | 3 +-- docs/java/multi-thread/java线程池学习总结.md | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md index 8b92632d..365d5aec 100644 --- a/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md +++ b/docs/java/multi-thread/2020最新Java并发进阶常见面试题总结.md @@ -619,8 +619,7 @@ public ThreadPoolExecutor(int corePoolSize, 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任时,`ThreadPoolTaskExecutor` 定义一些策略: - **`ThreadPoolExecutor.AbortPolicy`:** 抛出 `RejectedExecutionException`来拒绝新任务的处理。 -- **`ThreadPoolExecutor.CallerRunsPolicy`:** -调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 +- **`ThreadPoolExecutor.CallerRunsPolicy`:** 调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 - **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。 - **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。 diff --git a/docs/java/multi-thread/java线程池学习总结.md b/docs/java/multi-thread/java线程池学习总结.md index eb266f3a..1adf4081 100644 --- a/docs/java/multi-thread/java线程池学习总结.md +++ b/docs/java/multi-thread/java线程池学习总结.md @@ -173,10 +173,10 @@ public class ScheduledThreadPoolExecutor 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任务时,`ThreadPoolTaskExecutor` 定义一些策略: -- **`ThreadPoolExecutor.AbortPolicy`**:抛出 `RejectedExecutionException`来拒绝新任务的处理。 -- **`ThreadPoolExecutor.CallerRunsPolicy`**:调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 -- **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。 -- **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。 +- **`ThreadPoolExecutor.AbortPolicy`** :抛出 `RejectedExecutionException`来拒绝新任务的处理。 +- **`ThreadPoolExecutor.CallerRunsPolicy`** :调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 +- **`ThreadPoolExecutor.DiscardPolicy`** :不处理新任务,直接丢弃掉。 +- **`ThreadPoolExecutor.DiscardOldestPolicy`** : 此策略将丢弃最早的未处理的任务请求。 举个例子: From 3238f67bd51fa2dac8cbe42aff9905778d1ade25 Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 11 Aug 2021 11:17:22 +0800 Subject: [PATCH 158/257] =?UTF-8?q?Update=20=E5=B9=B6=E5=8F=91=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/multi-thread/并发容器总结.md | 134 +++++++------------ 1 file changed, 51 insertions(+), 83 deletions(-) diff --git a/docs/java/multi-thread/并发容器总结.md b/docs/java/multi-thread/并发容器总结.md index fcc900e6..e4042ebe 100644 --- a/docs/java/multi-thread/并发容器总结.md +++ b/docs/java/multi-thread/并发容器总结.md @@ -1,50 +1,24 @@ -点击关注[公众号](#公众号 "公众号")及时获取笔主最新更新文章,并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。 - - - -- [一 JDK 提供的并发容器总结](#一-jdk-提供的并发容器总结 "一 JDK 提供的并发容器总结") -- [二 ConcurrentHashMap](#二-concurrenthashmap "二 ConcurrentHashMap") -- [三 CopyOnWriteArrayList](#三-copyonwritearraylist "三 CopyOnWriteArrayList") - - [3.1 CopyOnWriteArrayList 简介](#31-copyonwritearraylist-简介 "3.1 CopyOnWriteArrayList 简介") - - [3.2 CopyOnWriteArrayList 是如何做到的?](#32-copyonwritearraylist-是如何做到的? "3.2 CopyOnWriteArrayList 是如何做到的?") - - [3.3 CopyOnWriteArrayList 读取和写入源码简单分析](#33-copyonwritearraylist-读取和写入源码简单分析 "3.3 CopyOnWriteArrayList 读取和写入源码简单分析") - - [3.3.1 CopyOnWriteArrayList 读取操作的实现](#331-copyonwritearraylist-读取操作的实现 "3.3.1 CopyOnWriteArrayList 读取操作的实现") - - [3.3.2 CopyOnWriteArrayList 写入操作的实现](#332-copyonwritearraylist-写入操作的实现 "3.3.2 CopyOnWriteArrayList 写入操作的实现") -- [四 ConcurrentLinkedQueue](#四-concurrentlinkedqueue "四 ConcurrentLinkedQueue") -- [五 BlockingQueue](#五-blockingqueue "五 BlockingQueue") - - [5.1 BlockingQueue 简单介绍](#51-blockingqueue-简单介绍 "5.1 BlockingQueue 简单介绍") - - [5.2 ArrayBlockingQueue](#52-arrayblockingqueue "5.2 ArrayBlockingQueue") - - [5.3 LinkedBlockingQueue](#53-linkedblockingqueue "5.3 LinkedBlockingQueue") - - [5.4 PriorityBlockingQueue](#54-priorityblockingqueue "5.4 PriorityBlockingQueue") -- [六 ConcurrentSkipListMap](#六-concurrentskiplistmap "六 ConcurrentSkipListMap") -- [七 参考](#七-参考 "七 参考") - - - -## 一 JDK 提供的并发容器总结 +## JDK 提供的并发容器总结 JDK 提供的这些容器大部分在 `java.util.concurrent` 包中。 -- **ConcurrentHashMap:** 线程安全的 HashMap -- **CopyOnWriteArrayList:** 线程安全的 List,在读多写少的场合性能非常好,远远好于 Vector. -- **ConcurrentLinkedQueue:** 高效的并发队列,使用链表实现。可以看做一个线程安全的 LinkedList,这是一个非阻塞队列。 -- **BlockingQueue:** 这是一个接口,JDK 内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。 -- **ConcurrentSkipListMap:** 跳表的实现。这是一个 Map,使用跳表的数据结构进行快速查找。 +- **`ConcurrentHashMap`** : 线程安全的 `HashMap` +- **`CopyOnWriteArrayList`** : 线程安全的 `List`,在读多写少的场合性能非常好,远远好于 `Vector`。 +- **`ConcurrentLinkedQueue`** : 高效的并发队列,使用链表实现。可以看做一个线程安全的 `LinkedList`,这是一个非阻塞队列。 +- **`BlockingQueue`** : 这是一个接口,JDK 内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。 +- **`ConcurrentSkipListMap`** : 跳表的实现。这是一个 Map,使用跳表的数据结构进行快速查找。 -## 二 ConcurrentHashMap +## ConcurrentHashMap -我们知道 HashMap 不是线程安全的,在并发场景下如果要保证一种可行的方式是使用 `Collections.synchronizedMap()` 方法来包装我们的 HashMap。但这是通过使用一个全局的锁来同步不同线程间的并发访问,因此会带来不可忽视的性能问题。 +我们知道 `HashMap` 不是线程安全的,在并发场景下如果要保证一种可行的方式是使用 `Collections.synchronizedMap()` 方法来包装我们的 `HashMap`。但这是通过使用一个全局的锁来同步不同线程间的并发访问,因此会带来不可忽视的性能问题。 -所以就有了 HashMap 的线程安全版本—— ConcurrentHashMap 的诞生。在 ConcurrentHashMap 中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时(几乎)不需要加锁,而在写操作时通过锁分段技术只对所操作的段加锁而不影响客户端对其它段的访问。 +所以就有了 `HashMap` 的线程安全版本—— `ConcurrentHashMap` 的诞生。 -关于 ConcurrentHashMap 相关问题,我在 [Java 集合框架常见面试题](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98.md "Java集合框架常见面试题") 这篇文章中已经提到过。下面梳理一下关于 ConcurrentHashMap 比较重要的问题: +在 `ConcurrentHashMap` 中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时(几乎)不需要加锁,而在写操作时通过锁分段技术只对所操作的段加锁而不影响客户端对其它段的访问。 -- [ConcurrentHashMap 和 Hashtable 的区别](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98.md#concurrenthashmap-%E5%92%8C-hashtable-%E7%9A%84%E5%8C%BA%E5%88%AB "ConcurrentHashMap 和 Hashtable 的区别") -- [ConcurrentHashMap 线程安全的具体实现方式/底层具体实现](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98.md#concurrenthashmap%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%E5%BA%95%E5%B1%82%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0 "ConcurrentHashMap线程安全的具体实现方式/底层具体实现") +## CopyOnWriteArrayList -## 三 CopyOnWriteArrayList - -### 3.1 CopyOnWriteArrayList 简介 +### CopyOnWriteArrayList 简介 ```java public class CopyOnWriteArrayList @@ -52,21 +26,21 @@ extends Object implements List, RandomAccess, Cloneable, Serializable ``` -在很多应用场景中,读操作可能会远远大于写操作。由于读操作根本不会修改原有的数据,因此对于每次读取都进行加锁其实是一种资源浪费。我们应该允许多个线程同时访问 List 的内部数据,毕竟读取操作是安全的。 +在很多应用场景中,读操作可能会远远大于写操作。由于读操作根本不会修改原有的数据,因此对于每次读取都进行加锁其实是一种资源浪费。我们应该允许多个线程同时访问 `List` 的内部数据,毕竟读取操作是安全的。 这和我们之前在多线程章节讲过 `ReentrantReadWriteLock` 读写锁的思想非常类似,也就是读读共享、写写互斥、读写互斥、写读互斥。JDK 中提供了 `CopyOnWriteArrayList` 类比相比于在读写锁的思想又更进一步。为了将读取的性能发挥到极致,`CopyOnWriteArrayList` 读取是完全不用加锁的,并且更厉害的是:写入也不会阻塞读取操作。只有写入和写入之间需要进行同步等待。这样一来,读操作的性能就会大幅度提升。**那它是怎么做的呢?** -### 3.2 CopyOnWriteArrayList 是如何做到的? +### CopyOnWriteArrayList 是如何做到的? `CopyOnWriteArrayList` 类的所有可变操作(add,set 等等)都是通过创建底层数组的新副本来实现的。当 List 需要被修改的时候,我并不修改原有内容,而是对原有数据进行一次复制,将修改的内容写入副本。写完之后,再将修改完的副本替换原来的数据,这样就可以保证写操作不会影响读操作了。 -从 `CopyOnWriteArrayList` 的名字就能看出`CopyOnWriteArrayList` 是满足`CopyOnWrite` 的 ArrayList,所谓`CopyOnWrite` 也就是说:在计算机,如果你想要对一块内存进行修改时,我们不在原有内存块中进行写操作,而是将内存拷贝一份,在新的内存中进行写操作,写完之后呢,就将指向原来内存指针指向新的内存,原来的内存就可以被回收掉了。 +从 `CopyOnWriteArrayList` 的名字就能看出 `CopyOnWriteArrayList` 是满足 `CopyOnWrite` 的。所谓 `CopyOnWrite` 也就是说:在计算机,如果你想要对一块内存进行修改时,我们不在原有内存块中进行写操作,而是将内存拷贝一份,在新的内存中进行写操作,写完之后呢,就将指向原来内存指针指向新的内存,原来的内存就可以被回收掉了。 -### 3.3 CopyOnWriteArrayList 读取和写入源码简单分析 +### CopyOnWriteArrayList 读取和写入源码简单分析 -#### 3.3.1 CopyOnWriteArrayList 读取操作的实现 +#### CopyOnWriteArrayList 读取操作的实现 -读取操作没有任何同步控制和锁操作,理由就是内部数组 array 不会发生修改,只会被另外一个 array 替换,因此可以保证数据安全。 +读取操作没有任何同步控制和锁操作,理由就是内部数组 `array` 不会发生修改,只会被另外一个 `array` 替换,因此可以保证数据安全。 ```java /** The array, accessed only via getArray/setArray. */ @@ -86,7 +60,7 @@ implements List, RandomAccess, Cloneable, Serializable #### 3.3.2 CopyOnWriteArrayList 写入操作的实现 -CopyOnWriteArrayList 写入操作 add() 方法在添加集合的时候加了锁,保证了同步,避免了多线程写的时候会 copy 出多个副本出来。 +`CopyOnWriteArrayList` 写入操作 `add()`方法在添加集合的时候加了锁,保证了同步,避免了多线程写的时候会 copy 出多个副本出来。 ```java /** @@ -111,41 +85,49 @@ CopyOnWriteArrayList 写入操作 add() 方法在添加集合的时候加了锁 } ``` -## 四 ConcurrentLinkedQueue +## ConcurrentLinkedQueue -Java 提供的线程安全的 Queue 可以分为**阻塞队列**和**非阻塞队列**,其中阻塞队列的典型例子是 BlockingQueue,非阻塞队列的典型例子是 ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 **阻塞队列可以通过加锁来实现,非阻塞队列可以通过 CAS 操作实现。** +Java 提供的线程安全的 `Queue` 可以分为**阻塞队列**和**非阻塞队列**,其中阻塞队列的典型例子是 `BlockingQueue`,非阻塞队列的典型例子是 `ConcurrentLinkedQueue`,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 **阻塞队列可以通过加锁来实现,非阻塞队列可以通过 CAS 操作实现。** -从名字可以看出,`ConcurrentLinkedQueue`这个队列使用链表作为其数据结构.ConcurrentLinkedQueue 应该算是在高并发环境中性能最好的队列了。它之所有能有很好的性能,是因为其内部复杂的实现。 +从名字可以看出,`ConcurrentLinkedQueue`这个队列使用链表作为其数据结构.`ConcurrentLinkedQueue` 应该算是在高并发环境中性能最好的队列了。它之所有能有很好的性能,是因为其内部复杂的实现。 -ConcurrentLinkedQueue 内部代码我们就不分析了,大家知道 ConcurrentLinkedQueue 主要使用 CAS 非阻塞算法来实现线程安全就好了。 +`ConcurrentLinkedQueue` 内部代码我们就不分析了,大家知道 `ConcurrentLinkedQueue` 主要使用 CAS 非阻塞算法来实现线程安全就好了。 -ConcurrentLinkedQueue 适合在对性能要求相对较高,同时对队列的读写存在多个线程同时进行的场景,即如果对队列加锁的成本较高则适合使用无锁的 ConcurrentLinkedQueue 来替代。 +`ConcurrentLinkedQueue` 适合在对性能要求相对较高,同时对队列的读写存在多个线程同时进行的场景,即如果对队列加锁的成本较高则适合使用无锁的 `ConcurrentLinkedQueue` 来替代。 -## 五 BlockingQueue +## BlockingQueue -### 5.1 BlockingQueue 简单介绍 +### BlockingQueue 简介 -上面我们己经提到了 ConcurrentLinkedQueue 作为高性能的非阻塞队列。下面我们要讲到的是阻塞队列——BlockingQueue。阻塞队列(BlockingQueue)被广泛使用在“生产者-消费者”问题中,其原因是 BlockingQueue 提供了可阻塞的插入和移除的方法。当队列容器已满,生产者线程会被阻塞,直到队列未满;当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止。 +上面我们己经提到了 `ConcurrentLinkedQueue` 作为高性能的非阻塞队列。下面我们要讲到的是阻塞队列——`BlockingQueue`。阻塞队列(`BlockingQueue`)被广泛使用在“生产者-消费者”问题中,其原因是 `BlockingQueue` 提供了可阻塞的插入和移除的方法。当队列容器已满,生产者线程会被阻塞,直到队列未满;当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止。 -BlockingQueue 是一个接口,继承自 Queue,所以其实现类也可以作为 Queue 的实现来使用,而 Queue 又继承自 Collection 接口。下面是 BlockingQueue 的相关实现类: +`BlockingQueue` 是一个接口,继承自 `Queue`,所以其实现类也可以作为 `Queue` 的实现来使用,而 `Queue` 又继承自 `Collection` 接口。下面是 `BlockingQueue` 的相关实现类: ![BlockingQueue 的实现类](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-9/51622268.jpg) -**下面主要介绍一下:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,这三个 BlockingQueue 的实现类。** +下面主要介绍一下 3 个常见的 `BlockingQueue` 的实现类:`ArrayBlockingQueue`、`LinkedBlockingQueue` 、`PriorityBlockingQueue` 。 -### 5.2 ArrayBlockingQueue +### ArrayBlockingQueue -**ArrayBlockingQueue** 是 BlockingQueue 接口的有界队列实现类,底层采用**数组**来实现。ArrayBlockingQueue 一旦创建,容量不能改变。其并发控制采用可重入锁来控制,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。当队列容量满时,尝试将元素放入队列将导致操作阻塞;尝试从一个空队列中取一个元素也会同样阻塞。 +`ArrayBlockingQueue` 是 `BlockingQueue` 接口的有界队列实现类,底层采用数组来实现。 -ArrayBlockingQueue 默认情况下不能保证线程访问队列的公平性,所谓公平性是指严格按照线程等待的绝对时间顺序,即最先等待的线程能够最先访问到 ArrayBlockingQueue。而非公平性则是指访问 ArrayBlockingQueue 的顺序不是遵守严格的时间顺序,有可能存在,当 ArrayBlockingQueue 可以被访问时,长时间阻塞的线程依然无法访问到 ArrayBlockingQueue。如果保证公平性,通常会降低吞吐量。如果需要获得公平性的 ArrayBlockingQueue,可采用如下代码: +```java +public class ArrayBlockingQueue +extends AbstractQueue +implements BlockingQueue, Serializable{} +``` + +`ArrayBlockingQueue` 一旦创建,容量不能改变。其并发控制采用可重入锁 `ReentrantLock` ,不管是插入操作还是读取操作,都需要获取到锁才能进行操作。当队列容量满时,尝试将元素放入队列将导致操作阻塞;尝试从一个空队列中取一个元素也会同样阻塞。 + +`ArrayBlockingQueue` 默认情况下不能保证线程访问队列的公平性,所谓公平性是指严格按照线程等待的绝对时间顺序,即最先等待的线程能够最先访问到 `ArrayBlockingQueue`。而非公平性则是指访问 `ArrayBlockingQueue` 的顺序不是遵守严格的时间顺序,有可能存在,当 `ArrayBlockingQueue` 可以被访问时,长时间阻塞的线程依然无法访问到 `ArrayBlockingQueue`。如果保证公平性,通常会降低吞吐量。如果需要获得公平性的 `ArrayBlockingQueue`,可采用如下代码: ```java private static ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(10,true); ``` -### 5.3 LinkedBlockingQueue +### LinkedBlockingQueue -**LinkedBlockingQueue** 底层基于**单向链表**实现的阻塞队列,可以当做无界队列也可以当做有界队列来使用,同样满足 FIFO 的特性,与 ArrayBlockingQueue 相比起来具有更高的吞吐量,为了防止 LinkedBlockingQueue 容量迅速增,损耗大量内存。通常在创建 LinkedBlockingQueue 对象时,会指定其大小,如果未指定,容量等于 Integer.MAX_VALUE。 +`LinkedBlockingQueue` 底层基于**单向链表**实现的阻塞队列,可以当做无界队列也可以当做有界队列来使用,同样满足 FIFO 的特性,与 `ArrayBlockingQueue` 相比起来具有更高的吞吐量,为了防止 `LinkedBlockingQueue` 容量迅速增,损耗大量内存。通常在创建 `LinkedBlockingQueue` 对象时,会指定其大小,如果未指定,容量等于 `Integer.MAX_VALUE` 。 **相关构造方法:** @@ -174,25 +156,21 @@ private static ArrayBlockingQueue blockingQueue = new ArrayBlockingQueu } ``` -### 5.4 PriorityBlockingQueue +### PriorityBlockingQueue -**PriorityBlockingQueue** 是一个支持优先级的无界阻塞队列。默认情况下元素采用自然顺序进行排序,也可以通过自定义类实现 `compareTo()` 方法来指定元素排序规则,或者初始化时通过构造器参数 `Comparator` 来指定排序规则。 +`PriorityBlockingQueue` 是一个支持优先级的无界阻塞队列。默认情况下元素采用自然顺序进行排序,也可以通过自定义类实现 `compareTo()` 方法来指定元素排序规则,或者初始化时通过构造器参数 `Comparator` 来指定排序规则。 -PriorityBlockingQueue 并发控制采用的是 **ReentrantLock**,队列为无界队列(ArrayBlockingQueue 是有界队列,LinkedBlockingQueue 也可以通过在构造函数中传入 capacity 指定队列最大的容量,但是 PriorityBlockingQueue 只能指定初始的队列大小,后面插入元素的时候,**如果空间不够的话会自动扩容**)。 +`PriorityBlockingQueue` 并发控制采用的是可重入锁 `ReentrantLock`,队列为无界队列(`ArrayBlockingQueue` 是有界队列,`LinkedBlockingQueue` 也可以通过在构造函数中传入 `capacity` 指定队列最大的容量,但是 `PriorityBlockingQueue` 只能指定初始的队列大小,后面插入元素的时候,**如果空间不够的话会自动扩容**)。 -简单地说,它就是 PriorityQueue 的线程安全版本。不可以插入 null 值,同时,插入队列的对象必须是可比较大小的(comparable),否则报 ClassCastException 异常。它的插入操作 put 方法不会 block,因为它是无界队列(take 方法在队列为空的时候会阻塞)。 +简单地说,它就是 `PriorityQueue` 的线程安全版本。不可以插入 null 值,同时,插入队列的对象必须是可比较大小的(comparable),否则报 `ClassCastException` 异常。它的插入操作 put 方法不会 block,因为它是无界队列(take 方法在队列为空的时候会阻塞)。 -**推荐文章:** +**推荐文章:** [《解读 Java 并发队列 BlockingQueue》](https://javadoop.com/post/java-concurrent-queue) -《解读 Java 并发队列 BlockingQueue》 - -[https://javadoop.com/post/java-concurrent-queue](https://javadoop.com/post/java-concurrent-queue "https://javadoop.com/post/java-concurrent-queue") - -## 六 ConcurrentSkipListMap +## ConcurrentSkipListMap 下面这部分内容参考了极客时间专栏[《数据结构与算法之美》](https://time.geekbang.org/column/intro/126?code=zl3GYeAsRI4rEJIBNu5B/km7LSZsPDlGWQEpAYw5Vu0=&utm_term=SPoster "《数据结构与算法之美》")以及《实战 Java 高并发程序设计》。 -**为了引出 ConcurrentSkipListMap,先带着大家简单理解一下跳表。** +为了引出 `ConcurrentSkipListMap`,先带着大家简单理解一下跳表。 对于一个单链表,即使链表是有序的,如果我们想要在其中查找某个数据,也只能从头到尾遍历链表,这样效率自然就会很低,跳表就不一样了。跳表是一种可以用来快速查找的数据结构,有点类似于平衡树。它们都可以对元素进行快速的查找。但一个重要的区别是:对平衡树的插入和删除往往很可能导致平衡树进行一次全局的调整。而对跳表的插入和删除只需要对整个数据结构的局部进行操作即可。这样带来的好处是:在高并发的情况下,你会需要一个全局锁来保证整个平衡树的线程安全。而对于跳表,你只需要部分锁即可。这样,在高并发环境下,你就可以拥有更好的性能。而就查询的性能而言,跳表的时间复杂度也是 **O(logn)** 所以在并发数据结构中,JDK 使用跳表来实现一个 Map。 @@ -210,20 +188,10 @@ PriorityBlockingQueue 并发控制采用的是 **ReentrantLock**,队列为无 从上面很容易看出,**跳表是一种利用空间换时间的算法。** -使用跳表实现 Map 和使用哈希算法实现 Map 的另外一个不同之处是:哈希并不会保存元素的顺序,而跳表内所有的元素都是排序的。因此在对跳表进行遍历时,你会得到一个有序的结果。所以,如果你的应用需要有序性,那么跳表就是你不二的选择。JDK 中实现这一数据结构的类是 ConcurrentSkipListMap。 +使用跳表实现 `Map` 和使用哈希算法实现 `Map` 的另外一个不同之处是:哈希并不会保存元素的顺序,而跳表内所有的元素都是排序的。因此在对跳表进行遍历时,你会得到一个有序的结果。所以,如果你的应用需要有序性,那么跳表就是你不二的选择。JDK 中实现这一数据结构的类是 `ConcurrentSkipListMap`。 -## 七 参考 +## 参考 - 《实战 Java 高并发程序设计》 - https://javadoop.com/post/java-concurrent-queue - https://juejin.im/post/5aeebd02518825672f19c546 - -## 公众号 - -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 - -**《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V2.0 PDF 版本[公众号](#公众号 "公众号")后台回复 **"面试突击"** 即可免费领取! - -**Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 - -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) From e0ce9e4e6bbd93e15252f01f1201563c81661291 Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 13 Aug 2021 21:38:06 +0800 Subject: [PATCH 159/257] =?UTF-8?q?Update=20=E4=BB=A3=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E8=AF=A6=E8=A7=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/代理模式详解.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/代理模式详解.md b/docs/java/basis/代理模式详解.md index 8323cedc..704de492 100644 --- a/docs/java/basis/代理模式详解.md +++ b/docs/java/basis/代理模式详解.md @@ -348,7 +348,7 @@ public class DebugMethodInterceptor implements MethodInterceptor { /** - * @param o 被代理的对象(需要增强的对象) + * @param o 代理对象(增强的对象) * @param method 被拦截的方法(需要增强的方法) * @param args 方法入参 * @param methodProxy 用于调用原始方法 From 4ad22b21c2d4e2bd485f89a047bde9c1d6e772f2 Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sat, 14 Aug 2021 01:17:45 +0800 Subject: [PATCH 160/257] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java集合框架常见面试题.md | 32 +++++++++++------- .../images/java-collection-hierarchy.png | Bin 0 -> 90889 bytes 2 files changed, 19 insertions(+), 13 deletions(-) create mode 100644 docs/java/collection/images/java-collection-hierarchy.png diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 5c0c5b38..e604f819 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -50,19 +50,21 @@ ### 1.1.1. Java 集合概览 -从下图可以看出,在 Java 中除了以 `Map` 结尾的类之外, 其他类都实现了 `Collection` 接口。 +Java 集合, 也叫作容器,主要是由两大接口派生而来:一个是 `Collecton`接口,主要用于存放单一元素;另一个是 `Map` 接口,主要用于存放键值对。对于`Collection` 接口,下面又有三个主要的子接口:`List`、`Set` 和 `Queue`。 -并且,以 `Map` 结尾的类都实现了 `Map` 接口。 +Java 集合框架如下图所示: -![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/source-code/dubbo/java-collection-hierarchy.png) +![](./images/java-collection-hierarchy.png) -

https://www.javatpoint.com/collections-in-java

-### 1.1.2. 说说 List,Set,Map 三者的区别? +注:图中只列举了主要的继承派生关系,并没有列举所有关系。比方省略了`AbstractList`, `NavigableSet`等抽象类以及其他的一些辅助类,如想深入了解,可自行查看源码。 -- `List`(对付顺序的好帮手): 存储的元素是有序的、可重复的。 +### 1.1.2. 说说 List, Set, Queue, Map 四者的区别? + +- `List`(对付顺序的好帮手): 存储的元素是有序的、可重复的。 - `Set`(注重独一无二的性质): 存储的元素是无序的、不可重复的。 -- `Map`(用 Key 来搜索的专家): 使用键值对(key-value)存储,类似于数学上的函数 y=f(x),“x”代表 key,"y"代表 value,Key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。 +- `Queue`(实现排队功能的叫号机): 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。 +- `Map`(用 key 来搜索的专家): 使用键值对(key-value)存储,类似于数学上的函数 y=f(x),"x" 代表 key,"y" 代表 value,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。 ### 1.1.3. 集合框架底层数据结构总结 @@ -70,19 +72,23 @@ #### 1.1.3.1. List -- `Arraylist`: `Object[]`数组 -- `Vector`:`Object[]`数组 +- `Arraylist`: `Object[]` 数组 +- `Vector`:`Object[]` 数组 - `LinkedList`: 双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环) #### 1.1.3.2. Set -- `HashSet`(无序,唯一): 基于 `HashMap` 实现的,底层采用 `HashMap` 来保存元素 -- `LinkedHashSet`:`LinkedHashSet` 是 `HashSet` 的子类,并且其内部是通过 `LinkedHashMap` 来实现的。有点类似于我们之前说的 `LinkedHashMap` 其内部是基于 `HashMap` 实现一样,不过还是有一点点区别的 -- `TreeSet`(有序,唯一): 红黑树(自平衡的排序二叉树) +- `HashSet`(无序,唯一): 基于 `HashMap` 实现的,底层采用 `HashMap` 来保存元素 +- `LinkedHashSet`: `LinkedHashSet` 是 `HashSet` 的子类,并且其内部是通过 `LinkedHashMap` 来实现的。有点类似于我们之前说的 `LinkedHashMap` 其内部是基于 `HashMap` 实现一样,不过还是有一点点区别的 +- `TreeSet`(有序,唯一): 红黑树(自平衡的排序二叉树) + +#### 1.1.3.3 Queue +- `PriorityQueue`: `Object[]` 数组来实现二叉堆 +- `ArrayQueue`: `Object[]` 数组 + 双指针 再来看看 `Map` 接口下面的集合。 -#### 1.1.3.3. Map +#### 1.1.3.4. Map - `HashMap`: JDK1.8 之前 `HashMap` 由数组+链表组成的,数组是 `HashMap` 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间 - `LinkedHashMap`: `LinkedHashMap` 继承自 `HashMap`,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,`LinkedHashMap` 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。详细可以查看:[《LinkedHashMap 源码详细分析(JDK1.8)》](https://www.imooc.com/article/22931) diff --git a/docs/java/collection/images/java-collection-hierarchy.png b/docs/java/collection/images/java-collection-hierarchy.png new file mode 100644 index 0000000000000000000000000000000000000000..78daf9808454703816958d3e2ce52875612c7345 GIT binary patch literal 90889 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 literal 0 HcmV?d00001 From 2a4f95308de1424dcb61deb3fda2bb6af64a2748 Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 14 Aug 2021 09:16:39 +0800 Subject: [PATCH 161/257] =?UTF-8?q?[feat]=20=E8=A1=A5=E5=85=85=20redis=20?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/Redis/redis-all.md | 118 ++++++++++--------------------- 1 file changed, 38 insertions(+), 80 deletions(-) diff --git a/docs/database/Redis/redis-all.md b/docs/database/Redis/redis-all.md index 64ea49d5..93227374 100644 --- a/docs/database/Redis/redis-all.md +++ b/docs/database/Redis/redis-all.md @@ -1,45 +1,5 @@ -点击关注[公众号](#公众号)及时获取笔主最新更新文章,并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。 - - - - -- [1. 简单介绍一下 Redis 呗!](#1-简单介绍一下-redis-呗) -- [2. 分布式缓存常见的技术选型方案有哪些?](#2-分布式缓存常见的技术选型方案有哪些) -- [3. 说一下 Redis 和 Memcached 的区别和共同点](#3-说一下-redis-和-memcached-的区别和共同点) -- [4. 缓存数据的处理流程是怎样的?](#4-缓存数据的处理流程是怎样的) -- [5. 为什么要用 Redis/为什么要用缓存?](#5-为什么要用-redis为什么要用缓存) -- [6. Redis 常见数据结构以及使用场景分析](#6-redis-常见数据结构以及使用场景分析) - - [6.1. string](#61-string) - - [6.2. list](#62-list) - - [6.3. hash](#63-hash) - - [6.4. set](#64-set) - - [6.5. sorted set](#65-sorted-set) - - [6.6 bitmap](#66-bitmap) -- [7. Redis 单线程模型详解](#7-redis-单线程模型详解) -- [8. Redis 没有使用多线程?为什么不使用多线程?](#8-redis-没有使用多线程为什么不使用多线程) -- [9. Redis6.0 之后为何引入了多线程?](#9-redis60-之后为何引入了多线程) -- [10. Redis 给缓存数据设置过期时间有啥用?](#10-redis-给缓存数据设置过期时间有啥用) -- [11. Redis 是如何判断数据是否过期的呢?](#11-redis-是如何判断数据是否过期的呢) -- [12. 过期的数据的删除策略了解么?](#12-过期的数据的删除策略了解么) -- [13. Redis 内存淘汰机制了解么?](#13-redis-内存淘汰机制了解么) -- [14. Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复)](#14-redis-持久化机制怎么保证-redis-挂掉之后再重启数据可以进行恢复) -- [15. Redis 事务](#15-redis-事务) -- [16. 缓存穿透](#16-缓存穿透) - - [16.1. 什么是缓存穿透?](#161-什么是缓存穿透) - - [16.2. 缓存穿透情况的处理流程是怎样的?](#162-缓存穿透情况的处理流程是怎样的) - - [16.3. 有哪些解决办法?](#163-有哪些解决办法) -- [17. 缓存雪崩](#17-缓存雪崩) - - [17.1. 什么是缓存雪崩?](#171-什么是缓存雪崩) - - [17.2. 有哪些解决办法?](#172-有哪些解决办法) -- [18. 如何保证缓存和数据库数据的一致性?](#18-如何保证缓存和数据库数据的一致性) -- [19. 参考](#19-参考) -- [20. 公众号](#20-公众号) - - - - -### 1. 简单介绍一下 Redis 呗! +### 简单介绍一下 Redis 呗! 简单来说 **Redis 就是一个使用 C 语言开发的数据库**,不过与传统数据库不同的是 **Redis 的数据是存在内存中的** ,也就是它是内存数据库,所以读写速度非常快,因此 Redis 被广泛应用于缓存方向。 @@ -47,7 +7,7 @@ **Redis 提供了多种数据类型来支持不同的业务场景。Redis 还支持事务 、持久化、Lua 脚本、多种集群方案。** -### 2. 分布式缓存常见的技术选型方案有哪些? +### 分布式缓存常见的技术选型方案有哪些? 分布式缓存的话,使用的比较多的主要是 **Memcached** 和 **Redis**。不过,现在基本没有看过还有项目使用 **Memcached** 来做缓存,都是直接用 **Redis**。 @@ -55,7 +15,7 @@ Memcached 是分布式缓存最开始兴起的那会,比较常用的。后来 分布式缓存主要解决的是单机缓存的容量受服务器限制并且无法保存通用信息的问题。因为,本地缓存只在当前服务里有效,比如如果你部署了两个相同的服务,他们两者之间的缓存数据是无法共同的。 -### 3. 说一下 Redis 和 Memcached 的区别和共同点 +### 说一下 Redis 和 Memcached 的区别和共同点 现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!不过,了解 Redis 和 Memcached 的区别和共同点,有助于我们在做相应的技术选型的时候,能够做到有理有据! @@ -78,7 +38,7 @@ Memcached 是分布式缓存最开始兴起的那会,比较常用的。后来 相信看了上面的对比之后,我们已经没有什么理由可以选择使用 Memcached 来作为自己项目的分布式缓存了。 -### 4. 缓存数据的处理流程是怎样的? +### 缓存数据的处理流程是怎样的? 作为暖男一号,我给大家画了一个草图。 @@ -91,7 +51,7 @@ Memcached 是分布式缓存最开始兴起的那会,比较常用的。后来 3. 数据库中存在的话就更新缓存中的数据。 4. 数据库中不存在的话就返回空数据。 -### 5. 为什么要用 Redis/为什么要用缓存? +### 为什么要用 Redis/为什么要用缓存? _简单,来说使用缓存主要是为了提升用户体验以及应对更多的用户。_ @@ -117,13 +77,21 @@ _简单,来说使用缓存主要是为了提升用户体验以及应对更多 由此可见,直接操作缓存能够承受的数据库请求数量是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。进而,我们也就提高了系统整体的并发。 -### 6. Redis 常见数据结构以及使用场景分析 +### Redis 除了做缓存,还能做什么? + +- **分布式锁** : 通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。相关阅读:[《分布式锁中的王者方案 - Redisson》](https://mp.weixin.qq.com/s/CbnPRfvq4m1sqo2uKI6qQw)。 +- **限流** :一般是通过 Redis + Lua 脚本的方式来实现限流。相关阅读:[《我司用了 6 年的 Redis 分布式限流器,可以说是非常厉害了!》](https://mp.weixin.qq.com/s/kyFAWH3mVNJvurQDt4vchA)。 +- **消息队列** :Redis 自带的 list 数据结构可以作为一个简单的队列使用。Redis5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka,有主题和消费组的概念,支持消息持久化以及 ACK 机制。 +- **复杂业务场景** :通过 Redis 以及 Redis 扩展(比如 Redisson)提供的数据结构,我们可以很方便地完成很多复杂的业务场景比如通过 bitmap 统计活跃用户、通过 sorted set 维护排行榜。 +- ...... + +### Redis 常见数据结构以及使用场景分析 你可以自己本机安装 redis 或者通过 redis 官网提供的[在线 redis 环境](https://try.redis.io/)。 ![try-redis](./images/redis-all/try-redis.png) -#### 6.1. string +#### string 1. **介绍** :string 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种 **简单动态字符串**(simple dynamic string,**SDS**)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串为 O(N)),除此之外,Redis 的 SDS API 是安全的,不会造成缓冲区溢出。 2. **常用命令:** `set,get,strlen,exists,decr,incr,setex` 等等。 @@ -184,7 +152,7 @@ OK (integer) 56 ``` -#### 6.2. list +#### list 1. **介绍** :**list** 即是 **链表**。链表是一种非常常见的数据结构,特点是易于数据元素的插入和删除并且可以灵活调整链表长度,但是链表的随机访问困难。许多高级编程语言都内置了链表的实现比如 Java 中的 **LinkedList**,但是 C 语言并没有实现链表,所以 Redis 实现了自己的链表数据结构。Redis 的 list 的实现为一个 **双向链表**,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。 2. **常用命令:** `rpush,lpop,lpush,rpop,lrange,llen` 等。 @@ -245,7 +213,7 @@ OK (integer) 3 ``` -#### 6.3. hash +#### hash 1. **介绍** :hash 类似于 JDK1.8 前的 HashMap,内部实现也差不多(数组 + 链表)。不过,Redis 的 hash 做了更多优化。另外,hash 是一个 string 类型的 field 和 value 的映射表,**特别适合用于存储对象**,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以 hash 数据结构来存储用户信息,商品信息等等。 2. **常用命令:** `hset,hmset,hexists,hget,hgetall,hkeys,hvals` 等。 @@ -282,7 +250,7 @@ OK "GuideGeGe" ``` -#### 6.4. set +#### set 1. **介绍 :** set 类似于 Java 中的 `HashSet` 。Redis 中的 set 类型是一种无序集合,集合中的元素没有先后顺序。当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作。比如:你可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis 可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程。 2. **常用命令:** `sadd,spop,smembers,sismember,scard,sinterstore,sunion` 等。 @@ -310,7 +278,7 @@ OK 1) "value2" ``` -#### 6.5. sorted set +#### sorted set 1. **介绍:** 和 set 相比,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。有点像是 Java 中 HashMap 和 TreeSet 的结合体。 2. **常用命令:** `zadd,zcard,zscore,zrange,zrevrange,zrem` 等。 @@ -337,7 +305,7 @@ OK 2) "value2" ``` -#### 6.6 bitmap +#### bitmap 1. **介绍:** bitmap 存储的是连续的二进制数字(0 和 1),通过 bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 bitmap 本身会极大的节省储存空间。 2. **常用命令:** `setbit` 、`getbit` 、`bitcount`、`bitop` @@ -417,7 +385,7 @@ BITOP operation destkey key [key ...] 只需要一个 key,然后用户 ID 为 offset,如果在线就设置为 1,不在线就设置为 0。 -### 7. Redis 单线程模型详解 +### Redis 单线程模型详解 **Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型** (Netty 的线程模型也基于 Reactor 模式,Reactor 模式不愧是高性能 IO 的基石),这套事件处理模型对应的是 Redis 中的文件事件处理器(file event handler)。由于文件事件处理器(file event handler)是单线程方式运行的,所以我们一般都说 Redis 是单线程模型。 @@ -450,7 +418,7 @@ Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接(

《Redis设计与实现:12章》

-### 8. Redis 没有使用多线程?为什么不使用多线程? +### Redis 没有使用多线程?为什么不使用多线程? 虽然说 Redis 是单线程模型,但是,实际上,**Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。** @@ -468,7 +436,7 @@ Redis 通过**IO 多路复用程序** 来监听来自客户端的大量连接( 2. Redis 的性能瓶颈不在 CPU ,主要在内存和网络; 3. 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。 -### 9. Redis6.0 之后为何引入了多线程? +### Redis6.0 之后为何引入了多线程? **Redis6.0 引入多线程主要是为了提高网络 IO 读写性能**,因为这个算是 Redis 中的一个性能瓶颈(Redis 的瓶颈主要受限于内存和网络)。 @@ -491,7 +459,7 @@ io-threads 4 #官网建议4核的机器建议设置为2或3个线程,8核的 1. [Redis 6.0 新特性-多线程连环 13 问!](https://mp.weixin.qq.com/s/FZu3acwK6zrCBZQ_3HoUgw) 2. [为什么 Redis 选择单线程模型](https://draveness.me/whys-the-design-redis-single-thread/) -### 10. Redis 给缓存数据设置过期时间有啥用? +### Redis 给缓存数据设置过期时间有啥用? 一般情况下,我们设置保存的缓存数据的时候都会设置一个过期时间。为什么呢? @@ -516,7 +484,7 @@ OK 如果使用传统的数据库来处理的话,一般都是自己判断过期,这样更麻烦并且性能要差很多。 -### 11. Redis 是如何判断数据是否过期的呢? +### Redis 是如何判断数据是否过期的呢? Redis 通过一个叫做过期字典(可以看作是 hash 表)来保存数据过期的时间。过期字典的键指向 Redis 数据库中的某个 key(键),过期字典的值是一个 long long 类型的整数,这个整数保存了 key 所指向的数据库键的过期时间(毫秒精度的 UNIX 时间戳)。 @@ -534,7 +502,7 @@ typedef struct redisDb { } redisDb; ``` -### 12. 过期的数据的删除策略了解么? +### 过期的数据的删除策略了解么? 如果假设你设置了一批 key 只能存活 1 分钟,那么 1 分钟后,Redis 是怎么对这批 key 进行删除的呢? @@ -549,7 +517,7 @@ typedef struct redisDb { 怎么解决这个问题呢?答案就是:**Redis 内存淘汰机制。** -### 13. Redis 内存淘汰机制了解么? +### Redis 内存淘汰机制了解么? > 相关问题:MySQL 里有 2000w 数据,Redis 中只存 20w 的数据,如何保证 Redis 中的数据都是热点数据? @@ -567,7 +535,7 @@ Redis 提供 6 种数据淘汰策略: 7. **volatile-lfu(least frequently used)**:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰 8. **allkeys-lfu(least frequently used)**:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key -### 14. Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复) +### Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复) 很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置。 @@ -629,7 +597,7 @@ AOF 重写是一个有歧义的名字,该功能是通过读取数据库中的 在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧两个 AOF 文件所保存的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。 -### 15. Redis 事务 +### Redis 事务 Redis 可以通过 **`MULTI`,`EXEC`,`DISCARD` 和 `WATCH`** 等命令来实现事务(transaction)功能。 @@ -704,19 +672,19 @@ Redis 官网也解释了自己为啥不支持回滚。简单来说就是 Redis - [issue452: 关于 Redis 事务不满足原子性的问题](https://github.com/Snailclimb/JavaGuide/issues/452) 。 - [Issue491:关于 redis 没有事务回滚?](https://github.com/Snailclimb/JavaGuide/issues/491) -### 16. 缓存穿透 +### 缓存穿透 -#### 16.1. 什么是缓存穿透? +#### 什么是缓存穿透? 缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的 key 发起大量请求,导致大量请求落到数据库。 -#### 16.2. 缓存穿透情况的处理流程是怎样的? +#### 缓存穿透情况的处理流程是怎样的? 如下图所示,用户的请求最终都要跑到数据库中查询一遍。 ![缓存穿透情况](./images/redis-all/缓存穿透情况.png) -#### 16.3. 有哪些解决办法? +#### 有哪些解决办法? 最基本的就是首先做好参数校验,一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。 @@ -777,9 +745,9 @@ _为什么会出现误判的情况呢? 我们还要从布隆过滤器的原理 更多关于布隆过滤器的内容可以看我的这篇原创:[《不了解布隆过滤器?一文给你整的明明白白!》](https://github.com/Snailclimb/JavaGuide/blob/master/docs/dataStructures-algorithms/data-structure/bloom-filter.md) ,强烈推荐,个人感觉网上应该找不到总结的这么明明白白的文章了。 -### 17. 缓存雪崩 +### 缓存雪崩 -#### 17.1. 什么是缓存雪崩? +#### 什么是缓存雪崩? 我发现缓存雪崩这名字起的有点意思,哈哈。 @@ -791,7 +759,7 @@ _为什么会出现误判的情况呢? 我们还要从布隆过滤器的原理 举个例子 :秒杀开始 12 个小时之前,我们统一存放了一批商品到 Redis 中,设置的缓存过期时间也是 12 个小时,那么秒杀开始的时候,这些秒杀的商品的访问直接就失效了。导致的情况就是,相应的请求直接就落到了数据库上,就像雪崩一样可怕。 -#### 17.2. 有哪些解决办法? +#### 有哪些解决办法? **针对 Redis 服务不可用的情况:** @@ -803,7 +771,7 @@ _为什么会出现误判的情况呢? 我们还要从布隆过滤器的原理 1. 设置不同的失效时间比如随机设置缓存的失效时间。 2. 缓存永不失效。 -### 18. 如何保证缓存和数据库数据的一致性? +### 如何保证缓存和数据库数据的一致性? 细说的话可以扯很多,但是我觉得其实没太大必要(小声 BB:很多解决方案我也没太弄明白)。我个人觉得引入缓存之后,如果为了短时间的不一致性问题,选择让系统设计变得更加复杂的话,完全没必要。 @@ -816,20 +784,10 @@ Cache Aside Pattern 中遇到写请求是这样的:更新 DB,然后直接删 1. **缓存失效时间变短(不推荐,治标不治本)** :我们让缓存数据的过期时间变短,这样的话缓存就会从数据库中加载数据。另外,这种解决办法对于先操作缓存后操作数据库的场景不适用。 2. **增加 cache 更新重试机制(常用)**: 如果 cache 服务当前不可用导致缓存删除失败的话,我们就隔一段时间进行重试,重试次数可以自己定。如果多次重试还是失败的话,我们可以把当前更新失败的 key 存入队列中,等缓存服务可用之后,再将缓存中对应的 key 删除即可。 -### 19. 参考 +### 参考 - 《Redis 开发与运维》 - 《Redis 设计与实现》 - Redis 命令总结:http://Redisdoc.com/string/set.html - 通俗易懂的 Redis 数据结构基础教程:[https://juejin.im/post/5b53ee7e5188251aaa2d2e16](https://juejin.im/post/5b53ee7e5188251aaa2d2e16) - WHY Redis choose single thread (vs multi threads): [https://medium.com/@jychen7/sharing-redis-single-thread-vs-multi-threads-5870bd44d153](https://medium.com/@jychen7/sharing-redis-single-thread-vs-multi-threads-5870bd44d153) - -### 20. 公众号 - -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 - -**《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java 面试突击"** 即可免费领取! - -**Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 - -![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) \ No newline at end of file From 2e813341619f8d92eaae850f78005a63b9629f80 Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 14 Aug 2021 10:05:36 +0800 Subject: [PATCH 162/257] =?UTF-8?q?Update=20=E4=B8=87=E5=AD=97=E8=AF=A6?= =?UTF-8?q?=E8=A7=A3ThreadLocal=E5=85=B3=E9=94=AE=E5=AD=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../万字详解ThreadLocal关键字.md | 124 ++++++++---------- 1 file changed, 58 insertions(+), 66 deletions(-) diff --git a/docs/java/multi-thread/万字详解ThreadLocal关键字.md b/docs/java/multi-thread/万字详解ThreadLocal关键字.md index 3650ddbb..a7c79807 100644 --- a/docs/java/multi-thread/万字详解ThreadLocal关键字.md +++ b/docs/java/multi-thread/万字详解ThreadLocal关键字.md @@ -1,19 +1,19 @@ -> 本文来自一枝花算不算浪漫投稿, 原文地址:[https://juejin.im/post/5eacc1c75188256d976df748](https://juejin.im/post/5eacc1c75188256d976df748)。 +> 本文来自一枝花算不算浪漫投稿, 原文地址:[https://juejin.im/post/5eacc1c75188256d976df748](https://juejin.im/post/5eacc1c75188256d976df748)。 ### 前言 ![](./images/thread-local/1.png) -**全文共10000+字,31张图,这篇文章同样耗费了不少的时间和精力才创作完成,原创不易,请大家点点关注+在看,感谢。** +**全文共 10000+字,31 张图,这篇文章同样耗费了不少的时间和精力才创作完成,原创不易,请大家点点关注+在看,感谢。** 对于`ThreadLocal`,大家的第一反应可能是很简单呀,线程的变量副本,每个线程隔离。那这里有几个问题大家可以思考一下: -- `ThreadLocal`的key是**弱引用**,那么在 `ThreadLocal`.get()的时候,发生**GC**之后,key是否为**null**? +- `ThreadLocal`的 key 是**弱引用**,那么在 `ThreadLocal`.get()的时候,发生**GC**之后,key 是否为**null**? - `ThreadLocal`中`ThreadLocalMap`的**数据结构**? -- `ThreadLocalMap`的**Hash算法**? -- `ThreadLocalMap`中**Hash冲突**如何解决? +- `ThreadLocalMap`的**Hash 算法**? +- `ThreadLocalMap`中**Hash 冲突**如何解决? - `ThreadLocalMap`的**扩容机制**? -- `ThreadLocalMap`中**过期key的清理机制**?**探测式清理**和**启发式清理**流程? +- `ThreadLocalMap`中**过期 key 的清理机制**?**探测式清理**和**启发式清理**流程? - `ThreadLocalMap.set()`方法实现原理? - `ThreadLocalMap.get()`方法实现原理? - 项目中`ThreadLocal`使用情况?遇到的坑? @@ -23,8 +23,6 @@ ### 目录 - - **注明:** 本文源码基于`JDK 1.8` ### `ThreadLocal`代码演示 @@ -80,19 +78,18 @@ size: 0 我们还要注意`Entry`, 它的`key`是`ThreadLocal k` ,继承自`WeakReference`, 也就是我们常说的弱引用类型。 -### GC 之后key是否为null? +### GC 之后 key 是否为 null? 回应开头的那个问题, `ThreadLocal` 的`key`是弱引用,那么在`ThreadLocal.get()`的时候,发生`GC`之后,`key`是否是`null`? 为了搞清楚这个问题,我们需要搞清楚`Java`的**四种引用类型**: -- **强引用**:我们常常new出来的对象就是强引用类型,只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足的时候 -- **软引用**:使用SoftReference修饰的对象被称为软引用,软引用指向的对象在内存要溢出的时候被回收 -- **弱引用**:使用WeakReference修饰的对象被称为弱引用,只要发生垃圾回收,若这个对象只被弱引用指向,那么就会被回收 +- **强引用**:我们常常 new 出来的对象就是强引用类型,只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足的时候 +- **软引用**:使用 SoftReference 修饰的对象被称为软引用,软引用指向的对象在内存要溢出的时候被回收 +- **弱引用**:使用 WeakReference 修饰的对象被称为弱引用,只要发生垃圾回收,若这个对象只被弱引用指向,那么就会被回收 - **虚引用**:虚引用是最弱的引用,在 Java 中使用 PhantomReference 进行定义。虚引用中唯一的作用就是用队列接收对象即将死亡的通知 - -接着再来看下代码,我们使用反射的方式来看看`GC`后`ThreadLocal`中的数据情况:(下面代码来源自:https://blog.csdn.net/thewindkee/article/details/103726942 本地运行演示GC回收场景) +接着再来看下代码,我们使用反射的方式来看看`GC`后`ThreadLocal`中的数据情况:(下面代码来源自:https://blog.csdn.net/thewindkee/article/details/103726942 本地运行演示 GC 回收场景) ```java public class ThreadLocalDemo { @@ -140,6 +137,7 @@ public class ThreadLocalDemo { ``` 结果如下: + ```java 弱引用key:java.lang.ThreadLocal@433619b6,值:abc 弱引用key:java.lang.ThreadLocal@418a15e3,值:java.lang.ref.SoftReference@bf97a12 @@ -192,7 +190,7 @@ void createMap(Thread t, T firstValue) { 主要的核心逻辑还是在`ThreadLocalMap`中的,一步步往下看,后面还有更详细的剖析。 -### `ThreadLocalMap` Hash算法 +### `ThreadLocalMap` Hash 算法 既然是`Map`结构,那么`ThreadLocalMap`当然也要实现自己的`hash`算法来解决散列表数组冲突问题。 @@ -200,7 +198,7 @@ void createMap(Thread t, T firstValue) { int i = key.threadLocalHashCode & (len-1); ``` -`ThreadLocalMap`中`hash`算法很简单,这里`i`就是当前key在散列表中对应的数组下标位置。 +`ThreadLocalMap`中`hash`算法很简单,这里`i`就是当前 key 在散列表中对应的数组下标位置。 这里最关键的就是`threadLocalHashCode`值的计算,`ThreadLocal`中有一个属性为`HASH_INCREMENT = 0x61c88647` @@ -215,7 +213,7 @@ public class ThreadLocal { private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT); } - + static class ThreadLocalMap { ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { table = new Entry[INITIAL_CAPACITY]; @@ -231,7 +229,7 @@ public class ThreadLocal { 每当创建一个`ThreadLocal`对象,这个`ThreadLocal.nextHashCode` 这个值就会增长 `0x61c88647` 。 -这个值很特殊,它是**斐波那契数** 也叫 **黄金分割数**。`hash`增量为 这个数字,带来的好处就是 `hash` **分布非常均匀**。 +这个值很特殊,它是**斐波那契数** 也叫 **黄金分割数**。`hash`增量为 这个数字,带来的好处就是 `hash` **分布非常均匀**。 我们自己可以尝试下: @@ -239,7 +237,7 @@ public class ThreadLocal { 可以看到产生的哈希码分布很均匀,这里不去细纠**斐波那契**具体算法,感兴趣的可以自行查阅相关资料。 -### `ThreadLocalMap` Hash冲突 +### `ThreadLocalMap` Hash 冲突 > **注明:** 下面所有示例图中,**绿色块**`Entry`代表**正常数据**,**灰色块**代表`Entry`的`key`值为`null`,**已被垃圾回收**。**白色块**表示`Entry`为`null`。 @@ -247,22 +245,21 @@ public class ThreadLocal { `HashMap`中解决冲突的方法是在数组上构造一个**链表**结构,冲突的数据挂载到链表上,如果链表长度超过一定数量则会转化成**红黑树**。 -而`ThreadLocalMap`中并没有链表结构,所以这里不能适用`HashMap`解决冲突的方式了。 +而 `ThreadLocalMap` 中并没有链表结构,所以这里不能使用 `HashMap` 解决冲突的方式了。 ![](./images/thread-local/7.png) +如上图所示,如果我们插入一个`value=27`的数据,通过 `hash` 计算后应该落入第 4 个槽位中,而槽位 4 已经有了 `Entry` 数据。 -如上图所示,如果我们插入一个`value=27`的数据,通过`hash`计算后应该落入第4个槽位中,而槽位4已经有了`Entry`数据。 +此时就会线性向后查找,一直找到 `Entry` 为 `null` 的槽位才会停止查找,将当前元素放入此槽位中。当然迭代过程中还有其他的情况,比如遇到了 `Entry` 不为 `null` 且 `key` 值相等的情况,还有 `Entry` 中的 `key` 值为 `null` 的情况等等都会有不同的处理,后面会一一详细讲解。 -此时就会线性向后查找,一直找到`Entry`为`null`的槽位才会停止查找,将当前元素放入此槽位中。当然迭代过程中还有其他的情况,比如遇到了`Entry`不为`null`且`key`值相等的情况,还有`Entry`中的`key`值为`null`的情况等等都会有不同的处理,后面会一一详细讲解。 - -这里还画了一个`Entry`中的`key`为`null`的数据(**Entry=2的灰色块数据**),因为`key`值是**弱引用**类型,所以会有这种数据存在。在`set`过程中,如果遇到了`key`过期的`Entry`数据,实际上是会进行一轮**探测式清理**操作的,具体操作方式后面会讲到。 +这里还画了一个`Entry`中的`key`为`null`的数据(**Entry=2 的灰色块数据**),因为`key`值是**弱引用**类型,所以会有这种数据存在。在`set`过程中,如果遇到了`key`过期的`Entry`数据,实际上是会进行一轮**探测式清理**操作的,具体操作方式后面会讲到。 ### `ThreadLocalMap.set()`详解 #### `ThreadLocalMap.set()`原理图解 -看完了`ThreadLocal` **hash算法**后,我们再来看`set`是如何实现的。 +看完了`ThreadLocal` **hash 算法**后,我们再来看`set`是如何实现的。 往`ThreadLocalMap`中`set`数据(**新增**或者**更新**数据)分为好几种情况,针对不同的情况我们画图来说说明。 @@ -282,36 +279,33 @@ public class ThreadLocal { ![](./images/thread-local/11.png) -遍历散列数组,线性往后查找,如果找到`Entry`为`null`的槽位,则将数据放入该槽位中,或者往后遍历过程中,遇到了**key值相等**的数据,直接更新即可。 +遍历散列数组,线性往后查找,如果找到`Entry`为`null`的槽位,则将数据放入该槽位中,或者往后遍历过程中,遇到了**key 值相等**的数据,直接更新即可。 **第四种情况:** 槽位数据不为空,往后遍历过程中,在找到`Entry`为`null`的槽位之前,遇到`key`过期的`Entry`,如下图,往后遍历过程中,一到了`index=7`的槽位数据`Entry`的`key=null`: ![](./images/thread-local/12.png) -散列数组下标为7位置对应的`Entry`数据`key`为`null`,表明此数据`key`值已经被垃圾回收掉了,此时就会执行`replaceStaleEntry()`方法,该方法含义是**替换过期数据的逻辑**,以**index=7**位起点开始遍历,进行探测式数据清理工作。 +散列数组下标为 7 位置对应的`Entry`数据`key`为`null`,表明此数据`key`值已经被垃圾回收掉了,此时就会执行`replaceStaleEntry()`方法,该方法含义是**替换过期数据的逻辑**,以**index=7**位起点开始遍历,进行探测式数据清理工作。 初始化探测式清理过期数据扫描的开始位置:`slotToExpunge = staleSlot = 7` 以当前`staleSlot`开始 向前迭代查找,找其他过期的数据,然后更新过期数据起始扫描下标`slotToExpunge`。`for`循环迭代,直到碰到`Entry`为`null`结束。 -如果找到了过期的数据,继续向前迭代,直到遇到`Entry=null`的槽位才停止迭代,如下图所示,**slotToExpunge被更新为0**: +如果找到了过期的数据,继续向前迭代,直到遇到`Entry=null`的槽位才停止迭代,如下图所示,**slotToExpunge 被更新为 0**: ![](./images/thread-local/13.png) -以当前节点(`index=7`)向前迭代,检测是否有过期的`Entry`数据,如果有则更新`slotToExpunge`值。碰到`null`则结束探测。以上图为例`slotToExpunge`被更新为0。 +以当前节点(`index=7`)向前迭代,检测是否有过期的`Entry`数据,如果有则更新`slotToExpunge`值。碰到`null`则结束探测。以上图为例`slotToExpunge`被更新为 0。 上面向前迭代的操作是为了更新探测清理过期数据的起始下标`slotToExpunge`的值,这个值在后面会讲解,它是用来判断当前过期槽位`staleSlot`之前是否还有过期元素。 -接着开始以`staleSlot`位置(index=7)向后迭代,**如果找到了相同key值的Entry数据:** +接着开始以`staleSlot`位置(index=7)向后迭代,**如果找到了相同 key 值的 Entry 数据:** ![](./images/thread-local/14.png) 从当前节点`staleSlot`向后查找`key`值相等的`Entry`元素,找到后更新`Entry`的值并交换`staleSlot`元素的位置(`staleSlot`位置为过期元素),更新`Entry`数据,然后开始进行过期`Entry`的清理工作,如下图所示: -![Yu4oWT.png](https://user-gold-cdn.xitu.io/2020/5/8/171f3ba9af057e1e?w=1336&h=361&f=png&s=63049) - - -**向后遍历过程中,如果没有找到相同key值的Entry数据:** +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/view.png)向后遍历过程中,如果没有找到相同 key 值的 Entry 数据: ![](./images/thread-local/15.png) @@ -367,6 +361,7 @@ int i = key.threadLocalHashCode & (len-1); ``` 什么情况下桶才是可以使用的呢? + 1. `k = key` 说明是替换操作,可以使用 2. 碰到一个过期的桶,执行替换逻辑,占用过期桶 3. 查找过程中,碰到桶中`Entry=null`的情况,直接使用 @@ -386,16 +381,17 @@ private static int prevIndex(int i, int len) { ``` 接着看剩下`for`循环中的逻辑: + 1. 遍历当前`key`值对应的桶中`Entry`数据为空,这说明散列数组这里没有数据冲突,跳出`for`循环,直接`set`数据到对应的桶中 2. 如果`key`值对应的桶中`Entry`数据不为空 -2.1 如果`k = key`,说明当前`set`操作是一个替换操作,做替换逻辑,直接返回 -2.2 如果`key = null`,说明当前桶位置的`Entry`是过期数据,执行`replaceStaleEntry()`方法(核心方法),然后返回 + 2.1 如果`k = key`,说明当前`set`操作是一个替换操作,做替换逻辑,直接返回 + 2.2 如果`key = null`,说明当前桶位置的`Entry`是过期数据,执行`replaceStaleEntry()`方法(核心方法),然后返回 3. `for`循环执行完毕,继续往下执行说明向后迭代的过程中遇到了`entry`为`null`的情况 -3.1 在`Entry`为`null`的桶中创建一个新的`Entry`对象 -3.2 执行`++size`操作 + 3.1 在`Entry`为`null`的桶中创建一个新的`Entry`对象 + 3.2 执行`++size`操作 4. 调用`cleanSomeSlots()`做一次启发式清理工作,清理散列数组中`Entry`的`key`过期的数据 -4.1 如果清理工作完成后,未清理到任何数据,且`size`超过了阈值(数组长度的2/3),进行`rehash()`操作 -4.2 `rehash()`中会先进行一轮探测式清理,清理过期`key`,清理完成后如果**size >= threshold - threshold / 4**,就会执行真正的扩容逻辑(扩容逻辑往后看) + 4.1 如果清理工作完成后,未清理到任何数据,且`size`超过了阈值(数组长度的 2/3),进行`rehash()`操作 + 4.2 `rehash()`中会先进行一轮探测式清理,清理过期`key`,清理完成后如果**size >= threshold - threshold / 4**,就会执行真正的扩容逻辑(扩容逻辑往后看) 接着重点看下`replaceStaleEntry()`方法,`replaceStaleEntry()`方法提供替换过期数据的功能,我们可以对应上面**第四种情况**的原理图来再回顾下,具体代码如下: @@ -446,7 +442,7 @@ private void replaceStaleEntry(ThreadLocal key, Object value, } ``` -`slotToExpunge`表示开始探测式清理过期数据的开始下标,默认从当前的`staleSlot`开始。以当前的`staleSlot`开始,向前迭代查找,找到没有过期的数据,`for`循环一直碰到`Entry`为`null`才会结束。如果向前找到了过期数据,更新探测清理过期数据的开始下标为i,即`slotToExpunge=i` +`slotToExpunge`表示开始探测式清理过期数据的开始下标,默认从当前的`staleSlot`开始。以当前的`staleSlot`开始,向前迭代查找,找到没有过期的数据,`for`循环一直碰到`Entry`为`null`才会结束。如果向前找到了过期数据,更新探测清理过期数据的开始下标为 i,即`slotToExpunge=i` ```java for (int i = prevIndex(staleSlot, len); @@ -460,7 +456,7 @@ for (int i = prevIndex(staleSlot, len); ``` 接着开始从`staleSlot`向后查找,也是碰到`Entry`为`null`的桶结束。 -如果迭代过程中,**碰到k == key**,这说明这里是替换逻辑,替换新数据并且交换当前`staleSlot`位置。如果`slotToExpunge == staleSlot`,这说明`replaceStaleEntry()`一开始向前查找过期数据时并未找到过期的`Entry`数据,接着向后查找过程中也未发现过期数据,修改开始探测式清理过期数据的下标为当前循环的index,即`slotToExpunge = i`。最后调用`cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);`进行启发式过期数据清理。 +如果迭代过程中,**碰到 k == key**,这说明这里是替换逻辑,替换新数据并且交换当前`staleSlot`位置。如果`slotToExpunge == staleSlot`,这说明`replaceStaleEntry()`一开始向前查找过期数据时并未找到过期的`Entry`数据,接着向后查找过程中也未发现过期数据,修改开始探测式清理过期数据的下标为当前循环的 index,即`slotToExpunge = i`。最后调用`cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);`进行启发式过期数据清理。 ```java if (k == key) { @@ -468,7 +464,7 @@ if (k == key) { tab[i] = tab[staleSlot]; tab[staleSlot] = e; - + if (slotToExpunge == staleSlot) slotToExpunge = i; @@ -479,7 +475,7 @@ if (k == key) { `cleanSomeSlots()`和`expungeStaleEntry()`方法后面都会细讲,这两个是和清理相关的方法,一个是过期`key`相关`Entry`的启发式清理(`Heuristically scan`),另一个是过期`key`相关`Entry`的探测式清理。 -**如果k != key**则会接着往下走,`k == null`说明当前遍历的`Entry`是一个过期数据,`slotToExpunge == staleSlot`说明,一开始的向前查找数据并未找到过期的`Entry`。如果条件成立,则更新`slotToExpunge` 为当前位置,这个前提是前驱节点扫描时未发现过期数据。 +**如果 k != key**则会接着往下走,`k == null`说明当前遍历的`Entry`是一个过期数据,`slotToExpunge == staleSlot`说明,一开始的向前查找数据并未找到过期的`Entry`。如果条件成立,则更新`slotToExpunge` 为当前位置,这个前提是前驱节点扫描时未发现过期数据。 ```java if (k == null && slotToExpunge == staleSlot) @@ -494,12 +490,13 @@ tab[staleSlot] = new Entry(key, value); ``` 最后判断除了`staleSlot`以外,还发现了其他过期的`slot`数据,就要开启清理数据的逻辑: + ```java if (slotToExpunge != staleSlot) cleanSomeSlots(expungeStaleEntry(slotToExpunge), len); ``` -### `ThreadLocalMap`过期key的探测式清理流程 +### `ThreadLocalMap`过期 key 的探测式清理流程 上面我们有提及`ThreadLocalMap`的两种过期`key`数据清理方式:**探测式清理**和**启发式清理**。 @@ -507,7 +504,7 @@ if (slotToExpunge != staleSlot) ![](./images/thread-local/18.png) -如上图,`set(27)` 经过hash计算后应该落到`index=4`的桶中,由于`index=4`桶已经有了数据,所以往后迭代最终数据放入到`index=7`的桶中,放入后一段时间后`index=5`中的`Entry`数据`key`变为了`null` +如上图,`set(27)` 经过 hash 计算后应该落到`index=4`的桶中,由于`index=4`桶已经有了数据,所以往后迭代最终数据放入到`index=7`的桶中,放入后一段时间后`index=5`中的`Entry`数据`key`变为了`null` ![](./images/thread-local/19.png) @@ -529,7 +526,7 @@ if (slotToExpunge != staleSlot) ![](./images/thread-local/22.png) -执行完第二步后,index=4的元素挪到index=3的槽位中。 +执行完第二步后,index=4 的元素挪到 index=3 的槽位中。 继续往后迭代检查,碰到正常数据,计算该数据位置是否偏移,如果被偏移,则重新计算`slot`位置,目的是让正常数据尽可能存放在正确位置或离正确位置更近的位置 @@ -581,7 +578,7 @@ if (k == null) { e.value = null; tab[i] = null; size--; -} +} ``` 如果`key`没有过期,重新计算当前`key`的下标位置是不是当前槽位下标位置,如果不是,那么说明产生了`hash`冲突,此时以新计算出来正确的槽位位置往后迭代,找到最近一个可以存放`entry`的位置。 @@ -686,7 +683,7 @@ private void resize() { ![](./images/thread-local/27.png) -我们以`get(ThreadLocal1)`为例,通过`hash`计算后,正确的`slot`位置应该是4,而`index=4`的槽位已经有了数据,且`key`值不等于`ThreadLocal1`,所以需要继续往后迭代查找。 +我们以`get(ThreadLocal1)`为例,通过`hash`计算后,正确的`slot`位置应该是 4,而`index=4`的槽位已经有了数据,且`key`值不等于`ThreadLocal1`,所以需要继续往后迭代查找。 迭代到`index=5`的数据时,此时`Entry.key=null`,触发一次探测式数据回收操作,执行`expungeStaleEntry()`方法,执行完后,`index 5,8`的数据都会被回收,而`index 6,7`的数据都会前移,此时继续往后迭代,到`index = 6`的时候即找到了`key`值相等的`Entry`数据,如下图所示: @@ -724,9 +721,7 @@ private Entry getEntryAfterMiss(ThreadLocal key, int i, Entry e) { } ``` - -### `ThreadLocalMap`过期key的启发式清理流程 - +### `ThreadLocalMap`过期 key 的启发式清理流程 上面多次提及到`ThreadLocalMap`过期可以的两种清理方式:**探测式清理(expungeStaleEntry())**、**启发式清理(cleanSomeSlots())** @@ -760,7 +755,7 @@ private boolean cleanSomeSlots(int i, int n) { 我们使用`ThreadLocal`的时候,在异步场景下是无法给子线程共享父线程中创建的线程副本数据的。 -为了解决这个问题,JDK中还有一个`InheritableThreadLocal`类,我们来看一个例子: +为了解决这个问题,JDK 中还有一个`InheritableThreadLocal`类,我们来看一个例子: ```java public class InheritableThreadLocalDemo { @@ -816,11 +811,11 @@ private void init(ThreadGroup g, Runnable target, String name, 我们现在项目中日志记录用的是`ELK+Logstash`,最后在`Kibana`中进行展示和检索。 -现在都是分布式系统统一对外提供服务,项目间调用的关系可以通过traceId来关联,但是不同项目之间如何传递`traceId`呢? +现在都是分布式系统统一对外提供服务,项目间调用的关系可以通过 `traceId` 来关联,但是不同项目之间如何传递 `traceId` 呢? -这里我们使用`org.slf4j.MDC`来实现此功能,内部就是通过`ThreadLocal`来实现的,具体实现如下: +这里我们使用 `org.slf4j.MDC` 来实现此功能,内部就是通过 `ThreadLocal` 来实现的,具体实现如下: -当前端发送请求到**服务A**时,**服务A**会生成一个类似`UUID`的`traceId`字符串,将此字符串放入当前线程的`ThreadLocal`中,在调用**服务B**的时候,将`traceId`写入到请求的`Header`中,**服务B**在接收请求时会先判断请求的`Header`中是否有`traceId`,如果存在则写入自己线程的`ThreadLocal`中。 +当前端发送请求到**服务 A**时,**服务 A**会生成一个类似`UUID`的`traceId`字符串,将此字符串放入当前线程的`ThreadLocal`中,在调用**服务 B**的时候,将`traceId`写入到请求的`Header`中,**服务 B**在接收请求时会先判断请求的`Header`中是否有`traceId`,如果存在则写入自己线程的`ThreadLocal`中。 ![](./images/thread-local/30.png) @@ -830,9 +825,10 @@ private void init(ThreadGroup g, Runnable target, String name, 针对于这些场景,我们都可以有相应的解决方案,如下所示 -#### Feign远程调用解决方案 +#### Feign 远程调用解决方案 **服务发送请求:** + ```java @Component @Slf4j @@ -849,6 +845,7 @@ public class FeignInvokeInterceptor implements RequestInterceptor { ``` **服务接收请求:** + ```java @Slf4j @Component @@ -876,13 +873,13 @@ public class LogInterceptor extends HandlerInterceptorAdapter { } ``` -#### 线程池异步调用,requestId传递 +#### 线程池异步调用,requestId 传递 因为`MDC`是基于`ThreadLocal`去实现的,异步过程中,子线程并没有办法获取到父线程`ThreadLocal`存储的数据,所以这里可以自定义线程池执行器,修改其中的`run()`方法: ```java public class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { - + @Override public void execute(Runnable runnable) { Map context = MDC.getCopyOfContextMap(); @@ -903,11 +900,6 @@ public class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { } ``` -#### 使用MQ发送消息给第三方系统 - -在MQ发送的消息体中自定义属性`requestId`,接收方消费消息后,自己解析`requestId`使用即可。 - - - - +#### 使用 MQ 发送消息给第三方系统 +在 MQ 发送的消息体中自定义属性`requestId`,接收方消费消息后,自己解析`requestId`使用即可。 From cfa58e4f68412ea48feef6bb3993fea00234e2b4 Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sat, 14 Aug 2021 17:53:39 +0800 Subject: [PATCH 163/257] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?.md=20-=20add=20chapter=20Queue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java集合框架常见面试题.md | 95 +++++++++++++++---- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index e604f819..c960924e 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -310,9 +310,66 @@ Output: `TreeSet` 底层使用红黑树,能够按照添加元素的顺序进行遍历,排序的方式有自然排序和定制排序。 -## 1.4. Map 接口 +## 1.4 Collection 子接口之 Queue -### 1.4.1. HashMap 和 Hashtable 的区别 +### 1.4.1 Queue 与 Deque 的区别 + +`Queue` 是单端队列,只能从一端插入元素,另一端删除元素,实现上一般遵循 **先进先出(FIFO)** 规则。 + +`Queue` 扩展了 `Collection` 的接口,根据 **因为容量问题而导致操作失败后处理方式的不同** 可以分为两类方法: 一种在操作失败后会抛出异常,另一种则会返回特殊值。 + +| `Queue` 接口| 抛出异常 | 返回特殊值 | +| ------------ | --------- | ---------- | +| 插入队尾 | add(E e) | offer(E e) | +| 删除队首 | remove() | poll() | +| 查询队首元素 | element() | peek() | + +`Deque` 是双端队列,在队列的两端均可以插入或删除元素。 + +`Deque` 扩展了 `Queue` 的接口, 增加了在队首和队尾进行插入和删除的方法,同样根据失败后处理方式的不同分为两类: + +| `Deque`接口 | 抛出异常 | 返回特殊值 | +| ------------ | ------------- | --------------- | +| 插入队首 | addFirst(E e) | offerFirst(E e) | +| 插入队尾 | addLast(E e) | offerLast(E e) | +| 删除队首 | removeFirst() | pollFirst() | +| 删除队尾 | removeLast() | pollLast() | +| 查询队首元素 | getFirst() | peekFirst() | +| 查询队尾元素 | getLast() | peekLast() | + +事实上,`Deque` 还提供有 `push()` 和 `pop()` 等其他方法,用于模拟栈。 + + +### 1.4.2 ArrayDeque 与 LinkedList 的区别 + +`ArrayDeque` 和 `LinkedList` 都实现了`Deque`接口,两者都具有队列的功能,但两者有什么区别呢? + +- `ArrayDeque` 是基于可变长的数组和双指针来实现,而 `LinkedList` 则通过链表来实现。 + +- `ArrayDeque` 不支持存储 `NULL` 数据,但 `LinkedList` 支持。 + +- `ArrayDeque` 是在 JDK1.6 才被引入的,而`LinkedList` 早在 JDK1.2 时就已经存在。 + +- `ArrayDeque` 插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。虽然 `LinkedList` 不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。 + +从性能的角度上,选用 `ArrayDeque` 去实现队列要比 `LinkedList` 更好。此外,`ArrayDeque` 也可以用于实现栈。 + +### 1.4.3 说一说 PriorityQueue + +`PriorityQueue` 是在 JDK1.5 中被引入的, 其与 `Queue` 的区别在于元素出队顺序是与优先级相关的,即总是优先级最高的元素先出队。 + +这里列举其相关的一些要点: + +- `PriorityQueue` 利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据 +- `PriorityQueue` 通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。 +- `PriorityQueue` 是非线程安全的,且不支持存储 `NULL` 和 `non-comparable` 的对象。 +- `PriorityQueue` 默认是小顶堆,可以接收一个`Comparator`作为构造参数来比较队列中元素的优先级。 + +`PriorityQueue` 在面试中可能更多的会出现在手撕算法的时候,典型例题包括堆排序、求第K大的数、带权图的遍历等,所以需要学会熟练使用才行。 + +## 1.5. Map 接口 + +### 1.5.1. HashMap 和 Hashtable 的区别 1. **线程是否安全:** `HashMap` 是非线程安全的,`HashTable` 是线程安全的,因为 `HashTable` 内部的方法基本都经过`synchronized` 修饰。(如果你要保证线程安全的话就使用 `ConcurrentHashMap` 吧!); 2. **效率:** 因为线程安全的问题,`HashMap` 要比 `HashTable` 效率高一点。另外,`HashTable` 基本被淘汰,不要在代码中使用它; @@ -357,7 +414,7 @@ Output: } ``` -### 1.4.2. HashMap 和 HashSet 区别 +### 1.5.2. HashMap 和 HashSet 区别 如果你看过 `HashSet` 源码的话就应该知道:`HashSet` 底层就是基于 `HashMap` 实现的。(`HashSet` 的源码非常非常少,因为除了 `clone()`、`writeObject()`、`readObject()`是 `HashSet` 自己不得不实现之外,其他方法都是直接调用 `HashMap` 中的方法。 @@ -368,7 +425,7 @@ Output: | 调用 `put()`向 map 中添加元素 | 调用 `add()`方法向 `Set` 中添加元素 | | `HashMap` 使用键(Key)计算 `hashcode` | `HashSet` 使用成员对象来计算 `hashcode` 值,对于两个对象来说 `hashcode` 可能相同,所以`equals()`方法用来判断对象的相等性 | -### 1.4.3. HashMap 和 TreeMap 区别 +### 1.5.3. HashMap 和 TreeMap 区别 `TreeMap` 和`HashMap` 都继承自`AbstractMap` ,但是需要注意的是`TreeMap`它还实现了`NavigableMap`接口和`SortedMap` 接口。 @@ -436,7 +493,7 @@ TreeMap treeMap = new TreeMap<>((person1, person2) -> { **综上,相比于`HashMap`来说 `TreeMap` 主要多了对集合中的元素根据键排序的能力以及对集合内元素的搜索的能力。** -### 1.4.4. HashSet 如何检查重复 +### 1.5.4. HashSet 如何检查重复 以下内容摘自我的 Java 启蒙书《Head first java》第二版: @@ -479,9 +536,9 @@ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, 对于引用类型(包括包装类型)来说,equals 如果没有被重写,对比它们的地址是否相等;如果 equals()方法被重写(例如 String),则比较的是地址里的内容。 -### 1.4.5. HashMap 的底层实现 +### 1.5.5. HashMap 的底层实现 -#### 1.4.5.1. JDK1.8 之前 +#### 1.5.5.1. JDK1.8 之前 JDK1.8 之前 `HashMap` 底层是 **数组和链表** 结合在一起使用也就是 **链表散列**。**HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。** @@ -520,7 +577,7 @@ static int hash(int h) { ![jdk1.8之前的内部结构-HashMap](images/jdk1.8之前的内部结构-HashMap.png) -#### 1.4.5.2. JDK1.8 之后 +#### 1.5.5.2. JDK1.8 之后 相比于之前的版本, JDK1.8 之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。 @@ -528,7 +585,7 @@ static int hash(int h) { > TreeMap、TreeSet 以及 JDK1.8 之后的 HashMap 底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 -### 1.4.6. HashMap 的长度为什么是 2 的幂次方 +### 1.5.6. HashMap 的长度为什么是 2 的幂次方 为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648 到 2147483647,前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个 40 亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“ `(n - 1) & hash`”。(n 代表数组长度)。这也就解释了 HashMap 的长度为什么是 2 的幂次方。 @@ -536,17 +593,17 @@ static int hash(int h) { 我们首先可能会想到采用%取余的操作来实现。但是,重点来了:**“取余(%)操作中如果除数是 2 的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是 2 的 n 次方;)。”** 并且 **采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是 2 的幂次方。** -### 1.4.7. HashMap 多线程操作导致死循环问题 +### 1.5.7. HashMap 多线程操作导致死循环问题 主要原因在于并发下的 Rehash 会造成元素之间会形成一个循环链表。不过,jdk 1.8 后解决了这个问题,但是还是不建议在多线程下使用 HashMap,因为多线程下使用 HashMap 还是会存在其他问题比如数据丢失。并发环境下推荐使用 ConcurrentHashMap 。 详情请查看: -### 1.4.8. HashMap 有哪几种常见的遍历方式? +### 1.5.8. HashMap 有哪几种常见的遍历方式? [HashMap 的 7 种遍历方式与性能分析!](https://mp.weixin.qq.com/s/zQBN3UvJDhRTKP6SzcZFKw) -### 1.4.9. ConcurrentHashMap 和 Hashtable 的区别 +### 1.5.9. ConcurrentHashMap 和 Hashtable 的区别 `ConcurrentHashMap` 和 `Hashtable` 的区别主要体现在实现线程安全的方式上不同。 @@ -573,9 +630,9 @@ static int hash(int h) { JDK1.8 的 `ConcurrentHashMap` 不在是 **Segment 数组 + HashEntry 数组 + 链表**,而是 **Node 数组 + 链表 / 红黑树**。不过,Node 只能用于链表的情况,红黑树的情况需要使用 **`TreeNode`**。当冲突链表达到一定长度时,链表会转换成红黑树。 -### 1.4.10. ConcurrentHashMap 线程安全的具体实现方式/底层具体实现 +### 1.5.10. ConcurrentHashMap 线程安全的具体实现方式/底层具体实现 -#### 1.4.10.1. JDK1.7(上面有示意图) +#### 1.5.10.1. JDK1.7(上面有示意图) 首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。 @@ -590,13 +647,13 @@ static class Segment extends ReentrantLock implements Serializable { 一个 `ConcurrentHashMap` 里包含一个 `Segment` 数组。`Segment` 的结构和 `HashMap` 类似,是一种数组和链表结构,一个 `Segment` 包含一个 `HashEntry` 数组,每个 `HashEntry` 是一个链表结构的元素,每个 `Segment` 守护着一个 `HashEntry` 数组里的元素,当对 `HashEntry` 数组的数据进行修改时,必须首先获得对应的 `Segment` 的锁。 -#### 1.4.10.2. JDK1.8 (上面有示意图) +#### 1.5.10.2. JDK1.8 (上面有示意图) `ConcurrentHashMap` 取消了 `Segment` 分段锁,采用 CAS 和 `synchronized` 来保证并发安全。数据结构跟 HashMap1.8 的结构类似,数组+链表/红黑二叉树。Java 8 在链表长度超过一定阈值(8)时将链表(寻址时间复杂度为 O(N))转换为红黑树(寻址时间复杂度为 O(log(N))) `synchronized` 只锁定当前链表或红黑二叉树的首节点,这样只要 hash 不冲突,就不会产生并发,效率又提升 N 倍。 -## 1.5. Collections 工具类 +## 1.6. Collections 工具类 Collections 工具类常用方法: @@ -604,7 +661,7 @@ Collections 工具类常用方法: 2. 查找,替换操作 3. 同步控制(不推荐,需要线程安全的集合类型时请考虑使用 JUC 包下的并发集合) -### 1.5.1. 排序操作 +### 1.6.1. 排序操作 ```java void reverse(List list)//反转 @@ -615,7 +672,7 @@ void swap(List list, int i , int j)//交换两个索引位置的元素 void rotate(List list, int distance)//旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面 ``` -### 1.5.2. 查找,替换操作 +### 1.6.2. 查找,替换操作 ```java int binarySearch(List list, Object key)//对List进行二分查找,返回索引,注意List必须是有序的 @@ -627,7 +684,7 @@ int indexOfSubList(List list, List target)//统计target在list中第一次出 boolean replaceAll(List list, Object oldVal, Object newVal)//用新元素替换旧元素 ``` -### 1.5.3. 同步控制 +### 1.6.3. 同步控制 `Collections` 提供了多个`synchronizedXxx()`方法·,该方法可以将指定集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题。 From 04e7b5892830c62582c9cb01e9909e6b507e8d1d Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sat, 14 Aug 2021 18:47:40 +0800 Subject: [PATCH 164/257] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java集合框架常见面试题.md | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index c960924e..67953e38 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -3,11 +3,12 @@ - [1. 剖析面试最常见问题之 Java 集合框架](#1-剖析面试最常见问题之-java-集合框架) - [1.1. 集合概述](#11-集合概述) - [1.1.1. Java 集合概览](#111-java-集合概览) - - [1.1.2. 说说 List,Set,Map 三者的区别?](#112-说说-listsetmap-三者的区别) + - [1.1.2. 说说 List, Set, Queue, Map 四者的区别?](#112-说说-list-set-queue-map-四者的区别) - [1.1.3. 集合框架底层数据结构总结](#113-集合框架底层数据结构总结) - [1.1.3.1. List](#1131-list) - [1.1.3.2. Set](#1132-set) - - [1.1.3.3. Map](#1133-map) + - [1.1.3.3 Queue](#1133-queue) + - [1.1.3.4. Map](#1134-map) - [1.1.4. 如何选用集合?](#114-如何选用集合) - [1.1.5. 为什么要使用集合?](#115-为什么要使用集合) - [1.2. Collection 子接口之 List](#12-collection-子接口之-list) @@ -22,25 +23,29 @@ - [1.3.1.2. 重写 compareTo 方法实现按年龄来排序](#1312-重写-compareto-方法实现按年龄来排序) - [1.3.2. 无序性和不可重复性的含义是什么](#132-无序性和不可重复性的含义是什么) - [1.3.3. 比较 HashSet、LinkedHashSet 和 TreeSet 三者的异同](#133-比较-hashsetlinkedhashset-和-treeset-三者的异同) - - [1.4. Map 接口](#14-map-接口) - - [1.4.1. HashMap 和 Hashtable 的区别](#141-hashmap-和-hashtable-的区别) - - [1.4.2. HashMap 和 HashSet 区别](#142-hashmap-和-hashset-区别) - - [1.4.3. HashMap 和 TreeMap 区别](#143-hashmap-和-treemap-区别) - - [1.4.4. HashSet 如何检查重复](#144-hashset-如何检查重复) - - [1.4.5. HashMap 的底层实现](#145-hashmap-的底层实现) - - [1.4.5.1. JDK1.8 之前](#1451-jdk18-之前) - - [1.4.5.2. JDK1.8 之后](#1452-jdk18-之后) - - [1.4.6. HashMap 的长度为什么是 2 的幂次方](#146-hashmap-的长度为什么是-2-的幂次方) - - [1.4.7. HashMap 多线程操作导致死循环问题](#147-hashmap-多线程操作导致死循环问题) - - [1.4.8. HashMap 有哪几种常见的遍历方式?](#148-hashmap-有哪几种常见的遍历方式) - - [1.4.9. ConcurrentHashMap 和 Hashtable 的区别](#149-concurrenthashmap-和-hashtable-的区别) - - [1.4.10. ConcurrentHashMap 线程安全的具体实现方式/底层具体实现](#1410-concurrenthashmap-线程安全的具体实现方式底层具体实现) - - [1.4.10.1. JDK1.7(上面有示意图)](#14101-jdk17上面有示意图) - - [1.4.10.2. JDK1.8 (上面有示意图)](#14102-jdk18-上面有示意图) - - [1.5. Collections 工具类](#15-collections-工具类) - - [1.5.1. 排序操作](#151-排序操作) - - [1.5.2. 查找,替换操作](#152-查找替换操作) - - [1.5.3. 同步控制](#153-同步控制) + - [1.4 Collection 子接口之 Queue](#14-collection-子接口之-queue) + - [1.4.1 Queue 与 Deque 的区别](#141-queue-与-deque-的区别) + - [1.4.2 ArrayDeque 与 LinkedList 的区别](#142-arraydeque-与-linkedlist-的区别) + - [1.4.3 说一说 PriorityQueue](#143-说一说-priorityqueue) + - [1.5. Map 接口](#15-map-接口) + - [1.5.1. HashMap 和 Hashtable 的区别](#151-hashmap-和-hashtable-的区别) + - [1.5.2. HashMap 和 HashSet 区别](#152-hashmap-和-hashset-区别) + - [1.5.3. HashMap 和 TreeMap 区别](#153-hashmap-和-treemap-区别) + - [1.5.4. HashSet 如何检查重复](#154-hashset-如何检查重复) + - [1.5.5. HashMap 的底层实现](#155-hashmap-的底层实现) + - [1.5.5.1. JDK1.8 之前](#1551-jdk18-之前) + - [1.5.5.2. JDK1.8 之后](#1552-jdk18-之后) + - [1.5.6. HashMap 的长度为什么是 2 的幂次方](#156-hashmap-的长度为什么是-2-的幂次方) + - [1.5.7. HashMap 多线程操作导致死循环问题](#157-hashmap-多线程操作导致死循环问题) + - [1.5.8. HashMap 有哪几种常见的遍历方式?](#158-hashmap-有哪几种常见的遍历方式) + - [1.5.9. ConcurrentHashMap 和 Hashtable 的区别](#159-concurrenthashmap-和-hashtable-的区别) + - [1.5.10. ConcurrentHashMap 线程安全的具体实现方式/底层具体实现](#1510-concurrenthashmap-线程安全的具体实现方式底层具体实现) + - [1.5.10.1. JDK1.7(上面有示意图)](#15101-jdk17上面有示意图) + - [1.5.10.2. JDK1.8 (上面有示意图)](#15102-jdk18-上面有示意图) + - [1.6. Collections 工具类](#16-collections-工具类) + - [1.6.1. 排序操作](#161-排序操作) + - [1.6.2. 查找,替换操作](#162-查找替换操作) + - [1.6.3. 同步控制](#163-同步控制) From fb609a83ed1804ed6467305c69811e0e0cc6ea07 Mon Sep 17 00:00:00 2001 From: kaka2634 <996529090@qq.com> Date: Sat, 14 Aug 2021 19:03:14 +0800 Subject: [PATCH 165/257] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection/Java集合框架常见面试题.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 67953e38..ce99f804 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -333,7 +333,7 @@ Output: `Deque` 扩展了 `Queue` 的接口, 增加了在队首和队尾进行插入和删除的方法,同样根据失败后处理方式的不同分为两类: -| `Deque`接口 | 抛出异常 | 返回特殊值 | +| `Deque` 接口 | 抛出异常 | 返回特殊值 | | ------------ | ------------- | --------------- | | 插入队首 | addFirst(E e) | offerFirst(E e) | | 插入队尾 | addLast(E e) | offerLast(E e) | @@ -342,12 +342,12 @@ Output: | 查询队首元素 | getFirst() | peekFirst() | | 查询队尾元素 | getLast() | peekLast() | -事实上,`Deque` 还提供有 `push()` 和 `pop()` 等其他方法,用于模拟栈。 +事实上,`Deque` 还提供有 `push()` 和 `pop()` 等其他方法,可用于模拟栈。 ### 1.4.2 ArrayDeque 与 LinkedList 的区别 -`ArrayDeque` 和 `LinkedList` 都实现了`Deque`接口,两者都具有队列的功能,但两者有什么区别呢? +`ArrayDeque` 和 `LinkedList` 都实现了 `Deque` 接口,两者都具有队列的功能,但两者有什么区别呢? - `ArrayDeque` 是基于可变长的数组和双指针来实现,而 `LinkedList` 则通过链表来实现。 @@ -357,7 +357,7 @@ Output: - `ArrayDeque` 插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。虽然 `LinkedList` 不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。 -从性能的角度上,选用 `ArrayDeque` 去实现队列要比 `LinkedList` 更好。此外,`ArrayDeque` 也可以用于实现栈。 +从性能的角度上,选用 `ArrayDeque` 来实现队列要比 `LinkedList` 更好。此外,`ArrayDeque` 也可以用于实现栈。 ### 1.4.3 说一说 PriorityQueue @@ -368,9 +368,9 @@ Output: - `PriorityQueue` 利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据 - `PriorityQueue` 通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。 - `PriorityQueue` 是非线程安全的,且不支持存储 `NULL` 和 `non-comparable` 的对象。 -- `PriorityQueue` 默认是小顶堆,可以接收一个`Comparator`作为构造参数来比较队列中元素的优先级。 +- `PriorityQueue` 默认是小顶堆,但可以接收一个 `Comparator` 作为构造参数,从而来自定义元素优先级的先后。 -`PriorityQueue` 在面试中可能更多的会出现在手撕算法的时候,典型例题包括堆排序、求第K大的数、带权图的遍历等,所以需要学会熟练使用才行。 +`PriorityQueue` 在面试中可能更多的会出现在手撕算法的时候,典型例题包括堆排序、求第K大的数、带权图的遍历等,所以需要会熟练使用才行。 ## 1.5. Map 接口 From d5d61b303c341bcf40ec48e0636000d02494b272 Mon Sep 17 00:00:00 2001 From: guide Date: Sun, 15 Aug 2021 08:54:19 +0800 Subject: [PATCH 166/257] =?UTF-8?q?[feat]MySQL=E4=B8=89=E5=A4=A7=E6=97=A5?= =?UTF-8?q?=E5=BF=97(binlog=E3=80=81redo=20log=E5=92=8Cundo=20log)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +- ...大日志(binlog、redo log和undo log).md | 280 ++++++++++++++++++ 2 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 docs/database/mysql/MySQL三大日志(binlog、redo log和undo log).md diff --git a/README.md b/README.md index 7cf58b25..eca328cc 100644 --- a/README.md +++ b/README.md @@ -147,9 +147,10 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle 1. [MySQL数据库索引总结](docs/database/mysql/MySQL数据库索引.md) 2. [事务隔离级别(图文详解)](docs/database/mysql/事务隔离级别(图文详解).md) -3. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/InnoDB对MVCC的实现.md) -4. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/mysql/一条sql语句在mysql中如何执行的.md) -5. [关于数据库中如何存储时间的一点思考](docs/database/mysql/关于数据库存储时间的一点思考.md) +3. [MySQL三大日志(binlog、redo log和undo log)详解](docs/database/mysql/MySQL三大日志(binlog、redo log和undo log).md) +4. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/InnoDB对MVCC的实现.md) +5. [一条 SQL 语句在 MySQL 中如何执行的](docs/database/mysql/一条sql语句在mysql中如何执行的.md) +6. [关于数据库中如何存储时间的一点思考](docs/database/mysql/关于数据库存储时间的一点思考.md) ### Redis diff --git a/docs/database/mysql/MySQL三大日志(binlog、redo log和undo log).md b/docs/database/mysql/MySQL三大日志(binlog、redo log和undo log).md new file mode 100644 index 00000000..616fab71 --- /dev/null +++ b/docs/database/mysql/MySQL三大日志(binlog、redo log和undo log).md @@ -0,0 +1,280 @@ +> 本文来自公号程序猿阿星投稿,JavaGuide 对其做了补充完善。 + +## 前言 + +`MySQL` 日志 主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。其中,比较重要的还要属二进制日志 `binlog`(归档日志)和事务日志 `redo log`(重做日志)和 `undo log`(回滚日志)。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/01.png) + +今天就来聊聊 `redo log`(重做日志)、`binlog`(归档日志)、两阶段提交、`undo log` (回滚日志)。 + +## redo log + +`redo log`(重做日志)是`InnoDB`存储引擎独有的,它让`MySQL`拥有了崩溃恢复能力。 + +比如 `MySQL` 实例挂了或宕机了,重启时,`InnoDB`存储引擎会使用`redo log`恢复数据,保证数据的持久性与完整性。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/02.png) + +`MySQL` 中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 `Buffer Pool` 中。 + +后续的查询都是先从 `Buffer Pool` 中找,没有命中再去硬盘加载,减少硬盘 `IO` 开销,提升性能。 + +更新表数据的时候,也是如此,发现 `Buffer Pool` 里存在要更新的数据,就直接在 `Buffer Pool` 里更新。 + +然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(`redo log buffer`)里,接着刷盘到 `redo log` 文件里。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/03.png) + +理想情况,事务一提交就会进行刷盘操作,但实际上,刷盘的时机是根据策略来进行的。 + +> 小贴士:每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成 + +### 刷盘时机 + +`InnoDB` 存储引擎为 `redo log` 的刷盘策略提供了 `innodb_flush_log_at_trx_commit` 参数,它支持三种策略: + +- **0** :设置为 0 的时候,表示每次事务提交时不进行刷盘操作 +- **1** :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值) +- **2** :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache + +`innodb_flush_log_at_trx_commit` 参数默认为 1 ,也就是说当事务提交时会调用 `fsync` 对 redo log 进行刷盘 + +另外,`InnoDB` 存储引擎有一个后台线程,每隔`1` 秒,就会把 `redo log buffer` 中的内容写到文件系统缓存(`page cache`),然后调用 `fsync` 刷盘。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/04.png) + +也就是说,一个没有提交事务的 `redo log` 记录,也可能会刷盘。 + +**为什么呢?** + +因为在事务执行过程 `redo log` 记录是会写入`redo log buffer` 中,这些 `redo log` 记录会被后台线程刷盘。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/05.png) + +除了后台线程每秒`1`次的轮询操作,还有一种情况,当 `redo log buffer` 占用的空间即将达到 `innodb_log_buffer_size` 一半的时候,后台线程会主动刷盘。 + +下面是不同刷盘策略的流程图。 + +#### innodb_flush_log_at_trx_commit=0 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/06.png) + +为`0`时,如果`MySQL`挂了或宕机可能会有`1`秒数据的丢失。 + +#### innodb_flush_log_at_trx_commit=1 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/07.png) + +为`1`时, 只要事务提交成功,`redo log`记录就一定在硬盘里,不会有任何数据丢失。 + +如果事务执行期间`MySQL`挂了或宕机,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损失。 + +#### innodb_flush_log_at_trx_commit=2 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/09.png) + +为`2`时, 只要事务提交成功,`redo log buffer`中的内容只写入文件系统缓存(`page cache`)。 + +如果仅仅只是`MySQL`挂了不会有任何数据丢失,但是宕机可能会有`1`秒数据的丢失。 + +### 日志文件组 + +硬盘上存储的 `redo log` 日志文件不只一个,而是以一个**日志文件组**的形式出现的,每个的`redo`日志文件大小都是一样的。 + +比如可以配置为一组`4`个文件,每个文件的大小是 `1GB`,整个 `redo log` 日志文件组可以记录`4G`的内容。 + +它采用的是环形数组形式,从头开始写,写到末尾又回到头循环写,如下图所示。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/10.png) + +在个**日志文件组**中还有两个重要的属性,分别是 `write pos、checkpoint` + +- **write pos** 是当前记录的位置,一边写一边后移 +- **checkpoint** 是当前要擦除的位置,也是往后推移 + +每次刷盘 `redo log` 记录到**日志文件组**中,`write pos` 位置就会后移更新。 + +每次 `MySQL` 加载**日志文件组**恢复数据时,会清空加载过的 `redo log` 记录,并把 `checkpoint` 后移更新。 + +`write pos` 和 `checkpoint` 之间的还空着的部分可以用来写入新的 `redo log` 记录。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/11.png) + +如果 `write pos` 追上 `checkpoint` ,表示**日志文件组**满了,这时候不能再写入新的 `redo log` 记录,`MySQL` 得停下来,清空一些记录,把 `checkpoint` 推进一下。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/03/12.png) + +### redo log 小结 + +相信大家都知道 `redo log` 的作用和它的刷盘时机、存储形式。 + +现在我们来思考一个问题: **只要每次把修改后的数据页直接刷盘不就好了,还有 `redo log` 什么事?** + +它们不都是刷盘么?差别在哪里? + +```java +1 Byte = 8bit +1 KB = 1024 Byte +1 MB = 1024 KB +1 GB = 1024 MB +1 TB = 1024 GB +``` + +实际上,数据页大小是`16KB`,刷盘比较耗时,可能就修改了数据页里的几 `Byte` 数据,有必要把完整的数据页刷盘吗? + +而且数据页刷盘是随机写,因为一个数据页对应的位置可能在硬盘文件的随机位置,所以性能是很差。 + +如果是写 `redo log`,一行记录可能就占几十 `Byte`,只包含表空间号、数据页号、磁盘文件偏移 +量、更新值,再加上是顺序写,所以刷盘速度很快。 + +所以用 `redo log` 形式记录修改内容,性能会远远超过刷数据页的方式,这也让数据库的并发能力更强。 + +> 其实内存的数据页在一定时机也会刷盘,我们把这称为页合并,讲 `Buffer Pool`的时候会对这块细说 + +## binlog + +`redo log` 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 `InnoDB` 存储引擎。 + +而 `binlog` 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于`MySQL Server` 层。 + +不管用什么存储引擎,只要发生了表数据更新,都会产生 `binlog` 日志。 + +那 `binlog` 到底是用来干嘛的? + +可以说`MySQL`数据库的**数据备份、主备、主主、主从**都离不开`binlog`,需要依靠`binlog`来同步数据,保证数据一致性。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/01.png) + +`binlog`会记录所有涉及更新数据的逻辑操作,并且是顺序写。 + +### 记录格式 + +`binlog` 日志有三种格式,可以通过`binlog_format`参数指定。 + +- **statement** +- **row** +- **mixed** + +指定`statement`,记录的内容是`SQL`语句原文,比如执行一条`update T set update_time=now() where id=1`,记录的内容如下。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/02.png) + +同步数据时,会执行记录的`SQL`语句,但是有个问题,`update_time=now()`这里会获取当前系统时间,直接执行会导致与原库的数据不一致。 + +为了解决这种问题,我们需要指定为`row`,记录的内容不再是简单的`SQL`语句了,还包含操作的具体数据,记录内容如下。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/03.png) + +`row`格式记录的内容看不到详细信息,要通过`mysqlbinlog`工具解析出来。 + +`update_time=now()`变成了具体的时间`update_time=1627112756247`,条件后面的@1、@2、@3 都是该行数据第 1 个~3 个字段的原始值(**假设这张表只有 3 个字段**)。 + +这样就能保证同步数据的一致性,通常情况下都是指定为`row`,这样可以为数据库的恢复与同步带来更好的可靠性。 + +但是这种格式,需要更大的容量来记录,比较占用空间,恢复与同步时会更消耗`IO`资源,影响执行速度。 + +所以就有了一种折中的方案,指定为`mixed`,记录的内容是前两者的混合。 + +`MySQL`会判断这条`SQL`语句是否可能引起数据不一致,如果是,就用`row`格式,否则就用`statement`格式。 + +### 写入机制 + +`binlog`的写入时机也非常简单,事务执行过程中,先把日志写到`binlog cache`,事务提交的时候,再把`binlog cache`写到`binlog`文件中。 + +因为一个事务的`binlog`不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为`binlog cache`。 + +我们可以通过`binlog_cache_size`参数控制单个线程 binlog cache 大小,如果存储内容超过了这个参数,就要暂存到磁盘(`Swap`)。 + +`binlog`日志刷盘流程如下 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/04.png) + +- **上图的 write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快** +- **上图的 fsync,才是将数据持久化到磁盘的操作** + +`write`和`fsync`的时机,可以由参数`sync_binlog`控制,默认是`0`。 + +为`0`的时候,表示每次提交事务都只`write`,由系统自行判断什么时候执行`fsync`。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/05.png) + +虽然性能得到提升,但是机器宕机,`page cache`里面的 binglog 会丢失。 + +为了安全起见,可以设置为`1`,表示每次提交事务都会执行`fsync`,就如同**binlog 日志刷盘流程**一样。 + +最后还有一种折中方式,可以设置为`N(N>1)`,表示每次提交事务都`write`,但累积`N`个事务后才`fsync`。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/04/06.png) + +在出现`IO`瓶颈的场景里,将`sync_binlog`设置成一个比较大的值,可以提升性能。 + +同样的,如果机器宕机,会丢失最近`N`个事务的`binlog`日志。 + +## 两阶段提交 + +`redo log`(重做日志)让`InnoDB`存储引擎拥有了崩溃恢复能力。 + +`binlog`(归档日志)保证了`MySQL`集群架构的数据一致性。 + +虽然它们都属于持久化的保证,但是则重点不同。 + +在执行更新语句过程,会记录`redo log`与`binlog`两块日志,以基本的事务为单位,`redo log`在事务执行过程中可以不断写入,而`binlog`只有在提交事务时才写入,所以`redo log`与`binlog`的写入时机不一样。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/01.png) + +回到正题,`redo log`与`binlog`两份日志之间的逻辑不一致,会出现什么问题? + +我们以`update`语句为例,假设`id=2`的记录,字段`c`值是`0`,把字段`c`值更新成`1`,`SQL`语句为`update T set c=1 where id=2`。 + +假设执行过程中写完`redo log`日志后,`binlog`日志写期间发生了异常,会出现什么情况呢? + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/02.png) + +由于`binlog`没写完就异常,这时候`binlog`里面没有对应的修改记录。因此,之后用`binlog`日志恢复数据时,就会少这一次更新,恢复出来的这一行`c`值是`0`,而原库因为`redo log`日志恢复,这一行`c`值是`1`,最终数据不一致。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/03.png) + +为了解决两份日志之间的逻辑一致问题,`InnoDB`存储引擎使用**两阶段提交**方案。 + +原理很简单,将`redo log`的写入拆成了两个步骤`prepare`和`commit`,这就是**两阶段提交**。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/04.png) + +使用**两阶段提交**后,写入`binlog`时发生异常也不会有影响,因为`MySQL`根据`redo log`日志恢复数据时,发现`redo log`还处于`prepare`阶段,并且没有对应`binlog`日志,就会回滚该事务。 + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/05.png) + +再看一个场景,`redo log`设置`commit`阶段发生异常,那会不会回滚事务呢? + +![](https://cdn.jsdelivr.net/gh/18702524676/CND5/image/mysql/05/06.png) + +并不会回滚事务,它会执行上图框住的逻辑,虽然`redo log`是处于`prepare`阶段,但是能通过事务`id`找到对应的`binlog`日志,所以`MySQL`认为是完整的,就会提交事务恢复数据。 + +## undo log + +> 这部分内容为 JavaGuide 的补充: + +我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行**回滚**,在 MySQL 中,恢复机制是通过 **回滚日志(undo log)** 实现的,所有事务进行的修改都会先先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 **回滚日志** 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。 + +另外,`MVCC` 的实现依赖于:**隐藏字段、Read View、undo log**。在内部实现中,`InnoDB` 通过数据行的 `DB_TRX_ID` 和 `Read View` 来判断数据的可见性,如不可见,则通过数据行的 `DB_ROLL_PTR` 找到 `undo log` 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 `Read View` 之前已经提交的修改和该事务本身做的修改 + +## 总结 + +> 这部分内容为 JavaGuide 的补充: + +MySQL InnoDB 引擎使用 **redo log(重做日志)** 保证事务的**持久性**,使用 **undo log(回滚日志)** 来保证事务的**原子性**。 + +`MySQL`数据库的**数据备份、主备、主主、主从**都离不开`binlog`,需要依靠`binlog`来同步数据,保证数据一致性。 + +## 站在巨人的肩膀上 + +- 《MySQL 实战 45 讲》 +- 《从零开始带你成为 MySQL 实战优化高手》 +- 《MySQL 是怎样运行的:从根儿上理解 MySQL》 +- 《MySQL 技术 Innodb 存储引擎》 + +## MySQL 好文推荐 + +- [CURD 这么多年,你有了解过 MySQL 的架构设计吗?](https://mp.weixin.qq.com/s/R-1km7r0z3oWfwYQV8iiqA) +- [浅谈 MySQL InnoDB 的内存组件](https://mp.weixin.qq.com/s/7Kab4IQsNcU_bZdbv_MuOg) \ No newline at end of file From b46a3c382a6af7fcb33f836f122e72aa4c55edd8 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 16 Aug 2021 14:42:44 +0800 Subject: [PATCH 167/257] =?UTF-8?q?[feat]java9=20=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 227 ++++++++++++++---- 1 file changed, 179 insertions(+), 48 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index 2d56e512..dc1d4318 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -1,32 +1,161 @@ -大家好,我是Guide哥!这篇文章来自读者的投稿,经过了两次较大的改动,两周的完善终于完成。Java 8新特性见这里:[Java8新特性最佳指南](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484744&idx=1&sn=9db31dca13d327678845054af75efb74&chksm=cea24a83f9d5c3956f4feb9956b068624ab2fdd6c4a75fe52d5df5dca356a016577301399548&token=1082669959&lang=zh_CN&scene=21#wechat_redirect) 。 +Java 8 新特性见这里:[Java8 新特性最佳指南](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484744&idx=1&sn=9db31dca13d327678845054af75efb74&chksm=cea24a83f9d5c3956f4feb9956b068624ab2fdd6c4a75fe52d5df5dca356a016577301399548&token=1082669959&lang=zh_CN&scene=21#wechat_redirect) 。 -*Guide 哥:别人家的特性都用了几年了,我 Java 才出来,哈哈!真实!* +_Guide 哥:别人家的特性都用了几年了,我 Java 才出来,哈哈!真实!_ ## Java9 -发布于 2017 年 9 月 21 日 。作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如集合、Stream 流 +发布于 2017 年 9 月 21 日 。作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如集合、Stream 流 ### Java 平台模块系统 -Java 平台模块系统,也就是 Project Jigsaw,把模块化开发实践引入到了 Java 平台中。在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。 +Java 平台模块系统是[Jigsaw Project](https://openjdk.java.net/projects/jigsaw/)的一部分,把模块化开发实践引入到了 Java 平台中,可以让我们的代码可重用性更好! -Java 9 模块的重要特征是在其工件(artifact)的根目录中包含了一个描述模块的 module-info.class 文 件。 工件的格式可以是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。 +什么是模块系统?官方的定义是:A uniquely named, reusable group of related packages, as well as resources (such as images and XML files) and a module descriptor. + +简单来说,你可以将一个模块看作是一组唯一命名、可重用的包、资源和模块描述文件(module-info.java)。 + +任意一个 jar 文件,只要加上一个 模块描述文件(module-info.java),就可以升级为一个模块。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/module-structure.png) + +在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。 + +我们可以通过 exports 关键词精准控制哪些类可以对外开放使用,哪些类只能内部使用。 + +```java +module my.module { + //exports 公开指定包的所有公共成员 + exports com.my.package.name; +} + +module my.module { + //exports…to 限制访问的成员范围 + export com.my.package.name to com.specific.package; +} +``` + +Java 9 模块的重要特征是在其工件(artifact)的根目录中包含了一个描述模块的 `module-info.java` 文 件。 工件的格式可以是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。 + +想要深入了解 Java 9 的模块化,参见: + +- [Project Jigsaw: Module System Quick-Start Guide](https://openjdk.java.net/projects/jigsaw/quick-start) +- [Java 9 Modules: part 1](https://stacktraceguru.com/java9/module-introduction) ### Jshell jshell 是 Java 9 新增的一个实用工具。为 Java 提供了类似于 Python 的实时命令行交互工具。 -在 Jshell 中可以直接输入表达式并查看其执行结果 +在 Jshell 中可以直接输入表达式并查看其执行结果。 -### 集合、Stream 和 Optional +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210816083417616.png) -- 增加 了 `List.of()`、`Set.of()`、`Map.of()` 和 `Map.ofEntries()`等工厂方法来创建不可变集合,比如`List.of("Java", "C++");`、`Map.of("Java", 1, "C++", 2)`;(这部分内容有点参考 Guava 的味道) -- `Stream` 中增加了新的方法 `ofNullable`、`dropWhile`、`takeWhile` 和 `iterate` 方法。`Collectors` 中增加了新的方法 `filtering` 和 `flatMapping` -- `Optional` 类中新增了 `ifPresentOrElse`、`or` 和 `stream` 等方法 +### 集合增强 + +增加 了 `List.of()`、`Set.of()`、`Map.of()` 和 `Map.ofEntries()`等工厂方法来创建不可变集合(这部分内容有点参考 Guava 的味道) + +```java +List.of("Java", "C++"); +Set.of("Java", "C++"); +Map.of("Java", 1, "C++", 2)`; +``` + +`Collectors` 中增加了新的方法 `filtering()` 和 `flatMapping()`。 + +`Collectors` 的 `filtering()` 方法类似于 `Stream` 类的 `filter()` 方法,都是用于过滤元素。 + +> Java 8 为 `Collectors` 类引入了 `groupingBy` 操作,用于根据特定的属性将对象分组。 + +```java +List list = List.of("x","www", "yy", "zz"); +Map> result = list.stream() + .collect(Collectors.groupingBy(String::length, + Collectors.filtering(s -> !s.contains("z"), + Collectors.toList()))); + +System.out.println(result); // {1=[x], 2=[yy], 3=[www]} +``` + +### Stream & Optional 增强 + +`Stream` 中增加了新的方法 `ofNullable()`、`dropWhile()`、`takeWhile()` 以及 `iterate()` 方法的重载方法。 + +Java 9 中的 `ofNullable()` 方 法允许我们创建一个单元素的 `Stream`,可以包含一个非空元素,也可以创建一个空 `Stream`。 而在 Java 8 中则不可以创建空的 `Stream` 。 + +```java +Stream stringStream = Stream.ofNullable("Java"); +System.out.println(stringStream.count());// 1 +Stream nullStream = Stream.ofNullable(null); +System.out.println(nullStream.count());//0 +``` + +`takeWhile()` 方法可以从 `Stream` 中依次获取满足条件的元素,直到不满足条件为止结束获取。 + +```java +List integerList = List.of(11, 33, 66, 8, 9, 13); +integerList.stream().takeWhile(x -> x < 50).forEach(System.out::println);// 11 33 +``` + +`dropWhile()` 方法的效果和 `takeWhile()` 相反。 + +```java +List integerList2 = List.of(11, 33, 66, 8, 9, 13); +integerList2.stream().dropWhile(x -> x < 50).forEach(System.out::println);// 66 8 9 13 +``` + +`iterate()` 方法的新重载方法提供了一个 `Predicate` 参数 (判断条件)来决定什么时候结束迭代 + +```java +public static Stream iterate(final T seed, final UnaryOperator f) { +} +// 新增加的重载方法 +public static Stream iterate(T seed, Predicate hasNext, UnaryOperator next) { + +} +``` + +两者的使用对比如下,新的 `iterate()` 重载方法更加灵活一些。 + +```java +// 使用原始 iterate() 方法输出数字 1~10 +Stream.iterate(1, i -> i + 1).limit(10).forEach(System.out::println); +// 使用新的 iterate() 重载方法输出数字 1~10 +Stream.iterate(1, i -> i <= 10, i -> i + 1).forEach(System.out::println); +``` + +`Optional` 类中新增了 `ifPresentOrElse()`、`or()` 和 `stream()` 等方法 + +`ifPresentOrElse()` 方法接受两个参数 `Consumer` 和 `Runnable` ,如果 `Optional` 不为空调用 `Consumer` 参数,为空则调用 `Runnable` 参数。 + +```java +public void ifPresentOrElse(Consumer action, Runnable emptyAction) + +Optional objectOptional = Optional.empty(); +objectOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Empty!!!"));// Empty!!! +``` + +`or()` 方法接受一个 `Supplier` 参数 ,如果 `Optional` 为空则返回 `Supplier` 参数指定的 `Optional` 值。 + +```java +public Optional or(Supplier> supplier) + +Optional objectOptional = Optional.empty(); +objectOptional.or(() -> Optional.of("java")).ifPresent(System.out::println);//java +``` + +### String 存储结构变更 + +JDK 8 及之前的版本,`String` 一直是用 `char[]` 存储。在 Java 9 之后,`String` 的实现改用 `byte[]` 数组存储字符串。 ### 进程 API -Java 9 增加了 `ProcessHandle` 接口,可以对原生进程进行管理,尤其适合于管理长时间运行的进程 +Java 9 增加了 `ProcessHandle` 接口,可以对原生进程进行管理,尤其适合于管理长时间运行的进程。 + +```java +System.out.println(ProcessHandle.current().pid()); +System.out.println(ProcessHandle.current().info()); +``` + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210816104614414.png) ### 平台日志 API 和服务 @@ -41,21 +170,34 @@ Java 9 允许为 JDK 和应用配置同样的日志实现。新增了 `System.Lo ### 变量句柄 -- 变量句柄是一个变量或一组变量的引用,包括静态域,非静态域,数组元素和堆外数据结构中的组成部分等 -- 变量句柄的含义类似于已有的方法句柄`MethodHandle` -- 由 Java 类`java.lang.invoke.VarHandle` 来表示,可以使用类 `java.lang.invoke.MethodHandles.Lookup` 中的静态工厂方法来创建 `VarHandle` 对 象 +变量句柄是一个变量或一组变量的引用,包括静态域,非静态域,数组元素和堆外数据结构中的组成部分等 + +变量句柄的含义类似于已有的方法句柄 `MethodHandle` ,由 Java 类 `java.lang.invoke.VarHandle` 来表示,可以使用类 `java.lang.invoke.MethodHandles.Lookup` 中的静态工厂方法来创建 `VarHandle` 对象。 + +`VarHandle` 的出现替代了 `java.util.concurrent.atomic` 和 `sun.misc.Unsafe` 的部分操作。并且提供了一系列标准的内存屏障操作,用于更加细粒度的控制内存排序。在安全性、可用性、性能上都要优于现有的 API。 ### 改进方法句柄(Method Handle) -- 方法句柄从 Java7 开始引入,Java9 在类`java.lang.invoke.MethodHandles` 中新增了更多的静态方法来创建不同类型的方法句柄 +方法句柄从 Java7 开始引入,Java9 在类`java.lang.invoke.MethodHandles` 中新增了更多的静态方法来创建不同类型的方法句柄。 + +### 接口私有方法 + +Java 9 允许在接口中使用私有方法。 + +```java +public interface MyInterface { + private void methodPrivate(){ + + } +} +``` ### 其它新特性 -- **接口私有方法** :Java 9 允许在接口中使用私有方法 - **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 [https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)) -- **类 `CompletableFuture` 中增加了几个新的方法(`completeAsync` ,`orTimeout` 等)** -- **Nashorn 引擎的增强** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性 -- **I/O 流的新特性** :增加了新的方法来读取和复制 InputStream 中包含的数据 +- 类 `CompletableFuture` 中增加了几个新的方法(`completeAsync` ,`orTimeout` 等) +- **Nashorn 引擎的增强** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性(Java 11 中已经被弃用)。 +- **I/O 流的新特性** :增加了新的方法来读取和复制 `InputStream` 中包含的数据 - **改进应用的安全性能** :Java 9 新增了 4 个 SHA- 3 哈希算法,SHA3-224、SHA3-256、SHA3-384 和 S HA3-512 - ...... @@ -121,17 +263,17 @@ _Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面 //判断字符串是否为空 " ".isBlank();//true //去除字符串首尾空格 -" Java ".strip();// "Java" +" Java ".strip();// "Java" //去除字符串首部空格 -" Java ".stripLeading(); // "Java " +" Java ".stripLeading(); // "Java " //去除字符串尾部空格 -" Java ".stripTrailing(); // " Java" +" Java ".stripTrailing(); // " Java" //重复字符串多少次 -"Java".repeat(3); // "JavaJavaJava" +"Java".repeat(3); // "JavaJavaJava" //返回由行终止符分隔的字符串集合。 -"A\nB\nC".lines().count(); // 3 -"A\nB\nC".lines().collect(Collectors.toList()); +"A\nB\nC".lines().count(); // 3 +"A\nB\nC".lines().collect(Collectors.toList()); ``` ### ZGC:可伸缩低延迟垃圾收集器 @@ -158,31 +300,20 @@ Java 11 对 Java 9 中引入并在 Java 10 中进行了更新的 Http Client API 使用起来也很简单,如下: ```java -var request = HttpRequest.newBuilder() - - .uri(URI.create("https://javastack.cn")) - - .GET() - - .build(); - -var client = HttpClient.newHttpClient(); - -// 同步 - -HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - -System.out.println(response.body()); - -// 异步 - -client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - - .thenApply(HttpResponse::body) - - .thenAccept(System.out::println); +var request = HttpRequest.newBuilder() + .uri(URI.create("https://javastack.cn")) + .GET() + .build(); +var client = HttpClient.newHttpClient(); +// 同步 +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.body()); +// 异步 +client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body) + .thenAccept(System.out::println); ``` ### 简化启动单个源代码文件的方法 From 814780f7390af74864cf6b39d78e967157c19bc7 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 16 Aug 2021 16:42:31 +0800 Subject: [PATCH 168/257] =?UTF-8?q?[feat]java10,11=20=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 152 +++++++++++++----- 1 file changed, 113 insertions(+), 39 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index dc1d4318..4354d219 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -38,8 +38,8 @@ Java 9 模块的重要特征是在其工件(artifact)的根目录中包含 想要深入了解 Java 9 的模块化,参见: -- [Project Jigsaw: Module System Quick-Start Guide](https://openjdk.java.net/projects/jigsaw/quick-start) -- [Java 9 Modules: part 1](https://stacktraceguru.com/java9/module-introduction) +- [《Project Jigsaw: Module System Quick-Start Guide》](https://openjdk.java.net/projects/jigsaw/quick-start) +- [《Java 9 Modules: part 1》](https://stacktraceguru.com/java9/module-introduction) ### Jshell @@ -59,6 +59,8 @@ Set.of("Java", "C++"); Map.of("Java", 1, "C++", 2)`; ``` +使用 `of()` 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 `java.lang.UnsupportedOperationException` 异常。 + `Collectors` 中增加了新的方法 `filtering()` 和 `flatMapping()`。 `Collectors` 的 `filtering()` 方法类似于 `Stream` 类的 `filter()` 方法,都是用于过滤元素。 @@ -165,8 +167,9 @@ Java 9 允许为 JDK 和应用配置同样的日志实现。新增了 `System.Lo ### 反应式流 ( Reactive Streams ) -- 在 Java9 中的 `java.util.concurrent.Flow` 类中新增了反应式流规范的核心接口 -- Flow 中包含了 `Flow.Publisher`、`Flow.Subscriber`、`Flow.Subscription` 和 `Flow.Processor` 等 4 个核心接口。Java 9 还提供了`SubmissionPublisher` 作为`Flow.Publisher` 的一个实现。 +在 Java9 中的 `java.util.concurrent.Flow` 类中新增了反应式流规范的核心接口 。 + +`Flow` 中包含了 `Flow.Publisher`、`Flow.Subscriber`、`Flow.Subscription` 和 `Flow.Processor` 等 4 个核心接口。Java 9 还提供了`SubmissionPublisher` 作为`Flow.Publisher` 的一个实现。 ### 变量句柄 @@ -192,9 +195,9 @@ public interface MyInterface { } ``` -### 其它新特性 +### Java9 其它新特性 -- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 [https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)) +- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章:[《Effectively Final Variables in Java》](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html) - 类 `CompletableFuture` 中增加了几个新的方法(`completeAsync` ,`orTimeout` 等) - **Nashorn 引擎的增强** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性(Java 11 中已经被弃用)。 - **I/O 流的新特性** :增加了新的方法来读取和复制 `InputStream` 中包含的数据 @@ -205,16 +208,45 @@ public interface MyInterface { 发布于 2018 年 3 月 20 日,最知名的特性应该是 var 关键字(局部变量类型推断)的引入了,其他还有垃圾收集器改善、GC 改进、性能提升、线程管控等一批新特性 -### var 关键字 +### var(局部变量推断) -- **介绍** :提供了 var 关键字声明局部变量:`var list = new ArrayList(); // ArrayList` -- **局限性** :只能用于带有构造器的**局部变量**和 for 循环中 +由于太多 Java 开发者希望 Java 中引入局部变量推断,于是 Java 10 的时候它来了,也算是众望所归了! -_Guide 哥:实际上 Lombok 早就体用了一个类似的关键字,使用它可以简化代码,但是可能会降低程序的易读性、可维护性。一般情况下,我个人都不太推荐使用。_ +Java 10 提供了 var 关键字声明局部变量。 -### 不可变集合 +> Scala 和 Kotlin 中有 val 关键字 ( `final var` 组合关键字),Java10 中并没有引入。 -**list,set,map 提供了静态方法`copyOf()`返回入参集合的一个不可变拷贝(以下为 JDK 的源码)** +Java 10 只引入了 var,而 + +```java +var id = 0; +var codefx = new URL("https://mp.weixin.qq.com/"); +var list = new ArrayList<>(); +var list = List.of(1, 2, 3); +var map = new HashMap(); +var p = Paths.of("src/test/java/Java9FeaturesTest.java"); +var numbers = List.of("a", "b", "c"); +for (var n : list) + System.out.print(n+ " "); +``` + +var 关键字只能用于带有构造器的局部变量和 for 循环中。 + +```java +var count=null; //❌编译不通过,不能声明为 null +var r = () -> Math.random();//❌编译不通过,不能声明为 Lambda表达式 +var array = {1,2,3};//❌编译不通过,不能声明数组 +``` + +var 并不会改变 Java 是一门静态类型语言的事实,编译器负责推断出类型。 + +相关阅读:[《Java 10 新特性之局部变量类型推断》](https://zhuanlan.zhihu.com/p/34911982)。 + +### 集合增强 + +`list`,`set`,`map` 提供了静态方法`copyOf()`返回入参集合的一个不可变拷贝。 + +以下为 JDK 的源码: ```java static List copyOf(Collection coll) { @@ -222,11 +254,26 @@ static List copyOf(Collection coll) { } ``` -**`java.util.stream.Collectors`中新增了静态方法,用于将流中的元素收集为不可变的集合** +使用 `copyOf()` 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 `java.lang.UnsupportedOperationException` 异常。 IDEA 也会有相应的提示。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210816154125579.png) + +`java.util.stream.Collectors` 中新增了静态方法,用于将流中的元素收集为不可变的集合。 + +```java +var list = new ArrayList<>(); +list.stream().collect(Collectors.toUnmodifiableList()); +list.stream().collect(Collectors.toUnmodifiableSet()); +``` ### Optional -- 新增了`orElseThrow()`方法来在没有值时抛出异常 +新增了`orElseThrow()`方法来在没有值时抛出指定的异常。 + +```java +Optional.ofNullable(cache.getIfPresent(key)) + .orElseThrow(() -> new PrestoException(NOT_FOUND, "Missing entry found for key: " + key)); +``` ### 并行全垃圾回收器 G1 @@ -240,12 +287,12 @@ static List copyOf(Collection coll) { Java 10 在现有的 CDS 功能基础上再次拓展,以允许应用类放置在共享存档中。CDS 特性在原来的 bootstrap 类基础之上,扩展加入了应用类的 CDS (Application Class-Data Sharing) 支持。其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时直接读取此启动文本并加载。设想如果应用环境没有大的变化,启动速度就会得到提升 -### 其他特性 +### Java10 其他新特性 - **线程-局部管控**:Java 10 中线程管控引入 JVM 安全点的概念,将允许在不运行全局 JVM 安全点的情况下实现线程回调,由线程本身或者 JVM 线程来执行,同时保持线程处于阻塞状态,这种方式使得停止单个线程变成可能,而不是只能启用或停止所有线程 - - **备用存储装置上的堆分配**:Java 10 中将使得 JVM 能够使用适用于不同类型的存储机制的堆,在可选内存设备上进行堆内存分配 - **统一的垃圾回收接口**:Java 10 中,hotspot/gc 代码实现方面,引入一个干净的 GC 接口,改进不同 GC 源代码的隔离性,多个 GC 之间共享的实现细节代码应该存在于辅助类中。统一垃圾回收接口的主要原因是:让垃圾回收器(GC)这部分代码更加整洁,便于新人上手开发,便于后续排查相关问题。 +- ...... ## Java11 @@ -253,11 +300,11 @@ Java11 于 2018 年 9 月 25 日正式发布,这是很重要的一个版本! ![](https://img-blog.csdnimg.cn/20210603202746605.png) -### 字符串加强 +### String Java 11 增加了一系列的字符串处理方法,如以下所示。 -_Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面上常见的工具类框架啊!_ +_Guide:说白点就是多了层封装,JDK 开发组的人没少看市面上常见的工具类框架啊!_ ```java //判断字符串是否为空 @@ -276,6 +323,15 @@ _Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面 "A\nB\nC".lines().collect(Collectors.toList()); ``` +### Optional + +新增了`empty()`方法来判断指定的 `Optional` 对象是否为空。 + +```java +var op = Optional.empty(); +System.out.println(op.isEmpty());//判断指定的 Optional 对象是否为空 +``` + ### ZGC:可伸缩低延迟垃圾收集器 **ZGC 即 Z Garbage Collector**,是一个可伸缩的、低延迟的垃圾收集器。 @@ -289,15 +345,19 @@ ZGC 主要为了满足如下目标进行设计: - 针以及 Load barriers 优化奠定基础 - 当前只支持 Linux/x64 位平台 -ZGC 目前 **处在实验阶段**,只支持 Linux/x64 平台 +ZGC 目前 **处在实验阶段**,只支持 Linux/x64 平台。 + +与 CMS 中的 ParNew 和 G1 类似,ZGC 也采用标记-复制算法,不过 ZGC 对该算法做了重大改进。 + +在 ZGC 中出现 Stop The World 的情况会更少! + +详情可以看 : [《新一代垃圾回收器 ZGC 的探索与实践》](https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html) ### 标准 HTTP Client 升级 Java 11 对 Java 9 中引入并在 Java 10 中进行了更新的 Http Client API 进行了标准化,在前两个版本中进行孵化的同时,Http Client 几乎被完全重写,并且现在完全支持异步非阻塞。 -并且,Java11 中,Http Client 的包名由 `jdk.incubator.http` 改为`java.net.http`,该 API 通过 `CompleteableFuture` 提供非阻塞请求和响应语义。 - -使用起来也很简单,如下: +并且,Java11 中,Http Client 的包名由 `jdk.incubator.http` 改为`java.net.http`,该 API 通过 `CompleteableFuture` 提供非阻塞请求和响应语义。使用起来也很简单,如下: ```java var request = HttpRequest.newBuilder() @@ -316,28 +376,42 @@ client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenAccept(System.out::println); ``` -### 简化启动单个源代码文件的方法 +### var(Lambda 参数的局部变量语法) -- 增强了 Java 启动器,使其能够运行单一文件的 Java 源代码。此功能允许使用 Java 解释器直接执行 Java 源代码。源代码在内存中编译,然后由解释器执行。唯一的约束在于所有相关的类必须定义在同一个 Java 文件中 -- 对于 Java 初学者并希望尝试简单程序的人特别有用,并且能和 jshell 一起使用 -- 一定能程度上增强了使用 Java 来写脚本程序的能力 +从 Java 10 开始,便引入了局部变量类型推断这一关键特性。类型推断允许使用关键字 var 作为局部变量的类型而不是实际类型,编译器根据分配给变量的值推断出类型。 -### 用于 Lambda 参数的局部变量语法 +Java 10 中对 var 关键字存在几个限制 -- 从 Java 10 开始,便引入了局部变量类型推断这一关键特性。类型推断允许使用关键字 var 作为局部变量的类型而不是实际类型,编译器根据分配给变量的值推断出类型 -- Java 10 中对 var 关键字存在几个限制 - - 只能用于局部变量上 - - 声明时必须初始化 - - 不能用作方法参数 - - 不能在 Lambda 表达式中使用 -- Java11 开始允许开发者在 Lambda 表达式中使用 var 进行参数声明 +- 只能用于局部变量上 +- 声明时必须初始化 +- 不能用作方法参数 +- 不能在 Lambda 表达式中使用 -### 其他特性 +Java11 开始允许开发者在 Lambda 表达式中使用 var 进行参数声明。 -- 新的垃圾回收器 Epsilon,一个完全消极的 GC 实现,分配有限的内存资源,最大限度的降低内存占用和内存吞吐延迟时间 -- 低开销的 Heap Profiling:Java 11 中提供一种低开销的 Java 堆分配采样方法,能够得到堆分配的 Java 对象信息,并且能够通过 JVMTI 访问堆信息 -- TLS1.3 协议:Java 11 中包含了传输层安全性(TLS)1.3 规范(RFC 8446)的实现,替换了之前版本中包含的 TLS,包括 TLS 1.2,同时还改进了其他 TLS 功能,例如 OCSP 装订扩展(RFC 6066,RFC 6961),以及会话散列和扩展主密钥扩展(RFC 7627),在安全性和性能方面也做了很多提升 -- 飞行记录器:飞行记录器之前是商业版 JDK 的一项分析工具,但在 Java 11 中,其代码被包含到公开代码库中,这样所有人都能使用该功能了 +```java +// 下面两者是等价的 +Consumer consumer = (var i) -> System.out.println(i); +Consumer consumer = (String i) -> System.out.println(i); +``` + +### 启动单文件源代码程序 + +[JEP 330:启动单文件源代码程序(aunch Single-File Source-Code Programs)](https://openjdk.java.net/jeps/330) 可以让我们运行单一文件的 Java 源代码。此功能允许使用 Java 解释器直接执行 Java 源代码。源代码在内存中编译,然后由解释器执行,不需要在磁盘上生成 `.class` 文件了。 + +唯一的约束在于所有相关的类必须定义在同一个 Java 文件中。 + +对于 Java 初学者并希望尝试简单程序的人特别有用,并且能和 jshell 一起使用 + +一定能程度上增强了使用 Java 来写脚本程序的能力。 + +### Java11 其他新特性 + +- **新的垃圾回收器 Epsilon** :一个完全消极的 GC 实现,分配有限的内存资源,最大限度的降低内存占用和内存吞吐延迟时间 +- **低开销的 Heap Profiling** :Java 11 中提供一种低开销的 Java 堆分配采样方法,能够得到堆分配的 Java 对象信息,并且能够通过 JVMTI 访问堆信息 +- **TLS1.3 协议** :Java 11 中包含了传输层安全性(TLS)1.3 规范(RFC 8446)的实现,替换了之前版本中包含的 TLS,包括 TLS 1.2,同时还改进了其他 TLS 功能,例如 OCSP 装订扩展(RFC 6066,RFC 6961),以及会话散列和扩展主密钥扩展(RFC 7627),在安全性和性能方面也做了很多提升 +- **飞行记录器(Java Flight Recorder)** :飞行记录器之前是商业版 JDK 的一项分析工具,但在 Java 11 中,其代码被包含到公开代码库中,这样所有人都能使用该功能了。 +- ...... ## Java12 From e4bb8f845fa8a3e269597f26db3166a975822230 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 17 Aug 2021 14:39:54 +0800 Subject: [PATCH 169/257] =?UTF-8?q?[fix]=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E6=8B=BC=E6=8E=A5=E5=9B=BE=E7=89=87=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/jvm/Java内存区域.md | 2 +- .../字符串拼接-常量池.drawio | 1 + .../字符串拼接-常量池.png | Bin 0 -> 150195 bytes .../字符串拼接-常量池2.png | Bin 34188 -> 0 bytes 4 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.drawio create mode 100644 docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.png delete mode 100644 docs/java/jvm/pictures/java内存区域/字符串拼接-常量池2.png diff --git a/docs/java/jvm/Java内存区域.md b/docs/java/jvm/Java内存区域.md index 11210af1..918585a0 100644 --- a/docs/java/jvm/Java内存区域.md +++ b/docs/java/jvm/Java内存区域.md @@ -371,7 +371,7 @@ System.out.println(str3 == str5);//true System.out.println(str4 == str5);//false ``` -![字符串拼接](./pictures/java内存区域/字符串拼接-常量池2.png) +![字符串拼接](./pictures/java内存区域/字符串拼接-常量池.png) 尽量避免多个字符串拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer。 diff --git a/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.drawio b/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.drawio new file mode 100644 index 00000000..764cc0be --- /dev/null +++ b/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.drawio @@ -0,0 +1 @@ +7Vpdb6M4FP011j61AoMNPCZpZkYrrbRStZqZRxccsOLgDDhNMr9+bTAhfKSTtqG0melL8L3mYp9zbny5DXBmq93njKyTf0REOYBWtAPOHYDQti2sPrRlX1r8AJaGOGORmVQb7tlPaoyWsW5YRPPGRCkEl2zdNIYiTWkoGzaSZWLbnLYQvPnUNYlpx3AfEt61fmWRTMwuoFfbv1AWJ9WTbRyUnhWpJpud5AmJxPbI5MyBM8uEkOXVajejXINX4VLe9+mE97CwjKbynBuW6c/Zcu/fPOZp8vjfarvJ/57cmCiPhG/MhgHEXMWbLoQKq1Yt9wYK/GMjKsdNXhA1UROgs97VTnUV689cZnYVSS2pDFa6DBqHuDATmzSiepW2cm8TJun9moTau1WiUrZErrhxx5zkubk+IFoMllSGiRmYXdFM0t1JuOwDCUq9VKyozPZqirnBN7QZ3TqeGW9rFdiWsSVHCkDGRozw4kPkmht1Yeh5BlVwOKrQVVGF0dhUOcNR5V4VVcgfmyp3OKqc66LKHpsqNBxV8Kqoct2xqcI9VH0IJCFCTSitLpSOi7pQOtZQWHonZZ+vSfpy2dcWlQANd5UJZfwPlQmHMq3izxk7FfzB6WNpfLX0jV4fBAMdOo3sO8XgBzyK2gyi0ROwqlueOoxUGLbO6a9xFMrDpN6bOmMV1YzzmeAiK8I4EaH+Iiw5FUt65MGhTx8Wg59ePr6FrQOsp2yD2LvtOcKgjYaioKfNMEdgYgEfd7hQ25dN0JtopiKlLeiNiXAWp2oYKriosk81mCwkfGIcKxZF/BTLdT5ZPUSrTDTNKTu4DFlu0HptrcqKI6bcnkSBgyVKT4dBs3QHAg/MPTCZgQkGcxdMfTAtXPrCB/MA+B7wP4E5BlNbs/q7UuqgTv6hoMuqDfvzbzBi+/oR7W/ANJrodqnGWp8VLGwS1kaL7pj8Znz6+rsGWe2qHN3tDObFYG8G5UNp1Om4tvBVCxObLKRPbamcJ0kWU/mr4rnL1xEZ6ImzKKOcSPbYXG4fPeYJ/wpW1ASVfk69l1Uhym2au2qSO4Gg0wzkBK1AJQ6dQIVaDtt+hYD6uiSDCMh7MwWhMxXkj6qgdjVlv1RBsCVF/MYK6mvevFJBFxSDe6YYgnclBv9CYjjU6G8lhm576K8zaoaMqpcq8lBM0F8Ga72+YsVoCtDds6oFTh4on5JwGRc1wlGlvij+nlMfmH89mpWBA7rHQnwiKU5WE9ati3CDqOrYe6mQqiliscjpMNSe7lb9eV/uLRmx26AYj967tfs6Vh+7WnTO/Hq331W5iC9VLqK3Lhf7mmavVVCq1vSt0okeHGlID2sRFaPnq+idH/5tcXjoMuLAGF1IHGpY/5qlnF7/JsiZ/w8= \ No newline at end of file diff --git a/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.png b/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池.png new file mode 100644 index 0000000000000000000000000000000000000000..4c6f20e9508bef66557d4663479dea4781de97a7 GIT binary patch literal 150195 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

siZ`Z7(bG>kkS_+iw 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éM-Aa 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 literal 0 HcmV?d00001 diff --git a/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池2.png b/docs/java/jvm/pictures/java内存区域/字符串拼接-常量池2.png deleted file mode 100644 index b680fb60204100c6386c245a3eabc918215c9e90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34188 zcmc$_^FYwti0>2Q;NXyHs6z~KaBiIee_Dk2 zK#M|zZWay>fxWM)sjqv0qqCa>4kt+Ezh9i9!cIsZUrrE&Q&bd%LJ8V?+n@xUk-&ez zC3mE~v!kH-gi3FMSGcd*rR_PrSeBq<1z0GfHU)QxqtIYm`~-)_#X4!{@G!Oj(V(?!L}8|eFkU4boj5;-ofA54tVBGt0$lUpa0!_(*jZj6m9QpgYdR- z2QEARPmvyWZen^;#%Om{C$NSi!c-Wojs9-{4;w)Ie`}!+3?(4)-yq^JZ*4nYAB38| zu#GXyQ5UWPc6Bgx1?J=GVQc7aC+_NMYN)BHf-yAHQ`h1Y1?$57wNVIH_>KBiU7P{^ zt9g2Q=)iSR+At7APuWP)Ow9?StBaJ<^l%0AujZhtVg@$#1_vNDT~tsITWL3pIMOJ< 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 Date: Tue, 17 Aug 2021 18:17:10 +0800 Subject: [PATCH 170/257] =?UTF-8?q?Update=20=E4=B8=80=E6=96=87=E5=B8=A6?= =?UTF-8?q?=E4=BD=A0=E7=9C=8B=E9=81=8DJDK9=E5=88=B014=E7=9A=84=E9=87=8D?= =?UTF-8?q?=E8=A6=81=E6=96=B0=E7=89=B9=E6=80=A7.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 148 ++++++++++++++---- 1 file changed, 115 insertions(+), 33 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index 4354d219..552b03f0 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -415,43 +415,133 @@ Consumer consumer = (String i) -> System.out.println(i); ## Java12 -### 增强 Switch +### String -- 传统的 switch 语法存在容易漏写 break 的问题,而且从代码整洁性层面来看,多个 break 本质也是一种重复 +Java 11 增加了两个的字符串处理方法,如以下所示。 -- Java12 提供了 swtich 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break +`indent()` 方法可以实现字符串缩进。 -- 作为预览特性加入,需要在`javac`编译和`java`运行时增加参数`--enable-preview` +```java +String text = "Java"; +// 缩进 4 格 +text = text.indent(4); +System.out.println(text); +text = text.indent(-10); +System.out.println(text); +``` - ```java - switch (day) { - case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); - case TUESDAY -> System.out.println(7); - case THURSDAY, SATURDAY -> System.out.println(8); - case WEDNESDAY -> System.out.println(9); - } - ``` +输出: + +``` + Java +Java +``` + +`transform()` 方法可以用来转变指定字符串。 + +```java +String result = "foo".transform(input -> input + " bar"); +System.out.println(result); // foo bar +``` + +### 文件比较 + +Java 12 添加了以下方法来比较两个文件: + +```java +public static long mismatch(Path path, Path path2) throws IOException +``` + +`mismatch()` 方法用于比较两个文件,并返回第一个不匹配字符的位置,如果文件相同则返回 -1L。 + +代码示例(两个文件内容相同的情况): + +```java +Path filePath1 = Files.createTempFile("file1", ".txt"); +Path filePath2 = Files.createTempFile("file2", ".txt"); +Files.writeString(filePath1, "Java 12 Article"); +Files.writeString(filePath2, "Java 12 Article"); + +long mismatch = Files.mismatch(filePath1, filePath2); +assertEquals(-1, mismatch); +``` + +代码示例(两个文件内容不相同的情况): + +```java +Path filePath3 = Files.createTempFile("file3", ".txt"); +Path filePath4 = Files.createTempFile("file4", ".txt"); +Files.writeString(filePath3, "Java 12 Article"); +Files.writeString(filePath4, "Java 12 Tutorial"); + +long mismatch = Files.mismatch(filePath3, filePath4); +assertEquals(8, mismatch); +``` ### 数字格式化工具类 -- `NumberFormat` 新增了对复杂的数字进行格式化的支持 +`NumberFormat` 新增了对复杂的数字进行格式化的支持 - ```java - NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT); - String result = fmt.format(1000); - System.out.println(result); // 输出为 1K,计算工资是多少K更方便了。。。 - ``` +```java +NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT); +String result = fmt.format(1000); + System.out.println(result); // 输出为 1K,计算工资是多少K更方便了。。。 +``` ### Shenandoah GC -- Redhat 主导开发的 Pauseless GC 实现,主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等 -- 和 Java11 开源的 ZGC 相比(需要升级到 JDK11 才能使用),Shenandoah GC 有稳定的 JDK8u 版本,在 Java8 占据主要市场份额的今天有更大的可落地性 +Redhat 主导开发的 Pauseless GC 实现,主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等 + +和 Java11 开源的 ZGC 相比(需要升级到 JDK11 才能使用),Shenandoah GC 有稳定的 JDK8u 版本,在 Java8 占据主要市场份额的今天有更大的可落地性。 ### G1 收集器提升 -- **Java12 为默认的垃圾收集器 G1 带来了两项更新:** - - 可中止的混合收集集合:JEP344 的实现,为了达到用户提供的停顿时间目标,JEP 344 通过把要被回收的区域集(混合收集集合)拆分为强制和可选部分,使 G1 垃圾回收器能中止垃圾回收过程。 G1 可以中止可选部分的回收以达到停顿时间目标 - - 及时返回未使用的已分配内存:JEP346 的实现,增强 G1 GC,以便在空闲时自动将 Java 堆内存返回给操作系统 +Java12 为默认的垃圾收集器 G1 带来了两项更新: + +- **可中止的混合收集集合** :JEP344 的实现,为了达到用户提供的停顿时间目标,JEP 344 通过把要被回收的区域集(混合收集集合)拆分为强制和可选部分,使 G1 垃圾回收器能中止垃圾回收过程。 G1 可以中止可选部分的回收以达到停顿时间目标 +- **及时返回未使用的已分配内存** :JEP346 的实现,增强 G1 GC,以便在空闲时自动将 Java 堆内存返回给操作系统 + +### 预览新特性 + +作为预览特性加入,需要在`javac`编译和`java`运行时增加参数`--enable-preview` 。 + +#### 增强 Switch + +传统的 `switch` 语法存在容易漏写 `break` 的问题,而且从代码整洁性层面来看,多个 break 本质也是一种重复 + +Java12 提供了 `swtich` 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break 。 + +```java +switch (day) { + case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); + case TUESDAY -> System.out.println(7); + case THURSDAY, SATURDAY -> System.out.println(8); + case WEDNESDAY -> System.out.println(9); +} +``` + +#### instanceof 模式匹配 + +`instanceof` 主要在**类型强转前探测对象的具体类型**。 + +之前的版本中,我们需要显示地对对象进行类型转换。 + +```java +Object obj = "我是字符串"; +if(obj instanceof String){ + String str = (String) obj; + System.out.println(str); +} +``` + +新版的 `instanceof` 可以在判断是否属于具体的类型同时完成转换。 + +```java +Object obj = "我是字符串"; +if(obj instanceof String str){ + System.out.println(str); +} +``` ## Java13 @@ -599,16 +689,7 @@ switch (day) { ### instanceof 增强 -- instanceof 主要在**类型强转前探测对象的具体类型**,然后执行具体的强转 - -- 新版的 instanceof 可以在判断的是否属于具体的类型同时完成转换 - -```java -Object obj = "我是字符串"; -if(obj instanceof String str){ - System.out.println(str); -} -``` +依然是**预览特性** ,Java 12 新特性中介绍过。 ### 其他特性 @@ -640,6 +721,7 @@ if(obj instanceof String str){ - Java 11 – Features and Comparison: - Oracle Java12 ReleaseNote - Oracle Java13 ReleaseNote +- New Features in Java 12 - New Java13 Features - Java13 新特性概述 - Oracle Java14 record From e7e8d481d2c5a8a888de7cfaada10affb31356ed Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 18 Aug 2021 08:47:59 +0800 Subject: [PATCH 171/257] =?UTF-8?q?[feat]=20Java13=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 131 ++++++++++++++---- 1 file changed, 103 insertions(+), 28 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index 552b03f0..1e7ba175 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -1,5 +1,9 @@ Java 8 新特性见这里:[Java8 新特性最佳指南](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484744&idx=1&sn=9db31dca13d327678845054af75efb74&chksm=cea24a83f9d5c3956f4feb9956b068624ab2fdd6c4a75fe52d5df5dca356a016577301399548&token=1082669959&lang=zh_CN&scene=21#wechat_redirect) 。 +你可以在 [Archived OpenJDK General-Availability Releases](http://jdk.java.net/archive/) 上下载自己需要的 JDK 版本! + +官方的新特性说明文档地址: https://openjdk.java.net/projects/jdk/ 。 + _Guide 哥:别人家的特性都用了几年了,我 Java 才出来,哈哈!真实!_ ## Java9 @@ -281,11 +285,11 @@ Optional.ofNullable(cache.getIfPresent(key)) 为了最大限度地减少 Full GC 造成的应用停顿的影响,从 Java10 开始,G1 的 FullGC 改为并行的标记清除算法,同时会使用与年轻代回收和混合回收相同的并行工作线程数量,从而减少了 Full GC 的发生,以带来更好的性能提升、更大的吞吐量。 -### 应用程序类数据共享 +### 应用程序类数据共享(扩展CDS功能) -在 Java 5 中就已经引入了类数据共享机制 (Class Data Sharing,简称 CDS),允许将一组类预处理为共享归档文件,以便在运行时能够进行内存映射以减少 Java 程序的启动时间,当多个 Java 虚拟机(JVM)共享相同的归档文件时,还可以减少动态内存的占用量,同时减少多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用 +在 Java 5 中就已经引入了类数据共享机制 (Class Data Sharing,简称 CDS),允许将一组类预处理为共享归档文件,以便在运行时能够进行内存映射以减少 Java 程序的启动时间,当多个 Java 虚拟机(JVM)共享相同的归档文件时,还可以减少动态内存的占用量,同时减少多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用。CDS 在当时还是 Oracle JDK 的商业特性。 -Java 10 在现有的 CDS 功能基础上再次拓展,以允许应用类放置在共享存档中。CDS 特性在原来的 bootstrap 类基础之上,扩展加入了应用类的 CDS (Application Class-Data Sharing) 支持。其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时直接读取此启动文本并加载。设想如果应用环境没有大的变化,启动速度就会得到提升 +Java 10 在现有的 CDS 功能基础上再次拓展,以允许应用类放置在共享存档中。CDS 特性在原来的 bootstrap 类基础之上,扩展加入了应用类的 CDS 为 (Application Class-Data Sharing,AppCDS) 支持,大大加大了 CDS 的适用范围。其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时直接读取此启动文本并加载。设想如果应用环境没有大的变化,启动速度就会得到提升。 ### Java10 其他新特性 @@ -545,35 +549,25 @@ if(obj instanceof String str){ ## Java13 -### 引入 yield 关键字到 Switch 中 +### 预览新特性 -- `Switch` 表达式中就多了一个关键字用于跳出 `Switch` 块的关键字 `yield`,主要用于返回一个值 +#### 文本块 -- `yield`和 `return` 的区别在于:`return` 会直接跳出当前循环或者方法,而 `yield` 只会跳出当前 `Switch` 块,同时在使用 `yield` 时,需要有 `default` 条件 +解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本 - ```java - private static String descLanguage(String name) { - return switch (name) { - case "Java": yield "object-oriented, platform independent and secured"; - case "Ruby": yield "a programmer's best friend"; - default: yield name +" is a good language"; - }; - } - ``` +两个`"""`中间的任何内容都会被解释为字符串的一部分,包括换行符。 -### 文本块 - -- 解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本 - -- 两个`"""`中间的任何内容都会被解释为字符串的一部分,包括换行符 +未支持文本块之前的 HTML 写法: ```java String json ="{\n" + " \"name\":\"mkyong\",\n" + " \"age\":38\n" + - "}\n"; // 未支持文本块之前 + "}\n"; ``` +支持文本块之后的 HTML 写法: + ```java String json = """ @@ -584,19 +578,100 @@ if(obj instanceof String str){ """; ``` -### 增强 ZGC 释放未使用内存 +未支持文本块之前的 SQL 写法: -- 在 Java 11 中是实验性的引入的 ZGC 在实际的使用中存在未能主动将未使用的内存释放给操作系统的问题 -- ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages 区域时,它们将被释放并返回到页面缓存 **ZPageCache** 中,此缓存中的 ZPages 按最近最少使用(LRU)的顺序,并按照大小进行组织 -- 在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程重用 +```sql +String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" + + "WHERE `CITY` = 'INDIANAPOLIS'\n" + + "ORDER BY `EMP_ID`, `LAST_NAME`;\n"; +``` + +支持文本块之后的 SQL 写法: + +```sql +String query = """ + SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` + WHERE `CITY` = 'INDIANAPOLIS' + ORDER BY `EMP_ID`, `LAST_NAME`; + """; +``` + +另外,`String` 类新增加了 3 个新的方法来操作文本块: + +- `formatted(Object... args)` :它类似于 `String` 的` format() `方法。添加它是为了支持文本块的格式设置。 +- `stripIndent()` :用于去除文本块中每一行开头和结尾的空格。 +- `translateEscapes()` :转义序列如 *“\\\t”* 转换为 *“\t”* + +由于文本块是一项预览功能,可以在未来版本中删除,因此这些新方法被标记为弃用。 + +```java +@Deprecated(forRemoval=true, since="13") +public String stripIndent() { +} +@Deprecated(forRemoval=true, since="13") +public String formatted(Object... args) { + +} +@Deprecated(forRemoval=true, since="13") +public String translateEscapes() { +} +``` + +#### Switch(引入 yield 关键字到 Switch 中) + +`Switch` 表达式中就多了一个关键字用于跳出 `Switch` 块的关键字 `yield`,主要用于返回一个值 + +`yield`和 `return` 的区别在于:`return` 会直接跳出当前循环或者方法,而 `yield` 只会跳出当前 `Switch` 块,同时在使用 `yield` 时,需要有 `default` 条件 + +```java + private static String descLanguage(String name) { + return switch (name) { + case "Java": yield "object-oriented, platform independent and secured"; + case "Ruby": yield "a programmer's best friend"; + default: yield name +" is a good language"; + }; + } +``` + +### 增强 ZGC(释放未使用内存) + +在 Java 11 中是实验性的引入的 ZGC 在实际的使用中存在未能主动将未使用的内存释放给操作系统的问题。 + +ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages 区域时,它们将被释放并返回到页面缓存 **ZPageCache** 中,此缓存中的 ZPages 按最近最少使用(LRU)的顺序,并按照大小进行组织。 + +在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程重用。 ### SocketAPI 重构 -- Java 13 为 Socket API 带来了新的底层实现方法,并且在 Java 13 中是默认使用新的 Socket 实现,使其易于发现并在排除问题同时增加可维护性 +Java Socket API 终于迎来了重大更新! -### 动态应用程序类-数据共享 +Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 ``PlainSocketImpl`` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`。 -- Java 13 中对 Java 10 中引入的 应用程序类数据共享进行了进一步的简化、改进和扩展,即:**允许在 Java 应用程序执行结束时动态进行类归档**,具体能够被归档的类包括:所有已被加载,但不属于默认基层 CDS 的应用程序类和引用类库中的类 +并且,在 Java 13 中是默认使用新的 Socket 实现,使其易于发现并在排除问题同时增加可维护性 + +```java +public final class NioSocketImpl extends SocketImpl implements PlatformSocketImpl { +} +``` + +### FileSystems + +`FileSystems` 类中添加了以下三种新方法,以便更容易地使用将文件内容视为文件系统的文件系统提供程序: + +- `newFileSystem(Path)` +- `newFileSystem(Path, Map)` +- `newFileSystem(Path, Map, ClassLoader)` + +### 动态 CDS 存档 + +Java 13 中对 Java 10 中引入的应用程序类数据共享(AppCDS)进行了进一步的简化、改进和扩展,即:**允许在 Java 应用程序执行结束时动态进行类归档**,具体能够被归档的类包括所有已被加载,但不属于默认基层 CDS 的应用程序类和引用类库中的类。 + +这提高了应用程序类数据共享([AppCDS](https://openjdk.java.net/jeps/310))的可用性。无需用户进行试运行来为每个应用程序创建类列表。 + +```bash +$ java -XX:ArchiveClassesAtExit=my_app_cds.jsa -cp my_app.jar +$ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar +``` ## Java14 From 801c2200fc2262f8515e752d114228a8905d99bd Mon Sep 17 00:00:00 2001 From: guide Date: Wed, 18 Aug 2021 09:36:54 +0800 Subject: [PATCH 172/257] =?UTF-8?q?[feat]=20Java14=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 250 ++++++++++-------- 1 file changed, 137 insertions(+), 113 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index 1e7ba175..cb0669f3 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -285,7 +285,7 @@ Optional.ofNullable(cache.getIfPresent(key)) 为了最大限度地减少 Full GC 造成的应用停顿的影响,从 Java10 开始,G1 的 FullGC 改为并行的标记清除算法,同时会使用与年轻代回收和混合回收相同的并行工作线程数量,从而减少了 Full GC 的发生,以带来更好的性能提升、更大的吞吐量。 -### 应用程序类数据共享(扩展CDS功能) +### 应用程序类数据共享(扩展 CDS 功能) 在 Java 5 中就已经引入了类数据共享机制 (Class Data Sharing,简称 CDS),允许将一组类预处理为共享归档文件,以便在运行时能够进行内存映射以减少 Java 程序的启动时间,当多个 Java 虚拟机(JVM)共享相同的归档文件时,还可以减少动态内存的占用量,同时减少多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用。CDS 在当时还是 Oracle JDK 的商业特性。 @@ -513,7 +513,7 @@ Java12 为默认的垃圾收集器 G1 带来了两项更新: 传统的 `switch` 语法存在容易漏写 `break` 的问题,而且从代码整洁性层面来看,多个 break 本质也是一种重复 -Java12 提供了 `swtich` 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break 。 +Java12 增强了 `swtich` 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break 。 ```java switch (day) { @@ -553,30 +553,30 @@ if(obj instanceof String str){ #### 文本块 -解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本 +解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本。 -两个`"""`中间的任何内容都会被解释为字符串的一部分,包括换行符。 +Java 13 支持两个 `"""` 符号中间的任何内容都会被解释为字符串的一部分,包括换行符。 未支持文本块之前的 HTML 写法: - ```java - String json ="{\n" + - " \"name\":\"mkyong\",\n" + - " \"age\":38\n" + - "}\n"; - ``` +```java +String json ="{\n" + + " \"name\":\"mkyong\",\n" + + " \"age\":38\n" + + "}\n"; +``` 支持文本块之后的 HTML 写法: - ```java - - String json = """ - { - "name":"mkyong", - "age":38 - } - """; - ``` +```java + + String json = """ + { + "name":"mkyong", + "age":38 + } + """; +``` 未支持文本块之前的 SQL 写法: @@ -598,9 +598,9 @@ String query = """ 另外,`String` 类新增加了 3 个新的方法来操作文本块: -- `formatted(Object... args)` :它类似于 `String` 的` format() `方法。添加它是为了支持文本块的格式设置。 +- `formatted(Object... args)` :它类似于 `String` 的`format()`方法。添加它是为了支持文本块的格式设置。 - `stripIndent()` :用于去除文本块中每一行开头和结尾的空格。 -- `translateEscapes()` :转义序列如 *“\\\t”* 转换为 *“\t”* +- `translateEscapes()` :转义序列如 _“\\\t”_ 转换为 _“\t”_ 由于文本块是一项预览功能,可以在未来版本中删除,因此这些新方法被标记为弃用。 @@ -610,14 +610,14 @@ public String stripIndent() { } @Deprecated(forRemoval=true, since="13") public String formatted(Object... args) { - + } @Deprecated(forRemoval=true, since="13") public String translateEscapes() { } ``` -#### Switch(引入 yield 关键字到 Switch 中) +#### 增强 Switch(引入 yield 关键字到 Switch 中) `Switch` 表达式中就多了一个关键字用于跳出 `Switch` 块的关键字 `yield`,主要用于返回一个值 @@ -645,7 +645,7 @@ ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages Java Socket API 终于迎来了重大更新! -Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 ``PlainSocketImpl`` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`。 +Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 `PlainSocketImpl` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`。 并且,在 Java 13 中是默认使用新的 Socket 实现,使其易于发现并在排除问题同时增加可维护性 @@ -675,120 +675,143 @@ $ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar ## Java14 -### record 关键字 - -- 简化数据类的定义方式,使用 record 代替 class 定义的类,只需要声明属性,就可以在获得属性的访问方法,以及 toString,hashCode,equals 方法 - -- 类似于使用 Class 定义类,同时使用了 lomobok 插件,并打上了`@Getter,@ToString,@EqualsAndHashCode`注解 - -- 作为预览特性引入 - - ```java - /** - * 这个类具有两个特征 - * 1. 所有成员属性都是final - * 2. 全部方法由构造方法,和两个成员属性访问器组成(共三个) - * 那么这种类就很适合使用record来声明 - */ - final class Rectangle implements Shape { - final double length; - final double width; - - public Rectangle(double length, double width) { - this.length = length; - this.width = width; - } - - double length() { return length; } - double width() { return width; } - } - /** - * 1. 使用record声明的类会自动拥有上面类中的三个方法 - * 2. 在这基础上还附赠了equals(),hashCode()方法以及toString()方法 - * 3. toString方法中包括所有成员属性的字符串表示形式及其名称 - */ - record Rectangle(float length, float width) { } - ``` - ### 空指针异常精准提示 -- 通过 JVM 参数中添加`-XX:+ShowCodeDetailsInExceptionMessages`,可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题 - - ```java - a.b.c.i = 99; // 假设这段代码会发生空指针 - ``` - - ```java - Exception in thread "main" java.lang.NullPointerException: - Cannot read field 'c' because 'a.b' is null. - at Prog.main(Prog.java:5) // 增加参数后提示的异常中很明确的告知了哪里为空导致 - ``` - -### switch 的增强终于转正 - -- JDK12 引入的 switch(预览特性)在 JDK14 变为正式版本,不需要增加参数来启用,直接在 JDK14 中就能使用 -- 主要是用`->`来替代以前的`:`+`break`;另外就是提供了 yield 来在 block 中返回值 - -_Before Java 14_ +通过 JVM 参数中添加`-XX:+ShowCodeDetailsInExceptionMessages`,可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题。 ```java -switch (day) { - case MONDAY: - case FRIDAY: - case SUNDAY: - System.out.println(6); - break; - case TUESDAY: - System.out.println(7); - break; - case THURSDAY: - case SATURDAY: - System.out.println(8); - break; - case WEDNESDAY: - System.out.println(9); - break; -} +a.b.c.i = 99; // 假设这段代码会发生空指针 ``` -_Java 14 enhancements_ +Java 14 之前: ```java -switch (day) { - case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); - case TUESDAY -> System.out.println(7); - case THURSDAY, SATURDAY -> System.out.println(8); - case WEDNESDAY -> System.out.println(9); -} +Exception in thread "main" java.lang.NullPointerException + at NullPointerExample.main(NullPointerExample.java:5) ``` -### instanceof 增强 +Java 14 之后: + +```java + // 增加参数后提示的异常中很明确的告知了哪里为空导致 +Exception in thread "main" java.lang.NullPointerException: + Cannot read field 'c' because 'a.b' is null. + at Prog.main(Prog.java:5) +``` + +### switch 的增强(转正) + +Java12 引入的 switch(预览特性)在 Java14 变为正式版本,不需要增加参数来启用,直接在 JDK14 中就能使用。 + +Java12 为 switch 表达式引入了类似 lambda 语法条件匹配成功后的执行块,不需要多写 break ,Java13 提供了 `yield` 来在 block 中返回值。 + +```java +String result = switch (day) { + case "M", "W", "F" -> "MWF"; + case "T", "TH", "S" -> "TTS"; + default -> { + if(day.isEmpty()) + yield "Please insert a valid day."; + else + yield "Looks like a Sunday."; + } + + }; +System.out.println(result); +``` + +### 预览新特性 + +#### record 关键字 + +简化数据类的定义方式,使用 `record` 代替 `class` 定义的类,只需要声明属性,就可以在获得属性的访问方法,以及 `toString()`,`hashCode()`, `equals()`方法 + +类似于使用 `class` 定义类,同时使用了 lomobok 插件,并打上了`@Getter,@ToString,@EqualsAndHashCode`注解 + +```java +/** + * 这个类具有两个特征 + * 1. 所有成员属性都是final + * 2. 全部方法由构造方法,和两个成员属性访问器组成(共三个) + * 那么这种类就很适合使用record来声明 + */ +final class Rectangle implements Shape { + final double length; + final double width; + + public Rectangle(double length, double width) { + this.length = length; + this.width = width; + } + + double length() { return length; } + double width() { return width; } +} +/** + * 1. 使用record声明的类会自动拥有上面类中的三个方法 + * 2. 在这基础上还附赠了equals(),hashCode()方法以及toString()方法 + * 3. toString方法中包括所有成员属性的字符串表示形式及其名称 + */ +record Rectangle(float length, float width) { } +``` + +#### 文本块 + +Java14 中,文本块依然是预览特性,不过,其引入了两个新的转义字符: + +- `\` : 表示行尾,不引入换行符 +- `\s` :表示单个空格 + +```java +String str = "凡心所向,素履所往,生如逆旅,一苇以航。"; + +String str2 = """ + 凡心所向,素履所往, \ + 生如逆旅,一苇以航。"""; +System.out.println(str2);// 凡心所向,素履所往, 生如逆旅,一苇以航。 +String text = """ + java + c++\sphp + """; +System.out.println(text); +//输出: +java +c++ php +``` + +#### instanceof 增强 依然是**预览特性** ,Java 12 新特性中介绍过。 -### 其他特性 +### Java14 其他特性 - 从 Java11 引入的 ZGC 作为继 G1 过后的下一代 GC 算法,从支持 Linux 平台到 Java14 开始支持 MacOS 和 Window(个人感觉是终于可以在日常开发工具中先体验下 ZGC 的效果了,虽然其实 G1 也够用) -- 移除了 CMS 垃圾收集器(功成而退) +- 移除了 CMS(Concurrent Mark Sweep) 垃圾收集器(功成而退) - 新增了 jpackage 工具,标配将应用打成 jar 包外,还支持不同平台的特性包,比如 linux 下的`deb`和`rpm`,window 平台下的`msi`和`exe` ## 总结 ### 关于预览特性 -- 先贴一段 oracle 官网原文:`This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.` -- 这是一个预览功能,该功能的设计,规格和实现是完整的,但不是永久性的,这意味着该功能可能以其他形式存在或在将来的 JDK 版本中根本不存在。 要编译和运行包含预览功能的代码,必须指定其他命令行选项。 -- 就以`switch`的增强为例子,从 Java12 中推出,到 Java13 中将继续增强,直到 Java14 才正式转正进入 JDK 可以放心使用,不用考虑后续 JDK 版本对其的改动或修改 -- 一方面可以看出 JDK 作为标准平台在增加新特性的严谨态度,另一方面个人认为是对于预览特性应该采取审慎使用的态度。特性的设计和实现容易,但是其实际价值依然需要在使用中去验证 +先贴一段 oracle 官网原文:`This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.` + +这是一个预览功能,该功能的设计,规格和实现是完整的,但不是永久性的,这意味着该功能可能以其他形式存在或在将来的 JDK 版本中根本不存在。 要编译和运行包含预览功能的代码,必须指定其他命令行选项。 + +就以`switch`的增强为例子,从 Java12 中推出,到 Java13 中将继续增强,直到 Java14 才正式转正进入 JDK 可以放心使用,不用考虑后续 JDK 版本对其的改动或修改 + +一方面可以看出 JDK 作为标准平台在增加新特性的严谨态度,另一方面个人认为是对于预览特性应该采取审慎使用的态度。特性的设计和实现容易,但是其实际价值依然需要在使用中去验证 ### JVM 虚拟机优化 -- 每次 Java 版本的发布都伴随着对 JVM 虚拟机的优化,包括对现有垃圾回收算法的改进,引入新的垃圾回收算法,移除老旧的不再适用于今天的垃圾回收算法等 -- 整体优化的方向是**高效,低时延的垃圾回收表现** -- 对于日常的应用开发者可能比较关注新的语法特性,但是从一个公司角度来说,在考虑是否升级 Java 平台时更加考虑的是**JVM 运行时的提升** +每次 Java 版本的发布都伴随着对 JVM 虚拟机的优化,包括对现有垃圾回收算法的改进,引入新的垃圾回收算法,移除老旧的不再适用于今天的垃圾回收算法等 -## 参考信息 +整体优化的方向是**高效,低时延的垃圾回收表现** +对于日常的应用开发者可能比较关注新的语法特性,但是从一个公司角度来说,在考虑是否升级 Java 平台时更加考虑的是**JVM 运行时的提升** + +## 参考资料 + +- JDK Project Overview : - IBM Developer Java9 - Guide to Java10 - Java 10 新特性介绍 @@ -800,4 +823,5 @@ switch (day) { - New Java13 Features - Java13 新特性概述 - Oracle Java14 record -- java14-features \ No newline at end of file +- java14-features +- Java 14 Features : \ No newline at end of file From 7f853ef42f13a3ca7572ee7a6392bf2ab78e98fd Mon Sep 17 00:00:00 2001 From: ObSob <32333557+ObSob@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:44:36 +0800 Subject: [PATCH 173/257] Update zookeeper-plus.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit typo: 应为Atomic --- .../distributed-system/zookeeper/zookeeper-plus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md b/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md index 44b5abf6..ef37abb3 100644 --- a/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md +++ b/docs/system-design/distributed-system/zookeeper/zookeeper-plus.md @@ -184,7 +184,7 @@ ### 5.1. `Zookeeper` 架构 -作为一个优秀高效且可靠的分布式协调框架,`ZooKeeper` 在解决分布式数据一致性问题时并没有直接使用 `Paxos` ,而是专门定制了一致性协议叫做 `ZAB(ZooKeeper Automic Broadcast)` 原子广播协议,该协议能够很好地支持 **崩溃恢复** 。 +作为一个优秀高效且可靠的分布式协调框架,`ZooKeeper` 在解决分布式数据一致性问题时并没有直接使用 `Paxos` ,而是专门定制了一致性协议叫做 `ZAB(ZooKeeper Atomic Broadcast)` 原子广播协议,该协议能够很好地支持 **崩溃恢复** 。 ![Zookeeper架构](https://img-blog.csdnimg.cn/img_convert/0c38d08ea026e25bf3849cc7654a4e79.png) From 1bfc5c14abbaa2571da57e5273176490043aff9f Mon Sep 17 00:00:00 2001 From: guide Date: Fri, 20 Aug 2021 17:07:47 +0800 Subject: [PATCH 174/257] =?UTF-8?q?[feat]Java=2015=20=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- ...要新特性.md => java新特性总结.md} | 207 ++++++++++++++---- docs/system-design/naming.md | 93 +++++--- 3 files changed, 230 insertions(+), 72 deletions(-) rename docs/java/new-features/{一文带你看遍JDK9到14的重要新特性.md => java新特性总结.md} (90%) diff --git a/README.md b/README.md index eca328cc..4b4e7557 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle ### 新特性 1. **Java 8** :[Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md) 、[Java 8 学习资源推荐](docs/java/new-features/Java8教程推荐.md)、[Java8 forEach 指南](docs/java/new-features/Java8foreach指南.md) -2. **Java9~Java14** : [一文带你看遍 JDK9~14 的重要新特性!](./docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md) +2. **Java9~Java15** : [一文带你看遍 JDK9~15 的重要新特性!](./docs/java/new-features/java新特性总结.md) ## 计算机基础 diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/java新特性总结.md similarity index 90% rename from docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md rename to docs/java/new-features/java新特性总结.md index cb0669f3..c815fa1a 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/java新特性总结.md @@ -336,7 +336,7 @@ var op = Optional.empty(); System.out.println(op.isEmpty());//判断指定的 Optional 对象是否为空 ``` -### ZGC:可伸缩低延迟垃圾收集器 +### ZGC(可伸缩低延迟垃圾收集器) **ZGC 即 Z Garbage Collector**,是一个可伸缩的、低延迟的垃圾收集器。 @@ -549,6 +549,46 @@ if(obj instanceof String str){ ## Java13 +### 增强 ZGC(释放未使用内存) + +在 Java 11 中是实验性的引入的 ZGC 在实际的使用中存在未能主动将未使用的内存释放给操作系统的问题。 + +ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages 区域时,它们将被释放并返回到页面缓存 **ZPageCache** 中,此缓存中的 ZPages 按最近最少使用(LRU)的顺序,并按照大小进行组织。 + +在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程重用。 + +### SocketAPI 重构 + +Java Socket API 终于迎来了重大更新! + +Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 `PlainSocketImpl` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`。 + +并且,在 Java 13 中是默认使用新的 Socket 实现。 + +```java +public final class NioSocketImpl extends SocketImpl implements PlatformSocketImpl { +} +``` + +### FileSystems + +`FileSystems` 类中添加了以下三种新方法,以便更容易地使用将文件内容视为文件系统的文件系统提供程序: + +- `newFileSystem(Path)` +- `newFileSystem(Path, Map)` +- `newFileSystem(Path, Map, ClassLoader)` + +### 动态 CDS 存档 + +Java 13 中对 Java 10 中引入的应用程序类数据共享(AppCDS)进行了进一步的简化、改进和扩展,即:**允许在 Java 应用程序执行结束时动态进行类归档**,具体能够被归档的类包括所有已被加载,但不属于默认基层 CDS 的应用程序类和引用类库中的类。 + +这提高了应用程序类数据共享([AppCDS](https://openjdk.java.net/jeps/310))的可用性。无需用户进行试运行来为每个应用程序创建类列表。 + +```bash +$ java -XX:ArchiveClassesAtExit=my_app_cds.jsa -cp my_app.jar +$ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar +``` + ### 预览新特性 #### 文本块 @@ -569,7 +609,6 @@ String json ="{\n" + 支持文本块之后的 HTML 写法: ```java - String json = """ { "name":"mkyong", @@ -633,46 +672,6 @@ public String translateEscapes() { } ``` -### 增强 ZGC(释放未使用内存) - -在 Java 11 中是实验性的引入的 ZGC 在实际的使用中存在未能主动将未使用的内存释放给操作系统的问题。 - -ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages 区域时,它们将被释放并返回到页面缓存 **ZPageCache** 中,此缓存中的 ZPages 按最近最少使用(LRU)的顺序,并按照大小进行组织。 - -在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程重用。 - -### SocketAPI 重构 - -Java Socket API 终于迎来了重大更新! - -Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 `PlainSocketImpl` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`。 - -并且,在 Java 13 中是默认使用新的 Socket 实现,使其易于发现并在排除问题同时增加可维护性 - -```java -public final class NioSocketImpl extends SocketImpl implements PlatformSocketImpl { -} -``` - -### FileSystems - -`FileSystems` 类中添加了以下三种新方法,以便更容易地使用将文件内容视为文件系统的文件系统提供程序: - -- `newFileSystem(Path)` -- `newFileSystem(Path, Map)` -- `newFileSystem(Path, Map, ClassLoader)` - -### 动态 CDS 存档 - -Java 13 中对 Java 10 中引入的应用程序类数据共享(AppCDS)进行了进一步的简化、改进和扩展,即:**允许在 Java 应用程序执行结束时动态进行类归档**,具体能够被归档的类包括所有已被加载,但不属于默认基层 CDS 的应用程序类和引用类库中的类。 - -这提高了应用程序类数据共享([AppCDS](https://openjdk.java.net/jeps/310))的可用性。无需用户进行试运行来为每个应用程序创建类列表。 - -```bash -$ java -XX:ArchiveClassesAtExit=my_app_cds.jsa -cp my_app.jar -$ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar -``` - ## Java14 ### 空指针异常精准提示 @@ -789,6 +788,127 @@ c++ php - 移除了 CMS(Concurrent Mark Sweep) 垃圾收集器(功成而退) - 新增了 jpackage 工具,标配将应用打成 jar 包外,还支持不同平台的特性包,比如 linux 下的`deb`和`rpm`,window 平台下的`msi`和`exe` +## Java15 + +### CharSequence + +`CharSequence` 接口添加了一个默认方法 `isEmpty()` 来判断字符序列为空,如果是则返回 true。 + +```java +public interface CharSequence { + default boolean isEmpty() { + return this.length() == 0; + } +} +``` + +### TreeMap + +`TreeMap` 新引入了下面这些方法: + +- `putIfAbsent()` +- `computeIfAbsent()` +- `computeIfPresent()` +- `compute()` +- `merge()` + +### ZGC(转正) + +Java11 的时候 ,ZGC 还在试验阶段。 + +当时,ZGC 的出现让众多 Java 开发者看到了垃圾回收器的另外一种可能,因此备受关注。 + +经过多个版本的迭代,不断的完善和修复问题,ZGC 在 Java 15 已经可以正式使用了! + +不过,默认的垃圾回收器依然是 G1。你可以通过下面的参数启动 ZGC: + +```bash +$ java -XX:+UseZGC className +``` + +### EdDSA(数字签名算法) + +新加入了一个安全性和性能都更强的基于 Edwards-Curve Digital Signature Algorithm (EdDSA)实现的数字签名算法。 + +虽然其性能优于现有的 ECDSA 实现,不过,它并不会完全取代 JDK 中现有的椭圆曲线数字签名算法( ECDSA)。 + +```java +KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519"); +KeyPair kp = kpg.generateKeyPair(); + +byte[] msg = "test_string".getBytes(StandardCharsets.UTF_8); + +Signature sig = Signature.getInstance("Ed25519"); +sig.initSign(kp.getPrivate()); +sig.update(msg); +byte[] s = sig.sign(); + +String encodedString = Base64.getEncoder().encodeToString(s); +System.out.println(encodedString); +``` + +输出: + +``` +0Hc0lxxASZNvS52WsvnncJOH/mlFhnA8Tc6D/k5DtAX5BSsNVjtPF4R4+yMWXVjrvB2mxVXmChIbki6goFBgAg== +``` + +### 文本块(转正) + +在 Java 15 ,文本块是正式的功能特性了。 + +### 隐藏类(Hidden Classes) + +隐藏类是为框架(frameworks)所设计的,隐藏类不能直接被其他类的字节码使用,只能在运行时生成类并通过反射间接使用它们。 + +### 预览新特性 + +#### record 关键字 + +Java 15 对 Java 14 中引入的预览新特性进行了增强,主要是引入了一个新的概念 **密封类(Sealed Classes)。** + +密封类可以对继承或者实现它们的类进行限制。 + +比如抽象类 `Person` 只允许 `Employee` 和 `Manager` 继承。 + +```java +public abstract sealed class Person + permits Employee, Manager { + + //... +} +``` + +另外,任何扩展密封类的类本身都必须声明为 `sealed`、`non-sealed` 或 `final`。 + +```java +public final class Employee extends Person { +} + +public non-sealed class Manager extends Person { +} +``` + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20210820153955587.png) + +在 `java.lang.Class` 增加了两个公共方法用于获取 `Record` 类信息: + +1. `RecordComponent[] getRecordComponents()` +2. `boolean isRecord()` + +#### instanceof 模式匹配 + +Java 15 并没有对此特性进行调整,继续预览特性,主要用于接受更多的使用反馈。 + +在未来的 Java 版本中,Java 的目标是继续完善 `instanceof` 模式匹配新特性。 + +### Java15 其他新特性 + +- **Nashorn JavaScript 引擎彻底移除** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性。在 Java 11 中就已经被弃用,到了 Java 15 就彻底被删除了。 +- **DatagramSocket API 重构** +- **禁用和废弃偏向锁(Biased Locking)** : 偏向锁的引入增加了 JVM 的复杂性大于其带来的性能提升。不过,你仍然可以使用 `-XX:+UseBiasedLocking` 启用偏向锁定,但它会提示 这是一个已弃用的 API。 +- ...... + ## 总结 ### 关于预览特性 @@ -824,4 +944,5 @@ c++ php - Java13 新特性概述 - Oracle Java14 record - java14-features -- Java 14 Features : \ No newline at end of file +- Java 14 Features : +- What is new in Java 15: https://mkyong.com/java/what-is-new-in-java-15/ \ No newline at end of file diff --git a/docs/system-design/naming.md b/docs/system-design/naming.md index 33d0db49..33579c91 100644 --- a/docs/system-design/naming.md +++ b/docs/system-design/naming.md @@ -1,14 +1,42 @@ -编程过程中,有太多太多让我们头疼的事情了,比如命名、维护其他人的代码、写测试、与其他人沟通交流等等。就连世界级软件大师 **Martin Fowler** 大神都说过 CS 领域有两大最难的事情,一是**缓存失效**,一是**程序命名**(@ [https://martinfowler.com/bliki/TwoHardThings.html](https://martinfowler.com/bliki/TwoHardThings.html))。 +> 可选标题:工作半年,变量命名不规范,被diss了! +> +> 项目组新来的实习生因为变量命名被 “diss” 了! -![](pictures/marting-naming.png) +大家好,这里是热爱分享的 Guide ! -今天 Guide 就单独拎出 “**命名**” 来聊聊,据说之前在 Quora 网站,由接近 5000 名程序员票选出来的最难的事情就是“命名”。 +我还记得我刚工作那一段时间, 项目 Code Review 的时候,我经常因为变量命名不规范而被 “diss”! + +究其原因还是自己那会经验不足,而且,大学那会写项目的时候不太注意这些问题,想着只要把功能实现出来就行了。 + +但是,工作中就不一样,为了代码的可读性、可维护性,项目组对于代码质量的要求还是很高的! + +前段时间,项目组新来的一个实习生也经常在 Code Review 因为变量命名不规范而被 “diss”,这让我想到自己刚到公司写代码那会的日子。 + +于是,我就简单写了这篇关于变量命名规范的文章,希望能对同样有此困扰的小伙伴提供一些帮助。 + +确实,编程过程中,有太多太多让我们头疼的事情了,比如命名、维护其他人的代码、写测试、与其他人沟通交流等等。 + +据说之前在 Quora 网站,由接近 5000 名程序员票选出来的最难的事情就是“命名”。 + +大名鼎鼎的《重构》的作者老马(Martin Fowler)曾经在[TwoHardThings](https://martinfowler.com/bliki/TwoHardThings.html)这篇文章中提到过CS 领域有两大最难的事情:一是 **缓存失效** ,一是 **程序命名** 。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/marting-naming.png) + +这个句话实际上也是老马引用别人的,类似的表达还有很多。比如分布式系统领域有两大最难的事情:一是 **保证消息顺序** ,一是 **严格一次传递** 。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/20210629104844645.png) + +今天咱们就单独拎出 “**命名**” 来聊聊! 这篇文章配合我之前发的 [《编码 5 分钟,命名 2 小时?史上最全的 Java 命名规范参考!》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486449&idx=1&sn=c3b502529ff991c7180281bcc22877af&chksm=cea2443af9d5cd2c1c87049ed15ccf6f88275419c7dbe542406166a703b27d0f3ecf2af901f8&token=999884676&lang=zh_CN#rd) 这篇文章阅读效果更佳哦! ## 为什么需要重视命名? -**好的命名即是注释,别人一看到你的命名就知道你的变量、方法或者类是做什么的!** 好的命名对于其他人(包括你自己)理解你的代码有着很大的帮助! +咱们需要先搞懂为什么要重视编程中的命名这一行为,它对于我们的编码工作有着什么意义。 + +**为什么命名很重要呢?** 这是因为 **好的命名即是注释,别人一看到你的命名就知道你的变量、方法或者类是做什么的!** + +简单来说就是 **别人根据你的命名就能知道你的代码要表达的意思** (不过,前提这个人也要有基本的英语知识,对于一些编程中常见的单词比较熟悉)。 简单举个例子说明一下命名的重要性。 @@ -64,7 +92,9 @@ serviceDiscovery、Serviceinstance、LRUCacheFactory 正例: ```java -getUserInfo()、createCustomThreadPool()、setNameFormat(String nameFormat) +getUserInfo() +createCustomThreadPool() +setNameFormat(String nameFormat) Uservice userService; ``` @@ -81,7 +111,9 @@ Uservice user_service 在蛇形命名法中,各个单词之间通过下划线“\_”连接,比如`should_get_200_status_code_when_request_is_valid`、`CLIENT_CONNECT_SERVER_FAILURE`。 -蛇形命名法的优势是命名所需要的单词比较多的时候,比如我把上面的命名通过小驼峰命名法给大家看一下:“shouldGet200StatusCodoWhenRequestIsValid”。**感觉如何? 相比于使用蛇形命名法(snake_case)来说是不是不那么易读?\*\*** +蛇形命名法的优势是命名所需要的单词比较多的时候,比如我把上面的命名通过小驼峰命名法给大家看一下:“shouldGet200StatusCodoWhenRequestIsValid”。 + +感觉如何? 相比于使用蛇形命名法(snake_case)来说是不是不那么易读? 正例: @@ -103,29 +135,29 @@ void shouldGet200StatusCodoWhenRequestIsValid() { ### 串式命名法(kebab-case) -在串式命名法中,各个单词之间通过下划线“-”连接,比如`dubbo-registry`。 +在串式命名法中,各个单词之间通过连接符“-”连接,比如`dubbo-registry`。 建议项目文件夹名称使用串式命名法(kebab-case),比如 dubbo 项目的各个模块的命名是下面这样的。 -![](./pictures/dubbo-naming.png) +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/dubbo-naming.png) ## 常见命名规范 ### Java 语言基本命名规范 -**1.类名需要使用大驼峰命名法(UpperCamelCase)风格。方法名、参数名、成员变量、局部变量需要使用小驼峰命名法(lowerCamelCase)。** +**1、类名需要使用大驼峰命名法(UpperCamelCase)风格。方法名、参数名、成员变量、局部变量需要使用小驼峰命名法(lowerCamelCase)。** -**2.测试方法名、常量、枚举名称需要使用蛇形命名法(snake_case)**,比如`should_get_200_status_code_when_request_is_valid`、`CLIENT_CONNECT_SERVER_FAILURE`。并且,**测试方法名称要求全部小写,常量以及枚举名称需要全部大写。** +**2、测试方法名、常量、枚举名称需要使用蛇形命名法(snake_case)**,比如`should_get_200_status_code_when_request_is_valid`、`CLIENT_CONNECT_SERVER_FAILURE`。并且,**测试方法名称要求全部小写,常量以及枚举名称需要全部大写。** -**3.项目文件夹名称使用串式命名法(kebab-case),比如`dubbo-registry`。** +**3、项目文件夹名称使用串式命名法(kebab-case),比如`dubbo-registry`。** -**4.包名统一使用小写,尽量使用单个名词作为包名,各个单词通过 "." 分隔符连接,并且各个单词必须为单数。** +**4、包名统一使用小写,尽量使用单个名词作为包名,各个单词通过 "." 分隔符连接,并且各个单词必须为单数。** 正例: `org.apache.dubbo.common.threadlocal` 反例: ~~`org.apache_dubbo.Common.threadLocals`~~ -**5.抽象类命名使用 Abstract 开头**。 +**5、抽象类命名使用 Abstract 开头**。 ```java //为远程传输部分抽象出来的一个抽象类(出处:Dubbo源码) @@ -134,7 +166,7 @@ public abstract class AbstractClient extends AbstractEndpoint implements Client } ``` -**6.异常类命名使用 Exception 结尾。** +**6、异常类命名使用 Exception 结尾。** ```java //自定义的 NoSuchMethodException(出处:Dubbo源码) @@ -151,7 +183,7 @@ public class NoSuchMethodException extends RuntimeException { } ``` -**7.测试类命名以它要测试的类的名称开始,以 Test 结尾。** +**7、测试类命名以它要测试的类的名称开始,以 Test 结尾。** ```java //为 AnnotationUtils 类写的测试类(出处:Dubbo源码) @@ -166,19 +198,19 @@ POJO 类中布尔类型的变量,都不要加 is 前缀,否则部分框架 ### 命名易读性规范 -**1.为了能让命名更加易懂和易读,尽量不要缩写/简写单词,除非这些单词已经被公认可以被这样缩写/简写。比如 `CustomThreadFactory` 不可以被写成 ~~`CustomTF` 。** +**1、为了能让命名更加易懂和易读,尽量不要缩写/简写单词,除非这些单词已经被公认可以被这样缩写/简写。比如 `CustomThreadFactory` 不可以被写成 ~~`CustomTF` 。** -**2.命名不像函数一样要尽量追求短,可读性强的名字优先于简短的名字,虽然可读性强的名字会比较长一点。** 这个对应我们上面说的第 1 点。 +**2、命名不像函数一样要尽量追求短,可读性强的名字优先于简短的名字,虽然可读性强的名字会比较长一点。** 这个对应我们上面说的第 1 点。 -**3.避免无意义的命名,你起的每一个名字都要能表明意思。** +**3、避免无意义的命名,你起的每一个名字都要能表明意思。** 正例:`UserService userService;` `int userCount`; 反例: ~~`UserService service`~~ ~~`int count`~~ -**4.避免命名过长(50 个字符以内最好),过长的命名难以阅读并且丑陋。** +**4、避免命名过长(50 个字符以内最好),过长的命名难以阅读并且丑陋。** -5.**不要使用拼音,更不要使用中文。** 注意:像 alibaba 、wuhan、taobao 这种国际通用名词可以当做英文来看待。 +**5、不要使用拼音,更不要使用中文。** 不过像 alibaba 、wuhan、taobao 这种国际通用名词可以当做英文来看待。 正例:discount @@ -186,7 +218,7 @@ POJO 类中布尔类型的变量,都不要加 is 前缀,否则部分框架 ## Codelf:变量命名神器? -这是一个由国人开发的网站,网上有很多人称其为变量命名神器, Guide 在实际使用了几天之后感觉没那么好用。小伙伴们可以自行体验一下,然后再给出自己的判断。 +这是一个由国人开发的网站,网上有很多人称其为变量命名神器, 我在实际使用了几天之后感觉没那么好用。小伙伴们可以自行体验一下,然后再给出自己的判断。 Codelf 提供了在线网站版本,网址:[https://unbug.github.io/codelf/](https://unbug.github.io/codelf/),具体使用情况如下: @@ -198,17 +230,22 @@ Codelf 提供了在线网站版本,网址:[https://unbug.github.io/codelf/]( ![](pictures/vscode-codelf.png) -## 总结 - -Guide 制作了一个涵盖上面所有重要内容的思维导图,便于小伙伴们日后查阅。 - -![](pictures/naming-mindmap.png) - -## 其他推荐阅读 +## 相关阅读推荐 1. 《阿里巴巴 Java 开发手册》 2. 《Clean Code》 3. Google Java 代码指南:https://google.github.io/styleguide/javaguide.html#s5.1-identifier-name 4. 告别编码5分钟,命名2小时!史上最全的Java命名规范参考:https://www.cnblogs.com/liqiangchn/p/12000361.html +## 总结 + +作为一个合格的程序员,小伙伴们应该都知道代码表义的重要性。想要写出高质量代码,好的命名就是第一步! + +好的命名对于其他人(包括你自己)理解你的代码有着很大的帮助!你的代码越容易被理解,可维护性就越强,侧面也就说明你的代码设计的也就越好! + +在日常编码过程中,我们需要谨记常见命名规范比如类名需要使用大驼峰命名法、不要使用拼音,更不要使用中文......。 + +另外,国人开发的一个叫做 Codelf 的网站被很多人称为“变量命名神器”,当你为命名而头疼的时候,你可以去参考一下上面提供的一些命名示例。 + +最后,祝愿大家都不用再为命名而困扰! From d535742fe36641d5e86eaba6de88b5ddabe2111c Mon Sep 17 00:00:00 2001 From: guide Date: Sat, 21 Aug 2021 20:36:58 +0800 Subject: [PATCH 175/257] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b4e7557..8e214899 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://zhuanlan.zhihu.com/p/379041500) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线!另外,我整理了一份各个技术的学习路线,需要的小伙伴[加我微信](#联系我)备注“**Github-学习路线**”即可! +👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://zhuanlan.zhihu.com/p/379041500) (原创不易,欢迎点赞),这是 2021 最新最完善的 Java 学习路线!另外,[我的朋友整理了一份消息队列常见面试题,需要的小伙伴可以点击领取!](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100025985&idx=1&sn=681af486050fabbeea27fa1c3bec5d65&chksm=4ea1e94a79d6605c72f280b5268100c6e96c6ab1dc9a0178b33e25a72ff5f4eac3dcb56fa44f#rd) 👉 推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来) From 7a16bb8763bb7f3b31528aa4277987c13f5b6a01 Mon Sep 17 00:00:00 2001 From: Aaron Ge <525032143@qq.com> Date: Sun, 22 Aug 2021 21:04:01 +0800 Subject: [PATCH 176/257] =?UTF-8?q?Update=20=E4=BB=A3=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E8=AF=A6=E8=A7=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文本内容"只能只能"为"只能" --- docs/java/basis/代理模式详解.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/代理模式详解.md b/docs/java/basis/代理模式详解.md index 704de492..868bc012 100644 --- a/docs/java/basis/代理模式详解.md +++ b/docs/java/basis/代理模式详解.md @@ -405,7 +405,7 @@ after method send ### 3.3. JDK 动态代理和 CGLIB 动态代理对比 -1. **JDK 动态代理只能只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类。** 另外, CGLIB 动态代理是通过生成一个被代理类的子类来拦截被代理类的方法调用,因此不能代理声明为 final 类型的类和方法。 +1. **JDK 动态代理只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类。** 另外, CGLIB 动态代理是通过生成一个被代理类的子类来拦截被代理类的方法调用,因此不能代理声明为 final 类型的类和方法。 2. 就二者的效率来说,大部分情况都是 JDK 动态代理更优秀,随着 JDK 版本的升级,这个优势更加明显。 ## 4. 静态代理和动态代理的对比 From 2cc2d9a969505163c293efa52b48b3c045c15ce3 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 23 Aug 2021 12:01:00 +0800 Subject: [PATCH 177/257] =?UTF-8?q?[refractor&feat]=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E5=AE=8C=E5=96=84&=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 56 +++--- .../几道常见的字符串算法题.md | 0 .../几道常见的链表算法题.md | 0 .../algorithms}/剑指offer部分编程题.md | 0 .../data-structure/bloom-filter.md | 45 ++--- .../data-structure/pictures/图/图.png | Bin .../pictures/图/广度优先搜索1.drawio | 0 .../pictures/图/广度优先搜索1.png | Bin .../pictures/图/广度优先搜索2.drawio | 0 .../pictures/图/广度优先搜索2.png | Bin .../pictures/图/广度优先搜索3.drawio | 0 .../pictures/图/广度优先搜索3.png | Bin .../pictures/图/广度优先搜索4.drawio | 0 .../pictures/图/广度优先搜索4.png | Bin .../pictures/图/广度优先搜索5.drawio | 0 .../pictures/图/广度优先搜索5.png | Bin .../pictures/图/广度优先搜索6.drawio | 0 .../pictures/图/广度优先搜索6.png | Bin .../图/广度优先搜索图示.drawio | 0 .../pictures/图/广度优先搜索图示.png | Bin .../图/无向图的邻接矩阵存储.drawio | 0 .../图/无向图的邻接矩阵存储.png | Bin .../图/无向图的邻接表存储.drawio | 0 .../图/无向图的邻接表存储.png | Bin .../图/有向图的邻接矩阵存储.drawio | 0 .../图/有向图的邻接矩阵存储.png | Bin ...图的邻接矩阵存储的副本.drawio | 0 .../图/有向图的邻接表存储.drawio | 0 .../图/有向图的邻接表存储.png | Bin .../pictures/图/深度优先搜索1.drawio | 0 .../pictures/图/深度优先搜索1.png | Bin .../pictures/图/深度优先搜索2.drawio | 0 .../pictures/图/深度优先搜索2.png | Bin .../pictures/图/深度优先搜索3.drawio | 0 .../pictures/图/深度优先搜索3.png | Bin .../pictures/图/深度优先搜索4.drawio | 0 .../pictures/图/深度优先搜索4.png | Bin .../pictures/图/深度优先搜索5.drawio | 0 .../pictures/图/深度优先搜索5.png | Bin .../pictures/图/深度优先搜索6.drawio | 0 .../pictures/图/深度优先搜索6.png | Bin .../图/深度优先搜索图示.drawio | 0 .../pictures/图/深度优先搜索图示.png | Bin .../pictures/堆/删除堆顶元素1.png | Bin .../pictures/堆/删除堆顶元素2.png | Bin .../pictures/堆/删除堆顶元素3.png | Bin .../pictures/堆/删除堆顶元素4.png | Bin .../pictures/堆/删除堆顶元素5.png | Bin .../pictures/堆/删除堆顶元素6.png | Bin .../pictures/堆/堆-插入元素1.png | Bin .../pictures/堆/堆-插入元素2.png | Bin .../pictures/堆/堆-插入元素3.png | Bin .../data-structure/pictures/堆/堆1.png | Bin .../data-structure/pictures/堆/堆2.png | Bin .../pictures/堆/堆排序1.png | Bin .../pictures/堆/堆排序2.png | Bin .../pictures/堆/堆排序3.png | Bin .../pictures/堆/堆排序4.png | Bin .../pictures/堆/堆排序5.png | Bin .../pictures/堆/堆排序6.png | Bin .../pictures/堆/堆的存储.png | Bin .../data-structure/pictures/堆/建堆1.png | Bin .../data-structure/pictures/堆/建堆2.png | Bin .../data-structure/pictures/堆/建堆3.png | Bin .../data-structure/pictures/堆/建堆4.png | Bin .../pictures/树/中序遍历.drawio | 1 + .../pictures/树/中序遍历.png | Bin 0 -> 35285 bytes .../pictures/树/中序遍历2.drawio | 1 + .../pictures/树/中序遍历2.png | Bin 0 -> 11447 bytes .../pictures/树/先序遍历.drawio | 1 + .../pictures/树/先序遍历.png | Bin 0 -> 35364 bytes .../pictures/树/后序遍历.drawio | 1 + .../pictures/树/后序遍历.png | Bin 0 -> 35267 bytes .../pictures/树/完全二叉树.drawio | 1 + .../pictures/树/完全二叉树.png | Bin 0 -> 28497 bytes .../pictures/树/平衡二叉树.drawio | 1 + .../pictures/树/平衡二叉树.png | Bin 0 -> 20533 bytes .../data-structure/pictures/树/斜树.drawio | 1 + .../data-structure/pictures/树/斜树.png | Bin 0 -> 20671 bytes .../pictures/树/满二叉树.drawio | 1 + .../pictures/树/满二叉树.png | Bin 0 -> 20027 bytes .../pictures/树/链式存储二叉树.drawio | 1 + .../pictures/树/链式存储二叉树.png | Bin 0 -> 22043 bytes .../pictures/树/顺序存储.drawio | 1 + .../pictures/树/顺序存储.png | Bin 0 -> 47860 bytes .../pictures/树/顺序存储2.drawio | 1 + .../pictures/树/顺序存储2.png | Bin 0 -> 54408 bytes .../线性数据结构/单链表2.png | Bin .../线性数据结构/双向循环链表.png | Bin .../线性数据结构/双向链表.png | Bin .../循环队列-堆满.png | Bin .../pictures/线性数据结构/数组.png | Bin .../pictures/线性数据结构/栈.png | Bin .../栈实现浏览器倒退和前进.drawio | 0 .../栈实现浏览器倒退和前进.png | Bin .../pictures/线性数据结构/队列.png | Bin .../顺序队列假溢出.png | Bin .../data-structure/图.md | 0 .../data-structure/堆.md | 3 + docs/cs-basics/data-structure/树.md | 174 +++++++++++++++++ docs/cs-basics/data-structure/红黑树.md | 14 ++ .../data-structure/线性数据结构.md | 0 .../{ => cs-basics}/network/HTTPS中的TLS.md | 0 .../network/images/Cut-Trough-Switching_0.gif | Bin docs/{ => cs-basics}/network/images/isp.png | Bin .../network/images/七层体系结构图.png | Bin .../network/images/传输层.png | Bin .../network/images/应用层.png | Bin .../network/images/数据链路层.png | Bin .../network/images/物理层.png | Bin .../network/images/网络层.png | Bin .../万维网的大致工作工程.png | Bin .../network/计算机网络.md | 0 .../network/计算机网络知识总结.md | 0 .../{ => cs-basics}/operating-system/Shell.md | 0 .../{ => cs-basics}/operating-system/basis.md | 0 .../operating-system/images/Linux-Logo.png | Bin .../operating-system/images/Linux之父.png | Bin .../images/Linux权限命令.png | Bin .../images/Linux权限解读.png | Bin .../images/Linux目录树.png | Bin .../operating-system/images/linux.png | Bin .../operating-system/images/macos.png | Bin .../operating-system/images/unix.png | Bin .../operating-system/images/windows.png | Bin .../images/修改文件权限.png | Bin .../images/文件inode信息.png | Bin .../images/用户态与内核态.png | Bin .../{ => cs-basics}/operating-system/linux.md | 0 .../dataStructures-algorithms/数据结构.md | 179 ------------------ docs/java/{ => tips}/JAD反编译tricks.md | 90 ++++----- ...手教你定位常见Java性能问题.md | 160 ++++++++-------- 132 files changed, 376 insertions(+), 356 deletions(-) rename docs/{dataStructures-algorithms => cs-basics/algorithms}/几道常见的字符串算法题.md (100%) rename docs/{dataStructures-algorithms => cs-basics/algorithms}/几道常见的链表算法题.md (100%) rename docs/{dataStructures-algorithms => cs-basics/algorithms}/剑指offer部分编程题.md (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/bloom-filter.md (74%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/图.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索1.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索2.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索3.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索4.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索4.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索5.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索5.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索6.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索6.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索图示.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/广度优先搜索图示.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/无向图的邻接矩阵存储.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/无向图的邻接矩阵存储.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/无向图的邻接表存储.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/无向图的邻接表存储.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/有向图的邻接矩阵存储.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/有向图的邻接矩阵存储.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/有向图的邻接表存储.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/有向图的邻接表存储.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索1.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索2.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索3.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索4.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索4.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索5.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索5.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索6.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索6.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索图示.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/图/深度优先搜索图示.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素4.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素5.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/删除堆顶元素6.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆-插入元素1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆-插入元素2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆-插入元素3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序4.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序5.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆排序6.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/堆的存储.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/建堆1.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/建堆2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/建堆3.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/堆/建堆4.png (100%) create mode 100644 docs/cs-basics/data-structure/pictures/树/中序遍历.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/中序遍历.png create mode 100644 docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/中序遍历2.png create mode 100644 docs/cs-basics/data-structure/pictures/树/先序遍历.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/先序遍历.png create mode 100644 docs/cs-basics/data-structure/pictures/树/后序遍历.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/后序遍历.png create mode 100644 docs/cs-basics/data-structure/pictures/树/完全二叉树.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/完全二叉树.png create mode 100644 docs/cs-basics/data-structure/pictures/树/平衡二叉树.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/平衡二叉树.png create mode 100644 docs/cs-basics/data-structure/pictures/树/斜树.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/斜树.png create mode 100644 docs/cs-basics/data-structure/pictures/树/满二叉树.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/满二叉树.png create mode 100644 docs/cs-basics/data-structure/pictures/树/链式存储二叉树.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/链式存储二叉树.png create mode 100644 docs/cs-basics/data-structure/pictures/树/顺序存储.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/顺序存储.png create mode 100644 docs/cs-basics/data-structure/pictures/树/顺序存储2.drawio create mode 100644 docs/cs-basics/data-structure/pictures/树/顺序存储2.png rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/单链表2.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/双向循环链表.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/双向链表.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/循环队列-堆满.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/数组.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/栈.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.drawio (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/队列.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/pictures/线性数据结构/顺序队列假溢出.png (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/图.md (100%) rename docs/{dataStructures-algorithms => cs-basics}/data-structure/堆.md (99%) create mode 100644 docs/cs-basics/data-structure/树.md create mode 100644 docs/cs-basics/data-structure/红黑树.md rename docs/{dataStructures-algorithms => cs-basics}/data-structure/线性数据结构.md (100%) rename docs/{ => cs-basics}/network/HTTPS中的TLS.md (100%) rename docs/{ => cs-basics}/network/images/Cut-Trough-Switching_0.gif (100%) rename docs/{ => cs-basics}/network/images/isp.png (100%) rename docs/{ => cs-basics}/network/images/七层体系结构图.png (100%) rename docs/{ => cs-basics}/network/images/传输层.png (100%) rename docs/{ => cs-basics}/network/images/应用层.png (100%) rename docs/{ => cs-basics}/network/images/数据链路层.png (100%) rename docs/{ => cs-basics}/network/images/物理层.png (100%) rename docs/{ => cs-basics}/network/images/网络层.png (100%) rename docs/{ => cs-basics}/network/images/计算机网络知识点总结/万维网的大致工作工程.png (100%) rename docs/{ => cs-basics}/network/计算机网络.md (100%) rename docs/{ => cs-basics}/network/计算机网络知识总结.md (100%) rename docs/{ => cs-basics}/operating-system/Shell.md (100%) rename docs/{ => cs-basics}/operating-system/basis.md (100%) rename docs/{ => cs-basics}/operating-system/images/Linux-Logo.png (100%) rename docs/{ => cs-basics}/operating-system/images/Linux之父.png (100%) rename docs/{ => cs-basics}/operating-system/images/Linux权限命令.png (100%) rename docs/{ => cs-basics}/operating-system/images/Linux权限解读.png (100%) rename docs/{ => cs-basics}/operating-system/images/Linux目录树.png (100%) rename docs/{ => cs-basics}/operating-system/images/linux.png (100%) rename docs/{ => cs-basics}/operating-system/images/macos.png (100%) rename docs/{ => cs-basics}/operating-system/images/unix.png (100%) rename docs/{ => cs-basics}/operating-system/images/windows.png (100%) rename docs/{ => cs-basics}/operating-system/images/修改文件权限.png (100%) rename docs/{ => cs-basics}/operating-system/images/文件inode信息.png (100%) rename docs/{ => cs-basics}/operating-system/images/用户态与内核态.png (100%) rename docs/{ => cs-basics}/operating-system/linux.md (100%) delete mode 100644 docs/dataStructures-algorithms/数据结构.md rename docs/java/{ => tips}/JAD反编译tricks.md (68%) rename docs/java/{ => tips}/手把手教你定位常见Java性能问题.md (54%) diff --git a/README.md b/README.md index 8e214899..786e0ccf 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ ### 基础 -**知识点/面试题:**(必看:+1: ) +**知识点/面试题** : (必看:+1: ) 1. **[Java 基础知识](docs/java/basis/Java基础知识.md)** 2. **[Java 基础知识疑难点/易错点](docs/java/basis/Java基础知识疑难点.md)** @@ -71,11 +71,11 @@ **重要知识点详解:** -2. **线程池**:[Java 线程池学习总结](./docs/java/multi-thread/java线程池学习总结.md)、[拿来即用的线程池最佳实践](./docs/java/multi-thread/拿来即用的线程池最佳实践.md) -4. [ ThreadLocal 关键字解析](docs/java/multi-thread/万字详解ThreadLocal关键字.md) -5. [并发容器总结](docs/java/multi-thread/并发容器总结.md) -6. [JUC 中的 Atomic 原子类总结](docs/java/multi-thread/Atomic原子类总结.md) -7. [AQS 原理以及 AQS 同步组件总结](docs/java/multi-thread/AQS原理以及AQS同步组件总结.md) +1. **线程池**:[Java 线程池学习总结](./docs/java/multi-thread/java线程池学习总结.md)、[拿来即用的线程池最佳实践](./docs/java/multi-thread/拿来即用的线程池最佳实践.md) +2. [ ThreadLocal 关键字解析](docs/java/multi-thread/万字详解ThreadLocal关键字.md) +3. [并发容器总结](docs/java/multi-thread/并发容器总结.md) +4. [JUC 中的 Atomic 原子类总结](docs/java/multi-thread/Atomic原子类总结.md) +5. [AQS 原理以及 AQS 同步组件总结](docs/java/multi-thread/AQS原理以及AQS同步组件总结.md) ### JVM (必看 :+1:) @@ -95,28 +95,38 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle 1. **Java 8** :[Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md) 、[Java 8 学习资源推荐](docs/java/new-features/Java8教程推荐.md)、[Java8 forEach 指南](docs/java/new-features/Java8foreach指南.md) 2. **Java9~Java15** : [一文带你看遍 JDK9~15 的重要新特性!](./docs/java/new-features/java新特性总结.md) +### 小技巧 + +1. [JAD 反编译](docs/java/tips/JAD反编译tricks.md) +2. [手把手教你定位常见 Java 性能问题](./docs/java/tips/手把手教你定位常见Java性能问题.md) + ## 计算机基础 👉 **[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。 ### 操作系统 -1. [操作系统常见问题总结!](docs/operating-system/basis.md) -2. [后端程序员必备的 Linux 基础知识](docs/operating-system/linux.md) -3. [Shell 编程入门](docs/operating-system/Shell.md) +1. [操作系统常见问题总结!](docs/cs-basics/operating-system/basis.md) +2. [后端程序员必备的 Linux 基础知识总结](docs/cs-basics/operating-system/linux.md) +3. [Shell 编程入门](docs/cs-basics/operating-system/Shell.md) ### 网络 -1. [计算机网络常见面试题](docs/network/计算机网络.md) -2. [计算机网络基础知识总结](docs/network/计算机网络知识总结.md) +1. [计算机网络常见面试题](docs/cs-basics/network/计算机网络.md) +2. [计算机网络基础知识总结](docs/cs-basics/network/计算机网络知识总结.md) ### 数据结构 -- **图解数据结构:** - 1. [线性数据结构 :数组、链表、栈、队列](docs/dataStructures-algorithms/data-structure/线性数据结构.md) - 2. [图](docs/dataStructures-algorithms/data-structure/图.md) - 3. [堆](docs/dataStructures-algorithms/data-structure/堆.md) -- [不了解布隆过滤器?一文给你整的明明白白!](docs/dataStructures-algorithms/data-structure/bloom-filter.md) +**图解数据结构:** + +1. [线性数据结构 :数组、链表、栈、队列](docs/cs-basics/data-structure/线性数据结构.md) +2. [图](docs/cs-basics/data-structure/图.md) +3. [堆](docs/cs-basics/data-structure/堆.md) +4. [树](docs/cs-basics/data-structure/树.md) :重点关注[红黑树](docs/cs-basics/data-structure/红黑树.md)、B-,B+,B*树、LSM树 + +其他常用数据结构 : + +1. [布隆过滤器](docs/cs-basics/data-structure/bloom-filter.md) ### 算法 @@ -125,11 +135,13 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle - [算法学习书籍+资源推荐](https://www.zhihu.com/question/323359308/answer/1545320858) 。 - [如何刷Leetcode?](https://www.zhihu.com/question/31092580/answer/1534887374) -**常见算法问题总结:** +**常见算法问题总结** : -- [几道常见的字符串算法题总结 ](docs/dataStructures-algorithms/几道常见的字符串算法题.md) -- [几道常见的链表算法题总结 ](docs/dataStructures-algorithms/几道常见的链表算法题.md) -- [剑指 offer 部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) +- [几道常见的字符串算法题总结 ](docs/cs-basics/algorithms/几道常见的字符串算法题.md) +- [几道常见的链表算法题总结 ](docs/cs-basics/algorithms/几道常见的链表算法题.md) +- [剑指 offer 部分编程题](docs/cs-basics/algorithms/剑指offer部分编程题.md) + +另外,[GeeksforGeeks]( https://www.geeksforgeeks.org/fundamentals-of-algorithms/) 这个网站总结了常见的算法 ,比较全面系统。 ## 数据库 @@ -354,7 +366,6 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ## 工具 -1. **Java** :[JAD 反编译](docs/java/JAD反编译tricks.md)、[手把手教你定位常见 Java 性能问题](./docs/java/手把手教你定位常见Java性能问题.md) 2. **Git** :[Git 入门](docs/tools/Git.md) 3. **Github** : [Github小技巧](docs/tools/Github技巧.md) 4. **Docker** : [Docker 基本概念解读](docs/tools/Docker.md) 、[Docker从入门到上手干事](docs/tools/Docker从入门到实战.md) @@ -378,7 +389,8 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ### 待办 -- [ ] 数据结构总结重构 +- [ ] 计算机网络知识点完善 +- [ ] 分布式常见理论和算法总结完善 ### 捐赠支持 diff --git a/docs/dataStructures-algorithms/几道常见的字符串算法题.md b/docs/cs-basics/algorithms/几道常见的字符串算法题.md similarity index 100% rename from docs/dataStructures-algorithms/几道常见的字符串算法题.md rename to docs/cs-basics/algorithms/几道常见的字符串算法题.md diff --git a/docs/dataStructures-algorithms/几道常见的链表算法题.md b/docs/cs-basics/algorithms/几道常见的链表算法题.md similarity index 100% rename from docs/dataStructures-algorithms/几道常见的链表算法题.md rename to docs/cs-basics/algorithms/几道常见的链表算法题.md diff --git a/docs/dataStructures-algorithms/剑指offer部分编程题.md b/docs/cs-basics/algorithms/剑指offer部分编程题.md similarity index 100% rename from docs/dataStructures-algorithms/剑指offer部分编程题.md rename to docs/cs-basics/algorithms/剑指offer部分编程题.md diff --git a/docs/dataStructures-algorithms/data-structure/bloom-filter.md b/docs/cs-basics/data-structure/bloom-filter.md similarity index 74% rename from docs/dataStructures-algorithms/data-structure/bloom-filter.md rename to docs/cs-basics/data-structure/bloom-filter.md index bfb7efe7..9b5afd6d 100644 --- a/docs/dataStructures-algorithms/data-structure/bloom-filter.md +++ b/docs/cs-basics/data-structure/bloom-filter.md @@ -6,18 +6,18 @@ 2. 布隆过滤器的原理介绍。 3. 布隆过滤器使用场景。 4. 通过 Java 编程手动实现布隆过滤器。 -5. 利用Google开源的Guava中自带的布隆过滤器。 +5. 利用 Google 开源的 Guava 中自带的布隆过滤器。 6. Redis 中的布隆过滤器。 ### 1.什么是布隆过滤器? 首先,我们需要了解布隆过滤器的概念。 -布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于1970年提出的。我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。 +布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于 1970 年提出的。我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。 ![布隆过滤器示意图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/布隆过滤器-bit数组.png) -位数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000Bit / 8 = 125000 Byte = 125000/1024 kb ≈ 122kb 的空间。 +位数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000Bit / 8 = 125000 Byte = 125000/1024 kb ≈ 122kb 的空间。 总结:**一个名叫 Bloom 的人提出了一种来检索元素是否在给定大集合中的数据结构,这种数据结构是高效且性能很好的,但缺点是具有一定的错误识别率和删除难度。并且,理论情况下,添加到集合中的元素越多,误报的可能性就越大。** @@ -35,11 +35,9 @@ 举个简单的例子: - - ![布隆过滤器hash计算](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/布隆过滤器-hash运算.png) -如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 +如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为 0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。 @@ -49,7 +47,7 @@ ### 3.布隆过滤器使用场景 -1. 判断给定数据是否存在:比如判断一个数字是否存在于包含大量数字的数字集中(数字集很大,5亿以上!)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤、黑名单功能等等。 +1. 判断给定数据是否存在:比如判断一个数字是否存在于包含大量数字的数字集中(数字集很大,5 亿以上!)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤、黑名单功能等等。 2. 去重:比如爬给定网址的时候对已经爬取过的 URL 去重。 ### 4.通过 Java 编程手动实现布隆过滤器 @@ -206,7 +204,7 @@ true 实际使用如下: -我们创建了一个最多存放 最多 1500个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) +我们创建了一个最多存放 最多 1500 个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) ```java // 创建布隆过滤器对象 @@ -224,7 +222,7 @@ System.out.println(filter.mightContain(1)); System.out.println(filter.mightContain(2)); ``` -在我们的示例中,当`mightContain()` 方法返回 *true* 时,我们可以99%确定该元素在过滤器中,当过滤器返回 *false* 时,我们可以100%确定该元素不存在于过滤器中。 +在我们的示例中,当`mightContain()` 方法返回 _true_ 时,我们可以 99%确定该元素在过滤器中,当过滤器返回 _false_ 时,我们可以 100%确定该元素不存在于过滤器中。 **Guava 提供的布隆过滤器的实现还是很不错的(想要详细了解的可以看一下它的源码实现),但是它有一个重大的缺陷就是只能单机使用(另外,容量扩展也不容易),而现在互联网一般都是分布式的场景。为了解决这个问题,我们就需要用到 Redis 中的布隆过滤器了。** @@ -234,17 +232,17 @@ System.out.println(filter.mightContain(2)); Redis v4.0 之后有了 Module(模块/插件) 功能,Redis Modules 让 Redis 可以使用外部模块扩展其功能 。布隆过滤器就是其中的 Module。详情可以查看 Redis 官方对 Redis Modules 的介绍 :https://redis.io/modules -另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom。其他还有: +另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom。其他还有: - redis-lua-scaling-bloom-filter(lua 脚本实现):https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter -- pyreBloom(Python中的快速Redis 布隆过滤器) :https://github.com/seomoz/pyreBloom +- pyreBloom(Python 中的快速 Redis 布隆过滤器) :https://github.com/seomoz/pyreBloom - ...... RedisBloom 提供了多种语言的客户端支持,包括:Python、Java、JavaScript 和 PHP。 -#### 6.2 使用Docker安装 +#### 6.2 使用 Docker 安装 -如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 +如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 **具体操作如下:** @@ -252,15 +250,15 @@ RedisBloom 提供了多种语言的客户端支持,包括:Python、Java、Ja ➜ ~ docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest ➜ ~ docker exec -it redis-redisbloom bash root@21396d02c252:/data# redis-cli -127.0.0.1:6379> +127.0.0.1:6379> ``` -#### 6.3常用命令一览 +#### 6.3 常用命令一览 -> 注意: key : 布隆过滤器的名称,item : 添加的元素。 +> 注意: key : 布隆过滤器的名称,item : 添加的元素。 -1. **`BF.ADD `**:将元素添加到布隆过滤器中,如果该过滤器尚不存在,则创建该过滤器。格式:`BF.ADD {key} {item}`。 -2. **`BF.MADD `** : 将一个或多个元素添加到“布隆过滤器”中,并创建一个尚不存在的过滤器。该命令的操作方式`BF.ADD`与之相同,只不过它允许多个输入并返回多个值。格式:`BF.MADD {key} {item} [item ...]` 。 +1. **`BF.ADD`**:将元素添加到布隆过滤器中,如果该过滤器尚不存在,则创建该过滤器。格式:`BF.ADD {key} {item}`。 +2. **`BF.MADD`** : 将一个或多个元素添加到“布隆过滤器”中,并创建一个尚不存在的过滤器。该命令的操作方式`BF.ADD`与之相同,只不过它允许多个输入并返回多个值。格式:`BF.MADD {key} {item} [item ...]` 。 3. **`BF.EXISTS` ** : 确定元素是否在布隆过滤器中存在。格式:`BF.EXISTS {key} {item}`。 4. **`BF.MEXISTS`** : 确定一个或者多个元素是否在布隆过滤器中存在格式:`BF.MEXISTS {key} {item} [item ...]`。 @@ -268,19 +266,19 @@ root@21396d02c252:/data# redis-cli 这个命令的格式如下: -`BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion] `。 +`BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion]`。 下面简单介绍一下每个参数的具体含义: 1. key:布隆过滤器的名称 -2. error_rate :误报的期望概率。这应该是介于0到1之间的十进制值。例如,对于期望的误报率0.1%(1000中为1),error_rate应该设置为0.001。该数字越接近零,则每个项目的内存消耗越大,并且每个操作的CPU使用率越高。 -3. capacity: 过滤器的容量。当实际存储的元素个数超过这个值之后,性能将开始下降。实际的降级将取决于超出限制的程度。随着过滤器元素数量呈指数增长,性能将线性下降。 +2. error_rate :误报的期望概率。这应该是介于 0 到 1 之间的十进制值。例如,对于期望的误报率 0.1%(1000 中为 1),error_rate 应该设置为 0.001。该数字越接近零,则每个项目的内存消耗越大,并且每个操作的 CPU 使用率越高。 +3. capacity: 过滤器的容量。当实际存储的元素个数超过这个值之后,性能将开始下降。实际的降级将取决于超出限制的程度。随着过滤器元素数量呈指数增长,性能将线性下降。 可选参数: -- expansion:如果创建了一个新的子过滤器,则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。 +- expansion:如果创建了一个新的子过滤器,则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为 2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。 -#### 6.4实际使用 +#### 6.4 实际使用 ```shell 127.0.0.1:6379> BF.ADD myFilter java @@ -294,4 +292,3 @@ root@21396d02c252:/data# redis-cli 127.0.0.1:6379> BF.EXISTS myFilter github (integer) 0 ``` - diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/图.png b/docs/cs-basics/data-structure/pictures/图/图.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/图.png rename to docs/cs-basics/data-structure/pictures/图/图.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索1.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索1.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索2.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索2.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索3.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索3.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索4.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索4.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索5.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索5.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索6.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索6.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.drawio b/docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.drawio rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.png b/docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.png rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.drawio b/docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.drawio rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.png b/docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.png rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.png b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.png rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.png b/docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.png rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索1.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索1.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索2.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索2.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索3.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索3.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索4.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索4.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索5.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索5.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索6.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索6.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素3.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素3.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素5.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素5.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素6.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素6.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素2.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素2.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素3.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素3.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png b/docs/cs-basics/data-structure/pictures/堆/堆1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png rename to docs/cs-basics/data-structure/pictures/堆/堆1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png b/docs/cs-basics/data-structure/pictures/堆/堆2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png rename to docs/cs-basics/data-structure/pictures/堆/堆2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序1.png b/docs/cs-basics/data-structure/pictures/堆/堆排序1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序1.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序2.png b/docs/cs-basics/data-structure/pictures/堆/堆排序2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序2.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png b/docs/cs-basics/data-structure/pictures/堆/堆排序3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png b/docs/cs-basics/data-structure/pictures/堆/堆排序4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序5.png b/docs/cs-basics/data-structure/pictures/堆/堆排序5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序5.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序6.png b/docs/cs-basics/data-structure/pictures/堆/堆排序6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序6.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆的存储.png b/docs/cs-basics/data-structure/pictures/堆/堆的存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆的存储.png rename to docs/cs-basics/data-structure/pictures/堆/堆的存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png b/docs/cs-basics/data-structure/pictures/堆/建堆1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png rename to docs/cs-basics/data-structure/pictures/堆/建堆1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png b/docs/cs-basics/data-structure/pictures/堆/建堆2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png rename to docs/cs-basics/data-structure/pictures/堆/建堆2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆3.png b/docs/cs-basics/data-structure/pictures/堆/建堆3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆3.png rename to docs/cs-basics/data-structure/pictures/堆/建堆3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆4.png b/docs/cs-basics/data-structure/pictures/堆/建堆4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆4.png rename to docs/cs-basics/data-structure/pictures/堆/建堆4.png diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio b/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio new file mode 100644 index 00000000..f8fe81d2 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio @@ -0,0 +1 @@ +7Vtbk6I4FP41eZwukgBJHr1g727tVk1VV+30PNKSVmbQuIit7q/fBAISBLVbFHfa8sHkJORyzpcv5xwR4MFs8xj7i+lfIuARQFawAXgIEILQcuWXkmwzCWMkE0ziMNCddoKn8F+uhZaWrsKAL42OiRBREi5M4VjM53ycGDI/jsXa7PYqInPWhT/he4KnsR/tS7+FQTLNpBSRnfw3Hk6m+czQZVnLzM87650sp34g1iUR9gAexEIkWWm2GfBIKS/XS/bcqKG1WFjM58kpD6yenT8ev/39O3VCf/C2ZpuF7X/Ro7z50UpvGCA3kuP1X9SSk63Wg/vPSq2z/yrmyZdlaqWe7ICcxWbXKEsT9d3Lx5CLecmFWgnFiEiuThpRVvrraZjwp4U/Vi1riSMpmyazSNagLPrLRWbZ13DDA7WIMIoGIhJxOhB+feXueCzlyyQWP3mpJSDsxbKKyd94nPBNo/pgYRSJZi5mPIm3sot+gGBtRw1kzHR9XYKFFk1LiMhlvgbipBh5ZytZ0OZ6h+lQjemqKp4HPXUGZG0u5txUq9x3vH0uV76XK0O1b6uobXUtm4MHe6emoke5DrGKx/zABrA+zn484ckxjO7bpaR3p0bvuSzmkZ+Eb+Zy64yhZ/gqQrmRndktYpidWBV7ZtvUT5WPX3Ug5jwgaiMCkU1sN1+JHtYm1GzF5iyZkvZmSYFT6OTjWMKNNLBc+POPM0GJTDLBoJ4aClk23a/BGJSajGF3zRj2tazc/0RWdq0bs7JzLSsPP5GVHWRa2SEdW9m9lpUfP5GVmXtjVibn+nibMHkulb/nPp0s7xw8Vcn9u8IrLCpX9grt/4NX6FaAQuAHvUKKqIk4hq7q+NFzAVYbRFhH4JLD0irBEh6EZQcAc7oEGKneN+yjYYdDD4UdrNOwg52JvhZR4Z6ICtwlKiiCDy7GDrapdEgQNI3pUPjAIGO27AZtNw9c301J2D2AGIdada1XAkxOs5d3e7xP5Pa49MbcHliXljzX7zl8wdT7Pccusi78HqvelldyfMw8FWQmcCB8INAhiBIHOZhWhj/5zrJqh8nvLFq7hGsxEGpkIEU0LTKQfYSBsukaGEiSQWIeCZNB9JEp040W+VE4mcvqWCKYS3lfUUs49qOebpiFQRA1cVssVvNAMdmwLW5ilfSKtc9Ndg3e0cW4qTlX2jIA0B0AilOcyuXUOQCa06gtA8C9AyD1R28NAM0Z1pYBAO8ASC/8CgBo1wBw971R6QI+6arWoqkHESdTMRFzP/pTiIU2yA+eJFv9zoO/SkRDbsV6cDpKxuVvXHwwGXeys3meOeqypBcJCkefKCik1q0Fha3lKt+V2n5/Cr3N80dOPICdpqWgZQZsxIwKXYjrWt8bFbKDmUwJzy7zUnWZzIu4BM7dJZAthNyYS5APfHkAkDsAFBlUg4LOAdD8JmXLAMB3AKhLxb41ADQnBs/zQod9rzcalF/DOOhm/jIWJpXf2N3OLYz3/c1LhH35j+NZ1HdtlzPH8VGXM+vYVdCHarJwngP6Huh5wLOBjNV6EHguYBZgA+AhQNOCycnjInbanToZXzGG8f5BfAyT6epFjUk9wCjwGKAEMDkLVZOq6RxAKWCoiY31KoYFp8en0AK0a+8FORnrA+apQs8GdNjKJr8OR0dXL/crNSA9EbXfEWCuXotUvlIFAT1c0glRBUZSWwxAv5d2HqUFojrkx/rmOCzyX3jU98c/J6m8OrlUjT7D0Nb1UijeTz8theLQZEIb7zNhQXtnUqGs7v6SkoVHuz/2YO8/ \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历.png b/docs/cs-basics/data-structure/pictures/树/中序遍历.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad5782c8bde94ea9d99f36987b69e2578f20024 GIT binary patch literal 35285 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 Ja$)_i{~rKnb#4Fv literal 0 HcmV?d00001 diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio b/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio new file mode 100644 index 00000000..31e3097a --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio @@ -0,0 +1 @@ +5ZhNc5swEIZ/jY/uYLDBHGPsuIdmpmMfmhxlkEGtYKkQBvLrK1niq46bJm0Zpj6hfSWtpH12NSMmlheXW4bS6AECTCemEZQTaz0xzdnMsMVHKpVSXNdRQshIoAe1wp48Yy0aWs1JgLPeQA5AOUn7og9Jgn3e0xBjUPSHHYH2V01RiC+EvY/opfqFBDxS6tJ0Wv0jJmFUrzyzXdUTo3qwPkkWoQCKjmRtJpbHALhqxaWHqQxeHRc17/5Kb7MxhhP+OxN22UPg7CLH2z06MV1Pt0bxPNVeTojm+sAT06bC3+ogt8wrHQf7ey73uTpCwqfZmdKdGGAu0rLtFK1Qfu9qH2Izh1rUQWg8mmJ3AqIwVkVEON6nyJc9hcgjoUU8psKaiSbKUkX2SEocyE0QSj2gwM6OrOMR274v9Iwz+IY7PYHjHgyjWfyEGcfl1fDNGigimzHEmLNKDNET7DojdSLPa7vopIWWok5G1BrSiRg2nltWoqFxvQGdeRVdlqLk/fQ6CaAE72WcjaaW+z8oO+7IKFtDUV7dEOW5NTLK86Eor2+IsjUfGeXFUJS3N0R56bjjomwPRXlzQ5QX5shq2bmMaCAeDtpMIJGhZZAngQzaWoYBGI8ghATRTwCpDu9XzHmlnz0o59APvogOqx7l/A+L2nzq9q1L7VxZlbbey0ie4deExJEhZz5+/U3BEQsxf23cJXGGKeLk1N/HX+e3HKpK72+oSh1jZFXqDlOlJeGdIhXWU12Vot2WqDT+fYX+QUXpqZ+BCI/ty/enu7e5i2sX6kbQs7p/IN7qSF0ZF47O6JvzvJQNwmx/pKjh7e8oa/MD \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历2.png b/docs/cs-basics/data-structure/pictures/树/中序遍历2.png new file mode 100644 index 0000000000000000000000000000000000000000..fe6956b9d09c3503aaa88c0d3ed833d0f9b9d1a6 GIT binary patch literal 11447 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 b=Il4%yripmCIPsRd`2Cnqg<+J^W?t(mQb_Y literal 0 HcmV?d00001 diff --git a/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio b/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio new file mode 100644 index 00000000..b92e5c29 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio @@ -0,0 +1 @@ +7Vtbk6I4FP41eZwuIDfyKIq9D7tVU9u1tTOPKGllGo2L2Or8+k0kIEFQ2xvOtOWDyUnI5ZwvJ985IoDdyeo5CWbjv0TIY+BY4QrAHnAc27aI/FKSdSZhjGaCURKFutNW8BL95FpoaekiCvnc6JgKEafRzBQOxXTKh6khC5JELM1uryI2Z50FI74jeBkG8a703yhMx5nUdehW/gePRuN8ZpuwrGUS5J31TubjIBTLkgj6AHYTIdKsNFl1eayUl+sle67f0FosLOHT9JgHEuvvH2+rZPbTI6O56/T+WTrPX/Qo70G80BsGDonleN5ALTldaz2Q/xZqnd6rmKZf5hsrdWQHB89W20ZZGqnvTj6GXMwgF2olFCM6cnXSiLLiLcdRyl9mwVC1LCWOpGycTmJZs2UxmM8yy75GKx6qRURx3BWxSDYDwddXToZDKZ+niXjjpZaQsoFlFZO/8yTlq0b12YVRJJq5mPA0Wcsu+gGCtB01kCHW9WUJFlo0LiEilwUaiKNi5K2tZEGb6wOmc2pMV1XxNOyoMyBrUzHlplrlvpP1t3Lle7nSU/u2itpa17I5eLhzaip6lOsQi2TI92wA6uMcJCOeHsLorl1Kesc1es9lCY+DNHo3l1tnDD3DVxHJjWzNblPD7IRU7JltUz9VPn6VgaiFnxwXOdR2EEUkX4keFkHXbIXmLJmSdmbZAKfQyelYgo1uYD4Lpqd7gpIzyQTdetdQyLLpfg+PQZnpMVDbHgPdysreJ7Iytu/MyvhWVu59IisjaFoZw5atTG5l5edPZGWX3pmV6bkcbxWl30rl7zmnk+UtwVOVnN8VrLCo3JgVol+BFeIKUAg9lRVC10Qcdm5K/NxzAVYbRFgH4JLD0irB0t4LyxYAhtsEGKneN/hEgBHi7gs7cKthBzsTfRdEBTkSFbBNVFBoPxEIMUQulhe4bRoTI/uJ2YwhV7YgYtETXRIiexCDkVXXeiPA5Fz7+rTH/0S0B7M7oz12XVryXN6z/4Kp5z2HLrI2eI9Vb8sbER/XuDBsZl4n1H6iNqaSSGOJIrcy/NF3ll07TD4Jql3CrTyQ0+iBlKO5oAeyD3igbLoGDySdQWoeCdOD6CNTdjdaFMTRaCqrQ4lgLuWeci3RMIg7umEShWHc5NsSsZiGypP1LpV2typpd7Lrm1AN3p2r+abmXOmFAeA8AKCMS0wAoNYB0JxGvTAA8AMAGz56bwBozrBeGADwAQDl8qv0FLUNALLLRiUFfNFVrUVTDyJJx2IkpkH8pxAzbZAfPE3X+p2HYJGKhtyK9YRbSsblb1ycmIw7mmyeZ466LOlVgsL+JwoKqX1vQeHFcpUfSm1/PIV+yfNHjzyAraalmBmvUTMoxBTWtX40KHT3JjIlOttMS9UlMq/CCMiDEcgW4t4ZI8gHvj4A6AMAyhmgewNA84uUFwYAegAAlH4PuxsANOcFzyOhHa/nd/vltzD2sszfxsKk+hN76xaGu3TzGlFf/tt4FvTdmnHmOD7IOLOObcV8Tk0SzsfA80HHBz4CMlTr2MAngFmAdYHvAHdTMH3ysAidtqdOhleMQbh7EJ+jdLwYqDFdHzAX+Ay4FDA5i6smVdNh4LqAOU3eWK+iV/j05Bi3YKPae0FOxjzAfFXoIOD2LrLJr73+wdXL/UoNSCai9tsHjOi1SOUrVVDQgSWdUFVgdGOLLvA6m879TYGqDjmVuzsfFgcDHnvB8G20kVcnl6rRZ9hGul6KxL3N50KReOVdkCIfVvKEhds70xXK6vYfKVl4tP1fD/T/Bw== \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/先序遍历.png b/docs/cs-basics/data-structure/pictures/树/先序遍历.png new file mode 100644 index 0000000000000000000000000000000000000000..5c80cedf7d6561c8aa8c55d7762d4ea5edd17b02 GIT binary patch literal 35364 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

1FpyaKKKJ)iO8+72n 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 N002ovPDHLkV1hPf{aFA2 literal 0 HcmV?d00001 diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie-intro.jpeg b/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie-intro.jpeg deleted file mode 100644 index feca0114904b3cc9500c6224ca5b975e8a58d199..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27529 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 \ No newline at end of file diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.png b/docs/system-design/authority-certification/images/basis-of-authority-certification/session-cookie.png new file mode 100644 index 0000000000000000000000000000000000000000..b3724f5284a31b752788aa240a5519cc5f9e6baf GIT binary patch literal 171104 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 ~b#;hZ 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 \ No newline at end of file diff --git a/docs/system-design/authority-certification/images/basis-of-authority-certification/sso.png b/docs/system-design/authority-certification/images/basis-of-authority-certification/sso.png new file mode 100644 index 0000000000000000000000000000000000000000..8a87978a2f87336aa0b1a3da3284c7a13370dd7a GIT binary patch literal 52153 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

@@ -91,18 +92,20 @@ 1. **Java 8** :[Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md) 、[Java 8 学习资源推荐](docs/java/new-features/Java8教程推荐.md)、[Java8 forEach 指南](docs/java/new-features/Java8foreach指南.md) 2. **Java9~Java14** : [一文带你看遍 JDK9~14 的重要新特性!](./docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md) -## 网络 +## 计算机基础 -1. [计算机网络常见面试题](docs/network/计算机网络.md) -2. [计算机网络基础知识总结](docs/network/计算机网络知识总结.md) +👉 **[图解计算机基础 PDF 下载](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。 -## 操作系统 +### 操作系统 1. [操作系统常见问题总结!](docs/operating-system/basis.md) 2. [后端程序员必备的 Linux 基础知识](docs/operating-system/linux.md) 3. [Shell 编程入门](docs/operating-system/Shell.md) -## 数据结构与算法 +### 网络 + +1. [计算机网络常见面试题](docs/network/计算机网络.md) +2. [计算机网络基础知识总结](docs/network/计算机网络知识总结.md) ### 数据结构 @@ -371,14 +374,6 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: - [ ] 数据结构总结重构 -### 优质原创PDF资源 - -![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-2@main/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B8%93%E4%B8%9A/image-20201027160348395.png) - -为了避免恶意传播,微信搜“**Github掘金计划**”后台回复 **“006”** 即可获取。 - - - ### 捐赠支持 项目的发展离不开你的支持,如果 JavaGuide 帮助到了你找到自己满意的 offer,请作者喝杯咖啡吧 ☕ 后续会继续完善更新!加油! From 3b6e53b8625e2123e5c7fc895886f32cfcebbb63 Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 1 Jun 2021 16:31:09 +0800 Subject: [PATCH 020/257] =?UTF-8?q?Delete=20JDK=E5=8A=A8=E6=80=81=E4=BB=A3?= =?UTF-8?q?=E7=90=86-=E5=81=A5=E7=BE=8E=E7=8C=AA.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/basis/JDK动态代理-健美猪.md | 425 ------------------- 1 file changed, 425 deletions(-) delete mode 100644 docs/java/basis/JDK动态代理-健美猪.md diff --git a/docs/java/basis/JDK动态代理-健美猪.md b/docs/java/basis/JDK动态代理-健美猪.md deleted file mode 100644 index 51503d62..00000000 --- a/docs/java/basis/JDK动态代理-健美猪.md +++ /dev/null @@ -1,425 +0,0 @@ -最近在整理关于AOP的资料,发现绕不开代理(Proxy)这个概念,所以还是先梳理下这块的知识点,为以后做做铺垫,全文很长,改了很多版才敢发出来,约7000字,概念也比较多,可以先收藏慢慢看,毕竟不管多难的文章,**收藏=我会了**: - - -**但如果真看懂了,就来个赞吧,创作不易就想来点鼓励**。 - -## 什么是代理Proxy -代理我理解是一种**代码增强**,即在原先的方法逻辑上加上额外操作,在方法执行之前和之后加点通用逻辑,方便实现和维护,代理粗略可以分为静态代理和动态代理,本文的重点是后者,至于为什么要这么写,恐怕大部分人都是一知半解,所以本文的重点是解析JDK动态代码写法背后的过程和实现逻辑,但纯文字谁要看,所以文章里画了不少流程图希望能帮助你看懂。** - -## 静态代理 -先说下静态代理,比较简单,我通过一个例子简单讲下,比如有一个业务:**炜哥要去银行存钱10000块钱**,那么可以这样做: -定义一个 `SaveMoney` 的接口,需要实现的方法是**存钱** -```java -/** - * 去银行存钱 - * - * @author 炜哥 - */ -public interface SaveMoney { - - /** - * 去银行存钱 - */ - public void saveMoney(); -} -``` -然后有个具体实现类 `SaveMoneyToBankImpl` :**谁存钱,存了多少钱** -```java -/** - * 存钱实现 - * 谁存钱,存了多少钱 - * - * @author - */ -public class SaveMoneyToBankImpl implements SaveMoney { - - private String peopleName; - - private int money; - - public SaveMoneyToBankImpl(String peopleName,int money) { - this.peopleName = peopleName; - this.money = money; - } - - /** - * 具体实现存钱 - */ - public void saveMoney() { - System.out.println(peopleName + "在银行存了" + money + "元"); - } -} -``` -平常代码(存钱)到这里就结束了,不过假设业务流程需要调整: - -- 需要加一个校验(即存的钱是不是真的) -- 实现类不能动(来存钱的人不会自己验钞) - -你肯定会想到在**实现类**的 `saveMoney()` 中前后增加一些操作: -```java -/** - * 具体实现存钱 - */ -public void saveMoney() { - System.out.println("工作人员开始验钞..."); - System.out.println("验钞通过..."); - System.out.println(peopleName + "在银行存了" + money + "元"); - System.out.println("存钱完毕..."); -} -``` -这样做可以吗?**当然可以**,逻辑都实现了有啥不可以,但这时候**普通程序员**和**架构师**的区别就体现出来了: -> **普通程序员**:什么?加点额外操作,加!直接在原逻辑上开搞 -> **架构师**:这个额外操作看着有点普遍,会不会其他地方也需要?如果其他代码也需要难道都一个个手动加么,能不能给原逻辑某个执行点前后自动加上所需操作,从而解放(拯救)我们码农的双手(头发)? - -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620378296918-b8eeb9fd-37f6-41be-aefc-5297cba56b57.png) -**能不能另外弄一个代理程序,包含原程序需要执行的方法和额外操作,到时候只要执行下这个对象的方法不就行了么**,先不管通用不通用了,看看能不能把有这种功能的代理程序弄出来,既然思路有了就开搞: -为存钱这个动作做一个代理(**有一个银行工作人员帮你验钞**),即定义一个银行工作人员的代理类 `SaveMoneyByWokerProxy` ,构造函数的入参是实际对象(也就是XX要存XX钱的一个对象) -```java -/** - * 存钱代理,银行柜员代理存钱 - * - * @author 炜哥 - * @since 2021-04-15 21:56:39 - */ -public class SaveMoneyByWokerProxy implements SaveMoney { - - //代理对象 - SaveMoney saveMoneyProxy; - - //通过构造器给代理对象赋值 - public SaveMoneyByWokerProxy(SaveMoney saveMoney) { - this.saveMoneyProxy = saveMoney; - } - - /** - * 用代理存钱(工作人员帮忙存钱) - * 在这里会有一些业务流程上的操作 - */ - public void saveMoney() { - System.out.println("工作人员开始验钞..."); - System.out.println("验钞通过..."); - saveMoneyProxy.saveMoney(); - System.out.println("存钱完毕..."); - } -} -``` -OK,接下来就是测试下了 -```java -/** - * 代理存钱测试类 - * - * @author 炜哥 - * @since 2021-04-15 22:01:53 - */ -public class SaveMoneyProxyTest { - - public static void main(String[] args) { - - //定义一个炜哥存钱10000元的实际对象,炜哥要去存10000元了 - //这边为什么不是实现类对象 = new 实现类(); - //1.可以统一化管理所有子类,只需要提供一个共有的方法 - //2.java设计原则之一:依赖于抽象编程,而不是实现 - SaveMoney weigeSaveMoney = new SaveMoneyToBankImpl("炜哥",10000); - - //炜哥把要存的一万元和身份信息交给银行工作人员(生成一个代理对象) - SaveMoneyByWokerProxy workerProxySaveMoney = new SaveMoneyByWokerProxy(weigeSaveMoney); - - //代理对象也就是银行工作人员开始存钱(实际由代理类完成实际对象的方法) - workerProxySaveMoney.saveMoney(); - } -} -``` -运行结果: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1618541115094-d43003f1-254b-4c72-8e3e-6673b7f7a270.png) -到这里可能就会有人说了,这代理跟接口实现有什么区别吗,都用了关键词 `implements` 来实现 -**有区别**,我们看下面用红框框起来的内容: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620373395192-6aa39252-6480-4881-92bd-c720afc303b3.png) -代理对象 `saveMoneyProxy` 不仅做了实际对象需要做的操作 `saveMoney()` ,而且在这个操作的前后做了一些额外操作(这个额外操作在实际项目里很多应用场景,比如计算方法执行时间、执行前的校验、执行后的统一输出等),也就是**方法增强概念。而且静态代理还实现了目标接口类和增强代码的解耦,**但静态代理有非常致命的缺陷,为什么这么说呢,先来回顾下上述例子实现静态代理的过程: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620379095140-028c2a5c-6f51-4d5b-bf91-ab3ff3d6c980.png) -显而易见,虽然原有程序(**目标类**)和增强代码解耦了,但是原有程序(**目标类**)跟代理程序(**代理类**)又纠缠不清了,为什么这么说呢,体现在两个方面: - -- 代理的对象每次只能设定一种,如果上面的实际对象 `saveMoney` 换成其他就需要新增代理类 -- 因为需要实现相同的方法,所以如果原有程序新增/修改方法,那么代理程序也都需要同步新增/修改 - - - -比较灵性的人看到这,会说,这两个问题有啥难的,我只要**用Object类和Method分别接收目标对象和目标对象需要增强的方法**不就行啦,至于需要实现接口的所有方法,那我**不实现接口**不行吗,为啥非要实现目标接口呢?多此一举,来,上**小爷的“动态代理类”**: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620824714014-b8bcbb60-3953-406f-befd-2cbfe8b8edad.png) -执行代码改一改,变成这样: -```java -//炜哥把要存的一万元和身份信息交给银行工作人员(生成一个代理对象) -SaveMoneyByWokerProxy workerProxySaveMoney = new SaveMoneyByWokerProxy(weigeSaveMoney, weigeSaveMoney.getClass().getMethod("saveMoney")); -``` -执行结果: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620824854980-769cc7b7-f30b-4958-b8bc-3a8c299bbf91.png) -程序实现确实没有问题,但是我们忽略了一个问题,代理的**初衷**是什么,或者说什么是代理: - - -代理类是为目标类而服务的,目标类更占主导地位,后者只关心自己需要执行的方法,通俗点讲就是:**“你讲你的开场白和结束语,别影响我的真功夫表演”,**而上面这个所谓的代理类虽然实现了一样的作用但总有种**被托管**的味道,有点就像是“**我把我的真功夫给你,你替我发扬光大**”的意思,因为此时的代理类跟目标类没有任何关系了。 - - -实际上,这种“代理类”被世人称之为**装饰器模式**,这两种模式在本文里的应用场景下根本体会不到它们之间的细微差别,因此继续讨论下去的意义不大,有兴趣去查下资料,**动态代理模式和装饰者模式之间的区别**,这里就不做展开,徒增你们的记忆负担了。 - - -好了,回到正题,如何解决上述这两个问题,既要实现接口来体现代理的含义,又要解决因此带来的棘手问题 - -## JDK动态代理 -**它的出现就是为了解决上述两大难,但如果是你,会如何去设计动态代理,不急,先分析下静态的过程** - -### 创建代理类的目的 - -1. 创建上述的代理类 `SaveMoneyByWokerProxy` 是为了做什么,是不是为了初始化时接收目标类实例从而生成一个代理对象 -1. 生成代理对象是为了干什么,是不是为了能够调用目标类实例的方法并同时执行代理对象中的增强代码 - -所以,重点来了,能不能通过不设计**完全没头绪的动态代理类**得到**代理对象**,从而调用**目标类实例方法**和**增强代码**,因为后面这两个才是我们最终想要的。 -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620880813876-8b72cdd8-a4a4-4ed6-a0a8-de0e4c4ebed7.png) -按照静态代理的思路,获得目标实例的代理对象**一我们需要目标类的实例化对象,二需要一个代理类去接收该对象,获得对象方法,重写方法时在目标对象方法前后加点料(方法增强)。    ** -第一步没有什么问题,虽然接口不能直接new一个对象,说到new,**可能有比较灵性的同学会想到,接口是有class对象的,能否通过class对象的 `newInstance` 方法反射创建对象呢?**很遗憾,反射没用**,因为它没有构造函数**,不信看下面代码: -```java -//获取接口的构造器 -Constructor[] constructors = SaveMoney.class.getConstructors(); -for (Constructor constructor : constructors) { - System.out.println(constructor); -} -``` -**输出的结果是空的,**那为什么这个代码看起来那么像是接口被实例化了,生成了“接口对象”: -```java -SaveMoney weigeSaveMoney = new SaveMoneyToBankImpl("炜哥",10000); -``` -NoNoNo,千万别搞错了,很多人喜欢把一个 `A a = new A()` 的这个a当成一个对象,这样你完全没有办法理解后面的多态是怎么一回事,所以我更喜欢把a当成是一个引用,就像C语言的指针一样,指向的是右边真正创建的对象,也就是栈内存和堆内存存放数据类型之间的关系。 - - -**所以,只要目标类被某个类实现了,目标对象不是什么问题(JDK动态代理的前提是接口至少被一个实现类实现,否则就无法生成代理对象)**,因此重点在于第二步。 - - -想一下,如果我们要设计一个**动态代理类**,是不是应该把代理类设计成**一个可以接收所有目标对象和实现所有目标对象中所有方法**的样子,怎么去弄,我擦嘞!完全没头绪啊。 - -### 贴心的JDK -好难,第二个条件好难,有没有什么办法直接通过一个**API方法**来获得**代理对象**啊 -**有!!!** -贴心的JDK中有一个 `java.lang.reflect` 包下的 `Proxy` 类,字面意思就是代理,我们看下它有哪些方法: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620437611840-381617a1-f880-4935-93a8-0892cb18bc1f.png) -红框框起来的字面意思看起来跟我们需要解决的问题有很大关系,先看下第一个方法_getProxyClass_ -_![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620437741640-7eff4536-c9b9-4cd9-823e-11a94e0aa056.png)_ -入参是类加载器和Class对象,返回了一个新的Class对象,想要更确切的信息看下源码中的英文注释: -> _Returns the {_**@code **_java.lang.Class} object for a proxy class given a class loader and an array of interfaces.  The proxy class will be defined by the specified class loader and will implement all of the supplied interfaces.  If any of the given interfaces is non-public, the proxy class will be non-public. If a proxy class for the same permutation of interfaces has already been defined by the class loader, then the existing proxy class will be returned; otherwise, a proxy class for those interfaces will be generated dynamically and defined by the class loader._ - -直接反手一个有道翻译: -> **返回代理类的{@code java.lang.Class}对象,给出类装入器和接口数组**。代理类将由指定的类装入器定义,并将实现提供的所有接口。如果任何给定接口是非公共的,则代理类是非公共的。如果类装入器已经定义了用于相同接口排列的代理类,那么将返回现有的代理类;否则,将动态生成这些接口的代理类,并由类装入器定义 - - - -我们只要关注第一句加粗的话,返回**代理类的Class对象**,等于说,我们上面绞尽脑汁想要的,这里只要一句话就搞定了!!! -```java -Class proxyClass = Proxy.getProxyClass(SaveMoney.class.getClassLoader(), SaveMoney.class.getInterfaces()); -``` -**既然代理类的Class对象拿到了,那得到代理对象不是分分钟的事情,不就要求传入类加载器和类信息么,开搞:** -```java -//获得代理类的Class对象 -Class proxyClass = Proxy.getProxyClass(SaveMoney.class.getClassLoader(), SaveMoney.class.getInterfaces()); -//通过Class反射获得代理类实例 -SaveMoneyToBankImpl saveMoneyToBankImpl = (SaveMoneyToBankImpl)proxyClass.newInstance(); -``` -很遗憾,第二句代码的 `newInstance` 不行,为什么: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620438625034-011d0fa1-b570-4c4e-9237-547eb150c8ad.png) -`Proxy` 的默认无参构造函数是private类型的(代理类继承了Proxy),而且注释上的_Prohibits instantiation._清清楚楚表达着:**别用这个,不允许** -** -其实你看上述代码应该也能想到,就算这样能创建出来的代理对象也是没软用的,为什么? -**因为目标对象 `saveMoney` 根本没用到呀,**`SaveMoney` 实现类那么多,但**我们只用了 **`**SaveMoney**` **接口,没用到目标对象的话怎么找到并执行目标对象的方法呢** -还有没有其他办法了,再往下看: - -### Proxy的有参构造函数 -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620438761618-b0ce91a2-1b8d-40cb-85a3-29822eeb4e12.png) -又发现了一个构造器,这个修饰词是protect,肯定能直接用,不过有个入参,类型是 `InvocationHandler` ,这个类做什么的? - - -在你不知道某个类干嘛用的,又找不到对应的api文档时,只能硬着头皮进源码看一眼了,但这次你会发现这个类出奇的简单: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620439092284-2b722a3a-2630-484a-b3fe-22b32681f644.png) -只有一个 `invoke` 方法,对反射有经验的看到`invoke`应该能想到,反射类Method中也有`invoke`,那么是不是意味着这个`InvocationHandler`跟方法有关系,也就是跟增强代码可能有点联系。 - - -而且你发现没有,`InvocationHandler`是一个接口,需要有实现类去实现,所以`invoke`方法得重写,问题又来了,invoke方法重写成什么样子,要想知道怎么重写首先得知道各个方法入参是什么意思: - -- **dynamic_proxy**:代理对象com.sun.dynamic_proxy.$Proxy0 -- **method**:代理对象的Method方法实例 -- **args**:指代代理对象方法传递的参数 - - - -看了中文注释是不是还是有点懵逼?没关系,一个个来: - -- 第一个com.sun.dynamic_proxy.$Proxy0是什么意思,其实是这样的,jvm会根据我们传入的参数生成代理类,被类加载加载后生成class字节码文件(也就是Class对象),类型名是**“$Proxy”+序号(据说使用后会被删除掉,所以你找不到这个class文件)**,这个类实现了所有传入接口的所有方法,也就是我们上面一心想要拿到的代理对象,但这个参数基本不会用到。 -- 第二个method你可以理解为代理对象中的方法反射,因为通过Proxy生成的代理Class对象已经传入了接口所有需要实现的方法,所以通过这个参数我们能反射执行所有接口方法,了解反射的同学肯定知道Class对象中有个反射Data,里面就有Method实例 -- 第三个比较好理解,就是一些参数之类的传递 -- 除此之外,还有个return的Object,**这个object你可以理解成是和被代理对象方法相同的返回值,即目标对象的该方法返回什么,那么Object就是什么** - -** -**先不管这么多了,我只要个代理对象,先随便重写下invoke方法试试看吧:** -**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879082496-217134bd-ca73-4a83-9728-021ecb04f241.png)** -报错了,无法创建目标类的代理对象,为啥啊,我都按照api要求传入需要的参数了呀: -还是上述说的那个问题,**不传入目标对象,Proxy怎么给你造一个可以执行目标对象方法的代理对象**啊,一句话总结就是:**获得代理Class对象可以只用接口,但生成代理对象则需要目标对象**,所以我们换一种写法: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879460015-6752ecc8-ba36-4f0b-aad9-fb495deb4102.png) -可能有人对**`InvocationHandler`**这个参数还是没概念,那只能使出我的**和稀泥大法**:**你只要理解成把`InvocationHandler`丢到代理类 `Proxy` 中,JDK底层在`Proxy`中一通鸡儿操作,最后向下转型生成的代理类对象执行目标对象方法时,会自动调用`InvocationHandler`中重写的 `invoke` 方法,这样说的话,那重写的invoke方法是不是可以大做文章了?** -**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879552715-b18fd367-5e8c-4b8c-a73d-187d7598607c.png)** -**![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620881202389-bc475d83-0e2d-493b-ba95-ac0ea8f4a7bd.png)** -**所以 `Proxy` 类不光帮我们解决了如何获得代理对象,又允许我们通过`InvocationHandler`把目标对象和增强方法也放进去!!!** - - -说的有点深了,有些人已经忘记之前的思路是什么样子了,这里再回顾下: - -- 需要能够接受所有泛型类和实现所有泛型类方法的动态代理类-》动态代理类不知道怎么创建-》拿不到代理对象-》**这条路走不通了** -- ①JDK有个Proxy类可以通过传入不需要实例化的接口就能生成代理类的**Class对象**-》 -- ②**代理Class对象**有构造函数所以可以通过**反射**直接拿到代理对象,但**构造函数**需要传入`InvocationHandler`-》 -- ③`InvocationHandler` 入参需要重写invoke方法,此时可以传入目标对象,通过**方法反射**执行目标对象方法,增强代码此时也可以放入,而通过**该构造函数生成的代理对象**执行目标方法时会自动执行`InvocationHandler` 中的重写invoke方法,最终达到代码增强的效果 - -所以最终JDK动态代理的思路大概应该是: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620882373243-f00409ff-066e-4712-929f-b3e00ced291e.png) -ok,思路有了,Method实例有了,是不是可以通过 `method.invoke` 来执行目标类的方法,但invoke方法还需要传入目标对象,目标对象当然不是第一个参数_代理对象com.sun.dynamic_proxy.$Proxy0_ ,所以传入的目标对象**saveMoney**,上面的代码再改一改: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620879727230-1f043b81-8bd6-4160-92dc-445c74f5c577.png) -执行输出: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620450709671-e195eb45-e1a4-4f36-9363-538f052992d5.png) -代码执行了,也达到预期效果了,但有些小萌新还是会有点疑惑: - -- 为什么要先反射获取代理Class对象的构造函数Constructor,然后通过Constructor的newInstance()方法创建代理对象,不能直接用代理Class对象的newInstance()方法创建代理对象吗? -- 为什么代理对象只能用接口`SaveMoney` 去接,不能使用它的实现类比如 `SaveMoneyToBankImpl` 去接收吗? - - - -第一个问题,其实这个看Class源码就能知道,Class对象的newInstance()方法实际上还是调用构造器Constructor的无参构造函数newInstance(),比较局限,如果Class对象没有无参构造器,那么直接调用newInstance()就会报错,Constructor里支持无参和有参构造,因为需传入`InvocationHandler` 的关系所以得通过Constructor获得有参构造函数对象: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620453535075-c5f48894-276d-488d-83f2-29356210b891.png) -至于第二个,我的解释非常简单,代理类已经实现了目标接口的所有方法,那么你可以把它看做就是个目标接口实现类,那么想用**另外一个目标接口实现类去接收代理对象**就相当于这样: -```java -public interface 接口 {...} -class 实现类1 implements 接口{...} -class 实现类2 implements 接口{...} //把代理类看做是实现类2 -class Test{ - public static void main(String[] args) { - //相当于这样 - 实现类1 实现类1对象 = (实现类1) new 实现类2(); - } -} -``` -这个操作肯定不允许啊,实现类1和实现类2之间又没有直接的联系,怎么能相互之间强转呢?_ - -### 直接拿代理对象_ -OK,其实我们的目的已经达到了,不过可以往回看一眼, `Proxy` 类中除了 `getProxyClass` 方法之外,还有另外一个方法 `newProxyInstance` ,即直接返回给你一个代理对象! -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620453873833-3fd5c3d4-5eff-4de8-9083-67089b941efe.png) -这就更简单了,不需要再自己弄一个有参构造函数对象,直接调用这个Api就可以拿到代理对象了,是上述方法的**简化版**: -```java -//初始化目标类对象 -SaveMoney saveMoney = new SaveMoneyToBankImpl("炜哥", 1000); - -//通过有参构造函数得到代理对象 -SaveMoney saveMoneyProxy = (SaveMoney) Proxy.newProxyInstance( - saveMoney.getClass().getClassLoader(), - saveMoney.getClass().getInterfaces(), - new InvocationHandler() { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - //为了实现功能,先这样写 - System.out.println("工作人员开始验钞..."); - System.out.println("验钞通过..."); - Object o = method.invoke(saveMoney, args); - System.out.println("存钱完毕..."); - return o; - } - }); - -//这个saveMoney方法其实已经包含了上面的增强代码 -saveMoneyProxy.saveMoney(); -``` -执行的结果和上面是一样的,同样需要先确定目标对象 - - -不过上面的代码有点小瑕疵,需要抽取 `new InvocationHandler` 这块对象,因为如果还有其他增强业务呢,总不能把增强业务写死吧,而且内部的目标对象也不能写死: -![image.png](https://cdn.nlark.com/yuque/0/2021/png/12928968/1620459362534-47c3f17a-ab3f-48b3-87ca-317396676642.png) -把抽取出来的代码命名为`ProxyHandler` ,同时增加有参构造函数来接收像SaveMoney这样的变量 -```java -/** - * @author :炜哥 - * @description:TODO 代理类 - * @date :2021/4/15 14:20 - */ -public class ProxyHandler implements InvocationHandler { - - //代理对象 - private Object target; - - //真实对象赋值 - public ProxyHandler(Object target) { - this.target = target; - } - - /** - * dynamic_proxy:代理对象com.sun.dynamic_proxy.$Proxy0 - * method:代理对象的Method方法实例 - * args:指代代理对象方法传递的参数 - */ - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - System.out.println("工作人员开始验钞..."); - System.out.println("验钞通过..."); - Object o = method.invoke(target, args); - System.out.println("存钱完毕..."); - return o; - } -} -``` -这个代理类跟静态代理中的 `SaveMoneyByWokerProxy` 类起到相同的作用,但不同的是实现了 `InvocationHandler` 接口,重写了 `invoke()` 方法,构造器入参由之前的**特定类**变成了**Object** - - -最后用 `Proxy` 类生成代理对象测试下(**解释各个入参的含义我已经尽力了......**) -```java -/** - * 动态代理测试 - * - * @author :炜哥 - * @description:TODO - * @date :2021/4/14 16:36 - */ -public class SaveProxyTest { - - public static void main(String[] args) { - - //定义一个炜哥存钱10000元的实际对象,炜哥要去存10000元了 - SaveMoney saveMoney = new SaveMoneyToBankImpl("炜哥",10000); - - /** - * 代理对象的调用处理程序 - * 你可以把它想象成一个“传入真实对象生成代理对象”的程序,其内置的invoke()方法会最终调用真实对象的方法 - */ - InvocationHandler invocationHandler = new ProxyHandler(saveMoney); - - /** - * 炜哥把要存的一万元和身份信息交给银行工作人员(通过newProxyInstance创建一个代理对象) - * - * 第一个参数 the class loader to define the dynamic_proxy class - * 谁被代理就用谁的类加载器,是一种固定的写法,用来加载代理Class对象字节码 - * - * 第二个参数 the list of interfaces for the dynamic_proxy class to implement - * 让代理对象有跟被代理对象相同的方法,谁被代理就写谁的getInterfaces,也是一种固定写法 - * - * 第三个参数 invocationHandler的invoke方法the invocation handler to dispatch method invocations to - * 让我们可以把增强代码放入该handler中,从而实现代理 - * - * 返回参数 - * a dynamic_proxy instance with the specified invocation handler of a that is defined by the specified class loader - * and that implements the specified interfaces - * 返回一个代理对象,该对象是被指定的类加载器定义并且实现了指定接口 - * - */ - SaveMoney saveMoneyProxy = (SaveMoney) Proxy.newProxyInstance( - saveMoney.getClass().getClassLoader(), - saveMoney.getClass().getInterfaces(), - invocationHandler); - - //这个saveMoney方法其实已经包含了上面的增强代码 - saveMoneyProxy.saveMoney(); - } -} -``` -这样,增强代码放在了InvocationHandler中,并且可以通过反射执行目标类的所有方法,**实现了增强代码和目标类的解耦;**代理对象可以通过Proxy配合InvocationHandler获得,没有像静态代理一样与目标类纠缠不清的代理类,不管有多少个目标类,通过这两个类配合统统可以接收,**实现了目标类与代理对象的解耦**,这种通过接口获取代理对象的叫做**JDK动态代理(**不能用在非接口类的代理上面,因为newProxyInstance方法中第二个参数就是要求传入目标类对象的接口数组**)。** -** -在JDK动态代理中,为什么一定要基于接口实现?这个问题其实你可以通过代理类class反推,通过反编译得到一个结果:**代理类都继承了Proxy,因为java单继承的关系,只能通过实现关系来满足代理的意义**,那如果想基于没有被任何实现类实现的java类呢,能不能生成动态代理对象,答案当然是肯定的: - - -但是有空再说这种动态代理-cglib From 1d3d55ea2f964e72be401752e93b58696d9e413f Mon Sep 17 00:00:00 2001 From: guide Date: Tue, 1 Jun 2021 21:31:57 +0800 Subject: [PATCH 021/257] typo --- README.md | 2 +- ...符串算法题.md => 几道常见的字符串算法题.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/dataStructures-algorithms/{几道常见的子符串算法题.md => 几道常见的字符串算法题.md} (100%) diff --git a/README.md b/README.md index 70a97473..dd9f96bf 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ **常见算法问题总结:** -- [几道常见的字符串算法题总结 ](docs/dataStructures-algorithms/几道常见的子符串算法题.md) +- [几道常见的字符串算法题总结 ](docs/dataStructures-algorithms/几道常见的字符串算法题.md) - [几道常见的链表算法题总结 ](docs/dataStructures-algorithms/几道常见的链表算法题.md) - [剑指 offer 部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) diff --git a/docs/dataStructures-algorithms/几道常见的子符串算法题.md b/docs/dataStructures-algorithms/几道常见的字符串算法题.md similarity index 100% rename from docs/dataStructures-algorithms/几道常见的子符串算法题.md rename to docs/dataStructures-algorithms/几道常见的字符串算法题.md From a7cb255e46325108df85568176b244f581765a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E4=B9=9D=E9=BC=8E?= <109224573@qq.com> Date: Wed, 2 Jun 2021 12:46:32 +0000 Subject: [PATCH 022/257] Use https for some links --- README.md | 4 +-- .../几道常见的链表算法题.md | 6 ++--- .../剑指offer部分编程题.md | 2 +- .../dataStructures-algorithms/数据结构.md | 2 +- docs/database/MySQL Index.md | 8 +++--- .../MySQL高性能优化规范建议.md | 2 +- docs/java/basis/Java基础知识.md | 10 +++---- docs/java/basis/Java常见关键字总结.md | 2 +- .../Java集合框架常见面试题.md | 4 +-- docs/java/jvm/JVM垃圾回收.md | 4 +-- ...Java并发进阶常见面试题总结.md | 4 +-- .../AQS原理以及AQS同步组件总结.md | 2 +- docs/java/multi-thread/并发容器总结.md | 6 ++--- ...带你看遍JDK9到14的重要新特性.md | 2 +- docs/operating-system/Shell.md | 26 +++++++++---------- .../SSO单点登录看这一篇就够了.md | 8 +++--- .../RabbitMQ入门看这一篇就够了.md | 22 ++++++++-------- .../distributed-system/rpc/Dubbo.md | 4 +-- ...调用为啥不直接用HTTP而用RPC.md | 4 +-- docs/system-design/framework/spring/Spring.md | 6 ++--- .../framework/spring/Spring事务总结.md | 2 +- .../spring/Spring常见问题总结.md | 10 +++---- ...统架构你不得不懂的10个问题.md | 2 +- docs/tools/Git.md | 4 +-- docs/tools/Github技巧.md | 2 +- docs/公众号历史文章汇总.md | 4 +-- 26 files changed, 76 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index dd9f96bf..e8db97f4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。 > 2. **PDF版本** : [《JavaGuide 面试突击版》PDF 版本](#公众号) 。 -> 3. **图解计算机基础** :[图解计算机基础 PDF 下载](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 +> 3. **图解计算机基础** :[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。 > 4. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。星球内部更新的[《Java面试进阶指北 打造个人的技术竞争力》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7)这个小册的质量很高,专为面试打造。 > 5. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java 面试进阶指南》](https://xiaozhuanlan.com/javainterview?rel=javaguide) > 6. **转载须知** :以下所有文章如非文首说明皆为我(Guide哥)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️ @@ -94,7 +94,7 @@ ## 计算机基础 -👉 **[图解计算机基础 PDF 下载](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。 +👉 **[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。 ### 操作系统 diff --git a/docs/dataStructures-algorithms/几道常见的链表算法题.md b/docs/dataStructures-algorithms/几道常见的链表算法题.md index 9daa0fc1..7b824368 100644 --- a/docs/dataStructures-algorithms/几道常见的链表算法题.md +++ b/docs/dataStructures-algorithms/几道常见的链表算法题.md @@ -50,7 +50,7 @@ Leetcode官方详细解答地址: 我们使用变量来跟踪进位,并从包含最低有效位的表头开始模拟逐 位相加的过程。 -![图1,对两数相加方法的可视化: 342 + 465 = 807342+465=807, 每个结点都包含一个数字,并且数字按位逆序存储。](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/34910956.jpg) +![图1,对两数相加方法的可视化: 342 + 465 = 807342+465=807, 每个结点都包含一个数字,并且数字按位逆序存储。](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/34910956.jpg) ### Solution @@ -98,7 +98,7 @@ public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ### 题目描述 > 剑指 offer:输入一个链表,反转链表后,输出链表的所有元素。 -![翻转链表](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/81431871.jpg) +![翻转链表](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/81431871.jpg) ### 问题分析 @@ -269,7 +269,7 @@ public class Solution { 我们注意到这个问题可以容易地简化成另一个问题:删除从列表开头数起的第 (L - n + 1)个结点,其中 L是列表的长度。只要我们找到列表的长度 L,这个问题就很容易解决。 -![图 1. 删除列表中的第 L - n + 1 个元素](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/94354387.jpg) +![图 1. 删除列表中的第 L - n + 1 个元素](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/94354387.jpg) ### Solution diff --git a/docs/dataStructures-algorithms/剑指offer部分编程题.md b/docs/dataStructures-algorithms/剑指offer部分编程题.md index b7b077fb..84a21a5f 100644 --- a/docs/dataStructures-algorithms/剑指offer部分编程题.md +++ b/docs/dataStructures-algorithms/剑指offer部分编程题.md @@ -566,7 +566,7 @@ public ListNode Merge(ListNode list1,ListNode list2) { **栈:**后进先出(LIFO) **队列:** 先进先出 很明显我们需要根据JDK给我们提供的栈的一些基本方法来实现。先来看一下Stack类的一些基本方法: -![Stack类的一些常见方法](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-4-4/5985000.jpg) +![Stack类的一些常见方法](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-4-4/5985000.jpg) 既然题目给了我们两个栈,我们可以这样考虑当push的时候将元素push进stack1,pop的时候我们先把stack1的元素pop到stack2,然后再对stack2执行pop操作,这样就可以保证是先进先出的。(负[pop]负[pop]得正[先进先出]) diff --git a/docs/dataStructures-algorithms/数据结构.md b/docs/dataStructures-algorithms/数据结构.md index 314b2a85..5caffaac 100644 --- a/docs/dataStructures-algorithms/数据结构.md +++ b/docs/dataStructures-algorithms/数据结构.md @@ -165,7 +165,7 @@ B+树最大的性能问题是会产生大量的随机IO 为了克服B+树的弱点,HBase引入了LSM树的概念,即Log-Structured Merge-Trees。 -[LSM树由来、设计思想以及应用到HBase的索引](http://www.cnblogs.com/yanghuahui/p/3483754.html) +[LSM树由来、设计思想以及应用到HBase的索引](https://www.cnblogs.com/yanghuahui/p/3483754.html) ## 图 diff --git a/docs/database/MySQL Index.md b/docs/database/MySQL Index.md index 69d606f1..ea683c15 100644 --- a/docs/database/MySQL Index.md +++ b/docs/database/MySQL Index.md @@ -44,9 +44,9 @@ select username , age from user where username = 'Java' and age = 22 MySQL的基本存储结构是页(记录都存在页里边): -![MySQL的基本存储结构是页](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/28559421.jpg) +![MySQL的基本存储结构是页](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/28559421.jpg) -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/82053134.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/82053134.jpg) - **各个数据页可以组成一个双向链表** - **每个数据页中的记录又可以组成一个单向链表** @@ -65,11 +65,11 @@ MySQL的基本存储结构是页(记录都存在页里边): 索引做了些什么可以让我们查询加快速度呢?其实就是将无序的数据变成有序(相对): -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/5373082.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/5373082.jpg) 要找到id为8的记录简要步骤: -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/89338047.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-2/89338047.jpg) 很明显的是:没有用索引我们是需要遍历双向链表来定位对应的页,现在通过 **“目录”** 就可以很快地定位到对应的页上了!(二分查找,时间复杂度近似为O(logn)) diff --git a/docs/database/MySQL高性能优化规范建议.md b/docs/database/MySQL高性能优化规范建议.md index 60f17583..1e380508 100644 --- a/docs/database/MySQL高性能优化规范建议.md +++ b/docs/database/MySQL高性能优化规范建议.md @@ -168,7 +168,7 @@ MySQL 内存临时表不支持 TEXT、BLOB 这样的大数据类型,如果查 **2、TEXT 或 BLOB 类型只能使用前缀索引** -因为[MySQL](http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247487885&idx=1&sn=65b1bf5f7d4505502620179669a9c2df&chksm=ebd62ea1dca1a7b7bf884bcd9d538d78ba064ee03c09436ca8e57873b1d98a55afd6d7884cfc&scene=21#wechat_redirect) 对索引字段长度是有限制的,所以 TEXT 类型只能使用前缀索引,并且 TEXT 列上是不能有默认值的 +因为[MySQL](https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247487885&idx=1&sn=65b1bf5f7d4505502620179669a9c2df&chksm=ebd62ea1dca1a7b7bf884bcd9d538d78ba064ee03c09436ca8e57873b1d98a55afd6d7884cfc&scene=21#wechat_redirect) 对索引字段长度是有限制的,所以 TEXT 类型只能使用前缀索引,并且 TEXT 列上是不能有默认值的 ### 3. 避免使用 ENUM 类型 diff --git a/docs/java/basis/Java基础知识.md b/docs/java/basis/Java基础知识.md index 4911d88f..8ec03170 100644 --- a/docs/java/basis/Java基础知识.md +++ b/docs/java/basis/Java基础知识.md @@ -175,7 +175,7 @@ Java 语言既具有编译型语言的特征,也具有解释型语言的特征 > 字符封装类 `Character` 有一个成员常量 `Character.SIZE` 值为 16,单位是`bits`,该值除以 8(`1byte=8bits`)后就可以得到 2 个字节 > java 编程思想第四版:2.2.2 节 -> ![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-15/86735519.jpg) +> ![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-15/86735519.jpg) ### 注释 @@ -790,7 +790,7 @@ num2 = 20 **解析:** -![example 1 ](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/22191348.jpg) +![example 1 ](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/22191348.jpg) 在 swap 方法中,a、b 的值进行交换,并不会影响到 num1、num2。因为,a、b 中的值,只是从 num1、num2 的复制过来的。也就是说,a、b 相当于 num1、num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。 @@ -821,7 +821,7 @@ num2 = 20 **解析:** -![example 2](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/3825204.jpg) +![example 2](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/3825204.jpg) array 被初始化 arr 的拷贝也就是一个对象的引用,也就是说 array 和 arr 指向的是同一个数组对象。 因此,外部对引用对象的改变会反映到所对应的对象上。 @@ -866,11 +866,11 @@ s2:小李 交换之前: -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/88729818.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/88729818.jpg) 交换之后: -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/34384414.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/34384414.jpg) 通过上面两张图可以很清晰的看出: **方法并没有改变存储在变量 s1 和 s2 中的对象引用。swap 方法的参数 x 和 y 被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝** diff --git a/docs/java/basis/Java常见关键字总结.md b/docs/java/basis/Java常见关键字总结.md index 01fcdf2c..a37ef4b6 100644 --- a/docs/java/basis/Java常见关键字总结.md +++ b/docs/java/basis/Java常见关键字总结.md @@ -186,7 +186,7 @@ static { 一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/88531075.jpg) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/88531075.jpg) 静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问. diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 39bf90f7..2db5c4b1 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -532,13 +532,13 @@ static int hash(int h) { ![HashTable全表锁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HashTable全表锁.png) -