diff --git a/README.md b/README.md
index 8e3f41daad44d8217ca77095fb8cbf5b04b5e6c6..b567d5369b7a11ff6e9dd5824c898aae84de9678 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,13 @@
-
Special Sponsors
+Special Sponsors
+
-
-
+
+
@@ -280,25 +281,20 @@ Markdown 格式参考:[Github Markdown格式](https://guides.github.com/featur
![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg)
-
-### 架构
-
-
-
-
-
### Contributor
下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后!
-
-
+
+
+
+
diff --git a/docs/HomePage.md b/docs/HomePage.md
index 4fccd1651e870e81dddb3d2e6cd1bd9972365c20..086d6a97f92e6dc41f3e366a5e76a32b01d9d6a8 100644
--- a/docs/HomePage.md
+++ b/docs/HomePage.md
@@ -1,6 +1,6 @@
Java后端技术交流群(限工作一年及以上,架构视频免费领取) :[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-869815609-red.svg)](https://jq.qq.com/?_wv=1027&k=5QqyxIx)
-强烈推荐七牛云CEO老许的[架构专栏](#架构),微信扫描二维码购买后,[加我好友](#联系我)私聊我领取24元返现。129元的课程相当于75入手。
+点击订阅[Java面试进阶指南](https://xiaozhuanlan.com/javainterview?rel=javaguide)(专为Java面试方向准备)。[为什么要弄这个专栏?](https://shimo.im/docs/9BJjNsNg7S4dCnz3/)
Java 学习/面试指南
@@ -10,8 +10,8 @@ Java后端技术交流群(限工作一年及以上,架构视频免费领取)
Special Sponsors
-
-
+
+
@@ -20,169 +20,172 @@ Java后端技术交流群(限工作一年及以上,架构视频免费领取)
### 基础
-* [Java 基础知识回顾](./java/Java基础知识.md)
-* [J2EE 基础知识回顾](./java/J2EE基础知识.md)
-* [Collections 工具类和 Arrays 工具类常见方法](./java/Basis/Arrays%2CCollectionsCommonMethods.md)
-* [Java常见关键字总结:static、final、this、super](./java/Basis/final、static、this、super.md)
+* [Java 基础知识回顾](java/Java基础知识.md)
+* [J2EE 基础知识回顾](java/J2EE基础知识.md)
+* [Collections 工具类和 Arrays 工具类常见方法](java/Basis/Arrays%2CCollectionsCommonMethods.md)
+* [Java常见关键字总结:static、final、this、super](java/Basis/final、static、this、super.md)
### 容器
* **常见问题总结:**
- * [这几道Java集合框架面试题几乎必问](./java/这几道Java集合框架面试题几乎必问.md)
- * [Java 集合框架常见面试题总结](./java/Java集合框架常见面试题总结.md)
+ * [这几道Java集合框架面试题几乎必问](java/这几道Java集合框架面试题几乎必问.md)
+ * [Java 集合框架常见面试题总结](java/Java集合框架常见面试题总结.md)
* **源码分析:**
- * [ArrayList 源码学习](./java/ArrayList.md)
- * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./java/ArrayList-Grow.md)
- * [LinkedList 源码学习](./java/LinkedList.md)
- * [HashMap(JDK1.8)源码学习](./java/HashMap.md)
+ * [ArrayList 源码学习](java/ArrayList.md)
+ * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](java/ArrayList-Grow.md)
+ * [LinkedList 源码学习](java/LinkedList.md)
+ * [HashMap(JDK1.8)源码学习](java/HashMap.md)
### 并发
-* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./java/synchronized.md)
-* [并发编程面试必备:乐观锁与悲观锁](./essential-content-for-interview/面试必备之乐观锁与悲观锁.md)
-* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./java/Multithread/Atomic.md)
-* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./java/Multithread/AQS.md)
-* [BATJ都爱问的多线程面试题](./java/Multithread/BATJ都爱问的多线程面试题.md)
-* [并发容器总结](./java/Multithread/并发容器总结.md)
+* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReentrantLock 的对比](java/synchronized.md)
+* [并发编程面试必备:乐观锁与悲观锁](essential-content-for-interview/面试必备之乐观锁与悲观锁.md)
+* [并发编程面试必备:JUC 中的 Atomic 原子类总结](java/Multithread/Atomic.md)
+* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](java/Multithread/AQS.md)
+* [BATJ都爱问的多线程面试题](java/Multithread/BATJ都爱问的多线程面试题.md)
+* [并发容器总结](java/Multithread/并发容器总结.md)
### JVM
-* [可能是把Java内存区域讲的最清楚的一篇文章](./java/可能是把Java内存区域讲的最清楚的一篇文章.md)
-* [搞定JVM垃圾回收就是这么简单](./java/搞定JVM垃圾回收就是这么简单.md)
-* [《深入理解Java虚拟机》第2版学习笔记](./java/Java虚拟机(jvm).md)
+* [可能是把Java内存区域讲的最清楚的一篇文章](java/可能是把Java内存区域讲的最清楚的一篇文章.md)
+* [搞定JVM垃圾回收就是这么简单](java/搞定JVM垃圾回收就是这么简单.md)
+* [《深入理解Java虚拟机》第2版学习笔记](java/Java虚拟机(jvm).md)
### I/O
-* [BIO,NIO,AIO 总结 ](./java/BIO-NIO-AIO.md)
-* [Java IO 与 NIO系列文章](./java/Java%20IO与NIO.md)
+* [BIO,NIO,AIO 总结 ](java/BIO-NIO-AIO.md)
+* [Java IO 与 NIO系列文章](java/Java%20IO与NIO.md)
### Java 8
-* [Java 8 新特性总结](./java/What's%20New%20in%20JDK8/Java8Tutorial.md)
-* [Java 8 学习资源推荐](./java/What's%20New%20in%20JDK8/Java8教程推荐.md)
+* [Java 8 新特性总结](java/What's%20New%20in%20JDK8/Java8Tutorial.md)
+* [Java 8 学习资源推荐](java/What's%20New%20in%20JDK8/Java8教程推荐.md)
### 编程规范
-- [Java 编程规范](./java/Java编程规范.md)
+- [Java 编程规范](java/Java编程规范.md)
## 网络
-* [计算机网络常见面试题](./network/计算机网络.md)
-* [计算机网络基础知识总结](./network/干货:计算机网络知识总结.md)
-* [HTTPS中的TLS](./network/HTTPS中的TLS.md)
+* [计算机网络常见面试题](network/计算机网络.md)
+* [计算机网络基础知识总结](network/干货:计算机网络知识总结.md)
+* [HTTPS中的TLS](network/HTTPS中的TLS.md)
## 操作系统
### Linux相关
-* [后端程序员必备的 Linux 基础知识](./operating-system/后端程序员必备的Linux基础知识.md)
-* [Shell 编程入门](./operating-system/Shell.md)
+* [后端程序员必备的 Linux 基础知识](operating-system/后端程序员必备的Linux基础知识.md)
+* [Shell 编程入门](operating-system/Shell.md)
## 数据结构与算法
### 数据结构
-- [数据结构知识学习与面试](./dataStructures-algorithms/数据结构.md)
+- [数据结构知识学习与面试](dataStructures-algorithms/数据结构.md)
### 算法
-- [算法学习资源推荐](./dataStructures-algorithms/算法学习资源推荐.md)
-- [算法总结——几道常见的子符串算法题 ](./dataStructures-algorithms/几道常见的子符串算法题.md)
-- [算法总结——几道常见的链表算法题 ](./dataStructures-algorithms/几道常见的链表算法题.md)
-- [剑指offer部分编程题](./dataStructures-algorithms/剑指offer部分编程题.md)
-- [公司真题](./dataStructures-algorithms/公司真题.md)
-- [回溯算法经典案例之N皇后问题](./dataStructures-algorithms/Backtracking-NQueens.md)
+- [算法学习资源推荐](dataStructures-algorithms/算法学习资源推荐.md)
+- [算法总结——几道常见的子符串算法题 ](dataStructures-algorithms/几道常见的子符串算法题.md)
+- [算法总结——几道常见的链表算法题 ](dataStructures-algorithms/几道常见的链表算法题.md)
+- [剑指offer部分编程题](dataStructures-algorithms/剑指offer部分编程题.md)
+- [公司真题](dataStructures-algorithms/公司真题.md)
+- [回溯算法经典案例之N皇后问题](dataStructures-algorithms/Backtracking-NQueens.md)
## 数据库
### MySQL
-* [MySQL 学习与面试](./database/MySQL.md)
-* [一千行MySQL学习笔记](./database/一千行MySQL命令.md)
-* [【思维导图-索引篇】搞定数据库索引就是这么简单](./database/MySQL%20Index.md)
-* [事务隔离级别(图文详解)](./database/事务隔离级别(图文详解).md)
-* [一条SQL语句在MySQL中如何执行的](./database/一条sql语句在mysql中如何执行的.md)
+* [MySQL 学习与面试](database/MySQL.md)
+* [一千行MySQL学习笔记](database/一千行MySQL命令.md)
+* [MySQL高性能优化规范建议](database/MySQL高性能优化规范建议.md)
+* [搞定数据库索引就是这么简单](database/MySQL%20Index.md)
+* [事务隔离级别(图文详解)](database/事务隔离级别(图文详解).md)
+* [一条SQL语句在MySQL中如何执行的](database/一条sql语句在mysql中如何执行的.md)
### Redis
-* [Redis 总结](./database/Redis/Redis.md)
-* [Redlock分布式锁](./database/Redis/Redlock分布式锁.md)
-* [如何做可靠的分布式锁,Redlock真的可行么](./database/Redis/如何做可靠的分布式锁,Redlock真的可行么.md)
+* [Redis 总结](database/Redis/Redis.md)
+* [Redlock分布式锁](database/Redis/Redlock分布式锁.md)
+* [如何做可靠的分布式锁,Redlock真的可行么](database/Redis/如何做可靠的分布式锁,Redlock真的可行么.md)
## 系统设计
### 设计模式
-- [设计模式系列文章](./system-design/设计模式.md)
+- [设计模式系列文章](system-design/设计模式.md)
### 常用框架
#### Spring
-- [Spring 学习与面试](./system-design/framework/Spring学习与面试.md)
-- [Spring中bean的作用域与生命周期](./system-design/framework/SpringBean.md)
-- [SpringMVC 工作原理详解](./system-design/framework/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md)
+- [Spring 学习与面试](system-design/framework/Spring学习与面试.md)
+- [Spring中bean的作用域与生命周期](system-design/framework/SpringBean.md)
+- [SpringMVC 工作原理详解](system-design/framework/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md)
#### ZooKeeper
-- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./system-design/framework/ZooKeeper.md)
-- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./system-design/framework/ZooKeeper数据模型和常见命令.md)
+- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](system-design/framework/ZooKeeper.md)
+- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](system-design/framework/ZooKeeper数据模型和常见命令.md)
### 数据通信
-- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./system-design/data-communication/数据通信(RESTful、RPC、消息队列).md)
-- [Dubbo 总结:关于 Dubbo 的重要知识点](./system-design/data-communication/dubbo.md)
-- [消息队列总结:新手也能看懂,消息队列其实很简单](./system-design/data-communication/message-queue.md)
-- [一文搞懂 RabbitMQ 的重要概念以及安装](./system-design/data-communication/rabbitmq.md)
+- [数据通信(RESTful、RPC、消息队列)相关知识点总结](system-design/data-communication/数据通信(RESTful、RPC、消息队列).md)
+- [Dubbo 总结:关于 Dubbo 的重要知识点](system-design/data-communication/dubbo.md)
+- [消息队列总结:新手也能看懂,消息队列其实很简单](system-design/data-communication/message-queue.md)
+- [一文搞懂 RabbitMQ 的重要概念以及安装](system-design/data-communication/rabbitmq.md)
### 网站架构
-- [一文读懂分布式应该学什么](./system-design/website-architecture/分布式.md)
-- [8 张图读懂大型网站技术架构](./system-design/website-architecture/8%20张图读懂大型网站技术架构.md)
-- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./system-design/website-architecture/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md)
+- [一文读懂分布式应该学什么](system-design/website-architecture/分布式.md)
+- [8 张图读懂大型网站技术架构](system-design/website-architecture/8%20张图读懂大型网站技术架构.md)
+- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](system-design/website-architecture/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md)
## 面试指南
### 备战面试
-* [【备战面试1】程序员的简历就该这样写](./essential-content-for-interview/PreparingForInterview/程序员的简历之道.md)
-* [【备战面试2】初出茅庐的程序员该如何准备面试?](./essential-content-for-interview/PreparingForInterview/interviewPrepare.md)
-* [【备战面试3】7个大部分程序员在面试前很关心的问题](./essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md)
-* [【备战面试4】Github上开源的Java面试/学习相关的仓库推荐](./essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md)
-* [【备战面试5】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./essential-content-for-interview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md)
-* [【备战面试6】美团面试常见问题总结(附详解答案)](./essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md)
+* [【备战面试1】程序员的简历就该这样写](essential-content-for-interview/PreparingForInterview/程序员的简历之道.md)
+* [【备战面试2】初出茅庐的程序员该如何准备面试?](essential-content-for-interview/PreparingForInterview/interviewPrepare.md)
+* [【备战面试3】7个大部分程序员在面试前很关心的问题](essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md)
+* [【备战面试4】Github上开源的Java面试/学习相关的仓库推荐](essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md)
+* [【备战面试5】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](essential-content-for-interview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md)
+* [【备战面试6】美团面试常见问题总结(附详解答案)](essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md)
### 常见面试题总结
-* [第一周(2018-8-7)](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals)
-* [第二周(2018-8-13)](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......)
-* [第三周(2018-08-22)](./java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结)
-* [第四周(2018-8-30).md](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。)
+* [第一周(2018-8-7)](essential-content-for-interview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals)
+* [第二周(2018-8-13)](essential-content-for-interview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......)
+* [第三周(2018-08-22)](java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结)
+* [第四周(2018-8-30).md](essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。)
### 面经
-- [5面阿里,终获offer(2018年秋招)](./essential-content-for-interview/BATJrealInterviewExperience/5面阿里,终获offer.md)
+- [5面阿里,终获offer(2018年秋招)](essential-content-for-interview/BATJrealInterviewExperience/5面阿里,终获offer.md)
+- [蚂蚁金服2019实习生面经总结(已拿口头offer)](essential-content-for-interview/BATJrealInterviewExperience/蚂蚁金服实习生面经总结(已拿口头offer).md)
+- [2019年蚂蚁金服、头条、拼多多的面试总结](essential-content-for-interview/BATJrealInterviewExperience/2019alipay-pinduoduo-toutiao.md)
## 工具
### Git
-* [Git入门](./tools/Git.md)
+* [Git入门](tools/Git.md)
### Docker
-* [Docker 入门](./tools/Docker.md)
-* [一文搞懂 Docker 镜像的常用操作!](./tools/Docker-Image.md)
+* [Docker 入门](tools/Docker.md)
+* [一文搞懂 Docker 镜像的常用操作!](tools/Docker-Image.md)
## 资料
### 书单
-- [Java程序员必备书单](./data/java-recommended-books.md)
+- [Java程序员必备书单](data/java-recommended-books.md)
### Github榜单
-- [Java 项目月榜单](./github-trending/JavaGithubTrending.md)
+- [Java 项目月榜单](github-trending/JavaGithubTrending.md)
***
@@ -201,13 +204,6 @@ Java后端技术交流群(限工作一年及以上,架构视频免费领取)
![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg)
-
-## 架构
-
-
-
-
-
## 公众号
- 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
diff --git a/docs/database/Redis/Redis.md b/docs/database/Redis/Redis.md
index e9eefeecba8a39be063a8c8371eec90eaebfbbaf..fa64bd60565b7977c2a9aa4bcd35bf6d864a0dab 100644
--- a/docs/database/Redis/Redis.md
+++ b/docs/database/Redis/Redis.md
@@ -1,32 +1,32 @@
-
+
+
- [redis 简介](#redis-简介)
-- [为什么要用 redis /为什么要用缓存](#为什么要用-redis-为什么要用缓存)
+- [为什么要用 redis/为什么要用缓存](#为什么要用-redis为什么要用缓存)
- [为什么要用 redis 而不用 map/guava 做缓存?](#为什么要用-redis-而不用-mapguava-做缓存)
- [redis 和 memcached 的区别](#redis-和-memcached-的区别)
- [redis 常见数据结构以及使用场景分析](#redis-常见数据结构以及使用场景分析)
- - [1. String](#1-string)
- - [2.Hash](#2hash)
- - [3.List](#3list)
- - [4.Set](#4set)
- - [5.Sorted Set](#5sorted-set)
+ - [1.String](#1string)
+ - [2.Hash](#2hash)
+ - [3.List](#3list)
+ - [4.Set](#4set)
+ - [5.Sorted Set](#5sorted-set)
- [redis 设置过期时间](#redis-设置过期时间)
-- [redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?)](#redis-内存淘汰机制(mysql里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?))
-- [redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)](#redis-持久化机制(怎么保证-redis-挂掉之后再重启数据可以进行恢复))
+- [redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?)](#redis-内存淘汰机制mysql里有2000w数据redis中只存20w的数据如何保证redis中的数据都是热点数据)
+- [redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)](#redis-持久化机制怎么保证-redis-挂掉之后再重启数据可以进行恢复)
- [redis 事务](#redis-事务)
- [缓存雪崩和缓存穿透问题解决方案](#缓存雪崩和缓存穿透问题解决方案)
- [如何解决 Redis 的并发竞争 Key 问题](#如何解决-redis-的并发竞争-key-问题)
-- [如何保证缓存与数据库双写时的数据一致性?](#如何保证缓存与数据库双写时的数据一致性?)
-- [参考:](#参考:)
-
-
+- [如何保证缓存与数据库双写时的数据一致性?](#如何保证缓存与数据库双写时的数据一致性)
+- [参考:](#参考)
+
### redis 简介
简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。
-### 为什么要用 redis /为什么要用缓存
+### 为什么要用 redis/为什么要用缓存
主要从“高性能”和“高并发”这两点来看待这个问题。
@@ -72,7 +72,7 @@
### redis 常见数据结构以及使用场景分析
-#### 1. String
+#### 1.String
> **常用命令:** set,get,decr,incr,mget 等。
@@ -151,7 +151,7 @@ Redis中有个设置时间过期的功能,即对存储在 redis 数据库中
**redis 内存淘汰机制。**
-### redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?)
+### redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?)
redis 配置文件 redis.conf 中有相关注释,我这里就不贴了,大家可以自行查阅或者通过这个网址查看: [http://download.redis.io/redis-stable/redis.conf](http://download.redis.io/redis-stable/redis.conf)
@@ -168,7 +168,7 @@ redis 配置文件 redis.conf 中有相关注释,我这里就不贴了,大
**备注: 关于 redis 设置过期时间以及内存淘汰机制,我这里只是简单的总结一下,后面会专门写一篇文章来总结!**
-### redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)
+### redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)
很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后回复数据),或者是为了防止系统故障而将数据备份到一个远程位置。
@@ -189,7 +189,6 @@ save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
```
-
**AOF(append-only file)持久化**
与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:
@@ -210,15 +209,12 @@ appendfsync no #让操作系统决定何时进行同步
为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。
-
**Redis 4.0 对于持久化机制的优化**
Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 `aof-use-rdb-preamble` 开启)。
如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。
-
-
**补充内容:AOF 重写**
AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
@@ -227,10 +223,9 @@ AOF重写是一个有歧义的名字,该功能是通过读取数据库中的
在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作
-
**更多内容可以查看我的这篇文章:**
-- [https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/Redis/Redis持久化.md](https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/Redis/Redis持久化.md)
+- [Redis持久化](Redis持久化.md)
### redis 事务
@@ -278,9 +273,7 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。
- https://www.jianshu.com/p/8bddd381de06
-
-### 如何保证缓存与数据库双写时的数据一致性?
-
+### 如何保证缓存与数据库双写时的数据一致性?
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
diff --git "a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" "b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md"
index a1beb70e1707c067ffc861ba0ee9ffac0bb547d6..82d0a02b0b1534cebecf86bc77aacbb344220505 100644
--- "a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md"
+++ "b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md"
@@ -16,39 +16,40 @@
## 2. 线程有哪些基本状态?这些状态是如何定义的?
-1. **新建(new)**:新创建了一个线程对象。
-2. **可运行(runnable)**:线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取cpu的使用权。
-3. **运行(running)**:可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。
-4. **阻塞(block)**:阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。阻塞的情况分三种:
- - **(一). 等待阻塞**:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waiting queue)中。
- - **(二). 同步阻塞**:运行(running)的线程在获取对象的同步锁时,若该同步 锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
- - **(三). 其他阻塞**: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
-5. **死亡(dead)**:线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
+Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4 节)。
-![](https://user-gold-cdn.xitu.io/2018/8/9/1651f19d7c4e93a3?w=876&h=492&f=png&s=128092)
+![Java 线程的状态 ](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%E7%BA%BF%E7%A8%8B%E7%9A%84%E7%8A%B6%E6%80%81.png)
-备注: 可以用早起坐地铁来比喻这个过程(下面参考自牛客网某位同学的回答):
+线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4 节):
-1. 还没起床:sleeping
-2. 起床收拾好了,随时可以坐地铁出发:Runnable
-3. 等地铁来:Waiting
-4. 地铁来了,但要排队上地铁:I/O阻塞
-5. 上了地铁,发现暂时没座位:synchronized阻塞
-6. 地铁上找到座位:Running
-7. 到达目的地:Dead
+![Java 线程状态变迁 ](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%20%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81.png)
+
+由上图可以看出:线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。
+
+> 操作系统隐藏 Java 虚拟机(JVM)中的 RUNNABLE 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinjava.com/):[Java Thread Life Cycle and Thread States](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/)),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。
+
+![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png)
+
+当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)**状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的` run() `方法之后将会进入到 **TERMINATED(终止)** 状态。
+
## 3. 何为多线程?
多线程就是多个线程同时运行或交替运行。单核CPU的话是顺序执行,也就是交替运行。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行。
-## 4. 为什么多线程是必要的?
+## 4. 为什么要使用多线程?
+
+先从总体上来说:
+
+- **从计算机底层来说:**线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
+- **从当代互联网发展趋势来说:**现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。
-1. 使用线程可以把占据长时间的程序中的任务放到后台去处理。
-2. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
-3. 程序的运行速度可能加快。
+再深入到计算机底层来探讨:
+- **单核时代:** 在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。
+- **多核时代:** 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个线程就可以让多个 CPU 核心被利用到,这样就提高了 CPU 的利用率。
## 5 使用多线程常见的三种方式
### ①继承Thread类
diff --git a/docs/java/HashMap.md b/docs/java/HashMap.md
index 45fad50cdb3617b94f0b0a08a230538bd43cc63f..716bb1f34a56cb4b0bde2867fc92dbf514b983b6 100644
--- a/docs/java/HashMap.md
+++ b/docs/java/HashMap.md
@@ -235,7 +235,7 @@ HashMap只提供了put用于添加元素,putVal方法只是给put方法调用
**对putVal方法添加元素的分析如下:**
- ①如果定位到的数组位置没有元素 就直接插入。
-- ②如果定位到的数组位置有元素就和要插入的key比较,如果key相同就直接覆盖,如果key不相同,就判断p是否是一个树节点,如果是就调用`e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value)`将元素添加进入。如果不是就遍历链表插入。
+- ②如果定位到的数组位置有元素就和要插入的key比较,如果key相同就直接覆盖,如果key不相同,就判断p是否是一个树节点,如果是就调用`e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value)`将元素添加进入。如果不是就遍历链表插入(插入的是链表尾部)。