diff --git a/docs/notes/Docker.md b/docs/notes/Docker.md index e4b906a5..16f5df74 100644 --- a/docs/notes/Docker.md +++ b/docs/notes/Docker.md @@ -14,13 +14,13 @@ Docker 主要解决环境配置问题,它是一种虚拟化技术,对进程进行隔离,被隔离的进程独立于宿主操作系统和其它隔离的进程。使用 Docker 可以不修改应用程序代码,不需要开发人员学习特定环境下的技术,就能够将现有的应用程序部署在其它机器上。 -

+

# 二、与虚拟机的比较 虚拟机也是一种虚拟化技术,它与 Docker 最大的区别在于它是通过模拟硬件,并在硬件上安装操作系统来实现。 -

+

## 启动速度 @@ -74,7 +74,7 @@ Docker 轻量级的特点使得它很适合用于部署、维护、组合微服 构建容器时,通过在镜像的基础上添加一个可写层(writable layer),用来保存着容器运行过程中的修改。 -

+

# 参考资料 diff --git a/docs/notes/Git.md b/docs/notes/Git.md index 6bbb1965..f3697494 100644 --- a/docs/notes/Git.md +++ b/docs/notes/Git.md @@ -18,7 +18,7 @@ Git 属于分布式版本控制系统,而 SVN 属于集中式。 -

+

集中式版本控制只有中心服务器拥有一份代码,而分布式版本控制每个人的电脑上就有一份完整的代码。 @@ -40,45 +40,45 @@ Github 就是一个中心服务器。 Git 的版本库有一个称为 Stage 的暂存区以及最后的 History 版本库,History 中存有所有分支,使用一个 HEAD 指针指向当前分支。 -

+

- git add files 把文件的修改添加到暂存区 - git commit 把暂存区的修改提交到当前分支,提交之后暂存区就被清空了 - git reset -- files 使用当前分支上的修改覆盖暂存区,用来撤销最后一次 git add files - git checkout -- files 使用暂存区的修改覆盖工作目录,用来撤销本地修改 -

+

可以跳过暂存区域直接从分支中取出修改,或者直接提交修改到分支中。 - git commit -a 直接把所有文件的修改添加到暂存区然后执行提交 - git checkout HEAD -- files 取出最后一次修改,可以用来进行回滚操作 -

+

# 分支实现 使用指针将每个提交连接成一条时间线,HEAD 指针指向当前分支指针。 -

+

新建分支是新建一个指针指向时间线的最后一个节点,并让 HEAD 指针指向新分支表示新分支成为当前分支。 -

+

每次提交只会让当前分支指针向前移动,而其它分支指针不会移动。 -

+

合并分支也只需要改变指针即可。 -

+

# 冲突 当两个分支都对同一个文件的同一行进行了修改,在分支合并时就会产生冲突。 -

+

Git 会使用 <<<<<<< ,======= ,>>>>>>> 标记出不同分支的内容,只需要把不同分支中冲突部分修改成一样就能解决冲突。 @@ -100,7 +100,7 @@ Creating a new branch is quick AND simple. $ git merge --no-ff -m "merge with no-ff" dev ``` -

+

# 分支管理策略 @@ -108,7 +108,7 @@ master 分支应该是非常稳定的,只用来发布新版本; 日常开发在开发分支 dev 上进行。 -

+

# 储藏(Stashing) @@ -148,7 +148,7 @@ $ ssh-keygen -t rsa -C "youremail@example.com" # Git 命令一览 -

+

比较详细的地址:http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf diff --git a/docs/notes/HTTP.md b/docs/notes/HTTP.md index d584c906..81236f4b 100644 --- a/docs/notes/HTTP.md +++ b/docs/notes/HTTP.md @@ -62,17 +62,17 @@ URI 包含 URL 和 URN。 -

+

## 请求和响应报文 ### 1. 请求报文 -

+

### 2. 响应报文 -

+

# 二、HTTP 方法 @@ -159,7 +159,7 @@ DELETE /file.html HTTP/1.1 CONNECT www.example.com:443 HTTP/1.1 ``` -

+

## TRACE @@ -302,7 +302,7 @@ CONNECT www.example.com:443 HTTP/1.1 ## 连接管理 -

+

### 1. 短连接与长连接 @@ -631,11 +631,11 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名, - 用户察觉得到正向代理的存在。 -

+

- 而反向代理一般位于内部网络中,用户察觉不到。 -

+

### 2. 网关 @@ -657,7 +657,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) 通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。 -

+

## 加密 @@ -668,7 +668,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) - 优点:运算速度快; - 缺点:无法安全地将密钥传输给通信方。 -

+

### 2.非对称密钥加密 @@ -681,13 +681,13 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) - 优点:可以更安全地将公开密钥传输给通信发送方; - 缺点:运算速度慢。 -

+

### 3. HTTPS 采用的加密方式 HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。(下图中的 Session Key 就是对称密钥) -

+

## 认证 @@ -699,7 +699,7 @@ HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对 进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。 -

+

## 完整性保护 @@ -728,7 +728,7 @@ HTTP/1.x 实现简单是以牺牲性能为代价的: HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。 -

+

在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。 @@ -736,13 +736,13 @@ HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式 - 消息(Message)是与逻辑请求或响应对应的完整的一系列帧。 - 帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。 -

+

## 服务端推送 HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。 -

+

## 首部压缩 @@ -752,7 +752,7 @@ HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见 不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。 -

+

# 八、HTTP/1.1 新特性 diff --git a/docs/notes/Java IO.md b/docs/notes/Java IO.md index 47d6cbf6..46dd845a 100644 --- a/docs/notes/Java IO.md +++ b/docs/notes/Java IO.md @@ -97,7 +97,7 @@ Java I/O 使用了装饰者模式来实现。以 InputStream 为例, - FileInputStream 是 InputStream 的子类,属于具体组件,提供了字节流的输入操作; - FilterInputStream 属于抽象装饰者,装饰者用于装饰组件,为组件提供额外的功能。例如 BufferedInputStream 为 FileInputStream 提供缓存的功能。 -

+

