From f4f1cb4b42bdd0d25f58df12dab64bc45a3c742d Mon Sep 17 00:00:00 2001
From: "hollis.zhl"
Date: Sun, 29 Mar 2020 19:33:26 +0800
Subject: [PATCH] =?UTF-8?q?V3.0=20,=E7=9F=A5=E8=AF=86=E4=BD=93=E7=B3=BB?=
=?UTF-8?q?=E5=AE=8C=E5=96=84=EF=BC=8C=E9=80=9A=E8=BF=87GitHub=20Pages?=
=?UTF-8?q?=E6=8F=90=E4=BE=9B=E6=9B=B4=E5=A5=BD=E7=9A=84=E9=98=85=E8=AF=BB?=
=?UTF-8?q?=E4=BD=93=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 990 +-----------
basics/java-basic/basic-data-types.md | 11 -
basics/java-basic/data-structure/list.md | 0
basics/jvm/java-object-model.md | 14 -
basics/jvm/jvm-memory-structure.md | 28 -
catalog/catalog.md | 88 --
docs/README.md | 43 +-
docs/_coverpage.md | 4 +-
docs/_sidebar.md | 1349 ++++++++++++++++-
docs/basement/_sidebar.md | 89 ++
docs/basement/jvm/_sidebar.md | 68 +
.../basement}/jvm/java-memory-model.md | 0
.../basement/jvm}/stack-alloc.md | 0
docs/basics/_sidebar.md | 415 +++++
docs/basics/concurrent-coding/_sidebar.md | 102 ++
.../concurrent-vs-parallel.md | 7 +
docs/basics/concurrent-coding/concurrent.md | 13 +
.../concurrent-coding}/deadlock-java-level.md | 0
docs/basics/concurrent-coding/parallel.md | 2 +
.../basics/concurrent-coding}/synchronized.md | 0
docs/basics/java-basic/ASCII.md | 16 +
.../basics}/java-basic/Arrays-asList.md | 0
.../basics}/java-basic/CET-UTC-GMT-CST.md | 0
{basics => docs/basics}/java-basic/Class.md | 0
.../java-basic/Collection-vs-Collections.md | 0
.../java-basic/ConcurrentSkipListMap.md | 0
.../java-basic/CopyOnWriteArrayList.md | 0
.../java-basic/Enumeration-vs-Iterator.md | 0
{basics => docs/basics}/java-basic/GMT.md | 0
.../HashMap-HashTable-ConcurrentHashMap.md | 0
docs/basics/java-basic/README.md | 12 +
.../StandardTime-vs-daylightSavingTime.md | 0
{basics => docs/basics}/java-basic/UNICODE.md | 0
.../basics}/java-basic/UTF8-UTF16-UTF32.md | 0
docs/basics/java-basic/Wildcard-Character.md | 10 +
docs/basics/java-basic/YYYY-vs-yyyy.md | 57 +
docs/basics/java-basic/_sidebar.md | 274 ++++
.../java-basic/annotation-in-spring.md | 0
.../basics}/java-basic/aop-vs-proxy.md | 0
.../basics}/java-basic/api-vs-spi.md | 0
.../arraylist-vs-linkedlist-vs-vector.md | 0
docs/basics/java-basic/basic-data-types.md | 17 +
.../java-basic/big-endian-vs-little-endian.md | 0
.../basics}/java-basic/bio-vs-nio-vs-aio.md | 0
.../java-basic/block-vs-non-blocking.md | 0
.../basics}/java-basic/boxing-unboxing.md | 0
.../byte-stream-vs-character-stream.md | 0
.../basics}/java-basic/constructor.md | 0
.../basics}/java-basic/create-annotation.md | 0
.../basics}/java-basic/create-spi.md | 0
.../basics}/java-basic/custom-annotation.md | 0
docs/basics/java-basic/define-exception.md | 6 +
.../diff-serializable-vs-externalizable.md | 17 +
.../dynamic-proxy-implementation.md | 0
.../java-basic/dynamic-proxy-vs-reflection.md | 0
.../basics}/java-basic/dynamic-proxy.md | 0
.../basics}/java-basic/enum-compare.md | 0
.../basics}/java-basic/enum-impl.md | 0
.../basics}/java-basic/enum-serializable.md | 0
.../basics}/java-basic/enum-singleton.md | 0
.../basics}/java-basic/enum-switch.md | 0
.../basics}/java-basic/enum-thread-safe.md | 0
.../basics}/java-basic/enum-usage.md | 0
docs/basics/java-basic/error-vs-exception.md | 6 +
docs/basics/java-basic/exception-chain.md | 26 +
docs/basics/java-basic/exception-type.md | 20 +
docs/basics/java-basic/extends-vs-super.md | 48 +
.../java-basic/fail-fast-vs-fail-safe.md | 0
.../basics}/java-basic/final-string.md | 0
.../basics}/java-basic/float-amount.md | 0
{basics => docs/basics}/java-basic/float.md | 0
.../basics}/java-basic/gbk-gb2312-gb18030.md | 0
.../java-basic/genericity-list-wildcard.md | 0
.../basics}/java-basic/genericity-list.md | 0
docs/basics/java-basic/generics-problem.md | 42 +
docs/basics/java-basic/generics.md | 5 +
.../basics/java-basic/get-los_angeles-time.md | 52 +
docs/basics/java-basic/handle-exception.md | 6 +
.../java-basic/inheritance-composition.md | 0
.../input-stream-vs-output-stream.md | 0
.../basics}/java-basic/integer-cache.md | 0
.../basics}/java-basic/integer-scope.md | 0
{basics => docs/basics}/java-basic/k-t-v-e.md | 0
.../java-basic/keyword-about-exception.md | 11 +
.../basics}/java-basic/linux-io.md | 0
.../basics}/java-basic/meta-annotation.md | 0
.../java-basic/order-about-finllly-return.md | 6 +
docs/basics/java-basic/protobuf.md | 9 +
.../basics}/java-basic/reflection.md | 0
{basics => docs/basics}/java-basic/scope.md | 0
.../java-basic/serialVersionUID-modify.md | 278 ++++
docs/basics/java-basic/serialVersionUID.md | 21 +
.../basics/java-basic/serialize-in-java.md | 35 -
docs/basics/java-basic/serialize-principle.md | 397 +++++
.../basics}/java-basic/serialize-singleton.md | 0
.../basics}/java-basic/serialize.md | 0
.../basics}/java-basic/set-repetition.md | 0
.../basics}/java-basic/set-vs-list.md | 0
.../simpledateformat-thread-safe.md | 0
.../basics}/java-basic/single-double-float.md | 0
.../basics}/java-basic/spi-principle.md | 0
.../basics/java-basic}/stack-alloc.md | 0
.../basics}/java-basic/static-proxy.md | 0
{basics => docs/basics}/java-basic/stream.md | 0
.../basics}/java-basic/string-append.md | 0
.../basics}/java-basic/string-concat.md | 0
.../basics}/java-basic/substring.md | 0
.../basics}/java-basic/switch-string.md | 0
.../synchronized-vs-asynchronization.md | 0
.../java-basic/synchronizedlist-vector.md | 0
.../basics}/java-basic/syntactic-sugar.md | 0
docs/basics/java-basic/time-in-java8.md | 57 +
.../basics}/java-basic/time-zone.md | 0
.../basics}/java-basic/timestamp.md | 0
docs/basics/java-basic/transient.md | 1 +
docs/basics/java-basic/try-with-resources.md | 91 ++
docs/basics/java-basic/type-erasue.md | 199 +++
.../basics}/java-basic/url-encode.md | 0
.../basics}/java-basic/usage-of-reflection.md | 0
.../java-basic/value-of-vs-to-string.md | 0
.../basics}/java-basic/variable.md | 0
{basics => docs/basics}/java-basic/why-gbk.md | 0
.../basics}/java-basic/why-utf8.md | 0
docs/basics/object-oriented/_sidebar.md | 32 +
.../object-oriented}/characteristics.md | 8 +-
docs/basics/object-oriented/constructor.md | 5 +
.../inheritance-composition.md | 67 +
docs/basics/object-oriented/java-pass-by.md | 57 +
.../basics/object-oriented}/jvm-language.md | 0
.../object-oriented-vs-procedure-oriented.md | 10 +-
.../overloading-vs-overriding.md | 0
.../object-oriented}/platform-independent.md | 20 +-
.../basics/object-oriented}/polymorphism.md | 7 +-
.../basics/object-oriented}/principle.md | 3 +
docs/basics/object-oriented/scope.md | 11 +
docs/basics/object-oriented/variable.md | 27 +
.../object-oriented/why-pass-by-reference.md | 139 +-
docs/contact/wechat-hollis.jpg | Bin 0 -> 8333 bytes
docs/css/my.css | 3 +
docs/index.html | 85 +-
140 files changed, 4079 insertions(+), 1337 deletions(-)
delete mode 100644 basics/java-basic/basic-data-types.md
delete mode 100644 basics/java-basic/data-structure/list.md
delete mode 100644 basics/jvm/java-object-model.md
delete mode 100644 basics/jvm/jvm-memory-structure.md
delete mode 100644 catalog/catalog.md
create mode 100644 docs/basement/_sidebar.md
create mode 100644 docs/basement/jvm/_sidebar.md
rename {basics => docs/basement}/jvm/java-memory-model.md (100%)
rename {basics/java-basic => docs/basement/jvm}/stack-alloc.md (100%)
create mode 100644 docs/basics/_sidebar.md
create mode 100644 docs/basics/concurrent-coding/_sidebar.md
create mode 100644 docs/basics/concurrent-coding/concurrent-vs-parallel.md
create mode 100644 docs/basics/concurrent-coding/concurrent.md
rename {basics/java-basic => docs/basics/concurrent-coding}/deadlock-java-level.md (100%)
create mode 100644 docs/basics/concurrent-coding/parallel.md
rename {basics/java-basic => docs/basics/concurrent-coding}/synchronized.md (100%)
create mode 100644 docs/basics/java-basic/ASCII.md
rename {basics => docs/basics}/java-basic/Arrays-asList.md (100%)
rename {basics => docs/basics}/java-basic/CET-UTC-GMT-CST.md (100%)
rename {basics => docs/basics}/java-basic/Class.md (100%)
rename {basics => docs/basics}/java-basic/Collection-vs-Collections.md (100%)
rename {basics => docs/basics}/java-basic/ConcurrentSkipListMap.md (100%)
rename {basics => docs/basics}/java-basic/CopyOnWriteArrayList.md (100%)
rename {basics => docs/basics}/java-basic/Enumeration-vs-Iterator.md (100%)
rename {basics => docs/basics}/java-basic/GMT.md (100%)
rename {basics => docs/basics}/java-basic/HashMap-HashTable-ConcurrentHashMap.md (100%)
create mode 100644 docs/basics/java-basic/README.md
rename {basics => docs/basics}/java-basic/StandardTime-vs-daylightSavingTime.md (100%)
rename {basics => docs/basics}/java-basic/UNICODE.md (100%)
rename {basics => docs/basics}/java-basic/UTF8-UTF16-UTF32.md (100%)
create mode 100644 docs/basics/java-basic/Wildcard-Character.md
create mode 100644 docs/basics/java-basic/YYYY-vs-yyyy.md
create mode 100644 docs/basics/java-basic/_sidebar.md
rename {basics => docs/basics}/java-basic/annotation-in-spring.md (100%)
rename {basics => docs/basics}/java-basic/aop-vs-proxy.md (100%)
rename {basics => docs/basics}/java-basic/api-vs-spi.md (100%)
rename {basics => docs/basics}/java-basic/arraylist-vs-linkedlist-vs-vector.md (100%)
create mode 100644 docs/basics/java-basic/basic-data-types.md
rename {basics => docs/basics}/java-basic/big-endian-vs-little-endian.md (100%)
rename {basics => docs/basics}/java-basic/bio-vs-nio-vs-aio.md (100%)
rename {basics => docs/basics}/java-basic/block-vs-non-blocking.md (100%)
rename {basics => docs/basics}/java-basic/boxing-unboxing.md (100%)
rename {basics => docs/basics}/java-basic/byte-stream-vs-character-stream.md (100%)
rename {basics => docs/basics}/java-basic/constructor.md (100%)
rename {basics => docs/basics}/java-basic/create-annotation.md (100%)
rename {basics => docs/basics}/java-basic/create-spi.md (100%)
rename {basics => docs/basics}/java-basic/custom-annotation.md (100%)
create mode 100644 docs/basics/java-basic/define-exception.md
create mode 100644 docs/basics/java-basic/diff-serializable-vs-externalizable.md
rename {basics => docs/basics}/java-basic/dynamic-proxy-implementation.md (100%)
rename {basics => docs/basics}/java-basic/dynamic-proxy-vs-reflection.md (100%)
rename {basics => docs/basics}/java-basic/dynamic-proxy.md (100%)
rename {basics => docs/basics}/java-basic/enum-compare.md (100%)
rename {basics => docs/basics}/java-basic/enum-impl.md (100%)
rename {basics => docs/basics}/java-basic/enum-serializable.md (100%)
rename {basics => docs/basics}/java-basic/enum-singleton.md (100%)
rename {basics => docs/basics}/java-basic/enum-switch.md (100%)
rename {basics => docs/basics}/java-basic/enum-thread-safe.md (100%)
rename {basics => docs/basics}/java-basic/enum-usage.md (100%)
create mode 100644 docs/basics/java-basic/error-vs-exception.md
create mode 100644 docs/basics/java-basic/exception-chain.md
create mode 100644 docs/basics/java-basic/exception-type.md
create mode 100644 docs/basics/java-basic/extends-vs-super.md
rename {basics => docs/basics}/java-basic/fail-fast-vs-fail-safe.md (100%)
rename {basics => docs/basics}/java-basic/final-string.md (100%)
rename {basics => docs/basics}/java-basic/float-amount.md (100%)
rename {basics => docs/basics}/java-basic/float.md (100%)
rename {basics => docs/basics}/java-basic/gbk-gb2312-gb18030.md (100%)
rename {basics => docs/basics}/java-basic/genericity-list-wildcard.md (100%)
rename {basics => docs/basics}/java-basic/genericity-list.md (100%)
create mode 100644 docs/basics/java-basic/generics-problem.md
create mode 100644 docs/basics/java-basic/generics.md
create mode 100644 docs/basics/java-basic/get-los_angeles-time.md
create mode 100644 docs/basics/java-basic/handle-exception.md
rename {basics => docs/basics}/java-basic/inheritance-composition.md (100%)
rename {basics => docs/basics}/java-basic/input-stream-vs-output-stream.md (100%)
rename {basics => docs/basics}/java-basic/integer-cache.md (100%)
rename {basics => docs/basics}/java-basic/integer-scope.md (100%)
rename {basics => docs/basics}/java-basic/k-t-v-e.md (100%)
create mode 100644 docs/basics/java-basic/keyword-about-exception.md
rename {basics => docs/basics}/java-basic/linux-io.md (100%)
rename {basics => docs/basics}/java-basic/meta-annotation.md (100%)
create mode 100644 docs/basics/java-basic/order-about-finllly-return.md
create mode 100644 docs/basics/java-basic/protobuf.md
rename {basics => docs/basics}/java-basic/reflection.md (100%)
rename {basics => docs/basics}/java-basic/scope.md (100%)
create mode 100644 docs/basics/java-basic/serialVersionUID-modify.md
create mode 100644 docs/basics/java-basic/serialVersionUID.md
rename basics/java-basic/serialize-principle.md => docs/basics/java-basic/serialize-in-java.md (78%)
create mode 100644 docs/basics/java-basic/serialize-principle.md
rename {basics => docs/basics}/java-basic/serialize-singleton.md (100%)
rename {basics => docs/basics}/java-basic/serialize.md (100%)
rename {basics => docs/basics}/java-basic/set-repetition.md (100%)
rename {basics => docs/basics}/java-basic/set-vs-list.md (100%)
rename {basics => docs/basics}/java-basic/simpledateformat-thread-safe.md (100%)
rename {basics => docs/basics}/java-basic/single-double-float.md (100%)
rename {basics => docs/basics}/java-basic/spi-principle.md (100%)
rename {basics/jvm => docs/basics/java-basic}/stack-alloc.md (100%)
rename {basics => docs/basics}/java-basic/static-proxy.md (100%)
rename {basics => docs/basics}/java-basic/stream.md (100%)
rename {basics => docs/basics}/java-basic/string-append.md (100%)
rename {basics => docs/basics}/java-basic/string-concat.md (100%)
rename {basics => docs/basics}/java-basic/substring.md (100%)
rename {basics => docs/basics}/java-basic/switch-string.md (100%)
rename {basics => docs/basics}/java-basic/synchronized-vs-asynchronization.md (100%)
rename {basics => docs/basics}/java-basic/synchronizedlist-vector.md (100%)
rename {basics => docs/basics}/java-basic/syntactic-sugar.md (100%)
create mode 100644 docs/basics/java-basic/time-in-java8.md
rename {basics => docs/basics}/java-basic/time-zone.md (100%)
rename {basics => docs/basics}/java-basic/timestamp.md (100%)
create mode 100644 docs/basics/java-basic/transient.md
create mode 100644 docs/basics/java-basic/try-with-resources.md
create mode 100644 docs/basics/java-basic/type-erasue.md
rename {basics => docs/basics}/java-basic/url-encode.md (100%)
rename {basics => docs/basics}/java-basic/usage-of-reflection.md (100%)
rename {basics => docs/basics}/java-basic/value-of-vs-to-string.md (100%)
rename {basics => docs/basics}/java-basic/variable.md (100%)
rename {basics => docs/basics}/java-basic/why-gbk.md (100%)
rename {basics => docs/basics}/java-basic/why-utf8.md (100%)
create mode 100644 docs/basics/object-oriented/_sidebar.md
rename {basics/java-basic => docs/basics/object-oriented}/characteristics.md (93%)
create mode 100644 docs/basics/object-oriented/constructor.md
create mode 100644 docs/basics/object-oriented/inheritance-composition.md
create mode 100644 docs/basics/object-oriented/java-pass-by.md
rename {basics/java-basic => docs/basics/object-oriented}/jvm-language.md (100%)
rename {basics/java-basic => docs/basics/object-oriented}/object-oriented-vs-procedure-oriented.md (90%)
rename {basics/java-basic => docs/basics/object-oriented}/overloading-vs-overriding.md (100%)
rename {basics/java-basic => docs/basics/object-oriented}/platform-independent.md (97%)
rename {basics/java-basic => docs/basics/object-oriented}/polymorphism.md (96%)
rename {basics/java-basic => docs/basics/object-oriented}/principle.md (99%)
create mode 100644 docs/basics/object-oriented/scope.md
create mode 100644 docs/basics/object-oriented/variable.md
rename basics/java-basic/java-pass-by.md => docs/basics/object-oriented/why-pass-by-reference.md (55%)
create mode 100644 docs/contact/wechat-hollis.jpg
create mode 100644 docs/css/my.css
diff --git a/README.md b/README.md
index 5f2bfc6..e986fba 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-[![](http://www.hollischuang.com/wp-content/uploads/2018/10/Hollis.png)](https://www.hollischuang.com)
-
## To Be Top Javaer - Java工程师成神之路
![](https://img.shields.io/badge/version-v2.0.0-green.svg) ![](https://img.shields.io/badge/author-Hollis-yellow.svg) ![](https://img.shields.io/badge/license-GPL-blue.svg)
@@ -7,993 +5,47 @@
| 主要版本 | 更新时间 | 备注 |
| ---- | ---------- | -------------- |
-| v1.0 | 2015-08-01 | 首次发布 |
-| v1.1 | 2018-03-12 | 增加新技术知识、完善知识体系 |
+| v3.0 | 2020-03-29 | 知识体系完善
通过GitHub Page搭建,便于阅读|
| v2.0 | 2019-02-19 | 结构调整,更适合从入门到精通;
进一步完善知识体系;
新技术补充;|
+| v1.1 | 2018-03-12 | 增加新技术知识、完善知识体系 |
+| v1.0 | 2015-08-01 | 首次发布 |
-欢迎关注[Java之道]公众号,最新内容均会在该公众号中同步发出!
-![](pics/wechat.png)
-
-
-[全套思维导图](/mind-map.md)
-
-## 一、基础篇
-
-### 面向对象
-
-#### 什么是面向对象
-
-[面向对象、面向过程](/basics/java-basic/object-oriented-vs-procedure-oriented.md)
-
-[面向对象的三大基本特征](/basics/java-basic/characteristics.md)和[五大基本原则](/basics/java-basic/principle.md)
-
-#### 平台无关性
-
-[Java如何实现的平台无关性的](/basics/java-basic/platform-independent.md)
-
-[JVM还支持哪些语言(Kotlin、Groovy、JRuby、Jython、Scala)](/basics/java-basic/jvm-language.md)
-
-#### 值传递
-
-[值传递、引用传递](/basics/java-basic/java-pass-by.md)
-
-[为什么说Java中只有值传递](/basics/java-basic/java-pass-by.md)
-
-#### 封装、继承、多态
-
-[什么是多态](/basics/java-basic/polymorphism.md)、[方法重写与重载](/basics/java-basic/overloading-vs-overriding.md)
-
-Java的继承与实现
-
-[Java的继承与组合](/basics/java-basic/inheritance-composition.md)
-
-[构造函数与默认构造函数](/basics/java-basic/constructor.md)
-
-[类变量、成员变量和局部变量](/basics/java-basic/variable.md)
-
-[成员变量和方法作用域](/basics/java-basic/scope.md)
-
-### Java基础知识
-
-#### 基本数据类型
-
-[8种基本数据类型:整型、浮点型、布尔型、字符型](/basics/java-basic/basic-data-types.md)
-
-[整型中byte、short、int、long的取值范围](/basics/java-basic/integer-scope.md)
-
-[什么是浮点型?](/basics/java-basic/float.md)
-
-[什么是单精度和双精度?](/basics/java-basic/single-double-float.md)
-
-[为什么不能用浮点型表示金额?](/basics/java-basic/float-amount.md)
-
-#### 自动拆装箱
-
-[什么是包装类型、什么是基本类型、什么是自动拆装箱](/basics/java-basic/boxing-unboxing.md)
-
-[Integer的缓存机制](/basics/java-basic/integer-cache.md)
-
-#### String
-
-[字符串的不可变性](/basics/java-basic/final-string.md)
-
-[JDK 6和JDK 7中substring的原理及区别](/basics/java-basic/substring.md)
-
-replaceFirst、replaceAll、replace区别、
-
-[String对“+”的重载](/basics/java-basic/string-append.md)
-
-[字符串拼接的几种方式和区别](/basics/java-basic/string-concat.md)
-
-[String.valueOf和Integer.toString的区别](/basics/java-basic/value-of-vs-to-string.md)
-
-[switch对String的支持](/basics/java-basic/switch-string.md)
-
-字符串池、常量池(运行时常量池、Class常量池)、intern
-
-#### 熟悉Java中各种关键字
-
-transient、instanceof、volatile、synchronized、final、static、const 原理及用法。
-
-#### 集合类
-
-常用集合类的使用
-
-[ArrayList和LinkedList和Vector的区别](/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md)
-
-[SynchronizedList和Vector的区别](/basics/java-basic/synchronizedlist-vector.md)、
-
-[HashMap、HashTable、ConcurrentHashMap区别](/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md)
-
-[Set和List区别?](/basics/java-basic/set-vs-list.md)
-
-[Set如何保证元素不重复?](/basics/java-basic/set-repetition.md)
-
-[Java 8中stream相关用法](/basics/java-basic/stream.md)、
-
-apache集合处理工具类的使用、
-
-不同版本的JDK中HashMap的实现的区别以及原因
-
-[Collection和Collections区别](/basics/java-basic/Collection-vs-Collections.md)
-
-[Arrays.asList获得的List使用时需要注意什么](/basics/java-basic/Arrays-asList.md)
-
-[Enumeration和Iterator区别](/basics/java-basic/Enumeration-vs-Iterator.md)
-
-[fail-fast 和 fail-safe](/basics/java-basic/fail-fast-vs-fail-safe.md)
-
-[CopyOnWriteArrayList](/basics/java-basic/CopyOnWriteArrayList.md)
-
-[ConcurrentSkipListMap](/basics/java-basic/ConcurrentSkipListMap.md)
-
-#### 枚举
-
-[枚举的用法](/basics/java-basic/enum-usage.md)
-
-[枚举的实现](/basics/java-basic/enum-impl.md)
-
-[枚举与单例](/basics/java-basic/enum-singleton.md)、Enum类
-
-[Java枚举如何比较](/basics/java-basic/enum-compare.md)
-
-[switch对枚举的支持](/basics/java-basic/enum-switch.md)
-
-[枚举的序列化如何实现](/basics/java-basic/enum-serializable.md)
-
-[枚举的线程安全性问题](/basics/java-basic/enum-thread-safe.md)
-
-#### IO
-
-[字符流、字节流](/basics/java-basic/byte-stream-vs-character-stream.md)、[输入流、输出流](/basics/java-basic/input-stream-vs-output-stream.md)
-
-[同步、异步](/basics/java-basic/synchronized-vs-asynchronization.md)、[阻塞、非阻塞](/basics/java-basic/block-vs-non-blocking.md)、[Linux 5种IO模型](/basics/java-basic/linux-io.md)
-
-[BIO、NIO和AIO的区别、三种IO的用法与原理](/basics/java-basic/bio-vs-nio-vs-aio.md)、netty
-
-#### Java反射与javassist
-
-[反射](/basics/java-basic/reflection.md)与工厂模式、 [反射有什么作用](/basics/java-basic/usage-of-reflection.md)
-
-[Class类](/basics/java-basic/Class.md)
-
-`java.lang.reflect.*`
-
-#### 动态代理
-
-[静态代理](/basics/java-basic/static-proxy.md)、[动态代理](/basics/java-basic/dynamic-proxy.md)
-
-[动态代理和反射的关系](/basics/java-basic/dynamic-proxy-vs-reflection.md)
-
-[动态代理的几种实现方式](/basics/java-basic/dynamic-proxy-implementation.md)
-
-[AOP](/basics/java-basic/aop-vs-proxy.md)
-
-#### 序列化
-
-[什么是序列化与反序列化](/basics/java-basic/serialize.md)、为什么序列化、[序列化底层原理](/basics/java-basic/serialize-principle.md)、[序列化与单例模式](/basics/java-basic/serialize-singleton.md)、protobuf、为什么说序列化并不安全
-
-#### 注解
-
-[元注解](/basics/java-basic/meta-annotation.md)、[自定义注解](/basics/java-basic/custom-annotation.md)、Java中常用注解使用、注解与反射的结合
-
-[如何自定义一个注解?](/basics/java-basic/create-annotation.md)
-
-[Spring常用注解](/basics/java-basic/annotation-in-spring.md)
-
-#### JMS
-
-什么是Java消息服务、JMS消息传送模型
-
-#### JMX
-
-`java.lang.management.*`、 `javax.management.*`
-
-#### 泛型
-
-泛型与继承、类型擦除、[泛型中K T V E ? object等的含义](/basics/java-basic/k-t-v-e.md)、泛型各种用法
-
-限定通配符和非限定通配符、上下界限定符extends 和 super
-
-[List
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 7324002..23ed0fe 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -1,12 +1,1349 @@
+* 基础篇
-## 一、基础篇
+ * 面向对象
+
+ * 什么是面向对象
+
+ * [面向对象与面向过程](/basics/object-oriented/object-oriented-vs-procedure-oriented.md)
+
+ * [面向对象的三大基本特征](/basics/object-oriented/characteristics.md)
+
+ * [面向对象的五大基本原则](/basics/object-oriented/principle.md)
+ * 平台无关性
+
+ * [Java如何实现的平台无关性的](/basics/object-oriented/platform-independent.md)
+
+ * [JVM还支持哪些语言](/basics/object-oriented/jvm-language.md)
+
+ * 值传递
+
+ * [值传递、引用传递](/basics/object-oriented/java-pass-by.md)
+
+ * [为什么说Java中只有值传递](/basics/object-oriented/why-pass-by-reference.md)
+
+ * 封装、继承、多态
+ * [什么是多态](/basics/object-oriented/polymorphism.md)
+
+ * [方法重写与重载](/basics/object-oriented/overloading-vs-overriding.md)
+ * Java的继承与实现
+
+ * [Java的继承与组合](/basics/object-oriented/inheritance-composition.md)
+
+ * [构造函数与默认构造函数](/basics/object-oriented/constructor.md)
+
+ * [类变量、成员变量和局部变量](/basics/object-oriented/variable.md)
+
+ * [成员变量和方法作用域](/basics/object-oriented/scope.md)
+
+ * Java基础知识
+
+ * 基本数据类型
-### 面向对象
+ * [8种基本数据类型](/basics/java-basic/basic-data-types.md)
-#### 什么是面向对象
+ * [整型中byte、short、int、long的取值范围](/basics/java-basic/integer-scope.md)
-* [面向对象、面向过程](../basics/java-basic/object-oriented-vs-procedure-oriented.md)
+ * [什么是浮点型?](/basics/java-basic/float.md)
-* [面向对象的三大基本特征](/basics/java-basic/characteristics.md)
+ * [什么是单精度和双精度?](/basics/java-basic/single-double-float.md)
-* [五大基本原则](/basics/java-basic/principle.md)
+ * [为什么不能用浮点型表示金额?](/basics/java-basic/float-amount.md)
+
+ * 自动拆装箱
+
+ * [自动拆装箱](/basics/java-basic/boxing-unboxing.md)
+
+ * [Integer的缓存机制](/basics/java-basic/integer-cache.md)
+
+ * String
+
+ * [字符串的不可变性](/basics/java-basic/final-string.md)
+
+ * [JDK 6和JDK 7中substring的原理及区别](/basics/java-basic/substring.md)
+
+ * replaceFirst、replaceAll、replace区别
+
+ * [String对“+”的重载](/basics/java-basic/string-append.md)
+
+ * [字符串拼接的几种方式和区别](/basics/java-basic/string-concat.md)
+
+ * [String.valueOf和Integer.toString的区别](/basics/java-basic/value-of-vs-to-string.md)
+
+ * [switch对String的支持](/basics/java-basic/switch-string.md)
+ * 字符串池
+ * 常量池(运行时常量池、Class常量池)
+ * intern
+ * Java中各种关键字
+ * transient
+ * instanceof
+ * volatile
+ * synchronized
+ * final
+ * static
+ * const
+ * 集合类
+
+ * 常用集合类的使用
+
+ * [ArrayList和LinkedList和Vector的区别](/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md)
+
+ * [SynchronizedList和Vector的区别](/basics/java-basic/synchronizedlist-vector.md)
+
+ * [HashMap、HashTable、ConcurrentHashMap区别](/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md)
+
+ * [Set和List区别?](/basics/java-basic/set-vs-list.md)
+
+ * [Set如何保证元素不重复?](/basics/java-basic/set-repetition.md)
+
+ * [Java 8中stream相关用法](/basics/java-basic/stream.md)
+
+ * Apache集合处理工具类的使用
+
+ * 不同版本的JDK中HashMap的实现的区别以及原因
+
+ * [Collection和Collections区别](/basics/java-basic/Collection-vs-Collections.md)
+
+ * [Arrays.asList获得的List使用时需要注意什么](/basics/java-basic/Arrays-asList.md)
+
+ * [Enumeration和Iterator区别](/basics/java-basic/Enumeration-vs-Iterator.md)
+
+ * [fail-fast 和 fail-safe](/basics/java-basic/fail-fast-vs-fail-safe.md)
+
+ * [CopyOnWriteArrayList](/basics/java-basic/CopyOnWriteArrayList.md)
+
+ * [ConcurrentSkipListMap](/basics/java-basic/ConcurrentSkipListMap.md)
+
+ * 枚举
+
+ * [枚举的用法](/basics/java-basic/enum-usage.md)
+
+ * [枚举的实现](/basics/java-basic/enum-impl.md)
+
+ * [枚举与单例](/basics/java-basic/enum-singleton.md)
+
+ * Enum类
+
+ * [Java枚举如何比较](/basics/java-basic/enum-compare.md)
+
+ * [switch对枚举的支持](/basics/java-basic/enum-switch.md)
+
+ * [枚举的序列化如何实现](/basics/java-basic/enum-serializable.md)
+
+ * [枚举的线程安全性问题](/basics/java-basic/enum-thread-safe.md)
+
+ * IO
+
+ * [字符流、字节流](/basics/java-basic/byte-stream-vs-character-stream.md)
+
+ * [输入流、输出流](/basics/java-basic/input-stream-vs-output-stream.md)
+
+ * [同步、异步](/basics/java-basic/synchronized-vs-asynchronization.md)
+
+ * [阻塞、非阻塞](/basics/java-basic/block-vs-non-blocking.md)
+
+ * [Linux 5种IO模型](/basics/java-basic/linux-io.md)
+
+ * [BIO、NIO和AIO的区别、三种IO的用法与原理](/basics/java-basic/bio-vs-nio-vs-aio.md)
+
+ * netty
+
+ * 反射
+
+ * [反射](/basics/java-basic/reflection.md)与工厂模式、
+
+ * [反射有什么作用](/basics/java-basic/usage-of-reflection.md)
+
+ * [Class类](/basics/java-basic/Class.md)
+
+ * `java.lang.reflect.*`
+
+ * 动态代理
+
+ * [静态代理](/basics/java-basic/static-proxy.md)
+
+ * [动态代理](/basics/java-basic/dynamic-proxy.md)
+
+ * [动态代理和反射的关系](/basics/java-basic/dynamic-proxy-vs-reflection.md)
+
+ * [动态代理的几种实现方式](/basics/java-basic/dynamic-proxy-implementation.md)
+
+ * [AOP](/basics/java-basic/aop-vs-proxy.md)
+
+ * 序列化
+
+ * [什么是序列化与反序列化](basics/java-basic/serialize.md)
+ * [Java如何实现序列化与反序列化](basics/java-basic/serialize-in-java.md)
+ * [Serializable 和 Externalizable 有何不同](basics/java-basic/diff-serializable-vs-externalizable.md)
+ * 为什么序列化
+ * [serialVersionUID](basics/java-basic/serialVersionUID.md)
+ * [为什么serialVersionUID不能随便改](basics/java-basic/serialVersionUID-modify.md)
+ * [transient](basics/java-basic/transient.md)
+ * [序列化底层原理](basics/java-basic/serialize-principle.md)
+ * [序列化与单例模式](basics/java-basic/serialize-singleton.md)
+ * [protobuf](basics/java-basic/protobuf.md)
+ * 为什么说序列化并不安全
+
+ * 注解
+
+ * [元注解](/basics/java-basic/meta-annotation.md)
+ * [自定义注解](/basics/java-basic/custom-annotation.md)
+ * Java中常用注解使用
+ * 注解与反射的结合
+
+ * [如何自定义一个注解?](/basics/java-basic/create-annotation.md)
+
+ * [Spring常用注解](/basics/java-basic/annotation-in-spring.md)
+ * JMS
+
+ * 什么是Java消息服务
+ * JMS消息传送模型
+
+ * JMX
+
+ * `java.lang.management.*`
+ * `javax.management.*`
+
+ * 泛型
+
+ * [什么是泛型](/basics/java-basic/generics.md)
+ * [类型擦除](/basics/java-basic/type-erasue.md)
+ * [泛型带来的问题](/basics/java-basic/generics-problem.md)
+ * [泛型中K T V E ? object等的含义](/basics/java-basic/k-t-v-e.md)
+ * 泛型各种用法
+
+ * [限定通配符和非限定通配符](/basics/java-basic/Wildcard-Character.md)
+ * [上下界限定符extends 和 super](/basics/java-basic/extends-vs-super.md)
+
+ * [`List`和原始类型`List`之间的区别?](/basics/java-basic/genericity-list.md)
+
+ * [`List>`和`List`之间的区别是什么?](/basics/java-basic/genericity-list-wildcard.md)
+
+ * 单元测试
+
+ * junit
+ * mock
+ * mockito
+ * 内存数据库(h2)
+
+ * 正则表达式
+
+ * `java.lang.util.regex.*`
+
+ * 常用的Java工具库
+
+ * `commons.lang`
+ * `commons.*...`
+ * `guava-libraries`
+ * `netty`
+
+ * API&SPI
+
+ * API
+ * [API和SPI的关系和区别](/basics/java-basic/api-vs-spi.md)
+
+ * [如何定义SPI](/basics/java-basic/create-spi.md)
+ * [SPI的实现原理](/basics/java-basic/spi-principle.md)
+
+ * 异常
+
+ * [Error和Exception](/basics/java-basic/error-vs-exception.md)
+ * [异常类型](/basics/java-basic/exception-type.md)
+ * [异常相关关键字](/basics/java-basic/keyword-about-exception.md)
+ * [正确处理异常](/basics/java-basic/handle-exception.md)
+ * [自定义异常](/basics/java-basic/define-exception.md)
+ * [异常链](/basics/java-basic/exception-chain.md)
+ * [try-with-resources](/basics/java-basic/try-with-resources.md)
+ * [finally和return的执行顺序](/basics/java-basic/order-about-finllly-return.md)
+
+ * 时间处理
+
+ * [时区](/basics/java-basic/time-zone.md)
+ * [冬令时和夏令时](/basics/java-basic/StandardTime-vs-daylightSavingTime.md)
+ * [时间戳](/basics/java-basic/timestamp.md)
+ * Java中时间API
+
+ * [格林威治时间](/basics/java-basic/GMT.md)
+ * [CET,UTC,GMT,CST几种常见时间的含义和关系](/basics/java-basic/CET-UTC-GMT-CST.md)
+
+ * [SimpleDateFormat的线程安全性问题](/basics/java-basic/simpledateformat-thread-safe.md)
+
+ * [Java 8中的时间处理](/basics/java-basic/time-in-java8.md)
+
+ * [如何在东八区的计算机上获取美国时间](/basics/java-basic/get-los_angeles-time.md)
+
+ * [yyyy和YYYY有什么区别?](/basics/java-basic/YYYY-vs-yyyy.md)
+
+ * 编码方式
+
+ * [什么是ASCII?](/basics/java-basic/ASCII.md)
+
+ * [Unicode](/basics/java-basic/UNICODE.md)
+
+ * [有了Unicode为啥还需要UTF-8](/basics/java-basic/why-utf8.md)
+
+ * [UTF8、UTF16、UTF32区别](/basics/java-basic/UTF8-UTF16-UTF32.md)
+
+ * 有了UTF8为什么还需要GBK?
+
+ * [GBK、GB2312、GB18030之间的区别](/basics/java-basic/gbk-gb2312-gb18030.md)
+
+ * [URL编解码](/basics/java-basic/url-encode.md)
+ * [Big Endian和Little Endian](/basics/java-basic/big-endian-vs-little-endian.md)
+
+ * 如何解决乱码问题
+
+ * 语法糖
+
+ * [Java中语法糖原理、解语法糖](/basics/java-basic/syntactic-sugar.md)
+
+ * [语法糖介绍](/basics/java-basic/syntactic-sugar.md)
+
+ * 阅读源代码
+
+ * String
+ * Integer
+ * Long
+ * Enum
+ * BigDecimal
+ * ThreadLocal
+ * ClassLoader & URLClassLoader
+ * ArrayList & LinkedList
+ * HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap
+ * HashSet & LinkedHashSet & TreeSet
+
+ * Java并发编程
+
+ * 并发与并行
+
+ * [什么是并发](/basics/concurrent-coding/concurrent.md)
+
+ * [什么是并行](/basics/concurrent-coding/parallel.md)
+
+ * [并发与并行的区别](/basics/concurrent-coding/concurrent-vs-parallel.md)
+
+ * 线程
+
+ * 线程的实现
+ * 线程的状态
+ * 线程优先级
+ * 线程调度
+ * 创建线程的多种方式
+ * 守护线程
+ * 线程与进程的区别
+
+ * 线程池
+
+ * 自己设计线程池
+ * submit() 和 execute()
+ * 线程池原理
+ * 为什么不允许使用Executors创建线程池
+
+ * 线程安全
+
+ * [死锁?](/basics/concurrent-coding/deadlock-java-level.md)
+ * 死锁如何排查
+ * 线程安全和内存模型的关系
+
+ * 锁
+
+ * CAS
+ * 乐观锁与悲观锁
+ * 数据库相关锁机制
+ * 分布式锁
+ * 偏向锁
+ * 轻量级锁
+ * 重量级锁
+ * monitor
+ * 锁优化
+ * 锁消除
+ * 锁粗化
+ * 自旋锁
+ * 可重入锁
+ * 阻塞锁
+
+ * 死锁
+
+ * 死锁的原因
+
+ * 死锁的解决办法
+
+ * synchronized
+
+ * [synchronized是如何实现的?](/basics/concurrent-coding/synchronized.md)
+
+ * synchronized和lock之间关系
+ * 不使用synchronized如何实现一个线程安全的单例
+ * synchronized和原子性、可见性和有序性之间的关系
+
+ * volatile
+
+ * happens-before
+ * 内存屏障
+ * 编译器指令重排和CPU指令重排
+
+ * volatile的实现原理
+
+ * volatile和原子性
+ * 可见性和有序性之间的关系
+
+ * 有了symchronized为什么还需要volatile
+
+ * sleep 和 wait
+
+ * wait 和 notify
+
+ * notify 和 notifyAll
+
+ * ThreadLocal
+
+ * 写一个死锁的程序
+
+ * 写代码来解决生产者消费者问题
+
+ * 并发包
+
+ * 阅读源代码,并学会使用
+
+ * Thread
+ * Runnable
+ * Callable
+ * ReentrantLock
+ * ReentrantReadWriteLock
+ * Atomic*
+ * Semaphore
+ * CountDownLatch
+ * ConcurrentHashMap
+ * Executors
+
+* 底层篇
+
+ * JVM
+
+ * JVM内存结构
+
+ * class文件格式
+ * 运行时数据区
+ * 堆和栈区别
+ * [Java中的对象一定在堆上分配吗?](/basement/jvm/stack-alloc.md)
+
+ * Java内存模型
+
+ * 计算机内存模型
+ * 缓存一致性
+ * MESI协议
+
+ * 可见性
+ * 原子性
+ * 顺序性
+ * happens-before
+
+ * 内存屏障
+ * synchronized
+ * volatile
+ * final
+ * 锁
+
+ * 垃圾回收
+
+ * GC算法:标记清除、引用计数、复制、标记压缩、分代回收、增量式回收
+
+ * GC参数
+ * 对象存活的判定
+ * 垃圾收集器(CMS、G1、ZGC、Epsilon)
+
+ * JVM参数及调优
+
+ * -Xmx
+ * -Xmn
+ * -Xms
+ * Xss
+ * -XX:SurvivorRatio
+
+ * -XX:PermSize
+ * -XX:MaxPermSize
+ * -XX:MaxTenuringThreshold
+
+ * Java对象模型
+
+ * oop-klass
+ * 对象头
+
+ * HotSpot
+
+ * 即时编译器
+ * 编译优化
+
+ * 虚拟机性能监控与故障处理工具
+
+ * jps
+ * jstack
+ * jmap
+ * jstat
+ * jconsole
+ * jinfo
+ * jhat
+ * javap
+ * btrace
+ * TProfiler
+ * jlink
+ * Arthas
+
+ * 类加载机制
+
+ * classLoader
+ * 类加载过程
+ * 双亲委派(破坏双亲委派)
+ * 模块化(jboss modules、osgi、jigsaw)
+
+ * 编译与反编译
+
+ * 什么是编译(前端编译、后端编译)
+ * 什么是反编译
+
+ * JIT
+ * JIT优化(逃逸分析、栈上分配、标量替换、锁优化)
+
+ * 编译工具:javac
+
+ * 反编译工具:javap 、jad 、CRF
+
+* 进阶篇
+ * Java底层知识
+
+ * 字节码
+
+ * class文件格式
+
+ * CPU缓存,L1,L2,L3和伪共享
+
+ * 尾递归
+
+ * 位运算
+
+ 用位运算实现加、减、乘、除、取余
+
+ * 设计模式
+
+ * 设计模式的六大原则
+
+ * 开闭原则(Open Close Principle)
+ * 里氏代换原则(Liskov Substitution Principle)
+ * 依赖倒转原则(Dependence Inversion Principle)
+ * 接口隔离原则(Interface Segregation Principle)
+ * 迪米特法则(最少知道原则)(Demeter Principle)
+ * 合成复用原则(Composite Reuse Principle)
+
+ * 了解23种设计模式
+
+ * 创建型模式
+ * 单例模式
+ * 抽象工厂模式
+ * 建造者模式
+ * 工厂模式
+ * 原型模式
+
+ * 结构型模式
+ * 适配器模式
+ * 桥接模式
+ * 装饰模式
+ * 组合模式
+ * 外观模式
+ * 享元模式
+ * 代理模式
+
+ * 行为型模式
+ * 模版方法模式
+ * 命令模式
+ * 迭代器模式
+ * 观察者模式
+ * 中介者模式
+ * 备忘录模式
+ * 解释器模式
+ * 状态模式
+ * 策略模式
+ * 责任链模式
+ * 访问者模式
+
+ * 会使用常用设计模式
+
+ * 单例的七种写法
+ * 懒汉——线程不安全
+ * 懒汉——线程安全
+ * 饿汉
+ * 饿汉——变种
+ * 静态内部类
+ * 枚举
+ * 双重校验锁
+
+ * 工厂模式
+ * 适配器模式
+ * 策略模式
+ * 模板方法模式
+ * 观察者模式
+ * 外观模式
+ * 代理模式
+
+ * 不用synchronized和lock,实现线程安全的单例模式
+
+ * 实现AOP
+
+ * 实现IOC
+
+ * nio和reactor设计模式
+
+ * 网络编程知识
+
+ * tcp、udp、http、https等常用协议
+
+ * 三次握手与四次关闭
+ * 流量控制和拥塞控制
+ * OSI七层模型
+ * tcp粘包与拆包
+
+ * http/1.0 http/1.1 http/2之间的区别
+
+ * http中 get和post区别
+
+ * 常见的web请求返回的状态码
+
+ * 404、302、301、500分别代表什么
+
+ * http/2
+
+ * Java RMI,Socket,HttpClient
+
+ * cookie 与 session
+
+ * cookie被禁用,如何实现session
+
+ * 用Java写一个简单的静态文件的HTTP服务器
+
+ * 了解nginx和apache服务器的特性并搭建一个对应的服务器
+
+ * 用Java实现FTP、SMTP协议
+
+ * 进程间通讯的方式
+
+ * 什么是CDN?如果实现?
+
+ * DNS?
+
+ * 什么是DNS
+ * 记录类型:A记录、CNAME记录、AAAA记录等
+
+ * 域名解析
+ * 根域名服务器
+
+ * DNS污染
+ * DNS劫持
+ * 公共DNS:114 DNS、Google DNS、OpenDNS
+
+ * 反向代理
+
+ * 正向代理
+ * 反向代理
+
+ * 反向代理服务器
+
+ * 框架知识
+
+ * Servlet
+
+ * 生命周期
+
+ * 线程安全问题
+
+ * filter和listener
+
+ * web.xml中常用配置及作用
+
+ * Hibernate
+
+ * 什么是OR Mapping
+
+ * Hibernate的缓存机制
+
+ * Hibernate的懒加载
+
+ * Hibernate/Ibatis/MyBatis之间的区别
+
+ * Spring
+
+ * Bean的初始化
+
+ * AOP原理
+
+ * 实现Spring的IOC
+
+ * spring四种依赖注入方式
+
+ * Spring MVC
+
+ * 什么是MVC
+
+ * Spring mvc与Struts mvc的区别
+
+ * Spring Boot
+
+ * Spring Boot 2.0
+ * 起步依赖
+ * 自动配置
+
+ * Spring Boot的starter原理
+ * 自己实现一个starter
+
+ * Spring Security
+
+ * Spring Cloud
+
+ * 服务发现与注册:Eureka、Zookeeper、Consul
+
+ * 负载均衡:Feign、Spring Cloud Loadbalance
+
+ * 服务配置:Spring Cloud Config
+
+ * 服务限流与熔断:Hystrix
+
+ * 服务链路追踪:Dapper
+
+ * 服务网关、安全、消息
+
+ * 应用服务器知识
+
+ * JBoss
+
+ * tomcat
+
+ * jetty
+
+ * Weblogic
+
+ * 工具
+
+ * git & svn
+
+ * maven & gradle
+
+ * Intellij IDEA
+
+ * 常用插件:
+ * Maven Helper
+ * FindBugs-IDEA
+ * 阿里巴巴代码规约检测
+ * GsonFormat
+
+ * Lombok plugin
+ * .ignore
+ * Mybatis plugin
+
+* 高级篇
+
+ * 新技术
+
+ * Java 8
+
+ * lambda表达式
+ * Stream API
+ * 时间API
+
+ * Java 9
+
+ * Jigsaw
+ * Jshell
+ * Reactive Streams
+
+ * Java 10
+
+ * 局部变量类型推断
+ * G1的并行Full GC
+ * ThreadLocal握手机制
+
+ * Java 11
+
+ * ZGC
+ * Epsilon
+ * 增强var
+ * Java 12
+
+ * Switch 表达式
+
+ * Java 13
+
+ * Text Blocks
+ * Dynamic CDS Archives
+
+ * Java 14
+
+ * Java打包工具
+ * 更有价值的NullPointerException
+ * record类型
+
+ * Spring 5
+
+ * 响应式编程
+
+ * Spring Boot 2.0
+
+ * http/2
+
+ * http/3
+
+ * 性能优化
+
+ * 使用单例
+ * 使用Future模式
+ * 使用线程池
+ * 选择就绪
+ * 减少上下文切换
+ * 减少锁粒度
+ * 数据压缩
+ * 结果缓存
+
+ * 线上问题分析
+
+ * dump获取
+
+ * 线程Dump
+ * 内存Dump
+ * gc情况
+
+ * dump分析
+
+ * 分析死锁
+ * 分析内存泄露
+
+ * dump分析及获取工具
+
+ * jstack
+ * jstat
+ * jmap
+ * jhat
+ * Arthas
+
+ * 自己编写各种outofmemory,stackoverflow程序
+
+ * HeapOutOfMemory
+ * Young OutOfMemory
+ * MethodArea OutOfMemory
+ * ConstantPool OutOfMemory
+ * DirectMemory OutOfMemory
+ * Stack OutOfMemory Stack OverFlow
+
+ * Arthas
+
+ * jvm相关
+ * class/classloader相关
+ * monitor/watch/trace相关
+
+ * options
+ * 管道
+ * 后台异步任务
+
+ * 常见问题解决思路
+
+ * 内存溢出
+ * 线程死锁
+ * 类加载冲突
+
+ * 使用工具尝试解决以下问题,并写下总结
+
+ * 当一个Java程序响应很慢时如何查找问题
+
+ * 当一个Java程序频繁FullGC时如何解决问题
+
+ * 如何查看垃圾回收日志
+
+ * 当一个Java应用发生OutOfMemory时该如何解决
+
+ * 如何判断是否出现死锁
+
+ * 如何判断是否存在内存泄露
+
+ * 使用Arthas快速排查Spring Boot应用404/401问题
+
+ * 使用Arthas排查线上应用日志打满问题
+
+ * 利用Arthas排查Spring Boot应用NoSuchMethodError
+
+ * 编译原理知识
+
+ * 编译与反编译
+
+ * Java代码的编译与反编译
+
+ * Java的反编译工具
+
+ * javap
+ * jad
+ * CRF
+
+ * 即时编译器
+
+ * 词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化
+
+ * 操作系统知识
+
+ * Linux的常用命令
+
+ * 进程间通信
+
+ * 进程同步
+
+ * 生产者消费者问题
+ * 哲学家就餐问题
+ * 读者写者问题
+
+ * 缓冲区溢出
+
+ * 分段和分页
+
+ * 虚拟内存与主存
+
+ * 虚拟内存管理
+
+ * 换页算法
+
+ * 数据库知识
+
+ * MySql 执行引擎
+
+ * MySQL 执行计划
+
+ * 如何查看执行计划
+ * 如何根据执行计划进行SQL优化
+
+ * 索引
+
+ * Hash索引
+ * B树索引(B+树、和B树、R树)
+
+ * 普通索引
+ * 唯一索引
+
+ * 覆盖索引
+ * 最左前缀原则
+ * 索引下推
+
+ * SQL优化
+
+ * 数据库事务和隔离级别
+
+ * 事务的隔离级别
+ * 事务能不能实现锁的功能
+
+ * 数据库锁
+
+ * 行锁
+ * 表锁
+ * 使用数据库锁实现乐观锁
+
+ * 连接
+
+ * 内连接
+ * 左连接
+ * 右连接
+
+ * 数据库主备搭建
+
+ * binlog
+
+ * redolog
+
+ * 内存数据库
+
+ * h2
+
+ * 分库分表
+
+ * 读写分离
+
+ * 常用的nosql数据库
+
+ * redis
+ * memcached
+
+ * 分别使用数据库锁、NoSql实现分布式锁
+
+ * 性能调优
+
+ * 数据库连接池
+
+ * 数据结构与算法知识
+
+ * 简单的数据结构
+
+ * 栈
+ * 队列
+ * 链表
+ * 数组* 哈希表
+
+ * 栈和队列的相同和不同之处
+
+ * 栈通常采用的两种存储结构
+
+ * 树
+
+ * 二叉树
+ * 字典树
+ * 平衡树
+ * 排序树
+ * B树
+ * B+树
+ * R树
+ * 多路树
+ * 红黑树
+
+ * 堆
+
+ * 大根堆
+ * 小根堆
+
+ * 图
+
+ * 有向图
+ * 无向图
+ * 拓扑
+
+ * 排序算法
+
+ * 稳定的排序
+ * 冒泡排序
+ * 插入排序
+ * 鸡尾酒排序
+ * 桶排序
+ * 计数排序
+ * 归并排序
+ * 原地归并排序
+ * 二叉排序树排序
+ * 鸽巢排序
+ * 基数排序
+ * 侏儒排序
+ * 图书馆排序
+ * 块排序
+
+ * 不稳定的排序
+ * 选择排序
+ * 希尔排序
+ * Clover排序算法
+ * 梳排序
+ * 堆排序
+ * 平滑排序
+ * 快速排序
+ * 内省排序
+ * 耐心排序
+
+ * 各种排序算法和时间复杂度
+
+ * 深度优先和广度优先搜索
+
+ * 全排列
+ * 贪心算法
+ * KMP算法
+ * hash算法
+
+ * 海量数据处理
+
+ * 分治
+ * hash映射
+ * 堆排序
+ * 双层桶划分
+ * Bloom Filter
+ * bitmap
+ * 数据库索引
+ * mapreduce等。
+
+ * 两个栈实现队列,和两个队列实现栈
+
+ * 大数据知识
+
+ * Zookeeper
+
+ * 基本概念
+ * 常见用法
+
+ * Solr,Lucene,ElasticSearch
+
+ * 在linux上部署solr
+ * solrcloud,新增、删除、查询索引
+
+ * Storm,流式计算,了解Spark,S4
+
+ * 在linux上部署storm
+ * 用zookeeper做协调
+ * 运行storm hello world
+ * local和remote模式运行调试storm topology
+
+ * Hadoop,离线计算
+
+ * HDFS
+ * MapReduce
+
+ * 分布式日志收集flume,kafka,logstash
+
+ * 数据挖掘,mahout
+
+ * 网络安全知识
+
+ * XSS
+
+ * XSS的防御
+
+ * CSRF
+
+ * 注入攻击
+
+ * SQL注入
+ * XML注入
+ * CRLF注入
+
+ * 文件上传漏洞
+
+ * 加密与解密
+
+ * 对称加密
+ * 非对称加密
+ * 哈希算法
+ * 加盐哈希算法
+
+ * MD5,SHA1、DES、AES、RSA、DSA
+
+ * 彩虹表
+
+ * DDOS攻击
+
+ * DOS攻击
+ * DDOS攻击
+
+ * memcached为什么可以导致DDos攻击
+ * 什么是反射型DDoS
+
+ * 如何通过Hash碰撞进行DOS攻击
+
+ * SSL、TLS,HTTPS
+
+ * 用openssl签一个证书部署到apache或nginx
+
+* 架构篇
+
+ * 分布式
+
+ * 数据一致性
+ * 服务治理
+ * 服务降级
+ * 分布式理论
+ * 2PC
+ * 3PC
+ * CAP
+ * BASE
+
+ * 分布式事务
+ * 可靠消息最终一致性
+ * 最大努力通知
+ * TCC
+
+ * Dubbo
+
+ * 服务注册
+ * 服务发现
+ * 服务治理
+
+ * 分布式数据库
+
+ * 怎样打造一个分布式数据库
+ * 什么时候需要分布式数据库
+ * mycat
+ * otter
+ * HBase
+
+ * 分布式文件系统
+
+ * mfs
+ * fastdfs
+
+ * 分布式缓存
+
+ * 缓存一致性
+ * 缓存命中率
+ * 缓存冗余
+
+ * 限流降级
+
+ * Hystrix
+ * Sentinal
+
+ * 算法
+
+ * 共识算法
+ * Raft协议
+ * Paxos 算法与 Raft 算法
+ * 拜占庭问题与算法
+
+ * 2PC
+ * 3PC
+
+ * 微服务
+
+ * SOA
+ * 康威定律
+
+ * ServiceMesh
+
+ * sidecar
+
+ * Docker & Kubernets
+
+ * Spring Boot
+
+ * Spring Cloud
+
+ * 高并发
+
+ * 分库分表
+
+ * CDN技术
+
+ * 消息队列
+
+ * ActiveMQ
+
+ * 监控
+
+ * 监控什么
+
+ * CPU
+ * 内存
+ * 磁盘I/O
+ * 网络I/O等
+
+ * 监控手段
+
+ * 进程监控
+ * 语义监控
+ * 机器资源监控
+ * 数据波动
+
+ * 监控数据采集
+
+ * 日志
+ * 埋点
+
+ * Dapper
+
+ * 负载均衡
+
+ * tomcat负载均衡
+ * Nginx负载均衡
+
+ * 四层负载均衡
+ * 七层负载均衡
+
+ * DNS
+
+ * DNS原理
+ * DNS的设计
+
+ * CDN
+
+ * 数据一致性
+
+* 扩展篇
+
+ * 云计算
+
+ * IaaS
+ * SaaS
+ * PaaS
+ * 虚拟化技术
+ * openstack
+ * Serverlsess
+
+ * 搜索引擎
+
+ * Solr
+ * Lucene
+ * Nutch
+ * Elasticsearch
+
+ * 权限管理
+
+ * Shiro
+
+ * 区块链
+
+ * 哈希算法
+ * Merkle树
+ * 公钥密码算法
+ * 共识算法
+ * Raft协议
+ * Paxos 算法与 Raft 算法
+ * 拜占庭问题与算法
+ * 消息认证码与数字签名
+
+ * 比特币
+
+ * 挖矿
+ * 共识机制
+ * 闪电网络
+ * 侧链
+ * 热点问题
+ * 分叉
+
+ * 以太坊
+
+ * 超级账本
+
+ * 人工智能
+
+ * 数学基础
+ * 机器学习
+ * 人工神经网络
+ * 深度学习
+ * 应用场景
+
+ * 常用框架
+
+ * TensorFlow
+ * DeepLearning4J
+
+ * IoT
+
+ * 量子计算
+
+ * AR & VR
+
+ * 其他语言
+
+ * Groovy
+ * Kotlin
+ * Python
+ * Go
+ * NodeJs
+ * Swift
+ * Rust
+* 推荐书籍
+
+ *《深入理解Java虚拟机》
+
+ *《Effective Java》
+
+ *《深入分析Java Web技术内幕》
+
+ *《大型网站技术架构》
+
+ *《代码整洁之道》
+
+ *《架构整洁之道》
+
+ *《Head First设计模式》
+
+ *《maven实战》
+
+ *《区块链原理、设计与应用》
+
+ *《Java并发编程实战》
+
+ *《鸟哥的Linux私房菜》
+
+ *《从Paxos到Zookeeper》
+
+ *《架构即未来》
diff --git a/docs/basement/_sidebar.md b/docs/basement/_sidebar.md
new file mode 100644
index 0000000..5129de0
--- /dev/null
+++ b/docs/basement/_sidebar.md
@@ -0,0 +1,89 @@
+* JVM
+
+ * JVM内存结构
+
+ * class文件格式
+ * 运行时数据区
+ * 堆和栈区别
+ * [Java中的对象一定在堆上分配吗?](/basement/jvm/stack-alloc.md)
+
+ * Java内存模型
+
+ * 计算机内存模型
+ * 缓存一致性
+ * MESI协议
+
+ * 可见性
+ * 原子性
+ * 顺序性
+ * happens-before
+
+ * 内存屏障
+ * synchronized
+ * volatile
+ * final
+ * 锁
+
+ * 垃圾回收
+
+ * GC算法:标记清除、引用计数、复制、标记压缩、分代回收、增量式回收
+
+ * GC参数
+ * 对象存活的判定
+ * 垃圾收集器(CMS、G1、ZGC、Epsilon)
+
+ * JVM参数及调优
+
+ * -Xmx
+ * -Xmn
+ * -Xms
+ * Xss
+ * -XX:SurvivorRatio
+
+ * -XX:PermSize
+ * -XX:MaxPermSize
+ * -XX:MaxTenuringThreshold
+
+ * Java对象模型
+
+ * oop-klass
+ * 对象头
+
+ * HotSpot
+
+ * 即时编译器
+ * 编译优化
+
+ * 虚拟机性能监控与故障处理工具
+
+ * jps
+ * jstack
+ * jmap
+ * jstat
+ * jconsole
+ * jinfo
+ * jhat
+ * javap
+ * btrace
+ * TProfiler
+ * jlink
+ * Arthas
+
+* 类加载机制
+
+ * classLoader
+ * 类加载过程
+ * 双亲委派(破坏双亲委派)
+ * 模块化(jboss modules、osgi、jigsaw)
+
+* 编译与反编译
+
+ * 什么是编译(前端编译、后端编译)
+ * 什么是反编译
+
+ * JIT
+ * JIT优化(逃逸分析、栈上分配、标量替换、锁优化)
+
+ * 编译工具:javac
+
+ * 反编译工具:javap 、jad 、CRF
\ No newline at end of file
diff --git a/docs/basement/jvm/_sidebar.md b/docs/basement/jvm/_sidebar.md
new file mode 100644
index 0000000..57ba225
--- /dev/null
+++ b/docs/basement/jvm/_sidebar.md
@@ -0,0 +1,68 @@
+* JVM内存结构
+
+ * class文件格式
+ * 运行时数据区
+ * 堆和栈区别
+ * [Java中的对象一定在堆上分配吗?](/basement/jvm/stack-alloc.md)
+
+* Java内存模型
+
+ * 计算机内存模型
+ * 缓存一致性
+ * MESI协议
+
+ * 可见性
+ * 原子性
+ * 顺序性
+ * happens-before
+
+ * 内存屏障
+ * synchronized
+ * volatile
+ * final
+ * 锁
+
+* 垃圾回收
+
+ * GC算法:标记清除、引用计数、复制、标记压缩、分代回收、增量式回收
+
+ * GC参数
+ * 对象存活的判定
+ * 垃圾收集器(CMS、G1、ZGC、Epsilon)
+
+* JVM参数及调优
+
+ * -Xmx
+ * -Xmn
+ * -Xms
+ * Xss
+ * -XX:SurvivorRatio
+
+ * -XX:PermSize
+ * -XX:MaxPermSize
+ * -XX:MaxTenuringThreshold
+
+* Java对象模型
+
+ * oop-klass
+ * 对象头
+
+* HotSpot
+
+ * 即时编译器
+ * 编译优化
+
+* 虚拟机性能监控与故障处理工具
+
+ * jps
+ * jstack
+ * jmap
+ * jstat
+ * jconsole
+ * jinfo
+ * jhat
+ * javap
+ * btrace
+ * TProfiler
+ * jlink
+ * Arthas
\ No newline at end of file
diff --git a/basics/jvm/java-memory-model.md b/docs/basement/jvm/java-memory-model.md
similarity index 100%
rename from basics/jvm/java-memory-model.md
rename to docs/basement/jvm/java-memory-model.md
diff --git a/basics/java-basic/stack-alloc.md b/docs/basement/jvm/stack-alloc.md
similarity index 100%
rename from basics/java-basic/stack-alloc.md
rename to docs/basement/jvm/stack-alloc.md
diff --git a/docs/basics/_sidebar.md b/docs/basics/_sidebar.md
new file mode 100644
index 0000000..bd22850
--- /dev/null
+++ b/docs/basics/_sidebar.md
@@ -0,0 +1,415 @@
+* 面向对象
+
+ * 什么是面向对象
+
+ * [面向对象与面向过程](/basics/object-oriented/object-oriented-vs-procedure-oriented.md)
+
+ * [面向对象的三大基本特征](/basics/object-oriented/characteristics.md)
+
+ * [面向对象的五大基本原则](/basics/object-oriented/principle.md)
+ * 平台无关性
+
+ * [Java如何实现的平台无关性的](/basics/object-oriented/platform-independent.md)
+
+ * [JVM还支持哪些语言](/basics/object-oriented/jvm-language.md)
+
+ * 值传递
+
+ * [值传递、引用传递](/basics/object-oriented/java-pass-by.md)
+
+ * [为什么说Java中只有值传递](/basics/object-oriented/why-pass-by-reference.md)
+
+ * 封装、继承、多态
+ * [什么是多态](/basics/object-oriented/polymorphism.md)
+
+ * [方法重写与重载](/basics/object-oriented/overloading-vs-overriding.md)
+ * Java的继承与实现
+
+ * [Java的继承与组合](/basics/object-oriented/inheritance-composition.md)
+
+ * [构造函数与默认构造函数](/basics/object-oriented/constructor.md)
+
+ * [类变量、成员变量和局部变量](/basics/object-oriented/variable.md)
+
+ * [成员变量和方法作用域](/basics/object-oriented/scope.md)
+
+* Java基础知识
+
+ * 基本数据类型
+
+ * [8种基本数据类型](/basics/java-basic/basic-data-types.md)
+
+ * [整型中byte、short、int、long的取值范围](/basics/java-basic/integer-scope.md)
+
+ * [什么是浮点型?](/basics/java-basic/float.md)
+
+ * [什么是单精度和双精度?](/basics/java-basic/single-double-float.md)
+
+ * [为什么不能用浮点型表示金额?](/basics/java-basic/float-amount.md)
+
+ * 自动拆装箱
+
+ * [自动拆装箱](/basics/java-basic/boxing-unboxing.md)
+
+ * [Integer的缓存机制](/basics/java-basic/integer-cache.md)
+
+ * String
+
+ * [字符串的不可变性](/basics/java-basic/final-string.md)
+
+ * [JDK 6和JDK 7中substring的原理及区别](/basics/java-basic/substring.md)
+
+ * replaceFirst、replaceAll、replace区别
+
+ * [String对“+”的重载](/basics/java-basic/string-append.md)
+
+ * [字符串拼接的几种方式和区别](/basics/java-basic/string-concat.md)
+
+ * [String.valueOf和Integer.toString的区别](/basics/java-basic/value-of-vs-to-string.md)
+
+ * [switch对String的支持](/basics/java-basic/switch-string.md)
+ * 字符串池
+ * 常量池(运行时常量池、Class常量池)
+ * intern
+ * Java中各种关键字
+ * transient
+ * instanceof
+ * volatile
+ * synchronized
+ * final
+ * static
+ * const
+ * 集合类
+
+ * 常用集合类的使用
+
+ * [ArrayList和LinkedList和Vector的区别](/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md)
+
+ * [SynchronizedList和Vector的区别](/basics/java-basic/synchronizedlist-vector.md)
+
+ * [HashMap、HashTable、ConcurrentHashMap区别](/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md)
+
+ * [Set和List区别?](/basics/java-basic/set-vs-list.md)
+
+ * [Set如何保证元素不重复?](/basics/java-basic/set-repetition.md)
+
+ * [Java 8中stream相关用法](/basics/java-basic/stream.md)
+
+ * Apache集合处理工具类的使用
+
+ * 不同版本的JDK中HashMap的实现的区别以及原因
+
+ * [Collection和Collections区别](/basics/java-basic/Collection-vs-Collections.md)
+
+ * [Arrays.asList获得的List使用时需要注意什么](/basics/java-basic/Arrays-asList.md)
+
+ * [Enumeration和Iterator区别](/basics/java-basic/Enumeration-vs-Iterator.md)
+
+ * [fail-fast 和 fail-safe](/basics/java-basic/fail-fast-vs-fail-safe.md)
+
+ * [CopyOnWriteArrayList](/basics/java-basic/CopyOnWriteArrayList.md)
+
+ * [ConcurrentSkipListMap](/basics/java-basic/ConcurrentSkipListMap.md)
+
+ * 枚举
+
+ * [枚举的用法](/basics/java-basic/enum-usage.md)
+
+ * [枚举的实现](/basics/java-basic/enum-impl.md)
+
+ * [枚举与单例](/basics/java-basic/enum-singleton.md)
+
+ * Enum类
+
+ * [Java枚举如何比较](/basics/java-basic/enum-compare.md)
+
+ * [switch对枚举的支持](/basics/java-basic/enum-switch.md)
+
+ * [枚举的序列化如何实现](/basics/java-basic/enum-serializable.md)
+
+ * [枚举的线程安全性问题](/basics/java-basic/enum-thread-safe.md)
+
+ * IO
+
+ * [字符流、字节流](/basics/java-basic/byte-stream-vs-character-stream.md)
+
+ * [输入流、输出流](/basics/java-basic/input-stream-vs-output-stream.md)
+
+ * [同步、异步](/basics/java-basic/synchronized-vs-asynchronization.md)
+
+ * [阻塞、非阻塞](/basics/java-basic/block-vs-non-blocking.md)
+
+ * [Linux 5种IO模型](/basics/java-basic/linux-io.md)
+
+ * [BIO、NIO和AIO的区别、三种IO的用法与原理](/basics/java-basic/bio-vs-nio-vs-aio.md)
+
+ * netty
+
+ * 反射
+
+ * [反射](/basics/java-basic/reflection.md)与工厂模式、
+
+ * [反射有什么作用](/basics/java-basic/usage-of-reflection.md)
+
+ * [Class类](/basics/java-basic/Class.md)
+
+ * `java.lang.reflect.*`
+
+ * 动态代理
+
+ * [静态代理](/basics/java-basic/static-proxy.md)
+
+ * [动态代理](/basics/java-basic/dynamic-proxy.md)
+
+ * [动态代理和反射的关系](/basics/java-basic/dynamic-proxy-vs-reflection.md)
+
+ * [动态代理的几种实现方式](/basics/java-basic/dynamic-proxy-implementation.md)
+
+ * [AOP](/basics/java-basic/aop-vs-proxy.md)
+
+ * 序列化
+
+ * [什么是序列化与反序列化](basics/java-basic/serialize.md)
+ * [Java如何实现序列化与反序列化](basics/java-basic/serialize-in-java.md)
+ * [Serializable 和 Externalizable 有何不同](basics/java-basic/diff-serializable-vs-externalizable.md)
+ * 为什么序列化
+ * [serialVersionUID](basics/java-basic/serialVersionUID.md)
+ * [为什么serialVersionUID不能随便改](basics/java-basic/serialVersionUID-modify.md)
+ * [transient](basics/java-basic/transient.md)
+ * [序列化底层原理](basics/java-basic/serialize-principle.md)
+ * [序列化与单例模式](basics/java-basic/serialize-singleton.md)
+ * [protobuf](basics/java-basic/protobuf.md)
+ * 为什么说序列化并不安全
+
+ * 注解
+
+ * [元注解](/basics/java-basic/meta-annotation.md)
+ * [自定义注解](/basics/java-basic/custom-annotation.md)
+ * Java中常用注解使用
+ * 注解与反射的结合
+
+ * [如何自定义一个注解?](/basics/java-basic/create-annotation.md)
+
+ * [Spring常用注解](/basics/java-basic/annotation-in-spring.md)
+ * JMS
+
+ * 什么是Java消息服务
+ * JMS消息传送模型
+
+ * JMX
+
+ * `java.lang.management.*`
+ * `javax.management.*`
+
+ * 泛型
+
+ * [什么是泛型](/basics/java-basic/generics.md)
+ * [类型擦除](/basics/java-basic/type-erasue.md)
+ * [泛型带来的问题](/basics/java-basic/generics-problem.md)
+ * [泛型中K T V E ? object等的含义](/basics/java-basic/k-t-v-e.md)
+ * 泛型各种用法
+
+ * [限定通配符和非限定通配符](/basics/java-basic/Wildcard-Character.md)
+ * [上下界限定符extends 和 super](/basics/java-basic/extends-vs-super.md)
+
+ * [`List`和原始类型`List`之间的区别?](/basics/java-basic/genericity-list.md)
+
+ * [`List>`和`List`之间的区别是什么?](/basics/java-basic/genericity-list-wildcard.md)
+
+ * 单元测试
+
+ * junit
+ * mock
+ * mockito
+ * 内存数据库(h2)
+
+ * 正则表达式
+
+ * `java.lang.util.regex.*`
+
+ * 常用的Java工具库
+
+ * `commons.lang`
+ * `commons.*...`
+ * `guava-libraries`
+ * `netty`
+
+ * API&SPI
+
+ * API
+ * [API和SPI的关系和区别](/basics/java-basic/api-vs-spi.md)
+
+ * [如何定义SPI](/basics/java-basic/create-spi.md)
+ * [SPI的实现原理](/basics/java-basic/spi-principle.md)
+
+ * 异常
+
+ * [Error和Exception](/basics/java-basic/error-vs-exception.md)
+ * [异常类型](/basics/java-basic/exception-type.md)
+ * [异常相关关键字](/basics/java-basic/keyword-about-exception.md)
+ * [正确处理异常](/basics/java-basic/handle-exception.md)
+ * [自定义异常](/basics/java-basic/define-exception.md)
+ * [异常链](/basics/java-basic/exception-chain.md)
+ * [try-with-resources](/basics/java-basic/try-with-resources.md)
+ * [finally和return的执行顺序](/basics/java-basic/order-about-finllly-return.md)
+
+ * 时间处理
+
+ * [时区](/basics/java-basic/time-zone.md)
+ * [冬令时和夏令时](/basics/java-basic/StandardTime-vs-daylightSavingTime.md)
+ * [时间戳](/basics/java-basic/timestamp.md)
+ * Java中时间API
+
+ * [格林威治时间](/basics/java-basic/GMT.md)
+ * [CET,UTC,GMT,CST几种常见时间的含义和关系](/basics/java-basic/CET-UTC-GMT-CST.md)
+
+ * [SimpleDateFormat的线程安全性问题](/basics/java-basic/simpledateformat-thread-safe.md)
+
+ * [Java 8中的时间处理](/basics/java-basic/time-in-java8.md)
+
+ * [如何在东八区的计算机上获取美国时间](/basics/java-basic/get-los_angeles-time.md)
+
+ * [yyyy和YYYY有什么区别?](/basics/java-basic/YYYY-vs-yyyy.md)
+
+ * 编码方式
+
+ * [什么是ASCII?](/basics/java-basic/ASCII.md)
+
+ * [Unicode](/basics/java-basic/UNICODE.md)
+
+ * [有了Unicode为啥还需要UTF-8](/basics/java-basic/why-utf8.md)
+
+ * [UTF8、UTF16、UTF32区别](/basics/java-basic/UTF8-UTF16-UTF32.md)
+
+ * 有了UTF8为什么还需要GBK?
+
+ * [GBK、GB2312、GB18030之间的区别](/basics/java-basic/gbk-gb2312-gb18030.md)
+
+ * [URL编解码](/basics/java-basic/url-encode.md)
+ * [Big Endian和Little Endian](/basics/java-basic/big-endian-vs-little-endian.md)
+
+ * 如何解决乱码问题
+
+ * 语法糖
+
+ * [Java中语法糖原理、解语法糖](/basics/java-basic/syntactic-sugar.md)
+
+ * [语法糖介绍](/basics/java-basic/syntactic-sugar.md)
+
+ * 阅读源代码
+
+ * String
+ * Integer
+ * Long
+ * Enum
+ * BigDecimal
+ * ThreadLocal
+ * ClassLoader & URLClassLoader
+ * ArrayList & LinkedList
+ * HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap
+ * HashSet & LinkedHashSet & TreeSet
+
+* Java并发编程
+
+ * 并发与并行
+
+ * [什么是并发](/basics/concurrent-coding/concurrent.md)
+
+ * [什么是并行](/basics/concurrent-coding/parallel.md)
+
+ * [并发与并行的区别](/basics/concurrent-coding/concurrent-vs-parallel.md)
+
+ * 线程
+
+ * 线程的实现
+ * 线程的状态
+ * 线程优先级
+ * 线程调度
+ * 创建线程的多种方式
+ * 守护线程
+ * 线程与进程的区别
+
+ * 线程池
+
+ * 自己设计线程池
+ * submit() 和 execute()
+ * 线程池原理
+ * 为什么不允许使用Executors创建线程池
+
+ * 线程安全
+
+ * [死锁?](/basics/concurrent-coding/deadlock-java-level.md)
+ * 死锁如何排查
+ * 线程安全和内存模型的关系
+
+ * 锁
+
+ * CAS
+ * 乐观锁与悲观锁
+ * 数据库相关锁机制
+ * 分布式锁
+ * 偏向锁
+ * 轻量级锁
+ * 重量级锁
+ * monitor
+ * 锁优化
+ * 锁消除
+ * 锁粗化
+ * 自旋锁
+ * 可重入锁
+ * 阻塞锁
+
+ * 死锁
+
+ * 死锁的原因
+
+ * 死锁的解决办法
+
+ * synchronized
+
+ * [synchronized是如何实现的?](/basics/concurrent-coding/synchronized.md)
+
+ * synchronized和lock之间关系
+ * 不使用synchronized如何实现一个线程安全的单例
+ * synchronized和原子性、可见性和有序性之间的关系
+
+ * volatile
+
+ * happens-before
+ * 内存屏障
+ * 编译器指令重排和CPU指令重排
+
+ * volatile的实现原理
+
+ * volatile和原子性
+ * 可见性和有序性之间的关系
+
+ * 有了symchronized为什么还需要volatile
+
+ * sleep 和 wait
+
+ * wait 和 notify
+
+ * notify 和 notifyAll
+
+ * ThreadLocal
+
+ * 写一个死锁的程序
+
+ * 写代码来解决生产者消费者问题
+
+* 并发包
+
+ * 阅读源代码,并学会使用
+
+ * Thread
+ * Runnable
+ * Callable
+ * ReentrantLock
+ * ReentrantReadWriteLock
+ * Atomic*
+ * Semaphore
+ * CountDownLatch
+ * ConcurrentHashMap
+ * Executors
+
\ No newline at end of file
diff --git a/docs/basics/concurrent-coding/_sidebar.md b/docs/basics/concurrent-coding/_sidebar.md
new file mode 100644
index 0000000..c0144d9
--- /dev/null
+++ b/docs/basics/concurrent-coding/_sidebar.md
@@ -0,0 +1,102 @@
+* 并发与并行
+
+ * [什么是并发](/basics/concurrent-coding/concurrent.md)
+
+ * [什么是并行](/basics/concurrent-coding/parallel.md)
+
+ * [并发与并行的区别](/basics/concurrent-coding/concurrent-vs-parallel.md)
+
+* 线程
+
+ * 线程的实现
+ * 线程的状态
+ * 线程优先级
+ * 线程调度
+ * 创建线程的多种方式
+ * 守护线程
+ * 线程与进程的区别
+
+* 线程池
+
+ * 自己设计线程池
+ * submit() 和 execute()
+ * 线程池原理
+ * 为什么不允许使用Executors创建线程池
+
+* 线程安全
+
+ * [死锁?](/basics/concurrent-coding/deadlock-java-level.md)
+ * 死锁如何排查
+ * 线程安全和内存模型的关系
+
+* 锁
+
+ * CAS
+ * 乐观锁与悲观锁
+ * 数据库相关锁机制
+ * 分布式锁
+ * 偏向锁
+ * 轻量级锁
+ * 重量级锁
+ * monitor
+ * 锁优化
+ * 锁消除
+ * 锁粗化
+ * 自旋锁
+ * 可重入锁
+ * 阻塞锁
+
+* 死锁
+
+ * 死锁的原因
+
+ * 死锁的解决办法
+
+* synchronized
+
+ * [synchronized是如何实现的?](/basics/concurrent-coding/synchronized.md)
+
+ * synchronized和lock之间关系
+ * 不使用synchronized如何实现一个线程安全的单例
+ * synchronized和原子性、可见性和有序性之间的关系
+
+* volatile
+
+ * happens-before
+ * 内存屏障
+ * 编译器指令重排和CPU指令重排
+
+ * volatile的实现原理
+
+ * volatile和原子性
+ * 可见性和有序性之间的关系
+
+ * 有了symchronized为什么还需要volatile
+
+* sleep 和 wait
+
+* wait 和 notify
+
+* notify 和 notifyAll
+
+* ThreadLocal
+
+* 写一个死锁的程序
+
+* 写代码来解决生产者消费者问题
+
+* 并发包
+
+* 阅读源代码,并学会使用
+
+ * Thread
+ * Runnable
+ * Callable
+ * ReentrantLock
+ * ReentrantReadWriteLock
+ * Atomic*
+ * Semaphore
+ * CountDownLatch
+ * ConcurrentHashMap
+ * Executors
+
\ No newline at end of file
diff --git a/docs/basics/concurrent-coding/concurrent-vs-parallel.md b/docs/basics/concurrent-coding/concurrent-vs-parallel.md
new file mode 100644
index 0000000..d815168
--- /dev/null
+++ b/docs/basics/concurrent-coding/concurrent-vs-parallel.md
@@ -0,0 +1,7 @@
+Erlang 之父 Joe Armstrong 用一张比较形象的图解释了并发与并行的区别:
+
+![](http://www.hollischuang.com/wp-content/uploads/2018/12/CON.jpg)
+
+并发是两个队伍交替使用一台咖啡机。并行是两个队伍同时使用两台咖啡机。
+
+映射到计算机系统中,上图中的咖啡机就是CPU,两个队伍指的就是两个进程。
diff --git a/docs/basics/concurrent-coding/concurrent.md b/docs/basics/concurrent-coding/concurrent.md
new file mode 100644
index 0000000..4f14ebb
--- /dev/null
+++ b/docs/basics/concurrent-coding/concurrent.md
@@ -0,0 +1,13 @@
+并发(Concurrent),在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
+
+那么,操作系统视如何实现这种并发的呢?
+
+现在我们用到操作系统,无论是Windows、Linux还是MacOS等其实都是**多用户多任务分时操作系统**。使用这些操作系统的用户是可以“同时”干多件事的。
+
+但是实际上,对于单CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。为了看起来像是“同时干多件事”,分时操作系统是把CPU的时间划分成长短基本相同的时间区间,即”时间片”,通过操作系统的管理,把这些时间片依次轮流地分配给各个用户使用。
+
+如果某个作业在时间片结束之前,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做.此时CPU又分配给另一个作业去使用。
+
+由于计算机的处理速度很快,只要时间片的间隔取得适当,那么一个用户作业从用完分配给它的一个时间片到获得下一个CPU时间片,中间有所”停顿”,但用户察觉不出来,好像整个系统全由它”独占”似的。
+
+所以,在单CPU的计算机中,我们看起来“同时干多件事”,其实是通过CPU时间片技术,并发完成的。
diff --git a/basics/java-basic/deadlock-java-level.md b/docs/basics/concurrent-coding/deadlock-java-level.md
similarity index 100%
rename from basics/java-basic/deadlock-java-level.md
rename to docs/basics/concurrent-coding/deadlock-java-level.md
diff --git a/docs/basics/concurrent-coding/parallel.md b/docs/basics/concurrent-coding/parallel.md
new file mode 100644
index 0000000..2ab6b0d
--- /dev/null
+++ b/docs/basics/concurrent-coding/parallel.md
@@ -0,0 +1,2 @@
+
+并行(Parallel),当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
\ No newline at end of file
diff --git a/basics/java-basic/synchronized.md b/docs/basics/concurrent-coding/synchronized.md
similarity index 100%
rename from basics/java-basic/synchronized.md
rename to docs/basics/concurrent-coding/synchronized.md
diff --git a/docs/basics/java-basic/ASCII.md b/docs/basics/java-basic/ASCII.md
new file mode 100644
index 0000000..ddfe639
--- /dev/null
+++ b/docs/basics/java-basic/ASCII.md
@@ -0,0 +1,16 @@
+ASCII( American Standard Code for InformationInterchange, 美国信息交换标准代码) 是基于拉丁字母的⼀套电脑编码系统, 主要⽤于显⽰现代英语和其他西欧语⾔。
+
+它是现今最通⽤的单字节编码系统, 并等同于国际标准ISO/IEC646。
+
+标准ASCII 码也叫基础ASCII码, 使⽤7 位⼆进制数( 剩下的1位⼆进制为0) 来表⽰所有的⼤写和⼩写字母, 数字0 到9、 标点符号, 以及在美式英语中使⽤的特殊控制字符。
+
+
+其中:
+
+0~31及127(共33个)是控制字符或通信专⽤字符( 其余为可显⽰字符) , 如控制符: LF( 换⾏) 、 CR( 回车) 、 FF( 换页) 、 DEL( 删除) 、 BS( 退格)、 BEL( 响铃) 等; 通信专⽤字符: SOH( ⽂头) 、 EOT( ⽂尾) 、 ACK( 确认) 等;
+
+ASCII值为8、 9、 10 和13 分别转换为退格、 制表、 换⾏和回车字符。 它们并没有特定的图形显⽰, 但会依不同的应⽤程序,⽽对⽂本显⽰有不同的影响
+
+32~126(共95个)是字符(32是空格) , 其中48~57为0到9⼗个阿拉伯数字。
+
+65~90为26个⼤写英⽂字母, 97~122号为26个⼩写英⽂字母, 其余为⼀些标点符号、 运算符号等。
\ No newline at end of file
diff --git a/basics/java-basic/Arrays-asList.md b/docs/basics/java-basic/Arrays-asList.md
similarity index 100%
rename from basics/java-basic/Arrays-asList.md
rename to docs/basics/java-basic/Arrays-asList.md
diff --git a/basics/java-basic/CET-UTC-GMT-CST.md b/docs/basics/java-basic/CET-UTC-GMT-CST.md
similarity index 100%
rename from basics/java-basic/CET-UTC-GMT-CST.md
rename to docs/basics/java-basic/CET-UTC-GMT-CST.md
diff --git a/basics/java-basic/Class.md b/docs/basics/java-basic/Class.md
similarity index 100%
rename from basics/java-basic/Class.md
rename to docs/basics/java-basic/Class.md
diff --git a/basics/java-basic/Collection-vs-Collections.md b/docs/basics/java-basic/Collection-vs-Collections.md
similarity index 100%
rename from basics/java-basic/Collection-vs-Collections.md
rename to docs/basics/java-basic/Collection-vs-Collections.md
diff --git a/basics/java-basic/ConcurrentSkipListMap.md b/docs/basics/java-basic/ConcurrentSkipListMap.md
similarity index 100%
rename from basics/java-basic/ConcurrentSkipListMap.md
rename to docs/basics/java-basic/ConcurrentSkipListMap.md
diff --git a/basics/java-basic/CopyOnWriteArrayList.md b/docs/basics/java-basic/CopyOnWriteArrayList.md
similarity index 100%
rename from basics/java-basic/CopyOnWriteArrayList.md
rename to docs/basics/java-basic/CopyOnWriteArrayList.md
diff --git a/basics/java-basic/Enumeration-vs-Iterator.md b/docs/basics/java-basic/Enumeration-vs-Iterator.md
similarity index 100%
rename from basics/java-basic/Enumeration-vs-Iterator.md
rename to docs/basics/java-basic/Enumeration-vs-Iterator.md
diff --git a/basics/java-basic/GMT.md b/docs/basics/java-basic/GMT.md
similarity index 100%
rename from basics/java-basic/GMT.md
rename to docs/basics/java-basic/GMT.md
diff --git a/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md b/docs/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md
similarity index 100%
rename from basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md
rename to docs/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md
diff --git a/docs/basics/java-basic/README.md b/docs/basics/java-basic/README.md
new file mode 100644
index 0000000..e6fef94
--- /dev/null
+++ b/docs/basics/java-basic/README.md
@@ -0,0 +1,12 @@
+## To Be Top Javaer - Java工程师成神之路
+
+![](https://img.shields.io/badge/version-v2.0.0-green.svg) ![](https://img.shields.io/badge/author-Hollis-yellow.svg) ![](https://img.shields.io/badge/license-GPL-blue.svg)
+
+
+| 主要版本 | 更新时间 | 备注 |
+| ---- | ---------- | -------------- |
+| v1.0 | 2015-08-01 | 首次发布 |
+| v1.1 | 2018-03-12 | 增加新技术知识、完善知识体系 |
+| v2.0 | 2019-02-19 | 结构调整,更适合从入门到精通;
进一步完善知识体系;
新技术补充;|
+
+Java 基础
\ No newline at end of file
diff --git a/basics/java-basic/StandardTime-vs-daylightSavingTime.md b/docs/basics/java-basic/StandardTime-vs-daylightSavingTime.md
similarity index 100%
rename from basics/java-basic/StandardTime-vs-daylightSavingTime.md
rename to docs/basics/java-basic/StandardTime-vs-daylightSavingTime.md
diff --git a/basics/java-basic/UNICODE.md b/docs/basics/java-basic/UNICODE.md
similarity index 100%
rename from basics/java-basic/UNICODE.md
rename to docs/basics/java-basic/UNICODE.md
diff --git a/basics/java-basic/UTF8-UTF16-UTF32.md b/docs/basics/java-basic/UTF8-UTF16-UTF32.md
similarity index 100%
rename from basics/java-basic/UTF8-UTF16-UTF32.md
rename to docs/basics/java-basic/UTF8-UTF16-UTF32.md
diff --git a/docs/basics/java-basic/Wildcard-Character.md b/docs/basics/java-basic/Wildcard-Character.md
new file mode 100644
index 0000000..b9e2a1b
--- /dev/null
+++ b/docs/basics/java-basic/Wildcard-Character.md
@@ -0,0 +1,10 @@
+`限定通配符`对类型进⾏限制, 泛型中有两种限定通配符:
+
+表示类型的上界,格式为:<? extends T>,即类型必须为T类型或者T子类
+表示类型的下界,格式为:<? super T>,即类型必须为T类型或者T的父类
+
+泛型类型必须⽤限定内的类型来进⾏初始化,否则会导致编译错误。
+
+
+
+`⾮限定通配符`表⽰可以⽤任意泛型类型来替代,类型为
\ No newline at end of file
diff --git a/docs/basics/java-basic/YYYY-vs-yyyy.md b/docs/basics/java-basic/YYYY-vs-yyyy.md
new file mode 100644
index 0000000..cfc5528
--- /dev/null
+++ b/docs/basics/java-basic/YYYY-vs-yyyy.md
@@ -0,0 +1,57 @@
+在使用SimpleDateFormat的时候,需要通过字母来描述时间元素,并组装成想要的日期和时间模式。常用的时间元素和字母的对应表(JDK 1.8)如下:
+
+![](http://www.hollischuang.com/wp-content/uploads/2020/01/15781278483147.jpg)
+
+可以看到,*y表示Year ,而Y表示Week Year*
+
+
+
+### 什么是Week Year
+
+我们知道,不同的国家对于一周的开始和结束的定义是不同的。如在中国,我们把星期一作为一周的第一天,而在美国,他们把星期日作为一周的第一天。
+
+同样,如何定义哪一周是一年当中的第一周?这也是一个问题,有很多种方式。
+
+比如下图是2019年12月-2020年1月的一份日历。
+
+![](http://www.hollischuang.com/wp-content/uploads/2020/01/15781286552869.jpg)
+
+
+
+到底哪一周才算2020年的第一周呢?不同的地区和国家,甚至不同的人,都有不同的理解。
+
+* 1、1月1日是周三,到下周三(1月8日),这7天算作这一年的第一周。
+* 2、因为周日(周一)才是一周的第一天,所以,要从2020年的第一个周日(周一)开始往后推7天才算这一年的第一周。
+* 3、因为12.29、12.30、12.31是2019年,而1.1、1.2、1.3才是2020年,而1.4周日是下一周的开始,所以,第一周应该只有1.1、1.2、1.3这三天。
+
+#### ISO 8601
+
+因为不同人对于日期和时间的表示方法有不同的理解,于是,大家就共同制定了了一个国际规范:ISO 8601 。
+
+国际标准化组织的国际标准ISO 8601是日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。
+
+在 ISO 8601中。对于一年的第一个日历星期有以下四种等效说法:
+* 1,本年度第一个星期四所在的星期;
+* 2,1月4日所在的星期;
+* 3,本年度第一个至少有4天在同一星期内的星期;
+* 4,星期一在去年12月29日至今年1月4日以内的星期;
+
+根据这个标准,我们可以推算出:
+
+2020年第一周:2019.12.29-2020.1.4
+
+所以,根据ISO 8601标准,2019年12月29日、2019年12月30日、2019年12月31日这两天,其实不属于2019年的最后一周,而是属于2020年的第一周。
+
+
+#### JDK针对ISO 8601提供的支持
+
+根据ISO 8601中关于日历星期和日表示法的定义,2019.12.29-2020.1.4是2020年的第一周。
+
+我们希望输入一个日期,然后程序告诉我们,根据ISO 8601中关于日历日期的定义,这个日期到底属于哪一年。
+
+比如我输入2019-12-20,他告诉我是2019;而我输入2019-12-30的时候,他告诉我是2020。
+
+为了提供这样的数据,Java 7引入了「YYYY」作为一个新的日期模式来作为标识。使用「YYYY」作为标识,。再通过SimpleDateFormat就可以得到一个日期所属的周属于哪一年了
+
+
+所以,当我们要表示日期的时候,一定要使用 yyyy-MM-dd 而不是 YYYY-MM-dd ,这两者的返回结果大多数情况下都一样,但是极端情况就会有问题了。
\ No newline at end of file
diff --git a/docs/basics/java-basic/_sidebar.md b/docs/basics/java-basic/_sidebar.md
new file mode 100644
index 0000000..7b28c6c
--- /dev/null
+++ b/docs/basics/java-basic/_sidebar.md
@@ -0,0 +1,274 @@
+* 基本数据类型
+
+ * [8种基本数据类型](/basics/java-basic/basic-data-types.md)
+
+ * [整型中byte、short、int、long的取值范围](/basics/java-basic/integer-scope.md)
+
+ * [什么是浮点型?](/basics/java-basic/float.md)
+
+ * [什么是单精度和双精度?](/basics/java-basic/single-double-float.md)
+
+ * [为什么不能用浮点型表示金额?](/basics/java-basic/float-amount.md)
+
+* 自动拆装箱
+
+ * [自动拆装箱](/basics/java-basic/boxing-unboxing.md)
+
+ * [Integer的缓存机制](/basics/java-basic/integer-cache.md)
+
+* String
+
+ * [字符串的不可变性](/basics/java-basic/final-string.md)
+
+ * [JDK 6和JDK 7中substring的原理及区别](/basics/java-basic/substring.md)
+
+ * replaceFirst、replaceAll、replace区别
+
+ * [String对“+”的重载](/basics/java-basic/string-append.md)
+
+ * [字符串拼接的几种方式和区别](/basics/java-basic/string-concat.md)
+
+ * [String.valueOf和Integer.toString的区别](/basics/java-basic/value-of-vs-to-string.md)
+
+ * [switch对String的支持](/basics/java-basic/switch-string.md)
+ * 字符串池
+ * 常量池(运行时常量池、Class常量池)
+ * intern
+* Java中各种关键字
+ * transient
+ * instanceof
+ * volatile
+ * synchronized
+ * final
+ * static
+ * const
+* 集合类
+
+ * 常用集合类的使用
+
+ * [ArrayList和LinkedList和Vector的区别](/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md)
+
+ * [SynchronizedList和Vector的区别](/basics/java-basic/synchronizedlist-vector.md)
+
+ * [HashMap、HashTable、ConcurrentHashMap区别](/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md)
+
+ * [Set和List区别?](/basics/java-basic/set-vs-list.md)
+
+ * [Set如何保证元素不重复?](/basics/java-basic/set-repetition.md)
+
+ * [Java 8中stream相关用法](/basics/java-basic/stream.md)
+
+ * Apache集合处理工具类的使用
+
+ * 不同版本的JDK中HashMap的实现的区别以及原因
+
+ * [Collection和Collections区别](/basics/java-basic/Collection-vs-Collections.md)
+
+ * [Arrays.asList获得的List使用时需要注意什么](/basics/java-basic/Arrays-asList.md)
+
+ * [Enumeration和Iterator区别](/basics/java-basic/Enumeration-vs-Iterator.md)
+
+ * [fail-fast 和 fail-safe](/basics/java-basic/fail-fast-vs-fail-safe.md)
+
+ * [CopyOnWriteArrayList](/basics/java-basic/CopyOnWriteArrayList.md)
+
+ * [ConcurrentSkipListMap](/basics/java-basic/ConcurrentSkipListMap.md)
+
+* 枚举
+
+ * [枚举的用法](/basics/java-basic/enum-usage.md)
+
+ * [枚举的实现](/basics/java-basic/enum-impl.md)
+
+ * [枚举与单例](/basics/java-basic/enum-singleton.md)
+
+ * Enum类
+
+ * [Java枚举如何比较](/basics/java-basic/enum-compare.md)
+
+ * [switch对枚举的支持](/basics/java-basic/enum-switch.md)
+
+ * [枚举的序列化如何实现](/basics/java-basic/enum-serializable.md)
+
+ * [枚举的线程安全性问题](/basics/java-basic/enum-thread-safe.md)
+
+* IO
+
+ * [字符流、字节流](/basics/java-basic/byte-stream-vs-character-stream.md)
+
+ * [输入流、输出流](/basics/java-basic/input-stream-vs-output-stream.md)
+
+ * [同步、异步](/basics/java-basic/synchronized-vs-asynchronization.md)
+
+ * [阻塞、非阻塞](/basics/java-basic/block-vs-non-blocking.md)
+
+ * [Linux 5种IO模型](/basics/java-basic/linux-io.md)
+
+ * [BIO、NIO和AIO的区别、三种IO的用法与原理](/basics/java-basic/bio-vs-nio-vs-aio.md)
+
+ * netty
+
+* 反射
+
+ * [反射](/basics/java-basic/reflection.md)与工厂模式、
+
+ * [反射有什么作用](/basics/java-basic/usage-of-reflection.md)
+
+ * [Class类](/basics/java-basic/Class.md)
+
+ * `java.lang.reflect.*`
+
+* 动态代理
+
+ * [静态代理](/basics/java-basic/static-proxy.md)
+
+ * [动态代理](/basics/java-basic/dynamic-proxy.md)
+
+ * [动态代理和反射的关系](/basics/java-basic/dynamic-proxy-vs-reflection.md)
+
+ * [动态代理的几种实现方式](/basics/java-basic/dynamic-proxy-implementation.md)
+
+ * [AOP](/basics/java-basic/aop-vs-proxy.md)
+
+* 序列化
+
+ * [什么是序列化与反序列化](basics/java-basic/serialize.md)
+ * [Java如何实现序列化与反序列化](basics/java-basic/serialize-in-java.md)
+ * [Serializable 和 Externalizable 有何不同](basics/java-basic/diff-serializable-vs-externalizable.md)
+ * 为什么序列化
+ * [serialVersionUID](basics/java-basic/serialVersionUID.md)
+ * [为什么serialVersionUID不能随便改](basics/java-basic/serialVersionUID-modify.md)
+ * [transient](basics/java-basic/transient.md)
+ * [序列化底层原理](basics/java-basic/serialize-principle.md)
+ * [序列化与单例模式](basics/java-basic/serialize-singleton.md)
+ * [protobuf](basics/java-basic/protobuf.md)
+ * 为什么说序列化并不安全
+
+* 注解
+
+ * [元注解](/basics/java-basic/meta-annotation.md)
+ * [自定义注解](/basics/java-basic/custom-annotation.md)
+ * Java中常用注解使用
+ * 注解与反射的结合
+
+ * [如何自定义一个注解?](/basics/java-basic/create-annotation.md)
+
+ * [Spring常用注解](/basics/java-basic/annotation-in-spring.md)
+* JMS
+
+ * 什么是Java消息服务
+ * JMS消息传送模型
+
+* JMX
+
+ * `java.lang.management.*`
+ * `javax.management.*`
+
+* 泛型
+
+ * [什么是泛型](/basics/java-basic/generics.md)
+ * [类型擦除](/basics/java-basic/type-erasue.md)
+ * [泛型带来的问题](/basics/java-basic/generics-problem.md)
+ * [泛型中K T V E ? object等的含义](/basics/java-basic/k-t-v-e.md)
+ * 泛型各种用法
+
+ * [限定通配符和非限定通配符](/basics/java-basic/Wildcard-Character.md)
+ * [上下界限定符extends 和 super](/basics/java-basic/extends-vs-super.md)
+
+ * [`List`和原始类型`List`之间的区别?](/basics/java-basic/genericity-list.md)
+
+ * [`List>`和`List`之间的区别是什么?](/basics/java-basic/genericity-list-wildcard.md)
+
+* 单元测试
+
+ * junit
+ * mock
+ * mockito
+ * 内存数据库(h2)
+
+* 正则表达式
+
+ * `java.lang.util.regex.*`
+
+* 常用的Java工具库
+
+ * `commons.lang`
+ * `commons.*...`
+ * `guava-libraries`
+ * `netty`
+
+* API&SPI
+
+ * API
+ * [API和SPI的关系和区别](/basics/java-basic/api-vs-spi.md)
+
+ * [如何定义SPI](/basics/java-basic/create-spi.md)
+ * [SPI的实现原理](/basics/java-basic/spi-principle.md)
+
+* 异常
+
+ * [Error和Exception](/basics/java-basic/error-vs-exception.md)
+ * [异常类型](/basics/java-basic/exception-type.md)
+ * [异常相关关键字](/basics/java-basic/keyword-about-exception.md)
+ * [正确处理异常](/basics/java-basic/handle-exception.md)
+ * [自定义异常](/basics/java-basic/define-exception.md)
+ * [异常链](/basics/java-basic/exception-chain.md)
+ * [try-with-resources](/basics/java-basic/try-with-resources.md)
+ * [finally和return的执行顺序](/basics/java-basic/order-about-finllly-return.md)
+
+* 时间处理
+
+ * [时区](/basics/java-basic/time-zone.md)
+ * [冬令时和夏令时](/basics/java-basic/StandardTime-vs-daylightSavingTime.md)
+ * [时间戳](/basics/java-basic/timestamp.md)
+ * Java中时间API
+
+ * [格林威治时间](/basics/java-basic/GMT.md)
+ * [CET,UTC,GMT,CST几种常见时间的含义和关系](/basics/java-basic/CET-UTC-GMT-CST.md)
+
+ * [SimpleDateFormat的线程安全性问题](/basics/java-basic/simpledateformat-thread-safe.md)
+
+ * [Java 8中的时间处理](/basics/java-basic/time-in-java8.md)
+
+ * [如何在东八区的计算机上获取美国时间](/basics/java-basic/get-los_angeles-time.md)
+
+ * [yyyy和YYYY有什么区别?](/basics/java-basic/YYYY-vs-yyyy.md)
+
+* 编码方式
+
+ * [什么是ASCII?](/basics/java-basic/ASCII.md)
+
+ * [Unicode](/basics/java-basic/UNICODE.md)
+
+ * [有了Unicode为啥还需要UTF-8](/basics/java-basic/why-utf8.md)
+
+ * [UTF8、UTF16、UTF32区别](/basics/java-basic/UTF8-UTF16-UTF32.md)
+
+ * 有了UTF8为什么还需要GBK?
+
+ * [GBK、GB2312、GB18030之间的区别](/basics/java-basic/gbk-gb2312-gb18030.md)
+
+ * [URL编解码](/basics/java-basic/url-encode.md)
+ * [Big Endian和Little Endian](/basics/java-basic/big-endian-vs-little-endian.md)
+
+ * 如何解决乱码问题
+
+* 语法糖
+
+ * [Java中语法糖原理、解语法糖](/basics/java-basic/syntactic-sugar.md)
+
+ * [语法糖介绍](/basics/java-basic/syntactic-sugar.md)
+
+* 阅读源代码
+
+ * String
+ * Integer
+ * Long
+ * Enum
+ * BigDecimal
+ * ThreadLocal
+ * ClassLoader & URLClassLoader
+ * ArrayList & LinkedList
+ * HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap
+ * HashSet & LinkedHashSet & TreeSet
+
\ No newline at end of file
diff --git a/basics/java-basic/annotation-in-spring.md b/docs/basics/java-basic/annotation-in-spring.md
similarity index 100%
rename from basics/java-basic/annotation-in-spring.md
rename to docs/basics/java-basic/annotation-in-spring.md
diff --git a/basics/java-basic/aop-vs-proxy.md b/docs/basics/java-basic/aop-vs-proxy.md
similarity index 100%
rename from basics/java-basic/aop-vs-proxy.md
rename to docs/basics/java-basic/aop-vs-proxy.md
diff --git a/basics/java-basic/api-vs-spi.md b/docs/basics/java-basic/api-vs-spi.md
similarity index 100%
rename from basics/java-basic/api-vs-spi.md
rename to docs/basics/java-basic/api-vs-spi.md
diff --git a/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md b/docs/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md
similarity index 100%
rename from basics/java-basic/arraylist-vs-linkedlist-vs-vector.md
rename to docs/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md
diff --git a/docs/basics/java-basic/basic-data-types.md b/docs/basics/java-basic/basic-data-types.md
new file mode 100644
index 0000000..a54b406
--- /dev/null
+++ b/docs/basics/java-basic/basic-data-types.md
@@ -0,0 +1,17 @@
+Java中有8种基本数据类型分为三大类。
+
+### 字符型
+
+char
+
+### 布尔型
+
+boolean
+
+### 数值型
+
+1.整型:byte、short、int、long
+
+2.浮点型:float、double
+
+*String不是基本数据类型,是引用类型。*
\ No newline at end of file
diff --git a/basics/java-basic/big-endian-vs-little-endian.md b/docs/basics/java-basic/big-endian-vs-little-endian.md
similarity index 100%
rename from basics/java-basic/big-endian-vs-little-endian.md
rename to docs/basics/java-basic/big-endian-vs-little-endian.md
diff --git a/basics/java-basic/bio-vs-nio-vs-aio.md b/docs/basics/java-basic/bio-vs-nio-vs-aio.md
similarity index 100%
rename from basics/java-basic/bio-vs-nio-vs-aio.md
rename to docs/basics/java-basic/bio-vs-nio-vs-aio.md
diff --git a/basics/java-basic/block-vs-non-blocking.md b/docs/basics/java-basic/block-vs-non-blocking.md
similarity index 100%
rename from basics/java-basic/block-vs-non-blocking.md
rename to docs/basics/java-basic/block-vs-non-blocking.md
diff --git a/basics/java-basic/boxing-unboxing.md b/docs/basics/java-basic/boxing-unboxing.md
similarity index 100%
rename from basics/java-basic/boxing-unboxing.md
rename to docs/basics/java-basic/boxing-unboxing.md
diff --git a/basics/java-basic/byte-stream-vs-character-stream.md b/docs/basics/java-basic/byte-stream-vs-character-stream.md
similarity index 100%
rename from basics/java-basic/byte-stream-vs-character-stream.md
rename to docs/basics/java-basic/byte-stream-vs-character-stream.md
diff --git a/basics/java-basic/constructor.md b/docs/basics/java-basic/constructor.md
similarity index 100%
rename from basics/java-basic/constructor.md
rename to docs/basics/java-basic/constructor.md
diff --git a/basics/java-basic/create-annotation.md b/docs/basics/java-basic/create-annotation.md
similarity index 100%
rename from basics/java-basic/create-annotation.md
rename to docs/basics/java-basic/create-annotation.md
diff --git a/basics/java-basic/create-spi.md b/docs/basics/java-basic/create-spi.md
similarity index 100%
rename from basics/java-basic/create-spi.md
rename to docs/basics/java-basic/create-spi.md
diff --git a/basics/java-basic/custom-annotation.md b/docs/basics/java-basic/custom-annotation.md
similarity index 100%
rename from basics/java-basic/custom-annotation.md
rename to docs/basics/java-basic/custom-annotation.md
diff --git a/docs/basics/java-basic/define-exception.md b/docs/basics/java-basic/define-exception.md
new file mode 100644
index 0000000..489811f
--- /dev/null
+++ b/docs/basics/java-basic/define-exception.md
@@ -0,0 +1,6 @@
+⾃定义异常就是开发⼈员⾃⼰定义的异常, ⼀般通过继承`Exception`的⼦类的⽅式实现。
+
+
+编写⾃定义异常类实际上是继承⼀个API标准异常类, ⽤新定义的异常处理信息覆盖原有信息的过程。
+
+这种⽤法在Web开发中也⽐较常见, ⼀般可以⽤来⾃定义业务异常。 如余额不⾜、 重复提交等。 这种⾃定义异常有业务含义, 更容易让上层理解和处理
\ No newline at end of file
diff --git a/docs/basics/java-basic/diff-serializable-vs-externalizable.md b/docs/basics/java-basic/diff-serializable-vs-externalizable.md
new file mode 100644
index 0000000..5b2ed9a
--- /dev/null
+++ b/docs/basics/java-basic/diff-serializable-vs-externalizable.md
@@ -0,0 +1,17 @@
+Java中的类通过实现 `java.io.Serializable` 接口以启⽤其序列化功能。 未实现此接⼜的类将⽆法使其任何状态序列化或反序列化。
+
+可序列化类的所有⼦类型本⾝都是可序列化的。
+
+序列化接⼜没有⽅法或字段, 仅⽤于标识可序列化的语义。
+
+当试图对⼀个对象进⾏序列化的时候, 如果遇到不⽀持`Serializable` 接口的对象。 在此情况下, 将抛`NotSerializableException`。
+
+如果要序列化的类有⽗类, 要想同时将在⽗类中定义过的变量持久化下来, 那么⽗类也应该集成`java.io.Serializable`接口。
+
+`Externalizable`继承了`Serializable`, 该接⼜中定义了两个抽象⽅法:`writeExternal()`与`readExternal()`。 当使⽤`Externalizable`接口来进⾏序列化与反序列化的时候需要开发⼈员重写writeExternal()与readExternal()⽅法。
+
+如果没有在这两个⽅法中定义序列化实现细节, 那么序列化之后, 对象内容为空。
+
+实现`Externalizable`接⼜的类必须要提供⼀个`public`的⽆参的构造器。
+
+所以, 实现`Externalizable`, 并实现`writeExternal()`和`readExternal()`⽅法可以指定序列化哪些属性。
diff --git a/basics/java-basic/dynamic-proxy-implementation.md b/docs/basics/java-basic/dynamic-proxy-implementation.md
similarity index 100%
rename from basics/java-basic/dynamic-proxy-implementation.md
rename to docs/basics/java-basic/dynamic-proxy-implementation.md
diff --git a/basics/java-basic/dynamic-proxy-vs-reflection.md b/docs/basics/java-basic/dynamic-proxy-vs-reflection.md
similarity index 100%
rename from basics/java-basic/dynamic-proxy-vs-reflection.md
rename to docs/basics/java-basic/dynamic-proxy-vs-reflection.md
diff --git a/basics/java-basic/dynamic-proxy.md b/docs/basics/java-basic/dynamic-proxy.md
similarity index 100%
rename from basics/java-basic/dynamic-proxy.md
rename to docs/basics/java-basic/dynamic-proxy.md
diff --git a/basics/java-basic/enum-compare.md b/docs/basics/java-basic/enum-compare.md
similarity index 100%
rename from basics/java-basic/enum-compare.md
rename to docs/basics/java-basic/enum-compare.md
diff --git a/basics/java-basic/enum-impl.md b/docs/basics/java-basic/enum-impl.md
similarity index 100%
rename from basics/java-basic/enum-impl.md
rename to docs/basics/java-basic/enum-impl.md
diff --git a/basics/java-basic/enum-serializable.md b/docs/basics/java-basic/enum-serializable.md
similarity index 100%
rename from basics/java-basic/enum-serializable.md
rename to docs/basics/java-basic/enum-serializable.md
diff --git a/basics/java-basic/enum-singleton.md b/docs/basics/java-basic/enum-singleton.md
similarity index 100%
rename from basics/java-basic/enum-singleton.md
rename to docs/basics/java-basic/enum-singleton.md
diff --git a/basics/java-basic/enum-switch.md b/docs/basics/java-basic/enum-switch.md
similarity index 100%
rename from basics/java-basic/enum-switch.md
rename to docs/basics/java-basic/enum-switch.md
diff --git a/basics/java-basic/enum-thread-safe.md b/docs/basics/java-basic/enum-thread-safe.md
similarity index 100%
rename from basics/java-basic/enum-thread-safe.md
rename to docs/basics/java-basic/enum-thread-safe.md
diff --git a/basics/java-basic/enum-usage.md b/docs/basics/java-basic/enum-usage.md
similarity index 100%
rename from basics/java-basic/enum-usage.md
rename to docs/basics/java-basic/enum-usage.md
diff --git a/docs/basics/java-basic/error-vs-exception.md b/docs/basics/java-basic/error-vs-exception.md
new file mode 100644
index 0000000..0e13030
--- /dev/null
+++ b/docs/basics/java-basic/error-vs-exception.md
@@ -0,0 +1,6 @@
+Exception和 Error, ⼆者都是 Java异常处理的重要⼦类, 各⾃都包含⼤量⼦类。均继承自Throwable类。
+
+
+Error表⽰系统级的错误, 是java运⾏环境内部错误或者硬件问题, 不能指望程序来处理这样的问题, 除了退出运⾏外别⽆选择, 它是Java虚拟机抛出的。
+
+Exception 表⽰程序需要捕捉、 需要处理的常, 是由与程序设计的不完善⽽出现的问题, 程序必须处理的问题。
\ No newline at end of file
diff --git a/docs/basics/java-basic/exception-chain.md b/docs/basics/java-basic/exception-chain.md
new file mode 100644
index 0000000..44e6e32
--- /dev/null
+++ b/docs/basics/java-basic/exception-chain.md
@@ -0,0 +1,26 @@
+“异常链”是Java中⾮常流⾏的异常处理概念, 是指在进⾏⼀个异常处理时抛出了另外⼀个异常, 由此产⽣了⼀个异常链条。
+
+该技术⼤多⽤于将“ 受检查异常” ( checked exception) 封装成为“⾮受检查异常”( unchecked exception)或者RuntimeException。
+
+顺便说⼀下, 如果因为因为异常你决定抛出⼀个新的异常, 你⼀定要包含原有的异常, 这样, 处理程序才可以通过getCause()和initCause()⽅法来访问异常最终的根源。
+
+从 Java 1.4版本开始,几乎所有的异常都支持异常链。
+
+以下是Throwable中支持异常链的方法和构造函数。
+
+ Throwable getCause()
+ Throwable initCause(Throwable)
+ Throwable(String, Throwable)
+ Throwable(Throwable)
+
+initCause和Throwable构造函数的Throwable参数是导致当前异常的异常。 getCause返回导致当前异常的异常,initCause设置当前异常的原因。
+
+以下示例显示如何使用异常链。
+
+ try {
+
+ } catch (IOException e) {
+ throw new SampleException("Other IOException", e);
+ }
+
+在此示例中,当捕获到IOException时,将创建一个新的SampleException异常,并附加原始的异常原因,并将异常链抛出到下一个更高级别的异常处理程序。
\ No newline at end of file
diff --git a/docs/basics/java-basic/exception-type.md b/docs/basics/java-basic/exception-type.md
new file mode 100644
index 0000000..7e8de55
--- /dev/null
+++ b/docs/basics/java-basic/exception-type.md
@@ -0,0 +1,20 @@
+Java中的异常, 主要可以分为两⼤类, 即受检异常( checked exception) 和 ⾮受检异常( unchecked exception)
+
+### 受检异常
+对于受检异常来说, 如果⼀个⽅法在声明的过程中证明了其要有受检异常抛出:
+
+ public void test() throw new Exception{ }
+
+那么,当我们在程序中调⽤他的时候, ⼀定要对该异常进⾏处理( 捕获或者向上抛出) , 否则是⽆法编译通过的。 这是⼀种强制规范。
+
+这种异常在IO操作中⽐较多。 ⽐如FileNotFoundException , 当我们使⽤IO流处理⼀个⽂件的时候, 有⼀种特殊情况, 就是⽂件不存在, 所以, 在⽂件处理的接⼜定义时他会显⽰抛出FileNotFoundException, ⽬的就是告诉这个⽅法的调⽤者,我这个⽅法不保证⼀定可以成功, 是有可能找不到对应的⽂件
+的, 你要明确的对这种情况做特殊处理哦。
+
+所以说, 当我们希望我们的⽅法调⽤者, 明确的处理⼀些特殊情况的时候, 就应该使⽤受检异常。
+
+### 非受检异常
+对于⾮受检异常来说, ⼀般是运⾏时异常, 继承⾃RuntimeException。 在编写代码的时候, 不需要显⽰的捕获,但是如果不捕获, 在运⾏期如果发⽣异常就会中断程序的执⾏。
+
+这种异常⼀般可以理解为是代码原因导致的。 ⽐如发⽣空指针、 数组越界等。 所以, 只要代码写的没问题, 这些异常都是可以避免的。 也就不需要我们显⽰的进⾏处理。
+
+试想⼀下, 如果你要对所有可能发⽣空指针的地⽅做异常处理的话, 那相当于你的所有代码都需要做这件事。
\ No newline at end of file
diff --git a/docs/basics/java-basic/extends-vs-super.md b/docs/basics/java-basic/extends-vs-super.md
new file mode 100644
index 0000000..e52fcbe
--- /dev/null
+++ b/docs/basics/java-basic/extends-vs-super.md
@@ -0,0 +1,48 @@
+` extends T>`和` super T>`是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念。
+
+` extends T>`:是指 “上界通配符(Upper Bounds Wildcards)”,即泛型中的类必须为当前类的子类或当前类。
+
+` super T>`:是指 “下界通配符(Lower Bounds Wildcards)”,即泛型中的类必须为当前类或者其父类。
+
+
+先看一个列子:
+
+ public class Food {}
+ public class Fruit extends Food {}
+ public class Apple extends Fruit {}
+ public class Banana extends Fruit{}
+
+ public class GenericTest {
+
+ public void testExtends(List extends Fruit> list){
+
+ //报错,extends为上界通配符,只能取值,不能放.
+ //因为Fruit的子类不只有Apple还有Banana,这里不能确定具体的泛型到底是Apple还是Banana,所以放入任何一种类型都会报错
+ //list.add(new Apple());
+
+ //可以正常获取
+ Fruit fruit = list.get(1);
+ }
+
+ public void testSuper(List super Fruit> list){
+
+ //super为下界通配符,可以存放元素,但是也只能存放当前类或者子类的实例,以当前的例子来讲,
+ //无法确定Fruit的父类是否只有Food一个(Object是超级父类)
+ //因此放入Food的实例编译不通过
+ list.add(new Apple());
+ // list.add(new Food());
+
+ Object object = list.get(1);
+ }
+ }
+
+在testExtends方法中,因为泛型中用的是extends,在向list中存放元素的时候,我们并不能确定List中的元素的具体类型,即可能是Apple也可能是Banana。因此调用add方法时,不论传入new Apple()还是new Banana(),都会出现编译错误。
+
+
+理解了extends之后,再看super就很容易理解了,即我们不能确定testSuper方法的参数中的泛型是Fruit的哪个父类,因此在调用get方法时只能返回Object类型。结合extends可见,在获取泛型元素时,使用extends获取到的是泛型中的上边界的类型(本例子中为Fruit),范围更小。
+
+在使用泛型时,存取元素时用super,获取元素时,用extends。
+
+频繁往外读取内容的,适合用上界Extends。经常往里插入的,适合用下界Super。
+
+本文来源:https://juejin.im/post/5c653fe06fb9a049e3089d88
\ No newline at end of file
diff --git a/basics/java-basic/fail-fast-vs-fail-safe.md b/docs/basics/java-basic/fail-fast-vs-fail-safe.md
similarity index 100%
rename from basics/java-basic/fail-fast-vs-fail-safe.md
rename to docs/basics/java-basic/fail-fast-vs-fail-safe.md
diff --git a/basics/java-basic/final-string.md b/docs/basics/java-basic/final-string.md
similarity index 100%
rename from basics/java-basic/final-string.md
rename to docs/basics/java-basic/final-string.md
diff --git a/basics/java-basic/float-amount.md b/docs/basics/java-basic/float-amount.md
similarity index 100%
rename from basics/java-basic/float-amount.md
rename to docs/basics/java-basic/float-amount.md
diff --git a/basics/java-basic/float.md b/docs/basics/java-basic/float.md
similarity index 100%
rename from basics/java-basic/float.md
rename to docs/basics/java-basic/float.md
diff --git a/basics/java-basic/gbk-gb2312-gb18030.md b/docs/basics/java-basic/gbk-gb2312-gb18030.md
similarity index 100%
rename from basics/java-basic/gbk-gb2312-gb18030.md
rename to docs/basics/java-basic/gbk-gb2312-gb18030.md
diff --git a/basics/java-basic/genericity-list-wildcard.md b/docs/basics/java-basic/genericity-list-wildcard.md
similarity index 100%
rename from basics/java-basic/genericity-list-wildcard.md
rename to docs/basics/java-basic/genericity-list-wildcard.md
diff --git a/basics/java-basic/genericity-list.md b/docs/basics/java-basic/genericity-list.md
similarity index 100%
rename from basics/java-basic/genericity-list.md
rename to docs/basics/java-basic/genericity-list.md
diff --git a/docs/basics/java-basic/generics-problem.md b/docs/basics/java-basic/generics-problem.md
new file mode 100644
index 0000000..ccbd2ab
--- /dev/null
+++ b/docs/basics/java-basic/generics-problem.md
@@ -0,0 +1,42 @@
+
+
+###一、当泛型遇到重载
+
+ public class GenericTypes {
+
+ public static void method(List list) {
+ System.out.println("invoke method(List list)");
+ }
+
+ public static void method(List list) {
+ System.out.println("invoke method(List list)");
+ }
+ }
+
+
+上面这段代码,有两个重载的函数,因为他们的参数类型不同,一个是`List`另一个是`List` ,但是,这段代码是编译通不过的。因为我们前面讲过,参数`List`和`List`编译之后都被擦除了,变成了一样的原生类型List,擦除动作导致这两个方法的特征签名变得一模一样。
+
+### 二、当泛型遇到catch
+
+如果我们自定义了一个泛型异常类GenericException,那么,不要尝试用多个catch取匹配不同的异常类型,例如你想要分别捕获GenericException、GenericException,这也是有问题的。
+
+### 三、当泛型内包含静态变量
+
+ public class StaticTest{
+ public static void main(String[] args){
+ GT gti = new GT();
+ gti.var=1;
+ GT gts = new GT();
+ gts.var=2;
+ System.out.println(gti.var);
+ }
+ }
+ class GT{
+ public static int var=0;
+ public void nothing(T x){}
+ }
+
+
+答案是——2!
+
+由于经过类型擦除,所有的泛型类实例都关联到同一份字节码上,泛型类的所有静态变量是共享的。
diff --git a/docs/basics/java-basic/generics.md b/docs/basics/java-basic/generics.md
new file mode 100644
index 0000000..2ba7a3e
--- /dev/null
+++ b/docs/basics/java-basic/generics.md
@@ -0,0 +1,5 @@
+Java泛型( generics) 是JDK 5中引⼊的⼀个新特性, 允许在定义类和接⼜的时候使⽤类型参数( type parameter) 。
+
+声明的类型参数在使⽤时⽤具体的类型来替换。 泛型最主要的应⽤是在JDK 5中的新集合类框架中。
+
+泛型最⼤的好处是可以提⾼代码的复⽤性。 以List接⼜为例,我们可以将String、 Integer等类型放⼊List中, 如不⽤泛型, 存放String类型要写⼀个List接口, 存放Integer要写另外⼀个List接口, 泛型可以很好的解决这个问题。
\ No newline at end of file
diff --git a/docs/basics/java-basic/get-los_angeles-time.md b/docs/basics/java-basic/get-los_angeles-time.md
new file mode 100644
index 0000000..2517a9e
--- /dev/null
+++ b/docs/basics/java-basic/get-los_angeles-time.md
@@ -0,0 +1,52 @@
+了解Java8 的朋友可能都知道,Java8提供了一套新的时间处理API,这套API比以前的时间处理API要友好的多。
+
+Java8 中加入了对时区的支持,带时区的时间为分别为:`ZonedDate`、`ZonedTime`、`ZonedDateTime`。
+
+其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式,如`Asia/Shanghai`、`America/Los_Angeles`等。
+
+在Java8中,直接使用以下代码即可输出美国洛杉矶的时间:
+
+ LocalDateTime now = LocalDateTime.now(ZoneId.of("America/Los_Angeles"));
+ System.out.println(now);
+
+
+
+为什么以下代码无法获得美国时间呢?
+
+ System.out.println(Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")).getTime());
+
+当我们使用System.out.println来输出一个时间的时候,他会调用Date类的toString方法,而该方法会读取操作系统的默认时区来进行时间的转换。
+
+ public String toString() {
+ // "EEE MMM dd HH:mm:ss zzz yyyy";
+ BaseCalendar.Date date = normalize();
+ ...
+ }
+
+ private final BaseCalendar.Date normalize() {
+ ...
+ TimeZone tz = TimeZone.getDefaultRef();
+ if (tz != cdate.getZone()) {
+ cdate.setZone(tz);
+ CalendarSystem cal = getCalendarSystem(cdate);
+ cal.getCalendarDate(fastTime, cdate);
+ }
+ return cdate;
+ }
+
+ static TimeZone getDefaultRef() {
+ TimeZone defaultZone = defaultTimeZone;
+ if (defaultZone == null) {
+ // Need to initialize the default time zone.
+ defaultZone = setDefaultZone();
+ assert defaultZone != null;
+ }
+ // Don't clone here.
+ return defaultZone;
+ }
+
+主要代码如上。也就是说如果我们想要通过`System.out.println`输出一个Date类的时候,输出美国洛杉矶时间的话,就需要想办法把`defaultTimeZone`改为`America/Los_Angeles`
+
+但是,通过阅读Calendar的源码,我们可以发现,getInstance方法虽然有一个参数可以传入时区,但是并没有将默认时区设置成传入的时区。
+
+而在Calendar.getInstance.getTime后得到的时间只是一个时间戳,其中未保留任何和时区有关的信息,所以,在输出时,还是显示的是当前系统默认时区的时间。
\ No newline at end of file
diff --git a/docs/basics/java-basic/handle-exception.md b/docs/basics/java-basic/handle-exception.md
new file mode 100644
index 0000000..ec5c24d
--- /dev/null
+++ b/docs/basics/java-basic/handle-exception.md
@@ -0,0 +1,6 @@
+异常的处理⽅式有两种。 1、 ⾃⼰处理。 2、 向上抛, 交给调⽤者处理。
+
+
+异常, 千万不能捕获了之后什么也不做。 或者只是使⽤`e.printStacktrace`。
+
+具体的处理⽅式的选择其实原则⽐较简明: ⾃⼰明确的知道如何处理的, 就要处理掉。 不知道如何处理的, 就交给调⽤者处理。
\ No newline at end of file
diff --git a/basics/java-basic/inheritance-composition.md b/docs/basics/java-basic/inheritance-composition.md
similarity index 100%
rename from basics/java-basic/inheritance-composition.md
rename to docs/basics/java-basic/inheritance-composition.md
diff --git a/basics/java-basic/input-stream-vs-output-stream.md b/docs/basics/java-basic/input-stream-vs-output-stream.md
similarity index 100%
rename from basics/java-basic/input-stream-vs-output-stream.md
rename to docs/basics/java-basic/input-stream-vs-output-stream.md
diff --git a/basics/java-basic/integer-cache.md b/docs/basics/java-basic/integer-cache.md
similarity index 100%
rename from basics/java-basic/integer-cache.md
rename to docs/basics/java-basic/integer-cache.md
diff --git a/basics/java-basic/integer-scope.md b/docs/basics/java-basic/integer-scope.md
similarity index 100%
rename from basics/java-basic/integer-scope.md
rename to docs/basics/java-basic/integer-scope.md
diff --git a/basics/java-basic/k-t-v-e.md b/docs/basics/java-basic/k-t-v-e.md
similarity index 100%
rename from basics/java-basic/k-t-v-e.md
rename to docs/basics/java-basic/k-t-v-e.md
diff --git a/docs/basics/java-basic/keyword-about-exception.md b/docs/basics/java-basic/keyword-about-exception.md
new file mode 100644
index 0000000..1a41630
--- /dev/null
+++ b/docs/basics/java-basic/keyword-about-exception.md
@@ -0,0 +1,11 @@
+throws、 throw、 try、 catch、 finally
+
+try⽤来指定⼀块预防所有异常的程序;
+
+catch⼦句紧跟在try块后⾯, ⽤来指定你想要捕获的异常的类型;
+
+finally为确保⼀段代码不管发⽣什么异常状况都要被执⾏;
+
+throw语句⽤来明确地抛出⼀个异常;
+
+throws⽤来声明⼀个⽅法可能抛出的各种异常;
\ No newline at end of file
diff --git a/basics/java-basic/linux-io.md b/docs/basics/java-basic/linux-io.md
similarity index 100%
rename from basics/java-basic/linux-io.md
rename to docs/basics/java-basic/linux-io.md
diff --git a/basics/java-basic/meta-annotation.md b/docs/basics/java-basic/meta-annotation.md
similarity index 100%
rename from basics/java-basic/meta-annotation.md
rename to docs/basics/java-basic/meta-annotation.md
diff --git a/docs/basics/java-basic/order-about-finllly-return.md b/docs/basics/java-basic/order-about-finllly-return.md
new file mode 100644
index 0000000..6f9de99
--- /dev/null
+++ b/docs/basics/java-basic/order-about-finllly-return.md
@@ -0,0 +1,6 @@
+
+
+ `try()` ⾥⾯有⼀个`return`语句, 那么后⾯的`finally{}`⾥⾯的code会不会被执⾏, 什么时候执⾏, 是在`return`前还是`return`后?
+
+
+如果try中有return语句, 那么finally中的代码还是会执⾏。因为return表⽰的是要整个⽅法体返回, 所以,finally中的语句会在return之前执⾏。
\ No newline at end of file
diff --git a/docs/basics/java-basic/protobuf.md b/docs/basics/java-basic/protobuf.md
new file mode 100644
index 0000000..f8c8738
--- /dev/null
+++ b/docs/basics/java-basic/protobuf.md
@@ -0,0 +1,9 @@
+
+Protocol Buffer (简称Protobuf) 是Google出品的性能优异、跨语言、跨平台的序列化库。
+
+2001年初,Protobuf首先在Google内部创建, 我们把它称之为 proto1,一直以来在Google的内部使用,其中也不断的演化,根据使用者的需求也添加很多新的功能,一些内部库依赖它。几乎每个Google的开发者都会使用到它。
+
+Google开始开源它的内部项目时,因为依赖的关系,所以他们决定首先把Protobuf开源出去。
+
+目前Protobuf的稳定版本是3.9.2,于2019年9月23日发布。由于很多公司很早的就采用了Protobuf,所以很多项目还在使用proto2协议,目前是proto2和proto3同时在使用的状态。
+
diff --git a/basics/java-basic/reflection.md b/docs/basics/java-basic/reflection.md
similarity index 100%
rename from basics/java-basic/reflection.md
rename to docs/basics/java-basic/reflection.md
diff --git a/basics/java-basic/scope.md b/docs/basics/java-basic/scope.md
similarity index 100%
rename from basics/java-basic/scope.md
rename to docs/basics/java-basic/scope.md
diff --git a/docs/basics/java-basic/serialVersionUID-modify.md b/docs/basics/java-basic/serialVersionUID-modify.md
new file mode 100644
index 0000000..6b1e26a
--- /dev/null
+++ b/docs/basics/java-basic/serialVersionUID-modify.md
@@ -0,0 +1,278 @@
+关于`serialVersionUID` 。这个字段到底有什么用?如果不设置会怎么样?为什么《阿里巴巴Java开发手册》中有以下规定:
+
+![-w934][4]
+
+### 背景知识
+
+**Serializable 和 Externalizable**
+
+类通过实现 `java.io.Serializable` 接口以启用其序列化功能。**未实现此接口的类将无法进行序列化或反序列化。**可序列化类的所有子类型本身都是可序列化的。
+
+如果读者看过`Serializable`的源码,就会发现,他只是一个空的接口,里面什么东西都没有。**Serializable接口没有方法或字段,仅用于标识可序列化的语义。**但是,如果一个类没有实现这个接口,想要被序列化的话,就会抛出`java.io.NotSerializableException`异常。
+
+它是怎么保证只有实现了该接口的方法才能进行序列化与反序列化的呢?
+
+原因是在执行序列化的过程中,会执行到以下代码:
+
+ if (obj instanceof String) {
+ writeString((String) obj, unshared);
+ } else if (cl.isArray()) {
+ writeArray(obj, desc, unshared);
+ } else if (obj instanceof Enum) {
+ writeEnum((Enum>) obj, desc, unshared);
+ } else if (obj instanceof Serializable) {
+ writeOrdinaryObject(obj, desc, unshared);
+ } else {
+ if (extendedDebugInfo) {
+ throw new NotSerializableException(
+ cl.getName() + "\n" + debugInfoStack.toString());
+ } else {
+ throw new NotSerializableException(cl.getName());
+ }
+ }
+
+
+在进行序列化操作时,会判断要被序列化的类是否是`Enum`、`Array`和`Serializable`类型,如果都不是则直接抛出`NotSerializableException`。
+
+Java中还提供了`Externalizable`接口,也可以实现它来提供序列化能力。
+
+`Externalizable`继承自`Serializable`,该接口中定义了两个抽象方法:`writeExternal()`与`readExternal()`。
+
+当使用`Externalizable`接口来进行序列化与反序列化的时候需要开发人员重写`writeExternal()`与`readExternal()`方法。否则所有变量的值都会变成默认值。
+
+**transient**
+
+`transient` 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,`transient` 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
+
+**自定义序列化策略**
+
+在序列化过程中,如果被序列化的类中定义了`writeObject` 和 `readObject` 方法,虚拟机会试图调用对象类里的 `writeObject` 和 `readObject` 方法,进行用户自定义的序列化和反序列化。
+
+如果没有这样的方法,则默认调用是 `ObjectOutputStream` 的 `defaultWriteObject` 方法以及 `ObjectInputStream` 的 `defaultReadObject` 方法。
+
+用户自定义的 `writeObject` 和 `readObject` 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。
+
+所以,对于一些特殊字段需要定义序列化的策略的时候,可以考虑使用transient修饰,并自己重写`writeObject` 和 `readObject` 方法,如`java.util.ArrayList`中就有这样的实现。
+
+我们随便找几个Java中实现了序列化接口的类,如String、Integer等,我们可以发现一个细节,那就是这些类除了实现了`Serializable`外,还定义了一个`serialVersionUID` ![][5]
+
+那么,到底什么是`serialVersionUID`呢?为什么要设置这样一个字段呢?
+
+### 什么是serialVersionUID
+
+序列化是将对象的状态信息转换为可存储或传输的形式的过程。我们都知道,Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了。
+
+而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来的方案。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(如二进制流),比如保存在文件中。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。
+
+虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,这个所谓的序列化ID,就是我们在代码中定义的`serialVersionUID`。
+
+### 如果serialVersionUID变了会怎样
+
+我们举个例子吧,看看如果`serialVersionUID`被修改了会发生什么?
+
+ public class SerializableDemo1 {
+ public static void main(String[] args) {
+ //Initializes The Object
+ User1 user = new User1();
+ user.setName("hollis");
+ //Write Obj to File
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
+ oos.writeObject(user);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(oos);
+ }
+ }
+ }
+
+ class User1 implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private String name;
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+
+我们先执行以上代码,把一个User1对象写入到文件中。然后我们修改一下User1类,把`serialVersionUID`的值改为`2L`。
+
+ class User1 implements Serializable {
+ private static final long serialVersionUID = 2L;
+ private String name;
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+
+然后执行以下代码,把文件中的对象反序列化出来:
+
+ public class SerializableDemo2 {
+ public static void main(String[] args) {
+ //Read Obj from File
+ File file = new File("tempFile");
+ ObjectInputStream ois = null;
+ try {
+ ois = new ObjectInputStream(new FileInputStream(file));
+ User1 newUser = (User1) ois.readObject();
+ System.out.println(newUser);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(ois);
+ try {
+ FileUtils.forceDelete(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+执行结果如下:
+
+ java.io.InvalidClassException: com.hollis.User1; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
+
+
+可以发现,以上代码抛出了一个`java.io.InvalidClassException`,并且指出`serialVersionUID`不一致。
+
+这是因为,在进行反序列化时,JVM会把传来的字节流中的`serialVersionUID`与本地相应实体类的`serialVersionUID`进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是`InvalidCastException`。
+
+这也是《阿里巴巴Java开发手册》中规定,在兼容性升级中,在修改类的时候,不要修改`serialVersionUID`的原因。**除非是完全不兼容的两个版本**。所以,**`serialVersionUID`其实是验证版本一致性的。**
+
+如果读者感兴趣,可以把各个版本的JDK代码都拿出来看一下,那些向下兼容的类的`serialVersionUID`是没有变化过的。比如String类的`serialVersionUID`一直都是`-6849794470754667710L`。
+
+但是,作者认为,这个规范其实还可以再严格一些,那就是规定:
+
+如果一个类实现了`Serializable`接口,就必须手动添加一个`private static final long serialVersionUID`变量,并且设置初始值。
+
+### 为什么要明确定一个serialVersionUID
+
+如果我们没有在类中明确的定义一个`serialVersionUID`的话,看看会发生什么。
+
+尝试修改上面的demo代码,先使用以下类定义一个对象,该类中不定义`serialVersionUID`,将其写入文件。
+
+ class User1 implements Serializable {
+ private String name;
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+
+然后我们修改User1类,向其中增加一个属性。在尝试将其从文件中读取出来,并进行反序列化。
+
+ class User1 implements Serializable {
+ private String name;
+ private int age;
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public int getAge() {
+ return age;
+ }
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+
+
+执行结果: `java.io.InvalidClassException: com.hollis.User1; local class incompatible: stream classdesc serialVersionUID = -2986778152837257883, local class serialVersionUID = 7961728318907695402`
+
+同样,抛出了`InvalidClassException`,并且指出两个`serialVersionUID`不同,分别是`-2986778152837257883`和`7961728318907695402`。
+
+从这里可以看出,系统自己添加了一个`serialVersionUID`。
+
+所以,一旦类实现了`Serializable`,就建议明确的定义一个`serialVersionUID`。不然在修改类的时候,就会发生异常。
+
+`serialVersionUID`有两种显示的生成方式:
+一是默认的1L,比如:`private static final long serialVersionUID = 1L;`
+二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
+`private static final long serialVersionUID = xxxxL;`
+
+后面这种方式,可以借助IDE生成,后面会介绍。
+
+### 背后原理
+
+知其然,要知其所以然,我们再来看看源码,分析一下为什么`serialVersionUID`改变的时候会抛异常?在没有明确定义的情况下,默认的`serialVersionUID`是怎么来的?
+
+为了简化代码量,反序列化的调用链如下:
+
+`ObjectInputStream.readObject -> readObject0 -> readOrdinaryObject -> readClassDesc -> readNonProxyDesc -> ObjectStreamClass.initNonProxy`
+
+在`initNonProxy`中 ,关键代码如下:
+
+![][6]
+
+在反序列化过程中,对`serialVersionUID`做了比较,如果发现不相等,则直接抛出异常。
+
+深入看一下`getSerialVersionUID`方法:
+
+ public long getSerialVersionUID() {
+ // REMIND: synchronize instead of relying on volatile?
+ if (suid == null) {
+ suid = AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Long run() {
+ return computeDefaultSUID(cl);
+ }
+ }
+ );
+ }
+ return suid.longValue();
+ }
+
+
+在没有定义`serialVersionUID`的时候,会调用`computeDefaultSUID` 方法,生成一个默认的`serialVersionUID`。
+
+这也就找到了以上两个问题的根源,其实是代码中做了严格的校验。
+
+### IDEA提示
+
+为了确保我们不会忘记定义`serialVersionUID`,可以调节一下Intellij IDEA的配置,在实现`Serializable`接口后,如果没定义`serialVersionUID`的话,IDEA(eclipse一样)会进行提示: ![][7]
+
+并且可以一键生成一个:
+
+![][8]
+
+当然,这个配置并不是默认生效的,需要手动到IDEA中设置一下:
+
+![][9]
+
+在图中标号3的地方(Serializable class without serialVersionUID的配置),打上勾,保存即可。
+
+### 总结
+
+`serialVersionUID`是用来验证版本一致性的。所以在做兼容性升级的时候,不要改变类中`serialVersionUID`的值。
+
+如果一个类实现了Serializable接口,一定要记得定义`serialVersionUID`,否则会发生异常。可以在IDE中通过设置,让他帮忙提示,并且可以一键快速生成一个`serialVersionUID`。
+
+之所以会发生异常,是因为反序列化过程中做了校验,并且如果没有明确定义的话,会根据类的属性自动生成一个。
+
+ [1]: http://www.hollischuang.com/archives/1150
+ [2]: http://www.hollischuang.com/archives/1140
+ [3]: http://www.hollischuang.com/archives/1144
+ [4]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455608799770.jpg
+ [5]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455622116411.jpg
+ [6]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455655236269.jpg
+ [7]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455657868672.jpg
+ [8]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455658088098.jpg
+ [9]: http://www.hollischuang.com/wp-content/uploads/2018/12/15455659620042.jpg
\ No newline at end of file
diff --git a/docs/basics/java-basic/serialVersionUID.md b/docs/basics/java-basic/serialVersionUID.md
new file mode 100644
index 0000000..dc53318
--- /dev/null
+++ b/docs/basics/java-basic/serialVersionUID.md
@@ -0,0 +1,21 @@
+序列化是将对象的状态信息转换为可存储或传输的形式的过程。
+
+我们都知道, Java对象是保存在JVM的堆内存中的, 也就是说, 如果JVM堆不存在了, 那么对象也就跟着消失了。
+
+⽽序列化提供了⼀种⽅案, 可以让你在即使JVM停机的情况下也能把对象保存下来的⽅案。 就像我们平时⽤的U盘⼀样。 把Java对象序列化成可存储或传输的形式( 如⼆进制流) , ⽐如保存在⽂件中。 这样, 当再次需要这个对象的时候, 从⽂件中读取出⼆进制流, 再从⼆进制流中反序列化出对象。
+
+
+但是, 虚拟机是否允许反序列化, 不仅取决于类路径和功能代码是否⼀致, ⼀个⾮常重要的⼀点是两个类的序列化 ID 是否⼀致, 即`serialVersionUID`要求⼀致。
+
+
+在进⾏反序列化时, JVM会把传来的字节流中的`serialVersionUID`与本地相应实体类的`serialVersionUID`进⾏⽐较, 如果相同就认为是⼀致的, 可以进⾏反序列化, 否则就会出现序列化版本不⼀致的异常, 即是`InvalidCastException`。
+
+这样做是为了保证安全, 因为⽂件存储中的内容可能被篡改。
+
+
+当实现`java.io.Serializable`接口的类没有显式地定义⼀个`serialVersionUID`变量时候, Java序列化机制会根据编译的Class⾃动⽣成⼀个`serialVersionUID`作序列化版本⽐较⽤, 这种情况下, 如果Class⽂件没有发⽣变化, 就算再编译多
+次, serialVersionUID也不会变化的。
+
+但是, 如果发⽣了变化,那么这个⽂件对应的`serialVersionUID`也就会发⽣变化。
+
+基于以上原理, 如果我们⼀个类实现了Serializable接口, 但是没有定义`serialVersionUID`, 然后序列化。 在序列化之后, 由于某些原因, 我们对该类做了变更, 重新启动应⽤后, 我们相对之前序列化过的对象进⾏反序列化的话就会报错
\ No newline at end of file
diff --git a/basics/java-basic/serialize-principle.md b/docs/basics/java-basic/serialize-in-java.md
similarity index 78%
rename from basics/java-basic/serialize-principle.md
rename to docs/basics/java-basic/serialize-in-java.md
index 31a4a1c..bf982c8 100644
--- a/basics/java-basic/serialize-principle.md
+++ b/docs/basics/java-basic/serialize-in-java.md
@@ -1,6 +1,3 @@
-## 序列化与反序列化
-
-序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等。在网络传输过程中,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这个相反的过程又称为反序列化。
## Java对象的序列化与反序列化
@@ -135,7 +132,6 @@ Java为了方便开发人员将Java对象进行序列化及反序列化提供了
//User{name='hollis', age=23}
-更多关于Serializable的使用,请参考[代码实例][2]
## Externalizable接口
@@ -319,37 +315,6 @@ Externalizable继承了Serializable,该接口中定义了两个抽象方法:
> 如果User类中没有无参数的构造函数,在运行时会抛出异常:`java.io.InvalidClassException`
-更多Externalizable接口使用实例请参考[代码实例][3]
-
-## ObjectOutput和ObjectInput 接口
-
-ObjectInput接口 扩展自 DataInput 接口以包含对象的读操作。
-
-> DataInput 接口用于从二进制流中读取字节,并根据所有 Java 基本类型数据进行重构。同时还提供根据 UTF-8 修改版格式的数据重构 String 的工具。
->
-> 对于此接口中的所有数据读取例程来说,如果在读取所需字节数之前已经到达文件末尾 (end of file),则将抛出 EOFException(IOException 的一种)。如果因为到达文件末尾以外的其他原因无法读取字节,则将抛出 IOException 而不是 EOFException。尤其是,在输入流已关闭的情况下,将抛出 IOException。
-
-ObjectOutput 扩展 DataOutput 接口以包含对象的写入操作。
-
-> DataOutput 接口用于将数据从任意 Java 基本类型转换为一系列字节,并将这些字节写入二进制流。同时还提供了一个将 String 转换成 UTF-8 修改版格式并写入所得到的系列字节的工具。
->
-> 对于此接口中写入字节的所有方法,如果由于某种原因无法写入某个字节,则抛出 IOException。
-
-## ObjectOutputStream类和ObjectInputStream类
-
-通过前面的代码片段中我们也能知道,我们一般使用ObjectOutputStream的`writeObject`方法把一个对象进行持久化。再使用ObjectInputStream的`readObject`从持久化存储中把对象读取出来。
-
-更多关于ObjectInputStream和ObjectOutputStream的相关知识欢迎阅读我的另外两篇博文:[深入分析Java的序列化与反序列化][4]、[单例与序列化的那些事儿][5]
-
-## Transient 关键字
-
-Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。关于Transient 关键字的拓展知识欢迎阅读[深入分析Java的序列化与反序列化][4]
-
-## 序列化ID
-
-虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 `private static final long serialVersionUID`)
-
-序列化 ID 在 Eclipse 下提供了两种生成策略,一个是固定的 1L,一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具生成),在这里有一个建议,如果没有特殊需求,就是用默认的 1L 就可以,这样可以确保代码一致时反序列化成功。那么随机生成的序列化 ID 有什么作用呢,有些时候,通过改变序列化 ID 可以用来限制某些用户的使用。
## 参考资料
diff --git a/docs/basics/java-basic/serialize-principle.md b/docs/basics/java-basic/serialize-principle.md
new file mode 100644
index 0000000..993ae5b
--- /dev/null
+++ b/docs/basics/java-basic/serialize-principle.md
@@ -0,0 +1,397 @@
+序列化是一种对象持久化的手段。普遍应用在网络传输、RMI等场景中。本文通过分析ArrayList的序列化来介绍Java序列化的相关内容。主要涉及到以下几个问题:
+
+> 怎么实现Java的序列化
+>
+> 为什么实现了java.io.Serializable接口才能被序列化
+>
+> transient的作用是什么
+>
+> 怎么自定义序列化策略
+>
+> 自定义的序列化策略是如何被调用的
+>
+> ArrayList对序列化的实现有什么好处
+
+## Java对象的序列化
+
+Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。
+
+使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的"状态",即它的成员变量。由此可知,**对象序列化不会关注类中的静态变量**。
+
+除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。Java序列化API为处理对象序列化提供了一个标准机制,该API简单易用。
+
+## 如何对Java对象进行序列化与反序列化
+
+在Java中,只要一个类实现了`java.io.Serializable`接口,那么它就可以被序列化。这里先来一段代码:
+
+code 1 创建一个User类,用于序列化及反序列化
+
+ package com.hollis;
+ import java.io.Serializable;
+ import java.util.Date;
+
+ /**
+ * Created by hollis on 16/2/2.
+ */
+ public class User implements Serializable{
+ private String name;
+ private int age;
+ private Date birthday;
+ private transient String gender;
+ private static final long serialVersionUID = -6849794470754667710L;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public Date getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ ", age=" + age +
+ ", gender=" + gender +
+ ", birthday=" + birthday +
+ '}';
+ }
+ }
+
+
+code 2 对User进行序列化及反序列化的Demo
+
+ package com.hollis;
+ import org.apache.commons.io.FileUtils;
+ import org.apache.commons.io.IOUtils;
+ import java.io.*;
+ import java.util.Date;
+
+ /**
+ * Created by hollis on 16/2/2.
+ */
+ public class SerializableDemo {
+
+ public static void main(String[] args) {
+ //Initializes The Object
+ User user = new User();
+ user.setName("hollis");
+ user.setGender("male");
+ user.setAge(23);
+ user.setBirthday(new Date());
+ System.out.println(user);
+
+ //Write Obj to File
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
+ oos.writeObject(user);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(oos);
+ }
+
+ //Read Obj from File
+ File file = new File("tempFile");
+ ObjectInputStream ois = null;
+ try {
+ ois = new ObjectInputStream(new FileInputStream(file));
+ User newUser = (User) ois.readObject();
+ System.out.println(newUser);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(ois);
+ try {
+ FileUtils.forceDelete(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }
+ //output
+ //User{name='hollis', age=23, gender=male, birthday=Tue Feb 02 17:37:38 CST 2016}
+ //User{name='hollis', age=23, gender=null, birthday=Tue Feb 02 17:37:38 CST 2016}
+
+
+## 序列化及反序列化相关知识
+
+1、在Java中,只要一个类实现了`java.io.Serializable`接口,那么它就可以被序列化。
+
+2、通过`ObjectOutputStream`和`ObjectInputStream`对对象进行序列化及反序列化
+
+3、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 `private static final long serialVersionUID`)
+
+4、序列化并不保存静态变量。
+
+5、要想将父类对象也序列化,就需要让父类也实现`Serializable` 接口。
+
+6、Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
+
+7、服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。
+
+## ArrayList的序列化
+
+在介绍ArrayList序列化之前,先来考虑一个问题:
+
+> **如何自定义的序列化和反序列化策略**
+
+带着这个问题,我们来看`java.util.ArrayList`的源码
+
+code 3
+
+ public class ArrayList extends AbstractList
+ implements List, RandomAccess, Cloneable, java.io.Serializable
+ {
+ private static final long serialVersionUID = 8683452581122892189L;
+ transient Object[] elementData; // non-private to simplify nested class access
+ private int size;
+ }
+
+
+笔者省略了其他成员变量,从上面的代码中可以知道ArrayList实现了`java.io.Serializable`接口,那么我们就可以对它进行序列化及反序列化。因为elementData是`transient`的,所以我们认为这个成员变量不会被序列化而保留下来。我们写一个Demo,验证一下我们的想法:
+
+code 4
+
+ public static void main(String[] args) throws IOException, ClassNotFoundException {
+ List stringList = new ArrayList();
+ stringList.add("hello");
+ stringList.add("world");
+ stringList.add("hollis");
+ stringList.add("chuang");
+ System.out.println("init StringList" + stringList);
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("stringlist"));
+ objectOutputStream.writeObject(stringList);
+
+ IOUtils.close(objectOutputStream);
+ File file = new File("stringlist");
+ ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
+ List newStringList = (List)objectInputStream.readObject();
+ IOUtils.close(objectInputStream);
+ if(file.exists()){
+ file.delete();
+ }
+ System.out.println("new StringList" + newStringList);
+ }
+ //init StringList[hello, world, hollis, chuang]
+ //new StringList[hello, world, hollis, chuang]
+
+
+了解ArrayList的人都知道,ArrayList底层是通过数组实现的。那么数组`elementData`其实就是用来保存列表中的元素的。通过该属性的声明方式我们知道,他是无法通过序列化持久化下来的。那么为什么code 4的结果却通过序列化和反序列化把List中的元素保留下来了呢?
+
+### writeObject和readObject方法
+
+在ArrayList中定义了来个方法: `writeObject`和`readObject`。
+
+这里先给出结论:
+
+> 在序列化过程中,如果被序列化的类中定义了writeObject 和 readObject 方法,虚拟机会试图调用对象类里的 writeObject 和 readObject 方法,进行用户自定义的序列化和反序列化。
+>
+> 如果没有这样的方法,则默认调用是 ObjectOutputStream 的 defaultWriteObject 方法以及 ObjectInputStream 的 defaultReadObject 方法。
+>
+> 用户自定义的 writeObject 和 readObject 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。
+
+来看一下这两个方法的具体实现:
+
+code 5
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ elementData = EMPTY_ELEMENTDATA;
+
+ // Read in size, and any hidden stuff
+ s.defaultReadObject();
+
+ // Read in capacity
+ s.readInt(); // ignored
+
+ if (size > 0) {
+ // be like clone(), allocate array based upon size not capacity
+ ensureCapacityInternal(size);
+
+ Object[] a = elementData;
+ // Read in all elements in the proper order.
+ for (int i=0; i 如何自定义的序列化和反序列化策略
+
+答:可以通过在被序列化的类中增加writeObject 和 readObject方法。那么问题又来了:
+
+> 虽然ArrayList中写了writeObject 和 readObject 方法,但是这两个方法并没有显示的被调用啊。
+>
+> **那么如果一个类中包含writeObject 和 readObject 方法,那么这两个方法是怎么被调用的呢?**
+
+## ObjectOutputStream
+
+从code 4中,我们可以看出,对象的序列化过程通过ObjectOutputStream和ObjectInputputStream来实现的,那么带着刚刚的问题,我们来分析一下ArrayList中的writeObject 和 readObject 方法到底是如何被调用的呢?
+
+为了节省篇幅,这里给出ObjectOutputStream的writeObject的调用栈:
+
+`writeObject ---> writeObject0 --->writeOrdinaryObject--->writeSerialData--->invokeWriteObject`
+
+这里看一下invokeWriteObject:
+
+ void invokeWriteObject(Object obj, ObjectOutputStream out)
+ throws IOException, UnsupportedOperationException
+ {
+ if (writeObjectMethod != null) {
+ try {
+ writeObjectMethod.invoke(obj, new Object[]{ out });
+ } catch (InvocationTargetException ex) {
+ Throwable th = ex.getTargetException();
+ if (th instanceof IOException) {
+ throw (IOException) th;
+ } else {
+ throwMiscException(th);
+ }
+ } catch (IllegalAccessException ex) {
+ // should not occur, as access checks have been suppressed
+ throw new InternalError(ex);
+ }
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+其中`writeObjectMethod.invoke(obj, new Object[]{ out });`是关键,通过反射的方式调用writeObjectMethod方法。官方是这么解释这个writeObjectMethod的:
+
+> class-defined writeObject method, or null if none
+
+在我们的例子中,这个方法就是我们在ArrayList中定义的writeObject方法。通过反射的方式被调用了。
+
+至此,我们先试着来回答刚刚提出的问题:
+
+> **如果一个类中包含writeObject 和 readObject 方法,那么这两个方法是怎么被调用的?**
+
+答:在使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法时,会通过反射的方式调用。
+
+* * *
+
+至此,我们已经介绍完了ArrayList的序列化方式。那么,不知道有没有人提出这样的疑问:
+
+
+
+
+> **Serializable明明就是一个空的接口,它是怎么保证只有实现了该接口的方法才能进行序列化与反序列化的呢?**
+
+Serializable接口的定义:
+
+ public interface Serializable {
+ }
+
+
+读者可以尝试把code 1中的继承Serializable的代码去掉,再执行code 2,会抛出`java.io.NotSerializableException`。
+
+其实这个问题也很好回答,我们再回到刚刚ObjectOutputStream的writeObject的调用栈:
+
+`writeObject ---> writeObject0 --->writeOrdinaryObject--->writeSerialData--->invokeWriteObject`
+
+writeObject0方法中有这么一段代码:
+
+ if (obj instanceof String) {
+ writeString((String) obj, unshared);
+ } else if (cl.isArray()) {
+ writeArray(obj, desc, unshared);
+ } else if (obj instanceof Enum) {
+ writeEnum((Enum>) obj, desc, unshared);
+ } else if (obj instanceof Serializable) {
+ writeOrdinaryObject(obj, desc, unshared);
+ } else {
+ if (extendedDebugInfo) {
+ throw new NotSerializableException(
+ cl.getName() + "\n" + debugInfoStack.toString());
+ } else {
+ throw new NotSerializableException(cl.getName());
+ }
+ }
+
+
+在进行序列化操作时,会判断要被序列化的类是否是Enum、Array和Serializable类型,如果不是则直接抛出`NotSerializableException`。
+
+## 总结
+
+1、如果一个类想被序列化,需要实现Serializable接口。否则将抛出`NotSerializableException`异常,这是因为,在序列化操作过程中会对类型进行检查,要求被序列化的类必须属于Enum、Array和Serializable类型其中的任何一种。
+
+2、在变量声明前加上该关键字,可以阻止该变量被序列化到文件中。
+
+3、在类中增加writeObject 和 readObject 方法可以实现自定义序列化策略
+
+## 参考资料
+
+[Java 序列化的高级认识][1]
+
+ [1]: https://www.ibm.com/developerworks/cn/java/j-lo-serial/
\ No newline at end of file
diff --git a/basics/java-basic/serialize-singleton.md b/docs/basics/java-basic/serialize-singleton.md
similarity index 100%
rename from basics/java-basic/serialize-singleton.md
rename to docs/basics/java-basic/serialize-singleton.md
diff --git a/basics/java-basic/serialize.md b/docs/basics/java-basic/serialize.md
similarity index 100%
rename from basics/java-basic/serialize.md
rename to docs/basics/java-basic/serialize.md
diff --git a/basics/java-basic/set-repetition.md b/docs/basics/java-basic/set-repetition.md
similarity index 100%
rename from basics/java-basic/set-repetition.md
rename to docs/basics/java-basic/set-repetition.md
diff --git a/basics/java-basic/set-vs-list.md b/docs/basics/java-basic/set-vs-list.md
similarity index 100%
rename from basics/java-basic/set-vs-list.md
rename to docs/basics/java-basic/set-vs-list.md
diff --git a/basics/java-basic/simpledateformat-thread-safe.md b/docs/basics/java-basic/simpledateformat-thread-safe.md
similarity index 100%
rename from basics/java-basic/simpledateformat-thread-safe.md
rename to docs/basics/java-basic/simpledateformat-thread-safe.md
diff --git a/basics/java-basic/single-double-float.md b/docs/basics/java-basic/single-double-float.md
similarity index 100%
rename from basics/java-basic/single-double-float.md
rename to docs/basics/java-basic/single-double-float.md
diff --git a/basics/java-basic/spi-principle.md b/docs/basics/java-basic/spi-principle.md
similarity index 100%
rename from basics/java-basic/spi-principle.md
rename to docs/basics/java-basic/spi-principle.md
diff --git a/basics/jvm/stack-alloc.md b/docs/basics/java-basic/stack-alloc.md
similarity index 100%
rename from basics/jvm/stack-alloc.md
rename to docs/basics/java-basic/stack-alloc.md
diff --git a/basics/java-basic/static-proxy.md b/docs/basics/java-basic/static-proxy.md
similarity index 100%
rename from basics/java-basic/static-proxy.md
rename to docs/basics/java-basic/static-proxy.md
diff --git a/basics/java-basic/stream.md b/docs/basics/java-basic/stream.md
similarity index 100%
rename from basics/java-basic/stream.md
rename to docs/basics/java-basic/stream.md
diff --git a/basics/java-basic/string-append.md b/docs/basics/java-basic/string-append.md
similarity index 100%
rename from basics/java-basic/string-append.md
rename to docs/basics/java-basic/string-append.md
diff --git a/basics/java-basic/string-concat.md b/docs/basics/java-basic/string-concat.md
similarity index 100%
rename from basics/java-basic/string-concat.md
rename to docs/basics/java-basic/string-concat.md
diff --git a/basics/java-basic/substring.md b/docs/basics/java-basic/substring.md
similarity index 100%
rename from basics/java-basic/substring.md
rename to docs/basics/java-basic/substring.md
diff --git a/basics/java-basic/switch-string.md b/docs/basics/java-basic/switch-string.md
similarity index 100%
rename from basics/java-basic/switch-string.md
rename to docs/basics/java-basic/switch-string.md
diff --git a/basics/java-basic/synchronized-vs-asynchronization.md b/docs/basics/java-basic/synchronized-vs-asynchronization.md
similarity index 100%
rename from basics/java-basic/synchronized-vs-asynchronization.md
rename to docs/basics/java-basic/synchronized-vs-asynchronization.md
diff --git a/basics/java-basic/synchronizedlist-vector.md b/docs/basics/java-basic/synchronizedlist-vector.md
similarity index 100%
rename from basics/java-basic/synchronizedlist-vector.md
rename to docs/basics/java-basic/synchronizedlist-vector.md
diff --git a/basics/java-basic/syntactic-sugar.md b/docs/basics/java-basic/syntactic-sugar.md
similarity index 100%
rename from basics/java-basic/syntactic-sugar.md
rename to docs/basics/java-basic/syntactic-sugar.md
diff --git a/docs/basics/java-basic/time-in-java8.md b/docs/basics/java-basic/time-in-java8.md
new file mode 100644
index 0000000..ec9264a
--- /dev/null
+++ b/docs/basics/java-basic/time-in-java8.md
@@ -0,0 +1,57 @@
+在Java8中, 新的时间及⽇期API位于java.time包中, 该包中有哪些重要的类。 分别代表了什么?
+
+
+`Instant`: 时间戳
+
+`Duration`: 持续时间, 时间差
+
+`LocalDate`: 只包含⽇期, ⽐如: 2016-10-20
+
+`LocalTime`: 只包含时间, ⽐如: 23:12:10
+
+`LocalDateTime`: 包含⽇期和时间, ⽐如: 2016-10-20 23:14:21
+
+`Period`: 时间段
+
+`ZoneOffset`: 时区偏移量, ⽐如: +8:00
+
+`ZonedDateTime`: 带时区的时间
+
+`Clock`: 时钟, ⽐如获取⽬前美国纽约的时间
+
+### LocalTime 和 LocalDate的区别?
+
+
+`LocalDate`表⽰⽇期, 年⽉⽇, `LocalTime`表⽰时间, 时分
+秒
+
+### 获取当前时间
+
+在Java8中,使用如下方式获取当前时间:
+
+ LocalDate today = LocalDate.now();
+ int year = today.getYear();
+ int month = today.getMonthValue();
+ int day = today.getDayOfMonth();
+ System.out.printf("Year : %d Month : %d day : %d t %n", year,month, day);
+
+
+### 创建指定日期的时间
+
+ LocalDate date = LocalDate.of(2018, 01, 01);
+
+
+### 检查闰年
+
+直接使⽤LocalDate的isLeapYear即可判断是否闰年
+
+ LocalDate nowDate = LocalDate.now();
+ //判断闰年
+ boolean leapYear = nowDate.isLeapYear();
+
+### 计算两个⽇期之间的天数和⽉数
+
+在Java 8中可以⽤java.time.Period类来做计算。
+
+ Period period = Period.between(LocalDate.of(2018, 1, 5),LocalDate.of(2018, 2, 5));
+
diff --git a/basics/java-basic/time-zone.md b/docs/basics/java-basic/time-zone.md
similarity index 100%
rename from basics/java-basic/time-zone.md
rename to docs/basics/java-basic/time-zone.md
diff --git a/basics/java-basic/timestamp.md b/docs/basics/java-basic/timestamp.md
similarity index 100%
rename from basics/java-basic/timestamp.md
rename to docs/basics/java-basic/timestamp.md
diff --git a/docs/basics/java-basic/transient.md b/docs/basics/java-basic/transient.md
new file mode 100644
index 0000000..9fb9252
--- /dev/null
+++ b/docs/basics/java-basic/transient.md
@@ -0,0 +1 @@
+transient 关键字的作⽤是控制变量的序列化, 在变量声明前加上该关键字, 可以阻⽌该变量被序列化到⽂件中, 在被反序列化后, transient 变量的值被设为初始值, 如 int 型的是 0,对象型的是 null。
\ No newline at end of file
diff --git a/docs/basics/java-basic/try-with-resources.md b/docs/basics/java-basic/try-with-resources.md
new file mode 100644
index 0000000..632e92f
--- /dev/null
+++ b/docs/basics/java-basic/try-with-resources.md
@@ -0,0 +1,91 @@
+Java里,对于文件操作IO流、数据库连接等开销非常昂贵的资源,用完之后必须及时通过close方法将其关闭,否则资源会一直处于打开状态,可能会导致内存泄露等问题。
+
+关闭资源的常用方式就是在finally块里是释放,即调用close方法。比如,我们经常会写这样的代码:
+
+ public static void main(String[] args) {
+ BufferedReader br = null;
+ try {
+ String line;
+ br = new BufferedReader(new FileReader("d:\\hollischuang.xml"));
+ while ((line = br.readLine()) != null) {
+ System.out.println(line);
+ }
+ } catch (IOException e) {
+ // handle exception
+ } finally {
+ try {
+ if (br != null) {
+ br.close();
+ }
+ } catch (IOException ex) {
+ // handle exception
+ }
+ }
+ }
+
+从Java 7开始,jdk提供了一种更好的方式关闭资源,使用try-with-resources语句,改写一下上面的代码,效果如下:
+
+ public static void main(String... args) {
+ try (BufferedReader br = new BufferedReader(new FileReader("d:\\ hollischuang.xml"))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ System.out.println(line);
+ }
+ } catch (IOException e) {
+ // handle exception
+ }
+ }
+
+看,这简直是一大福音啊,虽然我之前一般使用IOUtils去关闭流,并不会使用在finally中写很多代码的方式,但是这种新的语法糖看上去好像优雅很多呢。看下他的背后:
+
+ public static transient void main(String args[])
+ {
+ BufferedReader br;
+ Throwable throwable;
+ br = new BufferedReader(new FileReader("d:\\ hollischuang.xml"));
+ throwable = null;
+ String line;
+ try
+ {
+ while((line = br.readLine()) != null)
+ System.out.println(line);
+ }
+ catch(Throwable throwable2)
+ {
+ throwable = throwable2;
+ throw throwable2;
+ }
+ if(br != null)
+ if(throwable != null)
+ try
+ {
+ br.close();
+ }
+ catch(Throwable throwable1)
+ {
+ throwable.addSuppressed(throwable1);
+ }
+ else
+ br.close();
+ break MISSING_BLOCK_LABEL_113;
+ Exception exception;
+ exception;
+ if(br != null)
+ if(throwable != null)
+ try
+ {
+ br.close();
+ }
+ catch(Throwable throwable3)
+ {
+ throwable.addSuppressed(throwable3);
+ }
+ else
+ br.close();
+ throw exception;
+ IOException ioexception;
+ ioexception;
+ }
+ }
+
+其实背后的原理也很简单,那些我们没有做的关闭资源的操作,编译器都帮我们做了。所以,再次印证了,语法糖的作用就是方便程序员的使用,但最终还是要转成编译器认识的语言。
\ No newline at end of file
diff --git a/docs/basics/java-basic/type-erasue.md b/docs/basics/java-basic/type-erasue.md
new file mode 100644
index 0000000..f1f40ea
--- /dev/null
+++ b/docs/basics/java-basic/type-erasue.md
@@ -0,0 +1,199 @@
+
+
+### 一、各种语言中的编译器是如何处理泛型的
+
+通常情况下,一个编译器处理泛型有两种方式:
+
+1\.`Code specialization`。在实例化一个泛型类或泛型方法时都产生一份新的目标代码(字节码or二进制代码)。例如,针对一个泛型`list`,可能需要 针对`string`,`integer`,`float`产生三份目标代码。
+
+2\.`Code sharing`。对每个泛型类只生成唯一的一份目标代码;该泛型类的所有实例都映射到这份目标代码上,在需要的时候执行类型检查和类型转换。
+
+**C++**中的模板(`template`)是典型的`Code specialization`实现。**C++**编译器会为每一个泛型类实例生成一份执行代码。执行代码中`integer list`和`string list`是两种不同的类型。这样会导致**代码膨胀(code bloat)**。 **C#**里面泛型无论在程序源码中、编译后的`IL`中(Intermediate Language,中间语言,这时候泛型是一个占位符)或是运行期的CLR中都是切实存在的,`List`与`List`就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型被称为`真实泛型`。 **Java**语言中的泛型则不一样,它只在程序源码中存在,在编译后的字节码文件中,就已经被替换为原来的原生类型(Raw Type,也称为裸类型)了,并且在相应的地方插入了强制转型代码,因此对于运行期的Java语言来说,`ArrayList`与`ArrayList`就是同一个类。所以说泛型技术实际上是Java语言的一颗语法糖,Java语言中的泛型实现方法称为**类型擦除**,基于这种方法实现的泛型被称为`伪泛型`。
+
+`C++`和`C#`是使用`Code specialization`的处理机制,前面提到,他有一个缺点,那就是**会导致代码膨胀**。另外一个弊端是在引用类型系统中,浪费空间,因为引用类型集合中元素本质上都是一个指针。没必要为每个类型都产生一份执行代码。而这也是Java编译器中采用`Code sharing`方式处理泛型的主要原因。
+
+`Java`编译器通过`Code sharing`方式为每个泛型类型创建唯一的字节码表示,并且将该泛型类型的实例都映射到这个唯一的字节码表示上。将多种泛型类形实例映射到唯一的字节码表示是通过**类型擦除**(`type erasue`)实现的。
+
+* * *
+
+### 二、什么是类型擦除
+
+前面我们多次提到这个词:**类型擦除**(`type erasue`)**,那么到底什么是类型擦除呢?
+
+> 类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。 类型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。 类型擦除的主要过程如下: 1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。(这部分内容可以看:[Java泛型中extends和super的理解][2]) 2.移除所有的类型参数。
+
+* * *
+
+### 三、Java编译器处理泛型的过程
+
+**code 1:**
+
+ public static void main(String[] args) {
+ Map map = new HashMap();
+ map.put("name", "hollis");
+ map.put("age", "22");
+ System.out.println(map.get("name"));
+ System.out.println(map.get("age"));
+ }
+
+
+**反编译后的code 1:**
+
+ public static void main(String[] args) {
+ Map map = new HashMap();
+ map.put("name", "hollis");
+ map.put("age", "22");
+ System.out.println((String) map.get("name"));
+ System.out.println((String) map.get("age"));
+ }
+
+
+我们发现泛型都不见了,程序又变回了Java泛型出现之前的写法,泛型类型都变回了原生类型,
+
+* * *
+
+**code 2:**
+
+ interface Comparable {
+ public int compareTo(A that);
+ }
+
+ public final class NumericValue implements Comparable {
+ private byte value;
+
+ public NumericValue(byte value) {
+ this.value = value;
+ }
+
+ public byte getValue() {
+ return value;
+ }
+
+ public int compareTo(NumericValue that) {
+ return this.value - that.value;
+ }
+ }
+
+
+**反编译后的code 2:**
+
+ interface Comparable {
+ public int compareTo( Object that);
+ }
+
+ public final class NumericValue
+ implements Comparable
+ {
+ public NumericValue(byte value)
+ {
+ this.value = value;
+ }
+ public byte getValue()
+ {
+ return value;
+ }
+ public int compareTo(NumericValue that)
+ {
+ return value - that.value;
+ }
+ public volatile int compareTo(Object obj)
+ {
+ return compareTo((NumericValue)obj);
+ }
+ private byte value;
+ }
+
+
+* * *
+
+**code 3:**
+
+ public class Collections {
+ public static > A max(Collection xs) {
+ Iterator xi = xs.iterator();
+ A w = xi.next();
+ while (xi.hasNext()) {
+ A x = xi.next();
+ if (w.compareTo(x) < 0)
+ w = x;
+ }
+ return w;
+ }
+ }
+
+
+**反编译后的code 3:**
+
+ public class Collections
+ {
+ public Collections()
+ {
+ }
+ public static Comparable max(Collection xs)
+ {
+ Iterator xi = xs.iterator();
+ Comparable w = (Comparable)xi.next();
+ while(xi.hasNext())
+ {
+ Comparable x = (Comparable)xi.next();
+ if(w.compareTo(x) < 0)
+ w = x;
+ }
+ return w;
+ }
+ }
+
+
+第2个泛型类`Comparable `擦除后 A被替换为最左边界`Object`。`Comparable`的类型参数`NumericValue`被擦除掉,但是这直 接导致`NumericValue`没有实现接口`Comparable的compareTo(Object that)`方法,于是编译器充当好人,添加了一个**桥接方法**。 第3个示例中限定了类型参数的边界`>A`,A必须为`Comparable`的子类,按照类型擦除的过程,先讲所有的类型参数 ti换为最左边界`Comparable`,然后去掉参数类型`A`,得到最终的擦除后结果。
+
+* * *
+
+### 四、泛型带来的问题
+
+**一、当泛型遇到重载:**
+
+ public class GenericTypes {
+
+ public static void method(List list) {
+ System.out.println("invoke method(List list)");
+ }
+
+ public static void method(List list) {
+ System.out.println("invoke method(List list)");
+ }
+ }
+
+
+上面这段代码,有两个重载的函数,因为他们的参数类型不同,一个是`List`另一个是`List` ,但是,这段代码是编译通不过的。因为我们前面讲过,参数`List`和`List`编译之后都被擦除了,变成了一样的原生类型List,擦除动作导致这两个方法的特征签名变得一模一样。
+
+**二、当泛型遇到catch:**
+
+如果我们自定义了一个泛型异常类GenericException,那么,不要尝试用多个catch取匹配不同的异常类型,例如你想要分别捕获GenericException、GenericException,这也是有问题的。
+
+三、当泛型内包含静态变量
+
+ public class StaticTest{
+ public static void main(String[] args){
+ GT gti = new GT();
+ gti.var=1;
+ GT gts = new GT();
+ gts.var=2;
+ System.out.println(gti.var);
+ }
+ }
+ class GT{
+ public static int var=0;
+ public void nothing(T x){}
+ }
+
+
+答案是——2!由于经过类型擦除,所有的泛型类实例都关联到同一份字节码上,泛型类的所有静态变量是共享的。
+
+* * *
+
+### 五、总结
+
+1\.虚拟机中没有泛型,只有普通类和普通方法,所有泛型类的类型参数在编译时都会被擦除,泛型类并没有自己独有的Class类对象。比如并不存在`List`.class或是`List.class`,而只有`List.class`。 2.创建泛型对象时请指明类型,让编译器尽早的做参数检查(**Effective Java,第23条:请不要在新代码中使用原生态类型**) 3.不要忽略编译器的警告信息,那意味着潜在的`ClassCastException`等着你。 4.静态变量是被泛型类的所有实例所共享的。对于声明为`MyClass`的类,访问其中的静态变量的方法仍然是 `MyClass.myStaticVar`。不管是通过`new MyClass`还是`new MyClass`创建的对象,都是共享一个静态变量。 5.泛型的类型参数不能用在`Java`异常处理的`catch`语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,`JVM`是无法区分两个异常类型`MyException`和`MyException`的。对于`JVM`来说,它们都是 `MyException`类型的。也就无法执行与异常对应的`catch`语句。
+
+ [1]: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
+ [2]: /archives/255
\ No newline at end of file
diff --git a/basics/java-basic/url-encode.md b/docs/basics/java-basic/url-encode.md
similarity index 100%
rename from basics/java-basic/url-encode.md
rename to docs/basics/java-basic/url-encode.md
diff --git a/basics/java-basic/usage-of-reflection.md b/docs/basics/java-basic/usage-of-reflection.md
similarity index 100%
rename from basics/java-basic/usage-of-reflection.md
rename to docs/basics/java-basic/usage-of-reflection.md
diff --git a/basics/java-basic/value-of-vs-to-string.md b/docs/basics/java-basic/value-of-vs-to-string.md
similarity index 100%
rename from basics/java-basic/value-of-vs-to-string.md
rename to docs/basics/java-basic/value-of-vs-to-string.md
diff --git a/basics/java-basic/variable.md b/docs/basics/java-basic/variable.md
similarity index 100%
rename from basics/java-basic/variable.md
rename to docs/basics/java-basic/variable.md
diff --git a/basics/java-basic/why-gbk.md b/docs/basics/java-basic/why-gbk.md
similarity index 100%
rename from basics/java-basic/why-gbk.md
rename to docs/basics/java-basic/why-gbk.md
diff --git a/basics/java-basic/why-utf8.md b/docs/basics/java-basic/why-utf8.md
similarity index 100%
rename from basics/java-basic/why-utf8.md
rename to docs/basics/java-basic/why-utf8.md
diff --git a/docs/basics/object-oriented/_sidebar.md b/docs/basics/object-oriented/_sidebar.md
new file mode 100644
index 0000000..5c8c498
--- /dev/null
+++ b/docs/basics/object-oriented/_sidebar.md
@@ -0,0 +1,32 @@
+* 什么是面向对象
+
+ * [面向对象与面向过程](/basics/object-oriented/object-oriented-vs-procedure-oriented.md)
+
+ * [面向对象的三大基本特征](/basics/object-oriented/characteristics.md)
+
+ * [面向对象的五大基本原则](/basics/object-oriented/principle.md)
+* 平台无关性
+
+ * [Java如何实现的平台无关性的](/basics/object-oriented/platform-independent.md)
+
+ * [JVM还支持哪些语言](/basics/object-oriented/jvm-language.md)
+
+* 值传递
+
+ * [值传递、引用传递](/basics/object-oriented/java-pass-by.md)
+
+ * [为什么说Java中只有值传递](/basics/object-oriented/why-pass-by-reference.md)
+
+* 封装、继承、多态
+ * [什么是多态](/basics/object-oriented/polymorphism.md)
+
+ * [方法重写与重载](/basics/object-oriented/overloading-vs-overriding.md)
+* Java的继承与实现
+
+ * [Java的继承与组合](/basics/object-oriented/inheritance-composition.md)
+
+ * [构造函数与默认构造函数](/basics/object-oriented/constructor.md)
+
+ * [类变量、成员变量和局部变量](/basics/object-oriented/variable.md)
+
+ * [成员变量和方法作用域](/basics/object-oriented/scope.md)
\ No newline at end of file
diff --git a/basics/java-basic/characteristics.md b/docs/basics/object-oriented/characteristics.md
similarity index 93%
rename from basics/java-basic/characteristics.md
rename to docs/basics/object-oriented/characteristics.md
index ce725a4..5b3b3bc 100644
--- a/basics/java-basic/characteristics.md
+++ b/docs/basics/object-oriented/characteristics.md
@@ -1,14 +1,14 @@
-面向对象三大特征:
-### (1)封装(Encapsulation)
+
+### 封装(Encapsulation)
所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
-### (2)继承(Inheritance)
+### 继承(Inheritance)
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
-### (3)多态(Polymorphism)
+### 多态(Polymorphism)
所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
diff --git a/docs/basics/object-oriented/constructor.md b/docs/basics/object-oriented/constructor.md
new file mode 100644
index 0000000..a0b3c01
--- /dev/null
+++ b/docs/basics/object-oriented/constructor.md
@@ -0,0 +1,5 @@
+构造函数,是一种特殊的方法。 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。 特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。
+
+构造函数跟一般的实例方法十分相似;但是与其它方法不同,构造器没有返回类型,不会被继承,且可以有范围修饰符。构造器的函数名称必须和它所属的类的名称相同。 它承担着初始化对象数据成员的任务。
+
+如果在编写一个可实例化的类时没有专门编写构造函数,多数编程语言会自动生成缺省构造器(默认构造函数)。默认构造函数一般会把成员变量的值初始化为默认值,如int -> 0,Integer -> null。
diff --git a/docs/basics/object-oriented/inheritance-composition.md b/docs/basics/object-oriented/inheritance-composition.md
new file mode 100644
index 0000000..5eff0d3
--- /dev/null
+++ b/docs/basics/object-oriented/inheritance-composition.md
@@ -0,0 +1,67 @@
+Java是一个面向对象的语言。每一个学习过Java的人都知道,封装、继承、多态是面向对象的三个特征。每个人在刚刚学习继承的时候都会或多或少的有这样一个印象:继承可以帮助我实现类的复用。所以,很多开发人员在需要复用一些代码的时候会很自然的使用类的继承的方式,因为书上就是这么写的(老师就是这么教的)。但是,其实这样做是不对的。长期大量的使用继承会给代码带来很高的维护成本。
+
+本文将介绍组合和继承的概念及区别,并从多方面分析在写代码时如何进行选择。
+
+## 面向对象的复用技术
+
+前面提到复用,这里就简单介绍一下面向对象的复用技术。
+
+复用性是面向对象技术带来的很棒的潜在好处之一。如果运用的好的话可以帮助我们节省很多开发时间,提升开发效率。但是,如果被滥用那么就可能产生很多难以维护的代码。
+
+作为一门面向对象开发的语言,代码复用是Java引人注意的功能之一。Java代码的复用有继承,组合以及代理三种具体的表现形式。本文将重点介绍继承复用和组合复用。
+
+## 继承
+
+继承(Inheritance)是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;继承是一种[`is-a`][1]关系。(图片来自网络,侵删。)
+
+![Inheritance][2]
+
+## 组合
+
+组合(Composition)体现的是整体与部分、拥有的关系,即[`has-a`][3]的关系。
+
+![Composition][4]
+
+## 组合与继承的区别和联系
+
+> 在`继承`结构中,父类的内部细节对于子类是可见的。所以我们通常也可以说通过继承的代码复用是一种`白盒式代码复用`。(如果基类的实现发生改变,那么派生类的实现也将随之改变。这样就导致了子类行为的不可预知性;)
+>
+> `组合`是通过对现有的对象进行拼装(组合)产生新的、更复杂的功能。因为在对象之间,各自的内部细节是不可见的,所以我们也说这种方式的代码复用是`黑盒式代码复用`。(因为组合中一般都定义一个类型,所以在编译期根本不知道具体会调用哪个实现类的方法)
+>
+> `继承`,在写代码的时候就要指名具体继承哪个类,所以,在`编译期`就确定了关系。(从基类继承来的实现是无法在运行期动态改变的,因此降低了应用的灵活性。)
+>
+> `组合`,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在`运行期`确定。
+
+## 优缺点对比
+
+| 组 合 关 系 | 继 承 关 系 |
+| -------------------------------- | -------------------------------------- |
+| 优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 | 缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性 |
+| 优点:具有较好的可扩展性 | 缺点:支持扩展,但是往往以增加系统结构的复杂度为代价 |
+| 优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象 | 缺点:不支持动态继承。在运行时,子类无法选择不同的父类 |
+| 优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口 | 缺点:子类不能改变父类的接口 |
+| 缺点:整体类不能自动获得和局部类同样的接口 | 优点:子类能自动继承父类的接口 |
+| 缺点:创建整体类的对象时,需要创建所有局部类的对象 | 优点:创建子类的对象时,无须创建父类的对象 |
+
+## 如何选择
+
+相信很多人都知道面向对象中有一个比较重要的原则『多用组合、少用继承』或者说『组合优于继承』。从前面的介绍已经优缺点对比中也可以看出,组合确实比继承更加灵活,也更有助于代码维护。
+
+所以,
+
+> **`建议在同样可行的情况下,优先使用组合而不是继承。`**
+>
+> **`因为组合更安全,更简单,更灵活,更高效。`**
+
+注意,并不是说继承就一点用都没有了,前面说的是【在同样可行的情况下】。有一些场景还是需要使用继承的,或者是更适合使用继承。
+
+> 继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。《[Java编程思想][5]》
+>
+> 只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在[`is-a`][1]关系的时候,类B才应该继承类A。《[Effective Java][6]》
+
+ [1]: https://zh.wikipedia.org/wiki/Is-a
+ [2]: http://www.hollischuang.com/wp-content/uploads/2016/03/Generalization.jpg
+ [3]: https://en.wikipedia.org/wiki/Has-a
+ [4]: http://www.hollischuang.com/wp-content/uploads/2016/03/Composition.jpg
+ [5]: http://s.click.taobao.com/t?e=m%3D2%26s%3DHzJzud6zOdocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67vo5P8BMUBgoEC56fBbgyn5pS4hLH%2FP02ckKYNRBWOBBey11vvWwHXSniyi5vWXIZhtlrJbLMDAQihpQCXu2JnPFYKQlNeOGCsYMXU3NNCg%2F&pvid=10_125.119.86.125_222_1458652212179
+ [6]: http://s.click.taobao.com/t?e=m%3D2%26s%3DwIPn8%2BNPqLwcQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67vo5P8BMUBgoUOZr0mLjusdpS4hLH%2FP02ckKYNRBWOBBey11vvWwHXSniyi5vWXIZvgXwmdyquYbNLnO%2BjzYQLqKnzbV%2FMLqnMYMXU3NNCg%2F&pvid=10_125.119.86.125_345_1458652241780
diff --git a/docs/basics/object-oriented/java-pass-by.md b/docs/basics/object-oriented/java-pass-by.md
new file mode 100644
index 0000000..ef1f02e
--- /dev/null
+++ b/docs/basics/object-oriented/java-pass-by.md
@@ -0,0 +1,57 @@
+
+### 实参与形参
+
+我们都知道,在Java中定义方法的时候是可以定义参数的。比如Java中的main方法,`public static void main(String[] args)`,这里面的args就是参数。参数在程序语言中分为形式参数和实际参数。
+
+> 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
+>
+> 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。
+
+简单举个例子:
+
+```
+public static void main(String[] args) {
+ ParamTest pt = new ParamTest();
+ pt.sout("Hollis");//实际参数为 Hollis
+}
+
+public void sout(String name) { //形式参数为 name
+ System.out.println(name);
+}
+```
+
+实际参数是调用有参方法的时候真正传递的内容,而形式参数是用于接收实参内容的参数。
+
+### 值传递与引用传递
+
+上面提到了,当我们调用一个有参函数的时候,会把实际参数传递给形式参数。但是,在程序语言中,这个传递过程中传递的两种情况,即值传递和引用传递。我们来看下程序语言中是如何定义和区分值传递和引用传递的。
+
+> 值传递(pass by value)是指在调用函数时将实际参数`复制`一份传递到函数中,这样在函数中如果对`参数`进行修改,将不会影响到实际参数。
+>
+> 引用传递(pass by reference)是指在调用函数时将实际参数的地址`直接`传递到函数中,那么在函数中对`参数`所进行的修改,将影响到实际参数。
+
+那么,我来给大家总结一下,值传递和引用传递之前的区别的重点是什么:
+
+[
][3]
+
+这里我们来举一个形象的例子。再来深入理解一下值传递和引用传递:
+
+你有一把钥匙,当你的朋友想要去你家的时候,如果你`直接`把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。
+
+你有一把钥匙,当你的朋友想要去你家的时候,你`复刻`了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。
+
+
+### 参考资料
+
+[Evaluation strategy][7]
+
+[关于值传递和引用传递][8]
+
+[按值传递、按引用传递、按共享传递][9]
+
+[Is Java “pass-by-reference” or “pass-by-value”?][2]
+
+[2]: https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
+[7]: https://en.wikipedia.org/wiki/Evaluation_strategy
+[8]: http://chenwenbo.github.io/2016/05/11/%E5%85%B3%E4%BA%8E%E5%80%BC%E4%BC%A0%E9%80%92%E5%92%8C%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92/
+[9]: http://menzhongxin.com/2017/02/07/%E6%8C%89%E5%80%BC%E4%BC%A0%E9%80%92-%E6%8C%89%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92%E5%92%8C%E6%8C%89%E5%85%B1%E4%BA%AB%E4%BC%A0%E9%80%92/
diff --git a/basics/java-basic/jvm-language.md b/docs/basics/object-oriented/jvm-language.md
similarity index 100%
rename from basics/java-basic/jvm-language.md
rename to docs/basics/object-oriented/jvm-language.md
diff --git a/basics/java-basic/object-oriented-vs-procedure-oriented.md b/docs/basics/object-oriented/object-oriented-vs-procedure-oriented.md
similarity index 90%
rename from basics/java-basic/object-oriented-vs-procedure-oriented.md
rename to docs/basics/object-oriented/object-oriented-vs-procedure-oriented.md
index 39f0555..d10394c 100644
--- a/basics/java-basic/object-oriented-vs-procedure-oriented.md
+++ b/docs/basics/object-oriented/object-oriented-vs-procedure-oriented.md
@@ -1,6 +1,8 @@
+
+
### 什么是面向过程?
-####概述: 自顶而下的编程模式.
+#### 概述: 自顶而下的编程模式.
把问题分解成一个一个步骤,每个步骤用函数实现,依次调用即可。
@@ -11,7 +13,7 @@
### 什么是面向对象?
-####概述: 将事务高度抽象化的编程模式.
+#### 概述: 将事务高度抽象化的编程模式.
将问题分解成一个一个步骤,对每个步骤进行相应的抽象,形成对象,通过不同对象之间的调用,组合解决问题。
@@ -19,7 +21,7 @@
比如:想要造一辆车,上来要先把车的各种属性定义出来,然后抽象成一个Car类。
-#### 举例说明区别
+### 举例说明区别
同样一个象棋设计.
@@ -27,7 +29,7 @@
面向过程:开始—黑走—棋盘—判断—白走—棋盘—判断—循环。只需要关注每一步怎么实现即可.
-#### 优劣对比
+### 优劣对比
面向对象:占用资源相对高,速度相对慢
diff --git a/basics/java-basic/overloading-vs-overriding.md b/docs/basics/object-oriented/overloading-vs-overriding.md
similarity index 100%
rename from basics/java-basic/overloading-vs-overriding.md
rename to docs/basics/object-oriented/overloading-vs-overriding.md
diff --git a/basics/java-basic/platform-independent.md b/docs/basics/object-oriented/platform-independent.md
similarity index 97%
rename from basics/java-basic/platform-independent.md
rename to docs/basics/object-oriented/platform-independent.md
index 073686a..61c3ca7 100644
--- a/basics/java-basic/platform-independent.md
+++ b/docs/basics/object-oriented/platform-independent.md
@@ -6,7 +6,7 @@
也就是说,用Java创建的可执行二进制程序,能够不加改变的运行于多个平台。
-**平台无关性好处**
+#### 平台无关性好处
作为一门平台无关性语言,无论是在自身发展,还是对开发者的友好度上都是很突出的。
@@ -18,7 +18,7 @@
对于Java的平台无关性的支持,就像对安全性和网络移动性的支持一样,是分布在整个Java体系结构中的。其中扮演者重要的角色的有Java语言规范、Class文件、Java虚拟机(JVM)等。
-**编译原理基础**
+#### 编译原理基础
讲到Java语言规范、Class文件、Java虚拟机就不得不提Java到底是是如何运行起来的。
@@ -28,7 +28,7 @@
在[深入分析Java的编译原理][2]中我们介绍过,在Java平台中,想要把Java文件,编译成二进制文件,需要经过两步编译,前端编译和后端编译:
-![][3]
+![][3]
前端编译主要指与源语言有关但与目标机无关的部分。Java中,我们所熟知的`javac`的编译就是前端编译。除了这种以外,我们使用的很多IDE,如eclipse,idea等,都内置了前端编译器。主要功能就是把`.java`代码转换成`.class`代码。
@@ -36,11 +36,11 @@
后端编译主要是将中间代码再翻译成机器语言。Java中,这一步骤就是Java虚拟机来执行的。
-![][4]
+![][4]
所以,我们说的,Java的平台无关性实现主要作用于以上阶段。如下图所示:
-![][5]
+![][5]
我们从后往前介绍一下这三位主演:Java虚拟机、Class文件、Java语言规范
@@ -52,17 +52,17 @@
而这一工作,主要由我们的Java虚拟机完成。虽然Java语言是平台无关的,但是JVM确实平台有关的,不同的操作系统上面要安装对应的JVM。
-![][6]
+![][6]
上图是Oracle官网下载JDK的指引,不同的操作系统需要下载对应的Java虚拟机。
有了Java虚拟机,想要执行a+b操作,A操作系统上面的虚拟机就会把指令翻译成10001000,B操作系统上面的虚拟机就会把指令翻译成11101110。
-![][7] ps:图中的Class文件中内容为mock内容
+![][7] ps:图中的Class文件中内容为mock内容
所以,Java之所以可以做到跨平台,是因为Java虚拟机充当了桥梁。他扮演了运行时Java程序与其下的硬件和操作系统之间的缓冲角色。
-**字节码**
+#### 字节码
各种不同的平台的虚拟机都使用统一的程序存储格式——字节码(ByteCode)是构成平台无关性的另一个基石。Java虚拟机只与由字节码组成的Class文件进行交互。
@@ -70,7 +70,7 @@
因为Java Class文件可以在任何平台创建,也可以被任何平台的Java虚拟机装载并执行,所以才有了Java的平台无关性。
-**Java语言规范**
+#### Java语言规范
已经有了统一的Class文件,以及可以在不同平台上将Class文件翻译成对应的二进制文件的Java虚拟机,Java就可以彻底实现跨平台了吗?
@@ -82,7 +82,7 @@
但是在C++中却不是固定的了。在16位计算机上,int类型的长度可能为两字节;在32位计算机上,可能为4字节;当64位计算机流行起来后,int类型的长度可能会达到8字节。(这里说的都是可能哦!)
-![][8]
+![][8]
通过保证基本数据类型在所有平台的一致性,Java语言为平台无关性提供强了有力的支持。
diff --git a/basics/java-basic/polymorphism.md b/docs/basics/object-oriented/polymorphism.md
similarity index 96%
rename from basics/java-basic/polymorphism.md
rename to docs/basics/object-oriented/polymorphism.md
index 8cea3c1..ff84a31 100644
--- a/basics/java-basic/polymorphism.md
+++ b/docs/basics/object-oriented/polymorphism.md
@@ -1,8 +1,10 @@
-### 什么是多态,多态有什么好处,多态的必要条件是什么、Java中多态的实现方式
+### 什么是多态
多态的概念呢比较简单,就是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
如果按照这个概念来定义的话,那么多态应该是一种运行期的状态。
+
+### 多态的必要条件
为了实现运行期的多态,或者说是动态绑定,需要满足三个条件。
即有类继承或者接口实现、子类要重写父类的方法、父类的引用指向子类的对象。
@@ -37,11 +39,14 @@
}
这样,就实现了多态,同样是Parent类的实例,p.call 调用的是Son类的实现、p1.call调用的是Daughter的实现。
+
有人说,你自己定义的时候不就已经知道p是son,p1是Daughter了么。但是,有些时候你用到的对象并不都是自己声明的啊 。
+
比如Spring 中的IOC出来的对象,你在使用的时候就不知道他是谁,或者说你可以不用关心他是谁。根据具体情况而定。
另外,还有一种说法,包括维基百科也说明,多态还分为动态多态和静态多态。
+
上面提到的那种动态绑定认为是动态多态,因为只有在运行期才能知道真正调用的是哪个类的方法。
还有一种静态多态,一般认为Java中的函数重载是一种静态多态,因为他需要在编译期决定具体调用哪个方法、
diff --git a/basics/java-basic/principle.md b/docs/basics/object-oriented/principle.md
similarity index 99%
rename from basics/java-basic/principle.md
rename to docs/basics/object-oriented/principle.md
index b21c8c4..64b3745 100644
--- a/basics/java-basic/principle.md
+++ b/docs/basics/object-oriented/principle.md
@@ -1,3 +1,6 @@
+
+
+
### 单一职责原则(Single-Resposibility Principle)
其核心思想为:一个类,最好只做一件事,只有一个引起它的变化。单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原因就越多,这将导致职责依赖,相互之间就产生影响,从而大大损伤其内聚性和耦合度。通常意义下的单一职责,就是指只有一种单一功能,不要为类实现过多的功能点,以保证实体只有一个引起它变化的原因。
diff --git a/docs/basics/object-oriented/scope.md b/docs/basics/object-oriented/scope.md
new file mode 100644
index 0000000..39c43aa
--- /dev/null
+++ b/docs/basics/object-oriented/scope.md
@@ -0,0 +1,11 @@
+
+对于成员变量和方法的作用域,public,protected,private以及不写之间的区别:
+
+
+`public` : 表明该成员变量或者方法是对所有类或者对象都是可见的,所有类或者对象都可以直接访问
+
+`private` : 表明该成员变量或者方法是私有的,只有当前类对其具有访问权限,除此之外其他类或者对象都没有访问权限.子类也没有访问权限.
+
+`protected` : 表明成员变量或者方法对类自身,与同在一个包中的其他类可见,其他包下的类不可访问,除非是他的子类
+
+`default` : 表明该成员变量或者方法只有自己和其位于同一个包的内可见,其他包内的类不能访问,即便是它的子类
\ No newline at end of file
diff --git a/docs/basics/object-oriented/variable.md b/docs/basics/object-oriented/variable.md
new file mode 100644
index 0000000..cc3849c
--- /dev/null
+++ b/docs/basics/object-oriented/variable.md
@@ -0,0 +1,27 @@
+Java中共有三种变量,分别是类变量、成员变量和局部变量。他们分别存放在JVM的方法区、堆内存和栈内存中。
+```java
+ /**
+ * @author Hollis
+ */
+ public class Variables {
+
+ /**
+ * 类变量
+ */
+ private static int a;
+
+ /**
+ * 成员变量
+ */
+ private int b;
+
+ /**
+ * 局部变量
+ * @param c
+ */
+ public void test(int c){
+ int d;
+ }
+ }
+```
+上面定义的三个变量中,变量a就是类变量,变量b就是成员变量,而变量c和d是局部变量。
diff --git a/basics/java-basic/java-pass-by.md b/docs/basics/object-oriented/why-pass-by-reference.md
similarity index 55%
rename from basics/java-basic/java-pass-by.md
rename to docs/basics/object-oriented/why-pass-by-reference.md
index 72e98dd..d879c06 100644
--- a/basics/java-basic/java-pass-by.md
+++ b/docs/basics/object-oriented/why-pass-by-reference.md
@@ -1,6 +1,4 @@
-# 为什么说Java中只有值传递
-
-对于初学者来说,要想把这个问题回答正确,是比较难的。在第二天整理答案的时候,我发现我竟然无法通过简单的语言把这个事情描述的很容易理解,遗憾的是,我也没有在网上找到哪篇文章可以把这个事情讲解的通俗易懂。所以,就有了我写这篇文章的初衷。这篇文章中,我从什么是方法的实际参数和形式参数开始,给你讲解为什么说Java中只有值传递。
+对于初学者来说,要想把这个问题回答正确,是比较难的。在第二天整理答案的时候,我发现我竟然无法通过简单的语言把这个事情描述的很容易理解,遗憾的是,我也没有在网上找到哪篇文章可以把这个事情讲解的通俗易懂。所以,就有了我写这篇文章的初衷。
### 辟谣时间
@@ -14,63 +12,22 @@
>
> 错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。
-### 实参与形参
-
-我们都知道,在Java中定义方法的时候是可以定义参数的。比如Java中的main方法,`public static void main(String[] args)`,这里面的args就是参数。参数在程序语言中分为形式参数和实际参数。
-
-> 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
->
-> 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。
-
-简单举个例子:
-```
-public static void main(String[] args) {
- ParamTest pt = new ParamTest();
- pt.sout("Hollis");//实际参数为 Hollis
-}
-
-public void sout(String name) { //形式参数为 name
- System.out.println(name);
-}
-```
-
-实际参数是调用有参方法的时候真正传递的内容,而形式参数是用于接收实参内容的参数。
-
-### 值传递与引用传递
+### Java中的值传递
-上面提到了,当我们调用一个有参函数的时候,会把实际参数传递给形式参数。但是,在程序语言中,这个传递过程中传递的两种情况,即值传递和引用传递。我们来看下程序语言中是如何定义和区分值传递和引用传递的。
+值传递和引用传的的定义如下:
-> 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
+> 值传递(pass by value)是指在调用函数时将实际参数`复制`一份传递到函数中,这样在函数中如果对`参数`进行修改,将不会影响到实际参数。
>
-> 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
-
-有了上面的概念,然后大家就可以写代码实践了,来看看Java中到底是值传递还是引用传递 ,于是,最简单的一段代码出来了:
-```
-public static void main(String[] args) {
- ParamTest pt = new ParamTest();
-
- int i = 10;
- pt.pass(i);
- System.out.println("print in main , i is " + i);
-}
+> 引用传递(pass by reference)是指在调用函数时将实际参数的地址`直接`传递到函数中,那么在函数中对`参数`所进行的修改,将影响到实际参数。
-public void pass(int j) {
- j = 20;
- System.out.println("print in pass , j is " + j);
-}
-```
-上面的代码中,我们在pass方法中修改了参数j的值,然后分别在pass方法和main方法中打印参数的值。输出结果如下:
+你有一把钥匙,当你的朋友想要去你家的时候,如果你`直接`把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。
-```
-print in pass , j is 20
-print in main , i is 10
-```
+你有一把钥匙,当你的朋友想要去你家的时候,你`复刻`了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。
-可见,pass方法内部对name的值的修改并没有改变实际参数i的值。那么,按照上面的定义,有人得到结论:Java的方法传递是值传递。
-但是,很快就有人提出质疑了(哈哈,所以,不要轻易下结论咯。)。然后,他们会搬出以下代码:
+我们举一个实际的代码例子:
```
public static void main(String[] args) {
ParamTest pt = new ParamTest();
@@ -83,68 +40,32 @@ public static void main(String[] args) {
}
public void pass(User user) {
+ user = new User();
user.setName("hollischuang");
System.out.println("print in pass , user is " + user);
}
-```
-同样是一个pass方法,同样是在pass方法内修改参数的值。输出结果如下:
```
-print in pass , user is User{name='hollischuang', gender='Male'}
-print in main , user is User{name='hollischuang', gender='Male'}
-```
-
-经过pass方法执行后,实参的值竟然被改变了,那按照上面的引用传递的定义,实际参数的值被改变了,这不就是引用传递了么。于是,根据上面的两段代码,有人得出一个新的结论:Java的方法中,在传递普通类型的时候是值传递,在传递对象类型的时候是引用传递。
-
-但是,这种表述仍然是错误的。不信你看下面这个参数类型为对象的参数传递:
-```
-public static void main(String[] args) {
- ParamTest pt = new ParamTest();
-
- String name = "Hollis";
- pt.pass(name);
- System.out.println("print in main , name is " + name);
-}
-public void pass(String name) {
- name = "hollischuang";
- System.out.println("print in pass , name is " + name);
-}
-```
-
-上面的代码输出结果为
+上面的代码中,我们在pass方法中,改变了user对象,输出结果如下:
```
-print in pass , name is hollischuang
-print in main , name is Hollis
+print in pass , user is User{name='hollischuang', gender='Male'}
+print in main , user is User{name='Hollis', gender='Male'}
```
-这又作何解释呢?同样传递了一个对象,但是原始参数的值并没有被修改,难道传递对象又变成值传递了?
-
-### Java中的值传递
-
-上面,我们举了三个例子,表现的结果却不一样,这也是导致很多初学者,甚至很多高级程序员对于Java的传递类型有困惑的原因。
-
-其实,我想告诉大家的是,上面的概念没有错,只是代码的例子有问题。来,我再来给大家画一下概念中的重点,然后再举几个真正恰当的例子。
-> 值传递(pass by value)是指在调用函数时将实际参数`复制`一份传递到函数中,这样在函数中如果对`参数`进行修改,将不会影响到实际参数。
->
-> 引用传递(pass by reference)是指在调用函数时将实际参数的地址`直接`传递到函数中,那么在函数中对`参数`所进行的修改,将影响到实际参数。
-
-那么,我来给大家总结一下,值传递和引用传递之前的区别的重点是什么。
-
-[
][3]
+我们来画一张图,看一下整个过程中发生了什么,然后我再告诉你,为啥Java中只有值传递。
-我们上面看过的几个pass的例子中,都只关注了实际参数内容是否有改变。如传递的是User对象,我们试着改变他的name属性的值,然后检查是否有改变。其实,在实验方法上就错了,当然得到的结论也就有问题了。
+[
][4]
-为什么说实验方法错了呢?这里我们来举一个形象的例子。再来深入理解一下值传递和引用传递,然后你就知道为啥错了。
+稍微解释下这张图,当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后hollis持有该内存的地址`0x123456`(图1)。当尝试调用pass方法,并且hollis作为实际参数传递给形式参数user的时候,会把这个地址`0x123456`交给user,这时,user也指向了这个地址(图2)。然后在pass方法内对参数进行修改的时候,即`user = new User();`,会重新开辟一块`0X456789`的内存,赋值给user。后面对user的任何修改都不会改变内存`0X123456`的内容(图3)。
-你有一把钥匙,当你的朋友想要去你家的时候,如果你`直接`把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。
+上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在`user=new User()`的时候,实际参数的引用也应该改为指向`0X456789`,但是实际上并没有。
-你有一把钥匙,当你的朋友想要去你家的时候,你`复刻`了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。
+通过概念我们也能知道,这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,**上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。**
-但是,不管上面那种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?而我们在pass方法中,改变user对象的name属性的值的时候,不就是在“砸电视”么。
+我们再来看下面的例子:
-还拿上面的一个例子来举例,我们`真正的改变参数`,看看会发生什么?
```
public static void main(String[] args) {
ParamTest pt = new ParamTest();
@@ -157,30 +78,18 @@ public static void main(String[] args) {
}
public void pass(User user) {
- user = new User();
user.setName("hollischuang");
- user.setGender("Male");
System.out.println("print in pass , user is " + user);
}
-```
-上面的代码中,我们在pass方法中,改变了user对象,输出结果如下:
+```
+输出结果:
```
print in pass , user is User{name='hollischuang', gender='Male'}
-print in main , user is User{name='Hollis', gender='Male'}
+print in main , user is User{name='hollischuang', gender='Male'}
```
-我们来画一张图,看一下整个过程中发生了什么,然后我再告诉你,为啥Java中只有值传递。
-
-[
][4]
-
-稍微解释下这张图,当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后hollis持有该内存的地址`0x123456`(图1)。当尝试调用pass方法,并且hollis作为实际参数传递给形式参数user的时候,会把这个地址`0x123456`交给user,这时,user也指向了这个地址(图2)。然后在pass方法内对参数进行修改的时候,即`user = new User();`,会重新开辟一块`0X456789`的内存,赋值给user。后面对user的任何修改都不会改变内存`0X123456`的内容(图3)。
-
-上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在`user=new User()`的时候,实际参数的引用也应该改为指向`0X456789`,但是实际上并没有。
-
-通过概念我们也能知道,这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,**上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。**
-
-我们再来回顾下之前的那个“砸电视”的例子,看那个例子中的传递过程发生了什么。
+过程如下:
[
][5]
@@ -188,10 +97,6 @@ print in main , user is User{name='Hollis', gender='Male'}
所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。在判断实参内容有没有受影响的时候,要看传的的是什么,如果你传递的是个地址,那么就看这个地址的变化会不会有影响,而不是看地址指向的对象的变化。就像钥匙和房子的关系。
-那么,既然这样,为啥上面同样是传递对象,传递的String对象和User对象的表现结果不一样呢?我们在pass方法中使用`name = "hollischuang";`试着去更改name的值,阴差阳错的直接改变了name的引用的地址。因为这段代码,会new一个String,在把引用交给name,即等价于`name = new String("hollischuang");`。而原来的那个"Hollis"字符串还是由实参持有着的,所以,并没有修改到实际参数的值。
-
-[
][6]
-
**所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。**
### 总结
diff --git a/docs/contact/wechat-hollis.jpg b/docs/contact/wechat-hollis.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4457b5399012f29e8df1a2b35b5a446d12e9f123
GIT binary patch
literal 8333
zcmdUUdpOkV*Y`aJpN;6e$Vf@uIGKP>;2=Mnx>ig&iB68TA%ee9$4g1$v0cN}$KZP;
zts*mLk+H4pT=yM>#Wa#hbkb!x-L=J4sva#vdZzxNG4cxY=Bue|ELo~=V7Sa|<*L=@
z7MAP&WoN(M!O_Xn%iG6y(`LV&0YB{u3<};I7JlI1p@_qgvByuGj63xUGdbmK>bbP@
z7t*g}W#{DPUCl4JSyEb7e(Uy~yT3oEuBol7Z)j|7d(z&~`SjWIH*dRp-o5Yb>mL{%
z866w{{AFTt3bPA`@H1w?zcYsYn_Vhkmz1%pzmiIkxVE9kjWN
zO`_#UYm+V)SIO&|dJL)hhqfrp(=&UsWEe9|V%h)Bu$ccV%lje&)#pb$@OH&53Ga6?MLx=Y2KcEw
z_IqwBli-I$`KSHQ&Y_rRsdL_K&q#;&4LWm~lxLiG0h$`3{9z_?uGZW+oI_a5P0i>W
z-zaN<^rcd0`f7q;2iT1TTY2ETW@{_)Y$-b4#EYDWwS)fs0K0^tTKvD9`$(z`y3CPX({7&4XD?6U$-cuii-&@6
zjx`XL?cjnx(!FPHivn8WHE`hCi@}e>C<<$QFlIPd%!I!paE;Ma-r&qPs)B2u
zIRoI(s3*wXj)W6>`Hpb4
zpWMW!AoZ0(&wUoPMw6Qfvhf(Oowl$tf2A8mXqCZYDik#mD*GS9i=*)E@J0VE=3u=W
z?(0+P5V)LM5K5yqR!M_v-63zZPiUWjAB}-0Cfq0B!;LO7bR+Xx0|Ft(&_V!c%UO7B
zaudXErJ(SP9bDSe70{Ao+jD^PF60Jy*5i{_DL!dqops3MR%
zgB0!d@89q#7Np2!{}*y^f7I5*czLEPP+LlTJcOCVLu*=Sb!
z3R}*=`4LNzx1fl1={7(xO@|mnSe$O}Fy%XPE2*C%-@z?7%6nOAyTQElor8hUnniHHp4z-ax{Nhk#nuvn!n4K?Q9c&MmTjqid_Nd1e5WNAP{
z#WiM{8e5Zta1Ug;1;%YT-&;a>I{pM9083NDGzDC1E(s_NTN-R^cJ&LgE_Ts{NWEvw
z=lX3t0$FJ3!IN6Ot~Qw6IZ{egqI*r$Abg)e-3_3zamm(?C>VeEYKH%Q8q>YLpW0Xn
zNQ`D8zrTCqj3tj~r~AF@wr`mUNKuytcUz8e2F?(V2r)!k2VpVrNC?6MqN(jRk&+OV
zI+!6AVE90;%J>WhwA+o%C9Zcn-0$>EmxOqxKnWNl$40ltghskaxl`LM%m*nJfS|@2
zRp2=6mF^|vPj0G$-NjM}Ga26uIT~XOzOY*a8-IN4s&u3q4wkl-&{=N18JY`Z?f}~w
z8_SJ;0_iU(3U8u&!%|pU;epD14EXkj>q!VlZC_!L+r^?g?T1tg=e!GSWvtJkdtIcx
zV$3%Otm^q^5bdpl^B~RsXY%pt!P~De3|0oz`7pZsLZ-5}#l{~4=rqX2ga!e7TU!Tb
zT_^j|pppavF?h^vHoL~7O}2JJ+~%fG6bRPv8_yIMKBOriJ5%fT_#?nH25gyyk)7iX
zc^O9z^R6_LW648(h
zbqdk|*@K@tFMk0#G*nkJ+wO*U%=^K%)}XQ$)
z6S(sT5APC|h*gA6fx%-XNg@6ZWD_+mDLpRVScP>qPajM8trDUSR_}e0LpKT-ZDq`!
z1(YBMsN5gvS;8`YjZs-ea4@^eBNhwM47XRRa|SZBe`iQhFiPoAw-6dlZqa9*MYtFf
zbIvu9lo(Z+-8U5+9THyW2Ig&!*kXIn)#UkfwWpOUqVxHHfi+OK%+tT-BPUwdIO^e4$*piNnRS<48old#+<7;#|ltxvYpi
zJ5w(+<+j#Rcg}wFXoc$|Iec{VYcm`#Z}Fwg+^6#{HPwk^Hi%J;2YtupUhRJJgz67s
zq)O2Uk2f(g3tAN@ilPsFPZcdo6RAv-rw)rzt>ZcM?W}c+*4FL5S==yPEoEY_yc>zOVHAN+qDE^E
zd596?xoai)`Oj`8L&8EI4I(#K>sD}}Ebp9X=UoRT8!`2M{d~1gZpyb&x@U|njb94f
z-D|db-DAV7#9CmH-@zVnSbiC>z`#-XTT6-W<=
zx*)8w-?@2@=P60ACR2B`bKI%Ipw~LZaTa@T
zT|VY(CEQ)#6V9n^o>-n#SNB?~TXZ5xjB-3XdpGkT4r_oEL&`&@a&&cN89=&?Pt^yh
z?P~q4X%#@XK{!e;G&I|V5qUuKK%Vo!&>a&mn
z3byKE?$^Yq7GjS3w~CYDJ95JwN>)v1FhvKKj{HR4)4t=bXP`lm50CYzpDTIUXzF7
zhI@`W6%IM&Ne6!mW4Om%Cd5*WBkoanM;CDh&b3yt{a#Ggyjd+GUTAT@qmaDzjph$7
zjNzv6mIv!dca|K?HUZXlC*1Jo}1}6#h7eVx~-JPdjh+c5ze>ia3*`%3zPV{Nurx?A`
zvcsW|DC!FGnyj}KncFPdxF1W&Q!9h>XmcDWPtvSYG9Pu0G)8b*s1wVhb-M?nPj!n7
zXCV85ImX|p{0`DK>=l5-cifo;ZOLZqAgnGTlb{;Z)j7T)#v}{~CH49R$-IEUB|rm1
z8Vn_QSU1`az*_MU#tOO@HtfYq`sTl}&4%r*F%ATh3bbwV4Q#yGy=s70XNJCQf
z`T@`e_%TnBT;_=2*l_(qfeC%AKtUMIOECL%K`3}VwQ}GS8Hxvv+?pRmA0duOKI_A$
z3~xLAhN}^A|HX!iknB#ghd|C}cKrks>b}N2RKklvT>7Q;CYgAO*%yW4DC?Iav1(DB-=8YLd7xU|ZRjgSWwcNt~
zbFO9@K9{fHKcD{5a)W{H-OW*JFDHI?ho3RL>A^yelpaUxz4?7!4L8Q~r#Cm${p%%H
z>)N|N#@1-dL|orMy7ffh!c^VgYX9Sfim;f>OA&E(Kgw$3PTn7`%_?{})Uw3!#HWk-
zdWO=Bl=4kd*DUnawm)*zOlbdj`~Lmb>*IUZJ}Rr<^dY7(XRU$mqqEVm@uQvbT1Q&m
zG%NOt49ka?#udI;#|c_ZTdQI8aIH?}ng_FsGRC%rMiN6Dk9;gY+~Op^gg0qS-u2`B
zZeemn%A2_AtApXsoPJq!M{hw`((SwKhpPzFT9Y-$R=#n4wx&``Yv@y2h|P%|#|r(n
zoXTxywf`$^dAzB)1;J`4Y@EZ2(i2ttHCMg#cO?mCSKPT-9(I>+J9^$^c4+Q=={bZi
z3l^7(7KmQmJ(;%uu70AG@v((ZOyutHP`PjO(j
zKIgqic3=Kh<>cB>ITYFB({WFXbVS?{jIvXG*R}6Cx+Qnhz-QOHhMtd@-a12(@d?Vd
zlio$)^lGl?#X6`r9;FG@)(v{l6C{gKCwU-bGEf&<@r_)|bTPUkbl!@WDqO2|$!Kz`
zl|rDCD1Vwq7%7X7f1i#KZx1F>z{HNARGwKCRUlWs`4q7JmklKSe&njjoz{f7?hd|FxuE
z@x-XFJ=;d71TWe~9>T6Kx&FQ0u-=fZ%x^85YD^w}H+nho@VZoQ&)6>vy>2zqlD!PU
zuVNJQENu8o<&t^V6ba>%r
zM`Es{_AE=rnlP$<+l)*V-{bbuXwt7ck57@G8Oqd}fJkM(R_5L!={XSO(oI@V(0Ocf
z1hR`B%hpeU`i_TIqNlrJX&8?u)q}&@eN8cP68SW5I}3w!iyaA5b|lYQtL_(o%s`Hx
zDE}0p2w^Q-$pp{l4rhSHM7utKF2{NIGu998&1z+=fH`%uCX0KC?sbVj>Gw@)akXmY
z*w*!Kz(#WyXM~_}*~fz61*Q@hbsWi}0+COBZxJ>#hO_1NU7q_dud$UA3x?*46t)a!
zc4^0b3|HJRt*jcfiZ1{c{D<`d8NgYAD9{wVL@ucjBda#iBndb1
zT8xxSCUPURWQL-m(%?tG{oMUpKzh)tsjs4~RjjEJoeLZ;QRwC9yW5epfzKEvPHmR7P21)_J-N9)(g)
z@S~Y`lO&===SXpU=eTn^lCOj|RSmj^v7E;=&>y|BX4F+6$z&K^RE3_sf4FDTfCVez
z|FP+7O~TUME1_*}tic0CVYB@C@SN<0hC#S*w;F9d+tURdh0}~Cx(ZYRT@s)>CEDH=
zQ?ew|%6?a1ywu;Y4jBfnMqYh=Ha7Ay0$P~vRsEBl^VSXMGBy%1`31i;
zUKP|!*v#Rz1-e~1_>6Rmg^1no)XEbFJni;6{&4tc%BT83`L=kuFg;`#bg*W8b!2ath^+^{?KviJx
z2VoiX1u%niR77e6jDjZ_gM4*{tj-a7w;IeH92JsPzc6
zWG#FVDR4%L$+aS8rqYdAC(jd=)NM+^@wg->OjBbb_fDXn!@W6H@yu0;n3Pk}EYZ_k
z|B{?B>3NaP0nn@Mx3Vg(P5RZ3!Ky5vFtP$!0ra>&&>)AhhW`9;TU-(oK8^%25cULU
z^2gfHS|tO`F#&%nTkAI-z68oz!r7q+&Om%PpQ7M`jXIzx26!IqPDfk2VG2$HwX%QG
z(^Vft9&b`yj&!vBp>QxC)I4qhE!_Y?jjSSNaUk@_3d2Qgzpa|thtD6O>U;d)!o39A
z5FqIb>&Y@WCy?hs3mz0C4fa${ES5Mip
z-Ag5y8hipW>|ty2GR){JOl0u&=>mxc0~>VTnBC3z932bu8VSCj>gNxCkjRkWY*GG@
z5-3&x1a2zb3ErOGo&Xt9hAH!_aGE?>86=H&u($Ng2UTrHSLev>_0~by_@0BLyF3rg
zp}{!WG;_$3VxFVPpnYR;1FLb&v(mANutShP)f=!REH|`;<0Iplj$L`+!d)%$GD>7O
zxLyL(T2n~b#|~B=yJ9=Ay$wSfZv|$+naXa2Tg)`Tur=yf4*tL-WW893xI-0N(+$do
z1hi)~dn6K_J<`M~5jft{pPQQKCo1^Inba3mYx46;aAEdJBsNC+_w
z)64=nPEZZ=n#Z=w
zcK?x4EFu5omB+MnMXA3|Tyg|5Kyle`8KIzg_%*8m4B6Y=B)9lROvED?zT(s6;AkgJ
zIs-fm9>5L=+~lkQxCRcPs
z4_iy7`oE43|LLYYD;~!DSHQ}ne^ahQ9n@H`KV|2A7W80XhXCniQY>hz{hOJ=n
zgPiet3Twd$-OS;ScDn`8U4Z1llRrDOCp-&J?hnkNZ&p&H~9tzn
-
- Document
-
-
-
-
+
+ Document
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
--
GitLab