diff --git a/README.md b/README.md index 8e214899..786e0ccf 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ ### 基础 -**知识点/面试题:**(必看:+1: ) +**知识点/面试题** : (必看:+1: ) 1. **[Java 基础知识](docs/java/basis/Java基础知识.md)** 2. **[Java 基础知识疑难点/易错点](docs/java/basis/Java基础知识疑难点.md)** @@ -71,11 +71,11 @@ **重要知识点详解:** -2. **线程池**:[Java 线程池学习总结](./docs/java/multi-thread/java线程池学习总结.md)、[拿来即用的线程池最佳实践](./docs/java/multi-thread/拿来即用的线程池最佳实践.md) -4. [ ThreadLocal 关键字解析](docs/java/multi-thread/万字详解ThreadLocal关键字.md) -5. [并发容器总结](docs/java/multi-thread/并发容器总结.md) -6. [JUC 中的 Atomic 原子类总结](docs/java/multi-thread/Atomic原子类总结.md) -7. [AQS 原理以及 AQS 同步组件总结](docs/java/multi-thread/AQS原理以及AQS同步组件总结.md) +1. **线程池**:[Java 线程池学习总结](./docs/java/multi-thread/java线程池学习总结.md)、[拿来即用的线程池最佳实践](./docs/java/multi-thread/拿来即用的线程池最佳实践.md) +2. [ ThreadLocal 关键字解析](docs/java/multi-thread/万字详解ThreadLocal关键字.md) +3. [并发容器总结](docs/java/multi-thread/并发容器总结.md) +4. [JUC 中的 Atomic 原子类总结](docs/java/multi-thread/Atomic原子类总结.md) +5. [AQS 原理以及 AQS 同步组件总结](docs/java/multi-thread/AQS原理以及AQS同步组件总结.md) ### JVM (必看 :+1:) @@ -95,28 +95,38 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle 1. **Java 8** :[Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md) 、[Java 8 学习资源推荐](docs/java/new-features/Java8教程推荐.md)、[Java8 forEach 指南](docs/java/new-features/Java8foreach指南.md) 2. **Java9~Java15** : [一文带你看遍 JDK9~15 的重要新特性!](./docs/java/new-features/java新特性总结.md) +### 小技巧 + +1. [JAD 反编译](docs/java/tips/JAD反编译tricks.md) +2. [手把手教你定位常见 Java 性能问题](./docs/java/tips/手把手教你定位常见Java性能问题.md) + ## 计算机基础 👉 **[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。 ### 操作系统 -1. [操作系统常见问题总结!](docs/operating-system/basis.md) -2. [后端程序员必备的 Linux 基础知识](docs/operating-system/linux.md) -3. [Shell 编程入门](docs/operating-system/Shell.md) +1. [操作系统常见问题总结!](docs/cs-basics/operating-system/basis.md) +2. [后端程序员必备的 Linux 基础知识总结](docs/cs-basics/operating-system/linux.md) +3. [Shell 编程入门](docs/cs-basics/operating-system/Shell.md) ### 网络 -1. [计算机网络常见面试题](docs/network/计算机网络.md) -2. [计算机网络基础知识总结](docs/network/计算机网络知识总结.md) +1. [计算机网络常见面试题](docs/cs-basics/network/计算机网络.md) +2. [计算机网络基础知识总结](docs/cs-basics/network/计算机网络知识总结.md) ### 数据结构 -- **图解数据结构:** - 1. [线性数据结构 :数组、链表、栈、队列](docs/dataStructures-algorithms/data-structure/线性数据结构.md) - 2. [图](docs/dataStructures-algorithms/data-structure/图.md) - 3. [堆](docs/dataStructures-algorithms/data-structure/堆.md) -- [不了解布隆过滤器?一文给你整的明明白白!](docs/dataStructures-algorithms/data-structure/bloom-filter.md) +**图解数据结构:** + +1. [线性数据结构 :数组、链表、栈、队列](docs/cs-basics/data-structure/线性数据结构.md) +2. [图](docs/cs-basics/data-structure/图.md) +3. [堆](docs/cs-basics/data-structure/堆.md) +4. [树](docs/cs-basics/data-structure/树.md) :重点关注[红黑树](docs/cs-basics/data-structure/红黑树.md)、B-,B+,B*树、LSM树 + +其他常用数据结构 : + +1. [布隆过滤器](docs/cs-basics/data-structure/bloom-filter.md) ### 算法 @@ -125,11 +135,13 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle - [算法学习书籍+资源推荐](https://www.zhihu.com/question/323359308/answer/1545320858) 。 - [如何刷Leetcode?](https://www.zhihu.com/question/31092580/answer/1534887374) -**常见算法问题总结:** +**常见算法问题总结** : -- [几道常见的字符串算法题总结 ](docs/dataStructures-algorithms/几道常见的字符串算法题.md) -- [几道常见的链表算法题总结 ](docs/dataStructures-algorithms/几道常见的链表算法题.md) -- [剑指 offer 部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) +- [几道常见的字符串算法题总结 ](docs/cs-basics/algorithms/几道常见的字符串算法题.md) +- [几道常见的链表算法题总结 ](docs/cs-basics/algorithms/几道常见的链表算法题.md) +- [剑指 offer 部分编程题](docs/cs-basics/algorithms/剑指offer部分编程题.md) + +另外,[GeeksforGeeks]( https://www.geeksforgeeks.org/fundamentals-of-algorithms/) 这个网站总结了常见的算法 ,比较全面系统。 ## 数据库 @@ -354,7 +366,6 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ## 工具 -1. **Java** :[JAD 反编译](docs/java/JAD反编译tricks.md)、[手把手教你定位常见 Java 性能问题](./docs/java/手把手教你定位常见Java性能问题.md) 2. **Git** :[Git 入门](docs/tools/Git.md) 3. **Github** : [Github小技巧](docs/tools/Github技巧.md) 4. **Docker** : [Docker 基本概念解读](docs/tools/Docker.md) 、[Docker从入门到上手干事](docs/tools/Docker从入门到实战.md) @@ -378,7 +389,8 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读: ### 待办 -- [ ] 数据结构总结重构 +- [ ] 计算机网络知识点完善 +- [ ] 分布式常见理论和算法总结完善 ### 捐赠支持 diff --git a/docs/dataStructures-algorithms/几道常见的字符串算法题.md b/docs/cs-basics/algorithms/几道常见的字符串算法题.md similarity index 100% rename from docs/dataStructures-algorithms/几道常见的字符串算法题.md rename to docs/cs-basics/algorithms/几道常见的字符串算法题.md diff --git a/docs/dataStructures-algorithms/几道常见的链表算法题.md b/docs/cs-basics/algorithms/几道常见的链表算法题.md similarity index 100% rename from docs/dataStructures-algorithms/几道常见的链表算法题.md rename to docs/cs-basics/algorithms/几道常见的链表算法题.md diff --git a/docs/dataStructures-algorithms/剑指offer部分编程题.md b/docs/cs-basics/algorithms/剑指offer部分编程题.md similarity index 100% rename from docs/dataStructures-algorithms/剑指offer部分编程题.md rename to docs/cs-basics/algorithms/剑指offer部分编程题.md diff --git a/docs/dataStructures-algorithms/data-structure/bloom-filter.md b/docs/cs-basics/data-structure/bloom-filter.md similarity index 74% rename from docs/dataStructures-algorithms/data-structure/bloom-filter.md rename to docs/cs-basics/data-structure/bloom-filter.md index bfb7efe7..9b5afd6d 100644 --- a/docs/dataStructures-algorithms/data-structure/bloom-filter.md +++ b/docs/cs-basics/data-structure/bloom-filter.md @@ -6,18 +6,18 @@ 2. 布隆过滤器的原理介绍。 3. 布隆过滤器使用场景。 4. 通过 Java 编程手动实现布隆过滤器。 -5. 利用Google开源的Guava中自带的布隆过滤器。 +5. 利用 Google 开源的 Guava 中自带的布隆过滤器。 6. Redis 中的布隆过滤器。 ### 1.什么是布隆过滤器? 首先,我们需要了解布隆过滤器的概念。 -布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于1970年提出的。我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。 +布隆过滤器(Bloom Filter)是一个叫做 Bloom 的老哥于 1970 年提出的。我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。 ![布隆过滤器示意图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/布隆过滤器-bit数组.png) -位数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000Bit / 8 = 125000 Byte = 125000/1024 kb ≈ 122kb 的空间。 +位数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000Bit / 8 = 125000 Byte = 125000/1024 kb ≈ 122kb 的空间。 总结:**一个名叫 Bloom 的人提出了一种来检索元素是否在给定大集合中的数据结构,这种数据结构是高效且性能很好的,但缺点是具有一定的错误识别率和删除难度。并且,理论情况下,添加到集合中的元素越多,误报的可能性就越大。** @@ -35,11 +35,9 @@ 举个简单的例子: - - ![布隆过滤器hash计算](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/布隆过滤器-hash运算.png) -如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 +如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为 0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。 如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。 @@ -49,7 +47,7 @@ ### 3.布隆过滤器使用场景 -1. 判断给定数据是否存在:比如判断一个数字是否存在于包含大量数字的数字集中(数字集很大,5亿以上!)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤、黑名单功能等等。 +1. 判断给定数据是否存在:比如判断一个数字是否存在于包含大量数字的数字集中(数字集很大,5 亿以上!)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤、黑名单功能等等。 2. 去重:比如爬给定网址的时候对已经爬取过的 URL 去重。 ### 4.通过 Java 编程手动实现布隆过滤器 @@ -206,7 +204,7 @@ true 实际使用如下: -我们创建了一个最多存放 最多 1500个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) +我们创建了一个最多存放 最多 1500 个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之(0.01) ```java // 创建布隆过滤器对象 @@ -224,7 +222,7 @@ System.out.println(filter.mightContain(1)); System.out.println(filter.mightContain(2)); ``` -在我们的示例中,当`mightContain()` 方法返回 *true* 时,我们可以99%确定该元素在过滤器中,当过滤器返回 *false* 时,我们可以100%确定该元素不存在于过滤器中。 +在我们的示例中,当`mightContain()` 方法返回 _true_ 时,我们可以 99%确定该元素在过滤器中,当过滤器返回 _false_ 时,我们可以 100%确定该元素不存在于过滤器中。 **Guava 提供的布隆过滤器的实现还是很不错的(想要详细了解的可以看一下它的源码实现),但是它有一个重大的缺陷就是只能单机使用(另外,容量扩展也不容易),而现在互联网一般都是分布式的场景。为了解决这个问题,我们就需要用到 Redis 中的布隆过滤器了。** @@ -234,17 +232,17 @@ System.out.println(filter.mightContain(2)); Redis v4.0 之后有了 Module(模块/插件) 功能,Redis Modules 让 Redis 可以使用外部模块扩展其功能 。布隆过滤器就是其中的 Module。详情可以查看 Redis 官方对 Redis Modules 的介绍 :https://redis.io/modules -另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom。其他还有: +另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module,地址:https://github.com/RedisBloom/RedisBloom。其他还有: - redis-lua-scaling-bloom-filter(lua 脚本实现):https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter -- pyreBloom(Python中的快速Redis 布隆过滤器) :https://github.com/seomoz/pyreBloom +- pyreBloom(Python 中的快速 Redis 布隆过滤器) :https://github.com/seomoz/pyreBloom - ...... RedisBloom 提供了多种语言的客户端支持,包括:Python、Java、JavaScript 和 PHP。 -#### 6.2 使用Docker安装 +#### 6.2 使用 Docker 安装 -如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 +如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案(这是我平常解决问题的一种方式,分享一下),具体地址:https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。 **具体操作如下:** @@ -252,15 +250,15 @@ RedisBloom 提供了多种语言的客户端支持,包括:Python、Java、Ja ➜ ~ docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest ➜ ~ docker exec -it redis-redisbloom bash root@21396d02c252:/data# redis-cli -127.0.0.1:6379> +127.0.0.1:6379> ``` -#### 6.3常用命令一览 +#### 6.3 常用命令一览 -> 注意: key : 布隆过滤器的名称,item : 添加的元素。 +> 注意: key : 布隆过滤器的名称,item : 添加的元素。 -1. **`BF.ADD `**:将元素添加到布隆过滤器中,如果该过滤器尚不存在,则创建该过滤器。格式:`BF.ADD {key} {item}`。 -2. **`BF.MADD `** : 将一个或多个元素添加到“布隆过滤器”中,并创建一个尚不存在的过滤器。该命令的操作方式`BF.ADD`与之相同,只不过它允许多个输入并返回多个值。格式:`BF.MADD {key} {item} [item ...]` 。 +1. **`BF.ADD`**:将元素添加到布隆过滤器中,如果该过滤器尚不存在,则创建该过滤器。格式:`BF.ADD {key} {item}`。 +2. **`BF.MADD`** : 将一个或多个元素添加到“布隆过滤器”中,并创建一个尚不存在的过滤器。该命令的操作方式`BF.ADD`与之相同,只不过它允许多个输入并返回多个值。格式:`BF.MADD {key} {item} [item ...]` 。 3. **`BF.EXISTS` ** : 确定元素是否在布隆过滤器中存在。格式:`BF.EXISTS {key} {item}`。 4. **`BF.MEXISTS`** : 确定一个或者多个元素是否在布隆过滤器中存在格式:`BF.MEXISTS {key} {item} [item ...]`。 @@ -268,19 +266,19 @@ root@21396d02c252:/data# redis-cli 这个命令的格式如下: -`BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion] `。 +`BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion]`。 下面简单介绍一下每个参数的具体含义: 1. key:布隆过滤器的名称 -2. error_rate :误报的期望概率。这应该是介于0到1之间的十进制值。例如,对于期望的误报率0.1%(1000中为1),error_rate应该设置为0.001。该数字越接近零,则每个项目的内存消耗越大,并且每个操作的CPU使用率越高。 -3. capacity: 过滤器的容量。当实际存储的元素个数超过这个值之后,性能将开始下降。实际的降级将取决于超出限制的程度。随着过滤器元素数量呈指数增长,性能将线性下降。 +2. error_rate :误报的期望概率。这应该是介于 0 到 1 之间的十进制值。例如,对于期望的误报率 0.1%(1000 中为 1),error_rate 应该设置为 0.001。该数字越接近零,则每个项目的内存消耗越大,并且每个操作的 CPU 使用率越高。 +3. capacity: 过滤器的容量。当实际存储的元素个数超过这个值之后,性能将开始下降。实际的降级将取决于超出限制的程度。随着过滤器元素数量呈指数增长,性能将线性下降。 可选参数: -- expansion:如果创建了一个新的子过滤器,则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。 +- expansion:如果创建了一个新的子过滤器,则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为 2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。 -#### 6.4实际使用 +#### 6.4 实际使用 ```shell 127.0.0.1:6379> BF.ADD myFilter java @@ -294,4 +292,3 @@ root@21396d02c252:/data# redis-cli 127.0.0.1:6379> BF.EXISTS myFilter github (integer) 0 ``` - diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/图.png b/docs/cs-basics/data-structure/pictures/图/图.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/图.png rename to docs/cs-basics/data-structure/pictures/图/图.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索1.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索1.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索1.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索2.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索2.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索2.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索3.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索3.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索3.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索4.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索4.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索4.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索5.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索5.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索5.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索6.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索6.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索6.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.drawio b/docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.drawio rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.png b/docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/广度优先搜索图示.png rename to docs/cs-basics/data-structure/pictures/图/广度优先搜索图示.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.drawio b/docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.drawio rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.png b/docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接矩阵存储.png rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接矩阵存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.drawio b/docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.drawio rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.png b/docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/无向图的邻接表存储.png rename to docs/cs-basics/data-structure/pictures/图/无向图的邻接表存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.png b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储.png rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接矩阵存储的副本.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.drawio b/docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.drawio rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.png b/docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/有向图的邻接表存储.png rename to docs/cs-basics/data-structure/pictures/图/有向图的邻接表存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索1.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索1.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索1.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索2.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索2.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索2.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索3.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索3.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索3.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索4.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索4.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索4.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索5.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索5.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索5.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索6.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索6.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索6.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.drawio b/docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.drawio rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.png b/docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/图/深度优先搜索图示.png rename to docs/cs-basics/data-structure/pictures/图/深度优先搜索图示.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素1.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素2.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素3.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素3.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素4.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素5.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素5.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素6.png b/docs/cs-basics/data-structure/pictures/堆/删除堆顶元素6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/删除堆顶元素6.png rename to docs/cs-basics/data-structure/pictures/堆/删除堆顶元素6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素1.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素2.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素2.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素3.png b/docs/cs-basics/data-structure/pictures/堆/堆-插入元素3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆-插入元素3.png rename to docs/cs-basics/data-structure/pictures/堆/堆-插入元素3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png b/docs/cs-basics/data-structure/pictures/堆/堆1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆1.png rename to docs/cs-basics/data-structure/pictures/堆/堆1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png b/docs/cs-basics/data-structure/pictures/堆/堆2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆2.png rename to docs/cs-basics/data-structure/pictures/堆/堆2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序1.png b/docs/cs-basics/data-structure/pictures/堆/堆排序1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序1.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序2.png b/docs/cs-basics/data-structure/pictures/堆/堆排序2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序2.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png b/docs/cs-basics/data-structure/pictures/堆/堆排序3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序3.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png b/docs/cs-basics/data-structure/pictures/堆/堆排序4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序4.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序4.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序5.png b/docs/cs-basics/data-structure/pictures/堆/堆排序5.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序5.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序5.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序6.png b/docs/cs-basics/data-structure/pictures/堆/堆排序6.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆排序6.png rename to docs/cs-basics/data-structure/pictures/堆/堆排序6.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/堆的存储.png b/docs/cs-basics/data-structure/pictures/堆/堆的存储.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/堆的存储.png rename to docs/cs-basics/data-structure/pictures/堆/堆的存储.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png b/docs/cs-basics/data-structure/pictures/堆/建堆1.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆1.png rename to docs/cs-basics/data-structure/pictures/堆/建堆1.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png b/docs/cs-basics/data-structure/pictures/堆/建堆2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆2.png rename to docs/cs-basics/data-structure/pictures/堆/建堆2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆3.png b/docs/cs-basics/data-structure/pictures/堆/建堆3.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆3.png rename to docs/cs-basics/data-structure/pictures/堆/建堆3.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/堆/建堆4.png b/docs/cs-basics/data-structure/pictures/堆/建堆4.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/堆/建堆4.png rename to docs/cs-basics/data-structure/pictures/堆/建堆4.png diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio b/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio new file mode 100644 index 00000000..f8fe81d2 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/中序遍历.drawio @@ -0,0 +1 @@ +7Vtbk6I4FP41eZwukgBJHr1g727tVk1VV+30PNKSVmbQuIit7q/fBAISBLVbFHfa8sHkJORyzpcv5xwR4MFs8xj7i+lfIuARQFawAXgIEILQcuWXkmwzCWMkE0ziMNCddoKn8F+uhZaWrsKAL42OiRBREi5M4VjM53ycGDI/jsXa7PYqInPWhT/he4KnsR/tS7+FQTLNpBSRnfw3Hk6m+czQZVnLzM87650sp34g1iUR9gAexEIkWWm2GfBIKS/XS/bcqKG1WFjM58kpD6yenT8ev/39O3VCf/C2ZpuF7X/Ro7z50UpvGCA3kuP1X9SSk63Wg/vPSq2z/yrmyZdlaqWe7ICcxWbXKEsT9d3Lx5CLecmFWgnFiEiuThpRVvrraZjwp4U/Vi1riSMpmyazSNagLPrLRWbZ13DDA7WIMIoGIhJxOhB+feXueCzlyyQWP3mpJSDsxbKKyd94nPBNo/pgYRSJZi5mPIm3sot+gGBtRw1kzHR9XYKFFk1LiMhlvgbipBh5ZytZ0OZ6h+lQjemqKp4HPXUGZG0u5txUq9x3vH0uV76XK0O1b6uobXUtm4MHe6emoke5DrGKx/zABrA+zn484ckxjO7bpaR3p0bvuSzmkZ+Eb+Zy64yhZ/gqQrmRndktYpidWBV7ZtvUT5WPX3Ug5jwgaiMCkU1sN1+JHtYm1GzF5iyZkvZmSYFT6OTjWMKNNLBc+POPM0GJTDLBoJ4aClk23a/BGJSajGF3zRj2tazc/0RWdq0bs7JzLSsPP5GVHWRa2SEdW9m9lpUfP5GVmXtjVibn+nibMHkulb/nPp0s7xw8Vcn9u8IrLCpX9grt/4NX6FaAQuAHvUKKqIk4hq7q+NFzAVYbRFhH4JLD0irBEh6EZQcAc7oEGKneN+yjYYdDD4UdrNOwg52JvhZR4Z6ICtwlKiiCDy7GDrapdEgQNI3pUPjAIGO27AZtNw9c301J2D2AGIdada1XAkxOs5d3e7xP5Pa49MbcHliXljzX7zl8wdT7Pccusi78HqvelldyfMw8FWQmcCB8INAhiBIHOZhWhj/5zrJqh8nvLFq7hGsxEGpkIEU0LTKQfYSBsukaGEiSQWIeCZNB9JEp040W+VE4mcvqWCKYS3lfUUs49qOebpiFQRA1cVssVvNAMdmwLW5ilfSKtc9Ndg3e0cW4qTlX2jIA0B0AilOcyuXUOQCa06gtA8C9AyD1R28NAM0Z1pYBAO8ASC/8CgBo1wBw971R6QI+6arWoqkHESdTMRFzP/pTiIU2yA+eJFv9zoO/SkRDbsV6cDpKxuVvXHwwGXeys3meOeqypBcJCkefKCik1q0Fha3lKt+V2n5/Cr3N80dOPICdpqWgZQZsxIwKXYjrWt8bFbKDmUwJzy7zUnWZzIu4BM7dJZAthNyYS5APfHkAkDsAFBlUg4LOAdD8JmXLAMB3AKhLxb41ADQnBs/zQod9rzcalF/DOOhm/jIWJpXf2N3OLYz3/c1LhH35j+NZ1HdtlzPH8VGXM+vYVdCHarJwngP6Huh5wLOBjNV6EHguYBZgA+AhQNOCycnjInbanToZXzGG8f5BfAyT6epFjUk9wCjwGKAEMDkLVZOq6RxAKWCoiY31KoYFp8en0AK0a+8FORnrA+apQs8GdNjKJr8OR0dXL/crNSA9EbXfEWCuXotUvlIFAT1c0glRBUZSWwxAv5d2HqUFojrkx/rmOCzyX3jU98c/J6m8OrlUjT7D0Nb1UijeTz8theLQZEIb7zNhQXtnUqGs7v6SkoVHuz/2YO8/ \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历.png b/docs/cs-basics/data-structure/pictures/树/中序遍历.png new file mode 100644 index 00000000..3ad5782c Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/中序遍历.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio b/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio new file mode 100644 index 00000000..31e3097a --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/中序遍历2.drawio @@ -0,0 +1 @@ +5ZhNc5swEIZ/jY/uYLDBHGPsuIdmpmMfmhxlkEGtYKkQBvLrK1niq46bJm0Zpj6hfSWtpH12NSMmlheXW4bS6AECTCemEZQTaz0xzdnMsMVHKpVSXNdRQshIoAe1wp48Yy0aWs1JgLPeQA5AOUn7og9Jgn3e0xBjUPSHHYH2V01RiC+EvY/opfqFBDxS6tJ0Wv0jJmFUrzyzXdUTo3qwPkkWoQCKjmRtJpbHALhqxaWHqQxeHRc17/5Kb7MxhhP+OxN22UPg7CLH2z06MV1Pt0bxPNVeTojm+sAT06bC3+ogt8wrHQf7ey73uTpCwqfZmdKdGGAu0rLtFK1Qfu9qH2Izh1rUQWg8mmJ3AqIwVkVEON6nyJc9hcgjoUU8psKaiSbKUkX2SEocyE0QSj2gwM6OrOMR274v9Iwz+IY7PYHjHgyjWfyEGcfl1fDNGigimzHEmLNKDNET7DojdSLPa7vopIWWok5G1BrSiRg2nltWoqFxvQGdeRVdlqLk/fQ6CaAE72WcjaaW+z8oO+7IKFtDUV7dEOW5NTLK86Eor2+IsjUfGeXFUJS3N0R56bjjomwPRXlzQ5QX5shq2bmMaCAeDtpMIJGhZZAngQzaWoYBGI8ghATRTwCpDu9XzHmlnz0o59APvogOqx7l/A+L2nzq9q1L7VxZlbbey0ie4deExJEhZz5+/U3BEQsxf23cJXGGKeLk1N/HX+e3HKpK72+oSh1jZFXqDlOlJeGdIhXWU12Vot2WqDT+fYX+QUXpqZ+BCI/ty/enu7e5i2sX6kbQs7p/IN7qSF0ZF47O6JvzvJQNwmx/pKjh7e8oa/MD \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/中序遍历2.png b/docs/cs-basics/data-structure/pictures/树/中序遍历2.png new file mode 100644 index 00000000..fe6956b9 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/中序遍历2.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio b/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio new file mode 100644 index 00000000..b92e5c29 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/先序遍历.drawio @@ -0,0 +1 @@ +7Vtbk6I4FP41eZwuIDfyKIq9D7tVU9u1tTOPKGllGo2L2Or8+k0kIEFQ2xvOtOWDyUnI5ZwvJ985IoDdyeo5CWbjv0TIY+BY4QrAHnAc27aI/FKSdSZhjGaCURKFutNW8BL95FpoaekiCvnc6JgKEafRzBQOxXTKh6khC5JELM1uryI2Z50FI74jeBkG8a703yhMx5nUdehW/gePRuN8ZpuwrGUS5J31TubjIBTLkgj6AHYTIdKsNFl1eayUl+sle67f0FosLOHT9JgHEuvvH2+rZPbTI6O56/T+WTrPX/Qo70G80BsGDonleN5ALTldaz2Q/xZqnd6rmKZf5hsrdWQHB89W20ZZGqnvTj6GXMwgF2olFCM6cnXSiLLiLcdRyl9mwVC1LCWOpGycTmJZs2UxmM8yy75GKx6qRURx3BWxSDYDwddXToZDKZ+niXjjpZaQsoFlFZO/8yTlq0b12YVRJJq5mPA0Wcsu+gGCtB01kCHW9WUJFlo0LiEilwUaiKNi5K2tZEGb6wOmc2pMV1XxNOyoMyBrUzHlplrlvpP1t3Lle7nSU/u2itpa17I5eLhzaip6lOsQi2TI92wA6uMcJCOeHsLorl1Kesc1es9lCY+DNHo3l1tnDD3DVxHJjWzNblPD7IRU7JltUz9VPn6VgaiFnxwXOdR2EEUkX4keFkHXbIXmLJmSdmbZAKfQyelYgo1uYD4Lpqd7gpIzyQTdetdQyLLpfg+PQZnpMVDbHgPdysreJ7Iytu/MyvhWVu59IisjaFoZw5atTG5l5edPZGWX3pmV6bkcbxWl30rl7zmnk+UtwVOVnN8VrLCo3JgVol+BFeIKUAg9lRVC10Qcdm5K/NxzAVYbRFgH4JLD0irB0t4LyxYAhtsEGKneN/hEgBHi7gs7cKthBzsTfRdEBTkSFbBNVFBoPxEIMUQulhe4bRoTI/uJ2YwhV7YgYtETXRIiexCDkVXXeiPA5Fz7+rTH/0S0B7M7oz12XVryXN6z/4Kp5z2HLrI2eI9Vb8sbER/XuDBsZl4n1H6iNqaSSGOJIrcy/NF3ll07TD4Jql3CrTyQ0+iBlKO5oAeyD3igbLoGDySdQWoeCdOD6CNTdjdaFMTRaCqrQ4lgLuWeci3RMIg7umEShWHc5NsSsZiGypP1LpV2typpd7Lrm1AN3p2r+abmXOmFAeA8AKCMS0wAoNYB0JxGvTAA8AMAGz56bwBozrBeGADwAQDl8qv0FLUNALLLRiUFfNFVrUVTDyJJx2IkpkH8pxAzbZAfPE3X+p2HYJGKhtyK9YRbSsblb1ycmIw7mmyeZ466LOlVgsL+JwoKqX1vQeHFcpUfSm1/PIV+yfNHjzyAraalmBmvUTMoxBTWtX40KHT3JjIlOttMS9UlMq/CCMiDEcgW4t4ZI8gHvj4A6AMAyhmgewNA84uUFwYAegAAlH4PuxsANOcFzyOhHa/nd/vltzD2sszfxsKk+hN76xaGu3TzGlFf/tt4FvTdmnHmOD7IOLOObcV8Tk0SzsfA80HHBz4CMlTr2MAngFmAdYHvAHdTMH3ysAidtqdOhleMQbh7EJ+jdLwYqDFdHzAX+Ay4FDA5i6smVdNh4LqAOU3eWK+iV/j05Bi3YKPae0FOxjzAfFXoIOD2LrLJr73+wdXL/UoNSCai9tsHjOi1SOUrVVDQgSWdUFVgdGOLLvA6m879TYGqDjmVuzsfFgcDHnvB8G20kVcnl6rRZ9hGul6KxL3N50KReOVdkCIfVvKEhds70xXK6vYfKVl4tP1fD/T/Bw== \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/先序遍历.png b/docs/cs-basics/data-structure/pictures/树/先序遍历.png new file mode 100644 index 00000000..5c80cedf Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/先序遍历.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/后序遍历.drawio b/docs/cs-basics/data-structure/pictures/树/后序遍历.drawio new file mode 100644 index 00000000..c324e801 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/后序遍历.drawio @@ -0,0 +1 @@ +7VvLluI2EP0aLacPlqzXEoPpLJKcySHJPHZurAZnDCLGdEN/fSQsGwtsoHmZTHNYIJVkPaqurqoKA1BnvHhMgunoNxmKGMBWuACoCyB0nBZRX1qyzCSc00wwTKLQdFoL+tGbMMKWkc6jUMysjqmUcRpNbeFATiZikFqyIEnkq93tWcb2rNNgKLYE/UEQb0u/RGE6yqQM0rX8FxENR/nMDuFZyzjIO5udzEZBKF9LIuQD1EmkTLPSeNERsVZerpfsuV5Na7GwREzSQx6I2vhvtYG/fv/jz7cvuP+9P38bfTKjvATx3GwYQBKr8bwnveR0afRA/p3rdXrPcpJ+mq2s1FYdIJ4u1o2qNNTf7XwMtZinXGiUUIwI1eqUEVXFex1FqehPg4FueVU4UrJROo5VzVHFYDbNLPscLUSoFxHFcUfGMlkNhJ6fBRkMlHyWJvKHKLWElD+1WsXkLyJJxaJWfU5hFIVmIcciTZaqi3mA5HY0QIbU1F9LsDCiUQkRuSwwQBwWI69tpQrGXO8wHaww3aaKJ2FbnwFVm8iJsNWq9p0sv5Yr38qVrt53q6gtTS2bQ4Rbp2ZDj2odcp4MxI4NIHOcg2Qo0n0Y3bZLSe+4Qu+5LBFxkEYv9nKrjGFm+CwjtZHC7DjnK2N2vGnPbJvmqfLx2xiIMPwAmQupA13qknwlZliEmd2K7FkyJW3NsgJOoZPjsYRqaWA2DSbHM0GJTDJBp5oaClk23c/BGJTajIGaZgz3Wlb2PpCVXX5jVsbXsnL3I1nZsa3s4oatTK5l5ccPZGWGb8zK9FQfbxGlX0vlb7lPp8prB09Xcv+u8AqLypW9Qvd/4RVuAAXzI71C6jAbcRRe1fFjpwKsMoho7YFLDstWCZbOTlg2ADDcJMDI5n1Djw07XLYr7KCNhh38RPSdERXkQFSgJlFBHeeBIISRy7C6wB3bmC5xHrjDuctUi0ta9EhKgmQHYtS4TSImPxaX93v8D+T3YHpjfo9TlZc81fHZfcNUOz77brImHJ9WtS2v5PkQ68ZwuH2fcOeBOphCRjHEiG0MfygF4eph8kmql3AtBoK1DKSJ5owMRPcwUDZdDQMpMkjtI2EziDkyZboxoiCOhhNVHSgECyX3NLVEgyBum4ZxFIZxHbclcj4JNZN1z8VNzOamgnRKeHcr8A4vxk31ydIzAwDdAaCN69oAQI0DoD6PemYAkDsAVg7prQGgPsV6ZgA4dwCAUkp9HYM0DACy7Y0qF7BvqkaLth5kko7kUE6C+Fcpp8Yg/4g0XZqXHoJ5KmuSK60H3FA2Ln/l4shs3MHO5mnmqEqTXiQo7H2goJDwWwsKz5asfFdu+/059HOeP3rgAWw0L8XseI3aQaHLkdXKjkxMsZ2pTAXPRhNTVbnMi/gE7t0n0OxEbswnyAe+PADwHQCaDeCtAaD+XcozAwDeAaDvLnRrAKjPDJ7mhnZ9r/fYKb9Vu9PP/GksTDZ/ZW/cwmjb4bxE3Jf/PJ6Ffdf2OXMc7/U5s45NRX2wIg3nY+D5oO0D3wUqWGs7wCdAxTG8A3wI2Kpgc/KgCJ7Wp04FWJwjtH0QH6N0NH/SYzIfcAZ8DpQzy9UsTE+qp8OAMcBhHRubVXQLTk8OoQXHrbwX1GTcA9zXhbYLWPcsm/zc7e1dvdqv0oBHV/vtAU7MWpTytSooaKOSTqgucLqyRQd47VXn3qpAdYc8Yrw5DouDJxF7weDHcCXfnFypxpxhxzX1UizurT6XicUR3GbCgvZOpEJVXf8pJQuP1n/tQf5/ \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/后序遍历.png b/docs/cs-basics/data-structure/pictures/树/后序遍历.png new file mode 100644 index 00000000..87bf512e Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/后序遍历.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/完全二叉树.drawio b/docs/cs-basics/data-structure/pictures/树/完全二叉树.drawio new file mode 100644 index 00000000..69326285 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/完全二叉树.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/完全二叉树.png b/docs/cs-basics/data-structure/pictures/树/完全二叉树.png new file mode 100644 index 00000000..564685ab Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/完全二叉树.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/平衡二叉树.drawio b/docs/cs-basics/data-structure/pictures/树/平衡二叉树.drawio new file mode 100644 index 00000000..11133b53 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/平衡二叉树.drawio @@ -0,0 +1 @@ +7VnJdpswFP0aL+OjiWmZOEm7SIdzsmjSHQbZcAqIynKM+/UVRmIysR2SYKfuCr0r8TTcq6eHGOFJnH3ibhp8YT6NRgj42QhfjxCCEJjykSPrAnEcqwDmPPRVowq4D/9QBQKFLkOfLhoNBWORCNMm6LEkoZ5oYC7nbNVsNmNRs9fUndMt4N5zo230R+iLoEBtZFX4ZxrOA90zNJ2iJnZ1YzWTReD6bFWD8M0ITzhjoijF2YRG+eLpdSneu32mthwYp4k45IU7eumBOPrJb52v09m3AKzusgvl5cmNlmrCI2RG0t/VVBbmeUE+3TiVhWS6SAt702DGZL9yWmKt1sr8vWS64mKxYfJSNkBGmlWV2ivQbuSAC09lbxqujQA1OkJyYpJ/aVytglDQ+9T18pqVlKDEAhFH0oKy6C7SQhSzMKN+PrYwiiYsYnzjCM9m1PQ8iS8EZ79orca3nCkAZedPlAuaPbvysORTbgTKYir4WjZRL2BTSUDtAaTtVU1RCgpqYtKYqzQ8Lz1XNMuCYvoFrKMO1ttLnPiX+faRVsIS2lxWOW++fqgbj3XjOp83KK21svquPfW3tmhr5eXI2ZJ7dMeUsYodLp9TsW9DbDNZY8roYEpjnEauCJ+aw+2iT/XwnYWbTaSFQppCMYyWAoppqrfqe73tyGk5Ai1HxTpsOdqoqZx2f4Hhg8LKG4QRdEZhhLTUUarlWGGEPMvyInWT/qRuaQV201liRXf/BsslXafCsjHUXsZntJcRaLJM0JFZNodi2Tgjlg10Yixbr038slA81MqPOtGT5Srryw2d9JWpYmmcfKpIPmSqaPZMFQ1gNzVK0KCpov1aSXZ+i4A9AtNCBjUhw51C/hCSNI4pSdI+00hPSRJsj5FNkAURsYiJIG5lRN3VAwnWeRfBnnRENA+UHz6q/Bw8NjE2pDzkuYvKm0etRuCMHeg4xEYQEhNYPbXZErmBh/2y1vei7//RRc7oo6t9Q3f0RA12Xcy+NlPbfcB1Z2r7DtIPcSxC0M3+QKma0TivoNM8zUw4tqBhIdsyZDSxW+4PvvGzO93oTnDnEIaKWWiomGWeUcxqXxSVd7xHi1ldt77/Y1b3ddr+mIVON2YRuDOcvE3MImRnYOwds6RZ/XQtmle/rvHNXw== \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/平衡二叉树.png b/docs/cs-basics/data-structure/pictures/树/平衡二叉树.png new file mode 100644 index 00000000..673f3e32 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/平衡二叉树.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/斜树.drawio b/docs/cs-basics/data-structure/pictures/树/斜树.drawio new file mode 100644 index 00000000..6eeaa610 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/斜树.drawio @@ -0,0 +1 @@ +5VhNc9owEP01HMnY+rCtY0LSdibNTKc5NOnN2AJ7KixXiGD667vGsi0bSGlKcTI5sfskrbT73grBCE8WxUcV5smdjLkYIScuRvh6hJDrOh58lMimQhjzK2Cu0thMaoH79Bc3oGPQVRrzZWeillLoNO+CkcwyHukOFiol191pMym6u+bhnO8A91EodtFvaayTCg2Q3+KfeDpP6p1dj1Uji7CebDJZJmEs1xaEb0Z4oqTUlbUoJlyUxavrUq37cGC0OZjimT5mwfT2s7i+U1/V7ePDOLv8TokYj02Up1CsTMIj5AmIdzUFY14a8BkucjCy6TKv/O2EmYR9IS29MbXyfq5kPTBebpm8hAmI5kU7WEd16jBw4CpSs1sNWydAnY0QJAb8g3O1TlLN7/MwKkfWIEHAEr0Q4Llghsu8EsUsLXhcni0VYiKFVNtAeDbjXhQBvtRK/uDWSOyzqeM0mz9xpXlxsPJuwyc0ApcLrtUGppgFxDcSMD2AqPHXlqIMlFhiqrHQaHjeRG5pBsMw/Resoz2s90ucxZdl+4CXyYx3ywp5q82D7TzaznWZt9N4G+O9tPY83mnRXuXh5HKlIv5MytjcHaGac/2nhthl0mKK7mGqxhQXoU6fusfdR5/Z4YtMt01UC4V2hUJxTwFVmmaV3eu9QNTpBiJ9KVV12Am0VVOT9ssFho+6Vk5wjbjv6BqhPXVgPPA1Qg6y/G+k7mgF7afzAPNvm2UP91rXHZhleq5exu+ol323xzIbmGXvXCyT98Qy632f+wOz7A/y8ONFqh8s+9Gy2yWl8yqeiuTIpyJ+VU9FcqqnIjvvUzE4lSQdW5LOkZJ0LUm6b1+SdEhJUoYvPIwpJgGF2991u69Vn10wlzESwAjxHP+FciXBBQoIfIHCz2riod4mqDeKz6plNsj1OqgyvbegTM95VpnBaZRJn1Um/k/KBLf9D7Ga3v4Ti29+Aw== \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/斜树.png b/docs/cs-basics/data-structure/pictures/树/斜树.png new file mode 100644 index 00000000..af129158 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/斜树.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/满二叉树.drawio b/docs/cs-basics/data-structure/pictures/树/满二叉树.drawio new file mode 100644 index 00000000..8379028d --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/满二叉树.drawio @@ -0,0 +1 @@ +5VnLcpswFP0aL+PRG1gmTpq2M5nJTBZNuiNGNkwxogLHOF9fYSSMME5c2/WjXqF7JK4e5+jqCnp4MCnupZ+GDyLgcQ+BoOjh2x5CEAKmHiUyrxDPcypgLKNAN1oCT9E71yDQ6DQKeGY1zIWI8yi1waFIEj7MLcyXUszsZiMR272m/pivAE9DP15Ff0RBHlaoi5wl/pVH49D0DJlX1Ux801jPJAv9QMwaEL7r4YEUIq9Kk2LA43LxzLpU731ZU1sPTPIk3+SFZ4cW19/kzzALJmPy8P39HlxdaS9vfjzVE+4hFit/N6+qMC4L6ulPUlVIXrO0shcNRkL1q6aVz/Vasd9TYSqusgWT16oBommxrDRegXGjBlx5qnszcGMEyOoIqYkp/pVxMwujnD+l/rCsmSkJKizMJ7GyoCr6WVqJYhQVPCjHFsXxQMRCLhzh0Yiz4VDhWS7FL96oCRzvFYC68zcuc16sXXlY86k2AhcTnsu5aqJfwExLQO8BZOxZQ1EaChtiMpivNTyuPS9pVgXN9F+wjjpYby9xElyX20dZiUi4vaxq3nL+3DRemsZtOW9QW3Ntbbv2PFjZoq2VVyMXUznkH0wZ69jhyzHPP9sQq0w2mKIdTBlM8tjPozd7uF306R4eRbTYREYoxBYKpS0FVNPUbzX3etuR13IEWo6qdVhxtFBTPe3tBYY3Cit7CCPogsIIcZlFKqZHDiNkLctZ6ifbk7qiFdhNZ41V3f0fLCMMTotleqi9jC9oL0Nqs0zwkVlmh2KZXhDLBJLTYtnZNfErovy5UX4xiZ4qL7O+0jBJX50q1sbJp4rkLFNFtmWqSIFra5Sgg6aK7q6S7LyLgE8EZoQMGkKGHwr5LCRJjyrJ9pm29e3FdfvIJciBiDiEIYhbGVF39YEE6+1LsOcTEdmG8sPHlB/FXp9hTDFxqUo+ILTFCL2+Bz2PuKqGMOBsJ01C7DsYJYe9WJvPov/+zkUu6M6F4Yll47Dru+yuidrH51t3WPrsHD2LUxGCbvYPdCwC67iCnn2YObDvQOog16EqhLkt9xsfmbjTjemEdA7hUDFr/XeiPd8t2QXdLSk7tZjV9Qlh90x+/4lRnfv3oUObF9k+qO01MVIZj1xGasG41Nge4xncNKAdNc8intv3GEMeBESlWi61ZchAnzqk/ENKkUsZZdsFNIrtRIvsLdFS5vKna9V8+esa3/0B \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/满二叉树.png b/docs/cs-basics/data-structure/pictures/树/满二叉树.png new file mode 100644 index 00000000..c0f30c04 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/满二叉树.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.drawio b/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.drawio new file mode 100644 index 00000000..37585459 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.drawio @@ -0,0 +1 @@ +7Zxbb9owFMc/DY+bcg95LPQyaUya2kntHl1iiFcTZ8bc+ul3HBxIloXCgMQPFkjEx5fE/h38z3EMPXc4Wz9wlCXfWIxpz7Hidc+97TmObVsBfEjLZmuJonBrmHISq0J7wxN5x8poKeuCxHheKSgYo4JkVeOYpSkei4oNcc5W1WITRqtnzdAU1wxPY0Tr1mcSi2Rr7Tvh3v4Fk2lSnNkOom3ODBWFVU/mCYrZqmRy73rukDMmtkez9RBTOXjFuGzr3Tfk7i6M41QcU2HgfX9xfi98h44e3r/es+dF9PbJUdcmNkWHcQz9V8mUpfAx4GyRxlg2Y0GKcZGwKUsRHTGWgdEG4y8sxEbRQwvBwJSIGVW5cIV88yLrf/aL5E/VXJ64XVdSG5WaC87e8JBRxvOLcy0rCPw+5ExYKkp2fyhfYN92R/ahcZSUac4WfIwPDU1fuRviUywOFfR2NOFrgNkMQx+gIscUCbKsXglS/jjdldsjgwNF7QSCriF4NkE76JKgZwge/modQbDfJUDfADwboOt0STAwBA/PjcdMop0SDA3BswmWbks7IKjEeonoQp3pFglUwwq30Zk8FOhVmsp0VgkR+ClD+WisIB7JRx5xoXh6EgUECgKRFHNVacwoRdmc5K3lsMYJofEIbdhCFOcpUjmuwqlkbUTJNIXjMVCRTQ6WmAsC4cONypiROM6vc0IoLYF27KF145/hGvJEeH3YOeooVQWvCK9UVOb1VXq1j3HsInBJSvFNaF2JftQIGnolCKKPEN2hdHoM8zrSmLPsR+H+0pAxIoHdLWHA5spWJqQmDJHPCzKT4klR95UJwWYqwdXY7BrNB8YfwBuGaijnCR96M4S0vU/DWxbnwDcFBwB/lG1gNBcrPBfX84pT7p0K1zjSM9xreUbhqqWJYSRhXNJf8rUDtPeXs12BAYgJzcP9BGYAnLbMNPo30xLEoFWGdo3hY35aA/F0iOsqwM6YOkawWxPsMNRNsO36wpNR7JYmhqZQSxvJ9oxknw7V1UyzfaPZl6Ooi2gHRrRbE+3+X6Ltel7Xol1fJjOi3dbM0PCQSRvRri/AGdH+EGqomWhHRrQvR1ET0XbqK2BGtK8l2pF2kfbuQY8R7dZFu+mRmC6i7dQX4Yxofwi1YQbobH53jWhfjqIuol1fAzOifS3R9m3dIm2nvinMiHZbM0PDhlxtRLu+CGdE+0OovmaiHRrRvhxFXUTbbEJrT7SDqCrau1/KdCfaZhdad6Kt+Ta0omEj2qdA1Wwfmmv2oV2Qoiai7dbXwIxoX020tds57pqNaJ2JdtOvtrQRbbMR7T+garYRzTUb0S5I8eqiDcn9nxrkeaW/hnDv/gA= \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.png b/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.png new file mode 100644 index 00000000..c0ce15b7 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/链式存储二叉树.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/顺序存储.drawio b/docs/cs-basics/data-structure/pictures/树/顺序存储.drawio new file mode 100644 index 00000000..1ddbb02d --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/顺序存储.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/顺序存储.png b/docs/cs-basics/data-structure/pictures/树/顺序存储.png new file mode 100644 index 00000000..33f3c6e3 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/顺序存储.png differ diff --git a/docs/cs-basics/data-structure/pictures/树/顺序存储2.drawio b/docs/cs-basics/data-structure/pictures/树/顺序存储2.drawio new file mode 100644 index 00000000..8048a1a7 --- /dev/null +++ b/docs/cs-basics/data-structure/pictures/树/顺序存储2.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/cs-basics/data-structure/pictures/树/顺序存储2.png b/docs/cs-basics/data-structure/pictures/树/顺序存储2.png new file mode 100644 index 00000000..70c6da26 Binary files /dev/null and b/docs/cs-basics/data-structure/pictures/树/顺序存储2.png differ diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/单链表2.png b/docs/cs-basics/data-structure/pictures/线性数据结构/单链表2.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/单链表2.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/单链表2.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/双向循环链表.png b/docs/cs-basics/data-structure/pictures/线性数据结构/双向循环链表.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/双向循环链表.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/双向循环链表.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/双向链表.png b/docs/cs-basics/data-structure/pictures/线性数据结构/双向链表.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/双向链表.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/双向链表.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/循环队列-堆满.png b/docs/cs-basics/data-structure/pictures/线性数据结构/循环队列-堆满.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/循环队列-堆满.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/循环队列-堆满.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/数组.png b/docs/cs-basics/data-structure/pictures/线性数据结构/数组.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/数组.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/数组.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈.png b/docs/cs-basics/data-structure/pictures/线性数据结构/栈.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/栈.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.drawio b/docs/cs-basics/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.drawio similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.drawio rename to docs/cs-basics/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.drawio diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.png b/docs/cs-basics/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/栈实现浏览器倒退和前进.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/队列.png b/docs/cs-basics/data-structure/pictures/线性数据结构/队列.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/队列.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/队列.png diff --git a/docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/顺序队列假溢出.png b/docs/cs-basics/data-structure/pictures/线性数据结构/顺序队列假溢出.png similarity index 100% rename from docs/dataStructures-algorithms/data-structure/pictures/线性数据结构/顺序队列假溢出.png rename to docs/cs-basics/data-structure/pictures/线性数据结构/顺序队列假溢出.png diff --git a/docs/dataStructures-algorithms/data-structure/图.md b/docs/cs-basics/data-structure/图.md similarity index 100% rename from docs/dataStructures-algorithms/data-structure/图.md rename to docs/cs-basics/data-structure/图.md diff --git a/docs/dataStructures-algorithms/data-structure/堆.md b/docs/cs-basics/data-structure/堆.md similarity index 99% rename from docs/dataStructures-algorithms/data-structure/堆.md rename to docs/cs-basics/data-structure/堆.md index 7e8f9811..cd186132 100644 --- a/docs/dataStructures-algorithms/data-structure/堆.md +++ b/docs/cs-basics/data-structure/堆.md @@ -1,4 +1,7 @@ +# 堆 + ## 什么是堆 + 堆是一种满足以下条件的树: 堆中的每一个节点值都大于等于(或小于等于)子树中所有节点的值。或者说,任意一个节点的值都大于等于(或小于等于)所有子节点的值。 diff --git a/docs/cs-basics/data-structure/树.md b/docs/cs-basics/data-structure/树.md new file mode 100644 index 00000000..010cff99 --- /dev/null +++ b/docs/cs-basics/data-structure/树.md @@ -0,0 +1,174 @@ +# 树 + +树就是一种类似现实生活中的树的数据结构(倒置的树)。任何一颗非空树只有一个根节点。 + +一棵树具有以下特点: + +1. 一棵树中的任意两个结点有且仅有唯一的一条路径连通。 +2. 一棵树如果有 n 个结点,那么它一定恰好有 n-1 条边。 +3. 一棵树不包含回路。 + +下图就是一颗树,并且是一颗二叉树。 + +![二叉树](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/二叉树-2.png) + +如上图所示,通过上面这张图说明一下树中的常用概念: + +- **节点** :树中的每个元素都可以统称为节点。 +- **根节点** :顶层节点或者说没有父节点的节点。上图中 A 节点就是根节点。 +- **父节点** :若一个节点含有子节点,则这个节点称为其子节点的父节点。上图中的 B 节点是 D 节点、E 节点的父节点。 +- **子节点** :一个节点含有的子树的根节点称为该节点的子节点。上图中 D 节点、E 节点是 B 节点的子节点。 +- **兄弟节点** :具有相同父节点的节点互称为兄弟节点。上图中 D 节点、E 节点的共同父节点是 B 节点,故 D 和 E 为兄弟节点。 +- **叶子节点** :没有子节点的节点。上图中的 D、F、H、I 都是叶子节点。 +- **节点的高度** :该节点到叶子节点的最长路径所包含的边数。 +- **节点的深度** :根节点到该节点的路径所包含的边数 +- **节点的层数** :节点的深度+1。 +- **树的高度** :根节点的高度。 + +## 二叉树的分类 + +**二叉树**(Binary tree)是每个节点最多只有两个分支(即不存在分支度大于 2 的节点)的树结构。 + +**二叉树** 的分支通常被称作“**左子树**”或“**右子树**”。并且,**二叉树** 的分支具有左右次序,不能随意颠倒。 + +**二叉树** 的第 i 层至多拥有 `2^(i-1)` 个节点,深度为 k 的二叉树至多总共有 `2^k-1` 个节点 + +### 满二叉树 + +一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是 **满二叉树**。也就是说,如果一个二叉树的层数为 K,且结点总数是(2^k) -1 ,则它就是 **满二叉树**。如下图所示: + +![](./pictures/树/满二叉树.png) + +### 完全二叉树 + +除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则这个二叉树就是 **完全二叉树** 。 + +大家可以想象为一棵树从根结点开始扩展,扩展完左子节点才能开始扩展右子节点,每扩展完一层,才能继续扩展下一层。如下图所示: + +![](./pictures/树/完全二叉树.png) + +完全二叉树有一个很好的性质:**父结点和子节点的序号有着对应关系。** + +细心的小伙伴可能发现了,当根节点的值为 1 的情况下,若父结点的序号是 i,那么左子节点的序号就是 2i,右子节点的序号是 2i+1。这个性质使得完全二叉树利用数组存储时可以极大地节省空间,以及利用序号找到某个节点的父结点和子节点,后续二叉树的存储会详细介绍。 + +### 平衡二叉树 + +**平衡二叉树** 是一棵二叉排序树,且具有以下性质: + +1. 可以是一棵空树 +2. 如果不是空树,它的左右两个子树的高度差的绝对值不超过 1,并且左右两个子树都是一棵平衡二叉树。 + +平衡二叉树的常用实现方法有 **红黑树**、**AVL 树**、**替罪羊树**、**加权平衡树**、**伸展树** 等。 + +在给大家展示平衡二叉树之前,先给大家看一棵树: + +![](./pictures/树/斜树.png) + +**你管这玩意儿叫树???** + +没错,这玩意儿还真叫树,只不过这棵树已经退化为一个链表了,我们管它叫 **斜树**。 + +**如果这样,那我为啥不直接用链表呢?** + +谁说不是呢? + +二叉树相比于链表,由于父子节点以及兄弟节点之间往往具有某种特殊的关系,这种关系使得我们在树中对数据进行**搜索**和**修改**时,相对于链表更加快捷便利。 + +但是,如果二叉树退化为一个链表了,那么那么树所具有的优秀性质就难以表现出来,效率也会大打折,为了避免这样的情况,我们希望每个做 “家长”(父结点) 的,都 **一碗水端平**,分给左儿子和分给右儿子的尽可能一样多,相差最多不超过一层,如下图所示: + +![](./pictures/树/平衡二叉树.png) + +## 二叉树的存储 + +二叉树的存储主要分为 **链式存储** 和 **顺序存储** 两种: + +### 链式存储 + +和链表类似,二叉树的链式存储依靠指针将各个节点串联起来,不需要连续的存储空间。 + +每个节点包括三个属性: + +- 数据 data。data 不一定是单一的数据,根据不同情况,可以是多个具有不同类型的数据。 +- 左节点指针 left +- 右节点指针 right。 + +可是 JAVA 没有指针啊! + +那就直接引用对象呗(别问我对象哪里找) + +![](./pictures/树/链式存储二叉树.png) + +### 顺序存储 + +顺序存储就是利用数组进行存储,数组中的每一个位置仅存储节点的 data,不存储左右子节点的指针,子节点的索引通过数组下标完成。根结点的序号为 1,对于每个节点 Node,假设它存储在数组中下标为 i 的位置,那么它的左子节点就存储在 2 _ i 的位置,它的右子节点存储在下标为 2 _ i+1 的位置。 + +一棵完全二叉树的数组顺序存储如下图所示: + +![](./pictures/树/顺序存储.png) + +大家可以试着填写一下存储如下二叉树的数组,比较一下和完全二叉树的顺序存储有何区别: + +![](./pictures/树/顺序存储2.png) + +可以看到,如果我们要存储的二叉树不是完全二叉树,在数组中就会出现空隙,导致内存利用率降低 + +## 二叉树的遍历 + +### 先序遍历 + +![](./pictures/树/先序遍历.png) + +二叉树的先序遍历,就是先输出根结点,再遍历左子树,最后遍历右子树,遍历左子树和右子树的时候,同样遵循先序遍历的规则,也就是说,我们可以递归实现先序遍历。 + +代码如下: + +```java +public void preOrder(TreeNode root){ + if(root == null){ + return; + } + system.out.println(root.data); + preOrder(root.left); + preOrder(root.right); +} +``` + +### 中序遍历 + +![](./pictures/树/中序遍历.png) + +二叉树的中序遍历,就是先递归中序遍历左子树,再输出根结点的值,再递归中序遍历右子树,大家可以想象成一巴掌把树压扁,父结点被拍到了左子节点和右子节点的中间,如下图所示: + +![](./pictures/树/中序遍历2.png) + +代码如下: + +```java +public void inOrder(TreeNode root){ + if(root == null){ + return; + } + inOrder(root.left); + system.out.println(root.data); + inOrder(root.right); +} +``` + +### 后序遍历 + +![](./pictures/树/后序遍历.png) + +二叉树的后序遍历,就是先递归后序遍历左子树,再递归后序遍历右子树,最后输出根结点的值 + +代码如下: + +```java +public void postOrder(TreeNode root){ + if(root == null){ + return; + } + postOrder(root.left); + postOrder(root.right); + system.out.println(root.data); +} +``` \ No newline at end of file diff --git a/docs/cs-basics/data-structure/红黑树.md b/docs/cs-basics/data-structure/红黑树.md new file mode 100644 index 00000000..1f13744f --- /dev/null +++ b/docs/cs-basics/data-structure/红黑树.md @@ -0,0 +1,14 @@ +**红黑树特点** : + +1. 每个节点非红即黑; +2. 根节点总是黑色的; +3. 每个叶子节点都是黑色的空节点(NIL节点); +4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定); +5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。 + +**红黑树的应用** :TreeMap、TreeSet以及JDK1.8的HashMap底层都用到了红黑树。 + +**为什么要用红黑树?** 简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。详细了解可以查看 [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐) + +**相关阅读** :[《红黑树深入剖析及Java实现》](https://zhuanlan.zhihu.com/p/24367771)(美团点评技术团队) + diff --git a/docs/dataStructures-algorithms/data-structure/线性数据结构.md b/docs/cs-basics/data-structure/线性数据结构.md similarity index 100% rename from docs/dataStructures-algorithms/data-structure/线性数据结构.md rename to docs/cs-basics/data-structure/线性数据结构.md diff --git a/docs/network/HTTPS中的TLS.md b/docs/cs-basics/network/HTTPS中的TLS.md similarity index 100% rename from docs/network/HTTPS中的TLS.md rename to docs/cs-basics/network/HTTPS中的TLS.md diff --git a/docs/network/images/Cut-Trough-Switching_0.gif b/docs/cs-basics/network/images/Cut-Trough-Switching_0.gif similarity index 100% rename from docs/network/images/Cut-Trough-Switching_0.gif rename to docs/cs-basics/network/images/Cut-Trough-Switching_0.gif diff --git a/docs/network/images/isp.png b/docs/cs-basics/network/images/isp.png similarity index 100% rename from docs/network/images/isp.png rename to docs/cs-basics/network/images/isp.png diff --git a/docs/network/images/七层体系结构图.png b/docs/cs-basics/network/images/七层体系结构图.png similarity index 100% rename from docs/network/images/七层体系结构图.png rename to docs/cs-basics/network/images/七层体系结构图.png diff --git a/docs/network/images/传输层.png b/docs/cs-basics/network/images/传输层.png similarity index 100% rename from docs/network/images/传输层.png rename to docs/cs-basics/network/images/传输层.png diff --git a/docs/network/images/应用层.png b/docs/cs-basics/network/images/应用层.png similarity index 100% rename from docs/network/images/应用层.png rename to docs/cs-basics/network/images/应用层.png diff --git a/docs/network/images/数据链路层.png b/docs/cs-basics/network/images/数据链路层.png similarity index 100% rename from docs/network/images/数据链路层.png rename to docs/cs-basics/network/images/数据链路层.png diff --git a/docs/network/images/物理层.png b/docs/cs-basics/network/images/物理层.png similarity index 100% rename from docs/network/images/物理层.png rename to docs/cs-basics/network/images/物理层.png diff --git a/docs/network/images/网络层.png b/docs/cs-basics/network/images/网络层.png similarity index 100% rename from docs/network/images/网络层.png rename to docs/cs-basics/network/images/网络层.png diff --git a/docs/network/images/计算机网络知识点总结/万维网的大致工作工程.png b/docs/cs-basics/network/images/计算机网络知识点总结/万维网的大致工作工程.png similarity index 100% rename from docs/network/images/计算机网络知识点总结/万维网的大致工作工程.png rename to docs/cs-basics/network/images/计算机网络知识点总结/万维网的大致工作工程.png diff --git a/docs/network/计算机网络.md b/docs/cs-basics/network/计算机网络.md similarity index 100% rename from docs/network/计算机网络.md rename to docs/cs-basics/network/计算机网络.md diff --git a/docs/network/计算机网络知识总结.md b/docs/cs-basics/network/计算机网络知识总结.md similarity index 100% rename from docs/network/计算机网络知识总结.md rename to docs/cs-basics/network/计算机网络知识总结.md diff --git a/docs/operating-system/Shell.md b/docs/cs-basics/operating-system/Shell.md similarity index 100% rename from docs/operating-system/Shell.md rename to docs/cs-basics/operating-system/Shell.md diff --git a/docs/operating-system/basis.md b/docs/cs-basics/operating-system/basis.md similarity index 100% rename from docs/operating-system/basis.md rename to docs/cs-basics/operating-system/basis.md diff --git a/docs/operating-system/images/Linux-Logo.png b/docs/cs-basics/operating-system/images/Linux-Logo.png similarity index 100% rename from docs/operating-system/images/Linux-Logo.png rename to docs/cs-basics/operating-system/images/Linux-Logo.png diff --git a/docs/operating-system/images/Linux之父.png b/docs/cs-basics/operating-system/images/Linux之父.png similarity index 100% rename from docs/operating-system/images/Linux之父.png rename to docs/cs-basics/operating-system/images/Linux之父.png diff --git a/docs/operating-system/images/Linux权限命令.png b/docs/cs-basics/operating-system/images/Linux权限命令.png similarity index 100% rename from docs/operating-system/images/Linux权限命令.png rename to docs/cs-basics/operating-system/images/Linux权限命令.png diff --git a/docs/operating-system/images/Linux权限解读.png b/docs/cs-basics/operating-system/images/Linux权限解读.png similarity index 100% rename from docs/operating-system/images/Linux权限解读.png rename to docs/cs-basics/operating-system/images/Linux权限解读.png diff --git a/docs/operating-system/images/Linux目录树.png b/docs/cs-basics/operating-system/images/Linux目录树.png similarity index 100% rename from docs/operating-system/images/Linux目录树.png rename to docs/cs-basics/operating-system/images/Linux目录树.png diff --git a/docs/operating-system/images/linux.png b/docs/cs-basics/operating-system/images/linux.png similarity index 100% rename from docs/operating-system/images/linux.png rename to docs/cs-basics/operating-system/images/linux.png diff --git a/docs/operating-system/images/macos.png b/docs/cs-basics/operating-system/images/macos.png similarity index 100% rename from docs/operating-system/images/macos.png rename to docs/cs-basics/operating-system/images/macos.png diff --git a/docs/operating-system/images/unix.png b/docs/cs-basics/operating-system/images/unix.png similarity index 100% rename from docs/operating-system/images/unix.png rename to docs/cs-basics/operating-system/images/unix.png diff --git a/docs/operating-system/images/windows.png b/docs/cs-basics/operating-system/images/windows.png similarity index 100% rename from docs/operating-system/images/windows.png rename to docs/cs-basics/operating-system/images/windows.png diff --git a/docs/operating-system/images/修改文件权限.png b/docs/cs-basics/operating-system/images/修改文件权限.png similarity index 100% rename from docs/operating-system/images/修改文件权限.png rename to docs/cs-basics/operating-system/images/修改文件权限.png diff --git a/docs/operating-system/images/文件inode信息.png b/docs/cs-basics/operating-system/images/文件inode信息.png similarity index 100% rename from docs/operating-system/images/文件inode信息.png rename to docs/cs-basics/operating-system/images/文件inode信息.png diff --git a/docs/operating-system/images/用户态与内核态.png b/docs/cs-basics/operating-system/images/用户态与内核态.png similarity index 100% rename from docs/operating-system/images/用户态与内核态.png rename to docs/cs-basics/operating-system/images/用户态与内核态.png diff --git a/docs/operating-system/linux.md b/docs/cs-basics/operating-system/linux.md similarity index 100% rename from docs/operating-system/linux.md rename to docs/cs-basics/operating-system/linux.md diff --git a/docs/dataStructures-algorithms/数据结构.md b/docs/dataStructures-algorithms/数据结构.md deleted file mode 100644 index 5caffaac..00000000 --- a/docs/dataStructures-algorithms/数据结构.md +++ /dev/null @@ -1,179 +0,0 @@ -> 注意!!!这部分内容会进行重构,以下内容仅作为参考。 -> - -- [Queue](#queue) - - [什么是队列](#什么是队列) - - [队列的种类](#队列的种类) - - [Java 集合框架中的队列 Queue](#java-集合框架中的队列-queue) - - [推荐文章](#推荐文章) -- [Set](#set) - - [什么是 Set](#什么是-set) - - [补充:有序集合与无序集合说明](#补充:有序集合与无序集合说明) - - [HashSet 和 TreeSet 底层数据结构](#hashset-和-treeset-底层数据结构) - - [推荐文章](#推荐文章-1) -- [List](#list) - - [什么是List](#什么是list) - - [List的常见实现类](#list的常见实现类) - - [ArrayList 和 LinkedList 源码学习](#arraylist-和-linkedlist-源码学习) - - [推荐阅读](#推荐阅读) -- [Map](#map) -- [树](#树) - - - - -## Queue - -### 什么是队列 -队列是数据结构中比较重要的一种类型,它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。 - -### 队列的种类 - -- **单队列**(单队列就是常见的队列, 每次添加元素时,都是添加到队尾,存在“假溢出”的问题也就是明明有位置却不能添加的情况) -- **循环队列**(避免了“假溢出”的问题) - -### Java 集合框架中的队列 Queue - -Java 集合中的 Queue 继承自 Collection 接口 ,Deque, LinkedList, PriorityQueue, BlockingQueue 等类都实现了它。 -Queue 用来存放 等待处理元素 的集合,这种场景一般用于缓冲、并发访问。 -除了继承 Collection 接口的一些方法,Queue 还添加了额外的 添加、删除、查询操作。 - -## Set - -### 什么是 Set -Set 继承于 Collection 接口,是一个不允许出现重复元素,并且无序的集合,主要 HashSet 和 TreeSet 两大实现类。 - -在判断重复元素的时候,HashSet 集合会调用 hashCode()和 equal()方法来实现;TreeSet 集合会调用compareTo方法来实现。 - -### 补充:有序集合与无序集合说明 -- 有序集合:集合里的元素可以根据 key 或 index 访问 (List、Map) -- 无序集合:集合里的元素只能遍历。(Set) - - -### HashSet 和 TreeSet 底层数据结构 - -**HashSet** 是哈希表结构,主要利用 HashMap 的 key 来存储元素,计算插入元素的 hashCode 来获取元素在集合中的位置; - -**TreeSet** 是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序; - -## List - -### 什么是List - -在 List 中,用户可以精确控制列表中每个元素的插入位置,另外用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。 与 Set 不同,List 通常允许重复的元素。 另外 List 是有序集合而 Set 是无序集合。 - -### List的常见实现类 - -**ArrayList** 是一个数组队列,相当于动态数组。它由数组实现,随机访问效率高,随机插入、随机删除效率低。 - -**LinkedList** 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率高。 - -**Vector** 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。 - -**Stack** 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out)。 - -## 树 - -### 1 二叉树 - -[二叉树](https://baike.baidu.com/item/%E4%BA%8C%E5%8F%89%E6%A0%91)(百度百科) - -(1)[完全二叉树](https://baike.baidu.com/item/%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91)——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。 - -(2)[满二叉树](https://baike.baidu.com/item/%E6%BB%A1%E4%BA%8C%E5%8F%89%E6%A0%91)——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。 - -(3)[平衡二叉树](https://baike.baidu.com/item/%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91/10421057)——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 - -### 2 完全二叉树 - -[完全二叉树](https://baike.baidu.com/item/%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91)(百度百科) - -完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。 - -### 3 满二叉树 - -[满二叉树](https://baike.baidu.com/item/%E6%BB%A1%E4%BA%8C%E5%8F%89%E6%A0%91)(百度百科,国内外的定义不同) - -国内教程定义:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。 - -### 堆 - -[数据结构之堆的定义](https://blog.csdn.net/qq_33186366/article/details/51876191) - -堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。 - -### 4 二叉查找树(BST) - -[浅谈算法和数据结构: 七 二叉查找树](https://www.yycoding.xyz/post/2014/3/24/introduce-binary-search-tree) - -二叉查找树的特点: - -1. 若任意节点的左子树不空,则左子树上所有结点的 值均小于它的根结点的值; -2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; -3. 任意节点的左、右子树也分别为二叉查找树; -4. 没有键值相等的节点(no duplicate nodes)。 - -### 5 平衡二叉树(Self-balancing binary search tree) - -[ 平衡二叉树](https://baike.baidu.com/item/%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91)(百度百科,平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等) - -### 6 红黑树 - -红黑树特点: - -1. 每个节点非红即黑; -2. 根节点总是黑色的; -3. 每个叶子节点都是黑色的空节点(NIL节点); -4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定); -5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。 - - -红黑树的应用: - -TreeMap、TreeSet以及JDK1.8的HashMap底层都用到了红黑树。 - -**为什么要用红黑树?** - - -简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。详细了解可以查看 [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐) - -推荐文章: - -- [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐) -- [寻找红黑树的操作手册](http://dandanlove.com/2018/03/18/red-black-tree/)(文章排版以及思路真的不错) -- [红黑树深入剖析及Java实现](https://zhuanlan.zhihu.com/p/24367771)(美团点评技术团队) - -### 7 B-,B+,B*树 - -[二叉树学习笔记之B树、B+树、B*树 ](https://yq.aliyun.com/articles/38345) - -[《B-树,B+树,B*树详解》](https://blog.csdn.net/aqzwss/article/details/53074186) - -[《B-树,B+树与B*树的优缺点比较》](https://blog.csdn.net/bigtree_3721/article/details/73632405) - -B-树(或B树)是一种平衡的多路查找(又称排序)树,在文件系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance) - -1. B+ 树的叶子节点链表结构相比于 B- 树便于扫库,和范围检索。 -2. B+树支持range-query(区间查询)非常方便,而B树不支持。这是数据库选用B+树的最主要原因。 -3. B\*树 是B+树的变体,B\*树分配新结点的概率比B+树要低,空间使用率更高; - -### 8 LSM 树 - -[[HBase] LSM树 VS B+树](https://blog.csdn.net/dbanote/article/details/8897599) - -B+树最大的性能问题是会产生大量的随机IO - -为了克服B+树的弱点,HBase引入了LSM树的概念,即Log-Structured Merge-Trees。 - -[LSM树由来、设计思想以及应用到HBase的索引](https://www.cnblogs.com/yanghuahui/p/3483754.html) - - -## 图 - - - - -## BFS及DFS - -- [《使用BFS及DFS遍历树和图的思路及实现》](https://blog.csdn.net/Gene1994/article/details/85097507) - diff --git a/docs/java/JAD反编译tricks.md b/docs/java/tips/JAD反编译tricks.md similarity index 68% rename from docs/java/JAD反编译tricks.md rename to docs/java/tips/JAD反编译tricks.md index f9d11bec..34477a45 100644 --- a/docs/java/JAD反编译tricks.md +++ b/docs/java/tips/JAD反编译tricks.md @@ -1,10 +1,10 @@ -[jad](https://varaneckas.com/jad/)反编译工具,已经不再更新,且只支持JDK1.4,但并不影响其强大的功能。 +[jad](https://varaneckas.com/jad/)反编译工具,已经不再更新,且只支持 JDK1.4,但并不影响其强大的功能。 -基本用法:`jad xxx.class`,会生成直接可读的xxx.jad文件。 +基本用法:`jad xxx.class`,会生成直接可读的 `xxx.jad` 文件。 ## 自动拆装箱 -对于基本类型和包装类型之间的转换,通过xxxValue()和valueOf()两个方法完成自动拆装箱,使用jad进行反编译可以看到该过程: +对于基本类型和包装类型之间的转换,通过 xxxValue()和 valueOf()两个方法完成自动拆装箱,使用 jad 进行反编译可以看到该过程: ```java public class Demo { @@ -12,8 +12,9 @@ public class Demo { int x = new Integer(10); // 自动拆箱 Integer y = x; // 自动装箱 } -} +} ``` + 反编译后结果: ```java @@ -29,11 +30,9 @@ public class Demo } ``` +## foreach 语法糖 - -## foreach语法糖 - -在遍历迭代时可以foreach语法糖,对于数组类型直接转换成for循环: +在遍历迭代时可以 foreach 语法糖,对于数组类型直接转换成 for 循环: ```java // 原始代码 @@ -57,9 +56,7 @@ for(int j = 0; j < i; j++) } ``` - - -对于容器类的遍历会使用iterator进行迭代: +对于容器类的遍历会使用 iterator 进行迭代: ```java import java.io.PrintStream; @@ -85,11 +82,9 @@ public class Demo } ``` - - ## Arrays.asList(T...) -熟悉Arrays.asList(T...)用法的小伙伴都应该知道,asList()方法传入的参数不能是基本类型的数组,必须包装成包装类型再使用,否则对应生成的列表的大小永远是1: +熟悉 Arrays.asList(T...)用法的小伙伴都应该知道,asList()方法传入的参数不能是基本类型的数组,必须包装成包装类型再使用,否则对应生成的列表的大小永远是 1: ```java import java.util.*; @@ -105,7 +100,7 @@ public class Demo { } ``` -从反编译结果来解释,为什么传入基本类型的数组后,返回的List大小是1: +从反编译结果来解释,为什么传入基本类型的数组后,返回的 List 大小是 1: ```java // 反编译后文件 @@ -126,7 +121,7 @@ public class Demo Integer ainteger[] = { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }; - + // 注意这里被反编译成二维数组,而且是一个1行三列的二维数组 // list.size()当然返回1 List list = Arrays.asList(new int[][] { ai }); @@ -137,13 +132,11 @@ public class Demo } ``` -从上面结果可以看到,传入基本类型的数组后,会被转换成一个二维数组,而且是**new int\[1]\[arr.length]**这样的数组,调用list.size()当然返回1。 - - +从上面结果可以看到,传入基本类型的数组后,会被转换成一个二维数组,而且是**new int\[1]\[arr.length]**这样的数组,调用 list.size()当然返回 1。 ## 注解 -Java中的类、接口、枚举、注解都可以看做是类类型。使用jad来看一下@interface被转换成什么: +Java 中的类、接口、枚举、注解都可以看做是类类型。使用 jad 来看一下@interface 被转换成什么: ```java import java.lang.annotation.Retention; @@ -155,10 +148,11 @@ public @interface Foo{ boolean bar(); } ``` + 查看反编译代码可以看出: -- 自定义的注解类Foo被转换成接口Foo,并且继承Annotation接口 -- 原来自定义接口中的value()和bar()被转换成抽象方法 +- 自定义的注解类 Foo 被转换成接口 Foo,并且继承 Annotation 接口 +- 原来自定义接口中的 value()和 bar()被转换成抽象方法 ```java import java.lang.annotation.Annotation; @@ -171,7 +165,9 @@ public interface Foo public abstract boolean bar(); } ``` + 注解通常和反射配合使用,而且既然自定义的注解最终被转换成接口,注解中的属性被转换成接口中的抽象方法,那么通过反射之后拿到接口实例,在通过接口实例自然能够调用对应的抽象方法: + ```java import java.util.Arrays; @@ -185,12 +181,9 @@ public class Demo{ } ``` - ## 枚举 -通过jad反编译可以很好地理解枚举类。 - - +通过 jad 反编译可以很好地理解枚举类。 ### 空枚举 @@ -200,14 +193,15 @@ public class Demo{ public enum DummyEnum { } ``` -使用jad反编译查看结果: -- 自定义枚举类被转换成final类,并且继承Enum -- 提供了两个参数(name,odinal)的私有构造器,并且调用了父类的构造器。注意即使没有提供任何参数,也会有该该构造器,其中name就是枚举实例的名称,odinal是枚举实例的索引号 -- 初始化了一个private static final自定义类型的空数组 **$VALUES** -- 提供了两个public static方法: - - values()方法通过clone()方法返回内部$VALUES的浅拷贝。这个方法结合私有构造器可以完美实现单例模式,想一想values()方法是不是和单例模式中getInstance()方法功能类似 - - valueOf(String s):调用父类Enum的valueOf方法并强转返回 +使用 jad 反编译查看结果: + +- 自定义枚举类被转换成 final 类,并且继承 Enum +- 提供了两个参数(name,odinal)的私有构造器,并且调用了父类的构造器。注意即使没有提供任何参数,也会有该该构造器,其中 name 就是枚举实例的名称,odinal 是枚举实例的索引号 +- 初始化了一个 private static final 自定义类型的空数组 **\$VALUES** +- 提供了两个 public static 方法: + - values()方法通过 clone()方法返回内部\$VALUES 的浅拷贝。这个方法结合私有构造器可以完美实现单例模式,想一想 values()方法是不是和单例模式中 getInstance()方法功能类似 + - valueOf(String s):调用父类 Enum 的 valueOf 方法并强转返回 ```java public final class DummyEnum extends Enum @@ -233,6 +227,7 @@ public final class DummyEnum extends Enum } ``` + ### 包含抽象方法的枚举 枚举类中也可以包含抽象方法,但是必须定义枚举实例并且立即重写抽象方法,就像下面这样: @@ -255,22 +250,23 @@ public enum DummyEnum { } ``` + 再来反编译看看有哪些变化: -- 原来final class变成了abstract class:这很好理解,有抽象方法的类自然是抽象类 -- 多了两个public static final的成员DUMMY1、DUMMY2,这两个实例的初始化过程被放到了static代码块中,并且实例过程中直接重写了抽象方法,类似于匿名内部类的形式。 -- 数组**$VALUES[]**初始化时放入枚举实例 +- 原来 final class 变成了 abstract class:这很好理解,有抽象方法的类自然是抽象类 +- 多了两个 public static final 的成员 DUMMY1、DUMMY2,这两个实例的初始化过程被放到了 static 代码块中,并且实例过程中直接重写了抽象方法,类似于匿名内部类的形式。 +- 数组**\$VALUES[]**初始化时放入枚举实例 还有其它变化么? -在反编译后的DummyEnum类中,是存在抽象方法的,而枚举实例在静态代码块中初始化过程中重写了抽象方法。在Java中,抽象方法和抽象方法重写同时放在一个类中,只能通过内部类形式完成。因此上面第二点应该说成就是以内部类形式初始化。 +在反编译后的 DummyEnum 类中,是存在抽象方法的,而枚举实例在静态代码块中初始化过程中重写了抽象方法。在 Java 中,抽象方法和抽象方法重写同时放在一个类中,只能通过内部类形式完成。因此上面第二点应该说成就是以内部类形式初始化。 -可以看一下DummyEnum.class存放的位置,应该多了两个文件: +可以看一下 DummyEnum.class 存放的位置,应该多了两个文件: -- DummyEnum$1.class -- DummyEnum$2.class +- DummyEnum\$1.class +- DummyEnum\$2.class -Java中.class文件出现$符号表示有内部类存在,就像OutClass$InnerClass,这两个文件出现也应证了上面的匿名内部类初始化的说法。 +Java 中.class 文件出现 $ 符号表示有内部类存在,就像OutClass$InnerClass,这两个文件出现也应证了上面的匿名内部类初始化的说法。 ```java import java.io.PrintStream; @@ -299,9 +295,9 @@ public abstract class DummyEnum extends Enum public static final DummyEnum DUMMY1; public static final DummyEnum DUMMY2; private static final DummyEnum $VALUES[]; - + // static代码块进行初始化 - static + static { DUMMY1 = new DummyEnum("DUMMY1", 0) { public void dummyMethod() @@ -325,13 +321,11 @@ public abstract class DummyEnum extends Enum } ``` - - ### 正常的枚举类 -实际开发中,枚举类通常的形式是有两个参数(int code,Sring msg)的构造器,可以作为状态码进行返回。Enum类实际上也是提供了包含两个参数且是protected的构造器,这里为了避免歧义,将枚举类的构造器设置为三个,使用jad反编译: +实际开发中,枚举类通常的形式是有两个参数(int code,Sring msg)的构造器,可以作为状态码进行返回。Enum 类实际上也是提供了包含两个参数且是 protected 的构造器,这里为了避免歧义,将枚举类的构造器设置为三个,使用 jad 反编译: -最大的变化是:现在的private构造器从2个参数变成5个,而且在内部仍然将前两个参数通过super传递给父类,剩余的三个参数才是真正自己提供的参数。可以想象,如果自定义的枚举类只提供了一个参数,最终生成底层代码中private构造器应该有三个参数,前两个依然通过super传递给父类。 +最大的变化是:现在的 private 构造器从 2 个参数变成 5 个,而且在内部仍然将前两个参数通过 super 传递给父类,剩余的三个参数才是真正自己提供的参数。可以想象,如果自定义的枚举类只提供了一个参数,最终生成底层代码中 private 构造器应该有三个参数,前两个依然通过 super 传递给父类。 ```java public final class CustomEnum extends Enum @@ -362,7 +356,7 @@ public final class CustomEnum extends Enum private Object data; private static final CustomEnum $VALUES[]; - static + static { FIRST = new CustomEnum("FIRST", 0, 10010, "first", Long.valueOf(100L)); SECOND = new CustomEnum("SECOND", 1, 10020, "second", "Foo"); diff --git a/docs/java/手把手教你定位常见Java性能问题.md b/docs/java/tips/手把手教你定位常见Java性能问题.md similarity index 54% rename from docs/java/手把手教你定位常见Java性能问题.md rename to docs/java/tips/手把手教你定位常见Java性能问题.md index 980eeefb..2550d8b3 100644 --- a/docs/java/手把手教你定位常见Java性能问题.md +++ b/docs/java/tips/手把手教你定位常见Java性能问题.md @@ -1,27 +1,27 @@ -## 手把手教你定位常见Java性能问题 +## 手把手教你定位常见 Java 性能问题 ## 概述 -性能优化一向是后端服务优化的重点,但是线上性能故障问题不是经常出现,或者受限于业务产品,根本就没办法出现性能问题,包括笔者自己遇到的性能问题也不多,所以为了提前储备知识,当出现问题的时候不会手忙脚乱,我们本篇文章来模拟下常见的几个Java性能故障,来学习怎么去分析和定位。 +性能优化一向是后端服务优化的重点,但是线上性能故障问题不是经常出现,或者受限于业务产品,根本就没办法出现性能问题,包括笔者自己遇到的性能问题也不多,所以为了提前储备知识,当出现问题的时候不会手忙脚乱,我们本篇文章来模拟下常见的几个 Java 性能故障,来学习怎么去分析和定位。 ## 预备知识 既然是定位问题,肯定是需要借助工具,我们先了解下需要哪些工具可以帮忙定位问题。 - **top命令** +**top 命令** -`top`命令使我们最常用的Linux命令之一,它可以实时的显示当前正在执行的进程的CPU使用率,内存使用率等系统信息。`top -Hp pid` 可以查看线程的系统资源使用情况。 +`top`命令使我们最常用的 Linux 命令之一,它可以实时的显示当前正在执行的进程的 CPU 使用率,内存使用率等系统信息。`top -Hp pid` 可以查看线程的系统资源使用情况。 - **vmstat命令** +**vmstat 命令** -vmstat是一个指定周期和采集次数的虚拟内存检测工具,可以统计内存,CPU,swap的使用情况,它还有一个重要的常用功能,用来观察进程的上下文切换。字段说明如下: +vmstat 是一个指定周期和采集次数的虚拟内存检测工具,可以统计内存,CPU,swap 的使用情况,它还有一个重要的常用功能,用来观察进程的上下文切换。字段说明如下: -- r: 运行队列中进程数量(当数量大于CPU核数表示有阻塞的线程) -- b: 等待IO的进程数量 +- r: 运行队列中进程数量(当数量大于 CPU 核数表示有阻塞的线程) +- b: 等待 IO 的进程数量 - swpd: 使用虚拟内存大小 - free: 空闲物理内存大小 - buff: 用作缓冲的内存大小(内存和硬盘的缓冲区) -- cache: 用作缓存的内存大小(CPU和内存之间的缓冲区) +- cache: 用作缓存的内存大小(CPU 和内存之间的缓冲区) - si: 每秒从交换区写到内存的大小,由磁盘调入内存 - so: 每秒写入交换区的内存大小,由内存调入磁盘 - bi: 每秒读取的块数 @@ -30,30 +30,30 @@ vmstat是一个指定周期和采集次数的虚拟内存检测工具,可以 - cs: 每秒上下文切换数。 - us: 用户进程执行时间百分比(user time) - sy: 内核系统进程执行时间百分比(system time) -- wa: IO等待时间百分比 +- wa: IO 等待时间百分比 - id: 空闲时间百分比 - **pidstat命令** + **pidstat 命令** pidstat 是 Sysstat 中的一个组件,也是一款功能强大的性能监测工具,`top` 和 `vmstat` 两个命令都是监测进程的内存、CPU 以及 I/O 使用情况,而 pidstat 命令可以检测到线程级别的。`pidstat`命令线程切换字段说明如下: -- UID :被监控任务的真实用户ID。 +- UID :被监控任务的真实用户 ID。 -- TGID :线程组ID。 +- TGID :线程组 ID。 -- TID:线程ID。 +- TID:线程 ID。 - cswch/s:主动切换上下文次数,这里是因为资源阻塞而切换线程,比如锁等待等情况。 -- nvcswch/s:被动切换上下文次数,这里指CPU调度切换了线程。 +- nvcswch/s:被动切换上下文次数,这里指 CPU 调度切换了线程。 - **jstack命令** + **jstack 命令** -jstack是JDK工具命令,它是一种线程堆栈分析工具,最常用的功能就是使用 `jstack pid` 命令查看线程的堆栈信息,也经常用来排除死锁情况。 +jstack 是 JDK 工具命令,它是一种线程堆栈分析工具,最常用的功能就是使用 `jstack pid` 命令查看线程的堆栈信息,也经常用来排除死锁情况。 **jstat 命令** -它可以检测Java程序运行的实时情况,包括堆内存信息和垃圾回收信息,我们常常用来查看程序垃圾回收情况。常用的命令是`jstat -gc pid`。信息字段说明如下: +它可以检测 Java 程序运行的实时情况,包括堆内存信息和垃圾回收信息,我们常常用来查看程序垃圾回收情况。常用的命令是`jstat -gc pid`。信息字段说明如下: - S0C:年轻代中 To Survivor 的容量(单位 KB); @@ -85,31 +85,27 @@ jstack是JDK工具命令,它是一种线程堆栈分析工具,最常用的 - GCT:从应用程序启动到采样时 gc 用的总时间 (s)。 + **jmap 命令** +jmap 也是 JDK 工具命令,他可以查看堆内存的初始化信息以及堆内存的使用情况,还可以生成 dump 文件来进行详细分析。查看堆内存情况命令`jmap -heap pid`。 - **jmap命令** +**mat 内存工具** -jmap也是JDK工具命令,他可以查看堆内存的初始化信息以及堆内存的使用情况,还可以生成dump文件来进行详细分析。查看堆内存情况命令`jmap -heap pid`。 +MAT(Memory Analyzer Tool)工具是 eclipse 的一个插件(MAT 也可以单独使用),它分析大内存的 dump 文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用 OQL 对象查询,以及可以很方便的找出对象 GC Roots 的相关信息。 - **mat内存工具** +**idea 中也有这么一个插件,就是 JProfiler**。 -MAT(Memory Analyzer Tool)工具是eclipse的一个插件(MAT也可以单独使用),它分析大内存的dump文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用OQL对象查询,以及可以很方便的找出对象GC Roots的相关信息。 - -**idea中也有这么一个插件,就是JProfiler**。 - -相关阅读: - -1. 《性能诊断利器 JProfiler 快速入门和最佳实践》:[https://segmentfault.com/a/1190000017795841](https://segmentfault.com/a/1190000017795841) +相关阅读:[《性能诊断利器 JProfiler 快速入门和最佳实践》](https://segmentfault.com/a/1190000017795841) ## 模拟环境准备 -基础环境jdk1.8,采用SpringBoot框架来写几个接口来触发模拟场景,首先是模拟CPU占满情况 +基础环境 jdk1.8,采用 SpringBoot 框架来写几个接口来触发模拟场景,首先是模拟 CPU 占满情况 -## CPU占满 +### CPU 占满 -模拟CPU占满还是比较简单,直接写一个死循环计算消耗CPU即可。 +模拟 CPU 占满还是比较简单,直接写一个死循环计算消耗 CPU 即可。 -````java +```java /** * 模拟CPU占满 */ @@ -127,27 +123,27 @@ MAT(Memory Analyzer Tool)工具是eclipse的一个插件(MAT也可以单独使 } } -```` +``` -请求接口地址测试`curl localhost:8080/cpu/loop`,发现CPU立马飙升到100% +请求接口地址测试`curl localhost:8080/cpu/loop`,发现 CPU 立马飙升到 100% ![](./images/performance-tuning/java-performance1.png) -通过执行`top -Hp 32805` 查看Java线程情况 +通过执行`top -Hp 32805` 查看 Java 线程情况 ![](./images/performance-tuning/java-performance2.png) -执行 `printf '%x' 32826` 获取16进制的线程id,用于`dump`信息查询,结果为 `803a`。最后我们执行`jstack 32805 |grep -A 20 803a `来查看下详细的`dump`信息。 +执行 `printf '%x' 32826` 获取 16 进制的线程 id,用于`dump`信息查询,结果为 `803a`。最后我们执行`jstack 32805 |grep -A 20 803a`来查看下详细的`dump`信息。 ![](./images/performance-tuning/java-performance3.png) -这里`dump`信息直接定位出了问题方法以及代码行,这就定位出了CPU占满的问题。 +这里`dump`信息直接定位出了问题方法以及代码行,这就定位出了 CPU 占满的问题。 -## 内存泄露 +### 内存泄露 -模拟内存泄漏借助了ThreadLocal对象来完成,ThreadLocal是一个线程私有变量,可以绑定到线程上,在整个线程的生命周期都会存在,但是由于ThreadLocal的特殊性,ThreadLocal是基于ThreadLocalMap实现的,ThreadLocalMap的Entry继承WeakReference,而Entry的Key是WeakReference的封装,换句话说Key就是弱引用,弱引用在下次GC之后就会被回收,如果ThreadLocal在set之后不进行后续的操作,因为GC会把Key清除掉,但是Value由于线程还在存活,所以Value一直不会被回收,最后就会发生内存泄漏。 +模拟内存泄漏借助了 ThreadLocal 对象来完成,ThreadLocal 是一个线程私有变量,可以绑定到线程上,在整个线程的生命周期都会存在,但是由于 ThreadLocal 的特殊性,ThreadLocal 是基于 ThreadLocalMap 实现的,ThreadLocalMap 的 Entry 继承 WeakReference,而 Entry 的 Key 是 WeakReference 的封装,换句话说 Key 就是弱引用,弱引用在下次 GC 之后就会被回收,如果 ThreadLocal 在 set 之后不进行后续的操作,因为 GC 会把 Key 清除掉,但是 Value 由于线程还在存活,所以 Value 一直不会被回收,最后就会发生内存泄漏。 -````Java +```Java /** * 模拟内存泄漏 */ @@ -158,43 +154,43 @@ MAT(Memory Analyzer Tool)工具是eclipse的一个插件(MAT也可以单独使 localVariable.set(new Byte[4096 * 1024]);// 为线程添加变量 return "ok"; } -```` +``` 我们给启动加上堆内存大小限制,同时设置内存溢出的时候输出堆栈快照并输出日志。 -`java -jar -Xms500m -Xmx500m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/tmp/heaplog.log analysis-demo-0.0.1-SNAPSHOT.jar` +`java -jar -Xms500m -Xmx500m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/tmp/heaplog.log analysis-demo-0.0.1-SNAPSHOT.jar` -启动成功后我们循环执行100次,`for i in {1..500}; do curl localhost:8080/memory/leak;done`,还没执行完毕,系统已经返回500错误了。查看系统日志出现了如下异常: +启动成功后我们循环执行 100 次,`for i in {1..500}; do curl localhost:8080/memory/leak;done`,还没执行完毕,系统已经返回 500 错误了。查看系统日志出现了如下异常: ``` java.lang.OutOfMemoryError: Java heap space ``` -我们用`jstat -gc pid` 命令来看看程序的GC情况。 +我们用`jstat -gc pid` 命令来看看程序的 GC 情况。 ![](./images/performance-tuning/java-performance4.png) -很明显,内存溢出了,堆内存经过45次 Full Gc 之后都没释放出可用内存,这说明当前堆内存中的对象都是存活的,有GC Roots引用,无法回收。那是什么原因导致内存溢出呢?是不是我只要加大内存就行了呢?如果是普通的内存溢出也许扩大内存就行了,但是如果是内存泄漏的话,扩大的内存不一会就会被占满,所以我们还需要确定是不是内存泄漏。我们之前保存了堆 Dump 文件,这个时候借助我们的MAT工具来分析下。导入工具选择`Leak Suspects Report`,工具直接就会给你列出问题报告。 +很明显,内存溢出了,堆内存经过 45 次 Full Gc 之后都没释放出可用内存,这说明当前堆内存中的对象都是存活的,有 GC Roots 引用,无法回收。那是什么原因导致内存溢出呢?是不是我只要加大内存就行了呢?如果是普通的内存溢出也许扩大内存就行了,但是如果是内存泄漏的话,扩大的内存不一会就会被占满,所以我们还需要确定是不是内存泄漏。我们之前保存了堆 Dump 文件,这个时候借助我们的 MAT 工具来分析下。导入工具选择`Leak Suspects Report`,工具直接就会给你列出问题报告。 ![](./images/performance-tuning/java-performance5.png) -这里已经列出了可疑的4个内存泄漏问题,我们点击其中一个查看详情。 +这里已经列出了可疑的 4 个内存泄漏问题,我们点击其中一个查看详情。 ![](./images/performance-tuning/java-performance6.png) -这里已经指出了内存被线程占用了接近50M的内存,占用的对象就是ThreadLocal。如果想详细的通过手动去分析的话,可以点击`Histogram`,查看最大的对象占用是谁,然后再分析它的引用关系,即可确定是谁导致的内存溢出。 +这里已经指出了内存被线程占用了接近 50M 的内存,占用的对象就是 ThreadLocal。如果想详细的通过手动去分析的话,可以点击`Histogram`,查看最大的对象占用是谁,然后再分析它的引用关系,即可确定是谁导致的内存溢出。 ![](./images/performance-tuning/java-performance7.png) -上图发现占用内存最大的对象是一个Byte数组,我们看看它到底被那个GC Root引用导致没有被回收。按照上图红框操作指引,结果如下图: +上图发现占用内存最大的对象是一个 Byte 数组,我们看看它到底被那个 GC Root 引用导致没有被回收。按照上图红框操作指引,结果如下图: ![](./images/performance-tuning/java-performance8.png) -我们发现Byte数组是被线程对象引用的,图中也标明,Byte数组对像的GC Root是线程,所以它是不会被回收的,展开详细信息查看,我们发现最终的内存占用对象是被ThreadLocal对象占据了。这也和MAT工具自动帮我们分析的结果一致。 +我们发现 Byte 数组是被线程对象引用的,图中也标明,Byte 数组对像的 GC Root 是线程,所以它是不会被回收的,展开详细信息查看,我们发现最终的内存占用对象是被 ThreadLocal 对象占据了。这也和 MAT 工具自动帮我们分析的结果一致。 -## 死锁 +### 死锁 -死锁会导致耗尽线程资源,占用内存,表现就是内存占用升高,CPU不一定会飙升(看场景决定),如果是直接new线程,会导致JVM内存被耗尽,报无法创建线程的错误,这也是体现了使用线程池的好处。 +死锁会导致耗尽线程资源,占用内存,表现就是内存占用升高,CPU 不一定会飙升(看场景决定),如果是直接 new 线程,会导致 JVM 内存被耗尽,报无法创建线程的错误,这也是体现了使用线程池的好处。 ```java ExecutorService service = new ThreadPoolExecutor(4, 10, @@ -240,13 +236,13 @@ public class DeadLockThread implements Runnable { } ``` -我们循环请求接口2000次,发现不一会系统就出现了日志错误,线程池和队列都满了,由于我选择的当队列满了就拒绝的策略,所以系统直接抛出异常。 +我们循环请求接口 2000 次,发现不一会系统就出现了日志错误,线程池和队列都满了,由于我选择的当队列满了就拒绝的策略,所以系统直接抛出异常。 ``` java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@2760298 rejected from java.util.concurrent.ThreadPoolExecutor@7ea7cd51[Running, pool size = 10, active threads = 10, queued tasks = 1024, completed tasks = 846] ``` -通过`ps -ef|grep java`命令找出 Java 进程 pid,执行`jstack pid` 即可出现java线程堆栈信息,这里发现了5个死锁,我们只列出其中一个,很明显线程`pool-1-thread-2`锁住了`0x00000000f8387d88`等待`0x00000000f8387d98`锁,线程`pool-1-thread-1`锁住了`0x00000000f8387d98`等待锁`0x00000000f8387d88`,这就产生了死锁。 +通过`ps -ef|grep java`命令找出 Java 进程 pid,执行`jstack pid` 即可出现 java 线程堆栈信息,这里发现了 5 个死锁,我们只列出其中一个,很明显线程`pool-1-thread-2`锁住了`0x00000000f8387d88`等待`0x00000000f8387d98`锁,线程`pool-1-thread-1`锁住了`0x00000000f8387d98`等待锁`0x00000000f8387d88`,这就产生了死锁。 ```JAVA Java stack information for the threads listed above: @@ -269,13 +265,13 @@ Java stack information for the threads listed above: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) - + Found 5 deadlocks. ``` -## 线程频繁切换 +### 线程频繁切换 -上下文切换会导致将大量CPU时间浪费在寄存器、内核栈以及虚拟内存的保存和恢复上,导致系统整体性能下降。当你发现系统的性能出现明显的下降时候,需要考虑是否发生了大量的线程上下文切换。 +上下文切换会导致将大量 CPU 时间浪费在寄存器、内核栈以及虚拟内存的保存和恢复上,导致系统整体性能下降。当你发现系统的性能出现明显的下降时候,需要考虑是否发生了大量的线程上下文切换。 ```java @GetMapping(value = "/thread/swap") @@ -303,7 +299,7 @@ public class ThreadSwap1 implements Runnable { } ``` -这里我创建多个线程去执行基础的原子+1操作,然后让出 CPU 资源,理论上 CPU 就会去调度别的线程,我们请求接口创建100个线程看看效果如何,`curl localhost:8080/thread/swap?num=100`。接口请求成功后,我们执行`vmstat 1 10,表示每1秒打印一次,打印10次,线程切换采集结果如下: +这里我创建多个线程去执行基础的原子+1 操作,然后让出 CPU 资源,理论上 CPU 就会去调度别的线程,我们请求接口创建 100 个线程看看效果如何,`curl localhost:8080/thread/swap?num=100`。接口请求成功后,我们执行 `vmstat 1 10`,表示每 1 秒打印一次,打印 10 次,线程切换采集结果如下: ``` procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- @@ -316,37 +312,35 @@ procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- 100 0 128000 878384 908 468688 0 0 0 108 4182 8346826 14 86 0 0 0 ``` +这里我们关注 4 个指标,`r`,`cs`,`us`,`sy`。 +**r=100**,说明等待的进程数量是 100,线程有阻塞。 -这里我们关注4个指标,`r`,`cs`,`us`,`sy`。 +**cs=800 多万**,说明每秒上下文切换了 800 多万次,这个数字相当大了。 -**r=100**,说明等待的进程数量是100,线程有阻塞。 +**us=14**,说明用户态占用了 14%的 CPU 时间片去处理逻辑。 -**cs=800多万**,说明每秒上下文切换了800多万次,这个数字相当大了。 +**sy=86**,说明内核态占用了 86%的 CPU,这里明显就是做上下文切换工作了。 -**us=14**,说明用户态占用了14%的CPU时间片去处理逻辑。 - -**sy=86**,说明内核态占用了86%的CPU,这里明显就是做上下文切换工作了。 - -我们通过`top`命令以及`top -Hp pid`查看进程和线程CPU情况,发现Java线程CPU占满了,但是线程CPU使用情况很平均,没有某一个线程把CPU吃满的情况。 +我们通过`top`命令以及`top -Hp pid`查看进程和线程 CPU 情况,发现 Java 线程 CPU 占满了,但是线程 CPU 使用情况很平均,没有某一个线程把 CPU 吃满的情况。 ``` -PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND - 87093 root 20 0 4194788 299056 13252 S 399.7 16.1 65:34.67 java +PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND + 87093 root 20 0 4194788 299056 13252 S 399.7 16.1 65:34.67 java ``` ``` - PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND - 87189 root 20 0 4194788 299056 13252 R 4.7 16.1 0:41.11 java - 87129 root 20 0 4194788 299056 13252 R 4.3 16.1 0:41.14 java - 87130 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.51 java - 87133 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.59 java - 87134 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.95 java + PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND + 87189 root 20 0 4194788 299056 13252 R 4.7 16.1 0:41.11 java + 87129 root 20 0 4194788 299056 13252 R 4.3 16.1 0:41.14 java + 87130 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.51 java + 87133 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.59 java + 87134 root 20 0 4194788 299056 13252 R 4.3 16.1 0:40.95 java ``` -结合上面用户态CPU只使用了14%,内核态CPU占用了86%,可以基本判断是Java程序线程上下文切换导致性能问题。 +结合上面用户态 CPU 只使用了 14%,内核态 CPU 占用了 86%,可以基本判断是 Java 程序线程上下文切换导致性能问题。 -我们使用`pidstat`命令来看看Java进程内部的线程切换数据,执行`pidstat -p 87093 -w 1 10 `,采集数据如下: +我们使用`pidstat`命令来看看 Java 进程内部的线程切换数据,执行`pidstat -p 87093 -w 1 10`,采集数据如下: ``` 11:04:30 PM UID TGID TID cswch/s nvcswch/s Command @@ -362,19 +356,19 @@ PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11:04:30 PM 0 - 87137 0.00 16.04 |__java ``` -根据上面采集的信息,我们知道Java的线程每秒切换15次左右,正常情况下,应该是个位数或者小数。结合这些信息我们可以断定Java线程开启过多,导致频繁上下文切换,从而影响了整体性能。 +根据上面采集的信息,我们知道 Java 的线程每秒切换 15 次左右,正常情况下,应该是个位数或者小数。结合这些信息我们可以断定 Java 线程开启过多,导致频繁上下文切换,从而影响了整体性能。 -**为什么系统的上下文切换是每秒800多万,而 Java 进程中的某一个线程切换才15次左右?** +**为什么系统的上下文切换是每秒 800 多万,而 Java 进程中的某一个线程切换才 15 次左右?** 系统上下文切换分为三种情况: -1、多任务:在多任务环境中,一个进程被切换出CPU,运行另外一个进程,这里会发生上下文切换。 +1、多任务:在多任务环境中,一个进程被切换出 CPU,运行另外一个进程,这里会发生上下文切换。 -2、中断处理:发生中断时,硬件会切换上下文。在vmstat命令中是`in` +2、中断处理:发生中断时,硬件会切换上下文。在 vmstat 命令中是`in` 3、用户和内核模式切换:当操作系统中需要在用户模式和内核模式之间进行转换时,需要进行上下文切换,比如进行系统函数调用。 -Linux 为每个 CPU 维护了一个就绪队列,将活跃进程按照优先级和等待 CPU 的时间排序,然后选择最需要 CPU 的进程,也就是优先级最高和等待 CPU 时间最长的进程来运行。也就是vmstat命令中的`r`。 +Linux 为每个 CPU 维护了一个就绪队列,将活跃进程按照优先级和等待 CPU 的时间排序,然后选择最需要 CPU 的进程,也就是优先级最高和等待 CPU 时间最长的进程来运行。也就是 vmstat 命令中的`r`。 那么,进程在什么时候才会被调度到 CPU 上运行呢? @@ -385,13 +379,13 @@ Linux 为每个 CPU 维护了一个就绪队列,将活跃进程按照优先级 - 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行。 - 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序。 -结合我们之前的内容分析,阻塞的就绪队列是100左右,而我们的CPU只有4核,这部分原因造成的上下文切换就可能会相当高,再加上中断次数是4000左右和系统的函数调用等,整个系统的上下文切换到800万也不足为奇了。Java内部的线程切换才15次,是因为线程使用`Thread.yield()`来让出CPU资源,但是CPU有可能继续调度该线程,这个时候线程之间并没有切换,这也是为什么内部的某个线程切换次数并不是非常大的原因。 +结合我们之前的内容分析,阻塞的就绪队列是 100 左右,而我们的 CPU 只有 4 核,这部分原因造成的上下文切换就可能会相当高,再加上中断次数是 4000 左右和系统的函数调用等,整个系统的上下文切换到 800 万也不足为奇了。Java 内部的线程切换才 15 次,是因为线程使用`Thread.yield()`来让出 CPU 资源,但是 CPU 有可能继续调度该线程,这个时候线程之间并没有切换,这也是为什么内部的某个线程切换次数并不是非常大的原因。 ## 总结 -本文模拟了常见的性能问题场景,分析了如何定位CPU100%、内存泄漏、死锁、线程频繁切换问题。分析问题我们需要做好两件事,第一,掌握基本的原理,第二,借助好工具。本文也列举了分析问题的常用工具和命令,希望对你解决问题有所帮助。当然真正的线上环境可能十分复杂,并没有模拟的环境那么简单,但是原理是一样的,问题的表现也是类似的,我们重点抓住原理,活学活用,相信复杂的线上问题也可以顺利解决。 +本文模拟了常见的性能问题场景,分析了如何定位 CPU100%、内存泄漏、死锁、线程频繁切换问题。分析问题我们需要做好两件事,第一,掌握基本的原理,第二,借助好工具。本文也列举了分析问题的常用工具和命令,希望对你解决问题有所帮助。当然真正的线上环境可能十分复杂,并没有模拟的环境那么简单,但是原理是一样的,问题的表现也是类似的,我们重点抓住原理,活学活用,相信复杂的线上问题也可以顺利解决。 -## 参考 +## 参考 1、https://linux.die.net/man/1/pidstat