实例化一个具有缓存功能的字节流对象时,只需要在 FileInputStream 对象上再套一层 BufferedInputStream 对象即可。 @@ -277,7 +277,7 @@ public static void main(String[] args) throws IOException { - Socket:客户端类 - 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。 -

+

## Datagram @@ -339,23 +339,23 @@ I/O 包和 NIO 已经很好地集成了,java.io.\* 已经以 NIO 为基础重 ① 新建一个大小为 8 个字节的缓冲区,此时 position 为 0,而 limit = capacity = 8。capacity 变量不会改变,下面的讨论会忽略它。 -

+

② 从输入通道中读取 5 个字节数据写入缓冲区中,此时 position 为 5,limit 保持不变。 -

+

③ 在将缓冲区的数据写到输出通道之前,需要先调用 flip() 方法,这个方法将 limit 设置为当前 position,并将 position 设置为 0。 -

+

④ 从缓冲区中取 4 个字节到输出缓冲中,此时 position 设为 4。 -

+

⑤ 最后需要调用 clear() 方法来清空缓冲区,此时 position 和 limit 都被设置为最初位置。 -

+

## 文件 NIO 实例 @@ -413,7 +413,7 @@ NIO 实现了 IO 多路复用中的 Reactor 模型,一个线程 Thread 使用 应该注意的是,只有套接字 Channel 才能配置为非阻塞,而 FileChannel 不能,为 FileChannel 配置非阻塞也没有意义。 -

+

### 1. 创建选择器 diff --git a/docs/notes/Java 基础.md b/docs/notes/Java 基础.md index c3fb3637..442f2cf2 100644 --- a/docs/notes/Java 基础.md +++ b/docs/notes/Java 基础.md @@ -189,7 +189,7 @@ value 数组被声明为 final,这意味着 value 数组初始化之后就不 如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。 -

+

**3. 安全性** @@ -1338,7 +1338,7 @@ Throwable 可以用来表示任何可以作为异常抛出的类,分为两种 - **受检异常** :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复; - **非受检异常** :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。 -

+

- [Java 入门之异常处理](https://www.tianmaying.com/tutorial/Java-Exception) - [Java 异常的面试问题及答案 -Part 1](http://www.importnew.com/7383.html) diff --git a/docs/notes/Java 容器.md b/docs/notes/Java 容器.md index d9ddcd8a..9e823d4b 100644 --- a/docs/notes/Java 容器.md +++ b/docs/notes/Java 容器.md @@ -24,7 +24,7 @@ ## Collection -

+

### 1. Set @@ -50,7 +50,7 @@ ## Map -

+

- TreeMap:基于红黑树实现。 @@ -65,7 +65,7 @@ ## 迭代器模式 -

+

Collection 继承了 Iterable 接口,其中的 iterator() 方法能够产生一个 Iterator 对象,通过这个对象就可以迭代遍历 Collection 中的元素。 @@ -126,7 +126,7 @@ public class ArrayList extends AbstractList private static final int DEFAULT_CAPACITY = 10; ``` -

+

### 2. 扩容 @@ -389,7 +389,7 @@ transient Node first; transient Node last; ``` -

+

### 2. 与 ArrayList 的比较 @@ -411,7 +411,7 @@ transient Entry[] table; Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值相同的 Entry。 -

+

```java static class Entry implements Map.Entry { @@ -487,7 +487,7 @@ map.put("K3", "V3"); - 计算键值对所在的桶; - 在链表上顺序查找,时间复杂度显然和链表的长度成正比。 -

+

### 3. put 操作 @@ -823,7 +823,7 @@ final Segment[] segments; static final int DEFAULT_CONCURRENCY_LEVEL = 16; ``` -

+

### 2. size 操作 diff --git a/docs/notes/Java 并发.md b/docs/notes/Java 并发.md index 5b32b0ec..9f923986 100644 --- a/docs/notes/Java 并发.md +++ b/docs/notes/Java 并发.md @@ -61,7 +61,7 @@ # 一、线程状态转换 -

+

## 新建(New) @@ -736,7 +736,7 @@ java.util.concurrent(J.U.C)大大提高了并发性能,AQS 被认为是 J. 维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。 -

+

```java public class CountdownLatchExample { @@ -785,7 +785,7 @@ public CyclicBarrier(int parties) { } ``` -

+

```java public class CyclicBarrierExample { @@ -1022,7 +1022,7 @@ public class ForkJoinPool extends AbstractExecutorService ForkJoinPool 实现了工作窃取算法来提高 CPU 的利用率。每个线程都维护了一个双端队列,用来存储需要执行的任务。工作窃取算法允许空闲的线程从其它线程的双端队列中窃取一个任务来执行。窃取的任务必须是最晚的任务,避免和队列所属线程发生竞争。例如下图中,Thread2 从 Thread1 的队列中拿出最晚的 Task1 任务,Thread1 会拿出 Task2 来执行,这样就避免发生竞争。但是如果队列中只有一个任务时还是会发生竞争。 -

+

# 九、线程不安全示例 @@ -1077,19 +1077,19 @@ Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异, 加入高速缓存带来了一个新的问题:缓存一致性。如果多个缓存共享同一块主内存区域,那么多个缓存的数据可能会不一致,需要一些协议来解决这个问题。 -

+

所有的变量都存储在主内存中,每个线程还有自己的工作内存,工作内存存储在高速缓存或者寄存器中,保存了该线程使用的变量的主内存副本拷贝。 线程只能直接操作工作内存中的变量,不同线程之间的变量值传递需要通过主内存来完成。 -

+

## 内存间交互操作 Java 内存模型定义了 8 个操作来完成主内存和工作内存的交互操作。 -

+

- read:把一个变量的值从主内存传输到工作内存中 - load:在 read 之后执行,把 read 得到的值放入工作内存的变量副本中 @@ -1112,11 +1112,11 @@ Java 内存模型保证了 read、load、use、assign、store、write、lock 和 下图演示了两个线程同时对 cnt 进行操作,load、assign、store 这一系列操作整体上看不具备原子性,那么在 T1 修改 cnt 并且还没有将修改后的值写入主内存,T2 依然可以读入旧值。可以看出,这两个线程虽然执行了两次自增运算,但是主内存中 cnt 的值最后为 1 而不是 2。因此对 int 类型读写操作满足原子性只是说明 load、assign、store 这些单个操作具备原子性。 -

+

AtomicInteger 能保证多个线程修改的原子性。 -

+

使用 AtomicInteger 重写之前线程不安全的代码之后得到以下线程安全实现: @@ -1224,7 +1224,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 在一个线程内,在程序前面的操作先行发生于后面的操作。 -

+

### 2. 管程锁定规则 @@ -1232,7 +1232,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 一个 unlock 操作先行发生于后面对同一个锁的 lock 操作。 -

+

### 3. volatile 变量规则 @@ -1240,7 +1240,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 对一个 volatile 变量的写操作先行发生于后面对这个变量的读操作。 -

+

### 4. 线程启动规则 @@ -1248,7 +1248,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 Thread 对象的 start() 方法调用先行发生于此线程的每一个动作。 -

+

### 5. 线程加入规则 @@ -1256,7 +1256,7 @@ Thread 对象的 start() 方法调用先行发生于此线程的每一个动作 Thread 对象的结束先行发生于 join() 方法返回。 -

+

### 6. 线程中断规则 @@ -1474,7 +1474,7 @@ public class ThreadLocalExample1 { 它所对应的底层结构图为: -

+

每个 Thread 都有一个 ThreadLocal.ThreadLocalMap 对象。 @@ -1577,17 +1577,17 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态: 以下是 HotSpot 虚拟机对象头的内存布局,这些数据被称为 Mark Word。其中 tag bits 对应了五个状态,这些状态在右侧的 state 表格中给出。除了 marked for gc 状态,其它四个状态已经在前面介绍过了。 -

+

下图左侧是一个线程的虚拟机栈,其中有一部分称为 Lock Record 的区域,这是在轻量级锁运行过程创建的,用于存放锁对象的 Mark Word。而右侧就是一个锁对象,包含了 Mark Word 和其它信息。 -

+

轻量级锁是相对于传统的重量级锁而言,它使用 CAS 操作来避免重量级锁使用互斥量的开销。对于绝大部分的锁,在整个同步周期内都是不存在竞争的,因此也就不需要都使用互斥量进行同步,可以先采用 CAS 操作进行同步,如果 CAS 失败了再改用互斥量进行同步。 当尝试获取一个锁对象时,如果锁对象标记为 0 01,说明锁对象的锁未锁定(unlocked)状态。此时虚拟机在当前线程的虚拟机栈中创建 Lock Record,然后使用 CAS 操作将对象的 Mark Word 更新为 Lock Record 指针。如果 CAS 操作成功了,那么线程就获取了该对象上的锁,并且对象的 Mark Word 的锁标记变为 00,表示该对象处于轻量级锁状态。 -

+

如果 CAS 操作失败了,虚拟机首先会检查对象的 Mark Word 是否指向当前线程的虚拟机栈,如果是的话说明当前线程已经拥有了这个锁对象,那就可以直接进入同步块继续执行,否则说明这个锁对象已经被其他线程线程抢占了。如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁。 @@ -1599,7 +1599,7 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态: 当有另外一个线程去尝试获取这个锁对象时,偏向状态就宣告结束,此时撤销偏向(Revoke Bias)后恢复到未锁定状态或者轻量级锁状态。 -

+

# 十三、多线程开发良好的实践 diff --git a/docs/notes/Java 虚拟机.md b/docs/notes/Java 虚拟机.md index c0cd8409..e0f445ac 100644 --- a/docs/notes/Java 虚拟机.md +++ b/docs/notes/Java 虚拟机.md @@ -30,7 +30,7 @@ # 一、运行时数据区域 -

+

## 程序计数器 @@ -40,7 +40,7 @@ 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 -

+

可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小: @@ -59,7 +59,7 @@ java -Xss512M HackTheJava 本地方法一般是用其它语言(C、C++ 或汇编语言等)编写的,并且被编译为基于本机硬件和操作系统的程序,对待这些方法需要特别处理。 -

+

## 堆 @@ -144,7 +144,7 @@ Java 虚拟机使用该算法来判断对象是否可被回收,GC Roots 一般 - 方法区中类静态属性引用的对象 - 方法区中的常量引用的对象 -

+

### 3. 方法区的回收 @@ -225,7 +225,7 @@ obj = null; ### 1. 标记 - 清除 -

+

在标记阶段,程序会检查每个对象是否为活动对象,如果是活动对象,则程序会在对象头部打上标记。 @@ -240,7 +240,7 @@ obj = null; ### 2. 标记 - 整理 -

+

让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。 @@ -254,7 +254,7 @@ obj = null; ### 3. 复制 -

+

将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。 @@ -275,7 +275,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1,保证了内 ## 垃圾收集器 -

+

以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 @@ -284,7 +284,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1,保证了内 ### 1. Serial 收集器 -

+

Serial 翻译为串行,也就是说它以串行的方式执行。 @@ -296,7 +296,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 2. ParNew 收集器 -

+

它是 Serial 收集器的多线程版本。 @@ -316,7 +316,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 4. Serial Old 收集器 -

+

是 Serial 收集器的老年代版本,也是给 Client 场景下的虚拟机使用。如果用在 Server 场景下,它有两大用途: @@ -325,7 +325,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 5. Parallel Old 收集器 -

+

是 Parallel Scavenge 收集器的老年代版本。 @@ -333,7 +333,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 6. CMS 收集器 -

+

CMS(Concurrent Mark Sweep),Mark Sweep 指的是标记 - 清除算法。 @@ -358,17 +358,17 @@ G1(Garbage-First),它是一款面向服务端应用的垃圾收集器, 堆被分为新生代和老年代,其它收集器进行收集的范围都是整个新生代或者老年代,而 G1 可以直接对新生代和老年代一起回收。 -

+

G1 把堆划分成多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。 -

+

通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。这种划分方法带来了很大的灵活性,使得可预测的停顿时间模型成为可能。通过记录每个 Region 垃圾回收时间以及回收所获得的空间(这两个值是通过过去回收的经验获得),并维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region。 每个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。通过使用 Remembered Set,在做可达性分析的时候就可以避免全堆扫描。 -

+

如果不计算维护 Remembered Set 的操作,G1 收集器的运作大致可划分为以下几个步骤: @@ -456,7 +456,7 @@ G1 把堆划分成多个大小相等的独立区域(Region),新生代和 ## 类的生命周期 -

+

包括以下 7 个阶段: @@ -629,7 +629,7 @@ System.out.println(ConstClass.HELLOWORLD); 下图展示了类加载器之间的层次关系,称为双亲委派模型(Parents Delegation Model)。该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。这里的父子关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)。 -

+

### 1. 工作过程 diff --git a/docs/notes/Leetcode 题解 - 动态规划.md b/docs/notes/Leetcode 题解 - 动态规划.md index 52cde651..52269508 100644 --- a/docs/notes/Leetcode 题解 - 动态规划.md +++ b/docs/notes/Leetcode 题解 - 动态规划.md @@ -59,7 +59,7 @@ -

+

考虑到 dp[i] 只与 dp[i - 1] 和 dp[i - 2] 有关,因此可以只用两个变量来存储 dp[i - 1] 和 dp[i - 2],使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度。 @@ -91,7 +91,7 @@ public int climbStairs(int n) { -

+

```java public int rob(int[] nums) { @@ -145,7 +145,7 @@ private int rob(int[] nums, int first, int last) { -

+

## 母牛生产 @@ -157,7 +157,7 @@ private int rob(int[] nums, int first, int last) { -

+

# 矩阵路径 @@ -203,7 +203,7 @@ public int minPathSum(int[][] grid) { 题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向右或者向下移动。 -

+

```java public int uniquePaths(int m, int n) { @@ -400,7 +400,7 @@ public int numDecodings(String s) { -

+

对于一个长度为 N 的序列,最长递增子序列并不一定会以 SN 为结尾,因此 dp[N] 不是序列的最长递增子序列的长度,需要遍历 dp 数组找出最大值才是所要的结果,max{ dp[i] | 1 <= i <= N} 即为所求。 @@ -567,7 +567,7 @@ public int wiggleMaxLength(int[] nums) { -

+

对于长度为 N 的序列 S1 和长度为 M 的序列 S2,dp[N][M] 就是序列 S1 和序列 S2 的最长公共子序列长度。 @@ -607,7 +607,7 @@ public int lengthOfLCS(int[] nums1, int[] nums2) { -

+

```java public int knapsack(int W, int N, int[] weights, int[] values) { @@ -632,7 +632,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) { -

+

因为 dp[j-w] 表示 dp[i-1][j-w],因此不能先求 dp[i][j-w],以防将 dp[i-1][j-w] 覆盖。也就是说要先计算 dp[i][j] 再计算 dp[i][j-w],在程序实现时需要按倒序来循环求解。 @@ -976,7 +976,7 @@ public int combinationSum4(int[] nums, int target) { 题目描述:交易之后需要有一天的冷却时间。 -

+

```java public int maxProfit(int[] prices) { @@ -1017,7 +1017,7 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. 题目描述:每交易一次,都要支付一定的费用。 -

+

```java public int maxProfit(int[] prices, int fee) { diff --git a/docs/notes/Leetcode 题解 - 排序.md b/docs/notes/Leetcode 题解 - 排序.md index ab34b24f..af32585e 100644 --- a/docs/notes/Leetcode 题解 - 排序.md +++ b/docs/notes/Leetcode 题解 - 排序.md @@ -191,7 +191,7 @@ public String frequencySort(String s) { 它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。 -

+

## 按颜色进行排序 diff --git a/docs/notes/Leetcode 题解 - 搜索.md b/docs/notes/Leetcode 题解 - 搜索.md index d9c48eb7..bc7ff9e3 100644 --- a/docs/notes/Leetcode 题解 - 搜索.md +++ b/docs/notes/Leetcode 题解 - 搜索.md @@ -32,7 +32,7 @@ # BFS -

+

广度优先搜索一层一层地进行遍历,每层遍历都以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点。需要注意的是,遍历过的节点不能再次被遍历。 @@ -261,7 +261,7 @@ private int getShortestPath(List[] graphic, int start, int end) { # DFS -

+

广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。 @@ -572,7 +572,7 @@ Backtracking(回溯)属于 DFS。 [17. Letter Combinations of a Phone Number (Medium)](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) -

+

```html Input:Digit string "23" @@ -1149,7 +1149,7 @@ private boolean isPalindrome(String s, int begin, int end) { [37. Sudoku Solver (Hard)](https://leetcode.com/problems/sudoku-solver/description/) -

+

```java private boolean[][] rowsUsed = new boolean[9][10]; @@ -1169,7 +1169,7 @@ public void solveSudoku(char[][] board) { colsUsed[j][num] = true; cubesUsed[cubeNum(i, j)][num] = true; } - backtracking(0, 0); + backtracking(0, 0); } private boolean backtracking(int row, int col) { @@ -1206,7 +1206,7 @@ private int cubeNum(int i, int j) { [51. N-Queens (Hard)](https://leetcode.com/problems/n-queens/description/) -

+

在 n\*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,求所有的 n 皇后的解。 @@ -1214,12 +1214,12 @@ private int cubeNum(int i, int j) { 45 度对角线标记数组的长度为 2 \* n - 1,通过下图可以明确 (r, c) 的位置所在的数组下标为 r + c。 -

+

135 度对角线标记数组的长度也是 2 \* n - 1,(r, c) 的位置所在的数组下标为 n - 1 - (r - c)。 -

+

```java private List> solutions; diff --git a/docs/notes/Leetcode 题解 - 树.md b/docs/notes/Leetcode 题解 - 树.md index b58cb11b..5ba65af0 100644 --- a/docs/notes/Leetcode 题解 - 树.md +++ b/docs/notes/Leetcode 题解 - 树.md @@ -987,7 +987,7 @@ private void inOrder(TreeNode node, List nums) { # Trie -

+

Trie,又称前缀树或字典树,用于判断字符串是否存在或者是否具有某种字符串前缀。 diff --git a/docs/notes/Linux.md b/docs/notes/Linux.md index fe1f217f..5b8e2fcb 100644 --- a/docs/notes/Linux.md +++ b/docs/notes/Linux.md @@ -157,7 +157,7 @@ Linux 发行版是 Linux 内核及各种应用软件的集成版本。 - 编辑模式(Insert mode):按下 "i" 等按键之后进入,可以对文本进行编辑; - 指令列模式(Bottom-line mode):按下 ":" 按键之后进入,用于保存退出等操作。 -

+

在指令列模式下,有以下命令用于离开或者保存文件。 @@ -191,25 +191,25 @@ GNU 计划,译为革奴计划,它的目标是创建一套完全自由的操 IDE(ATA)全称 Advanced Technology Attachment,接口速度最大为 133MB/s,因为并口线的抗干扰性太差,且排线占用空间较大,不利电脑内部散热,已逐渐被 SATA 所取代。 -

+

### 2. SATA SATA 全称 Serial ATA,也就是使用串口的 ATA 接口,抗干扰性强,且对数据线的长度要求比 ATA 低很多,支持热插拔等功能。SATA-II 的接口速度为 300MiB/s,而新的 SATA-III 标准可达到 600MiB/s 的传输速度。SATA 的数据线也比 ATA 的细得多,有利于机箱内的空气流通,整理线材也比较方便。 -

+

### 3. SCSI SCSI 全称是 Small Computer System Interface(小型机系统接口),经历多代的发展,从早期的 SCSI-II 到目前的 Ultra320 SCSI 以及 Fiber-Channel(光纤通道),接口型式也多种多样。SCSI 硬盘广为工作站以及个人电脑以及服务器所使用,因此会使用较为先进的技术,如碟片转速 15000rpm 的高转速,且传输时 CPU 占用率较低,但是单价也比相同容量的 ATA 及 SATA 硬盘更加昂贵。 -

+

### 4. SAS SAS(Serial Attached SCSI)是新一代的 SCSI 技术,和 SATA 硬盘相同,都是采取序列式技术以获得更高的传输速度,可达到 6Gb/s。此外也通过缩小连接线改善系统内部空间等。 -

+

## 磁盘的文件名 @@ -244,7 +244,7 @@ GPT 没有扩展分区概念,都是主分区,每个 LBA 可以分 4 个分 MBR 不支持 2.2 TB 以上的硬盘,GPT 则最多支持到 233 TB = 8 ZB。 -

+

## 开机检测程序 @@ -252,7 +252,7 @@ MBR 不支持 2.2 TB 以上的硬盘,GPT 则最多支持到 233 TB BIOS(Basic Input/Output System,基本输入输出系统),它是一个固件(嵌入在硬件中的软件),BIOS 程序存放在断电后内容不会丢失的只读内存中。 -

+

BIOS 是开机的时候计算机执行的第一个程序,这个程序知道可以开机的磁盘,并读取磁盘第一个扇区的主要开机记录(MBR),由主要开机记录(MBR)执行其中的开机管理程序,这个开机管理程序会加载操作系统的核心文件。 @@ -260,7 +260,7 @@ BIOS 是开机的时候计算机执行的第一个程序,这个程序知道可 下图中,第一扇区的主要开机记录(MBR)中的开机管理程序提供了两个选单:M1、M2,M1 指向了 Windows 操作系统,而 M2 指向其它分区的启动扇区,里面包含了另外一个开机管理程序,提供了一个指向 Linux 的选单。 -

+

安装多重引导,最好先安装 Windows 再安装 Linux。因为安装 Windows 时会覆盖掉主要开机记录(MBR),而 Linux 可以选择将开机管理程序安装在主要开机记录(MBR)或者其它分区的启动扇区,并且可以设置开机管理程序的选单。 @@ -286,17 +286,17 @@ BIOS 不可以读取 GPT 分区表,而 UEFI 可以。 - superblock:记录文件系统的整体信息,包括 inode 和 block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等; - block bitmap:记录 block 是否被使用的位域。 -

+

## 文件读取 对于 Ext2 文件系统,当要读取一个文件的内容时,先在 inode 中去查找文件内容所在的所有 block,然后把所有 block 的内容读出来。 -

+

而对于 FAT 文件系统,它没有 inode,每个 block 中存储着下一个 block 的编号。 -

+

## 磁盘碎片 @@ -333,7 +333,7 @@ inode 具有以下特点: inode 中记录了文件内容所在的 block 编号,但是每个 block 非常小,一个大文件随便都需要几十万的 block。而一个 inode 大小有限,无法直接引用这么多 block 编号。因此引入了间接、双间接、三间接引用。间接引用是指,让 inode 记录的引用 block 块记录引用信息。 -

+

## 目录 @@ -359,7 +359,7 @@ ext3/ext4 文件系统引入了日志功能,可以利用日志来修复文件 - /usr (unix software resource):所有系统默认软件都会安装到这个目录; - /var (variable):存放系统或程序运行过程中的数据文件。 -

+

# 五、文件 @@ -534,7 +534,7 @@ cp [-adfilprsu] source destination -f :如果目标文件存在时,先删除目标文件 ``` -

+

### 1. 实体链接 @@ -655,7 +655,7 @@ example: find . -name "shadow*" +4、4 和 -4 的指示的时间范围如下: -

+

**② 与文件拥有者和所属群组有关的选项** @@ -1168,7 +1168,7 @@ dmtsai lines: 5 columns: 9 | Z | zombie (terminated but not reaped by its parent) | | T | stopped (either by a job control signal or because it is being traced) |
-

+

## SIGCHLD @@ -1181,7 +1181,7 @@ dmtsai lines: 5 columns: 9 在子进程退出时,它的进程描述符不会立即释放,这是为了让父进程得到子进程信息,父进程通过 wait() 和 waitpid() 来获得一个已经退出的子进程的信息。 -

+

## wait() diff --git a/docs/notes/MySQL.md b/docs/notes/MySQL.md index b920b64b..de53fa1d 100644 --- a/docs/notes/MySQL.md +++ b/docs/notes/MySQL.md @@ -42,7 +42,7 @@ B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具 在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。 -

+

### 2. 操作 @@ -84,11 +84,11 @@ B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具 InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。 -

+

辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。 -

+

### 2. 哈希索引 @@ -350,7 +350,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。 -

+

## 垂直切分 @@ -358,7 +358,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。 -

+

## Sharding 策略 @@ -392,7 +392,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 - **I/O 线程** :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。 - **SQL 线程** :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中执行。 -

+

## 读写分离 @@ -406,7 +406,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。 -

+

# 参考资料 diff --git a/docs/notes/Redis.md b/docs/notes/Redis.md index 452d217c..d0c225fb 100644 --- a/docs/notes/Redis.md +++ b/docs/notes/Redis.md @@ -67,7 +67,7 @@ Redis 支持很多特性,例如将内存中的数据持久化到硬盘中, ## STRING -

+

```html > set hello world @@ -82,7 +82,7 @@ OK ## LIST -

+

```html > rpush list-key item @@ -110,7 +110,7 @@ OK ## SET -

+

```html > sadd set-key item @@ -144,7 +144,7 @@ OK ## HASH -

+

```html > hset hash-key sub-key1 value1 @@ -175,7 +175,7 @@ OK ## ZSET -

+

```html > zadd zset-key 728 member1 @@ -317,11 +317,11 @@ int dictRehash(dict *d, int n) { 跳跃表是基于多指针有序链表实现的,可以看成多个有序链表。 -

+

在查找时,从上层指针开始查找,找到对应的区间之后再到下一层去查找。下图演示了查找 22 的过程。 -

+

与红黑树等平衡树相比,跳跃表具有以下优点: @@ -472,7 +472,7 @@ Redis 服务器是一个事件驱动程序。 Redis 基于 Reactor 模式开发了自己的网络事件处理器,使用 I/O 多路复用程序来同时监听多个套接字,并将到达的事件传送给文件事件分派器,分派器会根据套接字产生的事件类型调用相应的事件处理器。 -

+

## 时间事件 @@ -525,7 +525,7 @@ def main(): 从事件处理的角度来看,服务器运行流程如下: -

+

# 十一、复制 @@ -545,7 +545,7 @@ def main(): 随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。 -

+

# 十二、Sentinel @@ -580,7 +580,7 @@ Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入 Redis 没有关系型数据库中的表这一概念来将同种类型的数据存放在一起,而是使用命名空间的方式来实现这一功能。键名的前面部分存储命名空间,后面部分的内容存储 ID,通常使用 : 来进行分隔。例如下面的 HASH 的键名为 article:92617,其中 article 为命名空间,ID 为 92617。 -

+

## 点赞功能 @@ -588,13 +588,13 @@ Redis 没有关系型数据库中的表这一概念来将同种类型的数据 为了节约内存,规定一篇文章发布满一周之后,就不能再对它进行投票,而文章的已投票集合也会被删除,可以为文章的已投票集合设置一个一周的过期时间就能实现这个规定。 -

+

## 对文章进行排序 为了按发布时间和点赞数进行排序,可以建立一个文章发布时间的有序集合和一个文章点赞数的有序集合。(下图中的 score 就是这里所说的点赞数;下面所示的有序集合分值并不直接是时间和点赞数,而是根据时间和点赞数间接计算出来的) -

+

# 参考资料 diff --git a/docs/notes/Socket.md b/docs/notes/Socket.md index a3ff120f..4b357bb7 100644 --- a/docs/notes/Socket.md +++ b/docs/notes/Socket.md @@ -46,7 +46,7 @@ Unix 有五种 I/O 模型: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); ``` -

+

## 非阻塞式 I/O @@ -54,7 +54,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 由于 CPU 要处理更多的系统调用,因此这种模型的 CPU 利用率比较低。 -

+

## I/O 复用 @@ -64,7 +64,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 如果一个 Web 服务器没有 I/O 复用,那么每一个 Socket 连接都需要创建一个线程去处理。如果同时有几万个连接,那么就需要创建相同数量的线程。相比于多进程和多线程技术,I/O 复用不需要进程线程创建和切换的开销,系统开销更小。 -

+

## 信号驱动 I/O @@ -72,7 +72,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 相比于非阻塞式 I/O 的轮询方式,信号驱动 I/O 的 CPU 利用率更高。 -

+

## 异步 I/O @@ -80,7 +80,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 异步 I/O 与信号驱动 I/O 的区别在于,异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O。 -

+

## 五大 I/O 模型比较 @@ -91,7 +91,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 非阻塞式 I/O 、信号驱动 I/O 和异步 I/O 在第一阶段不会阻塞。 -

+

# 二、I/O 复用 diff --git a/docs/notes/代码可读性.md b/docs/notes/代码可读性.md index fd1b3179..3675bb3a 100644 --- a/docs/notes/代码可读性.md +++ b/docs/notes/代码可读性.md @@ -48,11 +48,11 @@ - 用 min、max 表示数量范围; - 用 first、last 表示访问空间的包含范围; -

+

- begin、end 表示访问空间的排除范围,即 end 不包含尾部。 -

+

# 四、良好的代码风格 diff --git a/docs/notes/分布式.md b/docs/notes/分布式.md index 5ed09dac..752acbfe 100644 --- a/docs/notes/分布式.md +++ b/docs/notes/分布式.md @@ -70,7 +70,7 @@ EXPIRE 指令可以为一个键值对设置一个过期时间,从而避免了 Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父节点为 /app1。 -

+

### 2. 节点类型 @@ -111,7 +111,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 2. 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。 3. 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。 -

+

## 2PC @@ -123,7 +123,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 协调者询问参与者事务是否执行成功,参与者发回事务执行结果。 -

+

#### 1.2 提交阶段 @@ -131,7 +131,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。 -

+

### 2. 存在的问题 @@ -155,7 +155,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容忍性(P:Partition Tolerance),最多只能同时满足其中两项。 -

+

## 一致性 @@ -184,7 +184,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 - 为了保证一致性(CP),不能访问未同步完成的节点,也就失去了部分可用性; - 为了保证可用性(AP),允许读取所有节点的数据,但是数据可能不一致。 -

+

# 四、BASE @@ -221,7 +221,7 @@ ACID 要求强一致性,通常运用在传统的数据库系统上。而 BASE - 接受者(Acceptor):对每个提议进行投票; - 告知者(Learner):被告知投票的结果,不参与投票过程。 -

+

## 执行过程 @@ -231,19 +231,19 @@ ACID 要求强一致性,通常运用在传统的数据库系统上。而 BASE 下图演示了两个 Proposer 和三个 Acceptor 的系统中运行该算法的初始过程,每个 Proposer 都会向所有 Acceptor 发送 Prepare 请求。 -

+

当 Acceptor 接收到一个 Prepare 请求,包含的提议为 [n1, v1],并且之前还未接收过 Prepare 请求,那么发送一个 Prepare 响应,设置当前接收到的提议为 [n1, v1],并且保证以后不会再接受序号小于 n1 的提议。 如下图,Acceptor X 在收到 [n=2, v=8] 的 Prepare 请求时,由于之前没有接收过提议,因此就发送一个 [no previous] 的 Prepare 响应,设置当前接收到的提议为 [n=2, v=8],并且保证以后不会再接受序号小于 2 的提议。其它的 Acceptor 类似。 -

+

如果 Acceptor 接收到一个 Prepare 请求,包含的提议为 [n2, v2],并且之前已经接收过提议 [n1, v1]。如果 n1 > n2,那么就丢弃该提议请求;否则,发送 Prepare 响应,该 Prepare 响应包含之前已经接收过的提议 [n1, v1],设置当前接收到的提议为 [n2, v2],并且保证以后不会再接受序号小于 n2 的提议。 如下图,Acceptor Z 收到 Proposer A 发来的 [n=2, v=8] 的 Prepare 请求,由于之前已经接收过 [n=4, v=5] 的提议,并且 n > 2,因此就抛弃该提议请求;Acceptor X 收到 Proposer B 发来的 [n=4, v=5] 的 Prepare 请求,因为之前接收到的提议为 [n=2, v=8],并且 2 <= 4,因此就发送 [n=2, v=8] 的 Prepare 响应,设置当前接收到的提议为 [n=4, v=5],并且保证以后不会再接受序号小于 4 的提议。Acceptor Y 类似。 -

+

### 2. Accept 阶段 @@ -253,13 +253,13 @@ Proposer A 接收到两个 Prepare 响应之后,就发送 [n=2, v=8] Accept Proposer B 过后也收到了两个 Prepare 响应,因此也开始发送 Accept 请求。需要注意的是,Accept 请求的 v 需要取它收到的最大提议编号对应的 v 值,也就是 8。因此它发送 [n=4, v=8] 的 Accept 请求。 -

+

### 3. Learn 阶段 Acceptor 接收到 Accept 请求时,如果序号大于等于该 Acceptor 承诺的最小序号,那么就发送 Learn 提议给所有的 Learner。当 Learner 发现有大多数的 Acceptor 接收了某个提议,那么该提议的提议值就被 Paxos 选择出来。 -

+

## 约束条件 @@ -285,47 +285,47 @@ Raft 也是分布式一致性协议,主要是用来竞选主节点。 - 下图展示一个分布式系统的最初阶段,此时只有 Follower 没有 Leader。Node A 等待一个随机的竞选超时时间之后,没收到 Leader 发来的心跳包,因此进入竞选阶段。 -

+

- 此时 Node A 发送投票请求给其它所有节点。 -

+

- 其它节点会对请求进行回复,如果超过一半的节点回复了,那么该 Candidate 就会变成 Leader。 -

+

- 之后 Leader 会周期性地发送心跳包给 Follower,Follower 接收到心跳包,会重新开始计时。 -

+

## 多个 Candidate 竞选 - 如果有多个 Follower 成为 Candidate,并且所获得票数相同,那么就需要重新开始投票。例如下图中 Node B 和 Node D 都获得两票,需要重新开始投票。 -

+

- 由于每个节点设置的随机竞选超时时间不同,因此下一次再次出现多个 Candidate 并获得同样票数的概率很低。 -

+

## 数据同步 - 来自客户端的修改都会被传入 Leader。注意该修改还未被提交,只是写入日志中。 -

+

- Leader 会把修改复制到所有 Follower。 -

+

- Leader 会等待大多数的 Follower 也进行了修改,然后才将修改提交。 -

+

- 此时 Leader 会通知的所有 Follower 让它们也提交修改,此时所有节点的值达成一致。 -

+

# 参考 diff --git a/docs/notes/剑指 Offer 题解 - 10~19.md b/docs/notes/剑指 Offer 题解 - 10~19.md index 390e2cb4..38f084eb 100644 --- a/docs/notes/剑指 Offer 题解 - 10~19.md +++ b/docs/notes/剑指 Offer 题解 - 10~19.md @@ -26,13 +26,13 @@ -

+

## 解题思路 如果使用递归求解,会重复计算一些子问题。例如,计算 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。 -

+

递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 @@ -93,7 +93,7 @@ public class Solution { 我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? -

+

## 解题思路 @@ -120,7 +120,7 @@ public int RectCover(int n) { 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 -

+

## 解题思路 @@ -147,7 +147,7 @@ public int JumpFloor(int n) { 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 -

+

## 解题思路 @@ -271,7 +271,7 @@ private int minNumber(int[] nums, int l, int h) { 例如下面的矩阵包含了一条 bfce 路径。 -

+

## 解题思路 @@ -481,7 +481,7 @@ public int NumberOf1(int n) { -

+

因为 (x\*x)n/2 可以通过递归求解,并且每次递归 n 都减小一半,因此整个算法的时间复杂度为 O(logN)。 @@ -551,13 +551,13 @@ private void printNumber(char[] number) { ① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 -

+

② 如果链表只有一个节点,那么直接 ② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 -

+

综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 @@ -591,7 +591,7 @@ public ListNode deleteNode(ListNode head, ListNode tobeDelete) { ## 题目描述 -

+

## 解题描述 diff --git a/docs/notes/剑指 Offer 题解 - 20~29.md b/docs/notes/剑指 Offer 题解 - 20~29.md index 0480b2c6..7a568ee1 100644 --- a/docs/notes/剑指 Offer 题解 - 20~29.md +++ b/docs/notes/剑指 Offer 题解 - 20~29.md @@ -68,7 +68,7 @@ public boolean isNumeric(char[] str) { 需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。 -

+

## 解题思路 @@ -98,7 +98,7 @@ public void reOrderArray(int[] nums) { 设链表的长度为 N。设两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到 N - K 个节点处,该位置就是倒数第 K 个节点。 -

+

```java public ListNode FindKthToTail(ListNode head, int k) { @@ -132,7 +132,7 @@ public ListNode FindKthToTail(ListNode head, int k) { 在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 -

+

```java public ListNode EntryNodeOfLoop(ListNode pHead) { @@ -193,7 +193,7 @@ public ListNode ReverseList(ListNode head) { ## 题目描述 -

+

## 解题思路 @@ -245,7 +245,7 @@ public ListNode Merge(ListNode list1, ListNode list2) { ## 题目描述 -

+

## 解题思路 @@ -273,7 +273,7 @@ private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) { ## 题目描述 -

+

## 解题思路 @@ -299,7 +299,7 @@ private void swap(TreeNode root) { ## 题目描述 -

+

## 解题思路 @@ -329,7 +329,7 @@ boolean isSymmetrical(TreeNode t1, TreeNode t2) { 下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 -

+

## 解题思路 diff --git a/docs/notes/剑指 Offer 题解 - 30~39.md b/docs/notes/剑指 Offer 题解 - 30~39.md index fdd0b24f..ffcad1a4 100644 --- a/docs/notes/剑指 Offer 题解 - 30~39.md +++ b/docs/notes/剑指 Offer 题解 - 30~39.md @@ -87,7 +87,7 @@ public boolean IsPopOrder(int[] pushSequence, int[] popSequence) { 例如,以下二叉树层次遍历的结果为:1,2,3,4,5,6,7 -

+

## 解题思路 @@ -195,7 +195,7 @@ public ArrayList> Print(TreeNode pRoot) { 例如,下图是后序遍历序列 1,3,2 所对应的二叉搜索树。 -

+

## 解题思路 @@ -230,7 +230,7 @@ private boolean verify(int[] sequence, int first, int last) { 下图的二叉树有两条和为 22 的路径:10, 5, 7 和 10, 12 -

+

## 解题思路 @@ -277,21 +277,21 @@ public class RandomListNode { } ``` -

+

## 解题思路 第一步,在每个节点的后面插入复制的节点。 -

+

第二步,对复制节点的 random 链接进行赋值。 -

+

第三步,拆分。 -

+

```java public RandomListNode Clone(RandomListNode pHead) { @@ -333,7 +333,7 @@ public RandomListNode Clone(RandomListNode pHead) { 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 -

+

## 解题思路 diff --git a/docs/notes/剑指 Offer 题解 - 3~9.md b/docs/notes/剑指 Offer 题解 - 3~9.md index 91085c60..1ef7b351 100644 --- a/docs/notes/剑指 Offer 题解 - 3~9.md +++ b/docs/notes/剑指 Offer 题解 - 3~9.md @@ -33,7 +33,7 @@ Output: 以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复: -

+

```java public boolean duplicate(int[] nums, int length, int[] duplication) { @@ -86,7 +86,7 @@ Given target = 20, return false. 该二维数组中的一个数,它左边的数都比它小,下边的数都比它大。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间,当前元素的查找区间为左下角的所有元素。 -

+

```java public boolean Find(int target, int[][] matrix) { @@ -131,7 +131,7 @@ Output: 从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。 -

+

```java public String replaceSpace(StringBuffer str) { @@ -163,13 +163,13 @@ public String replaceSpace(StringBuffer str) { 从尾到头反过来打印出每个结点的值。 -

+

## 解题思路 ### 使用递归 -

+

```java @@ -193,7 +193,7 @@ public ArrayList printListFromTailToHead(ListNode listNode) { - 第一个节点就是链表的第一个真正存储值的节点。 -

+

```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -218,7 +218,7 @@ public ArrayList printListFromTailToHead(ListNode listNode) { ### 使用栈 -

+

```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -247,13 +247,13 @@ preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] ``` -

+

## 解题思路 前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。 -

+

```java // 缓存中序遍历数组每个值对应的索引 @@ -303,11 +303,11 @@ public class TreeLinkNode { ① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点; -

+

② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。 -

+

```java public TreeLinkNode GetNext(TreeLinkNode pNode) { @@ -340,7 +340,7 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) { in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 -

+

```java diff --git a/docs/notes/剑指 Offer 题解 - 50~59.md b/docs/notes/剑指 Offer 题解 - 50~59.md index 0459e591..a8136ee8 100644 --- a/docs/notes/剑指 Offer 题解 - 50~59.md +++ b/docs/notes/剑指 Offer 题解 - 50~59.md @@ -115,7 +115,7 @@ private void merge(int[] nums, int l, int m, int h) { ## 题目描述 -

+

## 解题思路 @@ -207,7 +207,7 @@ private void inOrder(TreeNode root, int k) { 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 -

+

## 解题思路 @@ -225,7 +225,7 @@ public int TreeDepth(TreeNode root) { 平衡二叉树左右子树高度差不超过 1。 -

+

## 解题思路 diff --git a/docs/notes/剑指 Offer 题解 - 60~68.md b/docs/notes/剑指 Offer 题解 - 60~68.md index e53fc552..c8984e8f 100644 --- a/docs/notes/剑指 Offer 题解 - 60~68.md +++ b/docs/notes/剑指 Offer 题解 - 60~68.md @@ -19,7 +19,7 @@ 把 n 个骰子仍在地上,求点数和为 s 的概率。 -

+

## 解题思路 @@ -92,7 +92,7 @@ public List> dicesSum(int n) { 五张牌,其中大小鬼为癞子,牌面大小为 0。判断这五张牌是否能组成顺子。 -

+

## 解题思路 @@ -152,7 +152,7 @@ public int LastRemaining_Solution(int n, int m) { 可以有一次买入和一次卖出,那么买入必须在前。求最大收益。 -

+

## 解题思路 @@ -224,7 +224,7 @@ public int Add(int a, int b) { 给定一个数组 A[0, 1,..., n-1],请构建一个数组 B[0, 1,..., n-1],其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]。要求不能使用除法。 -

+

## 解题思路 @@ -289,7 +289,7 @@ public int StrToInt(String str) { 二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val。 -

+

```java public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { @@ -309,7 +309,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 在左右子树中查找是否存在 p 或者 q,如果 p 和 q 分别在两个子树中,那么就说明根节点就是最低公共祖先。 -

+

```java public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { diff --git a/docs/notes/数据库系统原理.md b/docs/notes/数据库系统原理.md index 8e062a5e..ff714da3 100644 --- a/docs/notes/数据库系统原理.md +++ b/docs/notes/数据库系统原理.md @@ -47,7 +47,7 @@ 事务指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。 -

+

## ACID @@ -80,7 +80,7 @@ - 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。 - 事务满足持久化是为了能应对数据库崩溃的情况。 -

+

## AUTOCOMMIT @@ -94,25 +94,25 @@ MySQL 默认采用自动提交模式。也就是说,如果不显式使用`STAR T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。 -

+

## 读脏数据 T1 修改一个数据,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。 -

+

## 不可重复读 T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。 -

+

## 幻影读 T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。 -

+

---- @@ -130,7 +130,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 在选择封锁粒度时,需要在锁开销和并发程度之间做一个权衡。 -

+

## 封锁类型 @@ -321,7 +321,7 @@ MVCC 在每行记录后面都保存着两个隐藏的列,用来存储两个版 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回滚指针把一个数据行(Record)的所有快照连接起来。 -

+

## 实现过程 @@ -437,7 +437,7 @@ SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; 高级别范式的依赖于低级别的范式,1NF 是最低级别的范式。 -

+

### 1. 第一范式 (1NF) @@ -537,7 +537,7 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 下图的 Course 和 Student 是一对多的关系。 -

+

## 表示出现多次的关系 @@ -545,23 +545,23 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 下图表示一个课程的先修关系,先修关系出现两个 Course 实体,第一个是先修课程,后一个是后修课程,因此需要用两条线来表示这种关系。 -

+

## 联系的多向性 虽然老师可以开设多门课,并且可以教授多名学生,但是对于特定的学生和课程,只有一个老师教授,这就构成了一个三元联系。 -

+

一般只使用二元联系,可以把多元联系转换为二元联系。 -

+

## 表示子类 用一个三角形和两条线来连接类和子类,与子类有关的属性和联系都连到子类上,而与父类和子类都有关的连到父类上。 -

+

# 参考资料 diff --git a/docs/notes/构建工具.md b/docs/notes/构建工具.md index 85ef4ace..975b3702 100644 --- a/docs/notes/构建工具.md +++ b/docs/notes/构建工具.md @@ -35,7 +35,7 @@ 主要包括 Ant、Maven 和 Gradle。 -

+

Gradle 和 Maven 的区别是,它使用 Groovy 这种特定领域语言(DSL)来管理构建脚本,而不再使用 XML 这种标记性语言。因为项目如果庞大的话,XML 很容易就变得臃肿。 diff --git a/docs/notes/正则表达式.md b/docs/notes/正则表达式.md index ded641a4..4d5de35c 100644 --- a/docs/notes/正则表达式.md +++ b/docs/notes/正则表达式.md @@ -173,7 +173,7 @@ a.+c ^\s*\/\/.*$ ``` -

+

**匹配结果** diff --git a/docs/notes/消息队列.md b/docs/notes/消息队列.md index 91055cf7..f68b7b07 100644 --- a/docs/notes/消息队列.md +++ b/docs/notes/消息队列.md @@ -19,20 +19,20 @@ 消息生产者向消息队列中发送了一个消息之后,只能被一个消费者消费一次。 -

+

## 发布/订阅 消息生产者向频道发送一个消息之后,多个消费者可以从该频道订阅到这条消息并消费。 -

+

发布与订阅模式和观察者模式有以下不同: - 观察者模式中,观察者和主题都知道对方的存在;而在发布与订阅模式中,发布者与订阅者不知道对方的存在,它们之间通过频道进行通信。 - 观察者模式是同步的,当事件触发时,主题会调用观察者的方法,然后等待方法返回;而发布与订阅模式是异步的,发布者向频道发送一个消息之后,就不需要关心订阅者何时去订阅这个消息,可以立即返回。 -

+

# 二、使用场景 diff --git a/docs/notes/算法 - 其它.md b/docs/notes/算法 - 其它.md index 4821229d..66ef4080 100644 --- a/docs/notes/算法 - 其它.md +++ b/docs/notes/算法 - 其它.md @@ -6,7 +6,7 @@ # 汉诺塔 -

+

有三个柱子,分别为 from、buffer、to。需要将 from 上的圆盘全部移动到 to 上,并且要保证小圆盘始终在大圆盘上。 @@ -14,15 +14,15 @@ ① 将 n-1 个圆盘从 from -> buffer -

+

② 将 1 个圆盘从 from -> to -

+

③ 将 n-1 个圆盘从 buffer -> to -

+

如果只有一个圆盘,那么只需要进行一次移动操作。 @@ -73,7 +73,7 @@ from H1 to H3 生成编码时,从根节点出发,向左遍历则添加二进制位 0,向右则添加二进制位 1,直到遍历到叶子节点,叶子节点代表的字符的编码就是这个路径编码。 -

+

```java public class Huffman { diff --git a/docs/notes/算法 - 并查集.md b/docs/notes/算法 - 并查集.md index 1e2692e5..a2d51e57 100644 --- a/docs/notes/算法 - 并查集.md +++ b/docs/notes/算法 - 并查集.md @@ -12,7 +12,7 @@ 用于解决动态连通性问题,能动态连接两个点,并且判断两个点是否连通。 -

+

| 方法 | 描述 | | :---: | :---: | @@ -51,7 +51,7 @@ public abstract class UF { 但是 union 操作代价却很高,需要将其中一个连通分量中的所有节点 id 值都修改为另一个节点的 id 值。 -

+

```java public class QuickFindUF extends UF { @@ -91,7 +91,7 @@ public class QuickFindUF extends UF { 但是 find 操作开销很大,因为同一个连通分量的节点 id 值不同,id 值只是用来指向另一个节点。因此需要一直向上查找操作,直到找到最上层的节点。 -

+

```java public class QuickUnionUF extends UF { @@ -124,7 +124,7 @@ public class QuickUnionUF extends UF { 这种方法可以快速进行 union 操作,但是 find 操作和树高成正比,最坏的情况下树的高度为节点的数目。 -

+

# 加权 Quick Union @@ -132,7 +132,7 @@ public class QuickUnionUF extends UF { 理论研究证明,加权 quick-union 算法构造的树深度最多不超过 logN。 -

+

```java public class WeightedQuickUnionUF extends UF { diff --git a/docs/notes/算法 - 排序.md b/docs/notes/算法 - 排序.md index bac21268..b130ed35 100644 --- a/docs/notes/算法 - 排序.md +++ b/docs/notes/算法 - 排序.md @@ -58,7 +58,7 @@ public abstract class Sort> { 选择排序需要 \~N2/2 次比较和 \~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。 -

+

```java public class Selection> extends Sort { @@ -85,7 +85,7 @@ public class Selection> extends Sort { 在一轮循环中,如果没有发生交换,那么说明数组已经是有序的,此时可以直接退出。 -

+

```java public class Bubble> extends Sort { @@ -119,7 +119,7 @@ public class Bubble> extends Sort { - 最坏的情况下需要 \~N2/2 比较以及 \~N2/2 次交换,最坏的情况是数组是倒序的; - 最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。 -

+

```java public class Insertion> extends Sort { @@ -142,7 +142,7 @@ public class Insertion> extends Sort { 希尔排序使用插入排序对间隔 h 的序列进行排序。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。 -

+

```java public class Shell> extends Sort { @@ -176,7 +176,7 @@ public class Shell> extends Sort { 归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。 -

+

## 1. 归并方法 @@ -272,7 +272,7 @@ public class Down2UpMergeSort> extends MergeSort { - 归并排序将数组分为两个子数组分别排序,并将有序的子数组归并使得整个数组排序; - 快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了。 -

+

```java public class QuickSort> extends Sort { @@ -303,7 +303,7 @@ public class QuickSort> extends Sort { 取 a[l] 作为切分元素,然后从数组的左端向右扫描直到找到第一个大于等于它的元素,再从数组的右端向左扫描找到第一个小于它的元素,交换这两个元素。不断进行这个过程,就可以保证左指针 i 的左侧元素都不大于切分元素,右指针 j 的右侧元素都不小于切分元素。当两个指针相遇时,将切分元素 a[l] 和 a[j] 交换位置。 -

+

```java private int partition(T[] nums, int l, int h) { @@ -407,7 +407,7 @@ public T select(T[] nums, int k) { 堆可以用数组来表示,这是因为堆是完全二叉树,而完全二叉树很容易就存储在数组中。位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1。这里不使用数组索引为 0 的位置,是为了更清晰地描述节点的位置关系。 -

+

```java public class Heap> { @@ -443,7 +443,7 @@ public class Heap> { 在堆中,当一个节点比父节点大,那么需要交换这个两个节点。交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,把这种操作称为上浮。 -

+

```java private void swim(int k) { @@ -456,7 +456,7 @@ private void swim(int k) { 类似地,当一个节点比子节点来得小,也需要不断地向下进行比较和交换操作,把这种操作称为下沉。一个节点如果有两个子节点,应当与两个子节点中最大那个节点进行交换。 -

+

```java private void sink(int k) { @@ -505,13 +505,13 @@ public T delMax() { 无序数组建立堆最直接的方法是从左到右遍历数组进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。 -

+

#### 5.2 交换堆顶元素与最后一个元素 交换之后需要进行下沉操作维持堆的有序状态。 -

+

```java public class HeapSort> extends Sort { diff --git a/docs/notes/算法 - 符号表.md b/docs/notes/算法 - 符号表.md index eeccaa3d..1eb1652b 100644 --- a/docs/notes/算法 - 符号表.md +++ b/docs/notes/算法 - 符号表.md @@ -245,13 +245,13 @@ public class BinarySearchOrderedST, Value> implement **二叉树** 是一个空链接,或者是一个有左右两个链接的节点,每个链接都指向一颗子二叉树。 -

+

**二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。 BST 有一个重要性质,就是它的中序遍历结果递增排序。 -

+

基本数据结构: @@ -325,7 +325,7 @@ private Value get(Node x, Key key) { 当插入的键不存在于树中,需要创建一个新节点,并且更新上层节点的链接指向该节点,使得该节点正确地链接到树中。 -

+

```java @Override @@ -354,11 +354,11 @@ private Node put(Node x, Key key, Value value) { 最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。 -

+

在最坏的情况下,树的高度为 N。 -

+

## 4. floor() @@ -436,7 +436,7 @@ private Node min(Node x) { 令指向最小节点的链接指向最小节点的右子树。 -

+

```java public void deleteMin() { @@ -457,7 +457,7 @@ public Node deleteMin(Node x) { - 如果待删除的节点只有一个子树, 那么只需要让指向待删除节点的链接指向唯一的子树即可; - 否则,让右子树的最小节点替换该节点。 -

+

```java public void delete(Key key) { @@ -520,7 +520,7 @@ private List keys(Node x, Key l, Key h) { 2-3 查找树引入了 2- 节点和 3- 节点,目的是为了让树平衡。一颗完美平衡的 2-3 查找树的所有空链接到根节点的距离应该是相同的。 -

+

## 1. 插入操作 @@ -530,11 +530,11 @@ private List keys(Node x, Key l, Key h) { - 如果插入到 2- 节点上,那么直接将新节点和原来的节点组成 3- 节点即可。 -

+

- 如果是插入到 3- 节点上,就会产生一个临时 4- 节点时,需要将 4- 节点分裂成 3 个 2- 节点,并将中间的 2- 节点移到上层节点中。如果上移操作继续产生临时 4- 节点则一直进行分裂上移,直到不存在临时 4- 节点。 -

+

## 2. 性质 @@ -546,7 +546,7 @@ private List keys(Node x, Key l, Key h) { 红黑树是 2-3 查找树,但它不需要分别定义 2- 节点和 3- 节点,而是在普通的二叉查找树之上,为节点添加颜色。指向一个节点的链接颜色如果为红色,那么这个节点和上层节点表示的是一个 3- 节点,而黑色则是普通链接。 -

+

红黑树具有以下性质: @@ -555,7 +555,7 @@ private List keys(Node x, Key l, Key h) { 画红黑树时可以将红链接画平。 -

+

```java public class RedBlackBST, Value> extends BST { @@ -575,7 +575,7 @@ public class RedBlackBST, Value> extends BST
+

```java public Node rotateLeft(Node h) { @@ -594,7 +594,7 @@ public Node rotateLeft(Node h) { 进行右旋转是为了转换两个连续的左红链接,这会在之后的插入过程中探讨。 -

+

```java public Node rotateRight(Node h) { @@ -613,7 +613,7 @@ public Node rotateRight(Node h) { 一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的。分裂 4- 节点除了需要将子节点的颜色由红变黑之外,同时需要将父节点的颜色由黑变红,从 2-3 树的角度看就是将中间节点移到上层节点。 -

+

```java void flipColors(Node h) { @@ -631,7 +631,7 @@ void flipColors(Node h) { - 如果左子节点是红色的,而且左子节点的左子节点也是红色的,进行右旋转; - 如果左右子节点均为红色的,进行颜色转换。 -

+

```java @Override @@ -756,7 +756,7 @@ public class Transaction { 对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。 -

+

## 3. 线性探测法 @@ -765,7 +765,7 @@ public class Transaction { 使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。 -

+

```java public class LinearProbingHashST implements UnorderedST { @@ -867,7 +867,7 @@ public void delete(Key key) { 线性探测法的成本取决于连续条目的长度,连续条目也叫聚簇。当聚簇很长时,在查找和插入时也需要进行很多次探测。例如下图中 2\~4 位置就是一个聚簇。 -

+

α = N/M,把 α 称为使用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。为了保证散列表的性能,应当调整数组的大小,使得 α 在 [1/4, 1/2] 之间。 diff --git a/docs/notes/缓存.md b/docs/notes/缓存.md index 3f13061c..c05ad6a6 100644 --- a/docs/notes/缓存.md +++ b/docs/notes/缓存.md @@ -203,7 +203,7 @@ CDN 主要有以下优点: - 通过部署多台服务器,从而提高系统整体的带宽性能; - 多台服务器可以看成是一种冗余机制,从而具有高可用性。 -

+

# 五、缓存问题 @@ -264,11 +264,11 @@ Distributed Hash Table(DHT) 是一种哈希分布方式,其目的是为了 将哈希空间 [0, 2n-1] 看成一个哈希环,每个服务器节点都配置到哈希环上。每个数据对象通过哈希取模得到哈希值之后,存放到哈希环中顺时针方向第一个大于等于该哈希值的节点上。 -

+

一致性哈希在增加或者删除节点时只会影响到哈希环中相邻的节点,例如下图中新增节点 X,只需要将它前一个节点 C 上的数据重新进行分布即可,对于节点 A、B、D 都没有影响。 -

+

## 虚拟节点 diff --git a/docs/notes/计算机操作系统 - 内存管理.md b/docs/notes/计算机操作系统 - 内存管理.md index c2c35ac7..d4ff10b2 100644 --- a/docs/notes/计算机操作系统 - 内存管理.md +++ b/docs/notes/计算机操作系统 - 内存管理.md @@ -22,7 +22,7 @@ 从上面的描述中可以看出,虚拟内存允许程序不用将地址空间中的每一页都映射到物理内存,也就是说一个程序不需要全部调入内存就可以运行,这使得有限的内存运行大程序成为可能。例如有一台计算机可以产生 16 位地址,那么一个程序的地址空间范围是 0\~64K。该计算机只有 32KB 的物理内存,虚拟内存技术允许该计算机运行一个 64K 大小的程序。 -

+

# 分页系统地址映射 @@ -32,7 +32,7 @@ 下图的页表存放着 16 个页,这 16 个页需要用 4 个比特位来进行索引定位。例如对于虚拟地址(0010 000000000100),前 4 位是存储页面号 2,读取表项内容为(110 1),页表项最后一位表示是否存在于内存中,1 表示存在。后 12 位存储偏移量。这个页对应的页框的地址为 (110 000000000100)。 -

+

# 页面置换算法 @@ -72,7 +72,7 @@ 4,7,0,7,1,0,1,2,1,2,6 ``` -

+

## 3. 最近未使用 @@ -103,7 +103,7 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 当页面被访问 (读或写) 时设置该页面的 R 位为 1。需要替换的时候,检查最老页面的 R 位。如果 R 位是 0,那么这个页面既老又没有被使用,可以立刻置换掉;如果是 1,就将 R 位清 0,并把该页面放到链表的尾端,修改它的装入时间使它就像刚装入的一样,然后继续从链表的头部开始搜索。 -

+

## 6. 时钟 @@ -111,7 +111,7 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 第二次机会算法需要在链表中移动页面,降低了效率。时钟算法使用环形链表将页面连接起来,再使用一个指针指向最老的页面。 -

+

# 分段 @@ -119,11 +119,11 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 下图为一个编译器在编译过程中建立的多个表,有 4 个表是动态增长的,如果使用分页系统的一维地址空间,动态增长的特点会导致覆盖问题的出现。 -

+

分段的做法是把每个表分成段,一个段构成一个独立的地址空间。每个段的长度可以不同,并且可以动态增长。 -

+

# 段页式 diff --git a/docs/notes/计算机操作系统 - 概述.md b/docs/notes/计算机操作系统 - 概述.md index 686df0c7..575df43d 100644 --- a/docs/notes/计算机操作系统 - 概述.md +++ b/docs/notes/计算机操作系统 - 概述.md @@ -76,7 +76,7 @@ 如果一个进程在用户态需要使用内核态的功能,就进行系统调用从而陷入内核,由操作系统代为完成。 -

+

Linux 的系统调用主要有以下这些: @@ -105,7 +105,7 @@ Linux 的系统调用主要有以下这些: 因为需要频繁地在用户态和核心态之间进行切换,所以会有一定的性能损失。 -

+

# 中断分类 diff --git a/docs/notes/计算机操作系统 - 死锁.md b/docs/notes/计算机操作系统 - 死锁.md index 6b176380..659dfc3f 100644 --- a/docs/notes/计算机操作系统 - 死锁.md +++ b/docs/notes/计算机操作系统 - 死锁.md @@ -20,7 +20,7 @@ # 必要条件 -

+

- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。 - 占有和等待:已经得到了某个资源的进程可以再请求新的资源。 @@ -52,7 +52,7 @@ ## 1. 每种类型一个资源的死锁检测 -

+

上图为资源分配图,其中方框表示资源,圆圈表示进程。资源指向进程表示该资源已经分配给该进程,进程指向资源表示进程请求获取该资源。 @@ -62,7 +62,7 @@ ## 2. 每种类型多个资源的死锁检测 -

+

上图中,有三个进程四个资源,每个数据代表的含义如下: @@ -111,7 +111,7 @@ ## 1. 安全状态 -

+

图 a 的第二列 Has 表示已拥有的资源数,第三列 Max 表示总共需要的资源数,Free 表示还有可以使用的资源数。从图 a 开始出发,先让 B 拥有所需的所有资源(图 b),运行结束后释放 B,此时 Free 变为 5(图 c);接着以同样的方式运行 C 和 A,使得所有进程都能成功运行,因此可以称图 a 所示的状态时安全的。 @@ -123,13 +123,13 @@ 一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。 -

+

上图 c 为不安全状态,因此算法会拒绝之前的请求,从而避免进入图 c 中的状态。 ## 3. 多个资源的银行家算法 -

+

上图中有五个进程,四个资源。左边的图表示已经分配的资源,右边的图表示还需要分配的资源。最右边的 E、P 以及 A 分别表示:总资源、已分配资源以及可用资源,注意这三个为向量,而不是具体数值,例如 A=(1020),表示 4 个资源分别还剩下 1/0/2/0。 diff --git a/docs/notes/计算机操作系统 - 设备管理.md b/docs/notes/计算机操作系统 - 设备管理.md index 6c07e59a..aa531204 100644 --- a/docs/notes/计算机操作系统 - 设备管理.md +++ b/docs/notes/计算机操作系统 - 设备管理.md @@ -16,7 +16,7 @@ - 制动手臂(Actuator arm):用于在磁道之间移动磁头; - 主轴(Spindle):使整个盘面转动。 -

+

# 磁盘调度算法 @@ -44,7 +44,7 @@ 虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥饿现象。 -

+

## 3. 电梯算法 @@ -56,7 +56,7 @@ 因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了 SSTF 的饥饿问题。 -

+

diff --git a/docs/notes/计算机操作系统 - 进程管理.md b/docs/notes/计算机操作系统 - 进程管理.md index 8c87d931..b17e30a9 100644 --- a/docs/notes/计算机操作系统 - 进程管理.md +++ b/docs/notes/计算机操作系统 - 进程管理.md @@ -36,7 +36,7 @@ 下图显示了 4 个程序创建了 4 个进程,这 4 个进程可以并发地执行。 -

+

## 2. 线程 @@ -46,7 +46,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。 -

+

## 3. 区别 @@ -68,7 +68,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H # 进程状态的切换 -

+

- 就绪状态(ready):等待被调度 - 运行状态(running) @@ -116,7 +116,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H - 因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。 - 而如果时间片过长,那么实时性就不能得到保证。 -

+

**2.2 优先级调度** @@ -134,7 +134,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 可以将这种调度算法看成是时间片轮转调度算法和优先级调度算法的结合。 -

+

## 3. 实时系统 @@ -453,7 +453,7 @@ void reader() ## 2. 哲学家进餐问题 -

+

五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭以及思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。 @@ -547,7 +547,7 @@ int pipe(int fd[2]); - 只支持半双工通信(单向交替传输); - 只能在父子进程中使用。 -

+

## 2. FIFO @@ -561,7 +561,7 @@ int mkfifoat(int fd, const char *path, mode_t mode); FIFO 常用于客户-服务器应用程序中,FIFO 用作汇聚点,在客户进程和服务器进程之间传递数据。 -

+

## 3. 消息队列 diff --git a/docs/notes/计算机操作系统 - 链接.md b/docs/notes/计算机操作系统 - 链接.md index 8fced59d..ff555f27 100644 --- a/docs/notes/计算机操作系统 - 链接.md +++ b/docs/notes/计算机操作系统 - 链接.md @@ -29,7 +29,7 @@ gcc -o hello hello.c 这个过程大致如下: -

+

- 预处理阶段:处理以 # 开头的预处理命令; - 编译阶段:翻译成汇编文件; @@ -43,7 +43,7 @@ gcc -o hello hello.c - 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。 - 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。 -

+

# 目标文件 @@ -63,7 +63,7 @@ gcc -o hello hello.c - 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中; - 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享。 -

+

diff --git a/docs/notes/计算机网络 - 传输层.md b/docs/notes/计算机网络 - 传输层.md index 39bd07ed..fa445180 100644 --- a/docs/notes/计算机网络 - 传输层.md +++ b/docs/notes/计算机网络 - 传输层.md @@ -23,13 +23,13 @@ # UDP 首部格式 -

+

首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。 # TCP 首部格式 -

+

- **序号** :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。 @@ -47,7 +47,7 @@ # TCP 的三次握手 -

+

假设 A 为客户端,B 为服务器端。 @@ -69,7 +69,7 @@ # TCP 的四次挥手 -

+

以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。 @@ -119,7 +119,7 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。 -

+

# TCP 流量控制 @@ -131,7 +131,7 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。 -

+

TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。 @@ -142,7 +142,7 @@ TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、 - 接收方有足够大的接收缓存,因此不会发生流量控制; - 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。 -

+

## 1. 慢开始与拥塞避免 @@ -162,7 +162,7 @@ TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、 慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。 -

+

diff --git a/docs/notes/计算机网络 - 应用层.md b/docs/notes/计算机网络 - 应用层.md index fb1837a4..3784301e 100644 --- a/docs/notes/计算机网络 - 应用层.md +++ b/docs/notes/计算机网络 - 应用层.md @@ -22,7 +22,7 @@ DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转 域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。 -

+

DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。在两种情况下会使用 TCP 进行传输: @@ -40,11 +40,11 @@ FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件: - 主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0\~1023 是熟知端口号。 -

+

- 被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。 -

+

主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。 @@ -61,7 +61,7 @@ DHCP 工作过程如下: 3. 如果客户端选择了某个 DHCP 服务器提供的信息,那么就发送 Request 报文给该 DHCP 服务器。 4. DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。 -

+

# 远程登录协议 @@ -75,13 +75,13 @@ TELNET 可以适应许多计算机和操作系统的差异,例如不同操作 邮件协议包含发送协议和读取协议,发送协议常用 SMTP,读取协议常用 POP3 和 IMAP。 -

+

## 1. SMTP SMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则。 -

+

## 2. POP3 diff --git a/docs/notes/计算机网络 - 概述.md b/docs/notes/计算机网络 - 概述.md index 1a85b510..98479bb3 100644 --- a/docs/notes/计算机网络 - 概述.md +++ b/docs/notes/计算机网络 - 概述.md @@ -22,27 +22,27 @@ 网络把主机连接起来,而互联网是把多种不同的网络连接起来,因此互联网是网络的网络。 -

+

# ISP 互联网服务提供商 ISP 可以从互联网管理机构获得许多 IP 地址,同时拥有通信线路以及路由器等联网设备,个人或机构向 ISP 缴纳一定的费用就可以接入互联网。 -

+

目前的互联网是一种多层次 ISP 结构,ISP 根据覆盖面积的大小分为第一层 ISP、区域 ISP 和接入 ISP。互联网交换点 IXP 允许两个 ISP 直接相连而不用经过第三个 ISP。 -

+

# 主机之间的通信方式 - 客户-服务器(C/S):客户是服务的请求方,服务器是服务的提供方。 -

+

- 对等(P2P):不区分客户和服务器。 -

+

# 电路交换与分组交换 @@ -60,7 +60,7 @@ 总时延 = 排队时延 + 处理时延 + 传输时延 + 传播时延 -

+

## 1. 排队时延 @@ -76,7 +76,7 @@ -

+

其中 l 表示数据帧的长度,v 表示传输速率。 @@ -87,13 +87,13 @@ -

+

其中 l 表示信道长度,v 表示电磁波在信道上的传播速度。 # 计算机网络体系结构 -

+

## 1. 五层协议 @@ -123,7 +123,7 @@ TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。 -

+

## 4. 数据在各层之间的传递过程 diff --git a/docs/notes/计算机网络 - 物理层.md b/docs/notes/计算机网络 - 物理层.md index 162f4e2d..f0ec3a30 100644 --- a/docs/notes/计算机网络 - 物理层.md +++ b/docs/notes/计算机网络 - 物理层.md @@ -16,7 +16,7 @@ 模拟信号是连续的信号,数字信号是离散的信号。带通调制把数字信号转换为模拟信号。 -

+

diff --git a/docs/notes/计算机网络 - 网络层.md b/docs/notes/计算机网络 - 网络层.md index 75c609d7..85885040 100644 --- a/docs/notes/计算机网络 - 网络层.md +++ b/docs/notes/计算机网络 - 网络层.md @@ -26,7 +26,7 @@ 使用 IP 协议,可以把异构的物理网络连接起来,使得在网络层看起来好像是一个统一的网络。 -

+

与 IP 协议配套使用的还有三个协议: @@ -36,7 +36,7 @@ # IP 数据报格式 -

+

- **版本** : 有 4(IPv4)和 6(IPv6)两个值; @@ -56,7 +56,7 @@ - **片偏移** : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。 -

+

# IP 地址编址方式 @@ -72,7 +72,7 @@ IP 地址的编址方式经历了三个历史阶段: IP 地址 ::= {< 网络号 >, < 主机号 >} -

+

## 2. 子网划分 @@ -102,27 +102,27 @@ CIDR 的地址掩码可以继续称为子网掩码,子网掩码首 1 长度为 网络层实现主机之间的通信,而链路层实现具体每段链路之间的通信。因此在通信过程中,IP 数据报的源地址和目的地址始终不变,而 MAC 地址随着链路的改变而改变。 -

+

ARP 实现由 IP 地址得到 MAC 地址。 -

+

每个主机都有一个 ARP 高速缓存,里面有本局域网上的各主机和路由器的 IP 地址到 MAC 地址的映射表。 如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。 -

+

# 网际控制报文协议 ICMP ICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中,但是不属于高层协议。 -

+

ICMP 报文分为差错报告报文和询问报文。 -

+

## 1. Ping @@ -155,7 +155,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 下图中,场所 A 和 B 的通信经过互联网,如果场所 A 的主机 X 要和另一个场所 B 的主机 Y 通信,IP 数据报的源地址是 10.1.0.1,目的地址是 10.2.0.3。数据报先发送到与互联网相连的路由器 R1,R1 对内部数据进行加密,然后重新加上数据报的首部,源地址是路由器 R1 的全球地址 125.1.2.3,目的地址是路由器 R2 的全球地址 194.4.5.6。路由器 R2 收到数据报后将数据部分进行解密,恢复原来的数据报,此时目的地址为 10.2.0.3,就交付给 Y。 -

+

# 网络地址转换 NAT @@ -163,7 +163,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 在以前,NAT 将本地 IP 和全球 IP 一一对应,这种方式下拥有 n 个全球 IP 地址的专用网内最多只可以同时有 n 台主机接入互联网。为了更有效地利用全球 IP 地址,现在常用的 NAT 转换表把传输层的端口号也用上了,使得多个专用网内部的主机共用一个全球 IP 地址。使用端口号的 NAT 也叫做网络地址与端口转换 NAPT。 -

+

# 路由器的结构 @@ -171,7 +171,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 分组转发结构由三个部分组成:交换结构、一组输入端口和一组输出端口。 -

+

# 路由器分组转发流程 @@ -182,7 +182,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 - 若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器; - 报告转发分组出错。 -

+

# 路由选择协议 @@ -239,7 +239,7 @@ BGP 只能寻找一条比较好的路由,而不是最佳路由。 每个 AS 都必须配置 BGP 发言人,通过在两个相邻 BGP 发言人之间建立 TCP 连接来交换路由信息。 -

+

diff --git a/docs/notes/计算机网络 - 链路层.md b/docs/notes/计算机网络 - 链路层.md index 503d14ae..4d100d59 100644 --- a/docs/notes/计算机网络 - 链路层.md +++ b/docs/notes/计算机网络 - 链路层.md @@ -28,7 +28,7 @@ 将网络层传下来的分组添加首部和尾部,用于标记帧的开始和结束。 -

+

## 2. 透明传输 @@ -36,7 +36,7 @@ 帧使用首部和尾部进行定界,如果帧的数据部分含有和首部尾部相同的内容,那么帧的开始和结束位置就会被错误的判定。需要在数据部分出现首部尾部相同的内容前面插入转义字符。如果数据部分出现转义字符,那么就在转义字符前面再加个转义字符。在接收端进行处理之后可以还原出原始数据。这个过程透明传输的内容是转义字符,用户察觉不到转义字符的存在。 -

+

## 3. 差错检测 @@ -64,13 +64,13 @@ 频分复用的所有主机在相同的时间占用不同的频率带宽资源。 -

+

## 2. 时分复用 时分复用的所有主机在不同的时间占用相同的频率带宽资源。 -

+

使用频分复用和时分复用进行通信,在通信的过程中主机会一直占用一部分信道资源。但是由于计算机数据的突发性质,通信过程没必要一直占用信道资源而不让出给其它用户使用,因此这两种方式对信道的利用率都不高。 @@ -78,7 +78,7 @@ 是对时分复用的一种改进,不固定每个用户在时分复用帧中的位置,只要有数据就集中起来组成统计时分复用帧然后发送。 -

+

## 4. 波分复用 @@ -90,7 +90,7 @@ -

+

为了讨论方便,取 m=8,设码片 为 00011011。在拥有该码片的用户发送比特 1 时就发送该码片,发送比特 0 时就发送该码片的反码 11100100。 @@ -100,9 +100,9 @@ -

+

-

+

其中 的反码。 @@ -110,7 +110,7 @@ 码分复用需要发送的数据量为原先的 m 倍。 -

+

# CSMA/CD 协议 @@ -125,13 +125,13 @@ CSMA/CD 表示载波监听多点接入 / 碰撞检测。 当发生碰撞时,站点要停止发送,等待一段时间再发送。这个时间采用 **截断二进制指数退避算法** 来确定。从离散的整数集合 {0, 1, .., (2k-1)} 中随机取出一个数,记作 r,然后取 r 倍的争用期作为重传等待时间。 -

+

# PPP 协议 互联网用户通常需要连接到某个 ISP 之后才能接入到互联网,PPP 协议是用户计算机和 ISP 进行通信时所使用的数据链路层协议。 -

+

PPP 的帧格式: @@ -140,7 +140,7 @@ PPP 的帧格式: - FCS 字段是使用 CRC 的检验序列 - 信息部分的长度不超过 1500 -

+

# MAC 地址 @@ -156,7 +156,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 可以按照网络拓扑结构对局域网进行分类: -

+

# 以太网 @@ -172,7 +172,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 - **数据** :长度在 46-1500 之间,如果太小则需要填充; - **FCS** :帧检验序列,使用的是 CRC 检验方法; -

+

# 交换机 @@ -182,7 +182,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 下图中,交换机有 4 个接口,主机 A 向主机 B 发送数据帧时,交换机把主机 A 到接口 1 的映射写入交换表中。为了发送数据帧到 B,先查交换表,此时没有主机 B 的表项,那么主机 A 就发送广播帧,主机 C 和主机 D 会丢弃该帧,主机 B 回应该帧向主机 A 发送数据包时,交换机查找交换表得到主机 A 映射的接口为 1,就发送数据帧到接口 1,同时交换机添加主机 B 到接口 2 的映射。 -

+

# 虚拟局域网 @@ -192,7 +192,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 使用 VLAN 干线连接来建立虚拟局域网,每台交换机上的一个特殊接口被设置为干线接口,以互连 VLAN 交换机。IEEE 定义了一种扩展的以太网帧格式 802.1Q,它在标准以太网帧上加进了 4 字节首部 VLAN 标签,用于表示该帧属于哪一个虚拟局域网。 -

+

diff --git a/docs/notes/设计模式.md b/docs/notes/设计模式.md index 341b4175..431c85d2 100644 --- a/docs/notes/设计模式.md +++ b/docs/notes/设计模式.md @@ -54,7 +54,7 @@ 私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。 -

+

### Implementation @@ -255,7 +255,7 @@ secondName 这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。 -

+

### Implementation @@ -338,7 +338,7 @@ public class Client { 下图中,Factory 有一个 doSomething() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。 -

+

### Implementation @@ -402,7 +402,7 @@ public class ConcreteFactory2 extends Factory { 从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。 -

+

### Implementation @@ -492,7 +492,7 @@ public class Client { ### Class Diagram -

+

### Implementation @@ -582,7 +582,7 @@ abcdefghijklmnopqrstuvwxyz ### Class Diagram -

+

### Implementation @@ -643,7 +643,7 @@ abc - Handler:定义处理请求的接口,并且实现后继链(successor) -

+

### Implementation @@ -781,13 +781,13 @@ request2 is handle by ConcreteHandler2 - Invoker:通过它来调用命令 - Client:可以设置命令与命令的接收者 -

+

### Implementation 设计一个遥控器,可以控制电灯开关。 -

+

```java public interface Command { @@ -902,7 +902,7 @@ public class Client { - TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。 - Context:上下文,包含解释器之外的一些全局信息。 -

+

### Implementation @@ -1027,7 +1027,7 @@ false - Iterator 主要定义了 hasNext() 和 next() 方法。 - Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。 -

+

### Implementation @@ -1116,17 +1116,17 @@ public class Client { - Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。 - Colleague:同事,相关对象 -

+

### Implementation Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构: -

+

使用中介者模式可以将复杂的依赖结构变成星形结构: -

+

```java public abstract class Colleague { @@ -1286,7 +1286,7 @@ doSprinkler() - Caretaker:负责保存好备忘录 - Menento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。 -

+

### Implementation @@ -1459,7 +1459,7 @@ public class Client { 主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。 -

+

### Class Diagram @@ -1467,13 +1467,13 @@ public class Client { 观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。 -

+

### Implementation 天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。 -

+

```java public interface Subject { @@ -1594,13 +1594,13 @@ StatisticsDisplay.update: 1.0 1.0 1.0 ### Class Diagram -

+

### Implementation 糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。 -

+

```java public interface State { @@ -1901,7 +1901,7 @@ No gumball dispensed - Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。 - Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。 -

+

### 与状态模式的比较 @@ -1988,13 +1988,13 @@ quack! ### Class Diagram -

+

### Implementation 冲咖啡和冲茶都有类似的流程,但是某些步骤会有点不一样,要求复用那些相同步骤的代码。 -

+

```java public abstract class CaffeineBeverage { @@ -2091,7 +2091,7 @@ Tea.addCondiments - ConcreteVisitor:具体访问者,存储遍历过程中的累计结果 - ObjectStructure:对象结构,可以是组合结构,或者是一个集合。 -

+

### Implementation @@ -2296,7 +2296,7 @@ Number of items: 6 ### Class Diagram -

+

### Implementation @@ -2348,11 +2348,11 @@ public class Client { 把一个类接口转换成另一个用户需要的接口。 -

+

### Class Diagram -

+

### Implementation @@ -2424,7 +2424,7 @@ public class Client { - Abstraction:定义抽象类的接口 - Implementor:定义实现类接口 -

+

### Implementation @@ -2582,7 +2582,7 @@ public class Client { 组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。 -

+

### Implementation @@ -2714,7 +2714,7 @@ Composite:root 装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的,这属于它的功能,然后调用被装饰者的方法实现,从而也保留了被装饰者的功能。可以看到,具体组件应当是装饰层次的最低层,因为只有具体组件的方法实现不需要依赖于其它对象。 -

+

### Implementation @@ -2722,7 +2722,7 @@ Composite:root 下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料,之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹,Mocha 又被 Whip 包裹。它们都继承自相同父类,都有 cost() 方法,外层类的 cost() 方法调用了内层类的 cost() 方法。 -

+

```java public interface Beverage { @@ -2820,7 +2820,7 @@ public class Client { ### Class Diagram -

+

### Implementation @@ -2879,7 +2879,7 @@ public class Client { - IntrinsicState:内部状态,享元对象共享内部状态 - ExtrinsicState:外部状态,每个享元对象的外部状态不同 -

+

### Implementation @@ -2968,7 +2968,7 @@ Java 利用缓存来加速大量小对象的访问时间。 - 保护代理(Protection Proxy):按权限控制对象的访问,它负责检查调用者是否具有实现一个请求所必须的访问权限。 - 智能代理(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作:记录对象的引用次数;当第一次引用一个对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。 -

+

### Implementation diff --git a/docs/notes/集群.md b/docs/notes/集群.md index cfec2274..d4a20038 100644 --- a/docs/notes/集群.md +++ b/docs/notes/集群.md @@ -33,12 +33,12 @@ 下图中,一共有 6 个客户端产生了 6 个请求,这 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送。(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。 -

+

该算法比较适合每个服务器的性能差不多的场景,如果有性能存在差异的情况下,那么性能较差的服务器可能无法承担过大的负载(下图的 Server 2)。 -

+

### 2. 加权轮询(Weighted Round Robbin) @@ -46,7 +46,7 @@ 例如下图中,服务器 1 被赋予的权值为 5,服务器 2 被赋予的权值为 1,那么 (1, 2, 3, 4, 5) 请求会被发送到服务器 1,(6) 请求会被发送到服务器 2。 -

+

### 3. 最少连接(least Connections) @@ -54,13 +54,13 @@ 例如下图中,(1, 3, 5) 请求会被发送到服务器 1,但是 (1, 3) 很快就断开连接,此时只有 (5) 请求连接服务器 1;(2, 4, 6) 请求被发送到服务器 2,只有 (2) 的连接断开,此时 (6, 4) 请求连接服务器 2。该系统继续运行时,服务器 2 会承担过大的负载。 -

+

最少连接算法就是将请求发送给当前最少连接数的服务器上。 例如下图中,服务器 1 当前连接数最小,那么新到来的请求 6 就会被发送到服务器 1 上。 -

+

### 4. 加权最少连接(Weighted Least Connection) @@ -72,7 +72,7 @@ 和轮询算法类似,该算法比较适合服务器性能差不多的场景。 -

+

### 6. 源地址哈希法 (IP Hash) @@ -80,7 +80,7 @@ 可以保证同一 IP 的客户端的请求会转发到同一台服务器上,用来实现会话粘滞(Sticky Session) -

+

## 转发实现 @@ -95,7 +95,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 该负载均衡转发的缺点比较明显,实际场景中很少使用它。 -

+

### 2. DNS 域名解析 @@ -111,7 +111,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 大型网站基本使用了 DNS 做为第一级负载均衡手段,然后在内部使用其它方式做第二级负载均衡。也就是说,域名解析的结果为内部的负载均衡服务器 IP 地址。 -

+

### 3. 反向代理服务器 @@ -168,7 +168,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 当服务器宕机时,将丢失该服务器上的所有 Session。 -

+

## Session Replication @@ -179,7 +179,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 占用过多内存; - 同步过程占用网络带宽以及服务器处理器时间。 -

+

## Session Server @@ -193,7 +193,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 需要去实现存取 Session 的代码。 -

+

参考: diff --git a/docs/notes/面向对象思想.md b/docs/notes/面向对象思想.md index 4689d867..1852d2ed 100644 --- a/docs/notes/面向对象思想.md +++ b/docs/notes/面向对象思想.md @@ -130,7 +130,7 @@ public class Music { 用来描述继承关系,在 Java 中使用 extends 关键字。 -

+

```text @startuml @@ -151,7 +151,7 @@ Vihical <|-- Trunck 用来实现一个接口,在 Java 中使用 implements 关键字。 -

+

```text @startuml @@ -172,7 +172,7 @@ MoveBehavior <|.. Run 表示整体由部分组成,但是整体和部分不是强依赖的,整体不存在了部分还是会存在。 -

+

```text @startuml @@ -195,7 +195,7 @@ Computer o-- Screen 和聚合不同,组合中整体和部分是强依赖的,整体不存在了部分也不存在了。比如公司和部门,公司没了部门就不存在了。但是公司和员工就属于聚合关系了,因为公司没了员工还在。 -

+

```text @startuml @@ -216,7 +216,7 @@ Company *-- DepartmentB 表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。因此也可以用 1 对 1、多对 1、多对多这种关联关系来表示。比如学生和学校就是一种关联关系,一个学校可以有很多学生,但是一个学生只属于一个学校,因此这是一种多对一的关系,在运行开始之前就可以确定。 -

+

```text @startuml @@ -239,7 +239,7 @@ School "1" - "n" Student - A 类是 B 类方法当中的一个参数; - A 类向 B 类发送消息,从而影响 B 类发生变化。 -

+

```text @startuml diff --git a/docs/pics/0157d362-98dd-4e51-ac26-00ecb76beb3e.png b/docs/pics/0157d362-98dd-4e51-ac26-00ecb76beb3e.png deleted file mode 100644 index fc0999f9..00000000 Binary files a/docs/pics/0157d362-98dd-4e51-ac26-00ecb76beb3e.png and /dev/null differ diff --git a/docs/pics/01809172-b223-42ac-a0d1-87944fe7dc8f_200.png b/docs/pics/01809172-b223-42ac-a0d1-87944fe7dc8f_200.png deleted file mode 100644 index c9613d8c..00000000 Binary files a/docs/pics/01809172-b223-42ac-a0d1-87944fe7dc8f_200.png and /dev/null differ diff --git a/docs/pics/032771e7-f60f-47bf-aa79-f45c32799211.png b/docs/pics/032771e7-f60f-47bf-aa79-f45c32799211.png deleted file mode 100644 index 5b9202f6..00000000 Binary files a/docs/pics/032771e7-f60f-47bf-aa79-f45c32799211.png and /dev/null differ diff --git a/docs/pics/0635cbe8.png b/docs/pics/0635cbe8.png deleted file mode 100644 index 849c9eaf..00000000 Binary files a/docs/pics/0635cbe8.png and /dev/null differ diff --git a/docs/pics/066f9c11-0154-42c3-8685-301a70e9bd39.jpg b/docs/pics/066f9c11-0154-42c3-8685-301a70e9bd39.jpg deleted file mode 100644 index 84d371b8..00000000 Binary files a/docs/pics/066f9c11-0154-42c3-8685-301a70e9bd39.jpg and /dev/null differ diff --git a/docs/pics/07e5a8d9-94bb-4d3b-8d53-c138946f1a68_200.png b/docs/pics/07e5a8d9-94bb-4d3b-8d53-c138946f1a68_200.png deleted file mode 100644 index 3fb62dee..00000000 Binary files a/docs/pics/07e5a8d9-94bb-4d3b-8d53-c138946f1a68_200.png and /dev/null differ diff --git a/docs/pics/080fc925-5116-4d91-b8dd-9da5a541931d_200.png b/docs/pics/080fc925-5116-4d91-b8dd-9da5a541931d_200.png deleted file mode 100644 index a3a93ae4..00000000 Binary files a/docs/pics/080fc925-5116-4d91-b8dd-9da5a541931d_200.png and /dev/null differ diff --git a/docs/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png b/docs/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png deleted file mode 100644 index 13d49836..00000000 Binary files a/docs/pics/08427d38-8df1-49a1-8990-e0ce5ee36ca2.png and /dev/null differ diff --git a/docs/pics/09184175-9bf2-40ff-8a68-3b467c77216a.png b/docs/pics/09184175-9bf2-40ff-8a68-3b467c77216a.png deleted file mode 100644 index 17f4d5b7..00000000 Binary files a/docs/pics/09184175-9bf2-40ff-8a68-3b467c77216a.png and /dev/null differ diff --git a/docs/pics/0f6f92e8-f15e-4c09-8562-b9c6114df9ce.png b/docs/pics/0f6f92e8-f15e-4c09-8562-b9c6114df9ce.png deleted file mode 100644 index 78843b1c..00000000 Binary files a/docs/pics/0f6f92e8-f15e-4c09-8562-b9c6114df9ce.png and /dev/null differ diff --git a/docs/pics/0f9b9d2a-c5cc-4a3f-b138-2c1035950f39_200.png b/docs/pics/0f9b9d2a-c5cc-4a3f-b138-2c1035950f39_200.png deleted file mode 100644 index 0b4a5838..00000000 Binary files a/docs/pics/0f9b9d2a-c5cc-4a3f-b138-2c1035950f39_200.png and /dev/null differ diff --git a/docs/pics/101550406418006.gif b/docs/pics/101550406418006.gif deleted file mode 100644 index df380209..00000000 Binary files a/docs/pics/101550406418006.gif and /dev/null differ diff --git a/docs/pics/107a6a2b-f15b-4cad-bced-b7fb95258c9c.png b/docs/pics/107a6a2b-f15b-4cad-bced-b7fb95258c9c.png deleted file mode 100644 index 35c2ddb1..00000000 Binary files a/docs/pics/107a6a2b-f15b-4cad-bced-b7fb95258c9c.png and /dev/null differ diff --git a/docs/pics/10a6d3ee-04b2-46b4-b171-d596e5ab0f84.jpg b/docs/pics/10a6d3ee-04b2-46b4-b171-d596e5ab0f84.jpg deleted file mode 100644 index 043964ae..00000000 Binary files a/docs/pics/10a6d3ee-04b2-46b4-b171-d596e5ab0f84.jpg and /dev/null differ diff --git a/docs/pics/111550407277293.gif b/docs/pics/111550407277293.gif deleted file mode 100644 index ce296a05..00000000 Binary files a/docs/pics/111550407277293.gif and /dev/null differ diff --git a/docs/pics/11548741556940.gif b/docs/pics/11548741556940.gif deleted file mode 100644 index 25571c54..00000000 Binary files a/docs/pics/11548741556940.gif and /dev/null differ diff --git a/docs/pics/11548742010310.gif b/docs/pics/11548742010310.gif deleted file mode 100644 index 7bc74734..00000000 Binary files a/docs/pics/11548742010310.gif and /dev/null differ diff --git a/docs/pics/11548742157520.gif b/docs/pics/11548742157520.gif deleted file mode 100644 index 6fbe4bf2..00000000 Binary files a/docs/pics/11548742157520.gif and /dev/null differ diff --git a/docs/pics/11550465817827.gif b/docs/pics/11550465817827.gif deleted file mode 100644 index 5a718e70..00000000 Binary files a/docs/pics/11550465817827.gif and /dev/null differ diff --git a/docs/pics/1164a71f-413d-494a-9cc8-679fb6a2613d.jpg b/docs/pics/1164a71f-413d-494a-9cc8-679fb6a2613d.jpg deleted file mode 100644 index 1804cdb1..00000000 Binary files a/docs/pics/1164a71f-413d-494a-9cc8-679fb6a2613d.jpg and /dev/null differ diff --git a/docs/pics/11_200.png b/docs/pics/11_200.png deleted file mode 100644 index 42966322..00000000 Binary files a/docs/pics/11_200.png and /dev/null differ diff --git a/docs/pics/11a786f0-5e02-46a6-92f0-f302c9cf6ca3_200.png b/docs/pics/11a786f0-5e02-46a6-92f0-f302c9cf6ca3_200.png deleted file mode 100644 index 53683386..00000000 Binary files a/docs/pics/11a786f0-5e02-46a6-92f0-f302c9cf6ca3_200.png and /dev/null differ diff --git a/docs/pics/121550407878282.gif b/docs/pics/121550407878282.gif deleted file mode 100644 index 5a17a553..00000000 Binary files a/docs/pics/121550407878282.gif and /dev/null differ diff --git a/docs/pics/131550414680831.gif b/docs/pics/131550414680831.gif deleted file mode 100644 index caa4d001..00000000 Binary files a/docs/pics/131550414680831.gif and /dev/null differ diff --git a/docs/pics/13783e94-b481-4aea-9fa2-9d1973abd47e_200.png b/docs/pics/13783e94-b481-4aea-9fa2-9d1973abd47e_200.png deleted file mode 100644 index 10d2aab0..00000000 Binary files a/docs/pics/13783e94-b481-4aea-9fa2-9d1973abd47e_200.png and /dev/null differ diff --git a/docs/pics/141550414746389.gif b/docs/pics/141550414746389.gif deleted file mode 100644 index 17cb2562..00000000 Binary files a/docs/pics/141550414746389.gif and /dev/null differ diff --git a/docs/pics/14ab3de0-0d48-4466-9ea7-90b9be822034_200.png b/docs/pics/14ab3de0-0d48-4466-9ea7-90b9be822034_200.png deleted file mode 100644 index 399846e1..00000000 Binary files a/docs/pics/14ab3de0-0d48-4466-9ea7-90b9be822034_200.png and /dev/null differ diff --git a/docs/pics/15699a17-5a69-4fbe-852e-9d2b7cf05e80_200.png b/docs/pics/15699a17-5a69-4fbe-852e-9d2b7cf05e80_200.png deleted file mode 100644 index 85d93b27..00000000 Binary files a/docs/pics/15699a17-5a69-4fbe-852e-9d2b7cf05e80_200.png and /dev/null differ diff --git a/docs/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg b/docs/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg deleted file mode 100644 index a61ab275..00000000 Binary files a/docs/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg and /dev/null differ diff --git a/docs/pics/17976404-95f5-480e-9cb4-250e6aa1d55f.png b/docs/pics/17976404-95f5-480e-9cb4-250e6aa1d55f.png deleted file mode 100644 index 276969a7..00000000 Binary files a/docs/pics/17976404-95f5-480e-9cb4-250e6aa1d55f.png and /dev/null differ diff --git a/docs/pics/181edd46-e640-472a-9119-a697de0d2a82.jpg b/docs/pics/181edd46-e640-472a-9119-a697de0d2a82.jpg deleted file mode 100644 index 306d1c66..00000000 Binary files a/docs/pics/181edd46-e640-472a-9119-a697de0d2a82.jpg and /dev/null differ diff --git a/docs/pics/18c1ea05-bc12-4d1f-9179-76fda03cfa80_200.png b/docs/pics/18c1ea05-bc12-4d1f-9179-76fda03cfa80_200.png deleted file mode 100644 index 34907028..00000000 Binary files a/docs/pics/18c1ea05-bc12-4d1f-9179-76fda03cfa80_200.png and /dev/null differ diff --git a/docs/pics/1_200.png b/docs/pics/1_200.png deleted file mode 100644 index c6dc2bb5..00000000 Binary files a/docs/pics/1_200.png and /dev/null differ diff --git a/docs/pics/1_2001550415765493.png b/docs/pics/1_2001550415765493.png deleted file mode 100644 index d1c091ca..00000000 Binary files a/docs/pics/1_2001550415765493.png and /dev/null differ diff --git a/docs/pics/1_2001550465428749.png b/docs/pics/1_2001550465428749.png deleted file mode 100644 index e21e3837..00000000 Binary files a/docs/pics/1_2001550465428749.png and /dev/null differ diff --git a/docs/pics/1_2001550547261811.png b/docs/pics/1_2001550547261811.png deleted file mode 100644 index a3331e43..00000000 Binary files a/docs/pics/1_2001550547261811.png and /dev/null differ diff --git a/docs/pics/1a2f2998-d0da-41c8-8222-1fd95083a66b.png b/docs/pics/1a2f2998-d0da-41c8-8222-1fd95083a66b.png deleted file mode 100644 index c4592305..00000000 Binary files a/docs/pics/1a2f2998-d0da-41c8-8222-1fd95083a66b.png and /dev/null differ diff --git a/docs/pics/1b718cd5-7b1e-496c-9133-2bfd12bb5f89.jpg b/docs/pics/1b718cd5-7b1e-496c-9133-2bfd12bb5f89.jpg deleted file mode 100644 index 60edac95..00000000 Binary files a/docs/pics/1b718cd5-7b1e-496c-9133-2bfd12bb5f89.jpg and /dev/null differ diff --git a/docs/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png b/docs/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png deleted file mode 100644 index 35e992f7..00000000 Binary files a/docs/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png and /dev/null differ diff --git a/docs/pics/1ca52246-c443-48ae-b1f8-1cafc09ec75c.png b/docs/pics/1ca52246-c443-48ae-b1f8-1cafc09ec75c.png deleted file mode 100644 index 53596803..00000000 Binary files a/docs/pics/1ca52246-c443-48ae-b1f8-1cafc09ec75c.png and /dev/null differ diff --git a/docs/pics/1d2719d5-8d60-4c9b-a4ad-b2df7c7615af.jpg b/docs/pics/1d2719d5-8d60-4c9b-a4ad-b2df7c7615af.jpg deleted file mode 100644 index a9effcf7..00000000 Binary files a/docs/pics/1d2719d5-8d60-4c9b-a4ad-b2df7c7615af.jpg and /dev/null differ diff --git a/docs/pics/1e74234e-d70b-411c-9333-226bcbb9c8f0.png b/docs/pics/1e74234e-d70b-411c-9333-226bcbb9c8f0.png deleted file mode 100644 index 68ab02d1..00000000 Binary files a/docs/pics/1e74234e-d70b-411c-9333-226bcbb9c8f0.png and /dev/null differ diff --git a/docs/pics/1f080e53-4758-406c-bb5f-dbedf89b63ce.jpg b/docs/pics/1f080e53-4758-406c-bb5f-dbedf89b63ce.jpg deleted file mode 100644 index c1776a5c..00000000 Binary files a/docs/pics/1f080e53-4758-406c-bb5f-dbedf89b63ce.jpg and /dev/null differ diff --git a/docs/pics/20e61b68-effe-4a70-a7fd-58be23f9343a.png b/docs/pics/20e61b68-effe-4a70-a7fd-58be23f9343a.png deleted file mode 100644 index 7da1a21f..00000000 Binary files a/docs/pics/20e61b68-effe-4a70-a7fd-58be23f9343a.png and /dev/null differ diff --git a/docs/pics/21550397584141.gif b/docs/pics/21550397584141.gif deleted file mode 100644 index df5c1792..00000000 Binary files a/docs/pics/21550397584141.gif and /dev/null differ diff --git a/docs/pics/21550465890674.gif b/docs/pics/21550465890674.gif deleted file mode 100644 index 2ef91795..00000000 Binary files a/docs/pics/21550465890674.gif and /dev/null differ diff --git a/docs/pics/220790c6-4377-4a2e-8686-58398afc8a18.png b/docs/pics/220790c6-4377-4a2e-8686-58398afc8a18.png deleted file mode 100644 index 79105257..00000000 Binary files a/docs/pics/220790c6-4377-4a2e-8686-58398afc8a18.png and /dev/null differ diff --git a/docs/pics/26a7c9df-22f6-4df4-845a-745c053ab2e5.jpg b/docs/pics/26a7c9df-22f6-4df4-845a-745c053ab2e5.jpg deleted file mode 100644 index cf6ab009..00000000 Binary files a/docs/pics/26a7c9df-22f6-4df4-845a-745c053ab2e5.jpg and /dev/null differ diff --git a/docs/pics/27fce0c6-8262-4d11-abb4-243faa2a2eef.jpg b/docs/pics/27fce0c6-8262-4d11-abb4-243faa2a2eef.jpg deleted file mode 100644 index 72177f77..00000000 Binary files a/docs/pics/27fce0c6-8262-4d11-abb4-243faa2a2eef.jpg and /dev/null differ diff --git a/docs/pics/27ff9548-edb6-4465-92c8-7e6386e0b185.png b/docs/pics/27ff9548-edb6-4465-92c8-7e6386e0b185.png deleted file mode 100644 index 1aee414c..00000000 Binary files a/docs/pics/27ff9548-edb6-4465-92c8-7e6386e0b185.png and /dev/null differ diff --git a/docs/pics/280f7728-594f-4811-a03a-fa8d32c013da.png b/docs/pics/280f7728-594f-4811-a03a-fa8d32c013da.png deleted file mode 100644 index 526b6847..00000000 Binary files a/docs/pics/280f7728-594f-4811-a03a-fa8d32c013da.png and /dev/null differ diff --git a/docs/pics/2861e923-4862-4526-881c-15529279d49c.png b/docs/pics/2861e923-4862-4526-881c-15529279d49c.png deleted file mode 100644 index 6cc26c26..00000000 Binary files a/docs/pics/2861e923-4862-4526-881c-15529279d49c.png and /dev/null differ diff --git a/docs/pics/29011257-8390-4792-b0bf-898be001d0bd_200.png b/docs/pics/29011257-8390-4792-b0bf-898be001d0bd_200.png deleted file mode 100644 index b1edc253..00000000 Binary files a/docs/pics/29011257-8390-4792-b0bf-898be001d0bd_200.png and /dev/null differ diff --git a/docs/pics/293d2af9-de1d-403e-bed0-85d029383528.png b/docs/pics/293d2af9-de1d-403e-bed0-85d029383528.png deleted file mode 100644 index 36765e32..00000000 Binary files a/docs/pics/293d2af9-de1d-403e-bed0-85d029383528.png and /dev/null differ diff --git a/docs/pics/2959e455-e6cb-4461-aeb3-e319fe5c41db.jpg b/docs/pics/2959e455-e6cb-4461-aeb3-e319fe5c41db.jpg deleted file mode 100644 index 09ad339e..00000000 Binary files a/docs/pics/2959e455-e6cb-4461-aeb3-e319fe5c41db.jpg and /dev/null differ diff --git a/docs/pics/2_200.png b/docs/pics/2_200.png deleted file mode 100644 index c292d4ef..00000000 Binary files a/docs/pics/2_200.png and /dev/null differ diff --git a/docs/pics/2_2001550426232419.png b/docs/pics/2_2001550426232419.png deleted file mode 100644 index 810892ec..00000000 Binary files a/docs/pics/2_2001550426232419.png and /dev/null differ diff --git a/docs/pics/2_2001550466182933.png b/docs/pics/2_2001550466182933.png deleted file mode 100644 index 79d19762..00000000 Binary files a/docs/pics/2_2001550466182933.png and /dev/null differ diff --git a/docs/pics/2_2001550547456403.png b/docs/pics/2_2001550547456403.png deleted file mode 100644 index c9e53fe0..00000000 Binary files a/docs/pics/2_2001550547456403.png and /dev/null differ diff --git a/docs/pics/2_2001550810366269.png b/docs/pics/2_2001550810366269.png deleted file mode 100644 index 2d65f046..00000000 Binary files a/docs/pics/2_2001550810366269.png and /dev/null differ diff --git a/docs/pics/2a8e1442-2381-4439-a83f-0312c8678b1f.png b/docs/pics/2a8e1442-2381-4439-a83f-0312c8678b1f.png deleted file mode 100644 index a97e49a6..00000000 Binary files a/docs/pics/2a8e1442-2381-4439-a83f-0312c8678b1f.png and /dev/null differ diff --git a/docs/pics/2e6c72f5-3b8e-4e32-b87b-9491322628fe.png b/docs/pics/2e6c72f5-3b8e-4e32-b87b-9491322628fe.png deleted file mode 100644 index 701e37f2..00000000 Binary files a/docs/pics/2e6c72f5-3b8e-4e32-b87b-9491322628fe.png and /dev/null differ diff --git a/docs/pics/2f1c9839-d582-4f75-863e-8f0a2ac63fb8_200.png b/docs/pics/2f1c9839-d582-4f75-863e-8f0a2ac63fb8_200.png deleted file mode 100644 index a4b20378..00000000 Binary files a/docs/pics/2f1c9839-d582-4f75-863e-8f0a2ac63fb8_200.png and /dev/null differ diff --git a/docs/pics/2f237854-bb35-4c57-a7fe-ab2ab144f56e.jpg b/docs/pics/2f237854-bb35-4c57-a7fe-ab2ab144f56e.jpg deleted file mode 100644 index 5799fe39..00000000 Binary files a/docs/pics/2f237854-bb35-4c57-a7fe-ab2ab144f56e.jpg and /dev/null differ diff --git a/docs/pics/303873db-0d11-4683-a43c-f319b7aef2b6.jpg b/docs/pics/303873db-0d11-4683-a43c-f319b7aef2b6.jpg deleted file mode 100644 index 0983229b..00000000 Binary files a/docs/pics/303873db-0d11-4683-a43c-f319b7aef2b6.jpg and /dev/null differ diff --git a/docs/pics/3086c248-b552-499e-b101-9cffe5c2773e.png b/docs/pics/3086c248-b552-499e-b101-9cffe5c2773e.png deleted file mode 100644 index c23e85c9..00000000 Binary files a/docs/pics/3086c248-b552-499e-b101-9cffe5c2773e.png and /dev/null differ diff --git a/docs/pics/3144015c-dcfb-47ac-94a5-bab3b78b0f14.jpg b/docs/pics/3144015c-dcfb-47ac-94a5-bab3b78b0f14.jpg deleted file mode 100644 index a805e7f9..00000000 Binary files a/docs/pics/3144015c-dcfb-47ac-94a5-bab3b78b0f14.jpg and /dev/null differ diff --git a/docs/pics/31550398353573.gif b/docs/pics/31550398353573.gif deleted file mode 100644 index f9008efe..00000000 Binary files a/docs/pics/31550398353573.gif and /dev/null differ diff --git a/docs/pics/323ffd6c-8b54-4f3e-b361-555a6c8bf218.png b/docs/pics/323ffd6c-8b54-4f3e-b361-555a6c8bf218.png deleted file mode 100644 index 3316254e..00000000 Binary files a/docs/pics/323ffd6c-8b54-4f3e-b361-555a6c8bf218.png and /dev/null differ diff --git a/docs/pics/32b8374a-e822-4720-af0b-c0f485095ea2.jpg b/docs/pics/32b8374a-e822-4720-af0b-c0f485095ea2.jpg deleted file mode 100644 index 9de5783d..00000000 Binary files a/docs/pics/32b8374a-e822-4720-af0b-c0f485095ea2.jpg and /dev/null differ diff --git a/docs/pics/33ac2b23-cb85-4e99-bc41-b7b7199fad1c.png b/docs/pics/33ac2b23-cb85-4e99-bc41-b7b7199fad1c.png deleted file mode 100644 index 6e8383f3..00000000 Binary files a/docs/pics/33ac2b23-cb85-4e99-bc41-b7b7199fad1c.png and /dev/null differ diff --git a/docs/pics/348bc2db-582e-4aca-9f88-38c40e9a0e69.png b/docs/pics/348bc2db-582e-4aca-9f88-38c40e9a0e69.png deleted file mode 100644 index cb7e3681..00000000 Binary files a/docs/pics/348bc2db-582e-4aca-9f88-38c40e9a0e69.png and /dev/null differ diff --git a/docs/pics/3646544a-cb57-451d-9e03-d3c4f5e4434a.png b/docs/pics/3646544a-cb57-451d-9e03-d3c4f5e4434a.png deleted file mode 100644 index 76d45e19..00000000 Binary files a/docs/pics/3646544a-cb57-451d-9e03-d3c4f5e4434a.png and /dev/null differ diff --git a/docs/pics/37a72755-4890-4b42-9eab-b0084e0c54d9.png b/docs/pics/37a72755-4890-4b42-9eab-b0084e0c54d9.png deleted file mode 100644 index c74c59ef..00000000 Binary files a/docs/pics/37a72755-4890-4b42-9eab-b0084e0c54d9.png and /dev/null differ diff --git a/docs/pics/37e79a32-95a9-4503-bdb1-159527e628b8.png b/docs/pics/37e79a32-95a9-4503-bdb1-159527e628b8.png deleted file mode 100644 index 3b05b25b..00000000 Binary files a/docs/pics/37e79a32-95a9-4503-bdb1-159527e628b8.png and /dev/null differ diff --git a/docs/pics/386cd64f-7a9d-40e6-8c55-22b90ee2d258.png b/docs/pics/386cd64f-7a9d-40e6-8c55-22b90ee2d258.png deleted file mode 100644 index 5f5f5636..00000000 Binary files a/docs/pics/386cd64f-7a9d-40e6-8c55-22b90ee2d258.png and /dev/null differ diff --git a/docs/pics/38ce21e9-2075-41a3-862b-f3265a082132_200.png b/docs/pics/38ce21e9-2075-41a3-862b-f3265a082132_200.png deleted file mode 100644 index 325ac065..00000000 Binary files a/docs/pics/38ce21e9-2075-41a3-862b-f3265a082132_200.png and /dev/null differ diff --git a/docs/pics/3_200.png b/docs/pics/3_200.png deleted file mode 100644 index a35b29e4..00000000 Binary files a/docs/pics/3_200.png and /dev/null differ diff --git a/docs/pics/3_2001550473624627.png b/docs/pics/3_2001550473624627.png deleted file mode 100644 index d8bc9db0..00000000 Binary files a/docs/pics/3_2001550473624627.png and /dev/null differ diff --git a/docs/pics/3_2001550547558008.png b/docs/pics/3_2001550547558008.png deleted file mode 100644 index a42f6dc0..00000000 Binary files a/docs/pics/3_2001550547558008.png and /dev/null differ diff --git a/docs/pics/3_2001550810442775.png b/docs/pics/3_2001550810442775.png deleted file mode 100644 index 3a298036..00000000 Binary files a/docs/pics/3_2001550810442775.png and /dev/null differ diff --git a/docs/pics/3b49dd67-2c40-4b81-8ad2-7bbb1fe2fcbd.png b/docs/pics/3b49dd67-2c40-4b81-8ad2-7bbb1fe2fcbd.png deleted file mode 100644 index 13f53b6a..00000000 Binary files a/docs/pics/3b49dd67-2c40-4b81-8ad2-7bbb1fe2fcbd.png and /dev/null differ diff --git a/docs/pics/3fa0a6cb-a0a4-490a-9a80-7f4888f2500c.png b/docs/pics/3fa0a6cb-a0a4-490a-9a80-7f4888f2500c.png deleted file mode 100644 index 65bb211c..00000000 Binary files a/docs/pics/3fa0a6cb-a0a4-490a-9a80-7f4888f2500c.png and /dev/null differ diff --git a/docs/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png b/docs/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png deleted file mode 100644 index 266a4687..00000000 Binary files a/docs/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png and /dev/null differ diff --git a/docs/pics/40f29839-fd56-4ed0-9353-39dfe6f0bba5.jpg b/docs/pics/40f29839-fd56-4ed0-9353-39dfe6f0bba5.jpg deleted file mode 100644 index 355cdf57..00000000 Binary files a/docs/pics/40f29839-fd56-4ed0-9353-39dfe6f0bba5.jpg and /dev/null differ diff --git a/docs/pics/417cb02e-853d-4288-a36e-9161ded2c9fd_200.png b/docs/pics/417cb02e-853d-4288-a36e-9161ded2c9fd_200.png deleted file mode 100644 index d623b1e3..00000000 Binary files a/docs/pics/417cb02e-853d-4288-a36e-9161ded2c9fd_200.png and /dev/null differ diff --git a/docs/pics/420f4dc0-6c4b-486c-afea-274299014462.png b/docs/pics/420f4dc0-6c4b-486c-afea-274299014462.png deleted file mode 100644 index 257d73c6..00000000 Binary files a/docs/pics/420f4dc0-6c4b-486c-afea-274299014462.png and /dev/null differ diff --git a/docs/pics/43bf0957-0386-4c09-9ad7-e163c5b62559.jpg b/docs/pics/43bf0957-0386-4c09-9ad7-e163c5b62559.jpg deleted file mode 100644 index 556c01dd..00000000 Binary files a/docs/pics/43bf0957-0386-4c09-9ad7-e163c5b62559.jpg and /dev/null differ diff --git a/docs/pics/43f2cafa-3568-4a89-a895-4725666b94a6.png b/docs/pics/43f2cafa-3568-4a89-a895-4725666b94a6.png deleted file mode 100644 index 010278a2..00000000 Binary files a/docs/pics/43f2cafa-3568-4a89-a895-4725666b94a6.png and /dev/null differ diff --git a/docs/pics/4583e24f-424b-4d50-8a14-2c38a1827d4a.png b/docs/pics/4583e24f-424b-4d50-8a14-2c38a1827d4a.png deleted file mode 100644 index be98ce69..00000000 Binary files a/docs/pics/4583e24f-424b-4d50-8a14-2c38a1827d4a.png and /dev/null differ diff --git a/docs/pics/4628274c-25b6-4053-97cf-d1239b44c43d.png b/docs/pics/4628274c-25b6-4053-97cf-d1239b44c43d.png deleted file mode 100644 index 6db68ca5..00000000 Binary files a/docs/pics/4628274c-25b6-4053-97cf-d1239b44c43d.png and /dev/null differ diff --git a/docs/pics/46f66e88-e65a-4ad0-a060-3c63fe22947c.png b/docs/pics/46f66e88-e65a-4ad0-a060-3c63fe22947c.png deleted file mode 100644 index 0dcc8706..00000000 Binary files a/docs/pics/46f66e88-e65a-4ad0-a060-3c63fe22947c.png and /dev/null differ diff --git a/docs/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png b/docs/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png deleted file mode 100644 index 83d59359..00000000 Binary files a/docs/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png and /dev/null differ diff --git a/docs/pics/474e5579-38b1-47d2-8f76-a13ae086b039.jpg b/docs/pics/474e5579-38b1-47d2-8f76-a13ae086b039.jpg deleted file mode 100644 index 9af7bc09..00000000 Binary files a/docs/pics/474e5579-38b1-47d2-8f76-a13ae086b039.jpg and /dev/null differ diff --git a/docs/pics/49919961-856f-4a1d-940b-0019153ae06e_200.png b/docs/pics/49919961-856f-4a1d-940b-0019153ae06e_200.png deleted file mode 100644 index f6b4bac2..00000000 Binary files a/docs/pics/49919961-856f-4a1d-940b-0019153ae06e_200.png and /dev/null differ diff --git a/docs/pics/49e53613-46f8-4308-9ee5-c09d6231552088893397.png b/docs/pics/49e53613-46f8-4308-9ee5-c09d6231552088893397.png deleted file mode 100644 index e853dc13..00000000 Binary files a/docs/pics/49e53613-46f8-4308-9ee5-c09d6231552088893397.png and /dev/null differ diff --git a/docs/pics/49e53613-46f8-4308-9ee5-c09d62367577.png b/docs/pics/49e53613-46f8-4308-9ee5-c09d62367577.png deleted file mode 100644 index e853dc13..00000000 Binary files a/docs/pics/49e53613-46f8-4308-9ee5-c09d62367577.png and /dev/null differ diff --git a/docs/pics/4_2001550473915641.png b/docs/pics/4_2001550473915641.png deleted file mode 100644 index f86ccece..00000000 Binary files a/docs/pics/4_2001550473915641.png and /dev/null differ diff --git a/docs/pics/4_2001550547640585.png b/docs/pics/4_2001550547640585.png deleted file mode 100644 index d3f5c798..00000000 Binary files a/docs/pics/4_2001550547640585.png and /dev/null differ diff --git a/docs/pics/4_2001550810732828.png b/docs/pics/4_2001550810732828.png deleted file mode 100644 index 134cfb6b..00000000 Binary files a/docs/pics/4_2001550810732828.png and /dev/null differ diff --git a/docs/pics/4d741402-344d-4b7c-be01-e57184bcad0e.png b/docs/pics/4d741402-344d-4b7c-be01-e57184bcad0e.png deleted file mode 100644 index a4a5e7b0..00000000 Binary files a/docs/pics/4d741402-344d-4b7c-be01-e57184bcad0e.png and /dev/null differ diff --git a/docs/pics/4dc11e5e-c1d8-4391-be73-337cda32e155_200.png b/docs/pics/4dc11e5e-c1d8-4391-be73-337cda32e155_200.png deleted file mode 100644 index a5bd2b22..00000000 Binary files a/docs/pics/4dc11e5e-c1d8-4391-be73-337cda32e155_200.png and /dev/null differ diff --git a/docs/pics/4f151e62-6160-47f1-9eff-47b1f4dea4e9.jpg b/docs/pics/4f151e62-6160-47f1-9eff-47b1f4dea4e9.jpg deleted file mode 100644 index febf7a17..00000000 Binary files a/docs/pics/4f151e62-6160-47f1-9eff-47b1f4dea4e9.jpg and /dev/null differ diff --git a/docs/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png b/docs/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png deleted file mode 100644 index 649d16cd..00000000 Binary files a/docs/pics/4f48e806-f90b-4c09-a55f-ac0cd641c047.png and /dev/null differ diff --git a/docs/pics/4ff355cf-9a7f-4468-af43-e5b02038facc.jpg b/docs/pics/4ff355cf-9a7f-4468-af43-e5b02038facc.jpg deleted file mode 100644 index f81e5707..00000000 Binary files a/docs/pics/4ff355cf-9a7f-4468-af43-e5b02038facc.jpg and /dev/null differ diff --git a/docs/pics/51550399426594.gif b/docs/pics/51550399426594.gif deleted file mode 100644 index 6e931791..00000000 Binary files a/docs/pics/51550399426594.gif and /dev/null differ diff --git a/docs/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png b/docs/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png deleted file mode 100644 index d49b1727..00000000 Binary files a/docs/pics/51fb761d-8ce0-4472-92ff-2f227ac7888a.png and /dev/null differ diff --git a/docs/pics/5292faa6-0141-4638-bf0f-bb95b081dcba.jpg b/docs/pics/5292faa6-0141-4638-bf0f-bb95b081dcba.jpg deleted file mode 100644 index 32e1f054..00000000 Binary files a/docs/pics/5292faa6-0141-4638-bf0f-bb95b081dcba.jpg and /dev/null differ diff --git a/docs/pics/536c6dfd-305a-4b95-b12c-28ca5e8aa043.png b/docs/pics/536c6dfd-305a-4b95-b12c-28ca5e8aa043.png deleted file mode 100644 index 29bbc9de..00000000 Binary files a/docs/pics/536c6dfd-305a-4b95-b12c-28ca5e8aa043.png and /dev/null differ diff --git a/docs/pics/54e6d499-80df-488e-aa7e-081766c41538.jpg b/docs/pics/54e6d499-80df-488e-aa7e-081766c41538.jpg deleted file mode 100644 index 0ffa2a5b..00000000 Binary files a/docs/pics/54e6d499-80df-488e-aa7e-081766c41538.jpg and /dev/null differ diff --git a/docs/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png b/docs/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png deleted file mode 100644 index ad60a7e0..00000000 Binary files a/docs/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png and /dev/null differ diff --git a/docs/pics/56074abd-39d6-42a7-bed8-a360e81a82d8.jpg b/docs/pics/56074abd-39d6-42a7-bed8-a360e81a82d8.jpg deleted file mode 100644 index 28fad66e..00000000 Binary files a/docs/pics/56074abd-39d6-42a7-bed8-a360e81a82d8.jpg and /dev/null differ diff --git a/docs/pics/5617aa92-acc2-4b21-bc2a-eb9b0101ac6e_200.png b/docs/pics/5617aa92-acc2-4b21-bc2a-eb9b0101ac6e_200.png deleted file mode 100644 index f1990494..00000000 Binary files a/docs/pics/5617aa92-acc2-4b21-bc2a-eb9b0101ac6e_200.png and /dev/null differ diff --git a/docs/pics/584b05d4-a101-4bde-a758-f5388cb843c8.jpg b/docs/pics/584b05d4-a101-4bde-a758-f5388cb843c8.jpg deleted file mode 100644 index 5feb11d4..00000000 Binary files a/docs/pics/584b05d4-a101-4bde-a758-f5388cb843c8.jpg and /dev/null differ diff --git a/docs/pics/58e57a21-6b6b-40b6-af85-956dd4e0f55a.jpg b/docs/pics/58e57a21-6b6b-40b6-af85-956dd4e0f55a.jpg deleted file mode 100644 index a695be3a..00000000 Binary files a/docs/pics/58e57a21-6b6b-40b6-af85-956dd4e0f55a.jpg and /dev/null differ diff --git a/docs/pics/5_200.png b/docs/pics/5_200.png deleted file mode 100644 index f2f98c43..00000000 Binary files a/docs/pics/5_200.png and /dev/null differ diff --git a/docs/pics/5_2001550474110029.png b/docs/pics/5_2001550474110029.png deleted file mode 100644 index 858a456f..00000000 Binary files a/docs/pics/5_2001550474110029.png and /dev/null differ diff --git a/docs/pics/5_2001550810982206.png b/docs/pics/5_2001550810982206.png deleted file mode 100644 index f2f98c43..00000000 Binary files a/docs/pics/5_2001550810982206.png and /dev/null differ diff --git a/docs/pics/5d4a5181-65fb-4bf2-a9c6-899cab534b44.png b/docs/pics/5d4a5181-65fb-4bf2-a9c6-899cab534b44.png deleted file mode 100644 index 110bea35..00000000 Binary files a/docs/pics/5d4a5181-65fb-4bf2-a9c6-899cab534b44.png and /dev/null differ diff --git a/docs/pics/5e6e05d6-1028-4f5c-b9bd-1a40b90d6070.jpg b/docs/pics/5e6e05d6-1028-4f5c-b9bd-1a40b90d6070.jpg deleted file mode 100644 index f2a6c03a..00000000 Binary files a/docs/pics/5e6e05d6-1028-4f5c-b9bd-1a40b90d6070.jpg and /dev/null differ diff --git a/docs/pics/5effb189-d618-418b-bdda-06e6f6080c15_200.png b/docs/pics/5effb189-d618-418b-bdda-06e6f6080c15_200.png deleted file mode 100644 index 52d0bbb5..00000000 Binary files a/docs/pics/5effb189-d618-418b-bdda-06e6f6080c15_200.png and /dev/null differ diff --git a/docs/pics/61550402057509.gif b/docs/pics/61550402057509.gif deleted file mode 100644 index 7ba6f280..00000000 Binary files a/docs/pics/61550402057509.gif and /dev/null differ diff --git a/docs/pics/61942711-45a0-4e11-bbc9-434e31436f33.png b/docs/pics/61942711-45a0-4e11-bbc9-434e31436f33.png deleted file mode 100644 index 8f093ef6..00000000 Binary files a/docs/pics/61942711-45a0-4e11-bbc9-434e31436f33.png and /dev/null differ diff --git a/docs/pics/61d39d7a-c566-40dd-91ba-c6abaefa1a24.png b/docs/pics/61d39d7a-c566-40dd-91ba-c6abaefa1a24.png deleted file mode 100644 index 14d98b8c..00000000 Binary files a/docs/pics/61d39d7a-c566-40dd-91ba-c6abaefa1a24.png and /dev/null differ diff --git a/docs/pics/63010737-2cb4-48f3-999f-09194481b227.png b/docs/pics/63010737-2cb4-48f3-999f-09194481b227.png deleted file mode 100644 index c9d17851..00000000 Binary files a/docs/pics/63010737-2cb4-48f3-999f-09194481b227.png and /dev/null differ diff --git a/docs/pics/6539b9a4-2b24-4d10-8c94-2eb5aba1e296.png b/docs/pics/6539b9a4-2b24-4d10-8c94-2eb5aba1e296.png deleted file mode 100644 index 053a3dc6..00000000 Binary files a/docs/pics/6539b9a4-2b24-4d10-8c94-2eb5aba1e296.png and /dev/null differ diff --git a/docs/pics/6646db4a-7f43-45e4-96ff-0891a57a9ade.jpg b/docs/pics/6646db4a-7f43-45e4-96ff-0891a57a9ade.jpg deleted file mode 100644 index 693d7b97..00000000 Binary files a/docs/pics/6646db4a-7f43-45e4-96ff-0891a57a9ade.jpg and /dev/null differ diff --git a/docs/pics/67173c9f-ac87-496a-bd0a-0b1a5cfa735a.jpg b/docs/pics/67173c9f-ac87-496a-bd0a-0b1a5cfa735a.jpg deleted file mode 100644 index 48f3136c..00000000 Binary files a/docs/pics/67173c9f-ac87-496a-bd0a-0b1a5cfa735a.jpg and /dev/null differ diff --git a/docs/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png b/docs/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png deleted file mode 100644 index 39d7ec60..00000000 Binary files a/docs/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png and /dev/null differ diff --git a/docs/pics/68d76d01-f11f-4f6e-85ae-b9db4368d544_200.png b/docs/pics/68d76d01-f11f-4f6e-85ae-b9db4368d544_200.png deleted file mode 100644 index 3585c8aa..00000000 Binary files a/docs/pics/68d76d01-f11f-4f6e-85ae-b9db4368d544_200.png and /dev/null differ diff --git a/docs/pics/693426e6-b057-46a8-bfda-2cf681952756_200.png b/docs/pics/693426e6-b057-46a8-bfda-2cf681952756_200.png deleted file mode 100644 index 0cb973f3..00000000 Binary files a/docs/pics/693426e6-b057-46a8-bfda-2cf681952756_200.png and /dev/null differ diff --git a/docs/pics/6_2001550474388460.png b/docs/pics/6_2001550474388460.png deleted file mode 100644 index dadfd8fc..00000000 Binary files a/docs/pics/6_2001550474388460.png and /dev/null differ diff --git a/docs/pics/6_2001550476096035.png b/docs/pics/6_2001550476096035.png deleted file mode 100644 index bbf8dfd2..00000000 Binary files a/docs/pics/6_2001550476096035.png and /dev/null differ diff --git a/docs/pics/6_2001550811175246.png b/docs/pics/6_2001550811175246.png deleted file mode 100644 index 5d124af2..00000000 Binary files a/docs/pics/6_2001550811175246.png and /dev/null differ diff --git a/docs/pics/6aee49d3-f6c6-4d14-a81a-080c290de875.jpg b/docs/pics/6aee49d3-f6c6-4d14-a81a-080c290de875.jpg deleted file mode 100644 index 48b1bd5d..00000000 Binary files a/docs/pics/6aee49d3-f6c6-4d14-a81a-080c290de875.jpg and /dev/null differ diff --git a/docs/pics/6b7f33c4-2dad-4f4b-aa54-d99c0dccc4c1_200.png b/docs/pics/6b7f33c4-2dad-4f4b-aa54-d99c0dccc4c1_200.png deleted file mode 100644 index eee9ecfb..00000000 Binary files a/docs/pics/6b7f33c4-2dad-4f4b-aa54-d99c0dccc4c1_200.png and /dev/null differ diff --git a/docs/pics/6bcfad76-931a-4d85-9b58-78bb87d9a449_200.png b/docs/pics/6bcfad76-931a-4d85-9b58-78bb87d9a449_200.png deleted file mode 100644 index 201483f9..00000000 Binary files a/docs/pics/6bcfad76-931a-4d85-9b58-78bb87d9a449_200.png and /dev/null differ diff --git a/docs/pics/6c0cf1e8-b03f-4eff-9b1a-ab262e0c7866.png b/docs/pics/6c0cf1e8-b03f-4eff-9b1a-ab262e0c7866.png deleted file mode 100644 index 5b9202f6..00000000 Binary files a/docs/pics/6c0cf1e8-b03f-4eff-9b1a-ab262e0c7866.png and /dev/null differ diff --git a/docs/pics/6dd28bfc-6ef7-47cb-af50-a681ebc1bbaa.png b/docs/pics/6dd28bfc-6ef7-47cb-af50-a681ebc1bbaa.png deleted file mode 100644 index c951760f..00000000 Binary files a/docs/pics/6dd28bfc-6ef7-47cb-af50-a681ebc1bbaa.png and /dev/null differ diff --git a/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c6181555941244322.png b/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c6181555941244322.png deleted file mode 100644 index e26e9c28..00000000 Binary files a/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c6181555941244322.png and /dev/null differ diff --git a/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c618c25be_200.png b/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c618c25be_200.png deleted file mode 100644 index e26e9c28..00000000 Binary files a/docs/pics/6edb0f48-fdc8-4c57-8cb6-f19c618c25be_200.png and /dev/null differ diff --git a/docs/pics/6f1938e5-fc49-4e7b-a383-2b46f0942d70_200.png b/docs/pics/6f1938e5-fc49-4e7b-a383-2b46f0942d70_200.png deleted file mode 100644 index a830a7d4..00000000 Binary files a/docs/pics/6f1938e5-fc49-4e7b-a383-2b46f0942d70_200.png and /dev/null differ diff --git a/docs/pics/71f61bc3-582d-4c27-8bdd-dc7fb135bf8f.png b/docs/pics/71f61bc3-582d-4c27-8bdd-dc7fb135bf8f.png deleted file mode 100644 index 4e99159f..00000000 Binary files a/docs/pics/71f61bc3-582d-4c27-8bdd-dc7fb135bf8f.png and /dev/null differ diff --git a/docs/pics/72f0ff69-138d-4e54-b7ac-ebe025d978dc.png b/docs/pics/72f0ff69-138d-4e54-b7ac-ebe025d978dc.png deleted file mode 100644 index 5299728f..00000000 Binary files a/docs/pics/72f0ff69-138d-4e54-b7ac-ebe025d978dc.png and /dev/null differ diff --git a/docs/pics/731a5e8f-a2c2-43ff-b8dd-6aeb9fffbe26.jpg b/docs/pics/731a5e8f-a2c2-43ff-b8dd-6aeb9fffbe26.jpg deleted file mode 100644 index dda05f94..00000000 Binary files a/docs/pics/731a5e8f-a2c2-43ff-b8dd-6aeb9fffbe26.jpg and /dev/null differ diff --git a/docs/pics/73846795-675b-496b-88b0-d44233fdcfba.jpg b/docs/pics/73846795-675b-496b-88b0-d44233fdcfba.jpg deleted file mode 100644 index b045287d..00000000 Binary files a/docs/pics/73846795-675b-496b-88b0-d44233fdcfba.jpg and /dev/null differ diff --git a/docs/pics/73c72e75-193c-4092-aa43-b9c6703c4a22.jpg b/docs/pics/73c72e75-193c-4092-aa43-b9c6703c4a22.jpg deleted file mode 100644 index 5b905db1..00000000 Binary files a/docs/pics/73c72e75-193c-4092-aa43-b9c6703c4a22.jpg and /dev/null differ diff --git a/docs/pics/75996367-adc2-4be1-a92a-09cc4347638e.png b/docs/pics/75996367-adc2-4be1-a92a-09cc4347638e.png deleted file mode 100644 index ec381029..00000000 Binary files a/docs/pics/75996367-adc2-4be1-a92a-09cc4347638e.png and /dev/null differ diff --git a/docs/pics/766aedd0-1b00-4065-aa2b-7d31138df84f.png b/docs/pics/766aedd0-1b00-4065-aa2b-7d31138df84f.png deleted file mode 100644 index e8a69bff..00000000 Binary files a/docs/pics/766aedd0-1b00-4065-aa2b-7d31138df84f.png and /dev/null differ diff --git a/docs/pics/76c7597a-8316-460d-b8fb-9752c4c43947.jpg b/docs/pics/76c7597a-8316-460d-b8fb-9752c4c43947.jpg deleted file mode 100644 index 598ed2ed..00000000 Binary files a/docs/pics/76c7597a-8316-460d-b8fb-9752c4c43947.jpg and /dev/null differ diff --git a/docs/pics/7935be3d-c2b3-4213-90c9-1e68ec4ac4e7.png b/docs/pics/7935be3d-c2b3-4213-90c9-1e68ec4ac4e7.png deleted file mode 100644 index d146ec06..00000000 Binary files a/docs/pics/7935be3d-c2b3-4213-90c9-1e68ec4ac4e7.png and /dev/null differ diff --git a/docs/pics/79b12431-6d9d-4a7d-985b-1b79bc5bf5fb.png b/docs/pics/79b12431-6d9d-4a7d-985b-1b79bc5bf5fb.png deleted file mode 100644 index d2a30004..00000000 Binary files a/docs/pics/79b12431-6d9d-4a7d-985b-1b79bc5bf5fb.png and /dev/null differ diff --git a/docs/pics/79e9a938-43e2-4c5a-8de9-fe55522a14c9.png b/docs/pics/79e9a938-43e2-4c5a-8de9-fe55522a14c9.png deleted file mode 100644 index 4938fc58..00000000 Binary files a/docs/pics/79e9a938-43e2-4c5a-8de9-fe55522a14c9.png and /dev/null differ diff --git a/docs/pics/7_2001550475133282.png b/docs/pics/7_2001550475133282.png deleted file mode 100644 index 884eca83..00000000 Binary files a/docs/pics/7_2001550475133282.png and /dev/null differ diff --git a/docs/pics/7_2001550811502556.png b/docs/pics/7_2001550811502556.png deleted file mode 100644 index 41da48f5..00000000 Binary files a/docs/pics/7_2001550811502556.png and /dev/null differ diff --git a/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png b/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png deleted file mode 100644 index e1743f53..00000000 Binary files a/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png and /dev/null differ diff --git a/docs/pics/7c5bcdbf-e656-4b7c-be82-b247a3589ed5_200.png b/docs/pics/7c5bcdbf-e656-4b7c-be82-b247a3589ed5_200.png deleted file mode 100644 index cf1868b6..00000000 Binary files a/docs/pics/7c5bcdbf-e656-4b7c-be82-b247a3589ed5_200.png and /dev/null differ diff --git a/docs/pics/7c5e4fbe-8aab-4dd6-a7a0-aae39bfd110f_200.png b/docs/pics/7c5e4fbe-8aab-4dd6-a7a0-aae39bfd110f_200.png deleted file mode 100644 index c59ffca4..00000000 Binary files a/docs/pics/7c5e4fbe-8aab-4dd6-a7a0-aae39bfd110f_200.png and /dev/null differ diff --git a/docs/pics/7c98e1b6-c446-4cde-8513-5c11b9f52aea.jpg b/docs/pics/7c98e1b6-c446-4cde-8513-5c11b9f52aea.jpg deleted file mode 100644 index 7dcb6d1c..00000000 Binary files a/docs/pics/7c98e1b6-c446-4cde-8513-5c11b9f52aea.jpg and /dev/null differ diff --git a/docs/pics/7da6d7e0-f08b-4ebd-b385-add5d6f03b84_200.png b/docs/pics/7da6d7e0-f08b-4ebd-b385-add5d6f03b84_200.png deleted file mode 100644 index 0a1bfc3c..00000000 Binary files a/docs/pics/7da6d7e0-f08b-4ebd-b385-add5d6f03b84_200.png and /dev/null differ diff --git a/docs/pics/7de17ad2-de6e-4496-adaf-b8bc7b2f7f7b.png b/docs/pics/7de17ad2-de6e-4496-adaf-b8bc7b2f7f7b.png deleted file mode 100644 index c90982c2..00000000 Binary files a/docs/pics/7de17ad2-de6e-4496-adaf-b8bc7b2f7f7b.png and /dev/null differ diff --git a/docs/pics/7e6cb8fc-1b82-4135-8b03-ebcfc546d94c.png b/docs/pics/7e6cb8fc-1b82-4135-8b03-ebcfc546d94c.png deleted file mode 100644 index 56ca814b..00000000 Binary files a/docs/pics/7e6cb8fc-1b82-4135-8b03-ebcfc546d94c.png and /dev/null differ diff --git a/docs/pics/7e82ce01-2afb-4c15-b720-b81049c875c2_200.png b/docs/pics/7e82ce01-2afb-4c15-b720-b81049c875c2_200.png deleted file mode 100644 index 0741f44e..00000000 Binary files a/docs/pics/7e82ce01-2afb-4c15-b720-b81049c875c2_200.png and /dev/null differ diff --git a/docs/pics/7e873b60-44dc-4911-b080-defd5b8f0b49.png b/docs/pics/7e873b60-44dc-4911-b080-defd5b8f0b49.png deleted file mode 100644 index 66e26e80..00000000 Binary files a/docs/pics/7e873b60-44dc-4911-b080-defd5b8f0b49.png and /dev/null differ diff --git a/docs/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png b/docs/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png deleted file mode 100644 index 57e71b9c..00000000 Binary files a/docs/pics/7f38a583-2f2e-4738-97af-510e6fb403a7.png and /dev/null differ diff --git a/docs/pics/7f403a7a-5228-42c0-af1c-b21635c77016.jpg b/docs/pics/7f403a7a-5228-42c0-af1c-b21635c77016.jpg deleted file mode 100644 index aad341fd..00000000 Binary files a/docs/pics/7f403a7a-5228-42c0-af1c-b21635c77016.jpg and /dev/null differ diff --git a/docs/pics/8036ba3d-8de9-44aa-bf5d-1f8ca18ae89b.jpg b/docs/pics/8036ba3d-8de9-44aa-bf5d-1f8ca18ae89b.jpg deleted file mode 100644 index 7491217d..00000000 Binary files a/docs/pics/8036ba3d-8de9-44aa-bf5d-1f8ca18ae89b.jpg and /dev/null differ diff --git a/docs/pics/805812fa-6ab5-4b8f-a0aa-3bdcadaa829d.png b/docs/pics/805812fa-6ab5-4b8f-a0aa-3bdcadaa829d.png deleted file mode 100644 index 382cc19b..00000000 Binary files a/docs/pics/805812fa-6ab5-4b8f-a0aa-3bdcadaa829d.png and /dev/null differ diff --git a/docs/pics/80646c77-1f32-484c-810e-af80ce00f902.png b/docs/pics/80646c77-1f32-484c-810e-af80ce00f902.png deleted file mode 100644 index de3f5298..00000000 Binary files a/docs/pics/80646c77-1f32-484c-810e-af80ce00f902.png and /dev/null differ diff --git a/docs/pics/8089a19a-6239-47a0-bf69-54203117d4dc.jpg b/docs/pics/8089a19a-6239-47a0-bf69-54203117d4dc.jpg deleted file mode 100644 index 5f34004b..00000000 Binary files a/docs/pics/8089a19a-6239-47a0-bf69-54203117d4dc.jpg and /dev/null differ diff --git a/docs/pics/81550405360028.gif b/docs/pics/81550405360028.gif deleted file mode 100644 index 7960c782..00000000 Binary files a/docs/pics/81550405360028.gif and /dev/null differ diff --git a/docs/pics/8162aebb-8fd2-4620-b771-e65751ba7e41.png b/docs/pics/8162aebb-8fd2-4620-b771-e65751ba7e41.png deleted file mode 100644 index 2fa69582..00000000 Binary files a/docs/pics/8162aebb-8fd2-4620-b771-e65751ba7e41.png and /dev/null differ diff --git a/docs/pics/836a4eaf-4798-4e48-b52a-a3dab9435ace.png b/docs/pics/836a4eaf-4798-4e48-b52a-a3dab9435ace.png deleted file mode 100644 index be8ab737..00000000 Binary files a/docs/pics/836a4eaf-4798-4e48-b52a-a3dab9435ace.png and /dev/null differ diff --git a/docs/pics/839207f5-52fd-4516-9370-956dcdf2c2b5.png b/docs/pics/839207f5-52fd-4516-9370-956dcdf2c2b5.png deleted file mode 100644 index 891a9a37..00000000 Binary files a/docs/pics/839207f5-52fd-4516-9370-956dcdf2c2b5.png and /dev/null differ diff --git a/docs/pics/83e9c5ed-35a1-41fd-b0dd-ce571969b5f3_200.png b/docs/pics/83e9c5ed-35a1-41fd-b0dd-ce571969b5f3_200.png deleted file mode 100644 index 23fc9fbd..00000000 Binary files a/docs/pics/83e9c5ed-35a1-41fd-b0dd-ce571969b5f3_200.png and /dev/null differ diff --git a/docs/pics/8433fbb2-c35c-45ef-831d-e3ca42aebd51.png b/docs/pics/8433fbb2-c35c-45ef-831d-e3ca42aebd51.png deleted file mode 100644 index 5c0b076b..00000000 Binary files a/docs/pics/8433fbb2-c35c-45ef-831d-e3ca42aebd51.png and /dev/null differ diff --git a/docs/pics/847b9ba1-b3cd-4e52-aa72-dee0222ae09f.jpg b/docs/pics/847b9ba1-b3cd-4e52-aa72-dee0222ae09f.jpg deleted file mode 100644 index c68fd3ef..00000000 Binary files a/docs/pics/847b9ba1-b3cd-4e52-aa72-dee0222ae09f.jpg and /dev/null differ diff --git a/docs/pics/84d496d7-54b0-4a9b-9499-ce232057e499_200.png b/docs/pics/84d496d7-54b0-4a9b-9499-ce232057e499_200.png deleted file mode 100644 index 5423ac85..00000000 Binary files a/docs/pics/84d496d7-54b0-4a9b-9499-ce232057e499_200.png and /dev/null differ diff --git a/docs/pics/85583359-1b45-45f2-9811-4f7bb9a64db7.jpg b/docs/pics/85583359-1b45-45f2-9811-4f7bb9a64db7.jpg deleted file mode 100644 index 0abcf7d6..00000000 Binary files a/docs/pics/85583359-1b45-45f2-9811-4f7bb9a64db7.jpg and /dev/null differ diff --git a/docs/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png b/docs/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png deleted file mode 100644 index f77ff346..00000000 Binary files a/docs/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png and /dev/null differ diff --git a/docs/pics/862d5e07-ff6e-4c0d-abe4-08488cbf8049_200.png b/docs/pics/862d5e07-ff6e-4c0d-abe4-08488cbf8049_200.png deleted file mode 100644 index 9a90935b..00000000 Binary files a/docs/pics/862d5e07-ff6e-4c0d-abe4-08488cbf8049_200.png and /dev/null differ diff --git a/docs/pics/864bfa7d-1149-420c-a752-f9b3d4e782ec.png b/docs/pics/864bfa7d-1149-420c-a752-f9b3d4e782ec.png deleted file mode 100644 index 72cc988f..00000000 Binary files a/docs/pics/864bfa7d-1149-420c-a752-f9b3d4e782ec.png and /dev/null differ diff --git a/docs/pics/89a0024a-7485-4164-bc82-ebdea51f59e0_200.png b/docs/pics/89a0024a-7485-4164-bc82-ebdea51f59e0_200.png deleted file mode 100644 index 11319054..00000000 Binary files a/docs/pics/89a0024a-7485-4164-bc82-ebdea51f59e0_200.png and /dev/null differ diff --git a/docs/pics/8_200.png b/docs/pics/8_200.png deleted file mode 100644 index af9d663a..00000000 Binary files a/docs/pics/8_200.png and /dev/null differ diff --git a/docs/pics/8_2001550475451664.png b/docs/pics/8_2001550475451664.png deleted file mode 100644 index 772df79c..00000000 Binary files a/docs/pics/8_2001550475451664.png and /dev/null differ diff --git a/docs/pics/8_2001550812038190.png b/docs/pics/8_2001550812038190.png deleted file mode 100644 index 966bd4e2..00000000 Binary files a/docs/pics/8_2001550812038190.png and /dev/null differ diff --git a/docs/pics/8a182663-af78-4618-b893-96c63324a250_200.png b/docs/pics/8a182663-af78-4618-b893-96c63324a250_200.png deleted file mode 100644 index bf72918b..00000000 Binary files a/docs/pics/8a182663-af78-4618-b893-96c63324a250_200.png and /dev/null differ diff --git a/docs/pics/8ae4550b-f0cb-4e4d-9e2b-c550538bf230.png b/docs/pics/8ae4550b-f0cb-4e4d-9e2b-c550538bf230.png deleted file mode 100644 index 31ae5e0c..00000000 Binary files a/docs/pics/8ae4550b-f0cb-4e4d-9e2b-c550538bf230.png and /dev/null differ diff --git a/docs/pics/8c001caa-cf3d-4793-a64e-6e7dbc446c0d_200.png b/docs/pics/8c001caa-cf3d-4793-a64e-6e7dbc446c0d_200.png deleted file mode 100644 index 44cbdc25..00000000 Binary files a/docs/pics/8c001caa-cf3d-4793-a64e-6e7dbc446c0d_200.png and /dev/null differ diff --git a/docs/pics/8ea6d399-ebcb-4077-b9c7-b2d825fe256c_200.png b/docs/pics/8ea6d399-ebcb-4077-b9c7-b2d825fe256c_200.png deleted file mode 100644 index ea3eabc4..00000000 Binary files a/docs/pics/8ea6d399-ebcb-4077-b9c7-b2d825fe256c_200.png and /dev/null differ diff --git a/docs/pics/8f0cc500-5994-4c7a-91a9-62885d658662.png b/docs/pics/8f0cc500-5994-4c7a-91a9-62885d658662.png deleted file mode 100644 index 034205a8..00000000 Binary files a/docs/pics/8f0cc500-5994-4c7a-91a9-62885d658662.png and /dev/null differ diff --git a/docs/pics/8f3b9519-d705-48fe-87ad-2e4052fc81d2.png b/docs/pics/8f3b9519-d705-48fe-87ad-2e4052fc81d2.png deleted file mode 100644 index a8e36ee0..00000000 Binary files a/docs/pics/8f3b9519-d705-48fe-87ad-2e4052fc81d2.png and /dev/null differ diff --git a/docs/pics/8f6f9dc9-9ecd-47c8-b50e-2814f0219056.png b/docs/pics/8f6f9dc9-9ecd-47c8-b50e-2814f0219056.png deleted file mode 100644 index 21b8a930..00000000 Binary files a/docs/pics/8f6f9dc9-9ecd-47c8-b50e-2814f0219056.png and /dev/null differ diff --git a/docs/pics/8fdbb8f5-2cf8-41dc-b5f1-99d98abb52d9.jpg b/docs/pics/8fdbb8f5-2cf8-41dc-b5f1-99d98abb52d9.jpg deleted file mode 100644 index a9e33df4..00000000 Binary files a/docs/pics/8fdbb8f5-2cf8-41dc-b5f1-99d98abb52d9.jpg and /dev/null differ diff --git a/docs/pics/902b83ab-8054-4bd2-898f-9a4a0fe52830.jpg b/docs/pics/902b83ab-8054-4bd2-898f-9a4a0fe52830.jpg deleted file mode 100644 index 7b2d0143..00000000 Binary files a/docs/pics/902b83ab-8054-4bd2-898f-9a4a0fe52830.jpg and /dev/null differ diff --git a/docs/pics/9110c1a0-8a54-4145-a814-2477d0128114.png b/docs/pics/9110c1a0-8a54-4145-a814-2477d0128114.png deleted file mode 100644 index 68aa9f98..00000000 Binary files a/docs/pics/9110c1a0-8a54-4145-a814-2477d0128114.png and /dev/null differ diff --git a/docs/pics/912a7886-fb1d-4a05-902d-ab17ea17007f.jpg b/docs/pics/912a7886-fb1d-4a05-902d-ab17ea17007f.jpg deleted file mode 100644 index e30c6908..00000000 Binary files a/docs/pics/912a7886-fb1d-4a05-902d-ab17ea17007f.jpg and /dev/null differ diff --git a/docs/pics/91550405374894.gif b/docs/pics/91550405374894.gif deleted file mode 100644 index 2409a299..00000000 Binary files a/docs/pics/91550405374894.gif and /dev/null differ diff --git a/docs/pics/91aa7c29-438f-4fcc-8c63-2a75899139de.png b/docs/pics/91aa7c29-438f-4fcc-8c63-2a75899139de.png deleted file mode 100644 index dd90699b..00000000 Binary files a/docs/pics/91aa7c29-438f-4fcc-8c63-2a75899139de.png and /dev/null differ diff --git a/docs/pics/92691356-4f7a-46ec-9921-13055d3dcb12.jpg b/docs/pics/92691356-4f7a-46ec-9921-13055d3dcb12.jpg deleted file mode 100644 index 2a736557..00000000 Binary files a/docs/pics/92691356-4f7a-46ec-9921-13055d3dcb12.jpg and /dev/null differ diff --git a/docs/pics/938fc386-0340-47b5-aeaa-6993e3bb4fc0.png b/docs/pics/938fc386-0340-47b5-aeaa-6993e3bb4fc0.png deleted file mode 100644 index 9064fe0e..00000000 Binary files a/docs/pics/938fc386-0340-47b5-aeaa-6993e3bb4fc0.png and /dev/null differ diff --git a/docs/pics/94414cd3-5db9-4aca-a2af-539140955c62.jpg b/docs/pics/94414cd3-5db9-4aca-a2af-539140955c62.jpg deleted file mode 100644 index 5c53d38b..00000000 Binary files a/docs/pics/94414cd3-5db9-4aca-a2af-539140955c62.jpg and /dev/null differ diff --git a/docs/pics/952afa9a-458b-44ce-bba9-463e60162945.png b/docs/pics/952afa9a-458b-44ce-bba9-463e60162945.png deleted file mode 100644 index db93c1ac..00000000 Binary files a/docs/pics/952afa9a-458b-44ce-bba9-463e60162945.png and /dev/null differ diff --git a/docs/pics/963fac12-4eac-4922-8a5f-f262c11f80fb.jpg b/docs/pics/963fac12-4eac-4922-8a5f-f262c11f80fb.jpg deleted file mode 100644 index 97104ded..00000000 Binary files a/docs/pics/963fac12-4eac-4922-8a5f-f262c11f80fb.jpg and /dev/null differ diff --git a/docs/pics/96706658-b3f8-4f32-8eb3-dcb7fc8d5381.jpg b/docs/pics/96706658-b3f8-4f32-8eb3-dcb7fc8d5381.jpg deleted file mode 100644 index c4e77ba1..00000000 Binary files a/docs/pics/96706658-b3f8-4f32-8eb3-dcb7fc8d5381.jpg and /dev/null differ diff --git a/docs/pics/99208bd0-1454-4618-9969-0c2deb8bba0f.png b/docs/pics/99208bd0-1454-4618-9969-0c2deb8bba0f.png deleted file mode 100644 index 7d870990..00000000 Binary files a/docs/pics/99208bd0-1454-4618-9969-0c2deb8bba0f.png and /dev/null differ diff --git a/docs/pics/9_200.png b/docs/pics/9_200.png deleted file mode 100644 index 4cf0f56d..00000000 Binary files a/docs/pics/9_200.png and /dev/null differ diff --git a/docs/pics/9bae24e9-d2f5-4e1d-af42-1a868a5847cf.jpg b/docs/pics/9bae24e9-d2f5-4e1d-af42-1a868a5847cf.jpg deleted file mode 100644 index b985fdd8..00000000 Binary files a/docs/pics/9bae24e9-d2f5-4e1d-af42-1a868a5847cf.jpg and /dev/null differ diff --git a/docs/pics/9bd12b89-f99c-49f4-ae45-410f76a713d6.png b/docs/pics/9bd12b89-f99c-49f4-ae45-410f76a713d6.png deleted file mode 100644 index f726a4c2..00000000 Binary files a/docs/pics/9bd12b89-f99c-49f4-ae45-410f76a713d6.png and /dev/null differ diff --git a/docs/pics/9c60793f-5e7f-453b-8413-35890c24abc4.png b/docs/pics/9c60793f-5e7f-453b-8413-35890c24abc4.png deleted file mode 100644 index 89c84a73..00000000 Binary files a/docs/pics/9c60793f-5e7f-453b-8413-35890c24abc4.png and /dev/null differ diff --git a/docs/pics/9ccb276e-6840-4150-ae6d-fc57b8eef35b_200.png b/docs/pics/9ccb276e-6840-4150-ae6d-fc57b8eef35b_200.png deleted file mode 100644 index 72f2bba0..00000000 Binary files a/docs/pics/9ccb276e-6840-4150-ae6d-fc57b8eef35b_200.png and /dev/null differ diff --git a/docs/pics/9d0a637c-6a8f-4f5a-99b9-fdcfa26793ff.png b/docs/pics/9d0a637c-6a8f-4f5a-99b9-fdcfa26793ff.png deleted file mode 100644 index 34a8f664..00000000 Binary files a/docs/pics/9d0a637c-6a8f-4f5a-99b9-fdcfa26793ff.png and /dev/null differ diff --git a/docs/pics/9d3c6bfb-4c4c-4b77-9410-56b3f82106d1.jpg b/docs/pics/9d3c6bfb-4c4c-4b77-9410-56b3f82106d1.jpg deleted file mode 100644 index 9f4f5f04..00000000 Binary files a/docs/pics/9d3c6bfb-4c4c-4b77-9410-56b3f82106d1.jpg and /dev/null differ diff --git a/docs/pics/9e80f75a-b12b-4344-80c8-1f9ccc2d5246.jpg b/docs/pics/9e80f75a-b12b-4344-80c8-1f9ccc2d5246.jpg deleted file mode 100644 index 15d4b3c8..00000000 Binary files a/docs/pics/9e80f75a-b12b-4344-80c8-1f9ccc2d5246.jpg and /dev/null differ diff --git a/docs/pics/9ffb82ad-9b7f-44df-b93f-fc8b3f4093a6.jpg b/docs/pics/9ffb82ad-9b7f-44df-b93f-fc8b3f4093a6.jpg deleted file mode 100644 index 2ab8530a..00000000 Binary files a/docs/pics/9ffb82ad-9b7f-44df-b93f-fc8b3f4093a6.jpg and /dev/null differ diff --git a/docs/pics/ClienteServidorSockets1521731145260.jpg b/docs/pics/ClienteServidorSockets1521731145260.jpg deleted file mode 100644 index 18976fb3..00000000 Binary files a/docs/pics/ClienteServidorSockets1521731145260.jpg and /dev/null differ diff --git a/docs/pics/CountdownLatch.png b/docs/pics/CountdownLatch.png deleted file mode 100644 index 1a581bbf..00000000 Binary files a/docs/pics/CountdownLatch.png and /dev/null differ diff --git a/docs/pics/CyclicBarrier.png b/docs/pics/CyclicBarrier.png deleted file mode 100644 index 5fe5b88b..00000000 Binary files a/docs/pics/CyclicBarrier.png and /dev/null differ diff --git a/docs/pics/DP-Decorator-java.io.png b/docs/pics/DP-Decorator-java.io.png deleted file mode 100644 index 897a510b..00000000 Binary files a/docs/pics/DP-Decorator-java.io.png and /dev/null differ diff --git a/docs/pics/LOun2W9134NxVugmbJPp15d4LalxC4O.png b/docs/pics/LOun2W9134NxVugmbJPp15d4LalxC4O.png deleted file mode 100644 index 188460a5..00000000 Binary files a/docs/pics/LOun2W9134NxVugmbJPp15d4LalxC4O.png and /dev/null differ diff --git a/docs/pics/Semaphore.png b/docs/pics/Semaphore.png deleted file mode 100644 index 6b8c30b1..00000000 Binary files a/docs/pics/Semaphore.png and /dev/null differ diff --git a/docs/pics/SoWkIImgAStDuU8goIp9ILK8IatCoQn.png b/docs/pics/SoWkIImgAStDuU8goIp9ILK8IatCoQn.png deleted file mode 100644 index da66da14..00000000 Binary files a/docs/pics/SoWkIImgAStDuU8goIp9ILK8IatCoQn.png and /dev/null differ diff --git a/docs/pics/SoWkIImgAStDuU8goIp9ILLmB2xEJyv.png b/docs/pics/SoWkIImgAStDuU8goIp9ILLmB2xEJyv.png deleted file mode 100644 index e5ae5234..00000000 Binary files a/docs/pics/SoWkIImgAStDuU8goIp9ILLmB2xEJyv.png and /dev/null differ diff --git a/docs/pics/SoWkIImgAStDuU8goIp9ILLmJ4ylIar.png b/docs/pics/SoWkIImgAStDuU8goIp9ILLmJ4ylIar.png deleted file mode 100644 index e31398b6..00000000 Binary files a/docs/pics/SoWkIImgAStDuU8goIp9ILLmJ4ylIar.png and /dev/null differ diff --git a/docs/pics/SoWkIImgAStDuU8goIp9ILLmJyrBBKh.png b/docs/pics/SoWkIImgAStDuU8goIp9ILLmJyrBBKh.png deleted file mode 100644 index 055d995e..00000000 Binary files a/docs/pics/SoWkIImgAStDuU8goIp9ILLmJyrBBKh.png and /dev/null differ diff --git a/docs/pics/SoWkIImgAStDuU8goIp9ILLmpiyjo2_.png b/docs/pics/SoWkIImgAStDuU8goIp9ILLmpiyjo2_.png deleted file mode 100644 index 37f32c4c..00000000 Binary files a/docs/pics/SoWkIImgAStDuU8goIp9ILLmpiyjo2_.png and /dev/null differ diff --git a/docs/pics/_u6570_u7EC4_u4E2D_u91CD_u590D_1548260392361.gif b/docs/pics/_u6570_u7EC4_u4E2D_u91CD_u590D_1548260392361.gif deleted file mode 100644 index 07f3a910..00000000 Binary files a/docs/pics/_u6570_u7EC4_u4E2D_u91CD_u590D_1548260392361.gif and /dev/null differ diff --git a/docs/pics/a01d1516-8168-461a-a24b-620b9cfc40f4.png b/docs/pics/a01d1516-8168-461a-a24b-620b9cfc40f4.png deleted file mode 100644 index 4b9b4b48..00000000 Binary files a/docs/pics/a01d1516-8168-461a-a24b-620b9cfc40f4.png and /dev/null differ diff --git a/docs/pics/a0e90bd3-747d-4c3a-8fa0-179c59eeded0_200.png b/docs/pics/a0e90bd3-747d-4c3a-8fa0-179c59eeded0_200.png deleted file mode 100644 index 541acf31..00000000 Binary files a/docs/pics/a0e90bd3-747d-4c3a-8fa0-179c59eeded0_200.png and /dev/null differ diff --git a/docs/pics/a1198642-9159-4d88-8aec-c3b04e7a2563.jpg b/docs/pics/a1198642-9159-4d88-8aec-c3b04e7a2563.jpg deleted file mode 100644 index 30e92639..00000000 Binary files a/docs/pics/a1198642-9159-4d88-8aec-c3b04e7a2563.jpg and /dev/null differ diff --git a/docs/pics/a2d13178-f1ef-4811-a240-1fe95b55b1eb.png b/docs/pics/a2d13178-f1ef-4811-a240-1fe95b55b1eb.png deleted file mode 100644 index edc6840a..00000000 Binary files a/docs/pics/a2d13178-f1ef-4811-a240-1fe95b55b1eb.png and /dev/null differ diff --git a/docs/pics/a3da4342-078b-43e2-b748-7e71bec50dc4.png b/docs/pics/a3da4342-078b-43e2-b748-7e71bec50dc4.png deleted file mode 100644 index 03b37a61..00000000 Binary files a/docs/pics/a3da4342-078b-43e2-b748-7e71bec50dc4.png and /dev/null differ diff --git a/docs/pics/a3f34241-bb80-4879-8ec9-dff2d81b514e.jpg b/docs/pics/a3f34241-bb80-4879-8ec9-dff2d81b514e.jpg deleted file mode 100644 index 7b432fd1..00000000 Binary files a/docs/pics/a3f34241-bb80-4879-8ec9-dff2d81b514e.jpg and /dev/null differ diff --git a/docs/pics/a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg b/docs/pics/a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg deleted file mode 100644 index a7050bdf..00000000 Binary files a/docs/pics/a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg and /dev/null differ diff --git a/docs/pics/a4c17d43-fa5e-4935-b74e-147e7f7e782c.png b/docs/pics/a4c17d43-fa5e-4935-b74e-147e7f7e782c.png deleted file mode 100644 index 461fffb0..00000000 Binary files a/docs/pics/a4c17d43-fa5e-4935-b74e-147e7f7e782c.png and /dev/null differ diff --git a/docs/pics/a6ebcd0a-a44d-48c8-b29a-dfacece83301.png b/docs/pics/a6ebcd0a-a44d-48c8-b29a-dfacece83301.png deleted file mode 100644 index 9b6bcee2..00000000 Binary files a/docs/pics/a6ebcd0a-a44d-48c8-b29a-dfacece83301.png and /dev/null differ diff --git a/docs/pics/a79aec4f-aea4-4ee2-87e3-7c7c6049b90c_200.png b/docs/pics/a79aec4f-aea4-4ee2-87e3-7c7c6049b90c_200.png deleted file mode 100644 index be6e786b..00000000 Binary files a/docs/pics/a79aec4f-aea4-4ee2-87e3-7c7c6049b90c_200.png and /dev/null differ diff --git a/docs/pics/ace830df-9919-48ca-91b5-60b193f593d2.png b/docs/pics/ace830df-9919-48ca-91b5-60b193f593d2.png deleted file mode 100644 index 79efa287..00000000 Binary files a/docs/pics/ace830df-9919-48ca-91b5-60b193f593d2.png and /dev/null differ diff --git a/docs/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png b/docs/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png deleted file mode 100644 index 8de4fa4d..00000000 Binary files a/docs/pics/af4639f9-af54-4400-aaf5-4e261d96ace7.png and /dev/null differ diff --git a/docs/pics/b01e12b7-6cfc-485b-a03e-a575e6f7b773.jpg b/docs/pics/b01e12b7-6cfc-485b-a03e-a575e6f7b773.jpg deleted file mode 100644 index cfb2586d..00000000 Binary files a/docs/pics/b01e12b7-6cfc-485b-a03e-a575e6f7b773.jpg and /dev/null differ diff --git a/docs/pics/b02fcffd-ed09-4ef9-bc5f-8f0e0383eb1a.jpg b/docs/pics/b02fcffd-ed09-4ef9-bc5f-8f0e0383eb1a.jpg deleted file mode 100644 index a0df23c8..00000000 Binary files a/docs/pics/b02fcffd-ed09-4ef9-bc5f-8f0e0383eb1a.jpg and /dev/null differ diff --git a/docs/pics/b20a3466-44b4-445e-87c7-dd4fb9ef44b2.png b/docs/pics/b20a3466-44b4-445e-87c7-dd4fb9ef44b2.png deleted file mode 100644 index 3d5adabd..00000000 Binary files a/docs/pics/b20a3466-44b4-445e-87c7-dd4fb9ef44b2.png and /dev/null differ diff --git a/docs/pics/b28a7b1e-bf5a-4e23-8be7-701eacef0111.jpg b/docs/pics/b28a7b1e-bf5a-4e23-8be7-701eacef0111.jpg deleted file mode 100644 index d8085fa0..00000000 Binary files a/docs/pics/b28a7b1e-bf5a-4e23-8be7-701eacef0111.jpg and /dev/null differ diff --git a/docs/pics/b29f8971-9cb8-480d-b986-0e60c2ece069.png b/docs/pics/b29f8971-9cb8-480d-b986-0e60c2ece069.png deleted file mode 100644 index 65f73b0e..00000000 Binary files a/docs/pics/b29f8971-9cb8-480d-b986-0e60c2ece069.png and /dev/null differ diff --git a/docs/pics/b39a085e-e7a2-4657-b75e-ba1652a4b132.jpg b/docs/pics/b39a085e-e7a2-4657-b75e-ba1652a4b132.jpg deleted file mode 100644 index fa79744a..00000000 Binary files a/docs/pics/b39a085e-e7a2-4657-b75e-ba1652a4b132.jpg and /dev/null differ diff --git a/docs/pics/b3a421e3-41b4-4e99-b612-bc695a7f622f.jpg b/docs/pics/b3a421e3-41b4-4e99-b612-bc695a7f622f.jpg deleted file mode 100644 index eb46d412..00000000 Binary files a/docs/pics/b3a421e3-41b4-4e99-b612-bc695a7f622f.jpg and /dev/null differ diff --git a/docs/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png b/docs/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png deleted file mode 100644 index 59ea02cc..00000000 Binary files a/docs/pics/b4252c85-6fb0-4995-9a68-a1a5925fbdb1.png and /dev/null differ diff --git a/docs/pics/b48b9a7a-f9f8-4cf9-90f1-5cddd685b782_200.png b/docs/pics/b48b9a7a-f9f8-4cf9-90f1-5cddd685b782_200.png deleted file mode 100644 index ac9868d1..00000000 Binary files a/docs/pics/b48b9a7a-f9f8-4cf9-90f1-5cddd685b782_200.png and /dev/null differ diff --git a/docs/pics/b6a7e8af-91bf-44b2-8874-ccc6d9d52afc.jpg b/docs/pics/b6a7e8af-91bf-44b2-8874-ccc6d9d52afc.jpg deleted file mode 100644 index 96b80deb..00000000 Binary files a/docs/pics/b6a7e8af-91bf-44b2-8874-ccc6d9d52afc.jpg and /dev/null differ diff --git a/docs/pics/b84ba6fb-312b-4e69-8c77-fb6eb6fb38d4.png b/docs/pics/b84ba6fb-312b-4e69-8c77-fb6eb6fb38d4.png deleted file mode 100644 index dc44da3d..00000000 Binary files a/docs/pics/b84ba6fb-312b-4e69-8c77-fb6eb6fb38d4.png and /dev/null differ diff --git a/docs/pics/bab0fba6-38e4-45f7-b34d-3edaad43810f.jpg b/docs/pics/bab0fba6-38e4-45f7-b34d-3edaad43810f.jpg deleted file mode 100644 index c3815f20..00000000 Binary files a/docs/pics/bab0fba6-38e4-45f7-b34d-3edaad43810f.jpg and /dev/null differ diff --git a/docs/pics/bc5826f5-014d-47b4-9a76-d86b80968643.jpg b/docs/pics/bc5826f5-014d-47b4-9a76-d86b80968643.jpg deleted file mode 100644 index b27cd02f..00000000 Binary files a/docs/pics/bc5826f5-014d-47b4-9a76-d86b80968643.jpg and /dev/null differ diff --git a/docs/pics/bc775758-89ab-4805-9f9c-78b8739cf780.jpg b/docs/pics/bc775758-89ab-4805-9f9c-78b8739cf780.jpg deleted file mode 100644 index 4cd6f60f..00000000 Binary files a/docs/pics/bc775758-89ab-4805-9f9c-78b8739cf780.jpg and /dev/null differ diff --git a/docs/pics/be772b17-2bfe-4393-9805-946b15666ecd_200.png b/docs/pics/be772b17-2bfe-4393-9805-946b15666ecd_200.png deleted file mode 100644 index 9147420b..00000000 Binary files a/docs/pics/be772b17-2bfe-4393-9805-946b15666ecd_200.png and /dev/null differ diff --git a/docs/pics/be7dca03-12ec-456b-8b54-b1b3161f5531.png b/docs/pics/be7dca03-12ec-456b-8b54-b1b3161f5531.png deleted file mode 100644 index 2c2214de..00000000 Binary files a/docs/pics/be7dca03-12ec-456b-8b54-b1b3161f5531.png and /dev/null differ diff --git a/docs/pics/bfbb11e2-d208-4efa-b97b-24cd40467cd8.png b/docs/pics/bfbb11e2-d208-4efa-b97b-24cd40467cd8.png deleted file mode 100644 index b9d9dba2..00000000 Binary files a/docs/pics/bfbb11e2-d208-4efa-b97b-24cd40467cd8.png and /dev/null differ diff --git a/docs/pics/c26e7ce3-dd9e-47e2-a208-367b5b2cddf6.png b/docs/pics/c26e7ce3-dd9e-47e2-a208-367b5b2cddf6.png deleted file mode 100644 index cf8d36dc..00000000 Binary files a/docs/pics/c26e7ce3-dd9e-47e2-a208-367b5b2cddf6.png and /dev/null differ diff --git a/docs/pics/c2c2b633-c03a-426e-b436-5719a194667b.png b/docs/pics/c2c2b633-c03a-426e-b436-5719a194667b.png deleted file mode 100644 index b673d4a7..00000000 Binary files a/docs/pics/c2c2b633-c03a-426e-b436-5719a194667b.png and /dev/null differ diff --git a/docs/pics/c2eae474-b43f-41ba-a3d1-b8a6a7373e54_200.png b/docs/pics/c2eae474-b43f-41ba-a3d1-b8a6a7373e54_200.png deleted file mode 100644 index fb313f2a..00000000 Binary files a/docs/pics/c2eae474-b43f-41ba-a3d1-b8a6a7373e54_200.png and /dev/null differ diff --git a/docs/pics/c3212a02-d010-4e62-834b-5dd26dfb5692.jpg b/docs/pics/c3212a02-d010-4e62-834b-5dd26dfb5692.jpg deleted file mode 100644 index 51bc514c..00000000 Binary files a/docs/pics/c3212a02-d010-4e62-834b-5dd26dfb5692.jpg and /dev/null differ diff --git a/docs/pics/c6fdb958-578d-4685-a5fa-400857be91d5.jpg b/docs/pics/c6fdb958-578d-4685-a5fa-400857be91d5.jpg deleted file mode 100644 index 895d1ed5..00000000 Binary files a/docs/pics/c6fdb958-578d-4685-a5fa-400857be91d5.jpg and /dev/null differ diff --git a/docs/pics/c7399ff9-bdfe-48d8-94fe-eff5704b94eb_200.png b/docs/pics/c7399ff9-bdfe-48d8-94fe-eff5704b94eb_200.png deleted file mode 100644 index 3fa5f898..00000000 Binary files a/docs/pics/c7399ff9-bdfe-48d8-94fe-eff5704b94eb_200.png and /dev/null differ diff --git a/docs/pics/c7875be7-fce5-43c7-ac77-d8dbe6c0ae1b.png b/docs/pics/c7875be7-fce5-43c7-ac77-d8dbe6c0ae1b.png deleted file mode 100644 index bbed020a..00000000 Binary files a/docs/pics/c7875be7-fce5-43c7-ac77-d8dbe6c0ae1b.png and /dev/null differ diff --git a/docs/pics/c80bbac0-72b3-4bd0-a63e-b9a11e88e1b6_200.png b/docs/pics/c80bbac0-72b3-4bd0-a63e-b9a11e88e1b6_200.png deleted file mode 100644 index 85ca8002..00000000 Binary files a/docs/pics/c80bbac0-72b3-4bd0-a63e-b9a11e88e1b6_200.png and /dev/null differ diff --git a/docs/pics/c847d6e4-3610-4f3c-a909-89a5048426e6.png b/docs/pics/c847d6e4-3610-4f3c-a909-89a5048426e6.png deleted file mode 100644 index 167c33bc..00000000 Binary files a/docs/pics/c847d6e4-3610-4f3c-a909-89a5048426e6.png and /dev/null differ diff --git a/docs/pics/cb5d2258-a60e-4364-94a7-3429a3064554_200.png b/docs/pics/cb5d2258-a60e-4364-94a7-3429a3064554_200.png deleted file mode 100644 index 7a7c702d..00000000 Binary files a/docs/pics/cb5d2258-a60e-4364-94a7-3429a3064554_200.png and /dev/null differ diff --git a/docs/pics/cb80b6f8-85bc-442c-979c-63f109311d1f_200.png b/docs/pics/cb80b6f8-85bc-442c-979c-63f109311d1f_200.png deleted file mode 100644 index e9e08037..00000000 Binary files a/docs/pics/cb80b6f8-85bc-442c-979c-63f109311d1f_200.png and /dev/null differ diff --git a/docs/pics/cbd5f6f6-18de-4711-9e01-0f94e66f81b8_200.png b/docs/pics/cbd5f6f6-18de-4711-9e01-0f94e66f81b8_200.png deleted file mode 100644 index 215d2c8d..00000000 Binary files a/docs/pics/cbd5f6f6-18de-4711-9e01-0f94e66f81b8_200.png and /dev/null differ diff --git a/docs/pics/cc1acfb8-c507-4194-b16a-33388bd1cf82_200.png b/docs/pics/cc1acfb8-c507-4194-b16a-33388bd1cf82_200.png deleted file mode 100644 index 8e016408..00000000 Binary files a/docs/pics/cc1acfb8-c507-4194-b16a-33388bd1cf82_200.png and /dev/null differ diff --git a/docs/pics/cf779e26-0382-4495-8463-f1e19e2e38a0.jpg b/docs/pics/cf779e26-0382-4495-8463-f1e19e2e38a0.jpg deleted file mode 100644 index b3699644..00000000 Binary files a/docs/pics/cf779e26-0382-4495-8463-f1e19e2e38a0.jpg and /dev/null differ diff --git a/docs/pics/class_loader_hierarchy.png b/docs/pics/class_loader_hierarchy.png deleted file mode 100644 index 6f4baf6f..00000000 Binary files a/docs/pics/class_loader_hierarchy.png and /dev/null differ diff --git a/docs/pics/d011c697-2551-4968-ac51-e5e01a954204.jpg b/docs/pics/d011c697-2551-4968-ac51-e5e01a954204.jpg deleted file mode 100644 index 4e723087..00000000 Binary files a/docs/pics/d011c697-2551-4968-ac51-e5e01a954204.jpg and /dev/null differ diff --git a/docs/pics/d0c1f611-3bc3-446d-8c0b-1b442b0ae8c91_200.png b/docs/pics/d0c1f611-3bc3-446d-8c0b-1b442b0ae8c91_200.png deleted file mode 100644 index cf9e1e83..00000000 Binary files a/docs/pics/d0c1f611-3bc3-446d-8c0b-1b442b0ae8c91_200.png and /dev/null differ diff --git a/docs/pics/d1e4c8aa-c5da-447e-b1c8-7359114cf977_200.png b/docs/pics/d1e4c8aa-c5da-447e-b1c8-7359114cf977_200.png deleted file mode 100644 index 6a699ad1..00000000 Binary files a/docs/pics/d1e4c8aa-c5da-447e-b1c8-7359114cf977_200.png and /dev/null differ diff --git a/docs/pics/d2a12961-2b36-4463-b017-ca46a3308b8e.png b/docs/pics/d2a12961-2b36-4463-b017-ca46a3308b8e.png deleted file mode 100644 index ce6663bc..00000000 Binary files a/docs/pics/d2a12961-2b36-4463-b017-ca46a3308b8e.png and /dev/null differ diff --git a/docs/pics/d546e754-a5b2-4132-be09-b991f163884b_200.png b/docs/pics/d546e754-a5b2-4132-be09-b991f163884b_200.png deleted file mode 100644 index c00db4e6..00000000 Binary files a/docs/pics/d546e754-a5b2-4132-be09-b991f163884b_200.png and /dev/null differ diff --git a/docs/pics/d5ce91a7-45f9-4560-9917-0dccd4900826.png b/docs/pics/d5ce91a7-45f9-4560-9917-0dccd4900826.png deleted file mode 100644 index 5a138b6f..00000000 Binary files a/docs/pics/d5ce91a7-45f9-4560-9917-0dccd4900826.png and /dev/null differ diff --git a/docs/pics/d5d3b7ae-2712-412e-98f1-633ce6ec5955.png b/docs/pics/d5d3b7ae-2712-412e-98f1-633ce6ec5955.png deleted file mode 100644 index 2dde7dab..00000000 Binary files a/docs/pics/d5d3b7ae-2712-412e-98f1-633ce6ec5955.png and /dev/null differ diff --git a/docs/pics/d95d04b7-896b-4bba-bb43-1a029ef14032.png b/docs/pics/d95d04b7-896b-4bba-bb43-1a029ef14032.png deleted file mode 100644 index 9c56b634..00000000 Binary files a/docs/pics/d95d04b7-896b-4bba-bb43-1a029ef14032.png and /dev/null differ diff --git a/docs/pics/db239936-1237-464a-bb5c-a8eefdd4c361.png b/docs/pics/db239936-1237-464a-bb5c-a8eefdd4c361.png deleted file mode 100644 index fdca0324..00000000 Binary files a/docs/pics/db239936-1237-464a-bb5c-a8eefdd4c361.png and /dev/null differ diff --git a/docs/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png b/docs/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png deleted file mode 100644 index 1ee66db8..00000000 Binary files a/docs/pics/dbb8516d-37ba-4e2c-b26b-eefd7de21b45.png and /dev/null differ diff --git a/docs/pics/dd15a984-e977-4644-b127-708cddb8ca99.png b/docs/pics/dd15a984-e977-4644-b127-708cddb8ca99.png deleted file mode 100644 index 4397e88e..00000000 Binary files a/docs/pics/dd15a984-e977-4644-b127-708cddb8ca99.png and /dev/null differ diff --git a/docs/pics/dd78a1fe-1ff3-4bcf-a56f-8c003995beb6.jpg b/docs/pics/dd78a1fe-1ff3-4bcf-a56f-8c003995beb6.jpg deleted file mode 100644 index 69f4dd05..00000000 Binary files a/docs/pics/dd78a1fe-1ff3-4bcf-a56f-8c003995beb6.jpg and /dev/null differ diff --git a/docs/pics/de2740c2-c1b5-413d-b6d5-9680d3485c02_200.png b/docs/pics/de2740c2-c1b5-413d-b6d5-9680d3485c02_200.png deleted file mode 100644 index 0f2d1c8d..00000000 Binary files a/docs/pics/de2740c2-c1b5-413d-b6d5-9680d3485c02_200.png and /dev/null differ diff --git a/docs/pics/de9d8133-4c98-4e07-b39c-302e162784ea.jpg b/docs/pics/de9d8133-4c98-4e07-b39c-302e162784ea.jpg deleted file mode 100644 index 4a923dd8..00000000 Binary files a/docs/pics/de9d8133-4c98-4e07-b39c-302e162784ea.jpg and /dev/null differ diff --git a/docs/pics/deb18bdb-b3b3-4660-b778-b0823a48db12.jpg b/docs/pics/deb18bdb-b3b3-4660-b778-b0823a48db12.jpg deleted file mode 100644 index 7746a715..00000000 Binary files a/docs/pics/deb18bdb-b3b3-4660-b778-b0823a48db12.jpg and /dev/null differ diff --git a/docs/pics/df01dbcd-4a3c-4877-86e8-5590d7589788.jpg b/docs/pics/df01dbcd-4a3c-4877-86e8-5590d7589788.jpg deleted file mode 100644 index d04e9f6f..00000000 Binary files a/docs/pics/df01dbcd-4a3c-4877-86e8-5590d7589788.jpg and /dev/null differ diff --git a/docs/pics/df247180-4d5c-4d4b-ab0f-1aec61d13d45.png b/docs/pics/df247180-4d5c-4d4b-ab0f-1aec61d13d45.png deleted file mode 100644 index ef5b780f..00000000 Binary files a/docs/pics/df247180-4d5c-4d4b-ab0f-1aec61d13d45.png and /dev/null differ diff --git a/docs/pics/e026c24d-00fa-4e7c-97a8-95a98cdc383a.png b/docs/pics/e026c24d-00fa-4e7c-97a8-95a98cdc383a.png deleted file mode 100644 index 427cfbf8..00000000 Binary files a/docs/pics/e026c24d-00fa-4e7c-97a8-95a98cdc383a.png and /dev/null differ diff --git a/docs/pics/e19452dd-220a-4a6b-bcb0-91ad5e5c4706.png b/docs/pics/e19452dd-220a-4a6b-bcb0-91ad5e5c4706.png deleted file mode 100644 index c21e9af2..00000000 Binary files a/docs/pics/e19452dd-220a-4a6b-bcb0-91ad5e5c4706.png and /dev/null differ diff --git a/docs/pics/e2d2d90f-95eb-4877-9d36-99d7b93695de_200.png b/docs/pics/e2d2d90f-95eb-4877-9d36-99d7b93695de_200.png deleted file mode 100644 index a7c1778d..00000000 Binary files a/docs/pics/e2d2d90f-95eb-4877-9d36-99d7b93695de_200.png and /dev/null differ diff --git a/docs/pics/e2f0d889-2330-424c-8193-198edebecff7.png b/docs/pics/e2f0d889-2330-424c-8193-198edebecff7.png deleted file mode 100644 index d747d6f3..00000000 Binary files a/docs/pics/e2f0d889-2330-424c-8193-198edebecff7.png and /dev/null differ diff --git a/docs/pics/e31abb94-9201-4e06-9902-61101b92f475.png b/docs/pics/e31abb94-9201-4e06-9902-61101b92f475.png deleted file mode 100644 index 90833a5c..00000000 Binary files a/docs/pics/e31abb94-9201-4e06-9902-61101b92f475.png and /dev/null differ diff --git a/docs/pics/e3360fa0-680e-486b-945f-09ff5d8612e4.png b/docs/pics/e3360fa0-680e-486b-945f-09ff5d8612e4.png deleted file mode 100644 index 118096b7..00000000 Binary files a/docs/pics/e3360fa0-680e-486b-945f-09ff5d8612e4.png and /dev/null differ diff --git a/docs/pics/e3b53605-0c10-4a7e-be02-a9064778f8a5.png b/docs/pics/e3b53605-0c10-4a7e-be02-a9064778f8a5.png deleted file mode 100644 index a8e7e538..00000000 Binary files a/docs/pics/e3b53605-0c10-4a7e-be02-a9064778f8a5.png and /dev/null differ diff --git a/docs/pics/e4047473-a274-44d7-809a-c7312f52b55f.jpg b/docs/pics/e4047473-a274-44d7-809a-c7312f52b55f.jpg deleted file mode 100644 index b28765c5..00000000 Binary files a/docs/pics/e4047473-a274-44d7-809a-c7312f52b55f.jpg and /dev/null differ diff --git a/docs/pics/e49b6fe9-5ad7-4fe9-975d-dceb10ffe5b4_200.png b/docs/pics/e49b6fe9-5ad7-4fe9-975d-dceb10ffe5b4_200.png deleted file mode 100644 index dc4aa6cc..00000000 Binary files a/docs/pics/e49b6fe9-5ad7-4fe9-975d-dceb10ffe5b4_200.png and /dev/null differ diff --git a/docs/pics/e6b733ad-606d-4028-b3e8-83c3a73a3797.jpg b/docs/pics/e6b733ad-606d-4028-b3e8-83c3a73a3797.jpg deleted file mode 100644 index 8eda7a0a..00000000 Binary files a/docs/pics/e6b733ad-606d-4028-b3e8-83c3a73a3797.jpg and /dev/null differ diff --git a/docs/pics/e8454537-5a0c-49a2-8304-abae0b8887e1_200.png b/docs/pics/e8454537-5a0c-49a2-8304-abae0b8887e1_200.png deleted file mode 100644 index 89ce5c64..00000000 Binary files a/docs/pics/e8454537-5a0c-49a2-8304-abae0b8887e1_200.png and /dev/null differ diff --git a/docs/pics/ea2304ce-268b-4238-9486-4d8f8aea8ca4.png b/docs/pics/ea2304ce-268b-4238-9486-4d8f8aea8ca4.png deleted file mode 100644 index 59b54d2f..00000000 Binary files a/docs/pics/ea2304ce-268b-4238-9486-4d8f8aea8ca4.png and /dev/null differ diff --git a/docs/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png b/docs/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png deleted file mode 100644 index a54c85e1..00000000 Binary files a/docs/pics/ef280699-da36-4b38-9735-9b048a3c7fe0.png and /dev/null differ diff --git a/docs/pics/ef8eab00-1d5e-4d99-a7c2-d6d68ea7fe92.png b/docs/pics/ef8eab00-1d5e-4d99-a7c2-d6d68ea7fe92.png deleted file mode 100644 index f6256867..00000000 Binary files a/docs/pics/ef8eab00-1d5e-4d99-a7c2-d6d68ea7fe92.png and /dev/null differ diff --git a/docs/pics/efc60f47-1d6c-4610-87d4-5db168c77b02.gif b/docs/pics/efc60f47-1d6c-4610-87d4-5db168c77b02.gif deleted file mode 100644 index 305bc682..00000000 Binary files a/docs/pics/efc60f47-1d6c-4610-87d4-5db168c77b02.gif and /dev/null differ diff --git a/docs/pics/f1ff65ed-bbc2-4b92-8a94-7c5c0874da0f.jpg b/docs/pics/f1ff65ed-bbc2-4b92-8a94-7c5c0874da0f.jpg deleted file mode 100644 index 4308e4c9..00000000 Binary files a/docs/pics/f1ff65ed-bbc2-4b92-8a94-7c5c0874da0f.jpg and /dev/null differ diff --git a/docs/pics/f3080f83-6239-459b-8e9c-03b6641f7815.png b/docs/pics/f3080f83-6239-459b-8e9c-03b6641f7815.png deleted file mode 100644 index 77868686..00000000 Binary files a/docs/pics/f3080f83-6239-459b-8e9c-03b6641f7815.png and /dev/null differ diff --git a/docs/pics/f42443e0-208d-41ea-be44-c7fd97d2e3bf.png b/docs/pics/f42443e0-208d-41ea-be44-c7fd97d2e3bf.png deleted file mode 100644 index 4a5dbd1d..00000000 Binary files a/docs/pics/f42443e0-208d-41ea-be44-c7fd97d2e3bf.png and /dev/null differ diff --git a/docs/pics/f5477abd-c246-4851-89ab-6b1cde2549b1.png b/docs/pics/f5477abd-c246-4851-89ab-6b1cde2549b1.png deleted file mode 100644 index f358a009..00000000 Binary files a/docs/pics/f5477abd-c246-4851-89ab-6b1cde2549b1.png and /dev/null differ diff --git a/docs/pics/f5cd51c9-df11-4b6a-b250-f13a9151555832287464.png b/docs/pics/f5cd51c9-df11-4b6a-b250-f13a9151555832287464.png deleted file mode 100644 index 4fa7bd2c..00000000 Binary files a/docs/pics/f5cd51c9-df11-4b6a-b250-f13a9151555832287464.png and /dev/null differ diff --git a/docs/pics/f5d40b01-abf2-435e-9ce7-7889c41b2fa6.jpg b/docs/pics/f5d40b01-abf2-435e-9ce7-7889c41b2fa6.jpg deleted file mode 100644 index 46e9f0f8..00000000 Binary files a/docs/pics/f5d40b01-abf2-435e-9ce7-7889c41b2fa6.jpg and /dev/null differ diff --git a/docs/pics/f5dbd360-a66c-4a40-8c56-6ffbcb0a8cc9_200.png b/docs/pics/f5dbd360-a66c-4a40-8c56-6ffbcb0a8cc9_200.png deleted file mode 100644 index 71293085..00000000 Binary files a/docs/pics/f5dbd360-a66c-4a40-8c56-6ffbcb0a8cc9_200.png and /dev/null differ diff --git a/docs/pics/f76067a5-7d5f-4135-9549-8199c77d8f1c.jpg b/docs/pics/f76067a5-7d5f-4135-9549-8199c77d8f1c.jpg deleted file mode 100644 index d710e659..00000000 Binary files a/docs/pics/f76067a5-7d5f-4135-9549-8199c77d8f1c.jpg and /dev/null differ diff --git a/docs/pics/f77f06b6-7359-4066-b85d-3f6c09ddf425.jpg b/docs/pics/f77f06b6-7359-4066-b85d-3f6c09ddf425.jpg deleted file mode 100644 index 9fc2a271..00000000 Binary files a/docs/pics/f77f06b6-7359-4066-b85d-3f6c09ddf425.jpg and /dev/null differ diff --git a/docs/pics/f7f7e3e5-7dd4-4173-9999-576b9e2ac0a2.png b/docs/pics/f7f7e3e5-7dd4-4173-9999-576b9e2ac0a2.png deleted file mode 100644 index b85accf6..00000000 Binary files a/docs/pics/f7f7e3e5-7dd4-4173-9999-576b9e2ac0a2.png and /dev/null differ diff --git a/docs/pics/f8047846-efd4-42be-b6b7-27a7c4998b51.png b/docs/pics/f8047846-efd4-42be-b6b7-27a7c4998b51.png deleted file mode 100644 index 86e2294f..00000000 Binary files a/docs/pics/f8047846-efd4-42be-b6b7-27a7c4998b51.png and /dev/null differ diff --git a/docs/pics/f944fac3-482b-4ca3-9447-17aec4a3cca0.png b/docs/pics/f944fac3-482b-4ca3-9447-17aec4a3cca0.png deleted file mode 100644 index 56f05611..00000000 Binary files a/docs/pics/f944fac3-482b-4ca3-9447-17aec4a3cca0.png and /dev/null differ diff --git a/docs/pics/f9f9f993-8ece-4da7-b848-af9b438fad76.png b/docs/pics/f9f9f993-8ece-4da7-b848-af9b438fad76.png deleted file mode 100644 index 824904db..00000000 Binary files a/docs/pics/f9f9f993-8ece-4da7-b848-af9b438fad76.png and /dev/null differ diff --git a/docs/pics/fa1dc552-8501-439e-b85a-3d9eac704880_200.png b/docs/pics/fa1dc552-8501-439e-b85a-3d9eac704880_200.png deleted file mode 100644 index 2142bbb5..00000000 Binary files a/docs/pics/fa1dc552-8501-439e-b85a-3d9eac704880_200.png and /dev/null differ diff --git a/docs/pics/fa568fac-ac58-48dd-a9bb-23b3065bf2dc.png b/docs/pics/fa568fac-ac58-48dd-a9bb-23b3065bf2dc.png deleted file mode 100644 index 736a2861..00000000 Binary files a/docs/pics/fa568fac-ac58-48dd-a9bb-23b3065bf2dc.png and /dev/null differ diff --git a/docs/pics/fac3dfd6-1656-4329-9a80-7f6c51ef30c5_200.png b/docs/pics/fac3dfd6-1656-4329-9a80-7f6c51ef30c5_200.png deleted file mode 100644 index 31ae3277..00000000 Binary files a/docs/pics/fac3dfd6-1656-4329-9a80-7f6c51ef30c5_200.png and /dev/null differ diff --git a/docs/pics/fb546e12-e1fb-4b72-a1fb-8a7f5000dce6.jpg b/docs/pics/fb546e12-e1fb-4b72-a1fb-8a7f5000dce6.jpg deleted file mode 100644 index e15f11db..00000000 Binary files a/docs/pics/fb546e12-e1fb-4b72-a1fb-8a7f5000dce6.jpg and /dev/null differ diff --git a/docs/pics/fbe54203-c005-48f0-8883-b05e564a3173.png b/docs/pics/fbe54203-c005-48f0-8883-b05e564a3173.png deleted file mode 100644 index dee6a88d..00000000 Binary files a/docs/pics/fbe54203-c005-48f0-8883-b05e564a3173.png and /dev/null differ diff --git a/docs/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png b/docs/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png deleted file mode 100644 index 4eaa11ba..00000000 Binary files a/docs/pics/ff396233-1bb1-4e74-8bc2-d7c90146f5dd.png and /dev/null differ diff --git a/docs/pics/ff5b89ac-798e-4fbc-b0ce-da2fc2358570.jpg b/docs/pics/ff5b89ac-798e-4fbc-b0ce-da2fc2358570.jpg deleted file mode 100644 index 1fa40320..00000000 Binary files a/docs/pics/ff5b89ac-798e-4fbc-b0ce-da2fc2358570.jpg and /dev/null differ diff --git a/docs/pics/ff8812b2-77e8-4bca-b427-4336e0e75af3_200.png b/docs/pics/ff8812b2-77e8-4bca-b427-4336e0e75af3_200.png deleted file mode 100644 index 9a8d4079..00000000 Binary files a/docs/pics/ff8812b2-77e8-4bca-b427-4336e0e75af3_200.png and /dev/null differ diff --git a/docs/pics/ff98a336-a390-4d1c-adea-0a49e72fad82_200.png b/docs/pics/ff98a336-a390-4d1c-adea-0a49e72fad82_200.png deleted file mode 100644 index 9a252111..00000000 Binary files a/docs/pics/ff98a336-a390-4d1c-adea-0a49e72fad82_200.png and /dev/null differ diff --git a/docs/pics/monitor-lock-rule.png b/docs/pics/monitor-lock-rule.png deleted file mode 100644 index 6590d94b..00000000 Binary files a/docs/pics/monitor-lock-rule.png and /dev/null differ diff --git a/docs/pics/single-thread-rule.png b/docs/pics/single-thread-rule.png deleted file mode 100644 index d6583e9e..00000000 Binary files a/docs/pics/single-thread-rule.png and /dev/null differ diff --git a/docs/pics/thread-join-rule.png b/docs/pics/thread-join-rule.png deleted file mode 100644 index c17d0456..00000000 Binary files a/docs/pics/thread-join-rule.png and /dev/null differ diff --git a/docs/pics/thread-start-rule.png b/docs/pics/thread-start-rule.png deleted file mode 100644 index 60ee7862..00000000 Binary files a/docs/pics/thread-start-rule.png and /dev/null differ diff --git a/docs/pics/volatile-variable-rule.png b/docs/pics/volatile-variable-rule.png deleted file mode 100644 index 1747664b..00000000 Binary files a/docs/pics/volatile-variable-rule.png and /dev/null differ diff --git a/notes/Docker.md b/notes/Docker.md new file mode 100644 index 00000000..9e1f2f67 --- /dev/null +++ b/notes/Docker.md @@ -0,0 +1,95 @@ + +* [一、解决的问题](#一解决的问题) +* [二、与虚拟机的比较](#二与虚拟机的比较) +* [三、优势](#三优势) +* [四、使用场景](#四使用场景) +* [五、镜像与容器](#五镜像与容器) +* [参考资料](#参考资料) + + + +# 一、解决的问题 + +由于不同的机器有不同的操作系统,以及不同的库和组件,在将一个应用部署到多台机器上需要进行大量的环境配置操作。 + +Docker 主要解决环境配置问题,它是一种虚拟化技术,对进程进行隔离,被隔离的进程独立于宿主操作系统和其它隔离的进程。使用 Docker 可以不修改应用程序代码,不需要开发人员学习特定环境下的技术,就能够将现有的应用程序部署在其它机器上。 + +

+ +# 二、与虚拟机的比较 + +虚拟机也是一种虚拟化技术,它与 Docker 最大的区别在于它是通过模拟硬件,并在硬件上安装操作系统来实现。 + +

+ +## 启动速度 + +启动虚拟机需要先启动虚拟机的操作系统,再启动应用,这个过程非常慢; + +而启动 Docker 相当于启动宿主操作系统上的一个进程。 + +## 占用资源 + +虚拟机是一个完整的操作系统,需要占用大量的磁盘、内存和 CPU 资源,一台机器只能开启几十个的虚拟机。 + +而 Docker 只是一个进程,只需要将应用以及相关的组件打包,在运行时占用很少的资源,一台机器可以开启成千上万个 Docker。 + +# 三、优势 + +除了启动速度快以及占用资源少之外,Docker 具有以下优势: + +## 更容易迁移 + +提供一致性的运行环境。已经打包好的应用可以在不同的机器上进行迁移,而不用担心环境变化导致无法运行。 + +## 更容易维护 + +使用分层技术和镜像,使得应用可以更容易复用重复的部分。复用程度越高,维护工作也越容易。 + +## 更容易扩展 + +可以使用基础镜像进一步扩展得到新的镜像,并且官方和开源社区提供了大量的镜像,通过扩展这些镜像可以非常容易得到我们想要的镜像。 + +# 四、使用场景 + +## 持续集成 + +持续集成指的是频繁地将代码集成到主干上,这样能够更快地发现错误。 + +Docker 具有轻量级以及隔离性的特点,在将代码集成到一个 Docker 中不会对其它 Docker 产生影响。 + +## 提供可伸缩的云服务 + +根据应用的负载情况,可以很容易地增加或者减少 Docker。 + +## 搭建微服务架构 + +Docker 轻量级的特点使得它很适合用于部署、维护、组合微服务。 + +# 五、镜像与容器 + +镜像是一种静态的结构,可以看成面向对象里面的类,而容器是镜像的一个实例。 + +镜像包含着容器运行时所需要的代码以及其它组件,它是一种分层结构,每一层都是只读的(read-only layers)。构建镜像时,会一层一层构建,前一层是后一层的基础。镜像的这种分层存储结构很适合镜像的复用以及定制。 + +构建容器时,通过在镜像的基础上添加一个可写层(writable layer),用来保存着容器运行过程中的修改。 + +

+ +# 参考资料 + +- [DOCKER 101: INTRODUCTION TO DOCKER WEBINAR RECAP](https://blog.docker.com/2017/08/docker-101-introduction-docker-webinar-recap/) +- [Docker 入门教程](http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html) +- [Docker container vs Virtual machine](http://www.bogotobogo.com/DevOps/Docker/Docker_Container_vs_Virtual_Machine.php) +- [How to Create Docker Container using Dockerfile](https://linoxide.com/linux-how-to/dockerfile-create-docker-container/) +- [理解 Docker(2):Docker 镜像](http://www.cnblogs.com/sammyliu/p/5877964.html) +- [为什么要使用 Docker?](https://yeasy.gitbooks.io/docker_practice/introduction/why.html) +- [What is Docker](https://www.docker.com/what-docker) +- [持续集成是什么?](http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html) + + + + + +
🎨️欢迎关注我的公众号 CyC2018,在公众号后台回复关键字 **资料** 可领取复习大纲,这份大纲是我花了一整年时间整理的面试知识点列表,不仅系统整理了面试知识点,而且标注了各个知识点的重要程度,从而帮你理清多而杂的面试知识点。可以说我基本是按照这份大纲来进行复习的,这份大纲对我拿到了 BAT 头条等 Offer 起到很大的帮助。你们完全可以和我一样根据大纲上列的知识点来进行复习,就不用看很多不重要的内容,也可以知道哪些内容很重要从而多安排一些复习时间。

+
diff --git a/notes/Git.md b/notes/Git.md new file mode 100644 index 00000000..cd2e1acc --- /dev/null +++ b/notes/Git.md @@ -0,0 +1,166 @@ + +* [集中式与分布式](#集中式与分布式) +* [中心服务器](#中心服务器) +* [工作流](#工作流) +* [分支实现](#分支实现) +* [冲突](#冲突) +* [Fast forward](#fast-forward) +* [分支管理策略](#分支管理策略) +* [储藏(Stashing)](#储藏stashing) +* [SSH 传输设置](#ssh-传输设置) +* [.gitignore 文件](#gitignore-文件) +* [Git 命令一览](#git-命令一览) +* [参考资料](#参考资料) + + + +# 集中式与分布式 + +Git 属于分布式版本控制系统,而 SVN 属于集中式。 + +

+ +集中式版本控制只有中心服务器拥有一份代码,而分布式版本控制每个人的电脑上就有一份完整的代码。 + +集中式版本控制有安全性问题,当中心服务器挂了所有人都没办法工作了。 + +集中式版本控制需要连网才能工作,如果网速过慢,那么提交一个文件的会慢的无法让人忍受。而分布式版本控制不需要连网就能工作。 + +分布式版本控制新建分支、合并分支操作速度非常快,而集中式版本控制新建一个分支相当于复制一份完整代码。 + +# 中心服务器 + +中心服务器用来交换每个用户的修改,没有中心服务器也能工作,但是中心服务器能够 24 小时保持开机状态,这样就能更方便的交换修改。 + +Github 就是一个中心服务器。 + +# 工作流 + +新建一个仓库之后,当前目录就成为了工作区,工作区下有一个隐藏目录 .git,它属于 Git 的版本库。 + +Git 的版本库有一个称为 Stage 的暂存区以及最后的 History 版本库,History 中存有所有分支,使用一个 HEAD 指针指向当前分支。 + +

+ +- git add files 把文件的修改添加到暂存区 +- git commit 把暂存区的修改提交到当前分支,提交之后暂存区就被清空了 +- git reset -- files 使用当前分支上的修改覆盖暂存区,用来撤销最后一次 git add files +- git checkout -- files 使用暂存区的修改覆盖工作目录,用来撤销本地修改 + +

+ +可以跳过暂存区域直接从分支中取出修改,或者直接提交修改到分支中。 + +- git commit -a 直接把所有文件的修改添加到暂存区然后执行提交 +- git checkout HEAD -- files 取出最后一次修改,可以用来进行回滚操作 + +

+ +# 分支实现 + +使用指针将每个提交连接成一条时间线,HEAD 指针指向当前分支指针。 + +

+ +新建分支是新建一个指针指向时间线的最后一个节点,并让 HEAD 指针指向新分支表示新分支成为当前分支。 + +

+ +每次提交只会让当前分支指针向前移动,而其它分支指针不会移动。 + +

+ +合并分支也只需要改变指针即可。 + +

+ +# 冲突 + +当两个分支都对同一个文件的同一行进行了修改,在分支合并时就会产生冲突。 + +

+ +Git 会使用 <<<<<<< ,======= ,>>>>>>> 标记出不同分支的内容,只需要把不同分支中冲突部分修改成一样就能解决冲突。 + +``` +<<<<<<< HEAD +Creating a new branch is quick & simple. +======= +Creating a new branch is quick AND simple. +>>>>>>> feature1 +``` + +# Fast forward + +"快进式合并"(fast-farward merge),会直接将 master 分支指向合并的分支,这种模式下进行分支合并会丢失分支信息,也就不能在分支历史上看出分支信息。 + +可以在合并时加上 --no-ff 参数来禁用 Fast forward 模式,并且加上 -m 参数让合并时产生一个新的 commit。 + +``` +$ git merge --no-ff -m "merge with no-ff" dev +``` + +

+ +# 分支管理策略 + +master 分支应该是非常稳定的,只用来发布新版本; + +日常开发在开发分支 dev 上进行。 + +

+ +# 储藏(Stashing) + +在一个分支上操作之后,如果还没有将修改提交到分支上,此时进行切换分支,那么另一个分支上也能看到新的修改。这是因为所有分支都共用一个工作区的缘故。 + +可以使用 git stash 将当前分支的修改储藏起来,此时当前工作区的所有修改都会被存到栈上,也就是说当前工作区是干净的,没有任何未提交的修改。此时就可以安全的切换到其它分支上了。 + +``` +$ git stash +Saved working directory and index state \ "WIP on master: 049d078 added the index file" +HEAD is now at 049d078 added the index file (To restore them type "git stash apply") +``` + +该功能可以用于 bug 分支的实现。如果当前正在 dev 分支上进行开发,但是此时 master 上有个 bug 需要修复,但是 dev 分支上的开发还未完成,不想立即提交。在新建 bug 分支并切换到 bug 分支之前就需要使用 git stash 将 dev 分支的未提交修改储藏起来。 + +# SSH 传输设置 + +Git 仓库和 Github 中心仓库之间的传输是通过 SSH 加密。 + +如果工作区下没有 .ssh 目录,或者该目录下没有 id_rsa 和 id_rsa.pub 这两个文件,可以通过以下命令来创建 SSH Key: + +``` +$ ssh-keygen -t rsa -C "youremail@example.com" +``` + +然后把公钥 id_rsa.pub 的内容复制到 Github "Account settings" 的 SSH Keys 中。 + +# .gitignore 文件 + +忽略以下文件: + +- 操作系统自动生成的文件,比如缩略图; +- 编译生成的中间文件,比如 Java 编译产生的 .class 文件; +- 自己的敏感信息,比如存放口令的配置文件。 + +不需要全部自己编写,可以到 [https://github.com/github/gitignore](https://github.com/github/gitignore) 中进行查询。 + +# Git 命令一览 + +

+ +比较详细的地址:http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf + +# 参考资料 + +- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html) +- [图解 Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) +- [廖雪峰 : Git 教程](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000) +- [Learn Git Branching](https://learngitbranching.js.org/) + + + + +
🎨️欢迎关注我的公众号 CyC2018,在公众号后台回复关键字 **资料** 可领取复习大纲,这份大纲是我花了一整年时间整理的面试知识点列表,不仅系统整理了面试知识点,而且标注了各个知识点的重要程度,从而帮你理清多而杂的面试知识点。可以说我基本是按照这份大纲来进行复习的,这份大纲对我拿到了 BAT 头条等 Offer 起到很大的帮助。你们完全可以和我一样根据大纲上列的知识点来进行复习,就不用看很多不重要的内容,也可以知道哪些内容很重要从而多安排一些复习时间。

+
diff --git a/notes/HTTP.md b/notes/HTTP.md new file mode 100644 index 00000000..fc0c50e3 --- /dev/null +++ b/notes/HTTP.md @@ -0,0 +1,885 @@ + +* [一 、基础概念](#一-基础概念) + * [URI](#uri) + * [请求和响应报文](#请求和响应报文) +* [二、HTTP 方法](#二http-方法) + * [GET](#get) + * [HEAD](#head) + * [POST](#post) + * [PUT](#put) + * [PATCH](#patch) + * [DELETE](#delete) + * [OPTIONS](#options) + * [CONNECT](#connect) + * [TRACE](#trace) +* [三、HTTP 状态码](#三http-状态码) + * [1XX 信息](#1xx-信息) + * [2XX 成功](#2xx-成功) + * [3XX 重定向](#3xx-重定向) + * [4XX 客户端错误](#4xx-客户端错误) + * [5XX 服务器错误](#5xx-服务器错误) +* [四、HTTP 首部](#四http-首部) + * [通用首部字段](#通用首部字段) + * [请求首部字段](#请求首部字段) + * [响应首部字段](#响应首部字段) + * [实体首部字段](#实体首部字段) +* [五、具体应用](#五具体应用) + * [连接管理](#连接管理) + * [Cookie](#cookie) + * [缓存](#缓存) + * [内容协商](#内容协商) + * [内容编码](#内容编码) + * [范围请求](#范围请求) + * [分块传输编码](#分块传输编码) + * [多部分对象集合](#多部分对象集合) + * [虚拟主机](#虚拟主机) + * [通信数据转发](#通信数据转发) +* [六、HTTPS](#六https) + * [加密](#加密) + * [认证](#认证) + * [完整性保护](#完整性保护) + * [HTTPS 的缺点](#https-的缺点) +* [七、HTTP/2.0](#七http20) + * [HTTP/1.x 缺陷](#http1x-缺陷) + * [二进制分帧层](#二进制分帧层) + * [服务端推送](#服务端推送) + * [首部压缩](#首部压缩) +* [八、HTTP/1.1 新特性](#八http11-新特性) +* [九、GET 和 POST 比较](#九get-和-post-比较) + * [作用](#作用) + * [参数](#参数) + * [安全](#安全) + * [幂等性](#幂等性) + * [可缓存](#可缓存) + * [XMLHttpRequest](#xmlhttprequest) +* [参考资料](#参考资料) + + + +# 一 、基础概念 + +## URI + +URI 包含 URL 和 URN。 + +

+ +## 请求和响应报文 + +### 1. 请求报文 + +

+ +### 2. 响应报文 + +

+ +# 二、HTTP 方法 + +客户端发送的 **请求报文** 第一行为请求行,包含了方法字段。 + +## GET + +> 获取资源 + +当前网络请求中,绝大部分使用的是 GET 方法。 + +## HEAD + +> 获取报文首部 + +和 GET 方法类似,但是不返回报文实体主体部分。 + +主要用于确认 URL 的有效性以及资源更新的日期时间等。 + +## POST + +> 传输实体主体 + +POST 主要用来传输数据,而 GET 主要用来获取资源。 + +更多 POST 与 GET 的比较请见第九章。 + +## PUT + +> 上传文件 + +由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。 + +```html +PUT /new.html HTTP/1.1 +Host: example.com +Content-type: text/html +Content-length: 16 + +

New File

+``` + +## PATCH + +> 对资源进行部分修改 + +PUT 也可以用于修改资源,但是只能完全替代原始资源,PATCH 允许部分修改。 + +```html +PATCH /file.txt HTTP/1.1 +Host: www.example.com +Content-Type: application/example +If-Match: "e0023aa4e" +Content-Length: 100 + +[description of changes] +``` + +## DELETE + +> 删除文件 + +与 PUT 功能相反,并且同样不带验证机制。 + +```html +DELETE /file.html HTTP/1.1 +``` + +## OPTIONS + +> 查询支持的方法 + +查询指定的 URL 能够支持的方法。 + +会返回 `Allow: GET, POST, HEAD, OPTIONS` 这样的内容。 + +## CONNECT + +> 要求在与代理服务器通信时建立隧道 + +使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。 + +```html +CONNECT www.example.com:443 HTTP/1.1 +``` + +

+ +## TRACE + +> 追踪路径 + +服务器会将通信路径返回给客户端。 + +发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器就会减 1,当数值为 0 时就停止传输。 + +通常不会使用 TRACE,并且它容易受到 XST 攻击(Cross-Site Tracing,跨站追踪)。 + +# 三、HTTP 状态码 + +服务器返回的 **响应报文** 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。 + +| 状态码 | 类别 | 含义 | +| :---: | :---: | :---: | +| 1XX | Informational(信息性状态码) | 接收的请求正在处理 | +| 2XX | Success(成功状态码) | 请求正常处理完毕 | +| 3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 | +| 4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 | +| 5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 | + +## 1XX 信息 + +- **100 Continue** :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。 + +## 2XX 成功 + +- **200 OK** + +- **204 No Content** :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。 + +- **206 Partial Content** :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。 + +## 3XX 重定向 + +- **301 Moved Permanently** :永久性重定向 + +- **302 Found** :临时性重定向 + +- **303 See Other** :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。 + +- 注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在 301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法。 + +- **304 Not Modified** :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。 + +- **307 Temporary Redirect** :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。 + +## 4XX 客户端错误 + +- **400 Bad Request** :请求报文中存在语法错误。 + +- **401 Unauthorized** :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。 + +- **403 Forbidden** :请求被拒绝。 + +- **404 Not Found** + +## 5XX 服务器错误 + +- **500 Internal Server Error** :服务器正在执行请求时发生错误。 + +- **503 Service Unavailable** :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 + +# 四、HTTP 首部 + +有 4 种类型的首部字段:通用首部字段、请求首部字段、响应首部字段和实体首部字段。 + +各种首部字段及其含义如下(不需要全记,仅供查阅): + +## 通用首部字段 + +| 首部字段名 | 说明 | +| :--: | :--: | +| Cache-Control | 控制缓存的行为 | +| Connection | 控制不再转发给代理的首部字段、管理持久连接| +| Date | 创建报文的日期时间 | +| Pragma | 报文指令 | +| Trailer | 报文末端的首部一览 | +| Transfer-Encoding | 指定报文主体的传输编码方式 | +| Upgrade | 升级为其他协议 | +| Via | 代理服务器的相关信息 | +| Warning | 错误通知 | + +## 请求首部字段 + +| 首部字段名 | 说明 | +| :--: | :--: | +| Accept | 用户代理可处理的媒体类型 | +| Accept-Charset | 优先的字符集 | +| Accept-Encoding | 优先的内容编码 | +| Accept-Language | 优先的语言(自然语言) | +| Authorization | Web 认证信息 | +| Expect | 期待服务器的特定行为 | +| From | 用户的电子邮箱地址 | +| Host | 请求资源所在服务器 | +| If-Match | 比较实体标记(ETag) | +| If-Modified-Since | 比较资源的更新时间 | +| If-None-Match | 比较实体标记(与 If-Match 相反) | +| If-Range | 资源未更新时发送实体 Byte 的范围请求 | +| If-Unmodified-Since | 比较资源的更新时间(与 If-Modified-Since 相反) | +| Max-Forwards | 最大传输逐跳数 | +| Proxy-Authorization | 代理服务器要求客户端的认证信息 | +| Range | 实体的字节范围请求 | +| Referer | 对请求中 URI 的原始获取方 | +| TE | 传输编码的优先级 | +| User-Agent | HTTP 客户端程序的信息 | + +## 响应首部字段 + +| 首部字段名 | 说明 | +| :--: | :--: | +| Accept-Ranges | 是否接受字节范围请求 | +| Age | 推算资源创建经过时间 | +| ETag | 资源的匹配信息 | +| Location | 令客户端重定向至指定 URI | +| Proxy-Authenticate | 代理服务器对客户端的认证信息 | +| Retry-After | 对再次发起请求的时机要求 | +| Server | HTTP 服务器的安装信息 | +| Vary | 代理服务器缓存的管理信息 | +| WWW-Authenticate | 服务器对客户端的认证信息 | + +## 实体首部字段 + +| 首部字段名 | 说明 | +| :--: | :--: | +| Allow | 资源可支持的 HTTP 方法 | +| Content-Encoding | 实体主体适用的编码方式 | +| Content-Language | 实体主体的自然语言 | +| Content-Length | 实体主体的大小 | +| Content-Location | 替代对应资源的 URI | +| Content-MD5 | 实体主体的报文摘要 | +| Content-Range | 实体主体的位置范围 | +| Content-Type | 实体主体的媒体类型 | +| Expires | 实体主体过期的日期时间 | +| Last-Modified | 资源的最后修改日期时间 | + +# 五、具体应用 + +## 连接管理 + +

+ +### 1. 短连接与长连接 + +当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问 HTML 页面资源,还会请求图片资源。如果每进行一次 HTTP 通信就要新建一个 TCP 连接,那么开销会很大。 + +长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。 + +- 从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 `Connection : close`; +- 在 HTTP/1.1 之前默认是短连接的,如果需要使用长连接,则使用 `Connection : Keep-Alive`。 + +### 2. 流水线 + +默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到响应之后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。 + +流水线是在同一条长连接上发出连续的请求,而不用等待响应返回,这样可以避免连接延迟。 + +## Cookie + +HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务。HTTP/1.1 引入 Cookie 来保存状态信息。 + +Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。 + +Cookie 曾一度用于客户端数据的存储,因为当时并没有其它合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie 渐渐被淘汰。新的浏览器 API 已经允许开发者直接将数据存储到本地,如使用 Web storage API(本地存储和会话存储)或 IndexedDB。 + +### 1. 用途 + +- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息) +- 个性化设置(如用户自定义设置、主题等) +- 浏览器行为跟踪(如跟踪分析用户行为等) + +### 2. 创建过程 + +服务器发送的响应报文包含 Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。 + +```html +HTTP/1.0 200 OK +Content-type: text/html +Set-Cookie: yummy_cookie=choco +Set-Cookie: tasty_cookie=strawberry + +[page content] +``` + +客户端之后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并通过 Cookie 请求首部字段发送给服务器。 + +```html +GET /sample_page.html HTTP/1.1 +Host: www.example.org +Cookie: yummy_cookie=choco; tasty_cookie=strawberry +``` + +### 3. 分类 + +- 会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。 +- 持久性 Cookie:指定一个特定的过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie。 + +```html +Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; +``` + +### 4. 作用域 + +Domain 标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了 Domain,则一般包含子域名。例如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如 developer.mozilla.org)。 + +Path 标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中)。以字符 %x2F ("/") 作为路径分隔符,子路径也会被匹配。例如,设置 Path=/docs,则以下地址都会匹配: + +- /docs +- /docs/Web/ +- /docs/Web/HTTP + +### 5. JavaScript + +通过 `document.cookie` 属性可创建新的 Cookie,也可通过该属性访问非 HttpOnly 标记的 Cookie。 + +```html +document.cookie = "yummy_cookie=choco"; +document.cookie = "tasty_cookie=strawberry"; +console.log(document.cookie); +``` + +### 6. HttpOnly + +标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。跨站脚本攻击 (XSS) 常常使用 JavaScript 的 `document.cookie` API 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。 + +```html +Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly +``` + +### 7. Secure + +标记为 Secure 的 Cookie 只能通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性,Secure 标记也无法提供确实的安全保障。 + +### 8. Session + +除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。 + +Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在 Redis 这种内存型数据库中,效率会更高。 + +使用 Session 维护用户登录状态的过程如下: + +- 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中; +- 服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID; +- 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中; +- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。 + +应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。 + +### 9. 浏览器禁用 Cookie + +此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外,不能再将 Session ID 存放到 Cookie 中,而是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。 + +### 10. Cookie 与 Session 选择 + +- Cookie 只能存储 ASCII 码字符串,而 Session 则可以存取任何类型的数据,因此在考虑数据复杂性时首选 Session; +- Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密; +- 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。 + +## 缓存 + +### 1. 优点 + +- 缓解服务器压力; +- 降低客户端获取资源的延迟:缓存通常位于内存中,读取缓存的速度更快。并且缓存在地理位置上也有可能比源服务器来得近,例如浏览器缓存。 + +### 2. 实现方法 + +- 让代理服务器进行缓存; +- 让客户端浏览器进行缓存。 + +### 3. Cache-Control + +HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。 + +**3.1 禁止进行缓存** + +no-store 指令规定不能对请求或响应的任何一部分进行缓存。 + +```html +Cache-Control: no-store +``` + +**3.2 强制确认缓存** + +no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效才将能使用该缓存对客户端的请求进行响应。 + +```html +Cache-Control: no-cache +``` + +**3.3 私有缓存和公共缓存** + +private 指令规定了将资源作为私有缓存,只能被单独用户所使用,一般存储在用户浏览器中。 + +```html +Cache-Control: private +``` + +public 指令规定了将资源作为公共缓存,可以被多个用户所使用,一般存储在代理服务器中。 + +```html +Cache-Control: public +``` + +**3.4 缓存过期机制** + +max-age 指令出现在请求报文中,并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。 + +max-age 指令出现在响应报文中,表示缓存资源在缓存服务器中保存的时间。 + +```html +Cache-Control: max-age=31536000 +``` + +Expires 首部字段也可以用于告知缓存服务器该资源什么时候会过期。 + +```html +Expires: Wed, 04 Jul 2012 08:26:05 GMT +``` + +- 在 HTTP/1.1 中,会优先处理 max-age 指令; +- 在 HTTP/1.0 中,max-age 指令会被忽略掉。 + +### 4. 缓存验证 + +需要先了解 ETag 首部字段的含义,它是资源的唯一标识。URL 不能唯一表示资源,例如 `http://www.google.com/` 有中文和英文两个资源,只有 ETag 才能对这两个资源进行唯一标识。 + +```html +ETag: "82e22293907ce725faf67773957acd12" +``` + +可以将缓存资源的 ETag 值放入 If-None-Match 首部,服务器收到该请求后,判断缓存资源的 ETag 值和资源的最新 ETag 值是否一致,如果一致则表示缓存资源有效,返回 304 Not Modified。 + +```html +If-None-Match: "82e22293907ce725faf67773957acd12" +``` + +Last-Modified 首部字段也可以用于缓存验证,它包含在源服务器发送的响应报文中,指示源服务器对资源的最后修改时间。但是它是一种弱校验器,因为只能精确到一秒,所以它通常作为 ETag 的备用方案。如果响应首部字段里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存。服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200 OK。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 Not Modified 响应。 + +```html +Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT +``` + +```html +If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT +``` + +## 内容协商 + +通过内容协商返回最合适的内容,例如根据浏览器的默认语言选择返回中文界面还是英文界面。 + +### 1. 类型 + +**1.1 服务端驱动型** + +客户端设置特定的 HTTP 首部字段,例如 Accept、Accept-Charset、Accept-Encoding、Accept-Language,服务器根据这些字段返回特定的资源。 + +它存在以下问题: + +- 服务器很难知道客户端浏览器的全部信息; +- 客户端提供的信息相当冗长(HTTP/2 协议的首部压缩机制缓解了这个问题),并且存在隐私风险(HTTP 指纹识别技术); +- 给定的资源需要返回不同的展现形式,共享缓存的效率会降低,而服务器端的实现会越来越复杂。 + +**1.2 代理驱动型** + +服务器返回 300 Multiple Choices 或者 406 Not Acceptable,客户端从中选出最合适的那个资源。 + +### 2. Vary + +```html +Vary: Accept-Language +``` + +在使用内容协商的情况下,只有当缓存服务器中的缓存满足内容协商条件时,才能使用该缓存,否则应该向源服务器请求该资源。 + +例如,一个客户端发送了一个包含 Accept-Language 首部字段的请求之后,源服务器返回的响应包含 `Vary: Accept-Language` 内容,缓存服务器对这个响应进行缓存之后,在客户端下一次访问同一个 URL 资源,并且 Accept-Language 与缓存中的对应的值相同时才会返回该缓存。 + +## 内容编码 + +内容编码将实体主体进行压缩,从而减少传输的数据量。 + +常用的内容编码有:gzip、compress、deflate、identity。 + +浏览器发送 Accept-Encoding 首部,其中包含有它所支持的压缩算法,以及各自的优先级。服务器则从中选择一种,使用该算法对响应的消息主体进行压缩,并且发送 Content-Encoding 首部来告知浏览器它选择了哪一种算法。由于该内容协商过程是基于编码类型来选择资源的展现形式的,在响应的 Vary 首部至少要包含 Content-Encoding。 + +## 范围请求 + +如果网络出现中断,服务器只发送了一部分数据,范围请求可以使得客户端只请求服务器未发送的那部分数据,从而避免服务器重新发送所有数据。 + +### 1. Range + +在请求报文中添加 Range 首部字段指定请求的范围。 + +```html +GET /z4d4kWk.jpg HTTP/1.1 +Host: i.imgur.com +Range: bytes=0-1023 +``` + +请求成功的话服务器返回的响应包含 206 Partial Content 状态码。 + +```html +HTTP/1.1 206 Partial Content +Content-Range: bytes 0-1023/146515 +Content-Length: 1024 +... +(binary content) +``` + +### 2. Accept-Ranges + +响应首部字段 Accept-Ranges 用于告知客户端是否能处理范围请求,可以处理使用 bytes,否则使用 none。 + +```html +Accept-Ranges: bytes +``` + +### 3. 响应状态码 + +- 在请求成功的情况下,服务器会返回 206 Partial Content 状态码。 +- 在请求的范围越界的情况下,服务器会返回 416 Requested Range Not Satisfiable 状态码。 +- 在不支持范围请求的情况下,服务器会返回 200 OK 状态码。 + +## 分块传输编码 + +Chunked Transfer Encoding,可以把数据分割成多块,让浏览器逐步显示页面。 + +## 多部分对象集合 + +一份报文主体内可含有多种类型的实体同时发送,每个部分之间用 boundary 字段定义的分隔符进行分隔,每个部分都可以有首部字段。 + +例如,上传多个表单时可以使用如下方式: + +```html +Content-Type: multipart/form-data; boundary=AaB03x + +--AaB03x +Content-Disposition: form-data; name="submit-name" + +Larry +--AaB03x +Content-Disposition: form-data; name="files"; filename="file1.txt" +Content-Type: text/plain + +... contents of file1.txt ... +--AaB03x-- +``` + +## 虚拟主机 + +HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名,并且在逻辑上可以看成多个服务器。 + +## 通信数据转发 + +### 1. 代理 + +代理服务器接受客户端的请求,并且转发给其它服务器。 + +使用代理的主要目的是: + +- 缓存 +- 负载均衡 +- 网络访问控制 +- 访问日志记录 + +代理服务器分为正向代理和反向代理两种: + +- 用户察觉得到正向代理的存在。 + +

+ +- 而反向代理一般位于内部网络中,用户察觉不到。 + +

+ +### 2. 网关 + +与代理服务器不同的是,网关服务器会将 HTTP 转化为其它协议进行通信,从而请求其它非 HTTP 服务器的服务。 + +### 3. 隧道 + +使用 SSL 等加密手段,在客户端和服务器之间建立一条安全的通信线路。 + +# 六、HTTPS + +HTTP 有以下安全性问题: + +- 使用明文进行通信,内容可能会被窃听; +- 不验证通信方的身份,通信方的身份有可能遭遇伪装; +- 无法证明报文的完整性,报文有可能遭篡改。 + +HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPS 使用了隧道进行通信。 + +通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。 + +

+ +## 加密 + +### 1. 对称密钥加密 + +对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。 + +- 优点:运算速度快; +- 缺点:无法安全地将密钥传输给通信方。 + +

+ +### 2.非对称密钥加密 + +非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。 + +公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。 + +非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。 + +- 优点:可以更安全地将公开密钥传输给通信发送方; +- 缺点:运算速度慢。 + +

+ +### 3. HTTPS 采用的加密方式 + +HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。(下图中的 Session Key 就是对称密钥) + +

+ +## 认证 + +通过使用 **证书** 来对通信方进行认证。 + +数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。 + +服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。 + +进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。 + +

+ +## 完整性保护 + +SSL 提供报文摘要功能来进行完整性保护。 + +HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5 的值,通信接收方是无法意识到发生了篡改。 + +HTTPS 的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。 + +## HTTPS 的缺点 + +- 因为需要进行加密解密等过程,因此速度会更慢; +- 需要支付证书授权的高额费用。 + +# 七、HTTP/2.0 + +## HTTP/1.x 缺陷 + +HTTP/1.x 实现简单是以牺牲性能为代价的: + +- 客户端需要使用多个连接才能实现并发和缩短延迟; +- 不会压缩请求和响应首部,从而导致不必要的网络流量; +- 不支持有效的资源优先级,致使底层 TCP 连接的利用率低下。 + +## 二进制分帧层 + +HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。 + +

+ +在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。 + +- 一个数据流(Stream)都有一个唯一标识符和可选的优先级信息,用于承载双向信息。 +- 消息(Message)是与逻辑请求或响应对应的完整的一系列帧。 +- 帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。 + +

+ +## 服务端推送 + +HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。 + +

+ +## 首部压缩 + +HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。 + +HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。 + +不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。 + +

+ +# 八、HTTP/1.1 新特性 + +详细内容请见上文 + +- 默认是长连接 +- 支持流水线 +- 支持同时打开多个 TCP 连接 +- 支持虚拟主机 +- 新增状态码 100 +- 支持分块传输编码 +- 新增缓存处理指令 max-age + +# 九、GET 和 POST 比较 + +## 作用 + +GET 用于获取资源,而 POST 用于传输实体主体。 + +## 参数 + +GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具(Fiddler)查看。 + +因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 `中文` 会转换为 `%E4%B8%AD%E6%96%87`,而空格会转换为 `%20`。POST 参数支持标准字符集。 + +``` +GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1 +``` + +``` +POST /test/demo_form.asp HTTP/1.1 +Host: w3schools.com +name1=value1&name2=value2 +``` + +## 安全 + +安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。 + +GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数据,上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。 + +安全的方法除了 GET 之外还有:HEAD、OPTIONS。 + +不安全的方法除了 POST 之外还有 PUT、DELETE。 + +## 幂等性 + +幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。 + +所有的安全方法也都是幂等的。 + +在正确实现的条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。 + +GET /pageX HTTP/1.1 是幂等的,连续调用多次,客户端接收到的结果都是一样的: + +``` +GET /pageX HTTP/1.1 +GET /pageX HTTP/1.1 +GET /pageX HTTP/1.1 +GET /pageX HTTP/1.1 +``` + +POST /add_row HTTP/1.1 不是幂等的,如果调用多次,就会增加多行记录: + +``` +POST /add_row HTTP/1.1 -> Adds a 1nd row +POST /add_row HTTP/1.1 -> Adds a 2nd row +POST /add_row HTTP/1.1 -> Adds a 3rd row +``` + +DELETE /idX/delete HTTP/1.1 是幂等的,即便不同的请求接收到的状态码不一样: + +``` +DELETE /idX/delete HTTP/1.1 -> Returns 200 if idX exists +DELETE /idX/delete HTTP/1.1 -> Returns 404 as it just got deleted +DELETE /idX/delete HTTP/1.1 -> Returns 404 +``` + +## 可缓存 + +如果要对响应进行缓存,需要满足以下条件: + +- 请求报文的 HTTP 方法本身是可缓存的,包括 GET 和 HEAD,但是 PUT 和 DELETE 不可缓存,POST 在多数情况下不可缓存的。 +- 响应报文的状态码是可缓存的,包括:200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501。 +- 响应报文的 Cache-Control 首部字段没有指定不进行缓存。 + +## XMLHttpRequest + +为了阐述 POST 和 GET 的另一个区别,需要先了解 XMLHttpRequest: + +> XMLHttpRequest 是一个 API,它为客户端提供了在客户端和服务器之间传输数据的功能。它提供了一个通过 URL 来获取数据的简单方式,并且不会使整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。XMLHttpRequest 在 AJAX 中被大量使用。 + +- 在使用 XMLHttpRequest 的 POST 方法时,浏览器会先发送 Header 再发送 Data。但并不是所有浏览器会这么做,例如火狐就不会。 +- 而 GET 方法 Header 和 Data 会一起发送。 + +# 参考资料 + +- 上野宣. 图解 HTTP[M]. 人民邮电出版社, 2014. +- [MDN : HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP) +- [HTTP/2 简介](https://developers.google.com/web/fundamentals/performance/http2/?hl=zh-cn) +- [htmlspecialchars](http://php.net/manual/zh/function.htmlspecialchars.php) +- [Difference between file URI and URL in java](http://java2db.com/java-io/how-to-get-and-the-difference-between-file-uri-and-url-in-java) +- [How to Fix SQL Injection Using Java PreparedStatement & CallableStatement](https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement) +- [浅谈 HTTP 中 Get 与 Post 的区别](https://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html) +- [Are http:// and www really necessary?](https://www.webdancers.com/are-http-and-www-necesary/) +- [HTTP (HyperText Transfer Protocol)](https://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html) +- [Web-VPN: Secure Proxies with SPDY & Chrome](https://www.igvita.com/2011/12/01/web-vpn-secure-proxies-with-spdy-chrome/) +- [File:HTTP persistent connection.svg](http://en.wikipedia.org/wiki/File:HTTP_persistent_connection.svg) +- [Proxy server](https://en.wikipedia.org/wiki/Proxy_server) +- [What Is This HTTPS/SSL Thing And Why Should You Care?](https://www.x-cart.com/blog/what-is-https-and-ssl.html) +- [What is SSL Offloading?](https://securebox.comodo.com/ssl-sniffing/ssl-offloading/) +- [Sun Directory Server Enterprise Edition 7.0 Reference - Key Encryption](https://docs.oracle.com/cd/E19424-01/820-4811/6ng8i26bn/index.html) +- [An Introduction to Mutual SSL Authentication](https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication) +- [The Difference Between URLs and URIs](https://danielmiessler.com/study/url-uri/) +- [Cookie 与 Session 的区别](https://juejin.im/entry/5766c29d6be3ff006a31b84e#comment) +- [COOKIE 和 SESSION 有什么区别](https://www.zhihu.com/question/19786827) +- [Cookie/Session 的机制与安全](https://harttle.land/2015/08/10/cookie-session.html) +- [HTTPS 证书原理](https://shijianan.com/2017/06/11/https/) +- [What is the difference between a URI, a URL and a URN?](https://stackoverflow.com/questions/176264/what-is-the-difference-between-a-uri-a-url-and-a-urn) +- [XMLHttpRequest](https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest) +- [XMLHttpRequest (XHR) Uses Multiple Packets for HTTP POST?](https://blog.josephscott.org/2009/08/27/xmlhttprequest-xhr-uses-multiple-packets-for-http-post/) +- [Symmetric vs. Asymmetric Encryption – What are differences?](https://www.ssl2buy.com/wiki/symmetric-vs-asymmetric-encryption-what-are-differences) +- [Web 性能优化与 HTTP/2](https://www.kancloud.cn/digest/web-performance-http2) +- [HTTP/2 简介](https://developers.google.com/web/fundamentals/performance/http2/?hl=zh-cn) + + + + +
🎨️欢迎关注我的公众号 CyC2018,在公众号后台回复关键字 **资料** 可领取复习大纲,这份大纲是我花了一整年时间整理的面试知识点列表,不仅系统整理了面试知识点,而且标注了各个知识点的重要程度,从而帮你理清多而杂的面试知识点。可以说我基本是按照这份大纲来进行复习的,这份大纲对我拿到了 BAT 头条等 Offer 起到很大的帮助。你们完全可以和我一样根据大纲上列的知识点来进行复习,就不用看很多不重要的内容,也可以知道哪些内容很重要从而多安排一些复习时间。

+
diff --git a/notes/Java IO.md b/notes/Java IO.md new file mode 100644 index 00000000..c86440f8 --- /dev/null +++ b/notes/Java IO.md @@ -0,0 +1,626 @@ + +* [一、概览](#一概览) +* [二、磁盘操作](#二磁盘操作) +* [三、字节操作](#三字节操作) + * [实现文件复制](#实现文件复制) + * [装饰者模式](#装饰者模式) +* [四、字符操作](#四字符操作) + * [编码与解码](#编码与解码) + * [String 的编码方式](#string-的编码方式) + * [Reader 与 Writer](#reader-与-writer) + * [实现逐行输出文本文件的内容](#实现逐行输出文本文件的内容) +* [五、对象操作](#五对象操作) + * [序列化](#序列化) + * [Serializable](#serializable) + * [transient](#transient) +* [六、网络操作](#六网络操作) + * [InetAddress](#inetaddress) + * [URL](#url) + * [Sockets](#sockets) + * [Datagram](#datagram) +* [七、NIO](#七nio) + * [流与块](#流与块) + * [通道与缓冲区](#通道与缓冲区) + * [缓冲区状态变量](#缓冲区状态变量) + * [文件 NIO 实例](#文件-nio-实例) + * [选择器](#选择器) + * [套接字 NIO 实例](#套接字-nio-实例) + * [内存映射文件](#内存映射文件) + * [对比](#对比) +* [八、参考资料](#八参考资料) + + + +# 一、概览 + +Java 的 I/O 大概可以分成以下几类: + +- 磁盘操作:File +- 字节操作:InputStream 和 OutputStream +- 字符操作:Reader 和 Writer +- 对象操作:Serializable +- 网络操作:Socket +- 新的输入/输出:NIO + +# 二、磁盘操作 + +File 类可以用于表示文件和目录的信息,但是它不表示文件的内容。 + +递归地列出一个目录下所有文件: + +```java +public static void listAllFiles(File dir) { + if (dir == null || !dir.exists()) { + return; + } + if (dir.isFile()) { + System.out.println(dir.getName()); + return; + } + for (File file : dir.listFiles()) { + listAllFiles(file); + } +} +``` + +从 Java7 开始,可以使用 Paths 和 Files 代替 File。 + +# 三、字节操作 + +## 实现文件复制 + +```java +public static void copyFile(String src, String dist) throws IOException { + FileInputStream in = new FileInputStream(src); + FileOutputStream out = new FileOutputStream(dist); + + byte[] buffer = new byte[20 * 1024]; + int cnt; + + // read() 最多读取 buffer.length 个字节 + // 返回的是实际读取的个数 + // 返回 -1 的时候表示读到 eof,即文件尾 + while ((cnt = in.read(buffer, 0, buffer.length)) != -1) { + out.write(buffer, 0, cnt); + } + + in.close(); + out.close(); +} +``` + +## 装饰者模式 + +Java I/O 使用了装饰者模式来实现。以 InputStream 为例, + +- InputStream 是抽象组件; +- FileInputStream 是 InputStream 的子类,属于具体组件,提供了字节流的输入操作; +- FilterInputStream 属于抽象装饰者,装饰者用于装饰组件,为组件提供额外的功能。例如 BufferedInputStream 为 FileInputStream 提供缓存的功能。 + +

+ +实例化一个具有缓存功能的字节流对象时,只需要在 FileInputStream 对象上再套一层 BufferedInputStream 对象即可。 + +```java +FileInputStream fileInputStream = new FileInputStream(filePath); +BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); +``` + +DataInputStream 装饰者提供了对更多数据类型进行输入的操作,比如 int、double 等基本类型。 + +# 四、字符操作 + +## 编码与解码 + +编码就是把字符转换为字节,而解码是把字节重新组合成字符。 + +如果编码和解码过程使用不同的编码方式那么就出现了乱码。 + +- GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节; +- UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节; +- UTF-16be 编码中,中文字符和英文字符都占 2 个字节。 + +UTF-16be 中的 be 指的是 Big Endian,也就是大端。相应地也有 UTF-16le,le 指的是 Little Endian,也就是小端。 + +Java 的内存编码使用双字节编码 UTF-16be,这不是指 Java 只支持这一种编码方式,而是说 char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位,也就是两个字节,Java 使用这种双字节编码是为了让一个中文或者一个英文都能使用一个 char 来存储。 + +## String 的编码方式 + +String 可以看成一个字符序列,可以指定一个编码方式将它编码为字节序列,也可以指定一个编码方式将一个字节序列解码为 String。 + +```java +String str1 = "中文"; +byte[] bytes = str1.getBytes("UTF-8"); +String str2 = new String(bytes, "UTF-8"); +System.out.println(str2); +``` + +在调用无参数 getBytes() 方法时,默认的编码方式不是 UTF-16be。双字节编码的好处是可以使用一个 char 存储中文和英文,而将 String 转为 bytes[] 字节数组就不再需要这个好处,因此也就不再需要双字节编码。getBytes() 的默认编码方式与平台有关,一般为 UTF-8。 + +```java +byte[] bytes = str1.getBytes(); +``` + +## Reader 与 Writer + +不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符。但是在程序中操作的通常是字符形式的数据,因此需要提供对字符进行操作的方法。 + +- InputStreamReader 实现从字节流解码成字符流; +- OutputStreamWriter 实现字符流编码成为字节流。 + +## 实现逐行输出文本文件的内容 + +```java +public static void readFileContent(String filePath) throws IOException { + + FileReader fileReader = new FileReader(filePath); + BufferedReader bufferedReader = new BufferedReader(fileReader); + + String line; + while ((line = bufferedReader.readLine()) != null) { + System.out.println(line); + } + + // 装饰者模式使得 BufferedReader 组合了一个 Reader 对象 + // 在调用 BufferedReader 的 close() 方法时会去调用 Reader 的 close() 方法 + // 因此只要一个 close() 调用即可 + bufferedReader.close(); +} +``` + +# 五、对象操作 + +## 序列化 + +序列化就是将一个对象转换成字节序列,方便存储和传输。 + +- 序列化:ObjectOutputStream.writeObject() +- 反序列化:ObjectInputStream.readObject() + +不会对静态变量进行序列化,因为序列化只是保存对象的状态,静态变量属于类的状态。 + +## Serializable + +序列化的类需要实现 Serializable 接口,它只是一个标准,没有任何方法需要实现,但是如果不去实现它的话而进行序列化,会抛出异常。 + +```java +public static void main(String[] args) throws IOException, ClassNotFoundException { + + A a1 = new A(123, "abc"); + String objectFile = "file/a1"; + + ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(objectFile)); + objectOutputStream.writeObject(a1); + objectOutputStream.close(); + + ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(objectFile)); + A a2 = (A) objectInputStream.readObject(); + objectInputStream.close(); + System.out.println(a2); +} + +private static class A implements Serializable { + + private int x; + private String y; + + A(int x, String y) { + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return "x = " + x + " " + "y = " + y; + } +} +``` + +## transient + +transient 关键字可以使一些属性不会被序列化。 + +ArrayList 中存储数据的数组 elementData 是用 transient 修饰的,因为这个数组是动态扩展的,并不是所有的空间都被使用,因此就不需要所有的内容都被序列化。通过重写序列化和反序列化方法,使得可以只序列化数组中有内容的那部分数据。 + +```java +private transient Object[] elementData; +``` + +# 六、网络操作 + +Java 中的网络支持: + +- InetAddress:用于表示网络上的硬件资源,即 IP 地址; +- URL:统一资源定位符; +- Sockets:使用 TCP 协议实现网络通信; +- Datagram:使用 UDP 协议实现网络通信。 + +## InetAddress + +没有公有的构造函数,只能通过静态方法来创建实例。 + +```java +InetAddress.getByName(String host); +InetAddress.getByAddress(byte[] address); +``` + +## URL + +可以直接从 URL 中读取字节流数据。 + +```java +public static void main(String[] args) throws IOException { + + URL url = new URL("http://www.baidu.com"); + + /* 字节流 */ + InputStream is = url.openStream(); + + /* 字符流 */ + InputStreamReader isr = new InputStreamReader(is, "utf-8"); + + /* 提供缓存功能 */ + BufferedReader br = new BufferedReader(isr); + + String line; + while ((line = br.readLine()) != null) { + System.out.println(line); + } + + br.close(); +} +``` + +## Sockets + +- ServerSocket:服务器端类 +- Socket:客户端类 +- 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。 + +

+ +## Datagram + +- DatagramSocket:通信类 +- DatagramPacket:数据包类 + +# 七、NIO + +新的输入/输出 (NIO) 库是在 JDK 1.4 中引入的,弥补了原来的 I/O 的不足,提供了高速的、面向块的 I/O。 + +## 流与块 + +I/O 与 NIO 最重要的区别是数据打包和传输的方式,I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。 + +面向流的 I/O 一次处理一个字节数据:一个输入流产生一个字节数据,一个输出流消费一个字节数据。为流式数据创建过滤器非常容易,链接几个过滤器,以便每个过滤器只负责复杂处理机制的一部分。不利的一面是,面向流的 I/O 通常相当慢。 + +面向块的 I/O 一次处理一个数据块,按块处理数据比按流处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。 + +I/O 包和 NIO 已经很好地集成了,java.io.\* 已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如,java.io.\* 包中的一些类包含以块的形式读写数据的方法,这使得即使在面向流的系统中,处理速度也会更快。 + +## 通道与缓冲区 + +### 1. 通道 + +通道 Channel 是对原 I/O 包中的流的模拟,可以通过它读取和写入数据。 + +通道与流的不同之处在于,流只能在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类),而通道是双向的,可以用于读、写或者同时用于读写。 + +通道包括以下类型: + +- FileChannel:从文件中读写数据; +- DatagramChannel:通过 UDP 读写网络中数据; +- SocketChannel:通过 TCP 读写网络中数据; +- ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。 + +### 2. 缓冲区 + +发送给一个通道的所有数据都必须首先放到缓冲区中,同样地,从通道中读取的任何数据都要先读到缓冲区中。也就是说,不会直接对通道进行读写数据,而是要先经过缓冲区。 + +缓冲区实质上是一个数组,但它不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。 + +缓冲区包括以下类型: + +- ByteBuffer +- CharBuffer +- ShortBuffer +- IntBuffer +- LongBuffer +- FloatBuffer +- DoubleBuffer + +## 缓冲区状态变量 + +- capacity:最大容量; +- position:当前已经读写的字节数; +- limit:还可以读写的字节数。 + +状态变量的改变过程举例: + +① 新建一个大小为 8 个字节的缓冲区,此时 position 为 0,而 limit = capacity = 8。capacity 变量不会改变,下面的讨论会忽略它。 + +

+ +② 从输入通道中读取 5 个字节数据写入缓冲区中,此时 position 为 5,limit 保持不变。 + +

+ +③ 在将缓冲区的数据写到输出通道之前,需要先调用 flip() 方法,这个方法将 limit 设置为当前 position,并将 position 设置为 0。 + +

+ +④ 从缓冲区中取 4 个字节到输出缓冲中,此时 position 设为 4。 + +

+ +⑤ 最后需要调用 clear() 方法来清空缓冲区,此时 position 和 limit 都被设置为最初位置。 + +

+ +## 文件 NIO 实例 + +以下展示了使用 NIO 快速复制文件的实例: + +```java +public static void fastCopy(String src, String dist) throws IOException { + + /* 获得源文件的输入字节流 */ + FileInputStream fin = new FileInputStream(src); + + /* 获取输入字节流的文件通道 */ + FileChannel fcin = fin.getChannel(); + + /* 获取目标文件的输出字节流 */ + FileOutputStream fout = new FileOutputStream(dist); + + /* 获取输出字节流的文件通道 */ + FileChannel fcout = fout.getChannel(); + + /* 为缓冲区分配 1024 个字节 */ + ByteBuffer buffer = ByteBuffer.allocateDirect(1024); + + while (true) { + + /* 从输入通道中读取数据到缓冲区中 */ + int r = fcin.read(buffer); + + /* read() 返回 -1 表示 EOF */ + if (r == -1) { + break; + } + + /* 切换读写 */ + buffer.flip(); + + /* 把缓冲区的内容写入输出文件中 */ + fcout.write(buffer); + + /* 清空缓冲区 */ + buffer.clear(); + } +} +``` + +## 选择器 + +NIO 常常被叫做非阻塞 IO,主要是因为 NIO 在网络通信中的非阻塞特性被广泛使用。 + +NIO 实现了 IO 多路复用中的 Reactor 模型,一个线程 Thread 使用一个选择器 Selector 通过轮询的方式去监听多个通道 Channel 上的事件,从而让一个线程就可以处理多个事件。 + +通过配置监听的通道 Channel 为非阻塞,那么当 Channel 上的 IO 事件还未到达时,就不会进入阻塞状态一直等待,而是继续轮询其它 Channel,找到 IO 事件已经到达的 Channel 执行。 + +因为创建和切换线程的开销很大,因此使用一个线程来处理多个事件而不是一个线程处理一个事件,对于 IO 密集型的应用具有很好地性能。 + +应该注意的是,只有套接字 Channel 才能配置为非阻塞,而 FileChannel 不能,为 FileChannel 配置非阻塞也没有意义。 + +

+ +### 1. 创建选择器 + +```java +Selector selector = Selector.open(); +``` + +### 2. 将通道注册到选择器上 + +```java +ServerSocketChannel ssChannel = ServerSocketChannel.open(); +ssChannel.configureBlocking(false); +ssChannel.register(selector, SelectionKey.OP_ACCEPT); +``` + +通道必须配置为非阻塞模式,否则使用选择器就没有任何意义了,因为如果通道在某个事件上被阻塞,那么服务器就不能响应其它事件,必须等待这个事件处理完毕才能去处理其它事件,显然这和选择器的作用背道而驰。 + +在将通道注册到选择器上时,还需要指定要注册的具体事件,主要有以下几类: + +- SelectionKey.OP_CONNECT +- SelectionKey.OP_ACCEPT +- SelectionKey.OP_READ +- SelectionKey.OP_WRITE + +它们在 SelectionKey 的定义如下: + +```java +public static final int OP_READ = 1 << 0; +public static final int OP_WRITE = 1 << 2; +public static final int OP_CONNECT = 1 << 3; +public static final int OP_ACCEPT = 1 << 4; +``` + +可以看出每个事件可以被当成一个位域,从而组成事件集整数。例如: + +```java +int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE; +``` + +### 3. 监听事件 + +```java +int num = selector.select(); +``` + +使用 select() 来监听到达的事件,它会一直阻塞直到有至少一个事件到达。 + +### 4. 获取到达的事件 + +```java +Set keys = selector.selectedKeys(); +Iterator keyIterator = keys.iterator(); +while (keyIterator.hasNext()) { + SelectionKey key = keyIterator.next(); + if (key.isAcceptable()) { + // ... + } else if (key.isReadable()) { + // ... + } + keyIterator.remove(); +} +``` + +### 5. 事件循环 + +因为一次 select() 调用不能处理完所有的事件,并且服务器端有可能需要一直监听事件,因此服务器端处理事件的代码一般会放在一个死循环内。 + +```java +while (true) { + int num = selector.select(); + Set keys = selector.selectedKeys(); + Iterator keyIterator = keys.iterator(); + while (keyIterator.hasNext()) { + SelectionKey key = keyIterator.next(); + if (key.isAcceptable()) { + // ... + } else if (key.isReadable()) { + // ... + } + keyIterator.remove(); + } +} +``` + +## 套接字 NIO 实例 + +```java +public class NIOServer { + + public static void main(String[] args) throws IOException { + + Selector selector = Selector.open(); + + ServerSocketChannel ssChannel = ServerSocketChannel.open(); + ssChannel.configureBlocking(false); + ssChannel.register(selector, SelectionKey.OP_ACCEPT); + + ServerSocket serverSocket = ssChannel.socket(); + InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888); + serverSocket.bind(address); + + while (true) { + + selector.select(); + Set keys = selector.selectedKeys(); + Iterator keyIterator = keys.iterator(); + + while (keyIterator.hasNext()) { + + SelectionKey key = keyIterator.next(); + + if (key.isAcceptable()) { + + ServerSocketChannel ssChannel1 = (ServerSocketChannel) key.channel(); + + // 服务器会为每个新连接创建一个 SocketChannel + SocketChannel sChannel = ssChannel1.accept(); + sChannel.configureBlocking(false); + + // 这个新连接主要用于从客户端读取数据 + sChannel.register(selector, SelectionKey.OP_READ); + + } else if (key.isReadable()) { + + SocketChannel sChannel = (SocketChannel) key.channel(); + System.out.println(readDataFromSocketChannel(sChannel)); + sChannel.close(); + } + + keyIterator.remove(); + } + } + } + + private static String readDataFromSocketChannel(SocketChannel sChannel) throws IOException { + + ByteBuffer buffer = ByteBuffer.allocate(1024); + StringBuilder data = new StringBuilder(); + + while (true) { + + buffer.clear(); + int n = sChannel.read(buffer); + if (n == -1) { + break; + } + buffer.flip(); + int limit = buffer.limit(); + char[] dst = new char[limit]; + for (int i = 0; i < limit; i++) { + dst[i] = (char) buffer.get(i); + } + data.append(dst); + buffer.clear(); + } + return data.toString(); + } +} +``` + +```java +public class NIOClient { + + public static void main(String[] args) throws IOException { + Socket socket = new Socket("127.0.0.1", 8888); + OutputStream out = socket.getOutputStream(); + String s = "hello world"; + out.write(s.getBytes()); + out.close(); + } +} +``` + +## 内存映射文件 + +内存映射文件 I/O 是一种读和写文件数据的方法,它可以比常规的基于流或者基于通道的 I/O 快得多。 + +向内存映射文件写入可能是危险的,只是改变数组的单个元素这样的简单操作,就可能会直接修改磁盘上的文件。修改数据与将数据保存到磁盘是没有分开的。 + +下面代码行将文件的前 1024 个字节映射到内存中,map() 方法返回一个 MappedByteBuffer,它是 ByteBuffer 的子类。因此,可以像使用其他任何 ByteBuffer 一样使用新映射的缓冲区,操作系统会在需要时负责执行映射。 + +```java +MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024); +``` + +## 对比 + +NIO 与普通 I/O 的区别主要有以下两点: + +- NIO 是非阻塞的; +- NIO 面向块,I/O 面向流。 + +# 八、参考资料 + +- Eckel B, 埃克尔, 昊鹏, 等. Java 编程思想 [M]. 机械工业出版社, 2002. +- [IBM: NIO 入门](https://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html) +- [Java NIO Tutorial](http://tutorials.jenkov.com/java-nio/index.html) +- [Java NIO 浅析](https://tech.meituan.com/nio.html) +- [IBM: 深入分析 Java I/O 的工作机制](https://www.ibm.com/developerworks/cn/java/j-lo-javaio/index.html) +- [IBM: 深入分析 Java 中的中文编码问题](https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/index.html) +- [IBM: Java 序列化的高级认识](https://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html) +- [NIO 与传统 IO 的区别](http://blog.csdn.net/shimiso/article/details/24990499) +- [Decorator Design Pattern](http://stg-tud.github.io/sedc/Lecture/ws13-14/5.3-Decorator.html#mode=document) +- [Socket Multicast](http://labojava.blogspot.com/2012/12/socket-multicast.html) + + + + +
🎨️欢迎关注我的公众号 CyC2018,在公众号后台回复关键字 **资料** 可领取复习大纲,这份大纲是我花了一整年时间整理的面试知识点列表,不仅系统整理了面试知识点,而且标注了各个知识点的重要程度,从而帮你理清多而杂的面试知识点。可以说我基本是按照这份大纲来进行复习的,这份大纲对我拿到了 BAT 头条等 Offer 起到很大的帮助。你们完全可以和我一样根据大纲上列的知识点来进行复习,就不用看很多不重要的内容,也可以知道哪些内容很重要从而多安排一些复习时间。

+
diff --git a/notes/Java 基础.md b/notes/Java 基础.md new file mode 100644 index 00000000..0c3fdefa --- /dev/null +++ b/notes/Java 基础.md @@ -0,0 +1,1423 @@ + +* [一、数据类型](#一数据类型) + * [基本类型](#基本类型) + * [包装类型](#包装类型) + * [缓存池](#缓存池) +* [二、String](#二string) + * [概览](#概览) + * [不可变的好处](#不可变的好处) + * [String, StringBuffer and StringBuilder](#string,-stringbuffer-and-stringbuilder) + * [String Pool](#string-pool) + * [new String("abc")](#new-string"abc") +* [三、运算](#三运算) + * [参数传递](#参数传递) + * [float 与 double](#float-与-double) + * [隐式类型转换](#隐式类型转换) + * [switch](#switch) +* [四、继承](#四继承) + * [访问权限](#访问权限) + * [抽象类与接口](#抽象类与接口) + * [super](#super) + * [重写与重载](#重写与重载) +* [五、Object 通用方法](#五object-通用方法) + * [概览](#概览) + * [equals()](#equals) + * [hashCode()](#hashcode) + * [toString()](#tostring) + * [clone()](#clone) +* [六、关键字](#六关键字) + * [final](#final) + * [static](#static) +* [七、反射](#七反射) +* [八、异常](#八异常) +* [九、泛型](#九泛型) +* [十、注解](#十注解) +* [十一、特性](#十一特性) + * [Java 各版本的新特性](#java-各版本的新特性) + * [Java 与 C++ 的区别](#java-与-c-的区别) + * [JRE or JDK](#jre-or-jdk) +* [参考资料](#参考资料) + + + +# 一、数据类型 + +## 基本类型 + +- byte/8 +- char/16 +- short/16 +- int/32 +- float/32 +- long/64 +- double/64 +- boolean/\~ + +boolean 只有两个值:true、false,可以使用 1 bit 来存储,但是具体大小没有明确规定。JVM 会在编译时期将 boolean 类型的数据转换为 int,使用 1 来表示 true,0 表示 false。JVM 支持 boolean 数组,但是是通过读写 byte 数组来实现的。 + +- [Primitive Data Types](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) +- [The Java® Virtual Machine Specification](https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf) + +## 包装类型 + +基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。 + +```java +Integer x = 2; // 装箱 +int y = x; // 拆箱 +``` + +## 缓存池 + +new Integer(123) 与 Integer.valueOf(123) 的区别在于: + +- new Integer(123) 每次都会新建一个对象; +- Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。 + +```java +Integer x = new Integer(123); +Integer y = new Integer(123); +System.out.println(x == y); // false +Integer z = Integer.valueOf(123); +Integer k = Integer.valueOf(123); +System.out.println(z == k); // true +``` + +valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。 + +```java +public static Integer valueOf(int i) { + if (i >= IntegerCache.low && i <= IntegerCache.high) + return IntegerCache.cache[i + (-IntegerCache.low)]; + return new Integer(i); +} +``` + +在 Java 8 中,Integer 缓存池的大小默认为 -128\~127。 + +```java +static final int low = -128; +static final int high; +static final Integer cache[]; + +static { + // high value may be configured by property + int h = 127; + String integerCacheHighPropValue = + sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); + if (integerCacheHighPropValue != null) { + try { + int i = parseInt(integerCacheHighPropValue); + i = Math.max(i, 127); + // Maximum array size is Integer.MAX_VALUE + h = Math.min(i, Integer.MAX_VALUE - (-low) -1); + } catch( NumberFormatException nfe) { + // If the property cannot be parsed into an int, ignore it. + } + } + high = h; + + cache = new Integer[(high - low) + 1]; + int j = low; + for(int k = 0; k < cache.length; k++) + cache[k] = new Integer(j++); + + // range [-128, 127] must be interned (JLS7 5.1.7) + assert IntegerCache.high >= 127; +} +``` + +编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。 + +```java +Integer m = 123; +Integer n = 123; +System.out.println(m == n); // true +``` + +基本类型对应的缓冲池如下: + +- boolean values true and false +- all byte values +- short values between -128 and 127 +- int values between -128 and 127 +- char in the range \u0000 to \u007F + +在使用这些基本类型对应的包装类型时,就可以直接使用缓冲池中的对象。 + +[StackOverflow : Differences between new Integer(123), Integer.valueOf(123) and just 123 +](https://stackoverflow.com/questions/9030817/differences-between-new-integer123-integer-valueof123-and-just-123) + +# 二、String + +## 概览 + +String 被声明为 final,因此它不可被继承。 + +在 Java 8 中,String 内部使用 char 数组存储数据。 + +```java +public final class String + implements java.io.Serializable, Comparable, CharSequence { + /** The value is used for character storage. */ + private final char value[]; +} +``` + +在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 `coder` 来标识使用了哪种编码。 + +```java +public final class String + implements java.io.Serializable, Comparable, CharSequence { + /** The value is used for character storage. */ + private final byte[] value; + + /** The identifier of the encoding used to encode the bytes in {@code value}. */ + private final byte coder; +} +``` + +value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。 + +## 不可变的好处 + +**1. 可以缓存 hash 值** + +因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。 + +**2. String Pool 的需要** + +如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。 + +

+ +**3. 安全性** + +String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。 + +**4. 线程安全** + +String 不可变性天生具备线程安全,可以在多个线程中安全地使用。 + +[Program Creek : Why String is immutable in Java?](https://www.programcreek.com/2013/04/why-string-is-immutable-in-java/) + +## String, StringBuffer and StringBuilder + +**1. 可变性** + +- String 不可变 +- StringBuffer 和 StringBuilder 可变 + +**2. 线程安全** + +- String 不可变,因此是线程安全的 +- StringBuilder 不是线程安全的 +- StringBuffer 是线程安全的,内部使用 synchronized 进行同步 + +[StackOverflow : String, StringBuffer, and StringBuilder](https://stackoverflow.com/questions/2971315/string-stringbuffer-and-stringbuilder) + +## String Pool + +字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。不仅如此,还可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中。 + +当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。 + +下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同字符串,而 s3 和 s4 是通过 s1.intern() 方法取得一个字符串引用。intern() 首先把 s1 引用的字符串放到 String Pool 中,然后返回这个字符串引用。因此 s3 和 s4 引用的是同一个字符串。 + +```java +String s1 = new String("aaa"); +String s2 = new String("aaa"); +System.out.println(s1 == s2); // false +String s3 = s1.intern(); +String s4 = s1.intern(); +System.out.println(s3 == s4); // true +``` + +如果是采用 "bbb" 这种字面量的形式创建字符串,会自动地将字符串放入 String Pool 中。 + +```java +String s5 = "bbb"; +String s6 = "bbb"; +System.out.println(s5 == s6); // true +``` + +在 Java 7 之前,String Pool 被放在运行时常量池中,它属于永久代。而在 Java 7,String Pool 被移到堆中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致 OutOfMemoryError 错误。 + +- [StackOverflow : What is String interning?](https://stackoverflow.com/questions/10578984/what-is-string-interning) +- [深入解析 String#intern](https://tech.meituan.com/in_depth_understanding_string_intern.html) + +## new String("abc") + +使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 "abc" 字符串对象)。 + +- "abc" 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 "abc" 字符串字面量; +- 而使用 new 的方式会在堆中创建一个字符串对象。 + +创建一个测试类,其 main 方法中使用这种方式来创建字符串对象。 + +```java +public class NewStringTest { + public static void main(String[] args) { + String s = new String("abc"); + } +} +``` + +使用 javap -verbose 进行反编译,得到以下内容: + +```java +// ... +Constant pool: +// ... + #2 = Class #18 // java/lang/String + #3 = String #19 // abc +// ... + #18 = Utf8 java/lang/String + #19 = Utf8 abc +// ... + + public static void main(java.lang.String[]); + descriptor: ([Ljava/lang/String;)V + flags: ACC_PUBLIC, ACC_STATIC + Code: + stack=3, locals=2, args_size=1 + 0: new #2 // class java/lang/String + 3: dup + 4: ldc #3 // String abc + 6: invokespecial #4 // Method java/lang/String."":(Ljava/lang/String;)V + 9: astore_1 +// ... +``` + +在 Constant Pool 中,#19 存储这字符串字面量 "abc",#3 是 String Pool 的字符串对象,它指向 #19 这个字符串字面量。在 main 方法中,0: 行使用 new #2 在堆中创建一个字符串对象,并且使用 ldc #3 将 String Pool 中的字符串对象作为 String 构造函数的参数。 + +以下是 String 构造函数的源码,可以看到,在将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全复制 value 数组内容,而是都会指向同一个 value 数组。 + +```java +public String(String original) { + this.value = original.value; + this.hash = original.hash; +} +``` + +# 三、运算 + +## 参数传递 + +Java 的参数是以值传递的形式传入方法中,而不是引用传递。 + +以下代码中 Dog dog 的 dog 是一个指针,存储的是对象的地址。在将一个参数传入一个方法时,本质上是将对象的地址以值的方式传递到形参中。因此在方法中使指针引用其它对象,那么这两个指针此时指向的是完全不同的对象,在一方改变其所指向对象的内容时对另一方没有影响。 + +```java +public class Dog { + + String name; + + Dog(String name) { + this.name = name; + } + + String getName() { + return this.name; + } + + void setName(String name) { + this.name = name; + } + + String getObjectAddress() { + return super.toString(); + } +} +``` + +```java +public class PassByValueExample { + public static void main(String[] args) { + Dog dog = new Dog("A"); + System.out.println(dog.getObjectAddress()); // Dog@4554617c + func(dog); + System.out.println(dog.getObjectAddress()); // Dog@4554617c + System.out.println(dog.getName()); // A + } + + private static void func(Dog dog) { + System.out.println(dog.getObjectAddress()); // Dog@4554617c + dog = new Dog("B"); + System.out.println(dog.getObjectAddress()); // Dog@74a14482 + System.out.println(dog.getName()); // B + } +} +``` + +如果在方法中改变对象的字段值会改变原对象该字段值,因为改变的是同一个地址指向的内容。 + +```java +class PassByValueExample { + public static void main(String[] args) { + Dog dog = new Dog("A"); + func(dog); + System.out.println(dog.getName()); // B + } + + private static void func(Dog dog) { + dog.setName("B"); + } +} +``` + +[StackOverflow: Is Java “pass-by-reference” or “pass-by-value”?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) + +## float 与 double + +Java 不能隐式执行向下转型,因为这会使得精度降低。 + +1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型。 + +```java +// float f = 1.1; +``` + +1.1f 字面量才是 float 类型。 + +```java +float f = 1.1f; +``` + +## 隐式类型转换 + +因为字面量 1 是 int 类型,它比 short 类型精度要高,因此不能隐式地将 int 类型下转型为 short 类型。 + +```java +short s1 = 1; +// s1 = s1 + 1; +``` + +但是使用 += 或者 ++ 运算符可以执行隐式类型转换。 + +```java +s1 += 1; +// s1++; +``` + +上面的语句相当于将 s1 + 1 的计算结果进行了向下转型: + +```java +s1 = (short) (s1 + 1); +``` + +[StackOverflow : Why don't Java's +=, -=, *=, /= compound assignment operators require casting?](https://stackoverflow.com/questions/8710619/why-dont-javas-compound-assignment-operators-require-casting) + +## switch + +从 Java 7 开始,可以在 switch 条件判断语句中使用 String 对象。 + +```java +String s = "a"; +switch (s) { + case "a": + System.out.println("aaa"); + break; + case "b": + System.out.println("bbb"); + break; +} +``` + +switch 不支持 long,是因为 switch 的设计初衷是对那些只有少数的几个值进行等值判断,如果值过于复杂,那么还是用 if 比较合适。 + +```java +// long x = 111; +// switch (x) { // Incompatible types. Found: 'long', required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum' +// case 111: +// System.out.println(111); +// break; +// case 222: +// System.out.println(222); +// break; +// } +``` + +[StackOverflow : Why can't your switch statement data type be long, Java?](https://stackoverflow.com/questions/2676210/why-cant-your-switch-statement-data-type-be-long-java) + +# 四、继承 + +## 访问权限 + +Java 中有三个访问权限修饰符:private、protected 以及 public,如果不加访问修饰符,表示包级可见。 + +可以对类或类中的成员(字段以及方法)加上访问修饰符。 + +- 类可见表示其它类可以用这个类创建实例对象。 +- 成员可见表示其它类可以用这个类的实例对象访问到该成员; + +protected 用于修饰成员,表示在继承体系中成员对于子类可见,但是这个访问修饰符对于类没有意义。 + +设计良好的模块会隐藏所有的实现细节,把它的 API 与它的实现清晰地隔离开来。模块之间只通过它们的 API 进行通信,一个模块不需要知道其他模块的内部工作情况,这个概念被称为信息隐藏或封装。因此访问权限应当尽可能地使每个类或者成员不被外界访问。 + +如果子类的方法重写了父类的方法,那么子类中该方法的访问级别不允许低于父类的访问级别。这是为了确保可以使用父类实例的地方都可以使用子类实例,也就是确保满足里氏替换原则。 + +字段决不能是公有的,因为这么做的话就失去了对这个字段修改行为的控制,客户端可以对其随意修改。例如下面的例子中,AccessExample 拥有 id 公有字段,如果在某个时刻,我们想要使用 int 存储 id 字段,那么就需要修改所有的客户端代码。 + +```java +public class AccessExample { + public String id; +} +``` + +可以使用公有的 getter 和 setter 方法来替换公有字段,这样的话就可以控制对字段的修改行为。 + + +```java +public class AccessExample { + + private int id; + + public String getId() { + return id + ""; + } + + public void setId(String id) { + this.id = Integer.valueOf(id); + } +} +``` + +但是也有例外,如果是包级私有的类或者私有的嵌套类,那么直接暴露成员不会有特别大的影响。 + +```java +public class AccessWithInnerClassExample { + + private class InnerClass { + int x; + } + + private InnerClass innerClass; + + public AccessWithInnerClassExample() { + innerClass = new InnerClass(); + } + + public int getValue() { + return innerClass.x; // 直接访问 + } +} +``` + +## 抽象类与接口 + +**1. 抽象类** + +抽象类和抽象方法都使用 abstract 关键字进行声明。如果一个类中包含抽象方法,那么这个类必须声明为抽象类。 + +抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。 + +```java +public abstract class AbstractClassExample { + + protected int x; + private int y; + + public abstract void func1(); + + public void func2() { + System.out.println("func2"); + } +} +``` + +```java +public class AbstractExtendClassExample extends AbstractClassExample { + @Override + public void func1() { + System.out.println("func1"); + } +} +``` + +```java +// AbstractClassExample ac1 = new AbstractClassExample(); // 'AbstractClassExample' is abstract; cannot be instantiated +AbstractClassExample ac2 = new AbstractExtendClassExample(); +ac2.func1(); +``` + +**2. 接口** + +接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现。 + +从 Java 8 开始,接口也可以拥有默认的方法实现,这是因为不支持默认方法的接口的维护成本太高了。在 Java 8 之前,如果一个接口想要添加新的方法,那么要修改所有实现了该接口的类。 + +接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected。 + +接口的字段默认都是 static 和 final 的。 + +```java +public interface InterfaceExample { + + void func1(); + + default void func2(){ + System.out.println("func2"); + } + + int x = 123; + // int y; // Variable 'y' might not have been initialized + public int z = 0; // Modifier 'public' is redundant for interface fields + // private int k = 0; // Modifier 'private' not allowed here + // protected int l = 0; // Modifier 'protected' not allowed here + // private void fun3(); // Modifier 'private' not allowed here +} +``` + +```java +public class InterfaceImplementExample implements InterfaceExample { + @Override + public void func1() { + System.out.println("func1"); + } +} +``` + +```java +// InterfaceExample ie1 = new InterfaceExample(); // 'InterfaceExample' is abstract; cannot be instantiated +InterfaceExample ie2 = new InterfaceImplementExample(); +ie2.func1(); +System.out.println(InterfaceExample.x); +``` + +**3. 比较** + +- 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。 +- 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。 +- 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。 +- 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。 + +**4. 使用选择** + +使用接口: + +- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法; +- 需要使用多重继承。 + +使用抽象类: + +- 需要在几个相关的类中共享代码。 +- 需要能控制继承来的成员的访问权限,而不是都为 public。 +- 需要继承非静态和非常量字段。 + +在很多情况下,接口优先于抽象类。因为接口没有抽象类严格的类层次结构要求,可以灵活地为一个类添加行为。并且从 Java 8 开始,接口也可以有默认的方法实现,使得修改接口的成本也变的很低。 + +- [Abstract Methods and Classes](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) +- [深入理解 abstract class 和 interface](https://www.ibm.com/developerworks/cn/java/l-javainterface-abstract/) +- [When to Use Abstract Class and Interface](https://dzone.com/articles/when-to-use-abstract-class-and-intreface) + + +## super + +- 访问父类的构造函数:可以使用 super() 函数访问父类的构造函数,从而委托父类完成一些初始化的工作。 +- 访问父类的成员:如果子类重写了父类的某个方法,可以通过使用 super 关键字来引用父类的方法实现。 + +```java +public class SuperExample { + + protected int x; + protected int y; + + public SuperExample(int x, int y) { + this.x = x; + this.y = y; + } + + public void func() { + System.out.println("SuperExample.func()"); + } +} +``` + +```java +public class SuperExtendExample extends SuperExample { + + private int z; + + public SuperExtendExample(int x, int y, int z) { + super(x, y); + this.z = z; + } + + @Override + public void func() { + super.func(); + System.out.println("SuperExtendExample.func()"); + } +} +``` + +```java +SuperExample e = new SuperExtendExample(1, 2, 3); +e.func(); +``` + +```html +SuperExample.func() +SuperExtendExample.func() +``` + +[Using the Keyword super](https://docs.oracle.com/javase/tutorial/java/IandI/super.html) + +## 重写与重载 + +**1. 重写(Override)** + +存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。 + +为了满足里式替换原则,重写有有以下两个限制: + +使用 @Override 注解,可以让编译器帮忙检查是否满足上面的三个限制条件。 + +下面的示例中,SubClass 为 SuperClass 的子类,SubClass 重写了 SuperClass 的 func() 方法。其中: + +- 子类方法访问权限为 public,大于父类的 protected。 +- 子类的返回类型为 ArrayList,是父类返回类型 List 的子类。 +- 子类抛出的异常类型为 Exception,是父类抛出异常 Throwable 的子类。 +- 子类重写方法使用 @Override 注解,从而让编译器自动检查是否满足限制条件。 + +```java +class SuperClass { + protected List func() throws Throwable { + return new ArrayList<>(); + } +} + +class SubClass extends SuperClass { + @Override + public ArrayList func() throws Exception { + return new ArrayList<>(); + } +} +``` + +**2. 重载(Overload)** + +存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。 + +应该注意的是,返回值不同,其它都相同不算是重载。 + +**3. 实例** + +```java +class A { + public String show(D obj) { + return ("A and D"); + } + + public String show(A obj) { + return ("A and A"); + } +} + +class B extends A { + public String show(B obj) { + return ("B and B"); + } + + public String show(A obj) { + return ("B and A"); + } +} + +class C extends B { +} + +class D extends B { +} +``` + +```java +public class Test { + + public static void main(String[] args) { + A a1 = new A(); + A a2 = new B(); + B b = new B(); + C c = new C(); + D d = new D(); + System.out.println(a1.show(b)); // A and A + System.out.println(a1.show(c)); // A and A + System.out.println(a1.show(d)); // A and D + System.out.println(a2.show(b)); // B and A + System.out.println(a2.show(c)); // B and A + System.out.println(a2.show(d)); // A and D + System.out.println(b.show(b)); // B and B + System.out.println(b.show(c)); // B and B + System.out.println(b.show(d)); // A and D + } +} +``` + +涉及到重写时,方法调用的优先级为: + +- this.show(O) +- super.show(O) +- this.show((super)O) +- super.show((super)O) + +# 五、Object 通用方法 + +## 概览 + +```java + +public native int hashCode() + +public boolean equals(Object obj) + +protected native Object clone() throws CloneNotSupportedException + +public String toString() + +public final native Class getClass() + +protected void finalize() throws Throwable {} + +public final native void notify() + +public final native void notifyAll() + +public final native void wait(long timeout) throws InterruptedException + +public final void wait(long timeout, int nanos) throws InterruptedException + +public final void wait() throws InterruptedException +``` + +## equals() + +**1. 等价关系** + +Ⅰ 自反性 + +```java +x.equals(x); // true +``` + +Ⅱ 对称性 + +```java +x.equals(y) == y.equals(x); // true +``` + +Ⅲ 传递性 + +```java +if (x.equals(y) && y.equals(z)) + x.equals(z); // true; +``` + +Ⅳ 一致性 + +多次调用 equals() 方法结果不变 + +```java +x.equals(y) == x.equals(y); // true +``` + +Ⅴ 与 null 的比较 + +对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false + +```java +x.equals(null); // false; +``` + +**2. 等价与相等** + +- 对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。 +- 对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。 + +```java +Integer x = new Integer(1); +Integer y = new Integer(1); +System.out.println(x.equals(y)); // true +System.out.println(x == y); // false +``` + +**3. 实现** + +- 检查是否为同一个对象的引用,如果是直接返回 true; +- 检查是否是同一个类型,如果不是,直接返回 false; +- 将 Object 对象进行转型; +- 判断每个关键域是否相等。 + +```java +public class EqualExample { + + private int x; + private int y; + private int z; + + public EqualExample(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EqualExample that = (EqualExample) o; + + if (x != that.x) return false; + if (y != that.y) return false; + return z == that.z; + } +} +``` + +## hashCode() + +hashCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。 + +在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象散列值也相等。 + +下面的代码中,新建了两个等价的对象,并将它们添加到 HashSet 中。我们希望将这两个对象当成一样的,只在集合中添加一个对象,但是因为 EqualExample 没有实现 hasCode() 方法,因此这两个对象的散列值是不同的,最终导致集合添加了两个等价的对象。 + +```java +EqualExample e1 = new EqualExample(1, 1, 1); +EqualExample e2 = new EqualExample(1, 1, 1); +System.out.println(e1.equals(e2)); // true +HashSet set = new HashSet<>(); +set.add(e1); +set.add(e2); +System.out.println(set.size()); // 2 +``` + +理想的散列函数应当具有均匀性,即不相等的对象应当均匀分布到所有可能的散列值上。这就要求了散列函数要把所有域的值都考虑进来。可以将每个域都当成 R 进制的某一位,然后组成一个 R 进制的整数。R 一般取 31,因为它是一个奇素数,如果是偶数的话,当出现乘法溢出,信息就会丢失,因为与 2 相乘相当于向左移一位。 + +一个数与 31 相乘可以转换成移位和减法:`31*x == (x<<5)-x`,编译器会自动进行这个优化。 + +```java +@Override +public int hashCode() { + int result = 17; + result = 31 * result + x; + result = 31 * result + y; + result = 31 * result + z; + return result; +} +``` + +## toString() + +默认返回 ToStringExample@4554617c 这种形式,其中 @ 后面的数值为散列码的无符号十六进制表示。 + +```java +public class ToStringExample { + + private int number; + + public ToStringExample(int number) { + this.number = number; + } +} +``` + +```java +ToStringExample example = new ToStringExample(123); +System.out.println(example.toString()); +``` + +```html +ToStringExample@4554617c +``` + +## clone() + +**1. cloneable** + +clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。 + +```java +public class CloneExample { + private int a; + private int b; +} +``` + +```java +CloneExample e1 = new CloneExample(); +// CloneExample e2 = e1.clone(); // 'clone()' has protected access in 'java.lang.Object' +``` + +重写 clone() 得到以下实现: + +```java +public class CloneExample { + private int a; + private int b; + + @Override + public CloneExample clone() throws CloneNotSupportedException { + return (CloneExample)super.clone(); + } +} +``` + +```java +CloneExample e1 = new CloneExample(); +try { + CloneExample e2 = e1.clone(); +} catch (CloneNotSupportedException e) { + e.printStackTrace(); +} +``` + +```html +java.lang.CloneNotSupportedException: CloneExample +``` + +以上抛出了 CloneNotSupportedException,这是因为 CloneExample 没有实现 Cloneable 接口。 + +应该注意的是,clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。 + +```java +public class CloneExample implements Cloneable { + private int a; + private int b; + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } +} +``` + +**2. 浅拷贝** + +拷贝对象和原始对象的引用类型引用同一个对象。 + +```java +public class ShallowCloneExample implements Cloneable { + + private int[] arr; + + public ShallowCloneExample() { + arr = new int[10]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i; + } + } + + public void set(int index, int value) { + arr[index] = value; + } + + public int get(int index) { + return arr[index]; + } + + @Override + protected ShallowCloneExample clone() throws CloneNotSupportedException { + return (ShallowCloneExample) super.clone(); + } +} +``` + +```java +ShallowCloneExample e1 = new ShallowCloneExample(); +ShallowCloneExample e2 = null; +try { + e2 = e1.clone(); +} catch (CloneNotSupportedException e) { + e.printStackTrace(); +} +e1.set(2, 222); +System.out.println(e2.get(2)); // 222 +``` + +**3. 深拷贝** + +拷贝对象和原始对象的引用类型引用不同对象。 + +```java +public class DeepCloneExample implements Cloneable { + + private int[] arr; + + public DeepCloneExample() { + arr = new int[10]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i; + } + } + + public void set(int index, int value) { + arr[index] = value; + } + + public int get(int index) { + return arr[index]; + } + + @Override + protected DeepCloneExample clone() throws CloneNotSupportedException { + DeepCloneExample result = (DeepCloneExample) super.clone(); + result.arr = new int[arr.length]; + for (int i = 0; i < arr.length; i++) { + result.arr[i] = arr[i]; + } + return result; + } +} +``` + +```java +DeepCloneExample e1 = new DeepCloneExample(); +DeepCloneExample e2 = null; +try { + e2 = e1.clone(); +} catch (CloneNotSupportedException e) { + e.printStackTrace(); +} +e1.set(2, 222); +System.out.println(e2.get(2)); // 2 +``` + +**4. clone() 的替代方案** + +使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。 + +```java +public class CloneConstructorExample { + + private int[] arr; + + public CloneConstructorExample() { + arr = new int[10]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i; + } + } + + public CloneConstructorExample(CloneConstructorExample original) { + arr = new int[original.arr.length]; + for (int i = 0; i < original.arr.length; i++) { + arr[i] = original.arr[i]; + } + } + + public void set(int index, int value) { + arr[index] = value; + } + + public int get(int index) { + return arr[index]; + } +} +``` + +```java +CloneConstructorExample e1 = new CloneConstructorExample(); +CloneConstructorExample e2 = new CloneConstructorExample(e1); +e1.set(2, 222); +System.out.println(e2.get(2)); // 2 +``` + +# 六、关键字 + +## final + +**1. 数据** + +声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。 + +- 对于基本类型,final 使数值不变; +- 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。 + +```java +final int x = 1; +// x = 2; // cannot assign value to final variable 'x' +final A y = new A(); +y.a = 1; +``` + +**2. 方法** + +声明方法不能被子类重写。 + +private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。 + +**3. 类** + +声明类不允许被继承。 + +## static + +**1. 静态变量** + +- 静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份。 +- 实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。 + +```java +public class A { + + private int x; // 实例变量 + private static int y; // 静态变量 + + public static void main(String[] args) { + // int x = A.x; // Non-static field 'x' cannot be referenced from a static context + A a = new A(); + int x = a.x; + int y = A.y; + } +} +``` + +**2. 静态方法** + +静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。 + +```java +public abstract class A { + public static void func1(){ + } + // public abstract static void func2(); // Illegal combination of modifiers: 'abstract' and 'static' +} +``` + +只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。 + +```java +public class A { + + private static int x; + private int y; + + public static void func1(){ + int a = x; + // int b = y; // Non-static field 'y' cannot be referenced from a static context + // int b = this.y; // 'A.this' cannot be referenced from a static context + } +} +``` + +**3. 静态语句块** + +静态语句块在类初始化时运行一次。 + +```java +public class A { + static { + System.out.println("123"); + } + + public static void main(String[] args) { + A a1 = new A(); + A a2 = new A(); + } +} +``` + +```html +123 +``` + +**4. 静态内部类** + +非静态内部类依赖于外部类的实例,而静态内部类不需要。 + +```java +public class OuterClass { + + class InnerClass { + } + + static class StaticInnerClass { + } + + public static void main(String[] args) { + // InnerClass innerClass = new InnerClass(); // 'OuterClass.this' cannot be referenced from a static context + OuterClass outerClass = new OuterClass(); + InnerClass innerClass = outerClass.new InnerClass(); + StaticInnerClass staticInnerClass = new StaticInnerClass(); + } +} +``` + +静态内部类不能访问外部类的非静态的变量和方法。 + +**5. 静态导包** + +在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。 + +```java +import static com.xxx.ClassName.* +``` + +**6. 初始化顺序** + +静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。 + +```java +public static String staticField = "静态变量"; +``` + +```java +static { + System.out.println("静态语句块"); +} +``` + +```java +public String field = "实例变量"; +``` + +```java +{ + System.out.println("普通语句块"); +} +``` + +最后才是构造函数的初始化。 + +```java +public InitialOrderTest() { + System.out.println("构造函数"); +} +``` + +存在继承的情况下,初始化顺序为: + +- 父类(静态变量、静态语句块) +- 子类(静态变量、静态语句块) +- 父类(实例变量、普通语句块) +- 父类(构造函数) +- 子类(实例变量、普通语句块) +- 子类(构造函数) + + +# 七、反射 + +每个类都有一个 **Class** 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。 + +类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 `Class.forName("com.mysql.jdbc.Driver")` 这种方式来控制类的加载,该方法会返回一个 Class 对象。 + +反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。 + +Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类: + +- **Field** :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段; +- **Method** :可以使用 invoke() 方法调用与 Method 对象关联的方法; +- **Constructor** :可以用 Constructor 创建新的对象。 + +**反射的优点:** + +* **可扩展性** :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。 +* **类浏览器和可视化开发环境** :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。 +* **调试器和测试工具** : 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。 + +**反射的缺点:** + +尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。 + +* **性能开销** :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。 + +* **安全限制** :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。 + +* **内部暴露** :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。 + + +- [Trail: The Reflection API](https://docs.oracle.com/javase/tutorial/reflect/index.html) +- [深入解析 Java 反射(1)- 基础](http://www.sczyh30.com/posts/Java/java-reflection-1/) + +# 八、异常 + +Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: **Error** 和 **Exception**。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种: + +- **受检异常** :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复; +- **非受检异常** :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。 + +

+ +- [Java 入门之异常处理](https://www.tianmaying.com/tutorial/Java-Exception) +- [Java 异常的面试问题及答案 -Part 1](http://www.importnew.com/7383.html) + +# 九、泛型 + +```java +public class Box { + // T stands for "Type" + private T t; + public void set(T t) { this.t = t; } + public T get() { return t; } +} +``` + +- [Java 泛型详解](http://www.importnew.com/24029.html) +- [10 道 Java 泛型面试题](https://cloud.tencent.com/developer/article/1033693) + +# 十、注解 + +Java 注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。 + +[注解 Annotation 实现原理与自定义注解例子](https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html) + +# 十一、特性 + +## Java 各版本的新特性 + +**New highlights in Java SE 8** + +1. Lambda Expressions +2. Pipelines and Streams +3. Date and Time API +4. Default Methods +5. Type Annotations +6. Nashhorn JavaScript Engine +7. Concurrent Accumulators +8. Parallel operations +9. PermGen Error Removed + +**New highlights in Java SE 7** + +1. Strings in Switch Statement +2. Type Inference for Generic Instance Creation +3. Multiple Exception Handling +4. Support for Dynamic Languages +5. Try with Resources +6. Java nio Package +7. Binary Literals, Underscore in literals +8. Diamond Syntax + +- [Difference between Java 1.8 and Java 1.7?](http://www.selfgrowth.com/articles/difference-between-java-18-and-java-17) +- [Java 8 特性](http://www.importnew.com/19345.html) + +## Java 与 C++ 的区别 + +- Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 为了兼容 C 即支持面向对象也支持面向过程。 +- Java 通过虚拟机从而实现跨平台特性,但是 C++ 依赖于特定的平台。 +- Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。 +- Java 支持自动垃圾回收,而 C++ 需要手动回收。 +- Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。 +- Java 不支持操作符重载,虽然可以对两个 String 对象执行加法运算,但是这是语言内置支持的操作,不属于操作符重载,而 C++ 可以。 +- Java 的 goto 是保留字,但是不可用,C++ 可以使用 goto。 +- Java 不支持条件编译,C++ 通过 #ifdef #ifndef 等预处理命令从而实现条件编译。 + +[What are the main differences between Java and C++?](http://cs-fundamentals.com/tech-interview/java/differences-between-java-and-cpp.php) + +## JRE or JDK + +- JRE is the JVM program, Java application need to run on JRE. +- JDK is a superset of JRE, JRE + tools for developing java programs. e.g, it provides the compiler "javac" + +# 参考资料 + +- Eckel B. Java 编程思想[M]. 机械工业出版社, 2002. +- Bloch J. Effective java[M]. Addison-Wesley Professional, 2017. + + + + +
🎨️欢迎关注我的公众号 CyC2018,在公众号后台回复关键字 **资料** 可领取复习大纲,这份大纲是我花了一整年时间整理的面试知识点列表,不仅系统整理了面试知识点,而且标注了各个知识点的重要程度,从而帮你理清多而杂的面试知识点。可以说我基本是按照这份大纲来进行复习的,这份大纲对我拿到了 BAT 头条等 Offer 起到很大的帮助。你们完全可以和我一样根据大纲上列的知识点来进行复习,就不用看很多不重要的内容,也可以知道哪些内容很重要从而多安排一些复习时间。

+
diff --git a/notes/Java 容器.md b/notes/Java 容器.md new file mode 100644 index 00000000..e6fbc353 --- /dev/null +++ b/notes/Java 容器.md @@ -0,0 +1,1117 @@ + +* [一、概览](#一概览) + * [Collection](#collection) + * [Map](#map) +* [二、容器中的设计模式](#二容器中的设计模式) + * [迭代器模式](#迭代器模式) + * [适配器模式](#适配器模式) +* [三、源码分析](#三源码分析) + * [ArrayList](#arraylist) + * [Vector](#vector) + * [CopyOnWriteArrayList](#copyonwritearraylist) + * [LinkedList](#linkedlist) + * [HashMap](#hashmap) + * [ConcurrentHashMap](#concurrenthashmap) + * [LinkedHashMap](#linkedhashmap) + * [WeakHashMap](#weakhashmap) +* [参考资料](#参考资料) + + + +# 一、概览 + +容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。 + +## Collection + +

+ +### 1. Set + +- TreeSet:基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。 + +- HashSet:基于哈希表实现,支持快速查找,但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。 + +- LinkedHashSet:具有 HashSet 的查找效率,且内部使用双向链表维护元素的插入顺序。 + +### 2. List + +- ArrayList:基于动态数组实现,支持随机访问。 + +- Vector:和 ArrayList 类似,但它是线程安全的。 + +- LinkedList:基于双向链表实现,只能顺序访问,但是可以快速地在链表中间插入和删除元素。不仅如此,LinkedList 还可以用作栈、队列和双向队列。 + +### 3. Queue + +- LinkedList:可以用它来实现双向队列。 + +- PriorityQueue:基于堆结构实现,可以用它来实现优先队列。 + +## Map + +

+ +- TreeMap:基于红黑树实现。 + +- HashMap:基于哈希表实现。 + +- HashTable:和 HashMap 类似,但它是线程安全的,这意味着同一时刻多个线程可以同时写入 HashTable 并且不会导致数据不一致。它是遗留类,不应该去使用它。现在可以使用 ConcurrentHashMap 来支持线程安全,并且 ConcurrentHashMap 的效率会更高,因为 ConcurrentHashMap 引入了分段锁。 + +- LinkedHashMap:使用双向链表来维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序。 + + +# 二、容器中的设计模式 + +## 迭代器模式 + +

+ +Collection 继承了 Iterable 接口,其中的 iterator() 方法能够产生一个 Iterator 对象,通过这个对象就可以迭代遍历 Collection 中的元素。 + +从 JDK 1.5 之后可以使用 foreach 方法来遍历实现了 Iterable 接口的聚合对象。 + +```java +List list = new ArrayList<>(); +list.add("a"); +list.add("b"); +for (String item : list) { + System.out.println(item); +} +``` + +## 适配器模式 + +java.util.Arrays#asList() 可以把数组类型转换为 List 类型。 + +```java +@SafeVarargs +public static List asList(T... a) +``` + +应该注意的是 asList() 的参数为泛型的变长参数,不能使用基本类型数组作为参数,只能使用相应的包装类型数组。 + +```java +Integer[] arr = {1, 2, 3}; +List list = Arrays.asList(arr); +``` + +也可以使用以下方式调用 asList(): + +```java +List list = Arrays.asList(1, 2, 3); +``` + +# 三、源码分析 + +如果没有特别说明,以下源码分析基于 JDK 1.8。 + +在 IDEA 中 double shift 调出 Search EveryWhere,查找源码文件,找到之后就可以阅读源码。 + +## ArrayList + + +### 1. 概览 + +因为 ArrayList 是基于数组实现的,所以支持快速随机访问。RandomAccess 接口标识着该类支持快速随机访问。 + +```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable +``` + +数组的默认大小为 10。 + +```java +private static final int DEFAULT_CAPACITY = 10; +``` + +

+ +### 2. 扩容 + +添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,如果不够时,需要使用 grow() 方法进行扩容,新容量的大小为 `oldCapacity + (oldCapacity >> 1)`,也就是旧容量的 1.5 倍。 + +扩容操作需要调用 `Arrays.copyOf()` 把原数组整个复制到新数组中,这个操作代价很高,因此最好在创建 ArrayList 对象时就指定大概的容量大小,减少扩容操作的次数。 + +```java +public boolean add(E e) { + ensureCapacityInternal(size + 1); // Increments modCount!! + elementData[size++] = e; + return true; +} + +private void ensureCapacityInternal(int minCapacity) { + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); + } + ensureExplicitCapacity(minCapacity); +} + +private void ensureExplicitCapacity(int minCapacity) { + modCount++; + // overflow-conscious code + if (minCapacity - elementData.length > 0) + grow(minCapacity); +} + +private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); +} +``` + +### 3. 删除元素 + +需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看出 ArrayList 删除元素的代价是非常高的。 + +```java +public E remove(int index) { + rangeCheck(index); + modCount++; + E oldValue = elementData(index); + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, numMoved); + elementData[--size] = null; // clear to let GC do its work + return oldValue; +} +``` + +### 4. Fail-Fast + +modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。 + +在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。 + +```java +private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException{ + // Write out element count, and any hidden stuff + int expectedModCount = modCount; + s.defaultWriteObject(); + + // Write out size as capacity for behavioural compatibility with clone() + s.writeInt(size); + + // Write out all elements in the proper order. + for (int i=0; i