From d16661de62f79bbe9fc11d28ffe3b79bf03638ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E6=B5=9A?= Date: Tue, 19 Nov 2019 10:39:27 +0800 Subject: [PATCH 001/113] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E3=80=8AJava8?= =?UTF-8?q?=E6=96=B0=E7=89=B9=E6=80=A7=E7=BB=88=E6=9E=81=E6=8C=87=E5=8D=97?= =?UTF-8?q?.md=E3=80=8B=E4=B8=AD=E7=9A=84Lambda=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E5=92=8C=E5=8C=BF=E5=90=8D=E5=86=85=E9=83=A8=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E5=8C=BA=E5=88=AB=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\346\236\201\346\214\207\345\215\227.md" | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" index 8ab85ef..7cfa76b 100644 --- "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" +++ "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" @@ -171,6 +171,66 @@ Lambda是Java 8最大的卖点。它具有吸引越来越多程序员到Java平 void get(int i,String j); } +接下来看看Lambda和匿名内部类的区别 + +匿名内部类仍然是一个类,只是不需要我们显式指定类名,编译器会自动为该类取名。比如有如下形式的代码: + + public class LambdaTest { + public static void main(String[] args) { + new Thread(new Runnable() { + @Override + public void run() { + System.out.println("Hello World"); + } + }).start(); + } + } + +编译之后将会产生两个 class 文件: + + LambdaTest.class + LambdaTest$1.class + +使用 javap -c LambdaTest.class 进一步分析 LambdaTest.class 的字节码,部分结果如下: + + public static void main(java.lang.String[]); + Code: + 0: new #2 // class java/lang/Thread + 3: dup + 4: new #3 // class com/example/myapplication/lambda/LambdaTest$1 + 7: dup + 8: invokespecial #4 // Method com/example/myapplication/lambda/LambdaTest$1."":()V + 11: invokespecial #5 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V + 14: invokevirtual #6 // Method java/lang/Thread.start:()V + 17: return + +可以发现在 4: new #3 这一行创建了匿名内部类的对象。 + +而对于 Lambda表达式的实现, 接下来我们将上面的示例代码使用 Lambda 表达式实现,代码如下: + + public class LambdaTest { + public static void main(String[] args) { + new Thread(() -> System.out.println("Hello World")).start(); + } + } + +此时编译后只会产生一个文件 LambdaTest.class,再来看看通过 javap 对该文件反编译后的结果: + + public static void main(java.lang.String[]); + Code: + 0: new #2 // class java/lang/Thread + 3: dup + 4: invokedynamic #3, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; + 9: invokespecial #4 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V + 12: invokevirtual #5 // Method java/lang/Thread.start:()V + 15: return + +从上面的结果我们发现 Lambda 表达式被封装成了主类的一个私有方法,并通过 invokedynamic 指令进行调用。 + +因此,我们可以得出结论:Lambda 表达式是通过 invokedynamic 指令实现的,并且书写 Lambda 表达式不会产生新的类。 + +既然 Lambda 表达式不会创建匿名内部类,那么在 Lambda 表达式中使用 this 关键字时,其指向的是外部类的引用。 + ### 函数式接口 所谓的函数式接口就是只有一个抽象方法的接口,注意这里说的是抽象方法,因为Java8中加入了默认方法的特性,但是函数式接口是不关心接口中有没有默认方法的。 一般函数式接口可以使用@FunctionalInterface注解的形式来标注表示这是一个函数式接口,该注解标注与否对函数式接口没有实际的影响, 不过一般还是推荐使用该注解,就像使用@Override注解一样。 From 20f50daa0e4c74c6d664c5a39d4ded85fc0d9105 Mon Sep 17 00:00:00 2001 From: Gabriel <38080169+Gabriel-18@users.noreply.github.com> Date: Thu, 21 Nov 2019 12:35:05 +0800 Subject: [PATCH 002/113] Update ReadMe.md --- ReadMe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 2448856..937eb97 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -94,8 +94,8 @@ * [Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理](docs/java/collection/Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理.md) * [Java集合详解2:Queue和LinkedList](docs/java/collection/Java集合详解2:Queue和LinkedList.md) * [Java集合详解3:Iterator,fail-fast机制与比较器](docs/java/collection/Java集合详解3:Iterator,fail-fast机制与比较器.md) -* [Java集合详解5:深入理解LinkedHashMap和LRU缓存](docs/java/collection/Java集合详解4:HashMap和HashTable.md) -* [Java集合详解4:HashMap和HashTable](docs/java/collection/Java集合详解5:深入理解LinkedHashMap和LRU缓存.md) +* [Java集合详解4:HashMap和HashTable](docs/java/collection/Java集合详解4:HashMap和HashTable.md) +* [Java集合详解5:深入理解LinkedHashMap和LRU缓存](docs/java/collection/Java集合详解5:深入理解LinkedHashMap和LRU缓存.md) * [Java集合详解6:TreeMap和红黑树](docs/java/collection/Java集合详解6:TreeMap和红黑树.md) * [Java集合详解7:HashSet,TreeSet与LinkedHashSet](docs/java/collection/Java集合详解7:HashSet,TreeSet与LinkedHashSet.md) * [Java集合详解8:Java集合类细节精讲](docs/java/collection/Java集合详解8:Java集合类细节精讲.md) From f3bf13ca62bb5455cbbcb26e227560dff5bfe34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Java=E6=8A=80=E6=9C=AF=E6=B1=9F=E6=B9=96?= <362294931@qq.com> Date: Fri, 22 Nov 2019 13:12:00 +0800 Subject: [PATCH 003/113] =?UTF-8?q?Update=20=E6=8E=A2=E7=B4=A2Redis?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E4=B8=8E=E5=AE=9E=E7=8E=B01=EF=BC=9ARedis=20?= =?UTF-8?q?=E7=9A=84=E5=9F=BA=E7=A1=80=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E6=A6=82=E8=A7=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...256\347\273\223\346\236\204\346\246\202\350\247\210.md" | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" index 1da319d..81c390c 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" @@ -1,14 +1,15 @@ -本文转自互联网 +本文转自https://www.xilidou.com/2018/03/22/redis-event/ +作者:犀利豆 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +系列文章将整理于我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 From f7e91d715be83384bf68085be6941c54f233713f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Java=E6=8A=80=E6=9C=AF=E6=B1=9F=E6=B9=96?= <362294931@qq.com> Date: Fri, 22 Nov 2019 13:13:19 +0800 Subject: [PATCH 004/113] =?UTF-8?q?Update=20=E6=8E=A2=E7=B4=A2Redis?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E4=B8=8E=E5=AE=9E=E7=8E=B010=EF=BC=9ARedis?= =?UTF-8?q?=E7=9A=84=E4=BA=8B=E4=BB=B6=E9=A9=B1=E5=8A=A8=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E4=B8=8E=E5=91=BD=E4=BB=A4=E6=89=A7=E8=A1=8C=E8=BF=87=E7=A8=8B?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4\346\211\247\350\241\214\350\277\207\347\250\213.md" | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" index a5cab32..4fc881d 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" @@ -1,14 +1,15 @@ -本文转自互联网 +本文转自https://www.xilidou.com/2018/03/12/redis-data/ +作者:犀利豆 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +系列文章将整理在我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 @@ -302,4 +303,4 @@ eaMain() while(true) 的调用 aeProcessEvents()。 为什么 Redis 是一个单线程应用,却有如此高的性能? 如果你用本文提供的知识点回答这两个问题,一定会在面试官心中留下一个高大的形象。 -大家还可以阅读我的 Redis 相关的文章: \ No newline at end of file +大家还可以阅读我的 Redis 相关的文章: From 235026f6a1422045622f3648ca635bbb2d2e666d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 13:23:14 +0800 Subject: [PATCH 005/113] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E7=BC=96=E7=A0=81?= =?UTF-8?q?=C3=A3=C2=80=EF=BC=8C=E5=A2=9E=E5=8A=A0=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\345\211\221\346\214\207offer.md" | 82 ++++++++++++++++++- ...37\346\200\201\346\200\273\347\273\223.md" | 29 ++++++- ...36\347\216\260\345\216\237\347\220\206.md" | 16 ++++ ...70\345\277\203\346\246\202\345\277\265.md" | 16 +++- ...72\346\234\254\346\246\202\345\277\265.md" | 9 ++ ...22\346\216\222\347\264\242\345\274\225.md" | 9 ++ ...45\344\275\234\345\216\237\347\220\206.md" | 4 + ...06\344\270\216\345\256\236\350\267\265.md" | 34 ++++++++ ...45\351\227\250\345\256\236\350\267\265.md" | 43 ++++++++++ ...15\344\270\226\344\273\212\347\224\237.md" | 36 +++++++- ...37\345\214\226\346\212\200\346\234\257.md" | 6 +- ...347\232\204\345\237\272\347\237\263KVM.md" | 25 ++++++ ...66\346\236\204\350\256\276\350\256\241.md" | 16 +++- ...03\346\246\202\345\277\265\345\220\247.md" | 25 ++++++ ...AI\347\232\204\346\225\205\344\272\213.md" | 5 ++ ...36\350\267\265\346\200\273\347\273\223.md" | 25 +++++- ...47\350\241\214\350\277\207\347\250\213.md" | 6 +- ...60\347\241\254\347\233\230\344\270\255.md" | 10 +++ ...73\344\273\216\345\244\215\345\210\266.md" | 22 ++++- ...24\350\277\233\345\256\236\344\276\213.md" | 19 ++++- ...71\346\200\247\344\273\213\347\273\215.md" | 14 ++++ ...01\350\277\233\345\214\226\345\217\262.md" | 8 ++ ...23\346\236\204\346\246\202\350\247\210.md" | 7 ++ ...50\247\243\342\200\224\342\200\224dict.md" | 12 ++- ...350\247\243\342\200\224\342\200\224sds.md" | 20 +++++ ...247\243\342\200\224\342\200\224ziplist.md" | 11 ++- ...7\243\342\200\224\342\200\224quicklist.md" | 11 ++- ...47\243\342\200\224\342\200\224skiplist.md" | 17 +++- ...\247\243\342\200\224\342\200\224intset.md" | 16 +++- ...46\215\256\347\273\223\346\236\204robj.md" | 28 ++++++- ...40\351\231\244\347\255\226\347\225\245.md" | 4 + ...4\273\200\344\271\210\346\230\257Redis.md" | 14 +++- ...36\350\267\265\346\200\273\347\273\223.md" | 30 ++++++- ...33\346\227\245\345\277\227\344\273\254.md" | 13 ++- ...350\201\212SQL\346\263\250\345\205\245.md" | 13 +++ ...30\345\214\226\345\274\200\345\247\213.md" | 17 +++- ...13\345\212\241\344\270\216\351\224\201.md" | 39 ++++++++- ...01\347\232\204\345\205\263\347\263\273.md" | 20 ++++- ...45\344\270\216\345\256\236\350\267\265.md" | 28 ++++++- ...0\257\235MySQL\345\205\245\351\227\250.md" | 42 ++++++++++ ...2\343\200\217MySQL \345\222\214 InnoDB.md" | 30 ++++++- ...30\345\202\250\345\216\237\347\220\206.md" | 39 ++++++++- ...23\346\236\204\347\256\227\346\263\225.md" | 41 +++++++++- ...20\344\270\216\344\274\230\345\214\226.md" | 36 +++++++- ...04\351\224\201\345\256\236\347\216\260.md" | 17 +++- ...47\345\210\253\345\256\236\346\210\230.md" | 7 ++ ...\200\247\343\200\2012PC\345\222\2143PC.md" | 5 ++ ...5\237\272\347\241\2002 \357\274\232CAP.md" | 4 + ...13\344\273\266\351\241\272\345\272\217.md" | 4 + ...\237\272\347\241\2004\357\274\232Paxos.md" | 5 ++ ...76\345\222\214\347\247\237\347\272\246.md" | 4 + ...41\2006\357\274\232Raft\343\200\201Zab.md" | 5 ++ ...17\350\260\203\346\234\215\345\212\241.md" | 5 ++ ...03\345\210\260\345\205\245\351\227\250.md" | 4 + ...15\345\222\214\344\274\230\345\214\226.md" | 4 + ...06\344\270\216\345\256\236\350\267\265.md" | 23 +++++- ...44\270\200\350\207\264\346\200\247hash.md" | 15 +++- ...37\346\210\220\346\226\271\346\241\210.md" | 7 +- ...04\351\202\243\344\272\233\344\272\213.md" | 25 ++++++ ...6\210\220Redis\347\274\223\345\255\230.md" | 11 ++- ...60\347\232\204\345\245\227\350\267\257.md" | 13 ++- ...40\347\247\215\346\226\271\346\241\210.md" | 4 + ...03\345\274\217\344\272\213\345\212\241.md" | 6 +- ...43\345\206\263\346\226\271\346\241\210.md" | 16 +++- ...03\345\274\217\344\272\213\345\212\241.md" | 9 ++ ...72\346\234\254\346\246\202\345\277\265.md" | 4 + ...40\344\275\225\350\200\214\347\224\237.md" | 37 ++++++++- ...\201\257\346\212\200\346\234\257 Kafka.md" | 6 +- ...57\274\214Raft\347\256\227\346\263\225.md" | 4 + ...0\203\346\234\215\345\212\241zookeeper.md" | 6 +- ...01\347\250\213\350\257\246\350\247\243.md" | 31 +++++++ ...41\347\220\206\345\256\236\346\210\230.md" | 18 +++- ...57\345\217\212\345\256\236\350\267\265.md" | 26 +++++- ...73\346\265\201\346\226\271\346\241\210.md" | 0 ...37\347\220\206\345\211\226\346\236\220.md" | 0 ...06\344\270\216\345\256\236\350\267\265.md" | 0 ...36\350\267\265\346\200\273\347\273\223.md" | 34 +++++++- ...06\350\256\272\346\200\273\347\273\223.md" | 25 +++++- ...06\345\270\203\345\274\217\357\274\211.md" | 71 +++++++++++++++- ...33\346\200\273\347\273\223\357\274\211.md" | 17 ++++ ...31\346\235\241\350\267\257\357\274\237.md" | 10 +++ ...04\346\272\220\346\270\205\345\215\225.md" | 12 +++ ...00\345\274\240\345\233\276\357\274\201.md" | 34 ++++++++ ...17\345\244\247\345\220\210\351\233\206.md" | 19 +++++ docs/hxx/think/copy.md | 7 ++ .../2019alipay-pinduoduo-toutiao.md | 25 ++++++ ...\207\214,\347\273\210\350\216\267offer.md" | 11 +++ ...\213\277\345\217\243\345\244\264offer).md" | 8 ++ ...00\346\234\257\346\200\273\347\273\223.md" | 29 ++++++- .../JavaInterviewLibrary.md | 22 ++++- .../JavaProgrammerNeedKnow.md | 11 +++ .../PreparingForInterview/interviewPrepare.md | 15 ++++ ...02\344\275\225\345\233\236\347\255\224.md" | 13 ++- ...00\345\216\206\344\271\213\351\201\223.md" | 17 ++++ ...56\351\242\230\346\200\273\347\273\223.md" | 71 ++++++++++++++++ ...00\346\234\257\346\200\273\347\273\223.md" | 22 ++++- ...4\232SpringMVC\346\246\202\350\277\260.md" | 18 +++- ...5\277\265\344\270\216DispatcherServlet.md" | 12 ++- ...67\346\261\202\350\275\254\345\217\221.md" | 12 +++ ...\243\347\241\256\347\232\204Controller.md" | 11 ++- ...43\346\236\220\345\216\237\347\220\206.md" | 14 +++- ...6@ResponseBody\346\263\250\350\247\243.md" | 13 +++ ...\274\232Spring\346\246\202\350\277\260.md" | 9 ++ ...70\345\277\203\346\265\201\347\250\213.md" | 10 +++ ...40\350\275\275\350\277\207\347\250\213.md" | 17 +++- ...07\347\250\213\345\210\206\346\236\220.md" | 10 ++- ...37\347\220\206\350\257\246\350\247\243.md" | 18 +++- ...\232Spring AOP\346\246\202\350\277\260.md" | 12 ++- ...37\347\220\206\350\257\246\350\247\243.md" | 14 +++- ...13\345\212\241\346\246\202\350\277\260.md" | 20 ++++- ...20\347\240\201\345\211\226\346\236\220.md" | 13 ++- ...45\350\257\206\346\270\205\345\215\225.md" | 27 +++++- ...72\346\234\254\345\216\237\347\220\206.md" | 17 +++- ...JavaBean\350\256\262\345\210\260Spring.md" | 17 +++- ...0\257\225\346\241\206\346\236\266Junit.md" | 26 +++++- ...5\273\272\345\267\245\345\205\267Maven.md" | 30 ++++++- ...43\345\274\217\345\274\200\345\217\221.md" | 15 +++- ...274\232Mybatis\345\205\245\351\227\250.md" | 28 ++++++- ...\215\347\275\256\347\232\204SpringBoot.md" | 25 +++++- ...72\347\241\200\347\237\245\350\257\206.md" | 19 ++++- ...17\344\270\216\347\216\260\345\234\250.md" | 20 +++++ ...45\346\261\240\346\212\200\346\234\257.md" | 19 +++++ ...37\347\220\206\350\257\246\350\247\243.md" | 16 +++- ...67\346\261\202\350\277\207\347\250\213.md" | 10 +++ ...66\346\236\204\345\211\226\346\236\220.md" | 49 ++++++++++- ...50\347\232\204\345\214\272\345\210\253.md" | 16 +++- ...50\347\275\262\350\277\207\347\250\213.md" | 17 +++- ...37\344\270\216\345\217\221\345\261\225.md" | 22 ++++- ...13\343\200\201\346\263\233\345\236\213.md" | 2 +- ...01\346\236\232\344\270\276\347\261\273.md" | 2 +- ...73\345\222\214\346\216\245\345\217\243.md" | 23 ++++++ ...20\347\240\201\345\210\206\346\236\220.md" | 15 +++- ...\351\230\237\345\210\227 BlockingQueue.md" | 13 ++- ...20\347\240\201\345\256\236\347\216\260.md" | 15 +++- ...p \345\205\250\350\247\243\346\236\220.md" | 35 +++++++- ...7\232\204Unsafe\345\222\214Locksupport.md" | 8 ++ ...va\345\244\232\347\272\277\347\250\213.md" | 14 ++++ ...345\255\230\346\250\241\345\236\213JMM.md" | 21 ++++- ...357\274\214CAS\346\223\215\344\275\234.md" | 27 +++++- ...1\224\201 Lock\345\222\214synchronized.md" | 25 +++++- ...56\345\255\227\350\247\243\346\236\220.md" | 14 +++- ...345\236\213JMM\346\200\273\347\273\223.md" | 21 +++++ ...347\261\273AQS\350\257\246\350\247\243.md" | 12 ++- ...71\263\351\224\201\357\274\214Condtion.md" | 23 +++++- ...73\347\232\204\345\256\236\347\216\260.md" | 13 ++- ...27\346\263\225\345\211\226\346\236\220.md" | 7 ++ ...14\346\234\237\344\274\230\345\214\226.md" | 21 ++++- ...03\344\274\230\345\256\236\350\267\265.md" | 24 +++++- ...06\344\270\216\345\256\236\350\267\265.md" | 31 ++++++- ...15\344\270\216\345\256\236\346\210\230.md" | 18 +++- ...\345\217\212GC\345\256\236\350\267\265.md" | 17 +++- ...04\346\260\270\344\271\205\344\273\243.md" | 32 +++++++- ...06\345\222\214\347\256\227\346\263\225.md" | 35 +++++++- ...66\345\231\250\350\257\246\350\247\243.md" | 32 +++++++- ...43\346\236\220\345\256\236\350\267\265.md" | 15 ++++ ...47\350\241\214\345\274\225\346\223\216.md" | 21 ++++- ...40\350\275\275\346\234\272\345\210\266.md" | 20 ++++- ...75\345\231\250\345\256\236\347\216\260.md" | 17 +++- ...12\346\226\255\345\256\236\350\267\265.md" | 23 +++++- ...70\347\224\250\345\267\245\345\205\267.md" | 10 ++- ...347\232\204NIO\346\250\241\345\236\213.md" | 14 +++- ...346\236\220\357\274\210NIO\357\274\211.md" | 15 +++- ...67\346\261\202\346\250\241\345\236\213.md" | 27 +++++- ...3\200\201Channel \345\222\214 Selector.md" | 20 ++++- ...6\236\220mmap\345\222\214Direct Buffer.md" | 28 ++++++- ...32\344\277\241\346\234\272\345\210\266.md" | 17 +++- ...26\347\250\213\346\250\241\345\236\213.md" | 17 ++++ ...345\222\214\345\274\202\346\255\245 IO.md" | 16 +++- ...37\347\220\206\350\257\246\350\247\243.md" | 17 +++- ...36\347\216\260\345\216\237\347\220\206.md" | 20 ++++- ...7\250\213\346\241\206\346\236\266Netty.md" | 21 ++++- ...46\344\271\240\346\200\273\347\273\223.md" | 53 +++++++++++- ...46\344\271\240\346\200\273\347\273\223.md" | 69 +++++++++++++++- ...46\344\271\240\346\200\273\347\273\223.md" | 30 ++++++- .../\347\224\265\345\255\220\344\271\246.md" | 25 ++++++ src/main/java/md/mdToc.java | 2 +- 176 files changed, 3206 insertions(+), 112 deletions(-) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" (95%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" (99%) rename "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" => "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" (97%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" (96%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" (98%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" (97%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" (98%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" (96%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" (87%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" (96%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" (96%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" (99%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" (89%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" (95%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" (96%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" (100%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" (100%) rename "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" => "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" (100%) diff --git "a/docs/algorithms/\345\211\221\346\214\207offer.md" "b/docs/algorithms/\345\211\221\346\214\207offer.md" index 9b2be5b..a4f7aca 100644 --- "a/docs/algorithms/\345\211\221\346\214\207offer.md" +++ "b/docs/algorithms/\345\211\221\346\214\207offer.md" @@ -1,3 +1,83 @@ +# Table of Contents + +* [数论和数字规律](#数论和数字规律) + * [从1到n整数中1出现的次数](#从1到n整数中1出现的次数) + * [排数组排成最小的数](#排数组排成最小的数) + * [丑数](#丑数) +* [数组和矩阵](#数组和矩阵) + * [二维数组的查找](#二维数组的查找) + * [顺时针打印矩阵。](#顺时针打印矩阵。) + * [调整数组中数字的顺序,使正数在负数的前面](#调整数组中数字的顺序,使正数在负数的前面) + * [数组中出现次数超过一半的数字](#数组中出现次数超过一半的数字) + * [找出前k小的数](#找出前k小的数) + * [连续子数组的最大和](#连续子数组的最大和) + * [逆序对](#逆序对) + * [数字在排序数组中出现的次数](#数字在排序数组中出现的次数) + * [和为s的两个整数,和为s的连续正数序列](#和为s的两个整数,和为s的连续正数序列) + * [n个色子的点数](#n个色子的点数) + * [扑克牌的顺子](#扑克牌的顺子) + * [数组中重复的数字](#数组中重复的数字) + * [数组中重复的数字](#数组中重复的数字-1) + * [构建乘积数组](#构建乘积数组) + * [数据流的中位数](#数据流的中位数) + * [滑动窗口中的最大值](#滑动窗口中的最大值) +* [字符串](#字符串) + * [字符串的排列](#字符串的排列) + * [替换空格](#替换空格) + * [第一次只出现一次的字符](#第一次只出现一次的字符) + * [翻转单词顺序和左旋转字符串](#翻转单词顺序和左旋转字符串) + * [把字符串转换为整数](#把字符串转换为整数) + * [表示数值的字符串](#表示数值的字符串) + * [字符流中第一个不重复的字符](#字符流中第一个不重复的字符) +* [链表](#链表) + * [从尾到头打印链表](#从尾到头打印链表) + * [链表倒数第k个节点](#链表倒数第k个节点) + * [反转链表](#反转链表) + * [合并两个排序链表](#合并两个排序链表) + * [复杂链表的复制](#复杂链表的复制) + * [两个链表的第一个公共节点](#两个链表的第一个公共节点) + * [孩子们的游戏(圆圈中最后剩下的数)](#孩子们的游戏圆圈中最后剩下的数) + * [链表的环的入口结点](#链表的环的入口结点) + * [删除链表中重复的节点](#删除链表中重复的节点) + * [](#) + * [二叉搜索树转换为双向链表](#二叉搜索树转换为双向链表) + * [重建二叉树](#重建二叉树) + * [树的子结构](#树的子结构) + * [镜像二叉树](#镜像二叉树) + * [树的层次遍历](#树的层次遍历) + * [二叉树的深度](#二叉树的深度) + * [判断是否平衡二叉树](#判断是否平衡二叉树) + * [二叉搜索树的后序遍历](#二叉搜索树的后序遍历) + * [二叉树中和为某一值的路径](#二叉树中和为某一值的路径) + * [二叉树的下一个节点](#二叉树的下一个节点) + * [对称的二叉树](#对称的二叉树) + * [把二叉树打印成多行](#把二叉树打印成多行) + * [按之字形顺序打印二叉树](#按之字形顺序打印二叉树) + * [序列化和反序列化二叉树](#序列化和反序列化二叉树) + * [二叉搜索树的第k个结点](#二叉搜索树的第k个结点) +* [栈和队列](#栈和队列) + * [用两个队列实现栈,用两个栈实现队列。](#用两个队列实现栈,用两个栈实现队列。) + * [包含min函数的栈](#包含min函数的栈) + * [栈的压入和弹出序列](#栈的压入和弹出序列) +* [排序和查找](#排序和查找) + * [旋转数组的最小数字](#旋转数组的最小数字) +* [递归](#递归) + * [斐波那契数列](#斐波那契数列) + * [青蛙跳台阶](#青蛙跳台阶) + * [变态跳台阶](#变态跳台阶) + * [矩形覆盖](#矩形覆盖) +* [位运算](#位运算) + * [二进制中1的个数](#二进制中1的个数) + * [数组中只出现一次的数字](#数组中只出现一次的数字) + * [不用加减乘除做加法](#不用加减乘除做加法) +* [回溯和DFS](#回溯和dfs) + * [矩阵中的路径](#矩阵中的路径) + * [机器人的运动范围](#机器人的运动范围) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 点击关注[公众号](#公众号)及时获取笔主最新更新文章,并可免费领取Java工程师必备学习资源。 [TOC] @@ -1651,4 +1731,4 @@ public static int LastRemaining_Solution(int n, int m) { **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/big-backEnd/Hadoop\347\224\237\346\200\201\346\200\273\347\273\223.md" "b/docs/big-backEnd/Hadoop\347\224\237\346\200\201\346\200\273\347\273\223.md" index 1811472..0dbb50d 100644 --- "a/docs/big-backEnd/Hadoop\347\224\237\346\200\201\346\200\273\347\273\223.md" +++ "b/docs/big-backEnd/Hadoop\347\224\237\346\200\201\346\200\273\347\273\223.md" @@ -1,3 +1,30 @@ +# Table of Contents + +* [Hadoop生态](#hadoop生态) + * [hdfs](#hdfs) + * [架构](#架构) + * [读写](#读写) + * [高可用](#高可用) + * [MapReduce](#mapreduce) + * [架构和流程](#架构和流程) + * [wordcount](#wordcount) + * [hive](#hive) + * [hbase](#hbase) + * [简介](#简介) + * [存储](#存储) + * [zk](#zk) + * [sqoop](#sqoop) + * [yarn](#yarn) + * [kafka](#kafka) + * [flume](#flume) + * [ambari](#ambari) + * [spark](#spark) + * [storm](#storm) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: Hadoop生态学习总结 date: 2018-07-08 22:15:53 @@ -264,4 +291,4 @@ spout负责获取数据,并且将数据发送给bolt,这个过程就是把 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" index dc6207e..e4df0f1 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" @@ -1,3 +1,19 @@ +# Table of Contents + + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#namespaces)Namespaces](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoionamespacesnamespaces) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E8%BF%9B%E7%A8%8B)进程](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe8bf9be7a88b进程) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E7%BD%91%E7%BB%9C)网络](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe7bd91e7bb9c网络) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#libnetwork)libnetwork](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiolibnetworklibnetwork) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%8C%82%E8%BD%BD%E7%82%B9)挂载点](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe68c82e8bdbde782b9挂载点) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#chroot)chroot
](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiochrootchroot
) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#cgroups)CGroups](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiocgroupscgroups) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#unionfs)UnionFS](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiounionfsunionfs) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A8)存储驱动](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe5ad98e582a8e9a9b1e58aa8存储驱动) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#aufs)AUFS](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioaufsaufs) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E5%85%B6%E4%BB%96%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A8)其他存储驱动](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe585b6e4bb96e5ad98e582a8e9a9b1e58aa8其他存储驱动) + * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%80%BB%E7%BB%93)总结](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe680bbe7bb93总结) + + diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" index cda0102..72a42f0 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" @@ -1,3 +1,17 @@ +# Table of Contents + +* [十分钟带你理解Kubernetes核心概念](#十分钟带你理解kubernetes核心概念) + * [什么是Kubernetes?](#什么是kubernetes?) + * [集群](#集群) + * [Pod](#pod) + * [Lable](#lable) + * [Replication Controller](#replication-controller) + * [Service](#service) + * [Node](#node) + * [Kubernetes Master](#kubernetes-master) + * [下一步](#下一步) + + # 十分钟带你理解Kubernetes核心概念 本文将会简单介绍[Kubernetes](http://kubernetes.io/v1.1/docs/whatisk8s.html)的核心概念。因为这些定义可以在Kubernetes的文档中找到,所以文章也会避免用大段的枯燥的文字介绍。相反,我们会使用一些图表(其中一些是动画)和示例来解释这些概念。我们发现一些概念(比如Service)如果没有图表的辅助就很难全面地理解。在合适的地方我们也会提供Kubernetes文档的链接以便读者深入学习。 @@ -138,4 +152,4 @@ _如果Pods是短暂的,那么重启时IP地址可能会改变,怎么才能 **原文链接:[Learn the Kubernetes Key Concepts in 10 Minutes](http://omerio.com/2015/12/18/learn-the-kubernetes-key-concepts-in-10-minutes/)(翻译:崔婧雯)** =========================== 译者介绍 -崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。 \ No newline at end of file +崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" index 61f5906..99715ed 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [0x00 前言](#0x00-前言) + * [0x01 数据?数据!](#0x01-数据?数据!) + * [0x02 概览](#0x02-概览) + * [0x03 关于内容](#0x03-关于内容) + * [0xFF 总结](#0xff-总结) + + 作者:[**木东居士**] 个人主页:[http://www.mdjs.info](https://link.jianshu.com/?t=http%3A%2F%2Fwww.mdjs.info) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" index ec82cbe..604a0c2 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" @@ -1,3 +1,12 @@ +# Table of Contents + +* [[什么是倒排索引?](https://www.cnblogs.com/zlslch/p/6440114.html)](#[什么是倒排索引?]httpswwwcnblogscomzlslchp6440114html) + * [1.单词——文档矩阵](#1单词文档矩阵) + * [2.倒排索引基本概念](#2倒排索引基本概念) + * [3.倒排索引简单实例](#3倒排索引简单实例) + * [4\. 单词词典](#4-单词词典) + + # [什么是倒排索引?](https://www.cnblogs.com/zlslch/p/6440114.html) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" index 9e49ab7..090c652 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文作者:顿炖 链接:https://www.zhihu.com/question/19937854/answer/98791215 来源:知乎 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" index 35b1e35..539b237 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" @@ -1,3 +1,37 @@ +# Table of Contents + + * [二、索引里面究竟存些什么](#二、索引里面究竟存些什么) + * [三、如何创建索引](#三、如何创建索引) + * [第一步:一些要索引的原文档(Document)。](#第一步:一些要索引的原文档document。) + * [第二步:将原文档传给分次组件(Tokenizer)。](#第二步:将原文档传给分次组件tokenizer。) + * [第三步:将得到的词元(Token)传给语言处理组件(Linguistic Processor)。](#第三步:将得到的词元token传给语言处理组件linguistic-processor。) + * [第四步:将得到的词(Term)传给索引组件(Indexer)。](#第四步:将得到的词term传给索引组件indexer。) + * [三、如何对索引进行搜索?](#三、如何对索引进行搜索?) + * [第一步:用户输入查询语句。](#第一步:用户输入查询语句。) + * [第二步:对查询语句进行词法分析,语法分析,及语言处理。](#第二步:对查询语句进行词法分析,语法分析,及语言处理。) + * [第三步:搜索索引,得到符合语法树的文档。](#第三步:搜索索引,得到符合语法树的文档。) + * [第四步:根据得到的文档和查询语句的相关性,对结果进行排序。](#第四步:根据得到的文档和查询语句的相关性,对结果进行排序。) + * [1\. 计算权重(Term weight)的过程。](#1-计算权重term-weight的过程。) + * [2\. 判断Term之间的关系从而得到文档相关性的过程,也即向量空间模型的算法(VSM)。](#2-判断term之间的关系从而得到文档相关性的过程,也即向量空间模型的算法vsm。) +* [Spring Boot 中使用 Java API 调用 lucene](#spring-boot-中使用-java-api-调用-lucene) +* [Github 代码](#github-代码) + * [添加依赖](#添加依赖) + * [配置 lucene](#配置-lucene) + * [创建索引](#创建索引) + * [删除文档](#删除文档) + * [更新文档](#更新文档) + * [按词条搜索](#按词条搜索) + * [多条件查询](#多条件查询) + * [匹配前缀](#匹配前缀) + * [短语搜索](#短语搜索) + * [相近词语搜索](#相近词语搜索) + * [通配符搜索](#通配符搜索) + * [分词查询](#分词查询) + * [多个 Field 分词查询](#多个-field-分词查询) + * [中文分词器](#中文分词器) + * [高亮处理](#高亮处理) + + diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" index d23a442..8bf2dcb 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" @@ -1,3 +1,46 @@ +# Table of Contents + +* [阮一峰:全文搜索引擎 Elasticsearch 入门教程](#阮一峰:全文搜索引擎-elasticsearch-入门教程) + * [一、安装](#一、安装) + * [二、基本概念](#二、基本概念) + * [2.1 Node 与 Cluster](#21-node-与-cluster) + * [2.2 Index](#22-index) + * [2.3 Document](#23-document) + * [2.4 Type](#24-type) + * [三、新建和删除 Index](#三、新建和删除-index) + * [四、中文分词设置](#四、中文分词设置) + * [五、数据操作](#五、数据操作) + * [5.1 新增记录](#51-新增记录) + * [5.2 查看记录](#52-查看记录) + * [5.3 删除记录](#53-删除记录) + * [5.4 更新记录](#54-更新记录) + * [六、数据查询](#六、数据查询) + * [6.1 返回所有记录](#61-返回所有记录) + * [6.2 全文搜索](#62-全文搜索) + * [6.3 逻辑运算](#63-逻辑运算) + * [七、参考链接](#七、参考链接) + * [一、前言](#一、前言) + * [二、安装](#二、安装) + * [三、创建索引](#三、创建索引) + * [四、搜索干预](#四、搜索干预) + * [五、中文分词](#五、中文分词) + * [六、总结](#六、总结) + * [七、附录](#七、附录) +* [搜索引擎选型整理:Elasticsearch vs Solr](#搜索引擎选型整理:elasticsearch-vs-solr) + * [Elasticsearch简介[*](https://link.juejin.im/?target=http%3A%2F%2Ffuxiaopang.gitbooks.io%2Flearnelasticsearch)](#elasticsearch简介[]httpslinkjuejinimtargethttp3a2f2ffuxiaopanggitbooksio2flearnelasticsearch) + * [Elasticsearch的优缺点[*](https://link.juejin.im/?target=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F10213009%2Fsolr-vs-elasticsearch)[*](https://link.juejin.im/?target=http%3A%2F%2Fhuangx.in%2F22%2Ftranslation-solr-vs-elasticsearch):](#elasticsearch的优缺点[]httpslinkjuejinimtargethttp3a2f2fstackoverflowcom2fquestions2f102130092fsolr-vs-elasticsearch[]httpslinkjuejinimtargethttp3a2f2fhuangxin2f222ftranslation-solr-vs-elasticsearch) + * [优点](#优点) + * [缺点](#缺点) + * [Solr简介[*](https://link.juejin.im/?target=http%3A%2F%2Fzh.wikipedia.org%2Fwiki%2FSolr)](#solr简介[]httpslinkjuejinimtargethttp3a2f2fzhwikipediaorg2fwiki2fsolr) + * [Solr的优缺点](#solr的优缺点) + * [优点](#优点-1) + * [缺点](#缺点-1) + * [Elasticsearch与Solr的比较[*](https://link.juejin.im/?target=http%3A%2F%2Fblog.socialcast.com%2Frealtime-search-solr-vs-elasticsearch%2F)](#elasticsearch与solr的比较[]httpslinkjuejinimtargethttp3a2f2fblogsocialcastcom2frealtime-search-solr-vs-elasticsearch2f) + * [实际生产环境测试[*](https://link.juejin.im/?target=http%3A%2F%2Fblog.socialcast.com%2Frealtime-search-solr-vs-elasticsearch%2F)](#实际生产环境测试[]httpslinkjuejinimtargethttp3a2f2fblogsocialcastcom2frealtime-search-solr-vs-elasticsearch2f) + * [Elasticsearch 与 Solr 的比较总结](#elasticsearch-与-solr-的比较总结) + * [其他基于Lucene的开源搜索引擎解决方案[*](https://link.juejin.im/?target=http%3A%2F%2Fmail-archives.apache.org%2Fmod_mbox%2Fhbase-user%2F201006.mbox%2F%253C149150.78881.qm%40web50304.mail.re2.yahoo.com%253E)](#其他基于lucene的开源搜索引擎解决方案[]httpslinkjuejinimtargethttp3a2f2fmail-archivesapacheorg2fmod_mbox2fhbase-user2f201006mbox2f253c14915078881qm40web50304mailre2yahoocom253e) + + # 阮一峰:全文搜索引擎 Elasticsearch 入门教程 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" index e6bd69e..03ea6fe 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" @@ -1,3 +1,37 @@ +# Table of Contents + +* [云计算概述](#云计算概述) +* [云计算发展脉络](#云计算发展脉络) + * [第一阶段:合,即物理设备](#第一阶段:合,即物理设备) + * [物理设备简介](#物理设备简介) + * [物理设备的缺点](#物理设备的缺点) + * [第二阶段:分,即虚拟化](#第二阶段:分,即虚拟化) + * [虚拟化简介](#虚拟化简介) + * [虚拟化解决的问题](#虚拟化解决的问题) + * [虚拟化时代的生态](#虚拟化时代的生态) + * [虚拟化的缺点](#虚拟化的缺点) + * [第三阶段:合,即云计算](#第三阶段:合,即云计算) + * [云计算解决的问题](#云计算解决的问题) + * [私有云、公有云的两极分化](#私有云、公有云的两极分化) + * [私有云厂商与公有云厂商的联系与区别](#私有云厂商与公有云厂商的联系与区别) + * [公有云生态及老二的逆袭](#公有云生态及老二的逆袭) + * [OpenStack的组件](#openstack的组件) + * [OpenStack带来私有云市场的红海](#openstack带来私有云市场的红海) + * [公有or私有?[网易云](https://www.163yun.com/product-cloudcompute?tag=M_smf_1190000008091499)的选择](#公有or私有?[网易云]httpswww163yuncomproduct-cloudcomputetagm_smf_1190000008091499的选择) + * [第四阶段:分,即容器](#第四阶段:分,即容器) + * [现在来谈谈,应用层面,即PaaS层。](#现在来谈谈,应用层面,即paas层。) + * [1\. PaaS的定义与作用](#1-paas的定义与作用) + * [2\. PaaS的优点](#2-paas的优点) + * [3\. PaaS部署的问题](#3-paas部署的问题) + * [容器的诞生](#容器的诞生) + * [1\. 容器的定义](#1-容器的定义) + * [2.容器在开发中的应用](#2容器在开发中的应用) + * [容器的诞生](#容器的诞生-1) + * [容器管理平台](#容器管理平台) + * [容器初体验](#容器初体验) + * [容器管理平台初体验](#容器管理平台初体验) + + **作者简介:**刘超,[网易云](https://www.163yun.com/product-cloudcompute?tag=M_smf_1190000008091499)解决方案首席架构师。10年云计算领域研发及架构经验,Open DC/OS贡献者。长期专注于kubernetes, OpenStack、Hadoop、Docker、Lucene、Mesos等开源软件的企业级应用及产品化。曾出版《Lucene应用开发揭秘》。 **以下为正文:** @@ -306,4 +340,4 @@ N个Pod如果对外散兵作战,一是无法合力,二是给人很乱的感 作者:网易云基础服务 链接:https://www.jianshu.com/p/52312b1eb633 來源:简书 -简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 \ No newline at end of file +简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" index 0a695c9..42c16df 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 内核,是指的操作系统内核。 所有的操作系统都有内核,无论是Windows还是Linux,都管理着三个重要的资源:计算,网络,存储。 @@ -94,4 +98,4 @@ 如果您想更技术的了解本文背后的原理,请看书《系统虚拟化——原理与实现》 -![](https://img-blog.csdn.net/20180306202439418) \ No newline at end of file +![](https://img-blog.csdn.net/20180306202439418) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" index a749567..9a3e91c 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" @@ -1,3 +1,28 @@ +# Table of Contents + +* [[Qemu,KVM,Virsh傻傻的分不清](https://www.cnblogs.com/popsuper1982/p/8522535.html)](#[qemu,kvm,virsh傻傻的分不清]httpswwwcnblogscompopsuper1982p8522535html) + * [ Kvm虚拟化技术实践](# kvm虚拟化技术实践) + * [VMware虚拟机支持Kvm虚拟化技术?](#vmware虚拟机支持kvm虚拟化技术?) + * [安装Kvm虚拟化软件](#安装kvm虚拟化软件) +* [ifconfig virbr0virbr0 Link encap:Ethernet HWaddr 52:54:00:D7:23:AD inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)](#ifconfig-virbr0virbr0----link-encapethernet--hwaddr-525400d723ad------------inet-addr1921681221--bcast192168122255--mask2552552550----------up-broadcast-running-multicast--mtu1500--metric1----------rx-packets0-errors0-dropped0-overruns0-frame0----------tx-packets0-errors0-dropped0-overruns0-carrier0----------collisions0-txqueuelen0-----------rx-bytes0-00-b--tx-bytes0-00-b) +* [brctl showbridge name bridge id STP enabled interfacesvirbr0 8000.525400d723ad yes virbr0-nic](#brctl-showbridge-name-----bridge-id---------------stp-enabled-----interfacesvirbr0----------8000525400d723ad-------yes-------------virbr0-nic) +* [iptables -nvL -t natChain PREROUTING (policy ACCEPT 304 packets, 38526 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 7 packets, 483 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24 Chain OUTPUT (policy ACCEPT 7 packets, 483 bytes) pkts bytes target prot opt in out source destination](#iptables--nvl--t-natchain-prerouting-policy-accept-304-packets-38526-bytes-pkts-bytes-target-----prot-opt-in-----out-----source---------------destination----------chain-postrouting-policy-accept-7-packets-483-bytes-pkts-bytes-target-----prot-opt-in-----out-----source---------------destination-------------0-----0-masquerade--tcp-------------------192168122024----192168122024----masq-ports-1024-65535-----0-----0-masquerade--udp-------------------192168122024----192168122024----masq-ports-1024-65535-----0-----0-masquerade--all-------------------192168122024----192168122024-----chain-output-policy-accept-7-packets-483-bytes-pkts-bytes-target-----prot-opt-in-----out-----source---------------destination) + * [kvm创建虚拟机](#kvm创建虚拟机) +* [netstat -ntlp|grep 5900tcp 0 0 0.0.0.0:5900 0.0.0.0:* LISTEN 2504/qemu-kvm](#netstat--ntlpgrep-5900tcp--------0------0-00005900----------------0000-------------------listen------2504qemu-kvm) + * [虚拟机远程管理软件](#虚拟机远程管理软件) + * [KVM虚拟机管理](#kvm虚拟机管理) + * [libvirt虚拟机配置文件](#libvirt虚拟机配置文件) +* [lltotal 8-rw-------. 1 root root 3047 Oct 19 2016 Centos-6.6-x68_64.xmldrwx------. 3 root root 4096 Oct 17 2016 networks](#lltotal-8-rw--------1-root-root-3047-oct-19--2016-centos-66-x68_64xmldrwx-------3-root-root-4096-oct-17--2016-networks) + * [监控kvm虚拟机](#监控kvm虚拟机) + * [KVM修改NAT模式为桥接[案例]](#kvm修改nat模式为桥接[案例]) +* [virsh edit Centos-6.6-x68_64 # 命令 52 53 54 55 56 修改为:52 53 54 55 56 ](#virsh-edit-centos-66-x68_64---命令-52-----interface-typenetwork-----53-------mac-address5254002a2d60-----54-------source-networkdefault-----55------------56-----interface-修改为:52-----interface-typebridge-----53-------mac-address5254002a2d60-----54-------source-bridgebr0-----55------------56-----interface) +* [brctl showbridge name bridge id STP enabled interfacesbr0 8000.000c29f824c9 no eth0virbr0 8000.525400353d8e yes virbr0-nic](#brctl-showbridge-name-----bridge-id---------------stp-enabled-----interfacesbr0-------------8000000c29f824c9-------no--------------eth0virbr0----------8000525400353d8e-------yes-------------virbr0-nic) +* [virsh start CentOS-6.6-x86_64Domain CentOS-6.6-x86_64 started # brctl show bridge name bridge id STP enabled interfacesbr0 8000.000c29f824c9 no eth0 vnet0virbr0 8000.525400353d8e yes virbr0-nic](#virsh-start-centos-66-x86_64domain-centos-66-x86_64-started--brctl-show-------------------bridge-name-----bridge-id---------------stp-enabled-----interfacesbr0-------------8000000c29f824c9-------no--------------eth0--------------------------------------------------------vnet0virbr0----------8000525400353d8e-------yes-------------virbr0-nic) +* [ifup eth0](#ifup-eth0) +* [ssh 192.168.2.108root@192.168.2.108's password: Last login: Sat Jan 30 12:40:28 2016](#ssh-1921682108root1921682108s-password-last-login-sat-jan-30-124028-2016) + * [总结](#总结) + + # [Qemu,KVM,Virsh傻傻的分不清](https://www.cnblogs.com/popsuper1982/p/8522535.html) 原创文章,转载请注明: 转载自[Itweet](https://link.juejin.im/?target=http%3A%2F%2Fwww.itweet.cn)的博客 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" index 154a8c8..6b248f2 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [openstack 逻辑架构图](#openstack-逻辑架构图) + * [OpenStack 项目和组件](#openstack-项目和组件) + * [生产部署架构](#生产部署架构) + * [控制器](#控制器) + * [计算](#计算) + * [块设备存储](#块设备存储) + * [对象存储](#对象存储) + * [网络](#网络) + * [涉及的 Linux 网络技术](#涉及的-linux-网络技术) + * [总结](#总结) + + OpenStack 是开源云计算平台,支持多种虚拟化环境,并且其服务组件都提供了 API接口 便于二次开发。 OpenStack通过各种补充服务提供基础设施即服务 Infrastructure-as-a-Service (IaaS)`的解决方案。每个服务都提供便于集成的应用程序接口`Application Programming Interface (API)。 @@ -164,4 +178,4 @@ Neutron 的设计目标是实现“网络即服务”,为了达到这一目标 ### 总结 -openstack是一个非法复杂的分布式软件,涉及到很多底层技术,我自己对一些网络的理解也是非常有限,主要还是应用层面的知识,所以本章内容写的比较浅显一些,有问题请留言?在下一章节我们会进入生产环境如何实施规划openstack集群,至于openstack底层的技术,我也没有很深入研究,如果有任何不恰当的地方可以进行留言,非常感谢! \ No newline at end of file +openstack是一个非法复杂的分布式软件,涉及到很多底层技术,我自己对一些网络的理解也是非常有限,主要还是应用层面的知识,所以本章内容写的比较浅显一些,有问题请留言?在下一章节我们会进入生产环境如何实施规划openstack集群,至于openstack底层的技术,我也没有很深入研究,如果有任何不恰当的地方可以进行留言,非常感谢! diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" index 9572f7d..05c9368 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" @@ -1,3 +1,28 @@ +# Table of Contents + +* [可能是把Docker的概念讲的最清楚的一篇文章](#可能是把docker的概念讲的最清楚的一篇文章) + * [一 先从认识容器开始](#一-先从认识容器开始) + * [1.1 什么是容器?](#11-什么是容器?) + * [先来看看容器较为官方的解释](#先来看看容器较为官方的解释) + * [再来看看容器较为通俗的解释](#再来看看容器较为通俗的解释) + * [1.2 图解物理机、虚拟机与容器](#12-图解物理机、虚拟机与容器) + * [二 再来谈谈Docker的一些概念](#二-再来谈谈docker的一些概念) + * [2.1 什么是Docker?](#21-什么是docker?) + * [2.2 Docker思想](#22-docker思想) + * [2.3 Docker容器的特点](#23-docker容器的特点) + * [2.4 为什么要用Docker](#24-为什么要用docker) + * [三 容器 VS 虚拟机](#三-容器-vs-虚拟机) + * [3.1 两者对比图](#31-两者对比图) + * [3.2 容器与虚拟机 (VM) 总结](#32-容器与虚拟机-vm-总结) + * [3.3 容器与虚拟机 (VM)两者是可以共存的](#33-容器与虚拟机-vm两者是可以共存的) + * [四 Docker基本概念](#四-docker基本概念) + * [4.1 镜像(Image)——一个特殊的文件系统](#41-镜像(image)一个特殊的文件系统) + * [4.2 容器(Container)——镜像运行时的实体](#42-容器(container镜像运行时的实体) + * [4.3 仓库(Repository)——集中存放镜像文件的地方](#43-仓库(repository)集中存放镜像文件的地方) + * [五 最后谈谈:Build, Ship, and Run](#五-最后谈谈:build-ship-and-run) + * [六 总结](#六-总结) + + # 可能是把Docker的概念讲的最清楚的一篇文章 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\345\274\200\347\257\207\357\274\232\344\272\221\350\256\241\347\256\227\357\274\214\345\244\247\346\225\260\346\215\256\344\270\216AI\347\232\204\346\225\205\344\272\213.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\345\274\200\347\257\207\357\274\232\344\272\221\350\256\241\347\256\227\357\274\214\345\244\247\346\225\260\346\215\256\344\270\216AI\347\232\204\346\225\205\344\272\213.md" index 7e3ca3c..5fb6b8c 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\345\274\200\347\257\207\357\274\232\344\272\221\350\256\241\347\256\227\357\274\214\345\244\247\346\225\260\346\215\256\344\270\216AI\347\232\204\346\225\205\344\272\213.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\345\274\200\347\257\207\357\274\232\344\272\221\350\256\241\347\256\227\357\274\214\345\244\247\346\225\260\346\215\256\344\270\216AI\347\232\204\346\225\205\344\272\213.md" @@ -1,3 +1,8 @@ +# Table of Contents + +* [[快速看懂云计算,大数据,人工智能](https://www.cnblogs.com/popsuper1982/p/8505203.html)](#[快速看懂云计算,大数据,人工智能]httpswwwcnblogscompopsuper1982p8505203html) + + # [快速看懂云计算,大数据,人工智能](https://www.cnblogs.com/popsuper1982/p/8505203.html) diff --git "a/docs/cache/Redis\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" "b/docs/cache/Redis\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" index 91e0d95..4a2131b 100644 --- "a/docs/cache/Redis\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" +++ "b/docs/cache/Redis\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" @@ -1,3 +1,26 @@ +# Table of Contents + + * [使用和基础数据结构(外观)](#使用和基础数据结构(外观)) + * [底层数据结构](#底层数据结构) + * [redis server结构和数据库redisDb](#redis-server结构和数据库redisdb) + * [redis的事件模型](#redis的事件模型) + * [备份方式](#备份方式) + * [redis主从复制](#redis主从复制) + * [分布式锁实现](#分布式锁实现) + * [使用setnx加expire实现加锁和时限](#使用setnx加expire实现加锁和时限) + * [使用getset加锁和获取过期时间](#使用getset加锁和获取过期时间) + * [2.0的setnx可以配置过期时间。](#20的setnx可以配置过期时间。) + * [使用sentx将值设为时间戳,通过lua脚本进行cas比较和删除操作](#使用sentx将值设为时间戳,通过lua脚本进行cas比较和删除操作) + * [分布式Redis锁:Redlock](#分布式redis锁:redlock) + * [总结](#总结) + * [分布式方案](#分布式方案) + * [redis事务](#redis事务) + * [redis脚本事务](#redis脚本事务) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: Redis原理与实践总结 date: 2018-07-08 22:15:12 @@ -448,4 +471,4 @@ redis事务的ACID特性 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" index a5cab32..0333be9 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -302,4 +306,4 @@ eaMain() while(true) 的调用 aeProcessEvents()。 为什么 Redis 是一个单线程应用,却有如此高的性能? 如果你用本文提供的知识点回答这两个问题,一定会在面试官心中留下一个高大的形象。 -大家还可以阅读我的 Redis 相关的文章: \ No newline at end of file +大家还可以阅读我的 Redis 相关的文章: diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" index 2bc1bd0..f833e27 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" @@ -1,3 +1,13 @@ +# Table of Contents + +* [转自https://blog.csdn.net/xlgen157387/article/details/61925524](#转自httpsblogcsdnnetxlgen157387articledetails61925524) +* [前言](#前言) + * [快照持久化](#快照持久化) + * [AOF持久化](#aof持久化) + * [验证快照文件和AOF文件](#验证快照文件和aof文件) + * [总结](#总结) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" index a59247b..e0c797a 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" @@ -1,3 +1,23 @@ +# Table of Contents + +* [Redis复制概论](#redis复制概论) + * [Redis复制方式](#redis复制方式) + * [复制优点](#复制优点) + * [1、高可用性](#1、高可用性) + * [2、高性能](#2、高性能) + * [3、水平扩展性](#3、水平扩展性) + * [复制缺点](#复制缺点) + * [复制实时性和数据一致性矛盾](#复制实时性和数据一致性矛盾) +* [Redis复制原理及特性](#redis复制原理及特性) + * [slave指向master](#slave指向master) + * [复制过程](#复制过程) + * [增量复制](#增量复制) + * [免持久化复制](#免持久化复制) + * [slave只读模式](#slave只读模式) + * [半同步复制](#半同步复制) +* [总结](#总结) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -216,4 +236,4 @@ min-slaves-to-write min-slaves-max-lag # 总结 -本文在理解Redis复制概念和复制的优缺点的基础之上介绍了当前Redis复制工作原理以及主要特性,希望能够帮助大家。 \ No newline at end of file +本文在理解Redis复制概念和复制的优缺点的基础之上介绍了当前Redis复制工作原理以及主要特性,希望能够帮助大家。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" index 72f6230..44b499e 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" @@ -1,3 +1,20 @@ +# Table of Contents + + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#Replication%EF%BC%88%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%EF%BC%89 "Replication(主从复制)")Replication(主从复制)](#[]httpblog720uicom2016redis_action_04_clusterreplicationefbc88e4b8bbe4bb8ee5a48de588b6efbc89-replication(主从复制)replication(主从复制)) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E9%85%8D%E7%BD%AE%E4%B8%BB%E6%9C%8D%E5%8A%A1%E5%99%A8 "配置主服务器")配置主服务器](#[]httpblog720uicom2016redis_action_04_clustere9858de7bdaee4b8bbe69c8de58aa1e599a8-配置主服务器配置主服务器) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E9%85%8D%E7%BD%AE%E4%BB%8E%E6%9C%8D%E5%8A%A1%E5%99%A8 "配置从服务器")配置从服务器](#[]httpblog720uicom2016redis_action_04_clustere9858de7bdaee4bb8ee69c8de58aa1e599a8-配置从服务器配置从服务器) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E6%B5%8B%E8%AF%95 "测试")测试](#[]httpblog720uicom2016redis_action_04_clustere6b58be8af95-测试测试) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#Sentinel%EF%BC%88%E5%93%A8%E5%85%B5%EF%BC%89 "Sentinel(哨兵)")Sentinel(哨兵)](#[]httpblog720uicom2016redis_action_04_clustersentinelefbc88e593a8e585b5efbc89-sentinel(哨兵)sentinel(哨兵)) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E9%85%8D%E7%BD%AESentinel "配置Sentinel")配置Sentinel](#[]httpblog720uicom2016redis_action_04_clustere9858de7bdaesentinel-配置sentinel配置sentinel) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E5%90%AF%E5%8A%A8-Sentinel "启动 Sentinel")启动 Sentinel](#[]httpblog720uicom2016redis_action_04_clustere590afe58aa8-sentinel-启动-sentinel启动-sentinel) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E6%B5%8B%E8%AF%95-1 "测试")测试](#[]httpblog720uicom2016redis_action_04_clustere6b58be8af95-1-测试测试) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#Twemproxy "Twemproxy")Twemproxy](#[]httpblog720uicom2016redis_action_04_clustertwemproxy-twemproxytwemproxy) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#Codis "Codis")Codis](#[]httpblog720uicom2016redis_action_04_clustercodis-codiscodis) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#Redis-3-0%E9%9B%86%E7%BE%A4 "Redis 3.0集群")Redis 3.0集群](#[]httpblog720uicom2016redis_action_04_clusterredis-3-0e99b86e7bea4-redis-30集群redis-30集群) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA "环境搭建")环境搭建](#[]httpblog720uicom2016redis_action_04_clustere78eafe5a283e690ade5bbba-环境搭建环境搭建) + * [[](http://blog.720ui.com/2016/redis_action_04_cluster/#%E5%88%9B%E5%BB%BA%E9%9B%86%E7%BE%A4 "创建集群")创建集群](#[]httpblog720uicom2016redis_action_04_clustere5889be5bbbae99b86e7bea4-创建集群创建集群) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -267,4 +284,4 @@ Redis 3.0集群,目前支持的cluster特性 ![](http://image.chenyongjun.vip/redis3-cluster03.png) 5.3、测试 -![](http://image.chenyongjun.vip/redis3-cluster04.png) \ No newline at end of file +![](http://image.chenyongjun.vip/redis3-cluster04.png) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" index d4baeb9..dc528d4 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" @@ -1,3 +1,17 @@ +# Table of Contents + +* [事务](#事务) + * [用法](#用法) + * [事务中的错误](#事务中的错误) + * [为什么 Redis 不支持回滚(roll back)](#为什么-redis-不支持回滚(roll-back)) + * [放弃事务](#放弃事务) + * [使用 check-and-set 操作实现乐观锁](#使用-check-and-set-操作实现乐观锁) + * [了解 `WATCH`](#了解 `watch`) + * [使用 WATCH 实现 ZPOP](#使用-watch-实现-zpop) + * [Redis 脚本和事务](#redis-脚本和事务) +* [redis事务的ACID特性](#redis事务的acid特性) + + 本文转自互联网 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" index 9218532..ef83c44 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [Redis分布式锁进化史](#redis分布式锁进化史) + * [各个版本的Redis分布式锁](#各个版本的redis分布式锁) + * [分布式Redis锁:Redlock](#分布式redis锁:redlock) + * [总结](#总结) + + 本文转自互联网 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" index 1da319d..f7de1b5 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" @@ -1,3 +1,10 @@ +# Table of Contents + +* [[](https://www.xilidou.com/2018/03/12/redis-data/#SDS "SDS")SDS](#[]httpswwwxilidoucom20180312redis-datasds-sdssds) +* [[](https://www.xilidou.com/2018/03/12/redis-data/#%E9%93%BE%E8%A1%A8 "链表")链表](#[]httpswwwxilidoucom20180312redis-datae993bee8a1a8-链表链表) +* [[](https://www.xilidou.com/2018/03/12/redis-data/#%E5%AD%97%E5%85%B8 "字典")字典](#[]httpswwwxilidoucom20180312redis-datae5ad97e585b8-字典字典) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" index dd7c597..407986b 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [dict的数据结构定义](#dict的数据结构定义) + * [dict的创建(dictCreate)](#dict的创建(dictcreate)) + * [dict的查找(dictFind)](#dict的查找(dictfind)) + * [dictIsRehashing(d) ((d)->rehashidx != -1)](#dictisrehashingd-d-rehashidx---1) + * [dict的插入(dictAdd和dictReplace)](#dict的插入(dictadd和dictreplace)) + * [dict的删除(dictDelete)](#dict的删除(dictdelete)) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -374,4 +384,4 @@ dict的实现相对来说比较简单,本文就介绍到这。在下一篇中 **原创文章,转载请注明出处,并包含下面的二维码!否则拒绝转载!** **本文链接:**[http://zhangtielei.com/posts/blog-redis-dict.html](http://zhangtielei.com/posts/blog-redis-dict.html) -![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) \ No newline at end of file +![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" index 35821bf..b9ada4f 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" @@ -1,3 +1,23 @@ +# Table of Contents + + * [前言](#前言) + * [sds的数据结构定义](#sds的数据结构定义) + * [SDS_TYPE_5 0](#sds_type_5--0) + * [SDS_TYPE_8 1](#sds_type_8--1) + * [SDS_TYPE_16 2](#sds_type_16-2) + * [SDS_TYPE_32 3](#sds_type_32-3) + * [SDS_TYPE_64 4](#sds_type_64-4) + * [Redis dict结构举例](#redis-dict结构举例) + * [SDS_TYPE_MASK 7](#sds_type_mask-7) + * [SDS_TYPE_BITS 3](#sds_type_bits-3) + * [SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T)));](#sds_hdr_varts-struct-sdshdrt-sh--voids-sizeofstruct-sdshdrt) + * [SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))](#sds_hdrts-struct-sdshdrt-s-sizeofstruct-sdshdrt) + * [SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)](#sds_type_5_lenf-fsds_type_bits) + * [sds的创建和销毁](#sds的创建和销毁) + * [sds的连接(追加)操作](#sds的连接(追加)操作) + * [浅谈sds与string的关系](#浅谈sds与string的关系) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" index 3ae4b7b..2751608 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [什么是ziplist](#什么是ziplist) + * [ziplist的数据结构定义](#ziplist的数据结构定义) + * [ziplist的接口](#ziplist的接口) + * [ziplist的插入逻辑解析](#ziplist的插入逻辑解析) + * [hash与ziplist](#hash与ziplist) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -367,4 +376,4 @@ Redis的hash之所以这样设计,是因为当ziplist变得很大的时候, * 一旦发生内存拷贝,内存拷贝的成本也相应增加,因为要拷贝更大的一块数据。 * 当ziplist数据项过多的时候,在它上面查找指定的数据项就会性能变得很低,因为ziplist上的查找需要进行遍历。 -总之,ziplist本来就设计为各个数据项挨在一起组成连续的内存空间,这种结构并不擅长做修改操作。一旦数据发生改动,就会引发内存realloc,可能导致内存拷贝。 \ No newline at end of file +总之,ziplist本来就设计为各个数据项挨在一起组成连续的内存空间,这种结构并不擅长做修改操作。一旦数据发生改动,就会引发内存realloc,可能导致内存拷贝。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" index f7a5907..2620f6b 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [quicklist概述](#quicklist概述) + * [quicklist的数据结构定义](#quicklist的数据结构定义) + * [quicklist的创建](#quicklist的创建) + * [quicklist的push操作](#quicklist的push操作) + * [quicklist的其它操作](#quicklist的其它操作) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -368,4 +377,4 @@ quicklist不仅实现了从头部或尾部插入,也实现了从任意指定 **原创文章,转载请注明出处,并包含下面的二维码!否则拒绝转载!** **本文链接:**[http://zhangtielei.com/posts/blog-redis-quicklist.html](http://zhangtielei.com/posts/blog-redis-quicklist.html) -![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) \ No newline at end of file +![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" index c5f6137..3957aa3 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [skiplist数据结构简介](#skiplist数据结构简介) + * [skiplist的算法性能分析](#skiplist的算法性能分析) + * [skiplist与平衡树、哈希表的比较](#skiplist与平衡树、哈希表的比较) + * [Redis中的skiplist实现](#redis中的skiplist实现) + * [sorted set的命令举例](#sorted-set的命令举例) + * [Redis中skiplist实现的特殊性](#redis中skiplist实现的特殊性) + * [skiplist的数据结构定义](#skiplist的数据结构定义) + * [ZSKIPLIST_MAXLEVEL 32](#zskiplist_maxlevel-32) + * [ZSKIPLIST_P 0.25](#zskiplist_p-025) + * [Redis中的sorted set](#redis中的sorted-set) + * [Redis为什么用skiplist而不用平衡树?](#redis为什么用skiplist而不用平衡树?) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -450,4 +465,4 @@ typedef struct zset { **原创文章,转载请注明出处,并包含下面的二维码!否则拒绝转载!** **本文链接:**[http://zhangtielei.com/posts/blog-redis-skiplist.html](http://zhangtielei.com/posts/blog-redis-skiplist.html) -![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) \ No newline at end of file +![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" index c2ad59b..5b2645f 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [intset数据结构简介](#intset数据结构简介) + * [INTSET_ENC_INT16 (sizeof(int16_t))](#intset_enc_int16-sizeofint16_t) + * [INTSET_ENC_INT32 (sizeof(int32_t))](#intset_enc_int32-sizeofint32_t) + * [INTSET_ENC_INT64 (sizeof(int64_t))](#intset_enc_int64-sizeofint64_t) + * [intset的查找和添加操作](#intset的查找和添加操作) + * [Redis的set](#redis的set) + * [Redis set的并、交、差算法](#redis-set的并、交、差算法) + * [交集](#交集) + * [并集](#并集) + * [差集](#差集) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -318,4 +332,4 @@ Redis set的并、交、差算法的实现代码,在t_set.c中。其中计算 **原创文章,转载请注明出处,并包含下面的二维码!否则拒绝转载!** **本文链接:**[http://zhangtielei.com/posts/blog-redis-intset.html](http://zhangtielei.com/posts/blog-redis-intset.html) -![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) \ No newline at end of file +![我的微信公众号: tielei-blog (张铁蕾)](http://zhangtielei.com/assets/my_weixin_sign_sf_840.jpg) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" index 2692351..f8827a2 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" @@ -1,3 +1,29 @@ +# Table of Contents + + * [robj的数据结构定义](#robj的数据结构定义) + * [OBJ_STRING 0](#obj_string-0) + * [OBJ_LIST 1](#obj_list-1) + * [OBJ_SET 2](#obj_set-2) + * [OBJ_ZSET 3](#obj_zset-3) + * [OBJ_HASH 4](#obj_hash-4) + * [OBJ_ENCODING_RAW 0 /* Raw representation */](#obj_encoding_raw-0------raw-representation-) + * [OBJ_ENCODING_INT 1 /* Encoded as integer */](#obj_encoding_int-1------encoded-as-integer-) + * [OBJ_ENCODING_HT 2 /* Encoded as hash table */](#obj_encoding_ht-2-------encoded-as-hash-table-) + * [OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */](#obj_encoding_zipmap-3---encoded-as-zipmap-) + * [OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */](#obj_encoding_linkedlist-4--encoded-as-regular-linked-list-) + * [OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */](#obj_encoding_ziplist-5--encoded-as-ziplist-) + * [OBJ_ENCODING_INTSET 6 /* Encoded as intset */](#obj_encoding_intset-6---encoded-as-intset-) + * [OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */](#obj_encoding_skiplist-7---encoded-as-skiplist-) + * [OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */](#obj_encoding_embstr-8---embedded-sds-string-encoding-) + * [OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */](#obj_encoding_quicklist-9--encoded-as-linked-list-of-ziplists-) + * [LRU_BITS 24](#lru_bits-24) + * [string robj的编码过程](#string-robj的编码过程) + * [sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR)](#sdsencodedobjectobjptr-objptr-encoding--obj_encoding_raw--objptr-encoding--obj_encoding_embstr) + * [string robj的解码过程](#string-robj的解码过程) + * [再谈sds与string的关系](#再谈sds与string的关系) + * [robj的引用计数操作](#robj的引用计数操作) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -335,4 +361,4 @@ createEmbeddedStringObject对sds重新分配内存,将robj和sds放在一个 * * * -**后记**(追加于2016-07-09): 本文在解析“将string编码成long型”的代码时提到的判断21字节的问题,后来已经提交给@antirez并合并进了unstable分支,详见[commit f648c5a](https://github.com/antirez/redis/commit/f648c5a70c802aeb60ee9773dfdcf7cf08a06357)。 \ No newline at end of file +**后记**(追加于2016-07-09): 本文在解析“将string编码成long型”的代码时提到的判断21字节的问题,后来已经提交给@antirez并合并进了unstable分支,详见[commit f648c5a](https://github.com/antirez/redis/commit/f648c5a70c802aeb60ee9773dfdcf7cf08a06357)。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" index 84da8c0..0292122 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" index 81269ab..4f58639 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [redis 学习笔记](#redis-学习笔记) + * [redis 是什么?](#redis-是什么) + * [Redis 数据结构](#redis-数据结构) + * [Redis 数据类型](#redis-数据类型) + * [过期时间](#过期时间) + * [应用场景](#应用场景) + * [内存优化](#内存优化) + * [天下无难试之Redis面试刁难大全](#天下无难试之redis面试刁难大全) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -312,4 +324,4 @@ Redis可以使用主从同步,从从同步。第一次同步时,主节点做 Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。 -Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。 \ No newline at end of file +Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。 diff --git "a/docs/database/Mysql\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" "b/docs/database/Mysql\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" index 9c1db73..53ed5a0 100644 --- "a/docs/database/Mysql\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" +++ "b/docs/database/Mysql\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265\346\200\273\347\273\223.md" @@ -1,3 +1,31 @@ +# Table of Contents + +* [数据库原理](#数据库原理) + * [范式 反范式](#范式-反范式) + * [主键 外键](#主键-外键) + * [锁 共享锁和排它锁](#锁-共享锁和排它锁) + * [存储过程与视图](#存储过程与视图) + * [事务与隔离级别](#事务与隔离级别) + * [索引](#索引) +* [mysql原理](#mysql原理) + * [mysql客户端,服务端,存储引擎,文件系统](#mysql客户端,服务端,存储引擎,文件系统) + * [mysql常用语法](#mysql常用语法) + * [MySQL的存储原理](#mysql的存储原理) + * [数据页page](#数据页page) + * [mysql的索引,b树,聚集索引](#mysql的索引,b树,聚集索引) + * [mysql的explain 慢查询日志](#mysql的explain-慢查询日志) + * [mysql的binlog,redo log和undo log。](#mysql的binlogredo-log和undo-log。) + * [mysql的数据类型](#mysql的数据类型) + * [mysql的sql优化。](#mysql的sql优化。) + * [MySQL的事务实现和锁](#mysql的事务实现和锁) + * [分库分表](#分库分表) + * [主从复制,读写分离](#主从复制,读写分离) + * [分布式数据库](#分布式数据库) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: Mysql原理与实践总结 date: 2018-07-08 22:15:04 @@ -366,4 +394,4 @@ redis的分布式部署方案也比较成熟。 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" index b071b03..d089cc8 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [重新学习MySQL数据库10:MySQL里的那些日志们](#重新学习mysql数据库10:mysql里的那些日志们) + * [1.MySQL日志文件系统的组成](#1mysql日志文件系统的组成) + * [2.错误日志](#2错误日志) + * [3.InnoDB中的日志](#3innodb中的日志) + * [4- 慢查询日志](#4--慢查询日志) + * [5.二进制日志](#5二进制日志) + * [总结](#总结) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -112,4 +123,4 @@ mysql数据库的binlog和relay log日志有着举足轻重的作用,并且rel 2.binlog的作用 当有数据写入到数据库时,还会同时把更新的SQL语句写入到对应的binlog文件里,这个文件就是上文说的binlog文件。使用mysqldump备份时,只是对一段时间的数据进行全备,但是如果备份后突然发现数据库服务器故障,这个时候就要用到binlog的日志了。 -主要作用是用于数据库的主从复制及数据的增量恢复。 \ No newline at end of file +主要作用是用于数据库的主从复制及数据的增量恢复。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" index 5b9296d..68b160c 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [前言](#前言) + * [靶场准备](#靶场准备) + * [SQL注入测试](#sql注入测试) + * [注入原理分析](#注入原理分析) + * [JDBC的预处理](#jdbc的预处理) + * [Mybatis下注入防范](#mybatis下注入防范) + * [JPA注入防范](#jpa注入防范) + * [SQL注入的其他防范办法](#sql注入的其他防范办法) + * [小结](#小结) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" index 8d97691..bc03ab0 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [字段](#字段) + * [索引](#索引) + * [查询SQL](#查询sql) + * [引擎](#引擎) + * [MyISAM](#myisam) + * [InnoDB](#innodb) + * [0、自己写的海量数据sql优化实践](#0、自己写的海量数据sql优化实践) + * [mysql百万级分页优化](#mysql百万级分页优化) + * [  普通分页](#  普通分页) + * [   优化分页](#  -优化分页) + * [  总结](#  总结) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -670,4 +685,4 @@ SELECT s.* from Student s INNER JOIN SC sc on sc.s_id = s.s_id where sc.c_id=0 -转载于:https://my.oschina.net/alicoder/blog/3097141 \ No newline at end of file +转载于:https://my.oschina.net/alicoder/blog/3097141 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" index 82b413b..4411ceb 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" @@ -1,3 +1,40 @@ +# Table of Contents + + * [『浅入深出』MySQL 中事务的实现](#『浅入深出』mysql-中事务的实现) + * [原子性](#原子性) + * [回滚日志](#回滚日志) + * [事务的状态](#事务的状态) + * [并行事务的原子性](#并行事务的原子性) + * [持久性](#持久性) + * [重做日志](#重做日志) + * [回滚日志和重做日志](#回滚日志和重做日志) + * [隔离性](#隔离性) + * [事务的隔离级别](#事务的隔离级别) + * [隔离级别的实现](#隔离级别的实现) + * [锁](#锁) + * [时间戳](#时间戳) + * [多版本和快照隔离](#多版本和快照隔离) + * [隔离性与原子性](#隔离性与原子性) + * [一致性](#一致性) + * [ACID](#acid) + * [总结](#总结) + * [浅谈数据库并发控制 - 锁和 MVCC](#浅谈数据库并发控制---锁和-mvcc) + * [概述](#概述) + * [悲观并发控制](#悲观并发控制) + * [读写锁](#读写锁) + * [两阶段锁协议](#两阶段锁协议) + * [死锁的处理](#死锁的处理) + * [预防死锁](#预防死锁) + * [死锁检测和恢复](#死锁检测和恢复) + * [锁的粒度](#锁的粒度) + * [乐观并发控制](#乐观并发控制) + * [基于时间戳的协议](#基于时间戳的协议) + * [基于验证的协议](#基于验证的协议) + * [多版本并发控制](#多版本并发控制) + * [MySQL 与 MVCC](#mysql-与-mvcc) + * [PostgreSQL 与 MVCC](#postgresql-与-mvcc) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -475,4 +512,4 @@ InnoDB执行UPDATE,实际上是新插入了一行记录,并保存其创建 | 2 | long | 1 | 5 | | 3 | fei | 1 | undefined | -还是和事务2中(1)select 得到相同的结果. \ No newline at end of file +还是和事务2中(1)select 得到相同的结果. diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" index f53452b..c8ed7e2 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" @@ -1,3 +1,21 @@ +# Table of Contents + + * [Innodb中的事务隔离级别和锁的关系](#innodb中的事务隔离级别和锁的关系) + * [事务中的加锁方式](#事务中的加锁方式) + * [](#) + * [MySQL中锁的种类](#mysql中锁的种类) + * [Read Committed(读取提交内容)](#read-committed(读取提交内容)) + * [Repeatable Read(可重读)](#repeatable-read(可重读)) + * [](#-1) + * [不可重复读和幻读的区别](#不可重复读和幻读的区别) + * [悲观锁和乐观锁](#悲观锁和乐观锁) + * [MVCC在MySQL的InnoDB中的实现](#mvcc在mysql的innodb中的实现) + * [“读”与“读”的区别](#读与读的区别) + * [](#-2) + * [](#-3) + * [](#-4) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -329,4 +347,4 @@ update的teacher_id=20是在(5,30]区间,即使没有修改任何数据,In ###Serializable 这个级别很简单,**读加共享锁,写加排他锁,读写互斥**。使用的**悲观锁的理论**,实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式。 -这里要吐槽一句,**不要看到select就说不会加锁了,在Serializable这个级别,还是会加锁的**! \ No newline at end of file +这里要吐槽一句,**不要看到select就说不会加锁了,在Serializable这个级别,还是会加锁的**! diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" index 89deb93..f2e1f0c 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" @@ -1,3 +1,29 @@ +# Table of Contents + + * [二、分表实现策略](#二、分表实现策略) + * [三、分库实现策略](#三、分库实现策略) + * [四、分库与分表实现策略](#四、分库与分表实现策略) + * [五、分库分表总结](#五、分库分表总结) + * [六、总结](#六、总结) + * [Mycat实现主从复制,读写分离,以及分库分表的实践](#mycat实现主从复制,读写分离,以及分库分表的实践) + * [Mycat是什么](#mycat是什么) + * [一、分区分表](#一、分区分表) + * [二、Mycat 数据分片的种类](#二、mycat-数据分片的种类) + * [三、Mycat 垂直切分、水平切分实战](#三、mycat-垂直切分、水平切分实战) + * [1、垂直切分](#1、垂直切分) + * [2、水平切分](#2、水平切分) +* [range start-end ,data node index](#range-start-end-data-node-index) +* [K=1000,M=10000.](#k1000m10000) + * [为什么需要读写分离](#为什么需要读写分离) + * [MySQL主从复制](#mysql主从复制) + * [Mycat读写分离设置](#mycat读写分离设置) + * [配置Mycat用户](#配置mycat用户) + * [配置Mycat逻辑库](#配置mycat逻辑库) + * [schema](#schema) + * [dataNode](#datanode) + * [dataHost](#datahost) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -594,4 +620,4 @@ Mycat的配置有很多,不过因为我们只是使用Mycat的读写分类的 前面已经差不多都解释清楚了,因为我只是用的基本的主从复制,所以我的将`dataHost`的`balance`设置成了3 -启动mycat,然后用数据库连接工具连接到mycat,可以测试是否配置成功,最简单的就是通过修改从库的数据,这样方便查看到底是运行到哪个库上面了,另外由于我是基于docker启动的mycat,所以如果是直接在系统中运行的mycat的,可以去看官方文档,看看到底怎么启动mycat \ No newline at end of file +启动mycat,然后用数据库连接工具连接到mycat,可以测试是否配置成功,最简单的就是通过修改从库的数据,这样方便查看到底是运行到哪个库上面了,另外由于我是基于docker启动的mycat,所以如果是直接在系统中运行的mycat的,可以去看官方文档,看看到底怎么启动mycat diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" index e14d8cb..a4445eb 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" @@ -1,3 +1,45 @@ +# Table of Contents + + * [前言](#前言) + * [登录MySQL](#登录mysql) + * [创建数据库](#创建数据库) + * [创建数据库表](#创建数据库表) + * [增删改查](#增删改查) + * [SELECT](#select) + * [UPDATE](#update) + * [INSERT](#insert) + * [DELETE](#delete) + * [WHERE](#where) + * [AND 和 OR](#and-和-or) + * [AND](#and) + * [OR](#or) + * [ORDER BY](#order-by) + * [IN](#in) + * [NOT](#not) + * [UNION](#union) + * [AS](#as) + * [JOIN](#join) + * [SQL 函数](#sql-函数) + * [COUNT](#count) + * [MAX](#max) + * [触发器](#触发器) + * [添加索引](#添加索引) + * [普通索引(INDEX)](#普通索引index) + * [主键索引(PRIMARY key)](#主键索引primary-key) + * [唯一索引(UNIQUE)](#唯一索引unique) + * [全文索引(FULLTEXT)](#全文索引fulltext) + * [添加多列索引](#添加多列索引) + * [建立索引的时机](#建立索引的时机) + * [创建后表的修改](#创建后表的修改) + * [添加列](#添加列) + * [修改列](#修改列) + * [删除列](#删除列) + * [重命名表](#重命名表) + * [清空表数据](#清空表数据) + * [删除整张表](#删除整张表) + * [删除整个数据库](#删除整个数据库) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" index 709c3d3..e244e18 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" @@ -1,3 +1,31 @@ +# Table of Contents + + * [数据库的定义](#数据库的定义) + * [数据库和实例](#数据库和实例) + * [MySQL 的架构](#mysql-的架构) + * [数据的存储](#数据的存储) + * [如何存储表](#如何存储表) + * [如何存储记录](#如何存储记录) + * [数据页结构](#数据页结构) + * [索引](#索引) + * [索引的数据结构](#索引的数据结构) + * [聚集索引和辅助索引](#聚集索引和辅助索引) + * [索引的设计](#索引的设计) + * [锁](#锁) + * [并发控制机制](#并发控制机制) + * [锁的种类](#锁的种类) + * [锁的粒度](#锁的粒度) + * [锁的算法](#锁的算法) + * [死锁的发生](#死锁的发生) + * [事务与隔离级别](#事务与隔离级别) + * [几种隔离级别](#几种隔离级别) + * [脏读](#脏读) + * [不可重复读](#不可重复读) + * [幻读](#幻读) + * [总结](#总结) + * [[Innodb与Myisam引擎的区别与应用场景](https://www.cnblogs.com/changna1314/p/6878900.html)](#[innodb与myisam引擎的区别与应用场景]httpswwwcnblogscomchangna1314p6878900html) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -396,4 +424,4 @@ MVCC ( Multi-Version Concurrency Control )多版本并发控制  MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。 -InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且行锁定的机会比较大的情况。 \ No newline at end of file +InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且行锁定的机会比较大的情况。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" index 4e1f56f..09c5b22 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" @@ -1,3 +1,40 @@ +# Table of Contents + + * [前言](#前言) + * [[](https://draveness.me/mysql-innodb#%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E5%AE%9A%E4%B9%89)数据库的定义](#[]httpsdravenessmemysql-innodbe695b0e68daee5ba93e79a84e5ae9ae4b989数据库的定义) + * [[](https://draveness.me/mysql-innodb#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E5%AE%9E%E4%BE%8B)数据库和实例](#[]httpsdravenessmemysql-innodbe695b0e68daee5ba93e5928ce5ae9ee4be8b数据库和实例) + * [[](https://draveness.me/mysql-innodb#mysql-%E7%9A%84%E6%9E%B6%E6%9E%84)MySQL 的架构](#[]httpsdravenessmemysql-innodbmysql-e79a84e69eb6e69e84mysql-的架构) + * [[](https://draveness.me/mysql-innodb#%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8)数据的存储](#[]httpsdravenessmemysql-innodbe695b0e68daee79a84e5ad98e582a8数据的存储) + * [[](https://draveness.me/mysql-innodb#%E5%A6%82%E4%BD%95%E5%AD%98%E5%82%A8%E8%A1%A8)如何存储表](#[]httpsdravenessmemysql-innodbe5a682e4bd95e5ad98e582a8e8a1a8如何存储表) + * [[](https://draveness.me/mysql-innodb#frm-%E6%96%87%E4%BB%B6).frm 文件](#[]httpsdravenessmemysql-innodbfrm-e69687e4bbb6frm-文件) + * [[](https://draveness.me/mysql-innodb#ibd-%E6%96%87%E4%BB%B6).ibd 文件](#[]httpsdravenessmemysql-innodbibd-e69687e4bbb6ibd-文件) + * [[](https://draveness.me/mysql-innodb#%E5%A6%82%E4%BD%95%E5%AD%98%E5%82%A8%E8%AE%B0%E5%BD%95)如何存储记录](#[]httpsdravenessmemysql-innodbe5a682e4bd95e5ad98e582a8e8aeb0e5bd95如何存储记录) + * [[](https://draveness.me/mysql-innodb#%E8%A1%8C%E6%BA%A2%E5%87%BA%E6%95%B0%E6%8D%AE)行溢出数据](#[]httpsdravenessmemysql-innodbe8a18ce6baa2e587bae695b0e68dae行溢出数据) + * [[](https://draveness.me/mysql-innodb#%E6%95%B0%E6%8D%AE%E9%A1%B5%E7%BB%93%E6%9E%84)数据页结构](#[]httpsdravenessmemysql-innodbe695b0e68daee9a1b5e7bb93e69e84数据页结构) + * [[](https://draveness.me/mysql-innodb#%E7%B4%A2%E5%BC%95)索引](#[]httpsdravenessmemysql-innodbe7b4a2e5bc95索引) + * [[](https://draveness.me/mysql-innodb#%E7%B4%A2%E5%BC%95%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84)索引的数据结构](#[]httpsdravenessmemysql-innodbe7b4a2e5bc95e79a84e695b0e68daee7bb93e69e84索引的数据结构) + * [[](https://draveness.me/mysql-innodb#%E8%81%9A%E9%9B%86%E7%B4%A2%E5%BC%95%E5%92%8C%E8%BE%85%E5%8A%A9%E7%B4%A2%E5%BC%95)聚集索引和辅助索引](#[]httpsdravenessmemysql-innodbe8819ae99b86e7b4a2e5bc95e5928ce8be85e58aa9e7b4a2e5bc95聚集索引和辅助索引) + * [[](https://draveness.me/mysql-innodb#%E8%81%9A%E9%9B%86%E7%B4%A2%E5%BC%95)聚集索引](#[]httpsdravenessmemysql-innodbe8819ae99b86e7b4a2e5bc95聚集索引) + * [[](https://draveness.me/mysql-innodb#%E8%BE%85%E5%8A%A9%E7%B4%A2%E5%BC%95)辅助索引](#[]httpsdravenessmemysql-innodbe8be85e58aa9e7b4a2e5bc95辅助索引) + * [[](https://draveness.me/mysql-innodb#%E7%B4%A2%E5%BC%95%E7%9A%84%E8%AE%BE%E8%AE%A1)索引的设计](#[]httpsdravenessmemysql-innodbe7b4a2e5bc95e79a84e8aebee8aea1索引的设计) + * [[](https://draveness.me/mysql-innodb#%E9%94%81)锁](#[]httpsdravenessmemysql-innodbe99481锁) + * [[](https://draveness.me/mysql-innodb#%E5%B9%B6%E5%8F%91%E6%8E%A7%E5%88%B6%E6%9C%BA%E5%88%B6)并发控制机制](#[]httpsdravenessmemysql-innodbe5b9b6e58f91e68ea7e588b6e69cbae588b6并发控制机制) + * [[](https://draveness.me/mysql-innodb#%E9%94%81%E7%9A%84%E7%A7%8D%E7%B1%BB)锁的种类](#[]httpsdravenessmemysql-innodbe99481e79a84e7a78de7b1bb锁的种类) + * [[](https://draveness.me/mysql-innodb#%E9%94%81%E7%9A%84%E7%B2%92%E5%BA%A6)锁的粒度](#[]httpsdravenessmemysql-innodbe99481e79a84e7b292e5baa6锁的粒度) + * [[](https://draveness.me/mysql-innodb#%E9%94%81%E7%9A%84%E7%AE%97%E6%B3%95)锁的算法](#[]httpsdravenessmemysql-innodbe99481e79a84e7ae97e6b395锁的算法) + * [[](https://draveness.me/mysql-innodb#record-lock)Record Lock](#[]httpsdravenessmemysql-innodbrecord-lockrecord-lock) + * [[](https://draveness.me/mysql-innodb#gap-lock)Gap Lock](#[]httpsdravenessmemysql-innodbgap-lockgap-lock) + * [[](https://draveness.me/mysql-innodb#next-key-lock)Next-Key Lock](#[]httpsdravenessmemysql-innodbnext-key-locknext-key-lock) + * [[](https://draveness.me/mysql-innodb#%E6%AD%BB%E9%94%81%E7%9A%84%E5%8F%91%E7%94%9F)死锁的发生](#[]httpsdravenessmemysql-innodbe6adbbe99481e79a84e58f91e7949f死锁的发生) + * [[](https://draveness.me/mysql-innodb#%E4%BA%8B%E5%8A%A1%E4%B8%8E%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB)事务与隔离级别](#[]httpsdravenessmemysql-innodbe4ba8be58aa1e4b88ee99a94e7a6bbe7baa7e588ab事务与隔离级别) + * [[](https://draveness.me/mysql-innodb#%E5%87%A0%E7%A7%8D%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB)几种隔离级别](#[]httpsdravenessmemysql-innodbe587a0e7a78de99a94e7a6bbe7baa7e588ab几种隔离级别) + * [[](https://draveness.me/mysql-innodb#%E8%84%8F%E8%AF%BB)脏读](#[]httpsdravenessmemysql-innodbe8848fe8afbb脏读) + * [[](https://draveness.me/mysql-innodb#%E4%B8%8D%E5%8F%AF%E9%87%8D%E5%A4%8D%E8%AF%BB)不可重复读](#[]httpsdravenessmemysql-innodbe4b88de58fafe9878de5a48de8afbb不可重复读) + * [[](https://draveness.me/mysql-innodb#%E5%B9%BB%E8%AF%BB)幻读](#[]httpsdravenessmemysql-innodbe5b9bbe8afbb幻读) + * [[](https://draveness.me/mysql-innodb#%E6%80%BB%E7%BB%93)总结](#[]httpsdravenessmemysql-innodbe680bbe7bb93总结) + * [[](https://draveness.me/mysql-innodb#reference)Reference](#[]httpsdravenessmemysql-innodbreferencereference) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -406,4 +443,4 @@ CREATE TABLE test( * [InnoDB Locking](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html) * [乐观锁与悲观锁的区别](http://www.cnblogs.com/Bob-FD/p/3352216.html) * [Optimistic concurrency control](https://en.wikipedia.org/wiki/Optimistic_concurrency_control) -* [MySQL 四种事务隔离级的说明](http://www.cnblogs.com/zhoujinyi/p/3437475.html) \ No newline at end of file +* [MySQL 四种事务隔离级的说明](http://www.cnblogs.com/zhoujinyi/p/3437475.html) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" index f8702cb..909bad8 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" @@ -1,3 +1,42 @@ +# Table of Contents + + * [MySQL索引](#mysql索引) + * [一、简介](#一、简介) + * [二、语句](#二、语句) + * [三、索引类型](#三、索引类型) + * [四、缺点](#四、缺点) + * [五、注意事项](#五、注意事项) +* [摘要](#摘要) +* [数据结构及算法基础](#数据结构及算法基础) + * [索引的本质](#索引的本质) + * [B-Tree和B+Tree](#b-tree和btree) + * [B-Tree](#b-tree) + * [B+Tree](#btree) + * [带有顺序访问指针的B+Tree](#带有顺序访问指针的btree) + * [为什么使用B-Tree(B+Tree)](#为什么使用b-tree(btree)) + * [主存存取原理](#主存存取原理) + * [磁盘存取原理](#磁盘存取原理) + * [局部性原理与磁盘预读](#局部性原理与磁盘预读) + * [B-/+Tree索引的性能分析](#b-tree索引的性能分析) + * [MySQL索引实现](#mysql索引实现) + * [MyISAM索引实现](#myisam索引实现) + * [InnoDB索引实现](#innodb索引实现) + * [索引使用策略及优化](#索引使用策略及优化) + * [示例数据库](#示例数据库) + * [最左前缀原理与相关优化](#最左前缀原理与相关优化) + * [情况一:全列匹配。](#情况一:全列匹配。) + * [情况二:最左前缀匹配。](#情况二:最左前缀匹配。) + * [情况三:查询条件用到了索引中列的精确匹配,但是中间某个条件未提供。](#情况三:查询条件用到了索引中列的精确匹配,但是中间某个条件未提供。) + * [情况四:查询条件没有指定索引第一列。](#情况四:查询条件没有指定索引第一列。) + * [情况五:匹配某列的前缀字符串。](#情况五:匹配某列的前缀字符串。) + * [情况六:范围查询。](#情况六:范围查询。) + * [情况七:查询条件中含有函数或表达式。](#情况七:查询条件中含有函数或表达式。) + * [索引选择性与前缀索引](#索引选择性与前缀索引) + * [InnoDB的主键选择与插入优化](#innodb的主键选择与插入优化) +* [后记](#后记) +* [参考文献](#参考文献) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -852,4 +891,4 @@ title的选择性不足0.0001(精确值为0.00001579),所以实在没有 [5] Codd, E. F. (1970). "A relational model of data for large shared data banks". Communications of the ACM, , Vol. 13, No. 6, pp. 377-387 -[6] MySQL5.1参考手册 - [http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html") \ No newline at end of file +[6] MySQL5.1参考手册 - [http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html") diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" index 20aaf25..7551073 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" @@ -1,3 +1,37 @@ +# Table of Contents + + * [一:Mysql原理与慢查询](#一:mysql原理与慢查询) + * [一个慢查询引发的思考](#一个慢查询引发的思考) + * [二:索引建立](#二:索引建立) + * [三:浅析explain用法](#三:浅析explain用法) + * [有什么用?](#有什么用?) + * [怎么使用?](#怎么使用?) + * [参数介绍](#参数介绍) + * [id](#id) + * [select_type](#select_type) + * [extra](#extra) + * [possible_keys](#possible_keys) + * [key](#key) + * [key_len](#key_len) + * [ref](#ref) + * [rows](#rows) + * [四:慢查询优化](#四:慢查询优化) + * [建索引的几大原则](#建索引的几大原则) + * [回到开始的慢查询](#回到开始的慢查询) + * [查询优化神器 - explain命令](#查询优化神器---explain命令) + * [慢查询优化基本步骤](#慢查询优化基本步骤) + * [五:最左前缀原理与相关优化](#五:最左前缀原理与相关优化) + * [情况一:全列匹配。](#情况一:全列匹配。) + * [情况二:最左前缀匹配。](#情况二:最左前缀匹配。) + * [情况三:查询条件用到了索引中列的精确匹配,但是中间某个条件未提供。](#情况三:查询条件用到了索引中列的精确匹配,但是中间某个条件未提供。) + * [情况四:查询条件没有指定索引第一列。](#情况四:查询条件没有指定索引第一列。) + * [情况五:匹配某列的前缀字符串。](#情况五:匹配某列的前缀字符串。) + * [情况六:范围查询。](#情况六:范围查询。) + * [情况七:查询条件中含有函数或表达式。](#情况七:查询条件中含有函数或表达式。) + * [索引选择性与前缀索引](#索引选择性与前缀索引) + * [六:InnoDB的主键选择与插入优化](#六:innodb的主键选择与插入优化) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -483,4 +517,4 @@ title的选择性不足0.0001(精确值为0.00001579),所以实在没有 此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。 -因此,只要可以,请尽量在InnoDB上采用自增字段做主键。 \ No newline at end of file +因此,只要可以,请尽量在InnoDB上采用自增字段做主键。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" index 792b3de..e3f1b73 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [三类常见引擎:](#三类常见引擎:) + * [如何选择存储引擎:](#如何选择存储引擎:) + * [Mysql中的锁](#mysql中的锁) + * [MyISAM的锁机制:](#myisam的锁机制:) + * [并发插入](#并发插入) + * [锁调度](#锁调度) + * [InnoDB锁模式](#innodb锁模式) + * [锁的实现方式:](#锁的实现方式:) + * [何时在InnoDB中使用表锁:](#何时在innodb中使用表锁:) + * [死锁:](#死锁:) + * [避免死锁:](#避免死锁:) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -305,4 +320,4 @@ InnoDB在绝大部分情况会使用行级锁,因为事务和行锁往往是 2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率; -3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率; \ No newline at end of file +3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率; diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" index c901d44..5e1eab2 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" @@ -1,3 +1,10 @@ +# Table of Contents + + * [事务的基本要素(ACID)](#事务的基本要素(acid)) + * [事务的并发问题](#事务的并发问题) + * [MySQL事务隔离级别](#mysql事务隔离级别) + + 本文转自:https://blog.csdn.net/sinat_27143551/article/details/80876127 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" index 9a8728e..a02182f 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" @@ -1,3 +1,8 @@ +# Table of Contents + + * [**引言**](#引言) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" index 41db6d2..558acda 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" index c3dac66..de0c194 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 转自:https://www.cnblogs.com/bangerlee/p/5448766.html diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" index ca3536d..afb74d0 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" @@ -1,3 +1,8 @@ +# Table of Contents + + * [**引言**](#引言) + + 本文转自:https://www.cnblogs.com/bangerlee/p/5655754.html ## **引言** diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" index 325bd67..627599f 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自:https://www.cnblogs.com/bangerlee/p/5767845.html 选举(election)是分布式系统实践中常见的问题,通过打破节点间的对等关系,选得的leader(或叫master、coordinator)有助于实现事务原子性、提升决议效率。 多数派(quorum)的思路帮助我们在网络分化的情况下达成决议一致性,在leader选举的场景下帮助我们选出唯一leader。租约(lease)在一定期限内给予节点特定权利,也可以用于实现leader选举。 diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" index 64991d9..39ee1ee 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" @@ -1,3 +1,8 @@ +# Table of Contents + + * [**引言**](#引言) + + 本文转自:https://www.cnblogs.com/bangerlee/p/5991417.html ## **引言** diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" similarity index 95% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" index 82707d8..a0810e6 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" @@ -1,3 +1,8 @@ +# Table of Contents + + * [[分布式服务协调员zookeeper - 应用场景和监控](https://www.cnblogs.com/bangerlee/p/4427331.html)](#[分布式服务协调员zookeeper---应用场景和监控]httpswwwcnblogscombangerleep4427331html) + + ## [分布式服务协调员zookeeper - 应用场景和监控](https://www.cnblogs.com/bangerlee/p/4427331.html) zookeeper在分布式系统中作为协调员的角色,可应用于Leader选举、分布式锁、配置管理等服务的实现。以下我们从zookeeper供的API、应用场景和监控三方面学习和了解zookeeper(以下简称ZK)。 diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" index f87d63e..dd20632 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自 https://www.cnblogs.com/bangerlee/p/6216997.html 随承载用户数量的增加和容灾的需要,越来越多互联网后台系统从单机模式切换到分布式集群。回顾自己毕业五年来的工作内容,同样有这样的转变。 diff --git "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" similarity index 99% rename from "docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" rename to "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" index abe0a61..2b43b2b 100644 --- "a/docs/distrubuted/\347\220\206\350\256\272/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自:https://www.cnblogs.com/bangerlee/p/6189646.html diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" similarity index 97% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" index f60902d..94407e5 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" @@ -1,3 +1,24 @@ +# Table of Contents + +* [负载均衡的原理](#负载均衡的原理) + * [隐藏真实服务器](#隐藏真实服务器) + * [偷天换日](#偷天换日) + * [四层还是七层?](#四层还是七层) + * [责任分离](#责任分离) +* [1 什么是负载均衡(Load balancing)](#1-什么是负载均衡(load-balancing)) +* [2 负载均衡分类](#2-负载均衡分类) +* [3 常用负载均衡工具](#3-常用负载均衡工具) + * [3.1 LVS](#31-lvs) + * [3.2 Nginx](#32-nginx) + * [3.3 HAProxy](#33-haproxy) +* [4 常见负载均衡算法](#4-常见负载均衡算法) +* [负载均衡的几种算法Java实现代码](#负载均衡的几种算法java实现代码) + * [轮询](#轮询) + * [加权随机负载均衡算法](#加权随机负载均衡算法) + * [随机负载均衡算法](#随机负载均衡算法) + * [负载均衡 ip_hash算法](#负载均衡-ip_hash算法) + + # 负载均衡的原理 原创: 刘欣 码农翻身 4月23日 @@ -508,4 +529,4 @@ public class TestIpHash { * 192.168.1.18 */ } - } \ No newline at end of file + } diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" similarity index 96% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" index 53e192f..f3cd76d 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" @@ -1,3 +1,16 @@ +# Table of Contents + +* [一、问题的提出](#一、问题的提出) + * [1\. 什么是Session?](#1-什么是session?) + * [2\. 什么是Session一致性问题?](#2-什么是session一致性问题?) +* [二、Session一致性解决方案](#二、session一致性解决方案) + * [1\. Session Stiky](#1-session-stiky) + * [2\. Session Replication](#2-session-replication) + * [3\. Session数据集中存储](#3-session数据集中存储) + * [4\. Cookie Based](#4-cookie-based) +* [三、总结](#三、总结) + + # 一、问题的提出 ## 1\. 什么是Session? @@ -170,4 +183,4 @@ hash环上顺时针从整数0开始,一直到最大正整数,我们根据四 七、总结 -在分布式系统中一致性hash起着不可忽略的地位,无论是分布式缓存,还是分布式Rpc框架的负载均衡策略都有所使用。 \ No newline at end of file +在分布式系统中一致性hash起着不可忽略的地位,无论是分布式缓存,还是分布式Rpc框架的负载均衡策略都有所使用。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" similarity index 98% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" index a16ca0f..93525ee 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" @@ -1,3 +1,8 @@ +# Table of Contents + + * [分布式ID生成器 | 架构师之路](#分布式id生成器--架构师之路) + + ## 分布式ID生成器 | 架构师之路 转自: 58沈剑 架构师之路 2017-06-25 @@ -216,4 +221,4 @@ snowflake是twitter开源的分布式ID生成算法,其**核心思想为,** **缺点**: -* 由于“没有一个全局时钟”,每台服务器分配的ID是绝对递增的,但从全局看,生成的ID只是趋势递增的(有些服务器的时间早,有些服务器的时间晚) \ No newline at end of file +* 由于“没有一个全局时钟”,每台服务器分配的ID是绝对递增的,但从全局看,生成的ID只是趋势递增的(有些服务器的时间早,有些服务器的时间晚) diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" similarity index 97% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" index 845acdf..e822f1d 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" @@ -1,3 +1,28 @@ +# Table of Contents + +* [缓存和它的那些淘汰算法们](#缓存和它的那些淘汰算法们) +* [缓存技术杂谈](#缓存技术杂谈) +* [缓存特征](#缓存特征) + * [命中率](#命中率) + * [最大元素(或最大空间)](#最大元素(或最大空间)) + * [清空策略](#清空策略) +* [缓存介质](#缓存介质) +* [缓存分类和应用场景](#缓存分类和应用场景) + * [本地缓存](#本地缓存) + * [编程直接实现缓存](#编程直接实现缓存) + * [Ehcache](#ehcache) + * [分布式缓存](#分布式缓存) + * [memcached缓存](#memcached缓存) + * [Redis缓存](#redis缓存) +* [缓存常见问题](#缓存常见问题) + * [一、缓存雪崩](#一、缓存雪崩) + * [二、缓存穿透](#二、缓存穿透) + * [三、缓存预热](#三、缓存预热) + * [四、缓存更新](#四、缓存更新) + * [五、缓存降级](#五、缓存降级) + * [六、总结](#六、总结) + + diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" similarity index 98% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" index c665583..01e4550 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" @@ -1,3 +1,12 @@ +# Table of Contents + +* [Redis配置](#redis配置) +* [连接超时时间(毫秒)](#连接超时时间(毫秒)) + * [一、创建 Caching 配置类](#一、创建-caching-配置类) + * [二、创建需要缓存数据的类](#二、创建需要缓存数据的类) + * [三、测试方法](#三、测试方法) + + 本文转载自 linkedkeeper.com Spring Boot 熟悉后,集成一个外部扩展是一件很容易的事,集成Redis也很简单,看下面步骤配置: @@ -668,4 +677,4 @@ public class TestController { 至此完毕! -最后说一下,这个 @Cacheable 基本是可以放在所有方法上的,Controller 的方法上也是可以的(这个我没有测试 ^_^)。 \ No newline at end of file +最后说一下,这个 @Cacheable 基本是可以放在所有方法上的,Controller 的方法上也是可以的(这个我没有测试 ^_^)。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" similarity index 96% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" index b70d62d..ac52469 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" @@ -1,3 +1,14 @@ +# Table of Contents + +* [缓存更新的套路](#缓存更新的套路) + * [Cache Aside Pattern](#cache-aside-pattern) + * [Read/Write Through Pattern](#readwrite-through-pattern) + * [Read Through](#read-through) + * [Write Through](#write-through) + * [Write Behind Caching Pattern](#write-behind-caching-pattern) + * [再多唠叨一些](#再多唠叨一些) + + 本文转载自 linkedkeeper.com # 缓存更新的套路 @@ -78,4 +89,4 @@ Write Back套路,一句说就是,在更新数据的时候,只更新缓存 4)上面,我们没有考虑缓存(Cache)和持久层(Repository)的整体事务的问题。比如,更新Cache成功,更新数据库失败了怎么吗?或是反过来。关于这个事,如果你需要强一致性,你需要使用“两阶段提交协议”——prepare, commit/rollback,比如Java 7 的[XAResource](http://docs.oracle.com/javaee/7/api/javax/transaction/xa/XAResource.html),还有MySQL 5.7的 [XA Transaction](http://dev.mysql.com/doc/refman/5.7/en/xa.html),有些cache也支持XA,比如[EhCache](http://www.ehcache.org/documentation/3.0/xa.html)。当然,XA这样的强一致性的玩法会导致性能下降,关于分布式的事务的相关话题,你可以看看《[分布式系统的事务处理](https://coolshell.cn/articles/10910.html)》一文。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" index 936ae6f..df3ca80 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转载自 linkedkeeper.com 前言 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" index 1e6f993..5afd869 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转载自 linkedkeeper.com 众所周知,数据库能实现本地事务,也就是在同一个数据库中,你可以允许一组操作要么全都正确执行,要么全都不执行。这里特别强调了本地事务,也就是目前的数据库只能支持同一个数据库中的事务。但现在的系统往往采用微服务架构,业务系统拥有独立的数据库,因此就出现了跨多个数据库的事务需求,这种事务即为“分布式事务”。那么在目前数据库不支持跨库事务的情况下,我们应该如何实现分布式事务呢?本文首先会为大家梳理分布式事务的基本概念和理论基础,然后介绍几种目前常用的分布式事务解决方案。废话不多说,那就开始吧~ @@ -244,4 +248,4 @@ https://my.oschina.net/wangzhenchao/blog/736909 转载请并标注: “本文转载自 linkedkeeper.com ” ———————————————— 版权声明:本文为CSDN博主「黄小斜」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 -原文链接:https://blog.csdn.net/a724888/article/details/80790138 \ No newline at end of file +原文链接:https://blog.csdn.net/a724888/article/details/80790138 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" similarity index 87% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" index ad136c5..64835ef 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [分布式事务的解决方案](#分布式事务的解决方案) + * [方案1:全局事务(DTP模型)](#方案1:全局事务(dtp模型)) + * [实际方案:基于XA协议的两阶段提交](#实际方案:基于xa协议的两阶段提交) + * [方案2:基于可靠消息服务的分布式事务(事务消息中间件)](#方案2:基于可靠消息服务的分布式事务(事务消息中间件)) + * [方案3:最大努力通知(定期校对)也叫本地消息表](#方案3:最大努力通知(定期校对)也叫本地消息表) + * [方案4:TCC(两阶段型、补偿型)](#方案4:tcc(两阶段型、补偿型)) + * [[](http://wuwenliang.net/2017/03/25/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E4%B9%8B%E8%81%8A%E8%81%8ATCC/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#TCC%E7%9A%84%E6%9C%BA%E5%88%B6 "TCC的机制")TCC的机制](#[]httpwuwenliangnet20170325e58886e5b883e5bc8fe4ba8be58aa1e4b98be8818ae8818atcchmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiotcce79a84e69cbae588b6-tcc的机制tcc的机制) + * [[](http://wuwenliang.net/2017/03/25/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E4%B9%8B%E8%81%8A%E8%81%8ATCC/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E4%B8%80%E4%B8%AA%E5%AE%8C%E6%95%B4%E7%9A%84TCC%E4%BA%8B%E5%8A%A1%E5%8F%82%E4%B8%8E%E6%96%B9%E5%8C%85%E6%8B%AC%E4%B8%89%E9%83%A8%E5%88%86%EF%BC%9A "一个完整的TCC事务参与方包括三部分:")一个完整的TCC事务参与方包括三部分:](#[]httpwuwenliangnet20170325e58886e5b883e5bc8fe4ba8be58aa1e4b98be8818ae8818atcchmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe4b880e4b8aae5ae8ce695b4e79a84tcce4ba8be58aa1e58f82e4b88ee696b9e58c85e68bace4b889e983a8e58886efbc9a-一个完整的tcc事务参与方包括三部分:一个完整的tcc事务参与方包括三部分:) + * [[](http://wuwenliang.net/2017/03/25/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E4%B9%8B%E8%81%8A%E8%81%8ATCC/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#TCC%E7%9A%84%E4%BC%98%E7%82%B9%E5%92%8C%E9%99%90%E5%88%B6 "TCC的优点和限制")TCC的优点和限制](#[]httpwuwenliangnet20170325e58886e5b883e5bc8fe4ba8be58aa1e4b98be8818ae8818atcchmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiotcce79a84e4bc98e782b9e5928ce99990e588b6-tcc的优点和限制tcc的优点和限制) + * [[](http://wuwenliang.net/2017/03/25/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E4%B9%8B%E8%81%8A%E8%81%8ATCC/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E4%B8%80%E4%B8%AA%E6%A1%88%E4%BE%8B%E7%90%86%E8%A7%A3 "一个案例理解")一个案例理解](#[]httpwuwenliangnet20170325e58886e5b883e5bc8fe4ba8be58aa1e4b98be8818ae8818atcchmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe4b880e4b8aae6a188e4be8be79086e8a7a3-一个案例理解一个案例理解) + + 本文转载自 linkedkeeper.com @@ -200,4 +214,4 @@ TCC说实话,TCC的理论有点让人费解。故接下来将以账务拆分 只使用Try阶段预留的业务资源:只需要使用Try阶段帐户A和帐户B冻结的金额即可。 3、Cancel:取消执行业务 -释放Try阶段预留的业务资源:如果Try阶段部分成功,比如帐户A的余额够用,且冻结相应金额成功,帐户B的余额不够而冻结失败,则需要对帐户A做Cancel操作,将帐户A被冻结的金额解冻掉。 \ No newline at end of file +释放Try阶段预留的业务资源:如果Try阶段部分成功,比如帐户A的余额够用,且冻结相应金额成功,帐户B的余额不够而冻结失败,则需要对帐户A做Cancel操作,将帐户A被冻结的金额解冻掉。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" similarity index 96% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" index a7fa7fc..219e2c3 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" @@ -1,3 +1,12 @@ +# Table of Contents + +* [初步认识RocketMQ的核心模块](#初步认识rocketmq的核心模块) +* [错误的方案0](#错误的方案0) +* [方案1–业务方自己实现](#方案1业务方自己实现) +* [方案2 – RocketMQ 事务消息](#方案2--rocketmq-事务消息) +* [人工介入](#人工介入) + + 本文转载自 linkedkeeper.com diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" index 5e4d2f9..0d762b7 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文内容参考网络,侵删 本文较为粗略地讲述了CAP与BASE理论,以及分布式系统需要解决的一些问题,更加系统的理论可以参考后面的分布式系统理论专题文章。更加详细的实践内容也可以参考本专题的剩余文章 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" similarity index 96% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" index dd66d67..f64952d 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" @@ -1,3 +1,38 @@ +# Table of Contents + +* [何时需要消息队列](#何时需要消息队列) + * [解耦](#解耦) + * [最终一致性](#最终一致性) + * [广播](#广播) + * [错峰与流控](#错峰与流控) + * [消息队列的流派之争](#消息队列的流派之争) + * [MQ是什么](#mq是什么) + * [MQ的流派](#mq的流派) + * [有broker](#有broker) + * [无broker](#无broker) + * [MQ只能异步吗](#mq只能异步吗) + * [总结](#总结) +* [如何设计一个消息队列](#如何设计一个消息队列) + * [综述](#综述) + * [实现队列基本功能](#实现队列基本功能) + * [RPC通信协议](#rpc通信协议) + * [高可用](#高可用) + * [服务端承载消息堆积的能力](#服务端承载消息堆积的能力) + * [存储子系统的选择](#存储子系统的选择) + * [消费关系解析](#消费关系解析) + * [队列高级特性设计](#队列高级特性设计) + * [可靠投递(最终一致性)](#可靠投递(最终一致性)) + * [消费确认](#消费确认) + * [重复消息和顺序消息](#重复消息和顺序消息) + * [事务](#事务) + * [性能相关](#性能相关) + * [异步/同步](#异步同步) + * [push还是pull](#push还是pull) + * [慢消费](#慢消费) + * [消息延迟与忙等](#消息延迟与忙等) +* [总结](#总结-1) + + 本文转载自 linkedkeeper.com @@ -335,4 +370,4 @@ Future future = request(server);//server立刻返回future return future # 总结 -本文从为何使用消息队列开始讲起,然后主要介绍了如何从零开始设计一个消息队列,包括RPC、事务、最终一致性、广播、消息确认等关键问题。并对消息队列的push、pull模型做了简要分析,最后从批量和异步角度,分析了消息队列性能优化的思路。下篇会着重介绍一些高级话题,如存储系统的设计、流控和错峰的设计、公平调度等。希望通过这些,让大家对消息队列有个提纲挈领的整体认识,并给自主开发消息队列提供思路。另外,本文主要是源自自己在开发消息队列中的思考和读源码时的体会,比较不"官方",也难免会存在一些漏洞,欢迎大家多多交流。 \ No newline at end of file +本文从为何使用消息队列开始讲起,然后主要介绍了如何从零开始设计一个消息队列,包括RPC、事务、最终一致性、广播、消息确认等关键问题。并对消息队列的push、pull模型做了简要分析,最后从批量和异步角度,分析了消息队列性能优化的思路。下篇会着重介绍一些高级话题,如存储系统的设计、流控和错峰的设计、公平调度等。希望通过这些,让大家对消息队列有个提纲挈领的整体认识,并给自主开发消息队列提供思路。另外,本文主要是源自自己在开发消息队列中的思考和读源码时的体会,比较不"官方",也难免会存在一些漏洞,欢迎大家多多交流。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" index 29b337a..c86d17c 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转载自 linkedkeeper.com 本文主要介绍了这几部分内容: @@ -263,4 +267,4 @@ https://my.oschina.net/silence88/blog/856195 https://toutiao.io/posts/508935/app_preview -转载请并标注: “本文转载自 linkedkeeper.com ” \ No newline at end of file +转载请并标注: “本文转载自 linkedkeeper.com ” diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" index 2aeed2f..514f0b4 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文较为粗略地讲述了一致性协议与两种一致性算法,更加系统的理论可以参考后面的分布式系统理论专题文章。 2PC 由于BASE理论需要在一致性和可用性方面做出权衡,因此涌现了很多关于一致性的算法和协议。其中比较著名的有二阶提交协议(2 Phase Commitment Protocol),三阶提交协议(3 Phase Commitment Protocol)和Paxos算法。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" similarity index 99% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" index 182ecce..3720fb7 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" @@ -1,3 +1,7 @@ +# Table of Contents + + + 本文转自:微信公众号【码农翻身】 张大胖所在的公司这几年发展得相当不错,业务激增,人员也迅速扩展,转眼之间,张大胖已经成为公司的“资深”员工了,更重要的是,经过这些年的不懈努力,他终于坐上了架构师的宝座。 @@ -170,4 +174,4 @@ Zookeeper 所使用的树形结构和自己想象的非常类似,更重要的 _后记:本文从使用者的角度描述了Zookeeper有什么用处,至于它内部是如何工作,那是另外一个Big topic了,我们以后再讲。___ -(完) \ No newline at end of file +(完) diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" similarity index 89% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" index 938fef5..13dee71 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" @@ -1,3 +1,34 @@ +# Table of Contents + + * [ZAB协议](#zab协议) + * [消息广播模式](#消息广播模式) + * [崩溃恢复](#崩溃恢复) + * [数据同步](#数据同步) + * [ZAB协议原理](#zab协议原理) + * [Zookeeper设计目标](#zookeeper设计目标) +* [ZAB与FastLeaderElection选主算法流程详解](#zab与fastleaderelection选主算法流程详解) + * [选择机制中的概念](#选择机制中的概念) + * [服务器ID](#服务器id) + * [数据ID](#数据id) + * [逻辑时钟](#逻辑时钟) + * [选举状态](#选举状态) + * [选举消息内容](#选举消息内容) + * [选举流程图](#选举流程图) + * [源码分析](#源码分析) + * [QuorumPeer](#quorumpeer) + * [FastLeaderElection](#fastleaderelection) + * [判断是否已经胜出](#判断是否已经胜出) + * [选举流程简述](#选举流程简述) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E5%87%A0%E7%A7%8D%E9%A2%86%E5%AF%BC%E9%80%89%E4%B8%BE%E5%9C%BA%E6%99%AF "几种领导选举场景")几种领导选举场景](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe587a0e7a78de9a286e5afbce98089e4b8bee59cbae699af-几种领导选举场景几种领导选举场景) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E9%9B%86%E7%BE%A4%E5%90%AF%E5%8A%A8%E9%A2%86%E5%AF%BC%E9%80%89%E4%B8%BE "集群启动领导选举")集群启动领导选举](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe99b86e7bea4e590afe58aa8e9a286e5afbce98089e4b8be-集群启动领导选举集群启动领导选举) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#Follower%E9%87%8D%E5%90%AF "Follower重启")Follower重启](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiofollowere9878de590af-follower重启follower重启) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#Leader%E9%87%8D%E5%90%AF "Leader重启")Leader重启](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioleadere9878de590af-leader重启leader重启) +* [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E4%B8%80%E8%87%B4%E6%80%A7%E4%BF%9D%E8%AF%81 "一致性保证")一致性保证](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe4b880e887b4e680a7e4bf9de8af81-一致性保证一致性保证) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#Commit%E8%BF%87%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%A2%E5%A4%B1 "Commit过的数据不丢失")Commit过的数据不丢失](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoiocommite8bf87e79a84e695b0e68daee4b88de4b8a2e5a4b1-commit过的数据不丢失commit过的数据不丢失) + * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%9C%AACommit%E8%BF%87%E7%9A%84%E6%B6%88%E6%81%AF%E5%AF%B9%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8D%E5%8F%AF%E8%A7%81 "未Commit过的消息对客户端不可见")未Commit过的消息对客户端不可见](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe69caacommite8bf87e79a84e6b688e681afe5afb9e5aea2e688b7e7abafe4b88de58fafe8a781-未commit过的消息对客户端不可见未commit过的消息对客户端不可见) +* [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%80%BB%E7%BB%93 "总结")总结](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe680bbe7bb93-总结总结) + + ## ZAB协议 1. ZAB协议是专门为zookeeper实现分布式协调功能而设计。zookeeper主要是根据ZAB协议是实现分布式系统数据一致性。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" similarity index 95% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" index fb6c574..a3bee21 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" @@ -1,3 +1,19 @@ +# Table of Contents + + * [4.1 配置文件](#41-配置文件) + * [4.2 服务端命令](#42-服务端命令) + * [4.3 客户端命令](#43-客户端命令) + * [4.3.1 查看节点列表](#431-查看节点列表) + * [4.3.2 创建新节点](#432-创建新节点) + * [4.3.3 查看节点数据](#433-查看节点数据) + * [4.3.4 修改节点数据](#434-修改节点数据) + * [4.3.5 删除节点](#435-删除节点) + * [4.4 ZooKeeper四字命令](#44-zookeeper四字命令) + * [5.1 集群配置](#51-集群配置) + * [5.2 集群启动](#52-集群启动) + * [5.3 集群容灾](#53-集群容灾) + + ## 4.1 配置文件 ZooKeeper安装好之后,在安装目录的conf文件夹下可以找到一个名为“**zoo_sample.cfg**”的文件,是ZooKeeper配置文件的模板。 @@ -308,4 +324,4 @@ server.3=127.0.0.1:2890:3890 ![](https://img-blog.csdn.net/20161027092241119?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) -可见,关闭zk3以后,由于集群中的可用Server只剩下一台(达不到集群总数的半数以上),**集群将处于不可用的状态。** \ No newline at end of file +可见,关闭zk3以后,由于集群中的可用Server只剩下一台(达不到集群总数的半数以上),**集群将处于不可用的状态。** diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" similarity index 96% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" index 8ee17f7..8753510 100644 --- "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" @@ -1,3 +1,27 @@ +# Table of Contents + +* [一.ZooKeeper典型应用场景实践](#一zookeeper典型应用场景实践) +* [1 Zookeeper数据模型](#1-zookeeper数据模型) +* [2 如何使用Zookeeper](#2-如何使用zookeeper) + * [2.1 常用接口操作](#21-常用接口操作) +* [3 ZooKeeper 典型的应用场景](#3-zookeeper-典型的应用场景) + * [3.1 统一命名服务(Name Service)](#31-统一命名服务(name-service)) + * [3.2 配置管理(Configuration Management)](#32-配置管理(configuration-management)) + * [3.3 集群管理(Group Membership)](#33-集群管理(group-membership)) + * [3.4 共享锁(Locks)](#34-共享锁(locks)) + * [3.5 队列管理](#35-队列管理) + * [3.6 负载均衡](#36-负载均衡) + * [3.7 分布式通知/协调](#37-分布式通知协调) + * [二:典型场景描述总结](#二典型场景描述总结) + * [**数据发布与订阅**(配置管理)](#数据发布与订阅配置管理) + * [**负载均衡**](#负载均衡) + * [**分布通知/协调**](#分布通知协调) + * [**命名服务**](#命名服务) + * [**分布式锁**](#分布式锁) + * [**集群管理**](#集群管理) + * [**分布式队列**](#分布式队列) + + # 一.ZooKeeper典型应用场景实践 ZooKeeper是一个`高可用的分布式数据管理与系统协调框架`。`基于对Paxos算法的实现,使该框架保证了分布式环境中数据的强一致性`,也正是基于这样的特性,使得ZooKeeper解决很多分布式问题。网上对ZK的应用场景也有不少介绍,本文将介绍比较常用的项目例子,系统地对ZK的应用场景进行一个分门归类的介绍。 @@ -433,4 +457,4 @@ Master选举 第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。 -同步队列。一个job由多个task组成,只有所有任务完成后,job才运行完成。可为job创建一个/job目录,然后在该目录下,为每个完成的task创建一个临时znode,一旦临时节点数目达到task总数,则job运行完成。 \ No newline at end of file +同步队列。一个job由多个task组成,只有所有任务完成后,job才运行完成。可为job创建一个/job目录,然后在该目录下,为每个完成的task创建一个临时znode,一旦临时节点数目达到task总数,则job运行完成。 diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" similarity index 100% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" similarity index 100% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" diff --git "a/docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" similarity index 100% rename from "docs/distrubuted/\345\256\236\346\210\230/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" rename to "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" diff --git "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" "b/docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" index fb998c7..2c7c65f 100644 --- "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" +++ "b/docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" @@ -1,3 +1,35 @@ +# Table of Contents + +* [分布式技术](#分布式技术) + * [分布式数据和nosql](#分布式数据和nosql) + * [缓存 分布式缓存](#缓存-分布式缓存) + * [redis的部署方案:](#redis的部署方案:) + * [缓存需要解决的问题:](#缓存需要解决的问题:) + * [缓存更新的方法](#缓存更新的方法) + * [缓存在springboot中的使用](#缓存在springboot中的使用) + * [一致性哈希](#一致性哈希) + * [session和分布式session](#session和分布式session) + * [负载均衡](#负载均衡) + * [zookeeper](#zookeeper) + * [数据库的分布式事务](#数据库的分布式事务) + * [分布式锁问题](#分布式锁问题) + * [MySQL实现分布式锁](#mysql实现分布式锁) + * [redis实现分布式锁](#redis实现分布式锁) + * [zookeeper实现分布式锁](#zookeeper实现分布式锁) + * [消息队列](#消息队列) + * [微服务和Dubbo](#微服务和dubbo) + * [全局id](#全局id) + * [秒杀系统](#秒杀系统) + * [第一层,客户端怎么优化(浏览器层,APP层)](#第一层,客户端怎么优化(浏览器层,app层)) + * [第二层,站点层面的请求拦截](#第二层,站点层面的请求拦截) + * [第三层 服务层来拦截(反正就是不要让请求落到数据库上去)消息队列+缓存](#第三层-服务层来拦截(反正就是不要让请求落到数据库上去)消息队列缓存) + * [好了,最后是数据库层](#好了,最后是数据库层) + * [总结](#总结) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: 分布式技术实践总结 date: 2018-07-08 22:15:36 @@ -493,4 +525,4 @@ snowflake是twitter开源的分布式ID生成算法,其核心思想为,一 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" "b/docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" index bcc79c7..a118bdc 100644 --- "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" +++ "b/docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" @@ -1,3 +1,26 @@ +# Table of Contents + +* [分布式理论](#分布式理论) + * [CAP](#cap) + * [BASE](#base) + * [分布式系统关键词](#分布式系统关键词) + * [时钟,时间,事件顺序](#时钟,时间,事件顺序) + * [Lamport timestamps](#lamport-timestamps) + * [Vector clock](#vector-clock) + * [Version vector](#version-vector) + * [选主,租约,多数派](#选主,租约,多数派) + * [一致性,2pc和3pc](#一致性,2pc和3pc) + * [一致性算法paxos](#一致性算法paxos) + * [raft和zab](#raft和zab) + * [单个 Candidate 的竞选](#单个-candidate-的竞选) + * [[](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E4%B8%80%E8%87%B4%E6%80%A7.md#%E5%A4%9A%E4%B8%AA-candidate-%E7%AB%9E%E9%80%89)多个 Candidate 竞选](#[]httpsgithubcomcyc2018interview-notebookblobmasternotese4b880e887b4e680a7mde5a49ae4b8aa-candidate-e7ab9ee98089多个-candidate-竞选) + * [[](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E4%B8%80%E8%87%B4%E6%80%A7.md#%E6%97%A5%E5%BF%97%E5%A4%8D%E5%88%B6)日志复制](#[]httpsgithubcomcyc2018interview-notebookblobmasternotese4b880e887b4e680a7mde697a5e5bf97e5a48de588b6日志复制) + * [zookeeper](#zookeeper) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: 分布式理论学习总结 date: 2018-07-08 22:15:23 @@ -372,4 +395,4 @@ zookeeper以目录树的形式管理数据,提供znode监听、数据设置等 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" "b/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" index 3dc5550..7b4490d 100644 --- "a/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" +++ "b/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" @@ -1,3 +1,72 @@ +# Table of Contents + +* [网络](#网络) + * [1 TCP/IP卷一](#1-tcpip卷一) + * [2 计算机网络:自顶向下](#2-计算机网络:自顶向下) + * [3 图解HTTP和图解TCP/IP](#3-图解http和图解tcpip) + * [4 计算机网络](#4-计算机网络) +* [操作系统](#操作系统) + * [1 深入理解计算机系统](#1-深入理解计算机系统) + * [2 现代操作系统](#2-现代操作系统) + * [3 Linux内核设计与实现](#3-linux内核设计与实现) + * [4 Unix网络编程](#4-unix网络编程) +* [数据结构与算法](#数据结构与算法) + * [1 算法导论](#1-算法导论) + * [2 数据结构与算法(Java版)](#2-数据结构与算法(java版)) + * [3 算法图解,啊哈算法](#3-算法图解,啊哈算法) + * [4 剑指offer](#4-剑指offer) + * [5 LeetCode](#5-leetcode) +* [Java基础](#java基础) +* [1 Java编程思想](#1-java编程思想) +* [2 Java核心技术卷一](#2-java核心技术卷一) +* [Java进阶](#java进阶) + * [1 深入理解JVM虚拟机](#1-深入理解jvm虚拟机) + * [2 Java并发编程实战](#2-java并发编程实战) + * [3 Java并发编程艺术](#3-java并发编程艺术) + * [4 Effective Java](#4-effective-java) + * [5 Java性能调优指南](#5-java性能调优指南) + * [6 Netty权威指南](#6-netty权威指南) +* [JavaWeb](#javaweb) + * [1 深入JavaWeb技术内幕](#1-深入javaweb技术内幕) + * [2 How Tomcat Works](#2-how-tomcat-works) + * [3 Tomcat架构解析](#3-tomcat架构解析) + * [4 Spring实战](#4-spring实战) + * [5 Spring源码深度解析](#5-spring源码深度解析) + * [6 Spring MVC学习指南](#6-spring-mvc学习指南) + * [6 Maven实战](#6-maven实战) +* [数据库](#数据库) + * [1 数据库原理](#1-数据库原理) + * [1 sql必知必会](#1-sql必知必会) + * [2 深入浅出MySQL](#2-深入浅出mysql) + * [3 MySQL技术内幕:innodb存储引擎](#3-mysql技术内幕:innodb存储引擎) + * [4 高性能Mysql](#4-高性能mysql) + * [5 Redis实战](#5-redis实战) + * [6 Redis设计与实现](#6-redis设计与实现) +* [分布式](#分布式) + * [1 分布式Java应用](#1-分布式java应用) + * [2 大型网站技术架构](#2-大型网站技术架构) + * [3 大型分布式网站架构设计与实践](#3-大型分布式网站架构设计与实践) + * [4 分布式服务框架原理与实践](#4-分布式服务框架原理与实践) + * [5 大型网站系统与Java中间件开发实践](#5-大型网站系统与java中间件开发实践) + * [6 从Paxos到Zookeeper分布式一致性原理与实践](#6-从paxos到zookeeper分布式一致性原理与实践) + * [7 大规模分布式存储系统](#7-大规模分布式存储系统) +* [云计算](#云计算) + * [1 OpenStack设计与实现](#1-openstack设计与实现) + * [2 docker入门与实践](#2-docker入门与实践) + * [3 kubenetes权威指南](#3-kubenetes权威指南) +* [大数据](#大数据) + * [1 大数据技术原理与应用](#1-大数据技术原理与应用) + * [2 Hadoop实战](#2-hadoop实战) + * [3 Hadoop权威指南](#3-hadoop权威指南) +* [其他:](#其他:) + * [1 Git权威指南](#1-git权威指南) + * [2 重构](#2-重构) + * [3 - n](#3---n) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展。 今天我们就来介绍一下Java后端开发者的书单。 @@ -591,4 +660,4 @@ Git是现在大公司主流的代码协同工具,如果你想要了解其底 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" index 58b116f..1432c75 100644 --- "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" +++ "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" @@ -1,3 +1,20 @@ +# Table of Contents + +* [前言](#前言) +* [大学时期的迷茫与坚定](#大学时期的迷茫与坚定) +* [研究生时期的探索和规划](#研究生时期的探索和规划) +* [我的Java入门之路](#我的java入门之路) +* [我的Java进阶之路](#我的java进阶之路) +* [我的Java实习之路](#我的java实习之路) +* [抉择时刻:实习转正还是秋招](#抉择时刻:实习转正还是秋招) +* [Java修仙之路](#java修仙之路) +* [秋招回忆录](#秋招回忆录) +* [结束也是开始](#结束也是开始) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + ![](https://mmbiz.qpic.cn/mmbiz_jpg/XHh0SksQZPNibhTicDNtDkY4OicCvkS2Kz25mxuU09hVfia31PnXnTENnN7TE9TtlOic2vrDrGtIswWuouiaToHn3yLQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1) # 前言 diff --git "a/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" "b/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" index a1539d0..c72b4dd 100644 --- "a/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" +++ "b/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [谈谈我的技术方向选择](#谈谈我的技术方向选择) + * [谈谈各个技术方向的前景](#谈谈各个技术方向的前景) + * [研究生就应该做算法么?](#研究生就应该做算法么?) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + ​ 阅读本文大概需要 2.8 分钟。 diff --git "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" index ed74c16..b4a6a53 100644 --- "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" +++ "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [Java入门学习资源](#java入门学习资源) + * [Java后端技术专栏](#java后端技术专栏) + * [Java工程师书单](#java工程师书单) + * [技术社区推荐](#技术社区推荐) + * [技术大牛推荐](#技术大牛推荐) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + ![](https://picturecdn.8qwe5.com/18532be2f2284a96b0407e5b21cd525a.webp) 学习Java和其他技术的资源其实非常多,但是我们需要取其精华去其糟粕,选择那些最好的,最适合我们的,同时也要由浅入深,先易后难。基于这样的一个标准,我在这里为大家提供一份Java的学习资源清单。 diff --git "a/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" "b/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" index 366944b..202769b 100644 --- "a/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" +++ "b/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" @@ -1,3 +1,37 @@ +# Table of Contents + +* [![](https://mmbiz.qpic.cn/mmbiz_jpg/XHh0SksQZPNiac1cDGFicIqDTr2PoAq2jmvD3JnkUOiaBzxgZDjh9pcicS0rCKcGaWvGVnm7ZH2LvlODKAtzANlDZg/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)](#[]httpsmmbizqpiccnmmbiz_jpgxhh0sksqzpniac1cdgficiqdtr2poaq2jmvd3jnkuoiabzxgzdjh9pcics0rckcgawvgvnm7zh2lvlodkatzanldzg640wx_fmtjpegtpwebpwxfrom5wx_lazy1wx_co1) +* [前言](#前言) +* [1 计算机基础](#1-计算机基础) +* [2 Java编程](#2-java编程) + * [Java基础](#java基础) + * [设计模式](#设计模式) + * [Java Web技术](#java-web技术) + * [Java并发技术](#java并发技术) + * [Java网络编程和服务器](#java网络编程和服务器) + * [Jvm基础与调优](#jvm基础与调优) +* [3 Linux](#3-linux) +* [4 数据相关](#4-数据相关) + * [关系数据库Mysql](#关系数据库mysql) + * [缓存](#缓存) + * [搜索引擎](#搜索引擎) + * [大数据](#大数据) +* [6 分布式](#6-分布式) + * [web架构](#web架构) + * [分布式理论](#分布式理论) + * [一致性问题](#一致性问题) + * [分布式session](#分布式session) + * [分布式缓存](#分布式缓存) + * [分布式数据库](#分布式数据库) + * [负载均衡](#负载均衡) + * [消息队列](#消息队列) + * [服务化](#服务化) + * [虚拟化](#虚拟化) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + # ![](https://mmbiz.qpic.cn/mmbiz_jpg/XHh0SksQZPNiac1cDGFicIqDTr2PoAq2jmvD3JnkUOiaBzxgZDjh9pcicS0rCKcGaWvGVnm7ZH2LvlODKAtzANlDZg/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1) # 前言 diff --git "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" index 5b64d10..3b54d0f 100644 --- "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" +++ "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" @@ -1,3 +1,22 @@ +# Table of Contents + +* [阿里面经  ](#阿里面经  ) +* [腾讯面经  ](#腾讯面经  ) +* [百度面经  ](#百度面经  ) +* [网易面经  ](#网易面经  ) +* [头条面经  ](#头条面经  ) +* [快手&拼多多面经  ](#快手拼多多面经  ) +* [京东&美团面经](#京东美团面经) +* [斗鱼面经](#斗鱼面经) +* [有赞面经](#有赞面经) +* [华为&深信服等面经](#华为深信服等面经) +* [海康&商汤等面经](#海康商汤等面经) +* [携程&拼多多面经](#携程拼多多面经) +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + ![](https://mmbiz.qpic.cn/mmbiz_jpg/XHh0SksQZPPAdahlOcBvxxLrx0ibYleGQvVONWia2JjwyBDoUibkYrcm3viapMOCBPehbX6eOxWSHNAa8TYTqj2ibYQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1) diff --git a/docs/hxx/think/copy.md b/docs/hxx/think/copy.md index e5d6027..c62954a 100644 --- a/docs/hxx/think/copy.md +++ b/docs/hxx/think/copy.md @@ -1,3 +1,10 @@ +# Table of Contents + +* [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 新手程序员通常会走入一个误区,就是认为学习了一门语言,就可以称为是某某语言工程师了。但事实上真的是这样吗?其实并非如此。 diff --git a/docs/interview/BATJ-Experience/2019alipay-pinduoduo-toutiao.md b/docs/interview/BATJ-Experience/2019alipay-pinduoduo-toutiao.md index 183a185..1db1539 100644 --- a/docs/interview/BATJ-Experience/2019alipay-pinduoduo-toutiao.md +++ b/docs/interview/BATJ-Experience/2019alipay-pinduoduo-toutiao.md @@ -1,3 +1,28 @@ +# Table of Contents + +* [2019年蚂蚁金服、头条、拼多多的面试总结](#2019年蚂蚁金服、头条、拼多多的面试总结) + * [准备过程](#准备过程) + * [蚂蚁金服](#蚂蚁金服) + * [一面](#一面) + * [二面](#二面) + * [三面](#三面) + * [四面](#四面) + * [五面](#五面) + * [小结](#小结) + * [拼多多](#拼多多) + * [面试前](#面试前) + * [一面](#一面-1) + * [二面](#二面-1) + * [三面](#三面-1) + * [小结](#小结-1) + * [字节跳动](#字节跳动) + * [面试前](#面试前-1) + * [一面](#一面-2) + * [二面](#二面-2) + * [小结](#小结-2) + * [总结](#总结) + + 作者: rhwayfun,原文地址:https://mp.weixin.qq.com/s/msYty4vjjC0PvrwasRH5Bw ,JavaGuide 已经获得作者授权并对原文进行了重新排版。 diff --git "a/docs/interview/BATJ-Experience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/docs/interview/BATJ-Experience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" index 9efac14..5a6e7e3 100644 --- "a/docs/interview/BATJ-Experience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" +++ "b/docs/interview/BATJ-Experience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [前言](#前言) + * [一面(技术面)](#一面技术面) + * [二面(技术面)](#二面技术面) + * [三面(技术面)](#三面技术面) + * [四面(半个技术面)](#四面半个技术面) + * [五面(HR面)](#五面hr面) + * [总结](#总结) + + > 作者:ppxyn。本文来自读者投稿,同时也欢迎各位投稿,**对于不错的原创文章我根据你的选择给予现金(50-200)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 **目录** diff --git "a/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" "b/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" index 2e2df23..95f8403 100644 --- "a/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" +++ "b/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [一面 (37 分钟左右)](#一面-37-分钟左右) + * [二面 (33 分钟左右)](#二面-33-分钟左右) + * [三面 (46 分钟)](#三面-46-分钟) + * [HR 面](#hr-面) + + 本文来自 Anonymous 的投稿 ,JavaGuide 对原文进行了重新排版和一点完善。 diff --git "a/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" "b/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" index 76dce82..917620c 100644 --- "a/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" +++ "b/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" @@ -1,3 +1,30 @@ +# Table of Contents + + * [Java基础学习总结](#java基础学习总结) + * [面向对象三大特性](#面向对象三大特性) + * [基本数据类型](#基本数据类型) + * [String及包装类](#string及包装类) + * [final关键字](#final关键字) + * [抽象类和接口](#抽象类和接口) + * [代码块和加载顺序](#代码块和加载顺序) + * [包、内部类、外部类](#包、内部类、外部类) + * [异常](#异常) + * [泛型](#泛型) + * [Class类和Object类](#class类和object类) + * [javac和java](#javac和java) + * [反射](#反射) + * [枚举类](#枚举类) + * [序列化](#序列化) + * [动态代理](#动态代理) + * [多线程](#多线程) + * [IO流](#io流) + * [网络编程](#网络编程) + * [Java8](#java8) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: Java核心技术学习总结 date: 2018-07-10 22:37:47 @@ -292,4 +319,4 @@ https://blog.csdn.net/a724888 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git a/docs/interview/PreparingForInterview/JavaInterviewLibrary.md b/docs/interview/PreparingForInterview/JavaInterviewLibrary.md index 835b6a5..e3d4e1d 100644 --- a/docs/interview/PreparingForInterview/JavaInterviewLibrary.md +++ b/docs/interview/PreparingForInterview/JavaInterviewLibrary.md @@ -1,3 +1,23 @@ +# Table of Contents + + * [知识点相关](#知识点相关) + * [1.JavaGuide](#1javaguide) + * [2.CS-Notes](#2cs-notes) + * [3. advanced-java](#3-advanced-java) + * [4.JCSprout](#4jcsprout) + * [5.toBeTopJavaer](#5tobetopjavaer) + * [6.architect-awesome](#6architect-awesome) + * [7.technology-talk](#7technology-talk) + * [8.fullstack-tutorial](#8fullstack-tutorial) + * [9.3y](#93y) + * [10.java-bible](#10java-bible) + * [11.interviews](#11interviews) + * [算法相关](#算法相关) + * [1.LeetCodeAnimation](#1leetcodeanimation) + * [2.awesome-java-leetcode](#2awesome-java-leetcode) + * [3.leetcode](#3leetcode) + + 昨天我整理了公众号历史所有和面试相关的我觉得还不错的文章:[整理了一些有助于你拿Offer的文章]() 。今天分享一下最近逛Github看到了一些我觉得对于Java面试以及学习有帮助的仓库,这些仓库涉及Java核心知识点整理、Java常见面试题、算法、基础知识点比如网络和操作系统等等。 ## 知识点相关 @@ -86,4 +106,4 @@ - Github地址:[https://github.com/azl397985856/leetcode](https://github.com/azl397985856/leetcode) - star: 12.0k -- 介绍: LeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解,记录自己的leetcode解题之路。) \ No newline at end of file +- 介绍: LeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解,记录自己的leetcode解题之路。) diff --git a/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md b/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md index d515693..417d1f9 100644 --- a/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md +++ b/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md @@ -1,3 +1,14 @@ +# Table of Contents + + * [Question1:我是双非/三本/专科学校的,我有机会进入大厂吗?](#question1我是双非三本专科学校的,我有机会进入大厂吗?) + * [Question2:非计算机专业的学生能学好Java后台吗?我能进大厂吗?](#question2非计算机专业的学生能学好java后台吗?我能进大厂吗?) + * [Question3: 我没有实习经历的话找工作是不是特别艰难?](#question3-我没有实习经历的话找工作是不是特别艰难?) + * [Question4: 我该如何准备面试呢?面试的注意事项有哪些呢?](#question4-我该如何准备面试呢?面试的注意事项有哪些呢?) + * [Question5: 我该自学还是报培训班呢?](#question5-我该自学还是报培训班呢?) + * [Question6: 没有项目经历/博客/Github开源项目怎么办?](#question6-没有项目经历博客github开源项目怎么办?) + * [Question7: 大厂到底青睐什么样的应届生?](#question7-大厂到底青睐什么样的应届生?) + +   身边的朋友或者公众号的粉丝很多人都向我询问过:“我是双非/三本/专科学校的,我有机会进入大厂吗?”、“非计算机专业的学生能学好吗?”、“如何学习Java?”、“Java学习该学哪些东西?”、“我该如何准备Java面试?”......这些方面的问题。我会根据自己的一点经验对大部分人关心的这些问题进行答疑解惑。现在又刚好赶上考研结束,这篇文章也算是给考研结束准备往Java后端方向发展的朋友们指明一条学习之路。道理懂了如果没有实际行动,那这篇文章对你或许没有任何意义。 ### Question1:我是双非/三本/专科学校的,我有机会进入大厂吗? diff --git a/docs/interview/PreparingForInterview/interviewPrepare.md b/docs/interview/PreparingForInterview/interviewPrepare.md index 1ae36a3..89a3dc6 100644 --- a/docs/interview/PreparingForInterview/interviewPrepare.md +++ b/docs/interview/PreparingForInterview/interviewPrepare.md @@ -1,3 +1,18 @@ +# Table of Contents + + * [1 如何获取大厂面试机会?](#1-如何获取大厂面试机会?) + * [2 面试前的准备](#2--面试前的准备) + * [2.1 准备自己的自我介绍](#21-准备自己的自我介绍) + * [2.2 关于着装](#22-关于着装) + * [2.3 随身带上自己的成绩单和简历](#23-随身带上自己的成绩单和简历) + * [2.4 如果需要笔试就提前刷一些笔试题](#24-如果需要笔试就提前刷一些笔试题) + * [2.5 花时间一些逻辑题](#25-花时间一些逻辑题) + * [2.6 准备好自己的项目介绍](#26-准备好自己的项目介绍) + * [2.7 提前准备技术面试](#27-提前准备技术面试) + * [2.7 面试之前做好定向复习](#27-面试之前做好定向复习) + * [3 面试之后复盘](#3-面试之后复盘) + + 不论是校招还是社招都避免不了各种面试、笔试,如何去准备这些东西就显得格外重要。不论是笔试还是面试都是有章可循的,我这个“有章可循”说的意思只是说应对技术面试是可以提前准备。 我其实特别不喜欢那种临近考试就提前背啊记啊各种题的行为,非常反对!我觉得这种方法特别极端,而且在稍有一点经验的面试官面前是根本没有用的。建议大家还是一步一个脚印踏踏实实地走。 diff --git "a/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" "b/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" index 7a55d53..0dc99b2 100644 --- "a/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" +++ "b/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [这个问题对最终面试结果的影响到底大不大?](#这个问题对最终面试结果的影响到底大不大) + * [真诚一点,不要问太 Low 的问题](#真诚一点不要问太-low-的问题) + * [有哪些有价值的问题值得问?](#有哪些有价值的问题值得问) + * [面对HR或者其他Level比较低的面试官时](#面对hr或者其他level比较低的面试官时) + * [面对部门领导](#面对部门领导) + * [面对Level比较高的(比如总裁,老板)](#面对level比较高的比如总裁老板) + * [来个补充,顺便送个祝福给大家](#来个补充顺便送个祝福给大家) + + 我还记得当时我去参加面试的时候,几乎每一场面试,特别是HR面和高管面的时候,面试官总是会在结尾问我:“问了你这么多问题了,你有什么问题问我吗?”。这个时候很多人内心就会陷入短暂的纠结中:我该问吗?不问的话面试官会不会对我影响不好?问什么问题?问这个问题会不会让面试官对我的影响不好啊? ![无奈](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/无奈.jpg) @@ -61,4 +72,4 @@ 金三银四。过了二月就到了面试高峰期或者说是黄金期。几份惊喜几份愁,愿各位能始终不忘初心!每个人都有每个人的难处。引用一句《阿甘正传》里面的台词:“生活就像一盒巧克力,你永远不知道下一块是什么味道“。 -![加油!彩虹就要来了](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/生活就像一盒巧克力你永远不知道下一块是什么味道.JPEG) \ No newline at end of file +![加油!彩虹就要来了](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/生活就像一盒巧克力你永远不知道下一块是什么味道.JPEG) diff --git "a/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" "b/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" index 7feead7..096ecaf 100644 --- "a/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" +++ "b/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" @@ -1,3 +1,20 @@ +# Table of Contents + +* [程序员简历就该这样写](#程序员简历就该这样写) + * [为什么说简历很重要?](#为什么说简历很重要?) + * [先从面试前来说](#先从面试前来说) + * [再从面试中来说](#再从面试中来说) + * [下面这几点你必须知道](#下面这几点你必须知道) + * [必须了解的两大法则](#必须了解的两大法则) + * [STAR法则(Situation Task Action Result)](#star法则(situation-task-action-result)) + * [FAB 法则(Feature Advantage Benefit)](#fab-法则(feature-advantage-benefit)) + * [项目经历怎么写?](#项目经历怎么写?) + * [专业技能该怎么写?](#专业技能该怎么写?) + * [排版注意事项](#排版注意事项) + * [其他的一些小tips](#其他的一些小tips) + * [推荐的工具/网站](#推荐的工具网站) + + - [程序员简历就该这样写](#程序员简历就该这样写) diff --git "a/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" "b/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" index a76eed8..4e62535 100644 --- "a/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" +++ "b/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" @@ -1,3 +1,74 @@ +# Table of Contents + +* [一 基础篇](#一-基础篇) + * [1. `System.out.println(3|9)`输出什么?](#1-`systemoutprintln39`输出什么) + * [2. 说一下转发(Forward)和重定向(Redirect)的区别](#2-说一下转发forward和重定向redirect的区别) + * [3. 在浏览器中输入url地址到显示主页的过程,整个过程会使用哪些协议](#3-在浏览器中输入url地址到显示主页的过程整个过程会使用哪些协议) + * [4. TCP 三次握手和四次挥手](#4-tcp-三次握手和四次挥手) + * [为什么要三次握手](#为什么要三次握手) + * [为什么要传回 SYN](#为什么要传回-syn) + * [传了 SYN,为啥还要传 ACK](#传了-syn为啥还要传-ack) + * [为什么要四次挥手](#为什么要四次挥手) + * [5. IP地址与MAC地址的区别](#5-ip地址与mac地址的区别) + * [6. HTTP请求,响应报文格式](#6-http请求响应报文格式) + * [7. 为什么要使用索引?索引这么多优点,为什么不对表中的每一个列创建一个索引呢?索引是如何提高查询速度的?说一下使用索引的注意事项?Mysql索引主要使用的两种数据结构?什么是覆盖索引?](#7-为什么要使用索引索引这么多优点为什么不对表中的每一个列创建一个索引呢索引是如何提高查询速度的说一下使用索引的注意事项mysql索引主要使用的两种数据结构什么是覆盖索引) + * [8. 进程与线程的区别是什么?进程间的几种通信方式说一下?线程间的几种通信方式知道不?](#8-进程与线程的区别是什么进程间的几种通信方式说一下线程间的几种通信方式知道不) + * [9. 为什么要用单例模式?手写几种线程安全的单例模式?](#9-为什么要用单例模式手写几种线程安全的单例模式) + * [10. 简单介绍一下bean;知道Spring的bean的作用域与生命周期吗?](#10-简单介绍一下bean知道spring的bean的作用域与生命周期吗) + * [11. Spring 中的事务传播行为了解吗?TransactionDefinition 接口中哪五个表示隔离级别的常量?](#11-spring-中的事务传播行为了解吗transactiondefinition-接口中哪五个表示隔离级别的常量) + * [事务传播行为](#事务传播行为) + * [隔离级别](#隔离级别) + * [12. SpringMVC 原理了解吗?](#12-springmvc-原理了解吗) + * [13. Spring AOP IOC 实现原理](#13-spring-aop-ioc-实现原理) +* [二 进阶篇](#二-进阶篇) + * [1 消息队列MQ的套路](#1-消息队列mq的套路) + * [1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处](#11-介绍一下消息队列mq的应用场景使用消息队列的好处) + * [1)通过异步处理提高系统性能](#1通过异步处理提高系统性能) + * [2)降低系统耦合性](#2降低系统耦合性) + * [1.2 那么使用消息队列会带来什么问题?考虑过这些问题吗?](#12-那么使用消息队列会带来什么问题考虑过这些问题吗) + * [1.3 介绍一下你知道哪几种消息队列,该如何选择呢?](#13-介绍一下你知道哪几种消息队列该如何选择呢) + * [1.4 关于消息队列其他一些常见的问题展望](#14-关于消息队列其他一些常见的问题展望) + * [2 谈谈 InnoDB 和 MyIsam 两者的区别](#2-谈谈-innodb-和-myisam-两者的区别) + * [2.1 两者的对比](#21-两者的对比) + * [2.2 关于两者的总结](#22-关于两者的总结) + * [3 聊聊 Java 中的集合吧!](#3-聊聊-java-中的集合吧) + * [3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容)](#31-arraylist-与-linkedlist-有什么不同注意加上从数据结构分析的内容) + * [3.2 HashMap的底层实现](#32-hashmap的底层实现) + * [1)JDK1.8之前](#1jdk18之前) + * [2)JDK1.8之后](#2jdk18之后) + * [3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解](#33-既然谈到了红黑树你给我手绘一个出来吧然后简单讲一下自己对于红黑树的理解) + * [3.4 红黑树这么优秀,为何不直接使用红黑树得了?](#34-红黑树这么优秀为何不直接使用红黑树得了) + * [3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别](#35-hashmap-和-hashtable-的区别hashset-和-hashmap-区别) +* [三 终结篇](#三-终结篇) + * [1. Object类有哪些方法?](#1-object类有哪些方法) + * [1.1 Object类的常见方法总结](#11-object类的常见方法总结) + * [1.2 hashCode与equals](#12-hashcode与equals) + * [1.2.1 hashCode()介绍](#121-hashcode介绍) + * [1.2.2 为什么要有hashCode](#122-为什么要有hashcode) + * [1.2.3 hashCode()与equals()的相关规定](#123-hashcode与equals的相关规定) + * [1.2.4 为什么两个对象有相同的hashcode值,它们也不一定是相等的?](#124-为什么两个对象有相同的hashcode值它们也不一定是相等的) + * [1.3 ==与equals](#13--与equals) + * [2 ConcurrentHashMap 相关问题](#2-concurrenthashmap-相关问题) + * [2.1 ConcurrentHashMap 和 Hashtable 的区别](#21-concurrenthashmap-和-hashtable-的区别) + * [2.2 ConcurrentHashMap线程安全的具体实现方式/底层具体实现](#22-concurrenthashmap线程安全的具体实现方式底层具体实现) + * [JDK1.7(上面有示意图)](#jdk17上面有示意图) + * [JDK1.8(上面有示意图)](#jdk18上面有示意图) + * [3 谈谈 synchronized 和 ReentrantLock 的区别](#3-谈谈-synchronized-和-reentrantlock-的区别) + * [4 线程池了解吗?](#4-线程池了解吗) + * [4.1 为什么要用线程池?](#41-为什么要用线程池) + * [4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么?](#42-java-提供了哪几种线程池他们各自的使用场景是什么) + * [Java 主要提供了下面4种线程池](#java-主要提供了下面4种线程池) + * [各种线程池的适用场景介绍](#各种线程池的适用场景介绍) + * [4.3 创建的线程池的方式](#43-创建的线程池的方式) + * [5 Nginx](#5-nginx) + * [5.1 简单介绍一下Nginx](#51-简单介绍一下nginx) + * [反向代理](#反向代理) + * [负载均衡](#负载均衡) + * [动静分离](#动静分离) + * [5.2 为什么要用 Nginx?](#52-为什么要用-nginx) + * [5.3 Nginx 的四个主要组成部分了解吗?](#53-nginx-的四个主要组成部分了解吗) + + - [一 基础篇](#一-基础篇) diff --git "a/docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md" "b/docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md" index 7b4af07..39d6ef8 100644 --- "a/docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md" +++ "b/docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md" @@ -1,3 +1,23 @@ +# Table of Contents + + * [Servlet及相关类](#servlet及相关类) + * [Jsp和ViewResolver](#jsp和viewresolver) + * [filter,listener](#filter,listener) + * [web.xml](#webxml) + * [war包](#war包) + * [tomcat基础](#tomcat基础) + * [log4j](#log4j) + * [数据库驱动和连接池](#数据库驱动和连接池) + * [单元测试](#单元测试) + * [Maven](#maven) + * [Git](#git) + * [Json和xml](#json和xml) + * [hibernate和mybatis](#hibernate和mybatis) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: JavaWeb技术总结 date: 2018-07-08 22:13:33 @@ -133,4 +153,4 @@ mybatis比hibernate更轻量级,mybatis支持原生sql查询,并且也可以 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" index c97f2bb..167e1fe 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" @@ -1,3 +1,19 @@ +# Table of Contents + + * [Web MVC简介](#web-mvc简介) + * [Web开发中的请求-响应模型:](#web开发中的请求-响应模型:) + * [标准MVC模型概述](#标准mvc模型概述) + * [Web MVC概述](#web-mvc概述) + * [Web端开发发展历程](#web端开发发展历程) + * [Spring Web MVC是什么](#spring-web-mvc是什么) + * [Spring Web MVC能帮我们做什么](#spring-web-mvc能帮我们做什么) + * [Spring Web MVC架构](#spring-web-mvc架构) + * [Spring Web MVC处理请求的流程](#spring-web-mvc处理请求的流程) + * [Spring Web MVC架构](#spring-web-mvc架构-1) + * [Spring Web MVC优势](#spring-web-mvc优势) + * [DispatcherServlet作用](#dispatcherservlet作用) + + 转自:[跟开涛学SpringMVC](http://jinnianshilongnian.iteye.com/category/231099) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1221,4 +1237,4 @@ DispatcherServlet主要用作职责调度工作,本身主要用于控制流程 作者:黄小斜 链接:http://www.imooc.com/article/291594?block_id=tuijian_wz -来源:慕课网 \ No newline at end of file +来源:慕课网 diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" index 93c3633..fb56599 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [SpringMVC简介](#springmvc简介) + * [HandlerMapping接口](#handlermapping接口) + * [DispatcherServlet接受请求并找到对应Handler](#dispatcherservlet接受请求并找到对应handler) + * [HandlerInterceptor接口](#handlerinterceptor接口) + * [HandlerAdapter](#handleradapter) + * [请求流程总结](#请求流程总结) + + 转自:https://my.oschina.net/lichhao/blog 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -324,4 +334,4 @@ public interface View { 在一个典型的SpringMVC调用中,HandlerExecutionChain中封装handler对象就是用@Controller注解标识的类的一个实例,根据类级别和方法级别的@RequestMapping注解,由默认注册的DefaultAnnotationHandlerMapping(3.1.3中更新为RequestMappingHandlerMapping类,但是为了向后兼容,DefaultAnnotationHandlerMapping也可以使用)生成HandlerExecutionChain对象,再由AnnotationMethodHandlerAdapter(3.1.3中更新为RequestMappingHandlerAdapter类,但是为了向后兼容,AnnotationMethodHandlerAdapter也可以使用)来执行这个HandlerExecutionChain对象,生成最终的ModelAndView对象后,再由具体的View对象的render方法渲染视图。 -可以看到,作为一个表现层框架,SpringMVC没有像Struts2那样激进,并没有采用和Web容器完全解耦的设计思想,而是以原生的Servlet框架对象为依托,通过合理的抽象,制定了严谨的的处理流程。这样做的结果是,执行效率比Struts2要高,灵活性也上升了一个层次。 \ No newline at end of file +可以看到,作为一个表现层框架,SpringMVC没有像Struts2那样激进,并没有采用和Web容器完全解耦的设计思想,而是以原生的Servlet框架对象为依托,通过合理的抽象,制定了严谨的的处理流程。这样做的结果是,执行效率比Struts2要高,灵活性也上升了一个层次。 diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" index 194f86b..521604c 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [前言](#前言) + * [配置元素读取](#init-param配置元素读取init-param) + * [容器上下文的建立](#容器上下文的建立) + * [初始化SpringMVC默认实现类](#初始化springmvc默认实现类) +* [Default implementation classes for DispatcherServlet's strategy interfaces.](#default-implementation-classes-for-dispatcherservlets-strategy-interfaces) +* [Used as fallback when no matching beans are found in the DispatcherServlet context.](#used-as-fallback-when-no-matching-beans-are-found-in-the-dispatcherservlet-context) +* [Not meant to be customized by application developers.](#not-meant-to-be-customized-by-application-developers) + * [总结](#总结) + + 本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" index cf6171d..e349d33 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [前言](#前言) + * [源码分析](#源码分析) + * [实例](#实例) + * [资源文件映射](#资源文件映射) + * [总结](#总结) + + 本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -329,4 +338,4 @@ ResourceHttpRequestHandler进行handleRequest的时候,直接输出资源文 大致上整理了一下SpringMVC对请求的处理,包括其中比较关键的类和接口,希望对读者有帮助。 -让自己对SpringMVC有了更深入的认识,也为之后分析数据绑定,拦截器、HandlerAdapter等打下基础。 \ No newline at end of file +让自己对SpringMVC有了更深入的认识,也为之后分析数据绑定,拦截器、HandlerAdapter等打下基础。 diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" index 68e49df..e1fe779 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [目录](#目录) + * [前言](#前言) + * [重要接口和类介绍](#重要接口和类介绍) + * [源码分析](#源码分析) + * [编码自定义的ViewResolver](#编码自定义的viewresolver) + * [This is jsp page](#this-is-jsp-page) + * [This is freemarker page](#this-is-freemarker-page) + * [总结](#总结) + + 转自 [SpringMVC视图机制详解[附带源码分析]](https://www.cnblogs.com/fangjian0423/p/springMVC-view-viewResolver.html) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -382,4 +394,4 @@ public class TestViewResolverController { 希望这篇文章能帮助读者了解SpringMVC视图机制。 -文中难免有错误,希望读者能够指明出来。 \ No newline at end of file +文中难免有错误,希望读者能够指明出来。 diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" index 88d879b..7a3c1d0 100644 --- "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" +++ "b/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [目录](#目录) + * [前言](#前言) + * [现象](#现象) + * [源码分析](#源码分析) + * [实例讲解](#实例讲解) + * [关于配置](#关于配置) + * [总结](#总结) + * [详解RequestBody和@ResponseBody注解](#详解requestbody和responsebody注解) + * [参考资料](#参考资料) + + 转自 [SpringMVC关于json、xml自动转换的原理研究[附带源码分析]](https://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2201\357\274\232Spring\346\246\202\350\277\260.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2201\357\274\232Spring\346\246\202\350\277\260.md" index 34777de..0aa081b 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2201\357\274\232Spring\346\246\202\350\277\260.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2201\357\274\232Spring\346\246\202\350\277\260.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [Spring是什么](#spring是什么) + * [Spring能帮我们做什么](#spring能帮我们做什么) + * [为何需要Spring](#为何需要spring) + * [为什么需要Spring及Spring的优点](#为什么需要spring及spring的优点) + * [如何学好Spring](#如何学好spring) + + 原文出处: [张开涛](http://sishuok.com/forum/blogPost/list/0/2508.html) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" index e7ba103..50490ce 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [前言](#前言) + * [准备](#准备) + * [读取](#读取) + * [解析](#解析) + * [注册](#注册) + * [注入依赖](#注入依赖) + + 本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" index d75a51a..50c5dc2 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [spring ioc 容器的加载流程](#spring-ioc-容器的加载流程) + * [Spring Ioc Demo](#spring-ioc-demo) + * [ApplicationContext 继承结构](#applicationcontext-继承结构) + * [Spring Ioc容器加载过程源码详解](#spring-ioc容器加载过程源码详解) +* [refresh()方法](#refresh方法) + * [调试栈截图](#调试栈截图) + * [整体流程](#整体流程) + * [bean.xml的处理](#beanxml的处理) + * [loadBeanDefinitions](#loadbeandefinitions) + * [loadBeanDefinitions: 源码阅读](#loadbeandefinitions-源码阅读) +* [loadBeanDefinitions](#loadbeandefinitions-1) + + 本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1282,4 +1297,4 @@ XmlBeanDefinitionReader(计数、解析XML文档),BeanDefinitionDocumentRe 可以看出,在解析bean的过程中,这3个组件的分工是比较清晰的,各司其职,这种设计思想值得学习 -到此为止,bean的解析、注册、spring ioc 容器的实例化过程就基本分析结束了。 \ No newline at end of file +到此为止,bean的解析、注册、spring ioc 容器的实例化过程就基本分析结束了。 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2204\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2204\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" index 9c097b8..3d41877 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2204\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2204\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [前言](#前言) + * [step1:](#step1) + * [step2:](#step2) + * [step3 : 我们已经step by step 的看到了如何将xml文件转换成Document的,现在就要分析是如何提取和注册bean的。](#step3--我们已经step-by-step-的看到了如何将xml文件转换成document的,现在就要分析是如何提取和注册bean的。) + + 本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -143,4 +151,4 @@ Spring容器的BeanDefinitonRegistry就像是Spring配置信息的内存数据 然后就是各种对属性的解析的具体方法: -![89c0d5422e0495347f18fa03110bfb2afa255493](https://oss-cn-hangzhou.aliyuncs.com/yqfiles/89c0d5422e0495347f18fa03110bfb2afa255493.png) \ No newline at end of file +![89c0d5422e0495347f18fa03110bfb2afa255493](https://oss-cn-hangzhou.aliyuncs.com/yqfiles/89c0d5422e0495347f18fa03110bfb2afa255493.png) diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" index ba653e2..5bd2ca0 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -1,3 +1,19 @@ +# Table of Contents + + * [前言](#前言) + * [Java代理介绍](#java代理介绍) + * [静态代理](#静态代理) + * [JDK动态代理](#jdk动态代理) + * [JDK动态代理实现原理](#jdk动态代理实现原理) + * [Proxy类中的newProxyInstance](#proxy类中的newproxyinstance) + * [字节码生成](#字节码生成) + * [代理类的方法调用](#代理类的方法调用) + * [深入理解CGLIB动态代理机制](#深入理解cglib动态代理机制) + * [CGLIB动态代理示例](#cglib动态代理示例) + * [生成代理类对象](#生成代理类对象) + * [对委托类进行代理](#对委托类进行代理) + + 转自 https://www.jianshu.com/u/668d0795a95b 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -858,4 +874,4 @@ public class HelloServiceImpl$EnhancerByCGLIB$82ef2d06 | --- | --- | --- | --- | --- | | JDK静态代理 | 代理类与委托类实现同一接口,并且在代理类中需要硬编码接口 | 实现简单,容易理解 | 代理类需要硬编码接口,在实际应用中可能会导致重复编码,浪费存储空间并且效率很低 | 好像没啥特点 | | JDK动态代理 | 代理类与委托类实现同一接口,主要是通过代理类实现InvocationHandler并重写invoke方法来进行动态代理的,在invoke方法中将对方法进行增强处理 | 不需要硬编码接口,代码复用率高 | 只能够代理实现了接口的委托类 | 底层使用反射机制进行方法的调用 | -| CGLIB动态代理 | 代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理 | 可以在运行时对类或者是接口进行增强操作,且委托类无需实现接口 | 不能对final类以及final方法进行代理 | 底层将方法全部存入一个数组中,通过数组索引直接进行方法调用 | \ No newline at end of file +| CGLIB动态代理 | 代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理 | 可以在运行时对类或者是接口进行增强操作,且委托类无需实现接口 | 不能对final类以及final方法进行代理 | 底层将方法全部存入一个数组中,通过数组索引直接进行方法调用 | diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" index cbf4ade..87e1208 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [我们为什么要使用 AOP](#我们为什么要使用-aop) + * [使用装饰器模式](#使用装饰器模式) + * [使用代理模式](#使用代理模式) + * [使用CGLIB](#使用cglib) + * [使用AOP](#使用aop) + * [AOP总结](#aop总结) + + 本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -459,4 +469,4 @@ public class PermissionHandler { > 微信公众号【黄小斜】作者是蚂蚁金服 JAVA 工程师,专注于 JAVA > 后端技术栈:SpringBoot、SSM全家桶、MySQL、分布式、中间件、微服务,同时也懂点投资理财,坚持学习和写作,相信终身学习的力量!关注公众号后回复”架构师“即可领取 -> Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源 \ No newline at end of file +> Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2207\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2207\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" index 37d7b1f..03b0de6 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2207\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2207\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [AOP实现原理——找到Spring处理AOP的源头](#aop实现原理找到spring处理aop的源头) + * [解析增强器advisor](#解析增强器advisor) + * [解析切面的过程](#解析切面的过程) + * [AOP为Bean生成代理的时机分析](#aop为bean生成代理的时机分析) + * [代理对象实例化过程](#代理对象实例化过程) + * [平时我们说AOP原理三句话就能概括:](#平时我们说aop原理三句话就能概括:) + * [代理方法调用原理](#代理方法调用原理) + * [CGLIB代理实现](#cglib代理实现) + + 本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1097,4 +1109,4 @@ chain.get(2):AspectJAfterAdvice,用于在实际方法调用之后的处理 这里我们看到了与JDK动态代理同样的获取拦截器链的过程,并且CglibMethodInvokcation继承了我们在JDK动态代理看到的ReflectiveMethodInvocation,但是并没有重写其proceed方法,只是重写了执行目标方法的逻辑,所以整体上是大同小异的。 -到这里,整个Spring 动态AOP的源码就分析完了,Spring还支持静态AOP,这里就不过多赘述了,有兴趣的读者可以查阅相关资料来学习。 \ No newline at end of file +到这里,整个Spring 动态AOP的源码就分析完了,Spring还支持静态AOP,这里就不过多赘述了,有兴趣的读者可以查阅相关资料来学习。 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2208\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2208\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" index b88db5c..bbf94f7 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2208\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2208\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" @@ -1,3 +1,21 @@ +# Table of Contents + + * [数据库事务概述](#数据库事务概述) + * [事务类型](#事务类型) + * [Spring提供的事务管理](#spring提供的事务管理) + * [spring事务特性](#spring事务特性) + * [事务隔离级别](#事务隔离级别) + * [事务传播行为](#事务传播行为) + * [事务超时](#事务超时) + * [事务只读属性](#事务只读属性) + * [概述](#概述) + * [内置事务管理器实现](#内置事务管理器实现) + * [声明式事务](#声明式事务) + * [声明式事务概述](#声明式事务概述) + * [声明式实现事务管理](#声明式实现事务管理) + * [@Transactional实现事务管理](#transactional实现事务管理) + + 原文出处: [张开涛](http://sishuok.com/forum/blogPost/list/0/2508.html) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -595,4 +613,4 @@ Spring提供的@Transactional 注解事务管理内部同样利用环绕通知Tr 默认只对RuntimeException异常回滚; 在使用Spring代理时,默认只有在public可见度的方法的@Transactional 注解才是有效的,其它可见度(protected、private、包可见)的方法上即使有@Transactional -注解也不会应用这些事务属性的,Spring也不会报错,如果你非要使用非公共方法注解事务管理的话,可考虑使用AspectJ。 \ No newline at end of file +注解也不会应用这些事务属性的,Spring也不会报错,如果你非要使用非公共方法注解事务管理的话,可考虑使用AspectJ。 diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2209\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2209\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" index 75c9551..829f645 100644 --- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2209\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" +++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2209\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [声明式事务使用](#声明式事务使用) + * [TxNamespaceHandler](#txnamespacehandler) + * [注册事务功能bean](#注册事务功能bean) + * [使用bean的后处理方法获取增强器](#使用bean的后处理方法获取增强器) + * [Spring获取匹配的增强器](#spring获取匹配的增强器) + * [Transactional注解](#transactional注解) + * [开启事务过程](#开启事务过程) + + 转自:http://www.linkedkeeper.com/detail/blog.action?bid=1045 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -260,4 +271,4 @@ suspend挂起操作主要目的是将当前connectionHolder置为null,保存 http://blog.163.com/asd_wll/blog/static/2103104020124801348674/ -https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#spring-data-tier \ No newline at end of file +https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#spring-data-tier diff --git "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" "b/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" index da2cf0a..44c55aa 100644 --- "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" +++ "b/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" @@ -1,3 +1,28 @@ +# Table of Contents + + * [一、抛砖引玉:探索Spring IoC容器](#一、抛砖引玉:探索spring-ioc容器) + * [1.1、Spring IoC容器](#11、spring-ioc容器) + * [1.2、Spring容器扩展机制](#12、spring容器扩展机制) + * [二、夯实基础:JavaConfig与常见Annotation](#二、夯实基础:javaconfig与常见annotation) + * [2.1、JavaConfig](#21、javaconfig) + * [2.2、@ComponentScan](#22、componentscan) + * [2.3、@Import](#23、import) + * [2.4、@Conditional](#24、conditional) + * [2.5、@ConfigurationProperties与@EnableConfigurationProperties](#25、configurationproperties与enableconfigurationproperties) + * [](#) + * [三、削铁如泥:SpringFactoriesLoader详解](#三、削铁如泥:springfactoriesloader详解) + * [四、另一件武器:Spring容器的事件监听机制](#四、另一件武器:spring容器的事件监听机制) + * [Spring容器内的事件监听机制](#spring容器内的事件监听机制) + * [五、出神入化:揭秘自动配置原理](#五、出神入化:揭秘自动配置原理) + * [六、启动引导:Spring Boot应用启动的秘密](#六、启动引导:spring-boot应用启动的秘密) + * [6.1 SpringApplication初始化](#61-springapplication初始化) + * [6.2 Spring Boot启动流程](#62-spring-boot启动流程) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1054,4 +1079,4 @@ public void initialize(ConfigurableApplicationContext context) { ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" "b/docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" index fcb6a81..6e98136 100644 --- "a/docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" +++ "b/docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [引言](#引言) + * [工作原理原型图](#工作原理原型图) + * [工作原理解析](#工作原理解析) + * [mybatis层次图:](#mybatis层次图:) + * [[MyBatis框架及原理分析](https://www.cnblogs.com/adolfmc/p/8997281.html)](#[mybatis框架及原理分析]httpswwwcnblogscomadolfmcp8997281html) + * [MyBatis的配置](#mybatis的配置) + * [MyBatis的主要成员](#mybatis的主要成员) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -165,4 +180,4 @@ https://blog.csdn.net/weixin_43184769/article/details/91126687 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" index bd5e2dd..cb7f41f 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [**Java Bean**](#java-bean) + * [**JSP + Java Bean**](#jsp--java-bean) + * [Enterprise Java bean](#enterprise-java-bean) + * [Spring](#spring) + * [JavaBean 和 Spring中Bean的区别](#javabean-和-spring中bean的区别) + * [Jave bean](#jave-bean) + * [spring bean](#spring bean) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -261,4 +276,4 @@ https://blog.csdn.net/qq_42245219/article/details/82748460 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" index 3ffbe2c..f9ae3cc 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" @@ -1,3 +1,27 @@ +# Table of Contents + + * [简介](#简介) + * [概述](#概述) + * [好处](#好处) + * [Junit单元测试](#junit单元测试) + * [1 简介](#1-简介) + * [2 特点](#2-特点) + * [3 内容](#3-内容) + * [3.1 注解](#31-注解) + * [3.2 断言](#32-断言) + * [4 JUnit 3.X 和 JUnit 4.X 的区别](#4-junit-3x-和-junit-4x-的区别) + * [4.1 JUnit 3.X](#41-junit-3x) + * [4.2 JUnit 4.X](#42-junit-4x) + * [4.3 特别提醒](#43-特别提醒) + * [5 测试示例](#5-测试示例) + * [5.1 示例一:简单的 JUnit 3.X 测试](#51-示例一:简单的-junit-3x-测试) + * [6 个人建议](#6-个人建议) + * [8 大单元测试框架](#8-大单元测试框架) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -451,4 +475,4 @@ PowerMock是用于对源代码进行单元测试的Java框架,它可以作为 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" index 26b0cfe..389bac7 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" @@ -1,3 +1,31 @@ +# Table of Contents + + * [maven简介](#maven简介) + * [1.1 Maven是什么](#11-maven是什么) + * [1.2 Maven发展史](#12-maven发展史) + * [1.3 为什么要用Maven](#13-为什么要用maven) + * [Maven 新手入门](#maven-新手入门) + * [Maven概念](#maven概念) + * [maven的安装](#maven的安装) + * [maven目录](#maven目录) + * [Maven常用命令说明](#maven常用命令说明) + * [Maven使用](#maven使用) + * [[](http://tengj.top/2018/01/01/maven/#%E4%BE%9D%E8%B5%96%E7%9A%84%E9%85%8D%E7%BD%AE "依赖的配置")依赖的配置](#[]httptengjtop20180101mavene4be9de8b596e79a84e9858de7bdae-依赖的配置依赖的配置) + * [[](http://tengj.top/2018/01/01/maven/#%E4%BE%9D%E8%B5%96%E8%8C%83%E5%9B%B4 "依赖范围")依赖范围](#[]httptengjtop20180101mavene4be9de8b596e88c83e59bb4-依赖范围依赖范围) + * [传递性依赖](#传递性依赖) + * [依赖范围](#依赖范围) + * [Maven和Gradle的比较](#maven和gradle的比较) + * [依赖管理系统](#依赖管理系统) + * [多模块构建](#多模块构建) + * [一致的项目结构](#一致的项目结构) + * [一致的构建模型](#一致的构建模型) + * [插件机制](#插件机制) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -322,4 +350,4 @@ https://blog.csdn.net/u012131888/article/details/78209514 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" index ec6715c..dc4bd06 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [前言](#前言) + * [ORM概述](#orm概述) + * [测试](#测试) + * [相关类](#相关类) + * [扩展](#扩展) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -1064,4 +1077,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" index 9e3a03c..9957a37 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" @@ -1,3 +1,29 @@ +# Table of Contents + + * [前言](#前言) + * [Mybatis是什么](#mybatis是什么) + * [特点](#特点) + * [核心类介绍](#核心类介绍) + * [功能架构:我们把Mybatis的功能架构分为三层](#功能架构:我们把mybatis的功能架构分为三层) + * [框架结构:](#框架结构:) + * [执行流程:](#执行流程:) + * [与Hibernate的异同](#与hibernate的异同) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:黄小斜](#个人公众号:黄小斜) +* [mybatis新手上路](#mybatis新手上路) + * [MyBatis简介](#mybatis简介) + * [MyBatis整体架构及运行流程](#mybatis整体架构及运行流程) + * [1.数据源配置文件](#1数据源配置文件) + * [2.Sql映射文件](#2sql映射文件) + * [3.会话工厂与会话](#3会话工厂与会话) + * [4.运行流程](#4运行流程) + * [测试工程搭建](#测试工程搭建) + * [微信公众号](#微信公众号-1) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -423,4 +449,4 @@ public class TestClient { //定义会话SqlSession ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" index 6276375..93de865 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" @@ -1,3 +1,26 @@ +# Table of Contents + + * [Spring Boot 概述](#spring-boot-概述) + * [什么是 Spring Boot](#什么是-spring-boot) + * [使用 Spring Boot 有什么好处](#使用-spring-boot-有什么好处) + * [Spring Boot 快速搭建](#spring-boot-快速搭建) + * [第一步:新建项目](#第一步:新建项目) + * [第二步:HelloController](#第二步:hellocontroller) + * [第三步:利用 IDEA 启动 Spring Boot](#第三步:利用-idea-启动-spring-boot) + * [解析 Spring Boot 项目](#解析-spring-boot-项目) + * [解析 pom.xml 文件](#解析-pomxml-文件) + * [应用入口类](#应用入口类) + * [Spring Boot 的配置文件](#spring-boot-的配置文件) + * [Spring Boot 热部署](#spring-boot-热部署) + * [Spring Boot 使用](#spring-boot-使用) + * [Spring Boot 支持 JSP](#spring-boot-支持-jsp) + * [集成 MyBatis](#集成-mybatis) + * [springMVC和springboot的区别](#springmvc和springboot的区别) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -537,4 +560,4 @@ Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" index 88efa20..df4d6d5 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -1,3 +1,20 @@ +# Table of Contents + + * [什么是 Java Web](#什么是-java-web) + * [Web开发的历史](#web开发的历史) + * [开源框架时代](#开源框架时代) + * [Java Web基础知识](#java-web基础知识) + * [一、HTTP协议](#一、http协议) + * [二、服务器](#二、服务器) + * [1、概念](#1、概念) + * [2、web服务器](#2、web服务器) + * [三、JavaWeb项目结构](#三、javaweb项目结构) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -255,4 +272,4 @@ https://blog.csdn.net/qq_41911570/article/details/83279327 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" index d6c202a..1aafcee 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" @@ -1,3 +1,23 @@ +# Table of Contents + + * [servlet和jsp的区别](#servlet和jsp的区别) + * [servlet和jsp各自的特点](#servlet和jsp各自的特点) + * [通过MVC双剑合璧](#通过mvc双剑合璧) + * [JavaWeb基础知识](#javaweb基础知识) + * [一、Servlet 是什么?](#一、servlet-是什么?) + * [二、Servlet的生命周期](#二、servlet的生命周期) + * [init() 方法](#init-方法) + * [service() 方法](#service-方法) + * [ destroy() 方法](# destroy-方法) + * [相关面试题](#相关面试题) + * [怎样理解Servlet的单实例多线程?**](#怎样理解servlet的单实例多线程?) + * [JSP的中存在的多线程问题:](#jsp的中存在的多线程问题:) + * [如何开发线程安全的Servlet](#如何开发线程安全的servlet) + * [同步对共享数据的操作](#同步对共享数据的操作) + * [五、servlet与jsp的区别](#五、servlet与jsp的区别) + * [参考文章](#参考文章) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" index 9b0e0c9..7b1dc3f 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" @@ -1,3 +1,22 @@ +# Table of Contents + +* [JDBC数据库连接池](#jdbc数据库连接池) + * [谈谈连接池、线程池技术原理](#谈谈连接池、线程池技术原理) +* [JDBC 数据库连接池 ](#jdbc-数据库连接池 ) + * [什么情况下使用连接池?](#什么情况下使用连接池) + * [使用连接池的好处](#使用连接池的好处) + * [连接池的实现](#连接池的实现) + * [常用数据库连接池](#常用数据库连接池) + * [一、JDBC数据库连接池的必要性](#一、jdbc数据库连接池的必要性) + * [二、数据库连接池(connection pool)](#二、数据库连接池(connection-pool)) + * [  数据库连接池简单介绍](#  数据库连接池简单介绍) + * [  数据库连接池工作原理:](#  数据库连接池工作原理:) + * [  数据库连接池技术的优点](#  数据库连接池技术的优点) + * [  **资源重用:**](#  资源重用:) + * [三、两种开源的数据库连接池](#三、两种开源的数据库连接池) + * [参考文章](#参考文章) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" index ac97b74..7624200 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [什么是Servlet](#什么是servlet) + * [Servlet体系结构](#servlet体系结构) + * [Servlet工作原理](#servlet工作原理) + * [Servlet生命周期](#servlet生命周期) + * [Servlet中的Listener](#servlet中的listener) +* [Cookie与Session](#cookie与session) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -388,4 +402,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" index bfff643..a21cbb6 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" @@ -1,3 +1,13 @@ +# Table of Contents + +* [[走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程](https://www.cnblogs.com/xll1025/p/11366264.html)](#[走进javaweb技术世界5:初探tomcat的http请求过程]httpswwwcnblogscomxll1025p11366264html) + * [初探Tomcat的HTTP请求过程](#初探tomcat的http请求过程) + * [Tomcat的组织结构](#tomcat的组织结构) + * [由Server.xml的结构看Tomcat的体系结构](#由serverxml的结构看tomcat的体系结构) + * [Tomcat Server处理一个HTTP请求的过程](#tomcat-server处理一个http请求的过程) + * [参考文章](#参考文章) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" index 81f92c1..b57d34b 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" @@ -1,3 +1,50 @@ +# Table of Contents + + * [Tomcat 总体结构](#tomcat-总体结构) + * [以 Service 作为“婚姻”](#以-service-作为婚姻) + * [图 2\. Service 接口](#图-2-service-接口) + * [图 3\. StandardService 的类结构图](#图-3-standardservice-的类结构图) + * [清单 1\. StandardService. SetContainer](#清单-1-standardservice-setcontainer) + * [清单 2\. StandardService. addConnector](#清单-2-standardservice-addconnector) + * [以 Server 为“居”](#以-server-为居) + * [图 4\. Server 的类结构图](#图-4-server-的类结构图) + * [清单 3\. StandardServer.addService](#清单-3-standardserveraddservice) + * [组件的生命线“Lifecycle”](#组件的生命线lifecycle) + * [图 5\. Lifecycle 类结构图](#图-5-lifecycle-类结构图) + * [清单 4\. StandardServer.Start](#清单-4-standardserverstart) + * [清单 5\. StandardServer.Stop](#清单-5-standardserverstop) + * [Connector 组件](#connector-组件) + * [图 6\. Connector 处理一次请求顺序图](#图-6-connector-处理一次请求顺序图) + * [图 7\. Connector 的主要类图](#图-7-connector-的主要类图) + * [清单 6\. HttpConnector.Start](#清单-6-httpconnectorstart) + * [清单 7\. HttpProcessor.assign](#清单-7-httpprocessorassign) + * [清单 8\. HttpProcessor.Run](#清单-8-httpprocessorrun) + * [清单 9\. HttpProcessor.process](#清单-9-httpprocessorprocess) + * [Servlet 容器“Container”](#servlet-容器container) + * [清单 10\. Server.xml](#清单-10-serverxml) + * [容器的总体设计](#容器的总体设计) + * [图 8\. 四个容器的关系图](#图-8-四个容器的关系图) + * [图 9\. Engine 和 Host 处理请求的时序图](#图-9-engine-和-host-处理请求的时序图) + * [清单 11\. Server.xml](#清单-11-serverxml) + * [图 10\. Context 和 wrapper 的处理请求时序图](#图-10-context-和-wrapper-的处理请求时序图) + * [Engine 容器](#engine-容器) + * [图 11\. Engine 接口的类结构](#图-11-engine-接口的类结构) + * [清单 12\. StandardEngine. addChild](#清单-12-standardengine-addchild) + * [Host 容器](#host-容器) + * [图 12\. Host 相关的类图](#图-12-host-相关的类图) + * [Context 容器](#context-容器) + * [清单 13\. StandardContext.start](#清单-13-standardcontextstart) + * [清单 14\. Server.xml](#清单-14-serverxml) + * [清单 15\. StandardContext. backgroundProcess](#清单-15-standardcontext-backgroundprocess) + * [Wrapper 容器](#wrapper-容器) + * [清单 16\. StandardWrapper.loadServlet](#清单-16-standardwrapperloadservlet) + * [图 13\. ServletConfig 与 StandardWrapperFacade、StandardWrapper 的关系](#图-13-servletconfig-与-standardwrapperfacade、standardwrapper-的关系) + * [Tomcat 中其它组件](#tomcat-中其它组件) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -1150,4 +1197,4 @@ Tomcat 还有其它重要的组件,如安全组件 security、logger 日志组 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" index c51bd64..e9edcbb 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [Tomcat和物理服务器的区别](#tomcat和物理服务器的区别) + * [Tomcat:](#tomcat:) + * [物理服务器:](#物理服务器:) + * [详解tomcat 与 nginx,apache的区别及优缺点](#详解tomcat-与-nginx,apache的区别及优缺点) + * [定义:](#定义:) + * [区别](#区别) + * [总结](#总结) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -161,4 +175,4 @@ Apache在处理动态有优势,Nginx并发性比较好,CPU内存占用低, ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" index 82960b2..04a11f8 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [Overview](#overview) + * [Connector Init and Start](#connector-init-and-start) + * [Request Process](#request-process) + * [Acceptor](#acceptor) + * [Poller](#poller) + * [Worker](#worker) + * [Container](#container) + * [Reference](#reference) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -172,4 +187,4 @@ Acceptor、Poller、worker 所在的 ThreadPoolExecutor 都维护在 NioEndpoint ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" index 041efed..13c8bb7 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" @@ -1,3 +1,23 @@ +# Table of Contents + + * [Java日志系统的演变史](#java日志系统的演变史) + * [阶段一](#阶段一) + * [阶段二](#阶段二) + * [阶段三](#阶段三) + * [阶段四](#阶段四) + * [阶段五](#阶段五) + * [一、日志框架的分类](#一、日志框架的分类) + * [二、发展历程](#二、发展历程) + * [Log4j](#log4j) + * [J.U.L](#jul) + * [JCL(commons-logging)](#jcl(commons-logging)) + * [SLF4J & Logback](#slf4j--logback) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) + * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -235,4 +255,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) -​ \ No newline at end of file +​ diff --git "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" index 1096bfe..c09c602 100644 --- "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" +++ "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" @@ -20,7 +20,7 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- + - Java泛型 --- diff --git "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" index 5b1bf32..d3849a0 100644 --- "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" +++ "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" @@ -24,7 +24,7 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- + - Java枚举类 --- diff --git "a/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" "b/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" index fa9a5ff..2532d2a 100644 --- "a/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" +++ "b/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" @@ -1,3 +1,26 @@ +# Table of Contents + + * [抽象类介绍](#抽象类介绍) + * [为什么要用抽象类](#为什么要用抽象类) + * [一个抽象类小故事](#一个抽象类小故事) + * [一个抽象类小游戏](#一个抽象类小游戏) + * [接口介绍](#接口介绍) + * [接口与类相似点:](#接口与类相似点:) + * [接口与类的区别:](#接口与类的区别:) + * [接口特性](#接口特性) + * [抽象类和接口的区别](#抽象类和接口的区别) + * [接口的使用:](#接口的使用:) + * [接口最佳实践:设计模式中的工厂模式](#接口最佳实践:设计模式中的工厂模式) + * [接口与抽象类的本质区别是什么?](#接口与抽象类的本质区别是什么?) + * [基本语法区别](#基本语法区别) + * [设计思想区别](#设计思想区别) + * [如何回答面试题:接口和抽象类的区别?](#如何回答面试题:接口和抽象类的区别) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + * [抽象类介绍](#抽象类介绍) * [为什么要用抽象类](#为什么要用抽象类) * [一个抽象类小故事](#一个抽象类小故事) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" index 27bf958..01860bf 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [使用示例](#使用示例) + * [ReentrantReadWriteLock 总览](#reentrantreadwritelock-总览) + * [源码分析](#源码分析) + * [读锁获取](#读锁获取) + * [读锁释放](#读锁释放) + * [写锁获取](#写锁获取) + * [写锁释放](#写锁释放) + * [锁降级](#锁降级) + * [总结](#总结) + + 本文转自:https://www.javadoop.com/ **本文转载自互联网,侵删** @@ -583,4 +596,4 @@ protected final boolean tryAcquire(int acquires) { ![14](https://www.javadoop.com/blogimages/reentrant-read-write-lock/14.png) -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" index 94a2ffc..f082991 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [前言](#前言) + * [BlockingQueue](#blockingqueue) + * [BlockingQueue 实现之 ArrayBlockingQueue](#blockingqueue-实现之-arrayblockingqueue) + * [BlockingQueue 实现之 LinkedBlockingQueue](#blockingqueue-实现之-linkedblockingqueue) + * [BlockingQueue 实现之 SynchronousQueue](#blockingqueue-实现之-synchronousqueue) + * [BlockingQueue 实现之 PriorityBlockingQueue](#blockingqueue-实现之-priorityblockingqueue) + * [总结](#总结) + + 本文转自:https://www.javadoop.com/ **本文转载自互联网,侵删** @@ -833,4 +844,4 @@ SynchronousQueue 本身不带有空间来存储任何元素,使用上可以选 PriorityBlockingQueue 是无界队列,基于数组,数据结构为二叉堆,数组第一个也是树的根节点总是最小值。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" index f9ed1be..76f6d4b 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [前言](#前言) + * [总览](#总览) + * [Executor 接口](#executor-接口) + * [ExecutorService](#executorservice) + * [FutureTask](#futuretask) + * [AbstractExecutorService](#abstractexecutorservice) + * [ThreadPoolExecutor](#threadpoolexecutor) + * [Executors](#executors) + * [总结](#总结) + + 本文转自:https://www.javadoop.com/ 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1303,4 +1316,4 @@ else if (!addWorker(command, false)) 本文篇幅是有点长,如果读者发现什么不对的地方,或者有需要补充的地方,请不吝提出,谢谢。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" index d222e88..efa273f 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" @@ -1,3 +1,36 @@ +# Table of Contents + + * [前言](#前言) + * [Java7 HashMap](#java7-hashmap) + * [put 过程分析](#put-过程分析) + * [数组初始化](#数组初始化) + * [计算具体数组位置](#计算具体数组位置) + * [添加节点到链表中](#添加节点到链表中) + * [数组扩容](#数组扩容) + * [get 过程分析](#get-过程分析) + * [Java7 ConcurrentHashMap](#java7-concurrenthashmap) + * [初始化](#初始化) + * [put 过程分析](#put-过程分析-1) + * [初始化槽: ensureSegment](#初始化槽-ensuresegment) + * [获取写入锁: scanAndLockForPut](#获取写入锁-scanandlockforput) + * [扩容: rehash](#扩容-rehash) + * [get 过程分析](#get-过程分析-1) + * [并发问题分析](#并发问题分析) + * [Java8 HashMap](#java8-hashmap) + * [put 过程分析](#put-过程分析-2) + * [数组扩容](#数组扩容-1) + * [get 过程分析](#get-过程分析-2) + * [Java8 ConcurrentHashMap](#java8-concurrenthashmap) + * [初始化](#初始化-1) + * [put 过程分析](#put-过程分析-3) + * [初始化数组:initTable](#初始化数组:inittable) + * [链表转红黑树: treeifyBin](#链表转红黑树-treeifybin) + * [扩容:tryPresize](#扩容:trypresize) + * [数据迁移:transfer](#数据迁移:transfer) + * [get 过程分析](#get-过程分析-3) + * [总结](#总结) + + 本文转自:https://www.javadoop.com/ 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1383,4 +1416,4 @@ public V get(Object key) { 不要脸地自以为本文的质量还是挺高的,信息量比较大,如果你觉得有写得不好的地方,或者说看完本文你还是没看懂它们,那么请提出来~~~~~ -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" index a110e87..f1c33dc 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [前言](#前言) + * [Unsafe类是啥?](#unsafe类是啥?) + * [为什么叫Unsafe?](#为什么叫unsafe?) + * [JAVA高并发—LockSupport的学习及简单使用](#java高并发locksupport的学习及简单使用) + + 本文转自网络,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" index 453f314..e5cfa46 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [1多线程的优点](#1多线程的优点) + * [1.1资源利用率更好案例](#11资源利用率更好案例) + * [1.2程序响应更快](#12程序响应更快) + * [2多线程的代价](#2多线程的代价) + * [2.1设计更复杂](#21设计更复杂) + * [2.2上下文切换的开销](#22上下文切换的开销) + * [2.3增加资源消耗](#23增加资源消耗) + * [3竞态条件与临界区](#3竞态条件与临界区) + * [**4**线程的运行与创建](#4线程的运行与创建) + * [5线程的状态和优先级](#5线程的状态和优先级) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" index c13614c..a84e568 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" @@ -1,3 +1,22 @@ +# Table of Contents + + * [一:JMM基础与happens-before](#一:jmm基础与happens-before) + * [并发编程模型的分类](#并发编程模型的分类) + * [重排序](#重排序) + * [处理器重排序与内存屏障指令](#处理器重排序与内存屏障指令) + * [happens-before](#happens-before) + * [二:重排序与JMM的as-if-serial](#二:重排序与jmm的as-if-serial) + * [数据依赖性](#数据依赖性) + * [as-if-serial语义](#as-if-serial语义) + * [程序顺序规则](#程序顺序规则) + * [重排序对多线程的影响](#重排序对多线程的影响) + * [三:顺序一致性内存模型与JMM](#三:顺序一致性内存模型与jmm) + * [数据竞争与顺序一致性保证](#数据竞争与顺序一致性保证) + * [顺序一致性内存模型](#顺序一致性内存模型) + * [同步程序的顺序一致性效果](#同步程序的顺序一致性效果) + * [未同步程序的执行特性](#未同步程序的执行特性) + + **本文转载自并发编程网,侵删** 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -388,4 +407,4 @@ JMM不保证未同步程序的执行结果与该程序在顺序一致性模型 如上图所示,假设处理器A写一个long型变量,同时处理器B要读这个long型变量。处理器A中64位的写操作被拆分为两个32位的写操作,且 -这两个32位的写操作被分配到不同的写事务中执行。同时处理器B中64位的读操作被拆分为两个32位的读操作,且这两个32位的读操作被分配到同一个的读事务中执行。当处理器A和B按上图的时序来执行时,处理器B将看到仅仅被处理器A“写了一半“的无效值。 \ No newline at end of file +这两个32位的写操作被分配到不同的写事务中执行。同时处理器B中64位的读操作被拆分为两个32位的读操作,且这两个32位的读操作被分配到同一个的读事务中执行。当处理器A和B按上图的时序来执行时,处理器B将看到仅仅被处理器A“写了一半“的无效值。 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" index 085eaa3..4220389 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" @@ -1,3 +1,28 @@ +# Table of Contents + + * [序言](#序言) + * [原子性](#原子性) + * [可见性](#可见性) + * [有序性 ](#有序性 ) + * [volatile关键字详解:在JMM中volatile的内存语义是锁](#volatile关键字详解:在jmm中volatile的内存语义是锁) + * [volatile的特性](#volatile的特性) + * [volatile写-读建立的happens before关系](#volatile写-读建立的happens-before关系) + * [volatile写-读的内存语义](#volatile写-读的内存语义) + * [volatile内存语义的实现](#volatile内存语义的实现) + * [JSR-133为什么要增强volatile的内存语义](#jsr-133为什么要增强volatile的内存语义) + * [](#) + * [引言](#引言) + * [术语定义](#术语定义) + * [3    处理器如何实现原子操作](#3   -处理器如何实现原子操作) + * [3.1   处理器自动保证基本内存操作的原子性](#31  -处理器自动保证基本内存操作的原子性) + * [3.2   使用总线锁保证原子性](#32  -使用总线锁保证原子性) + * [3.3 使用缓存锁保证原子性](#33-使用缓存锁保证原子性) + * [4    JAVA如何实现原子操作](#4   -java如何实现原子操作) + * [4.1 使用循环CAS实现原子操作](#41-使用循环cas实现原子操作) + * [4.2 使用锁机制实现原子操作](#42-使用锁机制实现原子操作) + * [5      参考资料](#5     -参考资料) + + **本文转载自互联网,侵删** 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -543,4 +568,4 @@ JVM中的CAS操作正是利用了上一节中提到的处理器提供的CMPXCHG 1. [Java SE1.6中的Synchronized](http://www.infoq.com/cn/articles/java-se-16-synchronized) 2. [Intel 64和IA-32架构软件开发人员手册](http://www.intel.com/products/processor/manuals/) -3. [深入分析Volatile的实现原理](http://www.infoq.com/cn/articles/ftf-java-volatile) \ No newline at end of file +3. [深入分析Volatile的实现原理](http://www.infoq.com/cn/articles/ftf-java-volatile) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" index 2515f15..d3d1b76 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" @@ -1,3 +1,26 @@ +# Table of Contents + + * [Java中的锁机制及Lock类](#java中的锁机制及lock类) + * [锁的释放-获取建立的happens before 关系](#锁的释放-获取建立的happens-before-关系) + * [锁释放和获取的内存语义](#锁释放和获取的内存语义) + * [锁内存语义的实现](#锁内存语义的实现) + * [LOCK_IF_MP(mp) __asm cmp mp, 0 \](#lock_if_mpmp-__asm-cmp-mp-0--) + * [concurrent包的实现](#concurrent包的实现) + * [synchronized实现原理](#synchronized实现原理) + * [****1、实现原理****](#1、实现原理) + * [**2、Java对象头**](#2、java对象头) + * [**3、Monitor**](#3、monitor) + * [**4、锁优化**](#4、锁优化) + * [**5、自旋锁**](#5、自旋锁) + * [**6、适应自旋锁**](#6、适应自旋锁) + * [**7、锁消除**](#7、锁消除) + * [**8、锁粗化**](#8、锁粗化) + * [**9、轻量级锁**](#9、轻量级锁) + * [**10、偏向锁**](#10、偏向锁) + * [**11、重量级锁**](#11、重量级锁) + * [参考资料](#参考资料) + + **本文转载自并发编程网,侵删** 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -514,4 +537,4 @@ https://blog.csdn.net/qq_35357656/article/details/78657373 1. 周志明:《深入理解Java虚拟机》 2. 方腾飞:《Java并发编程的艺术》 -3. Java中synchronized的实现原理与应用 \ No newline at end of file +3. Java中synchronized的实现原理与应用 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" index 3ad0467..6d56e6e 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [前言](#前言) + * [写final域的重排序规则](#写final域的重排序规则) + * [读final域的重排序规则](#读final域的重排序规则) + * [如果final域是引用类型](#如果final域是引用类型) + * [为什么final引用不能从构造函数内“逸出”](#为什么final引用不能从构造函数内逸出) + * [final语义在处理器中的实现](#final语义在处理器中的实现) + * [JSR-133为什么要增强final的语义](#jsr-133为什么要增强final的语义) + * [参考文献](#参考文献) + + **本文转载自互联网,侵删** 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -202,4 +214,4 @@ public static void reader { 4. [ The JSR-133 Cookbook for Compiler Writers](http://gee.cs.oswego.edu/dl/jmm/cookbook.html) -[Intel® 64 and IA-32 ArchitecturesvSoftware Developer’s Manual Volume 3A: System Programming Guide, Part 1](http://download.intel.com/products/processor/manual/253668.pdf) \ No newline at end of file +[Intel® 64 and IA-32 ArchitecturesvSoftware Developer’s Manual Volume 3A: System Programming Guide, Part 1](http://download.intel.com/products/processor/manual/253668.pdf) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" index 38836a0..c708dfc 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" @@ -1,3 +1,24 @@ +# Table of Contents + + * [简介](#简介) + * [一、Java内存区域(JVM内存区域)](#一、java内存区域(jvm内存区域)) + * [二、Java内存模型](#二、java内存模型) + * [三、as-if-serial语义、happens-before原则](#三、as-if-serial语义、happens-before原则) + * [3.1 as-if-serial语义](#31-as-if-serial语义) + * [3.2 happens-before原则](#32-happens-before原则) + * [3.3 happens-before定义](#33-happens-before定义) + * [3.3 happens-before对比as-if-serial](#33-happens-before对比as-if-serial) + * [3.4 happens-before具体规则](#34-happens-before具体规则) + * [3.5 happens-before与JMM的关系图](#35-happens-before与jmm的关系图) + * [四、volatile、锁的内存语义](#四、volatile、锁的内存语义) + * [4.1 volatile的内存语义](#41-volatile的内存语义) + * [4.2 volatile内存语义的实现](#42-volatile内存语义的实现) + * [4.3 锁的内存语义](#43-锁的内存语义) + * [4.4 final域的内存语义](#44-final域的内存语义) + * [五、JMM是如何处理并发过程中的三大特性](#五、jmm是如何处理并发过程中的三大特性) + * [参考链接:](#参考链接:) + + 本文转自 https://www.cnblogs.com/kukri/p/9109639.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" index f476bc2..5a7da8e 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" @@ -1,3 +1,13 @@ +# Table of Contents + + * [简介](#简介) + * [AQS 结构](#aqs-结构) + * [线程抢锁](#线程抢锁) + * [解锁操作](#解锁操作) + * [总结](#总结) + * [示例图解析](#示例图解析) + + 本文转自:https://www.javadoop.com/post/AbstractQueuedSynchronizer#toc4 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -558,4 +568,4 @@ private Node enq(final Node node) { ![aqs-3](https://www.javadoop.com/blogimages/AbstractQueuedSynchronizer/aqs-3.png) -这里可以简单说下 waitStatus 中 SIGNAL(-1) 状态的意思,Doug Lea 注释的是:代表后继节点需要被唤醒。也就是说这个 waitStatus 其实代表的不是自己的状态,而是后继节点的状态,我们知道,每个 node 在入队的时候,都会把前驱节点的状态改为 SIGNAL,然后阻塞,等待被前驱唤醒。这里涉及的是两个问题:有线程取消了排队、唤醒操作。其实本质是一样的,读者也可以顺着 “waitStatus代表后继节点的状态” 这种思路去看一遍源码。 \ No newline at end of file +这里可以简单说下 waitStatus 中 SIGNAL(-1) 状态的意思,Doug Lea 注释的是:代表后继节点需要被唤醒。也就是说这个 waitStatus 其实代表的不是自己的状态,而是后继节点的状态,我们知道,每个 node 在入队的时候,都会把前驱节点的状态改为 SIGNAL,然后阻塞,等待被前驱唤醒。这里涉及的是两个问题:有线程取消了排队、唤醒操作。其实本质是一样的,读者也可以顺着 “waitStatus代表后继节点的状态” 这种思路去看一遍源码。 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" index 1e58978..ec8782e 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" @@ -1,3 +1,24 @@ +# Table of Contents + + * [公平锁和非公平锁](#公平锁和非公平锁) + * [Condition](#condition) + * [1\. 将节点加入到条件队列](#1-将节点加入到条件队列) + * [2\. 完全释放独占锁](#2-完全释放独占锁) + * [3\. 等待进入阻塞队列](#3-等待进入阻塞队列) + * [4\. signal 唤醒线程,转移到阻塞队列](#4-signal-唤醒线程,转移到阻塞队列) + * [5\. 唤醒后检查中断状态](#5-唤醒后检查中断状态) + * [6\. 获取独占锁](#6-获取独占锁) + * [7\. 处理中断状态](#7-处理中断状态) + * [* 带超时机制的 await](#-带超时机制的-await) + * [* 不抛出 InterruptedException 的 await](#-不抛出-interruptedexception-的-await) + * [AbstractQueuedSynchronizer 独占锁的取消排队](#abstractqueuedsynchronizer-独占锁的取消排队) + * [再说 java 线程中断和 InterruptedException 异常](#再说-java-线程中断和-interruptedexception-异常) + * [线程中断](#线程中断) + * [InterruptedException 概述](#interruptedexception-概述) + * [处理中断](#处理中断) + * [总结](#总结) + + 本文转自:http://hongjiev.github.io/2017/06/16/AbstractQueuedSynchronizer 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1004,4 +1025,4 @@ void awaitUninterruptibly(); 这篇文章的信息量真的很大,如果你花了时间,还是没有看懂,那是我的错了。 -欢迎大家向我提问,我不一定能每次都及时出现,我出现也不一定能解决大家的问题,欢迎探讨。 \ No newline at end of file +欢迎大家向我提问,我不一定能每次都及时出现,我出现也不一定能解决大家的问题,欢迎探讨。 diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" index 323c4dd..c966c90 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [前言](#前言) + * [CountDownLatch](#countdownlatch) + * [使用例子](#使用例子) + * [源码分析](#源码分析) + * [CyclicBarrier](#cyclicbarrier) + * [Semaphore](#semaphore) + * [总结](#总结) + + 本文转自:https://www.javadoop.com/ 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -918,4 +929,4 @@ Semphore 的源码确实很简单,基本上都是分析过的老代码的组 写到这里,终于把 AbstractQueuedSynchronizer 基本上说完了,对于 Java 并发,Doug Lea 真的是神一样的存在。日后我们还会接触到很多 Doug Lea 的代码,希望我们大家都可以朝着大神的方向不断打磨自己的技术,少一些高大上的架构,多一些实实在在的优秀代码吧。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" "b/docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" index 5caf95e..52d5ad3 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" @@ -1,3 +1,10 @@ +# Table of Contents + + * [Fork/Join框架介绍](#forkjoin框架介绍) + * [简介](#简介) + * [工作窃取算法介绍](#工作窃取算法介绍) + + 本文转自:https://www.imooc.com/article/24822 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" "b/docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" index 1e81d71..2db99f7 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" @@ -1,3 +1,22 @@ +# Table of Contents + + * [[java编译期优化](https://www.cnblogs.com/LeonNew/p/6187411.html)](#[java编译期优化]httpswwwcnblogscomleonnewp6187411html) + * [早期(编译期)优化](#早期(编译期)优化) + * [泛型与类型擦除](#泛型与类型擦除) + * [自动装箱、拆箱与遍历循环](#自动装箱、拆箱与遍历循环) + * [条件编译](#条件编译) + * [晚期(运行期)优化](#晚期(运行期)优化) + * [解释器与编译器](#解释器与编译器) + * [分层编译策略](#分层编译策略) + * [热点代码探测](#热点代码探测) + * [编译优化技术](#编译优化技术) + * [java与C/C++编译器对比](#java与cc编译器对比) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -232,4 +251,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27210\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27210\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" index f931812..07a6b33 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27210\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27210\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" @@ -1,3 +1,25 @@ +# Table of Contents + + * [目录](#目录) + * [调优准备](#调优准备) + * [性能分析](#性能分析) + * [CPU分析](#cpu分析) + * [内存分析](#内存分析) + * [IO分析](#io分析) + * [其他分析工具](#其他分析工具) + * [性能调优](#性能调优) + * [CPU调优](#cpu调优) + * [内存调优](#内存调优) + * [IO调优](#io调优) + * [其他优化建议](#其他优化建议) + * [JVM参数进阶](#jvm参数进阶) + * [参考资料](#参考资料) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自:https://www.rowkey.me/blog/2016/11/02/java-profile/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -407,4 +429,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27211\357\274\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27211\357\274\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" index 01dbf2e..0805113 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27211\357\274\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27211\357\274\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" @@ -1,3 +1,32 @@ +# Table of Contents + + * [实战内存溢出异常](#实战内存溢出异常) + * [1 . 对象的创建过程](#1--对象的创建过程) + * [2 . 对象的内存布局](#2--对象的内存布局) + * [3 . 对象的访问定位](#3--对象的访问定位) + * [4 .实战内存异常](#4-实战内存异常) + * [Java堆内存异常](#java堆内存异常) + * [Java栈内存异常](#java栈内存异常) + * [方法区内存异常](#方法区内存异常) + * [方法区与运行时常量池OOM](#方法区与运行时常量池oom) + * [附加-直接内存异常](#附加-直接内存异常) + * [Java内存泄漏](#java内存泄漏) + * [Java是如何管理内存?](#java是如何管理内存?) + * [什么是Java中的内存泄露?](#什么是java中的内存泄露?) + * [其他常见内存泄漏](#其他常见内存泄漏) + * [1、静态集合类引起内存泄露:](#1、静态集合类引起内存泄露:) + * [2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。](#2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。) + * [3、监听器](#3、监听器) + * [4、各种连接](#4、各种连接) + * [5、内部类和外部模块等的引用](#5、内部类和外部模块等的引用) + * [6、单例模式](#6、单例模式) + * [如何检测内存泄漏](#如何检测内存泄漏) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -448,4 +477,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27212\357\274\232JVM\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27212\357\274\232JVM\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" index e21b5a8..9df9174 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27212\357\274\232JVM\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27212\357\274\232JVM\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" @@ -1,3 +1,19 @@ +# Table of Contents + + * [一、VisualVM是什么?](#一、visualvm是什么?) + * [二、如何获取VisualVM?](#二、如何获取visualvm?) + * [三、获取那个版本?](#三、获取那个版本?) + * [四、VisualVM能做什么?](#四、visualvm能做什么?) + * [监控远程主机上的JAVA应用程序](#监控远程主机上的java应用程序) + * [排查JAVA应用程序内存泄漏](#排查java应用程序内存泄漏) + * [查找JAVA应用程序耗时的方法函数](#查找java应用程序耗时的方法函数) + * [排查JAVA应用程序线程锁](#排查java应用程序线程锁) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -257,4 +273,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27213\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27213\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md" index 54f4489..3167cfa 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27213\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\27213\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [一、背景](#一、背景) + * [二、简介](#二、简介) + * [1.强引用 StrongReference](#1强引用-strongreference) + * [2.弱引用 WeakReference](#2弱引用-weakreference) + * [3.软引用 SoftReference](#3软引用-softreference) + * [4.虚引用 PhantomReference](#4虚引用-phantomreference) + * [三、小结](#三、小结) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -230,4 +245,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2721\357\274\232JVM\345\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2721\357\274\232JVM\345\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" index de1a97a..d040fa5 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2721\357\274\232JVM\345\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2721\357\274\232JVM\345\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" @@ -1,3 +1,33 @@ +# Table of Contents + + * [前言](#前言) + * [Java堆(Heap)](#java堆(heap)) + * [方法区(Method Area)](#方法区(method-area)) + * [程序计数器(Program Counter Register)](#程序计数器(program-counter-register)) + * [JVM栈(JVM Stacks)](#jvm栈(jvm-stacks)) + * [本地方法栈(Native Method Stacks)](#本地方法栈(native-method-stacks)) + * [哪儿的OutOfMemoryError](#哪儿的outofmemoryerror) +* [[JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)](https://www.cnblogs.com/yulei126/p/6777323.html)](#[jdk8-废弃永久代(permgen)迎来元空间(metaspace)]httpswwwcnblogscomyulei126p6777323html) + * [一、背景](#一、背景) + * [1.1 永久代(PermGen)在哪里?](#11-永久代(permgen)在哪里?) + * [1.2 JDK8永久代的废弃](#12-jdk8永久代的废弃) + * [ 二、为什么废弃永久代(PermGen)](# 二、为什么废弃永久代(permgen)) + * [ 2.1 官方说明](# 21-官方说明) + * [Motivation](#motivation) + * [ 2.2 现实使用中易出问题](# 22-现实使用中易出问题) + * [三、深入理解元空间(Metaspace)](#三、深入理解元空间(metaspace)) + * [3.1元空间的内存大小](#31元空间的内存大小) + * [3.2常用配置参数](#32常用配置参数) + * [3.3测试并追踪元空间大小](#33测试并追踪元空间大小) + * [ 3.3.1.测试字符串常量](# 331测试字符串常量) + * [3.3.2.测试元空间溢出](#332测试元空间溢出) + * [ 四、总结](# 四、总结) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -438,4 +468,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2722\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2722\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md" index de39c9b..e8a7e29 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2722\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2722\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md" @@ -1,3 +1,36 @@ +# Table of Contents + + * [JVM GC基本原理与GC算法](#jvm-gc基本原理与gc算法) + * [Java关键术语](#java关键术语) + * [Java HotSpot 虚拟机](#java-hotspot-虚拟机) + * [Java堆内存](#java堆内存) + * [启动Java垃圾回收](#启动java垃圾回收) + * [各种GC的触发时机(When)](#各种gc的触发时机when) + * [GC类型](#gc类型) + * [触发时机](#触发时机) + * [FULL GC触发条件详解](#full-gc触发条件详解) + * [总结](#总结) + * [什么是Stop the world](#什么是stop-the-world) + * [Java垃圾回收过程](#java垃圾回收过程) + * [垃圾回收中实例的终结](#垃圾回收中实例的终结) + * [对象什么时候符合垃圾回收的条件?](#对象什么时候符合垃圾回收的条件?) + * [GC Scope 示例程序](#gc-scope-示例程序) + * [[JVM GC算法](https://www.cnblogs.com/wupeixuan/p/8670341.html)](#[jvm-gc算法]httpswwwcnblogscomwupeixuanp8670341html) + * [JVM垃圾判定算法](#jvm垃圾判定算法) + * [引用计数算法(Reference Counting)](#引用计数算法reference-counting) + * [可达性分析算法(根搜索算法)](#可达性分析算法(根搜索算法)) + * [四种引用](#四种引用) + * [JVM垃圾回收算法](#jvm垃圾回收算法) + * [标记—清除算法(Mark-Sweep)](#标记清除算法(mark-sweep)) + * [复制算法(Copying)](#复制算法(copying)) + * [标记—整理算法(Mark-Compact)](#标记整理算法(mark-compact)) + * [分代收集算法(Generational Collection)](#分代收集算法generational-collection) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -552,4 +585,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2723\357\274\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2723\357\274\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" index f731466..741c437 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2723\357\274\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2723\357\274\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" @@ -1,3 +1,33 @@ +# Table of Contents + + * [1 概述](#1-概述) + * [2 对象已经死亡?](#2-对象已经死亡?) + * [2.1引用计数法](#21引用计数法) + * [2.2可达性分析算法](#22可达性分析算法) + * [2.3 再谈引用](#23-再谈引用) + * [2.4 生存还是死亡](#24-生存还是死亡) + * [2.5 回收方法区](#25-回收方法区) + * [3 垃圾收集算法](#3-垃圾收集算法) + * [3.1 标记-清除算法](#31-标记-清除算法) + * [3.2 复制算法](#32-复制算法) + * [3.3 标记-整理算法](#33-标记-整理算法) + * [3.4分代收集算法](#34分代收集算法) + * [4 垃圾收集器](#4-垃圾收集器) + * [4.1 Serial收集器](#41-serial收集器) + * [4.2 ParNew收集器](#42-parnew收集器) + * [4.3 Parallel Scavenge收集器](#43-parallel-scavenge收集器) + * [4.4.Serial Old收集器](#44serial-old收集器) + * [4.5 Parallel Old收集器](#45-parallel-old收集器) + * [4.6 CMS收集器](#46-cms收集器) + * [4.7 G1收集器](#47-g1收集器) + * [5 内存分配与回收策略](#5-内存分配与回收策略) + * [5.1对象优先在Eden区分配](#51对象优先在eden区分配) + * [5.2 大对象直接进入老年代](#52-大对象直接进入老年代) + * [5.3长期存活的对象将进入老年代](#53长期存活的对象将进入老年代) + * [5.4 动态对象年龄判定](#54-动态对象年龄判定) + * [总结:](#总结:) + + 本文转自:https://www.cnblogs.com/snailclimb/p/9086341.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -242,4 +272,4 @@ G1收集器的运作大致分为以下几个步骤: ## 总结: 本节介绍了垃圾收集算法,几款JDK1.7中提供的垃圾收集器特点以及运作原理。 -内存回收与垃圾收集器在很多时候都是影响系统性能、并发能力的主要因素之一,虚拟机之所以提供多种不同的收集器以及大量调节参数,是因为只有根据实际应用的需求、实现方式选择最优的收集方式才能获取最高的性能。没有固定收集器、参数组合、也没有最优的调优方法,那么必须了解每一个具体收集器的行为、优势和劣势、调节参数。 \ No newline at end of file +内存回收与垃圾收集器在很多时候都是影响系统性能、并发能力的主要因素之一,虚拟机之所以提供多种不同的收集器以及大量调节参数,是因为只有根据实际应用的需求、实现方式选择最优的收集方式才能获取最高的性能。没有固定收集器、参数组合、也没有最优的调优方法,那么必须了解每一个具体收集器的行为、优势和劣势、调节参数。 diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" index d673436..2371f8f 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [前言](#前言) + * [Class文件](#class文件) + * [什么是Class文件?](#什么是class文件?) + * [基本结构](#基本结构) + * [解析](#解析) + * [字段类型](#字段类型) + * [常量池](#常量池) + * [字节码指令](#字节码指令) + * [运行](#运行) + * [总结](#总结) + * [参考:](#参考:) + + 本文转自:https://juejin.im/post/589834a20ce4630056097a56 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2725\357\274\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2725\357\274\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" index 2c75e89..faebc2d 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2725\357\274\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2725\357\274\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" @@ -1,3 +1,22 @@ +# Table of Contents + + * [1 概述](#1-概述) + * [2 运行时栈帧结构](#2-运行时栈帧结构) + * [2.1 局部变量表](#21-局部变量表) + * [2.2 操作数栈](#22-操作数栈) + * [2.3 动态连接](#23-动态连接) + * [2.4 方法返回地址](#24-方法返回地址) + * [2.5 附加信息](#25-附加信息) + * [3 方法调用](#3-方法调用) + * [3.1 解析](#31-解析) + * [3.2 分派](#32-分派) + * [3.3 动态类型语言的支持](#33-动态类型语言的支持) + * [4 基于栈的字节码解释执行引擎](#4-基于栈的字节码解释执行引擎) + * [4.1 解释执行](#41-解释执行) + * [4.2 基于栈的指令集和基于寄存器的指令集](#42-基于栈的指令集和基于寄存器的指令集) + * [总结](#总结) + + 本文转自:https://www.cnblogs.com/snailclimb/p/9086337.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -287,4 +306,4 @@ mov指令把EAX寄存器的值设置为1,然后add指令再把这个值加1, ## 总结 -本节中,我们分析了虚拟机在执行代码时,如何找到正确的方法、如何执行方法内的字节码,以及执行代码时涉及的内存结构。 \ No newline at end of file +本节中,我们分析了虚拟机在执行代码时,如何找到正确的方法、如何执行方法内的字节码,以及执行代码时涉及的内存结构。 diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2726\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2726\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" index ad7e7ea..60ad7b7 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2726\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2726\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" @@ -1,3 +1,21 @@ +# Table of Contents + + * [一.目标:](#一目标:) + * [二.原理 (类的加载过程及其最终产品):](#二原理-(类的加载过程及其最终产品)) + * [三.过程(类的生命周期):](#三过程(类的生命周期):) + * [加载:](#加载:) + * [校验:](#校验:) + * [准备:](#准备:) + * [解析:](#解析:) + * [初始化:](#初始化:) + * [四.类加载器:](#四类加载器:) + * [五.双亲委派机制:](#五双亲委派机制:) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -167,4 +185,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2727\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2727\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md" index 02ad960..1c3b52d 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2727\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2727\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [打破双亲委派模型](#打破双亲委派模型) + * [JNDI](#jndi) + * [[JNDI 的理解](https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fwww.cnblogs.com%2Fzhchoutai%2Fp%2F7389089.html)](#[jndi-的理解]httpsyqaliyuncomgoarticlerenderredirecturlhttps3a2f2fwwwcnblogscom2fzhchoutai2fp2f7389089html) + * [OSGI](#osgi) + * [1.如何正确的理解和认识OSGI技术?](#1如何正确的理解和认识osgi技术?) + * [Tomcat类加载器以及应用间class隔离与共享](#tomcat类加载器以及应用间class隔离与共享) + * [类加载器](#类加载器) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -385,4 +400,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2729\357\274\232JVM\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2729\357\274\232JVM\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" index f3bf2b9..ab03095 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2729\357\274\232JVM\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2729\357\274\232JVM\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" @@ -1,3 +1,24 @@ +# Table of Contents + + * [一、jvm常见监控工具&指令](#一、jvm常见监控工具指令) + * [1、 jps:jvm进程状况工具](#1、-jpsjvm进程状况工具) + * [2、jstat: jvm统计信息监控工具](#2、jstat-jvm统计信息监控工具) + * [3、jinfo: java配置信息](#3、jinfo:-java配置信息) + * [4、jmap: java 内存映射工具](#4、jmap-java-内存映射工具) + * [5、jhat:jvm堆快照分析工具](#5、jhatjvm堆快照分析工具) + * [6、jstack:java堆栈跟踪工具](#6、jstackjava堆栈跟踪工具) + * [二、可视化工具](#二、可视化工具) + * [三、应用](#三、应用) + * [1、cpu飙升](#1、cpu飙升) + * [2、线程死锁](#2、线程死锁) + * [2.查看java进程的线程快照信息](#2查看java进程的线程快照信息) + * [3、OOM内存泄露](#3、oom内存泄露) + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本文转自:https://juejin.im/post/59e6c1f26fb9a0451c397a8c 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -386,4 +407,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" index a4c7991..01adef6 100644 --- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" +++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [参考文章](#参考文章) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -43,4 +51,4 @@ https://blog.csdn.net/android_hl/article/details/53228348 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24310\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24310\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md" index f11d4bb..72e8943 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24310\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24310\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md" @@ -1,3 +1,15 @@ +# Table of Contents + + * [一、I/O复用模型解读](#一、io复用模型解读) + * [二、TOMCAT对IO模型的支持](#二、tomcat对io模型的支持) + * [三、TOMCAT中NIO的配置与使用](#三、tomcat中nio的配置与使用) + * [四、NioEndpoint组件关系图解读](#四、nioendpoint组件关系图解读) + * [五、NioEndpoint执行序列图](#五、nioendpoint执行序列图) + * [六、NioEndpoint源码解读](#六、nioendpoint源码解读) + * [七、关于性能](#七、关于性能) + * [八、总结](#八、总结) + + 本文转自:http://www.sohu.com/a/203838233_827544 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -177,4 +189,4 @@ NIO只是优化了网络IO的读写,如果系统的瓶颈不在这里,比如 对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源如内存,有关线程资源可参照这篇文章《一台java服务器可以跑多少个线程》。 -因此,使用的线程越少越好。而I/O复用模型正是利用少量的线程来管理大量的连接。在对于维护大量长连接的应用里面更适合用基于I/O复用模型NIO,比如web qq这样的应用。所以我们要清楚系统的瓶颈是I/O还是CPU的计算 \ No newline at end of file +因此,使用的线程越少越好。而I/O复用模型正是利用少量的线程来管理大量的连接。在对于维护大量长连接的应用里面更适合用基于I/O复用模型NIO,比如web qq这样的应用。所以我们要清楚系统的瓶颈是I/O还是CPU的计算 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24311\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24311\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md" index 59aa43a..ec325ea 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24311\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\24311\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md" @@ -1,3 +1,16 @@ +# Table of Contents + + * [前言](#前言) + * [源码环境准备](#源码环境准备) + * [endpoint](#endpoint) + * [init 过程分析](#init-过程分析) + * [start 过程分析](#start-过程分析) + * [Acceptor](#acceptor) + * [Poller](#poller) + * [processKey](#processkey) + * [总结](#总结) + + 本文转载 https://www.javadoop.com 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -819,4 +832,4 @@ protected SocketProcessorBase createSocketProcessor( 后续的流程,感兴趣的读者请自行分析,本文就说到这里了。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" index f2ebbc2..1d9a4e2 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" @@ -1,3 +1,28 @@ +# Table of Contents + + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BD%93%E5%89%8D%E7%8E%AF%E5%A2%83)当前环境](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bd93e5898de78eafe5a283当前环境) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E4%BB%A3%E7%A0%81%E5%9C%B0%E5%9D%80)代码地址](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde4bba3e7a081e59cb0e59d80代码地址) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E7%9F%A5%E8%AF%86%E7%82%B9)知识点](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde79fa5e8af86e782b9知识点) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%9C%BA%E6%99%AF)场景](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde59cbae699af场景) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#nio-%E7%9A%84%E9%98%BB%E5%A1%9E%E5%AE%9E%E7%8E%B0)nio 的阻塞实现](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomdnio-e79a84e998bbe5a19ee5ae9ee78eb0nio-的阻塞实现) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5)建立连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bbbae7ab8be8bf9ee68ea5建立连接) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E8%8E%B7%E5%8F%96-socket-%E8%BF%9E%E6%8E%A5)获取 socket 连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde88eb7e58f96-socket-e8bf9ee68ea5获取-socket-连接) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B)完整示例](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5ae8ce695b4e7a4bae4be8b完整示例) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#nio-%E7%9A%84%E9%9D%9E%E9%98%BB%E5%A1%9E%E5%AE%9E%E7%8E%B0)nio 的非阻塞实现](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomdnio-e79a84e99d9ee998bbe5a19ee5ae9ee78eb0nio-的非阻塞实现) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90)原理分析](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde58e9fe79086e58886e69e90原理分析) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%88%9B%E5%BB%BA%E9%80%89%E6%8B%A9%E5%99%A8)创建选择器](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5889be5bbbae98089e68ba9e599a8创建选择器) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%88%9B%E5%BB%BA%E9%9D%9E%E9%98%BB%E5%A1%9E-io)创建非阻塞 I/O](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5889be5bbbae99d9ee998bbe5a19e-io创建非阻塞-io) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BB%BA%E7%AB%8B%E9%80%89%E6%8B%A9%E5%99%A8%E4%B8%8E-socket-%E7%9A%84%E5%85%B3%E8%81%94)建立选择器与 socket 的关联](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bbbae7ab8be98089e68ba9e599a8e4b88e-socket-e79a84e585b3e88194建立选择器与-socket-的关联) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E9%80%89%E6%8B%A9%E5%99%A8%E7%9B%91%E5%90%AC-socket-%E5%8F%98%E5%8C%96)选择器监听 socket 变化](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde98089e68ba9e599a8e79b91e590ac-socket-e58f98e58c96选择器监听-socket-变化) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E8%BF%9E%E6%8E%A5%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理连接就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e8bf9ee68ea5e5b0b1e7bbaae4ba8be4bbb6处理连接就绪事件) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E5%86%99%E5%85%A5%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理写入就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e58699e585a5e5b0b1e7bbaae4ba8be4bbb6处理写入就绪事件) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E8%AF%BB%E5%8F%96%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理读取就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e8afbbe58f96e5b0b1e7bbaae4ba8be4bbb6处理读取就绪事件) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%AE%8C%E6%95%B4%E4%BB%A3%E7%A0%81)完整代码](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5ae8ce695b4e4bba3e7a081完整代码) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E7%A4%BA%E4%BE%8B%E6%95%88%E6%9E%9C)示例效果](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde7a4bae4be8be69588e69e9c示例效果) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E6%80%BB%E7%BB%93)总结](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde680bbe7bb93总结) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%90%8E%E7%BB%AD)后续](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5908ee7bbad后续) + + 本文转载自:[https://github.com/jasonGeng88/blog](https://github.com/jasonGeng88/blog) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -523,4 +548,4 @@ public class NioNonBlockingHttpClient { ## [](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%90%8E%E7%BB%AD)后续 -* Netty 下的异步请求实现 \ No newline at end of file +* Netty 下的异步请求实现 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" index 14ec40f..0720132 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" @@ -1,3 +1,21 @@ +# Table of Contents + + * [Buffer](#buffer) + * [position、limit、capacity](#position、limit、capacity) + * [初始化 Buffer](#初始化-buffer) + * [填充 Buffer](#填充-buffer) + * [提取 Buffer 中的值](#提取-buffer-中的值) + * [mark() & reset()](#mark--reset) + * [rewind() & clear() & compact()](#rewind--clear--compact) + * [Channel](#channel) + * [FileChannel](#filechannel) + * [SocketChannel](#socketchannel) + * [ServerSocketChannel](#serversocketchannel) + * [DatagramChannel](#datagramchannel) + * [Selector](#selector) + * [小结](#小结) + + 本文转载自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -454,4 +472,4 @@ Channel 基本上只和 Buffer 打交道,最重要的接口就是 channel.read Selector 用于实现非阻塞 IO,这里仅仅介绍接口使用,后续请关注非阻塞 IO 的介绍。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" index cf884ca..631e0e1 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" @@ -1,3 +1,29 @@ +# Table of Contents + +* [mmap基础概念](#mmap基础概念) +* [mmap内存映射原理](#mmap内存映射原理) +* [mmap和常规文件操作的区别](#mmap和常规文件操作的区别) +* [mmap优点总结](#mmap优点总结) +* [mmap使用细节](#mmap使用细节) + * [堆外内存](#堆外内存) + * [在讲解DirectByteBuffer之前,需要先简单了解两个知识点](#在讲解directbytebuffer之前,需要先简单了解两个知识点) + * [java引用类型,因为DirectByteBuffer是通过虚引用(Phantom Reference)来实现堆外内存的释放的。](#java引用类型,因为directbytebuffer是通过虚引用phantom-reference来实现堆外内存的释放的。) + * [关于linux的内核态和用户态](#关于linux的内核态和用户态) + * [DirectByteBuffer ———— 直接缓冲](#directbytebuffer--直接缓冲) + * [DirectByteBuffer堆外内存的创建和回收的源码解读](#directbytebuffer堆外内存的创建和回收的源码解读) + * [堆外内存分配](#堆外内存分配) + * [Bits.reserveMemory(size, cap) 方法](#bitsreservememorysize-cap-方法) + * [堆外内存回收](#堆外内存回收) + * [通过配置参数的方式来回收堆外内存](#通过配置参数的方式来回收堆外内存) + * [堆外内存那些事](#堆外内存那些事) + * [使用堆外内存的原因](#使用堆外内存的原因) + * [什么情况下使用堆外内存](#什么情况下使用堆外内存) + * [堆外内存 VS 内存池](#堆外内存-vs-内存池) + * [堆外内存的特点](#堆外内存的特点) + * [堆外内存的一些问题](#堆外内存的一些问题) + * [参考文章](#参考文章) + + 本文转自:https://www.cnblogs.com/huxiao-tee/p/4660352.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -569,4 +595,4 @@ thunk方法: [http://lovestblog.cn/blog/2015/05/12/direct-buffer/](https://link.jianshu.com/?t=http://lovestblog.cn/blog/2015/05/12/direct-buffer/) [http://www.infoq.com/cn/news/2014/12/external-memory-heap-memory](https://link.jianshu.com/?t=http://www.infoq.com/cn/news/2014/12/external-memory-heap-memory) [http://www.jianshu.com/p/85e931636f27](https://www.jianshu.com/p/85e931636f27) -圣思园《并发与Netty》课程 \ No newline at end of file +圣思园《并发与Netty》课程 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" index fdb2339..b24047e 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [当前环境](#当前环境) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E7%9F%A5%E8%AF%86%E7%82%B9)知识点](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde79fa5e8af86e782b9知识点) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%9C%BA%E6%99%AF)场景](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde59cbae699af场景) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%BB%BA%E7%AB%8B-socket-%E8%BF%9E%E6%8E%A5)建立 socket 连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5bbbae7ab8b-socket-e8bf9ee68ea5建立-socket-连接) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%A4%84%E7%90%86-socket-%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%B5%81)处理 socket 输入输出流](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5a484e79086-socket-e8be93e585a5e8be93e587bae6b581处理-socket-输入输出流) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E6%95%B0%E6%8D%AE%E8%AF%B7%E6%B1%82%E4%B8%8E%E5%93%8D%E5%BA%94)数据请求与响应](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde695b0e68daee8afb7e6b182e4b88ee5938de5ba94数据请求与响应) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E7%BB%93%E6%9E%9C%E5%B1%95%E7%A4%BA)结果展示](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde7bb93e69e9ce5b195e7a4ba结果展示) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%9E%8B%E4%BC%98%E5%8C%96)请求模型优化](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde8afb7e6b182e6a8a1e59e8be4bc98e58c96请求模型优化) + * [补充1:TCP客户端与服务端](#补充1:tcp客户端与服务端) + * [补充2:UDP客户端和服务端](#补充2:udp客户端和服务端) + * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%90%8E%E7%BB%AD)后续](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5908ee7bbad后续) + + 本文转自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -360,4 +375,4 @@ _关于启动的线程数,一般 CPU 密集型会设置在 N+1(N为CPU核数 ## [](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%90%8E%E7%BB%AD)后续 * JAVA 中是如何实现 IO多路复用 -* Netty 下的实现异步请求的 \ No newline at end of file +* Netty 下的实现异步请求的 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" index 3a96995..0834cf9 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" @@ -1,3 +1,20 @@ +# Table of Contents + + * [IO模型介绍](#io模型介绍) + * [阻塞 I/O(blocking IO)](#阻塞-io(blocking-io)) + * [非阻塞 I/O(nonblocking IO)](#非阻塞-io(nonblocking-io)) + * [I/O 多路复用( IO multiplexing)](#io-多路复用(-io-multiplexing)) + * [异步 I/O(asynchronous IO)](#异步-io(asynchronous-io)) + * [阻塞IO,非阻塞IO 与 同步IO, 异步IO的区别和联系](#阻塞io非阻塞io-与-同步io-异步io的区别和联系) + * [IO模型的形象举例](#io模型的形象举例) + * [Select/Poll/Epoll 轮询机制](#selectpollepoll-轮询机制) + * [Java网络编程模型](#java网络编程模型) + * [BIO](#bio) + * [NIO](#nio) + * [AIO](#aio) + * [对比](#对比) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" index 865685a..852291a 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [阻塞模式 IO](#阻塞模式-io) + * [非阻塞 IO](#非阻塞-io) + * [NIO.2 异步 IO](#nio2-异步-io) + * [1、返回 Future 实例](#1、返回-future-实例) + * [2、提供 CompletionHandler 回调函数](#2、提供-completionhandler-回调函数) + * [AsynchronousFileChannel](#asynchronousfilechannel) + * [AsynchronousServerSocketChannel](#asynchronousserversocketchannel) + * [AsynchronousSocketChannel](#asynchronoussocketchannel) + * [Asynchronous Channel Groups](#asynchronous-channel-groups) + * [小结](#小结) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -654,4 +668,4 @@ public static AsynchronousFileChannel open(Path file, 这也是为什么 Netty/Mina 如此盛行的原因,因为它们帮助封装好了很多细节,提供给我们用户友好的接口,后面有时间我也会对 Netty 进行介绍。 -(全文完) \ No newline at end of file +(全文完) diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" index 7c2fc4f..c5ca134 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -1,3 +1,18 @@ +# Table of Contents + + * [为什么要 I/O 多路复用](#为什么要-io-多路复用) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#select "select")select](#[]httpsjeffwtf201702io-multiplexingselect-selectselect) + * [](#sysselecth) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#poll "poll")poll](#[]httpsjeffwtf201702io-multiplexingpoll-pollpoll) + * [](#pollh) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll "epoll")epoll](#[]httpsjeffwtf201702io-multiplexingepoll-epollepoll) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-create-%E7%94%A8%E6%9D%A5%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA-epoll-%E6%8F%8F%E8%BF%B0%E7%AC%A6%EF%BC%9A "epoll_create 用来创建一个 epoll 描述符:")epoll_create 用来创建一个 epoll 描述符:](#[]httpsjeffwtf201702io-multiplexingepoll-create-e794a8e69da5e5889be5bbbae4b880e4b8aa-epoll-e68f8fe8bfb0e7aca6efbc9a-epoll_create-用来创建一个-epoll-描述符:epoll_create-用来创建一个-epoll-描述符:) + * [](#sysepollh) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-ctl-%E7%94%A8%E6%9D%A5%E5%A2%9E-%E5%88%A0-%E6%94%B9%E5%86%85%E6%A0%B8%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E8%A1%A8%EF%BC%9A "epoll_ctl 用来增/删/改内核中的事件表:")epoll_ctl 用来增/删/改内核中的事件表:](#[]httpsjeffwtf201702io-multiplexingepoll-ctl-e794a8e69da5e5a29e-e588a0-e694b9e58685e6a0b8e4b8ade79a84e4ba8be4bbb6e8a1a8efbc9a-epoll_ctl-用来增删改内核中的事件表:epoll_ctl-用来增删改内核中的事件表:) + * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-wait-%E7%94%A8%E6%9D%A5%E7%AD%89%E5%BE%85%E4%BA%8B%E4%BB%B6 "epoll_wait 用来等待事件")epoll_wait 用来等待事件](#[]httpsjeffwtf201702io-multiplexingepoll-wait-e794a8e69da5e7ad89e5be85e4ba8be4bbb6-epoll_wait-用来等待事件epoll_wait-用来等待事件) +* [DEFINE MAXEVENTS 4](#define-maxevents-4) + + 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -281,4 +296,4 @@ epoll 是在 Linux 2.5.44 中首度登场的。不像 select 和 poll ,它提 > 注 2 :有的新手会把文件描述符是否标记为阻塞 I/O 等同于 I/O 多路复用函数是否阻塞。其实文件描述符是否标记为阻塞,决定了你 `read` 或 `write` 它时如果它未准备好是阻塞等待,还是立即返回 EAGAIN ;而 I/O 多路复用函数除非你把 timeout 设置为 0 ,否则它总是会阻塞住你的程序。 -> 注 3 :上面的例子只是入门,可能是不准确或不全面的:一是数据要立即处理防止丢失;二是 EPOLLIN/EPOLLOUT 不完全等同于可读可写事件,具体要去搜索 poll/epoll 的事件具体有哪些;三是大多数实际例子里,比如一个 tcp server ,都会在运行中不断增加/删除的文件描述符而不是记住固定的 3 4 5 几个描述符(用这种例子更能看出 epoll 的优势);四是 epoll 的优势更多的体现在处理大量闲连接的情况,如果场景是处理少量短连接,用 select 反而更好,而且用 select 的代码能运行在所有平台上。 \ No newline at end of file +> 注 3 :上面的例子只是入门,可能是不准确或不全面的:一是数据要立即处理防止丢失;二是 EPOLLIN/EPOLLOUT 不完全等同于可读可写事件,具体要去搜索 poll/epoll 的事件具体有哪些;三是大多数实际例子里,比如一个 tcp server ,都会在运行中不断增加/删除的文件描述符而不是记住固定的 3 4 5 几个描述符(用这种例子更能看出 epoll 的优势);四是 epoll 的优势更多的体现在处理大量闲连接的情况,如果场景是处理少量短连接,用 select 反而更好,而且用 select 的代码能运行在所有平台上。 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" index ea8bebb..23676d9 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" @@ -1,3 +1,21 @@ +# Table of Contents + + * [概述](#概述) + * [Selector的中的重要属性](#selector的中的重要属性) + * [Selector 源码解析](#selector-源码解析) + * [1、Selector的构建](#1、selector的构建) + * [接下来看下 selector.open():](#接下来看下-selectoropen:) + * [EPollSelectorImpl](#epollselectorimpl) + * [EPollArrayWrapper](#epollarraywrapper) + * [ServerSocketChannel的构建](#serversocketchannel的构建) + * [将ServerSocketChannel注册到Selector](#将serversocketchannel注册到selector) + * [EPollSelectorImpl. implRegister](#epollselectorimpl-implregister) + * [Selection操作](#selection操作) + * [epoll原理](#epoll原理) + * [后记](#后记) + * [参考文章](#参考文章) + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -657,4 +675,4 @@ socket写数据 [http://www.jianshu.com/p/0d497fe5484a](https://www.jianshu.com/p/0d497fe5484a) [http://remcarpediem.com/2017/04/02/Netty](https://link.jianshu.com/?t=http://remcarpediem.com/2017/04/02/Netty)源码-三-I-O模型和Java-NIO底层原理/ -圣思园netty课程 \ No newline at end of file +圣思园netty课程 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" index 3a3d2bd..a7a948b 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" @@ -1,3 +1,22 @@ +# Table of Contents + + * [Netty概述](#netty概述) + * [etty简介](#etty简介) + * [Netty都有哪些组件?](#netty都有哪些组件?) + * [Netty是如何处理连接请求和业务逻辑的呢?](#netty是如何处理连接请求和业务逻辑的呢?) + * [如何配置一个Netty应用?](#如何配置一个netty应用?) + * [Netty是如何处理数据的?](#netty是如何处理数据的?) + * [如何处理我们的业务逻辑?](#如何处理我们的业务逻辑?) + * [ByteBuf](#bytebuf) + * [Channel](#channel) + * [ChannelHandler](#channelhandler) + * [ChannelPipeline](#channelpipeline) + * [EventLoop](#eventloop) + * [Bootstrap](#bootstrap) + * [Echo示例](#echo示例) + * [参考文献](#参考文献) + + 本文转自:https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introduction/ 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 @@ -1350,4 +1369,4 @@ new EchoClient(host, port).start(); * [epoll(7) - Linux manual page](http://man7.org/linux/man-pages/man7/epoll.7.html) -* [Java NIO](http://tutorials.jenkov.com/java-nio/) \ No newline at end of file +* [Java NIO](http://tutorials.jenkov.com/java-nio/) diff --git "a/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" index 60925ea..96a1ef4 100644 --- "a/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" +++ "b/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" @@ -1,3 +1,54 @@ +# Table of Contents + + * [网卡和路由器](#网卡和路由器) + * [交换机](#交换机) + * [以太网](#以太网) + * [虚拟局域网VLAN](#虚拟局域网vlan) + * [DHCP协议(动态主机配置协议)](#dhcp协议动态主机配置协议) + * [ARP协议](#arp协议) + * [网关和NAT](#网关和nat) + * [DNS协议和http请求过程](#dns协议和http请求过程) + * [ICMP](#icmp) + * [虚拟专用网VPN和内网ip](#虚拟专用网vpn和内网ip) + * [应用层](#应用层) + * [http](#http) + * [http1.0 1.1和2.0](#http10-11和20) + * [1.0和1.1的主要变化](#10和11的主要变化) + * [http1.0和http2.0的区别。](#http10和http20的区别。) + * [get和post](#get和post) + * [](#) + * [session和cookie](#session和cookie) + * [token](#token) + * [cas单点登录](#cas单点登录) + * [web安全和https](#web安全和https) + * [密码加密](#密码加密) + * [xss跨站脚本攻击](#xss跨站脚本攻击) + * [跨站点请求伪造csrf](#跨站点请求伪造csrf) + * [SQL 注入攻击](#sql-注入攻击) + * [拒绝服务攻击](#拒绝服务攻击) + * [https](#https) + * [传输层](#传输层) + * [UDP报文](#udp报文) + * [TCP 首部格式](#tcp-首部格式) + * [三次握手和四次挥手](#三次握手和四次挥手) + * [半连接syn和洪泛法攻击](#半连接syn和洪泛法攻击) + * [为什么要三次握手](#为什么要三次握手) + * [time wait的作用](#time-wait的作用) + * [可靠传输协议](#可靠传输协议) + * [tcp的粘包拆包](#tcp的粘包拆包) + * [网络层](#网络层) + * [IP 数据报格式](#ip-数据报格式) + * [某个聚合路由地址划分网络给n台机器,是否符合要求。。](#某个聚合路由地址划分网络给n台机器,是否符合要求。。) + * [IP 地址编址方式](#ip-地址编址方式) + * [[](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C.md#1-%E5%88%86%E7%B1%BB)1\. 分类](#[]httpsgithubcomcyc2018interview-notebookblobmasternotese8aea1e7ae97e69cbae7bd91e7bb9cmd1-e58886e7b1bb1-分类) + * [ip分片详谈](#ip分片详谈) + * [路由选择协议和算法](#路由选择协议和算法) + * [链路层](#链路层) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: 计算机网络学习总结 date: 2018-07-09 22:32:57 @@ -659,4 +710,4 @@ OSPF 具有以下特点: **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" index 483648c..3728891 100644 --- "a/docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" +++ "b/docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" @@ -1,3 +1,70 @@ +# Table of Contents + + * [文件系统和VFS](#文件系统和vfs) + * [进程和线程](#进程和线程) + * [fork方法](#fork方法) + * [写时复制](#写时复制) + * [父子进程,僵尸进程,孤儿进程,守护进程](#父子进程,僵尸进程,孤儿进程,守护进程) + * [进程组和会话](#进程组和会话) + * [守护进程](#守护进程) + * [硬连接和软连接](#硬连接和软连接) + * [线程](#线程) + * [线程模型](#线程模型) + * [内核线程实现](#内核线程实现) + * [文件系统](#文件系统) + * [IO操作](#io操作) +* [文件描述符](#文件描述符) +* [write函数](#write函数) +* [read函数](#read函数) +* [**read/write的语义:为什么会阻塞?**](#readwrite的语义:为什么会阻塞?) + * [Linux常用命令和基础知识](#linux常用命令和基础知识) + * [查看进程](#查看进程) +* [ps -l](#ps--l) +* [ps aux](#ps-aux) +* [ps aux | grep threadx](#ps-aux--grep-threadx) +* [top -d 2](#top--d-2) +* [pstree -A](#pstree--a) +* [netstat -anp | grep port](#netstat--anp--grep-port) + * [文件操作](#文件操作) + * [权限操作](#权限操作) + * [连接操作](#连接操作) +* [ln /etc/crontab .](#ln-etccrontab-) +* [ll -i /etc/crontab crontab](#ll--i-etccrontab-crontab) +* [ll -i /etc/crontab /root/crontab2](#ll--i-etccrontab-rootcrontab2) + * [获取内容](#获取内容) + * [搜索和定位](#搜索和定位) +* [locate [-ir] keyword](#locate-[-ir]-keyword) +* [find [basedir] [option]](#find-[basedir]-[option]) + * [压缩](#压缩) + * [管道指令](#管道指令) + * [正则](#正则) + * [linux指令实践和常见场景](#linux指令实践和常见场景) + * [查看进程状态](#查看进程状态) + * [strace](#strace) + * [tcpdump](#tcpdump) + * [nc](#nc) + * [curl](#curl) + * [lsof](#lsof) + * [ss](#ss) + * [awk/sed](#awksed) + * [vim](#vim) + * [crontab](#crontab) + * [service](#service) + * [free](#free) + * [top](#top) + * [df](#df) + * [kill](#kill) + * [mount](#mount) + * [chmod](#chmod) + * [chown](#chown) + * [ifconfig](#ifconfig) + * [uname](#uname) + * [实际场景问题](#实际场景问题) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: Linux内核与基础命令学习总结 date: 2018-07-09 22:33:14 @@ -865,4 +932,4 @@ uname可以显示一些重要的系统信息,例如内核名称、主机名、 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" index bf19a7b..d0e096f 100644 --- "a/docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" +++ "b/docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" @@ -1,3 +1,31 @@ +# Table of Contents + + * [CPU](#cpu) + * [程序执行过程](#程序执行过程) + * [高速缓存 读写缓冲区](#高速缓存-读写缓冲区) + * [内存管理和虚拟内存](#内存管理和虚拟内存) + * [分页](#分页) + * [虚拟内存](#虚拟内存) + * [页表和页面置换算法](#页表和页面置换算法) + * [中断和缺页中断](#中断和缺页中断) + * [分页和分段](#分页和分段) + * [进程与线程](#进程与线程) + * [进程](#进程) + * [多进程](#多进程) + * [线程](#线程) + * [多线程](#多线程) + * [线程通信和进程通信](#线程通信和进程通信) + * [进程调度](#进程调度) + * [死锁](#死锁) + * [IO和磁盘](#io和磁盘) + * [磁盘和寻址](#磁盘和寻址) + * [IO设备](#io设备) + * [文件系统](#文件系统) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + + --- title: 操作系统学习总结 date: 2018-07-09 22:33:03 @@ -320,4 +348,4 @@ linux使用inode来标识任意一个文件。inode存储除了文件名以外 **程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) \ No newline at end of file +![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/\347\224\265\345\255\220\344\271\246.md" "b/docs/\347\224\265\345\255\220\344\271\246.md" index 792ec26..9f5fa61 100644 --- "a/docs/\347\224\265\345\255\220\344\271\246.md" +++ "b/docs/\347\224\265\345\255\220\344\271\246.md" @@ -1,3 +1,28 @@ +# Table of Contents + +* [《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》](#《菜鸟程序员成长之路:从技术小白到阿里巴巴java工程师》) + * [Java学习](#java学习) + * [新手上路](#新手上路) + * [Java面试指南](#java面试指南) + * [Java干货资源](#java干货资源) + * [求职面试心得](#求职面试心得) + * [校招指南](#校招指南) + * [笔面试攻略](#笔面试攻略) + * [面经大全](#面经大全) + * [成长心得](#成长心得) + * [关于考研](#关于考研) + * [成长感悟和思考](#成长感悟和思考) + * [关于我](#关于我) + * [程序人生](#程序人生) + * [一些思考](#一些思考) + * [互联网行业思考](#互联网行业思考) + * [职场心得:](#职场心得:) + * [微信公众号](#微信公众号) + * [Java技术江湖](#java技术江湖) + * [个人公众号:黄小斜](#个人公众号:黄小斜) + * [知识星球](#知识星球) + + # 《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》 这本电子书整理了我过去一年时间里在微信公众号【黄小斜】里创作的文章,包括Java学习、求职面试、成长心得、感悟思考、程序人生等多个主题的内容,这些内容的主线,就是告诉读者,我是如何从一个技术小白一步步自学成为阿里巴巴工程师的,我把我一路的学习历程、成长经历、求职和工作的心得都记录了下来,并且通过写作的方式分享给更多走在这条路上的人们,希望对你们有所帮助。 diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java index 19060f6..3650a29 100644 --- a/src/main/java/md/mdToc.java +++ b/src/main/java/md/mdToc.java @@ -4,7 +4,7 @@ public class mdToc { public static void main(String[] args) { - String path = "D:\\javaTutorial\\docs\\java\\"; + String path = "D:\\javaTutorial\\docs\\distrubuted\\practice\\"; AtxMarkdownToc.newInstance().genTocDir(path); } } From 69ed074b8e19d0e110fe470b9e160ed881e92234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 13:45:34 +0800 Subject: [PATCH 006/113] change config --- .gitattributes | 2 ++ .gitignore | 1 + ReadMe.md | 1 + _config.yml | 3 +- backup.md | 3 +- ...43\200\201Java\345\274\202\345\270\270.md" | 23 ------------ ...55\347\232\204\345\233\236\350\260\203.md" | 3 +- ...12\343\200\201\345\217\215\345\260\204.md" | 4 +-- ...13\343\200\201\346\263\233\345\236\213.md" | 8 +---- ...01\346\236\232\344\270\276\347\261\273.md" | 5 +-- ...00\344\275\263\345\256\236\350\267\265.md" | 3 +- .../16\343\200\201JavaIO\346\265\201.md" | 5 +-- ...01\345\244\232\347\272\277\347\250\213.md" | 5 +-- ...43\345\206\205\351\203\250\347\261\273.md" | 5 +-- ...06\346\236\266\346\242\263\347\220\206.md" | 5 +-- ...71\350\261\241\345\237\272\347\241\200.md" | 35 ------------------- .../20\343\200\201javac\345\222\214javap.md" | 5 +-- ...10\346\236\201\346\214\207\345\215\227.md" | 5 +-- ...15\345\272\217\345\210\227\345\214\226.md" | 5 +-- ...36\347\216\260\345\216\237\347\220\206.md" | 5 +-- ...60\346\215\256\347\261\273\345\236\213.md" | 21 ----------- ...14\345\214\205\350\243\205\347\261\273.md" | 35 ------------------- ...56\345\255\227\347\211\271\346\200\247.md" | 26 -------------- ...va\347\261\273\345\222\214\345\214\205.md" | 23 ------------ ...73\345\222\214\346\216\245\345\217\243.md" | 24 +------------ ...47\350\241\214\351\241\272\345\272\217.md" | 25 ------------- ...17\347\232\204\347\247\230\345\257\206.md" | 22 ------------ ...\261\273\345\222\214Object\347\261\273.md" | 4 --- ...36\347\216\260\345\216\237\347\220\206.md" | 11 +++--- ...357\274\232Queue\345\222\214LinkedList.md" | 14 ++++---- ...16\346\257\224\350\276\203\345\231\250.md" | 9 ++--- ...57\274\232HashMap\345\222\214HashTable.md" | 11 +++--- ...345\222\214LRU\347\274\223\345\255\230.md" | 11 +++--- ...14\347\272\242\351\273\221\346\240\221.md" | 7 ++-- ...74\214TreeSet\344\270\216LinkedHashSet.md" | 10 +++--- ...06\350\212\202\347\262\276\350\256\262.md" | 8 +++-- pom.xml | 3 +- "\345\217\202\350\200\203.md" | 1 + ...00\347\273\210\346\225\210\346\236\234.md" | 1 + 39 files changed, 73 insertions(+), 324 deletions(-) diff --git a/.gitattributes b/.gitattributes index 2ab2d3c..e85bf95 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,5 @@ *.js linguist-language=java *.css linguist-language=java *.html linguist-language=java + + diff --git a/.gitignore b/.gitignore index d74ca4f..517ec8a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ out gen /target/ + diff --git a/ReadMe.md b/ReadMe.md index 2448856..19cf939 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -18,6 +18,7 @@ 推荐使用 https://how2playlife.com/ 在线阅读,在线阅读内容本仓库同步一致。这种方式阅读的优势在于:左侧边栏有目录,阅读体验更好。 + ## 目录 - [Java基础](#Java基础) diff --git a/_config.yml b/_config.yml index c419263..34ac42a 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1,2 @@ -theme: jekyll-theme-cayman \ No newline at end of file +theme: jekyll-theme-cayman + diff --git a/backup.md b/backup.md index 84f5e44..f2fb131 100644 --- a/backup.md +++ b/backup.md @@ -77,4 +77,5 @@ 另外我这个仓库的格式模仿的是@CyC2018 大佬的仓库 -并且其中一篇LeetCode刷题指南也是fork这位大佬而来的。我只是自己刷了一遍然后稍微加了一些解析,站在大佬肩膀上。 \ No newline at end of file +并且其中一篇LeetCode刷题指南也是fork这位大佬而来的。我只是自己刷了一遍然后稍微加了一些解析,站在大佬肩膀上。 + diff --git "a/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" "b/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" index 0fdd0d2..c937417 100644 --- "a/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" +++ "b/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" @@ -1,26 +1,3 @@ -# Table of Contents - -* [目录](#目录) - * [为什么要使用异常](#为什么要使用异常) - * [异常基本定义](#异常基本定义) - * [异常体系](#异常体系) - * [初识异常](#初识异常) - * [异常和错误](#异常和错误) - * [异常的处理方式](#异常的处理方式) - * ["不负责任"的throws](#不负责任的throws) - * [纠结的finally](#纠结的finally) - * [throw : JRE也使用的关键字](#throw--jre也使用的关键字) - * [异常调用链](#异常调用链) - * [自定义异常](#自定义异常) - * [异常的注意事项](#异常的注意事项) - * [当finally遇上return](#当finally遇上return) - * [JAVA异常常见面试题](#java异常常见面试题) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [为什么要使用异常](#为什么要使用异常) diff --git "a/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" "b/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" index 12627bc..1af4d91 100644 --- "a/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" +++ "b/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [模块间的调用](#模块间的调用) * [多线程中的“回调”](#多线程中的回调) * [Java回调机制实战](#java回调机制实战) diff --git "a/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" "b/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" index 25b33a4..0513f67 100644 --- "a/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" +++ "b/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" @@ -1,4 +1,4 @@ -# Table of Contents +# 目录 * [回顾:什么是反射?](#回顾:什么是反射?) * [反射的主要用途](#反射的主要用途) @@ -25,8 +25,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列12:深入理解Java中的反射机制 date: 2019-9-12 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" index c09c602..2251e75 100644 --- "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" +++ "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [泛型概述](#泛型概述) * [一个栗子](#一个栗子) * [特性](#特性) @@ -20,11 +19,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - - Java泛型 ---- - - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" index d3849a0..2891f98 100644 --- "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" +++ "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" @@ -1,4 +1,4 @@ -# Table of Contents +# 目录 * [初探枚举类](#初探枚举类) * [枚举类-语法](#枚举类-语法) @@ -24,10 +24,7 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - - Java枚举类 --- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" "b/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" index a03cbd2..ab4a401 100644 --- "a/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" +++ "b/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [Java注解简介](#java注解简介) * [注解如同标签](#注解如同标签) * [Java 注解概述](#java-注解概述) diff --git "a/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" "b/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" index f360cbf..a405b7f 100644 --- "a/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" +++ "b/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [IO概述](#io概述) * [什么是Java IO流](#什么是java-io流) * [IO文件](#io文件) @@ -25,8 +24,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列16:一文读懂Java IO流和常见面试题 date: 2019-9-16 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" "b/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" index cd37feb..e2cc758 100644 --- "a/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" +++ "b/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [Java中的线程](#java中的线程) * [Java线程状态机](#java线程状态机) * [一个线程的生命周期](#一个线程的生命周期) @@ -20,8 +19,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题 date: 2019-9-17 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" "b/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" index 70c794b..0ce799d 100644 --- "a/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" +++ "b/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [内部类初探](#内部类初探) * [什么是内部类?](#什么是内部类?) * [内部类的共性](#内部类的共性) @@ -18,8 +17,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列18:深入理解Java内部类及其实现原理 date: 2019-9-18 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" "b/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" index 204e477..8ad5827 100644 --- "a/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" +++ "b/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [集合类大图](#集合类大图) * [Collection接口](#collection接口) * [List接口](#list接口) @@ -30,8 +29,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列19:一文搞懂Java集合类框架,以及常见面试题 date: 2019-9-19 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" index e65b1fb..1ce17ab 100644 --- "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" +++ "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" @@ -1,38 +1,3 @@ -# Table of Contents - -* [Java面向对象三大特性(基础篇)](#java面向对象三大特性(基础篇)) - * [对象的概念](#对象的概念) - * [面向对象和面向过程的区别](#面向对象和面向过程的区别) - * [面向对象的三大核心特性简介](#面向对象的三大核心特性简介) - * [面向对象编程三大特性详解](#面向对象编程三大特性详解) - * [一、继承](#一、继承) - * [1、继承的概念](#1、继承的概念) - * [2、继承的好处](#2、继承的好处) - * [3、语法规则](#3、语法规则) - * [A、方法的重写](#a、方法的重写) - * [B、继承的初始化顺序](#b、继承的初始化顺序) - * [C、final关键字](#c、final关键字) - * [D、super关键字](#d、super关键字) - * [二、封装](#二、封装) - * [1、封装的概念](#1、封装的概念) - * [2、封装的优点](#2、封装的优点) - * [3、封装的实现步骤](#3、封装的实现步骤) - * [A、访问修饰符](#a、访问修饰符) - * [B、this关键字](#b、this关键字) - * [C、Java 中的内部类](#c、java-中的内部类) - * [三、多态](#三、多态) - * [1、多态的概念](#1、多态的概念) - * [2、多态的好处](#2、多态的好处) - * [3、Java中的多态](#3、java中的多态) - * [A、引用多态  ](#a、引用多态  ) - * [B、方法多态](#b、方法多态) - * [C、引用类型转换](#c、引用类型转换) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - 点击关注[公众号](#公众号)及时获取笔主最新更新文章,并可免费领取Java工程师必备学习资源。 * [Java面向对象三大特性(基础篇)](#java面向对象三大特性(基础篇)) diff --git "a/docs/java/basic/20\343\200\201javac\345\222\214javap.md" "b/docs/java/basic/20\343\200\201javac\345\222\214javap.md" index 77ea677..dde513d 100644 --- "a/docs/java/basic/20\343\200\201javac\345\222\214javap.md" +++ "b/docs/java/basic/20\343\200\201javac\345\222\214javap.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [聊聊IDE的实现原理](#聊聊ide的实现原理) * [源代码保存](#源代码保存) * [编译为class文件](#编译为class文件) @@ -32,8 +31,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令 date: 2019-9-20 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" index 7cfa76b..14b4137 100644 --- "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" +++ "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [Java语言新特性](#java语言新特性) * [Lambda表达式](#lambda表达式) * [函数式接口](#函数式接口) @@ -20,8 +19,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列21:Java8新特性终极指南 date: 2019-9-21 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" "b/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" index ae08417..6de5ffb 100644 --- "a/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" +++ "b/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [序列化与反序列化概念](#序列化与反序列化概念) * [Java对象的序列化与反序列化](#java对象的序列化与反序列化) * [相关接口及类](#相关接口及类) @@ -13,8 +12,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列22:一文读懂Java序列化和反序列化 date: 2019-9-22 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/23\343\200\201\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/basic/23\343\200\201\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" index 0e87569..9e30b88 100644 --- "a/docs/java/basic/23\343\200\201\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" +++ "b/docs/java/basic/23\343\200\201\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" @@ -1,5 +1,4 @@ -# Table of Contents - +# 目录 * [从JVM结构开始谈多态](#从jvm结构开始谈多态) * [JVM 的结构](#jvm-的结构) * [Java 的方法调用方式](#java-的方法调用方式) @@ -15,8 +14,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - --- title: 夯实Java基础系列23:深入理解Java继承、封装、多态的底层实现原理 date: 2019-9-23 15:56:26 # 文章生成时间,一般不改 diff --git "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" index bc3cbec..d601d6e 100644 --- "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" +++ "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" @@ -1,24 +1,3 @@ -# Table of Contents - -* [目录](#目录) -* [Java 基本数据类型](#java-基本数据类型) - * [Java 的两大数据类型:](#java-的两大数据类型) - * [内置数据类型](#内置数据类型) - * [引用类型](#引用类型) - * [Java 常量](#java-常量) - * [自动拆箱和装箱(详解)](#自动拆箱和装箱(详解)) - * [实现](#实现) - * [自动装箱与拆箱中的“坑”](#自动装箱与拆箱中的坑) - * [了解基本类型缓存(常量池)的最佳实践](#了解基本类型缓存(常量池)的最佳实践) - * [总结:](#总结:) - * [基本数据类型的存储方式](#基本数据类型的存储方式) - * [存在栈中](#存在栈中) - * [存在堆里](#存在堆里) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - # 目录 diff --git "a/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" "b/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" index 087ddc0..13dfe0a 100644 --- "a/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" +++ "b/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" @@ -1,38 +1,3 @@ -# Table of Contents - -* [目录](#目录) - * [string基础](#string基础) - * [Java String 类](#java-string-类) - * [创建字符串](#创建字符串) - * [StringDemo.java 文件代码:](#stringdemojava-文件代码:) - * [String基本用法](#string基本用法) - * [创建String对象的常用方法](#创建string对象的常用方法) - * [String中常用的方法,用法如图所示,具体问度娘](#string中常用的方法,用法如图所示,具体问度娘) - * [三个方法的使用: lenth() substring() charAt()](#三个方法的使用:-lenth---substring---charat) - * [字符串与byte数组间的相互转换](#字符串与byte数组间的相互转换) - * [==运算符和equals之间的区别:](#运算符和equals之间的区别:) - * [字符串的不可变性](#字符串的不可变性) - * [String的连接](#string的连接) - * [String、String builder和String buffer的区别](#string、string-builder和string-buffer的区别) - * [String类的源码分析](#string类的源码分析) - * [String类型的intern](#string类型的intern) - * [String类型的equals](#string类型的equals) - * [StringBuffer和Stringbuilder](#stringbuffer和stringbuilder) - * [append方法](#append方法) - * [扩容](#扩容) - * [](#) - * [删除](#删除) - * [system.arraycopy方法](#systemarraycopy方法) - * [String和JVM的关系](#string和jvm的关系) - * [String为什么不可变?](#string为什么不可变?) - * [不可变有什么好处?](#不可变有什么好处?) - * [String常用工具类](#string常用工具类) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [string基础](#string基础) diff --git "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" index 24f8c77..f9c0f39 100644 --- "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" +++ "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" @@ -1,29 +1,3 @@ -# Table of Contents - -* [目录](#目录) - * [final使用](#final使用) - * [final变量](#final变量) - * [final修饰基本数据类型变量和引用](#final修饰基本数据类型变量和引用) - * [final类](#final类) - * [final关键字的知识点](#final关键字的知识点) - * [final关键字的最佳实践](#final关键字的最佳实践) - * [final的用法](#final的用法) - * [关于空白final](#关于空白final) - * [final内存分配](#final内存分配) - * [使用final修饰方法会提高速度和效率吗](#使用final修饰方法会提高速度和效率吗) - * [使用final修饰变量会让变量的值不能被改变吗;](#使用final修饰变量会让变量的值不能被改变吗;) - * [如何保证数组内部不被修改](#如何保证数组内部不被修改) - * [final方法的三条规则](#final方法的三条规则) - * [final 和 jvm的关系](#final-和-jvm的关系) - * [写 final 域的重排序规则](#写-final-域的重排序规则) - * [读 final 域的重排序规则](#读-final-域的重排序规则) - * [如果 final 域是引用类型](#如果-final-域是引用类型) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [final使用](#final使用) diff --git "a/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" "b/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" index e661990..4084792 100644 --- "a/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" +++ "b/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" @@ -1,26 +1,3 @@ -# Table of Contents - -* [目录](#目录) - * [Java中的包概念](#java中的包概念) - * [包的作用](#包的作用) - * [package 的目录结构](#package-的目录结构) - * [设置 CLASSPATH 系统变量](#设置-classpath-系统变量) - * [常用jar包](#常用jar包) - * [java软件包的类型](#java软件包的类型) - * [dt.jar](#dtjar) - * [rt.jar](#rtjar) - * [*.java文件的奥秘](#java文件的奥秘) - * [*.Java文件简介](#java文件简介) - * [为什么一个java源文件中只能有一个public类?](#为什么一个java源文件中只能有一个public类?) - * [Main方法](#main方法) - * [外部类的访问权限](#外部类的访问权限) - * [Java包的命名规则](#java包的命名规则) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [Java中的包概念](#java中的包概念) diff --git "a/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" "b/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" index 2532d2a..e3bd41a 100644 --- "a/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" +++ "b/docs/java/basic/6\343\200\201\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" @@ -1,26 +1,4 @@ -# Table of Contents - - * [抽象类介绍](#抽象类介绍) - * [为什么要用抽象类](#为什么要用抽象类) - * [一个抽象类小故事](#一个抽象类小故事) - * [一个抽象类小游戏](#一个抽象类小游戏) - * [接口介绍](#接口介绍) - * [接口与类相似点:](#接口与类相似点:) - * [接口与类的区别:](#接口与类的区别:) - * [接口特性](#接口特性) - * [抽象类和接口的区别](#抽象类和接口的区别) - * [接口的使用:](#接口的使用:) - * [接口最佳实践:设计模式中的工厂模式](#接口最佳实践:设计模式中的工厂模式) - * [接口与抽象类的本质区别是什么?](#接口与抽象类的本质区别是什么?) - * [基本语法区别](#基本语法区别) - * [设计思想区别](#设计思想区别) - * [如何回答面试题:接口和抽象类的区别?](#如何回答面试题:接口和抽象类的区别) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - +# 目录 * [抽象类介绍](#抽象类介绍) * [为什么要用抽象类](#为什么要用抽象类) * [一个抽象类小故事](#一个抽象类小故事) diff --git "a/docs/java/basic/7\343\200\201\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md" "b/docs/java/basic/7\343\200\201\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md" index 22e9f23..09dc5b5 100644 --- "a/docs/java/basic/7\343\200\201\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md" +++ "b/docs/java/basic/7\343\200\201\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md" @@ -1,28 +1,3 @@ -# Table of Contents - -* [目录](#目录) - * [Java中的构造方法](#java中的构造方法) - * [构造方法简介](#构造方法简介) - * [构造方法实例](#构造方法实例) - * [例 1](#例-1) - * [例 2](#例-2) - * [Java中的几种构造方法详解](#java中的几种构造方法详解) - * [普通构造方法](#普通构造方法) - * [默认构造方法](#默认构造方法) - * [重载构造方法](#重载构造方法) - * [java子类构造方法调用父类构造方法](#java子类构造方法调用父类构造方法) - * [Java中的代码块简介](#java中的代码块简介) - * [Java代码块使用](#java代码块使用) - * [局部代码块](#局部代码块) - * [构造代码块](#构造代码块) - * [静态代码块](#静态代码块) - * [Java代码块、构造方法(包含继承关系)的执行顺序](#java代码块、构造方法(包含继承关系)的执行顺序) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [Java中的构造方法](#java中的构造方法) diff --git "a/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" "b/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" index c6c2d92..c6ed3af 100644 --- "a/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" +++ "b/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" @@ -1,25 +1,3 @@ -# Table of Contents - -* [目录](#目录) -* [Java 基本数据类型](#java-基本数据类型) - * [Java 的两大数据类型:](#java-的两大数据类型) - * [内置数据类型](#内置数据类型) - * [引用类型](#引用类型) - * [Java 常量](#java-常量) - * [自动拆箱和装箱(详解)](#自动拆箱和装箱(详解)) - * [简易实现](#简易实现) - * [自动装箱与拆箱中的“坑”](#自动装箱与拆箱中的坑) - * [了解基本类型缓存(常量池)的最佳实践](#了解基本类型缓存(常量池)的最佳实践) - * [总结:](#总结:) - * [基本数据类型的存储方式](#基本数据类型的存储方式) - * [存在栈中:](#存在栈中:) - * [存在堆里](#存在堆里) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) - * [Java技术江湖](#java技术江湖) - * [个人公众号:黄小斜](#个人公众号:黄小斜) - - # 目录 * [Java 基本数据类型](#java-基本数据类型) diff --git "a/docs/java/basic/9\343\200\201Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" "b/docs/java/basic/9\343\200\201Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" index 9f71fd0..4caf35a 100644 --- "a/docs/java/basic/9\343\200\201Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" +++ "b/docs/java/basic/9\343\200\201Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" @@ -20,10 +20,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - - Object类 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2431\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2431\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md" index 98a6881..df28c42 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2431\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2431\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md" @@ -21,20 +21,19 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考多篇优质技术博客,参考文章请在文末查看 - -本文非常详尽地介绍了Java中的三个集合类 -ArrayList,Vector与Stack - -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2432\357\274\232Queue\345\222\214LinkedList.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2432\357\274\232Queue\345\222\214LinkedList.md" index bae4c31..7849acb 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2432\357\274\232Queue\345\222\214LinkedList.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2432\357\274\232Queue\345\222\214LinkedList.md" @@ -24,23 +24,25 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考 http://cmsblogs.com/?p=155 +和 +https://www.jianshu.com/p/0e84b8d3606c - -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com -本文参考 http://cmsblogs.com/?p=155 -和 -https://www.jianshu.com/p/0e84b8d3606c + ## LinkedList ### 概述 diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2433\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2433\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md" index a1f361a..2f9dbf3 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2433\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2433\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md" @@ -17,23 +17,24 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考 cmsblogs.com/p=1185 - -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com 今天我们来探索一下LIterator,fail-fast机制与比较器的源码。 -本文参考 cmsblogs.com/p=1185 ## Iterator diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2434\357\274\232HashMap\345\222\214HashTable.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2434\357\274\232HashMap\345\222\214HashTable.md" index 178a0e2..d5a7072 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2434\357\274\232HashMap\345\222\214HashTable.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2434\357\274\232HashMap\345\222\214HashTable.md" @@ -18,23 +18,24 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) + +本文参考http://cmsblogs.com/?p=176 -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com -今天我们来探索一下HashMap和HashTable机制与比较器的源码。 - -本文参考http://cmsblogs.com/?p=176 ## HashMap diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2435\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2435\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md" index af9515a..bf76482 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2435\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2435\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md" @@ -28,21 +28,22 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考多篇优质技术博客,参考文章请在文末查看 -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com -今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存。 - 摘要: @@ -835,7 +836,7 @@ linkedhashmap的实现: > > 5 linkedhashmap的removeEldestEntry方法默认返回false,要实现lru很重要的一点就是集合满时要将最久未访问的元素删除,在linkedhashmap中这个元素就是头指针指向的元素。实现LRU可以直接实现继承linkedhashmap并重写removeEldestEntry方法来设置缓存大小。jdk中实现了LRUCache也可以直接使用。 -参考文章 +## 参考文章 http://cmsblogs.com/?p=176 https://www.jianshu.com/p/8f4f58b4b8ab diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2436\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2436\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md" index a82152f..1d7bdc2 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2436\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2436\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md" @@ -15,16 +15,19 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考多篇优质技术博客,参考文章请在文末查看 -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2437\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2437\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md" index 90030af..64108f8 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2437\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2437\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md" @@ -15,23 +15,25 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考 http://cmsblogs.com/?p=599 -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com 今天我们来探索一下HashSet,TreeSet与LinkedHashSet的基本原理与源码实现,由于这三个set都是基于之前文章的三个map进行实现的,所以推荐大家先看一下前面有关map的文章,结合使用味道更佳。 -本文参考 -http://cmsblogs.com/?p=599 + ## HashSet diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2438\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2438\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md" index a335f5b..658e558 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2438\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\2438\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md" @@ -14,16 +14,20 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) +本文参考多篇优质技术博客,参考文章请在文末查看 -《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 + +《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始整理的新系列文章。 +为了更好地诠释知识点,形成体系文章,本系列文章整理了很多优质的博客内容,如有侵权请联系我,一定删除。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 -文章首发于我的个人博客: +本系列文章将整理于我的个人博客: > www.how2playlife.com diff --git a/pom.xml b/pom.xml index c97fdb7..2cca927 100644 --- a/pom.xml +++ b/pom.xml @@ -16,5 +16,6 @@ 1.0.6 - + + \ No newline at end of file diff --git "a/\345\217\202\350\200\203.md" "b/\345\217\202\350\200\203.md" index e69de29..8b13789 100644 --- "a/\345\217\202\350\200\203.md" +++ "b/\345\217\202\350\200\203.md" @@ -0,0 +1 @@ + diff --git "a/\346\234\200\347\273\210\346\225\210\346\236\234.md" "b/\346\234\200\347\273\210\346\225\210\346\236\234.md" index 429b1d3..dc34623 100644 --- "a/\346\234\200\347\273\210\346\225\210\346\236\234.md" +++ "b/\346\234\200\347\273\210\346\225\210\346\236\234.md" @@ -1,5 +1,6 @@ 点击订阅[Java面试进阶指南](https://xiaozhuanlan.com/java-coder)(专为Java面试方向准备) + ## 目录 - [Java](#Java) From f402c30e4522b4ef853eadabd7aaf19baea15c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 13:49:08 +0800 Subject: [PATCH 007/113] auto create toc --- src/main/java/md/mdToc.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java index 3650a29..f437a60 100644 --- a/src/main/java/md/mdToc.java +++ b/src/main/java/md/mdToc.java @@ -4,7 +4,7 @@ public class mdToc { public static void main(String[] args) { - String path = "D:\\javaTutorial\\docs\\distrubuted\\practice\\"; + String path = "D:\\javaTutorial\\docs\\"; AtxMarkdownToc.newInstance().genTocDir(path); } } From e3b676899c6d15670a03936a7dc2cc2954a12cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:35:45 +0800 Subject: [PATCH 008/113] bigend --- ...36\347\216\260\345\216\237\347\220\206.md" | 14 ++++++++ ...70\345\277\203\346\246\202\345\277\265.md" | 18 +++++++++++ ...72\346\234\254\346\246\202\345\277\265.md" | 21 +++++++++--- ...22\346\216\222\347\264\242\345\274\225.md" | 18 +++++++++++ ...45\344\275\234\345\216\237\347\220\206.md" | 32 +++++++++++++++---- ...06\344\270\216\345\256\236\350\267\265.md" | 14 ++++++++ ...45\351\227\250\345\256\236\350\267\265.md" | 14 ++++++-- ...15\344\270\226\344\273\212\347\224\237.md" | 21 +++++++++++- ...37\345\214\226\346\212\200\346\234\257.md" | 18 +++++++++++ ...347\232\204\345\237\272\347\237\263KVM.md" | 15 ++++++++- ...66\346\236\204\350\256\276\350\256\241.md" | 18 +++++++++++ ...03\346\246\202\345\277\265\345\220\247.md" | 17 ++++++++++ src/main/java/md/mdToc.java | 2 +- 13 files changed, 206 insertions(+), 16 deletions(-) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" index e4df0f1..054addd 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21010\357\274\232Docker \346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\347\216\260\345\216\237\347\220\206.md" @@ -14,8 +14,22 @@ * [[](https://draveness.me/docker?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%80%BB%E7%BB%93)总结](#[]httpsdravenessmedockerhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe680bbe7bb93总结) +本文转自互联网,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" index 72a42f0..68f03f1 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21011\357\274\232\345\215\201\345\210\206\351\222\237\347\220\206\350\247\243Kubernetes\346\240\270\345\277\203\346\246\202\345\277\265.md" @@ -12,6 +12,24 @@ * [下一步](#下一步) +本文转自互联网,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + + # 十分钟带你理解Kubernetes核心概念 本文将会简单介绍[Kubernetes](http://kubernetes.io/v1.1/docs/whatisk8s.html)的核心概念。因为这些定义可以在Kubernetes的文档中找到,所以文章也会避免用大段的枯燥的文字介绍。相反,我们会使用一些图表(其中一些是动画)和示例来解释这些概念。我们发现一些概念(比如Service)如果没有图表的辅助就很难全面地理解。在合适的地方我们也会提供Kubernetes文档的链接以便读者深入学习。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" index 99715ed..d4b83ff 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\21012\357\274\232\346\215\213\344\270\200\346\215\213\345\244\247\346\225\260\346\215\256\347\240\224\345\217\221\347\232\204\345\237\272\346\234\254\346\246\202\345\277\265.md" @@ -7,13 +7,26 @@ * [0xFF 总结](#0xff-总结) -作者:[**木东居士**] +本文作者:[**木东居士**] -个人主页:[http://www.mdjs.info](https://link.jianshu.com/?t=http%3A%2F%2Fwww.mdjs.info) -也可以关注我:木东居士。 +转自个人主页:[http://www.mdjs.info](https://link.jianshu.com/?t=http%3A%2F%2Fwww.mdjs.info) +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + -_文章可以转载, 但必须以超链接形式标明文章原始出处和作者信息_ ## 0x00 前言 > 你了解你的数据吗? diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" index 604a0c2..56081a3 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2101\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\237\272\347\241\200\345\200\222\346\216\222\347\264\242\345\274\225.md" @@ -7,6 +7,24 @@ * [4\. 单词词典](#4-单词词典) +本文转载自 https://www.cnblogs.com/zlslch/p/6440114.html + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + + # [什么是倒排索引?](https://www.cnblogs.com/zlslch/p/6440114.html) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" index 090c652..f962101 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2102\357\274\232\346\220\234\347\264\242\345\274\225\346\223\216\345\267\245\344\275\234\345\216\237\347\220\206.md" @@ -1,18 +1,38 @@ # Table of Contents + * [写在前面](#写在前面) + * [搜索引擎发展过程](#搜索引擎发展过程) + * [搜索引擎分类](#搜索引擎分类) + * [相关实现技术](#相关实现技术) + * [自己实现搜索引擎](#自己实现搜索引擎) + * [搜索引擎解决方案](#搜索引擎解决方案) 本文作者:顿炖 链接:https://www.zhihu.com/question/19937854/answer/98791215 来源:知乎 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial -写在前面 +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + +## 写在前面 Max Grigorev最近写了一篇文章,题目是[《What every software engineer should know about search》](https://link.juejin.im/?target=https%3A%2F%2Fmedium.com%2Fstartup-grind%2Fwhat-every-software-engineer-should-know-about-search-27d1df99f80d),这篇文章里指出了现在一些软件工程师的问题,他们认为开发一个搜索引擎功能就是搭建一个ElasticSearch集群,而没有深究背后的技术,以及技术发展趋势。Max认为,除了搜索引擎自身的搜索问题解决、人类使用方式等之外,也需要解决索引、分词、权限控制、国际化等等的技术点,看了他的文章,勾起了我多年前的想法。 很多年前,我曾经想过自己实现一个搜索引擎,作为自己的研究生论文课题,后来琢磨半天没有想出新的技术突破点(相较于已发表的文章),所以切换到了大数据相关的技术点。当时没有写出来,心中有点小遗憾,毕竟凭借搜索引擎崛起的谷歌是我内心渴望的公司。今天我就想结合自己的一些积累,聊聊作为一名软件工程师,您需要了解的搜索引擎知识。 -搜索引擎发展过程 +## 搜索引擎发展过程 现代意义上的搜索引擎的祖先,是1990年由蒙特利尔大学学生Alan Emtage发明的Archie。即便没有英特网,网络中文件传输还是相当频繁的,而且由于大量的文件散布在各个分散的FTP主机中,查询起来非常不便,因此Alan Emtage想到了开发一个可以以文件名查找文件的系统,于是便有了Archie。Archie工作原理与现在的搜索引擎已经很接近,它依靠脚本程序自动搜索网上的文件,然后对有关信息进行索引,供使用者以一定的表达式查询。 @@ -20,7 +40,7 @@ Max Grigorev最近写了一篇文章,题目是[《What every software engineer 随着互联网的迅速发展,每天都会新增大量的网站、网页,检索所有新出现的网页变得越来越困难,因此,在Matthew Gray的Wanderer基础上,一些编程者将传统的“蜘蛛”程序工作原理作了些改进。现代搜索引擎都是以此为基础发展的。 -搜索引擎分类 +## 搜索引擎分类 * 全文搜索引擎 @@ -34,7 +54,7 @@ Max Grigorev最近写了一篇文章,题目是[《What every software engineer 元搜索引擎在接受用户查询请求时,同时在其他多个引擎上进行搜索,并将结果返回给用户。著名的元搜索引擎有InfoSpace、Dogpile、Vivisimo等,中文元搜索引擎中具代表性的有搜星搜索引擎。在搜索结果排列方面,有的直接按来源引擎排列搜索结果,如Dogpile,有的则按自定的规则将结果重新排列组合,如Vivisimo。 -相关实现技术 +## 相关实现技术 搜索引擎产品虽然一般都只有一个输入框,但是对于所提供的服务,背后有很多不同业务引擎支撑,每个业务引擎又有很多不同的策略,每个策略又有很多模块协同处理,及其复杂。 @@ -115,7 +135,7 @@ Cloudera是一家将Hadoop技术用于搜索引擎的公司,用户可以采用 国际化、个性化搜索、匿名搜索,这些都是Google这样的产品所不能完全覆盖到的,事实上,也没有任何一款产品可以适用于所有需求。 -自己实现搜索引擎 +## 自己实现搜索引擎 如果我们想要实现搜索引擎,最重要的是索引模块和搜索模块。索引模块在不同的机器上各自进行对资源的索引,并把索引文件统一传输到同一个地方(可以是在远程服务器上,也可以是在本地)。搜索模块则利用这些从多个索引模块收集到的数据完成用户的搜索请求。因此,我们可以理解两个模块之间相对是独立的,它们之间的关联不是通过代码,而是通过索引和元数据,如下图所示。 @@ -123,7 +143,7 @@ Cloudera是一家将Hadoop技术用于搜索引擎的公司,用户可以采用 对于索引的建立,我们需要注意性能问题。当需要进行索引的资源数目不多时,隔一定的时间进行一次完全索引,不会占用很长时间。但在大型应用中,资源的容量是巨大的,如果每次都进行完整的索引,耗费的时间会很惊人。我们可以通过跳过已经索引的资源内容,删除已不存在的资源内容的索引,并进行增量索引来解决这个问题。这可能会涉及文件校验和索引删除等。另一方面,框架可以提供查询缓存功能,提高查询效率。框架可以在内存中建立一级缓存,并使用如 OSCache或 EHCache缓存框架,实现磁盘上的二级缓存。当索引的内容变化不频繁时,使用查询缓存更会明显地提高查询速度、降低资源消耗。 -搜索引擎解决方案 +## 搜索引擎解决方案 * Sphinx diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" index 539b237..bf1322d 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2103\357\274\232Lucene\345\237\272\347\241\200\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" @@ -32,7 +32,21 @@ * [高亮处理](#高亮处理) +本文转自互联网,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" index 8bf2dcb..3efc648 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2104\357\274\232Elasticsearch\344\270\216solr\345\205\245\351\227\250\345\256\236\350\267\265.md" @@ -44,15 +44,23 @@ # 阮一峰:全文搜索引擎 Elasticsearch 入门教程 +作者:阮一峰 -阅读 1093 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial -收藏 76 +喜欢的话麻烦点下Star哈 -2017-08-23 +本系列文章将整理到我的个人博客 +> www.how2playlife.com +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + 原文链接:[www.ruanyifeng.com](https://link.juejin.im/?target=http%3A%2F%2Fwww.ruanyifeng.com%2Fblog%2F2017%2F08%2Felasticsearch.html) [9月7日-8日 北京,与 Google Twitch 等团队技术大咖面对面www.bagevent.com](https://www.bagevent.com/event/1291755?bag_track=juejin) diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" index 03ea6fe..edcbfa4 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2105\357\274\232\344\272\221\350\256\241\347\256\227\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" @@ -32,7 +32,26 @@ * [容器管理平台初体验](#容器管理平台初体验) -**作者简介:**刘超,[网易云](https://www.163yun.com/product-cloudcompute?tag=M_smf_1190000008091499)解决方案首席架构师。10年云计算领域研发及架构经验,Open DC/OS贡献者。长期专注于kubernetes, OpenStack、Hadoop、Docker、Lucene、Mesos等开源软件的企业级应用及产品化。曾出版《Lucene应用开发揭秘》。 +**作者简介:**刘超,[网易云](https://www.163yun.com/product-cloudcompute?tag=M_smf_1190000008091499)解决方案首席架构师。 + +10年云计算领域研发及架构经验,Open DC/OS贡献者。 + +长期专注于kubernetes, OpenStack、Hadoop、Docker、Lucene、Mesos等开源软件的企业级应用及产品化。曾出版《Lucene应用开发揭秘》。 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + **以下为正文:** diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" index 42c16df..6a38c85 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2106\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" @@ -2,6 +2,24 @@ +本文转自互联网,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + + 内核,是指的操作系统内核。 所有的操作系统都有内核,无论是Windows还是Linux,都管理着三个重要的资源:计算,网络,存储。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" index 9a3e91c..98961fe 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2107\357\274\232OpenStack\347\232\204\345\237\272\347\237\263KVM.md" @@ -25,10 +25,23 @@ # [Qemu,KVM,Virsh傻傻的分不清](https://www.cnblogs.com/popsuper1982/p/8522535.html) -原创文章,转载请注明: 转载自[Itweet](https://link.juejin.im/?target=http%3A%2F%2Fwww.itweet.cn)的博客 + 本文转载自[Itweet](https://link.juejin.im/?target=http%3A%2F%2Fwww.itweet.cn)的博客 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" index 6b248f2..f9ee3b5 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2108\357\274\232OpenStack\346\236\266\346\236\204\350\256\276\350\256\241.md" @@ -12,6 +12,24 @@ * [总结](#总结) +本文转自互联网,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + + OpenStack 是开源云计算平台,支持多种虚拟化环境,并且其服务组件都提供了 API接口 便于二次开发。 OpenStack通过各种补充服务提供基础设施即服务 Infrastructure-as-a-Service (IaaS)`的解决方案。每个服务都提供便于集成的应用程序接口`Application Programming Interface (API)。 diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" index 05c9368..edf38ec 100644 --- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" +++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\2109\357\274\232\345\205\210\346\220\236\346\207\202Docker\346\240\270\345\277\203\346\246\202\345\277\265\345\220\247.md" @@ -23,6 +23,23 @@ * [六 总结](#六-总结) +本文转载自互联网,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将整理到我的个人博客 +> www.how2playlife.com + +更多Java技术文章会更新在我的微信公众号【Java技术江湖】上,欢迎关注 +该系列博文会介绍常见的后端技术,这对后端工程师来说是一种综合能力,我们会逐步了解搜索技术,云计算相关技术、大数据研发等常见的技术喜提,以便让你更完整地了解后端技术栈的全貌,为后续参与分布式应用的开发和学习做好准备。 + + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系我,欢迎你参与本系列博文的创作和修订。 + + + # 可能是把Docker的概念讲的最清楚的一篇文章 diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java index f437a60..93392d6 100644 --- a/src/main/java/md/mdToc.java +++ b/src/main/java/md/mdToc.java @@ -4,7 +4,7 @@ public class mdToc { public static void main(String[] args) { - String path = "D:\\javaTutorial\\docs\\"; + String path = "D:\\javaTutorial\\docs\\big-backEnd\\"; AtxMarkdownToc.newInstance().genTocDir(path); } } From ca87e911b64843a4d59f0b7e446c52559139d904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:38:28 +0800 Subject: [PATCH 009/113] cache --- ...4\346\211\247\350\241\214\350\277\207\347\250\213.md" | 6 +----- ...6\345\210\260\347\241\254\347\233\230\344\270\255.md" | 8 ++------ ...s\344\270\273\344\273\216\345\244\215\345\210\266.md" | 8 ++------ ...4\346\274\224\350\277\233\345\256\236\344\276\213.md" | 5 +---- ...D\347\211\271\346\200\247\344\273\213\347\273\215.md" | 8 ++------ ...7\351\224\201\350\277\233\345\214\226\345\217\262.md" | 8 ++------ ...6\347\273\223\346\236\204\346\246\202\350\247\210.md" | 7 +------ ...0\257\246\350\247\243\342\200\224\342\200\224dict.md" | 9 ++------- ...50\257\246\350\247\243\342\200\224\342\200\224sds.md" | 7 ++----- ...57\246\350\247\243\342\200\224\342\200\224ziplist.md" | 7 ++----- ...\246\350\247\243\342\200\224\342\200\224quicklist.md" | 7 ++----- ...7\246\350\247\243\342\200\224\342\200\224skiplist.md" | 7 ++----- ...257\246\350\247\243\342\200\224\342\200\224intset.md" | 7 ++----- ...6\225\260\346\215\256\347\273\223\346\236\204robj.md" | 8 ++------ ...7\345\210\240\351\231\244\347\255\226\347\225\245.md" | 8 ++------ 15 files changed, 27 insertions(+), 83 deletions(-) diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" index 4fc881d..b7abc28 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26010\357\274\232Redis\347\232\204\344\272\213\344\273\266\351\251\261\345\212\250\346\250\241\345\236\213\344\270\216\345\221\275\344\273\244\346\211\247\350\241\214\350\277\207\347\250\213.md" @@ -1,14 +1,10 @@ 本文转自https://www.xilidou.com/2018/03/12/redis-data/ 作者:犀利豆 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -系列文章将整理在我的个人博客: -> www.how2playlife.com - 本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" index f833e27..058e6b8 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26011\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" @@ -9,16 +9,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" index e0c797a..0d23887 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26012\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" @@ -19,16 +19,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" index 44b499e..e487e83 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26013\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" @@ -22,10 +22,7 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" index dc528d4..a24f1b9 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26014\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" @@ -14,16 +14,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" index ef83c44..9f3d353 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\26015\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" @@ -8,16 +8,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" index a13207d..6b59545 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2601\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" @@ -4,19 +4,14 @@ * [[](https://www.xilidou.com/2018/03/12/redis-data/#%E9%93%BE%E8%A1%A8 "链表")链表](#[]httpswwwxilidoucom20180312redis-datae993bee8a1a8-链表链表) * [[](https://www.xilidou.com/2018/03/12/redis-data/#%E5%AD%97%E5%85%B8 "字典")字典](#[]httpswwwxilidoucom20180312redis-datae5ad97e585b8-字典字典) - -本文转自互联网 本文转自https://www.xilidou.com/2018/03/22/redis-event/ 作者:犀利豆 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -系列文章将整理于我的个人博客: -> www.how2playlife.com - 本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" index 407986b..f79f1bd 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2602\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" @@ -6,19 +6,14 @@ * [dictIsRehashing(d) ((d)->rehashidx != -1)](#dictisrehashingd-d-rehashidx---1) * [dict的插入(dictAdd和dictReplace)](#dict的插入(dictadd和dictreplace)) * [dict的删除(dictDelete)](#dict的删除(dictdelete)) - - 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" index b9ada4f..2d094b4 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2603\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" @@ -20,15 +20,12 @@ 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" index 2751608..85ebd5e 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2604\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" @@ -9,15 +9,12 @@ 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" index 2620f6b..fb47b21 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2605\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" @@ -9,15 +9,12 @@ 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" index 3957aa3..5133967 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2606\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" @@ -15,15 +15,12 @@ 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" index 5b2645f..5baa446 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2607\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" @@ -14,15 +14,12 @@ 本文转自互联网 -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" index f8827a2..3dd96d6 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2608\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" @@ -25,16 +25,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" index 0292122..769c091 100644 --- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" +++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\2609\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" @@ -3,16 +3,12 @@ 本文转自互联网 - -本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +本文将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: -> www.how2playlife.com - -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 From d12fc2667bb87d74a3fdaa492d6a6d510699a677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:41:10 +0800 Subject: [PATCH 010/113] mysql --- ...43\344\272\233\346\227\245\345\277\227\344\273\254.md" | 8 ++++++-- ...350\201\212\350\201\212SQL\346\263\250\345\205\245.md" | 8 ++++++-- ...45\344\274\230\345\214\226\345\274\200\345\247\213.md" | 8 ++++++-- ...55\344\272\213\345\212\241\344\270\216\351\224\201.md" | 8 ++++++-- ...14\351\224\201\347\232\204\345\205\263\347\263\273.md" | 8 ++++++-- ...26\347\225\245\344\270\216\345\256\236\350\267\265.md" | 8 ++++++-- ...5\272\237\350\257\235MySQL\345\205\245\351\227\250.md" | 6 ++++-- ...5\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" | 8 ++++++-- ...56\345\255\230\345\202\250\345\216\237\347\220\206.md" | 8 ++++++-- ...56\347\273\223\346\236\204\347\256\227\346\263\225.md" | 8 ++++++-- ...06\346\236\220\344\270\216\344\274\230\345\214\226.md" | 8 ++++++-- ...16\347\232\204\351\224\201\345\256\236\347\216\260.md" | 8 ++++++-- ...73\347\272\247\345\210\253\345\256\236\346\210\230.md" | 8 ++++++-- 13 files changed, 76 insertions(+), 26 deletions(-) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" index d089cc8..f233134 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22310\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" @@ -16,10 +16,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -27,6 +29,8 @@ + + ## 重新学习MySQL数据库10:MySQL里的那些日志们 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" index 68b160c..8ee94df 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22311\357\274\232\344\273\245Java\347\232\204\350\247\206\350\247\222\346\235\245\350\201\212\350\201\212SQL\346\263\250\345\205\245.md" @@ -18,10 +18,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -29,6 +31,8 @@ + + 本文转自互联网 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" index bc03ab0..fb8bce6 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\22312\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" @@ -20,10 +20,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -31,6 +33,8 @@ + + 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在`千万级`以下,字符串为主的表在`五百万`以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量: diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" index 4411ceb..94eee23 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2236\357\274\232\346\265\205\350\260\210MySQL\347\232\204\344\270\255\344\272\213\345\212\241\344\270\216\351\224\201.md" @@ -42,10 +42,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -53,6 +55,8 @@ + + ## 『浅入深出』MySQL 中事务的实现 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" index c8ed7e2..17dd649 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\2239\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" @@ -23,10 +23,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -34,6 +36,8 @@ + + ## Innodb中的事务隔离级别和锁的关系 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" index f2e1f0c..38d0148 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\25613\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" @@ -31,10 +31,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -42,6 +44,8 @@ + + 一、MySQL扩展具体的实现方式 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" index a4445eb..f33d12a 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2231\357\274\232\346\227\240\345\272\237\350\257\235MySQL\345\205\245\351\227\250.md" @@ -47,10 +47,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" index e244e18..40e7408 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" @@ -33,10 +33,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -44,6 +46,8 @@ + + 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite 还是工程上使用非常广泛的 MySQL、PostgreSQL,但是一直以来也没有对数据库有一个非常清晰并且成体系的认知,所以最近两个月的时间看了几本数据库相关的书籍并且阅读了 MySQL 的官方文档,希望对各位了解数据库的、不了解数据库的有所帮助。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" index 09c5b22..683b5ca 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2233\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" @@ -42,15 +42,19 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + ## 前言 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" index 909bad8..b15743e 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2234\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" @@ -44,15 +44,19 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + ## MySQL索引 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" index 7551073..276dae3 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2235\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" @@ -39,10 +39,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -50,6 +52,8 @@ + + ## 一:Mysql原理与慢查询 MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”、“SQL语句优化”、“了解数据库原理”等要求。我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" index e3f1b73..a562c57 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2237\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" @@ -20,10 +20,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -31,6 +33,8 @@ + + 说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同。 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" index 5e1eab2..0bda9d3 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2238\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" @@ -12,10 +12,12 @@ 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本也将整理到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《重新学习MySQL数据库》系列其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时间,通过执行计划对SQL性能进行分析,再到MySQL的主从复制、主备部署等内容,以便让你更完整地了解整个MySQL方面的技术体系,形成自己的知识框架。 @@ -23,6 +25,8 @@ + + ## 事务的基本要素(ACID) From d8e8b6398cd8afc6d6487d925f9ca9468482ae8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:47:43 +0800 Subject: [PATCH 011/113] ds-basic-practice --- ...\200\247\343\200\2012PC\345\222\2143PC.md" | 13 +- ...5\237\272\347\241\2002 \357\274\232CAP.md" | 14 +- ...13\344\273\266\351\241\272\345\272\217.md" | 14 +- ...\237\272\347\241\2004\357\274\232Paxos.md" | 16 ++- ...76\345\222\214\347\247\237\347\272\246.md" | 15 +- ...41\2006\357\274\232Raft\343\200\201Zab.md" | 15 +- ...17\350\260\203\346\234\215\345\212\241.md" | 18 ++- ...03\345\210\260\345\205\245\351\227\250.md" | 46 ------ ...15\345\222\214\344\274\230\345\214\226.md" | 14 +- ...06\344\270\216\345\256\236\350\267\265.md" | 20 ++- ...44\270\200\350\207\264\346\200\247hash.md" | 17 +++ ...37\346\210\220\346\226\271\346\241\210.md" | 16 +++ ...04\351\202\243\344\272\233\344\272\213.md" | 12 ++ ...6\210\220Redis\347\274\223\345\255\230.md" | 17 +++ ...60\347\232\204\345\245\227\350\267\257.md" | 17 +++ ...40\347\247\215\346\226\271\346\241\210.md" | 17 +++ ...03\345\274\217\344\272\213\345\212\241.md" | 23 ++- ...43\345\206\263\346\226\271\346\241\210.md" | 16 +++ ...03\345\274\217\344\272\213\345\212\241.md" | 16 ++- ...72\346\234\254\346\246\202\345\277\265.md" | 134 ++++++++++++------ ...40\344\275\225\350\200\214\347\224\237.md" | 16 +++ ...\201\257\346\212\200\346\234\257 Kafka.md" | 17 +++ ...57\274\214Raft\347\256\227\346\263\225.md" | 68 ++++++--- ...0\203\346\234\215\345\212\241zookeeper.md" | 18 +++ ...01\347\250\213\350\257\246\350\247\243.md" | 18 +++ ...41\347\220\206\345\256\236\346\210\230.md" | 18 +++ ...57\345\217\212\345\256\236\350\267\265.md" | 17 +++ ...73\346\265\201\346\226\271\346\241\210.md" | 0 ...37\347\220\206\345\211\226\346\236\220.md" | 0 ...06\344\270\216\345\256\236\350\267\265.md" | 0 src/main/java/md/mdToc.java | 2 +- 31 files changed, 503 insertions(+), 141 deletions(-) delete mode 100644 "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" delete mode 100644 "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" delete mode 100644 "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" delete mode 100644 "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" index a02182f..d192928 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" @@ -1,21 +1,16 @@ -# Table of Contents - - * [**引言**](#引言) - - -本文转自互联网 +本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本文也将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。 +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" index 558acda..6a920e9 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" @@ -1,10 +1,20 @@ -# Table of Contents +本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + **引言** CAP是分布式系统、特别是分布式存储领域中被讨论最多的理论,“[什么是CAP定理?](https://www.quora.com/What-Is-CAP-Theorem-1)”在Quora 分布式系统分类下排名 FAQ 的 No.1。CAP在程序员中也有较广的普及,它不仅仅是“C、A、P不能同时满足,最多只能3选2”,以下尝试综合各方观点,从发展历史、工程实践等角度讲述CAP理论。希望大家透过本文对CAP理论有更多地了解和认识。 diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" index de0c194..0381390 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" @@ -1,10 +1,20 @@ -# Table of Contents +转自:https://www.cnblogs.com/bangerlee/p/5448766.html +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -转自:https://www.cnblogs.com/bangerlee/p/5448766.html +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + > 十六号…… 四月十六号。一九六零年四月十六号下午三点之前的一分钟你和我在一起,因为你我会记住这一分钟。从现在开始我们就是一分钟的朋友,这是事实,你改变不了,因为已经过去了。我明天会再来。 > diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" index afb74d0..53fbd78 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" @@ -1,14 +1,22 @@ -# Table of Contents +本文转自:https://www.cnblogs.com/bangerlee/p/5655754.html - * [**引言**](#引言) +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -本文转自:https://www.cnblogs.com/bangerlee/p/5655754.html +本文也将同步到我的个人博客: +> www.how2playlife.com -## **引言** +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + +## **引言** [《分布式系统理论基础 - 一致性、2PC和3PC》](http://www.cnblogs.com/bangerlee/p/5268485.html)一文介绍了一致性、达成一致性需要面临的各种问题以及2PC、3PC模型,Paxos协议在节点宕机恢复、消息无序或丢失、网络分化的场景下能保证决议的一致性,是被讨论最广泛的一致性协议。 diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" index 627599f..8d80f62 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" @@ -1,9 +1,20 @@ -# Table of Contents +本文转自:https://www.cnblogs.com/bangerlee/p/5767845.html +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -本文转自:https://www.cnblogs.com/bangerlee/p/5767845.html +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + 选举(election)是分布式系统实践中常见的问题,通过打破节点间的对等关系,选得的leader(或叫master、coordinator)有助于实现事务原子性、提升决议效率。 多数派(quorum)的思路帮助我们在网络分化的情况下达成决议一致性,在leader选举的场景下帮助我们选出唯一leader。租约(lease)在一定期限内给予节点特定权利,也可以用于实现leader选举。 diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" index 39ee1ee..eed436a 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" @@ -1,15 +1,22 @@ -# Table of Contents +本文转自:https://www.cnblogs.com/bangerlee/p/5991417.html - * [**引言**](#引言) +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -本文转自:https://www.cnblogs.com/bangerlee/p/5991417.html +本文也将同步到我的个人博客: +> www.how2playlife.com -## **引言** +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + +## **引言** [《分布式系统理论进阶 - Paxos》](http://www.cnblogs.com/bangerlee/p/5655754.html)介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议——Raft和Zab。通过与Paxos对比,了解Raft和Zab的核心思想、加深对一致性协议的认识。 diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" index a0810e6..bdfd882 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" @@ -1,6 +1,20 @@ -# Table of Contents +本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html - * [[分布式服务协调员zookeeper - 应用场景和监控](https://www.cnblogs.com/bangerlee/p/4427331.html)](#[分布式服务协调员zookeeper---应用场景和监控]httpswwwcnblogscombangerleep4427331html) +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + ## [分布式服务协调员zookeeper - 应用场景和监控](https://www.cnblogs.com/bangerlee/p/4427331.html) diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" deleted file mode 100644 index dd20632..0000000 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\345\274\200\347\257\207\357\274\232\344\273\216\346\224\276\345\274\203\345\210\260\345\205\245\351\227\250.md" +++ /dev/null @@ -1,46 +0,0 @@ -# Table of Contents - - - -本文转自 https://www.cnblogs.com/bangerlee/p/6216997.html - - 随承载用户数量的增加和容灾的需要,越来越多互联网后台系统从单机模式切换到分布式集群。回顾自己毕业五年来的工作内容,同样有这样的转变。 - - - - - -毕业头两年负责维护运行在刀片机上的业务,在机房里拔插单板的日子是我逝去的青春。设备之间通过VCS组成冷备,但即使有双机软件保护,宕机、网络丢包等问题发生时业务仍会受影响。这样的系统架构下为保证SLA,有时候需要深入[Linux系统内核](http://blog.chinaunix.net/uid/27119491.html)或硬件层面分析机器重启的原因。 - -![](https://images2015.cnblogs.com/blog/116770/201612/116770-20161230220301179-785557260.png) - -接下来负责维护承载在分布式集群上的业务,相比前面的工作,这个阶段主要关注点不是单节点的异常,更多是系统整体的稳定和健壮。面对纷繁复杂的系统,刚开始的时候有这样的感觉: - -![](https://images2015.cnblogs.com/blog/116770/201612/116770-20161230223338164-480704827.png) - -庞大复杂的分布式系统前,应该从哪方面入手提升对其的认识和理解、提升专业性?网上可以找到很多分布式系统相关的论文和资料,但归纳起来要表达的主要意思是什么? - -结合自己这几年的工作经验,总结分布式系统的核心就是解决一个问题:不同节点间如何达成共识。 - -看似简单的问题因网络丢包、节点宕机恢复等场景变得复杂,由此才衍生出很多概念、协议和理论。为探究共识问题最大能解决的程度,于是有FLP、CAP边界理论;为在特定条件和范围内解决该问题,于是有一致性协议Paxos、Raft、Zab和Viewstamped Replication;为构建这些协议,于是有多数派、Leader选举、租约、逻辑时钟等概念和方法。 - -2016年我阅读了分布式系统领域一些代表性的论文和博文,围绕“不同节点如何达成共识”这个问题,加入自己的认识和理解后有下面7篇小结: - -[一致性、2PC和3PC](http://www.cnblogs.com/bangerlee/p/5268485.html) -[选举、多数派和租约](http://www.cnblogs.com/bangerlee/p/5767845.html) -[时间、时钟和事件顺序](http://www.cnblogs.com/bangerlee/p/5448766.html) -[CAP](http://www.cnblogs.com/bangerlee/p/5328888.html) -[Paxos](http://www.cnblogs.com/bangerlee/p/5655754.html) -[Raft、Zab](http://www.cnblogs.com/bangerlee/p/5991417.html) -[Paxos变种和优化](http://www.cnblogs.com/bangerlee/p/6189646.html) - -构思和写作技术类文章是一个辛苦的过程,一方面要阅读很多资料并转化成自己的理解、找到尽量不拾人牙慧的立意和角度,一方面要绞尽脑汁组织语言让预期的读者能够容易理解。 - -但它也是一个有趣的过程,把知识捋一遍后原本一些模糊的概念变得清晰,写作过程中想到的一些有意思的内容我也会将它穿插到文章里,有时候会被自己想到的一些小机灵逗乐 :) - -![](https://images2015.cnblogs.com/blog/116770/201612/116770-20161224112116776-69607530.png) - -希望这几篇整理能为系统性地介绍分布式理论中文资料添一块砖、加一片瓦。 - - - diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" index 2b43b2b..1f62cb4 100644 --- "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" +++ "b/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" @@ -1,10 +1,20 @@ -# Table of Contents +本文转自:https://www.cnblogs.com/bangerlee/p/6189646.html +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 -本文转自:https://www.cnblogs.com/bangerlee/p/6189646.html +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解zookeeper的实现,以及CAP、一致性原理等一些常见的分布式理论基础,以便让你更完整地了解分布式理论的基础,为后续学习分布式技术内容做好准备。 +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + **引言** diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" index 94407e5..9b4fe9e 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" @@ -19,9 +19,27 @@ * [负载均衡 ip_hash算法](#负载均衡-ip_hash算法) -# 负载均衡的原理 原创: 刘欣 码农翻身 4月23日 +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + +# 负载均衡的原理 + 这是1998年一个普通的上午。 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" index f3cd76d..503f9a4 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" @@ -11,6 +11,23 @@ * [三、总结](#三、总结) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + # 一、问题的提出 ## 1\. 什么是Session? diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" index 93525ee..b783cfb 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" @@ -2,7 +2,23 @@ * [分布式ID生成器 | 架构师之路](#分布式id生成器--架构师之路) +本文内容参考网络,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + ## 分布式ID生成器 | 架构师之路 转自: 58沈剑 架构师之路 2017-06-25 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" index e822f1d..724a514 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" @@ -22,11 +22,23 @@ * [五、缓存降级](#五、缓存降级) * [六、总结](#六、总结) +本文内容参考网络,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial +喜欢的话麻烦点下Star哈 +本文也将同步到我的个人博客: +> www.how2playlife.com +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + # 缓存和它的那些淘汰算法们 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" index 01e4550..fbc86b4 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" @@ -6,6 +6,23 @@ * [二、创建需要缓存数据的类](#二、创建需要缓存数据的类) * [三、测试方法](#三、测试方法) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + 本文转载自 linkedkeeper.com diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" index ac52469..3709ac4 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" @@ -8,6 +8,23 @@ * [Write Behind Caching Pattern](#write-behind-caching-pattern) * [再多唠叨一些](#再多唠叨一些) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + 本文转载自 linkedkeeper.com diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" index df3ca80..5ea423c 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" @@ -1,6 +1,23 @@ # Table of Contents +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + 本文转载自 linkedkeeper.com diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" index 5afd869..0b540f5 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" @@ -4,6 +4,24 @@ 本文转载自 linkedkeeper.com +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + 众所周知,数据库能实现本地事务,也就是在同一个数据库中,你可以允许一组操作要么全都正确执行,要么全都不执行。这里特别强调了本地事务,也就是目前的数据库只能支持同一个数据库中的事务。但现在的系统往往采用微服务架构,业务系统拥有独立的数据库,因此就出现了跨多个数据库的事务需求,这种事务即为“分布式事务”。那么在目前数据库不支持跨库事务的情况下,我们应该如何实现分布式事务呢?本文首先会为大家梳理分布式事务的基本概念和理论基础,然后介绍几种目前常用的分布式事务解决方案。废话不多说,那就开始吧~ 什么是事务? @@ -244,8 +262,3 @@ http://blog.csdn.net/suifeng3051/article/details/52691210 https://my.oschina.net/wangzhenchao/blog/736909 - -转载请并标注: “本文转载自 linkedkeeper.com ” -———————————————— -版权声明:本文为CSDN博主「黄小斜」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 -原文链接:https://blog.csdn.net/a724888/article/details/80790138 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" index 64835ef..6458851 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" @@ -14,7 +14,23 @@ 本文转载自 linkedkeeper.com +本文内容参考网络,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + ## 分布式事务的解决方案 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" index 219e2c3..2c577d9 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" @@ -9,9 +9,23 @@ 本文转载自 linkedkeeper.com +本文内容参考网络,侵删 -本文转载自 linkedkeeper.com +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + # 初步认识RocketMQ的核心模块 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" index 0d762b7..1564a3c 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" @@ -1,15 +1,66 @@ # Table of Contents + * [1、分布式](#1、分布式) + * [2、集群(Cluster)](#2、集群(cluster)) + * [3、负载均衡(Load Balancer)](#3、负载均衡(load-balancer)) + * [4、弹性](#4、弹性) + * [怎么办?](#怎么办?) + * [认识分布式架构](#认识分布式架构) + * [集中式与分布式](#集中式与分布式) + * [分布性](#分布性) + * [对等性](#对等性) + * [并发性](#并发性) + * [缺乏全局时钟](#缺乏全局时钟) + * [故障总是会发生](#故障总是会发生) + * [分布式系统面临的问题](#分布式系统面临的问题) + * [通信异常](#通信异常) + * [网络分区](#网络分区) + * [三态](#三态) + * [节点故障](#节点故障) + * [分布式理论(一) - CAP定理](#分布式理论一---cap定理) + * [1. CAP原则简介](#1-cap原则简介) + * [2. CAP原则论证](#2-cap原则论证) + * [3. CAP原则权衡](#3-cap原则权衡) + * [小结](#小结) + * [分布式理论(二) - BASE理论](#分布式理论二---base理论) + * [1. CAP的3选2伪命题](#1-cap的3选2伪命题) + * [3. BASE理论的内容](#3-base理论的内容) + * [3.1. 基本可用](#31-基本可用) + * [3.2. 软状态](#32-软状态) + * [3.3. 最终一致性](#33-最终一致性) + * [更具体的分布式问题](#更具体的分布式问题) + * [分布式事务](#分布式事务) + * [二、分布式锁](#二、分布式锁) + * [三、分布式 Session](#三、分布式-session) + * [四、负载均衡](#四、负载均衡) + * [高可用之“脑裂”](#高可用之脑裂) 本文内容参考网络,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + + 本文较为粗略地讲述了CAP与BASE理论,以及分布式系统需要解决的一些问题,更加系统的理论可以参考后面的分布式系统理论专题文章。更加详细的实践内容也可以参考本专题的剩余文章     -1、分布式 +## 1、分布式 小明的公司又3个系统:系统A,系统B和系统C,这三个系统所做的业务不同,被部署在3个独立的机器上运行,他们之间互相调用(当然是跨域网络的),通力合作完成公司的业务流程。 @@ -23,7 +74,7 @@   -2、集群(Cluster) +## 2、集群(Cluster) 小明的公司不差钱,就多买几台机器吧, 小明把系统A一下子部署了好几份(例如下图的3个服务器),每一份都是系统A的一个实例,对外提供同样的服务,这样,就不怕其中一个坏掉了,还有另外两个呢。 @@ -37,7 +88,7 @@   -3、负载均衡(Load Balancer) +## 3、负载均衡(Load Balancer) 小明要尽可能的让3个机器上的系统A工作均衡一些,比如有3万个请求,那就让3个服务器各处理1万个(理想情况),这叫负载均衡 @@ -59,13 +110,13 @@   -4、弹性 +## 4、弹性 如果3个系统A的实例还是满足不了大量请求,例如双十一,可以申请增加服务器,双十一过后,新增的服务器闲置,成了摆设,于是小明决定尝试云计算,在云端可以轻松的创建,删除虚拟的服务器,那样就可以轻松的随着用户的请求动图的增减服务器了。   - 5、失效转移 + ## 5、失效转移 上面的系统看起来很美好,但是做了一个不切实际的假设: @@ -87,7 +138,7 @@   -怎么办? +## 怎么办? 一种办法是把状态信息在集群的各个服务器之间复制,让集群的各个服务器达成一致,谁来干这个事情?只能像Webspher,Weblogic这样的应用服务器了。 @@ -103,11 +154,11 @@   -认识分布式架构 +## 认识分布式架构 认识分布式架构 随着计算机系统规模变得越来越大,将所有的业务单元集中部署在一个或若干个大型机上的体系结构,已经越来越不能满足当今计算机系统,尤其是大型互联网系统的快速发展,各种灵活多变的系统架构模型层出不穷。分布式的处理方式越来越受到业界的青睐——计算机系统正在经历一场前所未有的从集中式向分布式架构的变革。 -集中式与分布式 +## 集中式与分布式 集中式系统 所谓的集中式系统就是指由一台或多台主计算机组成中心节点,数据集中存储于这个中心节点中,并且整个系统的所有业务单元都集中部署在这个中心节点上,系统的所有功能均由其集中处理。 @@ -120,40 +171,40 @@ 从分布式系统的概念中我们知道,各个主机之间通信和协调主要通过网络进行,所以分布式系统中的计算机在空间上几乎没有任何限制,这些计算机可能被放在不同的机柜上,也可能被部署在不同的机房中,还可能在不同的城市中,对于大型的网站甚至可能分布在不同的国家和地区。但是,无论空间上如何分布,一个标准的分布式系统应该具有以下几个主要特征: -分布性 +### 分布性 分布式系统中的多台计算机之间在空间位置上可以随意分布,同时,机器的分布情况也会随时变动。 -对等性 +### 对等性 分布式系统中的计算机没有主/从之分,即没有控制整个系统的主机,也没有被控制的从机,组成分布式系统的所有计算机节点都是对等的。副本(Replica)是分布式系统最常见的概念之一,指的是分布式系统对数据和服务提供的一种冗余方式。在常见的分布式系统中,为了对外提供高可用的服务,我们往往会对数据和服务进行副本处理。数据副本是指在不同节点上持久化同一份数据,当某一个节点上存储的数据丢失时,可以从副本上读取该数据,这是解决分布式系统数据丢失问题最为有效的手段。另一类副本是服务副本,指多个节点提供同样的服务,每个节点都有能力接收来自外部的请求并进行相应的处理。 -并发性 +### 并发性 在一个计算机网络中,程序运行过程的并发性操作是非常常见的行为。例如同一个分布式系统中的多个节点,可能会并发地操作一些共享的资源,如何准确并高效地协调分布式并发操作也成为了分布式系统架构与设计中最大的挑战之一。 -缺乏全局时钟 +### 缺乏全局时钟 在分布式系统中,很难定义两个事件究竟谁先谁后,原因就是因为分布式系统缺乏一个全局的时钟序列控制。 -故障总是会发生 +### 故障总是会发生 组成分布式系统的所有计算机,都有可能发生任何形式的故障。除非需求指标允许,在系统设计时不能放过任何异常情况。 -分布式系统面临的问题 -通信异常 +## 分布式系统面临的问题 +### 通信异常 分布式系统需要在各个节点之间进行网络通信,因此网络通信都会伴随着网络不可用的风险或是系统不可用都会导致最终分布式系统无法顺利完成一次网络通信。另外,即使分布式系统各节点之间的网络通信能够正常进行,其延时也会远大于单机操作,会影响消息的收发的过程,因此消息丢失和消息延迟变得非常普遍。 -网络分区 +### 网络分区 当网络由于发生异常情况,导致分布式系统中部分节点之间的网络延时不断增大,最终导致组成分布式系统的所有节点中,只有部分节点之间能够进行正常通信,而另一些节点则不能——我们将这个现象称为网络分区,就是俗称的“脑裂”。当网络分区出现时,分布式系统会出现局部小集群,在极端情况下,这些局部小集群会独立完成原本需要整个分布式才能完成的功能,这就对分布式一致性提出类非常大的挑战。 -三态 +### 三态 分布式系统的每一次请求与响应,存在特有的“三态”概念,即成功、失败与超时。当出现超时现象时,网络通信的发起方是无法确定当前请求是否被成功处理的。 -节点故障 +### 节点故障 节点故障则是分布式环境下另一个比较常见的问题,指的是组成分布式系统的服务器节点出现的宕机或“僵死”现象。 @@ -161,7 +212,7 @@   -分布式理论(一) - CAP定理 +## 分布式理论(一) - CAP定理 前言 CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)这三个基本需求,最多只能同时满足其中的2个。 @@ -171,7 +222,7 @@ CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency( 初探分布式理论 正文 -1. CAP原则简介 +### 1. CAP原则简介 选项 描述 Consistency(一致性) 指数据在多个副本之间能够保持一致的特性(严格的一致性) Availability(可用性) 指系统提供的服务必须一直处于可用的状态,每次请求都能获取到非错的响应(不保证获取的数据为最新数据) @@ -180,8 +231,8 @@ Partition tolerance(分区容错性) 分布式系统在遇到任何网络分 在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但他们的内部子网络是正常的。从而导致了整个系统的环境被切分成了若干个孤立的区域,这就是分区。 -2. CAP原则论证 -如图所示,是我们证明CAP的基本场景,网络中有两个节点N1和N2,可以简单的理解N1和N2分别是两台计算机,他们之间网络可以连通,N1中有一个应用程序A,和一个数据库V,N2也有一个应用程序B和一个数据库V。现在,A和B是分布式系统的两个部分,V是分布式系统的数据存储的两个子数据库。 +### 2. CAP原则论证 +CAP的基本场景,网络中有两个节点N1和N2,可以简单的理解N1和N2分别是两台计算机,他们之间网络可以连通,N1中有一个应用程序A,和一个数据库V,N2也有一个应用程序B和一个数据库V。现在,A和B是分布式系统的两个部分,V是分布式系统的数据存储的两个子数据库。   @@ -192,7 +243,8 @@ Partition tolerance(分区容错性) 分布式系统在遇到任何网络分 在满足一致性的时候,N1和N2中的数据是一样的,V0=V0。 在满足可用性的时候,用户不管是请求N1或者N2,都会得到立即响应。 在满足分区容错性的情况下,N1和N2有任何一方宕机,或者网络不通的时候,都不会影响N1和N2彼此之间的正常运作。 -如图所示,这是分布式系统正常运转的流程,用户向N1机器请求数据更新,程序A更新数据库V0为V1。分布式系统将数据进行同步操作M,将V1同步的N2中V0,使得N2中的数据V0也更新为V1,N2中的数据再响应N2的请求。 + +这是分布式系统正常运转的流程,用户向N1机器请求数据更新,程序A更新数据库V0为V1。分布式系统将数据进行同步操作M,将V1同步的N2中V0,使得N2中的数据V0也更新为V1,N2中的数据再响应N2的请求。   @@ -207,12 +259,8 @@ Partition tolerance(分区容错性) 分布式系统在遇到任何网络分 分区容错性:N1和N2之间的网络是否互通。 这是正常运作的场景,也是理想的场景。作为一个分布式系统,它和单机系统的最大区别,就在于网络。现在假设一种极端情况,N1和N2之间的网络断开了,我们要支持这种网络异常。相当于要满足分区容错性,能不能同时满足一致性和可用性呢?还是说要对他们进行取舍? -  - -  - 假设在N1和N2之间网络断开的时候,有用户向N1发送数据更新请求,那N1中的数据V0将被更新为V1。由于网络是断开的,所以分布式系统同步操作M,所以N2中的数据依旧是V0。这个时候,有用户向N2发送数据读取请求,由于数据还没有进行同步,应用程序没办法立即给用户返回最新的数据V1,怎么办呢? 这里有两种选择: @@ -221,7 +269,7 @@ Partition tolerance(分区容错性) 分布式系统在遇到任何网络分 第二:牺牲可用性,保证数据一致性。阻塞等待,直到网络连接恢复,数据更新操作M完成之后,再给用户响应最新的数据V1。 这个过程,证明了要满足分区容错性的分布式系统,只能在一致性和可用性两者中,选择其中一个。 -3. CAP原则权衡 +### 3. CAP原则权衡 通过CAP理论,我们知道无法同时满足一致性、可用性和分区容错性这三个特性,那要舍弃哪个呢? 3.1. CA without P @@ -233,19 +281,19 @@ Partition tolerance(分区容错性) 分布式系统在遇到任何网络分 3.3. AP wihtout C 要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。 -小结 +## 小结 对于多数大型互联网应用的场景,主机众多、部署分散。而且现在的集群规模越来越大,所以节点故障、网络故障是常态。这种应用一般要保证服务可用性达到N个9,即保证P和A,只有舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。 对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁可停止服务,这是保证CA,舍弃P。貌似这几年国内银行业发生了不下10起事故,但影响面不大,报到也不多,广大群众知道的少。还有一种是保证CP,舍弃A,例如网络故障时只读不写。 孰优孰劣,没有定论,只能根据场景定夺,适合的才是最好的。 -分布式理论(二) - BASE理论 +## 分布式理论(二) - BASE理论 前言 BASE理论是由eBay架构师提出的。BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网分布式系统实践的总结,是基于CAP定律逐步演化而来。其核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,才用适当的方式来使系统打到最终一致性。 正文 -1. CAP的3选2伪命题 +### 1. CAP的3选2伪命题 实际上,不是为了P(分区容错性),必须在C(一致性)和A(可用性)之间任选其一。分区的情况很少出现,CAP在大多时间能够同时满足C和A。 对于分区存在或者探知其影响的情况下,需要提供一种预备策略做出处理: @@ -260,25 +308,25 @@ BASE理论是Basically Available(基本可用),Soft State(软状态)和Eve 既是无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。 -3. BASE理论的内容 +### 3. BASE理论的内容 基本可用(Basically Available) 软状态(Soft State) 最终一致性(Eventually Consistent) 下面展开讨论: -3.1. 基本可用 +#### 3.1. 基本可用 什么是基本可用呢?假设系统,出现了不可预知的故障,但还是能用,相比较正常的系统而言: 响应时间上的损失:正常情况下的搜索引擎0.5秒即返回给用户结果,而基本可用的搜索引擎可以在2秒作用返回结果。 功能上的损失:在一个电商网站上,正常情况下,用户可以顺利完成每一笔订单。但是到了大促期间,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。 -3.2. 软状态 +#### 3.2. 软状态 什么是软状态呢?相对于原子性而言,要求多个节点的数据副本都是一致的,这是一种“硬状态”。 软状态指的是:允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。 -3.3. 最终一致性 +#### 3.3. 最终一致性 上面说软状态,然后不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性,从而达到数据的最终一致性。这个时间期限取决于网络延时、系统负载、数据复制方案设计等等因素。 而在实际工程实践中,最终一致性分为5种: @@ -307,8 +355,8 @@ BASE理论是Basically Available(基本可用),Soft State(软状态)和Eve 实际上,不只是分布式系统使用最终一致性,关系型数据库在某个功能上,也是使用最终一致性的。比如备份,数据库的复制过程是需要时间的,这个复制过程中,业务读取到的值就是旧的。当然,最终还是达成了数据一致性。这也算是一个最终一致性的经典案例。 -更具体的分布式问题 -一、分布式事务 +### 更具体的分布式问题 +#### 分布式事务 指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。例如在下单场景下,库存和订单如果不在同一个节点上,就需要涉及分布式事务。 本地消息 @@ -328,13 +376,14 @@ BASE理论是Basically Available(基本可用),Soft State(软状态)和Eve 两阶段提交协议 2PC -二、分布式锁 +#### 二、分布式锁 可以使用 Java 提供的内置锁来实现进程同步:由 JVM 实现的 synchronized 和 JDK 提供的 Lock。但是在分布式场景下,需要同步的进程可能位于不同的节点上,那么就需要使用分布式锁来同步。 原理 锁可以有阻塞锁和乐观锁两种实现方式,这里主要探讨阻塞锁实现。阻塞锁通常使用互斥量来实现,互斥量为 1 表示有其它进程在使用锁,此时处于锁定状态,互斥量为 0 表示未锁定状态。1 和 0 可以用一个整型值来存储,也可以用某个数据存在或者不存在来存储,某个数据存在表示互斥量为 1,也就是锁定状态。 实现 + 1. 数据库的唯一索引 当想要获得锁时,就向表中插入一条记录,释放锁时就删除这条记录。唯一索引可以保证该记录只被插入一次,那么就可以用这个记录是否存在来判断是否存于锁定状态。 @@ -372,6 +421,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点表示 永久节点:不会因为会话结束或者超时而消失; 临时节点:如果会话结束或者超时就会消失; 有序节点:会在节点名的后面加一个数字后缀,并且是有序的,例如生成的有序节点为 /lock/node-0000000000,它的下一个有序节点则为 /lock/node-0000000001,依次类推。 + (三)监听器 为一个节点注册监听器,在节点状态发生改变时,会给客户端发送消息。 @@ -382,6 +432,8 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点表示 在 /lock 下创建临时的且有序的子节点,第一个客户端对应的子节点为 /lock/lock-0000000000,第二个为 /lock/lock-0000000001,以此类推; 客户端获取 /lock 下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁;否则监听自己的前一个子节点,获得子节点的变更通知后重复此步骤直至获得锁; 执行业务代码,完成后,删除对应的子节点。 + + (五)会话超时 如果一个已经获得锁的会话超时了,因为创建的是临时节点,所以该会话对应的临时节点会被删除,其它会话就可以获得锁了。可以看到,Zookeeper 分布式锁不会出现数据库的唯一索引实现分布式锁的死锁问题。 @@ -390,7 +442,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点表示 一个节点未获得锁,需要监听自己的前一个子节点,这是因为如果监听所有的子节点,那么任意一个子节点状态改变,其它所有子节点都会收到通知(羊群效应),而我们只希望它的后一个子节点收到通知。 -三、分布式 Session +#### 三、分布式 Session 在分布式场景下,一个用户的 Session 如果只存储在一个服务器上,那么当负载均衡器把用户的下一个请求转发到另一个服务器上,该服务器没有用户的 Session,就可能导致用户需要重新进行登录等操作。 @@ -427,7 +479,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点表示 4. In-Memory DataStore 可以使用 Redis 和 Memcached 这种内存型数据库对 Session 进行存储,可以大大提高 Session 的读写效率。内存型数据库同样可以持久化数据到磁盘中来保证数据的安全性。 -四、负载均衡 +#### 四、负载均衡 算法 1. 轮询(Round Robin) 轮询算法把每个请求轮流发送到每个服务器上。下图中,一共有 6 个客户端产生了 6 个请求,这 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送。最后,(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。 @@ -532,7 +584,7 @@ PAC 服务器是用来判断一个请求是否要经过代理。   -高可用之“脑裂” +#### 高可用之“脑裂” 在涉及到高可用性时,经常会听到”脑裂“,到底啥是”脑裂“? diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" index f64952d..bfdfe76 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" @@ -35,7 +35,23 @@ 本文转载自 linkedkeeper.com +本文内容参考网络,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。 当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify、MetaQ、RocketMQ等。 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" index c86d17c..3f9149f 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" @@ -3,6 +3,23 @@ 本文转载自 linkedkeeper.com +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + 本文主要介绍了这几部分内容: diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" index 514f0b4..dd353fb 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" @@ -1,9 +1,39 @@ # Table of Contents + * [2PC](#2pc) + * [1. 分布式事务](#1-分布式事务) + * [2. XA规范](#2-xa规范) + * [3. 二阶段提交(2PC)](#3-二阶段提交(2pc)) + * [小结](#小结) + * [3PC](#3pc) + * [1. 三阶段提交的定义](#1-三阶段提交的定义) + * [2. 三阶段提交的过程](#2-三阶段提交的过程) + * [3. 小结](#3-小结) + * [四、Paxos](#四、paxos) + * [BasicPaxos与FastPaxos](#basicpaxos与fastpaxos) + * [五、Raft](#五、raft) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + 本文较为粗略地讲述了一致性协议与两种一致性算法,更加系统的理论可以参考后面的分布式系统理论专题文章。 -2PC +## 2PC 由于BASE理论需要在一致性和可用性方面做出权衡,因此涌现了很多关于一致性的算法和协议。其中比较著名的有二阶提交协议(2 Phase Commitment Protocol),三阶提交协议(3 Phase Commitment Protocol)和Paxos算法。 本文要介绍的2PC协议,分为两个阶段提交一个事务。并通过协调者和各个参与者的配合,实现分布式一致性。 @@ -13,15 +43,14 @@ 角色 XA概念 作用 协调者 事务管理器 协调各个参与者,对分布式事务进行提交或回滚 参与者 资源管理器 分布式集群中的节点 -正文 -1. 分布式事务 +### 1. 分布式事务 分布式事务是指会涉及到操作多个数据库的事务,其实就是将对同一库事务的概念扩大到了对多个库的事务。目的是为了保证分布式系统中的数据一致性。 分布式事务处理的关键是: 需要记录事务在任何节点所做的所有动作; 事务进行的所有操作要么全部提交,要么全部回滚。 -2. XA规范 +### 2. XA规范 2.1. XA规范的组成 XA规范是由 X/Open组织(即现在的 Open Group )定义的分布式事务处理模型。 X/Open DTP 模型( 1994 )包括: @@ -48,7 +77,7 @@ AP结束全局事务时,TM会通知RM全局事务结束。开始二段提交 XA规范的流程,大致如图所示: -3. 二阶段提交(2PC) +### 3. 二阶段提交(2PC) 3.1. 二阶段提交的定义 二阶段提交的算法思路可以概括为:每个参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报,决定各参与者是否要提交操作还是中止操作。 @@ -128,13 +157,13 @@ d. 事务中断确认 容错性不好 如果在二阶段提交的提交询问阶段中,参与者出现故障,导致协调者始终无法获取到所有参与者的确认信息,这时协调者只能依靠其自身的超时机制,判断是否需要中断事务。显然,这种策略过于保守。换句话说,二阶段提交协议没有设计较为完善的容错机制,任意一个节点是失败都会导致整个事务的失败。 -小结 +### 小结 对于2PC协议存在的同步阻塞、单点问题,将在下一篇文章的3PC协议中引入解决方案。 -3PC +## 3PC 由于二阶段提交存在着诸如同步阻塞、单点问题、脑裂等缺陷。所以,研究者们在二阶段提交的基础上做了改进,提出了三阶段提交。 @@ -142,8 +171,8 @@ d. 事务中断确认 引入超时机制 - 同时在协调者和参与者中都引入超时机制。 在第一阶段和第二阶段中插入一个准备阶段,保证了在最后提交阶段之前各参与节点的状态是一致的。 -正文 -1. 三阶段提交的定义 + +### 1. 三阶段提交的定义 三阶段提交(Three-phase commit),也叫三阶段提交协议(Three-phase commit protocol),是二阶段提交(2PC)的改进版本。 所谓的三个阶段分别是:询问,然后再锁资源,最后真正提交。 @@ -151,7 +180,7 @@ d. 事务中断确认 第一阶段:CanCommit 第二阶段:PreCommit 第三阶段:Do Commit -2. 三阶段提交的过程 +### 2. 三阶段提交的过程 2.1. 阶段一:CanCommit 3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。 @@ -227,7 +256,7 @@ d. 中断事务 协调者接收到参与者反馈的 ACK 消息之后,完成事务的中断。 -3. 小结 +### 3. 小结 3.1. 三阶段提交的优点 相对于二阶段提交,三阶段提交主要解决的单点故障问题,并减少了阻塞的时间。 @@ -239,7 +268,7 @@ d. 中断事务 这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。 -四、Paxos +## 四、Paxos 用于达成共识性问题,即对多个节点产生的值,该算法能保证只选出唯一一个值。 主要有三类节点: @@ -293,7 +322,7 @@ Paxos 协议能够让 Proposer 发送的提议朝着能被大多数 Acceptor 接 -BasicPaxos与FastPaxos +## BasicPaxos与FastPaxos 1 Paxos算法 1.1 基本定义 @@ -388,7 +417,7 @@ Leader将用户的请求转化为对应的paxos实例,当然,它可以并发 (4).如何动态的扩展Acceptor -五、Raft +## 五、Raft Raft 和 Paxos 类似,但是更容易理解,也更容易实现。 Raft 主要是用来竞选主节点。 @@ -429,8 +458,9 @@ Leader 会等待大多数的 Follower 也进行了修改,然后才将修改提 参考资料 -倪超. 从 Paxos 到 ZooKeeper : 分布式一致性原理与实践 [M]. 电子工业出版社, 2015. -What is CAP theorem in distributed database system? -NEAT ALGORITHMS - PAXOS -Raft: Understandable Distributed Consensus -Paxos By Example + + 倪超. 从 Paxos 到 ZooKeeper : 分布式一致性原理与实践 [M]. 电子工业出版社, 2015. + What is CAP theorem in distributed database system? + NEAT ALGORITHMS - PAXOS + Raft: Understandable Distributed Consensus + Paxos By Example diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" index 3720fb7..8f4190f 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" @@ -4,6 +4,24 @@ 本文转自:微信公众号【码农翻身】 +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + 张大胖所在的公司这几年发展得相当不错,业务激增,人员也迅速扩展,转眼之间,张大胖已经成为公司的“资深”员工了,更重要的是,经过这些年的不懈努力,他终于坐上了架构师的宝座。 但是大胖很快发现,这架构师真不是好当的,技术选型、架构设计,尤其是大家搞不定的技术难点,最终都得自己扛起来。沟通、说服、妥协、甚至争吵都是家常便饭,比自己之前单纯做开发的时候难多了。 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" index 13dee71..562ebcb 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" @@ -29,6 +29,24 @@ * [[](http://www.jasongj.com/zookeeper/fastleaderelection/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#%E6%80%BB%E7%BB%93 "总结")总结](#[]httpwwwjasongjcomzookeeperfastleaderelectionhmsrtoutiaoioutm_mediumtoutiaoioutm_sourcetoutiaoioe680bbe7bb93-总结总结) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + ## ZAB协议 1. ZAB协议是专门为zookeeper实现分布式协调功能而设计。zookeeper主要是根据ZAB协议是实现分布式系统数据一致性。 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" index a3bee21..f624388 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" @@ -14,6 +14,24 @@ * [5.3 集群容灾](#53-集群容灾) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + + ## 4.1 配置文件 ZooKeeper安装好之后,在安装目录的conf文件夹下可以找到一个名为“**zoo_sample.cfg**”的文件,是ZooKeeper配置文件的模板。 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" index 8753510..d382758 100644 --- "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" +++ "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" @@ -21,6 +21,23 @@ * [**集群管理**](#集群管理) * [**分布式队列**](#分布式队列) +本文内容参考网络,侵删 + +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本文也将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。 + +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 + + # 一.ZooKeeper典型应用场景实践 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2577\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\346\246\202\345\277\265\344\270\216\344\270\273\346\265\201\346\226\271\346\241\210.md" deleted file mode 100644 index e69de29..0000000 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2578\357\274\232\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\345\211\226\346\236\220.md" deleted file mode 100644 index e69de29..0000000 diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2579\357\274\232Nginx\350\264\237\350\275\275\345\235\207\350\241\241\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java index 93392d6..3650a29 100644 --- a/src/main/java/md/mdToc.java +++ b/src/main/java/md/mdToc.java @@ -4,7 +4,7 @@ public class mdToc { public static void main(String[] args) { - String path = "D:\\javaTutorial\\docs\\big-backEnd\\"; + String path = "D:\\javaTutorial\\docs\\distrubuted\\practice\\"; AtxMarkdownToc.newInstance().genTocDir(path); } } From de043d1e4a8919a38bc38b5c8aef7c43000f6271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:54:47 +0800 Subject: [PATCH 012/113] =?UTF-8?q?=C3=A2=C2=80java=20web?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...216JavaBean\350\256\262\345\210\260Spring.md" | 12 ++++++------ ...\350\257\225\346\241\206\346\236\266Junit.md" | 10 +++++++--- ...\345\273\272\345\267\245\345\205\267Maven.md" | 10 +++++++--- ...7\243\345\274\217\345\274\200\345\217\221.md" | 7 +++++-- ...57\274\232Mybatis\345\205\245\351\227\250.md" | 10 +++++++--- ...205\215\347\275\256\347\232\204SpringBoot.md" | 7 +++++-- ...7\272\347\241\200\347\237\245\350\257\206.md" | 8 +++++--- ...3\217\344\270\216\347\216\260\345\234\250.md" | 7 +++++-- ...6\245\346\261\240\346\212\200\346\234\257.md" | 11 ++++++++--- ...6\237\347\220\206\350\257\246\350\247\243.md" | 10 ++++++---- ...7\267\346\261\202\350\277\207\347\250\213.md" | 10 ++++++---- ...6\266\346\236\204\345\211\226\346\236\220.md" | 10 ++++++---- ...1\250\347\232\204\345\214\272\345\210\253.md" | 16 +++++++++++++--- ...3\250\347\275\262\350\277\207\347\250\213.md" | 10 ++++++---- ...4\237\344\270\216\345\217\221\345\261\225.md" | 10 +++++++--- 15 files changed, 99 insertions(+), 49 deletions(-) diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" index cb7f41f..985e2e4 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21410\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md" @@ -12,22 +12,22 @@ * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) - +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。 +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 -**文末赠送8000G的Java架构师学习资料,需要的朋友可以到文末了解领取方式,资料包括Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源)** +如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" index f9ae3cc..3c00524 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21411\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" @@ -22,17 +22,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" index 389bac7..dac71a8 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21412\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" @@ -26,17 +26,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" index dc4bd06..738b37f 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21413\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" @@ -11,15 +11,18 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" index 9957a37..6a2976a 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21414\357\274\232Mybatis\345\205\245\351\227\250.md" @@ -24,16 +24,20 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 + +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" index 93de865..a5cbc34 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21416\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" @@ -21,15 +21,18 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" index df4d6d5..1377342 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2141\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -14,16 +14,18 @@ * [个人公众号:程序员黄小斜](#个人公众号:程序员黄小斜) * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) - +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" index 1aafcee..e396253 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2142\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" @@ -18,15 +18,18 @@ * [参考文章](#参考文章) +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" index 7b1dc3f..898f592 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2143\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" @@ -17,16 +17,21 @@ * [参考文章](#参考文章) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 + +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" index 7624200..4e4c0db 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -12,19 +12,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。 +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" index a21cbb6..921ddf8 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2145\357\274\232\345\210\235\346\216\242Tomcat\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" @@ -8,19 +8,21 @@ * [参考文章](#参考文章) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。 +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" index b57d34b..2434a07 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2146\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" @@ -45,19 +45,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。 +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" index e9edcbb..db38428 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2147\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" @@ -20,11 +20,21 @@ 文章首发于我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。 +本文转载自互联网,侵删 +本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 +> https://github.com/h2pl/Java-Tutorial + +喜欢的话麻烦点下Star哈 + +本系列文章将同步到我的个人博客: +> www.how2playlife.com + +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" index 04a11f8..c656802 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2148\357\274\232\346\265\205\346\236\220Tomcat9\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" @@ -13,19 +13,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个Java Web技术体系,形成自己的知识框架。 +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" index 13c8bb7..d265b76 100644 --- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" +++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2149\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" @@ -18,17 +18,21 @@ * [技术公众号:Java技术江湖](#技术公众号:java技术江湖) + +本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 -文章首发于我的个人博客: +本系列文章将同步到我的个人博客: > www.how2playlife.com -本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 +更多Java技术文章将陆续在微信公众号【Java技术江湖】更新,敬请关注。 + +本文是《走进JavaWeb技术世界》系列博文的其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。 -该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。 +该系列博文会告诉你如何从入门到进阶,从servlet到框架,从ssm再到SpringBoot,一步步地学习JavaWeb基础知识,并上手进行实战,接着了解JavaWeb项目中经常要使用的技术和组件,包括日志组件、Maven、Junit,等等内容,以便让你更完整地了解整个JavaWeb技术体系,形成自己的知识框架。为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 From 0c598fd99b4253ae8dc92913a6d0bff0e4743dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 22 Nov 2019 19:57:53 +0800 Subject: [PATCH 013/113] spring and javaweb --- ...67\346\261\202\346\250\241\345\236\213.md" | 25 ------------------- ...32\344\277\241\346\234\272\345\210\266.md" | 15 ----------- ...37\347\220\206\350\257\246\350\247\243.md" | 15 ----------- 3 files changed, 55 deletions(-) diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" index 1d9a4e2..81e4a96 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" @@ -1,28 +1,3 @@ -# Table of Contents - - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BD%93%E5%89%8D%E7%8E%AF%E5%A2%83)当前环境](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bd93e5898de78eafe5a283当前环境) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E4%BB%A3%E7%A0%81%E5%9C%B0%E5%9D%80)代码地址](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde4bba3e7a081e59cb0e59d80代码地址) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E7%9F%A5%E8%AF%86%E7%82%B9)知识点](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde79fa5e8af86e782b9知识点) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%9C%BA%E6%99%AF)场景](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde59cbae699af场景) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#nio-%E7%9A%84%E9%98%BB%E5%A1%9E%E5%AE%9E%E7%8E%B0)nio 的阻塞实现](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomdnio-e79a84e998bbe5a19ee5ae9ee78eb0nio-的阻塞实现) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5)建立连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bbbae7ab8be8bf9ee68ea5建立连接) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E8%8E%B7%E5%8F%96-socket-%E8%BF%9E%E6%8E%A5)获取 socket 连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde88eb7e58f96-socket-e8bf9ee68ea5获取-socket-连接) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B)完整示例](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5ae8ce695b4e7a4bae4be8b完整示例) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#nio-%E7%9A%84%E9%9D%9E%E9%98%BB%E5%A1%9E%E5%AE%9E%E7%8E%B0)nio 的非阻塞实现](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomdnio-e79a84e99d9ee998bbe5a19ee5ae9ee78eb0nio-的非阻塞实现) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90)原理分析](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde58e9fe79086e58886e69e90原理分析) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%88%9B%E5%BB%BA%E9%80%89%E6%8B%A9%E5%99%A8)创建选择器](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5889be5bbbae98089e68ba9e599a8创建选择器) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%88%9B%E5%BB%BA%E9%9D%9E%E9%98%BB%E5%A1%9E-io)创建非阻塞 I/O](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5889be5bbbae99d9ee998bbe5a19e-io创建非阻塞-io) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%BB%BA%E7%AB%8B%E9%80%89%E6%8B%A9%E5%99%A8%E4%B8%8E-socket-%E7%9A%84%E5%85%B3%E8%81%94)建立选择器与 socket 的关联](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5bbbae7ab8be98089e68ba9e599a8e4b88e-socket-e79a84e585b3e88194建立选择器与-socket-的关联) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E9%80%89%E6%8B%A9%E5%99%A8%E7%9B%91%E5%90%AC-socket-%E5%8F%98%E5%8C%96)选择器监听 socket 变化](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde98089e68ba9e599a8e79b91e590ac-socket-e58f98e58c96选择器监听-socket-变化) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E8%BF%9E%E6%8E%A5%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理连接就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e8bf9ee68ea5e5b0b1e7bbaae4ba8be4bbb6处理连接就绪事件) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E5%86%99%E5%85%A5%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理写入就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e58699e585a5e5b0b1e7bbaae4ba8be4bbb6处理写入就绪事件) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%A4%84%E7%90%86%E8%AF%BB%E5%8F%96%E5%B0%B1%E7%BB%AA%E4%BA%8B%E4%BB%B6)处理读取就绪事件](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5a484e79086e8afbbe58f96e5b0b1e7bbaae4ba8be4bbb6处理读取就绪事件) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%AE%8C%E6%95%B4%E4%BB%A3%E7%A0%81)完整代码](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5ae8ce695b4e4bba3e7a081完整代码) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E7%A4%BA%E4%BE%8B%E6%95%88%E6%9E%9C)示例效果](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde7a4bae4be8be69588e69e9c示例效果) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E6%80%BB%E7%BB%93)总结](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde680bbe7bb93总结) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-nio.md#%E5%90%8E%E7%BB%AD)后续](#[]httpsgithubcomjasongeng88blogblobmaster201708java-niomde5908ee7bbad后续) - - 本文转载自:[https://github.com/jasonGeng88/blog](https://github.com/jasonGeng88/blog) 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" index b24047e..b96bfd5 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" @@ -1,18 +1,3 @@ -# Table of Contents - - * [当前环境](#当前环境) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E7%9F%A5%E8%AF%86%E7%82%B9)知识点](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde79fa5e8af86e782b9知识点) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%9C%BA%E6%99%AF)场景](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde59cbae699af场景) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%BB%BA%E7%AB%8B-socket-%E8%BF%9E%E6%8E%A5)建立 socket 连接](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5bbbae7ab8b-socket-e8bf9ee68ea5建立-socket-连接) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%A4%84%E7%90%86-socket-%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%B5%81)处理 socket 输入输出流](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5a484e79086-socket-e8be93e585a5e8be93e587bae6b581处理-socket-输入输出流) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E6%95%B0%E6%8D%AE%E8%AF%B7%E6%B1%82%E4%B8%8E%E5%93%8D%E5%BA%94)数据请求与响应](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde695b0e68daee8afb7e6b182e4b88ee5938de5ba94数据请求与响应) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E7%BB%93%E6%9E%9C%E5%B1%95%E7%A4%BA)结果展示](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde7bb93e69e9ce5b195e7a4ba结果展示) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%9E%8B%E4%BC%98%E5%8C%96)请求模型优化](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde8afb7e6b182e6a8a1e59e8be4bc98e58c96请求模型优化) - * [补充1:TCP客户端与服务端](#补充1:tcp客户端与服务端) - * [补充2:UDP客户端和服务端](#补充2:udp客户端和服务端) - * [[](https://github.com/jasonGeng88/blog/blob/master/201708/java-socket.md#%E5%90%8E%E7%BB%AD)后续](#[]httpsgithubcomjasongeng88blogblobmaster201708java-socketmde5908ee7bbad后续) - - 本文转自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" index c5ca134..e480340 100644 --- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" +++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" @@ -1,18 +1,3 @@ -# Table of Contents - - * [为什么要 I/O 多路复用](#为什么要-io-多路复用) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#select "select")select](#[]httpsjeffwtf201702io-multiplexingselect-selectselect) - * [](#sysselecth) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#poll "poll")poll](#[]httpsjeffwtf201702io-multiplexingpoll-pollpoll) - * [](#pollh) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll "epoll")epoll](#[]httpsjeffwtf201702io-multiplexingepoll-epollepoll) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-create-%E7%94%A8%E6%9D%A5%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA-epoll-%E6%8F%8F%E8%BF%B0%E7%AC%A6%EF%BC%9A "epoll_create 用来创建一个 epoll 描述符:")epoll_create 用来创建一个 epoll 描述符:](#[]httpsjeffwtf201702io-multiplexingepoll-create-e794a8e69da5e5889be5bbbae4b880e4b8aa-epoll-e68f8fe8bfb0e7aca6efbc9a-epoll_create-用来创建一个-epoll-描述符:epoll_create-用来创建一个-epoll-描述符:) - * [](#sysepollh) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-ctl-%E7%94%A8%E6%9D%A5%E5%A2%9E-%E5%88%A0-%E6%94%B9%E5%86%85%E6%A0%B8%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E8%A1%A8%EF%BC%9A "epoll_ctl 用来增/删/改内核中的事件表:")epoll_ctl 用来增/删/改内核中的事件表:](#[]httpsjeffwtf201702io-multiplexingepoll-ctl-e794a8e69da5e5a29e-e588a0-e694b9e58685e6a0b8e4b8ade79a84e4ba8be4bbb6e8a1a8efbc9a-epoll_ctl-用来增删改内核中的事件表:epoll_ctl-用来增删改内核中的事件表:) - * [[](https://jeff.wtf/2017/02/IO-multiplexing/#epoll-wait-%E7%94%A8%E6%9D%A5%E7%AD%89%E5%BE%85%E4%BA%8B%E4%BB%B6 "epoll_wait 用来等待事件")epoll_wait 用来等待事件](#[]httpsjeffwtf201702io-multiplexingepoll-wait-e794a8e69da5e7ad89e5be85e4ba8be4bbb6-epoll_wait-用来等待事件epoll_wait-用来等待事件) -* [DEFINE MAXEVENTS 4](#define-maxevents-4) - - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial From 25d447b9750d7a1f93ce827c25d2b5e9a2871926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Java=E6=8A=80=E6=9C=AF=E6=B1=9F=E6=B9=96?= <362294931@qq.com> Date: Sat, 23 Nov 2019 15:34:12 +0800 Subject: [PATCH 014/113] Update ReadMe.md --- ReadMe.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index fda1c07..d8b2387 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,6 +3,8 @@ 这些文章和总结都是我近几年学习Java总结和整理出来的,非常实用,对于学习Java后端的朋友来说应该是最全面最完整的技术仓库。 我靠着这些内容进行复习,拿到了BAT等大厂的offer,这个仓库也已经帮助了很多的Java学习者,如果对你有用,希望能给个star支持我,谢谢! +为了更好地讲清楚每个知识模块,我们也参考了很多网上的优质博文,力求不漏掉每一个知识点,所有参考博文都将声明转载来源,如有侵权,请联系我。 + 点击关注[微信公众号](#微信公众号)及时获取笔主最新更新文章,并可免费领取Java工程师必备学习资源,以及我原创的电子书《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》

From e3810c903de90a077f3deb513eb8603631033f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Tue, 17 Dec 2019 19:15:14 +0800 Subject: [PATCH 015/113] Update ReadMe.md --- ReadMe.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index d8b2387..b9348a8 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -216,14 +216,14 @@ todo ## 计算机基础 ### 计算机网络 -* [计算机网络学习总结](docs/network/计算机网络学习总结.md) +todo ### 操作系统 -* [操作系统学习总结](docs/operateing-system/操作系统学习总结.md) +todo #### Linux相关 -* [Linux内核与基础命令学习总结](docs/operateing-system/Linux内核与基础命令学习总结.md) +todo ### 数据结构与算法 @@ -233,9 +233,10 @@ todo todo #### 算法 -* [剑指offer](docs/algorithms/剑指offer.md) +todo ## 数据库 +todo ### MySQL * [Mysql原理与实践总结](docs/database/Mysql原理与实践总结.md) From 2b3b1ce3eeaad3ba52e24da444fcc55bb14fdd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Thu, 23 Jan 2020 10:34:25 +0800 Subject: [PATCH 016/113] Update ReadMe.md --- ReadMe.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index b9348a8..05909c0 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -9,14 +9,10 @@

- +

-

- 阅读 - 微信公众号 -

推荐使用 https://how2playlife.com/ 在线阅读,在线阅读内容本仓库同步一致。这种方式阅读的优势在于:左侧边栏有目录,阅读体验更好。 From 76f85462e681cb91c187b3d8c234ed0a8f37797f Mon Sep 17 00:00:00 2001 From: Jack <30426054+dislazy@users.noreply.github.com> Date: Thu, 19 Mar 2020 15:27:09 +0800 Subject: [PATCH 017/113] =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...34\254\346\225\260\346\215\256\347\261\273\345\236\213.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" index d601d6e..655b4c2 100644 --- "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" +++ "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" @@ -468,9 +468,9 @@ public static void main(String[] args) { (2)Byte复用了全部256个对象[-128,127]; -(3)Short服用了[-128,127]这些对象; +(3)Short复用了[-128,127]这些对象; -(4)Long服用了[-128,127]; +(4)Long复用了[-128,127]; (5)Character复用了[0,127],Charater不能表示负数; From 2013dd94ec38f98fc13b05d05b86e9924261f18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Sun, 22 Mar 2020 15:50:23 +0800 Subject: [PATCH 018/113] Update ReadMe.md --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 05909c0..4b9fe38 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -5,7 +5,7 @@ 为了更好地讲清楚每个知识模块,我们也参考了很多网上的优质博文,力求不漏掉每一个知识点,所有参考博文都将声明转载来源,如有侵权,请联系我。 -点击关注[微信公众号](#微信公众号)及时获取笔主最新更新文章,并可免费领取Java工程师必备学习资源,以及我原创的电子书《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》 +点击关注[微信公众号](#微信公众号)及时获取笔主最新更新文章,并可免费领取Java工程师必备学习资源

From 5ec9025967eb4e919d97c2acc0c321aebe7dcfcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Sun, 7 Jun 2020 13:26:31 +0800 Subject: [PATCH 019/113] Update ReadMe.md --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 4b9fe38..54edfa2 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -113,7 +113,7 @@ * [走进JavaWeb技术世界1:JavaWeb的由来和基础知识](docs/java-web/走进JavaWeb技术世界1:JavaWeb的由来和基础知识.md) * [走进JavaWeb技术世界2:JSP与Servlet的曾经与现在](docs/java-web/走进JavaWeb技术世界2:JSP与Servlet的曾经与现在.md) * [走进JavaWeb技术世界3:JDBC的进化与连接池技术](docs/java-web/走进JavaWeb技术世界3:JDBC的进化与连接池技术.md) -* [走进JavaWeb技术世界4:Servlet 工作原理详解](docs/java-web/走进JavaWeb技术世界4:Servlet%29工作原理详解.md) +* [走进JavaWeb技术世界4:Servlet 工作原理详解](docs/java-web/走进JavaWeb技术世界4:Servlet%20工作原理详解.md) * [走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程](docs/java-web/走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程.md) * [走进JavaWeb技术世界6:Tomcat5总体架构剖析](docs/java-web/走进JavaWeb技术世界6:Tomcat5总体架构剖析.md) * [走进JavaWeb技术世界7:Tomcat和其他WEB容器的区别](docs/java-web/走进JavaWeb技术世界7:Tomcat和其他WEB容器的区别.md) From e878afe820ef2cf19f4cf2b6166d7df145246608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=80=E9=9B=80=E4=B8=8A=E5=A4=B4=E7=B2=91=E9=A2=97?= =?UTF-8?q?=E9=A5=AD?= Date: Tue, 28 Jul 2020 15:03:00 +0800 Subject: [PATCH 020/113] =?UTF-8?q?Update=204=E3=80=81final=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E5=AD=97=E7=89=B9=E6=80=A7.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正final域i、j部分地方写反了 --- ...\263\351\224\256\345\255\227\347\211\271\346\200\247.md" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" index f9c0f39..ff1118c 100644 --- "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" +++ "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" @@ -482,7 +482,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 在上图中,写普通域的操作被编译器重排序到了构造函数之外,读线程 B 错误的读取了普通变量 i 初始化之前的值。而写 final 域的操作,被写 final 域的重排序规则“限定”在了构造函数之内,读线程 B 正确的读取了 final 变量初始化之后的值。 -写 final 域的重排序规则可以确保:在对象引用为任意线程可见之前,对象的 final 域已经被正确初始化过了,而普通域不具有这个保障。以上图为例,在读线程 B“看到”对象引用 obj 时,很可能 obj 对象还没有构造完成(对普通域 i 的写操作被重排序到构造函数外,此时初始值 2 还没有写入普通域 i)。 +写 final 域的重排序规则可以确保:在对象引用为任意线程可见之前,对象的 final 域已经被正确初始化过了,而普通域不具有这个保障。以上图为例,在读线程 B“看到”对象引用 obj 时,很可能 obj 对象还没有构造完成(对普通域 i 的写操作被重排序到构造函数外,此时初始值 1 还没有写入普通域 i)。 ### 读 final 域的重排序规则 @@ -495,8 +495,8 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 reader() 方法包含三个操作: 1. 初次读引用变量 obj; -2. 初次读引用变量 obj 指向对象的普通域 j。 -3. 初次读引用变量 obj 指向对象的 final 域 i。 +2. 初次读引用变量 obj 指向对象的普通域 i。 +3. 初次读引用变量 obj 指向对象的 final 域 j。 现在我们假设写线程 A 没有发生任何重排序,同时程序在不遵守间接依赖的处理器上执行,下面是一种可能的执行时序: From d0169757c46b00ff8425698481170ad8d7718190 Mon Sep 17 00:00:00 2001 From: Rorke76753 <36150718+Rorke76753@users.noreply.github.com> Date: Mon, 3 Aug 2020 17:47:14 +0800 Subject: [PATCH 021/113] =?UTF-8?q?Update=20Java=E5=B9=B6=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=9712=EF=BC=9A=E6=B7=B1=E5=BA=A6=E8=A7=A3?= =?UTF-8?q?=E8=AF=BB=20java=20=E7=BA=BF=E7=A8=8B=E6=B1=A0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=80=9D=E6=83=B3=E5=8F=8A=E6=BA=90=E7=A0=81=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加worker的获取任务过程 --- ...20\347\240\201\345\256\236\347\216\260.md" | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" index 76f6d4b..ef59855 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" @@ -8,6 +8,7 @@ * [AbstractExecutorService](#abstractexecutorservice) * [ThreadPoolExecutor](#threadpoolexecutor) * [Executors](#executors) + * [Worker获取任务](#getTask) * [总结](#总结) @@ -1275,6 +1276,51 @@ else if (!addWorker(command, false)) > SynchronousQueue 是一个比较特殊的 BlockingQueue,其本身不储存任何元素,它有一个虚拟队列(或虚拟栈),不管读操作还是写操作,如果当前队列中存储的是与当前操作相同模式的线程,那么当前操作也进入队列中等待;如果是相反模式,则配对成功,从当前队列中取队头节点。具体的信息,可以看我的另一篇关于 BlockingQueue 的文章。 +## getTask + 前文已经分析了`runWorker`方法,我们可以看到该方法中有一行这样的代码 + ```java + //... + while (task != null || (task = getTask()) != null) { + //... + ``` + 这一行代码如果`task!=null`,即前一个条件为`true`时意味着传入的一个非`null`的`task`,同时代码会优化使得第二个条件不去执行;那么前一个条件为`false`时,就会尝试调用`getTask`方法。在这一个方法中,`worker`会尝试从工作队列中取出任务来进行执行。 + ```java + private Runnable getTask() { + boolean timedOut = false; + //不断尝试获得任务 + for (;;) { + int c = ctl.get(); + int rs = runStateOf(c); + // 前文已有相似的状态,这里不再赘述 + if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { + decrementWorkerCount(); + return null; + } + int wc = workerCountOf(c); + //是否设置了允许核心线程超时(设置了之后核心线程在超时后会销毁),或者当前worker数量比核心池大 + boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; + + if ((wc > maximumPoolSize || (timed && timedOut))&& (wc > 1 || workQueue.isEmpty())) { + if (compareAndDecrementWorkerCount(c)) + return null; + continue; + } + try { + //是否设置了允许核心线程超时(设置了之后核心线程在超时后会销毁),或者当前worker数量比核心池大 + //如果是调用queue的poll(int,TimeUnit)方法,否则直接调用take方法 + Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); + //能获取到非空的任务就返回 + //对于不设置允许核心线程超时的情况,核心线程就一直在getTask的这个循环中 + //一直等待有新的任务来执行 + if (r != null) + return r; + timedOut = true; + } catch (InterruptedException retry) { + timedOut = false; + } + } + } + ``` ## 总结 我一向不喜欢写总结,因为我把所有需要表达的都写在正文中了,写小篇幅的总结并不能真正将话说清楚,本文的总结部分为准备面试的读者而写,希望能帮到面试者或者没有足够的时间看完全文的读者。 From fadb4a9e986f3a2393382be1c224cafe7fe93eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=B2=E5=A8=87=E7=9A=84programer?= Date: Mon, 17 Aug 2020 20:37:52 +0800 Subject: [PATCH 022/113] =?UTF-8?q?Update=201=E3=80=81=E9=9D=A2=E5=90=91?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=9F=BA=E7=A1=80.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.修改文字描述错误 --- ...\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" index 1ce17ab..3570358 100644 --- "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" +++ "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" @@ -74,7 +74,7 @@ Java 是面向对象的编程语言,对象就是面向对象程序设计的核   面向过程最大的问题在于随着系统的膨胀,面向过程将无法应付,最终导致系统的崩溃。为了解决这一种软件危机,我们提出面向对象思想。 - 面向过程的缺陷: -   是采用指定而下的设计模式,在设计阶段就需要考虑每一个模块应该分解成哪些子模块,每一个子模块又细分为更小的子模块,如此类推,直到将模块细化为一个个函数。 +   是采用自顶而下的设计模式,在设计阶段就需要考虑每一个模块应该分解成哪些子模块,每一个子模块又细分为更小的子模块,如此类推,直到将模块细化为一个个函数。 - 存在的问题 From fdb8b02c1bb3d3c72ffd465d6c89809ea6023bd4 Mon Sep 17 00:00:00 2001 From: cyd <690648264@qq.com> Date: Tue, 25 Aug 2020 14:01:42 +0800 Subject: [PATCH 023/113] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=9F=BA=E7=A1=80=E7=9F=A5=E8=AF=86=E4=B8=8B21?= =?UTF-8?q?=E3=80=8122=E3=80=8123=E6=8C=87=E5=AE=9A=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ReadMe.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 54edfa2..b382ce2 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -81,9 +81,8 @@ * [JavaIO流](docs/java/basic/16、JavaIO流.md) * [多线程](docs/java/basic/17、多线程.md) * [深入理解内部类](docs/java/basic/18、深入理解内部类.md) -* [javac和javap](docs/java/basic/19、Java集合框架梳理.md) -* [Java8新特性终极指南](docs/java/basic/20、javac和javap.md) -* [Java类和包](docs/java/basic/21、Java8新特性终极指南.md) +* [javac和javap](docs/java/basic/20、javac和javap.md) +* [Java8新特性终极指南](docs/java/basic/21、Java8新特性终极指南.md) * [序列化和反序列化](docs/java/basic/22、序列化和反序列化.md) * [继承、封装、多态的实现原理](docs/java/basic/23、继承、封装、多态的实现原理.md) From 6d318f3aaf7ec53ab1d627f6b545a1246f3d3845 Mon Sep 17 00:00:00 2001 From: JustALee Date: Thu, 1 Oct 2020 17:49:25 +0800 Subject: [PATCH 024/113] Fix typo --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index b382ce2..83e1fb1 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -24,7 +24,7 @@ - [容器](#容器) - [设计模式](#设计模式) - [JavaWeb](#JavaWeb) - - [Srping](#Spring) + - [Spring](#Spring) - [SpringMVC](#SpringMVC) - [SpringBoot](#SpringBoot) - [Java进阶](#Java进阶) From d7eaa6d90b1bfab52fd2e8a9815b60b4096e51f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Fri, 14 May 2021 15:57:33 +0800 Subject: [PATCH 025/113] Update ReadMe.md --- ReadMe.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index b382ce2..f9a91fb 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -349,6 +349,12 @@ springboot和springcloud ## 微信公众号 +### 黄小斜学Java + +微信公众号【黄小斜学Java】 作者是蚂蚁金服Java工程师,专注分享Java领域干货,不限于BAT面试,算法、计算机基础、数据库、分布式、spring全家桶、微服务、高并发、JVM、Docker容器,ELK、大数据等相关知识,希望我们可以一起进步。 + +**500页Java面试手册PDF:** 关注公众号后回复 **”PDF“** 即可领取超级热门的Java面试宝典pdf + ### Java技术江湖 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号【Java技术江湖】一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发! @@ -358,17 +364,3 @@ springboot和springcloud **Java进阶架构师资料:** 关注公众号后回复 **”架构师“** 即可领取 Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源 ![我的公众号](https://img-blog.csdnimg.cn/20190805090108984.jpg) - -### 个人公众号:程序员黄小斜 -​ -黄小斜是 985 硕士,阿里巴巴Java工程师,在自学编程、技术求职、Java学习等方面有丰富经验和独到见解,希望帮助到更多想要从事互联网行业的程序员们。 -​ -作者专注于 JAVA 后端技术栈,热衷于分享程序员干货、学习经验、求职心得,以及自学编程和Java技术栈的相关干货。 -​ -黄小斜是一个斜杠青年,坚持学习和写作,相信终身学习的力量,希望和更多的程序员交朋友,一起进步和成长! - -**原创电子书:** 关注微信公众号【程序员黄小斜】后回复 **"原创电子书"** 即可领取我原创的电子书《菜鸟程序员修炼手册:从技术小白到阿里巴巴Java工程师》这份电子书总结了我2年的Java学习之路,包括学习方法、技术总结、求职经验和面试技巧等内容,已经帮助很多的程序员拿到了心仪的offer! - -**程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号【程序员黄小斜】后,后台回复关键字 **“资料”** 即可免费无套路获取,包括Java、python、C++、大数据、机器学习、前端、移动端等方向的技术资料。 - -![](https://img-blog.csdnimg.cn/20190829222750556.jpg) From 04e727568631b38bb83c73a93878a718d1f4987e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Thu, 9 Dec 2021 15:01:09 +0800 Subject: [PATCH 026/113] Update ReadMe.md --- ReadMe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index f9a91fb..5c79614 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -349,9 +349,9 @@ springboot和springcloud ## 微信公众号 -### 黄小斜学Java +### 程序员黄小斜 -微信公众号【黄小斜学Java】 作者是蚂蚁金服Java工程师,专注分享Java领域干货,不限于BAT面试,算法、计算机基础、数据库、分布式、spring全家桶、微服务、高并发、JVM、Docker容器,ELK、大数据等相关知识,希望我们可以一起进步。 +微信公众号【程序员黄小斜】作者是前蚂蚁金服Java工程师,专注分享Java技术干货和求职成长心得,不限于BAT面试,算法、计算机基础、数据库、分布式、spring全家桶、微服务、高并发、JVM、Docker容器,ELK、大数据等 **500页Java面试手册PDF:** 关注公众号后回复 **”PDF“** 即可领取超级热门的Java面试宝典pdf From b23bd5cd9b2eda81800a9a2ffaea7f57d2dcede8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Thu, 9 Dec 2021 15:01:39 +0800 Subject: [PATCH 027/113] Create ReadMe.md From f95f5cf2edb343d583cbe41f1bb7b9f0a8350a76 Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Sun, 26 Mar 2023 17:02:46 +0800 Subject: [PATCH 028/113] do nothing --- src/main/java/md/AtxMarkdownTocFileTest.java | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/main/java/md/AtxMarkdownTocFileTest.java diff --git a/src/main/java/md/AtxMarkdownTocFileTest.java b/src/main/java/md/AtxMarkdownTocFileTest.java deleted file mode 100644 index 531617d..0000000 --- a/src/main/java/md/AtxMarkdownTocFileTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package md; - -public class AtxMarkdownTocFileTest { -} From 8b486aeac24d32e8c1408e6d8146d9e0e4e00f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Sun, 26 Mar 2023 17:09:13 +0800 Subject: [PATCH 029/113] Update ReadMe.md --- ReadMe.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 5c79614..7df3d6d 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -349,15 +349,10 @@ springboot和springcloud ## 微信公众号 -### 程序员黄小斜 - -微信公众号【程序员黄小斜】作者是前蚂蚁金服Java工程师,专注分享Java技术干货和求职成长心得,不限于BAT面试,算法、计算机基础、数据库、分布式、spring全家桶、微服务、高并发、JVM、Docker容器,ELK、大数据等 - -**500页Java面试手册PDF:** 关注公众号后回复 **”PDF“** 即可领取超级热门的Java面试宝典pdf ### Java技术江湖 -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号【Java技术江湖】一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发! +如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号【Java技术江湖】前阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发! **Java工程师技术学习资料:** 一些Java工程师常用学习资源,关注公众号后,后台回复关键字 **“Java”** 即可免费无套路获取。 From 6e86a2cdca52b19246e8eccbd312e49e9b7d2f4a Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Fri, 31 Mar 2023 19:38:30 +0800 Subject: [PATCH 030/113] resolve distributed docs category problem --- ReadMe.md | 66 +++++++++---------- ...\200\247\343\200\2012PC\345\222\2143PC.md" | 0 ...5\237\272\347\241\2002 \357\274\232CAP.md" | 0 ...13\344\273\266\351\241\272\345\272\217.md" | 0 ...\237\272\347\241\2004\357\274\232Paxos.md" | 0 ...76\345\222\214\347\247\237\347\272\246.md" | 0 ...41\2006\357\274\232Raft\343\200\201Zab.md" | 0 ...17\350\260\203\346\234\215\345\212\241.md" | 0 ...15\345\222\214\344\274\230\345\214\226.md" | 0 ...06\344\270\216\345\256\236\350\267\265.md" | 0 ...44\270\200\350\207\264\346\200\247hash.md" | 0 ...37\346\210\220\346\226\271\346\241\210.md" | 0 ...04\351\202\243\344\272\233\344\272\213.md" | 0 ...6\210\220Redis\347\274\223\345\255\230.md" | 0 ...60\347\232\204\345\245\227\350\267\257.md" | 0 ...40\347\247\215\346\226\271\346\241\210.md" | 0 ...03\345\274\217\344\272\213\345\212\241.md" | 0 ...43\345\206\263\346\226\271\346\241\210.md" | 0 ...03\345\274\217\344\272\213\345\212\241.md" | 0 ...72\346\234\254\346\246\202\345\277\265.md" | 0 ...40\344\275\225\350\200\214\347\224\237.md" | 0 ...\201\257\346\212\200\346\234\257 Kafka.md" | 0 ...57\274\214Raft\347\256\227\346\263\225.md" | 0 ...0\203\346\234\215\345\212\241zookeeper.md" | 0 ...01\347\250\213\350\257\246\350\247\243.md" | 0 ...41\347\220\206\345\256\236\346\210\230.md" | 0 ...57\345\217\212\345\256\236\350\267\265.md" | 0 ...36\350\267\265\346\200\273\347\273\223.md" | 0 ...06\350\256\272\346\200\273\347\273\223.md" | 0 29 files changed, 33 insertions(+), 33 deletions(-) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" (100%) rename "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" => "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" (100%) rename "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" (100%) rename "docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" => "docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" (100%) rename "docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" => "docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" (100%) diff --git a/ReadMe.md b/ReadMe.md index 5c79614..0e7377f 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -292,40 +292,40 @@ todo ## 分布式 ### 理论 -* [分布式系统理论基础开篇:从放弃到入门](docs/distrubuted/理论/分布式系统理论基础开篇:从放弃到入门.md) -* [分布式系统理论基础1: 一致性、2PC和3PC ](docs/distrubuted/理论/分布式系统理论基础1:%20一致性、2PC和3PC.md) -* [分布式系统理论基础2:CAP ](docs/distrubuted/理论/分布式系统理论基础2%20:CAP.md) -* [分布式系统理论基础3: 时间、时钟和事件顺序](docs/distrubuted/理论/分布式系统理论基础3:%20时间、时钟和事件顺序.md) -* [分布式系统理论基础4:Paxos](docs/distrubuted/理论/分布式系统理论基础4:Paxos.md) -* [分布式系统理论基础5:选举、多数派和租约](docs/distrubuted/理论/分布式系统理论基础5:选举、多数派和租约.md) -* [分布式系统理论基础6:Raft、Zab ](docs/distrubuted/理论/分布式系统理论基础6:Raft、Zab.md) -* [分布式系统理论进阶7:Paxos变种和优化 ](docs/distrubuted/理论/分布式系统理论进阶7:Paxos变种和优化.md) -* [分布式系统理论基础8:zookeeper分布式协调服务 ](docs/distrubuted/理论/分布式系统理论基础8:zookeeper分布式协调服务.md) - +* [分布式系统理论基础1: 一致性、2PC和3PC ](docs/distributed/basic/分布式系统理论基础1:%20一致性、2PC和3PC.md) +* [分布式系统理论基础2:CAP ](docs/distributed/basic/分布式系统理论基础2%20:CAP.md) +* [分布式系统理论基础3: 时间、时钟和事件顺序](docs/distributed/basic/分布式系统理论基础3:%20时间、时钟和事件顺序.md) +* [分布式系统理论基础4:Paxos](docs/distributed/basic/分布式系统理论基础4:Paxos.md) +* [分布式系统理论基础5:选举、多数派和租约](docs/distributed/basic/分布式系统理论基础5:选举、多数派和租约.md) +* [分布式系统理论基础6:Raft、Zab ](docs/distributed/basic/分布式系统理论基础6:Raft、Zab.md) +* [分布式系统理论进阶7:Paxos变种和优化 ](docs/distributed/basic/分布式系统理论进阶7:Paxos变种和优化.md) +* [分布式系统理论基础8:zookeeper分布式协调服务 ](docs/distributed/basic/分布式系统理论基础8:zookeeper分布式协调服务.md) + +* [分布式技术实践总结](docs/distributed/分布式理论总结.md) ### 技术 -* [搞懂分布式技术1:分布式系统的一些基本概念 ](docs/distrubuted/实战/搞懂分布式技术1:分布式系统的一些基本概念.md ) -* [搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法](docs/distrubuted/实战/搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法.md) -* [搞懂分布式技术3:初探分布式协调服务zookeeper ](docs/distrubuted/实战/搞懂分布式技术3:初探分布式协调服务zookeeper.md ) -* [搞懂分布式技术4:ZAB协议概述与选主流程详解 ](docs/distrubuted/实战/搞懂分布式技术4:ZAB协议概述与选主流程详解.md ) -* [搞懂分布式技术5:Zookeeper的配置与集群管理实战](docs/distrubuted/实战/搞懂分布式技术5:Zookeeper的配置与集群管理实战.md) -* [搞懂分布式技术6:Zookeeper典型应用场景及实践 ](docs/distrubuted/实战/搞懂分布式技术6:Zookeeper典型应用场景及实践.md ) -* [搞懂分布式技术7:负载均衡概念与主流方案](docs/distrubuted/实战/搞懂分布式技术7:负载均衡概念与主流方案.md) -* [搞懂分布式技术8:负载均衡原理剖析 ](docs/distrubuted/实战/搞懂分布式技术8:负载均衡原理剖析.md ) -* [搞懂分布式技术9:Nginx负载均衡原理与实践 ](docs/distrubuted/实战/搞懂分布式技术9:Nginx负载均衡原理与实践.md) -* [搞懂分布式技术10:LVS实现负载均衡的原理与实践 ](docs/distrubuted/实战/搞懂分布式技术10:LVS实现负载均衡的原理与实践.md ) -* [搞懂分布式技术11:分布式session解决方案与一致性hash](docs/distrubuted/实战/搞懂分布式技术11:分布式session解决方案与一致性hash.md) -* [搞懂分布式技术12:分布式ID生成方案 ](docs/distrubuted/实战/搞懂分布式技术12:分布式ID生成方案.md ) -* [搞懂分布式技术13:缓存的那些事](docs/distrubuted/实战/搞懂分布式技术13:缓存的那些事.md) -* [搞懂分布式技术14:Spring Boot使用注解集成Redis缓存](docs/distrubuted/实战/搞懂分布式技术14:Spring%20Boot使用注解集成Redis缓存.md) -* [搞懂分布式技术15:缓存更新的套路 ](docs/distrubuted/实战/搞懂分布式技术15:缓存更新的套路.md ) -* [搞懂分布式技术16:浅谈分布式锁的几种方案 ](docs/distrubuted/实战/搞懂分布式技术16:浅谈分布式锁的几种方案.md ) -* [搞懂分布式技术17:浅析分布式事务 ](docs/distrubuted/实战/搞懂分布式技术17:浅析分布式事务.md ) -* [搞懂分布式技术18:分布式事务常用解决方案 ](docs/distrubuted/实战/搞懂分布式技术18:分布式事务常用解决方案.md ) -* [搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 ](docs/distrubuted/实战/搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务.md ) -* [搞懂分布式技术20:消息队列因何而生](docs/distrubuted/实战/搞懂分布式技术20:消息队列因何而生.md) -* [搞懂分布式技术21:浅谈分布式消息技术 Kafka ](docs/distrubuted/实战/搞懂分布式技术21:浅谈分布式消息技术%20Kafka.md ) - - +* [搞懂分布式技术1:分布式系统的一些基本概念 ](docs/distributed/practice/搞懂分布式技术1:分布式系统的一些基本概念.md ) +* [搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法](docs/distributed/practice/搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法.md) +* [搞懂分布式技术3:初探分布式协调服务zookeeper ](docs/distributed/practice/搞懂分布式技术3:初探分布式协调服务zookeeper.md ) +* [搞懂分布式技术4:ZAB协议概述与选主流程详解 ](docs/distributed/practice/搞懂分布式技术4:ZAB协议概述与选主流程详解.md ) +* [搞懂分布式技术5:Zookeeper的配置与集群管理实战](docs/distributed/practice/搞懂分布式技术5:Zookeeper的配置与集群管理实战.md) +* [搞懂分布式技术6:Zookeeper典型应用场景及实践 ](docs/distributed/practice/搞懂分布式技术6:Zookeeper典型应用场景及实践.md ) +* [搞懂分布式技术7:负载均衡概念与主流方案](docs/distributed/practice/搞懂分布式技术7:负载均衡概念与主流方案.md) +* [搞懂分布式技术8:负载均衡原理剖析 ](docs/distributed/practice/搞懂分布式技术8:负载均衡原理剖析.md ) +* [搞懂分布式技术9:Nginx负载均衡原理与实践 ](docs/distributed/practice/搞懂分布式技术9:Nginx负载均衡原理与实践.md) +* [搞懂分布式技术10:LVS实现负载均衡的原理与实践 ](docs/distributed/practice/搞懂分布式技术10:LVS实现负载均衡的原理与实践.md ) +* [搞懂分布式技术11:分布式session解决方案与一致性hash](docs/distributed/practice/搞懂分布式技术11:分布式session解决方案与一致性hash.md) +* [搞懂分布式技术12:分布式ID生成方案 ](docs/distributed/practice/搞懂分布式技术12:分布式ID生成方案.md ) +* [搞懂分布式技术13:缓存的那些事](docs/distributed/practice/搞懂分布式技术13:缓存的那些事.md) +* [搞懂分布式技术14:Spring Boot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:Spring%20Boot使用注解集成Redis缓存.md) +* [搞懂分布式技术15:缓存更新的套路 ](docs/distributed/practice/搞懂分布式技术15:缓存更新的套路.md ) +* [搞懂分布式技术16:浅谈分布式锁的几种方案 ](docs/distributed/practice/搞懂分布式技术16:浅谈分布式锁的几种方案.md ) +* [搞懂分布式技术17:浅析分布式事务 ](docs/distributed/practice/搞懂分布式技术17:浅析分布式事务.md ) +* [搞懂分布式技术18:分布式事务常用解决方案 ](docs/distributed/practice/搞懂分布式技术18:分布式事务常用解决方案.md ) +* [搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 ](docs/distributed/practice/搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务.md ) +* [搞懂分布式技术20:消息队列因何而生](docs/distributed/practice/搞懂分布式技术20:消息队列因何而生.md) +* [搞懂分布式技术21:浅谈分布式消息技术 Kafka ](docs/distributed/practice/搞懂分布式技术21:浅谈分布式消息技术%20Kafka.md ) + +* [分布式理论总结](docs/distributed/分布式技术实践总结.md) ## 面试指南 todo diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2001\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\2012PC\345\222\2143PC.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2002 \357\274\232CAP.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2003\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2004\357\274\232Paxos.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2005\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2006\357\274\232Raft\343\200\201Zab.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\2008\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" diff --git "a/docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" similarity index 100% rename from "docs/distrubuted/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" rename to "docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\2667\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25710\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25711\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25712\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25713\357\274\232\347\274\223\345\255\230\347\232\204\351\202\243\344\272\233\344\272\213.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25715\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25716\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25717\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25718\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25719\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2571\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25720\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2572\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2573\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2574\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2575\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" diff --git "a/docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" similarity index 100% rename from "docs/distrubuted/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\2576\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" diff --git "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" "b/docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" similarity index 100% rename from "docs/distrubuted/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" rename to "docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" diff --git "a/docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" "b/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" similarity index 100% rename from "docs/distrubuted/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" rename to "docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" From 3bb0926b7a594dd566ae23f7bacead1566c8be38 Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Fri, 31 Mar 2023 19:54:30 +0800 Subject: [PATCH 031/113] resolve pic problem in juc --- ...\227\357\274\214CAS\346\223\215\344\275\234.md" | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" index 4220389..b778e5e 100644 --- "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" +++ "b/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" @@ -264,7 +264,7 @@ volatile写的内存语义如下: 以上面示例程序VolatileExample为例,假设线程A首先执行writer()方法,随后线程B执行reader()方法,初始时两个线程的本地内存中的flag和a都是初始状态。下图是线程A执行volatile写后,共享变量的状态示意图: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/2.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3dmRtZ0NFNjBKeTlRODRsZ0VwdzNqaWFCREJmSjE2TkxZUEQ2a1dNeHBnOTNad0tUOVY2Ym1Ydy82NDA?x-oss-process=image/format,png) 如上图所示,线程A在写flag变量后,本地内存A中被线程A更新过的两个共享变量的值被刷新到主内存中。此时,本地内存A和主内存中的共享变量的值是一致的。 @@ -274,7 +274,7 @@ volatile读的内存语义如下: 下面是线程B读同一个volatile变量后,共享变量的状态示意图: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/3.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3WWcwMEt1bGVicDAza0MyU2ZHWmI3Tm5vaDcxaG5JS3dpYW5qcnJsUzBUN3dNZWljWUJySmY4YVEvNjQw?x-oss-process=image/format,png) 如上图所示,在读flag变量后,本地内存B已经被置为无效。此时,线程B必须从主内存中读取共享变量。线程B的读取操作将导致本地内存B与主内存中的共享变量的值也变成一致的了。 @@ -322,7 +322,7 @@ volatile读的内存语义如下: 下面是保守策略下,volatile写插入内存屏障后生成的指令序列示意图: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/4.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3U2dxcTJ0SnF1N1pwQllpYVZmZnpTd3F5NGhDY1dSWVhNVzlzM0VWSmljRFZzODY5cWc1M1A3eEEvNjQw?x-oss-process=image/format,png) 上图中的StoreStore屏障可以保证在volatile写之前,其前面的所有普通写操作已经对任意处理器可见了。这是因为StoreStore屏障将保障上面所有的普通写在volatile写之前刷新到主内存。 @@ -330,7 +330,7 @@ volatile读的内存语义如下: 下面是在保守策略下,volatile读插入内存屏障后生成的指令序列示意图: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/5.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3U2dxcTJ0SnF1N1pwQllpYVZmZnpTd3F5NGhDY1dSWVhNVzlzM0VWSmljRFZzODY5cWc1M1A3eEEvNjQw?x-oss-process=image/format,png) 上图中的LoadLoad屏障用来禁止处理器把上面的volatile读与下面的普通读重排序。LoadStore屏障用来禁止处理器把上面的volatile读与下面的普通写重排序。 @@ -354,7 +354,7 @@ volatile读的内存语义如下: 针对readAndWrite()方法,编译器在生成字节码时可以做如下的优化: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/6.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3RzlISFVoNTh0MHNCVUZwMEJyZVU4Njc0OGZHMFhKdmxRTXFpYXE3dUhRNklGd1Q5a1pZQktjZy82NDA?x-oss-process=image/format,png) 注意,最后的StoreLoad屏障不能省略。因为第二个volatile写之后,方法立即return。此时编译器可能无法准确断定后面是否会有volatile读或写,为了安全起见,编译器常常会在这里插入一个StoreLoad屏障。 @@ -362,7 +362,7 @@ volatile读的内存语义如下: 前面保守策略下的volatile读和写,在 x86处理器平台可以优化成: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/7.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3aWNaU1h6dURzT2pnZ0hBTmljYnljbTNPYjkwbkVVOURCTm1JaHE1Y2NVdTZMUnZxS3V1cmlhQ29nLzY0MA?x-oss-process=image/format,png) 前文提到过,x86处理器仅会对写-读操作做重排序。X86不会对读-读,读-写和写-写操作做重排序,因此在x86处理器中会省略掉这三种操作类型对应的内存屏障。在x86中,JMM仅需在volatile写后面插入一个StoreLoad屏障即可正确实现volatile写-读的内存语义。这意味着在x86处理器中,volatile写的开销比volatile读的开销会大很多(因为执行StoreLoad屏障开销会比较大)。 @@ -370,7 +370,7 @@ volatile读的内存语义如下: 在JSR-133之前的旧Java内存模型中,虽然不允许volatile变量之间重排序,但旧的Java内存模型允许volatile变量与普通变量之间重排序。在旧的内存模型中,VolatileExample示例程序可能被重排序成下列时序来执行: -![](https://res.infoq.com/articles/java-memory-model-4/zh/resources/8.png) +![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9UTEgzQ2ljUFZpYnJlMXJ3emFJWjJkT3VVdDVjekVBdVQ3TG9aamN2em13WUk3aGVJcksyemp2YWs5RGI5cHZKaFJ3NVR0cHFGMzNWUjFHb0tzd1lwNUdnLzY0MA?x-oss-process=image/format,png) 在旧的内存模型中,当1和2之间没有数据依赖关系时,1和2之间就可能被重排序(3和4类似)。其结果就是:读线程B执行4时,不一定能看到写线程A在执行1时对共享变量的修改。 From f6f1362df0adf58fde9f89cdef7680bf334887ab Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Fri, 31 Mar 2023 20:13:19 +0800 Subject: [PATCH 032/113] =?UTF-8?q?resolve=20pic=20problem=20in=20?= =?UTF-8?q?=E5=A4=9A=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\271\350\261\241\345\237\272\347\241\200.md" | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" index 3570358..20a3a96 100644 --- "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" +++ "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" @@ -452,9 +452,10 @@ java里的多态主要表现在两个方面:   这两句话是什么意思呢,让我们用代码来体验一下,首先我们创建一个父类Animal和一个子类Dog,在主函数里如下所示: -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701155536086-1897896282.png) +![img](https://cdn.mianshigee.com/upload/note/thumbnails/202202211611552259.png) -  注意:我们不能使用一个子类的引用来指向父类的对象,如:![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701155839586-923083573.png)。 +  注意:我们不能使用一个子类的引用来指向父类的对象,如: +![img](https://cdn.mianshigee.com/upload/note/thumbnails/202202211611556958.png)。   这里我们必须深刻理解引用多态的意义,才能更好记忆这种多态的特性。为什么子类的引用不能用来指向父类的对象呢?我在这里通俗给大家讲解一下:就以上面的例子来说,我们能说“狗是一种动物”,但是不能说“动物是一种狗”,狗和动物是父类和子类的继承关系,它们的从属是不能颠倒的。当父类的引用指向子类的对象时,该对象将只是看成一种特殊的父类(里面有重写的方法和属性),反之,一个子类的引用来指向父类的对象是不可行的!! @@ -482,23 +483,23 @@ java里的多态主要表现在两个方面:   就以上述的父类Animal和一个子类Dog来说明,当父类的引用可以指向子类的对象时,就是**向上类型转换**。如: -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701162630508-961507659.png) +![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjYzMDUwOC05NjE1MDc2NTkucG5n?x-oss-process=image/format,png)   **2. 向下类型转换(强制类型转换),是大类型转换到小类型(有风险,可能出现数据溢出)。**   将上述代码再加上一行,我们再次将父类转换为子类引用,那么会出现错误,编译器不允许我们直接这么做**,**虽然我们知道这个父类引用指向的就是子类对象,但是编译器认为这种转换是存在风险的**。**如: -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701162926477-3857975.png) +![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjkyNjQ3Ny0zODU3OTc1LnBuZw?x-oss-process=image/format,png) -  那么我们该怎么解决这个问题呢,我们可以在animal前加上(Dog)来强制类型转换。如:![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701163408383-2003626729.png) +  那么我们该怎么解决这个问题呢,我们可以在animal前加上(Dog)来强制类型转换。如:![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NDIyOTg5OS0xMDU1MTkwNzc0LnBuZw?x-oss-process=image/format,png) -  但是如果父类引用没有指向**该子类的对象**,则不能向下类型转换,虽然编译器不会报错,但是运行的时候程序会出错,如:![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701164229899-1055190774.png) +  但是如果父类引用没有指向**该子类的对象**,则不能向下类型转换,虽然编译器不会报错,但是运行的时候程序会出错,如:![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NTEzMzI4OS03MTc0MzkzNjAucG5n?x-oss-process=image/format,png)   其实这就是上面所说的子类的引用指向父类的对象,而强制转换类型也不能转换!!   还有一种情况是父类的引用指向**其他子类的对象**,则不能通过强制转为**该子类的对象**。如: -    ![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701165133289-717439360.png) +    ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NTEzMzI4OS03MTc0MzkzNjAucG5n?x-oss-process=image/format,png)   这是因为我们在编译的时候进行了强制类型转换,编译时的类型是我们强制转换的类型,所以编译器不会报错,而当我们运行的时候,程序给animal开辟的是Dog类型的内存空间,这与Cat类型内存空间不匹配,所以无法正常转换。这两种情况出错的本质是一样的,所以我们在使用强制类型转换的时候要特别注意这两种错误!!下面有个更安全的方式来实现向下类型转换。。。。 @@ -508,7 +509,7 @@ java里的多态主要表现在两个方面:   我们来使用instanceof运算符来规避上面的错误,代码修改如下: -  ![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701165626571-501228254.png) +  ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NTYyNjU3MS01MDEyMjgyNTQucG5n?x-oss-process=image/format,png)   利用if语句和instanceof运算符来判断两个对象的类型是否一致。 From 760cc8971613257429e4bd2332151e26e9242e48 Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Fri, 31 Mar 2023 20:28:04 +0800 Subject: [PATCH 033/113] resolve pic problem in network programing --- ReadMe.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 23bde83..f8b8ed6 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -196,17 +196,17 @@ todo ### Java网络编程 -* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/jvm/Java网络编程和NIO详解1:JAVA%20中原生的%20socket%20通信机制.md) -* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/jvm/Java网络编程与NIO详解2:JAVA%20NIO%20一步步构建IO多路复用的请求模型.md) -* [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/jvm/Java网络编程和NIO详解3:IO模型与Java网络编程模型.md) -* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A34%EF%BC%9A%E6%B5%85%E6%9E%90NIO%E5%8C%85%E4%B8%AD%E7%9A%84Buffer%E3%80%81Channel%20%E5%92%8C%20Selector.md) -* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%92%8CNIO%E8%AF%A6%E8%A7%A35%EF%BC%9AJava%20%E9%9D%9E%E9%98%BB%E5%A1%9E%20IO%20%E5%92%8C%E5%BC%82%E6%AD%A5%20IO.md) -* [Java网络编程和NIO详解6:Linux epoll实现原理详解](docs/java/jvm/Java网络编程和NIO详解6:Linux%20epoll实现原理详解.md) -* [Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理](Java网络编程和NIO详解7:浅谈%20Linux%20中NIO%20Selector%20的实现原理.md) -* [Java网络编程与NIO详解8:浅析mmap和Direct Buffer](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A38%EF%BC%9A%E6%B5%85%E6%9E%90mmap%E5%92%8CDirect%20Buffer.md) -* [Java网络编程和NIO详解9:基于NIO的网络编程框架Netty](docs/java/jvm/Java网络编程和NIO详解9:基于NIO的网络编程框架Netty.md) -* [Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A310%EF%BC%9A%E6%B7%B1%E5%BA%A6%E8%A7%A3%E8%AF%BBTomcat%E4%B8%AD%E7%9A%84NIO%E6%A8%A1%E5%9E%8B.md) -* [Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)](docs/java/jvm/Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO).md) +* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程和NIO详解1:JAVA%20中原生的%20socket%20通信机制.md) +* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JAVA%20NIO%20一步步构建IO多路复用的请求模型.md) +* [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/network-programming/Java网络编程和NIO详解3:IO模型与Java网络编程模型.md) +* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A34%EF%BC%9A%E6%B5%85%E6%9E%90NIO%E5%8C%85%E4%B8%AD%E7%9A%84Buffer%E3%80%81Channel%20%E5%92%8C%20Selector.md) +* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%92%8CNIO%E8%AF%A6%E8%A7%A35%EF%BC%9AJava%20%E9%9D%9E%E9%98%BB%E5%A1%9E%20IO%20%E5%92%8C%E5%BC%82%E6%AD%A5%20IO.md) +* [Java网络编程和NIO详解6:Linux epoll实现原理详解](docs/java/network-programming/Java网络编程和NIO详解6:Linux%20epoll实现原理详解.md) +* [Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理](docs/java/network-programming/Java网络编程和NIO详解7:浅谈%20Linux%20中NIO%20Selector%20的实现原理.md) +* [Java网络编程与NIO详解8:浅析mmap和Direct Buffer](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A38%EF%BC%9A%E6%B5%85%E6%9E%90mmap%E5%92%8CDirect%20Buffer.md) +* [Java网络编程和NIO详解9:基于NIO的网络编程框架Netty](docs/java/network-programming/Java网络编程和NIO详解9:基于NIO的网络编程框架Netty.md) +* [Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A310%EF%BC%9A%E6%B7%B1%E5%BA%A6%E8%A7%A3%E8%AF%BBTomcat%E4%B8%AD%E7%9A%84NIO%E6%A8%A1%E5%9E%8B.md) +* [Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)](docs/java/network-programming/Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO).md) ## 计算机基础 From bfb15b068176e70055ed8fd51bb76c6ccf7f217e Mon Sep 17 00:00:00 2001 From: h2pl <362294931@qq.com> Date: Fri, 31 Mar 2023 20:38:19 +0800 Subject: [PATCH 034/113] resolve docs in juc --- ...\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" "b/docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" index 2c05f7b..36d9432 100644 --- "a/docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" +++ "b/docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" @@ -91,7 +91,7 @@ hashmap的增删改查方式比较简单,都是遍历,替换。有一点要 ## CHM -concurrenthashmap也稍微提一下把,chm1.7使用分段锁来控制并发,每个segment对应一个segmentmask,通过key的hash值相与这个segmentmask得到segment位置,然后在找到具体的entry数组下标。所以chm需要维护多个segment,每个segment对应一个数组。分段锁使用的是reetreetlock可重入锁实现。查询时不加锁。 +concurrenthashmap也稍微提一下把,chm1.7使用分段锁来控制并发,每个segment对应一个segmentmask,通过key的hash值相与这个segmentmask得到segment位置,然后在找到具体的entry数组下标。所以chm需要维护多个segment,每个segment对应一个数组。分段锁使用的是ReentrantLock可重入锁实现。查询时不加锁。 1.8则放弃使用分段锁,改用cas+synchronized方式实现并发控制,查询时不加锁,插入时如果没有冲突直接cas到成功为止,有冲突则使用synchronized插入。 From 1d8d97d20f2cfcdf43fc1ebaf913b5eae589fa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Mon, 3 Apr 2023 11:57:22 +0800 Subject: [PATCH 035/113] modify catalog --- ReadMe.md | 119 +++++++++--------- .../\345\211\221\346\214\207offer.md" | 0 ...46\344\271\240\346\200\273\347\273\223.md" | 0 ...46\344\271\240\346\200\273\347\273\223.md" | 0 ...46\344\271\240\346\200\273\347\273\223.md" | 0 ...4\232SpringMVC\346\246\202\350\277\260.md" | 0 ...5\277\265\344\270\216DispatcherServlet.md" | 0 ...67\346\261\202\350\275\254\345\217\221.md" | 0 ...\243\347\241\256\347\232\204Controller.md" | 0 ...43\346\236\220\345\216\237\347\220\206.md" | 0 ...6@ResponseBody\346\263\250\350\247\243.md" | 0 ...72\346\234\254\345\216\237\347\220\206.md" | 0 ...20\347\240\201\345\210\206\346\236\220.md" | 0 ...\351\230\237\345\210\227 BlockingQueue.md" | 0 ...20\347\240\201\345\256\236\347\216\260.md" | 0 ...p \345\205\250\350\247\243\346\236\220.md" | 0 ...7\232\204Unsafe\345\222\214Locksupport.md" | 0 ...27\346\263\225\345\211\226\346\236\220.md" | 0 ...va\345\244\232\347\272\277\347\250\213.md" | 0 ...345\255\230\346\250\241\345\236\213JMM.md" | 0 ...357\274\214CAS\346\223\215\344\275\234.md" | 0 ...1\224\201 Lock\345\222\214synchronized.md" | 0 ...56\345\255\227\350\247\243\346\236\220.md" | 0 ...345\236\213JMM\346\200\273\347\273\223.md" | 0 ...347\261\273AQS\350\257\246\350\247\243.md" | 0 ...71\263\351\224\201\357\274\214Condtion.md" | 0 ...73\347\232\204\345\256\236\347\216\260.md" | 0 ...46\344\271\240\346\200\273\347\273\223.md" | 0 ...00\347\273\210\346\225\210\346\236\234.md" | 2 +- 29 files changed, 62 insertions(+), 59 deletions(-) rename "docs/algorithms/\345\211\221\346\214\207offer.md" => "docs/cs/algorithms/\345\211\221\346\214\207offer.md" (100%) rename "docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" => "docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" (100%) rename "docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" => "docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" (100%) rename "docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" => "docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" (100%) rename "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" => "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" (100%) rename "docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" => "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" (100%) rename "docs/java/currency/Java\345\271\266\345\217\221\346\200\273\347\273\223.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md" (100%) diff --git a/ReadMe.md b/ReadMe.md index f8b8ed6..f63c941 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -63,28 +63,28 @@ ### 基础知识 -* [面向对象基础](docs/java/basic/1、面向对象基础.md) -* [Java基本数据类型](docs/java/basic/2、Java基本数据类型.md) -* [string和包装类](docs/java/basic/3、string和包装类.md) -* [final关键字特性](docs/java/basic/4、final关键字特性.md) -* [Java类和包](docs/java/basic/5、Java类和包.md) -* [抽象类和接口](docs/java/basic/6、抽象类和接口.md) -* [代码块和代码执行顺序](docs/java/basic/7、代码块和代码执行顺序.md) -* [Java自动拆箱装箱里隐藏的秘密](docs/java/basic/8、Java自动拆箱装箱里隐藏的秘密.md) -* [Java中的Class类和Object类](docs/java/basic/9、Java中的Class类和Object类.md) -* [Java异常](docs/java/basic/10、Java异常.md) -* [解读Java中的回调](docs/java/basic/11、解读Java中的回调.md) -* [反射](docs/java/basic/12、反射.md) -* [泛型](docs/java/basic/13、泛型.md) -* [枚举类](docs/java/basic/14、枚举类.md) -* [Java注解和最佳实践](docs/java/basic/15、Java注解和最佳实践.md) -* [JavaIO流](docs/java/basic/16、JavaIO流.md) -* [多线程](docs/java/basic/17、多线程.md) -* [深入理解内部类](docs/java/basic/18、深入理解内部类.md) -* [javac和javap](docs/java/basic/20、javac和javap.md) -* [Java8新特性终极指南](docs/java/basic/21、Java8新特性终极指南.md) -* [序列化和反序列化](docs/java/basic/22、序列化和反序列化.md) -* [继承、封装、多态的实现原理](docs/java/basic/23、继承、封装、多态的实现原理.md) +* [1、面向对象基础](docs/java/basic/1、面向对象基础.md) +* [2、Java基本数据类型](docs/java/basic/2、Java基本数据类型.md) +* [3、string和包装类](docs/java/basic/3、string和包装类.md) +* [4、final关键字特性](docs/java/basic/4、final关键字特性.md) +* [5、Java类和包](docs/java/basic/5、Java类和包.md) +* [6、抽象类和接口](docs/java/basic/6、抽象类和接口.md) +* [7、代码块和代码执行顺序](docs/java/basic/7、代码块和代码执行顺序.md) +* [8、Java自动拆箱装箱里隐藏的秘密](docs/java/basic/8、Java自动拆箱装箱里隐藏的秘密.md) +* [9、Java中的Class类和Object类](docs/java/basic/9、Java中的Class类和Object类.md) +* [10、Java异常](docs/java/basic/10、Java异常.md) +* [11、解读Java中的回调](docs/java/basic/11、解读Java中的回调.md) +* [12、反射](docs/java/basic/12、反射.md) +* [13、泛型](docs/java/basic/13、泛型.md) +* [14、枚举类](docs/java/basic/14、枚举类.md) +* [15、Java注解和最佳实践](docs/java/basic/15、Java注解和最佳实践.md) +* [16、JavaIO流](docs/java/basic/16、JavaIO流.md) +* [17、多线程](docs/java/basic/17、多线程.md) +* [18、深入理解内部类](docs/java/basic/18、深入理解内部类.md) +* [20、javac和javap](docs/java/basic/20、javac和javap.md) +* [21、Java8新特性终极指南](docs/java/basic/21、Java8新特性终极指南.md) +* [22、序列化和反序列化](docs/java/basic/22、序列化和反序列化.md) +* [23、继承、封装、多态的实现原理](docs/java/basic/23、继承、封装、多态的实现原理.md) ### 容器 @@ -123,7 +123,7 @@ * [走进JavaWeb技术世界12:从手动编译打包到项目构建工具Maven](docs/java-web/走进JavaWeb技术世界12:从手动编译打包到项目构建工具Maven.md) * [走进JavaWeb技术世界13:Hibernate入门经典与注解式开发](docs/java-web/走进JavaWeb技术世界13:Hibernate入门经典与注解式开发.md) * [走进JavaWeb技术世界14:Mybatis入门](docs/java-web/走进JavaWeb技术世界14:Mybatis入门.md) -* [深入JavaWeb技术世界15:深入浅出Mybatis基本原理](docs/java-web/深入JavaWeb技术世界15:深入浅出Mybatis基本原理.md) +* [走进JavaWeb技术世界15:深入浅出Mybatis基本原理](docs/java-web/走进JavaWeb技术世界15:深入浅出Mybatis基本原理.md) * [走进JavaWeb技术世界16:极简配置的SpringBoot](docs/java-web/走进JavaWeb技术世界16:极简配置的SpringBoot.md) ### Spring @@ -140,12 +140,12 @@ ### SpringMVC -* [SpringMVC源码分析1:SpringMVC概述](docs/java-web/Spring/SSM/SpringMVC源码分析1:SpringMVC概述.md) -* [SpringMVC源码分析2:SpringMVC设计理念与DispatcherServlet](docs/java-web/Spring/SSM/SpringMVC源码分析2:SpringMVC设计理念与DispatcherServlet.md) -* [SpringMVC源码分析3:DispatcherServlet的初始化与请求转发 ](docs/java-web/Spring/SSM/SpringMVC源码分析3:DispatcherServlet的初始化与请求转发.md) -* [SpringMVC源码分析4:DispatcherServlet如何找到正确的Controller ](docs/java-web/Spring/SSM/SpringMVC源码分析4:DispatcherServlet如何找到正确的Controller.md) -* [SpringMVC源码剖析5:消息转换器HttpMessageConverter与@ResponseBody注解](docs/java-web/Spring/SSM/SpringMVC源码剖析5:消息转换器HttpMessageConverter与@ResponseBody注解.md) -* [SpringMVC源码分析6:SpringMVC的视图解析原理 ](docs/java-web/Spring/SSM/SpringMVC源码分析6:SpringMVC的视图解析原理.md) +* [SpringMVC源码分析1:SpringMVC概述](docs/java-web/SpringMVC/SpringMVC源码分析1:SpringMVC概述.md) +* [SpringMVC源码分析2:SpringMVC设计理念与DispatcherServlet](docs/java-web/SpringMVC/SpringMVC源码分析2:SpringMVC设计理念与DispatcherServlet.md) +* [SpringMVC源码分析3:DispatcherServlet的初始化与请求转发 ](docs/java-web/SpringMVC/SpringMVC源码分析3:DispatcherServlet的初始化与请求转发.md) +* [SpringMVC源码分析4:DispatcherServlet如何找到正确的Controller ](docs/java-web/SpringMVC/SpringMVC源码分析4:DispatcherServlet如何找到正确的Controller.md) +* [SpringMVC源码剖析5:消息转换器HttpMessageConverter与@ResponseBody注解](docs/java-web/SpringMVC/SpringMVC源码剖析5:消息转换器HttpMessageConverter与@ResponseBody注解.md) +* [SpringMVC源码分析6:SpringMVC的视图解析原理 ](docs/java-web/SpringMVC/SpringMVC源码分析6:SpringMVC的视图解析原理.md) ### SpringBoot @@ -159,22 +159,22 @@ todo ### 并发 -* [Java并发指南1:并发基础与Java多线程](docs/java/currency/Java并发指南1:并发基础与Java多线程.md) -* [Java并发指南2:深入理解Java内存模型JMM](docs/java/currency/Java并发指南2:深入理解Java内存模型JMM.md) -* [Java并发指南3:并发三大问题与volatile关键字,CAS操作](docs/java/currency/Java并发指南3:并发三大问题与volatile关键字,CAS操作.md) -* [Java并发指南4:Java中的锁 Lock和synchronized](docs/java/currency/Java并发指南4:Java中的锁%20Lock和synchronized.md) -* [Java并发指南5:JMM中的final关键字解析](docs/java/currency/Java并发指南5:JMM中的final关键字解析.md) -* [Java并发指南6:Java内存模型JMM总结](docs/java/currency/Java并发指南6:Java内存模型JMM总结.md) -* [Java并发指南7:JUC的核心类AQS详解](docs/java/currency/Java并发指南7:JUC的核心类AQS详解.md) -* [Java并发指南8:AQS中的公平锁与非公平锁,Condtion](docs/java/currency/Java并发指南8:AQS中的公平锁与非公平锁,Condtion.md) -* [Java并发指南9:AQS共享模式与并发工具类的实现](docs/java/currency/Java并发指南9:AQS共享模式与并发工具类的实现.md) -* [Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析](docs/java/currency/Java并发指南10:Java%20读写锁%20ReentrantReadWriteLock%20源码分析.md) -* [Java并发指南11:解读 Java 阻塞队列 BlockingQueue](docs/java/currency/Java并发指南11:解读%20Java%20阻塞队列%20BlockingQueue.md) -* [Java并发指南12:深度解读 java 线程池设计思想及源码实现](docs/java/currency/Java并发指南12:深度解读%20java%20线程池设计思想及源码实现.md) -* [Java并发指南13:Java 中的 HashMap 和 ConcurrentHashMap 全解析](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/currency/Java%E5%B9%B6%E5%8F%91%E6%8C%87%E5%8D%9713%EF%BC%9AJava%20%E4%B8%AD%E7%9A%84%20HashMap%20%E5%92%8C%20ConcurrentHashMap%20%E5%85%A8%E8%A7%A3%E6%9E%90.md) -* [Java并发指南14:JUC中常用的Unsafe和Locksupport](docs/java/currency/Java并发指南14:JUC中常用的Unsafe和Locksupport.md) -* [Java并发指南15:Fork join并发框架与工作窃取算法剖析](docs/java/currency/Java并发编程指南15:Fork%20join并发框架与工作窃取算法剖析.md) -* [Java并发编程学习总结](https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/currency/Java%E5%B9%B6%E5%8F%91%E6%80%BB%E7%BB%93.md) +* [Java并发指南1:并发基础与Java多线程](docs/java/concurrency/Java并发指南1:并发基础与Java多线程.md) +* [Java并发指南2:深入理解Java内存模型JMM](docs/java/concurrency/Java并发指南2:深入理解Java内存模型JMM.md) +* [Java并发指南3:并发三大问题与volatile关键字,CAS操作](docs/java/concurrency/Java并发指南3:并发三大问题与volatile关键字,CAS操作.md) +* [Java并发指南4:Java中的锁 Lock和synchronized](docs/java/concurrency/Java并发指南4:Java中的锁%20Lock和synchronized.md) +* [Java并发指南5:JMM中的final关键字解析](docs/java/concurrency/Java并发指南5:JMM中的final关键字解析.md) +* [Java并发指南6:Java内存模型JMM总结](docs/java/concurrency/Java并发指南6:Java内存模型JMM总结.md) +* [Java并发指南7:JUC的核心类AQS详解](docs/java/concurrency/Java并发指南7:JUC的核心类AQS详解.md) +* [Java并发指南8:AQS中的公平锁与非公平锁,Condtion](docs/java/concurrency/Java并发指南8:AQS中的公平锁与非公平锁,Condtion.md) +* [Java并发指南9:AQS共享模式与并发工具类的实现](docs/java/concurrency/Java并发指南9:AQS共享模式与并发工具类的实现.md) +* [Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析](docs/java/concurrency/Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析.md) +* [Java并发指南11:解读 Java 阻塞队列 BlockingQueue](docs/java/concurrency/Java并发指南11:解读 Java 阻塞队列 BlockingQueue.md) +* [Java并发指南12:深度解读 java 线程池设计思想及源码实现](docs/java/concurrency/Java并发指南12:深度解读 java 线程池设计思想及源码实现.md) +* [Java并发指南13:Java 中的 HashMap 和 ConcurrentHashMap 全解析](docs/java/concurrency/Java并发指南13:Java 中的 HashMap 和 ConcurrentHashMap 全解析.md) +* [Java并发指南14:JUC中常用的Unsafe和Locksupport](docs/java/concurrency/Java并发指南14:JUC中常用的Unsafe和Locksupport.md) +* [Java并发指南15:Fork join并发框架与工作窃取算法剖析](docs/java/concurrency/Java并发指南15:Fork join并发框架与工作窃取算法剖析.md) +* [Java并发编程学习总结](docs/java/concurrency/Java并发编程学习总结.md) ### JVM @@ -196,16 +196,16 @@ todo ### Java网络编程 -* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程和NIO详解1:JAVA%20中原生的%20socket%20通信机制.md) -* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JAVA%20NIO%20一步步构建IO多路复用的请求模型.md) +* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制.md) +* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型.md) * [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/network-programming/Java网络编程和NIO详解3:IO模型与Java网络编程模型.md) -* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A34%EF%BC%9A%E6%B5%85%E6%9E%90NIO%E5%8C%85%E4%B8%AD%E7%9A%84Buffer%E3%80%81Channel%20%E5%92%8C%20Selector.md) -* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%92%8CNIO%E8%AF%A6%E8%A7%A35%EF%BC%9AJava%20%E9%9D%9E%E9%98%BB%E5%A1%9E%20IO%20%E5%92%8C%E5%BC%82%E6%AD%A5%20IO.md) +* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector.md) +* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO.md) * [Java网络编程和NIO详解6:Linux epoll实现原理详解](docs/java/network-programming/Java网络编程和NIO详解6:Linux%20epoll实现原理详解.md) -* [Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理](docs/java/network-programming/Java网络编程和NIO详解7:浅谈%20Linux%20中NIO%20Selector%20的实现原理.md) -* [Java网络编程与NIO详解8:浅析mmap和Direct Buffer](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A38%EF%BC%9A%E6%B5%85%E6%9E%90mmap%E5%92%8CDirect%20Buffer.md) +* [Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理](docs/java/network-programming/Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理.md) +* [Java网络编程与NIO详解8:浅析mmap和Direct Buffer](docs/java/network-programming/Java网络编程与NIO详解8:浅析mmap和Direct Buffer.md) * [Java网络编程和NIO详解9:基于NIO的网络编程框架Netty](docs/java/network-programming/Java网络编程和NIO详解9:基于NIO的网络编程框架Netty.md) -* [Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型](docs/java/network-programming/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E4%B8%8ENIO%E8%AF%A6%E8%A7%A310%EF%BC%9A%E6%B7%B1%E5%BA%A6%E8%A7%A3%E8%AF%BBTomcat%E4%B8%AD%E7%9A%84NIO%E6%A8%A1%E5%9E%8B.md) +* [Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型](docs/java/network-programming/Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型.md) * [Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)](docs/java/network-programming/Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO).md) ## 计算机基础 @@ -236,7 +236,7 @@ todo ### MySQL * [Mysql原理与实践总结](docs/database/Mysql原理与实践总结.md) * [重新学习Mysql数据库1:无废话MySQL入门](docs/database/重新学习Mysql数据库1:无废话MySQL入门.md) -* [重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB](docs/database/重新学习Mysql数据库2:%20『浅入浅出』MySQL%20和%20InnoDB.md) +* [重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB](docs/database/重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB.md) * [重新学习Mysql数据库3:Mysql存储引擎与数据存储原理](docs/database/重新学习Mysql数据库3:Mysql存储引擎与数据存储原理.md) * [重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法](docs/database/重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法.md) * [重新学习Mysql数据库5:根据MySQL索引原理进行分析与优化](docs/database/重新学习Mysql数据库5:根据MySQL索引原理进行分析与优化.md) @@ -309,21 +309,24 @@ todo * [搞懂分布式技术4:ZAB协议概述与选主流程详解 ](docs/distributed/practice/搞懂分布式技术4:ZAB协议概述与选主流程详解.md ) * [搞懂分布式技术5:Zookeeper的配置与集群管理实战](docs/distributed/practice/搞懂分布式技术5:Zookeeper的配置与集群管理实战.md) * [搞懂分布式技术6:Zookeeper典型应用场景及实践 ](docs/distributed/practice/搞懂分布式技术6:Zookeeper典型应用场景及实践.md ) -* [搞懂分布式技术7:负载均衡概念与主流方案](docs/distributed/practice/搞懂分布式技术7:负载均衡概念与主流方案.md) -* [搞懂分布式技术8:负载均衡原理剖析 ](docs/distributed/practice/搞懂分布式技术8:负载均衡原理剖析.md ) -* [搞懂分布式技术9:Nginx负载均衡原理与实践 ](docs/distributed/practice/搞懂分布式技术9:Nginx负载均衡原理与实践.md) + +[//]: # (* [搞懂分布式技术7:负载均衡概念与主流方案](docs/distributed/practice/搞懂分布式技术7:负载均衡概念与主流方案.md)) + +[//]: # (* [搞懂分布式技术8:负载均衡原理剖析 ](docs/distributed/practice/搞懂分布式技术8:负载均衡原理剖析.md )) + +[//]: # (* [搞懂分布式技术9:Nginx负载均衡原理与实践 ](docs/distributed/practice/搞懂分布式技术9:Nginx负载均衡原理与实践.md)) * [搞懂分布式技术10:LVS实现负载均衡的原理与实践 ](docs/distributed/practice/搞懂分布式技术10:LVS实现负载均衡的原理与实践.md ) * [搞懂分布式技术11:分布式session解决方案与一致性hash](docs/distributed/practice/搞懂分布式技术11:分布式session解决方案与一致性hash.md) * [搞懂分布式技术12:分布式ID生成方案 ](docs/distributed/practice/搞懂分布式技术12:分布式ID生成方案.md ) * [搞懂分布式技术13:缓存的那些事](docs/distributed/practice/搞懂分布式技术13:缓存的那些事.md) -* [搞懂分布式技术14:Spring Boot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:Spring%20Boot使用注解集成Redis缓存.md) +* [搞懂分布式技术14:Spring Boot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:Spring Boot使用注解集成Redis缓存.md) * [搞懂分布式技术15:缓存更新的套路 ](docs/distributed/practice/搞懂分布式技术15:缓存更新的套路.md ) * [搞懂分布式技术16:浅谈分布式锁的几种方案 ](docs/distributed/practice/搞懂分布式技术16:浅谈分布式锁的几种方案.md ) * [搞懂分布式技术17:浅析分布式事务 ](docs/distributed/practice/搞懂分布式技术17:浅析分布式事务.md ) * [搞懂分布式技术18:分布式事务常用解决方案 ](docs/distributed/practice/搞懂分布式技术18:分布式事务常用解决方案.md ) * [搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 ](docs/distributed/practice/搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务.md ) * [搞懂分布式技术20:消息队列因何而生](docs/distributed/practice/搞懂分布式技术20:消息队列因何而生.md) -* [搞懂分布式技术21:浅谈分布式消息技术 Kafka ](docs/distributed/practice/搞懂分布式技术21:浅谈分布式消息技术%20Kafka.md ) +* [搞懂分布式技术21:浅谈分布式消息技术 Kafka ](docs/distributed/practice/搞懂分布式技术21:浅谈分布式消息技术 Kafka.md ) * [分布式理论总结](docs/distributed/分布式技术实践总结.md) ## 面试指南 diff --git "a/docs/algorithms/\345\211\221\346\214\207offer.md" "b/docs/cs/algorithms/\345\211\221\346\214\207offer.md" similarity index 100% rename from "docs/algorithms/\345\211\221\346\214\207offer.md" rename to "docs/cs/algorithms/\345\211\221\346\214\207offer.md" diff --git "a/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" similarity index 100% rename from "docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" rename to "docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" diff --git "a/docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" similarity index 100% rename from "docs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" rename to "docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" diff --git "a/docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" similarity index 100% rename from "docs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" rename to "docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2201\357\274\232SpringMVC\346\246\202\350\277\260.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2202\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2203\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2204\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\2206\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" diff --git "a/docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" similarity index 100% rename from "docs/java-web/SSM/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" rename to "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\211\226\346\236\2205\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" diff --git "a/docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" similarity index 100% rename from "docs/java-web/\346\267\261\345\205\245JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" rename to "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\21415\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22714\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\347\274\226\347\250\213\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2271\357\274\232\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2272\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2273\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2275\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2276\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2277\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2278\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2279\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md" diff --git "a/docs/java/currency/Java\345\271\266\345\217\221\346\200\273\347\273\223.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md" similarity index 100% rename from "docs/java/currency/Java\345\271\266\345\217\221\346\200\273\347\273\223.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md" diff --git "a/\346\234\200\347\273\210\346\225\210\346\236\234.md" "b/\346\234\200\347\273\210\346\225\210\346\236\234.md" index dc34623..0cf3d7d 100644 --- "a/\346\234\200\347\273\210\346\225\210\346\236\234.md" +++ "b/\346\234\200\347\273\210\346\225\210\346\236\234.md" @@ -52,7 +52,7 @@ ### 并发 -* [1 面向对象基础](docs/java/currency/Java并发总结.md) +* [1 面向对象基础](docs/java/concurrency/Java并发编程学习总结.md) ### JVM From 2831f9c502018b322da022c42558248468326e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Mon, 3 Apr 2023 12:24:40 +0800 Subject: [PATCH 036/113] modify catalog --- ReadMe.md | 38 +++++++++---------- ...272\343\200\217MySQL\345\222\214InnoDB.md" | 0 ...6\210\220Redis\347\274\223\345\255\230.md" | 0 ...6\201\257\346\212\200\346\234\257Kafka.md" | 0 ...20\347\240\201\345\210\206\346\236\220.md" | 0 ...6\351\230\237\345\210\227BlockingQueue.md" | 0 ...20\347\240\201\345\256\236\347\216\260.md" | 0 ...ap\345\205\250\350\247\243\346\236\220.md" | 0 ...27\346\263\225\345\211\226\346\236\220.md" | 0 ...51\224\201Lock\345\222\214synchronized.md" | 0 ...32\344\277\241\346\234\272\345\210\266.md" | 0 ...67\346\261\202\346\250\241\345\236\213.md" | 0 ...26\347\250\213\346\250\241\345\236\213.md" | 0 ...343\200\201Channel\345\222\214Selector.md" | 0 ...\345\222\214\345\274\202\346\255\245IO.md" | 0 ...37\347\220\206\350\257\246\350\247\243.md" | 0 ...36\347\216\260\345\216\237\347\220\206.md" | 0 ...46\236\220mmap\345\222\214DirectBuffer.md" | 0 ...7\250\213\346\241\206\346\236\266Netty.md" | 0 19 files changed, 19 insertions(+), 19 deletions(-) rename "docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" => "docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" (100%) rename "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" (100%) rename "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" (100%) rename "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" => "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2431\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2435\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2436\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md" (100%) rename "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" => "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" (100%) diff --git a/ReadMe.md b/ReadMe.md index f63c941..54c9ba8 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -162,18 +162,18 @@ todo * [Java并发指南1:并发基础与Java多线程](docs/java/concurrency/Java并发指南1:并发基础与Java多线程.md) * [Java并发指南2:深入理解Java内存模型JMM](docs/java/concurrency/Java并发指南2:深入理解Java内存模型JMM.md) * [Java并发指南3:并发三大问题与volatile关键字,CAS操作](docs/java/concurrency/Java并发指南3:并发三大问题与volatile关键字,CAS操作.md) -* [Java并发指南4:Java中的锁 Lock和synchronized](docs/java/concurrency/Java并发指南4:Java中的锁%20Lock和synchronized.md) +* [Java并发指南4:Java中的锁Lock和synchronized](docs/java/concurrency/Java并发指南4:Java中的锁Lock和synchronized.md) * [Java并发指南5:JMM中的final关键字解析](docs/java/concurrency/Java并发指南5:JMM中的final关键字解析.md) * [Java并发指南6:Java内存模型JMM总结](docs/java/concurrency/Java并发指南6:Java内存模型JMM总结.md) * [Java并发指南7:JUC的核心类AQS详解](docs/java/concurrency/Java并发指南7:JUC的核心类AQS详解.md) * [Java并发指南8:AQS中的公平锁与非公平锁,Condtion](docs/java/concurrency/Java并发指南8:AQS中的公平锁与非公平锁,Condtion.md) * [Java并发指南9:AQS共享模式与并发工具类的实现](docs/java/concurrency/Java并发指南9:AQS共享模式与并发工具类的实现.md) -* [Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析](docs/java/concurrency/Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析.md) -* [Java并发指南11:解读 Java 阻塞队列 BlockingQueue](docs/java/concurrency/Java并发指南11:解读 Java 阻塞队列 BlockingQueue.md) -* [Java并发指南12:深度解读 java 线程池设计思想及源码实现](docs/java/concurrency/Java并发指南12:深度解读 java 线程池设计思想及源码实现.md) -* [Java并发指南13:Java 中的 HashMap 和 ConcurrentHashMap 全解析](docs/java/concurrency/Java并发指南13:Java 中的 HashMap 和 ConcurrentHashMap 全解析.md) +* [Java并发指南10:Java读写锁ReentrantReadWriteLock源码分析](docs/java/concurrency/Java并发指南10:Java读写锁ReentrantReadWriteLock源码分析.md) +* [Java并发指南11:解读Java阻塞队列BlockingQueue](docs/java/concurrency/Java并发指南11:解读Java阻塞队列BlockingQueue.md) +* [Java并发指南12:深度解读java线程池设计思想及源码实现](docs/java/concurrency/Java并发指南12:深度解读Java线程池设计思想及源码实现.md) +* [Java并发指南13:Java中的HashMap和ConcurrentHashMap全解析](docs/java/concurrency/Java并发指南13:Java中的HashMap和ConcurrentHashMap全解析.md) * [Java并发指南14:JUC中常用的Unsafe和Locksupport](docs/java/concurrency/Java并发指南14:JUC中常用的Unsafe和Locksupport.md) -* [Java并发指南15:Fork join并发框架与工作窃取算法剖析](docs/java/concurrency/Java并发指南15:Fork join并发框架与工作窃取算法剖析.md) +* [Java并发指南15:ForkJoin并发框架与工作窃取算法剖析](docs/java/concurrency/Java并发指南15:ForkJoin并发框架与工作窃取算法剖析.md) * [Java并发编程学习总结](docs/java/concurrency/Java并发编程学习总结.md) ### JVM @@ -196,16 +196,16 @@ todo ### Java网络编程 -* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制.md) -* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型.md) -* [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/network-programming/Java网络编程和NIO详解3:IO模型与Java网络编程模型.md) -* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector.md) -* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO.md) -* [Java网络编程和NIO详解6:Linux epoll实现原理详解](docs/java/network-programming/Java网络编程和NIO详解6:Linux%20epoll实现原理详解.md) -* [Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理](docs/java/network-programming/Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理.md) -* [Java网络编程与NIO详解8:浅析mmap和Direct Buffer](docs/java/network-programming/Java网络编程与NIO详解8:浅析mmap和Direct Buffer.md) -* [Java网络编程和NIO详解9:基于NIO的网络编程框架Netty](docs/java/network-programming/Java网络编程和NIO详解9:基于NIO的网络编程框架Netty.md) -* [Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型](docs/java/network-programming/Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型.md) +* [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程与NIO详解1:JAVA中原生的socket通信机制.md) +* [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JavaNIO一步步构建IO多路复用的请求模型.md) +* [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/network-programming/Java网络编程与NIO详解3:IO模型与Java网络编程模型.md) +* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel和Selector.md) +* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java网络编程与NIO详解5:Java非阻塞IO和异步IO.md) +* [Java网络编程与NIO详解6:LinuxEpoll实现原理详解](docs/java/network-programming/Java网络编程与NIO详解6:LinuxEpoll实现原理详解.md.md) +* [Java网络编程与NIO详解7:浅谈Linux中Selector的实现原理](docs/java/network-programming/Java网络编程与NIO详解7:浅谈Linux中Selector的实现原理.md) +* [Java网络编程与NIO详解8:浅析mmap和DirectBuffer](docs/java/network-programming/Java网络编程与NIO详解8:浅析mmap和DirectBuffer.md) +* [Java网络编程与NIO详解9:基于NIO的网络编程框架Netty](docs/java/network-programming/Java网络编程与NIO详解9:基于NIO的网络编程框架Netty.md) +* [Java网络编程与NIO详解10:Java网络编程与NIO详解10](docs/java/network-programming/Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型.md) * [Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)](docs/java/network-programming/Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO).md) ## 计算机基础 @@ -236,7 +236,7 @@ todo ### MySQL * [Mysql原理与实践总结](docs/database/Mysql原理与实践总结.md) * [重新学习Mysql数据库1:无废话MySQL入门](docs/database/重新学习Mysql数据库1:无废话MySQL入门.md) -* [重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB](docs/database/重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB.md) +* [重新学习Mysql数据库2:『浅入浅出』MySQL和InnoDB](docs/database/重新学习Mysql数据库2:『浅入浅出』MySQL和InnoDB.md) * [重新学习Mysql数据库3:Mysql存储引擎与数据存储原理](docs/database/重新学习Mysql数据库3:Mysql存储引擎与数据存储原理.md) * [重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法](docs/database/重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法.md) * [重新学习Mysql数据库5:根据MySQL索引原理进行分析与优化](docs/database/重新学习Mysql数据库5:根据MySQL索引原理进行分析与优化.md) @@ -319,14 +319,14 @@ todo * [搞懂分布式技术11:分布式session解决方案与一致性hash](docs/distributed/practice/搞懂分布式技术11:分布式session解决方案与一致性hash.md) * [搞懂分布式技术12:分布式ID生成方案 ](docs/distributed/practice/搞懂分布式技术12:分布式ID生成方案.md ) * [搞懂分布式技术13:缓存的那些事](docs/distributed/practice/搞懂分布式技术13:缓存的那些事.md) -* [搞懂分布式技术14:Spring Boot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:Spring Boot使用注解集成Redis缓存.md) +* [搞懂分布式技术14:SpringBoot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:SpringBoot使用注解集成Redis缓存.md) * [搞懂分布式技术15:缓存更新的套路 ](docs/distributed/practice/搞懂分布式技术15:缓存更新的套路.md ) * [搞懂分布式技术16:浅谈分布式锁的几种方案 ](docs/distributed/practice/搞懂分布式技术16:浅谈分布式锁的几种方案.md ) * [搞懂分布式技术17:浅析分布式事务 ](docs/distributed/practice/搞懂分布式技术17:浅析分布式事务.md ) * [搞懂分布式技术18:分布式事务常用解决方案 ](docs/distributed/practice/搞懂分布式技术18:分布式事务常用解决方案.md ) * [搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 ](docs/distributed/practice/搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务.md ) * [搞懂分布式技术20:消息队列因何而生](docs/distributed/practice/搞懂分布式技术20:消息队列因何而生.md) -* [搞懂分布式技术21:浅谈分布式消息技术 Kafka ](docs/distributed/practice/搞懂分布式技术21:浅谈分布式消息技术 Kafka.md ) +* [搞懂分布式技术21:浅谈分布式消息技术Kafka](docs/distributed/practice/搞懂分布式技术21:浅谈分布式消息技术Kafka.md ) * [分布式理论总结](docs/distributed/分布式技术实践总结.md) ## 面试指南 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" similarity index 100% rename from "docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL \345\222\214 InnoDB.md" rename to "docs/database/\351\207\215\346\226\260\345\255\246\344\271\240Mysql\346\225\260\346\215\256\345\272\2232\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" similarity index 100% rename from "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232Spring Boot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25714\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" similarity index 100% rename from "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257 Kafka.md" rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\25721\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java \350\257\273\345\206\231\351\224\201 ReentrantReadWriteLock \346\272\220\347\240\201\345\210\206\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22710\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273 Java \351\230\273\345\241\236\351\230\237\345\210\227 BlockingQueue.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22711\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273 java \347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22712\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java \344\270\255\347\232\204 HashMap \345\222\214 ConcurrentHashMap \345\205\250\350\247\243\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22713\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232Fork join\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\22715\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.md" similarity index 100% rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201 Lock\345\222\214synchronized.md" rename to "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\2274\357\274\232Java\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2431\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2431\357\274\232JAVA \344\270\255\345\216\237\347\224\237\347\232\204 socket \351\200\232\344\277\241\346\234\272\345\210\266.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2431\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JAVA NIO \344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2432\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2433\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel \345\222\214 Selector.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2434\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2435\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2435\357\274\232Java \351\235\236\351\230\273\345\241\236 IO \345\222\214\345\274\202\346\255\245 IO.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2435\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2436\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2436\357\274\232Linux epoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2436\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210 Linux \344\270\255NIO Selector \347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2437\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214Direct Buffer.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2438\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md" diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" similarity index 100% rename from "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\345\222\214NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" rename to "docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\2439\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" From cfcc5bd7e56daccf03c1929491bf2735e907baac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Mon, 3 Apr 2023 20:28:04 +0800 Subject: [PATCH 037/113] use oss picgo --- ReadMe.md | 30 +- ...70\345\277\203\346\265\201\347\250\213.md" | 0 ...40\350\275\275\350\277\207\347\250\213.md" | 0 ...4\232SpringAOP\346\246\202\350\277\260.md" | 0 ...45\350\257\206\346\270\205\345\215\225.md" | 0 ...37\347\220\206\350\257\246\350\247\243.md" | 0 ...71\350\261\241\345\237\272\347\241\200.md" | 124 +-- ...60\346\215\256\347\261\273\345\236\213.md" | 169 ++-- ...14\345\214\205\350\243\205\347\261\273.md" | 923 +++++++++--------- ...56\345\255\227\347\211\271\346\200\247.md" | 54 +- ...va\347\261\273\345\222\214\345\214\205.md" | 263 +++-- ...17\347\232\204\347\247\230\345\257\206.md" | 422 ++++---- ...43\346\236\220\345\256\236\350\267\265.md" | 0 ...14\346\234\237\344\274\230\345\214\226.md" | 0 14 files changed, 918 insertions(+), 1067 deletions(-) rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" => "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" (100%) rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" => "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" (100%) rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" => "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232SpringAOP\346\246\202\350\277\260.md" (100%) rename "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" => "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" (100%) rename "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%) rename "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" => "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" (100%) rename "docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" => "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" (100%) diff --git a/ReadMe.md b/ReadMe.md index 54c9ba8..9e8a447 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -67,6 +67,7 @@ * [2、Java基本数据类型](docs/java/basic/2、Java基本数据类型.md) * [3、string和包装类](docs/java/basic/3、string和包装类.md) * [4、final关键字特性](docs/java/basic/4、final关键字特性.md) + * [5、Java类和包](docs/java/basic/5、Java类和包.md) * [6、抽象类和接口](docs/java/basic/6、抽象类和接口.md) * [7、代码块和代码执行顺序](docs/java/basic/7、代码块和代码执行顺序.md) @@ -112,7 +113,7 @@ * [走进JavaWeb技术世界1:JavaWeb的由来和基础知识](docs/java-web/走进JavaWeb技术世界1:JavaWeb的由来和基础知识.md) * [走进JavaWeb技术世界2:JSP与Servlet的曾经与现在](docs/java-web/走进JavaWeb技术世界2:JSP与Servlet的曾经与现在.md) * [走进JavaWeb技术世界3:JDBC的进化与连接池技术](docs/java-web/走进JavaWeb技术世界3:JDBC的进化与连接池技术.md) -* [走进JavaWeb技术世界4:Servlet 工作原理详解](docs/java-web/走进JavaWeb技术世界4:Servlet%20工作原理详解.md) +* [走进JavaWeb技术世界4:Servlet工作原理详解](docs/java-web/走进JavaWeb技术世界4:Servlet工作原理详解.md) * [走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程](docs/java-web/走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程.md) * [走进JavaWeb技术世界6:Tomcat5总体架构剖析](docs/java-web/走进JavaWeb技术世界6:Tomcat5总体架构剖析.md) * [走进JavaWeb技术世界7:Tomcat和其他WEB容器的区别](docs/java-web/走进JavaWeb技术世界7:Tomcat和其他WEB容器的区别.md) @@ -182,11 +183,11 @@ todo * [深入理解JVM虚拟机1:JVM内存的结构与消失的永久代](docs/java/jvm/深入理解JVM虚拟机1:JVM内存的结构与消失的永久代.md) * [深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法](docs/java/jvm/深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法.md) * [深入理解JVM虚拟机3:垃圾回收器详解](docs/java/jvm/深入理解JVM虚拟机3:垃圾回收器详解.md) -* [深入理解JVM虚拟机4:Javaclass介绍与解析实践](docs/java/jvm/深入理解JVM虚拟机4:Javaclass介绍与解析实践.md) +* [深入理解JVM虚拟机4:Javaclass介绍与解析实践](docs/java/jvm/深入理解JVM虚拟机4:Java字节码介绍与解析实践.md) * [深入理解JVM虚拟机5:虚拟机字节码执行引擎](docs/java/jvm/深入理解JVM虚拟机5:虚拟机字节码执行引擎.md) * [深入理解JVM虚拟机6:深入理解JVM类加载机制](docs/java/jvm/深入理解JVM虚拟机6:深入理解JVM类加载机制.md) * [深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现](docs/java/jvm/深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现.md) -* [深入了解JVM虚拟机8:Java的编译期优化与运行期优化](docs/java/jvm/深入了解JVM虚拟机8:Java的编译期优化与运行期优化.md) +* [深入了解JVM虚拟机8:Java的编译期优化与运行期优化](docs/java/jvm/深入理解JVM虚拟机8:Java的编译期优化与运行期优化.md) * [深入理解JVM虚拟机9:JVM监控工具与诊断实践](docs/java/jvm/深入理解JVM虚拟机9:JVM监控工具与诊断实践.md) * [深入理解JVM虚拟机10:JVM常用参数以及调优实践](docs/java/jvm/深入理解JVM虚拟机10:JVM常用参数以及调优实践.md) * [深入理解JVM虚拟机11:Java内存异常原理与实践](docs/java/jvm/深入理解JVM虚拟机11:Java内存异常原理与实践.md) @@ -199,8 +200,8 @@ todo * [Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制](docs/java/network-programming/Java网络编程与NIO详解1:JAVA中原生的socket通信机制.md) * [Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型](docs/java/network-programming/Java网络编程与NIO详解2:JavaNIO一步步构建IO多路复用的请求模型.md) * [Java网络编程和NIO详解3:IO模型与Java网络编程模型](docs/java/network-programming/Java网络编程与NIO详解3:IO模型与Java网络编程模型.md) -* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector](docs/java/network-programming/Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel和Selector.md) -* [Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO](docs/java/network-programming/Java网络编程与NIO详解5:Java非阻塞IO和异步IO.md) +* [Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel和Selector](docs/java/network-programming/Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel和Selector.md) +* [Java网络编程和NIO详解5:Java非阻塞IO和异步IO](docs/java/network-programming/Java网络编程与NIO详解5:Java非阻塞IO和异步IO.md) * [Java网络编程与NIO详解6:LinuxEpoll实现原理详解](docs/java/network-programming/Java网络编程与NIO详解6:LinuxEpoll实现原理详解.md.md) * [Java网络编程与NIO详解7:浅谈Linux中Selector的实现原理](docs/java/network-programming/Java网络编程与NIO详解7:浅谈Linux中Selector的实现原理.md) * [Java网络编程与NIO详解8:浅析mmap和DirectBuffer](docs/java/network-programming/Java网络编程与NIO详解8:浅析mmap和DirectBuffer.md) @@ -255,7 +256,7 @@ todo ### Redis * [Redis原理与实践总结](docs/cache/Redis原理与实践总结.md) * [探索Redis设计与实现开篇:什么是Redis](docs/cache/探索Redis设计与实现开篇:什么是Redis.md) -* [探索Redis设计与实现1:Redis 的基础数据结构概览](docs/cache/探索Redis设计与实现1:Redis%20的基础数据结构概览.md) +* [探索Redis设计与实现1:Redis的基础数据结构概览](docs/cache/探索Redis设计与实现1:Redis的基础数据结构概览.md) * [探索Redis设计与实现2:Redis内部数据结构详解——dict](docs/cache/探索Redis设计与实现2:Redis内部数据结构详解——dict.md) * [探索Redis设计与实现3:Redis内部数据结构详解——sds](docs/cache/探索Redis设计与实现3:Redis内部数据结构详解——sds.md) * [探索Redis设计与实现4:Redis内部数据结构详解——ziplist](docs/cache/探索Redis设计与实现4:Redis内部数据结构详解——ziplist.md) @@ -292,9 +293,9 @@ todo ## 分布式 ### 理论 -* [分布式系统理论基础1: 一致性、2PC和3PC ](docs/distributed/basic/分布式系统理论基础1:%20一致性、2PC和3PC.md) -* [分布式系统理论基础2:CAP ](docs/distributed/basic/分布式系统理论基础2%20:CAP.md) -* [分布式系统理论基础3: 时间、时钟和事件顺序](docs/distributed/basic/分布式系统理论基础3:%20时间、时钟和事件顺序.md) +* [分布式系统理论基础1:一致性、2PC和3PC ](docs/distributed/basic/分布式系统理论基础1:一致性、2PC和3PC.md) +* [分布式系统理论基础2:CAP ](docs/distributed/basic/分布式系统理论基础2:CAP.md) +* [分布式系统理论基础3:时间、时钟和事件顺序](docs/distributed/basic/分布式系统理论基础3:时间、时钟和事件顺序.md) * [分布式系统理论基础4:Paxos](docs/distributed/basic/分布式系统理论基础4:Paxos.md) * [分布式系统理论基础5:选举、多数派和租约](docs/distributed/basic/分布式系统理论基础5:选举、多数派和租约.md) * [分布式系统理论基础6:Raft、Zab ](docs/distributed/basic/分布式系统理论基础6:Raft、Zab.md) @@ -302,13 +303,14 @@ todo * [分布式系统理论基础8:zookeeper分布式协调服务 ](docs/distributed/basic/分布式系统理论基础8:zookeeper分布式协调服务.md) * [分布式技术实践总结](docs/distributed/分布式理论总结.md) + ### 技术 -* [搞懂分布式技术1:分布式系统的一些基本概念 ](docs/distributed/practice/搞懂分布式技术1:分布式系统的一些基本概念.md ) +* [搞懂分布式技术1:分布式系统的一些基本概念](docs/distributed/practice/搞懂分布式技术1:分布式系统的一些基本概念.md ) * [搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法](docs/distributed/practice/搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法.md) -* [搞懂分布式技术3:初探分布式协调服务zookeeper ](docs/distributed/practice/搞懂分布式技术3:初探分布式协调服务zookeeper.md ) -* [搞懂分布式技术4:ZAB协议概述与选主流程详解 ](docs/distributed/practice/搞懂分布式技术4:ZAB协议概述与选主流程详解.md ) +* [搞懂分布式技术3:初探分布式协调服务zookeeper](docs/distributed/practice/搞懂分布式技术3:初探分布式协调服务zookeeper.md ) +* [搞懂分布式技术4:ZAB协议概述与选主流程详解](docs/distributed/practice/搞懂分布式技术4:ZAB协议概述与选主流程详解.md ) * [搞懂分布式技术5:Zookeeper的配置与集群管理实战](docs/distributed/practice/搞懂分布式技术5:Zookeeper的配置与集群管理实战.md) -* [搞懂分布式技术6:Zookeeper典型应用场景及实践 ](docs/distributed/practice/搞懂分布式技术6:Zookeeper典型应用场景及实践.md ) +* [搞懂分布式技术6:Zookeeper典型应用场景及实践](docs/distributed/practice/搞懂分布式技术6:Zookeeper典型应用场景及实践.md ) [//]: # (* [搞懂分布式技术7:负载均衡概念与主流方案](docs/distributed/practice/搞懂分布式技术7:负载均衡概念与主流方案.md)) @@ -322,7 +324,7 @@ todo * [搞懂分布式技术14:SpringBoot使用注解集成Redis缓存](docs/distributed/practice/搞懂分布式技术14:SpringBoot使用注解集成Redis缓存.md) * [搞懂分布式技术15:缓存更新的套路 ](docs/distributed/practice/搞懂分布式技术15:缓存更新的套路.md ) * [搞懂分布式技术16:浅谈分布式锁的几种方案 ](docs/distributed/practice/搞懂分布式技术16:浅谈分布式锁的几种方案.md ) -* [搞懂分布式技术17:浅析分布式事务 ](docs/distributed/practice/搞懂分布式技术17:浅析分布式事务.md ) +* [搞懂分布式技术17:浅析分布式事务](docs/distributed/practice/搞懂分布式技术17:浅析分布式事务.md ) * [搞懂分布式技术18:分布式事务常用解决方案 ](docs/distributed/practice/搞懂分布式技术18:分布式事务常用解决方案.md ) * [搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 ](docs/distributed/practice/搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务.md ) * [搞懂分布式技术20:消息队列因何而生](docs/distributed/practice/搞懂分布式技术20:消息队列因何而生.md) diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" similarity index 100% rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242Spring IOC\346\240\270\345\277\203\346\265\201\347\250\213.md" rename to "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2202\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" similarity index 100% rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232Spring IOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" rename to "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2203\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232SpringAOP\346\246\202\350\277\260.md" similarity index 100% rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232Spring AOP\346\246\202\350\277\260.md" rename to "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\2206\357\274\232SpringAOP\346\246\202\350\277\260.md" diff --git "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" "b/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" similarity index 100% rename from "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275Spring Boot\347\237\245\350\257\206\346\270\205\345\215\225.md" rename to "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" similarity index 100% rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" rename to "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\2144\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" diff --git "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" index 20a3a96..0037f49 100644 --- "a/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" +++ "b/docs/java/basic/1\343\200\201\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" @@ -16,10 +16,6 @@ * [二、封装](#二、封装) * [1、封装的概念](#1、封装的概念) * [2、封装的优点](#2、封装的优点) - * [3、封装的实现步骤](#3、封装的实现步骤) - * [A、访问修饰符](#a、访问修饰符) - * [B、this关键字](#b、this关键字) - * [C、Java 中的内部类](#c、java-中的内部类) * [三、多态](#三、多态) * [1、多态的概念](#1、多态的概念) * [2、多态的好处](#2、多态的好处) @@ -67,27 +63,23 @@ Java 是面向对象的编程语言,对象就是面向对象程序设计的核 ## 面向对象和面向过程的区别 - 面向过程: -   一种较早的编程思想,顾名思义就是该思想是站着过程的角度思考问题,强调的就是功能行为,功能的执行过程,即先后顺序,而每一个功能我们都使用函数(类似于方法)把这些步骤一步一步实现。使用的时候依次调用函数就可以了。 +一种较早的编程思想,顾名思义就是该思想是站着过程的角度思考问题,强调的就是功能行为,功能的执行过程,即先后顺序,而每一个功能我们都使用函数(类似于方法)把这些步骤一步一步实现。使用的时候依次调用函数就可以了。 - 面向过程的设计: -   最小的程序单元是函数,每个函数负责完成某一个功能,用于接受输入数据,函数对输入数据进行处理,然后输出结果数据,整个软件系统由一个个的函数组成,其中作为程序入口的函数称之为主函数,主函数依次调用其他函数,普通函数之间可以相互调用,从而实现整个系统功能。 -   面向过程最大的问题在于随着系统的膨胀,面向过程将无法应付,最终导致系统的崩溃。为了解决这一种软件危机,我们提出面向对象思想。 + 最小的程序单元是函数,每个函数负责完成某一个功能,用于接受输入数据,函数对输入数据进行处理,然后输出结果数据,整个软件系统由一个个的函数组成,其中作为程序入口的函数称之为主函数,主函数依次调用其他函数,普通函数之间可以相互调用,从而实现整个系统功能。 + 面向过程最大的问题在于随着系统的膨胀,面向过程将无法应付,最终导致系统的崩溃。为了解决这一种软件危机,我们提出面向对象思想。 - 面向过程的缺陷: -   是采用自顶而下的设计模式,在设计阶段就需要考虑每一个模块应该分解成哪些子模块,每一个子模块又细分为更小的子模块,如此类推,直到将模块细化为一个个函数。 + 是采用自顶而下的设计模式,在设计阶段就需要考虑每一个模块应该分解成哪些子模块,每一个子模块又细分为更小的子模块,如此类推,直到将模块细化为一个个函数。 -- 存在的问题 - - ​ 设计不够直观,与人类的思维习惯不一致 +- 存在的问题 + 设计不够直观,与人类的思维习惯不一致 系统软件适应新差,可拓展性差,维护性低 -- 面向对象: - - ​ 一种基于面向过程的新编程思想,顾名思义就是该思想是站在对象的角度思考问题,我们把多个功能合理放到不同对象里,强调的是具备某些功能的对象。 - -   具备某种功能的实体,称为对象。面向对象最小的程序单元是:类。面向对象更加符合常规的思维方式,稳定性好,可重用性强,易于开发大型软件产品,有良好的可维护性。 - -  在软件工程上,面向对象可以使工程更加模块化,实现更低的耦合和更高的内聚。 +- 面向对象: + 一种基于面向过程的新编程思想,顾名思义就是该思想是站在对象的角度思考问题,我们把多个功能合理放到不同对象里,强调的是具备某些功能的对象。 + 具备某种功能的实体,称为对象。面向对象最小的程序单元是:类。面向对象更加符合常规的思维方式,稳定性好,可重用性强,易于开发大型软件产品,有良好的可维护性。 + 在软件工程上,面向对象可以使工程更加模块化,实现更低的耦合和更高的内聚。 ## 面向对象的三大核心特性简介 @@ -179,10 +171,7 @@ Java 是面向对象的编程语言,对象就是面向对象程序设计的核 使用这种层次形的分类方式,是为了将多个类的通用属性和方法提取出来,放在它们的父类中,然后只需要在子类中各自定义自己独有的属性和方法,并以继承的形式在父类中获取它们的通用属性和方法即可。 - 继承是类与类的一种关系,是一种“is a”的关系。比如“狗”继承“动物”,这里动物类是狗类的父类或者基类,狗类是动物类的子类或者派生类。如下图所示: - -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701123011243-2128400556.png) - + 继承是类与类的一种关系,是一种“is a”的关系。比如“狗”继承“动物”,这里动物类是狗类的父类或者基类,狗类是动物类的子类或者派生类。 注:java中的继承是**单继承**,即**一个类只有一个父类。** **补充:Java中的继承只能单继承,但是可以通过内部类继承其他类来实现多继承。** @@ -218,47 +207,37 @@ System.out.println("mom cook");  子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)从而实现了实现代码的复用;  -#### 3、语法规则 - -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701123421961-647167245.png) - ------- - ##### A、方法的重写 - 子类如果对继承的父类的方法不满意(不适合),可以自己编写继承的方法,这种方式就称为**方法的重写。当调用方法时会优先调用子类的方法。** +子类如果对继承的父类的方法不满意(不适合),可以自己编写继承的方法,这种方式就称为**方法的重写。当调用方法时会优先调用子类的方法。** - **重写要注意:** +**重写要注意:** -  a、返回值类型 +a、返回值类型 -  b、方法名 +b、方法名 -  c、参数类型及个数 +c、参数类型及个数 - 都要与父类继承的方法相同,才叫方法的重写。 +都要与父类继承的方法相同,才叫方法的重写。 - **重载和重写的区别:** +**重载和重写的区别:** -  方法重载:在同一个类中处理不同数据的多个相同方法名的多态手段。 +方法重载:在同一个类中处理不同数据的多个相同方法名的多态手段。 -  方法重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改。 +方法重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改。 ------ ##### B、继承的初始化顺序 -  1、初始化父类再初始化子类 - -  2、先执行初始化对象中属性,再执行构造方法中的初始化。 +1、初始化父类再初始化子类 - 基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是: +2、先执行初始化对象中属性,再执行构造方法中的初始化。 - **父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化--->子类对象构造方法**    +基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是: - 下面有个形象的图: - -![img](https://images2015.cnblogs.com/blog/1189312/201707/1189312-20170701144019071-1063399032.png) +**父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化--->子类对象构造方法**    ------ @@ -345,55 +324,22 @@ Java 封装,说白了就是将一大坨公共通用的实现逻辑玩意,装 4. 一对一,一个功能就只为这个功能服务;避免头发绳子一块用,导致最后一团糟 -#### 3、封装的实现步骤 - -![img](https://images2015.cnblogs.com/blog/1189312/201706/1189312-20170630170717493-357592353.png) - -    需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作。当然最好使用get/set方法,比较标准。 - ------- - - - -##### A、访问修饰符 - -![img](https://images2015.cnblogs.com/blog/1189312/201706/1189312-20170630174919274-1857293801.png) - -    从表格可以看出**从上到下封装性越来越差**。 - - - -##### B、this关键字 - - 1.this关键字**代表当前对象** - -  this.属性 操作当前对象的属性 - -  this.方法 调用当前对象的方法。 - - 2.封装对象的属性的时候,经常会使用this关键字。 - - 3.当getter和setter函数参数名和成员函数名重合的时候,**可以使用this****区别。如:** - -![img](https://images2015.cnblogs.com/blog/1189312/201706/1189312-20170630180217524-833886832.png) - - ##### C、Java 中的内部类 - 内部类( Inner Class )就是定义在另外一个类**里面**的类。与之对应,包含内部类的类被称为外部类。 +内部类( Inner Class )就是定义在另外一个类**里面**的类。与之对应,包含内部类的类被称为外部类。 - 那么问题来了:那为什么要将一个类定义在另一个类里面呢?清清爽爽的独立的一个类多好啊!! +那么问题来了:那为什么要将一个类定义在另一个类里面呢?清清爽爽的独立的一个类多好啊!! - 答:内部类的主要作用如下: +答:内部类的主要作用如下: -  1. 内部类提供了**更好的封装**,可以把内部类**隐藏**在外部类之内,**不允许**同一个包中的其他类访问该类。 +1. 内部类提供了**更好的封装**,可以把内部类**隐藏**在外部类之内,**不允许**同一个包中的其他类访问该类。 -  2. 内部类的方法可以**直接访问外部类的所有数据**,包括**私有的数据**。 +2. 内部类的方法可以**直接访问外部类的所有数据**,包括**私有的数据**。 -  3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。 +3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。 -  内部类可分为以下几种: +内部类可分为以下几种: - 成员内部类 @@ -401,8 +347,6 @@ Java 封装,说白了就是将一大坨公共通用的实现逻辑玩意,装 - 方法内部类 - 匿名内部类   - - ### 三、多态 #### 1、多态的概念 @@ -483,13 +427,13 @@ java里的多态主要表现在两个方面:   就以上述的父类Animal和一个子类Dog来说明,当父类的引用可以指向子类的对象时,就是**向上类型转换**。如: -![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjYzMDUwOC05NjE1MDc2NTkucG5n?x-oss-process=image/format,png) + ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjYzMDUwOC05NjE1MDc2NTkucG5n?x-oss-process=image/format,png)   **2. 向下类型转换(强制类型转换),是大类型转换到小类型(有风险,可能出现数据溢出)。**   将上述代码再加上一行,我们再次将父类转换为子类引用,那么会出现错误,编译器不允许我们直接这么做**,**虽然我们知道这个父类引用指向的就是子类对象,但是编译器认为这种转换是存在风险的**。**如: -![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjkyNjQ3Ny0zODU3OTc1LnBuZw?x-oss-process=image/format,png) + ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2MjkyNjQ3Ny0zODU3OTc1LnBuZw?x-oss-process=image/format,png)   那么我们该怎么解决这个问题呢,我们可以在animal前加上(Dog)来强制类型转换。如:![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NDIyOTg5OS0xMDU1MTkwNzc0LnBuZw?x-oss-process=image/format,png) @@ -499,7 +443,7 @@ java里的多态主要表现在两个方面:   还有一种情况是父类的引用指向**其他子类的对象**,则不能通过强制转为**该子类的对象**。如: -    ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NTEzMzI4OS03MTc0MzkzNjAucG5n?x-oss-process=image/format,png) +  ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTE4OTMxMi8yMDE3MDcvMTE4OTMxMi0yMDE3MDcwMTE2NTEzMzI4OS03MTc0MzkzNjAucG5n?x-oss-process=image/format,png)   这是因为我们在编译的时候进行了强制类型转换,编译时的类型是我们强制转换的类型,所以编译器不会报错,而当我们运行的时候,程序给animal开辟的是Dog类型的内存空间,这与Cat类型内存空间不匹配,所以无法正常转换。这两种情况出错的本质是一样的,所以我们在使用强制类型转换的时候要特别注意这两种错误!!下面有个更安全的方式来实现向下类型转换。。。。 diff --git "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" index 655b4c2..c6349c6 100644 --- "a/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" +++ "b/docs/java/basic/2\343\200\201Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" @@ -34,9 +34,6 @@ 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 - - - # Java 基本数据类型 @@ -53,7 +50,6 @@ - 内置数据类型 - 引用数据类型 -- - * ### 内置数据类型 @@ -128,50 +124,6 @@ Java语言提供了八种基本类型。六种数字类型(四个整数型, - char 数据类型可以储存任何字符; - 例子:char letter = 'A';。 -``` -//8位 -byte bx = Byte.MAX_VALUE; -byte bn = Byte.MIN_VALUE; -//16位 -short sx = Short.MAX_VALUE; -short sn = Short.MIN_VALUE; -//32位 -int ix = Integer.MAX_VALUE; -int in = Integer.MIN_VALUE; -//64位 -long lx = Long.MAX_VALUE; -long ln = Long.MIN_VALUE; -//32位 -float fx = Float.MAX_VALUE; -float fn = Float.MIN_VALUE; -//64位 -double dx = Double.MAX_VALUE; -double dn = Double.MIN_VALUE; -//16位 -char cx = Character.MAX_VALUE; -char cn = Character.MIN_VALUE; -//1位 -boolean bt = Boolean.TRUE; -boolean bf = Boolean.FALSE; -``` - - `127` - `-128` - `32767` - `-32768` - `2147483647` - `-2147483648` - `9223372036854775807` - `-9223372036854775808` - `3.4028235E38` - `1.4E-45` - `1.7976931348623157E308` - `4.9E-324` - `￿` - - `true` - `false` - ### 引用类型 - 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。 @@ -202,22 +154,24 @@ char a = 'A' ## 自动拆箱和装箱(详解) Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装类型的相互转换操作。在Java 5之前,如果要将一个int型的值转换成对应的包装器类型Integer,必须显式的使用new创建一个新的Integer对象,或者调用静态方法Integer.valueOf()。 - - //在Java 5之前,只能这样做 - Integer value = new Integer(10); - //或者这样做 - Integer value = Integer.valueOf(10); - //直接赋值是错误的 - //Integer value = 10;` - +```` +//在Java 5之前,只能这样做 +Integer value = new Integer(10); +//或者这样做 +Integer value = Integer.valueOf(10); +//直接赋值是错误的 +//Integer value = 10; +```` 在Java 5中,可以直接将整型赋给Integer对象,由编译器来完成从int型到Integer类型的转换,这就叫自动装箱。 - `//在Java 5中,直接赋值是合法的,由编译器来完成转换` - `Integer value = 10;` - `与此对应的,自动拆箱就是可以将包装类型转换为基本类型,具体的转换工作由编译器来完成。` - `//在Java 5 中可以直接这么做` - `Integer value = new Integer(10);` - `int i = value;` +```` +//在Java 5中,直接赋值是合法的,由编译器来完成转换 +Integer value = 10; +与此对应的,自动拆箱就是可以将包装类型转换为基本类型,具体的转换工作由编译器来完成。 +//在Java 5 中可以直接这么做 +Integer value = new Integer(10); +int i = value; +```` 自动装箱与自动拆箱为程序员提供了很大的方便,而在实际的应用中,自动装箱与拆箱也是使用最广泛的特性之一。自动装箱和自动拆箱其实是Java编译器提供的一颗语法糖(语法糖是指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通过可提高开发效率,增加代码可读性,增加代码的安全性)。 @@ -229,43 +183,41 @@ Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装 实例方法xxxValue():将具体的包装类型对象转换成基本类型; 下面我们以int和Integer为例,说明Java中自动装箱与自动拆箱的实现机制。看如下代码: - - class Auto //code1 - { - public static void main(String[] args) - { - //自动装箱 - Integer inte = 10; - //自动拆箱 - int i = inte; - - //再double和Double来验证一下 - Double doub = 12.40; - double d = doub; - - } - - } +```` + class Auto //code1 + { + public static void main(String[] args) + { + //自动装箱 + Integer inte = 10; + //自动拆箱 + int i = inte; + + //再double和Double来验证一下 + Double doub = 12.40; + double d = doub; + + } + + } +```` 上面的代码先将int型转为Integer对象,再讲Integer对象转换为int型,毫无疑问,这是可以正确运行的。可是,这种转换是怎么进行的呢?使用反编译工具,将生成的Class文件在反编译为Java文件,让我们看看发生了什么: +```` class Auto//code2 { public static void main(String[] paramArrayOfString) { Integer localInteger = Integer.valueOf(10); - - -​ -​ int i = localInteger.intValue(); - - -​ -​ -​ Double localDouble = Double.valueOf(12.4D); -​ double d = localDouble.doubleValue(); -​ -​ } -​ } + + int i = localInteger.intValue(); + + Double localDouble = Double.valueOf(12.4D); + double d = localDouble.doubleValue(); + + } + } +```` 我们可以看到经过javac编译之后,code1的代码被转换成了code2,实际运行时,虚拟机运行的就是code2的代码。也就是说,虚拟机根本不知道有自动拆箱和自动装箱这回事;在将Java源文件编译为class文件的过程中,javac编译器在自动装箱的时候,调用了Integer.valueOf()方法,在自动拆箱时,又调用了intValue()方法。我们可以看到,double和Double也是如此。 实现总结:其实自动装箱和自动封箱是编译器为我们提供的一颗语法糖。在自动装箱时,编译器调用包装类型的valueOf()方法;在自动拆箱时,编译器调用了相应的xxxValue()方法。 @@ -276,7 +228,7 @@ Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装 Integer源码 -``` +```` public final class Integer extends Number implements Comparable { private final int value; @@ -343,7 +295,7 @@ public final class Integer extends Number implements Comparable { private IntegerCache() {} } -``` +```` 以上是Oracle(Sun)公司JDK 1.7中Integer源码的一部分,通过分析上面的代码,得到: @@ -363,21 +315,22 @@ public final class Integer extends Number implements Comparable { 5)调用intValue(),直接返回value的值。 通过3)和4)可以发现,默认情况下,在使用自动装箱时,VM会复用[-128,127]之间的Integer对象。 - - Integer a1 = 1; - Integer a2 = 1; - Integer a3 = new Integer(1); - //会打印true,因为a1和a2是同一个对象,都是Integer.cache[129] - System.out.println(a1 == a2); - //false,a3构造了一个新的对象,不同于a1,a2 - System.out.println(a1 == a3); - +```` +Integer a1 = 1; +Integer a2 = 1; +Integer a3 = new Integer(1); +//会打印true,因为a1和a2是同一个对象,都是Integer.cache[129] +System.out.println(a1 == a2); +//false,a3构造了一个新的对象,不同于a1,a2 +System.out.println(a1 == a3); +```` ### 了解基本类型缓存(常量池)的最佳实践 ``` //基本数据类型的常量池是-128到127之间。 // 在这个范围中的基本数据类的包装类可以自动拆箱,比较时直接比较数值大小。 public static void main(String[] args) { + //int的自动拆箱和装箱只在-128到127范围中进行,超过该范围的两个integer的 == 判断是会返回false的。 Integer a1 = 128; Integer a2 = -128; @@ -394,7 +347,6 @@ public static void main(String[] args) { System.out.println(b1 == b2); System.out.println(b3 == b4); - // Long c1 = 128L; Long c2 = 128L; Long c3 = -128L; @@ -411,7 +363,6 @@ public static void main(String[] args) { System.out.println(d1 == d2); System.out.println(d3 == d4); - `结果` `false` @@ -423,8 +374,6 @@ public static void main(String[] args) { `false` `true` - - Integer i = 10; Byte b = 10; //比较Byte和Integer.两个对象无法直接比较,报错 @@ -460,8 +409,6 @@ public static void main(String[] args) { 需要注意的是:“==”在没遇到算术运算时,不会自动拆箱;基本类型只会自动装箱为对应的包装类型,代码中最后一条说明的内容。 - - 在JDK 1.5中提供了自动装箱与自动拆箱,这其实是Java 编译器的语法糖,编译器通过调用包装类型的valueOf()方法实现自动装箱,调用xxxValue()方法自动拆箱。自动装箱和拆箱会有一些陷阱,那就是包装类型复用了某些对象。 (1)Integer默认复用了[-128,127]这些对象,其中高位置可以修改; @@ -574,10 +521,6 @@ System.out.println(s3 == s4); JDK1.6以及以下:false false JDK1.7以及以上:false true ``` - -![image](https://img-blog.csdn.net/20180422231916788?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E3MjQ4ODg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) - -![image](https://img-blog.csdn.net/20180422231929413?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E3MjQ4ODg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) JDK1.6查找到常量池存在相同值的对象时会直接返回该对象的地址。 JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。 diff --git "a/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" "b/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" index 13dfe0a..064cb24 100644 --- "a/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" +++ "b/docs/java/basic/3\343\200\201string\345\222\214\345\214\205\350\243\205\347\261\273.md" @@ -46,11 +46,8 @@ 如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。 - - - ## string基础 ### Java String 类 @@ -70,9 +67,14 @@ String greeting = "菜鸟教程"; String 类有 11 种构造方法,这些方法提供不同的参数来初始化字符串,比如提供一个字符数组参数: ### StringDemo.java 文件代码: - - public class StringDemo{ public static void main(String args[]){ char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'}; String helloString = new String(helloArray); System.out.println( helloString ); } } - +```` +public class StringDemo{ +public static void main(String args[]){ +char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'}; +String helloString = new String(helloArray); +System.out.println( helloString ); +} } +```` 以上实例编译运行结果如下: ``` @@ -87,35 +89,37 @@ runoob ### 创建String对象的常用方法 -(1) String s1 = "mpptest" +(1) String s1 = "mpptest" - (2) String s2 = new String(); +(2) String s2 = new String(); - (3) String s3 = new String("mpptest") +(3) String s3 = new String("mpptest") ### String中常用的方法,用法如图所示,具体问度娘 ![](https://img2018.cnblogs.com/blog/710412/201902/710412-20190213220237169-1966705420.png) ### 三个方法的使用: lenth() substring() charAt() - - - -

package com.mpp.string; public class StringDemo1 { public static void main(String[] args) { //定义一个字符串"晚来天欲雪 能饮一杯无"
+````
+package com.mpp.string; 
+public class StringDemo1 {
+    public static void main(String[] args) { //定义一个字符串"晚来天欲雪 能饮一杯无"
         String str = "晚来天欲雪 能饮一杯无";
         System.out.println("字符串的长度是:"+str.length()); //字符串的雪字打印输出  charAt(int index)
         System.out.println(str.charAt(4)); //取出子串  天欲
         System.out.println(str.substring(2));   //取出从index2开始直到最后的子串,包含2
         System.out.println(str.substring(2,4));  //取出index从2到4的子串,包含2不包含4  顾头不顾尾
- }
-}
- - + } +} +```` - 两个方法的使用,求字符或子串第一次/最后一次在字符串中出现的位置: indexOf() lastIndexOf() +两个方法的使用,求字符或子串第一次/最后一次在字符串中出现的位置: +indexOf() lastIndexOf() -
package com.mpp.string; public class StringDemo2 { public static void main(String[] args) {
+````
+package com.mpp.string; public class StringDemo2 { 
+    public static void main(String[] args) {
         String str = new String("赵客缦胡缨 吴钩胡缨霜雪明"); //查找胡在字符串中第一次出现的位置
         System.out.println("\"胡\"在字符串中第一次出现的位置:"+str.indexOf("胡")); //查找子串"胡缨"在字符串中第一次出现的位置
         System.out.println("\"胡缨\"在字符串中第一次出现的位置"+str.indexOf("胡缨")); //查找胡在字符串中最后一次次出现的位置
@@ -123,35 +127,40 @@ runoob
         System.out.println(str.lastIndexOf("胡缨")); //从indexof为5的位置,找第一次出现的"吴"
         System.out.println(str.indexOf("吴",5));
     }
-}
- +} +```` ### 字符串与byte数组间的相互转换 - -
package com.mpp.string; import java.io.UnsupportedEncodingException; public class StringDemo3 { public static void main(String[] args) throws UnsupportedEncodingException { //字符串和byte数组之间的相互转换
- String str = new String("hhhabc银鞍照白马 飒沓如流星"); //将字符串转换为byte数组,并打印输出
-        byte[] arrs = str.getBytes("GBK"); for(int i=0;i){
+````
+package com.mpp.string; import java.io.UnsupportedEncodingException; 
+public class StringDemo3 { 
+    public static void main(String[] args) throws UnsupportedEncodingException { 
+        
+        //字符串和byte数组之间的相互转换
+        String str = new String("hhhabc银鞍照白马 飒沓如流星"); //将字符串转换为byte数组,并打印输出
+        byte[] arrs = str.getBytes("GBK"); 
+        for(int i=0;i){
             System.out.print(arrs[i]);
-        } //将byte数组转换成字符串
- System.out.println();
+        } 
+        
+        //将byte数组转换成字符串
+        System.out.println();
         String str1 = new String(arrs,"GBK");  //保持字符集的一致,否则会出现乱码
- System.out.println(str1);
+        System.out.println(str1);
     }
-}
- +} +```` ### ==运算符和equals之间的区别: -
引用指向的内容和引用指向的地址
+引用指向的内容和引用指向的地址 -![](https://img2018.cnblogs.com/blog/710412/201902/710412-20190214223341972-1204335921.png) - - - -
package com.mpp.string; public class StringDemo5 { public static void main(String[] args) {
+````
+package com.mpp.string; public class StringDemo5 { 
+    public static void main(String[] args) {
         String str1 = "mpp";
         String str2 = "mpp";
         String str3 = new String("mpp");
@@ -160,9 +169,9 @@ runoob
         System.out.println(str1.equals(str3));   //true  内容相同
         System.out.println(str1==str2);   //true   地址相同
         System.out.println(str1==str3);   //false  地址不同
- }
-}
- + } +} +```` ### 字符串的不可变性 @@ -170,7 +179,7 @@ String的对象一旦被创建,则不能修改,是不可变的 所谓的修改其实是创建了新的对象,所指向的内存空间不变 -![](https://img2018.cnblogs.com/blog/710412/201902/710412-20190214224055939-746946317.png) +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/blog/Java%E6%8A%80%E6%9C%AF%E6%B1%9F%E6%B9%96/%E4%BA%8C%E7%BB%B4%E7%A0%81/710412-20190214224055939-746946317.png) 上图中,s1不再指向imooc所在的内存空间,而是指向了hello,imooc ### String的连接 @@ -218,85 +227,86 @@ String str = "aa"+"bb"+"cc"; ## String类的源码分析 ### String类型的intern - - public void intern () { - //2:string的intern使用 - //s1是基本类型,比较值。s2是string实例,比较实例地址 - //字符串类型用equals方法比较时只会比较值 - String s1 = "a"; - String s2 = new String("a"); - //调用intern时,如果s2中的字符不在常量池,则加入常量池并返回常量的引用 - String s3 = s2.intern(); - System.out.println(s1 == s2); - System.out.println(s1 == s3); - } - +```` +public void intern () { + //2:string的intern使用 + //s1是基本类型,比较值。s2是string实例,比较实例地址 + //字符串类型用equals方法比较时只会比较值 + String s1 = "a"; + String s2 = new String("a"); + //调用intern时,如果s2中的字符不在常量池,则加入常量池并返回常量的引用 + String s3 = s2.intern(); + System.out.println(s1 == s2); + System.out.println(s1 == s3); +} +```` ### String类型的equals - - //字符串的equals方法 - // public boolean equals(Object anObject) { - // if (this == anObject) { - // return true; - // } - // if (anObject instanceof String) { - // String anotherString = (String)anObject; - // int n = value.length; - // if (n == anotherString.value.length) { - // char v1[] = value; - // char v2[] = anotherString.value; - // int i = 0; - // while (n-- != 0) { - // if (v1[i] != v2[i]) - // return false; - // i++; - // } - // return true; - // } - // } - // return false; - // } - +```` +//字符串的equals方法 +// public boolean equals(Object anObject) { +// if (this == anObject) { +// return true; +// } +// if (anObject instanceof String) { +// String anotherString = (String)anObject; +// int n = value.length; +// if (n == anotherString.value.length) { +// char v1[] = value; +// char v2[] = anotherString.value; +// int i = 0; +// while (n-- != 0) { +// if (v1[i] != v2[i]) +// return false; +// i++; +// } +// return true; +// } +// } +// return false; +// } +```` ### StringBuffer和Stringbuilder 底层是继承父类的可变字符数组value +```` +/** + +- The value is used for character storage. + */ + char[] value; + 初始化容量为16 + +/** + +- Constructs a string builder with no characters in it and an +- initial capacity of 16 characters. + */ + public StringBuilder() { + super(16); + } + 这两个类的append方法都是来自父类AbstractStringBuilder的方法 + +public AbstractStringBuilder append(String str) { + if (str == null) + return appendNull(); + int len = str.length(); + ensureCapacityInternal(count + len); + str.getChars(0, len, value, count); + count += len; + return this; +} +@Override +public StringBuilder append(String str) { + super.append(str); + return this; +} - /** - - - The value is used for character storage. - */ - char[] value; - 初始化容量为16 - - /** - - - Constructs a string builder with no characters in it and an - - initial capacity of 16 characters. - */ - public StringBuilder() { - super(16); - } - 这两个类的append方法都是来自父类AbstractStringBuilder的方法 - - public AbstractStringBuilder append(String str) { - if (str == null) - return appendNull(); - int len = str.length(); - ensureCapacityInternal(count + len); - str.getChars(0, len, value, count); - count += len; - return this; - } - @Override - public StringBuilder append(String str) { - super.append(str); - return this; - } - - @Override - public synchronized StringBuffer append(String str) { - toStringCache = null; - super.append(str); - return this; - } +@Override +public synchronized StringBuffer append(String str) { + toStringCache = null; + super.append(str); + return this; +} +```` ### append方法 Stringbuffer在大部分涉及字符串修改的操作上加了synchronized关键字来保证线程安全,效率较低。 @@ -312,19 +322,19 @@ a = a + a;时,实际上先把a封装成stringbuilder,调用append方法后 ensureCapacityInternal(count + len); 该方法是计算append之后的空间是否足够,不足的话需要进行扩容 - - public void ensureCapacity(int minimumCapacity) { - if (minimumCapacity > 0) - ensureCapacityInternal(minimumCapacity); - } - private void ensureCapacityInternal(int minimumCapacity) { - // overflow-conscious code - if (minimumCapacity - value.length > 0) { - value = Arrays.copyOf(value, - newCapacity(minimumCapacity)); - } +```` +public void ensureCapacity(int minimumCapacity) { + if (minimumCapacity > 0) + ensureCapacityInternal(minimumCapacity); +} +private void ensureCapacityInternal(int minimumCapacity) { + // overflow-conscious code + if (minimumCapacity - value.length > 0) { + value = Arrays.copyOf(value, + newCapacity(minimumCapacity)); } - +} +```` 如果新字符串长度大于value数组长度则进行扩容 扩容后的长度一般为原来的两倍 + 2; @@ -334,42 +344,39 @@ ensureCapacityInternal(count + len); 考虑两种情况 如果新的字符串长度超过int最大值,则抛出异常,否则直接使用数组最大长度作为新数组的长度。 - - private int hugeCapacity(int minCapacity) { - if (Integer.MAX_VALUE - minCapacity < 0) { // overflow - throw new OutOfMemoryError(); - } - return (minCapacity > MAX_ARRAY_SIZE) - ? minCapacity : MAX_ARRAY_SIZE; +```` +private int hugeCapacity(int minCapacity) { + if (Integer.MAX_VALUE - minCapacity < 0) { // overflow + throw new OutOfMemoryError(); } - + return (minCapacity > MAX_ARRAY_SIZE) + ? minCapacity : MAX_ARRAY_SIZE; +} +```` ### 删除 这两个类型的删除操作: 都是调用父类的delete方法进行删除 - - public AbstractStringBuilder delete(int start, int end) { - if (start < 0) - throw new StringIndexOutOfBoundsException(start); - if (end > count) - end = count; - if (start > end) - throw new StringIndexOutOfBoundsException(); - int len = end - start; - if (len > 0) { - System.arraycopy(value, start+len, value, start, count-end); - count -= len; - } - return this; - } - +```` +public AbstractStringBuilder delete(int start, int end) { + if (start < 0) + throw new StringIndexOutOfBoundsException(start); + if (end > count) + end = count; + if (start > end) + throw new StringIndexOutOfBoundsException(); + int len = end - start; + if (len > 0) { + System.arraycopy(value, start+len, value, start, count-end); + count -= len; + } + return this; +} +```` 事实上是将剩余的字符重新拷贝到字符数组value。 这里用到了system.arraycopy来拷贝数组,速度是比较快的 - - - ### system.arraycopy方法 转自知乎: @@ -386,37 +393,26 @@ ensureCapacityInternal(count + len); ## String和JVM的关系 - - - 下面我们了解下Java栈、Java堆、方法区和常量池: - - Java栈(线程私有数据区): ``` 每个Java虚拟机线程都有自己的Java虚拟机栈,Java虚拟机栈用来存放栈帧,每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 ``` - - Java堆(线程共享数据区): ``` 在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配。 ``` - - 方法区(线程共享数据区): ``` 方法区在虚拟机启动的时候被创建,它存储了每一个类的结构信息,例如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括在类、实例、接口初始化时用到的特殊方法。在JDK8之前永久代是方法区的一种实现,而JDK8元空间替代了永久代,永久代被移除,也可以理解为元空间是方法区的一种实现。 ``` - - 常量池(线程共享数据区): ``` @@ -437,23 +433,18 @@ Java堆(线程共享数据区): 使用字符串常量池,每当我们使用字面量(String s=”1”;)创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就将此字符串对象的地址赋值给引用s(引用s在Java栈中)。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,并将此字符串对象的地址赋值给引用s(引用s在Java栈中)。 ``` - - ``` 使用字符串常量池,每当我们使用关键字new(String s=new String(”1”);)创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么不再在字符串常量池创建该字符串对象,而直接堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s,如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,然后在堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s。 ``` - - - ## String为什么不可变? 翻开JDK源码,java.lang.String类起手前三行,是这样写的: - - public final class String implements java.io.Serializable, Comparable, CharSequence { - /** String本质是个char数组. 而且用final关键字修饰.*/ - private final char value[]; ... ... - } - +```` +public final class String implements java.io.Serializable, Comparable, CharSequence { + /** String本质是个char数组. 而且用final关键字修饰.*/ +private final char value[]; ... ... + } +```` 首先String类是用final关键字修饰,这说明String不可继承。再看下面,String类的主力成员字段value是个char[]数组,而且是用final修饰的。 final修饰的字段创建以后就不可改变。 有的人以为故事就这样完了,其实没有。因为虽然value是不可变,也只是value这个引用地址不可变。挡不住Array数组是可变的事实。 @@ -463,16 +454,16 @@ Array的数据结构看下图。 也就是说Array变量只是stack上的一个引用,数组的本体结构在heap堆。 String类里的value用final修饰,只是说stack里的这个叫value的引用地址不可变。没有说堆里array本身数据不可变。看下面这个例子, - - final int[] value={1,2,3} ; - int[] another={4,5,6}; - value=another; //编译器报错,final不可变 value用final修饰,编译器不允许我把value指向堆区另一个地址。 - 但如果我直接对数组元素动手,分分钟搞定。 - - final int[] value={1,2,3}; - value[2]=100; //这时候数组里已经是{1,2,100} 所以String是不可变,关键是因为SUN公司的工程师。 - 在后面所有String的方法里很小心的没有去动Array里的元素,没有暴露内部成员字段。private final char value[]这一句里,private的私有访问权限的作用都比final大。而且设计师还很小心地把整个String设成final禁止继承,避免被其他人继承后破坏。所以String是不可变的关键都在底层的实现,而不是一个final。考验的是工程师构造数据类型,封装数据的功力。 - +```` +final int[] value={1,2,3} ; +int[] another={4,5,6}; + value=another; //编译器报错,final不可变 value用final修饰,编译器不允许我把value指向堆区另一个地址。 +但如果我直接对数组元素动手,分分钟搞定。 + + final int[] value={1,2,3}; + value[2]=100; //这时候数组里已经是{1,2,100} 所以String是不可变,关键是因为SUN公司的工程师。 + 在后面所有String的方法里很小心的没有去动Array里的元素,没有暴露内部成员字段。private final char value[]这一句里,private的私有访问权限的作用都比final大。而且设计师还很小心地把整个String设成final禁止继承,避免被其他人继承后破坏。所以String是不可变的关键都在底层的实现,而不是一个final。考验的是工程师构造数据类型,封装数据的功力。 +```` ### 不可变有什么好处? 这个最简单地原因,就是为了安全。看下面这个场景(有评论反应例子不够清楚,现在完整地写出来),一个函数appendStr( )在不可变的String参数后面加上一段“bbb”后返回。appendSb( )负责在可变的StringBuilder后面加“bbb”。 @@ -485,28 +476,28 @@ String类里的value用final修饰,只是说stack里的这个叫value的引用 > 3 final修饰的char数组保证了char数组的引用不可变。但是可以通过char[0] = 'a’来修改值。不过String内部并不提供方法来完成这一操作,所以String的不可变也是基于代码封装和访问控制的。 举个例子 +```` +final class Fi { + int a; + final int b = 0; + Integer s; - final class Fi { - int a; - final int b = 0; - Integer s; - - } - final char[]a = {'a'}; - final int[]b = {1}; - @Test - public void final修饰类() { - //引用没有被final修饰,所以是可变的。 - //final只修饰了Fi类型,即Fi实例化的对象在堆中内存地址是不可变的。 - //虽然内存地址不可变,但是可以对内部的数据做改变。 - Fi f = new Fi(); - f.a = 1; - System.out.println(f); - f.a = 2; - System.out.println(f); - //改变实例中的值并不改变内存地址。 - -``` +} +final char[]a = {'a'}; +final int[]b = {1}; +@Test +public void final修饰类() { + //引用没有被final修饰,所以是可变的。 + //final只修饰了Fi类型,即Fi实例化的对象在堆中内存地址是不可变的。 + //虽然内存地址不可变,但是可以对内部的数据做改变。 + Fi f = new Fi(); + f.a = 1; + System.out.println(f); + f.a = 2; + System.out.println(f); + //改变实例中的值并不改变内存地址。 +```` +```` Fi ff = f; //让引用指向新的Fi对象,原来的f对象由新的引用ff持有。 //引用的指向改变也不会改变原来对象的地址 @@ -515,7 +506,7 @@ System.out.println(f); System.out.println(ff); } -``` +```` 这里的对f.a的修改可以理解为char[0] = 'a'这样的操作。只改变数据值,不改变内存值。 @@ -523,279 +514,283 @@ System.out.println(ff); 问题描述 很多时候我们需要对字符串进行很多固定的操作,而这些操作在JDK/JRE中又没有预置,于是我们想到了apache-commons组件,但是它也不能完全覆盖我们的业务需求,所以很多时候还是要自己写点代码的,下面就是基于apache-commons组件写的部分常用方法: - MAVEN依赖 + +```` org.apache.commons commons-lang3 ${commons-lang3.version} +```` 代码成果 - public class StringUtils extends org.apache.commons.lang3.StringUtils { - - /** 值为"NULL"的字符串 */ - private static final String NULL_STRING = "NULL"; - - private static final char SEPARATOR = '_'; - - - /** - * 满足一下情况返回true
- * ①.入参为空 - * ②.入参为空字符串 - * ③.入参为"null"字符串 - * - * @param string 需要判断的字符型 - * @return boolean - */ - public static boolean isNullOrEmptyOrNULLString(String string) { - return isBlank(string) || NULL_STRING.equalsIgnoreCase(string); - } - - /** - * 把字符串转为二进制码
- * 本方法不会返回null - * - * @param str 需要转换的字符串 - * @return 二进制字节码数组 - */ - public static byte[] toBytes(String str) { - return isBlank(str) ? new byte[]{} : str.getBytes(); - } - - /** - * 把字符串转为二进制码
- * 本方法不会返回null - * - * @param str 需要转换的字符串 - * @param charset 编码类型 - * @return 二进制字节码数组 - * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现 - */ - public static byte[] toBytes(String str, Charset charset) throws UnsupportedEncodingException { - return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName()); - } - - /** - * 把字符串转为二进制码
- * 本方法不会返回null - * - * @param str 需要转换的字符串 - * @param charset 编码类型 - * @param locale 编码类型对应的地区 - * @return 二进制字节码数组 - * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现 - */ - public static byte[] toBytes(String str, Charset charset, Locale locale) throws UnsupportedEncodingException { - return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName(locale)); - } - - /** - * 二进制码转字符串
- * 本方法不会返回null - * - * @param bytes 二进制码 - * @return 字符串 - */ - public static String bytesToString(byte[] bytes) { - return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes); - } - - /** - * 二进制码转字符串
- * 本方法不会返回null - * - * @param bytes 二进制码 - * @param charset 编码集 - * @return 字符串 - * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码 - */ - public static String byteToString(byte[] bytes, Charset charset) throws UnsupportedEncodingException { - return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName()); - } - - /** - * 二进制码转字符串
- * 本方法不会返回null - * - * @param bytes 二进制码 - * @param charset 编码集 - * @param locale 本地化 - * @return 字符串 - * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码 - */ - public static String byteToString(byte[] bytes, Charset charset, Locale locale) throws UnsupportedEncodingException { - return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName(locale)); - } - - /** - * 把对象转为字符串 - * - * @param object 需要转化的字符串 - * @return 字符串, 可能为空 - */ - public static String parseString(Object object) { - if (object == null) { - return null; - } - if (object instanceof byte[]) { - return bytesToString((byte[]) object); - } - return object.toString(); - } - - /** - * 把字符串转为int类型 - * - * @param str 需要转化的字符串 - * @return int - * @throws NumberFormatException 字符串格式不正确时抛出 - */ - public static int parseInt(String str) throws NumberFormatException { - return isBlank(str) ? 0 : Integer.parseInt(str); - } - - /** - * 把字符串转为double类型 - * - * @param str 需要转化的字符串 - * @return double - * @throws NumberFormatException 字符串格式不正确时抛出 - */ - public static double parseDouble(String str) throws NumberFormatException { - return isBlank(str) ? 0D : Double.parseDouble(str); - } - - /** - * 把字符串转为long类型 - * - * @param str 需要转化的字符串 - * @return long - * @throws NumberFormatException 字符串格式不正确时抛出 - */ - public static long parseLong(String str) throws NumberFormatException { - return isBlank(str) ? 0L : Long.parseLong(str); +```` +public class StringUtils extends org.apache.commons.lang3.StringUtils { + +/** 值为"NULL"的字符串 */ +private static final String NULL_STRING = "NULL"; + +private static final char SEPARATOR = '_'; + + +/** + * 满足一下情况返回true
+ * ①.入参为空 + * ②.入参为空字符串 + * ③.入参为"null"字符串 + * + * @param string 需要判断的字符型 + * @return boolean + */ +public static boolean isNullOrEmptyOrNULLString(String string) { + return isBlank(string) || NULL_STRING.equalsIgnoreCase(string); +} + +/** + * 把字符串转为二进制码
+ * 本方法不会返回null + * + * @param str 需要转换的字符串 + * @return 二进制字节码数组 + */ +public static byte[] toBytes(String str) { + return isBlank(str) ? new byte[]{} : str.getBytes(); +} + +/** + * 把字符串转为二进制码
+ * 本方法不会返回null + * + * @param str 需要转换的字符串 + * @param charset 编码类型 + * @return 二进制字节码数组 + * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现 + */ +public static byte[] toBytes(String str, Charset charset) throws UnsupportedEncodingException { + return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName()); +} + +/** + * 把字符串转为二进制码
+ * 本方法不会返回null + * + * @param str 需要转换的字符串 + * @param charset 编码类型 + * @param locale 编码类型对应的地区 + * @return 二进制字节码数组 + * @throws UnsupportedEncodingException 字符串转换的时候编码不支持时出现 + */ +public static byte[] toBytes(String str, Charset charset, Locale locale) throws UnsupportedEncodingException { + return isBlank(str) ? new byte[]{} : str.getBytes(charset.displayName(locale)); +} + +/** + * 二进制码转字符串
+ * 本方法不会返回null + * + * @param bytes 二进制码 + * @return 字符串 + */ +public static String bytesToString(byte[] bytes) { + return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes); +} + +/** + * 二进制码转字符串
+ * 本方法不会返回null + * + * @param bytes 二进制码 + * @param charset 编码集 + * @return 字符串 + * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码 + */ +public static String byteToString(byte[] bytes, Charset charset) throws UnsupportedEncodingException { + return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName()); +} + +/** + * 二进制码转字符串
+ * 本方法不会返回null + * + * @param bytes 二进制码 + * @param charset 编码集 + * @param locale 本地化 + * @return 字符串 + * @throws UnsupportedEncodingException 当前二进制码可能不支持传入的编码 + */ +public static String byteToString(byte[] bytes, Charset charset, Locale locale) throws UnsupportedEncodingException { + return bytes == null || bytes.length == 0 ? EMPTY : new String(bytes, charset.displayName(locale)); +} + +/** + * 把对象转为字符串 + * + * @param object 需要转化的字符串 + * @return 字符串, 可能为空 + */ +public static String parseString(Object object) { + if (object == null) { + return null; } - - /** - * 把字符串转为float类型 - * - * @param str 需要转化的字符串 - * @return float - * @throws NumberFormatException 字符串格式不正确时抛出 - */ - public static float parseFloat(String str) throws NumberFormatException { - return isBlank(str) ? 0L : Float.parseFloat(str); + if (object instanceof byte[]) { + return bytesToString((byte[]) object); } - - /** - * 获取i18n字符串 - * - * @param code - * @param args - * @return - */ - public static String getI18NMessage(String code, Object[] args) { - //LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class); - //HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); - //Locale locale = localLocaleResolver.resolveLocale(request); - //return SpringContextHolder.getApplicationContext().getMessage(code, args, locale); + return object.toString(); +} + +/** + * 把字符串转为int类型 + * + * @param str 需要转化的字符串 + * @return int + * @throws NumberFormatException 字符串格式不正确时抛出 + */ +public static int parseInt(String str) throws NumberFormatException { + return isBlank(str) ? 0 : Integer.parseInt(str); +} + +/** + * 把字符串转为double类型 + * + * @param str 需要转化的字符串 + * @return double + * @throws NumberFormatException 字符串格式不正确时抛出 + */ +public static double parseDouble(String str) throws NumberFormatException { + return isBlank(str) ? 0D : Double.parseDouble(str); +} + +/** + * 把字符串转为long类型 + * + * @param str 需要转化的字符串 + * @return long + * @throws NumberFormatException 字符串格式不正确时抛出 + */ +public static long parseLong(String str) throws NumberFormatException { + return isBlank(str) ? 0L : Long.parseLong(str); +} + +/** + * 把字符串转为float类型 + * + * @param str 需要转化的字符串 + * @return float + * @throws NumberFormatException 字符串格式不正确时抛出 + */ +public static float parseFloat(String str) throws NumberFormatException { + return isBlank(str) ? 0L : Float.parseFloat(str); +} + +/** + * 获取i18n字符串 + * + * @param code + * @param args + * @return + */ +public static String getI18NMessage(String code, Object[] args) { + //LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class); + //HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); + //Locale locale = localLocaleResolver.resolveLocale(request); + //return SpringContextHolder.getApplicationContext().getMessage(code, args, locale); + return ""; +} + +/** + * 获得用户远程地址 + * + * @param request 请求头 + * @return 用户ip + */ +public static String getRemoteAddr(HttpServletRequest request) { + String remoteAddr = request.getHeader("X-Real-IP"); + if (isNotBlank(remoteAddr)) { + remoteAddr = request.getHeader("X-Forwarded-For"); + } else if (isNotBlank(remoteAddr)) { + remoteAddr = request.getHeader("Proxy-Client-IP"); + } else if (isNotBlank(remoteAddr)) { + remoteAddr = request.getHeader("WL-Proxy-Client-IP"); + } + return remoteAddr != null ? remoteAddr : request.getRemoteAddr(); +} + +/** + * 驼峰命名法工具 + * + * @return toCamelCase(" hello_world ") == "helloWorld" + * toCapitalizeCamelCase("hello_world") == "HelloWorld" + * toUnderScoreCase("helloWorld") = "hello_world" + */ +public static String toCamelCase(String s, Locale locale, char split) { + if (isBlank(s)) { return ""; } - - /** - * 获得用户远程地址 - * - * @param request 请求头 - * @return 用户ip - */ - public static String getRemoteAddr(HttpServletRequest request) { - String remoteAddr = request.getHeader("X-Real-IP"); - if (isNotBlank(remoteAddr)) { - remoteAddr = request.getHeader("X-Forwarded-For"); - } else if (isNotBlank(remoteAddr)) { - remoteAddr = request.getHeader("Proxy-Client-IP"); - } else if (isNotBlank(remoteAddr)) { - remoteAddr = request.getHeader("WL-Proxy-Client-IP"); - } - return remoteAddr != null ? remoteAddr : request.getRemoteAddr(); - } - - /** - * 驼峰命名法工具 - * - * @return toCamelCase(" hello_world ") == "helloWorld" - * toCapitalizeCamelCase("hello_world") == "HelloWorld" - * toUnderScoreCase("helloWorld") = "hello_world" - */ - public static String toCamelCase(String s, Locale locale, char split) { - if (isBlank(s)) { - return ""; - } - - s = s.toLowerCase(locale); - - StringBuilder sb = new StringBuilder(); - for (char c : s.toCharArray()) { - sb.append(c == split ? Character.toUpperCase(c) : c); - } - - return sb.toString(); - } - - public static String toCamelCase(String s) { - return toCamelCase(s, Locale.getDefault(), SEPARATOR); - } - - public static String toCamelCase(String s, Locale locale) { - return toCamelCase(s, locale, SEPARATOR); - } - - public static String toCamelCase(String s, char split) { - return toCamelCase(s, Locale.getDefault(), split); - } - - public static String toUnderScoreCase(String s, char split) { - if (isBlank(s)) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - boolean nextUpperCase = (i < (s.length() - 1)) && Character.isUpperCase(s.charAt(i + 1)); - boolean upperCase = (i > 0) && Character.isUpperCase(c); - sb.append((!upperCase || !nextUpperCase) ? split : "").append(Character.toLowerCase(c)); - } - - return sb.toString(); + + s = s.toLowerCase(locale); + + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + sb.append(c == split ? Character.toUpperCase(c) : c); } - - public static String toUnderScoreCase(String s) { - return toUnderScoreCase(s, SEPARATOR); + + return sb.toString(); +} + +public static String toCamelCase(String s) { + return toCamelCase(s, Locale.getDefault(), SEPARATOR); +} + +public static String toCamelCase(String s, Locale locale) { + return toCamelCase(s, locale, SEPARATOR); +} + +public static String toCamelCase(String s, char split) { + return toCamelCase(s, Locale.getDefault(), split); +} + +public static String toUnderScoreCase(String s, char split) { + if (isBlank(s)) { + return ""; } - - /** - * 把字符串转换为JS获取对象值的三目运算表达式 - * - * @param objectString 对象串 - * 例如:入参:row.user.id/返回:!row?'':!row.user?'':!row.user.id?'':row.user.id - */ - public static String toJsGetValueExpression(String objectString) { - StringBuilder result = new StringBuilder(); - StringBuilder val = new StringBuilder(); - String[] fileds = split(objectString, "."); - for (int i = 0; i < fileds.length; i++) { - val.append("." + fileds[i]); - result.append("!" + (val.substring(1)) + "?'':"); - } - result.append(val.substring(1)); - return result.toString(); + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + boolean nextUpperCase = (i < (s.length() - 1)) && Character.isUpperCase(s.charAt(i + 1)); + boolean upperCase = (i > 0) && Character.isUpperCase(c); + sb.append((!upperCase || !nextUpperCase) ? split : "").append(Character.toLowerCase(c)); } + return sb.toString(); +} - } +public static String toUnderScoreCase(String s) { + return toUnderScoreCase(s, SEPARATOR); +} + +/** + * 把字符串转换为JS获取对象值的三目运算表达式 + * + * @param objectString 对象串 + * 例如:入参:row.user.id/返回:!row?'':!row.user?'':!row.user.id?'':row.user.id + */ +public static String toJsGetValueExpression(String objectString) { + StringBuilder result = new StringBuilder(); + StringBuilder val = new StringBuilder(); + String[] fileds = split(objectString, "."); + for (int i = 0; i < fileds.length; i++) { + val.append("." + fileds[i]); + result.append("!" + (val.substring(1)) + "?'':"); + } + result.append(val.substring(1)); + return result.toString(); +} + + +} +```` ## 参考文章 https://blog.csdn.net/qq_34490018/article/details/82110578 diff --git "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" index ff1118c..5609da9 100644 --- "a/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" +++ "b/docs/java/basic/4\343\200\201final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" @@ -184,7 +184,7 @@ final方法的好处: 2. final变量在多线程中并发安全,无需额外的同步开销 3. final方法是静态编译的,提高了调用速度 4. **final类创建的对象是只可读的,在多线程可以安全共享** -5. + ## final关键字的最佳实践 ### final的用法 @@ -198,7 +198,7 @@ final修饰的变量有三种:静态变量、实例变量和局部变量,分  另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。   但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。 - +```` public class FinalTest { final int p; final int q=3; @@ -210,19 +210,20 @@ final修饰的变量有三种:静态变量、实例变量和局部变量,分 q=i;//不能为一个final变量赋值 } } - +```` ### final内存分配 刚提到了内嵌机制,现在详细展开。 要知道调用一个函数除了函数本身的执行时间之外,还需要额外的时间去寻找这个函数(类内部有一个函数签名和函数地址的映射表)。所以减少函数调用次数就等于降低了性能消耗。 final修饰的函数会被编译器优化,优化的结果是减少了函数调用的次数。如何实现的,举个例子给你看: - +```` public class Test{ final void func(){System.out.println("g");}; public void main(String[] args){ for(int j=0;j<1000;j++) func(); }} + 经过编译器优化之后,这个类变成了相当于这样写: public class Test{ final void func(){System.out.println("g");}; @@ -230,7 +231,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 for(int j=0;j<1000;j++) {System.out.println("g");} }} - +```` 看出来区别了吧?编译器直接将func的函数体内嵌到了调用函数的地方,这样的结果是节省了1000次函数调用,当然编译器处理成字节码,只是我们可以想象成这样,看个明白。 不过,当函数体太长的话,用final可能适得其反,因为经过编译器内嵌之后代码长度大大增加,于是就增加了jvm解释字节码的时间。 @@ -243,7 +244,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 见下面的测试代码,我会执行五次: - +```` public class Test { public static void getJava() @@ -283,6 +284,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 } } +```` 结果为: 第一次: @@ -308,13 +310,13 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 由以上运行结果不难看出,执行最快的是“正常的执行”即代码直接编写,而使用final修饰的方法,不像有些书上或者文章上所说的那样,速度与效率与“正常的执行”无异,而是位于第二位,最差的是调用不加final修饰的方法。 -观点:加了比不加好一点。 + 观点:加了比不加好一点。 ### 使用final修饰变量会让变量的值不能被改变吗; 见代码: - +```` public class Final { public static void main(String[] args) @@ -335,18 +337,18 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 red blue yellow white 看!,黑色变成了白色。 - -​ -​ 在使用findbugs插件时,就会提示public static String[] color = { "red", "blue", "yellow", "black" };这行代码不安全,但加上final修饰,这行代码仍然是不安全的,因为final没有做到保证变量的值不会被修改! -​ -​ 原因是:final关键字只能保证变量本身不能被赋与新值,而不能保证变量的内部结构不被修改。例如在main方法有如下代码Color.color = new String[]{""};就会报错了。 +```` + + 在使用findbugs插件时,就会提示public static String[] color = { "red", "blue", "yellow", "black" };这行代码不安全,但加上final修饰,这行代码仍然是不安全的,因为final没有做到保证变量的值不会被修改! + + 原因是:final关键字只能保证变量本身不能被赋与新值,而不能保证变量的内部结构不被修改。例如在main方法有如下代码Color.color = new String[]{""};就会报错了。 ### 如何保证数组内部不被修改 那可能有的同学就会问了,加上final关键字不能保证数组不会被外部修改,那有什么方法能够保证呢?答案就是降低访问级别,把数组设为private。这样的话,就解决了数组在外部被修改的不安全性,但也产生了另一个问题,那就是这个数组要被外部使用的。 解决这个问题见代码: - +```` import java.util.AbstractList; import java.util.List; @@ -384,7 +386,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 } - +```` 这样就OK了,既保证了代码安全,又能让数组中的元素被访问了。 @@ -397,7 +399,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 规则3:父类中private final方法,子类可以重新定义,这种情况不是重写。 代码示例 - +```` 规则1代码 public class FinalMethodTest @@ -429,7 +431,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 // 下面方法定义将不会出现问题 public void test(){} } - +```` ## final 和 jvm的关系 @@ -439,8 +441,8 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 2. 初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序。 下面,我们通过一些示例性的代码来分别说明这两个规则: - -
public class FinalExample {
+````
+public class FinalExample {
     int i;                            // 普通变量 
     final int j;                      //final 变量 
     static FinalExample obj;
@@ -460,7 +462,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调
         int b = object.j;                // 读 final 域 
     }
 }
-
+```` 这里假设一个线程 A 执行 writer () 方法,随后另一个线程 B 执行 reader () 方法。下面我们通过这两个线程的交互来说明这两个规则。 @@ -478,7 +480,7 @@ final修饰的函数会被编译器优化,优化的结果是减少了函数调 假设线程 B 读对象引用与读对象的成员域之间没有重排序(马上会说明为什么需要这个假设),下图是一种可能的执行时序: -![](https://static001.infoq.cn/resource/image/66/3a/6628576a54f0ba625c8c3af4586cef3a.jpg) +![img](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/6628576a54f0ba625c8c3af4586cef3a.jpg) 在上图中,写普通域的操作被编译器重排序到了构造函数之外,读线程 B 错误的读取了普通变量 i 初始化之前的值。而写 final 域的操作,被写 final 域的重排序规则“限定”在了构造函数之内,读线程 B 正确的读取了 final 变量初始化之后的值。 @@ -511,8 +513,8 @@ reader() 方法包含三个操作: 上面我们看到的 final 域是基础数据类型,下面让我们看看如果 final 域是引用类型,将会有什么效果? 请看下列示例代码: - -
public class FinalReferenceExample {
+````
+public class FinalReferenceExample {
 final int[] intArray;                     //final 是引用类型 
 static FinalReferenceExample obj;
 
@@ -535,7 +537,7 @@ public static void reader () {              // 读线程 C 执行
     }
 }
 }
-
+```` 这里 final 域为一个引用类型,它引用一个 int 型的数组对象。对于引用类型,写 final 域的重排序规则对编译器和处理器增加了如下约束: @@ -543,14 +545,14 @@ public static void reader () { // 读线程 C 执行 对上面的示例程序,我们假设首先线程 A 执行 writerOne() 方法,执行完后线程 B 执行 writerTwo() 方法,执行完后线程 C 执行 reader () 方法。下面是一种可能的线程执行时序: -![](https://static001.infoq.cn/resource/image/29/db/29b097c36fd531028991826bb7c835db.png) - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/29b097c36fd531028991826bb7c835db.png) 在上图中,1 是对 final 域的写入,2 是对这个 final 域引用的对象的成员域的写入,3 是把被构造的对象的引用赋值给某个引用变量。这里除了前面提到的 1 不能和 3 重排序外,2 和 3 也不能重排序。 JMM 可以确保读线程 C 至少能看到写线程 A 在构造函数中对 final 引用对象的成员域的写入。即 C 至少能看到数组下标 0 的值为 1。而写线程 B 对数组元素的写入,读线程 C 可能看的到,也可能看不到。JMM 不保证线程 B 的写入对读线程 C 可见,因为写线程 B 和读线程 C 之间存在数据竞争,此时的执行结果不可预知。 如果想要确保读线程 C 看到写线程 B 对数组元素的写入,写线程 B 和读线程 C 之间需要使用同步原语(lock 或 volatile)来确保内存可见性。 + ## 参考文章 https://www.infoq.cn/article/java-memory-model-6 diff --git "a/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" "b/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" index 4084792..89dda2c 100644 --- "a/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" +++ "b/docs/java/basic/5\343\200\201Java\347\261\273\345\222\214\345\214\205.md" @@ -1,28 +1,24 @@ # 目录 - * [Java中的包概念](#java中的包概念) +* [Java中的包概念](#java中的包概念) * [包的作用](#包的作用) * [package 的目录结构](#package-的目录结构) * [设置 CLASSPATH 系统变量](#设置-classpath-系统变量) - * [常用jar包](#常用jar包) +* [常用jar包](#常用jar包) * [java软件包的类型](#java软件包的类型) * [dt.jar](#dtjar) * [rt.jar](#rtjar) - * [*.java文件的奥秘](#java文件的奥秘) +* [*.java文件的奥秘](#java文件的奥秘) * [*.Java文件简介](#java文件简介) * [为什么一个java源文件中只能有一个public类?](#为什么一个java源文件中只能有一个public类?) * [Main方法](#main方法) * [外部类的访问权限](#外部类的访问权限) * [Java包的命名规则](#java包的命名规则) - * [参考文章](#参考文章) - * [微信公众号](#微信公众号) +* [参考文章](#参考文章) +* [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- - - Java类 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -74,11 +70,7 @@ Java 使用包(package)这种机制是为了防止命名冲突,访问控 package net.java.util; public class Something{ ... } - - - - -那么它的路径应该是 **net/java/util/Something.java** 这样保存的。 package(包) 的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用。 +那么它的路径应该是**net/java/util/Something.java**这样保存的。 package(包) 的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用。 一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。 @@ -91,8 +83,6 @@ Java 使用包(package)这种机制是为了防止命名冲突,访问控 由于包创建了新的命名空间(namespace),所以不会跟其他包中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单。 - - ### package 的目录结构 类放在包中会有两种主要的结果: @@ -104,28 +94,18 @@ Java 使用包(package)这种机制是为了防止命名冲突,访问控 将类、接口等类型的源码放在一个文本中,这个文件的名字就是这个类型的名字,并以.java作为扩展名。例如: - - - - -// 文件名 : Car.java package vehicle; public class Car { // 类实现 } - - - - +```` +// 文件名 : Car.java +package vehicle; +public class Car { +// 类实现 +} +```` 接下来,把源文件放在一个目录中,这个目录要对应类所在包的名字。 - - - - ....\vehicle\Car.java - - - - 现在,正确的类名和路径将会是如下样子: * 类名 -> vehicle.Car @@ -134,51 +114,49 @@ Java 使用包(package)这种机制是为了防止命名冲突,访问控 通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录。 -例如:有一个 **com.runoob.test** 的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录: - - - - +例如:有一个**com.runoob.test**的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录: ....\com\runoob\test\Runoob.java - - - - 编译的时候,编译器为包中定义的每个类、接口等类型各创建一个不同的输出文件,输出文件的名字就是这个类型的名字,并加上 .class 作为扩展后缀。 例如: - - - - - -// 文件名: Runoob.java package com.runoob.test; public class Runoob { } class Google { } - - - +```` +// 文件名: Runoob.java +package com.runoob.test; +public class Runoob { } +class Google { } +```` 现在,我们用-d选项来编译这个文件,如下: - -
$javac -d .  Runoob.java
- +```` + $javac -d . Runoob.java +```` 这样会像下面这样放置编译了的文件: -
.\com\runoob\test\Runoob.class  .\com\runoob\test\Google.class
- -你可以像下面这样来导入所有** \com\runoob\test\ **中定义的类、接口等: +```` + .\com\runoob\test\Runoob.class + .\com\runoob\test\Google.class +```` -
import com.runoob.test.*;
+你可以像下面这样来导入所有**\com\runoob\test\**中定义的类、接口等: +```` + import com.runoob.test.*; +```` 编译之后的 .class 文件应该和 .java 源文件一样,它们放置的目录应该跟包的名字对应起来。但是,并不要求 .class 文件的路径跟相应的 .java 的路径一样。你可以分开来安排源码和类的目录。 -
\sources\com\runoob\test\Runoob.java \classes\com\runoob\test\Google.class
+```` + \sources\com\runoob\test\Runoob.java + \classes\com\runoob\test\Google.class +```` 这样,你可以将你的类目录分享给其他的编程人员,而不用透露自己的源码。用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型。 -类目录的绝对路径叫做 **class path**。设置在系统变量 **CLASSPATH** 中。编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径。 +类目录的绝对路径叫做**class path**。设置在系统变量**CLASSPATH**中。编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径。 -\classes 是 class path,package 名字是 com.runoob.test,而编译器和 JVM 会在 \classes\com\runoob\test 中找 .class 文件。 +```` + \classes 是 class path,package 名字是 com.runoob.test,而编译器和 JVM 会在 \classes\com\runoob\test 中找 .class 文件。 +```` 一个 class path 可能会包含好几个路径,多路径应该用分隔符分开。默认情况下,编译器和 JVM 查找当前目录。JAR 文件按包含 Java 平台相关的类,所以他们的目录默认放在了 class path 中。 @@ -222,55 +200,54 @@ java包的作用是为了区别类名的命名空间   在 animals 包中加入一个接口(interface): - package animals; - - interface Animal { - public void eat(); - public void travel(); - } -  接下来,在同一个包中加入该接口的实现: - - package animals; - - /* 文件名 : MammalInt.java */ - public class MammalInt implements Animal{ - - public void eat(){ - System.out.println("Mammal eats"); - } - - public void travel(){ - System.out.println("Mammal travels"); - } - - public int noOfLegs(){ - return 0; - } - - public static void main(String args[]){ - MammalInt m = new MammalInt(); - m.eat(); - m.travel(); - } - } - +```` +package animals; +interface Animal { + public void eat(); + public void travel(); +} +```` + +接下来,在同一个包中加入该接口的实现: + +```` +package animals; +/* 文件名 : MammalInt.java */ +public class MammalInt implements Animal{ + public void eat(){ + System.out.println("Mammal eats"); + } + public void travel(){ + System.out.println("Mammal travels"); + } + public int noOfLegs(){ + return 0; + } + public static void main(String args[]){ + MammalInt m = new MammalInt(); + m.eat(); + m.travel(); + } +} +```` import 关键字 为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用 "import" 语句可完成此功能。 在 java 源文件中 import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条,其语法格式为: -1 -import package1[.package2…].(classname|*); -  如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。 +```` + import package1[.package2…].(classname|*); +```` + +如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。 通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录。 例如:有一个 com.runoob.test 的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录: - -1 -....\com\runoob\test\Runoob.java - +``` + ....\com\runoob\test\Runoob.java +``` ## 常用jar包 ### java软件包的类型 @@ -291,36 +268,30 @@ import package1[.package2…].(classname|*); 6) java.net:包含支持网络操作的类。 ### dt.jar -> SUN对于dt.jar的定义:Also includes dt.jar, the DesignTime archive of BeanInfo files that tell interactive development environments (IDE's) how to display the Java components and how to let the developer customize them for the application。 -中文翻译过来就是:dt.jar是BeanInfo文件的DesignTime归档,BeanInfo文件用来告诉集成开发环境(IDE)如何显示Java组件还有如何让开发人员根据应用程序自定义它们。这段文字中提到了几个关键字:DesignTime,BeanInfo,IDE,Java components。其实dt.jar就是DesignTime Archive的缩写。那么何为DesignTime。 - -    何为DesignTime?翻译过来就是设计时。其实了解JavaBean的人都知道design time和runtime(运行时)这两个术语的含义。设计时(DesignTIme)是指在开发环境中通过添加控件,设置控件或窗体属性等方法,建立应用程序的时间。 -    -    与此相对应的运行时(RunTIme)是指可以象用户那样与应用程序交互作用的时间。那么现在再理解一下上面的翻译,其实dt.jar包含了swing控件中的BeanInfo,而IDE的GUI Designer需要这些信息。那让我们看一下dt.jar中到底有什么?下面是一张dt.jar下面的内容截图: +> SUN对于dt.jar的定义:Also includesdt.jar, the DesignTime archive of BeanInfo files that tell interactive development environments (IDE's) how to display the Java components and how to let the developer customize them for the application。 -![image](http://www.blogjava.net/images/blogjava_net/landon/dt-jar.jpg) +中文翻译过来就是:dt.jar是BeanInfo文件的DesignTime归档,BeanInfo文件用来告诉集成开发环境(IDE)如何显示Java组件还有如何让开发人员根据应用程序自定义它们。这段文字中提到了几个关键字:DesignTime,BeanInfo,IDE,Java components。其实dt.jar就是DesignTime Archive的缩写。那么何为DesignTime。 -    从上面的截图可以看出,dt.jar中全部是Swing组件的BeanInfo。那么到底什么是BeanInfo呢? +何为DesignTime?翻译过来就是设计时。其实了解JavaBean的人都知道design time和runtime(运行时)这两个术语的含义。设计时(DesignTIme)是指在开发环境中通过添加控件,设置控件或窗体属性等方法,建立应用程序的时间。 -    何为BeanInfo?JavaBean和BeanInfo有很大的关系。Sun所制定的JavaBean规范,很大程度上是为IDE准备的——它让IDE能够以可视化的方式设置JavaBean的属性。如果在IDE中开发一个可视化应用程序,我们需要通过属性设置的方式对组成应用的各种组件进行定制,IDE通过属性编辑器让开发人员使用可视化的方式设置组件的属性。 +与此相对应的运行时(RunTIme)是指可以象用户那样与应用程序交互作用的时间。那么现在再理解一下上面的翻译,其实dt.jar包含了swing控件中的BeanInfo,而IDE的GUI Designer需要这些信息。那让我们看一下dt.jar中到底有什么? -    一般的IDE都支持JavaBean规范所定义的属性编辑器,当组件开发商发布一个组件时,它往往将组件对应的属性编辑器捆绑发行,这样开发者就可以在IDE环境下方便地利用属性编辑器对组件进行定制工作。JavaBean规范通过java.beans.PropertyEditor定义了设置JavaBean属性的方法,通过BeanInfo描述了JavaBean哪些属性是可定制的,此外还描述了可定制属性与PropertyEditor的对应关系。 +dt.jar中全部是Swing组件的BeanInfo。那么到底什么是BeanInfo呢? -    BeanInfo与JavaBean之间的对应关系,通过两者之间规范的命名确立:对应JavaBean的BeanInfo采用如下的命名规范:BeanInfo。当JavaBean连同其属性编辑器相同的组件注册到IDE中后,当在开发界面中对JavaBean进行定制时,IDE就会根据JavaBean规范找到对应的BeanInfo,再根据BeanInfo中的描述信息找到JavaBean属性描述(是否开放、使用哪个属性编辑器),进而为JavaBean生成特定开发编辑界面。 +何为BeanInfo?JavaBean和BeanInfo有很大的关系。Sun所制定的JavaBean规范,很大程度上是为IDE准备的——它让IDE能够以可视化的方式设置JavaBean的属性。如果在IDE中开发一个可视化应用程序,我们需要通过属性设置的方式对组成应用的各种组件进行定制,IDE通过属性编辑器让开发人员使用可视化的方式设置组件的属性。 -    dt.jar里面主要是swing组件的BeanInfo。IDE根据这些BeanInfo显示这些组件以及开发人员如何定制他们。 +dt.jar里面主要是swing组件的BeanInfo。IDE根据这些BeanInfo显示这些组件以及开发人员如何定制他们。 ### rt.jar rt.jar是runtime的归档。Java基础类库,也就是Java doc里面看到的所有的类的class文件。 -![image](https://img-blog.csdnimg.cn/20181115130130739.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z1aGFuZ2hhbmc=,size_16,color_FFFFFF,t_70) +![image](https://www.pianshen.com/images/75/856cbbdf52da90fa4f9bbb7b0597ce63.png) - rt.jar 默认就在Root Classloader的加载路径里面的,而在Claspath配置该变量是不需要的;同时jre/lib目录下的其他jar:jce.jar、jsse.jar、charsets.jar、resources.jar都在Root Classloader中。 +rt.jar 默认就在Root Classloader的加载路径里面的,而在Claspath配置该变量是不需要的;同时jre/lib目录下的其他jar:jce.jar、jsse.jar、charsets.jar、resources.jar都在Root Classloader中。 -## *.java文件的奥秘 - -### *.Java文件简介 +## java文件的奥秘 +### Java文件简介 .java文件你可以认为只是一个文本文件, 这个文件即是用java语言写成的程序,或者说任务的代码块。 @@ -335,43 +306,41 @@ rt.jar是runtime的归档。Java基础类库,也就是Java doc里面看到的 这里的.class文件在计算的体系结构中本质上对应的是一种机器语言(而这里的机器叫作JVM),所以JVM本身是可以直接运行这里的.class文件。所以 你可以进一步地认为,.java与.class与其它的编程语法一样,它们都是程序员用来描述自己的任务的一种语言,只是它们面向的对象不一样,而计算机本身只能识别它自已定义的那些指令什么的(再次强调,这里的计算机本身没有那么严格的定义) > In short: -> +> > .java是Java的源文件后缀,里面存放程序员编写的功能代码。 -> +> > .class文件是字节码文件,由.java源文件通过javac命令编译后生成的文件。是可以运行在任何支持Java虚拟机的硬件平台和操作系统上的二进制文件。 -> +> > .class文件并不本地的可执行程序。Java虚拟机就是去运行.class文件从而实现程序的运行。 - - ### 为什么一个java源文件中只能有一个public类? -  在java编程思想(第四版)一书中有这样3段话(6.4 类的访问权限): +在java编程思想(第四版)一书中有这样3段话(6.4 类的访问权限): >   1.每个编译单元(文件)都只能有一个public类,这表示,每个编译单元都有单一的公共接口,用public类来表现。该接口可以按要求包含众多的支持包访问权限的类。如果在某个编译单元内有一个以上的public类,编译器就会给出错误信息。 -> +> >   2.public类的名称必须完全与含有该编译单元的文件名相同,包含大小写。如果不匹配,同样将得到编译错误。 -> +> >   3.虽然不是很常用,但编译单元内完全不带public类也是可能的。在这种情况下,可以随意对文件命名。 总结相关的几个问题: 1、一个”.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? ->   答:可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致。 +> 答:可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致。 2、为什么一个文件中只能有一个public的类 ->   答:编译器在编译时,针对一个java源代码文件(也称为“编译单元”)只会接受一个public类。否则报错。 +> 答:编译器在编译时,针对一个java源代码文件(也称为“编译单元”)只会接受一个public类。否则报错。 3、在java文件中是否可以没有public类 ->   答:public类不是必须的,java文件中可以没有public类。 +> 答:public类不是必须的,java文件中可以没有public类。 4、为什么这个public的类的类名必须和文件名相同 ->   答: 是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。 +> 答: 是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。 ### Main方法 @@ -400,27 +369,25 @@ rt.jar是runtime的归档。Java基础类库,也就是Java doc里面看到的 为什么要对外部类或类做修饰呢? -> 1.存在包概念:public 和 default 能区分这个外部类能对不同包作一个划分 (default修饰的类,其他包中引入不了这个类,public修饰的类才能被import) -> +> 1.存在包概念:public 和 default 能区分这个外部类能对不同包作一个划分 (default修饰的类,其他包中引入不了这个类,public修饰的类才能被import) +> > 2.protected是包内可见并且子类可见,但是当一个外部类想要继承一个protected修饰的非同包类时,压根找不到这个类,更别提几层了 -> +> > 3.private修饰的外部类,其他任何外部类都无法导入它。 - - //Java中的文件名要和public修饰的类名相同,否则会报错 - //如果没有public修饰的类,则文件可以随意命名 - public class Java中的类文件 { - - } - - //非公共开类的访问权限默认是包访问权限,不能用private和protected - //一个外部类的访问权限只有两种,一种是包内可见,一种是包外可见。 - //如果用private修饰,其他类根本无法看到这个类,也就没有意义了。 - //如果用protected,虽然也是包内可见,但是如果有子类想要继承该类但是不同包时, - //压根找不到这个类,也不可能继承它了,所以干脆用default代替。 - class A{ - - } +```` +//Java中的文件名要和public修饰的类名相同,否则会报错 +//如果没有public修饰的类,则文件可以随意命名 +public class Java中的类文件 { +} +//非公共开类的访问权限默认是包访问权限,不能用private和protected +//一个外部类的访问权限只有两种,一种是包内可见,一种是包外可见。 +//如果用private修饰,其他类根本无法看到这个类,也就没有意义了。 +//如果用protected,虽然也是包内可见,但是如果有子类想要继承该类但是不同包时, +//压根找不到这个类,也不可能继承它了,所以干脆用default代替。 +class A{ +} +```` ### Java包的命名规则 @@ -458,6 +425,6 @@ https://blog.csdn.net/qq_36626914/article/details/80627454 作者是 985 硕士,蚂蚁金服 JAVA 工程师,专注于 JAVA 后端技术栈:SpringBoot、MySQL、分布式、中间件、微服务,同时也懂点投资理财,偶尔讲点算法和计算机理论基础,坚持学习和写作,相信终身学习的力量! -**程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 +**程序员3T技术学习资源:** 一些程序员学习技术的资源大礼包,关注公众号后,后台回复关键字 **“资料”** 即可免费无套路获取。 ![](https://img-blog.csdnimg.cn/20190829222750556.jpg) diff --git "a/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" "b/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" index c6ed3af..0408300 100644 --- "a/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" +++ "b/docs/java/basic/8\343\200\201Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" @@ -18,10 +18,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - - Java基本数据类型 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -148,14 +144,14 @@ float fn = Float.MIN_VALUE; //64位 double dx = Double.MAX_VALUE; double dn = Double.MIN_VALUE; -//16位 -char cx = Character.MAX_VALUE; -char cn = Character.MIN_VALUE; //1位 boolean bt = Boolean.TRUE; boolean bf = Boolean.FALSE; ``` +``` +打印它们的结果可以得到 + `127` `-128` `32767` @@ -168,10 +164,9 @@ boolean bf = Boolean.FALSE; `1.4E-45` `1.7976931348623157E308` `4.9E-324` -`￿` - `true` `false` +``` ### 引用类型 @@ -203,23 +198,23 @@ char a = 'A' ## 自动拆箱和装箱(详解) Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装类型的相互转换操作。在Java 5之前,如果要将一个int型的值转换成对应的包装器类型Integer,必须显式的使用new创建一个新的Integer对象,或者调用静态方法Integer.valueOf()。 - +```` //在Java 5之前,只能这样做 Integer value = new Integer(10); //或者这样做 Integer value = Integer.valueOf(10); //直接赋值是错误的 //Integer value = 10;` - +```` 在Java 5中,可以直接将整型赋给Integer对象,由编译器来完成从int型到Integer类型的转换,这就叫自动装箱。 - -`//在Java 5中,直接赋值是合法的,由编译器来完成转换` -`Integer value = 10;` -`与此对应的,自动拆箱就是可以将包装类型转换为基本类型,具体的转换工作由编译器来完成。` -`//在Java 5 中可以直接这么做` -`Integer value = new Integer(10);` -`int i = value;` - +```` +//在Java 5中,直接赋值是合法的,由编译器来完成转换 +Integer value = 10; +与此对应的,自动拆箱就是可以将包装类型转换为基本类型,具体的转换工作由编译器来完成。 +//在Java 5 中可以直接这么做 +Integer value = new Integer(10); +int i = value; +```` 自动装箱与自动拆箱为程序员提供了很大的方便,而在实际的应用中,自动装箱与拆箱也是使用最广泛的特性之一。自动装箱和自动拆箱其实是Java编译器提供的一颗语法糖(语法糖是指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通过可提高开发效率,增加代码可读性,增加代码的安全性)。 ### 简易实现 @@ -231,6 +226,7 @@ Integer value = Integer.valueOf(10); 实例方法xxxValue():将具体的包装类型对象转换成基本类型; 下面我们以int和Integer为例,说明Java中自动装箱与自动拆箱的实现机制。看如下代码: +```` class Auto //code1 { public static void main(String[] args) @@ -246,7 +242,10 @@ class Auto //code1 } } +```` + 上面的代码先将int型转为Integer对象,再讲Integer对象转换为int型,毫无疑问,这是可以正确运行的。可是,这种转换是怎么进行的呢?使用反编译工具,将生成的Class文件在反编译为Java文件,让我们看看发生了什么: +```` class Auto//code2 { public static void main(String[] paramArrayOfString) @@ -254,17 +253,11 @@ class Auto//code2 Integer localInteger = Integer.valueOf(10); int i = localInteger.intValue(); - - - - - - - Double localDouble = Double.valueOf(12.4D); double d = localDouble.doubleValue(); } } +```` 我们可以看到经过javac编译之后,code1的代码被转换成了code2,实际运行时,虚拟机运行的就是code2的代码。也就是说,虚拟机根本不知道有自动拆箱和自动装箱这回事;在将Java源文件编译为class文件的过程中,javac编译器在自动装箱的时候,调用了Integer.valueOf()方法,在自动拆箱时,又调用了intValue()方法。我们可以看到,double和Double也是如此。 实现总结:其实自动装箱和自动封箱是编译器为我们提供的一颗语法糖。在自动装箱时,编译器调用包装类型的valueOf()方法;在自动拆箱时,编译器调用了相应的xxxValue()方法。 @@ -274,128 +267,132 @@ class Auto//code2 Integer源码 +```` public final class Integer extends Number implements Comparable { - private final int value; - - /*Integer的构造方法,接受一个整型参数,Integer对象表示的int值,保存在value中*/ - public Integer(int value) { - this.value = value; - } - - /*equals()方法判断的是:所代表的int型的值是否相等*/ - public boolean equals(Object obj) { - if (obj instanceof Integer) { - return value == ((Integer)obj).intValue(); - } - return false; - } - - /*返回这个Integer对象代表的int值,也就是保存在value中的值*/ - public int intValue() { - return value; - } - - /** - * 首先会判断i是否在[IntegerCache.low,Integer.high]之间 - * 如果是,直接返回Integer.cache中相应的元素 - * 否则,调用构造方法,创建一个新的Integer对象 - */ - public static Integer valueOf(int i) { - assert IntegerCache.high >= 127; - if (i >= IntegerCache.low && i <= IntegerCache.high) - return IntegerCache.cache[i + (-IntegerCache.low)]; - return new Integer(i); - } - - /** - * 静态内部类,缓存了从[low,high]对应的Integer对象 - * low -128这个值不会被改变 - * high 默认是127,可以改变,最大不超过:Integer.MAX_VALUE - (-low) -1 - * cache 保存从[low,high]对象的Integer对象 - */ - private static class IntegerCache { - static final int low = -128; - static final int high; - static final Integer cache[]; - - static { - // high value may be configured by property - int h = 127; - String integerCacheHighPropValue = - sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); - if (integerCacheHighPropValue != null) { - int i = parseInt(integerCacheHighPropValue); - i = Math.max(i, 127); - // Maximum array size is Integer.MAX_VALUE - h = Math.min(i, Integer.MAX_VALUE - (-low) -1); - } - high = h; - - cache = new Integer[(high - low) + 1]; - int j = low; - for(int k = 0; k < cache.length; k++) - cache[k] = new Integer(j++); - } - - private IntegerCache() {} - } + private final int value; + + /*Integer的构造方法,接受一个整型参数,Integer对象表示的int值,保存在value中*/ + public Integer(int value) { + this.value = value; + } + + /*equals()方法判断的是:所代表的int型的值是否相等*/ + public boolean equals(Object obj) { + if (obj instanceof Integer) { + return value == ((Integer)obj).intValue(); + } + return false; + } + + /*返回这个Integer对象代表的int值,也就是保存在value中的值*/ + public int intValue() { + return value; + } + + /** + * 首先会判断i是否在[IntegerCache.low,Integer.high]之间 + * 如果是,直接返回Integer.cache中相应的元素 + * 否则,调用构造方法,创建一个新的Integer对象 + */ + public static Integer valueOf(int i) { + assert IntegerCache.high >= 127; + if (i >= IntegerCache.low && i <= IntegerCache.high) + return IntegerCache.cache[i + (-IntegerCache.low)]; + return new Integer(i); + } + + /** + * 静态内部类,缓存了从[low,high]对应的Integer对象 + * low -128这个值不会被改变 + * high 默认是127,可以改变,最大不超过:Integer.MAX_VALUE - (-low) -1 + * cache 保存从[low,high]对象的Integer对象 + */ + private static class IntegerCache { + static final int low = -128; + static final int high; + static final Integer cache[]; + + static { + // high value may be configured by property + int h = 127; + String integerCacheHighPropValue = + sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); + if (integerCacheHighPropValue != null) { + int i = parseInt(integerCacheHighPropValue); + i = Math.max(i, 127); + // Maximum array size is Integer.MAX_VALUE + h = Math.min(i, Integer.MAX_VALUE - (-low) -1); + } + high = h; + + cache = new Integer[(high - low) + 1]; + int j = low; + for(int k = 0; k < cache.length; k++) + cache[k] = new Integer(j++); + } + + private IntegerCache() {} + } } -以上是Oracle(Sun)公司JDK 1.7中Integer源码的一部分,通过分析上面的代码,得到: -1)Integer有一个实例域value,它保存了这个Integer所代表的int型的值,且它是final的,也就是说这个Integer对象一经构造完成,它所代表的值就不能再被改变。 -2)Integer重写了equals()方法,它通过比较两个Integer对象的value,来判断是否相等。 -3)重点是静态内部类IntegerCache,通过类名就可以发现:它是用来缓存数据的。它有一个数组,里面保存的是连续的Integer对象。 - (a) low:代表缓存数据中最小的值,固定是-128。 - (b) high:代表缓存数据中最大的值,它可以被该改变,默认是127。high最小是127,最大是Integer.MAX_VALUE-(-low)-1,如果high超过了这个值,那么cache[ ]的长度就超过Integer.MAX_VALUE了,也就溢出了。 - (c) cache[]:里面保存着从[low,high]所对应的Integer对象,长度是high-low+1(因为有元素0,所以要加1)。 -4)调用valueOf(int i)方法时,首先判断i是否在[low,high]之间,如果是,则复用Integer.cache[i-low]。比如,如果Integer.valueOf(3),直接返回Integer.cache[131];如果i不在这个范围,则调用构造方法,构造出一个新的Integer对象。 -5)调用intValue(),直接返回value的值。 -通过3)和4)可以发现,默认情况下,在使用自动装箱时,VM会复用[-128,127]之间的Integer对象。 - -Integer a1 = 1; -Integer a2 = 1; -Integer a3 = new Integer(1); -//会打印true,因为a1和a2是同一个对象,都是Integer.cache[129] -System.out.println(a1 == a2); -//false,a3构造了一个新的对象,不同于a1,a2 -System.out.println(a1 == a3); +```` + + 以上是Oracle(Sun)公司JDK 1.7中Integer源码的一部分,通过分析上面的代码,得到: + 1)Integer有一个实例域value,它保存了这个Integer所代表的int型的值,且它是final的,也就是说这个Integer对象一经构造完成,它所代表的值就不能再被改变。 + 2)Integer重写了equals()方法,它通过比较两个Integer对象的value,来判断是否相等。 + 3)重点是静态内部类IntegerCache,通过类名就可以发现:它是用来缓存数据的。它有一个数组,里面保存的是连续的Integer对象。 + (a) low:代表缓存数据中最小的值,固定是-128。 + (b) high:代表缓存数据中最大的值,它可以被该改变,默认是127。high最小是127,最大是Integer.MAX_VALUE-(-low)-1,如果high超过了这个值,那么cache[ ]的长度就超过Integer.MAX_VALUE了,也就溢出了。 + (c) cache[]:里面保存着从[low,high]所对应的Integer对象,长度是high-low+1(因为有元素0,所以要加1)。 + 4)调用valueOf(int i)方法时,首先判断i是否在[low,high]之间,如果是,则复用Integer.cache[i-low]。比如,如果Integer.valueOf(3),直接返回Integer.cache[131];如果i不在这个范围,则调用构造方法,构造出一个新的Integer对象。 + 5)调用intValue(),直接返回value的值。 + 通过3)和4)可以发现,默认情况下,在使用自动装箱时,VM会复用[-128,127]之间的Integer对象。 + + Integer a1 = 1; + Integer a2 = 1; + Integer a3 = new Integer(1); + //会打印true,因为a1和a2是同一个对象,都是Integer.cache[129] + System.out.println(a1 == a2); + //false,a3构造了一个新的对象,不同于a1,a2 + System.out.println(a1 == a3); ### 了解基本类型缓存(常量池)的最佳实践 - //基本数据类型的常量池是-128到127之间。 - // 在这个范围中的基本数据类的包装类可以自动拆箱,比较时直接比较数值大小。 - public static void main(String[] args) { - //int的自动拆箱和装箱只在-128到127范围中进行,超过该范围的两个integer的 == 判断是会返回false的。 - Integer a1 = 128; - Integer a2 = -128; - Integer a3 = -128; - Integer a4 = 128; - System.out.println(a1 == a4); - System.out.println(a2 == a3); - - Byte b1 = 127; - Byte b2 = 127; - Byte b3 = -128; - Byte b4 = -128; - //byte都是相等的,因为范围就在-128到127之间 - System.out.println(b1 == b2); - System.out.println(b3 == b4); - - // - Long c1 = 128L; - Long c2 = 128L; - Long c3 = -128L; - Long c4 = -128L; - System.out.println(c1 == c2); - System.out.println(c3 == c4); - - //char没有负值 - //发现char也是在0到127之间自动拆箱 - Character d1 = 128; - Character d2 = 128; - Character d3 = 127; - Character d4 = 127; - System.out.println(d1 == d2); - System.out.println(d3 == d4); +```` +//基本数据类型的常量池是-128到127之间。 +// 在这个范围中的基本数据类的包装类可以自动拆箱,比较时直接比较数值大小。 +public static void main(String[] args) { + +//int的自动拆箱和装箱只在-128到127范围中进行,超过该范围的两个integer的 == 判断是会返回false的。 +Integer a1 = 128; +Integer a2 = -128; +Integer a3 = -128; +Integer a4 = 128; +System.out.println(a1 == a4); +System.out.println(a2 == a3); + +Byte b1 = 127; +Byte b2 = 127; +Byte b3 = -128; +Byte b4 = -128; +//byte都是相等的,因为范围就在-128到127之间 +System.out.println(b1 == b2); +System.out.println(b3 == b4); + +Long c1 = 128L; +Long c2 = 128L; +Long c3 = -128L; +Long c4 = -128L; +System.out.println(c1 == c2); +System.out.println(c3 == c4); + +//char没有负值 +//发现char也是在0到127之间自动拆箱 +Character d1 = 128; +Character d2 = 128; +Character d3 = 127; +Character d4 = 127; +System.out.println(d1 == d2); +System.out.println(d3 == d4); `结果` @@ -409,27 +406,29 @@ System.out.println(a1 == a3); `true` - Integer i = 10; - Byte b = 10; - //比较Byte和Integer.两个对象无法直接比较,报错 - //System.out.println(i == b); - System.out.println("i == b " + i.equals(b)); - //答案是false,因为包装类的比较时先比较是否是同一个类,不是的话直接返回false. - int ii = 128; - short ss = 128; - long ll = 128; - char cc = 128; - System.out.println("ii == bb " + (ii == ss)); - System.out.println("ii == ll " + (ii == ll)); - System.out.println("ii == cc " + (ii == cc)); - - 结果 - i == b false - ii == bb true - ii == ll true - ii == cc true - - //这时候都是true,因为基本数据类型直接比较值,值一样就可以。 +Integer i = 10; +Byte b = 10; +//比较Byte和Integer.两个对象无法直接比较,报错 +//System.out.println(i == b); +System.out.println("i == b " + i.equals(b)); +//答案是false,因为包装类的比较时先比较是否是同一个类,不是的话直接返回false. + +int ii = 128; +short ss = 128; +long ll = 128; +char cc = 128; +System.out.println("ii == bb " + (ii == ss)); +System.out.println("ii == ll " + (ii == ll)); +System.out.println("ii == cc " + (ii == cc)); + +结果 +i == b false +ii == bb true +ii == ll true +ii == cc true + +//这时候都是true,因为基本数据类型直接比较值,值一样就可以。 +```` ### 总结: @@ -439,12 +438,10 @@ System.out.println(a1 == a3); (2)当需要一个基本类型时会自动拆箱,比如int a = new Integer(10);算术运算是在基本类型间进行的,所以当遇到算术运算时会自动拆箱,比如代码中的 c == (a + b); -(3) 包装类型 == 基本类型时,包装类型自动拆箱; +(3)包装类型 == 基本类型时,包装类型自动拆箱; 需要注意的是:“==”在没遇到算术运算时,不会自动拆箱;基本类型只会自动装箱为对应的包装类型,代码中最后一条说明的内容。 - - 在JDK 1.5中提供了自动装箱与自动拆箱,这其实是Java 编译器的语法糖,编译器通过调用包装类型的valueOf()方法实现自动装箱,调用xxxValue()方法自动拆箱。自动装箱和拆箱会有一些陷阱,那就是包装类型复用了某些对象。 (1)Integer默认复用了[-128,127]这些对象,其中高位置可以修改; @@ -468,11 +465,13 @@ Boolean没有自动装箱与拆箱,它也复用了Boolean.TRUE和Boolean.FALSE 上面自动拆箱和装箱的原理其实与常量池有关。 ### 存在栈中: -public void(int a) -{ -int i = 1; -int j = 1; -} + + public void(int a) + { + int i = 1; + int j = 1; + } + 方法中的i 存在虚拟机栈的局部变量表里,i是一个引用,j也是一个引用,它们都指向局部变量表里的整型值 1. int a是传值引用,所以a也会存在局部变量表。 @@ -485,50 +484,53 @@ i是类的成员变量。类实例化的对象存在堆中,所以成员变量 3 包装类对象怎么存 其实我们说的常量池也可以叫对象池。 + 比如String a= new String("a").intern()时会先在常量池找是否有“a"对象如果有的话直接返回“a"对象在常量池的地址,即让引用a指向常量”a"对象的内存地址。 -public native String intern(); Integer也是同理。 下图是Integer类型在常量池中查找同值对象的方法。 - public static Integer valueOf(int i) { - if (i >= IntegerCache.low && i <= IntegerCache.high) - return IntegerCache.cache[i + (-IntegerCache.low)]; - return new Integer(i); - } - private static class IntegerCache { - static final int low = -128; - static final int high; - static final Integer cache[]; - - static { - // high value may be configured by property - int h = 127; - String integerCacheHighPropValue = - sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); - if (integerCacheHighPropValue != null) { - try { - int i = parseInt(integerCacheHighPropValue); - i = Math.max(i, 127); - // Maximum array size is Integer.MAX_VALUE - h = Math.min(i, Integer.MAX_VALUE - (-low) -1); - } catch( NumberFormatException nfe) { - // If the property cannot be parsed into an int, ignore it. - } +```` +public static Integer valueOf(int i) { + if (i >= IntegerCache.low && i <= IntegerCache.high) + return IntegerCache.cache[i + (-IntegerCache.low)]; + return new Integer(i); +} +private static class IntegerCache { + static final int low = -128; + static final int high; + static final Integer cache[]; + + static { + // high value may be configured by property + int h = 127; + String integerCacheHighPropValue = + sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); + if (integerCacheHighPropValue != null) { + try { + int i = parseInt(integerCacheHighPropValue); + i = Math.max(i, 127); + // Maximum array size is Integer.MAX_VALUE + h = Math.min(i, Integer.MAX_VALUE - (-low) -1); + } catch( NumberFormatException nfe) { + // If the property cannot be parsed into an int, ignore it. } - high = h; - - cache = new Integer[(high - low) + 1]; - int j = low; - for(int k = 0; k < cache.length; k++) - cache[k] = new Integer(j++); - - // range [-128, 127] must be interned (JLS7 5.1.7) - assert IntegerCache.high >= 127; } - - private IntegerCache() {} + high = h; + + cache = new Integer[(high - low) + 1]; + int j = low; + for(int k = 0; k < cache.length; k++) + cache[k] = new Integer(j++); + + // range [-128, 127] must be interned (JLS7 5.1.7) + assert IntegerCache.high >= 127; } + + private IntegerCache() {} +} +```` + 所以基本数据类型的包装类型可以在常量池查找对应值的对象,找不到就会自动在常量池创建该值的对象。 而String类型可以通过intern来完成这个操作。 @@ -537,7 +539,6 @@ JDK1.7后,常量池被放入到堆空间中,这导致intern()函数的功能 ``` -[java] view plain copy String s = new String("1"); s.intern(); String s2 = "1"; @@ -554,9 +555,6 @@ JDK1.6以及以下:false false JDK1.7以及以上:false true ``` -![image](https://img-blog.csdn.net/20180422231916788?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E3MjQ4ODg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) - -![image](https://img-blog.csdn.net/20180422231929413?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E3MjQ4ODg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) JDK1.6查找到常量池存在相同值的对象时会直接返回该对象的地址。 JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。 diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" similarity index 100% rename from "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java class\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" rename to "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2724\357\274\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" diff --git "a/docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" similarity index 100% rename from "docs/java/jvm/\346\267\261\345\205\245\344\272\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" rename to "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\2728\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" From ed040831f5e5b92008008b284f03f51218f33a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Mon, 3 Apr 2023 22:15:41 +0800 Subject: [PATCH 038/113] modify basic mds --- ...43\200\201Java\345\274\202\345\270\270.md" | 659 ++++++++--------- ...55\347\232\204\345\233\236\350\260\203.md" | 352 +++++---- ...12\343\200\201\345\217\215\345\260\204.md" | 561 +++++++-------- ...13\343\200\201\346\263\233\345\236\213.md" | 666 +++++++++-------- ...01\346\236\232\344\270\276\347\261\273.md" | 329 ++++----- ...00\344\275\263\345\256\236\350\267\265.md" | 123 ++-- .../16\343\200\201JavaIO\346\265\201.md" | 127 ++-- ...01\345\244\232\347\272\277\347\250\213.md" | 9 - ...43\345\206\205\351\203\250\347\261\273.md" | 568 +++++++-------- ...06\346\236\266\346\242\263\347\220\206.md" | 680 +++++++++--------- .../20\343\200\201javac\345\222\214javap.md" | 439 ++++++----- ...10\346\236\201\346\214\207\345\215\227.md" | 468 ++++++------ ...15\345\272\217\345\210\227\345\214\226.md" | 610 ++++++++-------- ...36\347\216\260\345\216\237\347\220\206.md" | 531 +++++--------- ...73\345\222\214\346\216\245\345\217\243.md" | 149 ++-- ...47\350\241\214\351\241\272\345\272\217.md" | 85 ++- ...\261\273\345\222\214Object\347\261\273.md" | 166 ++--- 17 files changed, 3118 insertions(+), 3404 deletions(-) diff --git "a/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" "b/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" index c937417..7e76b60 100644 --- "a/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" +++ "b/docs/java/basic/10\343\200\201Java\345\274\202\345\270\270.md" @@ -19,11 +19,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- - - - Java异常 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -51,7 +46,7 @@ > 3、 由调用函数来分析异常,这要求程序员对库函数有很深的了解。 > - 在OO中提供的异常处理机制是提供代码健壮的强有力的方式。使用异常机制它能够降低错误处理代码的复杂度,如果不使用异常,那么就必须检查特定的错误,并在程序中的许多地方去处理它。 +在OO中提供的异常处理机制是提供代码健壮的强有力的方式。使用异常机制它能够降低错误处理代码的复杂度,如果不使用异常,那么就必须检查特定的错误,并在程序中的许多地方去处理它。 而如果使用异常,那就不必在方法调用处进行检查,因为异常机制将保证能够捕获这个错误,并且,只需在一个地方处理错误,即所谓的异常处理程序中。 @@ -61,21 +56,20 @@ ## 异常基本定义 -> 在《Think in java》中是这样定义异常的:异常情形是指阻止当前方法或者作用域继续执行的问题。在这里一定要明确一点:异常代码某种程度的错误,尽管Java有异常处理机制,但是我们不能以“正常”的眼光来看待异常,异常处理机制的原因就是告诉你:这里可能会或者已经产生了错误,您的程序出现了不正常的情况,可能会导致程序失败! +> 在《Think in java》中是这样定义异常的:异常情形是指阻止当前方法或者作用域继续执行的问题。在这里一定要明确一点:异常代码某种程度的错误,尽管Java有异常处理机制,但是我们不能以“正常”的眼光来看待异常,异常处理机制的原因就是告诉你:这里可能会或者已经产生了错误,您的程序出现了不正常的情况,可能会导致程序失败! -> 那么什么时候才会出现异常呢?只有在你当前的环境下程序无法正常运行下去,也就是说程序已经无法来正确解决问题了,这时它所就会从当前环境中跳出,并抛出异常。抛出异常后,它首先会做几件事。 +> 那么什么时候才会出现异常呢?只有在你当前的环境下程序无法正常运行下去,也就是说程序已经无法来正确解决问题了,这时它所就会从当前环境中跳出,并抛出异常。抛出异常后,它首先会做几件事。 > 首先,它会使用new创建一个异常对象,然后在产生异常的位置终止程序,并且从当前环境中弹出对异常对象的引用,这时。异常处理机制就会接管程序,并开始寻找一个恰当的地方来继续执行程序,这个恰当的地方就是异常处理程序。 -> 总的来说异常处理机制就是当程序发生异常时,它强制终止程序运行,记录异常信息并将这些信息反馈给我们,由我们来确定是否处理异常。 +> 总的来说异常处理机制就是当程序发生异常时,它强制终止程序运行,记录异常信息并将这些信息反馈给我们,由我们来确定是否处理异常。 ## 异常体系 -[外链图片转存失败(img-KNxcBTK0-1569073569353)(https://images0.cnblogs.com/blog/381060/201311/22185952-834d92bc2bfe498f9a33414cc7a2c8a4.png)] +![img](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/22185952-834d92bc2bfe498f9a33414cc7a2c8a4.png) 从上面这幅图可以看出,Throwable是java语言中所有错误和异常的超类(万物即可抛)。它有两个子类:Error、Exception。 - Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。 Throwable又派生出Error类和Exception类。 @@ -103,7 +97,7 @@ Throwable又派生出Error类和Exception类。 异常是在执行某个函数时引发的,而函数又是层级调用,形成调用栈的,因为,只要一个函数发生了异常,那么他的所有的caller都会被异常影响。当这些被影响的函数以异常信息输出时,就形成的了异常追踪栈。 异常最先发生的地方,叫做异常抛出点。 - +```` public class 异常 { public static void main (String [] args ) { @@ -130,9 +124,7 @@ Throwable又派生出Error类和Exception类。 // at com.javase.异常.异常.devide(异常.java:24) // at com.javase.异常.异常.CMDCalculate(异常.java:19) // at com.javase.异常.异常.main(异常.java:12) - - -​ + // ----欢迎使用命令行除法计算器---- // r // Exception in thread "main" java.util.InputMismatchException @@ -143,8 +135,7 @@ Throwable又派生出Error类和Exception类。 // at com.javase.异常.异常.CMDCalculate(异常.java:17) // at com.javase.异常.异常.main(异常.java:12) - -[外链图片转存失败(img-9rqUQJQj-1569073569354)(http://incdn1.b0.upaiyun.com/2017/09/0b3e4ca2f4cf8d7116c7ad354940601f.png)] +```` 从上面的例子可以看出,当devide函数发生除0异常时,devide函数将抛出ArithmeticException异常,因此调用他的CMDCalculate函数也无法正常完成,因此也发送异常,而CMDCalculate的caller——main 因为CMDCalculate抛出异常,也发生了异常,这样一直向调用栈的栈底回溯。 @@ -157,7 +148,7 @@ Throwable又派生出Error类和Exception类。 ## 异常和错误 下面看一个例子 - +```` //错误即error一般指jvm无法处理的错误 //异常是Java定义的用于简化错误处理流程和定位错误的一种工具。 public class 错误和错误 { @@ -198,7 +189,7 @@ Throwable又派生出Error类和Exception类。 // at com.javase.异常.错误.main(错误.java:11) } - +```` ## 异常的处理方式 在编写代码处理异常时,对于检查异常,有2种不同的处理方式: @@ -213,7 +204,7 @@ Throwable又派生出Error类和Exception类。 上面的例子是运行时异常,不需要显示捕获。 下面这个例子是可检查异常需,要显示捕获或者抛出。 - +```` @Test public void testException() throws IOException { @@ -309,6 +300,7 @@ Throwable又派生出Error类和Exception类。 // at com.javase.异常.异常处理方式.test(异常处理方式.java:62) throw new StringIndexOutOfBoundsException(); } +```` 其实有的语言在遇到异常后仍然可以继续运行 @@ -321,11 +313,12 @@ Throwable又派生出Error类和Exception类。 throws是另一种处理异常的方式,它不同于try…catch…finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。 采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责。 - - public void foo() throws ExceptionType1 , ExceptionType2 ,ExceptionTypeN - { - //foo内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常,或者他们的子类的异常对象。 - } +```` +public void foo() throws ExceptionType1 , ExceptionType2 ,ExceptionTypeN +{ + //foo内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常,或者他们的子类的异常对象。 +} +```` ## 纠结的finally @@ -341,6 +334,7 @@ finally块不管异常是否发生,只要对应的try执行了,则它一定 3、在同一try…catch…finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。 +```` public class finally使用 { public static void main(String[] args) { try { @@ -357,6 +351,7 @@ finally块不管异常是否发生,只要对应的try执行了,则它一定 } } } +```` ## throw : JRE也使用的关键字 @@ -365,15 +360,14 @@ throw exceptionObject 程序员也可以通过throw语句手动显式的抛出一个异常。throw语句的后面必须是一个异常对象。 throw 语句必须写在函数中,执行throw 语句的地方就是一个异常抛出点,==它和由JRE自动形成的异常抛出点没有任何差别。== - - public void save(User user) - { - if(user == null) - throw new IllegalArgumentException("User对象为空"); - //...... - - } - +```` +public void save(User user) +{ + if(user == null) + throw new IllegalArgumentException("User对象为空"); + //...... +} +```` 后面开始的大部分内容都摘自http://www.cnblogs.com/lulipro/p/7504267.html 该文章写的十分细致到位,令人钦佩,是我目前为之看到关于异常最详尽的文章,可以说是站在巨人的肩膀上了。 @@ -389,88 +383,86 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 > 异常链化:以一个异常对象为参数构造新的异常对象。新的异对象将包含先前异常的信息。这项技术主要是异常类的一个带Throwable参数的函数来实现的。这个当做参数的异常,我们叫他根源异常(cause)。 查看Throwable类源码,可以发现里面有一个Throwable字段cause,就是它保存了构造时传递的根源异常参数。这种设计和链表的结点类设计如出一辙,因此形成链也是自然的了。 - - public class Throwable implements Serializable { - private Throwable cause = this; - - public Throwable(String message, Throwable cause) { - fillInStackTrace(); - detailMessage = message; - this.cause = cause; - } - public Throwable(Throwable cause) { - fillInStackTrace(); - detailMessage = (cause==null ? null : cause.toString()); - this.cause = cause; - } - - //........ +```` +public class Throwable implements Serializable { + private Throwable cause = this; + public Throwable(String message, Throwable cause) { + fillInStackTrace(); + detailMessage = message; + this.cause = cause; } - + public Throwable(Throwable cause) { + fillInStackTrace(); + detailMessage = (cause==null ? null : cause.toString()); + this.cause = cause; + } + //........ +} +```` 下面看一个比较实在的异常链例子哈 - - public class 异常链 { - @Test - public void test() { - C(); - } - public void A () throws Exception { - try { - int i = 1; - i = i / 0; - //当我注释掉这行代码并使用B方法抛出一个error时,运行结果如下 - // 四月 27, 2018 10:12:30 下午 org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines - // 信息: Discovered TestEngines with IDs: [junit-jupiter] - // java.lang.Error: B也犯了个错误 - // at com.javase.异常.异常链.B(异常链.java:33) - // at com.javase.异常.异常链.C(异常链.java:38) - // at com.javase.异常.异常链.test(异常链.java:13) - // at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - // Caused by: java.lang.Error - // at com.javase.异常.异常链.B(异常链.java:29) - - }catch (ArithmeticException e) { - //这里通过throwable类的构造方法将最底层的异常重新包装并抛出,此时注入了A方法的信息。最后打印栈信息时可以看到caused by - A方法的异常。 - //如果直接抛出,栈信息打印结果只能看到上层方法的错误信息,不能看到其实是A发生了错误。 - //所以需要包装并抛出 - throw new Exception("A方法计算错误", e); - } - +```` +public class 异常链 { + @Test + public void test() { + C(); + } + public void A () throws Exception { + try { + int i = 1; + i = i / 0; + //当我注释掉这行代码并使用B方法抛出一个error时,运行结果如下 +// 四月 27, 2018 10:12:30 下午 org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines +// 信息: Discovered TestEngines with IDs: [junit-jupiter] +// java.lang.Error: B也犯了个错误 +// at com.javase.异常.异常链.B(异常链.java:33) +// at com.javase.异常.异常链.C(异常链.java:38) +// at com.javase.异常.异常链.test(异常链.java:13) +// at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) +// Caused by: java.lang.Error +// at com.javase.异常.异常链.B(异常链.java:29) + + }catch (ArithmeticException e) { + //这里通过throwable类的构造方法将最底层的异常重新包装并抛出,此时注入了A方法的信息。最后打印栈信息时可以看到caused by + A方法的异常。 + //如果直接抛出,栈信息打印结果只能看到上层方法的错误信息,不能看到其实是A发生了错误。 + //所以需要包装并抛出 + throw new Exception("A方法计算错误", e); } - public void B () throws Exception,Error { - try { - //接收到A的异常, - A(); - throw new Error(); - }catch (Exception e) { - throw e; - }catch (Error error) { - throw new Error("B也犯了个错误", error); - } + + } + public void B () throws Exception,Error { + try { + //接收到A的异常, + A(); + throw new Error(); + }catch (Exception e) { + throw e; + }catch (Error error) { + throw new Error("B也犯了个错误", error); } - public void C () { - try { - B(); - }catch (Exception | Error e) { - e.printStackTrace(); - } - + } + public void C () { + try { + B(); + }catch (Exception | Error e) { + e.printStackTrace(); } - - //最后结果 - // java.lang.Exception: A方法计算错误 - // at com.javase.异常.异常链.A(异常链.java:18) - // at com.javase.异常.异常链.B(异常链.java:24) - // at com.javase.异常.异常链.C(异常链.java:31) - // at com.javase.异常.异常链.test(异常链.java:11) - // 省略 - // Caused by: java.lang.ArithmeticException: / by zero - // at com.javase.异常.异常链.A(异常链.java:16) - // ... 31 more + } + //最后结果 +// java.lang.Exception: A方法计算错误 +// at com.javase.异常.异常链.A(异常链.java:18) +// at com.javase.异常.异常链.B(异常链.java:24) +// at com.javase.异常.异常链.C(异常链.java:31) +// at com.javase.异常.异常链.test(异常链.java:11) +// 省略 +// Caused by: java.lang.ArithmeticException: / by zero +// at com.javase.异常.异常链.A(异常链.java:16) +// ... 31 more +} +```` ## 自定义异常 如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。 @@ -482,7 +474,7 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 一个带有String参数和Throwable参数,并都传递给父类构造函数 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。 下面是IOException类的完整源代码,可以借鉴。 - +```` public class IOException extends Exception { static final long serialVersionUID = 7818375828146090155L; @@ -507,7 +499,7 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 super(cause); } } - +```` ## 异常的注意事项 异常的注意事项 @@ -517,47 +509,47 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 > 例如,父类方法throws 的是2个异常,子类就不能throws 3个及以上的异常。父类throws IOException,子类就必须throws IOException或者IOException的子类。 至于为什么?我想,也许下面的例子可以说明。 - - class Father +```` +class Father +{ + public void start() throws IOException { - public void start() throws IOException - { - throw new IOException(); - } + throw new IOException(); } - - class Son extends Father +} + +class Son extends Father +{ + public void start() throws Exception { - public void start() throws Exception - { - throw new SQLException(); - } + throw new SQLException(); } +} /**********************假设上面的代码是允许的(实质是错误的)***********************/ - class Test +class Test +{ + public static void main(String[] args) { - public static void main(String[] args) + Father[] objs = new Father[2]; + objs[0] = new Father(); + objs[1] = new Son(); + + for(Father obj:objs) { - Father[] objs = new Father[2]; - objs[0] = new Father(); - objs[1] = new Son(); - - for(Father obj:objs) + //因为Son类抛出的实质是SQLException,而IOException无法处理它。 + //那么这里的try。。catch就不能处理Son中的异常。 + //多态就不能实现了。 + try { + obj.start(); + }catch(IOException) { - //因为Son类抛出的实质是SQLException,而IOException无法处理它。 - //那么这里的try。。catch就不能处理Son中的异常。 - //多态就不能实现了。 - try { - obj.start(); - }catch(IOException) - { - //处理IOException - } - } - } - } - + //处理IOException + } + } + } +} +```` ==Java的异常执行流程是线程独立的,线程之间没有影响== > Java程序可以是多线程的。每一个线程都是一个独立的执行流,独立的函数调用栈。如果程序只有一个线程,那么没有被任何代码处理的异常 会导致程序终止。如果是多线程的,那么没有被任何代码处理的异常仅仅会导致异常所在的线程结束。 @@ -565,44 +557,44 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 > 也就是说,Java中的异常是线程独立的,线程的问题应该由线程自己来解决,而不要委托到外部,也不会直接影响到其它线程的执行。 下面看一个例子 - - public class 多线程的异常 { - @Test - public void test() { - go(); - } - public void go () { - ExecutorService executorService = Executors.newFixedThreadPool(3); - for (int i = 0;i <= 2;i ++) { - int finalI = i; - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - executorService.execute(new Runnable() { - @Override - //每个线程抛出异常时并不会影响其他线程的继续执行 - public void run() { - try { - System.out.println("start thread" + finalI); - throw new Exception(); - }catch (Exception e) { - System.out.println("thread" + finalI + " go wrong"); - } - } - }); +```` +public class 多线程的异常 { + @Test + public void test() { + go(); + } + public void go () { + ExecutorService executorService = Executors.newFixedThreadPool(3); + for (int i = 0;i <= 2;i ++) { + int finalI = i; + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); } - // 结果: - // start thread0 - // thread0 go wrong - // start thread1 - // thread1 go wrong - // start thread2 - // thread2 go wrong - } + executorService.execute(new Runnable() { + @Override + //每个线程抛出异常时并不会影响其他线程的继续执行 + public void run() { + try { + System.out.println("start thread" + finalI); + throw new Exception(); + }catch (Exception e) { + System.out.println("thread" + finalI + " go wrong"); + } + } + }); + } +// 结果: +// start thread0 +// thread0 go wrong +// start thread1 +// thread1 go wrong +// start thread2 +// thread2 go wrong } - +} +```` ## 当finally遇上return @@ -610,163 +602,160 @@ throw 语句必须写在函数中,执行throw 语句的地方就是一个异 首先一个不容易理解的事实: 在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。 +```` +public static void main(String[] args) +{ + int re = bar(); + System.out.println(re); +} +private static int bar() +{ + try{ + return 5; + } finally{ + System.out.println("finally"); + } +} +/*输出: +finally +*/ +```` - public static void main(String[] args) +也就是说:try…catch…finally中的return 只要能执行,就都执行了,他们共同向同一个内存地址(假设地址是0×80)写入返回值,后执行的将覆盖先执行的数据,而真正被调用者取的返回值就是最后一次写入的。那么,按照这个思想,下面的这个例子也就不难理解了。 + +finally中的return 会覆盖 try 或者catch中的返回值。 +```` +public static void main(String[] args) { - int re = bar(); - System.out.println(re); + int result; + + result = foo(); + System.out.println(result); /////////2 + + result = bar(); + System.out.println(result); /////////2 } - private static int bar() + + @SuppressWarnings("finally") + public static int foo() { - try{ - return 5; + trz{ + int a = 5 / 0; + } catch (Exception e){ + return 1; } finally{ - System.out.println("finally"); + return 2; } + } - /*输出: - finally - */ -很多人面对这个问题时,总是在归纳执行的顺序和规律,不过我觉得还是很难理解。我自己总结了一个方法。用如下GIF图说明。 - - -[外链图片转存失败(img-SceF4t85-1569073569354)(http://incdn1.b0.upaiyun.com/2017/09/0471c2805ebd5a463211ced478eaf7f8.gif)] - -也就是说:try…catch…finally中的return 只要能执行,就都执行了,他们共同向同一个内存地址(假设地址是0×80)写入返回值,后执行的将覆盖先执行的数据,而真正被调用者取的返回值就是最后一次写入的。那么,按照这个思想,下面的这个例子也就不难理解了。 - - -finally中的return 会覆盖 try 或者catch中的返回值。 - - public static void main(String[] args) - { - int result; - - result = foo(); - System.out.println(result); /////////2 - - result = bar(); - System.out.println(result); /////////2 - } - - @SuppressWarnings("finally") - public static int foo() - { - trz{ - int a = 5 / 0; - } catch (Exception e){ - return 1; - } finally{ - return 2; - } - - } - - @SuppressWarnings("finally") - public static int bar() - { - try { - return 1; - }finally { - return 2; - } + + @SuppressWarnings("finally") + public static int bar() + { + try { + return 1; + }finally { + return 2; } - + } +```` finally中的return会抑制(消灭)前面try或者catch块中的异常 - - class TestException +```` +class TestException +{ + public static void main(String[] args) { - public static void main(String[] args) - { - int result; - try{ - result = foo(); - System.out.println(result); //输出100 - } catch (Exception e){ - System.out.println(e.getMessage()); //没有捕获到异常 - } - - try{ - result = bar(); - System.out.println(result); //输出100 - } catch (Exception e){ - System.out.println(e.getMessage()); //没有捕获到异常 - } + int result; + try{ + result = foo(); + System.out.println(result); //输出100 + } catch (Exception e){ + System.out.println(e.getMessage()); //没有捕获到异常 } - - //catch中的异常被抑制 - @SuppressWarnings("finally") - public static int foo() throws Exception - { - try { - int a = 5/0; - return 1; - }catch(ArithmeticException amExp) { - throw new Exception("我将被忽略,因为下面的finally中使用了return"); - }finally { - return 100; - } + + try{ + result = bar(); + System.out.println(result); //输出100 + } catch (Exception e){ + System.out.println(e.getMessage()); //没有捕获到异常 } - - //try中的异常被抑制 - @SuppressWarnings("finally") - public static int bar() throws Exception - { - try { - int a = 5/0; - return 1; - }finally { - return 100; - } + } + + //catch中的异常被抑制 + @SuppressWarnings("finally") + public static int foo() throws Exception + { + try { + int a = 5/0; + return 1; + }catch(ArithmeticException amExp) { + throw new Exception("我将被忽略,因为下面的finally中使用了return"); + }finally { + return 100; } } + + //try中的异常被抑制 + @SuppressWarnings("finally") + public static int bar() throws Exception + { + try { + int a = 5/0; + return 1; + }finally { + return 100; + } + } +} +```` finally中的异常会覆盖(消灭)前面try或者catch中的异常 - - class TestException +```` +class TestException +{ + public static void main(String[] args) { - public static void main(String[] args) - { - int result; - try{ - result = foo(); - } catch (Exception e){ - System.out.println(e.getMessage()); //输出:我是finaly中的Exception - } - - try{ - result = bar(); - } catch (Exception e){ - System.out.println(e.getMessage()); //输出:我是finaly中的Exception - } + int result; + try{ + result = foo(); + } catch (Exception e){ + System.out.println(e.getMessage()); //输出:我是finaly中的Exception } - - //catch中的异常被抑制 - @SuppressWarnings("finally") - public static int foo() throws Exception - { - try { - int a = 5/0; - return 1; - }catch(ArithmeticException amExp) { - throw new Exception("我将被忽略,因为下面的finally中抛出了新的异常"); - }finally { - throw new Exception("我是finaly中的Exception"); - } + + try{ + result = bar(); + } catch (Exception e){ + System.out.println(e.getMessage()); //输出:我是finaly中的Exception } - - //try中的异常被抑制 - @SuppressWarnings("finally") - public static int bar() throws Exception - { - try { - int a = 5/0; - return 1; - }finally { - throw new Exception("我是finaly中的Exception"); - } - + } + + //catch中的异常被抑制 + @SuppressWarnings("finally") + public static int foo() throws Exception + { + try { + int a = 5/0; + return 1; + }catch(ArithmeticException amExp) { + throw new Exception("我将被忽略,因为下面的finally中抛出了新的异常"); + }finally { + throw new Exception("我是finaly中的Exception"); } } - + + //try中的异常被抑制 + @SuppressWarnings("finally") + public static int bar() throws Exception + { + try { + int a = 5/0; + return 1; + }finally { + throw new Exception("我是finaly中的Exception"); + } + + } +} +```` 上面的3个例子都异于常人的编码思维,因此我建议: > 不要在fianlly中使用return。 @@ -782,22 +771,24 @@ finally中的异常会覆盖(消灭)前面try或者catch中的异常   下面是我个人总结的在Java和J2EE开发者在面试中经常被问到的有关Exception和Error的知识。在分享我的回答的时候,我也给这些问题作了快速修订,并且提供源码以便深入理解。我总结了各种难度的问题,适合新手码农和高级Java码农。如果你遇到了我列表中没有的问题,并且这个问题非常好,请在下面评论中分享出来。你也可以在评论中分享你面试时答错的情况。 **1) Java中什么是Exception?** -  这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问。我从来没见过面高级或者资深工程师的时候有人问这玩意,但是对于菜鸟,是很愿意问这个的。简单来说,异常是Java传达给你的系统和程序错误的方式。在java中,异常功能是通过实现比如Throwable,Exception,RuntimeException之类的类,然后还有一些处理异常时候的关键字,比如throw,throws,try,catch,finally之类的。 所有的异常都是通过Throwable衍生出来的。Throwable把错误进一步划分为 java.lang.Exception -和 java.lang.Error.  java.lang.Error 用来处理系统错误,例如java.lang.StackOverFlowError 之类的。然后 Exception用来处理程序错误,请求的资源不可用等等。 +这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问。我从来没见过面高级或者资深工程师的时候有人问这玩意,但是对于菜鸟,是很愿意问这个的。简单来说,异常是Java传达给你的系统和程序错误的方式。在java中,异常功能是通过实现比如Throwable,Exception,RuntimeException之类的类,然后还有一些处理异常时候的关键字,比如throw,throws,try,catch,finally之类的。所有的异常都是通过Throwable衍生出来的。Throwable把错误进一步划分为java.lang.Exception +和 java.lang.Error. + +java.lang.Error 用来处理系统错误,例如java.lang.StackOverFlowError 之类的。然后Exception用来处理程序错误,请求的资源不可用等等。 **2) Java中的检查型异常和非检查型异常有什么区别?** -  这又是一个非常流行的Java异常面试题,会出现在各种层次的Java面试中。检查型异常和非检查型异常的主要区别在于其处理方式。检查型异常需要使用try, catch和finally关键字在编译期进行处理,否则会出现编译器会报错。对于非检查型异常则不需要这样做。Java中所有继承自java.lang.Exception类的异常都是检查型异常,所有继承自RuntimeException的异常都被称为非检查型异常。 +这又是一个非常流行的Java异常面试题,会出现在各种层次的Java面试中。检查型异常和非检查型异常的主要区别在于其处理方式。检查型异常需要使用try, catch和finally关键字在编译期进行处理,否则会出现编译器会报错。对于非检查型异常则不需要这样做。Java中所有继承自java.lang.Exception类的异常都是检查型异常,所有继承自RuntimeException的异常都被称为非检查型异常。 **3) Java中的NullPointerException和ArrayIndexOutOfBoundException之间有什么相同之处?** -  在Java异常面试中这并不是一个很流行的问题,但会出现在不同层次的初学者面试中,用来测试应聘者对检查型异常和非检查型异常的概念是否熟悉。顺便说一下,该题的答案是,这两个异常都是非检查型异常,都继承自RuntimeException。该问题可能会引出另一个问题,即Java和C的数组有什么不同之处,因为C里面的数组是没有大小限制的,绝对不会抛出ArrayIndexOutOfBoundException。 +在Java异常面试中这并不是一个很流行的问题,但会出现在不同层次的初学者面试中,用来测试应聘者对检查型异常和非检查型异常的概念是否熟悉。顺便说一下,该题的答案是,这两个异常都是非检查型异常,都继承自RuntimeException。该问题可能会引出另一个问题,即Java和C的数组有什么不同之处,因为C里面的数组是没有大小限制的,绝对不会抛出ArrayIndexOutOfBoundException。 **4)在Java异常处理的过程中,你遵循的那些最好的实践是什么?** -  这个问题在面试技术经理是非常常见的一个问题。因为异常处理在项目设计中是非常关键的,所以精通异常处理是十分必要的。异常处理有很多最佳实践,下面列举集中,它们提高你代码的健壮性和灵活性: +这个问题在面试技术经理是非常常见的一个问题。因为异常处理在项目设计中是非常关键的,所以精通异常处理是十分必要的。异常处理有很多最佳实践,下面列举集中,它们提高你代码的健壮性和灵活性: -  1) 调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException。由于空指针是java异常里最恶心的异常 +  1) 调用方法的时候返回布尔值来代替返回null,这样可以NullPointerException。由于空指针是java异常里最恶心的异常   2) catch块里别不写代码。空catch块是异常处理里的错误事件,因为它只是捕获了异常,却没有任何处理或者提示。通常你起码要打印出异常信息,当然你最好根据需求对异常信息进行处理。 @@ -809,32 +800,20 @@ finally中的异常会覆盖(消灭)前面try或者catch中的异常 **5) 既然我们可以用RuntimeException来处理错误,那么你认为为什么Java中还存在检查型异常?** -  这是一个有争议的问题,在回答该问题时你应当小心。虽然他们肯定愿意听到你的观点,但其实他们最感兴趣的还是有说服力的理由。我认为其中一个理由是,存在检查型异常是一个设计上的决定,受到了诸如C++等比Java更早编程语言设计经验的影响。绝大多数检查型异常位于java.io包内,这是合乎情理的,因为在你请求了不存在的系统资源的时候,一段强壮的程序必须能够优雅的处理这种情况。通过把IOException声明为检查型异常,Java 确保了你能够优雅的对异常进行处理。另一个可能的理由是,可以使用catch或finally来确保数量受限的系统资源(比如文件描述符)在你使用后尽早得到释放。 Joshua -Bloch编写的 [Effective Java 一书](http://www.amazon.com/dp/0321356683/?tag=javamysqlanta-20) 中多处涉及到了该话题,值得一读。 - -**6)  throw 和 throws这两个关键字在java中有什么不同?** - -  一个java初学者应该掌握的面试问题。 throw 和 throws乍看起来是很相似的尤其是在你还是一个java初学者的时候。尽管他们看起来相似,都是在处理异常时候使用到的。但在代码里的使用方法和用到的地方是不同的。throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常, 你也可以申明未检查的异常,但这不是编译器强制的。如果方法抛出了异常那么调用这个方法的时候就需要将这个异常处理。另一个关键字  throw 是用来抛出任意异常的,按照语法你可以抛出任意 Throwable (i.e. Throwable -或任何Throwable的衍生类) , throw可以中断程序运行,因此可以用来代替return . 最常见的例子是用 throw 在一个空方法中需要return的地方抛出 UnSupportedOperationException 代码如下 : - - - - - -| 123 | `private``static` `void` `show() {``throw``new` `UnsupportedOperationException(``"Notyet implemented"``);``}` | -| --- | --- | - - - +这是一个有争议的问题,在回答该问题时你应当小心。虽然他们肯定愿意听到你的观点,但其实他们最感兴趣的还是有说服力的理由。我认为其中一个理由是,存在检查型异常是一个设计上的决定,受到了诸如C++等比Java更早编程语言设计经验的影响。绝大多数检查型异常位于java.io包内,这是合乎情理的,因为在你请求了不存在的系统资源的时候,一段强壮的程序必须能够优雅的处理这种情况。通过把IOException声明为检查型异常,Java 确保了你能够优雅的对异常进行处理。另一个可能的理由是,可以使用catch或finally来确保数量受限的系统资源(比如文件描述符)在你使用后尽早得到释放。Joshua +Bloch编写的[Effective Java 一书](http://www.amazon.com/dp/0321356683/?tag=javamysqlanta-20)中多处涉及到了该话题,值得一读。 +**6) throw 和 throws这两个关键字在java中有什么不同?** -  可以看下这篇 [文章](http://javarevisited.blogspot.com/2012/02/difference-between-throw-and-throws-in.html)查看这两个关键字在java中更多的差异 。 +  一个java初学者应该掌握的面试问题。throw 和 throws乍看起来是很相似的尤其是在你还是一个java初学者的时候。尽管他们看起来相似,都是在处理异常时候使用到的。但在代码里的使用方法和用到的地方是不同的。throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常, 你也可以申明未检查的异常,但这不是编译器强制的。如果方法抛出了异常那么调用这个方法的时候就需要将这个异常处理。另一个关键字 throw 是用来抛出任意异常的,按照语法你可以抛出任意 Throwable(i.e. Throwable +或任何Throwable的衍生类) , throw可以中断程序运行,因此可以用来代替return . 最常见的例子是用 throw 在一个空方法中需要return的地方抛出 UnSupportedOperationException. +可以看下这篇[文章](http://javarevisited.blogspot.com/2012/02/difference-between-throw-and-throws-in.html)查看这两个关键字在java中更多的差异 。 **7) 什么是“异常链”?**   “异常链”是Java中非常流行的异常处理概念,是指在进行一个异常处理时抛出了另外一个异常,由此产生了一个异常链条。该技术大多用于将“ 受检查异常” ( checked exception)封装成为“非受检查异常”(unchecked exception)或者RuntimeException。顺便说一下,如果因为因为异常你决定抛出一个新的异常,你一定要包含原有的异常,这样,处理程序才可以通过getCause()和initCause()方法来访问异常最终的根源。 -**) 你曾经自定义实现过异常吗?怎么写的?** +**8) 你曾经自定义实现过异常吗?怎么写的?**   很显然,我们绝大多数都写过自定义或者业务异常,像AccountNotFoundException。在面试过程中询问这个Java异常问题的主要原因是去发现你如何使用这个特性的。这可以更准确和精致的去处理异常,当然这也跟你选择checked 还是unchecked exception息息相关。通过为每一个特定的情况创建一个特定的异常,你就为调用者更好的处理异常提供了更好的选择。相比通用异常(general exception),我更倾向更为精确的异常。大量的创建自定义异常会增加项目class的个数,因此,在自定义异常和通用异常之间维持一个平衡是成功的关键。 diff --git "a/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" "b/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" index 1af4d91..02ace9b 100644 --- "a/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" +++ "b/docs/java/basic/11\343\200\201\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" @@ -11,18 +11,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - - ---- -title: 夯实Java基础系列11:深入理解Java中的回调机制 -date: 2019-9-11 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - 回调机制 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -73,49 +61,49 @@ tags: Java多线程中可以通过callable和future或futuretask结合来获取线程执行后的返回值。实现方法是通过get方法来调用callable的call方法获取返回值。 其实这种方法本质上不是回调,回调要求的是任务完成以后被调用者主动回调调用者的接口。而这里是调用者主动使用get方法阻塞获取返回值。 - - public class 多线程中的回调 { - //这里简单地使用future和callable实现了线程执行完后 - public static void main(String[] args) throws ExecutionException, InterruptedException { - ExecutorService executor = Executors.newCachedThreadPool(); - Future future = executor.submit(new Callable() { - @Override - public String call() throws Exception { - System.out.println("call"); - TimeUnit.SECONDS.sleep(1); - return "str"; - } - }); - //手动阻塞调用get通过call方法获得返回值。 - System.out.println(future.get()); - //需要手动关闭,不然线程池的线程会继续执行。 - executor.shutdown(); - - //使用futuretask同时作为线程执行单元和数据请求单元。 - FutureTask futureTask = new FutureTask(new Callable() { +```` +public class 多线程中的回调 { + //这里简单地使用future和callable实现了线程执行完后 + public static void main(String[] args) throws ExecutionException, InterruptedException { + ExecutorService executor = Executors.newCachedThreadPool(); + Future future = executor.submit(new Callable() { @Override - public Integer call() throws Exception { - System.out.println("dasds"); - return new Random().nextInt(); + public String call() throws Exception { + System.out.println("call"); + TimeUnit.SECONDS.sleep(1); + return "str"; } }); - new Thread(futureTask).start(); - //阻塞获取返回值 - System.out.println(futureTask.get()); - } - @Test - public void test () { - Callable callable = new Callable() { - @Override - public Object call() throws Exception { - return null; - } - }; - FutureTask futureTask = new FutureTask(callable); + //手动阻塞调用get通过call方法获得返回值。 + System.out.println(future.get()); + //需要手动关闭,不然线程池的线程会继续执行。 + executor.shutdown(); - } - } + //使用futuretask同时作为线程执行单元和数据请求单元。 + FutureTask futureTask = new FutureTask(new Callable() { + @Override + public Integer call() throws Exception { + System.out.println("dasds"); + return new Random().nextInt(); + } + }); + new Thread(futureTask).start(); + //阻塞获取返回值 + System.out.println(futureTask.get()); +} +@Test +public void test () { + Callable callable = new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }; + FutureTask futureTask = new FutureTask(callable); +} +} +```` ## Java回调机制实战 曾经自己偶尔听说过回调机制,隐隐约约能够懂一些意思,但是当让自己写一个简单的示例程序时,自己就傻眼了。随着工作经验的增加,自己经常听到这儿使用了回调,那儿使用了回调,自己是时候好好研究一下Java回调机制了。网上关于Java回调的文章一抓一大把,但是看完总是云里雾里,不知所云,特别是看到抓取别人的代码走两步时,总是现眼。于是自己决定写一篇关于Java机制的文章,以方便大家和自己更深入的学习Java回调机制。 @@ -138,22 +126,12 @@ Java多线程中可以通过callable和future或futuretask结合来获取线程 同步调用时序图: - - - - -![](https://upload-images.jianshu.io/upload_images/3796264-6a5b5b898aa3930e.png?imageMogr2/auto-orient/strip|imageView2/2/w/1031/format/webp) - - - -同步调用时序图 - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403210703.png) **1.1.1 底层服务类:BottomService.java** -``` - +```` package synchronization.demo; /** @@ -182,11 +160,11 @@ return param +" BottomService.bottom() execute -->"; } -``` + **1.1.2 上层服务接口: UpperService.java** -``` + package synchronization.demo; /** @@ -203,11 +181,11 @@ public String callBottomService(final String param); } -``` + **1.1.3 上层服务接口实现类:UpperServiceImpl.java** -``` + package synchronization.demo; /** @@ -244,11 +222,11 @@ return bottomService.bottom(param + " callBottomService.bottom() execute --> "); } -``` + **1.1.4 Test测试类:Test.java** -``` + package synchronization.demo; import java.util.Date; @@ -281,7 +259,7 @@ System.out.println("=============== callBottomService end ====================:" } -``` +```` **1.1.5 输出结果:** @@ -306,37 +284,37 @@ callBottomService start --> callBottomService.bottom() execute --> BottomServi 解答:回调更像是一个约定,就是如果我调用了b()方法,那么就必须要回调,而不需要显示调用 一、Java的回调-浅 我们用例子来解释:小明和小李相约一起去吃早饭,但是小李起的有点晚要先洗漱,等小李洗漱完成后,通知小明再一起去吃饭。小明就是类A,小李就是类B。一起去吃饭这个事件就是方法a(),小李去洗漱就是方法b()。 - - public class XiaoMing { - //小明和小李一起吃饭 - public void eatFood() { - XiaoLi xl = new XiaoLi(); - //A调用B的方法 - xl.washFace(); - } - - public void eat() { - System.out.print("小明和小李一起去吃大龙虾"); - } - } - 那么怎么让小李洗漱完后在通知小明一起去吃饭呢 - - public class XiaoMing { - //小明和小李一起吃饭 - public void eatFood() { - XiaoLi xl = new XiaoLi(); - //A调用B的方法 - xl.washFace(); - eat(); - } - - public void eat() { - System.out.print("小明和小李一起去吃大龙虾"); - } - } - +```` +public class XiaoMing { + //小明和小李一起吃饭 + public void eatFood() { + XiaoLi xl = new XiaoLi(); + //A调用B的方法 + xl.washFace(); + } + + public void eat() { + System.out.print("小明和小李一起去吃大龙虾"); + } +} +那么怎么让小李洗漱完后在通知小明一起去吃饭呢 + +public class XiaoMing { + //小明和小李一起吃饭 + public void eatFood() { + XiaoLi xl = new XiaoLi(); + //A调用B的方法 + xl.washFace(); + eat(); + } + + public void eat() { + System.out.print("小明和小李一起去吃大龙虾"); + } +} +```` 不过上面已经说过了这个不是回调函数,所以不能这样子,正确的方式如下 - +```` public class XiaoLi{//小李 public void washFace() { System.out.print("小李要洗漱"); @@ -345,7 +323,7 @@ callBottomService start --> callBottomService.bottom() execute --> BottomServi xm.eat();//洗漱完后,一起去吃饭 } } - +```` 这样子就可以实现washFace()同时也能实现eat()。小李洗漱完后,再通知小明一起去吃饭,这就是回调。 二、Java的回调-中 @@ -354,50 +332,50 @@ callBottomService start --> callBottomService.bottom() execute --> BottomServi 小明和小李相约一起去吃早饭,但是小李起的有点晚要先洗漱,等小李洗漱完成后,通知小明再一起去吃饭。小明就是类A,小李就是类B。不同的是我们新建一个吃饭的接口EatRice,接口中有个抽象方法eat()。在小明中调用这个接口,并实现eat();小李声明这个接口对象,并且调用这个接口的抽象方法。这里可能有点绕口,不过没关系,看看例子就很清楚了。 EatRice接口: +```` +public interface EatRice { + public void eat(String food); +} +小明: - public interface EatRice { - public void eat(String food); - } - 小明: - - public class XiaoMing implements EatRice{//小明 - - //小明和小李一起吃饭 - public void eatFood() { - XiaoLi xl = new XiaoLi(); - //A调用B的方法 - xl.washFace("大龙虾", this);//this指的是小明这个类实现的EatRice接口 - } - - @Override - public void eat(String food) { - // TODO Auto-generated method stub - System.out.println("小明和小李一起去吃" + food); - } - } - 小李: - - public class XiaoLi{//小李 - public void washFace(String food,EatRice er) { - System.out.println("小李要洗漱"); - //B调用了A的方法 - er.eat(food); - } - } - 测试Demo: - - public class demo { - public static void main(String args[]) { - XiaoMing xm = new XiaoMing(); - xm.eatFood(); - } - } +public class XiaoMing implements EatRice{//小明 + //小明和小李一起吃饭 + public void eatFood() { + XiaoLi xl = new XiaoLi(); + //A调用B的方法 + xl.washFace("大龙虾", this);//this指的是小明这个类实现的EatRice接口 + } + + @Override + public void eat(String food) { + // TODO Auto-generated method stub + System.out.println("小明和小李一起去吃" + food); + } +} +小李: + +public class XiaoLi{//小李 + public void washFace(String food,EatRice er) { + System.out.println("小李要洗漱"); + //B调用了A的方法 + er.eat(food); + } +} +测试Demo: + +public class demo { + public static void main(String args[]) { + XiaoMing xm = new XiaoMing(); + xm.eatFood(); + } +} +```` 测试结果: 这样子就通过接口的形式实现了软编码。通过接口的形式我可以实现小李洗漱完后,和小王一起去上网。代码如下 - +```` public class XiaoWang implements EatRice{//小王 //小王和小李一起去上网 @@ -413,7 +391,7 @@ EatRice接口: System.out.println("小王和小李一起去" + bar); } } - +```` ## 实例三:Tom做题 数学老师让Tom做一道题,并且Tom做题期间数学老师不用盯着Tom,而是在玩手机,等Tom把题目做完后再把答案告诉老师。 @@ -425,64 +403,64 @@ EatRice接口: > 3 Tom需要数学老师的一个引用,以便Tom把答案给这位老师,而不是隔壁的体育老师。 回调接口,可以理解为老师接口 +```` +//回调指的是A调用B来做一件事,B做完以后将结果告诉给A,这期间A可以做别的事情。 +//这个接口中有一个方法,意为B做完题目后告诉A时使用的方法。 +//所以我们必须提供这个接口以便让B来回调。 +//回调接口, +public interface CallBack { + void tellAnswer(int res); +} +```` - //回调指的是A调用B来做一件事,B做完以后将结果告诉给A,这期间A可以做别的事情。 - //这个接口中有一个方法,意为B做完题目后告诉A时使用的方法。 - //所以我们必须提供这个接口以便让B来回调。 - //回调接口, - public interface CallBack { - void tellAnswer(int res); - } - - 数学老师类 - - //老师类实例化回调接口,即学生写完题目之后通过老师的提供的方法进行回调。 - //那么学生如何调用到老师的方法呢,只要在学生类的方法中传入老师的引用即可。 - //而老师需要指定学生答题,所以也要传入学生的实例。 - public class Teacher implements CallBack{ - private Student student; - - Teacher(Student student) { - this.student = student; - } - - void askProblem (Student student, Teacher teacher) { - //main方法是主线程运行,为了实现异步回调,这里开启一个线程来操作 - new Thread(new Runnable() { - @Override - public void run() { - student.resolveProblem(teacher); - } - }).start(); - //老师让学生做题以后,等待学生回答的这段时间,可以做别的事,比如玩手机.\ - //而不需要同步等待,这就是回调的好处。 - //当然你可以说开启一个线程让学生做题就行了,但是这样无法让学生通知老师。 - //需要另外的机制去实现通知过程。 - // 当然,多线程中的future和callable也可以实现数据获取的功能。 - for (int i = 1;i < 4;i ++) { - System.out.println("等学生回答问题的时候老师玩了 " + i + "秒的手机"); +```` + //老师类实例化回调接口,即学生写完题目之后通过老师的提供的方法进行回调。 + //那么学生如何调用到老师的方法呢,只要在学生类的方法中传入老师的引用即可。 + //而老师需要指定学生答题,所以也要传入学生的实例。 +public class Teacher implements CallBack{ + private Student student; + + Teacher(Student student) { + this.student = student; + } + + void askProblem (Student student, Teacher teacher) { + //main方法是主线程运行,为了实现异步回调,这里开启一个线程来操作 + new Thread(new Runnable() { + @Override + public void run() { + student.resolveProblem(teacher); } - } - - @Override - public void tellAnswer(int res) { - System.out.println("the answer is " + res); + }).start(); + //老师让学生做题以后,等待学生回答的这段时间,可以做别的事,比如玩手机.\ + //而不需要同步等待,这就是回调的好处。 + //当然你可以说开启一个线程让学生做题就行了,但是这样无法让学生通知老师。 + //需要另外的机制去实现通知过程。 + // 当然,多线程中的future和callable也可以实现数据获取的功能。 + for (int i = 1;i < 4;i ++) { + System.out.println("等学生回答问题的时候老师玩了 " + i + "秒的手机"); } } - -学生接口 + @Override + public void tellAnswer(int res) { + System.out.println("the answer is " + res); + } +} +```` +学生接口 +```` //学生的接口,解决问题的方法中要传入老师的引用,否则无法完成对具体实例的回调。 //写为接口的好处就是,很多个学生都可以实现这个接口,并且老师在提问题时可以通过 //传入List来聚合学生,十分方便。 public interface Student { void resolveProblem (Teacher teacher); } - +```` 学生Tom - +```` public class Tom implements Student{ @Override @@ -496,9 +474,9 @@ EatRice接口: e.printStackTrace(); } } - +```` 测试类 - +```` public class Test { public static void main(String[] args) { //测试 @@ -513,9 +491,7 @@ EatRice接口: // the answer is 111 } } - - - +```` ## 参考文章 https://blog.csdn.net/fengye454545/article/details/80198446 diff --git "a/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" "b/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" index 0513f67..4eb6669 100644 --- "a/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" +++ "b/docs/java/basic/12\343\200\201\345\217\215\345\260\204.md" @@ -25,16 +25,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列12:深入理解Java中的反射机制 -date: 2019-9-12 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java反射 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -61,11 +51,11 @@ Oracle官方对反射的解释是 > The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control. > ->  简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。 +> 简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。 > > 程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。 > ->  反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。 +> 反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。 Java反射框架主要提供以下功能: @@ -82,27 +72,15 @@ Java反射框架主要提供以下功能: ## 反射的主要用途 ->  很多人都认为反射在实际的Java开发应用中并不广泛,其实不然。 - ->  当我们在使用IDE(如Eclipse,IDEA)时,当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。 - ->  反射最重要的用途就是开发各种通用框架。 +> 很多人都认为反射在实际的Java开发应用中并不广泛,其实不然。 ->  很多框架(比如Spring)都是配置化的(比如通过XML文件配置JavaBean,Action之类的),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射——运行时动态加载需要加载的对象。 +> 当我们在使用IDE(如Eclipse,IDEA)时,当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。 ->  举一个例子,在运用Struts 2框架的开发中我们一般会在struts.xml里去配置Action,比如: +> 反射最重要的用途就是开发各种通用框架。 - - /shop/shop-index.jsp - login.jsp - -配置文件与Action建立了一种映射关系,当View层发出请求时,请求会被StrutsPrepareAndExecuteFilter拦截,然后StrutsPrepareAndExecuteFilter会去动态地创建Action实例。 +> 很多框架(比如Spring)都是配置化的(比如通过XML文件配置JavaBean,Action之类的),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射——运行时动态加载需要加载的对象。 -——比如我们请求login.action,那么StrutsPrepareAndExecuteFilter就会去解析struts.xml文件,检索action中name为login的Action,并根据class属性创建SimpleLoginAction实例,并用invoke方法来调用execute方法,这个过程离不开反射。 - -> 对与框架开发人员来说,反射虽小但作用非常大,它是各种容器实现的核心。而对于一般的开发者来说,不深入框架开发则用反射用的就会少一点,不过了解一下框架的底层机制有助于丰富自己的编程思想,也是很有益的。 +> 对于框架开发人员来说,反射虽小但作用非常大,它是各种容器实现的核心。而对于一般的开发者来说,不深入框架开发则用反射用的就会少一点,不过了解一下框架的底层机制有助于丰富自己的编程思想,也是很有益的。 ## 反射的基础:关于Class类 @@ -117,25 +95,26 @@ Java反射框架主要提供以下功能: > 4、Class 对象只能由系统建立对象 > > 5、一个类在 JVM 中只会有一个Class实例 - - //总结一下就是,JDK有一个类叫做Class,这个类用来封装所有Java类型,包括这些类的所有信息,JVM中类信息是放在方法区的。 - - //所有类在加载后,JVM会为其在堆中创建一个Class<类名称>的对象,并且每个类只会有一个Class对象,这个类的所有对象都要通过Class<类名称>来进行实例化。 - - //上面说的是JVM进行实例化的原理,当然实际上在Java写代码时只需要用 类名称就可以进行实例化了。 - - public final class Class implements java.io.Serializable, - GenericDeclaration, - Type, - AnnotatedElement { - 虚拟机会保持唯一一 - //通过类名.class获得唯一的Class对象。 - Class cls = UserBean.class; - //通过integer.TYPEl来获取Class对象 - Class inti = Integer.TYPE; - //接口本质也是一个类,一样可以通过.class获取 - Class userClass = User.class; - +> +```` +//总结一下就是,JDK有一个类叫做Class,这个类用来封装所有Java类型,包括这些类的所有信息,JVM中类信息是放在方法区的。 + +//所有类在加载后,JVM会为其在堆中创建一个Class<类名称>的对象,并且每个类只会有一个Class对象,这个类的所有对象都要通过Class<类名称>来进行实例化。 + +//上面说的是JVM进行实例化的原理,当然实际上在Java写代码时只需要用 类名称就可以进行实例化了。 + +public final class Class implements java.io.Serializable, + GenericDeclaration, + Type, + AnnotatedElement { + //通过类名.class获得唯一的Class对象。 + Class cls = UserBean.class; + //通过integer.TYPEl来获取Class对象 + Class inti = Integer.TYPE; + //接口本质也是一个类,一样可以通过.class获取 + Class userClass = User.class; +} +```` JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象. @@ -146,8 +125,7 @@ JAVA反射机制是在运行状态中,对于任意一个类,都能够知道 如图是类的正常加载过程:反射的原理在与class对象。 熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。 -![](https://img-blog.csdn.net/20170513133210763) - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403211245.png) ## Java为什么需要反射?反射要解决什么问题? Java中编译类型有两种: @@ -176,29 +154,31 @@ Array类:提供了动态创建数组,以及访问数组的元素的静态方 1、获得Class对象方法有三种 (1)使用Class类的forName静态方法: - - public static Class forName(String className) - ``` - 在JDBC开发中常用此方法加载数据库驱动: - 要使用全类名来加载这个类,一般数据库驱动的配置信息会写在配置文件中。加载这个驱动前要先导入jar包 - ```java - Class.forName(driver); +```` +public static Class forName(String className) +```` +在JDBC开发中常用此方法加载数据库驱动: +要使用全类名来加载这个类,一般数据库驱动的配置信息会写在配置文件中。加载这个驱动前要先导入jar包 +```` +Class.forName(driver); +```` (2)直接获取某一个对象的class,比如: - - //Class是一个泛型表示,用于获取一个类的类型。 - Class klass = int.class; - Class classInt = Integer.TYPE; +```` +//Class是一个泛型表示,用于获取一个类的类型。 +Class klass = int.class; +Class classInt = Integer.TYPE; +```` (3)调用某个对象的getClass()方法,比如: - - StringBuilder str = new StringBuilder("123"); - Class klass = str.getClass(); - +```` +StringBuilder str = new StringBuilder("123"); +Class klass = str.getClass(); +```` ## 判断是否为某个类的实例 一般地,我们用instanceof关键字来判断是否为某个类的实例。同时我们也可以借助反射中Class对象的isInstance()方法来判断是否为某个类的实例,它是一个Native方法: - -==public native boolean isInstance(Object obj);== - +```` +public native boolean isInstance(Object obj); +```` ## 创建实例 通过反射来生成对象主要有两种方式。 @@ -206,20 +186,20 @@ Array类:提供了动态创建数组,以及访问数组的元素的静态方 (1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。 注意:利用newInstance创建对象:调用的类必须有无参的构造器 - - //Class代表任何类的一个类对象。 - //使用这个类对象可以为其他类进行实例化 - //因为jvm加载类以后自动在堆区生成一个对应的*.Class对象 - //该对象用于让JVM对进行所有*对象实例化。 - Class c = String.class; - - //Class 中的 ? 是通配符,其实就是表示任意符合泛类定义条件的类,和直接使用 Class - //效果基本一致,但是这样写更加规范,在某些类型转换时可以避免不必要的 unchecked 错误。 - - Object str = c.newInstance(); - +```` +//Class代表任何类的一个类对象。 +//使用这个类对象可以为其他类进行实例化 +//因为jvm加载类以后自动在堆区生成一个对应的*.Class对象 +//该对象用于让JVM对进行所有*对象实例化。 +Class c = String.class; + +//Class 中的 ? 是通配符,其实就是表示任意符合泛类定义条件的类,和直接使用 Class +//效果基本一致,但是这样写更加规范,在某些类型转换时可以避免不必要的 unchecked 错误。 + +Object str = c.newInstance(); +```` (2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。 - +```` //获取String所对应的Class对象 Class c = String.class; //获取String类带一个String参数的构造器 @@ -227,33 +207,35 @@ Array类:提供了动态创建数组,以及访问数组的元素的静态方 //根据构造器创建实例 Object obj = constructor.newInstance("23333"); System.out.println(obj); - +```` ## 获取方法 获取某个Class对象的方法集合,主要有以下几个方法: getDeclaredMethods()方法返回类或接口声明的所有方法,==包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法==。 - - public Method[] getDeclaredMethods() throws SecurityException - +```` +public Method[] getDeclaredMethods() throws SecurityException +```` getMethods()方法返回某个类的所有公用(public)方法,==包括其继承类的公用方法。== - - public Method[] getMethods() throws SecurityException +```` +public Method[] getMethods() throws SecurityException +```` getMethod方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象 - - - public Method getMethod(String name, Class... parameterTypes) +```` +public Method getMethod(String name, Class... parameterTypes) +```` 只是这样描述的话可能难以理解,我们用例子来理解这三个方法: 本文中的例子用到了以下这些类,用于反射的测试。 +```` //注解类,可可用于表示方法,可以通过反射获取注解的内容。 //Java注解的实现是很多注框架实现注解配置的基础 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Invoke { } - +```` userbean的父类personbean - +```` public class PersonBean { private String name; @@ -266,20 +248,17 @@ userbean的父类personbean public void setName(String name) { this.name = name; } - - -​ } - +```` 接口user - +```` public interface User { public void login (); } - +```` userBean实现user接口,继承personbean - +```` public class UserBean extends PersonBean implements User{ @Override public void login() { @@ -318,100 +297,100 @@ userBean实现user接口,继承personbean System.out.println("I'm a private method"); } } - +```` 1 getMethods和getDeclaredMethods的区别 - - public class 动态加载类的反射 { - public static void main(String[] args) { - try { - Class clazz = Class.forName("com.javase.反射.UserBean"); - for (Field field : clazz.getDeclaredFields()) { - // field.setAccessible(true); - System.out.println(field); - } - //getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 - System.out.println("------共有方法------"); - // getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 - // getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。 - for (Method method : clazz.getMethods()) { - String name = method.getName(); - System.out.println(name); - //打印出了UserBean.java的所有方法以及父类的方法 - } - System.out.println("------独占方法------"); - - for (Method method : clazz.getDeclaredMethods()) { - String name = method.getName(); - System.out.println(name); - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); +```` +public class 动态加载类的反射 { + public static void main(String[] args) { + try { + Class clazz = Class.forName("com.javase.反射.UserBean"); + for (Field field : clazz.getDeclaredFields()) { +// field.setAccessible(true); + System.out.println(field); + } + //getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 + System.out.println("------共有方法------"); +// getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 +// getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。 + for (Method method : clazz.getMethods()) { + String name = method.getName(); + System.out.println(name); + //打印出了UserBean.java的所有方法以及父类的方法 + } + System.out.println("------独占方法------"); + + for (Method method : clazz.getDeclaredMethods()) { + String name = method.getName(); + System.out.println(name); } + } catch (ClassNotFoundException e) { + e.printStackTrace(); } } +} - +```` 2 打印一个类的所有方法及详细信息: - - public class 打印所有方法 { - - public static void main(String[] args) { - Class userBeanClass = UserBean.class; - Field[] fields = userBeanClass.getDeclaredFields(); - //注意,打印方法时无法得到局部变量的名称,因为jvm只知道它的类型 - Method[] methods = userBeanClass.getDeclaredMethods(); - for (Method method : methods) { - //依次获得方法的修饰符,返回类型和名称,外加方法中的参数 - String methodString = Modifier.toString(method.getModifiers()) + " " ; // private static - methodString += method.getReturnType().getSimpleName() + " "; // void - methodString += method.getName() + "("; // staticMethod - Class[] parameters = method.getParameterTypes(); - Parameter[] p = method.getParameters(); - - for (Class parameter : parameters) { - methodString += parameter.getSimpleName() + " " ; // String - } - methodString += ")"; - System.out.println(methodString); +```` +public class 打印所有方法 { + + public static void main(String[] args) { + Class userBeanClass = UserBean.class; + Field[] fields = userBeanClass.getDeclaredFields(); + //注意,打印方法时无法得到局部变量的名称,因为jvm只知道它的类型 + Method[] methods = userBeanClass.getDeclaredMethods(); + for (Method method : methods) { + //依次获得方法的修饰符,返回类型和名称,外加方法中的参数 + String methodString = Modifier.toString(method.getModifiers()) + " " ; // private static + methodString += method.getReturnType().getSimpleName() + " "; // void + methodString += method.getName() + "("; // staticMethod + Class[] parameters = method.getParameterTypes(); + Parameter[] p = method.getParameters(); + + for (Class parameter : parameters) { + methodString += parameter.getSimpleName() + " " ; // String } - //注意方法只能获取到其类型,拿不到变量名 - /* public String getName() - public long getId() - public static void staticMethod(String int ) - public void publicMethod() - private void privateMethod()*/ + methodString += ")"; + System.out.println(methodString); } + //注意方法只能获取到其类型,拿不到变量名 +/* public String getName() + public long getId() + public static void staticMethod(String int ) + public void publicMethod() + private void privateMethod()*/ } - +} +```` ## 获取构造器信息 获取类构造器的用法与上述获取方法的用法类似。主要是通过Class类的getConstructor方法得到Constructor类的一个实例,而Constructor类有一个newInstance方法可以创建一个对象实例: - - public class 打印构造方法 { - public static void main(String[] args) { - // constructors - Class clazz = UserBean.class; - - Class userBeanClass = UserBean.class; - //获得所有的构造方法 - Constructor[] constructors = userBeanClass.getDeclaredConstructors(); - for (Constructor constructor : constructors) { - String s = Modifier.toString(constructor.getModifiers()) + " "; - s += constructor.getName() + "("; - //构造方法的参数类型 - Class[] parameters = constructor.getParameterTypes(); - for (Class parameter : parameters) { - s += parameter.getSimpleName() + ", "; - } - s += ")"; - System.out.println(s); - //打印结果//public com.javase.反射.UserBean(String, long, ) - +```` +public class 打印构造方法 { + public static void main(String[] args) { + // constructors + Class clazz = UserBean.class; + + Class userBeanClass = UserBean.class; + //获得所有的构造方法 + Constructor[] constructors = userBeanClass.getDeclaredConstructors(); + for (Constructor constructor : constructors) { + String s = Modifier.toString(constructor.getModifiers()) + " "; + s += constructor.getName() + "("; + //构造方法的参数类型 + Class[] parameters = constructor.getParameterTypes(); + for (Class parameter : parameters) { + s += parameter.getSimpleName() + ", "; } + s += ")"; + System.out.println(s); + //打印结果//public com.javase.反射.UserBean(String, long, ) + } } - +} +```` ## 获取类的成员变量(字段)信息 主要是这几个方法,在此不再赘述: @@ -419,140 +398,138 @@ getFiled: 访问公有的成员变量 getDeclaredField:所有已声明的成员变量。但不能得到其父类的成员变量 getFileds和getDeclaredFields用法同上(参照Method) - public class 打印成员变量 { - public static void main(String[] args) { - Class userBeanClass = UserBean.class; - //获得该类的所有成员变量,包括static private - Field[] fields = userBeanClass.getDeclaredFields(); - - for(Field field : fields) { - //private属性即使不用下面这个语句也可以访问 - // field.setAccessible(true); - - //因为类的私有域在反射中默认可访问,所以flag默认为true。 - String fieldString = ""; - fieldString += Modifier.toString(field.getModifiers()) + " "; // `private` - fieldString += field.getType().getSimpleName() + " "; // `String` - fieldString += field.getName(); // `userName` - fieldString += ";"; - System.out.println(fieldString); - - //打印结果 - // public String userName; - // protected int i; - // static int j; - // private int l; - // private long userId; - } - +```` +public class 打印成员变量 { + public static void main(String[] args) { + Class userBeanClass = UserBean.class; + //获得该类的所有成员变量,包括static private + Field[] fields = userBeanClass.getDeclaredFields(); + + for(Field field : fields) { + //private属性即使不用下面这个语句也可以访问 +// field.setAccessible(true); + + //因为类的私有域在反射中默认可访问,所以flag默认为true。 + String fieldString = ""; + fieldString += Modifier.toString(field.getModifiers()) + " "; // `private` + fieldString += field.getType().getSimpleName() + " "; // `String` + fieldString += field.getName(); // `userName` + fieldString += ";"; + System.out.println(fieldString); + + //打印结果 +// public String userName; +// protected int i; +// static int j; +// private int l; +// private long userId; } - } + } +} +```` ## 调用方法 当我们从类中获取了一个方法后,我们就可以用invoke()方法来调用这个方法。invoke方法的原型为: - - public Object invoke(Object obj, Object... args) - throws IllegalAccessException, IllegalArgumentException, - InvocationTargetException - - public class 使用反射调用方法 { - public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { - Class userBeanClass = UserBean.class; - //获取该类所有的方法,包括静态方法,实例方法。 - //此处也包括了私有方法,只不过私有方法在用invoke访问之前要设置访问权限 - //也就是使用setAccessible使方法可访问,否则会抛出异常 - // // IllegalAccessException的解释是 - // * An IllegalAccessException is thrown when an application tries - // * to reflectively create an instance (other than an array), - // * set or get a field, or invoke a method, but the currently - // * executing method does not have access to the definition of - // * the specified class, field, method or constructor. - - // getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 - // getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。 - - //就是说,当这个类,域或者方法被设为私有访问,使用反射调用但是却没有权限时会抛出异常。 - Method[] methods = userBeanClass.getDeclaredMethods(); // 获取所有成员方法 - for (Method method : methods) { - //反射可以获取方法上的注解,通过注解来进行判断 - if (method.isAnnotationPresent(Invoke.class)) { // 判断是否被 @Invoke 修饰 - //判断方法的修饰符是是static - if (Modifier.isStatic(method.getModifiers())) { // 如果是 static 方法 - //反射调用该方法 - //类方法可以直接调用,不必先实例化 - method.invoke(null, "wingjay",2); // 直接调用,并传入需要的参数 devName - } else { - //如果不是类方法,需要先获得一个实例再调用方法 - //传入构造方法需要的变量类型 - Class[] params = {String.class, long.class}; - //获取该类指定类型的构造方法 - //如果没有这种类型的方法会报错 - Constructor constructor = userBeanClass.getDeclaredConstructor(params); // 获取参数格式为 String,long 的构造函数 - //通过构造方法的实例来进行实例化 - Object userBean = constructor.newInstance("wingjay", 11); // 利用构造函数进行实例化,得到 Object - if (Modifier.isPrivate(method.getModifiers())) { - method.setAccessible(true); // 如果是 private 的方法,需要获取其调用权限 - // Set the {@code accessible} flag for this object to - // * the indicated boolean value. A value of {@code true} indicates that - // * the reflected object should suppress Java language access - // * checking when it is used. A value of {@code false} indicates - // * that the reflected object should enforce Java language access checks. - //通过该方法可以设置其可见或者不可见,不仅可以用于方法 - //后面例子会介绍将其用于成员变量 - //打印结果 - // I'm a public method - // Hi wingjay, I'm a static methodI'm a private method - } - method.invoke(userBean); // 调用 method,无须参数 - - -​ - +```` +public Object invoke(Object obj, Object... args) + throws IllegalAccessException, IllegalArgumentException, + InvocationTargetException + +public class 使用反射调用方法 { + public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + Class userBeanClass = UserBean.class; + //获取该类所有的方法,包括静态方法,实例方法。 + //此处也包括了私有方法,只不过私有方法在用invoke访问之前要设置访问权限 + //也就是使用setAccessible使方法可访问,否则会抛出异常 +// // IllegalAccessException的解释是 +// * An IllegalAccessException is thrown when an application tries +// * to reflectively create an instance (other than an array), +// * set or get a field, or invoke a method, but the currently +// * executing method does not have access to the definition of +// * the specified class, field, method or constructor. + +// getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。 +// getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。 + + //就是说,当这个类,域或者方法被设为私有访问,使用反射调用但是却没有权限时会抛出异常。 + Method[] methods = userBeanClass.getDeclaredMethods(); // 获取所有成员方法 + for (Method method : methods) { + //反射可以获取方法上的注解,通过注解来进行判断 + if (method.isAnnotationPresent(Invoke.class)) { // 判断是否被 @Invoke 修饰 + //判断方法的修饰符是是static + if (Modifier.isStatic(method.getModifiers())) { // 如果是 static 方法 + //反射调用该方法 + //类方法可以直接调用,不必先实例化 + method.invoke(null, "wingjay",2); // 直接调用,并传入需要的参数 devName + } else { + //如果不是类方法,需要先获得一个实例再调用方法 + //传入构造方法需要的变量类型 + Class[] params = {String.class, long.class}; + //获取该类指定类型的构造方法 + //如果没有这种类型的方法会报错 + Constructor constructor = userBeanClass.getDeclaredConstructor(params); // 获取参数格式为 String,long 的构造函数 + //通过构造方法的实例来进行实例化 + Object userBean = constructor.newInstance("wingjay", 11); // 利用构造函数进行实例化,得到 Object + if (Modifier.isPrivate(method.getModifiers())) { + method.setAccessible(true); // 如果是 private 的方法,需要获取其调用权限 +// Set the {@code accessible} flag for this object to +// * the indicated boolean value. A value of {@code true} indicates that +// * the reflected object should suppress Java language access +// * checking when it is used. A value of {@code false} indicates +// * that the reflected object should enforce Java language access checks. + //通过该方法可以设置其可见或者不可见,不仅可以用于方法 + //后面例子会介绍将其用于成员变量 + //打印结果 +// I'm a public method +// Hi wingjay, I'm a static methodI'm a private method } + method.invoke(userBean); // 调用 method,无须参数 } } } } - +} +```` ## 利用反射创建数组 数组在Java里是比较特殊的一种类型,它可以赋值给一个Object Reference。下面我们看一看利用反射创建数组的例子: - - public class 用反射创建数组 { - public static void main(String[] args) { - Class cls = null; - try { - cls = Class.forName("java.lang.String"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - Object array = Array.newInstance(cls,25); - //往数组里添加内容 - Array.set(array,0,"hello"); - Array.set(array,1,"Java"); - Array.set(array,2,"fuck"); - Array.set(array,3,"Scala"); - Array.set(array,4,"Clojure"); - //获取某一项的内容 - System.out.println(Array.get(array,3)); - //Scala +```` +public class 用反射创建数组 { + public static void main(String[] args) { + Class cls = null; + try { + cls = Class.forName("java.lang.String"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); } - + Object array = Array.newInstance(cls,25); + //往数组里添加内容 + Array.set(array,0,"hello"); + Array.set(array,1,"Java"); + Array.set(array,2,"fuck"); + Array.set(array,3,"Scala"); + Array.set(array,4,"Clojure"); + //获取某一项的内容 + System.out.println(Array.get(array,3)); + //Scala } +} +```` 其中的Array类为java.lang.reflect.Array类。我们通过Array.newInstance()创建数组对象,它的原型是: - - public static Object newInstance(Class componentType, int length) - throws NegativeArraySizeException { - return newArray(componentType, length); +```` +public static Object newInstance(Class componentType, int length) + throws NegativeArraySizeException { + return newArray(componentType, length); } +```` 而newArray()方法是一个Native方法,它在Hotspot JVM里的具体实现我们后边再研究,这里先把源码贴出来 +```` +private static native Object newArray(Class componentType, int length) + throws NegativeArraySizeException; - private static native Object newArray(Class componentType, int length) - throws NegativeArraySizeException; - - -​ +```` + ## Java反射常见面试题 diff --git "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" index 2251e75..d71286f 100644 --- "a/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" +++ "b/docs/java/basic/13\343\200\201\346\263\233\345\236\213.md" @@ -44,48 +44,45 @@ > > 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。 - - ### 一个栗子 一个被举了无数次的例子: - - List arrayList = new ArrayList(); - arrayList.add("aaaa"); - arrayList.add(100); - - for(int i = 0; i< arrayList.size();i++){ - String item = (String)arrayList.get(i); - Log.d("泛型测试","item = " + item); - } - +```` +List arrayList = new ArrayList(); +arrayList.add("aaaa"); +arrayList.add(100); + +for(int i = 0; i< arrayList.size();i++){ + String item = (String)arrayList.get(i); + Log.d("泛型测试","item = " + item); +} +```` 毫无疑问,程序的运行结果会以崩溃结束: -java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String + java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String ArrayList可以存放任意类型,例子中添加了一个String类型,添加了一个Integer类型,再使用时都以String的方式使用,因此程序崩溃了。为了解决类似这样的问题(在编译阶段就可以解决),泛型应运而生。 我们将第一行声明初始化list的代码更改一下,编译器会在编译阶段就能够帮我们发现类似这样的问题。 - +```` List arrayList = new ArrayList(); ... //arrayList.add(100); 在编译阶段,编译器就会报错 - +```` ### 特性 泛型只在编译阶段有效。看下面的代码: +```` +List stringArrayList = new ArrayList(); +List integerArrayList = new ArrayList(); - List stringArrayList = new ArrayList(); - List integerArrayList = new ArrayList(); - - Class classStringArrayList = stringArrayList.getClass(); - Class classIntegerArrayList = integerArrayList.getClass(); - - if(classStringArrayList.equals(classIntegerArrayList)){ - Log.d("泛型测试","类型相同"); - } - +Class classStringArrayList = stringArrayList.getClass(); +Class classIntegerArrayList = integerArrayList.getClass(); +if(classStringArrayList.equals(classIntegerArrayList)){ + Log.d("泛型测试","类型相同"); +} +```` > 通过上面的例子可以证明,在编译之后程序会采取去泛型化的措施。也就是说Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。 > 对此总结成一句话:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。 @@ -101,49 +98,49 @@ List arrayList = new ArrayList(); > 泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,如:List、Set、Map。 > > 泛型类的最基本写法(这么看可能会有点晕,会在下面的例子中详解): - +```` class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{ private 泛型标识 /*(成员变量类型)*/ var; ..... } - +```` 一个最普通的泛型类: //此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 +```` +//在实例化泛型类时,必须指定T的具体类型 +public class Generic{ + //在类中声明的泛型整个类里面都可以用,除了静态部分,因为泛型是实例化时声明的。 + //静态区域的代码在编译时就已经确定,只与类相关 + class A { + T t; + } + //类里面的方法或类中再次声明同名泛型是允许的,并且该泛型会覆盖掉父类的同名泛型T + class B { + T t; + } + //静态内部类也可以使用泛型,实例化时赋予泛型实际类型 + static class C { + T t; + } + public static void main(String[] args) { + //报错,不能使用T泛型,因为泛型T属于实例不属于类 +// T t = null; + } - //在实例化泛型类时,必须指定T的具体类型 - public class Generic{ - //在类中声明的泛型整个类里面都可以用,除了静态部分,因为泛型是实例化时声明的。 - //静态区域的代码在编译时就已经确定,只与类相关 - class A { - T t; - } - //类里面的方法或类中再次声明同名泛型是允许的,并且该泛型会覆盖掉父类的同名泛型T - class B { - T t; - } - //静态内部类也可以使用泛型,实例化时赋予泛型实际类型 - static class C { - T t; - } - public static void main(String[] args) { - //报错,不能使用T泛型,因为泛型T属于实例不属于类 - // T t = null; - } - - //key这个成员变量的类型为T,T的类型由外部指定 - private T key; - - public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定 - this.key = key; - } - - public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定 - return key; - } + //key这个成员变量的类型为T,T的类型由外部指定 + private T key; + + public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定 + this.key = key; } + public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定 + return key; + } +} +```` > 12-27 09:20:04.432 13063-13063/? D/泛型测试: key is 123456 > 12-27 09:20:04.432 13063-13063/? D/泛型测试: key is key_vlaue @@ -151,22 +148,22 @@ List arrayList = new ArrayList(); > 定义的泛型类,就一定要传入泛型类型实参么?并不是这样,在使用泛型的时候如果传入泛型实参,则会根据传入的泛型实参做相应的限制,此时泛型才会起到本应起到的限制作用。如果不传入泛型类型实参的话,在泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型。 看一个例子: - - Generic generic = new Generic("111111"); - Generic generic1 = new Generic(4444); - Generic generic2 = new Generic(55.55); - Generic generic3 = new Generic(false); - - Log.d("泛型测试","key is " + generic.getKey()); - Log.d("泛型测试","key is " + generic1.getKey()); - Log.d("泛型测试","key is " + generic2.getKey()); - Log.d("泛型测试","key is " + generic3.getKey()); - - D/泛型测试: key is 111111 - D/泛型测试: key is 4444 - D/泛型测试: key is 55.55 - D/泛型测试: key is false - +```` +Generic generic = new Generic("111111"); +Generic generic1 = new Generic(4444); +Generic generic2 = new Generic(55.55); +Generic generic3 = new Generic(false); + +Log.d("泛型测试","key is " + generic.getKey()); +Log.d("泛型测试","key is " + generic1.getKey()); +Log.d("泛型测试","key is " + generic2.getKey()); +Log.d("泛型测试","key is " + generic3.getKey()); + +D/泛型测试: key is 111111 +D/泛型测试: key is 4444 +D/泛型测试: key is 55.55 +D/泛型测试: key is false +```` 注意: 泛型的类型参数只能是类类型,不能是简单类型。 不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错。 @@ -176,78 +173,78 @@ List arrayList = new ArrayList(); ### 泛型接口 泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中,可以看一个例子: - - //定义一个泛型接口 - public interface Generator { - public T next(); - } - +```` +//定义一个泛型接口 +public interface Generator { + public T next(); +} +```` 当实现泛型接口的类,未传入泛型实参时: - - /** - * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中 - * 即:class FruitGenerator implements Generator{ - * 如果不声明泛型,如:class FruitGenerator implements Generator,编译器会报错:"Unknown class" - */ - class FruitGenerator implements Generator{ - @Override - public T next() { - return null; - } +```` +/** + * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中 + * 即:class FruitGenerator implements Generator{ + * 如果不声明泛型,如:class FruitGenerator implements Generator,编译器会报错:"Unknown class" + */ +class FruitGenerator implements Generator{ + @Override + public T next() { + return null; } - +} +```` 当实现泛型接口的类,传入泛型实参时: - - /** - * 传入泛型实参时: - * 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator - * 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。 - * 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型 - * 即:Generator,public T next();中的的T都要替换成传入的String类型。 - */ - public class FruitGenerator implements Generator { - - private String[] fruits = new String[]{"Apple", "Banana", "Pear"}; - - @Override - public String next() { - Random rand = new Random(); - return fruits[rand.nextInt(3)]; - } +```` +/** + * 传入泛型实参时: + * 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator + * 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。 + * 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型 + * 即:Generator,public T next();中的的T都要替换成传入的String类型。 + */ +public class FruitGenerator implements Generator { + + private String[] fruits = new String[]{"Apple", "Banana", "Pear"}; + + @Override + public String next() { + Random rand = new Random(); + return fruits[rand.nextInt(3)]; } - +} +```` ### 泛型通配符 我们知道Ingeter是Number的一个子类,同时在特性章节中我们也验证过Generic与Generic实际上是相同的一种基本类型。那么问题来了,在使用Generic作为形参的方法中,能否使用Generic的实例传入呢?在逻辑上类似于Generic和Generic是否可以看成具有父子关系的泛型类型呢? 为了弄清楚这个问题,我们使用Generic这个泛型类继续看下面的例子: +```` +public void showKeyValue1(Generic obj){ + Log.d("泛型测试","key value is " + obj.getKey()); +} - public void showKeyValue1(Generic obj){ - Log.d("泛型测试","key value is " + obj.getKey()); - } - - Generic gInteger = new Generic(123); - Generic gNumber = new Generic(456); - - showKeyValue(gNumber); - - // showKeyValue这个方法编译器会为我们报错:Generic - // cannot be applied to Generic - // showKeyValue(gInteger); +Generic gInteger = new Generic(123); +Generic gNumber = new Generic(456); +showKeyValue(gNumber); + +// showKeyValue这个方法编译器会为我们报错:Generic +// cannot be applied to Generic +// showKeyValue(gInteger); +```` 通过提示信息我们可以看到Generic不能被看作为`Generic的子类。由此可以看出:同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。 回到上面的例子,如何解决上面的问题?总不能为了定义一个新的方法来处理Generic类型的类,这显然与java中的多台理念相违背。因此我们需要一个在逻辑上可以表示同时是Generic和Generic父类的引用类型。由此类型通配符应运而生。 我们可以将上面的方法改一下: - - public void showKeyValue1(Generic obj){ - Log.d("泛型测试","key value is " + obj.getKey()); - +```` +public void showKeyValue1(Generic obj){ + Log.d("泛型测试","key value is " + obj.getKey()); +```` 类型通配符一般是使用?代替具体的类型实参,注意, 此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。是一种真实的类型。 可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型 - +```` public void showKeyValue(Generic obj){ System.out.println(obj); } @@ -266,7 +263,7 @@ public void showKeyValue(Generic obj){ // showKeyValue这个方法编译器会为我们报错:Generic // cannot be applied to Generic // showKeyValue(gInteger); -。 +```` ### 泛型方法 @@ -274,167 +271,165 @@ public void showKeyValue(Generic obj){ 尤其是我们见到的大多数泛型类中的成员方法也都使用了泛型,有的甚至泛型类中也包含着泛型方法,这样在初学者中非常容易将泛型方法理解错了。 泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。 +```` +/** + * 泛型方法的基本介绍 + * @param tClass 传入的泛型实参 + * @return T 返回值为T类型 + * 说明: + * 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。 + * 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 + * 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。 + * 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。 + */ + public T genericMethod(Class tClass)throws InstantiationException , + IllegalAccessException{ + T instance = tClass.newInstance(); + return instance; + } - /** - * 泛型方法的基本介绍 - * @param tClass 传入的泛型实参 - * @return T 返回值为T类型 - * 说明: - * 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。 - * 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 - * 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。 - * 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。 - */ - public T genericMethod(Class tClass)throws InstantiationException , - IllegalAccessException{ - T instance = tClass.newInstance(); - return instance; - } - - Object obj = genericMethod(Class.forName("com.test.test")); - +Object obj = genericMethod(Class.forName("com.test.test")); +```` ### 泛型方法的基本用法 光看上面的例子有的同学可能依然会非常迷糊,我们再通过一个例子,把我泛型方法再总结一下。 - - /** - * 这才是一个真正的泛型方法。 - * 首先在public与返回值之间的必不可少,这表明这是一个泛型方法,并且声明了一个泛型T - * 这个T可以出现在这个泛型方法的任意位置. - * 泛型的数量也可以为任意多个 - * 如:public K showKeyName(Generic container){ - * ... - * } - */ - - public class 泛型方法 { - @Test - public void test() { - test1(); - test2(new Integer(2)); - test3(new int[3],new Object()); - - //打印结果 - // null - // 2 - // [I@3d8c7aca - // java.lang.Object@5ebec15 - } - //该方法使用泛型T - public void test1() { - T t = null; - System.out.println(t); - } - //该方法使用泛型T - //并且参数和返回值都是T类型 - public T test2(T t) { - System.out.println(t); - return t; - } - - //该方法使用泛型T,E - //参数包括T,E - public void test3(T t, E e) { - System.out.println(t); - System.out.println(e); - } +```` +/** + * 这才是一个真正的泛型方法。 + * 首先在public与返回值之间的必不可少,这表明这是一个泛型方法,并且声明了一个泛型T + * 这个T可以出现在这个泛型方法的任意位置. + * 泛型的数量也可以为任意多个 + * 如:public K showKeyName(Generic container){ + * ... + * } + */ + + public class 泛型方法 { + @Test + public void test() { + test1(); + test2(new Integer(2)); + test3(new int[3],new Object()); + + //打印结果 + //null + //2 + //[I@3d8c7aca + //java.lang.Object@5ebec15 + } + //该方法使用泛型T + public void test1() { + T t = null; + System.out.println(t); + } + //该方法使用泛型T + //并且参数和返回值都是T类型 + public T test2(T t) { + System.out.println(t); + return t; } - -​ + //该方法使用泛型T,E + //参数包括T,E + public void test3(T t, E e) { + System.out.println(t); + System.out.println(e); + } +} +```` ### 类中的泛型方法 当然这并不是泛型方法的全部,泛型方法可以出现杂任何地方和任何场景中使用。但是有一种情况是非常特殊的,当泛型方法出现在泛型类中时,我们再通过一个例子看一下 - - //注意泛型类先写类名再写泛型,泛型方法先写泛型再写方法名 - //类中声明的泛型在成员和方法中可用 - class A { - { - T t1 ; - } - A (T t){ - this.t = t; - } - T t; - - public void test1() { - System.out.println(this.t); - } - - public void test2(T t,E e) { - System.out.println(t); - System.out.println(e); - } +```` +//注意泛型类先写类名再写泛型,泛型方法先写泛型再写方法名 +//类中声明的泛型在成员和方法中可用 +class A { + { + T t1 ; } - @Test - public void run () { - A a = new A<>(1); - a.test1(); - a.test2(2,"ds"); - // 1 - // 2 - // ds + A (T t){ + this.t = t; } - - static class B { - T t; - public void go () { - System.out.println(t); - } + T t; + + public void test1() { + System.out.println(this.t); + } + + public void test2(T t,E e) { + System.out.println(t); + System.out.println(e); } +} +@Test +public void run () { + A a = new A<>(1); + a.test1(); + a.test2(2,"ds"); +// 1 +// 2 +// ds +} +static class B { + T t; + public void go () { + System.out.println(t); + } +} +```` ### 泛型方法与可变参数 再看一个泛型方法和可变参数的例子: - - public class 泛型和可变参数 { - @Test - public void test () { - printMsg("dasd",1,"dasd",2.0,false); - print("dasdas","dasdas", "aa"); - } - //普通可变参数只能适配一种类型 - public void print(String ... args) { - for(String t : args){ - System.out.println(t); - } +```` +public class 泛型和可变参数 { + @Test + public void test () { + printMsg("dasd",1,"dasd",2.0,false); + print("dasdas","dasdas", "aa"); + } + //普通可变参数只能适配一种类型 + public void print(String ... args) { + for(String t : args){ + System.out.println(t); } - //泛型的可变参数可以匹配所有类型的参数。。有点无敌 - public void printMsg( T... args){ - for(T t : args){ - System.out.println(t); - } + } + //泛型的可变参数可以匹配所有类型的参数。。有点无敌 + public void printMsg( T... args){ + for(T t : args){ + System.out.println(t); } - //打印结果: - //dasd - //1 - //dasd - //2.0 - //false - } + //打印结果: + //dasd + //1 + //dasd + //2.0 + //false +} +```` ### 静态方法与泛型 静态方法有一种情况需要注意一下,那就是在类中的静态方法使用泛型:静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。 即:如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法 。 +```` +public class StaticGenerator { + .... + .... + /** + * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法) + * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。 + * 如:public static void show(T t){..},此时编译器会提示错误信息: + "StaticGenerator cannot be refrenced from static context" + */ + public static void show(T t){ - public class StaticGenerator { - .... - .... - /** - * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法) - * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。 - * 如:public static void show(T t){..},此时编译器会提示错误信息: - "StaticGenerator cannot be refrenced from static context" - */ - public static void show(T t){ - - } } - +} +```` ## 泛型方法总结 泛型方法能使方法独立于类而产生变化,以下是一个基本的指导原则: @@ -445,90 +440,93 @@ public void showKeyValue(Generic obj){ 在使用泛型的时候,我们还可以为传入的泛型类型实参进行上下边界的限制,如:类型实参只准传入某种类型的父类或某种类型的子类。 为泛型添加上边界,即传入的类型实参必须是指定类型的子类型 +```` +public class 泛型通配符与边界 { + public void showKeyValue(Generic obj){ + System.out.println("key value is " + obj.getKey()); + } + @Test + public void main() { + Generic gInteger = new Generic(123); + Generic gNumber = new Generic(456); + showKeyValue(gNumber); + //泛型中的子类也无法作为父类引用传入 +// showKeyValue(gInteger); + } + //直接使用?通配符可以接受任何类型作为泛型传入 + public void showKeyValueYeah(Generic obj) { + System.out.println(obj); + } + //只能传入number的子类或者number + public void showKeyValue1(Generic obj){ + System.out.println(obj); + } - public class 泛型通配符与边界 { - public void showKeyValue(Generic obj){ - System.out.println("key value is " + obj.getKey()); - } - @Test - public void main() { - Generic gInteger = new Generic(123); - Generic gNumber = new Generic(456); - showKeyValue(gNumber); - //泛型中的子类也无法作为父类引用传入 - // showKeyValue(gInteger); - } - //直接使用?通配符可以接受任何类型作为泛型传入 - public void showKeyValueYeah(Generic obj) { - System.out.println(obj); - } - //只能传入number的子类或者number - public void showKeyValue1(Generic obj){ - System.out.println(obj); - } - - //只能传入Integer的父类或者Integer - public void showKeyValue2(Generic obj){ - System.out.println(obj); - } - - @Test - public void testup () { - //这一行代码编译器会提示错误,因为String类型并不是Number类型的子类 - //showKeyValue1(generic1); - Generic generic1 = new Generic("11111"); - Generic generic2 = new Generic(2222); - Generic generic3 = new Generic(2.4f); - Generic generic4 = new Generic(2.56); - - showKeyValue1(generic2); - showKeyValue1(generic3); - showKeyValue1(generic4); - } - - @Test - public void testdown () { - - Generic generic1 = new Generic("11111"); - Generic generic2 = new Generic(2222); - Generic generic3 = new Generic(2); - // showKeyValue2(generic1);本行报错,因为String并不是Integer的父类 - showKeyValue2(generic2); - showKeyValue2(generic3); - } + //只能传入Integer的父类或者Integer + public void showKeyValue2(Generic obj){ + System.out.println(obj); + } + + @Test + public void testup () { + //这一行代码编译器会提示错误,因为String类型并不是Number类型的子类 + //showKeyValue1(generic1); + Generic generic1 = new Generic("11111"); + Generic generic2 = new Generic(2222); + Generic generic3 = new Generic(2.4f); + Generic generic4 = new Generic(2.56); + + showKeyValue1(generic2); + showKeyValue1(generic3); + showKeyValue1(generic4); } + @Test + public void testdown () { + + Generic generic1 = new Generic("11111"); + Generic generic2 = new Generic(2222); + Generic generic3 = new Generic(2); +// showKeyValue2(generic1);本行报错,因为String并不是Integer的父类 + showKeyValue2(generic2); + showKeyValue2(generic3); + } +} +```` == 关于泛型数组要提一下 == 看到了很多文章中都会提起泛型数组,经过查看sun的说明文档,在java中是”不能创建一个确切的泛型类型的数组”的。 - 也就是说下面的这个例子是不可以的: - - List[] ls = new ArrayList[10]; - - 而使用通配符创建泛型数组是可以的,如下面这个例子: - - List[] ls = new ArrayList[10]; - - 这样也是可以的: - - List[] ls = new ArrayList[10]; +也就是说下面的这个例子是不可以的: +```` +List[] ls = new ArrayList[10]; + +而使用通配符创建泛型数组是可以的,如下面这个例子: + +List[] ls = new ArrayList[10]; + +这样也是可以的: +List[] ls = new ArrayList[10]; +```` 下面使用Sun的一篇文档的一个例子来说明这个问题: - List[] lsa = new List[10]; // Not really allowed. - Object o = lsa; - Object[] oa = (Object[]) o; - List li = new ArrayList(); - li.add(new Integer(3)); - oa[1] = li; // Unsound, but passes run time store check - String s = lsa[1].get(0); // Run-time error: ClassCastException. +```` +List[] lsa = new List[10]; // Not really allowed. +Object o = lsa; +Object[] oa = (Object[]) o; +List li = new ArrayList(); +li.add(new Integer(3)); +oa[1] = li; // Unsound, but passes run time store check +String s = lsa[1].get(0); // Run-time error: ClassCastException. +```` > 这种情况下,由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList而不会出现异常,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。 > > 而对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题,比没有任何提示要强很多。 > 下面采用通配符的方式是被允许的:数组的类型不可以是类型变量,除非是采用通配符的方式,因为对于通配符的方式,最后取出数据是要做显式的类型转换的。 +```` List[] lsa = new List[10]; // OK, array of unbounded wildcard type. Object o = lsa; Object[] oa = (Object[]) o; @@ -536,6 +534,7 @@ public void showKeyValue(Generic obj){ li.add(new Integer(3)); oa[1] = li; // Correct. Integer i = (Integer) lsa[1].get(0); // OK +```` 最后 @@ -580,13 +579,13 @@ return cache.put(key, value); 8. 你可以把List传递给一个接受List参数的方法吗? 对任何一个不太熟悉泛型的人来说,这个Java泛型题目看起来令人疑惑,因为乍看起来String是一种Object,所以 List应当可以用在需要List的地方,但是事实并非如此。真这样做的话会导致编译错误。如 果你再深一步考虑,你会发现Java这样做是有意义的,因为List可以存储任何类型的对象包括String, Integer等等,而List却只能用来存储Strings。 - +```` List objectList; List stringList; objectList = stringList; //compilation error incompatible types - +```` 9. Array中可以用泛型吗? 这可能是Java泛型面试题中最简单的一个了,当然前提是你要知道Array事实上并不支持泛型,这也是为什么Joshua Bloch在Effective Java一书中建议使用List来代替Array,因为List可以提供编译期的类型安全保证,而Array却不能。 @@ -594,9 +593,9 @@ objectList = stringList; //compilation error incompatible types 10. 如何阻止Java中的类型未检查的警告? 如果你把泛型和原始类型混合起来使用,例如下列代码,Java 5的javac编译器会产生类型未检查的警告,例如 - +```` List rawList = new ArrayList() - +```` 注意: Hello.java使用了未检查或称为不安全的操作; 这种警告可以使用@SuppressWarnings(“unchecked”)注解来屏蔽。 @@ -609,9 +608,6 @@ https://www.cnblogs.com/dengchengchao/p/9717097.html https://www.cnblogs.com/cat520/p/9353291.html https://www.cnblogs.com/coprince/p/8603492.html - - - ## 微信公众号 ### Java技术江湖 diff --git "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" index 2891f98..e5219d4 100644 --- "a/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" +++ "b/docs/java/basic/14\343\200\201\346\236\232\344\270\276\347\261\273.md" @@ -94,136 +94,136 @@ ### 枚举类的具体使用 这部分内容参考https://blog.csdn.net/qq_27093465/article/details/52180865 #### 常量 - - public class 常量 { - } - enum Color { - Red, Green, Blue, Yellow - } - +```` +public class 常量 { +} +enum Color { + Red, Green, Blue, Yellow +} +```` #### switch JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。 - - public static void showColor(Color color) { - switch (color) { - case Red: - System.out.println(color); - break; - case Blue: - System.out.println(color); - break; - case Yellow: - System.out.println(color); - break; - case Green: - System.out.println(color); - break; - } - } - +```` +public static void showColor(Color color) { + switch (color) { + case Red: + System.out.println(color); + break; + case Blue: + System.out.println(color); + break; + case Yellow: + System.out.println(color); + break; + case Green: + System.out.println(color); + break; + } +} +```` #### 向枚举中添加新方法 如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。 - - enum Color { - //每个颜色都是枚举类的一个实例,并且构造方法要和枚举类的格式相符合。 - //如果实例后面有其他内容,实例序列结束时要加分号。 - Red("红色", 1), Green("绿色", 2), Blue("蓝色", 3), Yellow("黄色", 4); - String name; - int index; - Color(String name, int index) { - this.name = name; - this.index = index; - } - public void showAllColors() { - //values是Color实例的数组,在通过index和name可以获取对应的值。 - for (Color color : Color.values()) { - System.out.println(color.index + ":" + color.name); - } +```` +enum Color { + //每个颜色都是枚举类的一个实例,并且构造方法要和枚举类的格式相符合。 + //如果实例后面有其他内容,实例序列结束时要加分号。 + Red("红色", 1), Green("绿色", 2), Blue("蓝色", 3), Yellow("黄色", 4); + String name; + int index; + Color(String name, int index) { + this.name = name; + this.index = index; + } + public void showAllColors() { + //values是Color实例的数组,在通过index和name可以获取对应的值。 + for (Color color : Color.values()) { + System.out.println(color.index + ":" + color.name); } } - +} +```` #### 覆盖枚举的方法 所有枚举类都继承自Enum类,所以可以重写该类的方法 下面给出一个toString()方法覆盖的例子。 - - @Override - public String toString() { - return this.index + ":" + this.name; - } - +```` +@Override +public String toString() { + return this.index + ":" + this.name; +} +```` #### 实现接口 所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。 - - enum Color implements Print{ - @Override - public void print() { - System.out.println(this.name); - } +```` +enum Color implements Print{ + @Override + public void print() { + System.out.println(this.name); } - +} +```` #### 使用接口组织枚举 搞个实现接口,来组织枚举,简单讲,就是分类吧。如果大量使用枚举的话,这么干,在写代码的时候,就很方便调用啦。 - - public class 用接口组织枚举 { - public static void main(String[] args) { - Food cf = chineseFood.dumpling; - Food jf = Food.JapaneseFood.fishpiece; - for (Food food : chineseFood.values()) { - System.out.println(food); - } - for (Food food : Food.JapaneseFood.values()) { - System.out.println(food); - } +```` +public class 用接口组织枚举 { + public static void main(String[] args) { + Food cf = chineseFood.dumpling; + Food jf = Food.JapaneseFood.fishpiece; + for (Food food : chineseFood.values()) { + System.out.println(food); } - } - interface Food { - enum JapaneseFood implements Food { - suse, fishpiece + for (Food food : Food.JapaneseFood.values()) { + System.out.println(food); } } - enum chineseFood implements Food { - dumpling, tofu +} +interface Food { + enum JapaneseFood implements Food { + suse, fishpiece } - +} +enum chineseFood implements Food { + dumpling, tofu +} +```` #### 枚举类集合 java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。 EnumSet在JDK中没有找到实现类,这里写一个EnumMap的例子 - - public class 枚举类集合 { - public static void main(String[] args) { - EnumMap map = new EnumMap(Color.class); - map.put(Color.Blue, "Blue"); - map.put(Color.Yellow, "Yellow"); - map.put(Color.Red, "Red"); - System.out.println(map.get(Color.Red)); - } +```` +public class 枚举类集合 { + public static void main(String[] args) { + EnumMap map = new EnumMap(Color.class); + map.put(Color.Blue, "Blue"); + map.put(Color.Yellow, "Yellow"); + map.put(Color.Red, "Red"); + System.out.println(map.get(Color.Red)); } - +} +```` ## 使用枚举类的注意事项 -![image](https://img-blog.csdn.net/20170112172420090) +![image](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403212903.png) 枚举类型对象之间的值比较,是可以使用==,直接来比较值,是否相等的,不是必须使用equals方法的哟。 因为枚举类Enum已经重写了equals方法 - - /** - * Returns true if the specified object is equal to this - * enum constant. - * - * @param other the object to be compared for equality with this object. - * @return true if the specified object is equal to this - * enum constant. - */ - public final boolean equals(Object other) { - return this==other; - } - +```` +/** + * Returns true if the specified object is equal to this + * enum constant. + * + * @param other the object to be compared for equality with this object. + * @return true if the specified object is equal to this + * enum constant. + */ +public final boolean equals(Object other) { + return this==other; +} +```` ## 枚举类的实现原理 这部分参考https://blog.csdn.net/mhmyqn/article/details/48087247 @@ -235,46 +235,46 @@ EnumSet在JDK中没有找到实现类,这里写一个EnumMap的例子 > Java在1.5中添加了java.lang.Enum抽象类,它是所有枚举类型基类。提供了一些基础属性和基础方法。同时,对把枚举用作Set和Map也提供了支持,即java.util.EnumSet和java.util.EnumMap。 接下来定义一个简单的枚举类 - - public enum Day { - MONDAY { - @Override - void say() { - System.out.println("MONDAY"); - } +```` +public enum Day { + MONDAY { + @Override + void say() { + System.out.println("MONDAY"); } - , TUESDAY { - @Override - void say() { - System.out.println("TUESDAY"); - } - }, FRIDAY("work"){ - @Override - void say() { - System.out.println("FRIDAY"); - } - }, SUNDAY("free"){ - @Override - void say() { - System.out.println("SUNDAY"); - } - }; - String work; - //没有构造参数时,每个实例可以看做常量。 - //使用构造参数时,每个实例都会变得不一样,可以看做不同的类型,所以编译后会生成实例个数对应的class。 - private Day(String work) { - this.work = work; + } + , TUESDAY { + @Override + void say() { + System.out.println("TUESDAY"); } - private Day() { - + }, FRIDAY("work"){ + @Override + void say() { + System.out.println("FRIDAY"); } - //枚举实例必须实现枚举类中的抽象方法 - abstract void say (); - + }, SUNDAY("free"){ + @Override + void say() { + System.out.println("SUNDAY"); + } + }; + String work; + //没有构造参数时,每个实例可以看做常量。 + //使用构造参数时,每个实例都会变得不一样,可以看做不同的类型,所以编译后会生成实例个数对应的class。 + private Day(String work) { + this.work = work; } + private Day() { -反编译结果 + } + //枚举实例必须实现枚举类中的抽象方法 + abstract void say (); +} +```` +反编译结果 +```` D:\MyTech\out\production\MyTech\com\javase\枚举类>javap Day.class Compiled from "Day.java" @@ -291,43 +291,43 @@ EnumSet在JDK中没有找到实现类,这里写一个EnumMap的例子 com.javase.枚举类.Day(java.lang.String, int, java.lang.String, com.javase.枚举类.Day$1); static {}; } - +```` > 可以看到,一个枚举在经过编译器编译过后,变成了一个抽象类,它继承了java.lang.Enum;而枚举中定义的枚举常量,变成了相应的public static final属性,而且其类型就抽象类的类型,名字就是枚举常量的名字. > > 同时我们可以在Operator.class的相同路径下看到四个内部类的.class文件com/mikan/Day$1.class、com/mikan/Day$2.class、com/mikan/Day$3.class、com/mikan/Day$4.class,也就是说这四个命名字段分别使用了内部类来实现的;同时添加了两个方法values()和valueOf(String);我们定义的构造方法本来只有一个参数,但却变成了三个参数;同时还生成了一个静态代码块。这些具体的内容接下来仔细看看。 下面分析一下字节码中的各部分,其中: - - InnerClasses: - static #23; //class com/javase/枚举类/Day$4 - static #18; //class com/javase/枚举类/Day$3 - static #14; //class com/javase/枚举类/Day$2 - static #10; //class com/javase/枚举类/Day$1 - +```` +InnerClasses: + static #23; //class com/javase/枚举类/Day$4 + static #18; //class com/javase/枚举类/Day$3 + static #14; //class com/javase/枚举类/Day$2 + static #10; //class com/javase/枚举类/Day$1 +```` 从中可以看到它有4个内部类,这四个内部类的详细信息后面会分析。 - - static {}; - descriptor: ()V - flags: ACC_STATIC - Code: - stack=5, locals=0, args_size=0 - 0: new #10 // class com/javase/枚举类/Day$1 - 3: dup - 4: ldc #11 // String MONDAY - 6: iconst_0 - 7: invokespecial #12 // Method com/javase/枚举类/Day$1."":(Ljava/lang/String;I)V - 10: putstatic #13 // Field MONDAY:Lcom/javase/枚举类/Day; - 13: new #14 // class com/javase/枚举类/Day$2 - 16: dup - 17: ldc #15 // String TUESDAY - 19: iconst_1 - 20: invokespecial #16 // Method com/javase/枚举类/Day$2."":(Ljava/lang/String;I)V - //后面类似,这里省略 - } - +```` +static {}; + descriptor: ()V + flags: ACC_STATIC + Code: + stack=5, locals=0, args_size=0 + 0: new #10 // class com/javase/枚举类/Day$1 + 3: dup + 4: ldc #11 // String MONDAY + 6: iconst_0 + 7: invokespecial #12 // Method com/javase/枚举类/Day$1."":(Ljava/lang/String;I)V + 10: putstatic #13 // Field MONDAY:Lcom/javase/枚举类/Day; + 13: new #14 // class com/javase/枚举类/Day$2 + 16: dup + 17: ldc #15 // String TUESDAY + 19: iconst_1 + 20: invokespecial #16 // Method com/javase/枚举类/Day$2."":(Ljava/lang/String;I)V + //后面类似,这里省略 +} +```` 其实编译器生成的这个静态代码块做了如下工作:分别设置生成的四个公共静态常量字段的值,同时编译器还生成了一个静态字段$VALUES,保存的是枚举类型定义的所有枚举常量 编译器添加的values方法: - +```` public static com.javase.Day[] values(); flags: ACC_PUBLIC, ACC_STATIC Code: @@ -336,16 +336,17 @@ EnumSet在JDK中没有找到实现类,这里写一个EnumMap的例子 3: invokevirtual #3 // Method "[Lcom/mikan/Day;".clone:()Ljava/lang/Object; 6: checkcast #4 // class "[Lcom/javase/Day;" 9: areturn - 这个方法是一个公共的静态方法,所以我们可以直接调用该方法(Day.values()),返回这个枚举值的数组,另外,这个方法的实现是,克隆在静态代码块中初始化的$VALUES字段的值,并把类型强转成Day[]类型返回。 +```` +这个方法是一个公共的静态方法,所以我们可以直接调用该方法(Day.values()),返回这个枚举值的数组,另外,这个方法的实现是,克隆在静态代码块中初始化的$VALUES字段的值,并把类型强转成Day[]类型返回。 造方法为什么增加了两个参数? 有一个问题,构造方法我们明明只定义了一个参数,为什么生成的构造方法是三个参数呢? - 从Enum类中我们可以看到,为每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,所以才在构造方法中添加了两个参数。即: - - 另外三个枚举常量生成的内部类基本上差不多,这里就不重复说明了。 +从Enum类中我们可以看到,为每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,所以才在构造方法中添加了两个参数。即: + +另外三个枚举常量生成的内部类基本上差不多,这里就不重复说明了。 > 我们可以从Enum类的代码中看到,定义的name和ordinal属性都是final的,而且大部分方法也都是final的,特别是clone、readObject、writeObject这三个方法,这三个方法和枚举通过静态代码块来进行初始化一起。 diff --git "a/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" "b/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" index ab4a401..259a732 100644 --- "a/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" +++ "b/docs/java/basic/15\343\200\201Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" @@ -26,18 +26,6 @@ * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) - ---- -title: 夯实Java基础系列15:Java注解简介和最佳实践 -date: 2019-9-15 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - annotation - - Java注解 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -73,9 +61,7 @@ Annotation 中文译过来就是注解、标释的意思,在 Java 中注解是 并且,往抽象地说,标签并不一定是一张纸,它可以是对人和事物的属性评价。也就是说,标签具备对于抽象事物的解释。 -![](https://img-blog.csdn.net/20170627213419176?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYnJpYmx1ZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) - - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403213103.png) 所以,基于如此,我完成了自我的知识认知升级,我决定用标签来解释注解。 @@ -166,8 +152,8 @@ java.lang.annotation提供了四种元注解,专门注解其他的注解(在 JDK 内置注解 先来看几个 Java 内置的注解,让大家热热身。 - @Override 演示 - +@Override 演示 +```` class Parent { public void run() { } @@ -182,7 +168,9 @@ JDK 内置注解 public void run() { } } +```` @Deprecated 演示 +```` class Parent { /** @@ -201,7 +189,9 @@ class Parent { parent.run(); // 在编译器中此方法会显示过时标志 } } +```` @SuppressWarnings 演示 +```` class Parent { // 因为定义的 name 没有使用,那么编译器就会有警告,这时候使用此注解可以屏蔽掉警告 @@ -209,8 +199,10 @@ class Parent { @SuppressWarnings("all") private String name; } - +```` @FunctionalInterface 演示 + +```` /** * 此注解是 Java8 提出的函数式接口,接口中只允许有一个抽象方法 * 加上这个注解之后,类中多一个抽象方法或者少一个抽象方法都会报错 @@ -219,7 +211,7 @@ class Parent { interface Func { void run(); } - +```` ## 注解处理器实战 @@ -230,27 +222,30 @@ interface Func { 我们先来了解下如何通过在运行时使用反射获取在程序中的使用的注解信息。如下类注解和方法注解。 类注解 - Class aClass = ApiController.class; - Annotation[] annotations = aClass.getAnnotations(); - - for(Annotation annotation : annotations) { - if(annotation instanceof ApiAuthAnnotation) { - ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation; - System.out.println("name: " + apiAuthAnnotation.name()); - System.out.println("age: " + apiAuthAnnotation.age()); - } + +```` +Class aClass = ApiController.class; +Annotation[] annotations = aClass.getAnnotations(); + +for(Annotation annotation : annotations) { + if(annotation instanceof ApiAuthAnnotation) { + ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation; + System.out.println("name: " + apiAuthAnnotation.name()); + System.out.println("age: " + apiAuthAnnotation.age()); } - 方法注解 - Method method = ... //通过反射获取方法对象 - Annotation[] annotations = method.getDeclaredAnnotations(); - - for(Annotation annotation : annotations) { - if(annotation instanceof ApiAuthAnnotation) { - ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation; - System.out.println("name: " + apiAuthAnnotation.name()); - System.out.println("age: " + apiAuthAnnotation.age()); - } - } +} +方法注解 +Method method = ... //通过反射获取方法对象 +Annotation[] annotations = method.getDeclaredAnnotations(); + +for(Annotation annotation : annotations) { + if(annotation instanceof ApiAuthAnnotation) { + ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation; + System.out.println("name: " + apiAuthAnnotation.name()); + System.out.println("age: " + apiAuthAnnotation.age()); + } +} +```` 此部分内容可参考: 通过反射获取注解信息 注解处理器实战 @@ -260,33 +255,33 @@ interface Func { 接下来要做的事情: 写一个切面,拦截浏览器访问带注解的接口,取出注解信息,判断年龄来确定是否可以继续访问。 在 dispatcher-servlet.xml 文件中定义 aop 切面 - - - - - - - - - +```` + + + + + + + + +```` 切面类处理逻辑即注解处理器代码如 - - @Component("apiAuthAspect") - public class ApiAuthAspect { - - public Object auth(ProceedingJoinPoint pjp) throws Throwable { - Method method = ((MethodSignature) pjp.getSignature()).getMethod(); - ApiAuthAnnotation apiAuthAnnotation = method.getAnnotation(ApiAuthAnnotation.class); - Integer age = apiAuthAnnotation.age(); - if (age > 18) { - return pjp.proceed(); - } else { - throw new RuntimeException("你未满18岁,禁止访问"); - } +```` +@Component("apiAuthAspect") +public class ApiAuthAspect { + + public Object auth(ProceedingJoinPoint pjp) throws Throwable { + Method method = ((MethodSignature) pjp.getSignature()).getMethod(); + ApiAuthAnnotation apiAuthAnnotation = method.getAnnotation(ApiAuthAnnotation.class); + Integer age = apiAuthAnnotation.age(); + if (age > 18) { + return pjp.proceed(); + } else { + throw new RuntimeException("你未满18岁,禁止访问"); } } - - +} +```` ## 不同类型的注解 @@ -295,7 +290,7 @@ interface Func { 你可以在运行期访问类,方法或者变量的注解信息,下是一个访问类注解的例子: ``` - Class aClass = TheClass.class; +Class aClass = TheClass.class; Annotation[] annotations = aClass.getAnnotations(); for(Annotation annotation : annotations){ diff --git "a/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" "b/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" index a405b7f..4403458 100644 --- "a/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" +++ "b/docs/java/basic/16\343\200\201JavaIO\346\265\201.md" @@ -24,15 +24,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列16:一文读懂Java IO流和常见面试题 -date: 2019-9-16 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java IO流 ---- 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -60,7 +51,6 @@ tags: > 在这一小节,我会试着给出Java IO(java.io)包下所有类的概述。更具体地说,我会根据类的用途对类进行分组。这个分组将会使你在未来的工作中,进行类的用途判定时,或者是为某个特定用途选择类时变得更加容易。 -​ **输入和输出** 术语“输入”和“输出”有时候会有一点让人疑惑。一个应用程序的输入往往是另外一个应用程序的输出 @@ -174,7 +164,7 @@ java.io.InputStream类是所有Java IO输入流的基类。如果你正在开发 这使得RandomAccessFile可以覆盖一个文件的某些部分、或者追加内容到它的末尾、或者删除它的某些内容,当然它也可以从文件的任何位置开始读取文件。 下面是具体例子: - +```` @Test //文件流范例,打开一个文件的输入流,读取到字节数组,再写入另一个文件的输出流 public void test1() { @@ -193,6 +183,7 @@ java.io.InputStream类是所有Java IO输入流的基类。如果你正在开发 e.printStackTrace(); } } +```` ### 字符流和字节流 Java IO的Reader和Writer除了基于字符之外,其他方面都与InputStream和OutputStream非常类似。他们被用于读写文本。InputStream和OutputStream是基于字节的,还记得吗? @@ -204,46 +195,47 @@ Writer Writer类是Java IO中所有Writer的基类。子类包括BufferedWriter和PrintWriter等等。 这是一个简单的Java IO Reader的例子: +```` +Reader reader = new FileReader("c:\\data\\myfile.txt"); - Reader reader = new FileReader("c:\\data\\myfile.txt"); - - int data = reader.read(); - - while(data != -1){ - - char dataChar = (char) data; - - data = reader.read(); - - } +int data = reader.read(); + +while(data != -1){ + char dataChar = (char) data; + + data = reader.read(); + +} +```` 你通常会使用Reader的子类,而不会直接使用Reader。Reader的子类包括InputStreamReader,CharArrayReader,FileReader等等。可以查看Java IO概述浏览完整的Reader表格。 **整合Reader与InputStream** 一个Reader可以和一个InputStream相结合。如果你有一个InputStream输入流,并且想从其中读取字符,可以把这个InputStream包装到InputStreamReader中。把InputStream传递到InputStreamReader的构造函数中: - - Reader reader = new InputStreamReader(inputStream); +```` +Reader reader = new InputStreamReader(inputStream); +```` 在构造函数中可以指定解码方式。 **Writer** Writer类是Java IO中所有Writer的基类。子类包括BufferedWriter和PrintWriter等等。这是一个Java IO Writer的例子: +```` +Writer writer = new FileWriter("c:\\data\\file-output.txt"); - Writer writer = new FileWriter("c:\\data\\file-output.txt"); - - writer.write("Hello World Writer"); - - writer.close(); +writer.write("Hello World Writer"); +writer.close(); +```` 同样,你最好使用Writer的子类,不需要直接使用Writer,因为子类的实现更加明确,更能表现你的意图。常用子类包括OutputStreamWriter,CharArrayWriter,FileWriter等。Writer的write(int c)方法,会将传入参数的低16位写入到Writer中,忽略高16位的数据。 **整合Writer和OutputStream** 与Reader和InputStream类似,一个Writer可以和一个OutputStream相结合。把OutputStream包装到OutputStreamWriter中,所有写入到OutputStreamWriter的字符都将会传递给OutputStream。这是一个OutputStreamWriter的例子: - - Writer writer = new OutputStreamWriter(outputStream); - +```` +Writer writer = new OutputStreamWriter(outputStream); +```` ### IO管道 Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力。所以管道也可以作为数据源以及目标媒介。 @@ -258,37 +250,38 @@ Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的 Java IO管道示例 这是一个如何将PipedInputStream和PipedOutputStream关联起来的简单例子: - - //使用管道来完成两个线程间的数据点对点传递 - @Test - public void test2() throws IOException { - PipedInputStream pipedInputStream = new PipedInputStream(); - PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream); - new Thread(new Runnable() { - @Override - public void run() { - try { - pipedOutputStream.write("hello input".getBytes()); - pipedOutputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } +```` +//使用管道来完成两个线程间的数据点对点传递 + @Test + public void test2() throws IOException { + PipedInputStream pipedInputStream = new PipedInputStream(); + PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream); + new Thread(new Runnable() { + @Override + public void run() { + try { + pipedOutputStream.write("hello input".getBytes()); + pipedOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); } - }).start(); - new Thread(new Runnable() { - @Override - public void run() { - try { - byte []arr = new byte[128]; - while (pipedInputStream.read(arr) != -1) { - System.out.println(Arrays.toString(arr)); - } - pipedInputStream.close(); - } catch (IOException e) { - e.printStackTrace(); + } + }).start(); + new Thread(new Runnable() { + @Override + public void run() { + try { + byte []arr = new byte[128]; + while (pipedInputStream.read(arr) != -1) { + System.out.println(Arrays.toString(arr)); } + pipedInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); } - }).start(); + } + }).start(); +```` 管道和线程 请记得,当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。 @@ -304,7 +297,7 @@ Java中网络的内容或多或少的超出了Java IO的范畴。关于Java网 当两个进程之间建立了网络连接之后,他们通信的方式如同操作文件一样:利用InputStream读取数据,利用OutputStream写入数据。换句话来说,Java网络API用来在不同进程之间建立网络连接,而Java IO则用来在建立了连接之后的进程之间交换数据。 基本上意味着如果你有一份能够对文件进行写入某些数据的代码,那么这些数据也可以很容易地写入到网络连接中去。你所需要做的仅仅只是在代码中利用OutputStream替代FileOutputStream进行数据的写入。因为FileOutputStream是OuputStream的子类,所以这么做并没有什么问题。 - +```` //从网络中读取字节流也可以直接使用OutputStream public void test3() { //读取网络进程的输出流 @@ -318,7 +311,7 @@ Java中网络的内容或多或少的超出了Java IO的范畴。关于Java网 //处理网络信息 //do something with the OutputStream } - +```` ### 字节和字符数组 @@ -330,7 +323,7 @@ Java中网络的内容或多或少的超出了Java IO的范畴。关于Java网 前面的例子中,字符数组或字节数组是用来缓存数据的临时存储空间,不过它们同时也可以作为数据来源或者写入目的地。 举个例子: - +```` //字符数组和字节数组在io过程中的作用 public void test4() { //arr和brr分别作为数据源 @@ -339,7 +332,7 @@ Java中网络的内容或多或少的超出了Java IO的范畴。关于Java网 byte []brr = {1,2,3,4,5}; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(brr); } - +```` ### System.in, System.out, System.err System.in, System.out, System.err这3个流同样是常见的数据来源和数据流目的地。使用最多的可能是在控制台程序里利用System.out将输出打印到控制台上。 @@ -358,7 +351,7 @@ JVM启动的时候通过Java运行时初始化这3个流,所以你不需要初 System.out和System.err的简单例子: 这是一个System.out和System.err结合使用的简单示例: - +```` //测试System.in, System.out, System.err public static void main(String[] args) { int in = new Scanner(System.in).nextInt(); @@ -370,7 +363,7 @@ System.out和System.err的简单例子: // 10 // out } - +```` ### 字符流的Buffered和Filter @@ -437,8 +430,6 @@ Filter Stream是一种IO流主要作用是用来对存在的流增加一些额 在java.io包中主要由4个可用的filter Stream。两个字节filter stream,两个字符filter stream. 分别是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter.这些类是抽象类,不能被实例化的。 - - ### 在文件拷贝的时候,那一种流可用提升更多的性能? 在字节流的时候,使用BufferedInputStream和BufferedOutputStream。 在字符流的时候,使用BufferedReader 和 BufferedWriter diff --git "a/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" "b/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" index e2cc758..3045d4e 100644 --- "a/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" +++ "b/docs/java/basic/17\343\200\201\345\244\232\347\272\277\347\250\213.md" @@ -19,15 +19,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题 -date: 2019-9-17 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - 多线程 ---- 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial diff --git "a/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" "b/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" index 0ce799d..adf7861 100644 --- "a/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" +++ "b/docs/java/basic/18\343\200\201\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" @@ -12,21 +12,10 @@ * [内部类初始化](#内部类初始化) * [内部类的重载](#内部类的重载) * [内部类的继承](#内部类的继承) - * [Java内部类的实现原理](#java内部类的实现原理) * [参考文章](#参考文章) * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列18:深入理解Java内部类及其实现原理 -date: 2019-9-18 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java内部类 ---- - 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -58,8 +47,6 @@ tags: > > (4)外部类不能直接访问内部类的的成员,但可以通过内部类对象来访问 - -   内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。   因为当某个外围类的对象创建内部类的对象时,此内部类会捕获一个隐式引用,它引用了实例化该内部对象的外围类对象。通过这个指针,可以访问外围类对象的全部状态。 @@ -121,125 +108,125 @@ tags: 3 外部类和它的内部类之间的关系 +```` +//本节讨论内部类以及不同访问权限的控制 +//内部类只有在使用时才会被加载。 +//外部类B +public class B{ + int i = 1; + int j = 1; + static int s = 1; + static int ss = 1; + A a; + AA aa; + AAA aaa; + //内部类A + + public class A { +// static void go () { +// +// } +// static { +// +// } +// static int b = 1;//非静态内部类不能有静态成员变量和静态代码块和静态方法, + // 因为内部类在外部类加载时并不会被加载和初始化。 + //所以不会进行静态代码的调用 + int i = 2;//外部类无法读取内部类的成员,而内部类可以直接访问外部类成员 - //本节讨论内部类以及不同访问权限的控制 - //内部类只有在使用时才会被加载。 - //外部类B - public class B{ - int i = 1; - int j = 1; - static int s = 1; - static int ss = 1; - A a; - AA aa; - AAA aaa; - //内部类A - - public class A { - // static void go () { - // - // } - // static { - // - // } - // static int b = 1;//非静态内部类不能有静态成员变量和静态代码块和静态方法, - // 因为内部类在外部类加载时并不会被加载和初始化。 - //所以不会进行静态代码的调用 - int i = 2;//外部类无法读取内部类的成员,而内部类可以直接访问外部类成员 - - public void test() { - System.out.println(j); - j = 2; - System.out.println(j); - System.out.println(s);//可以访问类的静态成员变量 - } - public void test2() { - AA aa = new AA(); - AAA aaa = new AAA(); - } - - } - //静态内部类S,可以被外部访问 - public static class S { - int i = 1;//访问不到非静态变量。 - static int s = 0;//可以有静态变量 - - public static void main(String[] args) { - System.out.println(s); - } - @Test - public void test () { - // System.out.println(j);//报错,静态内部类不能读取外部类的非静态变量 - System.out.println(s); - System.out.println(ss); - s = 2; - ss = 2; - System.out.println(s); - System.out.println(ss); - } + public void test() { + System.out.println(j); + j = 2; + System.out.println(j); + System.out.println(s);//可以访问类的静态成员变量 } - - //内部类AA,其实这里加protected相当于default - //因为外部类要调用内部类只能通过B。并且无法直接继承AA,所以必须在同包 - //的类中才能调用到(这里不考虑静态内部类),那么就和default一样了。 - protected class AA{ - int i = 2;//内部类之间不共享变量 - public void test (){ - A a = new A(); - AAA aaa = new AAA(); - //内部类之间可以互相访问。 - } + public void test2() { + AA aa = new AA(); + AAA aaa = new AAA(); } - //包外部依然无法访问,因为包没有继承关系,所以找不到这个类 - protected static class SS{ - int i = 2;//内部类之间不共享变量 - public void test (){ - - //内部类之间可以互相访问。 - } - } - //私有内部类A,对外不可见,但对内部类和父类可见 - private class AAA { - int i = 2;//内部类之间不共享变量 - - public void test() { - A a = new A(); - AA aa = new AA(); - //内部类之间可以互相访问。 - } + + } + //静态内部类S,可以被外部访问 + public static class S { + int i = 1;//访问不到非静态变量。 + static int s = 0;//可以有静态变量 + + public static void main(String[] args) { + System.out.println(s); } @Test - public void test(){ + public void test () { +// System.out.println(j);//报错,静态内部类不能读取外部类的非静态变量 + System.out.println(s); + System.out.println(ss); + s = 2; + ss = 2; + System.out.println(s); + System.out.println(ss); + } + } + + //内部类AA,其实这里加protected相当于default + //因为外部类要调用内部类只能通过B。并且无法直接继承AA,所以必须在同包 + //的类中才能调用到(这里不考虑静态内部类),那么就和default一样了。 + protected class AA{ + int i = 2;//内部类之间不共享变量 + public void test (){ A a = new A(); - a.test(); - //内部类可以修改外部类的成员变量 - //打印出 1 2 - B b = new B(); - + AAA aaa = new AAA(); + //内部类之间可以互相访问。 } } + //包外部依然无法访问,因为包没有继承关系,所以找不到这个类 + protected static class SS{ + int i = 2;//内部类之间不共享变量 + public void test (){ + //内部类之间可以互相访问。 + } + } + //私有内部类A,对外不可见,但对内部类和父类可见 + private class AAA { + int i = 2;//内部类之间不共享变量 -​ - //另一个外部类 - class C { - @Test public void test() { - //首先,其他类内部类只能通过外部类来获取其实例。 - B.S s = new B.S(); - //静态内部类可以直接通过B类直接获取,不需要B的实例,和静态成员变量类似。 - //B.A a = new B.A(); - //当A不是静态类时这行代码会报错。 - //需要使用B的实例来获取A的实例 - B b = new B(); - B.A a = b.new A(); - B.AA aa = b.new AA();//B和C同包,所以可以访问到AA - // B.AAA aaa = b.new AAA();AAA为私有内部类,外部类不可见 - //当A使用private修饰时,使用B的实例也无法获取A的实例,这一点和私有变量是一样的。 - //所有普通的内部类与类中的一个变量是类似的。静态内部类则与静态成员类似。 + A a = new A(); + AA aa = new AA(); + //内部类之间可以互相访问。 } } + @Test + public void test(){ + A a = new A(); + a.test(); + //内部类可以修改外部类的成员变量 + //打印出 1 2 + B b = new B(); + } +} +```` + +```` +//另一个外部类 +class C { + @Test + public void test() { + //首先,其他类内部类只能通过外部类来获取其实例。 + B.S s = new B.S(); + //静态内部类可以直接通过B类直接获取,不需要B的实例,和静态成员变量类似。 + //B.A a = new B.A(); + //当A不是静态类时这行代码会报错。 + //需要使用B的实例来获取A的实例 + B b = new B(); + B.A a = b.new A(); + B.AA aa = b.new AA();//B和C同包,所以可以访问到AA +// B.AAA aaa = b.new AAA();AAA为私有内部类,外部类不可见 + //当A使用private修饰时,使用B的实例也无法获取A的实例,这一点和私有变量是一样的。 + //所有普通的内部类与类中的一个变量是类似的。静态内部类则与静态成员类似。 + } +} +```` ## 内部类的加载 可能刚才的例子中没办法直观地看到内部类是如何加载的,接下来用例子展示一下内部类加载的过程。 @@ -277,43 +264,43 @@ tags: 需要注意的是: 局部内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。 +```` +public class 局部内部类 { + class A {//局部内部类就是写在方法里的类,只在方法执行时加载,一次性使用。 + public void test() { + class B { + public void test () { + class C { - public class 局部内部类 { - class A {//局部内部类就是写在方法里的类,只在方法执行时加载,一次性使用。 - public void test() { - class B { - public void test () { - class C { - - } } } } } - @Test - public void test () { - int i = 1; - final int j = 2; - class A { - @Test - public void test () { - System.out.println(i); - System.out.println(j); - } - } - A a = new A(); - System.out.println(a); - } - - static class B { - public static void test () { - //static class A报错,方法里不能定义静态内部类。 - //因为只有在方法调用时才能进行类加载和初始化。 - + } + @Test + public void test () { + int i = 1; + final int j = 2; + class A { + @Test + public void test () { + System.out.println(i); + System.out.println(j); } } + A a = new A(); + System.out.println(a); } + static class B { + public static void test () { + //static class A报错,方法里不能定义静态内部类。 + //因为只有在方法调用时才能进行类加载和初始化。 + + } + } +} +```` ### 匿名内部类 简单地说:匿名内部类就是没有名字的内部类,并且,匿名内部类是局部内部类的一种特殊形式。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的: @@ -336,61 +323,61 @@ tags: >6  因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。 一个匿名内部类的例子: +```` +public class 匿名内部类 { + +} +interface D{ + void run (); +} +abstract class E{ + E (){ - public class 匿名内部类 { - - } - interface D{ - void run (); - } - abstract class E{ - E (){ - - } - abstract void work(); } - class A { - - @Test - public void test (int k) { - //利用接口写出一个实现该接口的类的实例。 - //有且仅有一个实例,这个类无法重用。 - new Runnable() { - @Override - public void run() { - // k = 1;报错,当外部方法中的局部变量在内部类使用中必须改为final类型。 - //因为方外部法中即使改变了这个变量也不会反映到内部类中。 - //所以对于内部类来讲这只是一个常量。 - System.out.println(100); - System.out.println(k); - } - }; - new D(){ - //实现接口的匿名类 - int i =1; - @Override - public void run() { - System.out.println("run"); - System.out.println(i); - System.out.println(k); - } - }.run(); - new E(){ - //继承抽象类的匿名类 - int i = 1; - void run (int j) { - j = 1; - } - - @Override - void work() { - - } - }; + abstract void work(); +} +class A { + + @Test + public void test (int k) { + //利用接口写出一个实现该接口的类的实例。 + //有且仅有一个实例,这个类无法重用。 + new Runnable() { + @Override + public void run() { +// k = 1;报错,当外部方法中的局部变量在内部类使用中必须改为final类型。 + //因为方外部法中即使改变了这个变量也不会反映到内部类中。 + //所以对于内部类来讲这只是一个常量。 + System.out.println(100); + System.out.println(k); } - + }; + new D(){ + //实现接口的匿名类 + int i =1; + @Override + public void run() { + System.out.println("run"); + System.out.println(i); + System.out.println(k); + } + }.run(); + new E(){ + //继承抽象类的匿名类 + int i = 1; + void run (int j) { + j = 1; + } + + @Override + void work() { + + } + }; } +} +```` ### 匿名内部类里的final 使用的形参为何要为final @@ -401,37 +388,36 @@ tags: > 为什么必须要为final呢? > > 首先我们知道在内部类编译成功后,它会产生一个class文件,该class文件与外部类并不是同一class文件,仅仅只保留对外部类的引用。当外部类传入的参数需要被内部类调用时,从java程序的角度来看是直接被调用: -> -> - public class OuterClass { - public void display(final String name,String age){ - class InnerClass{ - void display(){ - System.out.println(name); - } +```` +public class OuterClass { + public void display(final String name,String age){ + class InnerClass{ + void display(){ + System.out.println(name); } } } - +} +```` 从上面代码中看好像name参数应该是被内部类直接调用?其实不然,在java编译之后实际的操作如下: - - public class OuterClass$InnerClass { - public InnerClass(String name,String age){ - this.InnerClass$name = name; - this.InnerClass$age = age; - } +```` +public class OuterClass$InnerClass { + public InnerClass(String name,String age){ + this.InnerClass$name = name; + this.InnerClass$age = age; + } -​ - public void display(){ - System.out.println(this.InnerClass$name + "----" + this.InnerClass$age ); - } + + public void display(){ + System.out.println(this.InnerClass$name + "----" + this.InnerClass$age ); } - +} +```` 所以从上面代码来看,内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入的参数进行备份,自己内部方法调用的实际上时自己的属性而不是外部方法传递进来的参数。 -> 直到这里还没有解释为什么是final +> 直到这里还没有解释为什么是final > 在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的。 > @@ -444,63 +430,62 @@ tags: ## 内部类初始化 我们一般都是利用构造器来完成某个实例的初始化工作的,但是匿名内部类是没有构造器的!那怎么来初始化匿名内部类呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果。 - - public class OutClass { - public InnerClass getInnerClass(final int age,final String name){ - return new InnerClass() { - int age_ ; - String name_; - //构造代码块完成初始化工作 - { - if(0 < age && age < 200){ - age_ = age; - name_ = name; - } - } - public String getName() { - return name_; +```` +public class OutClass { + public InnerClass getInnerClass(final int age,final String name){ + return new InnerClass() { + int age_ ; + String name_; + //构造代码块完成初始化工作 + { + if(0 < age && age < 200){ + age_ = age; + name_ = name; } - - public int getAge() { - return age_; - } - }; - } - - -​ + } + public String getName() { + return name_; + } + + public int getAge() { + return age_; + } + }; + } +```` + ## 内部类的重载 +如果你创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被重载吗?这看起来似乎是个很有用的点子,但是“重载”内部类就好像它是外围类的一个方法,其实并不起什么作用: +```` +class Egg { + private Yolk y; + + protected class Yolk { + public Yolk() { + System.out.println("Egg.Yolk()"); + } + } + + public Egg() { + System.out.println("New Egg()"); + y = new Yolk(); + } +} + +public class BigEgg extends Egg { + public class Yolk { + public Yolk() { + System.out.println("BigEgg.Yolk()"); + } + } + + public static void main(String[] args) { + new BigEgg(); + } +} -  如果你创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被重载吗?这看起来似乎是个很有用的点子,但是“重载”内部类就好像它是外围类的一个方法,其实并不起什么作用: - - - class Egg { - private Yolk y; - - protected class Yolk { - public Yolk() { - System.out.println("Egg.Yolk()"); - } - } - - public Egg() { - System.out.println("New Egg()"); - y = new Yolk(); - } - } - - public class BigEgg extends Egg { - public class Yolk { - public Yolk() { - System.out.println("BigEgg.Yolk()"); - } - } - - public static void main(String[] args) { - new BigEgg(); - } - } +```` 复制代码 输出结果为: New Egg() @@ -512,7 +497,7 @@ tags: ## 内部类的继承 因为内部类的构造器要用到其外围类对象的引用,所以在你继承一个内部类的时候,事情变得有点复杂。问题在于,那个“秘密的”外围类对象的引用必须被初始化,而在被继承的类中并不存在要联接的缺省对象。要解决这个问题,需使用专门的语法来明确说清它们之间的关联: - +```` class WithInner { class Inner { Inner(){ @@ -533,10 +518,11 @@ tags: InheritInner ii = new InheritInner(wi); } } -复制代码 -输出结果为: -this is a constructor in WithInner.Inner -this is a constructor in InheritInner +```` + 复制代码 + 输出结果为: + this is a constructor in WithInner.Inner + this is a constructor in InheritInner 可以看到,InheritInner 只继承自内部类,而不是外围类。但是当要生成一个构造器时,缺省的构造器并不算好,而且你不能只是传递一个指向外围类对象的引用。此外,你必须在构造器内使用如下语法: enclosingClassReference.super(); @@ -544,38 +530,6 @@ enclosingClassReference.super(); 有关匿名内部类实现回调,事件驱动,委托等机制的文章将在下一节讲述。 -## Java内部类的实现原理 - -内部类为什么能够访问外部类的成员? - -定义内部类如下: - -![Java 内部类](http://p3.pstatp.com/large/pgc-image/1539338093053104f5529ec) - -使用javap命令进行反编译。 - -编译后得到Main.class Main$Inner.class两个文件,反编译Main$Inner.class文件如下: - -![Java 内部类](http://p1.pstatp.com/large/pgc-image/1539338144888f57662c7bc) - -可以看到,内部类其实拥有外部类的一个引用,在构造函数中将外部类的引用传递进来。 - -匿名内部类为什么只能访问局部的final变量? - -其实可以这样想,当方法执行完毕后,局部变量的生命周期就结束了,而局部内部类对象的生命周期可能还没有结束,那么在局部内部类中访问局部变量就不可能了,所以将局部变量改为final,改变其生命周期。 - -编写代码如下: - -![Java 内部类](http://p1.pstatp.com/large/pgc-image/15393408957685bcddd1c64) - -这段代码编译为Main.class Main$1.class两个文件,反编译Main$1.class文件如下: - -![Java 内部类](http://p3.pstatp.com/large/pgc-image/1539341219661a629a53b8c) - -可以看到,java将编译时已经确定的值直接复制,进行替换,将无法确定的值放到了内部类的常量池中,并在构造函数中将其从常量池取出到字段中。 - -可以看出,java将局部变量m直接进行复制,所以其并不是原来的值,若在内部类中将m更改,局部变量的m值不会变,就会出现数据不一致,所以java就将其限制为final,使其不能进行更改,这样数据不一致的问题就解决了。 - ## 参考文章 https://www.cnblogs.com/hujingnb/p/10181621.html diff --git "a/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" "b/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" index 8ad5827..c5c96e2 100644 --- "a/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" +++ "b/docs/java/basic/19\343\200\201Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" @@ -61,8 +61,7 @@ tags: 在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影! -![image](https://img-blog.csdnimg.cn/20190222094403579.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p6dzE1MzE0MzkwOTA=,size_16,color_FFFFFF,t_70) - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403214433.png) java中集合大家族的成员实在是太丰富了,有常用的ArrayList、HashMap、HashSet,也有不常用的Stack、Queue,有线程安全的Vector、HashTable,也有线程不安全的LinkedList、TreeMap等等! ![](https://images0.cnblogs.com/blog/381060/201312/28124707-3a873160808e457686d67c118af6fa70.png) @@ -90,63 +89,63 @@ java中集合大家族的成员实在是太丰富了,有常用的ArrayList、H 在Java中所有实现了Collection接口的类都必须提供两套标准的构造函数,一个是无参,用于创建一个空的Collection,一个是带有Collection参数的有参构造函数,用于创建一个新的Collection,这个新的Collection与传入进来的Collection具备相同的元素。 //要求实现基本的增删改查方法,并且需要能够转换为数组类型 +```` +public class Collection接口 { + class collect implements Collection { - public class Collection接口 { - class collect implements Collection { - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - return false; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Object[] toArray() { - return new Object[0]; - } - - @Override - public boolean add(Object o) { - return false; - } - - @Override - public boolean remove(Object o) { - return false; - } - - @Override - public boolean addAll(Collection c) { - return false; - } - - @Override - public void clear() { - - } - //省略部分代码 - - @Override - public Object[] toArray(Object[] a) { - return new Object[0]; - } + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public boolean add(Object o) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; } - } + @Override + public void clear() { + + } +//省略部分代码 + + @Override + public Object[] toArray(Object[] a) { + return new Object[0]; + } + } +} +```` ## List接口 > List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。 @@ -173,84 +172,84 @@ java中集合大家族的成员实在是太丰富了,有常用的ArrayList、H > > 2.4、Stack > Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。。 +```` +public class List接口 { + //下面是List的继承关系,由于List接口规定了包括诸如索引查询,迭代器的实现,所以实现List接口的类都会有这些方法。 + //所以不管是ArrayList和LinkedList底层都可以使用数组操作,但一般不提供这样外部调用方法。 + // public interface Iterable +// public interface Collection extends Iterable +// public interface List extends Collection + class MyList implements List { + + @Override + public int size() { + return 0; + } - public class List接口 { - //下面是List的继承关系,由于List接口规定了包括诸如索引查询,迭代器的实现,所以实现List接口的类都会有这些方法。 - //所以不管是ArrayList和LinkedList底层都可以使用数组操作,但一般不提供这样外部调用方法。 - // public interface Iterable - // public interface Collection extends Iterable - // public interface List extends Collection - class MyList implements List { - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - return false; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Object[] toArray() { - return new Object[0]; - } - - @Override - public boolean add(Object o) { - return false; - } - - @Override - public boolean remove(Object o) { - return false; - } - - @Override - public void clear() { - - } - - //省略部分代码 - - @Override - public Object get(int index) { - return null; - } - - @Override - public ListIterator listIterator() { - return null; - } - - @Override - public ListIterator listIterator(int index) { - return null; - } - - @Override - public List subList(int fromIndex, int toIndex) { - return null; - } - - @Override - public Object[] toArray(Object[] a) { - return new Object[0]; - } + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public boolean add(Object o) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public void clear() { + + } + + //省略部分代码 + + @Override + public Object get(int index) { + return null; } - } + @Override + public ListIterator listIterator() { + return null; + } + + @Override + public ListIterator listIterator(int index) { + return null; + } + + @Override + public List subList(int fromIndex, int toIndex) { + return null; + } + + @Override + public Object[] toArray(Object[] a) { + return new Object[0]; + } + } +} +```` ## Set接口 > Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。实现了Set接口的集合有:EnumSet、HashSet、TreeSet。 @@ -261,83 +260,84 @@ java中集合大家族的成员实在是太丰富了,有常用的ArrayList、H > 3.2、HashSet > HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。 - public class Set接口 { - // Set接口规定将set看成一个集合,并且使用和数组类似的增删改查方式,同时提供iterator迭代器 - // public interface Set extends Collection - // public interface Collection extends Iterable - // public interface Iterable - class MySet implements Set { - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - return false; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Object[] toArray() { - return new Object[0]; - } - - @Override - public boolean add(Object o) { - return false; - } - - @Override - public boolean remove(Object o) { - return false; - } - - @Override - public boolean addAll(Collection c) { - return false; - } - - @Override - public void clear() { - - } - - @Override - public boolean removeAll(Collection c) { - return false; - } - - @Override - public boolean retainAll(Collection c) { - return false; - } - - @Override - public boolean containsAll(Collection c) { - return false; - } - - @Override - public Object[] toArray(Object[] a) { - return new Object[0]; - } +```` +public class Set接口 { + // Set接口规定将set看成一个集合,并且使用和数组类似的增删改查方式,同时提供iterator迭代器 + // public interface Set extends Collection + // public interface Collection extends Iterable + // public interface Iterable + class MySet implements Set { + + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public boolean add(Object o) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; } - } + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public Object[] toArray(Object[] a) { + return new Object[0]; + } + } +} +```` ## Map接口 -> Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的有:HashMap、TreeMap、HashTable、Properties、EnumMap。 +> Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的有:HashMap、TreeMap、HashTable、Properties、EnumMap。 > 4.1、HashMap > 以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。 @@ -347,152 +347,152 @@ java中集合大家族的成员实在是太丰富了,有常用的ArrayList、H > > 4.3、HashTable > 也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式,不过性能比HashMap要低 +```` +public class Map接口 { + //Map接口是最上层接口,Map接口实现类必须实现put和get等哈希操作。 + //并且要提供keyset和values,以及entryset等查询结构。 + //public interface Map + class MyMap implements Map { + + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsKey(Object key) { + return false; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public Object get(Object key) { + return null; + } + + @Override + public Object put(Object key, Object value) { + return null; + } + + @Override + public Object remove(Object key) { + return null; + } + + @Override + public void putAll(Map m) { + + } + + @Override + public void clear() { - public class Map接口 { - //Map接口是最上层接口,Map接口实现类必须实现put和get等哈希操作。 - //并且要提供keyset和values,以及entryset等查询结构。 - //public interface Map - class MyMap implements Map { - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean containsKey(Object key) { - return false; - } - - @Override - public boolean containsValue(Object value) { - return false; - } - - @Override - public Object get(Object key) { - return null; - } - - @Override - public Object put(Object key, Object value) { - return null; - } - - @Override - public Object remove(Object key) { - return null; - } - - @Override - public void putAll(Map m) { - - } - - @Override - public void clear() { - - } - - @Override - public Set keySet() { - return null; - } - - @Override - public Collection values() { - return null; - } - - @Override - public Set entrySet() { - return null; - } } - } + @Override + public Set keySet() { + return null; + } + + @Override + public Collection values() { + return null; + } + + @Override + public Set entrySet() { + return null; + } + } +} +```` ## Queue > 队列,它主要分为两大类,一类是阻塞式队列,队列满了以后再插入元素则会抛出异常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。 +```` +public class Queue接口 { + //queue接口是对队列的一个实现,需要提供队列的进队出队等方法。一般使用linkedlist作为实现类 + class MyQueue implements Queue { + + @Override + public int size() { + return 0; + } - public class Queue接口 { - //queue接口是对队列的一个实现,需要提供队列的进队出队等方法。一般使用linkedlist作为实现类 - class MyQueue implements Queue { - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - return false; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Object[] toArray() { - return new Object[0]; - } - - @Override - public Object[] toArray(Object[] a) { - return new Object[0]; - } - - @Override - public boolean add(Object o) { - return false; - } - - @Override - public boolean remove(Object o) { - return false; - } - - //省略部分代码 - @Override - public boolean offer(Object o) { - return false; - } - - @Override - public Object remove() { - return null; - } - - @Override - public Object poll() { - return null; - } - - @Override - public Object element() { - return null; - } - - @Override - public Object peek() { - return null; - } + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public Object[] toArray(Object[] a) { + return new Object[0]; + } + + @Override + public boolean add(Object o) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + //省略部分代码 + @Override + public boolean offer(Object o) { + return false; } - } + @Override + public Object remove() { + return null; + } + + @Override + public Object poll() { + return null; + } + + @Override + public Object element() { + return null; + } + + @Override + public Object peek() { + return null; + } + } +} +```` ## 关于Java集合的小抄 这部分内容转自我偶像 江南白衣 的博客:http://calvin1978.blogcn.com/articles/collection.html diff --git "a/docs/java/basic/20\343\200\201javac\345\222\214javap.md" "b/docs/java/basic/20\343\200\201javac\345\222\214javap.md" index dde513d..de74810 100644 --- "a/docs/java/basic/20\343\200\201javac\345\222\214javap.md" +++ "b/docs/java/basic/20\343\200\201javac\345\222\214javap.md" @@ -31,15 +31,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令 -date: 2019-9-20 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java命令行 ---- 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -81,119 +72,119 @@ java提供了JavaCompiler,我们可以通过它来编译java源文件为class 通过上面一个查找class,得到Class对象后,可以通过newInstance()或构造器的newInstance()得到对象。然后得到Method,最后调用方法,传入相关参数即可。 示例代码: - - public class MyIDE { - - public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { - // 定义java代码,并保存到文件(Test.java) - StringBuilder sb = new StringBuilder(); - sb.append("package com.tommy.core.test.reflect;\n"); - sb.append("public class Test {\n"); - sb.append(" private String name;\n"); - sb.append(" public Test(String name){\n"); - sb.append(" this.name = name;\n"); - sb.append(" System.out.println(\"hello,my name is \" + name);\n"); - sb.append(" }\n"); - sb.append(" public String sayHello(String name) {\n"); - sb.append(" return \"hello,\" + name;\n"); - sb.append(" }\n"); - sb.append("}\n"); - - System.out.println(sb.toString()); - - String baseOutputDir = "F:\\output\\classes\\"; - String baseDir = baseOutputDir + "com\\tommy\\core\\test\\reflect\\"; - String targetJavaOutputPath = baseDir + "Test.java"; - // 保存为java文件 - FileWriter fileWriter = new FileWriter(targetJavaOutputPath); - fileWriter.write(sb.toString()); - fileWriter.flush(); - fileWriter.close(); - - // 编译为class文件 - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager manager = compiler.getStandardFileManager(null,null,null); - List files = new ArrayList<>(); - files.add(new File(targetJavaOutputPath)); - Iterable compilationUnits = manager.getJavaFileObjectsFromFiles(files); - - // 编译 - // 设置编译选项,配置class文件输出路径 - Iterable options = Arrays.asList("-d",baseOutputDir); - JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, options, null, compilationUnits); - // 执行编译任务 - task.call(); - - -​ -​ // 通过反射得到对象 -​ // Class clazz = Class.forName("com.tommy.core.test.reflect.Test"); -​ // 使用自定义的类加载器加载class -​ Class clazz = new MyClassLoader(baseOutputDir).loadClass("com.tommy.core.test.reflect.Test"); -​ // 得到构造器 -​ Constructor constructor = clazz.getConstructor(String.class); -​ // 通过构造器new一个对象 -​ Object test = constructor.newInstance("jack.tsing"); -​ // 得到sayHello方法 -​ Method method = clazz.getMethod("sayHello", String.class); -​ // 调用sayHello方法 -​ String result = (String) method.invoke(test, "jack.ma"); -​ System.out.println(result); -​ } -​ } - +```` +public class MyIDE { + + public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + // 定义java代码,并保存到文件(Test.java) + StringBuilder sb = new StringBuilder(); + sb.append("package com.tommy.core.test.reflect;\n"); + sb.append("public class Test {\n"); + sb.append(" private String name;\n"); + sb.append(" public Test(String name){\n"); + sb.append(" this.name = name;\n"); + sb.append(" System.out.println(\"hello,my name is \" + name);\n"); + sb.append(" }\n"); + sb.append(" public String sayHello(String name) {\n"); + sb.append(" return \"hello,\" + name;\n"); + sb.append(" }\n"); + sb.append("}\n"); + + System.out.println(sb.toString()); + + String baseOutputDir = "F:\\output\\classes\\"; + String baseDir = baseOutputDir + "com\\tommy\\core\\test\\reflect\\"; + String targetJavaOutputPath = baseDir + "Test.java"; + // 保存为java文件 + FileWriter fileWriter = new FileWriter(targetJavaOutputPath); + fileWriter.write(sb.toString()); + fileWriter.flush(); + fileWriter.close(); + + // 编译为class文件 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager manager = compiler.getStandardFileManager(null,null,null); + List files = new ArrayList<>(); + files.add(new File(targetJavaOutputPath)); + Iterable compilationUnits = manager.getJavaFileObjectsFromFiles(files); + + // 编译 + // 设置编译选项,配置class文件输出路径 + Iterable options = Arrays.asList("-d",baseOutputDir); + JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, options, null, compilationUnits); + // 执行编译任务 + task.call(); + + + + // 通过反射得到对象 +// Class clazz = Class.forName("com.tommy.core.test.reflect.Test"); + // 使用自定义的类加载器加载class + Class clazz = new MyClassLoader(baseOutputDir).loadClass("com.tommy.core.test.reflect.Test"); + // 得到构造器 + Constructor constructor = clazz.getConstructor(String.class); + // 通过构造器new一个对象 + Object test = constructor.newInstance("jack.tsing"); + // 得到sayHello方法 + Method method = clazz.getMethod("sayHello", String.class); + // 调用sayHello方法 + String result = (String) method.invoke(test, "jack.ma"); + System.out.println(result); + } +} +```` 自定义类加载器代码: +```` + +public class MyClassLoader extends ClassLoader { + private String baseDir; + public MyClassLoader(String baseDir) { + this.baseDir = baseDir; + } + @Override + protected Class findClass(String name) throws ClassNotFoundException { + String fullClassFilePath = this.baseDir + name.replace("\\.","/") + ".class"; + File classFilePath = new File(fullClassFilePath); + if (classFilePath.exists()) { + FileInputStream fileInputStream = null; + ByteArrayOutputStream byteArrayOutputStream = null; + try { + fileInputStream = new FileInputStream(classFilePath); + byte[] data = new byte[1024]; + int len = -1; + byteArrayOutputStream = new ByteArrayOutputStream(); + while ((len = fileInputStream.read(data)) != -1) { + byteArrayOutputStream.write(data,0,len); + } -​ -​ public class MyClassLoader extends ClassLoader { -​ private String baseDir; -​ public MyClassLoader(String baseDir) { -​ this.baseDir = baseDir; -​ } -​ @Override -​ protected Class findClass(String name) throws ClassNotFoundException { -​ String fullClassFilePath = this.baseDir + name.replace("\\.","/") + ".class"; -​ File classFilePath = new File(fullClassFilePath); -​ if (classFilePath.exists()) { -​ FileInputStream fileInputStream = null; -​ ByteArrayOutputStream byteArrayOutputStream = null; -​ try { -​ fileInputStream = new FileInputStream(classFilePath); -​ byte[] data = new byte[1024]; -​ int len = -1; -​ byteArrayOutputStream = new ByteArrayOutputStream(); -​ while ((len = fileInputStream.read(data)) != -1) { -​ byteArrayOutputStream.write(data,0,len); -​ } -​ - return defineClass(name,byteArrayOutputStream.toByteArray(),0,byteArrayOutputStream.size()); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (null != fileInputStream) { - try { - fileInputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } + return defineClass(name,byteArrayOutputStream.toByteArray(),0,byteArrayOutputStream.size()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (null != fileInputStream) { + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); } - - if (null != byteArrayOutputStream) { - try { - byteArrayOutputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } + } + + if (null != byteArrayOutputStream) { + try { + byteArrayOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); } } } - return super.findClass(name); } - } - + return super.findClass(name); + } +} +```` ## javac命令初窥 注:以下红色标记的参数在下文中有所讲解。 @@ -316,7 +307,7 @@ javac:如果当前你要编译的java文件中引用了其它的类(比如说 > 这里展示一个web项目的.classpath Xml代码 - +```` @@ -328,7 +319,7 @@ Xml代码 …… - +```` > XML文档包含一个根元素,就是classpath,类路径,那么这里面包含了什么信息呢?子元素是classpathentry,kind属性区别了种 类信息,src源码,con你看看后面的path就知道是JRE容器的信息。lib是项目依赖的第三方类库,output是src编译后的位置。 > 既然是web项目,那么就是WEB-INF/classes目录,可能用MyEclipse的同学会说他们那里是WebRoot或者是WebContext而不是webapp,有区别么?回答:完全没有! @@ -393,27 +384,27 @@ Xml代码 举个例子, - - public class A - { - public static void main(String[] args) { - B b = new B(); - b.print(); - } +```` +public class A +{ + public static void main(String[] args) { + B b = new B(); + b.print(); } +} -​ -​ -​ public class B -​ { -​ public void print() -​ { -​ System.out.println("old"); -​ } -​ } +public class B +{ + public void print() + { + System.out.println("old"); + } +} +```` + 目录结构如下: @@ -451,19 +442,19 @@ sourcepath //此处为当前目录 这里我用来实现一下这个功能,假设项目名称为project,此目录为当前目录,且在src/com目录中有一个Main.java文件。‘ -​ -​ package com; -​ public class Main -​ { -​ public static void main(String[] args) { -​ System.out.println("Hello"); -​ } -​ } +```` + package com; + public class Main + { + public static void main(String[] args) { + System.out.println("Hello"); + } + } -​ -​ -​ javac -d bin src/com/Main.java +```` + +javac -d bin src/com/Main.java 上面的语句将Main.class生成在bin/com目录下。 @@ -472,23 +463,23 @@ sourcepath //此处为当前目录 •如果有文件为A.java(其中有类A),且在类A中使用了类B,类B在B.java中,则编译A.java时,默认会自动编译B.java,且生成B.class。 •implicit:none:不自动生成隐式引用的类文件。 •implicit:class(默认):自动生成隐式引用的类文件。 - - public class A - { - public static void main(String[] args) { - B b = new B(); - } - } - - public class B - { +```` +public class A +{ + public static void main(String[] args) { + B b = new B(); } - - 如果使用: +} +public class B +{ +} +```` +如果使用: -​ -​ javac -implicit:none A.java + + +javac -implicit:none A.java 则不会生成 B.class。 @@ -578,18 +569,18 @@ src/com/yp/test/HelloWorld.java build/ -``` +```` ├─build └─src └─com └─yp └─test HelloWorld.java -``` +```` java文件非常简单 - +```` package com.yp.test; public class HelloWorld { @@ -597,12 +588,14 @@ java文件非常简单 System.out.println("helloWorld"); } } +```` + 编译: javac src/com/yp/test/HelloWorld.java -d build -d 表示编译到 build文件夹下 -``` +```` 查看build文件夹 ├─build │ └─com @@ -615,10 +608,11 @@ javac src/com/yp/test/HelloWorld.java -d build └─yp └─test HelloWorld.java -``` +```` 运行文件 + > E:\codeplace\n_learn\java\javacmd> java com/yp/test/HelloWorld.class > 错误: 找不到或无法加载主类 build.com.yp.test.HelloWorld.class > @@ -677,27 +671,28 @@ javac src/com/yp/test/HelloWorld.java -d build 先下一个jar包 这里直接下 log4j - * main函数改成 - - import com.yp.test.entity.Cat; - import org.apache.log4j.Logger; - - public class HelloWorld { - - static Logger log = Logger.getLogger(HelloWorld.class); - - public static void main(String[] args) { - Cat c = new Cat("keyboard"); - log.info("这是log4j"); - System.out.println("hello," + c.getName()); - } - +* main函数改成 + +```` +import com.yp.test.entity.Cat; +import org.apache.log4j.Logger; + +public class HelloWorld { + + static Logger log = Logger.getLogger(HelloWorld.class); + + public static void main(String[] args) { + Cat c = new Cat("keyboard"); + log.info("这是log4j"); + System.out.println("hello," + c.getName()); } +} +```` 现的文件是这样的 -``` +```` ├─build ├─lib │ log4j-1.2.17.jar @@ -710,8 +705,7 @@ javac src/com/yp/test/HelloWorld.java -d build │ └─entity Cat.java -``` - +```` 这个时候 javac命令要接上 -cp ./lib/*.jar E:\codeplace\n_learn\java\javacmd>javac -encoding "utf8" src/com/yp/test/HelloWorld.java -sourcepath src -d build -g -cp ./lib/*.jar @@ -729,21 +723,22 @@ javac src/com/yp/test/HelloWorld.java -d build 由于没有 log4j的配置文件,所以提示上面的问题,往 build 里面加上 log4j.xml - - - - - - - - - - - - - - - +```` + + + + + + + + + + + + + + +```` 再运行 E:\codeplace\n_learn\java\javacmd>java -cp lib/log4j-1.2.17.jar;build com.yp.tes t.HelloWorld @@ -757,7 +752,7 @@ ok 一个简单的java 工程就运行完了 但是 貌似有些繁琐, 需要手动键入 java文件 以及相应的jar包 很是麻烦, so 可以用 shell 来脚本来简化相关操作 shell 文件整理如下: - +```` #!/bin/bash echo "build start" @@ -788,6 +783,7 @@ shell 文件整理如下: #运行 通过-cp指定所有的引用jar包,指定入口函数运行 java -cp $BIN_PATH$jarfile com.zuiapps.danmaku.server.Main +```` > 有一点需要注意的是, javac -d $BIN_PATH/ -cp $jarfile @$SRC_FILE_LIST_PATH > 在要编译的文件很多时候,一个个敲命令会显得很长,也不方便修改, @@ -805,7 +801,7 @@ shell 文件整理如下: 1.需要吧 编译时设置的bin目录和 所有jar包加入到 classpath 中去 -​ + ## javap 的使用 > javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码。 @@ -815,37 +811,37 @@ shell 文件整理如下: > > > javap命令分解一个class文件,它根据options来决定到底输出什么。如果没有使用options,那么javap将会输出包,类里的protected和public域以及类里的所有方法。javap将会把它们输出在标准输出上。来看这个例子,先编译(javac)下面这个类。 - - import java.awt.*; - import java.applet.*; - - public class DocFooter extends Applet { - String date; - String email; - - public void init() { - resize(500,100); - date = getParameter("LAST_UPDATED"); - email = getParameter("EMAIL"); - } - } - +```` +import java.awt.*; +import java.applet.*; + +public class DocFooter extends Applet { + String date; + String email; + + public void init() { + resize(500,100); + date = getParameter("LAST_UPDATED"); + email = getParameter("EMAIL"); + } +} +```` 在命令行上键入javap DocFooter后,输出结果如下 Compiled from "DocFooter.java" - - public class DocFooter extends java.applet.Applet { - java.lang.String date; - java.lang.String email; - public DocFooter(); - public void init(); - } - +```` +public class DocFooter extends java.applet.Applet { + java.lang.String date; + java.lang.String email; + public DocFooter(); + public void init(); +} +```` 如果加入了-c,即javap -c DocFooter,那么输出结果如下 Compiled from "DocFooter.java" - +```` public class DocFooter extends java.applet.Applet { java.lang.String date; @@ -876,6 +872,7 @@ Compiled from "DocFooter.java" 29: return } +```` 上面输出的内容就是字节码。 用法摘要 diff --git "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" index 14b4137..157f61c 100644 --- "a/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" +++ "b/docs/java/basic/21\343\200\201Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" @@ -19,15 +19,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列21:Java8新特性终极指南 -date: 2019-9-21 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java8 ---- 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -48,8 +39,7 @@ tags: 这是一个Java8新增特性的总结图。接下来让我们一次实践一下这些新特性吧 -![image](https://img2018.cnblogs.com/blog/493447/201906/493447-20190604133048748-2090946599.png) - +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/20230403215737.png) ## Java语言新特性 ### Lambda表达式 @@ -100,13 +90,14 @@ java.lang.Runnable与java.util.concurrent.Callable是函数式接口最典型的 在实际使用过程中,函数式接口是容易出错的:如有某个人在接口定义中增加了另一个方法,这时,这个接口就不再是函数式的了,并且编译过程也会失败。 为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图,Java8增加了一种特殊的注解@FunctionalInterface(Java8中所有类库的已有接口都添加了@FunctionalInterface注解)。让我们看一下这种函数式接口的定义: - +```` @FunctionalInterface public interface Functional { void method(); } +```` 需要记住的一件事是:默认方法与静态方法并不影响函数式接口的契约,可以任意使用: - +```` @FunctionalInterface public interface FunctionalDefaultMethods { void method(); @@ -114,82 +105,83 @@ public interface FunctionalDefaultMethods { default void defaultMethod() { } } +```` Lambda是Java 8最大的卖点。它具有吸引越来越多程序员到Java平台上的潜力,并且能够在纯Java语言环境中提供一种优雅的方式来支持函数式编程。更多详情可以参考官方文档。 下面看一个例子: +```` +public class lambda和函数式编程 { + @Test + public void test1() { + List names = Arrays.asList("peter", "anna", "mike", "xenia"); - public class lambda和函数式编程 { - @Test - public void test1() { - List names = Arrays.asList("peter", "anna", "mike", "xenia"); - - Collections.sort(names, new Comparator() { - @Override - public int compare(String a, String b) { - return b.compareTo(a); - } - }); - System.out.println(Arrays.toString(names.toArray())); - } - - @Test - public void test2() { - List names = Arrays.asList("peter", "anna", "mike", "xenia"); - - Collections.sort(names, (String a, String b) -> { + Collections.sort(names, new Comparator() { + @Override + public int compare(String a, String b) { return b.compareTo(a); - }); - - Collections.sort(names, (String a, String b) -> b.compareTo(a)); - - Collections.sort(names, (a, b) -> b.compareTo(a)); - System.out.println(Arrays.toString(names.toArray())); - } - + } + }); + System.out.println(Arrays.toString(names.toArray())); } - - static void add(double a,String b) { - System.out.println(a + b); - } - @Test - public void test5() { - D d = (a,b) -> add(a,b); - // interface D { - // void get(int i,String j); - // } - //这里要求,add的两个参数和get的两个参数吻合并且返回类型也要相等,否则报错 - // static void add(double a,String b) { - // System.out.println(a + b); - // } - } - - @FunctionalInterface - interface D { - void get(int i,String j); - } -接下来看看Lambda和匿名内部类的区别 + @Test + public void test2() { + List names = Arrays.asList("peter", "anna", "mike", "xenia"); -匿名内部类仍然是一个类,只是不需要我们显式指定类名,编译器会自动为该类取名。比如有如下形式的代码: + Collections.sort(names, (String a, String b) -> { + return b.compareTo(a); + }); - public class LambdaTest { - public static void main(String[] args) { - new Thread(new Runnable() { - @Override - public void run() { - System.out.println("Hello World"); - } - }).start(); - } + Collections.sort(names, (String a, String b) -> b.compareTo(a)); + + Collections.sort(names, (a, b) -> b.compareTo(a)); + System.out.println(Arrays.toString(names.toArray())); } +} + + static void add(double a,String b) { + System.out.println(a + b); + } + @Test + public void test5() { + D d = (a,b) -> add(a,b); +// interface D { +// void get(int i,String j); +// } + //这里要求,add的两个参数和get的两个参数吻合并且返回类型也要相等,否则报错 +// static void add(double a,String b) { +// System.out.println(a + b); +// } + } + + @FunctionalInterface + interface D { + void get(int i,String j); + } +```` +接下来看看Lambda和匿名内部类的区别 + +匿名内部类仍然是一个类,只是不需要我们显式指定类名,编译器会自动为该类取名。比如有如下形式的代码: +```` +public class LambdaTest { + public static void main(String[] args) { + new Thread(new Runnable() { + @Override + public void run() { + System.out.println("Hello World"); + } + }).start(); + } +} +```` 编译之后将会产生两个 class 文件: LambdaTest.class LambdaTest$1.class 使用 javap -c LambdaTest.class 进一步分析 LambdaTest.class 的字节码,部分结果如下: - +```` public static void main(java.lang.String[]); Code: 0: new #2 // class java/lang/Thread @@ -200,28 +192,28 @@ Lambda是Java 8最大的卖点。它具有吸引越来越多程序员到Java平 11: invokespecial #5 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V 14: invokevirtual #6 // Method java/lang/Thread.start:()V 17: return - +```` 可以发现在 4: new #3 这一行创建了匿名内部类的对象。 而对于 Lambda表达式的实现, 接下来我们将上面的示例代码使用 Lambda 表达式实现,代码如下: - - public class LambdaTest { - public static void main(String[] args) { - new Thread(() -> System.out.println("Hello World")).start(); - } +```` +public class LambdaTest { + public static void main(String[] args) { + new Thread(() -> System.out.println("Hello World")).start(); } - +} +```` 此时编译后只会产生一个文件 LambdaTest.class,再来看看通过 javap 对该文件反编译后的结果: - - public static void main(java.lang.String[]); - Code: - 0: new #2 // class java/lang/Thread - 3: dup - 4: invokedynamic #3, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; - 9: invokespecial #4 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V - 12: invokevirtual #5 // Method java/lang/Thread.start:()V - 15: return - +```` +public static void main(java.lang.String[]); +Code: + 0: new #2 // class java/lang/Thread + 3: dup + 4: invokedynamic #3, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; + 9: invokespecial #4 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V + 12: invokevirtual #5 // Method java/lang/Thread.start:()V + 15: return +```` 从上面的结果我们发现 Lambda 表达式被封装成了主类的一个私有方法,并通过 invokedynamic 指令进行调用。 因此,我们可以得出结论:Lambda 表达式是通过 invokedynamic 指令实现的,并且书写 Lambda 表达式不会产生新的类。 @@ -238,50 +230,50 @@ lambda表达式是如何符合 Java 类型系统的?每个lambda对应于一 我们可以使用任意的接口作为lambda表达式,只要这个接口只包含一个抽象方法。为了保证你的接口满足需求,你需要增加@FunctionalInterface注解。编译器知道这个注解,一旦你试图给这个接口增加第二个抽象方法声明时,它将抛出一个编译器错误。 下面举几个例子 - - public class 函数式接口使用 { - @FunctionalInterface - interface A { - void say(); - default void talk() { - - } - } - @Test - public void test1() { - A a = () -> System.out.println("hello"); - a.say(); - } - - @FunctionalInterface - interface B { - void say(String i); - } - public void test2() { - //下面两个是等价的,都是通过B接口来引用一个方法,而方法可以直接使用::来作为方法引用 - B b = System.out::println; - B b1 = a -> Integer.parseInt("s");//这里的a其实换成别的也行,只是将方法传给接口作为其方法实现 - B b2 = Integer::valueOf;//i与方法传入参数的变量类型一直时,可以直接替换 - B b3 = String::valueOf; - //B b4 = Integer::parseInt;类型不符,无法使用 - - } - @FunctionalInterface - interface C { - int say(String i); - } - public void test3() { - C c = Integer::parseInt;//方法参数和接口方法的参数一样,可以替换。 - int i = c.say("1"); - //当我把C接口的int替换为void时就会报错,因为返回类型不一致。 - System.out.println(i); - //综上所述,lambda表达式提供了一种简便的表达方式,可以将一个方法传到接口中。 - //函数式接口是只提供一个抽象方法的接口,其方法由lambda表达式注入,不需要写实现类, - //也不需要写匿名内部类,可以省去很多代码,比如实现runnable接口。 - //函数式编程就是指把方法当做一个参数或引用来进行操作。除了普通方法以外,静态方法,构造方法也是可以这样操作的。 +```` +public class 函数式接口使用 { + @FunctionalInterface + interface A { + void say(); + default void talk() { + } } + @Test + public void test1() { + A a = () -> System.out.println("hello"); + a.say(); + } + + @FunctionalInterface + interface B { + void say(String i); + } + public void test2() { + //下面两个是等价的,都是通过B接口来引用一个方法,而方法可以直接使用::来作为方法引用 + B b = System.out::println; + B b1 = a -> Integer.parseInt("s");//这里的a其实换成别的也行,只是将方法传给接口作为其方法实现 + B b2 = Integer::valueOf;//i与方法传入参数的变量类型一直时,可以直接替换 + B b3 = String::valueOf; + //B b4 = Integer::parseInt;类型不符,无法使用 + } + @FunctionalInterface + interface C { + int say(String i); + } + public void test3() { + C c = Integer::parseInt;//方法参数和接口方法的参数一样,可以替换。 + int i = c.say("1"); + //当我把C接口的int替换为void时就会报错,因为返回类型不一致。 + System.out.println(i); + //综上所述,lambda表达式提供了一种简便的表达方式,可以将一个方法传到接口中。 + //函数式接口是只提供一个抽象方法的接口,其方法由lambda表达式注入,不需要写实现类, + //也不需要写匿名内部类,可以省去很多代码,比如实现runnable接口。 + //函数式编程就是指把方法当做一个参数或引用来进行操作。除了普通方法以外,静态方法,构造方法也是可以这样操作的。 + } +} +```` 请记住如果@FunctionalInterface 这个注解被遗漏,此代码依然有效。 ### 方法引用 @@ -290,7 +282,7 @@ Lambda表达式和方法引用 有了函数式接口之后,就可以使用Lambda表达式和方法引用了。其实函数式接口的表中的函数描述符就是Lambda表达式,在函数式接口中Lambda表达式相当于匿名内部类的效果。 举个简单的例子: - +```` public class TestLambda { public static void execute(Runnable runnable) { @@ -310,7 +302,7 @@ public class TestLambda { execute(() -> System.out.println("run")); } } - +```` 可以看到,相比于使用匿名内部类的方式,Lambda表达式可以使用更少的代码但是有更清晰的表述。注意,Lambda表达式也不是完全等价于匿名内部类的, 两者的不同点在于this的指向和本地变量的屏蔽上。 方法引用可以看作Lambda表达式的更简洁的一种表达形式,使用::操作符,方法引用主要有三类: @@ -351,31 +343,31 @@ public class TestLambda { ### 接口的默认方法 Java 8 使我们能够使用default 关键字给接口增加非抽象的方法实现。这个特性也被叫做 扩展方法(Extension Methods)。如下例所示: - - public class 接口的默认方法 { - class B implements A { - // void a(){}实现类方法不能重名 - } - interface A { - //可以有多个默认方法 - public default void a(){ - System.out.println("a"); - } - public default void b(){ - System.out.println("b"); - } - //报错static和default不能同时使用 - // public static default void c(){ - // System.out.println("c"); - // } +```` +public class 接口的默认方法 { + class B implements A { +// void a(){}实现类方法不能重名 + } + interface A { + //可以有多个默认方法 + public default void a(){ + System.out.println("a"); } - public void test() { - B b = new B(); - b.a(); - + public default void b(){ + System.out.println("b"); } + //报错static和default不能同时使用 +// public static default void c(){ +// System.out.println("c"); +// } } + public void test() { + B b = new B(); + b.a(); + } +} +```` 默认方法出现的原因是为了对原有接口的扩展,有了默认方法之后就不怕因改动原有的接口而对已经使用这些接口的程序造成的代码不兼容的影响。 在Java8中也对一些接口增加了一些默认方法,比如Map接口等等。一般来说,使用默认方法的场景有两个:可选方法和行为的多继承。 默认方法的使用相对来说比较简单,唯一要注意的点是如何处理默认方法的冲突。关于如何处理默认方法的冲突可以参考以下三条规则: @@ -385,7 +377,7 @@ Java 8 使我们能够使用default 关键字给接口增加非抽象的方法 如果无法依据第一条规则进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口。即如果B继承了A,那么B就比A更具体。 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。那么如何显式地指定呢: - +```` public class C implements B, A { public void hello() { @@ -393,43 +385,46 @@ Java 8 使我们能够使用default 关键字给接口增加非抽象的方法 } } +```` 使用X.super.m(..)显式地调用希望调用的方法。 Java 8用默认方法与静态方法这两个新概念来扩展接口的声明。默认方法使接口有点像Traits(Scala中特征(trait)类似于Java中的Interface,但它可以包含实现代码,也就是目前Java8新增的功能),但与传统的接口又有些不一样,它允许在已有的接口中添加新方法,而同时又保持了与旧版本代码的兼容性。 默认方法与抽象方法不同之处在于抽象方法必须要求实现,但是默认方法则没有这个要求。相反,每个接口都必须提供一个所谓的默认实现,这样所有的接口实现者将会默认继承它(如果有必要的话,可以覆盖这个默认实现)。让我们看看下面的例子: - - private interface Defaulable { - // Interfaces now allow default methods, the implementer may or - // may not implement (override) them. - default String notRequired() { - return "Default implementation"; - } - } - - private static class DefaultableImpl implements Defaulable { - } +```` +private interface Defaulable { + // Interfaces now allow default methods, the implementer may or + // may not implement (override) them. + default String notRequired() { + return "Default implementation"; + } +} - private static class OverridableImpl implements Defaulable { - @Override - public String notRequired() { - return "Overridden implementation"; - } +private static class DefaultableImpl implements Defaulable { +} + +private static class OverridableImpl implements Defaulable { + @Override + public String notRequired() { + return "Overridden implementation"; } +} +```` Defaulable接口用关键字default声明了一个默认方法notRequired(),Defaulable接口的实现者之一DefaultableImpl实现了这个接口,并且让默认方法保持原样。Defaulable接口的另一个实现者OverridableImpl用自己的方法覆盖了默认方法。 Java 8带来的另一个有趣的特性是接口可以声明(并且可以提供实现)静态方法。例如: - +```` private interface DefaulableFactory { // Interfaces now allow static methods static Defaulable create( Supplier< Defaulable > supplier ) { return supplier.get(); } } +```` 下面的一小段代码片段把上面的默认方法与静态方法黏合到一起。 - +```` public static void main( String[] args ) { Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new ); System.out.println( defaulable.notRequired() ); @@ -437,6 +432,7 @@ Java 8带来的另一个有趣的特性是接口可以声明(并且可以提 defaulable = DefaulableFactory.create( OverridableImpl::new ); System.out.println( defaulable.notRequired() ); } +```` 这个程序的控制台输出如下: Default implementation @@ -450,58 +446,57 @@ Overridden implementation 自从Java 5引入了注解机制,这一特性就变得非常流行并且广为使用。然而,使用注解的一个限制是相同的注解在同一位置只能声明一次,不能声明多次。Java 8打破了这条规则,引入了重复注解机制,这样相同的注解可以在同一地方声明多次。 重复注解机制本身必须用@Repeatable注解。事实上,这并不是语言层面上的改变,更多的是编译器的技巧,底层的原理保持不变。让我们看一个快速入门的例子: - - package com.javacodegeeks.java8.repeatable.annotations; +```` +package com.javacodegeeks.java8.repeatable.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public class RepeatingAnnotations { + @Target( ElementType.TYPE ) + @Retention( RetentionPolicy.RUNTIME ) + public @interface Filters { + Filter[] value(); + } - import java.lang.annotation.ElementType; - import java.lang.annotation.Repeatable; - import java.lang.annotation.Retention; - import java.lang.annotation.RetentionPolicy; - import java.lang.annotation.Target; + @Target( ElementType.TYPE ) + @Retention( RetentionPolicy.RUNTIME ) + @Repeatable( Filters.class ) + public @interface Filter { + String value(); + }; - public class RepeatingAnnotations { - @Target( ElementType.TYPE ) - @Retention( RetentionPolicy.RUNTIME ) - public @interface Filters { - Filter[] value(); - } - - @Target( ElementType.TYPE ) - @Retention( RetentionPolicy.RUNTIME ) - @Repeatable( Filters.class ) - public @interface Filter { - String value(); - }; - - @Filter( "filter1" ) - @Filter( "filter2" ) - public interface Filterable { - } - - public static void main(String[] args) { - for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) { - System.out.println( filter.value() ); - } + @Filter( "filter1" ) + @Filter( "filter2" ) + public interface Filterable { + } + + public static void main(String[] args) { + for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) { + System.out.println( filter.value() ); } } +} +```` 正如我们看到的,这里有个使用@Repeatable( Filters.class )注解的注解类Filter,Filters仅仅是Filter注解的数组,但Java编译器并不想让程序员意识到Filters的存在。这样,接口Filterable就拥有了两次Filter(并没有提到Filter)注解。 同时,反射相关的API提供了新的函数getAnnotationsByType()来返回重复注解的类型(请注意Filterable.class.getAnnotation( Filters.class )经编译器处理后将会返回Filters的实例)。 程序输出结果如下: -filter1 -filter2 + filter1 + filter2 更多详情请参考官方文档 - - ## Java编译器的新特性 ### 方法参数名字可以反射获取 很长一段时间里,Java程序员一直在发明不同的方式使得方法参数的名字能保留在Java字节码中,并且能够在运行时获取它们(比如,Paranamer类库)。最终,在Java 8中把这个强烈要求的功能添加到语言层面(通过反射API与Parameter.getName()方法)与字节码文件(通过新版的javac的–parameters选项)中。 - +```` package com.javacodegeeks.java8.parameter.names; import java.lang.reflect.Method; @@ -515,6 +510,7 @@ public class ParameterNames { } } } +```` 如果不使用–parameters参数来编译这个类,然后运行这个类,会得到下面的输出: Parameter: arg0 @@ -531,7 +527,7 @@ Java 8 通过增加大量新类,扩展已有类的功能的方式来改善对 Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。更多详情请参考官方文档。 我们下面用两个小例子来演示如何使用Optional类:一个允许为空值,一个不允许为空值。 - +```` public class 空指针Optional { public static void main(String[] args) { @@ -554,7 +550,7 @@ Optional实际上是个容器:它可以保存类型T的值,或者仅仅保 //输出Optional.empty。 } } - +```` 如果Optional类的实例为非空值的话,isPresent()返回true,否从返回false。为了防止Optional为空值,orElseGet()方法通过回调函数来产生一个默认值。map()函数对当前Optional的值进行转化,然后返回一个新的Optional实例。orElse()方法和orElseGet()方法类似,但是orElse接受一个默认值而不是一个回调函数。下面是这个程序的输出: Full Name is set? false @@ -581,14 +577,15 @@ Hey Tom! Stream API极大简化了集合框架的处理(但它的处理的范围不仅仅限于集合框架的处理,这点后面我们会看到)。让我们以一个简单的Task类为例进行介绍: Task类有一个分数的概念(或者说是伪复杂度),其次是还有一个值可以为OPEN或CLOSED的状态.让我们引入一个Task的小集合作为演示例子: - +```` final Collection< Task > tasks = Arrays.asList( new Task( Status.OPEN, 5 ), new Task( Status.OPEN, 13 ), new Task( Status.CLOSED, 8 ) ); +```` 我们下面要讨论的第一个问题是所有状态为OPEN的任务一共有多少分数?在Java 8以前,一般的解决方式用foreach循环,但是在Java 8里面我们可以使用stream:一串支持连续、并行聚集操作的元素。 - +```` // Calculate total points of all active tasks using sum() final long totalPointsOfOpenTasks = tasks .stream() @@ -597,9 +594,10 @@ Task类有一个分数的概念(或者说是伪复杂度),其次是还有 .sum(); System.out.println( "Total points: " + totalPointsOfOpenTasks ); +```` 程序在控制台上的输出如下: -Total points: 18 + Total points: 18 这里有几个注意事项。 @@ -617,7 +615,7 @@ Total points: 18 stream另一个有价值的地方是能够原生支持并行处理。让我们来看看这个算task分数和的例子。 stream另一个有价值的地方是能够原生支持并行处理。让我们来看看这个算task分数和的例子。 - +```` // Calculate total points of all tasks final double totalPoints = tasks .stream() @@ -626,23 +624,28 @@ stream另一个有价值的地方是能够原生支持并行处理。让我们 .reduce( 0, Integer::sum ); System.out.println( "Total points (all tasks): " + totalPoints ); +```` 这个例子和第一个例子很相似,但这个例子的不同之处在于这个程序是并行运行的,其次使用reduce方法来算最终的结果。 下面是这个例子在控制台的输出: Total points (all tasks): 26.0 经常会有这个一个需求:我们需要按照某种准则来对集合中的元素进行分组。Stream也可以处理这样的需求,下面是一个例子: - +```` // Group tasks by their status final Map< Status, List< Task > > map = tasks .stream() .collect( Collectors.groupingBy( Task::getStatus ) ); System.out.println( map ); +```` + 这个例子的控制台输出如下: -{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]} + {CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]} + 让我们来计算整个集合中每个task分数(或权重)的平均值来结束task的例子。 +```` // Calculate the weight of each tasks (as percent of total points) final Collection< String > result = tasks .stream() // Stream< String > @@ -655,15 +658,19 @@ Total points (all tasks): 26.0 .collect( Collectors.toList() ); // List< String > System.out.println( result ); +```` + 下面是这个例子的控制台输出: [19%, 50%, 30%] 最后,就像前面提到的,Stream API不仅仅处理Java集合框架。像从文本文件中逐行读取数据这样典型的I/O操作也很适合用Stream API来处理。下面用一个例子来应证这一点。 - +```` final Path path = new File( filename ).toPath(); try( Stream< String > lines = Files.lines( path, StandardCharsets.UTF_8 ) ) { lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println ); } +```` + 对一个stream对象调用onClose方法会返回一个在原有功能基础上新增了关闭功能的stream对象,当对stream对象调用close()方法时,与关闭相关的处理器就会执行。 Stream API、Lambda表达式与方法引用在接口默认方法与静态方法的配合下是Java 8对现代软件开发范式的回应。更多详情请参考官方文档。 @@ -674,19 +681,19 @@ Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时 这种情况直接导致了Joda-Time——一个可替换标准日期/时间处理且功能非常强大的Java API的诞生。Java 8新的Date-Time API (JSR 310)在很大程度上受到Joda-Time的影响,并且吸取了其精髓。新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。在设计新版API时,十分注重与旧版API的兼容性:不允许有任何的改变(从java.util.Calendar中得到的深刻教训)。如果需要修改,会返回这个类的一个新实例。 让我们用例子来看一下新版API主要类的使用方法。第一个是Clock类,它通过指定一个时区,然后就可以获取到当前的时刻,日期与时间。Clock可以替换System.currentTimeMillis()与TimeZone.getDefault()。 - +```` // Get the system clock as UTC offset final Clock clock = Clock.systemUTC(); System.out.println( clock.instant() ); System.out.println( clock.millis() ); - +```` 下面是程序在控制台上的输出: 2014-04-12T15:19:29.282Z 1397315969360 我们需要关注的其他类是LocaleDate与LocalTime。LocaleDate只持有ISO-8601格式且无时区信息的日期部分。相应的,LocaleTime只持有ISO-8601格式且无时区信息的时间部分。LocaleDate与LocalTime都可以从Clock中得到。 - +```` // Get the local date and local time final LocalDate date = LocalDate.now(); final LocalDate dateFromClock = LocalDate.now( clock ); @@ -700,7 +707,7 @@ Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时 System.out.println( time ); System.out.println( timeFromClock ); - +```` 下面是程序在控制台上的输出: 2014-04-12 @@ -715,7 +722,7 @@ Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时 2014-04-12T08:47:01.017-07:00[America/Los_Angeles] 最后,让我们看一下Duration类:在秒与纳秒级别上的一段时间。Duration使计算两个日期间的不同变的十分简单。下面让我们看一个这方面的例子。 - +```` // Get duration between two dates final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 ); final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 ); @@ -723,7 +730,7 @@ Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时 final Duration duration = Duration.between( from, to ); System.out.println( "Duration in days: " + duration.toDays() ); System.out.println( "Duration in hours: " + duration.toHours() ); - +```` 上面的例子计算了两个日期2014年4月16号与2014年4月16号之间的过程。下面是程序在控制台上的输出: Duration in days: 365 @@ -733,7 +740,7 @@ Duration in hours: 8783 ### 并行(parallel)数组 Java 8增加了大量的新方法来对数组进行并行处理。可以说,最重要的是parallelSort()方法,因为它可以在多核机器上极大提高数组排序的速度。下面的例子展示了新方法(parallelXxx)的使用。 - +```` package com.javacodegeeks.java8.parallel.arrays; import java.util.Arrays; @@ -755,7 +762,7 @@ Java 8增加了大量的新方法来对数组进行并行处理。可以说, System.out.println(); } } - +```` 上面的代码片段使用了parallelSetAll()方法来对一个有20000个元素的数组进行随机赋值。然后,调用parallelSort方法。这个程序首先打印出前10个元素的值,之后对整个数组排序。这个程序在控制台上的输出如下(请注意数组元素是随机生产的): Unsorted: 591217 891976 443951 424479 766825 351964 242997 642839 119108 552378 @@ -766,7 +773,7 @@ Sorted: 39 220 263 268 325 607 655 678 723 793 在Java8之前,我们会使用JDK提供的Future接口来进行一些异步的操作,其实CompletableFuture也是实现了Future接口, 并且基于ForkJoinPool来执行任务,因此本质上来讲,CompletableFuture只是对原有API的封装, 而使用CompletableFuture与原来的Future的不同之处在于可以将两个Future组合起来,或者如果两个Future是有依赖关系的,可以等第一个执行完毕后再实行第二个等特性。 **先来看看基本的使用方式:** - +```` public Future getPriceAsync(final String product) { final CompletableFuture futurePrice = new CompletableFuture<>(); new Thread(() -> { @@ -775,13 +782,14 @@ Sorted: 39 220 263 268 325 607 655 678 723 793 }).start(); return futurePrice; } +```` 得到Future之后就可以使用get方法来获取结果,CompletableFuture提供了一些工厂方法来简化这些API,并且使用函数式编程的方式来使用这些API,例如: Fufure price = CompletableFuture.supplyAsync(() -> calculatePrice(product)); 代码是不是一下子简洁了许多呢。之前说了,CompletableFuture可以组合多个Future,不管是Future之间有依赖的,还是没有依赖的。 **如果第二个请求依赖于第一个请求的结果,那么可以使用thenCompose方法来组合两个Future** - +```` public List findPriceAsync(String product) { List> priceFutures = tasks.stream() .map(task -> CompletableFuture.supplyAsync(() -> task.getPrice(product),executor)) @@ -791,24 +799,26 @@ Fufure price = CompletableFuture.supplyAsync(() -> calculatePrice(produc return priceFutures.stream().map(CompletableFuture::join).collect(Collectors.toList()); } +```` 上面这段代码使用了thenCompose来组合两个CompletableFuture。supplyAsync方法第二个参数接受一个自定义的Executor。 首先使用CompletableFuture执行一个任务,调用getPrice方法,得到一个Future,之后使用thenApply方法,将Future的结果应用parse方法, 之后再使用执行完parse之后的结果作为参数再执行一个applyCount方法,然后收集成一个CompletableFuture的List, 最后再使用一个流,调用CompletableFuture的join方法,这是为了等待所有的异步任务执行完毕,获得最后的结果。 注意,这里必须使用两个流,如果在一个流里调用join方法,那么由于Stream的延迟特性,所有的操作还是会串行的执行,并不是异步的。 **再来看一个两个Future之间没有依赖关系的例子:** - +```` Future futurePriceInUsd = CompletableFuture.supplyAsync(() -> shop.getPrice(“price1”)) .thenCombine(CompletableFuture.supplyAsync(() -> shop.getPrice(“price2”)), (s1, s2) -> s1 + s2); +```` 这里有两个异步的任务,使用thenCombine方法来组合两个Future,thenCombine方法的第二个参数就是用来合并两个Future方法返回值的操作函数。 有时候,我们并不需要等待所有的异步任务结束,只需要其中的一个完成就可以了,CompletableFuture也提供了这样的方法: - +```` //假设getStream方法返回一个Stream> CompletableFuture[] futures = getStream(“listen”).map(f -> f.thenAccept(System.out::println)).toArray(CompletableFuture[]::new); //等待其中的一个执行完毕 CompletableFuture.anyOf(futures).join(); 使用anyOf方法来响应CompletableFuture的completion事件。 - +```` ## Java虚拟机(JVM)的新特性 PermGen空间被移除了,取而代之的是Metaspace(JEP 122)。JVM选项-XX:PermSize与-XX:MaxPermSize分别被-XX:MetaSpaceSize与-XX:MaxMetaspaceSize所代替。 diff --git "a/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" "b/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" index 6de5ffb..c668e69 100644 --- "a/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" +++ "b/docs/java/basic/22\343\200\201\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" @@ -12,15 +12,6 @@ * [微信公众号](#微信公众号) * [Java技术江湖](#java技术江湖) * [个人公众号:黄小斜](#个人公众号:黄小斜) ---- -title: 夯实Java基础系列22:一文读懂Java序列化和反序列化 -date: 2019-9-22 15:56:26 # 文章生成时间,一般不改 -categories: - - Java技术江湖 - - Java基础 -tags: - - Java序列化 ---- 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > https://github.com/h2pl/Java-Tutorial @@ -37,7 +28,6 @@ tags: - 本文参考 http://www.importnew.com/17964.html和 https://www.ibm.com/developerworks/cn/java/j-lo-serial/ @@ -86,96 +76,93 @@ Java为了方便开发人员将Java对象进行序列化及反序列化提供了 如果要序列化的类有父类,要想同时将在父类中定义过的变量持久化下来,那么父类也应该集成java.io.Serializable接口。 下面是一个实现了java.io.Serializable接口的类 +```` +public class 序列化和反序列化 { + public static void main(String[] args) { - public class 序列化和反序列化 { - - -​ -​ public static void main(String[] args) { -​ - } - //注意,内部类不能进行序列化,因为它依赖于外部类 - @Test - public void test() throws IOException { - A a = new A(); - a.i = 1; - a.s = "a"; - FileOutputStream fileOutputStream = null; - FileInputStream fileInputStream = null; - try { - //将obj写入文件 - fileOutputStream = new FileOutputStream("temp"); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); - objectOutputStream.writeObject(a); - fileOutputStream.close(); - //通过文件读取obj - fileInputStream = new FileInputStream("temp"); - ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); - A a2 = (A) objectInputStream.readObject(); - fileInputStream.close(); - System.out.println(a2.i); - System.out.println(a2.s); - //打印结果和序列化之前相同 - } catch (IOException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } } - - class A implements Serializable { - - int i; - String s; + //注意,内部类不能进行序列化,因为它依赖于外部类 + @Test + public void test() throws IOException { + A a = new A(); + a.i = 1; + a.s = "a"; + FileOutputStream fileOutputStream = null; + FileInputStream fileInputStream = null; + try { + //将obj写入文件 + fileOutputStream = new FileOutputStream("temp"); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); + objectOutputStream.writeObject(a); + fileOutputStream.close(); + //通过文件读取obj + fileInputStream = new FileInputStream("temp"); + ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); + A a2 = (A) objectInputStream.readObject(); + fileInputStream.close(); + System.out.println(a2.i); + System.out.println(a2.s); + //打印结果和序列化之前相同 + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } } +} + +class A implements Serializable { + int i; + String s; +} +```` **Externalizable接口** 除了Serializable 之外,java中还提供了另一个序列化接口Externalizable 为了了解Externalizable接口和Serializable接口的区别,先来看代码,我们把上面的代码改成使用Externalizable的形式。 +```` +class B implements Externalizable { + //必须要有公开无参构造函数。否则报错 + public B() { - class B implements Externalizable { - //必须要有公开无参构造函数。否则报错 - public B() { - - } - int i; - String s; - @Override - public void writeExternal(ObjectOutput out) throws IOException { - - } - - @Override - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - - } } - - @Test - public void test2() throws IOException, ClassNotFoundException { - B b = new B(); - b.i = 1; - b.s = "a"; - //将obj写入文件 - FileOutputStream fileOutputStream = new FileOutputStream("temp"); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); - objectOutputStream.writeObject(b); - fileOutputStream.close(); - //通过文件读取obj - FileInputStream fileInputStream = new FileInputStream("temp"); - ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); - B b2 = (B) objectInputStream.readObject(); - fileInputStream.close(); - System.out.println(b2.i); - System.out.println(b2.s); - //打印结果为0和null,即初始值,没有被赋值 - //0 - //null - } + int i; + String s; + @Override + public void writeExternal(ObjectOutput out) throws IOException { + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + + } +} + +@Test + public void test2() throws IOException, ClassNotFoundException { + B b = new B(); + b.i = 1; + b.s = "a"; + //将obj写入文件 + FileOutputStream fileOutputStream = new FileOutputStream("temp"); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); + objectOutputStream.writeObject(b); + fileOutputStream.close(); + //通过文件读取obj + FileInputStream fileInputStream = new FileInputStream("temp"); + ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); + B b2 = (B) objectInputStream.readObject(); + fileInputStream.close(); + System.out.println(b2.i); + System.out.println(b2.s); + //打印结果为0和null,即初始值,没有被赋值 + //0 + //null + } +```` 通过上面的实例可以发现,对B类进行序列化及反序列化之后得到的对象的所有属性的值都变成了默认值。也就是说,之前的那个对象的状态并没有被持久化下来。这就是Externalizable接口和Serializable接口的区别: Externalizable继承了Serializable,该接口中定义了两个抽象方法:writeExternal()与readExternal()。 @@ -184,54 +171,56 @@ Externalizable继承了Serializable,该接口中定义了两个抽象方法: > 还有一点值得注意:在使用Externalizable进行序列化的时候,在读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。所以,实现Externalizable接口的类必须要提供一个public的无参的构造器。 - class C implements Externalizable { - int i; - int j; - String s; - public C() { - - } - //实现下面两个方法可以选择序列化中需要被复制的成员。 - //并且,写入顺序和读取顺序要一致,否则报错。 - //可以写入多个同类型变量,顺序保持一致即可。 - @Override - public void writeExternal(ObjectOutput out) throws IOException { - out.writeInt(i); - out.writeInt(j); - out.writeObject(s); - } - - @Override - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - i = in.readInt(); - j = in.readInt(); - s = (String) in.readObject(); - } +```` +class C implements Externalizable { + int i; + int j; + String s; + public C() { + } - - @Test - public void test3() throws IOException, ClassNotFoundException { - C c = new C(); - c.i = 1; - c.j = 2; - c.s = "a"; - //将obj写入文件 - FileOutputStream fileOutputStream = new FileOutputStream("temp"); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); - objectOutputStream.writeObject(c); - fileOutputStream.close(); - //通过文件读取obj - FileInputStream fileInputStream = new FileInputStream("temp"); - ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); - C c2 = (C) objectInputStream.readObject(); - fileInputStream.close(); - System.out.println(c2.i); - System.out.println(c2.j); - System.out.println(c2.s); - //打印结果为0和null,即初始值,没有被赋值 - //0 - //null - } + //实现下面两个方法可以选择序列化中需要被复制的成员。 + //并且,写入顺序和读取顺序要一致,否则报错。 + //可以写入多个同类型变量,顺序保持一致即可。 + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeInt(i); + out.writeInt(j); + out.writeObject(s); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + i = in.readInt(); + j = in.readInt(); + s = (String) in.readObject(); + } +} + +@Test +public void test3() throws IOException, ClassNotFoundException { + C c = new C(); + c.i = 1; + c.j = 2; + c.s = "a"; + //将obj写入文件 + FileOutputStream fileOutputStream = new FileOutputStream("temp"); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); + objectOutputStream.writeObject(c); + fileOutputStream.close(); + //通过文件读取obj + FileInputStream fileInputStream = new FileInputStream("temp"); + ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); + C c2 = (C) objectInputStream.readObject(); + fileInputStream.close(); + System.out.println(c2.i); + System.out.println(c2.j); + System.out.println(c2.s); + //打印结果为0和null,即初始值,没有被赋值 + //0 + //null +} +```` ## 序列化ID @@ -241,87 +230,89 @@ Externalizable继承了Serializable,该接口中定义了两个抽象方法: 问题:C 对象的全类路径假设为 com.inout.Test,在 A 和 B 端都有这么一个类文件,功能代码完全一致。也都实现了 Serializable 接口,但是反序列化时总是提示不成功。 解决:虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L)。清单 1 中,虽然两个类的功能代码完全一致,但是序列化 ID 不同,他们无法相互序列化和反序列化。 - - package com.inout; - - import java.io.Serializable; - - public class A implements Serializable { - - private static final long serialVersionUID = 1L; - - private String name; - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } +```` +package com.inout; + +import java.io.Serializable; + +public class A implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + + public String getName() + { + return name; } - - package com.inout; - - import java.io.Serializable; - - public class A 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 void setName(String name) + { + this.name = name; + } +} + +package com.inout; + +import java.io.Serializable; + +public class A implements Serializable { + + private static final long serialVersionUID = 2L; + + private String name; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } +} +```` ### 静态变量不参与序列化 清单 2 中的 main 方法,将对象序列化后,修改静态变量的数值,再将序列化对象读取出来,然后通过读取出来的对象获得静态变量的数值并打印出来。依照清单 2,这个 System.out.println(t.staticVar) 语句输出的是 10 还是 5 呢? - - public class Test implements Serializable { - - private static final long serialVersionUID = 1L; - - public static int staticVar = 5; - - public static void main(String[] args) { - try { - //初始时staticVar为5 - ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("result.obj")); - out.writeObject(new Test()); - out.close(); - - //序列化后修改为10 - Test.staticVar = 10; - - ObjectInputStream oin = new ObjectInputStream(new FileInputStream( - "result.obj")); - Test t = (Test) oin.readObject(); - oin.close(); - - //再读取,通过t.staticVar打印新的值 - System.out.println(t.staticVar); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } +```` +public class Test implements Serializable { + + private static final long serialVersionUID = 1L; + + public static int staticVar = 5; + + public static void main(String[] args) { + try { + //初始时staticVar为5 + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream("result.obj")); + out.writeObject(new Test()); + out.close(); + + //序列化后修改为10 + Test.staticVar = 10; + + ObjectInputStream oin = new ObjectInputStream(new FileInputStream( + "result.obj")); + Test t = (Test) oin.readObject(); + oin.close(); + + //再读取,通过t.staticVar打印新的值 + System.out.println(t.staticVar); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); } } +} +```` 最后的输出是 10,对于无法理解的读者认为,打印的 staticVar 是从读取的对象里获得的,应该是保存时的状态才对。之所以打印 10 的原因在于序列化时,并不保存静态变量,这其实比较容易理解,序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。 @@ -334,6 +325,7 @@ ArrayList的序列化 带着这个问题,我们来看java.util.ArrayList的源码 +```` public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { @@ -341,26 +333,27 @@ ArrayList的序列化 transient Object[] elementData; // non-private to simplify nested class access private int size; } +```` 笔者省略了其他成员变量,从上面的代码中可以知道ArrayList实现了java.io.Serializable接口,那么我们就可以对它进行序列化及反序列化。 因为elementData是transient的(1.8好像改掉了这一点),所以我们认为这个成员变量不会被序列化而保留下来。我们写一个Demo,验证一下我们的想法: - - public class ArrayList的序列化 { - public static void main(String[] args) throws IOException, ClassNotFoundException { - ArrayList list = new ArrayList(); - list.add("a"); - list.add("b"); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("arr")); - objectOutputStream.writeObject(list); - objectOutputStream.close(); - ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("arr")); - ArrayList list1 = (ArrayList) objectInputStream.readObject(); - objectInputStream.close(); - System.out.println(Arrays.toString(list.toArray())); - //序列化成功,里面的元素保持不变。 - } - +```` +public class ArrayList的序列化 { + public static void main(String[] args) throws IOException, ClassNotFoundException { + ArrayList list = new ArrayList(); + list.add("a"); + list.add("b"); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("arr")); + objectOutputStream.writeObject(list); + objectOutputStream.close(); + ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("arr")); + ArrayList list1 = (ArrayList) objectInputStream.readObject(); + objectInputStream.close(); + System.out.println(Arrays.toString(list.toArray())); + //序列化成功,里面的元素保持不变。 + } +```` 了解ArrayList的人都知道,ArrayList底层是通过数组实现的。那么数组elementData其实就是用来保存列表中的元素的。通过该属性的声明方式我们知道,他是无法通过序列化持久化下来的。那么为什么code 4的结果却通过序列化和反序列化把List中的元素保留下来了呢? **writeObject和readObject方法** @@ -376,50 +369,48 @@ ArrayList的序列化 > 用户自定义的 writeObject 和 readObject 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。 来看一下这两个方法的具体实现: +```` +private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + elementData = EMPTY_ELEMENTDATA; - 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