From be8db352923bcc3fc73b750c079d76310251a3ad Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Tue, 23 Apr 2019 19:49:59 +0800
Subject: [PATCH 01/10] Update HashMap.md
---
docs/java/HashMap.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/java/HashMap.md b/docs/java/HashMap.md
index 45fad50c..716bb1f3 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)`将元素添加进入。如果不是就遍历链表插入(插入的是链表尾部)。
From 25dbfb8e0d6543ced903edae4d59a13ad8f8367c Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 13:24:12 +0800
Subject: [PATCH 02/10] Update README.md
---
README.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index d37d3fb0..e2289c0a 100644
--- a/README.md
+++ b/README.md
@@ -292,13 +292,15 @@ Markdown 格式参考:[Github Markdown格式](https://guides.github.com/featur
下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后!
-
-
+
+
+
+
From 28ea82ba184bd4000d07afc83d2898d520a84171 Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 16:09:40 +0800
Subject: [PATCH 03/10] Update README.md
---
README.md | 7 -------
1 file changed, 7 deletions(-)
diff --git a/README.md b/README.md
index d8089108..626ea370 100644
--- a/README.md
+++ b/README.md
@@ -280,13 +280,6 @@ Markdown 格式参考:[Github Markdown格式](https://guides.github.com/featur

-
-### 架构
-
-
-
-
-
### Contributor
下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后!
From 006b2c61368d26ac416b7fcc91c70b911438a69c Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 18:21:41 +0800
Subject: [PATCH 04/10] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 626ea370..b4340e44 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,13 @@
-Special Sponsors
+Special Sponsors
+
-
+
From fbb8503c2b0e0135ef0e1cf499c26992c3cb34cc Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 18:22:39 +0800
Subject: [PATCH 05/10] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b4340e44..b567d536 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
Special Sponsors
-
+
From d88db4bee2865c90525fa7791fceaff121bfea4f Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 21:34:09 +0800
Subject: [PATCH 06/10] Update HomePage.md
---
docs/HomePage.md | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/docs/HomePage.md b/docs/HomePage.md
index 4fccd165..cf1cf37c 100644
--- a/docs/HomePage.md
+++ b/docs/HomePage.md
@@ -1,6 +1,6 @@
Java后端技术交流群(限工作一年及以上,架构视频免费领取) :[](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
-
-
+
+
@@ -201,13 +201,6 @@ Java后端技术交流群(限工作一年及以上,架构视频免费领取)

-
-## 架构
-
-
-
-
-
## 公众号
- 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
From e319b5582db062cee3a494d5ab22ea37413203e5 Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 21:35:49 +0800
Subject: [PATCH 07/10] Update HomePage.md
---
docs/HomePage.md | 149 ++++++++++++++++++++++++-----------------------
1 file changed, 76 insertions(+), 73 deletions(-)
diff --git a/docs/HomePage.md b/docs/HomePage.md
index cf1cf37c..086d6a97 100644
--- a/docs/HomePage.md
+++ b/docs/HomePage.md
@@ -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)
***
From 6dc0df88d38ea9ef3a571e06ec05722c67fcadff Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Wed, 24 Apr 2019 21:47:51 +0800
Subject: [PATCH 08/10] fix link error
---
docs/database/Redis/Redis.md | 45 +++++++++++++++---------------------
1 file changed, 19 insertions(+), 26 deletions(-)
diff --git a/docs/database/Redis/Redis.md b/docs/database/Redis/Redis.md
index a53a6481..7829310d 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
-
-### 如何保证缓存与数据库双写时的数据一致性?
-
+### 如何保证缓存与数据库双写时的数据一致性?
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
From 81615f30843769161e17cc6be07fdf318a6c2755 Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Thu, 25 Apr 2019 08:22:24 +0800
Subject: [PATCH 09/10] =?UTF-8?q?Update=20=E7=AC=AC=E5=9B=9B=E5=91=A8(2018?=
=?UTF-8?q?-8-30).md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../第四周(2018-8-30).md | 48 +++++++------------
1 file changed, 17 insertions(+), 31 deletions(-)
diff --git a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
index a1beb70e..cf19fac9 100644
--- a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
+++ b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
@@ -1,54 +1,40 @@
## 1. 简述线程,程序、进程的基本概念。以及他们之间关系是什么?
-**线程**与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
+Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4 节)。
-**程序**是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
+
-**进程**是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。
+线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4 节):
-**线程** 是 **进程** 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。
+
-**线程上下文的切换比进程上下文切换要快很多**
-- 进程切换时,涉及到当前进程的CPU环境的保存和新被调度运行进程的CPU环境的设置。
-- 线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
-## 2. 线程有哪些基本状态?这些状态是如何定义的?
+由上图可以看出:线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。
-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 虚拟机(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(运行中)** 状态 。
-
-
-备注: 可以用早起坐地铁来比喻这个过程(下面参考自牛客网某位同学的回答):
-
-1. 还没起床:sleeping
-2. 起床收拾好了,随时可以坐地铁出发:Runnable
-3. 等地铁来:Waiting
-4. 地铁来了,但要排队上地铁:I/O阻塞
-5. 上了地铁,发现暂时没座位:synchronized阻塞
-6. 地铁上找到座位:Running
-7. 到达目的地:Dead
+
+当线程执行 `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. 为什么要使用多线程?
-1. 使用线程可以把占据长时间的程序中的任务放到后台去处理。
-2. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
-3. 程序的运行速度可能加快。
+先从总体上来说:
+- **从计算机底层来说:**线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
+- **从当代互联网发展趋势来说:**现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。
+
+再深入到计算机底层来探讨:
+
+- **单核时代:** 在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。
+- **多核时代:** 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个线程就可以让多个 CPU 核心被利用到,这样就提高了 CPU 的利用率。
## 5 使用多线程常见的三种方式
### ①继承Thread类
From c953242f31a0f32c098774f86dda4ebf1f847bbe Mon Sep 17 00:00:00 2001
From: SnailClimb
Date: Thu, 25 Apr 2019 08:38:24 +0800
Subject: [PATCH 10/10] =?UTF-8?q?Update=20=E7=AC=AC=E5=9B=9B=E5=91=A8(2018?=
=?UTF-8?q?-8-30).md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../第四周(2018-8-30).md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
index cf19fac9..82d0a02b 100644
--- a/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
+++ b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md
@@ -1,6 +1,21 @@
## 1. 简述线程,程序、进程的基本概念。以及他们之间关系是什么?
+**线程**与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
+
+**程序**是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
+
+**进程**是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。
+
+**线程** 是 **进程** 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。
+
+**线程上下文的切换比进程上下文切换要快很多**
+
+- 进程切换时,涉及到当前进程的CPU环境的保存和新被调度运行进程的CPU环境的设置。
+- 线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
+
+## 2. 线程有哪些基本状态?这些状态是如何定义的?
+
Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4 节)。
