From 3c51ae2de7da46a69c0568fc9ef12d2c22a5de73 Mon Sep 17 00:00:00 2001 From: Ghost <375808041@qq.com> Date: Wed, 27 Feb 2019 16:22:00 +0800 Subject: [PATCH 001/232] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=94=99=E5=88=AB?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Java\347\233\270\345\205\263/synchronized.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/synchronized.md" "b/Java\347\233\270\345\205\263/synchronized.md" index dfca675f14a..b0b0700ad8e 100644 --- "a/Java\347\233\270\345\205\263/synchronized.md" +++ "b/Java\347\233\270\345\205\263/synchronized.md" @@ -168,4 +168,4 @@ synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团 **④ 性能已不是选择标准** -在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具体表示为:synchronized 关键字吞吐量岁线程数的增加,下降得非常严重。而ReenTrantLock 基本保持一个比较稳定的水平。我觉得这也侧面反映了, synchronized 关键字还有非常大的优化余地。后续的技术发展也证明了这一点,我们上面也讲了在 JDK1.6 之后 JVM 团队对 synchronized 关键字做了很多优化。**JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以网上那些说因为性能才选择 ReenTrantLock 的文章都是错的!JDK1.6之后,性能已经不是选择synchronized和ReenTrantLock的影响因素了!而且虚拟机在未来的性能改进中会更偏向于原生的synchronized,所以还是提倡在synchronized能满足你的需求的情况下,优先考虑使用synchronized关键字来进行同步!优化后的synchronized和ReenTrantLock一样,在很多地方都是用到了CAS操作**。 +在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具体表示为:synchronized 关键字吞吐量随线程数的增加,下降得非常严重。而ReenTrantLock 基本保持一个比较稳定的水平。我觉得这也侧面反映了, synchronized 关键字还有非常大的优化余地。后续的技术发展也证明了这一点,我们上面也讲了在 JDK1.6 之后 JVM 团队对 synchronized 关键字做了很多优化。**JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以网上那些说因为性能才选择 ReenTrantLock 的文章都是错的!JDK1.6之后,性能已经不是选择synchronized和ReenTrantLock的影响因素了!而且虚拟机在未来的性能改进中会更偏向于原生的synchronized,所以还是提倡在synchronized能满足你的需求的情况下,优先考虑使用synchronized关键字来进行同步!优化后的synchronized和ReenTrantLock一样,在很多地方都是用到了CAS操作**。 From 26b204371cb6ad7160c91281df6f47a7fa39fb5f Mon Sep 17 00:00:00 2001 From: ZhouLiMing Date: Wed, 27 Feb 2019 18:43:06 +0800 Subject: [PATCH 002/232] =?UTF-8?q?fix=20=20AQS.md->CyclicBarrier=20?= =?UTF-8?q?=E7=9A=84=E4=BD=BF=E7=94=A8=E7=A4=BA=E4=BE=8Bdemo=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E7=A4=BA=E4=BE=8B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Java\347\233\270\345\205\263/Multithread/AQS.md" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/Multithread/AQS.md" "b/Java\347\233\270\345\205\263/Multithread/AQS.md" index 487669e50d8..3717be6c260 100644 --- "a/Java\347\233\270\345\205\263/Multithread/AQS.md" +++ "b/Java\347\233\270\345\205\263/Multithread/AQS.md" @@ -336,7 +336,8 @@ public class CyclicBarrierExample2 { public static void test(int threadnum) throws InterruptedException, BrokenBarrierException { System.out.println("threadnum:" + threadnum + "is ready"); try { - cyclicBarrier.await(2000, TimeUnit.MILLISECONDS); + /**等待60秒,保证子线程完全执行结束*/ + cyclicBarrier.await(60, TimeUnit.SECONDS); } catch (Exception e) { System.out.println("-----CyclicBarrierException------"); } From f9e193c6c1d6b7c06011ca4d712580554b73a118 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 28 Feb 2019 22:12:10 +0800 Subject: [PATCH 003/232] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 75f7340dd3b..57fa9906fad 100644 --- "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -392,7 +392,7 @@ final关键字主要用在三个地方:变量、方法、类。 ### Java异常类层次结构图 -![Java异常类层次结构图](http://images2015.cnblogs.com/blog/641003/201607/641003-20160706232044280-355354790.png) +![Java异常类层次结构图](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/Exception.png) 在 Java 中,所有的异常都有一个共同的祖先java.lang包中的 **Throwable类**。Throwable: 有两个重要的子类:**Exception(异常)** 和 **Error(错误)** ,二者都是 Java 异常处理的重要子类,各自都包含大量子类。 **Error(错误):是程序无法处理的错误**,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。 From db1c987a47e6cf5969ed0fd179abb51d05d818b1 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 1 Mar 2019 10:51:59 +0800 Subject: [PATCH 004/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6cf87bba8e..442d3f50f77 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的目录供大家参考!如果有老哥对操作系统比较重要的知识总结过的话,欢迎找我哦! 一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。 -【限时福利,最后一天】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#我的微信) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 +【限时福利】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#我的微信) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。
From 072d8d2d8d77c43f153733541d252be0bd40328a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Fri, 1 Mar 2019 15:50:05 +0800 Subject: [PATCH 005/232] =?UTF-8?q?Update=20=E8=BF=99=E5=87=A0=E9=81=93Jav?= =?UTF-8?q?a=E9=9B=86=E5=90=88=E6=A1=86=E6=9E=B6=E9=9D=A2=E8=AF=95?= =?UTF-8?q?=E9=A2=98=E5=87=A0=E4=B9=8E=E5=BF=85=E9=97=AE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix 调整格式 --- ...2\230\345\207\240\344\271\216\345\277\205\351\227\256.md" | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git "a/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" "b/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" index eb86fc2e285..18587f42392 100644 --- "a/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" +++ "b/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" @@ -32,8 +32,7 @@ - **3. 插入和删除是否受元素位置的影响:** ① **ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。** 比如:执行`add(E e) `方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element) `)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② **LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。** - **4. 是否支持快速随机访问:** LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index) `方法)。 - **5. 内存空间占用:** ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。 --**6. 发 -**补充内容:RandomAccess接口** +-**6.补充内容:RandomAccess接口** ```java public interface RandomAccess { @@ -203,7 +202,7 @@ static int hash(int h) { 这个过程为,先将 A 复制到新的 hash 表中,然后接着复制 B 到链头(A 的前边:B.next=A),本来 B.next=null,到此也就结束了(跟线程二一样的过程),但是,由于线程二扩容的原因,将 B.next=A,所以,这里继续复制A,让 A.next=B,由此,环形链表出现:B.next=A; A.next=B -**注意:jdk1.8已经解决了死循环的问题。** +**注意:jdk1.8已经解决了死循环的问题。**详细信息请阅读[jdk1.8 hashmap多线程put不会造成死循环](https://blog.csdn.net/qq_27007251/article/details/71403647) ## HashSet 和 HashMap 区别 From 81d2f39317fbdbbfa0a7539727ad5e0932476ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Fri, 1 Mar 2019 16:31:38 +0800 Subject: [PATCH 006/232] =?UTF-8?q?Update=20Java=E9=9B=86=E5=90=88?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=B8=B8=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= =?UTF-8?q?=E6=80=BB=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix:格式调整 --- ...5\242\350\257\225\351\242\230\346\200\273\347\273\223.md" | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" "b/Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" index d18c68e0020..cb0bd1fe0e3 100644 --- "a/Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" +++ "b/Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" @@ -40,7 +40,7 @@ ## Arraylist 与 LinkedList 区别 -Arraylist底层使用的是数组(存读数据效率高,插入删除特定位置效率低),LinkedList底层使用的是双向循环链表数据结构(插入,删除效率特别高)。学过数据结构这门课后我们就知道采用链表存储,插入,删除元素时间复杂度不受元素位置的影响,都是近似O(1)而数组为近似O(n),因此当数据特别多,而且经常需要插入删除元素时建议选用LinkedList.一般程序只用Arraylist就够用了,因为一般数据量都不会蛮大,Arraylist是使用最多的集合类。 +Arraylist底层使用的是数组(存读数据效率高,插入删除特定位置效率低),LinkedList 底层使用的是双向链表数据结构(插入,删除效率特别高)(JDK1.6之前为循环链表,JDK1.7取消了循环。注意双向链表和双向循环链表的区别:); 详细可阅读JDK1.7-LinkedList循环链表优化。学过数据结构这门课后我们就知道采用链表存储,插入,删除元素时间复杂度不受元素位置的影响,都是近似O(1)而数组为近似O(n),因此当数据特别多,而且经常需要插入删除元素时建议选用LinkedList.一般程序只用Arraylist就够用了,因为一般数据量都不会蛮大,Arraylist是使用最多的集合类。 ## ArrayList 与 Vector 区别 Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector @@ -76,7 +76,8 @@ Hashtable和HashMap有几个主要的不同:线程安全以及速度。仅在 **==与equals的区别** 1. ==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同 -2. ==是指对内存地址进行比较 equals()是对字符串的内容进行比较3.==指引用是否相同 equals()指的是值是否相同 +2. ==是指对内存地址进行比较 equals()是对字符串的内容进行比较 +3. ==指引用是否相同 equals()指的是值是否相同 ## comparable 和 comparator的区别 - comparable接口实际上是出自java.lang包 它有一个 compareTo(Object obj)方法用来排序 From b65a3d0df045200e6122ccc6225349d8127f2cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Fri, 1 Mar 2019 16:43:20 +0800 Subject: [PATCH 007/232] Update ArrayList.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.格式调整 2. fix RandomAccess接口 --- "Java\347\233\270\345\205\263/ArrayList.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/ArrayList.md" "b/Java\347\233\270\345\205\263/ArrayList.md" index 471ea5bca6d..c3e8dd47896 100644 --- "a/Java\347\233\270\345\205\263/ArrayList.md" +++ "b/Java\347\233\270\345\205\263/ArrayList.md" @@ -21,7 +21,7 @@   ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。 -  ArrayList 实现了**RandomAccess 接口**,即提供了随机访问功能。RandomAccess 是 Java 中用来被 List 实现,为 List 提供**快速访问功能**的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。 +  ArrayList 实现了**RandomAccess 接口**, RandomAccess 是一个标志接口,表明实现这个这个接口的 List 集合是支持**快速随机访问**的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。   ArrayList 实现了**Cloneable 接口**,即覆盖了函数 clone(),**能被克隆**。 @@ -660,7 +660,7 @@ public class ArrayList extends AbstractList (3)private class SubList extends AbstractList implements RandomAccess (4)static final class ArrayListSpliterator implements Spliterator ``` -  ArrayList有四个内部类,其中的**Itr是实现了Iterator接口**,同时重写了里面的**hasNext()**,**next()**,**remove()**等方法;其中的**ListItr**继承**Itr**,实现了**ListIterator接口**,同时重写了**hasPrevious()**,**nextIndex()**,**previousIndex()**,**previous()**,**set(E e)**,**add(E e)**等方法,所以这也可以看出了**Iterator和ListIterator的区别:**ListIterator在Iterator的基础上增加了添加对象,修改对象,逆向遍历等方法,这些是Iterator不能实现的。 +  ArrayList有四个内部类,其中的**Itr是实现了Iterator接口**,同时重写了里面的**hasNext()**,**next()**,**remove()**等方法;其中的**ListItr**继承**Itr**,实现了**ListIterator接口**,同时重写了**hasPrevious()**,**nextIndex()**,**previousIndex()**,**previous()**,**set(E e)**,**add(E e)**等方法,所以这也可以看出了 **Iterator和ListIterator的区别:**ListIterator在Iterator的基础上增加了添加对象,修改对象,逆向遍历等方法,这些是Iterator不能实现的。 ### ArrayList经典Demo ```java From 6197be81cf353fdb2fd6152a37c5cc8e59e3ff81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=80=90=E5=BC=A0=E9=91=AB=E3=80=91?= <974567732@qq.com> Date: Sat, 2 Mar 2019 21:47:14 +0800 Subject: [PATCH 008/232] =?UTF-8?q?=E6=9C=80=E9=95=BF=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E5=89=8D=E7=BC=80=E9=A2=98=E7=9B=AE=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E8=BE=93=E5=85=A5=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、检查元素是否含有null 2、检查是否String数组是否为0 --- ...62\347\256\227\346\263\225\351\242\230.md" | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" index b7b1c3145c8..938f4a48f1a 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" @@ -108,38 +108,57 @@ public class Solution { 思路很简单!先利用Arrays.sort(strs)为数组排序,再将数组第一个元素和最后一个元素的字符从前往后对比即可! ```java -//https://leetcode-cn.com/problems/longest-common-prefix/description/ public class Main { - public static String replaceSpace(String[] strs) { - - // 数组长度 - int len = strs.length; - // 用于保存结果 - StringBuffer res = new StringBuffer(); - // 注意:=是赋值,==是判断 - if (strs == null || strs.length == 0) { - return ""; - } - // 给字符串数组的元素按照升序排序(包含数字的话,数字会排在前面) - Arrays.sort(strs); - int m = strs[0].length(); - int n = strs[len - 1].length(); - int num = Math.min(m, n); - for (int i = 0; i < num; i++) { - if (strs[0].charAt(i) == strs[len - 1].charAt(i)) { - res.append(strs[0].charAt(i)); - } else - break; - - } - return res.toString(); - - } - //测试 - public static void main(String[] args) { - String[] strs = { "customer", "car", "cat" }; - System.out.println(Main.replaceSpace(strs));//c - } + public static String replaceSpace(String[] strs) { + + // 如果检查值不合法及就返回空串 + if (!chechStrs(strs)) { + return ""; + } + // 数组长度 + int len = strs.length; + // 用于保存结果 + StringBuilder res = new StringBuilder(); + // 给字符串数组的元素按照升序排序(包含数字的话,数字会排在前面) + Arrays.sort(strs); + int m = strs[0].length(); + int n = strs[len - 1].length(); + int num = Math.min(m, n); + for (int i = 0; i < num; i++) { + if (strs[0].charAt(i) == strs[len - 1].charAt(i)) { + res.append(strs[0].charAt(i)); + } else + break; + + } + return res.toString(); + + } + + private static boolean chechStrs(String[] strs) { + boolean flag = false; + // 注意:=是赋值,==是判断 + if (strs != null) { + // 遍历strs检查元素值 + for (int i = 0; i < strs.length; i++) { + if (strs[i] != null && strs[i].length() != 0) { + flag = true; + } else { + flag = false; + } + } + } + return flag; + } + + // 测试 + public static void main(String[] args) { + String[] strs = { "customer", "car", "cat" }; + // String[] strs = { "customer", "car", null };//空串 + // String[] strs = {};//空串 + // String[] strs = null;//空串 + System.out.println(Main.replaceSpace(strs));// c + } } ``` From 4aec317e6008e279dce383c93644605bb833e084 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 09:47:51 +0800 Subject: [PATCH 009/232] Add contributors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增了一些对本仓库做过较有价值贡献的用户 --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 442d3f50f77..43926f2818c 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,28 @@ ![ Java并发编程专栏](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/Java并发编程实战.jpg) +### 致谢 + + + + + + + + + + + + + + + + + +" + + + ### 公众号 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。我是 ThoughtWorks 准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!可以扫描下方二维码或者通过微信的搜一搜搜索ID:“Java_Guide”即可。 From 1b794b545bd60367cfddb52bf0b8f287db2ead0a Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 09:56:17 +0800 Subject: [PATCH 010/232] Fix link error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 一个contributor的个人主页地址错误 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 43926f2818c..1dbf0831efa 100644 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ - + @@ -255,6 +255,7 @@ + ### 公众号 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。我是 ThoughtWorks 准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!可以扫描下方二维码或者通过微信的搜一搜搜索ID:“Java_Guide”即可。 From 95bbee054498b441c6aeeb7d0abcebb47f603745 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 10:25:23 +0800 Subject: [PATCH 011/232] Add Contributor --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1dbf0831efa..414fc01d265 100644 --- a/README.md +++ b/README.md @@ -235,27 +235,34 @@ ### 致谢 +下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! + - + - + - + - + - + - + " - + + + + + + + - ### 公众号 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。我是 ThoughtWorks 准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!可以扫描下方二维码或者通过微信的搜一搜搜索ID:“Java_Guide”即可。 From 037a280f9572cacb3112efe86e58c6fe09382f2d Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 11:20:32 +0800 Subject: [PATCH 012/232] Update format Adjustment format --- README.md | 108 ++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 414fc01d265..0a54c13235f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +# Java 学习/面试指南 为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的目录供大家参考!如果有老哥对操作系统比较重要的知识总结过的话,欢迎找我哦! 一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。 @@ -7,52 +8,47 @@

- [![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-984466017-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=10aee68bd241e739e59a8dfb0d4b33690bd3a4b5af0d09142cbdae2cb8c3966a)
微信交流群添加 [我的微信](#我的微信) 后回复关键字“加群”即可入群。 -
- - ## 目录 -- [:coffee: Java](#coffee-java) - - [Java/J2EE 基础](#javaj2ee-基础) - - [Java 集合框架](#java-集合框架) - - [Java 多线程](#java-多线程) - - [Java BIO,NIO,AIO](#java-bionioaio) - - [Java 虚拟机 jvm](#java-虚拟机-jvm) -- [:open_file_folder: 数据结构与算法](#open_file_folder-数据结构与算法) - - [数据结构](#数据结构) - - [算法](#算法) -- [:computer: 计算机网络与数据通信](#computer-计算机网络与数据通信) - - [网络相关](#网络相关) - - [数据通信\(RESTful,RPC,消息队列\)总结](#数据通信restfulrpc消息队列总结) -- [:iphone: 操作系统](#iphone-操作系统) - - [Linux相关](#linux相关) -- [:pencil2: 主流框架/软件](#pencil2-主流框架软件) - - [Spring](#spring) - - [ZooKeeper](#zookeeper) -- [:floppy_disk: 数据存储](#floppy_disk-数据存储) - - [MySQL](#mysql) - - [Redis](#redis) -- [:punch: 架构](#punch-架构) -- [:musical_note: 面试必备](#musical_note-面试必备) - - [备战春招/秋招系列](#备战春招秋招系列) - - [最最最常见的Java面试题总结](#最最最常见的java面试题总结) - - [Java学习/面试开源仓库推荐](#java学习面试开源仓库推荐) -- [:art: 闲谈](#art-闲谈) -- [:envelope: 说明](#envelope-说明) +* [:coffee: Java](#coffee-java) + * [Java/J2EE 基础](#javaj2ee-基础) + * [Java 集合框架](#java-集合框架) + * [Java 多线程](#java-多线程) + * [Java BIO,NIO,AIO](#java-bionioaio) + * [Java 虚拟机 jvm](#java-虚拟机-jvm) +* [:open_file_folder: 数据结构与算法](#open_file_folder-数据结构与算法) + * [数据结构](#数据结构) + * [算法](#算法) +* [:computer: 计算机网络与数据通信](#computer-计算机网络与数据通信) + * [网络相关](#网络相关) + * [数据通信\(RESTful,RPC,消息队列\)总结](#数据通信restfulrpc消息队列总结) +* [:iphone: 操作系统](#iphone-操作系统) + * [Linux相关](#linux相关) +* [:pencil2: 主流框架/软件](#pencil2-主流框架软件) + * [Spring](#spring) + * [ZooKeeper](#zookeeper) +* [:floppy_disk: 数据存储](#floppy_disk-数据存储) + * [MySQL](#mysql) + * [Redis](#redis) +* [:punch: 架构](#punch-架构) +* [:musical_note: 面试必备](#musical_note-面试必备) + * [备战春招/秋招系列](#备战春招秋招系列) + * [最最最常见的Java面试题总结](#最最最常见的java面试题总结) + * [Java学习/面试开源仓库推荐](#java学习面试开源仓库推荐) +* [:art: 闲谈](#art-闲谈) +* [:envelope: 说明](#envelope-说明) ## 待办 -- [ ] Java 8 新特性总结 -- [x] BIO,NIO,AIO 总结 -- [ ] Netty 总结 -- [ ] 数据结构总结重构 - +* [ ] Java 8 新特性总结 +* [x] BIO,NIO,AIO 总结 +* [ ] Netty 总结 +* [ ] 数据结构总结重构 ## :coffee: Java @@ -62,7 +58,7 @@ * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/J2EE基础知识.md) * [static、final、this、super关键字总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) * [static 关键字详解](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/static.md) - + ### Java 集合框架 * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) @@ -71,8 +67,9 @@ * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/ArrayList-Grow.md) * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/HashMap.md) - + ### Java 多线程 + * [多线程系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/多线程系列.md) * [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/synchronized.md) * [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/面试必备之乐观锁与悲观锁.md) @@ -87,7 +84,6 @@ * [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/搞定JVM垃圾回收就是这么简单.md) * [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Java虚拟机(jvm).md) - ### Java BIO,NIO,AIO * [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/BIO%2CNIO%2CAIO%20summary.md) @@ -98,7 +94,7 @@ * [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/设计模式.md) ## :open_file_folder: 数据结构与算法 - + ### 数据结构 * [数据结构知识学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/数据结构.md) @@ -170,15 +166,15 @@ * [【备战春招/秋招系列1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) * [手把手教你用Markdown写一份高质量的简历](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/手把手教你用Markdown写一份高质量的简历.md) * [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) -* [【备战春招/秋招系列3】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) -* [ 【备战春招/秋招系列4】美团面经总结基础篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-基础篇.md) -* [ 【备战春招/秋招系列5】美团面经总结进阶篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-进阶篇.md) -* [ 【备战春招/秋招系列5】美团面经总结终结篇篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-终结篇.md) +* [【备战春招/秋招系列3】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) +* [【备战春招/秋招系列4】美团面经总结基础篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-基础篇.md) +* [【备战春招/秋招系列5】美团面经总结进阶篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-进阶篇.md) +* [【备战春招/秋招系列5】美团面经总结终结篇篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-终结篇.md) ### 最最最常见的Java面试题总结 - + 这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。 - + * [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) * [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) * [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) @@ -187,7 +183,7 @@ ### Java学习/面试开源仓库推荐 * [盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/JavaInterviewGithub.md) - + ## :art: 闲谈 * [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/其他/选择技术方向都要考虑哪些因素.md) @@ -199,29 +195,29 @@ ## :envelope: 说明 -### 项目介绍 - -该文档主要是笔主在学习 Java 的过程中的一些学习笔记,但是为了能够涉及到大部分后端学习所需的技术知识点我也会偶尔引用一些别人的优秀文章的链接。文档大部分内容都是笔者参考书籍以及自己的原创。少部分面试题回答参考了其他人已有答案,上面都已注明。 +### 介绍 -该文档涉及的主要内容包括: Java、 数据结构与算法、计算机网络与数据通信、 操作系统、主流框架、数据存储、架构、面试必备知识点等等。相信不论你是前端还是后端都能在这份文档中收获到东西。 +* **对于 Java 初学者来说:** 本文档倾向于给你提供一个比较详细的学习路径,让你对于Java整体的知识体系有一个初步认识。另外,本文的一些文章 +也是你学习和复习 Java 知识不错的实践; +* **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。 ### 关于转载 -**如果需要引用到本仓库的一些东西,必须注明转载地址!!!毕竟大多都是手敲的,或者引用的是我的原创文章,希望大家尊重一下作者的劳动**:smiley::smiley::smiley:! +如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。 ### 如何对该开源文档进行贡献 1. 笔记内容大多是手敲,所以难免会有笔误,你可以帮我找错别字。 -2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。 +2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。(**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!快提 pr 给我投稿吧!**) 3. 现有的知识点难免存在不完善或者错误,所以你可以对已有知识点的修改/补充。 ### 为什么要做这个开源文档? -在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫:smile:)。所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以及面试的相关知识。本来是想通过Gitbook的形式来制作的,后来想了想觉得可能有点大题小做 :grin: 。另外,我自己一个人的力量毕竟有限,希望各位有想法的朋友可以提issue。开源的最大目的是,让更多人参与进来,这样文档的正确性才能得以保障! +初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。 ### 最后 -本人会利用业余时间一直更新下去,目前还有很多地方不完善,一些知识点我会原创总结,还有一些知识点如果说网上有比较好的文章了,我会把这些文章加入进去。您也可以关注我的微信公众号:“Java面试通关手册”,我会在这里分享一些自己的原创文章。 另外该文档格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。如果大家需要与我交流,可以扫描下方二维码添加我的微信: +本人会利用业余时间一直更新下去,目前还有很多地方不完善,一些知识点我会原创总结,还有一些知识点如果说网上有比较好的文章了,我会把这些文章加入进去。您也可以关注我的微信公众号:“JavaGuide”,我会在这里分享一些自己的原创文章。 另外该文档格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。如果大家需要与我交流,可以扫描下方二维码添加我的微信: ### 我的微信 @@ -263,9 +259,9 @@ + ### 公众号 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。我是 ThoughtWorks 准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!可以扫描下方二维码或者通过微信的搜一搜搜索ID:“Java_Guide”即可。 - ![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334) From 6cb32dba51463ea87e813b537098d531f03d3684 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 11:24:41 +0800 Subject: [PATCH 013/232] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a54c13235f..7d7bdb97e23 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@

-[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-984466017-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=10aee68bd241e739e59a8dfb0d4b33690bd3a4b5af0d09142cbdae2cb8c3966a) -
+ 微信交流群添加 [我的微信](#我的微信) 后回复关键字“加群”即可入群。 +
## 目录 From 2f91aeded308a49a56edac5874b1d4b43e3ae905 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:19:05 +0800 Subject: [PATCH 014/232] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7d7bdb97e23..d59cc556b45 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,8 @@ 也是你学习和复习 Java 知识不错的实践; * **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。 +本文档 Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。 + ### 关于转载 如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。 @@ -215,11 +217,9 @@ 初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。 -### 最后 - -本人会利用业余时间一直更新下去,目前还有很多地方不完善,一些知识点我会原创总结,还有一些知识点如果说网上有比较好的文章了,我会把这些文章加入进去。您也可以关注我的微信公众号:“JavaGuide”,我会在这里分享一些自己的原创文章。 另外该文档格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。如果大家需要与我交流,可以扫描下方二维码添加我的微信: +### 联系我 -### 我的微信 +如果大家需要与我交流,可以扫描下方二维码添加我的微信获取关注[我的公众号](#公众号): ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) From bcc5a8cc5b8e6c7c2cea43ed3440366d6fb358f4 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:19:35 +0800 Subject: [PATCH 015/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d59cc556b45..5584dcb6bcc 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的目录供大家参考!如果有老哥对操作系统比较重要的知识总结过的话,欢迎找我哦! 一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。 -【限时福利】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#我的微信) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 +【限时福利】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。
From a1ac5a76031bf96803c6768300a003677dd60496 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 14:37:30 +0800 Subject: [PATCH 016/232] Delete static.md --- "Java\347\233\270\345\205\263/static.md" | 241 ----------------------- 1 file changed, 241 deletions(-) delete mode 100644 "Java\347\233\270\345\205\263/static.md" diff --git "a/Java\347\233\270\345\205\263/static.md" "b/Java\347\233\270\345\205\263/static.md" deleted file mode 100644 index 17b09fe63a9..00000000000 --- "a/Java\347\233\270\345\205\263/static.md" +++ /dev/null @@ -1,241 +0,0 @@ - -# static 关键字 - -## static 关键字主要有以下四种使用场景 - -1. 修饰成员变量和成员方法 -2. 静态代码块 -3. 修饰类(只能修饰内部类) -4. 静态导包(用来导入类中的静态资源,1.5之后的新特性) - -### 修饰成员变量和成员方法(常用) - -被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。 - -方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。 - - HotSpot 虚拟机中方法区也常被称为 “永久代”,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。 - - - -调用格式: - -- 类名.静态变量名 -- 类名.静态方法名() - -如果变量或者方法被 private 则代表该属性或者该方法只能在类的内部被访问而不能在类的外部被访问。 - -测试方法: - -```java -public class StaticBean { - - String name; - 静态变量 - static int age; - - public StaticBean(String name) { - this.name = name; - } - 静态方法 - static void SayHello() { - System.out.println(Hello i am java); - } - @Override - public String toString() { - return StaticBean{ + - name=' + name + ''' + age + age + - '}'; - } -} -``` - -```java -public class StaticDemo { - - public static void main(String[] args) { - StaticBean staticBean = new StaticBean(1); - StaticBean staticBean2 = new StaticBean(2); - StaticBean staticBean3 = new StaticBean(3); - StaticBean staticBean4 = new StaticBean(4); - StaticBean.age = 33; - StaticBean{name='1'age33} StaticBean{name='2'age33} StaticBean{name='3'age33} StaticBean{name='4'age33} - System.out.println(staticBean+ +staticBean2+ +staticBean3+ +staticBean4); - StaticBean.SayHello();Hello i am java - } - -} -``` - - -### 静态代码块 - -静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。 该类不管创建多少对象,静态代码块只执行一次. - -静态代码块的格式是 - -``` -static { -语句体; -} -``` - - -一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 - -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/88531075.jpg) - -静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问. - - -### 静态内部类 - -静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着: - -1. 它的创建是不需要依赖外围类的创建。 -2. 它不能使用任何外围类的非static成员变量和方法。 - - -Example(静态内部类实现单例模式) - -```java -public class Singleton { - - 声明为 private 避免调用默认构造方法创建对象 - private Singleton() { - } - - 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问 - private static class SingletonHolder { - private static final Singleton INSTANCE = new Singleton(); - } - - public static Singleton getUniqueInstance() { - return SingletonHolder.INSTANCE; - } -} -``` - -当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 `getUniqueInstance() `方法从而触发 `SingletonHolder.INSTANCE` 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。 - -这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。 - -### 静态导包 - -格式为:import static - -这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法 - -```java - - - Math. --- 将Math中的所有静态资源导入,这时候可以直接使用里面的静态方法,而不用通过类名进行调用 - 如果只想导入单一某个静态方法,只需要将换成对应的方法名即可 - -import static java.lang.Math.; - - 换成import static java.lang.Math.max;具有一样的效果 - -public class Demo { - public static void main(String[] args) { - - int max = max(1,2); - System.out.println(max); - } -} - -``` - - -## 补充内容 - -### 静态方法与非静态方法 - -静态方法属于类本身,非静态方法属于从该类生成的每个对象。 如果您的方法执行的操作不依赖于其类的各个变量和方法,请将其设置为静态(这将使程序的占用空间更小)。 否则,它应该是非静态的。 - -Example - -```java -class Foo { - int i; - public Foo(int i) { - this.i = i; - } - - public static String method1() { - return An example string that doesn't depend on i (an instance variable); - - } - - public int method2() { - return this.i + 1; Depends on i - } - -} -``` -你可以像这样调用静态方法:`Foo.method1()`。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行:`Foo bar = new Foo(1);bar.method2();` - -总结: - -- 在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。 -- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 - -### static{}静态代码块与{}非静态代码块(构造代码块) - -相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。 - -不同点: 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。 - -一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:Arrays类,Character类,String类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的. - -Example - -```java -public class Test { - public Test() { - System.out.print(默认构造方法!--); - } - - 非静态代码块 - { - System.out.print(非静态代码块!--); - } - 静态代码块 - static { - System.out.print(静态代码块!--); - } - - public static void test() { - System.out.print(静态方法中的内容! --); - { - System.out.print(静态方法中的代码块!--); - } - - } - public static void main(String[] args) { - - Test test = new Test(); - Test.test();静态代码块!--静态方法中的内容! --静态方法中的代码块!-- - } -``` - -当执行 `Test.test();` 时输出: - -``` -静态代码块!--静态方法中的内容! --静态方法中的代码块!-- -``` - -当执行 `Test test = new Test();` 时输出: - -``` -静态代码块!--非静态代码块!--默认构造方法!-- -``` - - -非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。 - -### 参考 - -- httpsblog.csdn.netchen13579867831articledetails78995480 -- httpwww.cnblogs.comchenssyp3388487.html -- httpwww.cnblogs.comQian123p5713440.html From d4566430fae391abb54ec99137776549d6de848c Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 14:37:45 +0800 Subject: [PATCH 017/232] =?UTF-8?q?Update=20final=E3=80=81static=E3=80=81t?= =?UTF-8?q?his=E3=80=81super.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tatic\343\200\201this\343\200\201super.md" | 247 +++++++++++++++++- 1 file changed, 246 insertions(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" "b/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" index b6b47bfb770..541a183ce8c 100644 --- "a/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" +++ "b/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" @@ -1,3 +1,7 @@ + + +# final,static,this,super 关键字总结 + ## final 关键字 **final关键字主要用在三个地方:变量、方法、类。** @@ -70,7 +74,7 @@ public class Sub extends Super { **使用 this 和 super 要注意的问题:** - super 调用父类中的其他构造方法时,调用时要放在构造方法的首行!this 调用本类中的其他构造方法时,也要放在首行。 -- this、super不能用在static方法中。 +- this、super不能用在static方法中。 **简单解释一下:** @@ -82,3 +86,244 @@ public class Sub extends Super { - https://www.codejava.net/java-core/the-java-language/java-keywords - https://blog.csdn.net/u013393958/article/details/79881037 + +# static 关键字详解 + +## static 关键字主要有以下四种使用场景 + +1. 修饰成员变量和成员方法 +2. 静态代码块 +3. 修饰类(只能修饰内部类) +4. 静态导包(用来导入类中的静态资源,1.5之后的新特性) + +### 修饰成员变量和成员方法(常用) + +被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。 + +方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。 + + HotSpot 虚拟机中方法区也常被称为 “永久代”,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。 + + + +调用格式: + +- 类名.静态变量名 +- 类名.静态方法名() + +如果变量或者方法被 private 则代表该属性或者该方法只能在类的内部被访问而不能在类的外部被访问。 + +测试方法: + +```java +public class StaticBean { + + String name; + 静态变量 + static int age; + + public StaticBean(String name) { + this.name = name; + } + 静态方法 + static void SayHello() { + System.out.println(Hello i am java); + } + @Override + public String toString() { + return StaticBean{ + + name=' + name + ''' + age + age + + '}'; + } +} +``` + +```java +public class StaticDemo { + + public static void main(String[] args) { + StaticBean staticBean = new StaticBean(1); + StaticBean staticBean2 = new StaticBean(2); + StaticBean staticBean3 = new StaticBean(3); + StaticBean staticBean4 = new StaticBean(4); + StaticBean.age = 33; + StaticBean{name='1'age33} StaticBean{name='2'age33} StaticBean{name='3'age33} StaticBean{name='4'age33} + System.out.println(staticBean+ +staticBean2+ +staticBean3+ +staticBean4); + StaticBean.SayHello();Hello i am java + } + +} +``` + + +### 静态代码块 + +静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。 该类不管创建多少对象,静态代码块只执行一次. + +静态代码块的格式是 + +``` +static { +语句体; +} +``` + + +一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 + +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/88531075.jpg) + +静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问. + + +### 静态内部类 + +静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着: + +1. 它的创建是不需要依赖外围类的创建。 +2. 它不能使用任何外围类的非static成员变量和方法。 + + +Example(静态内部类实现单例模式) + +```java +public class Singleton { + + 声明为 private 避免调用默认构造方法创建对象 + private Singleton() { + } + + 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问 + private static class SingletonHolder { + private static final Singleton INSTANCE = new Singleton(); + } + + public static Singleton getUniqueInstance() { + return SingletonHolder.INSTANCE; + } +} +``` + +当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 `getUniqueInstance() `方法从而触发 `SingletonHolder.INSTANCE` 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。 + +这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。 + +### 静态导包 + +格式为:import static + +这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法 + +```java + + + Math. --- 将Math中的所有静态资源导入,这时候可以直接使用里面的静态方法,而不用通过类名进行调用 + 如果只想导入单一某个静态方法,只需要将换成对应的方法名即可 + +import static java.lang.Math.; + + 换成import static java.lang.Math.max;具有一样的效果 + +public class Demo { + public static void main(String[] args) { + + int max = max(1,2); + System.out.println(max); + } +} + +``` + + +## 补充内容 + +### 静态方法与非静态方法 + +静态方法属于类本身,非静态方法属于从该类生成的每个对象。 如果您的方法执行的操作不依赖于其类的各个变量和方法,请将其设置为静态(这将使程序的占用空间更小)。 否则,它应该是非静态的。 + +Example + +```java +class Foo { + int i; + public Foo(int i) { + this.i = i; + } + + public static String method1() { + return An example string that doesn't depend on i (an instance variable); + + } + + public int method2() { + return this.i + 1; Depends on i + } + +} +``` +你可以像这样调用静态方法:`Foo.method1()`。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行:`Foo bar = new Foo(1);bar.method2();` + +总结: + +- 在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。 +- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 + +### static{}静态代码块与{}非静态代码块(构造代码块) + +相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。 + +不同点: 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。 + +一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:Arrays类,Character类,String类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的. + +Example + +```java +public class Test { + public Test() { + System.out.print(默认构造方法!--); + } + + 非静态代码块 + { + System.out.print(非静态代码块!--); + } + 静态代码块 + static { + System.out.print(静态代码块!--); + } + + public static void test() { + System.out.print(静态方法中的内容! --); + { + System.out.print(静态方法中的代码块!--); + } + + } + public static void main(String[] args) { + + Test test = new Test(); + Test.test();静态代码块!--静态方法中的内容! --静态方法中的代码块!-- + } +``` + +当执行 `Test.test();` 时输出: + +``` +静态代码块!--静态方法中的内容! --静态方法中的代码块!-- +``` + +当执行 `Test test = new Test();` 时输出: + +``` +静态代码块!--非静态代码块!--默认构造方法!-- +``` + + +非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。 + +### 参考 + +- httpsblog.csdn.netchen13579867831articledetails78995480 +- httpwww.cnblogs.comchenssyp3388487.html +- httpwww.cnblogs.comQian123p5713440.html \ No newline at end of file From 31e27d3840f3c75c61e7a983ff52aa525510e18a Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:39:17 +0800 Subject: [PATCH 018/232] =?UTF-8?q?Add=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tatic\343\200\201this\343\200\201super.md" | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" "b/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" index 541a183ce8c..2c8a917f710 100644 --- "a/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" +++ "b/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" @@ -1,4 +1,23 @@ - + + +- [final,static,this,super 关键字总结](#finalstaticthissuper-关键字总结) + - [final 关键字](#final-关键字) + - [static 关键字](#static-关键字) + - [this 关键字](#this-关键字) + - [super 关键字](#super-关键字) + - [参考](#参考) +- [static 关键字详解](#static-关键字详解) + - [static 关键字主要有以下四种使用场景](#static-关键字主要有以下四种使用场景) + - [修饰成员变量和成员方法\(常用\)](#修饰成员变量和成员方法常用) + - [静态代码块](#静态代码块) + - [静态内部类](#静态内部类) + - [静态导包](#静态导包) + - [补充内容](#补充内容) + - [静态方法与非静态方法](#静态方法与非静态方法) + - [static{}静态代码块与{}非静态代码块\(构造代码块\)](#static静态代码块与非静态代码块构造代码块) + - [参考](#参考-1) + + # final,static,this,super 关键字总结 @@ -326,4 +345,4 @@ public class Test { - httpsblog.csdn.netchen13579867831articledetails78995480 - httpwww.cnblogs.comchenssyp3388487.html -- httpwww.cnblogs.comQian123p5713440.html \ No newline at end of file +- httpwww.cnblogs.comQian123p5713440.html From c79942fabb4743d14a04aab4c0059333e8d04230 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:40:42 +0800 Subject: [PATCH 019/232] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5584dcb6bcc..db558209a8d 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,8 @@ * [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java基础知识.md) * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/J2EE基础知识.md) -* [static、final、this、super关键字总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) -* [static 关键字详解](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/static.md) +* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) + ### Java 集合框架 From d6ede9db61918ca839669b4a2a8a7af727364fda Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:53:25 +0800 Subject: [PATCH 020/232] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index db558209a8d..fb6cd3eb579 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Java 学习/面试指南 -为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的目录供大家参考!如果有老哥对操作系统比较重要的知识总结过的话,欢迎找我哦! -一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。 +为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor] 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 + +**一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** 【限时福利】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 @@ -229,7 +230,7 @@ ![ Java并发编程专栏](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/Java并发编程实战.jpg) -### 致谢 +### Contributor 下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! From fb69c8c88d2ce37e92d8d43d8fbb7a920c2867b8 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 14:53:51 +0800 Subject: [PATCH 021/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb6cd3eb579..25fb18eaa43 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Java 学习/面试指南 -为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor] 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 +为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 **一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** From 8553b0b606bfaa352391f3147cf439f0e24a9812 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 15:01:53 +0800 Subject: [PATCH 022/232] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 25fb18eaa43..997b447370a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # Java 学习/面试指南 -为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 - **一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** -【限时福利】极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 +**【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 + + +为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。
From be1f00af739d7a29e1d6c686633df2a70410dee0 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 16:30:26 +0800 Subject: [PATCH 023/232] =?UTF-8?q?Delete=20=E7=BE=8E=E5=9B=A2-=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E7=AF=87.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-\345\237\272\347\241\200\347\257\207.md" | 357 ------------------ 1 file changed, 357 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\345\237\272\347\241\200\347\257\207.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\345\237\272\347\241\200\347\257\207.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\345\237\272\347\241\200\347\257\207.md" deleted file mode 100644 index 879f24c69fa..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\345\237\272\347\241\200\347\257\207.md" +++ /dev/null @@ -1,357 +0,0 @@ - - - -- [1. `System.out.println(3 | 9);`输出什么?](#1-systemoutprintln3-|-9输出什么) -- [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-实现原理) - - - -![备战春招/秋招系列】美团面经总结基础篇 (附详解答案)](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-10/3586727.jpg) - - -**系列文章:** - -- [【备战春招/秋招系列1】程序员的简历就该这样写](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484573&idx=1&sn=8c5965d4a3710d405d8e8cc10c7b0ce5&chksm=fd9852fccaefdbea8dfe0bc40188b7579f1cddb1e8905dc981669a3f21d2a04cadceafa9023f&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列3】Java程序员必备书单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484592&idx=1&sn=6d9731ce7401be49e97c1af6ed384ecc&chksm=fd9852d1caefdbc720a361ae65a8ad9d53cfb4800b15a7c68cbdc630b313215c6c52e0934ec2&token=1990180468&lang=zh_CN#rd) - -这是我总结的美团面经的基础篇,后面还有进阶和终结篇哦!下面只是我从很多份美团面经中总结的在面试中一些常见的问题。不同于个人面经,这份面经具有普适性。每次面试必备的自我介绍、项目介绍这些东西,大家可以自己私下好好思考。我在前面的文章中也提到了应该怎么做自我介绍与项目介绍,详情可以查看这篇文章:[【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd)。 - - -### 1. `System.out.println(3 | 9);`输出什么? - -正确答案:11. - -**考察知识点:&和&&;|和||** - -**&和&&:** - -共同点:两者都可做逻辑运算符。它们都表示运算符的两边都是true时,结果为true; - -不同点: &也是位运算符。& 表示在运算时两边都会计算,然后再判断;&&表示先运算符号左边的东西,然后判断是否为true,是true就继续运算右边的然后判断并输出,是false就停下来直接输出不会再运行后面的东西。 - -**|和||:** - -共同点:两者都可做逻辑运算符。它们都表示运算符的两边任意一边为true,结果为true,两边都不是true,结果就为false; - -不同点:|也是位运算符。| 表示两边都会运算,然后再判断结果;|| 表示先运算符号左边的东西,然后判断是否为true,是true就停下来直接输出不会再运行后面的东西,是false就继续运算右边的然后判断并输出。 - -**回到本题:** - -3 | 9=0011(二进制) | 1001(二进制)=1011(二进制)=11(十进制) - -### 2. 说一下转发(Forward)和重定向(Redirect)的区别 - -**转发是服务器行为,重定向是客户端行为。** - -**转发(Forword)** 通过RequestDispatcher对象的`forward(HttpServletRequest request,HttpServletResponse response)`方法实现的。`RequestDispatcher` 可以通过`HttpServletRequest` 的 `getRequestDispatcher()`方法获得。例如下面的代码就是跳转到 login_success.jsp 页面。 - -```java -request.getRequestDispatcher("login_success.jsp").forward(request, response); -``` - -**重定向(Redirect)** 是利用服务器返回的状态吗来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过HttpServletRequestResponse的setStatus(int status)方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。 - -1. **从地址栏显示来说:** forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址. redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL. -2. **从数据共享来说:** forward:转发页面和转发到的页面可以共享request里面的数据. redirect:不能共享数据. -3. **从运用地方来说:** forward:一般用于用户登陆的时候,根据角色转发到相应的模块. redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等 -4. **从效率来说:** forward:高. redirect:低. - - -### 3. 在浏览器中输入url地址到显示主页的过程,整个过程会使用哪些协议 - -图解(图片来源:《图解HTTP》): - -![状态码](https://user-gold-cdn.xitu.io/2018/4/19/162db5e985aabdbe?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) - -总体来说分为以下几个过程: - -1. DNS解析 -2. TCP连接 -3. 发送HTTP请求 -4. 服务器处理请求并返回HTTP报文 -5. 浏览器解析渲染页面 -6. 连接结束 - -具体可以参考下面这篇文章: - -- [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700) - -### 4. TCP 三次握手和四次挥手 - -为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。 - -**漫画图解:** - -图片来源:《图解HTTP》 -![TCP三次握手](https://user-gold-cdn.xitu.io/2018/5/8/1633e127396541f1?w=864&h=439&f=png&s=226095) - -**简单示意图:** -![TCP三次握手](https://user-gold-cdn.xitu.io/2018/5/8/1633e14233d95972?w=542&h=427&f=jpeg&s=15088) - -- 客户端–发送带有 SYN 标志的数据包–一次握手–服务端 -- 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端 -- 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端 - -#### 为什么要三次握手 - -**三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。** - -第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常。 - -第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己接收正常,对方发送正常 - -第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送接收正常 - -所以三次握手就能确认双发收发功能都正常,缺一不可。 - -#### 为什么要传回 SYN -接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。 - -> SYN 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement[汉译:确认字符 ,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误。 ])消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。 - - -#### 传了 SYN,为啥还要传 ACK - -双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方(主动关闭方)到接收方(被动关闭方)的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。 - -![TCP四次挥手](https://user-gold-cdn.xitu.io/2018/5/8/1633e1676e2ac0a3?w=500&h=340&f=jpeg&s=13406) - -断开一个 TCP 连接则需要“四次挥手”: - -- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送 -- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号 -- 服务器-关闭与客户端的连接,发送一个FIN给客户端 -- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1 - - -#### 为什么要四次挥手 - -任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 - -举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 - -上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891) - - - -### 5. IP地址与MAC地址的区别 - -参考:[https://blog.csdn.net/guoweimelon/article/details/50858597](https://blog.csdn.net/guoweimelon/article/details/50858597) - -IP地址是指互联网协议地址(Internet Protocol Address)IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。 - - - -MAC 地址又称为物理地址、硬件地址,用来定义网络设备的位置。网卡的物理地址通常是由网卡生产厂家写入网卡的,具有全球唯一性。MAC地址用于在网络中唯一标示一个网卡,一台电脑会有一或多个网卡,每个网卡都需要有一个唯一的MAC地址。 - -### 6. HTTP请求,响应报文格式 - - - -HTTP请求报文主要由请求行、请求头部、请求正文3部分组成 - -HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 - -详细内容可以参考:[https://blog.csdn.net/a19881029/article/details/14002273](https://blog.csdn.net/a19881029/article/details/14002273) - -### 7. 为什么要使用索引?索引这么多优点,为什么不对表中的每一个列创建一个索引呢?索引是如何提高查询速度的?说一下使用索引的注意事项?Mysql索引主要使用的两种数据结构?什么是覆盖索引? - -**为什么要使用索引?** - -1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 -2. 可以大大加快 数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因。 -3. 帮助服务器避免排序和临时表 -4. 将随机IO变为顺序IO -5. 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 - -**索引这么多优点,为什么不对表中的每一个列创建一个索引呢?** - -1. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 -2. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 -3. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 - -**索引是如何提高查询速度的?** - -将无序的数据变成相对有序的数据(就像查目录一样) - -**说一下使用索引的注意事项** - -1. 避免 where 子句中对字段施加函数,这会造成无法命中索引。 -2. 在使用InnoDB时使用与业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。 -3. 将打算加索引的列设置为 NOT NULL ,否则将导致引擎放弃使用索引而进行全表扫描 -4. 删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗 MySQL 5.7 可以通过查询 sys 库的 chema_unused_indexes 视图来查询哪些索引从未被使用 -5. 在使用 limit offset 查询缓慢时,可以借助索引来提高性能 - -**Mysql索引主要使用的哪两种数据结构?** - -- 哈希索引:对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。 -- BTree索引:Mysql的BTree索引使用的是B树中的B+Tree。但对于主要的两种存储引擎(MyISAM和InnoDB)的实现方式是不同的。 - -更多关于索引的内容可以查看我的这篇文章:[【思维导图-索引篇】搞定数据库索引就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484486&idx=1&sn=215450f11e042bca8a58eac9f4a97686&chksm=fd985227caefdb3117b8375f150676f5824aa20d1ebfdbcfb93ff06e23e26efbafae6cf6b48e&token=1990180468&lang=zh_CN#rd) - -**什么是覆盖索引?** - -如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称 -之为“覆盖索引”。我们知道在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次,这样就会比较慢。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作! - - -### 8. 进程与线程的区别是什么?进程间的几种通信方式说一下?线程间的几种通信方式知道不? - **进程与线程的区别是什么?** - -线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。另外,也正是因为共享资源,所以线程中执行时一般都要进行同步和互斥。总的来说,进程和线程的主要差别在于它们是不同的操作系统资源管理方式。 - -**进程间的几种通信方式说一下?** - - -1. **管道(pipe)**:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有血缘关系的进程间使用。进程的血缘关系通常指父子进程关系。管道分为pipe(无名管道)和fifo(命名管道)两种,有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间通信。 -2. **信号量(semophore)**:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它通常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 -4. **消息队列(message queue)**:消息队列是由消息组成的链表,存放在内核中 并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。 -5. **信号(signal)**:信号是一种比较复杂的通信方式,用于通知接收进程某一事件已经发生。 -6. **共享内存(shared memory)**:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问,共享内存是最快的IPC方式,它是针对其他进程间的通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信。 -7. **套接字(socket)**:socket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。也因为这样,套接字明确地将客户端和服务器区分开来。 - -**线程间的几种通信方式知道不?** - -1、锁机制 - -- 互斥锁:提供了以排它方式阻止数据结构被并发修改的方法。 -- 读写锁:允许多个线程同时读共享数据,而对写操作互斥。 -- 条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。 - -2、信号量机制:包括无名线程信号量与有名线程信号量 - -3、信号机制:类似于进程间的信号处理。 - -线程间通信的主要目的是用于线程同步,所以线程没有象进程通信中用于数据交换的通信机制。 - -### 9. 为什么要用单例模式?手写几种线程安全的单例模式? - -**简单来说使用单例模式可以带来下面几个好处:** - -- 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销; -- 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。 - -**懒汉式(双重检查加锁版本)** - -```java -public class Singleton { - - //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量 - private volatile static Singleton uniqueInstance; - private Singleton() { - } - public static Singleton getInstance() { - //检查实例,如果不存在,就进入同步代码块 - if (uniqueInstance == null) { - //只有第一次才彻底执行这里的代码 - synchronized(Singleton.class) { - //进入同步代码块后,再检查一次,如果仍是null,才创建实例 - if (uniqueInstance == null) { - uniqueInstance = new Singleton(); - } - } - } - return uniqueInstance; - } -} -``` - -**静态内部类方式** - -静态内部实现的单例是懒加载的且线程安全。 - -只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance(只有第一次使用这个单例的实例的时候才加载,同时不会有线程安全问题)。 - -```java -public class Singleton { - private static class SingletonHolder { - private static final Singleton INSTANCE = new Singleton(); - } - private Singleton (){} - public static final Singleton getInstance() { - return SingletonHolder.INSTANCE; - } -} -``` - -### 10. 简单介绍一下bean。知道Spring的bean的作用域与生命周期吗? - -在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。而 bean 的定义以及 bean 相互间的依赖关系将通过配置元数据来描述。 - -Spring中的bean默认都是单例的,这些单例Bean在多线程程序下如何保证线程安全呢? 例如对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Sevlet线程来处理请求,引入Spring框架之后,每个Action都是单例的,那么对于Spring托管的单例Service Bean,如何保证其安全呢? Spring的单例是基于BeanFactory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于 JVM,每个 JVM 内只有一个实例。 - -![pring的bean的作用域](https://user-gold-cdn.xitu.io/2018/11/10/166fd45773d5dd2e?w=563&h=299&f=webp&s=27930) - -Spring的bean的生命周期以及更多内容可以查看:[一文轻松搞懂Spring中bean的作用域与生命周期](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=2&sn=7201eb365102fce017f89cb3527fb0bc&chksm=fd985591caefdc872a2fac897288119f94c345e4e12150774f960bf5f816b79e4b9b46be3d7f&token=1990180468&lang=zh_CN#rd) - - -### 11. Spring 中的事务传播行为了解吗?TransactionDefinition 接口中哪五个表示隔离级别的常量? - -#### 事务传播行为 - -事务传播行为(为了解决业务层方法之间互相调用的事务问题): -当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量: - -**支持当前事务的情况:** - -- TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 -- TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 -- TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性) - -**不支持当前事务的情况:** - -- TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。 -- TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 -- TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。 - -**其他情况:** - -- TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。 - - -#### 隔离级别 - -TransactionDefinition 接口中定义了五个表示隔离级别的常量: - -- **TransactionDefinition.ISOLATION_DEFAULT:** 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别. -- **TransactionDefinition.ISOLATION_READ_UNCOMMITTED:** 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读 -- **TransactionDefinition.ISOLATION_READ_COMMITTED:** 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生 -- **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。 -- **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 - -### 12. SpringMVC 原理了解吗? - -![SpringMVC 原理](https://user-gold-cdn.xitu.io/2018/11/10/166fd45787394192?w=1015&h=466&f=webp&s=35352) - -客户端发送请求-> 前端控制器 DispatcherServlet 接受客户端请求 -> 找到处理器映射 HandlerMapping 解析请求对应的 Handler-> HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑 -> 处理器返回一个模型视图 ModelAndView -> 视图解析器进行解析 -> 返回一个视图对象->前端控制器 DispatcherServlet 渲染数据(Model)->将得到视图对象返回给用户 - -关于 SpringMVC 原理更多内容可以查看我的这篇文章:[SpringMVC 工作原理详解](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484496&idx=1&sn=5472ffa687fe4a05f8900d8ee6726de4&chksm=fd985231caefdb27fc75b44ecf76b6f43e4617e0b01b3c040f8b8fab32e51dfa5118eed1d6ad&token=1990180468&lang=zh_CN#rd) - -### 13. Spring AOP IOC 实现原理 - -过了秋招挺长一段时间了,说实话我自己也忘了如何简要概括 Spring AOP IOC 实现原理,就在网上找了一个较为简洁的答案,下面分享给各位。 - -**IOC:** 控制反转也叫依赖注入。IOC利用java反射机制,AOP利用代理模式。IOC 概念看似很抽象,但是很容易理解。说简单点就是将对象交给容器管理,你只需要在spring配置文件中配置对应的bean以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类。 - -**AOP:** 面向切面编程。(Aspect-Oriented Programming) 。AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理。 - - - From 539028b28987b01c023ebbcde32c8ed56cffb8e2 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 16:30:29 +0800 Subject: [PATCH 024/232] =?UTF-8?q?Delete=20=E7=BE=8E=E5=9B=A2-=E7=BB=88?= =?UTF-8?q?=E7=BB=93=E7=AF=87.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-\347\273\210\347\273\223\347\257\207.md" | 353 ------------------ 1 file changed, 353 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\347\273\210\347\273\223\347\257\207.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\347\273\210\347\273\223\347\257\207.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\347\273\210\347\273\223\347\257\207.md" deleted file mode 100644 index c4b30efe491..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\347\273\210\347\273\223\347\257\207.md" +++ /dev/null @@ -1,353 +0,0 @@ - - - -- [一. Object类有哪些方法?](#一-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) -- [二 ConcurrentHashMap 相关问题](#二-concurrenthashmap-相关问题) - - [2.1 ConcurrentHashMap 和 Hashtable 的区别](#21-concurrenthashmap-和-hashtable-的区别) - - [2.2 ConcurrentHashMap线程安全的具体实现方式/底层具体实现](#22-concurrenthashmap线程安全的具体实现方式底层具体实现) - - [JDK1.7(上面有示意图)](#jdk17(上面有示意图)) - - [JDK1.8 (上面有示意图)](#jdk18-(上面有示意图)) -- [三 谈谈 synchronized 和 ReenTrantLock 的区别](#三-谈谈-synchronized-和-reentrantlock-的区别) -- [四 线程池了解吗?](#四-线程池了解吗?) - - [4.1 为什么要用线程池?](#41-为什么要用线程池?) - - [4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么?](#42-java-提供了哪几种线程池?他们各自的使用场景是什么?) - - [Java 主要提供了下面4种线程池](#java-主要提供了下面4种线程池) - - [各种线程池的适用场景介绍](#各种线程池的适用场景介绍) - - [4.3 创建的线程池的方式](#43-创建的线程池的方式) -- [五 Nginx](#五-nginx) - - [5.1 简单介绍一下Nginx](#51-简单介绍一下nginx) - - [反向代理](#反向代理) - - [负载均衡](#负载均衡) - - [动静分离](#动静分离) - - [5.2 为什么要用 Nginx ?](#52-为什么要用-nginx-?) - - [5.3 Nginx 的四个主要组成部分了解吗?](#53-nginx-的四个主要组成部分了解吗?) - - - - -> 下面这个问题,面试中经常出现。我觉得不论是出于应付面试还是说更好地掌握Java这门编程语言,大家都要掌握! - -# 一. Object类有哪些方法? - -### 1.1 Object类的常见方法总结 - -Object类是一个特殊的类,是所有类的父类。它主要提供了以下11个方法: - -```java - -public final native Class getClass()//native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。 - -public native int hashCode() //native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。 -public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。 - -protected native Object clone() throws CloneNotSupportedException//naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。 - -public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。 - -public final native void notify()//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。 - -public final native void notifyAll()//native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。 - -public final native void wait(long timeout) throws InterruptedException//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。 - -public final void wait(long timeout, int nanos) throws InterruptedException//多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。 - -public final void wait() throws InterruptedException//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念 - -protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作 - -``` - -> 问完上面这个问题之后,面试官很可能紧接着就会问你“hashCode与equals”相关的问题。 - -### 1.2 hashCode与equals - -面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” - -#### 1.2.1 hashCode()介绍 -hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。 - -```java - public native int hashCode(); -``` - -散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象) - -#### 1.2.2 为什么要有hashCode - - -**我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:** - -当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。 - - -#### 1.2.3 hashCode()与equals()的相关规定 - -1. 如果两个对象相等,则hashcode一定也是相同的 -2. 两个对象相等,对两个对象分别调用equals方法都返回true -3. 两个对象有相同的hashcode值,它们也不一定是相等的 -4. **因此,equals方法被覆盖过,则hashCode方法也必须被覆盖** -5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据) - -#### 1.2.4 为什么两个对象有相同的hashcode值,它们也不一定是相等的? - -在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 - -因为hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。 - -我们刚刚也提到了 HashSet,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。 - -> ==与equals 的对比也是比较常问的基础问题之一! - -### 1.3 ==与equals - -**==** : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) - -**equals()** : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: - -- 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。 -- 情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。 - - -**举个例子:** - -```java -public class test1 { - public static void main(String[] args) { - String a = new String("ab"); // a 为一个引用 - String b = new String("ab"); // b为另一个引用,对象的内容一样 - String aa = "ab"; // 放在常量池中 - String bb = "ab"; // 从常量池中查找 - if (aa == bb) // true - System.out.println("aa==bb"); - if (a == b) // false,非同一对象 - System.out.println("a==b"); - if (a.equals(b)) // true - System.out.println("aEQb"); - if (42 == 42.0) { // true - System.out.println("true"); - } - } -} -``` - -**说明:** - -- String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。 -- 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。 - -> 在[【备战春招/秋招系列5】美团面经总结进阶篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484625&idx=1&sn=9c4fa1f7d4291a5fbd7daa44bac2b012&chksm=fd9852b0caefdba6edcf9a827aa4a17ddc97bf6ad2e5ee6f7e1aa1b443b54444d05d2b76732b&token=723699735&lang=zh_CN#rd) 这篇文章中,我们已经提到了一下关于 HashMap 在面试中常见的问题:HashMap 的底层实现、简单讲一下自己对于红黑树的理解、红黑树这么优秀,为何不直接使用红黑树得了、HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别。HashMap 和 ConcurrentHashMap 这俩兄弟在一般只要面试中问到集合相关的问题就一定会被问到,所以各位务必引起重视! - -# 二 ConcurrentHashMap 相关问题 - -### 2.1 ConcurrentHashMap 和 Hashtable 的区别 - -ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。 - -- **底层数据结构:** JDK1.7的 ConcurrentHashMap 底层采用 **分段的数组+链表** 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 **数组+链表** 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的; -- **实现线程安全的方式(重要):** ① **在JDK1.7的时候,ConcurrentHashMap(分段锁)** 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16个Segment,比Hashtable效率提高16倍。) **到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化)** 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② **Hashtable(同一把锁)** :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。 - -**两者的对比图:** - -图片来源:http://www.cnblogs.com/chengxiao/p/6842045.html - -HashTable: -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/50656681.jpg) - -JDK1.7的ConcurrentHashMap: -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/33120488.jpg) -JDK1.8的ConcurrentHashMap(TreeBin: 红黑二叉树节点 -Node: 链表节点): -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/97739220.jpg) - -### 2.2 ConcurrentHashMap线程安全的具体实现方式/底层具体实现 - -#### JDK1.7(上面有示意图) - -首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。 - -**ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成**。 - -Segment 实现了 ReentrantLock,所以 Segment 是一种可重入锁,扮演锁的角色。HashEntry 用于存储键值对数据。 - -```java -static class Segment extends ReentrantLock implements Serializable { -} -``` - -一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护着一个HashEntry数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment的锁。 - -#### JDK1.8 (上面有示意图) - -ConcurrentHashMap取消了Segment分段锁,采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。 - -synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。 - -# 三 谈谈 synchronized 和 ReenTrantLock 的区别 - -**① 两者都是可重入锁** - -两者都是可重入锁。“可重入锁”概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。 - -**② synchronized 依赖于 JVM 而 ReenTrantLock 依赖于 API** - -synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。ReenTrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock 方法配合 try/finally 语句块来完成),所以我们可以通过查看它的源代码,来看它是如何实现的。 - -**③ ReenTrantLock 比 synchronized 增加了一些高级功能** - -相比synchronized,ReenTrantLock增加了一些高级功能。主要来说主要有三点:**①等待可中断;②可实现公平锁;③可实现选择性通知(锁可以绑定多个条件)** - -- **ReenTrantLock提供了一种能够中断等待锁的线程的机制**,通过lock.lockInterruptibly()来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。 -- **ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。** ReenTrantLock默认情况是非公平的,可以通过 ReenTrantLock类的`ReentrantLock(boolean fair)`构造方法来制定是否是公平的。 -- synchronized关键字与wait()和notify/notifyAll()方法相结合可以实现等待/通知机制,ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition() 方法。Condition是JDK1.5之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),**线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的,用ReentrantLock类结合Condition实例可以实现“选择性通知”** ,这个功能非常重要,而且是Condition接口默认提供的。而synchronized关键字就相当于整个Lock对象中只有一个Condition实例,所有的线程都注册在它一个身上。如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法 只会唤醒注册在该Condition实例中的所有等待线程。 - -如果你想使用上述功能,那么选择ReenTrantLock是一个不错的选择。 - -**④ 两者的性能已经相差无几** - -在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具体表示为:synchronized 关键字吞吐量岁线程数的增加,下降得非常严重。而ReenTrantLock 基本保持一个比较稳定的水平。我觉得这也侧面反映了, synchronized 关键字还有非常大的优化余地。后续的技术发展也证明了这一点,我们上面也讲了在 JDK1.6 之后 JVM 团队对 synchronized 关键字做了很多优化。JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以网上那些说因为性能才选择 ReenTrantLock 的文章都是错的!JDK1.6之后,性能已经不是选择synchronized和ReenTrantLock的影响因素了!而且虚拟机在未来的性能改进中会更偏向于原生的synchronized,所以还是提倡在synchronized能满足你的需求的情况下,优先考虑使用synchronized关键字来进行同步!优化后的synchronized和ReenTrantLock一样,在很多地方都是用到了CAS操作。 - - -# 四 线程池了解吗? - - -### 4.1 为什么要用线程池? - -线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。 - -这里借用《Java并发编程的艺术》提到的来说一下使用线程池的好处: - -- **降低资源消耗。** 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 -- **提高响应速度。** 当任务到达时,任务可以不需要的等到线程创建就能立即执行。 -- **提高线程的可管理性。** 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 - -### 4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么? - -#### Java 主要提供了下面4种线程池 - -- **FixedThreadPool:** 该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。 -- **SingleThreadExecutor:** 方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。 -- **CachedThreadPool:** 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。 -- **ScheduledThreadPoolExecutor:** 主要用来在给定的延迟后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor又分为:ScheduledThreadPoolExecutor(包含多个线程)和SingleThreadScheduledExecutor (只包含一个线程)两种。 - -#### 各种线程池的适用场景介绍 - -- **FixedThreadPool:** 适用于为了满足资源管理需求,而需要限制当前线程数量的应用场景。它适用于负载比较重的服务器; -- **SingleThreadExecutor:** 适用于需要保证顺序地执行各个任务并且在任意时间点,不会有多个线程是活动的应用场景。 -- **CachedThreadPool:** 适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器; -- **ScheduledThreadPoolExecutor:** 适用于需要多个后台执行周期任务,同时为了满足资源管理需求而需要限制后台线程的数量的应用场景, -- **SingleThreadScheduledExecutor:** 适用于需要单个后台线程执行周期任务,同时保证顺序地执行各个任务的应用场景。 - -### 4.3 创建的线程池的方式 - -**(1) 使用 Executors 创建** - -我们上面刚刚提到了 Java 提供的几种线程池,通过 Executors 工具类我们可以很轻松的创建我们上面说的几种线程池。但是实际上我们一般都不是直接使用Java提供好的线程池,另外在《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 构造函数 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 - -```java -Executors 返回线程池对象的弊端如下: - -FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。 -CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。 - -``` -**(2) ThreadPoolExecutor的构造函数创建** - - -我们可以自己直接调用 ThreadPoolExecutor 的构造函数来自己创建线程池。在创建的同时,给 BlockQueue 指定容量就可以了。示例如下: - -```java -private static ExecutorService executor = new ThreadPoolExecutor(13, 13, - 60L, TimeUnit.SECONDS, - new ArrayBlockingQueue(13)); -``` - -这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列,队列已经满了便无法继续处理新的请求。但是异常(Exception)总比发生错误(Error)要好。 - -**(3) 使用开源类库** - -Hollis 大佬之前在他的文章中也提到了:“除了自己定义ThreadPoolExecutor外。还有其他方法。这个时候第一时间就应该想到开源类库,如apache和guava等。”他推荐使用guava提供的ThreadFactoryBuilder来创建线程池。下面是参考他的代码示例: - -```java -public class ExecutorsDemo { - - private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() - .setNameFormat("demo-pool-%d").build(); - - private static ExecutorService pool = new ThreadPoolExecutor(5, 200, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); - - public static void main(String[] args) { - - for (int i = 0; i < Integer.MAX_VALUE; i++) { - pool.execute(new SubThread()); - } - } -} -``` - -通过上述方式创建线程时,不仅可以避免OOM的问题,还可以自定义线程名称,更加方便的出错的时候溯源。 - -# 五 Nginx - -### 5.1 简单介绍一下Nginx - -Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。 Nginx 主要提供反向代理、负载均衡、动静分离(静态资源服务)等服务。下面我简单地介绍一下这些名词。 - -#### 反向代理 - -谈到反向代理,就不得不提一下正向代理。无论是正向代理,还是反向代理,说到底,就是代理模式的衍生版本罢了 - -- **正向代理:**某些情况下,代理我们用户去访问服务器,需要用户手动的设置代理服务器的ip和端口号。正向代理比较常见的一个例子就是 VPN了。 -- **反向代理:** 是用来代理服务器的,代理我们要访问的目标服务器。代理服务器接受请求,然后将请求转发给内部网络的服务器,并将从服务器上得到的结果返回给客户端,此时代理服务器对外就表现为一个服务器。 - -通过下面两幅图,大家应该更好理解(图源:http://blog.720ui.com/2016/nginx_action_05_proxy/): - -![正向代理](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-15/60925795.jpg) - -![反向代理](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-15/62563930.jpg) - -所以,简单的理解,就是正向代理是为客户端做代理,代替客户端去访问服务器,而反向代理是为服务器做代理,代替服务器接受客户端请求。 - -#### 负载均衡 - -在高并发情况下需要使用,其原理就是将并发请求分摊到多个服务器执行,减轻每台服务器的压力,多台服务器(集群)共同完成工作任务,从而提高了数据的吞吐量。 - -Nginx支持的weight轮询(默认)、ip_hash、fair、url_hash这四种负载均衡调度算法,感兴趣的可以自行查阅。 - -负载均衡相比于反向代理更侧重的时将请求分担到多台服务器上去,所以谈论负载均衡只有在提供某服务的服务器大于两台时才有意义。 - -#### 动静分离 - -动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。 - -### 5.2 为什么要用 Nginx ? - -> 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 - -如果面试官问你这个问题,就一定想看你知道 Nginx 服务器的一些优点吗。 - -Nginx 有以下5个优点: - -1. 高并发、高性能(这是其他web服务器不具有的) -2. 可扩展性好(模块化设计,第三方插件生态圈丰富) -3. 高可靠性(可以在服务器行持续不间断的运行数年) -4. 热部署(这个功能对于 Nginx 来说特别重要,热部署指可以在不停止 Nginx服务的情况下升级 Nginx) -5. BSD许可证(意味着我们可以将源代码下载下来进行修改然后使用自己的版本) - -### 5.3 Nginx 的四个主要组成部分了解吗? - -> 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 - -- Nginx 二进制可执行文件:由各模块源码编译出一个文件 -- Nginx.conf 配置文件:控制Nginx 行为 -- acess.log 访问日志: 记录每一条HTTP请求信息 -- error.log 错误日志:定位问题 From db9e98fe3146fae3d236eb4fcc585b8012d65e5a Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 16:30:32 +0800 Subject: [PATCH 025/232] =?UTF-8?q?Delete=20=E7=BE=8E=E5=9B=A2-=E8=BF=9B?= =?UTF-8?q?=E9=98=B6=E7=AF=87.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-\350\277\233\351\230\266\347\257\207.md" | 271 ------------------ 1 file changed, 271 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\350\277\233\351\230\266\347\257\207.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\350\277\233\351\230\266\347\257\207.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\350\277\233\351\230\266\347\257\207.md" deleted file mode 100644 index cb2d247ec91..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\276\216\345\233\242-\350\277\233\351\230\266\347\257\207.md" +++ /dev/null @@ -1,271 +0,0 @@ -![ 【备战春招/秋招系列】美团面经总结进阶篇 (附详解答案)](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c2ae52c?w=928&h=531&f=png&s=798562) - - -- [一 消息队列MQ的套路](#一-消息队列mq的套路) - - [1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处](#11-介绍一下消息队列mq的应用场景使用消息队列的好处) - - [①.通过异步处理提高系统性能](#①通过异步处理提高系统性能) - - [②.降低系统耦合性](#②降低系统耦合性) - - [1.2 那么使用消息队列会带来什么问题?考虑过这个问题吗?](#12-那么使用消息队列会带来什么问题考虑过这个问题吗) - - [1.3 介绍一下你知道哪几种消息队列,该如何选择呢?](#13-介绍一下你知道哪几种消息队列该如何选择呢) - - [1.4 关于消息队列其他一些常见的问题展望](#14-关于消息队列其他一些常见的问题展望) -- [二 谈谈 InnoDB 和 MyIsam 两者的区别](#二-谈谈-innodb-和-myisam-两者的区别) - - [2.1 两者的对比](#21-两者的对比) - - [2.2 关于两者的总结](#22-关于两者的总结) -- [三 聊聊 Java 中的集合吧!](#三-聊聊-java-中的集合吧!) - - [3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容)](#31-arraylist-与-linkedlist-有什么不同?(注意加上从数据结构分析的内容)) - - [3.2 HashMap的底层实现](#32-hashmap的底层实现) - - [① JDK1.8之前](#①-jdk18之前) - - [② JDK1.8之后](#②-jdk18之后) - - [3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解](#33-既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解) - - [3.4 红黑树这么优秀,为何不直接使用红黑树得了?](#34-红黑树这么优秀为何不直接使用红黑树得了) - - [3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别](#35-hashmap-和-hashtable-的区别hashset-和-hashmap-区别) - - - - -> 该文已加入开源文档:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识)。地址:https://github.com/Snailclimb/JavaGuide. - - -**系列文章:** - -- [【备战春招/秋招系列1】程序员的简历就该这样写](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484573&idx=1&sn=8c5965d4a3710d405d8e8cc10c7b0ce5&chksm=fd9852fccaefdbea8dfe0bc40188b7579f1cddb1e8905dc981669a3f21d2a04cadceafa9023f&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列3】Java程序员必备书单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484592&idx=1&sn=6d9731ce7401be49e97c1af6ed384ecc&chksm=fd9852d1caefdbc720a361ae65a8ad9d53cfb4800b15a7c68cbdc630b313215c6c52e0934ec2&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列4】美团面经总结基础篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484601&idx=1&sn=4907b7fef0856791c565d49d788ba8cc&chksm=fd9852d8caefdbce88e51c0a10a4ec77c97f382fd2af4a840ea47cffc828bfd0f993f50d5f0d&token=2045370425&lang=zh_CN#rd) - -这是我总结的美团面经的进阶篇,后面还有终结篇哦!下面只是我从很多份美团面经中总结的在美团面试中一些常见的问题。不同于个人面经,这份面经具有普适性。每次面试必备的自我介绍、项目介绍这些东西,大家可以自己私下好好思考。我在前面的文章中也提到了应该怎么做自我介绍与项目介绍,详情可以查看这篇文章:[【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd)。 - -有人私信我让我对美团面试难度做一个评级,我觉得如果有10级的话,美团面试的难度大概在6级左右吧!部分情况可能因人而异了。 - -> 消息队列/消息中间件应该是Java程序员必备的一个技能了,如果你之前没接触过消息队列的话,建议先去百度一下某某消息队列入门,然后花2个小时就差不多可以学会任何一种消息队列的使用了。如果说仅仅学会使用是万万不够的,在实际生产环境还要考虑消息丢失等等情况。关于消息队列面试相关的问题,推荐大家也可以看一下视频《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! - -# 一 消息队列MQ的套路 - -> 面试官一般会先问你这个问题,预热一下,看你知道消息队列不,一般在第一面的时候面试官可能只会问消息队列MQ的应用场景/使用消息队列的好处、使用消息队列会带来什么问题、消息队列的技术选型这几个问题,不会太深究下去,在后面的第二轮/第三轮技术面试中可能会深入问一下。 - -### 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 - -**《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。** - -#### ①.通过异步处理提高系统性能 -![通过异步处理提高系统性能](https://user-gold-cdn.xitu.io/2018/4/21/162e63a8e34ba534?w=910&h=350&f=jpeg&s=29123) -如上图,**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。** - -通过以上分析我们可以得出**消息队列具有很好的削峰作用的功能**——即**通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。** 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示: -![合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击](https://user-gold-cdn.xitu.io/2018/4/21/162e64583dd3ed01?w=780&h=384&f=jpeg&s=13550) -因为**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**。因此使用消息队列进行异步处理之后,需要**适当修改业务流程进行配合**,比如**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**,以免交易纠纷。这就类似我们平时手机订火车票和电影票。 - -### ②.降低系统耦合性 -我们知道模块分布式部署以后聚合方式通常有两种:1.**分布式消息队列**和2.**分布式服务**。 - -> **先来简单说一下分布式服务:** - -目前使用比较多的用来构建**SOA(Service Oriented Architecture面向服务体系结构)**的**分布式服务框架**是阿里巴巴开源的**Dubbo**.如果想深入了解Dubbo的可以看我写的关于Dubbo的这一篇文章:**《高性能优秀的服务框架-dubbo介绍》**:[https://juejin.im/post/5acadeb1f265da2375072f9c](https://juejin.im/post/5acadeb1f265da2375072f9c) - -> **再来谈我们的分布式消息队列:** - -我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。 - -我们最常见的**事件驱动架构**类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示: -![利用消息队列实现事件驱动结构](https://user-gold-cdn.xitu.io/2018/4/21/162e6665fa394b3b?w=790&h=290&f=jpeg&s=14946) -**消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。** 从上图可以看到**消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合**,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。**对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计**。 - -消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。 - -**另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。** - -**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的,**比如在我们的ActiveMQ消息队列中还有点对点工作模式**,具体的会在后面的文章给大家详细介绍,这一篇文章主要还是让大家对消息队列有一个更透彻的了解。 - -> 这个问题一般会在上一个问题问完之后,紧接着被问到。“使用消息队列会带来什么问题?”这个问题要引起重视,一般我们都会考虑使用消息队列会带来的好处而忽略它带来的问题! - -### 1.2 那么使用消息队列会带来什么问题?考虑过这个问题吗? - -- **系统可用性降低:** 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了! -- **系统复杂性提高:** 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题! -- **一致性问题:** 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了! - -> 了解下面这个问题是为了我们更好的进行技术选型!该部分摘自:《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! - -### 1.3 介绍一下你知道哪几种消息队列,该如何选择呢? - - -|特性 | ActiveMQ| RabbitMQ| RocketMQ| Kafaka| -| :-------- | ----------:|--------:|--------:|--------:| -| 单机吞吐量 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 |10万级,RocketMQ也是可以支撑高吞吐的一种MQ |10万级别,这是kafka最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景 | -| topic数量对吞吐量的影响 | | | topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic |topic从几十个到几百个的时候,吞吐量会大幅度下降。所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源| -|可用性 |高,基于主从架构实现高可用性|高,基于主从架构实现高可用性 | 非常高,分布式架构|非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用| -|消息可靠性 | 有较低的概率丢失数据 | | 经过参数优化配置,可以做到0丢失|经过参数优化配置,消息可以做到0丢失 | -|时效性 |ms级| 微秒级,这是rabbitmq的一大特点,延迟是最低的 | ms级 |延迟在ms级以内 | -|功能支持| MQ领域的功能极其完备 |基于erlang开发,所以并发能力很强,性能极其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 |功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 | -|优劣势总结| 非常成熟,功能强大,在业内大量的公司以及项目中都有应用。偶尔会有较低概率丢失消息,而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用 | erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备而且开源提供的管理界面非常棒,用起来很好用。社区相对比较活跃,几乎每个月都发布几个版本分在国内一些互联网公司近几年用rabbitmq也比较多一些但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。而且erlang开发,国内有几个公司有实力做erlang源码级别的研究和定制?如果说你没这个实力的话,确实偶尔会有一些问题,你很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。而且rabbitmq集群动态扩展会很麻烦,不过这个我觉得还好。其实主要是erlang语言本身带来的问题。很难读源码,很难定制和掌控。| 接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障。日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是ok的,还可以支撑大规模的topic数量,支持复杂MQ业务场景。而且一个很大的优势在于,阿里出品都是java系的,我们可以自己阅读源码,定制自己公司的MQ,可以掌控。社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准JMS规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ挺好的|kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量。而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。| - -> 这部分内容,我这里不给出答案,大家可以自行根据自己学习的消息队列查阅相关内容,我可能会在后面的文章中介绍到这部分内容。另外,下面这些问题在视频《Java工程师面试突击第1季-中华石杉老师》中都有提到,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! - -### 1.4 关于消息队列其他一些常见的问题展望 - -1. 引入消息队列之后如何保证高可用性 -2. 如何保证消息不被重复消费呢? -3. 如何保证消息的可靠性传输(如何处理消息丢失的问题)? -4. 我该怎么保证从消息队列里拿到的数据按顺序执行? -5. 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决? -6. 如果让你来开发一个消息队列中间件,你会怎么设计架构? - - - -# 二 谈谈 InnoDB 和 MyIsam 两者的区别 - -### 2.1 两者的对比 - -1) **count运算上的区别:** 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。 - -2) **是否支持事务和崩溃后的安全恢复:** MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 - -3)**是否支持外键:** MyISAM不支持,而InnoDB支持。 - - - -### 2.2 关于两者的总结 - -MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数据库做主从分离的情况下,经常选择MyISAM作为主库的存储引擎。 - -一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。如果你的数据量很大(MyISAM支持压缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM是最好的选择。 - - -# 三 聊聊 Java 中的集合吧! - - -### 3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容) - -- **1. 是否保证线程安全:** ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; -- **2. 底层数据结构:** Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(注意双向链表和双向循环链表的区别:); -- **3. 插入和删除是否受元素位置的影响:** ① **ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。** 比如:执行`add(E e) `方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element) `)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② **LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。** -- **4. 是否支持快速随机访问:** LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index) `方法)。 -- **5. 内存空间占用:** ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。 - -**补充内容:RandomAccess接口** - -```java -public interface RandomAccess { -} -``` - -查看源码我们发现实际上 RandomAccess 接口中什么都没有定义。所以,在我看来 RandomAccess 接口不过是一个标识罢了。标识什么? 标识实现这个接口的类具有随机访问功能。 - -在binarySearch()方法中,它要判断传入的list 是否RamdomAccess的实例,如果是,调用indexedBinarySearch()方法,如果不是,那么调用iteratorBinarySearch()方法 - -```java - public static - int binarySearch(List> list, T key) { - if (list instanceof RandomAccess || list.size() Java 中的集合这类问题几乎是面试必问的,问到这类问题的时候,HashMap 又是几乎必问的问题,所以大家一定要引起重视! - -### 3.2 HashMap的底层实现 - -#### ① JDK1.8之前 - -JDK1.8 之前 HashMap 底层是 **数组和链表** 结合在一起使用也就是 **链表散列**。**HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 `(n - 1) & hash` 判断当前元素存放的位置(这里的 n 指的时数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。** - -**所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。** - -**JDK 1.8 HashMap 的 hash 方法源码:** - -JDK 1.8 的 hash方法 相比于 JDK 1.7 hash 方法更加简化,但是原理不变。 - -```java - static final int hash(Object key) { - int h; - // key.hashCode():返回散列值也就是hashcode - // ^ :按位异或 - // >>>:无符号右移,忽略符号位,空位都以0补齐 - return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); - } -``` -对比一下 JDK1.7的 HashMap 的 hash 方法源码. - -```java -static int hash(int h) { - // This function ensures that hashCodes that differ only by - // constant multiples at each bit position have a bounded - // number of collisions (approximately 8 at default load factor). - - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); -} -``` - -相比于 JDK1.8 的 hash 方法 ,JDK 1.7 的 hash 方法的性能会稍差一点点,因为毕竟扰动了 4 次。 - -所谓 **“拉链法”** 就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。 - - - -![jdk1.8之前的内部结构](https://user-gold-cdn.xitu.io/2018/3/20/16240dbcc303d872?w=348&h=427&f=png&s=10991) - - -#### ② JDK1.8之后 - -相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。 - -![JDK1.8之后的HashMap底层数据结构](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c351da9?w=720&h=545&f=jpeg&s=23933) - -TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 - -> 问完 HashMap 的底层原理之后,面试官可能就会紧接着问你 HashMap 底层数据结构相关的问题! - -### 3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解 - -![红黑树](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c138cba?w=851&h=614&f=jpeg&s=34458) - -**红黑树特点:** - -1. 每个节点非红即黑; -2. 根节点总是黑色的; -3. 每个叶子节点都是黑色的空节点(NIL节点); -4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定); -5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度) - -**红黑树的应用:** - -TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。 - -**为什么要用红黑树** - -简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 - - -### 3.4 红黑树这么优秀,为何不直接使用红黑树得了? - -说一下自己对于这个问题的看法:我们知道红黑树属于(自)平衡二叉树,但是为了保持“平衡”是需要付出代价的,红黑树在插入新数据后可能需要通过左旋,右旋、变色这些操作来保持平衡,这费事啊。你说说我们引入红黑树就是为了查找数据快,如果链表长度很短的话,根本不需要引入红黑树的,你引入之后还要付出代价维持它的平衡。但是链表过长就不一样了。至于为什么选 8 这个值呢?通过概率统计所得,这个值是综合查询成本和新增元素成本得出的最好的一个值。 - -### 3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别 - -**HashMap 和 Hashtable 的区别** - -1. **线程是否安全:** HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 `synchronized` 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!); -2. **效率:** 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它; -3. **对Null key 和Null value的支持:** HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。 -4. **初始容量大小和每次扩充容量大小的不同 :** ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小(HashMap 中的`tableSizeFor()`方法保证,下面给出了源代码)。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。 -5. **底层数据结构:** JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。 - -**HashSet 和 HashMap 区别** - -如果你看过 HashSet 源码的话就应该知道:HashSet 底层就是基于 HashMap 实现的。(HashSet 的源码非常非常少,因为除了 clone() 方法、writeObject()方法、readObject()方法是 HashSet 自己不得不实现之外,其他方法都是直接调用 HashMap 中的方法。) - -![HashSet 和 HashMap 区别](https://user-gold-cdn.xitu.io/2018/3/2/161e717d734f3b23?w=896&h=363&f=jpeg&s=205536) - - From 3a99798b9c08b9b9a60714b815dca20e6faeb617 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 3 Mar 2019 16:30:37 +0800 Subject: [PATCH 026/232] =?UTF-8?q?Create=20=E7=BE=8E=E5=9B=A2=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E5=B8=B8=E8=A7=81=E9=97=AE=E9=A2=98=E6=80=BB=E7=BB=93?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...56\351\242\230\346\200\273\347\273\223.md" | 881 ++++++++++++++++++ 1 file changed, 881 insertions(+) create mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\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" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/\351\235\242\350\257\225\345\277\205\345\244\207/\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" new file mode 100644 index 00000000000..8f8cfd9756f --- /dev/null +++ "b/\351\235\242\350\257\225\345\277\205\345\244\207/\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" @@ -0,0 +1,881 @@ +这些问题是2018年去美团面试的同学被问到的一些常见的问题,希望对你有帮助! + +# 一 基础篇 + + +## 1. `System.out.println(3 | 9);`输出什么? + +正确答案:11. + +**考察知识点:&和&&;|和||** + +**&和&&:** + +共同点:两者都可做逻辑运算符。它们都表示运算符的两边都是true时,结果为true; + +不同点: &也是位运算符。& 表示在运算时两边都会计算,然后再判断;&&表示先运算符号左边的东西,然后判断是否为true,是true就继续运算右边的然后判断并输出,是false就停下来直接输出不会再运行后面的东西。 + +**|和||:** + +共同点:两者都可做逻辑运算符。它们都表示运算符的两边任意一边为true,结果为true,两边都不是true,结果就为false; + +不同点:|也是位运算符。| 表示两边都会运算,然后再判断结果;|| 表示先运算符号左边的东西,然后判断是否为true,是true就停下来直接输出不会再运行后面的东西,是false就继续运算右边的然后判断并输出。 + +**回到本题:** + +3 | 9=0011(二进制) | 1001(二进制)=1011(二进制)=11(十进制) + +## 2. 说一下转发(Forward)和重定向(Redirect)的区别 + +**转发是服务器行为,重定向是客户端行为。** + +**转发(Forword)** 通过RequestDispatcher对象的`forward(HttpServletRequest request,HttpServletResponse response)`方法实现的。`RequestDispatcher` 可以通过`HttpServletRequest` 的 `getRequestDispatcher()`方法获得。例如下面的代码就是跳转到 login_success.jsp 页面。 + +```java +request.getRequestDispatcher("login_success.jsp").forward(request, response); +``` + +**重定向(Redirect)** 是利用服务器返回的状态吗来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过HttpServletRequestResponse的setStatus(int status)方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。 + +1. **从地址栏显示来说:** forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址. redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL. +2. **从数据共享来说:** forward:转发页面和转发到的页面可以共享request里面的数据. redirect:不能共享数据. +3. **从运用地方来说:** forward:一般用于用户登陆的时候,根据角色转发到相应的模块. redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等 +4. **从效率来说:** forward:高. redirect:低. + + +## 3. 在浏览器中输入url地址到显示主页的过程,整个过程会使用哪些协议 + +图片来源:《图解HTTP》: + +![状态码](https://user-gold-cdn.xitu.io/2018/4/19/162db5e985aabdbe?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) + +总体来说分为以下几个过程: + +1. DNS解析 +2. TCP连接 +3. 发送HTTP请求 +4. 服务器处理请求并返回HTTP报文 +5. 浏览器解析渲染页面 +6. 连接结束 + +具体可以参考下面这篇文章: + +- [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700) + +## 4. TCP 三次握手和四次挥手 + +为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。 + +**漫画图解:** + +图片来源:《图解HTTP》 +![TCP三次握手](https://user-gold-cdn.xitu.io/2018/5/8/1633e127396541f1?w=864&h=439&f=png&s=226095) + +**简单示意图:** +![TCP三次握手](https://user-gold-cdn.xitu.io/2018/5/8/1633e14233d95972?w=542&h=427&f=jpeg&s=15088) + +- 客户端–发送带有 SYN 标志的数据包–一次握手–服务端 +- 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端 +- 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端 + +#### 为什么要三次握手 + +**三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。** + +第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常。 + +第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己接收正常,对方发送正常 + +第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送接收正常 + +所以三次握手就能确认双发收发功能都正常,缺一不可。 + +#### 为什么要传回 SYN +接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。 + +> SYN 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement[汉译:确认字符 ,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误。 ])消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。 + + +#### 传了 SYN,为啥还要传 ACK + +双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方(主动关闭方)到接收方(被动关闭方)的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。 + +![TCP四次挥手](https://user-gold-cdn.xitu.io/2018/5/8/1633e1676e2ac0a3?w=500&h=340&f=jpeg&s=13406) + +断开一个 TCP 连接则需要“四次挥手”: + +- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送 +- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号 +- 服务器-关闭与客户端的连接,发送一个FIN给客户端 +- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1 + + +#### 为什么要四次挥手 + +任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 + +举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。 + +上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891) + + + +## 5. IP地址与MAC地址的区别 + +参考:[https://blog.csdn.net/guoweimelon/article/details/50858597](https://blog.csdn.net/guoweimelon/article/details/50858597) + +IP地址是指互联网协议地址(Internet Protocol Address)IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。 + + + +MAC 地址又称为物理地址、硬件地址,用来定义网络设备的位置。网卡的物理地址通常是由网卡生产厂家写入网卡的,具有全球唯一性。MAC地址用于在网络中唯一标示一个网卡,一台电脑会有一或多个网卡,每个网卡都需要有一个唯一的MAC地址。 + +## 6. HTTP请求,响应报文格式 + + + +HTTP请求报文主要由请求行、请求头部、请求正文3部分组成 + +HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 + +详细内容可以参考:[https://blog.csdn.net/a19881029/article/details/14002273](https://blog.csdn.net/a19881029/article/details/14002273) + +## 7. 为什么要使用索引?索引这么多优点,为什么不对表中的每一个列创建一个索引呢?索引是如何提高查询速度的?说一下使用索引的注意事项?Mysql索引主要使用的两种数据结构?什么是覆盖索引? + +**为什么要使用索引?** + +1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 +2. 可以大大加快 数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因。 +3. 帮助服务器避免排序和临时表 +4. 将随机IO变为顺序IO +5. 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 + +**索引这么多优点,为什么不对表中的每一个列创建一个索引呢?** + +1. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 +2. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 +3. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 + +**索引是如何提高查询速度的?** + +将无序的数据变成相对有序的数据(就像查目录一样) + +**说一下使用索引的注意事项** + +1. 避免 where 子句中对字段施加函数,这会造成无法命中索引。 +2. 在使用InnoDB时使用与业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。 +3. 将打算加索引的列设置为 NOT NULL ,否则将导致引擎放弃使用索引而进行全表扫描 +4. 删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗 MySQL 5.7 可以通过查询 sys 库的 chema_unused_indexes 视图来查询哪些索引从未被使用 +5. 在使用 limit offset 查询缓慢时,可以借助索引来提高性能 + +**Mysql索引主要使用的哪两种数据结构?** + +- 哈希索引:对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。 +- BTree索引:Mysql的BTree索引使用的是B树中的B+Tree。但对于主要的两种存储引擎(MyISAM和InnoDB)的实现方式是不同的。 + +更多关于索引的内容可以查看我的这篇文章:[【思维导图-索引篇】搞定数据库索引就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484486&idx=1&sn=215450f11e042bca8a58eac9f4a97686&chksm=fd985227caefdb3117b8375f150676f5824aa20d1ebfdbcfb93ff06e23e26efbafae6cf6b48e&token=1990180468&lang=zh_CN#rd) + +**什么是覆盖索引?** + +如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称 +之为“覆盖索引”。我们知道在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次,这样就会比较慢。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作! + + +## 8. 进程与线程的区别是什么?进程间的几种通信方式说一下?线程间的几种通信方式知道不? + **进程与线程的区别是什么?** + +线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。另外,也正是因为共享资源,所以线程中执行时一般都要进行同步和互斥。总的来说,进程和线程的主要差别在于它们是不同的操作系统资源管理方式。 + +**进程间的几种通信方式说一下?** + + +1. **管道(pipe)**:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有血缘关系的进程间使用。进程的血缘关系通常指父子进程关系。管道分为pipe(无名管道)和fifo(命名管道)两种,有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间通信。 +2. **信号量(semophore)**:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它通常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 +3. **消息队列(message queue)**:消息队列是由消息组成的链表,存放在内核中 并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。 +4. **信号(signal)**:信号是一种比较复杂的通信方式,用于通知接收进程某一事件已经发生。 +5. **共享内存(shared memory)**:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问,共享内存是最快的IPC方式,它是针对其他进程间的通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信。 +6. **套接字(socket)**:socket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。也因为这样,套接字明确地将客户端和服务器区分开来。 + +**线程间的几种通信方式知道不?** + +1、锁机制 + +- 互斥锁:提供了以排它方式阻止数据结构被并发修改的方法。 +- 读写锁:允许多个线程同时读共享数据,而对写操作互斥。 +- 条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。 + +2、信号量机制:包括无名线程信号量与有名线程信号量 + +3、信号机制:类似于进程间的信号处理。 + +线程间通信的主要目的是用于线程同步,所以线程没有象进程通信中用于数据交换的通信机制。 + +## 9. 为什么要用单例模式?手写几种线程安全的单例模式? + +**简单来说使用单例模式可以带来下面几个好处:** + +- 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销; +- 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。 + +**懒汉式(双重检查加锁版本)** + +```java +public class Singleton { + + //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量 + private volatile static Singleton uniqueInstance; + private Singleton() { + } + public static Singleton getInstance() { + //检查实例,如果不存在,就进入同步代码块 + if (uniqueInstance == null) { + //只有第一次才彻底执行这里的代码 + synchronized(Singleton.class) { + //进入同步代码块后,再检查一次,如果仍是null,才创建实例 + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + } + } + return uniqueInstance; + } +} +``` + +**静态内部类方式** + +静态内部实现的单例是懒加载的且线程安全。 + +只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance(只有第一次使用这个单例的实例的时候才加载,同时不会有线程安全问题)。 + +```java +public class Singleton { + private static class SingletonHolder { + private static final Singleton INSTANCE = new Singleton(); + } + private Singleton (){} + public static final Singleton getInstance() { + return SingletonHolder.INSTANCE; + } +} +``` + +## 10. 简单介绍一下bean。知道Spring的bean的作用域与生命周期吗? + +在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。而 bean 的定义以及 bean 相互间的依赖关系将通过配置元数据来描述。 + +Spring中的bean默认都是单例的,这些单例Bean在多线程程序下如何保证线程安全呢? 例如对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Sevlet线程来处理请求,引入Spring框架之后,每个Action都是单例的,那么对于Spring托管的单例Service Bean,如何保证其安全呢? Spring的单例是基于BeanFactory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于 JVM,每个 JVM 内只有一个实例。 + +![pring的bean的作用域](https://user-gold-cdn.xitu.io/2018/11/10/166fd45773d5dd2e?w=563&h=299&f=webp&s=27930) + +Spring的bean的生命周期以及更多内容可以查看:[一文轻松搞懂Spring中bean的作用域与生命周期](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=2&sn=7201eb365102fce017f89cb3527fb0bc&chksm=fd985591caefdc872a2fac897288119f94c345e4e12150774f960bf5f816b79e4b9b46be3d7f&token=1990180468&lang=zh_CN#rd) + + +## 11. Spring 中的事务传播行为了解吗?TransactionDefinition 接口中哪五个表示隔离级别的常量? + +#### 事务传播行为 + +事务传播行为(为了解决业务层方法之间互相调用的事务问题): +当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量: + +**支持当前事务的情况:** + +- TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 +- TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 +- TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性) + +**不支持当前事务的情况:** + +- TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。 +- TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 +- TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。 + +**其他情况:** + +- TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。 + + +#### 隔离级别 + +TransactionDefinition 接口中定义了五个表示隔离级别的常量: + +- **TransactionDefinition.ISOLATION_DEFAULT:** 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别. +- **TransactionDefinition.ISOLATION_READ_UNCOMMITTED:** 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读 +- **TransactionDefinition.ISOLATION_READ_COMMITTED:** 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生 +- **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。 +- **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 + +## 12. SpringMVC 原理了解吗? + +![SpringMVC 原理](https://user-gold-cdn.xitu.io/2018/11/10/166fd45787394192?w=1015&h=466&f=webp&s=35352) + +客户端发送请求-> 前端控制器 DispatcherServlet 接受客户端请求 -> 找到处理器映射 HandlerMapping 解析请求对应的 Handler-> HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑 -> 处理器返回一个模型视图 ModelAndView -> 视图解析器进行解析 -> 返回一个视图对象->前端控制器 DispatcherServlet 渲染数据(Model)->将得到视图对象返回给用户 + +关于 SpringMVC 原理更多内容可以查看我的这篇文章:[SpringMVC 工作原理详解](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484496&idx=1&sn=5472ffa687fe4a05f8900d8ee6726de4&chksm=fd985231caefdb27fc75b44ecf76b6f43e4617e0b01b3c040f8b8fab32e51dfa5118eed1d6ad&token=1990180468&lang=zh_CN#rd) + +## 13. Spring AOP IOC 实现原理 + +过了秋招挺长一段时间了,说实话我自己也忘了如何简要概括 Spring AOP IOC 实现原理,就在网上找了一个较为简洁的答案,下面分享给各位。 + +**IOC:** 控制反转也叫依赖注入。IOC利用java反射机制,AOP利用代理模式。IOC 概念看似很抽象,但是很容易理解。说简单点就是将对象交给容器管理,你只需要在spring配置文件中配置对应的bean以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类。 + +**AOP:** 面向切面编程。(Aspect-Oriented Programming) 。AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理。 + + + +# 二 进阶篇 + +# 1 消息队列MQ的套路 + +消息队列/消息中间件应该是Java程序员必备的一个技能了,如果你之前没接触过消息队列的话,建议先去百度一下某某消息队列入门,然后花2个小时就差不多可以学会任何一种消息队列的使用了。如果说仅仅学会使用是万万不够的,在实际生产环境还要考虑消息丢失等等情况。关于消息队列面试相关的问题,推荐大家也可以看一下视频《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! + +### 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 + +面试官一般会先问你这个问题,预热一下,看你知道消息队列不,一般在第一面的时候面试官可能只会问消息队列MQ的应用场景/使用消息队列的好处、使用消息队列会带来什么问题、消息队列的技术选型这几个问题,不会太深究下去,在后面的第二轮/第三轮技术面试中可能会深入问一下。 + +**《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。** + +#### ①.通过异步处理提高系统性能 +![通过异步处理提高系统性能](https://user-gold-cdn.xitu.io/2018/4/21/162e63a8e34ba534?w=910&h=350&f=jpeg&s=29123) +如上图,**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。** + +通过以上分析我们可以得出**消息队列具有很好的削峰作用的功能**——即**通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。** 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示: +![合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击](https://user-gold-cdn.xitu.io/2018/4/21/162e64583dd3ed01?w=780&h=384&f=jpeg&s=13550) +因为**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**。因此使用消息队列进行异步处理之后,需要**适当修改业务流程进行配合**,比如**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**,以免交易纠纷。这就类似我们平时手机订火车票和电影票。 + +### ②.降低系统耦合性 +我们知道模块分布式部署以后聚合方式通常有两种:1.**分布式消息队列**和2.**分布式服务**。 + +> **先来简单说一下分布式服务:** + +目前使用比较多的用来构建**SOA(Service Oriented Architecture面向服务体系结构)**的**分布式服务框架**是阿里巴巴开源的**Dubbo**.如果想深入了解Dubbo的可以看我写的关于Dubbo的这一篇文章:**《高性能优秀的服务框架-dubbo介绍》**:[https://juejin.im/post/5acadeb1f265da2375072f9c](https://juejin.im/post/5acadeb1f265da2375072f9c) + +> **再来谈我们的分布式消息队列:** + +我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。 + +我们最常见的**事件驱动架构**类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示: +![利用消息队列实现事件驱动结构](https://user-gold-cdn.xitu.io/2018/4/21/162e6665fa394b3b?w=790&h=290&f=jpeg&s=14946) +**消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。** 从上图可以看到**消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合**,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。**对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计**。 + +消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。 + +**另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。** + +**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的,**比如在我们的ActiveMQ消息队列中还有点对点工作模式**,具体的会在后面的文章给大家详细介绍,这一篇文章主要还是让大家对消息队列有一个更透彻的了解。 + +> 这个问题一般会在上一个问题问完之后,紧接着被问到。“使用消息队列会带来什么问题?”这个问题要引起重视,一般我们都会考虑使用消息队列会带来的好处而忽略它带来的问题! + +### 1.2 那么使用消息队列会带来什么问题?考虑过这个问题吗? + +- **系统可用性降低:** 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了! +- **系统复杂性提高:** 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题! +- **一致性问题:** 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了! + +> 了解下面这个问题是为了我们更好的进行技术选型!该部分摘自:《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! + +### 1.3 介绍一下你知道哪几种消息队列,该如何选择呢? + + +| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafaka | +| :---------------------- | -----------------------------------------------------------: | -----------------------------------------------------------: | -----------------------------------------------------------: | -----------------------------------------------------------: | +| 单机吞吐量 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 | 10万级,RocketMQ也是可以支撑高吞吐的一种MQ | 10万级别,这是kafka最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景 | +| topic数量对吞吐量的影响 | | | topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic | topic从几十个到几百个的时候,吞吐量会大幅度下降。所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源 | +| 可用性 | 高,基于主从架构实现高可用性 | 高,基于主从架构实现高可用性 | 非常高,分布式架构 | 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 | +| 消息可靠性 | 有较低的概率丢失数据 | | 经过参数优化配置,可以做到0丢失 | 经过参数优化配置,消息可以做到0丢失 | +| 时效性 | ms级 | 微秒级,这是rabbitmq的一大特点,延迟是最低的 | ms级 | 延迟在ms级以内 | +| 功能支持 | MQ领域的功能极其完备 | 基于erlang开发,所以并发能力很强,性能极其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 | +| 优劣势总结 | 非常成熟,功能强大,在业内大量的公司以及项目中都有应用。偶尔会有较低概率丢失消息,而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用 | erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备而且开源提供的管理界面非常棒,用起来很好用。社区相对比较活跃,几乎每个月都发布几个版本分在国内一些互联网公司近几年用rabbitmq也比较多一些但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。而且erlang开发,国内有几个公司有实力做erlang源码级别的研究和定制?如果说你没这个实力的话,确实偶尔会有一些问题,你很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。而且rabbitmq集群动态扩展会很麻烦,不过这个我觉得还好。其实主要是erlang语言本身带来的问题。很难读源码,很难定制和掌控。 | 接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障。日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是ok的,还可以支撑大规模的topic数量,支持复杂MQ业务场景。而且一个很大的优势在于,阿里出品都是java系的,我们可以自己阅读源码,定制自己公司的MQ,可以掌控。社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准JMS规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ挺好的 | kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量。而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。 | + +> 这部分内容,我这里不给出答案,大家可以自行根据自己学习的消息队列查阅相关内容,我可能会在后面的文章中介绍到这部分内容。另外,下面这些问题在视频《Java工程师面试突击第1季-中华石杉老师》中都有提到,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! + +### 1.4 关于消息队列其他一些常见的问题展望 + +1. 引入消息队列之后如何保证高可用性 +2. 如何保证消息不被重复消费呢? +3. 如何保证消息的可靠性传输(如何处理消息丢失的问题)? +4. 我该怎么保证从消息队列里拿到的数据按顺序执行? +5. 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决? +6. 如果让你来开发一个消息队列中间件,你会怎么设计架构? + + + +## 2 谈谈 InnoDB 和 MyIsam 两者的区别 + +### 2.1 两者的对比 + +1) **count运算上的区别:** 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。 + +2) **是否支持事务和崩溃后的安全恢复:** MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 + +3)**是否支持外键:** MyISAM不支持,而InnoDB支持。 + + + +### 2.2 关于两者的总结 + +MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数据库做主从分离的情况下,经常选择MyISAM作为主库的存储引擎。 + +一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。如果你的数据量很大(MyISAM支持压缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM是最好的选择。 + + +## 3 聊聊 Java 中的集合吧! + + +### 3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容) + +- **1. 是否保证线程安全:** ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; +- **2. 底层数据结构:** Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(注意双向链表和双向循环链表的区别:); +- **3. 插入和删除是否受元素位置的影响:** ① **ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。** 比如:执行`add(E e) `方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element) `)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② **LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。** +- **4. 是否支持快速随机访问:** LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index) `方法)。 +- **5. 内存空间占用:** ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。 + +**补充内容:RandomAccess接口** + +```java +public interface RandomAccess { +} +``` + +查看源码我们发现实际上 RandomAccess 接口中什么都没有定义。所以,在我看来 RandomAccess 接口不过是一个标识罢了。标识什么? 标识实现这个接口的类具有随机访问功能。 + +在binarySearch()方法中,它要判断传入的list 是否RamdomAccess的实例,如果是,调用indexedBinarySearch()方法,如果不是,那么调用iteratorBinarySearch()方法 + +```java + public static + int binarySearch(List> list, T key) { + if (list instanceof RandomAccess || list.size() Java 中的集合这类问题几乎是面试必问的,问到这类问题的时候,HashMap 又是几乎必问的问题,所以大家一定要引起重视! + +### 3.2 HashMap的底层实现 + +#### ① JDK1.8之前 + +JDK1.8 之前 HashMap 底层是 **数组和链表** 结合在一起使用也就是 **链表散列**。**HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 `(n - 1) & hash` 判断当前元素存放的位置(这里的 n 指的时数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。** + +**所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。** + +**JDK 1.8 HashMap 的 hash 方法源码:** + +JDK 1.8 的 hash方法 相比于 JDK 1.7 hash 方法更加简化,但是原理不变。 + +```java + static final int hash(Object key) { + int h; + // key.hashCode():返回散列值也就是hashcode + // ^ :按位异或 + // >>>:无符号右移,忽略符号位,空位都以0补齐 + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + } +``` +对比一下 JDK1.7的 HashMap 的 hash 方法源码. + +```java +static int hash(int h) { + // This function ensures that hashCodes that differ only by + // constant multiples at each bit position have a bounded + // number of collisions (approximately 8 at default load factor). + + h ^= (h >>> 20) ^ (h >>> 12); + return h ^ (h >>> 7) ^ (h >>> 4); +} +``` + +相比于 JDK1.8 的 hash 方法 ,JDK 1.7 的 hash 方法的性能会稍差一点点,因为毕竟扰动了 4 次。 + +所谓 **“拉链法”** 就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。 + + + +![jdk1.8之前的内部结构](https://user-gold-cdn.xitu.io/2018/3/20/16240dbcc303d872?w=348&h=427&f=png&s=10991) + + +#### ② JDK1.8之后 + +相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。 + +![JDK1.8之后的HashMap底层数据结构](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c351da9?w=720&h=545&f=jpeg&s=23933) + +TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 + +> 问完 HashMap 的底层原理之后,面试官可能就会紧接着问你 HashMap 底层数据结构相关的问题! + +### 3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解 + +![红黑树](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c138cba?w=851&h=614&f=jpeg&s=34458) + +**红黑树特点:** + +1. 每个节点非红即黑; +2. 根节点总是黑色的; +3. 每个叶子节点都是黑色的空节点(NIL节点); +4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定); +5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度) + + +**红黑树的应用:** + +TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。 + +**为什么要用红黑树** + +简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 + + +### 3.4 红黑树这么优秀,为何不直接使用红黑树得了? + +说一下自己对于这个问题的看法:我们知道红黑树属于(自)平衡二叉树,但是为了保持“平衡”是需要付出代价的,红黑树在插入新数据后可能需要通过左旋,右旋、变色这些操作来保持平衡,这费事啊。你说说我们引入红黑树就是为了查找数据快,如果链表长度很短的话,根本不需要引入红黑树的,你引入之后还要付出代价维持它的平衡。但是链表过长就不一样了。至于为什么选 8 这个值呢?通过概率统计所得,这个值是综合查询成本和新增元素成本得出的最好的一个值。 + +### 3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别 + +**HashMap 和 Hashtable 的区别** + +1. **线程是否安全:** HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 `synchronized` 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!); +2. **效率:** 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它; +3. **对Null key 和Null value的支持:** HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。 +4. **初始容量大小和每次扩充容量大小的不同 :** ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小(HashMap 中的`tableSizeFor()`方法保证,下面给出了源代码)。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。 +5. **底层数据结构:** JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。 + +**HashSet 和 HashMap 区别** + +如果你看过 HashSet 源码的话就应该知道:HashSet 底层就是基于 HashMap 实现的。(HashSet 的源码非常非常少,因为除了 clone() 方法、writeObject()方法、readObject()方法是 HashSet 自己不得不实现之外,其他方法都是直接调用 HashMap 中的方法。) + +![HashSet 和 HashMap 区别](https://user-gold-cdn.xitu.io/2018/3/2/161e717d734f3b23?w=896&h=363&f=jpeg&s=205536) + +# 三 终结篇 + +## 1. Object类有哪些方法? + +这个问题,面试中经常出现。我觉得不论是出于应付面试还是说更好地掌握Java这门编程语言,大家都要掌握! + +### 1.1 Object类的常见方法总结 + +Object类是一个特殊的类,是所有类的父类。它主要提供了以下11个方法: + +```java + +public final native Class getClass()//native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。 + +public native int hashCode() //native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。 +public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。 + +protected native Object clone() throws CloneNotSupportedException//naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。 + +public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。 + +public final native void notify()//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。 + +public final native void notifyAll()//native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。 + +public final native void wait(long timeout) throws InterruptedException//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。 + +public final void wait(long timeout, int nanos) throws InterruptedException//多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。 + +public final void wait() throws InterruptedException//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念 + +protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作 + +``` + +> 问完上面这个问题之后,面试官很可能紧接着就会问你“hashCode与equals”相关的问题。 + +### 1.2 hashCode与equals + +面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” + +#### 1.2.1 hashCode()介绍 + +hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。 + +```java + public native int hashCode(); +``` + +散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象) + +#### 1.2.2 为什么要有hashCode + + +**我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:** + +当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。 + + +#### 1.2.3 hashCode()与equals()的相关规定 + +1. 如果两个对象相等,则hashcode一定也是相同的 +2. 两个对象相等,对两个对象分别调用equals方法都返回true +3. 两个对象有相同的hashcode值,它们也不一定是相等的 +4. **因此,equals方法被覆盖过,则hashCode方法也必须被覆盖** +5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据) + +#### 1.2.4 为什么两个对象有相同的hashcode值,它们也不一定是相等的? + +在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 + +因为hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。 + +我们刚刚也提到了 HashSet,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。 + +> ==与equals 的对比也是比较常问的基础问题之一! + +### 1.3 ==与equals + +**==** : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) + +**equals()** : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: + +- 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。 +- 情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。 + + +**举个例子:** + +```java +public class test1 { + public static void main(String[] args) { + String a = new String("ab"); // a 为一个引用 + String b = new String("ab"); // b为另一个引用,对象的内容一样 + String aa = "ab"; // 放在常量池中 + String bb = "ab"; // 从常量池中查找 + if (aa == bb) // true + System.out.println("aa==bb"); + if (a == b) // false,非同一对象 + System.out.println("a==b"); + if (a.equals(b)) // true + System.out.println("aEQb"); + if (42 == 42.0) { // true + System.out.println("true"); + } + } +} +``` + +**说明:** + +- String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。 +- 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。 + +> 在[【备战春招/秋招系列5】美团面经总结进阶篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484625&idx=1&sn=9c4fa1f7d4291a5fbd7daa44bac2b012&chksm=fd9852b0caefdba6edcf9a827aa4a17ddc97bf6ad2e5ee6f7e1aa1b443b54444d05d2b76732b&token=723699735&lang=zh_CN#rd) 这篇文章中,我们已经提到了一下关于 HashMap 在面试中常见的问题:HashMap 的底层实现、简单讲一下自己对于红黑树的理解、红黑树这么优秀,为何不直接使用红黑树得了、HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别。HashMap 和 ConcurrentHashMap 这俩兄弟在一般只要面试中问到集合相关的问题就一定会被问到,所以各位务必引起重视! + +## 2 ConcurrentHashMap 相关问题 + +### 2.1 ConcurrentHashMap 和 Hashtable 的区别 + +ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。 + +- **底层数据结构:** JDK1.7的 ConcurrentHashMap 底层采用 **分段的数组+链表** 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 **数组+链表** 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的; +- **实现线程安全的方式(重要):** ① **在JDK1.7的时候,ConcurrentHashMap(分段锁)** 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16个Segment,比Hashtable效率提高16倍。) **到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化)** 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② **Hashtable(同一把锁)** :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。 + +**两者的对比图:** + +图片来源:http://www.cnblogs.com/chengxiao/p/6842045.html + +HashTable: +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/50656681.jpg) + +JDK1.7的ConcurrentHashMap: +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/33120488.jpg) +JDK1.8的ConcurrentHashMap(TreeBin: 红黑二叉树节点 +Node: 链表节点): +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-22/97739220.jpg) + +### 2.2 ConcurrentHashMap线程安全的具体实现方式/底层具体实现 + +#### JDK1.7(上面有示意图) + +首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。 + +**ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成**。 + +Segment 实现了 ReentrantLock,所以 Segment 是一种可重入锁,扮演锁的角色。HashEntry 用于存储键值对数据。 + +```java +static class Segment extends ReentrantLock implements Serializable { +} +``` + +一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护着一个HashEntry数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment的锁。 + +#### JDK1.8 (上面有示意图) + +ConcurrentHashMap取消了Segment分段锁,采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。 + +synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。 + +## 3 谈谈 synchronized 和 ReenTrantLock 的区别 + +**① 两者都是可重入锁** + +两者都是可重入锁。“可重入锁”概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。 + +**② synchronized 依赖于 JVM 而 ReenTrantLock 依赖于 API** + +synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。ReenTrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock 方法配合 try/finally 语句块来完成),所以我们可以通过查看它的源代码,来看它是如何实现的。 + +**③ ReenTrantLock 比 synchronized 增加了一些高级功能** + +相比synchronized,ReenTrantLock增加了一些高级功能。主要来说主要有三点:**①等待可中断;②可实现公平锁;③可实现选择性通知(锁可以绑定多个条件)** + +- **ReenTrantLock提供了一种能够中断等待锁的线程的机制**,通过lock.lockInterruptibly()来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。 +- **ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。** ReenTrantLock默认情况是非公平的,可以通过 ReenTrantLock类的`ReentrantLock(boolean fair)`构造方法来制定是否是公平的。 +- synchronized关键字与wait()和notify/notifyAll()方法相结合可以实现等待/通知机制,ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition() 方法。Condition是JDK1.5之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),**线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的,用ReentrantLock类结合Condition实例可以实现“选择性通知”** ,这个功能非常重要,而且是Condition接口默认提供的。而synchronized关键字就相当于整个Lock对象中只有一个Condition实例,所有的线程都注册在它一个身上。如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法 只会唤醒注册在该Condition实例中的所有等待线程。 + +如果你想使用上述功能,那么选择ReenTrantLock是一个不错的选择。 + +**④ 两者的性能已经相差无几** + +在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具体表示为:synchronized 关键字吞吐量岁线程数的增加,下降得非常严重。而ReenTrantLock 基本保持一个比较稳定的水平。我觉得这也侧面反映了, synchronized 关键字还有非常大的优化余地。后续的技术发展也证明了这一点,我们上面也讲了在 JDK1.6 之后 JVM 团队对 synchronized 关键字做了很多优化。JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以网上那些说因为性能才选择 ReenTrantLock 的文章都是错的!JDK1.6之后,性能已经不是选择synchronized和ReenTrantLock的影响因素了!而且虚拟机在未来的性能改进中会更偏向于原生的synchronized,所以还是提倡在synchronized能满足你的需求的情况下,优先考虑使用synchronized关键字来进行同步!优化后的synchronized和ReenTrantLock一样,在很多地方都是用到了CAS操作。 + + +## 4 线程池了解吗? + + +### 4.1 为什么要用线程池? + +线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。 + +这里借用《Java并发编程的艺术》提到的来说一下使用线程池的好处: + +- **降低资源消耗。** 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 +- **提高响应速度。** 当任务到达时,任务可以不需要的等到线程创建就能立即执行。 +- **提高线程的可管理性。** 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 + +### 4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么? + +#### Java 主要提供了下面4种线程池 + +- **FixedThreadPool:** 该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。 +- **SingleThreadExecutor:** 方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。 +- **CachedThreadPool:** 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。 +- **ScheduledThreadPoolExecutor:** 主要用来在给定的延迟后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor又分为:ScheduledThreadPoolExecutor(包含多个线程)和SingleThreadScheduledExecutor (只包含一个线程)两种。 + +#### 各种线程池的适用场景介绍 + +- **FixedThreadPool:** 适用于为了满足资源管理需求,而需要限制当前线程数量的应用场景。它适用于负载比较重的服务器; +- **SingleThreadExecutor:** 适用于需要保证顺序地执行各个任务并且在任意时间点,不会有多个线程是活动的应用场景。 +- **CachedThreadPool:** 适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器; +- **ScheduledThreadPoolExecutor:** 适用于需要多个后台执行周期任务,同时为了满足资源管理需求而需要限制后台线程的数量的应用场景, +- **SingleThreadScheduledExecutor:** 适用于需要单个后台线程执行周期任务,同时保证顺序地执行各个任务的应用场景。 + +### 4.3 创建的线程池的方式 + +**(1) 使用 Executors 创建** + +我们上面刚刚提到了 Java 提供的几种线程池,通过 Executors 工具类我们可以很轻松的创建我们上面说的几种线程池。但是实际上我们一般都不是直接使用Java提供好的线程池,另外在《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 构造函数 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 + +```java +Executors 返回线程池对象的弊端如下: + +FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。 +CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。 + +``` +**(2) ThreadPoolExecutor的构造函数创建** + + +我们可以自己直接调用 ThreadPoolExecutor 的构造函数来自己创建线程池。在创建的同时,给 BlockQueue 指定容量就可以了。示例如下: + +```java +private static ExecutorService executor = new ThreadPoolExecutor(13, 13, + 60L, TimeUnit.SECONDS, + new ArrayBlockingQueue(13)); +``` + +这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列,队列已经满了便无法继续处理新的请求。但是异常(Exception)总比发生错误(Error)要好。 + +**(3) 使用开源类库** + +Hollis 大佬之前在他的文章中也提到了:“除了自己定义ThreadPoolExecutor外。还有其他方法。这个时候第一时间就应该想到开源类库,如apache和guava等。”他推荐使用guava提供的ThreadFactoryBuilder来创建线程池。下面是参考他的代码示例: + +```java +public class ExecutorsDemo { + + private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("demo-pool-%d").build(); + + private static ExecutorService pool = new ThreadPoolExecutor(5, 200, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); + + public static void main(String[] args) { + + for (int i = 0; i < Integer.MAX_VALUE; i++) { + pool.execute(new SubThread()); + } + } +} +``` + +通过上述方式创建线程时,不仅可以避免OOM的问题,还可以自定义线程名称,更加方便的出错的时候溯源。 + +## 5 Nginx + +### 5.1 简单介绍一下Nginx + +Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。 Nginx 主要提供反向代理、负载均衡、动静分离(静态资源服务)等服务。下面我简单地介绍一下这些名词。 + +#### 反向代理 + +谈到反向代理,就不得不提一下正向代理。无论是正向代理,还是反向代理,说到底,就是代理模式的衍生版本罢了 + +- **正向代理:**某些情况下,代理我们用户去访问服务器,需要用户手动的设置代理服务器的ip和端口号。正向代理比较常见的一个例子就是 VPN了。 +- **反向代理:** 是用来代理服务器的,代理我们要访问的目标服务器。代理服务器接受请求,然后将请求转发给内部网络的服务器,并将从服务器上得到的结果返回给客户端,此时代理服务器对外就表现为一个服务器。 + +通过下面两幅图,大家应该更好理解(图源:http://blog.720ui.com/2016/nginx_action_05_proxy/): + +![正向代理](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-15/60925795.jpg) + +![反向代理](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-15/62563930.jpg) + +所以,简单的理解,就是正向代理是为客户端做代理,代替客户端去访问服务器,而反向代理是为服务器做代理,代替服务器接受客户端请求。 + +#### 负载均衡 + +在高并发情况下需要使用,其原理就是将并发请求分摊到多个服务器执行,减轻每台服务器的压力,多台服务器(集群)共同完成工作任务,从而提高了数据的吞吐量。 + +Nginx支持的weight轮询(默认)、ip_hash、fair、url_hash这四种负载均衡调度算法,感兴趣的可以自行查阅。 + +负载均衡相比于反向代理更侧重的时将请求分担到多台服务器上去,所以谈论负载均衡只有在提供某服务的服务器大于两台时才有意义。 + +#### 动静分离 + +动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。 + +### 5.2 为什么要用 Nginx ? + +> 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 + +如果面试官问你这个问题,就一定想看你知道 Nginx 服务器的一些优点吗。 + +Nginx 有以下5个优点: + +1. 高并发、高性能(这是其他web服务器不具有的) +2. 可扩展性好(模块化设计,第三方插件生态圈丰富) +3. 高可靠性(可以在服务器行持续不间断的运行数年) +4. 热部署(这个功能对于 Nginx 来说特别重要,热部署指可以在不停止 Nginx服务的情况下升级 Nginx) +5. BSD许可证(意味着我们可以将源代码下载下来进行修改然后使用自己的版本) + +### 5.3 Nginx 的四个主要组成部分了解吗? + +> 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 + +- Nginx 二进制可执行文件:由各模块源码编译出一个文件 +- Nginx.conf 配置文件:控制Nginx 行为 +- acess.log 访问日志: 记录每一条HTTP请求信息 +- error.log 错误日志:定位问题 \ No newline at end of file From 7deb559af6d58a389cf8fa5957294b2d189cb1d6 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:38:41 +0800 Subject: [PATCH 027/232] Update README.md --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 997b447370a..f87f10a04e5 100644 --- a/README.md +++ b/README.md @@ -163,15 +163,13 @@ ## :musical_note: 面试必备 -### 备战春招/秋招系列 - -* [【备战春招/秋招系列1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) -* [手把手教你用Markdown写一份高质量的简历](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/手把手教你用Markdown写一份高质量的简历.md) -* [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) -* [【备战春招/秋招系列3】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) -* [【备战春招/秋招系列4】美团面经总结基础篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-基础篇.md) -* [【备战春招/秋招系列5】美团面经总结进阶篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-进阶篇.md) -* [【备战春招/秋招系列5】美团面经总结终结篇篇 (附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团-终结篇.md) +### 备战面试 + +* [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) +* [【备战面试3】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) +* [【备战面试4】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团面试常见问题总结.md) + ### 最最最常见的Java面试题总结 From ad574052d4b262cc5e2c48bb58ed6bba0280f9fb Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:39:29 +0800 Subject: [PATCH 028/232] =?UTF-8?q?Update=20=E5=A4=87=E6=88=98=E6=98=A5?= =?UTF-8?q?=E6=8B=9B/=E7=A7=8B=E6=8B=9B->=E5=A4=87=E6=88=98=E9=9D=A2?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f87f10a04e5..9279f332620 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ * [Redis](#redis) * [:punch: 架构](#punch-架构) * [:musical_note: 面试必备](#musical_note-面试必备) - * [备战春招/秋招系列](#备战春招秋招系列) + * [备战面试](#备战面试) * [最最最常见的Java面试题总结](#最最最常见的java面试题总结) * [Java学习/面试开源仓库推荐](#java学习面试开源仓库推荐) * [:art: 闲谈](#art-闲谈) From 9c7ab2d6846d839310fe498db9a3abc870330006 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:51:36 +0800 Subject: [PATCH 029/232] =?UTF-8?q?Fix=20=E6=A0=87=E9=A2=98=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E9=93=BE=E6=8E=A5=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...56\351\242\230\346\200\273\347\273\223.md" | 145 +++++++++++++----- 1 file changed, 107 insertions(+), 38 deletions(-) diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/\351\235\242\350\257\225\345\277\205\345\244\207/\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 8f8cfd9756f..c32e2a0a3dd 100644 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/\351\235\242\350\257\225\345\277\205\345\244\207/\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,9 +1,82 @@ + + +- [一 基础篇](#一-基础篇) + - [1. `System.out.println(3|9)`输出什么?](#1-systemoutprintln3|9输出什么?) + - [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-的四个主要组成部分了解吗) + + + + 这些问题是2018年去美团面试的同学被问到的一些常见的问题,希望对你有帮助! # 一 基础篇 -## 1. `System.out.println(3 | 9);`输出什么? +## 1. `System.out.println(3|9)`输出什么? 正确答案:11. @@ -140,7 +213,7 @@ HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 详细内容可以参考:[https://blog.csdn.net/a19881029/article/details/14002273](https://blog.csdn.net/a19881029/article/details/14002273) -## 7. 为什么要使用索引?索引这么多优点,为什么不对表中的每一个列创建一个索引呢?索引是如何提高查询速度的?说一下使用索引的注意事项?Mysql索引主要使用的两种数据结构?什么是覆盖索引? +## 7. 为什么要使用索引?索引这么多优点,为什么不对表中的每一个列创建一个索引呢?索引是如何提高查询速度的?说一下使用索引的注意事项?Mysql索引主要使用的两种数据结构?什么是覆盖索引? **为什么要使用索引?** @@ -181,7 +254,7 @@ HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 之为“覆盖索引”。我们知道在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次,这样就会比较慢。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作! -## 8. 进程与线程的区别是什么?进程间的几种通信方式说一下?线程间的几种通信方式知道不? +## 8. 进程与线程的区别是什么?进程间的几种通信方式说一下?线程间的几种通信方式知道不? **进程与线程的区别是什么?** 线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。另外,也正是因为共享资源,所以线程中执行时一般都要进行同步和互斥。总的来说,进程和线程的主要差别在于它们是不同的操作系统资源管理方式。 @@ -210,7 +283,7 @@ HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 线程间通信的主要目的是用于线程同步,所以线程没有象进程通信中用于数据交换的通信机制。 -## 9. 为什么要用单例模式?手写几种线程安全的单例模式? +## 9. 为什么要用单例模式?手写几种线程安全的单例模式? **简单来说使用单例模式可以带来下面几个好处:** @@ -260,7 +333,7 @@ public class Singleton { } ``` -## 10. 简单介绍一下bean。知道Spring的bean的作用域与生命周期吗? +## 10. 简单介绍一下bean;知道Spring的bean的作用域与生命周期吗? 在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。而 bean 的定义以及 bean 相互间的依赖关系将通过配置元数据来描述。 @@ -271,7 +344,7 @@ Spring中的bean默认都是单例的,这些单例Bean在多线程程序下如 Spring的bean的生命周期以及更多内容可以查看:[一文轻松搞懂Spring中bean的作用域与生命周期](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=2&sn=7201eb365102fce017f89cb3527fb0bc&chksm=fd985591caefdc872a2fac897288119f94c345e4e12150774f960bf5f816b79e4b9b46be3d7f&token=1990180468&lang=zh_CN#rd) -## 11. Spring 中的事务传播行为了解吗?TransactionDefinition 接口中哪五个表示隔离级别的常量? +## 11. Spring 中的事务传播行为了解吗?TransactionDefinition 接口中哪五个表示隔离级别的常量? #### 事务传播行为 @@ -305,7 +378,7 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: - **TransactionDefinition.ISOLATION_REPEATABLE_READ:** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。 - **TransactionDefinition.ISOLATION_SERIALIZABLE:** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 -## 12. SpringMVC 原理了解吗? +## 12. SpringMVC 原理了解吗? ![SpringMVC 原理](https://user-gold-cdn.xitu.io/2018/11/10/166fd45787394192?w=1015&h=466&f=webp&s=35352) @@ -325,17 +398,17 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: # 二 进阶篇 -# 1 消息队列MQ的套路 +## 1 消息队列MQ的套路 消息队列/消息中间件应该是Java程序员必备的一个技能了,如果你之前没接触过消息队列的话,建议先去百度一下某某消息队列入门,然后花2个小时就差不多可以学会任何一种消息队列的使用了。如果说仅仅学会使用是万万不够的,在实际生产环境还要考虑消息丢失等等情况。关于消息队列面试相关的问题,推荐大家也可以看一下视频《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! -### 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 +### 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 面试官一般会先问你这个问题,预热一下,看你知道消息队列不,一般在第一面的时候面试官可能只会问消息队列MQ的应用场景/使用消息队列的好处、使用消息队列会带来什么问题、消息队列的技术选型这几个问题,不会太深究下去,在后面的第二轮/第三轮技术面试中可能会深入问一下。 **《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。** -#### ①.通过异步处理提高系统性能 +#### 1)通过异步处理提高系统性能 ![通过异步处理提高系统性能](https://user-gold-cdn.xitu.io/2018/4/21/162e63a8e34ba534?w=910&h=350&f=jpeg&s=29123) 如上图,**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。** @@ -343,7 +416,7 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: ![合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击](https://user-gold-cdn.xitu.io/2018/4/21/162e64583dd3ed01?w=780&h=384&f=jpeg&s=13550) 因为**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**。因此使用消息队列进行异步处理之后,需要**适当修改业务流程进行配合**,比如**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**,以免交易纠纷。这就类似我们平时手机订火车票和电影票。 -### ②.降低系统耦合性 +#### 2)降低系统耦合性 我们知道模块分布式部署以后聚合方式通常有两种:1.**分布式消息队列**和2.**分布式服务**。 > **先来简单说一下分布式服务:** @@ -366,7 +439,7 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: > 这个问题一般会在上一个问题问完之后,紧接着被问到。“使用消息队列会带来什么问题?”这个问题要引起重视,一般我们都会考虑使用消息队列会带来的好处而忽略它带来的问题! -### 1.2 那么使用消息队列会带来什么问题?考虑过这个问题吗? +### 1.2 那么使用消息队列会带来什么问题?考虑过这些问题吗? - **系统可用性降低:** 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了! - **系统复杂性提高:** 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题! @@ -374,7 +447,7 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: > 了解下面这个问题是为了我们更好的进行技术选型!该部分摘自:《Java工程师面试突击第1季-中华石杉老师》,如果大家没有资源的话,可以在我的公众号“Java面试通关手册”后台回复关键字“1”即可! -### 1.3 介绍一下你知道哪几种消息队列,该如何选择呢? +### 1.3 介绍一下你知道哪几种消息队列,该如何选择呢? | 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafaka | @@ -404,12 +477,9 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量: ### 2.1 两者的对比 -1) **count运算上的区别:** 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。 - -2) **是否支持事务和崩溃后的安全恢复:** MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 - -3)**是否支持外键:** MyISAM不支持,而InnoDB支持。 - +1. **count运算上的区别:** 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存 +2. **是否支持事务和崩溃后的安全恢复:** MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 +3. **是否支持外键:** MyISAM不支持,而InnoDB支持。 ### 2.2 关于两者的总结 @@ -421,8 +491,7 @@ MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数 ## 3 聊聊 Java 中的集合吧! - -### 3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容) +### 3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容) - **1. 是否保证线程安全:** ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; - **2. 底层数据结构:** Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(注意双向链表和双向循环链表的区别:); @@ -464,7 +533,7 @@ ArraysList 实现了 RandomAccess 接口, 而 LinkedList 没有实现。为什 ### 3.2 HashMap的底层实现 -#### ① JDK1.8之前 +#### 1)JDK1.8之前 JDK1.8 之前 HashMap 底层是 **数组和链表** 结合在一起使用也就是 **链表散列**。**HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 `(n - 1) & hash` 判断当前元素存放的位置(这里的 n 指的时数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。** @@ -505,7 +574,7 @@ static int hash(int h) { ![jdk1.8之前的内部结构](https://user-gold-cdn.xitu.io/2018/3/20/16240dbcc303d872?w=348&h=427&f=png&s=10991) -#### ② JDK1.8之后 +#### 2)JDK1.8之后 相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。 @@ -515,7 +584,7 @@ TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红 > 问完 HashMap 的底层原理之后,面试官可能就会紧接着问你 HashMap 底层数据结构相关的问题! -### 3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解 +### 3.3 既然谈到了红黑树,你给我手绘一个出来吧,然后简单讲一下自己对于红黑树的理解 ![红黑树](https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c138cba?w=851&h=614&f=jpeg&s=34458) @@ -537,11 +606,11 @@ TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。 简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。 -### 3.4 红黑树这么优秀,为何不直接使用红黑树得了? +### 3.4 红黑树这么优秀,为何不直接使用红黑树得了? 说一下自己对于这个问题的看法:我们知道红黑树属于(自)平衡二叉树,但是为了保持“平衡”是需要付出代价的,红黑树在插入新数据后可能需要通过左旋,右旋、变色这些操作来保持平衡,这费事啊。你说说我们引入红黑树就是为了查找数据快,如果链表长度很短的话,根本不需要引入红黑树的,你引入之后还要付出代价维持它的平衡。但是链表过长就不一样了。至于为什么选 8 这个值呢?通过概率统计所得,这个值是综合查询成本和新增元素成本得出的最好的一个值。 -### 3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别 +### 3.5 HashMap 和 Hashtable 的区别/HashSet 和 HashMap 区别 **HashMap 和 Hashtable 的区别** @@ -598,7 +667,7 @@ protected void finalize() throws Throwable { }//实例被垃圾回收器回收 面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” -#### 1.2.1 hashCode()介绍 +#### 1.2.1 hashCode()介绍 hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。 @@ -616,7 +685,7 @@ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返 当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。 -#### 1.2.3 hashCode()与equals()的相关规定 +#### 1.2.3 hashCode()与equals()的相关规定 1. 如果两个对象相等,则hashcode一定也是相同的 2. 两个对象相等,对两个对象分别调用equals方法都返回true @@ -624,7 +693,7 @@ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返 4. **因此,equals方法被覆盖过,则hashCode方法也必须被覆盖** 5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据) -#### 1.2.4 为什么两个对象有相同的hashcode值,它们也不一定是相等的? +#### 1.2.4 为什么两个对象有相同的hashcode值,它们也不一定是相等的? 在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 @@ -675,7 +744,7 @@ public class test1 { ## 2 ConcurrentHashMap 相关问题 -### 2.1 ConcurrentHashMap 和 Hashtable 的区别 +### 2.1 ConcurrentHashMap 和 Hashtable 的区别 ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。 @@ -697,7 +766,7 @@ Node: 链表节点): ### 2.2 ConcurrentHashMap线程安全的具体实现方式/底层具体实现 -#### JDK1.7(上面有示意图) +#### JDK1.7(上面有示意图) 首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。 @@ -712,7 +781,7 @@ static class Segment extends ReentrantLock implements Serializable { 一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护着一个HashEntry数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment的锁。 -#### JDK1.8 (上面有示意图) +#### JDK1.8(上面有示意图) ConcurrentHashMap取消了Segment分段锁,采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。 @@ -743,10 +812,10 @@ synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团 在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具体表示为:synchronized 关键字吞吐量岁线程数的增加,下降得非常严重。而ReenTrantLock 基本保持一个比较稳定的水平。我觉得这也侧面反映了, synchronized 关键字还有非常大的优化余地。后续的技术发展也证明了这一点,我们上面也讲了在 JDK1.6 之后 JVM 团队对 synchronized 关键字做了很多优化。JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以网上那些说因为性能才选择 ReenTrantLock 的文章都是错的!JDK1.6之后,性能已经不是选择synchronized和ReenTrantLock的影响因素了!而且虚拟机在未来的性能改进中会更偏向于原生的synchronized,所以还是提倡在synchronized能满足你的需求的情况下,优先考虑使用synchronized关键字来进行同步!优化后的synchronized和ReenTrantLock一样,在很多地方都是用到了CAS操作。 -## 4 线程池了解吗? +## 4 线程池了解吗? -### 4.1 为什么要用线程池? +### 4.1 为什么要用线程池? 线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。 @@ -756,7 +825,7 @@ synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团 - **提高响应速度。** 当任务到达时,任务可以不需要的等到线程创建就能立即执行。 - **提高线程的可管理性。** 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 -### 4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么? +### 4.2 Java 提供了哪几种线程池?他们各自的使用场景是什么? #### Java 主要提供了下面4种线程池 @@ -857,7 +926,7 @@ Nginx支持的weight轮询(默认)、ip_hash、fair、url_hash这四种负 动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。 -### 5.2 为什么要用 Nginx ? +### 5.2 为什么要用 Nginx? > 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 @@ -871,11 +940,11 @@ Nginx 有以下5个优点: 4. 热部署(这个功能对于 Nginx 来说特别重要,热部署指可以在不停止 Nginx服务的情况下升级 Nginx) 5. BSD许可证(意味着我们可以将源代码下载下来进行修改然后使用自己的版本) -### 5.3 Nginx 的四个主要组成部分了解吗? +### 5.3 Nginx 的四个主要组成部分了解吗? > 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 - Nginx 二进制可执行文件:由各模块源码编译出一个文件 - Nginx.conf 配置文件:控制Nginx 行为 - acess.log 访问日志: 记录每一条HTTP请求信息 -- error.log 错误日志:定位问题 \ No newline at end of file +- error.log 错误日志:定位问题 From 9cfb647a25ecd8bf85e6a7ceb01e73964f6f58f7 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:54:51 +0800 Subject: [PATCH 030/232] =?UTF-8?q?Fix=20=E7=9B=AE=E5=BD=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...351\227\256\351\242\230\346\200\273\347\273\223.md" | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/\351\235\242\350\257\225\345\277\205\345\244\207/\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 c32e2a0a3dd..422d9402f12 100644 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/\351\235\242\350\257\225\345\277\205\345\244\207/\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,7 +1,7 @@ - [一 基础篇](#一-基础篇) - - [1. `System.out.println(3|9)`输出什么?](#1-systemoutprintln3|9输出什么?) + - [1. `System.out.println(3|9)`输出什么?](#1-systemoutprintln39输出什么) - [2. 说一下转发\(Forward\)和重定向\(Redirect\)的区别](#2-说一下转发forward和重定向redirect的区别) - [3. 在浏览器中输入url地址到显示主页的过程,整个过程会使用哪些协议](#3-在浏览器中输入url地址到显示主页的过程整个过程会使用哪些协议) - [4. TCP 三次握手和四次挥手](#4-tcp-三次握手和四次挥手) @@ -31,7 +31,7 @@ - [2 谈谈 InnoDB 和 MyIsam 两者的区别](#2-谈谈-innodb-和-myisam-两者的区别) - [2.1 两者的对比](#21-两者的对比) - [2.2 关于两者的总结](#22-关于两者的总结) - - [3 聊聊 Java 中的集合吧!](#3-聊聊-java-中的集合吧!) + - [3 聊聊 Java 中的集合吧!](#3-聊聊-java-中的集合吧) - [3.1 Arraylist 与 LinkedList 有什么不同?\(注意加上从数据结构分析的内容\)](#31-arraylist-与-linkedlist-有什么不同注意加上从数据结构分析的内容) - [3.2 HashMap的底层实现](#32-hashmap的底层实现) - [1)JDK1.8之前](#1jdk18之前) @@ -76,7 +76,7 @@ # 一 基础篇 -## 1. `System.out.println(3|9)`输出什么? +## 1. `System.out.println(3|9)`输出什么? 正确答案:11. @@ -489,7 +489,7 @@ MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数 一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。如果你的数据量很大(MyISAM支持压缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM是最好的选择。 -## 3 聊聊 Java 中的集合吧! +## 3 聊聊 Java 中的集合吧! ### 3.1 Arraylist 与 LinkedList 有什么不同?(注意加上从数据结构分析的内容) @@ -940,7 +940,7 @@ Nginx 有以下5个优点: 4. 热部署(这个功能对于 Nginx 来说特别重要,热部署指可以在不停止 Nginx服务的情况下升级 Nginx) 5. BSD许可证(意味着我们可以将源代码下载下来进行修改然后使用自己的版本) -### 5.3 Nginx 的四个主要组成部分了解吗? +### 5.3 Nginx 的四个主要组成部分了解吗? > 这部分内容参考极客时间—[Nginx核心知识100讲的内容](https://time.geekbang.org/course/intro/138?code=AycjiiQk6uQRxnVJzBupFkrGkvZlmYELPRsZbWzaAHE=)。 From bf96c8a593d931a94571130ac98cf023ff0e04a8 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:57:47 +0800 Subject: [PATCH 031/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9279f332620..3affa224314 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Java 学习/面试指南 -**一些常用资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** +**一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 From 3c17922707529b9e59b79871ff2e0ace1c0871b2 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 3 Mar 2019 16:59:00 +0800 Subject: [PATCH 032/232] Update README.md From f56c73b23af59baa7ef28b2eeed5b7ca175347b9 Mon Sep 17 00:00:00 2001 From: Silverados <295843706@qq.com> Date: Mon, 4 Mar 2019 00:38:43 +0800 Subject: [PATCH 033/232] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" "b/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" index 18587f42392..18d276c4e22 100644 --- "a/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" +++ "b/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" @@ -32,7 +32,7 @@ - **3. 插入和删除是否受元素位置的影响:** ① **ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。** 比如:执行`add(E e) `方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element) `)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② **LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。** - **4. 是否支持快速随机访问:** LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index) `方法)。 - **5. 内存空间占用:** ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。 --**6.补充内容:RandomAccess接口** +- **6.补充内容:RandomAccess接口** ```java public interface RandomAccess { From 89b0adba149ac7ea4d552b6fd429adcf0e194e72 Mon Sep 17 00:00:00 2001 From: Stage <1196089730@qq.com> Date: Mon, 4 Mar 2019 09:51:57 +0800 Subject: [PATCH 034/232] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E6=8B=BC=E5=86=99?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Servlet生命周期处,destroy拼写错误。 --- .../J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" index 00e67f7d779..ced017ab47b 100644 --- "a/Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -61,7 +61,7 @@ Servlet接口定义了5个方法,其中**前三个方法与Servlet生命周期 - java.lang.String getServletInfo() - ServletConfig getServletConfig() -**生命周期:** **Web容器加载Servlet并将其实例化后,Servlet生命周期开始**,容器运行其**init()方法**进行Servlet的初始化;请求到达时调用Servlet的**service()方法**,service()方法会根据需要调用与请求对应的**doGet或doPost**等方法;当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的**destroy()方法**。**init方法和destory方法只会执行一次,service方法客户端每次请求Servlet都会执行**。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。 +**生命周期:** **Web容器加载Servlet并将其实例化后,Servlet生命周期开始**,容器运行其**init()方法**进行Servlet的初始化;请求到达时调用Servlet的**service()方法**,service()方法会根据需要调用与请求对应的**doGet或doPost**等方法;当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的**destroy()方法**。**init方法和destroy方法只会执行一次,service方法客户端每次请求Servlet都会执行**。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。 参考:《javaweb整合开发王者归来》P81 From c7693078b8e2bf9fbde20621e1df8ac360d2388c Mon Sep 17 00:00:00 2001 From: Charles Wu Date: Mon, 4 Mar 2019 10:05:51 +0800 Subject: [PATCH 035/232] fix typo --- ...\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index 4f38f3a1261..5235ba73159 100644 --- "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -235,7 +235,7 @@ JDK1.4中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通 **验证:** ```java - String s1 = new String("abc");// 堆内存的地值值 + String s1 = new String("abc");// 堆内存的地址值 String s2 = "abc"; System.out.println(s1 == s2);// 输出false,因为一个是堆内存,一个是常量池的内存,故两者是不同的。 System.out.println(s1.equals(s2));// 输出true From 06c726d78cfc86176c49659d72e0c3ab40063ad6 Mon Sep 17 00:00:00 2001 From: tangtao Date: Mon, 4 Mar 2019 10:06:22 +0800 Subject: [PATCH 036/232] =?UTF-8?q?FIX:=20=E4=BF=AE=E5=A4=8D=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" index 79a03d391d8..8dddb1b9f4b 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" @@ -499,7 +499,7 @@ public class DesDemo { - **这种算法是在DES算法的基础上发展出来的,类似于三重DES。** - **发展IDEA也是因为感到DES具有密钥太短等缺点。** -- **DEA的密钥为128位,这么长的密钥在今后若干年内应该是安全的。** +- **IDEA的密钥为128位,这么长的密钥在今后若干年内应该是安全的。** - **在实际项目中用到的很少了解即可。** #### 代码实现: From 1f949675acdfbbb2040e0d82cd965e0ba5d6123b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 4 Mar 2019 22:21:26 +0800 Subject: [PATCH 037/232] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3affa224314..e141d04b053 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,15 @@ # Java 学习/面试指南 -**一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字“1”即可免费无套路获取。** - -**【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 - - 为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。

-微信交流群添加 [我的微信](#我的微信) 后回复关键字“加群”即可入群。 +1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 +2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 +3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本公众号后台回复 **"Java面试突击"** 即可免费领取! +4. **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。
From 539e685566f80c486e864336c8e2da44dab13970 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 4 Mar 2019 22:23:14 +0800 Subject: [PATCH 038/232] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e141d04b053..880ba8bd356 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@ # Java 学习/面试指南 -为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 -

+
+ +## 阅读之前必看 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本公众号后台回复 **"Java面试突击"** 即可免费领取! 4. **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 -
+为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 ## 目录 From 4540f90f2b4112dcbf00150bb4a165424ee50aa5 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 11:09:34 +0800 Subject: [PATCH 039/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 880ba8bd356..4db9e0f3a71 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 -3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本公众号后台回复 **"Java面试突击"** 即可免费领取! +3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! 4. **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 From aa8387b32d6fc880d20b9a4899f6cefd3e039451 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 11:09:57 +0800 Subject: [PATCH 040/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4db9e0f3a71..b4c42d09edf 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,6 @@ ### 公众号 -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。我是 ThoughtWorks 准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!可以扫描下方二维码或者通过微信的搜一搜搜索ID:“Java_Guide”即可。 +如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 ![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334) From 57b4d8552cba0ce23ddcbc5d50ba071dc09882b9 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:42 +0800 Subject: [PATCH 041/232] Delete 2018 summary.md --- "\345\205\266\344\273\226/2018 summary.md" | 174 --------------------- 1 file changed, 174 deletions(-) delete mode 100644 "\345\205\266\344\273\226/2018 summary.md" diff --git "a/\345\205\266\344\273\226/2018 summary.md" "b/\345\205\266\344\273\226/2018 summary.md" deleted file mode 100644 index 8d82e40b876..00000000000 --- "a/\345\205\266\344\273\226/2018 summary.md" +++ /dev/null @@ -1,174 +0,0 @@ -# 【2018总结】即使平凡,也要热爱自己的生活 - -2018 年于我而讲,虽然平凡,但是自己就是在这平凡的一年也收货了很多东西。不光是自己学到的知识,我觉得 2018 年最大的幸运有三:其一是自己拥有了一份爱情,一份甜蜜的初恋,我真的很幸运遇到我现在的女朋友,愿以后的日子都能有她;其一是在 2018 年,我拥有了一份自己还算满意的 offer,马上就要毕业了,自己也要正式进去社会了;其一是自己在 2018 年的实现了自己的经济独立,这是一件让我很高兴的事情,我觉得大在学生时代实现经济独立还算是一件很不错的事情,花了这么多年父母的辛苦钱,自己也终于能替他们分担一点了。2018 年,感恩父母,感恩老师,感恩朋友,感恩遇到的每个善良的人,同时感恩2018年那个还算努力的自己。2019 继续加油! - -## 一份甜蜜的初恋(分手) - -先说说爱情。我和我的女朋友在一起已经半年多了,准确的来说截止到今天也就是 2018-12-30 号已经 190 天了。 - -![我和傻欢](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/54482393.jpg) - -我俩是异地,我在荆州,她在三亚。相见一面不管是时间上还是经济上对于还是学生的我们来说都甚是不易。见过很多人议论异地恋的种种不好,但是,于我而言,一份好的感情是值得被等待的。“待每一天如初恋,互相尊重彼此生活,共同努力,等老了就退隐山林养老......”,这应该是我和她之间最好的承诺了。 - -## 还算不错的学习收获 - -再来说说学习。这一年还算是让人满意,虽然我也不知道这一年自己到底学到了什么。如果你要问我这一年在学习上做的最满意的事情是什么,我还真不好回答,下面就从下面几个维度来简单谈一谈。 - -### 开源 - -这一年自己在Github上还是挺活跃的,提交了很多的代码和文档,同时也收获了很多的star、follower、pr、issue以及fork。 - -![我的Github概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/41250517.jpg) - -![我的Github贡献概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/33580466.jpg) - -开源的Java学习/面试指南—JavaGuide 某种程度上让我挺满意的,3月份开源 ,到现在的18k+ star 也算是可以用厚积薄发来形容了。但是,JavaGuide 也有很多让我不满意的,在2019年以及以后我也会继续完善。JavaGuide 地址:[https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) - -![JavaGuide 概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-24/1352784.jpg) - -### 技术博客 - -我更新的博客主要都是关于Java方面的,也更新了几篇Python的,有一篇Python的文章竟然在我的CSDN上面阅读霸榜。 -![霸榜的 Python 文章](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/19527688.jpg) - -在这一年,我更新了挺多技术文章,这里就不一一列举了,我贴一下自己觉得不错的文章吧! - -#### 最常见面试题系列 - -- [最最最常见的Java面试题总结——第一周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484252&idx=1&sn=cb160d67fc1c0a95babc464b703df5e7&chksm=fd98553dcaefdc2b18f934957dd950aeaf04e90136099fa2817fffbd1e1df452b581e1caee17&token=1398134989&lang=zh_CN#rd) -- [最最最常见的Java面试题总结——第二周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484282&idx=1&sn=7f986dc3263b6ca0f9e182145fdd40a1&chksm=fd98551bcaefdc0d5aff9577692881dc79765a339ce97e55958e23e1956aa7092dfac44b68f1&token=1398134989&lang=zh_CN#rd) -- [这几道Java集合框架面试题在面试中几乎必问](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484308&idx=1&sn=e3607919aed604be629617f867f46844&chksm=fd9855f5caefdce3f1ee72cb33b9b3bf9899fa2b64bbb92f1e820c0ef3985245b1f7dfc05358&token=1398134989&lang=zh_CN#rd) -- [如果不会这几道多线程基础题,请自觉面壁!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484337&idx=1&sn=d5e953d4b2da7ed37a7f843bfb437ed8&chksm=fd9855d0caefdcc65cb2e5cc0c69d27f785fc41477bcf55fff2cdff3268b0b078eb1a5107726&token=1398134989&lang=zh_CN#rd) -- [值得立马保存的 synchronized 关键字总结](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484355&idx=1&sn=6da29974b6dd1a4aa0d032f44d5fa8de&chksm=fd9855a2caefdcb4c370814baafd4baca27dfccaf609c9edf82370637ba4856176ab143a375e&token=1398134989&lang=zh_CN#rd) -- [【面试必备】源码角度一步一步分析 ArrayList 扩容机制](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=1&sn=1b6155015fedfc9f78fabecc18da7b18&chksm=fd985591caefdc870cb018d27f92e1908b6c6e22816a77ead03c4e44b2f53caec00871172b1f&token=1398134989&lang=zh_CN#rd) -- [Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&token=1398134989&lang=zh_CN#rd) - -#### Github - -- [近几个月Github上最热门的Java项目一览](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484188&idx=1&sn=40037de4844f62316465bbe4e910c69c&chksm=fd98557dcaefdc6bedcaeb275aae7c340d46cf6ab0dc96e49c51982f9c53d6a44de283efc9a8&token=1398134989&lang=zh_CN#rd) -- [推荐10个Java方向最热门的开源项目(8月)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484333&idx=1&sn=8c97b029692877a537d55175a8c82977&chksm=fd9855cccaefdcdaffe0558ba5e8dca415495935b0ad1181e6b148b08e1c86ce5d841e9df901&token=1398134989&lang=zh_CN#rd) -- [Github上 Star 数相加超过 7w+ 的三个面试相关的仓库推荐](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484644&idx=1&sn=5016caaf97e498b76de2189e3f55e9dc&chksm=fd985285caefdb93f4e3c7545d30edac6ad31b99f1fcc4503350101f0b20bba9a9705ed7d124&token=1398134989&lang=zh_CN#rd) -- [11月 Github Trending 榜最热门的 10 个 Java 项目](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=1&sn=86e35dfea1478221b6d14a263e88ac89&chksm=fd98535bcaefda4d4f03bf0cd2e0a8fd9f44b1a2b118457a0c8b3de2ff8a1f4c4b7cd083f40e&token=1398134989&lang=zh_CN#rd) -- [盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484817&idx=1&sn=12f0c254a240c40c2ccab8314653216b&chksm=fd9853f0caefdae6d191e6bf085d44ab9c73f165e3323aa0362d830e420ccbfad93aa5901021&token=1398134989&lang=zh_CN#rd) - - -#### 备战面试系列 - -- [可能是一份最适合你的后端面试指南(部分内容前端同样适用)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484529&idx=1&sn=9c7a3d6ad124affcadc19b0ff49bf68a&chksm=fd985210caefdb0615a9643fa698cb6267e89562730423841d942cde17ec9c1280dfc3a2b933&token=1398134989&lang=zh_CN#rd) -- [【备战春招/秋招系列1】程序员的简历就该这样写](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484573&idx=1&sn=8c5965d4a3710d405d8e8cc10c7b0ce5&chksm=fd9852fccaefdbea8dfe0bc40188b7579f1cddb1e8905dc981669a3f21d2a04cadceafa9023f&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列3】Java程序员必备书单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484592&idx=1&sn=6d9731ce7401be49e97c1af6ed384ecc&chksm=fd9852d1caefdbc720a361ae65a8ad9d53cfb4800b15a7c68cbdc630b313215c6c52e0934ec2&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团面经总结基础篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484601&idx=1&sn=4907b7fef0856791c565d49d788ba8cc&chksm=fd9852d8caefdbce88e51c0a10a4ec77c97f382fd2af4a840ea47cffc828bfd0f993f50d5f0d&token=1895808268&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团面经总结进阶篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484625&idx=1&sn=9c4fa1f7d4291a5fbd7daa44bac2b012&chksm=fd9852b0caefdba6edcf9a827aa4a17ddc97bf6ad2e5ee6f7e1aa1b443b54444d05d2b76732b&token=1895808268&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484668&idx=1&sn=9d4631588393075d9c453f307410f0cd&chksm=fd98529dcaefdb8b5497d1f161834af6917c33ea3d305eb41872e522707fa94218769ca60101&token=1398134989&lang=zh_CN#rd) -- [GitHub 上四万 Star 大佬的求职回忆](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484739&idx=1&sn=25cf5b36090f69299150663bdccfeec2&chksm=fd985322caefda34df0734efa607114704d1937f083aee2230b797d1f5aa04f7d13bf2f81dc5&token=1398134989&lang=zh_CN#rd)(非原创) - - -#### 并发编程面试必备 - -- [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&scene=21#wechat_redirect) -- [并发编程面试必备:JUC 中的 Atomic 原子类总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484553&idx=1&sn=aca9fa19f723206eff7e33a10973a887&chksm=fd9852e8caefdbfe7180c34f83bbb422a1a0bef1ed44b1e84f56924244ea3fd2da720f25c6dd#rd) -- [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484559&idx=1&sn=28dae85c38c4c500201c39234d25d731&chksm=fd9852eecaefdbf80cc54a25204e7c7d81170ce659acf92b7fa4151799ca3d0d7df2225d4ff1#rd) -- [并发编程面试必备:BATJ都爱问的多线程面试题](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484564&idx=1&sn=d8467fdc5c1b3883e9b99485f7b0fb9a&chksm=fd9852f5caefdbe364d1c438865cff84acd8f40c1c9e2f9f5c8fef673b30f905b4c5f5255368&token=1398134989&lang=zh_CN#rd) - -#### 虚拟机 - -- [可能是把Java内存区域讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484303&idx=1&sn=af0fd436cef755463f59ee4dd0720cbd&chksm=fd9855eecaefdcf8d94ac581cfda4e16c8a730bda60c3b50bc55c124b92f23b6217f7f8e58d5&token=1398134989&lang=zh_CN#rd) -- [搞定 JVM 垃圾回收就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484328&idx=1&sn=214f5e18a6afa096eb552fd8627e0cea&chksm=fd9855c9caefdcdf70c746c74d31f65bbb109eedaea0cfe311a1e10af666047df59ff04c873b&token=1398134989&lang=zh_CN#rd) - -#### Spring Boot - -- [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个简单的分布式服务](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484706&idx=1&sn=d413fc17023482f67ca17cb6756b9ff8&chksm=fd985343caefda555969568fdf4734536e0a1745f9de337d434a7dbd04e893bd2d75f3641aab&token=1398134989&lang=zh_CN#rd) -- [基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=2&sn=9be4636dd9a416b46f9029df68fad232&chksm=fd98535bcaefda4dccf14a286a24fcd2b3d4ab0d0e4d89dfbc955df99d2b06a1e17392b3c10b&token=1398134989&lang=zh_CN#rd) -- [新手也能实现,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484737&idx=1&sn=e39693d845f022d689437ee58948ef6a&chksm=fd985320caefda36d5ab8abd52f5516c11cc5d1104608695bcea5909602b28dc40c132d6d46c&token=1398134989&lang=zh_CN#rd) -- [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484745&idx=1&sn=dbeec694916d204605929244d48a6b1c&chksm=fd985328caefda3e793170d81433c7c0b7dc1c4a4ae99395cce23b1d1a239482fd5bf1d89bc6&token=1398134989&lang=zh_CN#rd) - -#### 成长 - -- [结束了我短暂的秋招,说点自己的感受](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484516&idx=1&sn=4e2320613e76dd73a130c63beebbc3ca&chksm=fd985205caefdb13b4b611ed3c604d95314d28d567ec0c3b44585b89a7dc3142bcd52bc2d4cb&token=1398134989&lang=zh_CN#rd) -- [保研之路:从双非到南大](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484477&idx=1&sn=3b597e2431611aacca2b5d671a309d85&chksm=fd98525ccaefdb4a7e3742b5958244d453efe26f61f42f9f108190a0c18313f083189f10944e&token=1398134989&lang=zh_CN#rd)(非原创) -- [【周日闲谈】最近想说的几件小事](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484650&idx=1&sn=e97ea1eeebdb5def58bae1949bec9448&chksm=fd98528bcaefdb9d76ac62fd10544f058b1fee4a40ffd06ab9312b7eb3a62f86d67ea653b88a&token=1398134989&lang=zh_CN#rd) -- [这7个问题,可能大部分Java程序员都比较关心吧!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484836&idx=1&sn=a6ada99c9506af01dc3bb472f66c57be&chksm=fd9853c5caefdad3034dbed00cf04412ea990fc05b6168720e6828ae6c90c9a885793acd7a14&token=1398134989&lang=zh_CN#rd) - -#### Docker - -- [可能是把Docker的概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484127&idx=1&sn=70ee95619ec761da884c4f9af3e83194&chksm=fd9854becaefdda81a02bf6cf9bd07a2fc879efa7cefc79691a0d319b501d8572e8bad981d87&token=1398134989&lang=zh_CN#rd) - -#### Linux - -- [后端程序员必备的Linux基础知识](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484157&idx=1&sn=8b47e623e83fb3666bce7c680e4649b8&chksm=fd98549ccaefdd8ad815f3d8eaca86cc7e7245b4f8de1d23897af3017f5fdb3f152734c40f5e&token=1398134989&lang=zh_CN#rd) -- [快速入门大厂后端面试必备的 Shell 编程](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484696&idx=1&sn=d3c1ba5abc10c10ff844cae2109a2628&chksm=fd985379caefda6faff8e050b7dfa1e92fbfe2912e44150cb4ae349aea807836166355062970&token=1398134989&lang=zh_CN#rd) - -#### ZooKeeper - -- [可能是全网把 ZooKeeper 概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484379&idx=1&sn=036f5d3defa8a6979afb77acc82a9517&chksm=fd9855bacaefdcacc1462f781b634e5599f2ee9e806bd24297dae4af0e4196a70ca6bbd8c354&token=1398134989&lang=zh_CN#rd) - -#### Redis - -- [redis 总结——重构版](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484450&idx=1&sn=7ee03fa67aecd05c5becd2a8259d3631&chksm=fd985243caefdb554ebab9149e750ac0c819074c57bd208f2d7f097fbc461ed58223e71c05f1&token=1398134989&lang=zh_CN#rd) -- [史上最全Redis高可用技术解决方案大全](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484478&idx=1&sn=a1250d9b8025cd7cb6fc6a58238ab51e&chksm=fd98525fcaefdb499a027df0138c98d4b02d828f27bd6144a4d40a1c088d340c29dd53d4a026&token=1398134989&lang=zh_CN#rd)(非原创) - -#### 计算机网络 - -- [搞定计算机网络面试,看这篇就够了(补充版)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484289&idx=1&sn=6b556843c60aac9a17b0e7c2e3cd6bca&chksm=fd9855e0caefdcf6af4123b719448c81d90c5442d4052ae01a4698047e226c0c18c14b2cc54a&token=1398134989&lang=zh_CN#rd) - -#### 数据库 - -- [【思维导图-索引篇】搞定数据库索引就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484486&idx=1&sn=215450f11e042bca8a58eac9f4a97686&chksm=fd985227caefdb3117b8375f150676f5824aa20d1ebfdbcfb93ff06e23e26efbafae6cf6b48e&token=1398134989&lang=zh_CN#rd) - -#### 消息队列 - -- [新手也能看懂,消息队列其实很简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484789&idx=1&sn=ba972f0aac39e9a28b29ddf92fc15c18&chksm=fd985314caefda0278235427d43846b6374ff32f4149352dec063287cbf9733b888acbb79923&token=1398134989&lang=zh_CN#rd) -- [一文搞懂 RabbitMQ 的重要概念以及安装](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484796&idx=1&sn=bc56fecb634732669cfe7db8d1820ded&chksm=fd98531dcaefda0b07b8a9c13429ef225d36a6e287c96c53d7aa3dfd65c62ccd60d13b22ebbf&token=1398134989&lang=zh_CN#rd) - -### 读书 - -推荐一下 2018 年看过的书籍,小部分可能2017年也看过一些。 - -#### 已看完 - -- [《图解HTTP》](https://book.douban.com/subject/25863515/)(推荐,豆瓣评分 8.1 , 1.6K+人评价): 讲漫画一样的讲HTTP,很有意思,不会觉得枯燥,大概也涵盖也HTTP常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究HTTP相关知识的话,读这本书的话应该来说就差不多了。 -- [《大话数据结构》](https://book.douban.com/subject/6424904/)(推荐,豆瓣评分 7.9 , 1K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有数据结构基础或者说数据结构没学好的小伙伴用来入门数据结构。 -- [《算法图解》](https://book.douban.com/subject/26979890/)(推荐,豆瓣评分 8.4,0.6K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有算法基础或者说算法没学好的小伙伴用来入门。示例丰富,图文并茂,以让人容易理解的方式阐释了算法.读起来比较快,内容不枯燥! -- [《Java并发编程的艺术》](https://book.douban.com/subject/26591326/)(推荐,豆瓣评分 7.2,0.2K+人评价): 这本书不是很适合作为Java并发入门书籍,需要具备一定的JVM基础。我感觉有些东西讲的还是挺深入的,推荐阅读。 -- [《实战Java高并发程序设计》](https://book.douban.com/subject/26663605/)(推荐):豆瓣评分 8.3 ,书的质量没的说,推荐大家好好看一下。 -- [《深入理解Java虚拟机(第2版)周志明》](https://book.douban.com/subject/24722612/)(推荐,豆瓣评分 8.9,1.0K+人评价):建议多刷几遍,书中的所有知识点可以通过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列完全。 -- [《Netty实战》](https://book.douban.com/subject/27038538/)(推荐,豆瓣评分 7.8,92人评价):内容很细,如果想学Netty的话,推荐阅读这本书! -- [《从Paxos到Zookeeper》](https://book.douban.com/subject/26292004/)(推荐,豆瓣评分 7.8,0.3K人评价):简要介绍几种典型的分布式一致性协议,以及解决分布式一致性问题的思路,其中重点讲解了Paxos和ZAB协议。同时,本书深入介绍了分布式一致性问题的工业解决方案——ZooKeeper,并着重向读者展示这一分布式协调框架的使用方法、内部实现及运维技巧,旨在帮助读者全面了解ZooKeeper,并更好地使用和运维ZooKeeper。 -- [《Redis实战》](https://book.douban.com/subject/26612779/):如果你想了解Redis的一些概念性知识的话,这本书真的非常不错。 -- [《Redis设计与实现》](https://book.douban.com/subject/25900156/)(推荐,豆瓣评分 8.5,0.5K+人评价) -- [《大型网站技术架构:核心原理与案例分析+李智慧》](https://book.douban.com/subject/25723064/)(推荐):这本书我读过,基本不需要你有什么基础啊~读起来特别轻松,但是却可以学到很多东西,非常推荐了。另外我写过这本书的思维导图,关注我的微信公众号:“Java面试通关手册”回复“大型网站技术架构”即可领取思维导图。 - - -#### 未看完 - - -- [《鸟哥的Linux私房菜》](https://book.douban.com/subject/4889838/)(推荐,,豆瓣评分 9.1,0.3K+人评价):本书是最具知名度的Linux入门书《鸟哥的Linux私房菜基础学习篇》的最新版,全面而详细地介绍了Linux操作系统。全书分为5个部分:第一部分着重说明Linux的起源及功能,如何规划和安装Linux主机;第二部分介绍Linux的文件系统、文件、目录与磁盘的管理;第三部分介绍文字模式接口 shell和管理系统的好帮手shell脚本,另外还介绍了文字编辑器vi和vim的使用方法;第四部分介绍了对于系统安全非常重要的Linux账号的管理,以及主机系统与程序的管理,如查看进程、任务分配和作业管理;第五部分介绍了系统管理员(root)的管理事项,如了解系统运行状况、系统服务,针对登录文件进行解析,对系统进行备份以及核心的管理等。 -- [《亿级流量网站架构核心技术》](https://book.douban.com/subject/26999243/)(推荐):一书总结并梳理了亿级流量网站高可用和高并发原则,通过实例详细介绍了如何落地这些原则。本书分为四部分:概述、高可用原则、高并发原则、案例实战。从负载均衡、限流、降级、隔离、超时与重试、回滚机制、压测与预案、缓存、池化、异步化、扩容、队列等多方面详细介绍了亿级流量网站的架构核心技术,让读者看后能快速运用到实践项目中。 -- [《重构_改善既有代码的设计》](https://book.douban.com/subject/4262627/)(推荐):豆瓣 9.1 分,重构书籍的开山鼻祖。 -- [《深入剖析Tomcat》](https://book.douban.com/subject/10426640/)(推荐,豆瓣评分 8.4,0.2K+人评价):本书深入剖析Tomcat 4和Tomcat 5中的每个组件,并揭示其内部工作原理。通过学习本书,你将可以自行开发Tomcat组件,或者扩展已有的组件。 读完这本书,基本可以摆脱背诵面试题的尴尬。 -- [《高性能MySQL》](https://book.douban.com/subject/23008813/)(推荐,豆瓣评分 9.3,0.4K+人评价):mysql 领域的经典之作,拥有广泛的影响力。不但适合数据库管理员(dba)阅读,也适合开发人员参考学习。不管是数据库新手还是专家,相信都能从本书有所收获。 -- [深入理解Nginx(第2版)](https://book.douban.com/subject/26745255/):作者讲的非常细致,注释都写的都很工整,对于 Nginx 的开发人员非常有帮助。优点是细致,缺点是过于细致,到处都是代码片段,缺少一些抽象。 -- [《RabbitMQ实战指南》](https://book.douban.com/subject/27591386/):《RabbitMQ实战指南》从消息中间件的概念和RabbitMQ的历史切入,主要阐述RabbitMQ的安装、使用、配置、管理、运维、原理、扩展等方面的细节。如果你想浅尝RabbitMQ的使用,这本书是你最好的选择;如果你想深入RabbitMQ的原理,这本书也是你最好的选择;总之,如果你想玩转RabbitMQ,这本书一定是最值得看的书之一 -- [《Spring Cloud微服务实战》](https://book.douban.com/subject/27025912/):从时下流行的微服务架构概念出发,详细介绍了Spring Cloud针对微服务架构中几大核心要素的解决方案和基础组件。对于各个组件的介绍,《Spring Cloud微服务实战》主要以示例与源码结合的方式来帮助读者更好地理解这些组件的使用方法以及运行原理。同时,在介绍的过程中,还包含了作者在实践中所遇到的一些问题和解决思路,可供读者在实践中作为参考。 -- [《第一本Docker书》](https://book.douban.com/subject/26780404/):Docker入门书籍! -- [《Effective java 》](https://book.douban.com/subject/3360807/)(推荐,豆瓣评分 9.0,1.4K+人评价):本书介绍了在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案。通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰、健壮和高效的代码。本书中的每条规则都以简短、独立的小文章形式出现,并通过例子代码加以进一步说明。本书内容全面,结构清晰,讲解详细。可作为技术人员的参考用书。 -- [《算法 第四版》](https://book.douban.com/subject/10432347/)(推荐,豆瓣评分 9.3,0.4K+人评价):Java语言描述,算法领域经典的参考书,全面介绍了关于算法和数据结构的必备知识,并特别针对排序、搜索、图处理和字符串处理进行了论述。书的内容非常多,可以说是Java程序员的必备书籍之一了。 - -## 一些个人愚见 - -### 关于读书 - -不知道大家收藏栏是不是和我一样收藏了很多文章,但是有多少篇是你真真认真看的呢?或者那几篇你认真看之后,经过一个月之后还记得这篇文章的大概内容。现在这个社会真是一个信息爆炸的社会,我个人真的深有感触,就在刚刚我还取消关注了好多微信公众号,很多公众号给我推的文章都有好几十篇了,但是我一篇都没有看,所以索性取消关注,省个位置。我个人觉得遇到好的文章,我们不光要读,而且要记录下来。就拿我本人来说,我平时喜欢用 OneNote 来记录学习笔记以及其他我感觉重要的事情比如重要人的生日啦这些。每当遇到自己喜欢的文章的时候,我都先会把文章的地址保存到我分好类的笔记本上,我会先进行第一遍阅读,第一遍我会读的很仔细,如果晦涩难懂的话我会先快速把总体看一遍,然后在细细品读。一般第二遍的时候我就会在笔记本上记录这篇文章的一些要点,以便我日后看到这些要点可以快速回忆起整篇文章的内容。如果某篇文章的知识点太过庞大的话,我会去选择采用思维导图的方式展示要点。看视频一样,看教学视频的话,如果觉得老师讲的不错,我们不妨记录下来,Onenote 或者有道云笔记都行,记录大概,够我们日后回忆就好。 - -### 关于学习 - -做事不要有功利性,我最早在掘金写文章,其实也只是为了记录自己的学习,没想到会有人喜欢自己的文章,另外我课外学的很多东西,我自己也不清楚以后工作会不会用到,反正我自己感觉即然自己感兴趣,那么就去学吧。我相信,很多东西可能暂时带给你不了带多实质性的帮助,但是总有一天它会对你有帮助。如果感到迷茫的话,就做好眼前的事(拿我们班主任的话说,如果你感到迷茫,你就学好现在的专业知识就好了),我觉得没毛病。 - -### 关于个人 - -在生活中一定要保持谦虚,保持谦虚,保持谦虚,时刻都要有反省的准备,你要记住学无止境,永远不要满足现在的现状。另外,就是一定要掌控好自己的时间,多留点时间给父母亲人,以及那些自己在乎的人。如果对别人很在乎的话,不要去装作不在乎,因为这样真的不是太好,虽然我之前也会这样,很多时候撰写的消息,最后没发出去。 - -## 最后分享一句话 - -分享给大家,我笔记本里一直保存的杨绛老先生的一句话:“我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容……我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系!”。 From 5d72b7a9afa275943c6f8d627f1e6ae9a80f356f Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:45 +0800 Subject: [PATCH 042/232] =?UTF-8?q?Delete=202018=20=E7=A7=8B=E6=8B=9B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2018 \347\247\213\346\213\233.md" | 93 ------------------- 1 file changed, 93 deletions(-) delete mode 100644 "\345\205\266\344\273\226/2018 \347\247\213\346\213\233.md" diff --git "a/\345\205\266\344\273\226/2018 \347\247\213\346\213\233.md" "b/\345\205\266\344\273\226/2018 \347\247\213\346\213\233.md" deleted file mode 100644 index a2b47de8eee..00000000000 --- "a/\345\205\266\344\273\226/2018 \347\247\213\346\213\233.md" +++ /dev/null @@ -1,93 +0,0 @@ - - -# 秋招历程流水账总结 - -笔主大四准毕业生,在秋招末流比较幸运地进入了一家自己非常喜欢一家公司——ThoughtWorks. - -![今天去签约在门外拍的照片](https://images.gitbook.cn/1433af10-d5f7-11e8-841a-4f0b0cc7be7b) - -从9-6号投递出去第一份简历,到10-18号左右拿到第一份 offer ,中间差不多有 1 个半月的时间了。可能自己比较随缘,而且自己所在的大学所处的位置并不是互联网比较发达的城市的原因。所以,很少会有公司愿意跑到我们学校那边来宣讲,来的公司也大多是一些自己没听过或者不太喜欢的公司。所以,在前期,我仅仅能够通过网上投递简历的方式来找工作。 - -零零总总算了一下,自己在网上投了大概有 10 份左右的简历,都是些自己还算喜欢的公司。简单说一下自己投递的一些公司:网上投递的公司有:ThoughtWorks、网易、小米、携程、爱奇艺、知乎、小红书、搜狐、欢聚时代、京东;直接邮箱投递的有:烽火、中电数据、蚂蚁金服花呗部门、今日头条;线下宣讲会投递的有:玄武科技。 - -网上投递的大部分简历都是在做完笔试之后就没有了下文了,即使有几场笔试自我感觉做的很不错的情况下,还是没有收到后续的面试邀请。还有些邮箱投递的简历,后面也都没了回应。所以,我总共也只参加了3个公司的面试,ThoughtWorks、玄武科技和中电数据,都算是拿到了 offer。拿到 ThoughtWorks 的 offer之后,后面的一些笔试和少部分面试都拒了。决定去 ThoughtWorks 了,春招的大部队会没有我的存在。 - - -我个人对 ThoughtWorks 最有好感,ThoughtWorks 也是我自己之前很想去的一家公司。不光是因为我投递简历的时候可以不用重新填一遍表格可以直接发送我已经编辑好的PDF格式简历的友好,这个公司的文化也让我很喜欢。每次投递一家公司几乎都要重新填写一遍简历真的很让人头疼,即使是用牛客网的简历助手也还是有很多东西需要自己重新填写。 - -说句实话,自己在拿到第一份 offer 之前心里还是比较空的,虽然说对自己还是比较自信。包括自己当时来到武汉的原因,也是因为自己没有 offer ,就感觉心里空空的,我相信很多人在这个时候与我也有一样的感觉。然后,我就想到武汉参加一下别的学校宣讲会。现在看来,这个决定也是不必要的,因为我最后去的公司 ThoughtWorks,虽然就在我租的房子的附近,但之前投递的时候,选择的还是远程面试。来到武汉,简单的修整了一下之后,我就去参加了玄武科技在武理工的宣讲会,顺便做了笔试,然后接着就是技术面、HR面、高管面。总体来说,玄武科技的 HR 真的很热情,为他们点个赞,虽然自己最后没能去玄武科技,然后就是技术面非常简单,HR面和高管面也都还好,不会有压抑的感觉,总体聊得很愉快。需要注意的是 玄武科技和很多公司一样都有笔试中有逻辑题,我之前没有做过类似的题,所以当时第一次做有点懵逼。高管面的时候,高管还专门在我做的逻辑题上聊了一会,让我重新做了一些做错的题,并且给他讲一些题的思路,可以看出高层对于应聘者的这项能力还是比较看重的。 - - - -中电数据的技术面试是电话进行的,花了1个多小时一点,个人感觉问的还是比较深的,感觉自己总体回答的还是比较不错的。 - -这里我着重说一下 ThoughtWorks,也算是给想去 ThoughtWorks 的同学一点小小的提示。我是 9.11 号在官网:https://join.thoughtworks.cn/ 投递的简历,9.20 日邮件通知官网下载作业,作业总体来说不难,9.21 号花了半天多的时间做完,然后就直接在9.21 号下午提交了。然后等了挺长时间的,可能是因为 ThoughtWorks 在管理方面比较扁平化的原因,所以总体来说效率可能不算高。因为我选的是远程面试,所以直接下载好 zoom 之后,等HR打电话过来告诉你一个房间号,你就可以直接进去面试就好,一般技术面试有几个人看着你。技术面试的内容,首先就是在面试官让你在你之前做的作业的基础上新增加一个或者两个功能(20分钟)。所以,你在技术面试之前一定要保证你的程序的扩展性是不错的,另外就是你在技术面试之前最好能重构一下自己写的程序。重构本身就是你自己对你写的程序的理解加强很好的一种方式,另外重构也能让你发现你的程序的一些小问题。然后,这一步完成之后,面试官可能会问你一些基础问题,比较简单,所以我觉得 ThoughtWorks 可能更看重你的代码质量。ThoughtWorks 的 HR 面和其他公司的唯一不同可能在于,他会让你用英语介绍一下自己或者说自己的技术栈啊这些。 - -![思特沃克可爱的招聘官网](https://images.gitbook.cn/83f765e0-d5f6-11e8-9c1a-919e09988420) - - -# 关于面试一些重要的问题总结 -另外,再给大家总结一些我个人想到一些关于面试非常重要的一些问题。 - -### 面试前 - -**如何准备** - - -运筹帷幄之后,决胜千里之外!不打毫无准备的仗,我觉得大家可以先从下面几个方面来准备面试: - -1. 自我介绍。(你可千万这样介绍:“我叫某某,性别,来自哪里,学校是那个,自己爱干什么”,记住:多说点简历上没有的,多说点自己哪里比别人强!) -2. 自己面试中可能涉及哪些知识点、那些知识点是重点。 -3. 面试中哪些问题会被经常问到、面试中自己改如何回答。(强烈不推荐背题,第一:通过背这种方式你能记住多少?能记住多久?第二:背题的方式的学习很难坚持下去!) -4. 自己的简历该如何写。 - - - -另外,如果你想去类似阿里巴巴、腾讯这种比较大的互联网公司的话,一定要尽早做打算。像阿里巴巴在7月份左右就开始了提前批招聘,到了9月份差不多就已经招聘完毕了。所以,秋招没有参加到阿里的面试还是很遗憾的,毕竟面试即使失败了,也能从阿里难度Max的面试中学到很多东西。 - -**关于着装** - -穿西装、打领带、小皮鞋?NO!NO!NO!这是互联网公司面试又不是去走红毯,所以你只需要穿的简单大方就好,不需要太正式。 - -**关于自我介绍** - -如果你简历上写的基本信息就不要说了,比如性别、年龄、学校。另外,你也不要一上来就说自己爱好什么这方面内容。因为,面试官根本不关心这些东西。你直接挑和你岗位相关的重要经历和自己最突出的特点讲就好了。 - - - -**提前准备** - -面试之前可以在网上找找有没有你要面试的公司的面经。在我面试 ThoughtWorks 的前几天我就在网上找了一些关于 ThoughtWorks 的技术面的一些文章。然后知道了 ThoughtWorks 的技术面会让我们在之前做的作业的基础上增加一个或两个功能,所以我提前一天就把我之前做的程序重新重构了一下。然后在技术面的时候,简单的改了几行代码之后写个测试就完事了。如果没有提前准备,我觉得 20 分钟我很大几率会完不成这项任务。 - - -### 面试中 - -面试的时候一定要自信,千万不要怕自己哪里会答不出来,或者说某个问题自己忘记怎么回答了。面试过程中,很多问题可能是你之前没有碰到过的,这个时候你就要通过自己构建的知识体系来思考这些问题。如果某些问题你回答不上来,你也可以让面试官给你简单的提示一下。总之,你要自信,你自信的前提是自己要做好充分的准备。下面给大家总结一些面试非常常见的问题: - -- SpringMVC 工作原理 -- 说一下自己对 IOC 、AOP 的理解 -- Spring 中用到了那些设计模式,讲一下自己对于这些设计模式的理解 -- Spring Bean 的作用域和生命周期了解吗 -- Spring 事务中的隔离级别 -- Spring 事务中的事务传播行为 -- 手写一个 LRU 算法 -- 知道那些排序算法,简单介绍一下快排的原理,能不能手写一下快排 -- String 为什么是不可变的?String为啥要设计为不可变的? -- Arraylist 与 LinkedList 异同 -- HashMap的底层实现 -- HashMap 的长度为什么是2的幂次方 -- ConcurrentHashMap 和 Hashtable 的区别 -- ConcurrentHashMap线程安全的具体实现方式/底层具体实现 -- 如果你的简历写了redis 、dubbo、zookeeper、docker的话,面试官还会问一下这些东西。比如redis可能会问你:为什么要用 redis、为什么要用 redis 而不用 map/guava 做缓存、redis 常见数据结构以及使用场景分析、 redis 设置过期时间、redis 内存淘汰机制、 redis 持久化机制、 缓存雪崩和缓存穿透问题、如何解决 Redis 的并发竞争 Key 问题、如何保证缓存与数据库双写时的数据一致性。 -- 一些简单的 Linux 命令。 -- 为什么要用 消息队列 -- 关于 Java多线程,在面试的时候,问的比较多的就是①悲观锁和乐观锁②synchronized 和 ReenTrantLock 区别以及 volatile 和 synchronized 的区别,③可重入锁与非可重入锁的区别、④多线程是解决什么问题的、⑤线程池解决什么问题,为什么要用线程池 ⑥Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 ReenTrantLock 对比;⑦线程池使用时的注意事项、⑧AQS 原理以及 AQS 同步组件:Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock、⑨ReentranLock源码,设计原理,整体过程 等等问题。 -- 关于 Java 虚拟机问的比较多的是:①Java内存区域、②虚拟机垃圾算法、③虚拟机垃圾收集器、④JVM内存管理、⑤JVM调优这些问题。 - - -### 面试后 - -如果失败,不要灰心;如果通过,切勿狂喜。面试和工作实际上是两回事,可能很多面试未通过的人,工作能力比你强的多,反之亦然。我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油! - - - From 512a31911ce8f55d61692df6dc7ef38ddda81b8a Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:48 +0800 Subject: [PATCH 043/232] =?UTF-8?q?Delete=20=E9=80=89=E6=8B=A9=E6=8A=80?= =?UTF-8?q?=E6=9C=AF=E6=96=B9=E5=90=91=E9=83=BD=E8=A6=81=E8=80=83=E8=99=91?= =?UTF-8?q?=E5=93=AA=E4=BA=9B=E5=9B=A0=E7=B4=A0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...52\344\272\233\345\233\240\347\264\240.md" | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 "\345\205\266\344\273\226/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" diff --git "a/\345\205\266\344\273\226/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" "b/\345\205\266\344\273\226/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" deleted file mode 100644 index fa39c7c1150..00000000000 --- "a/\345\205\266\344\273\226/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" +++ /dev/null @@ -1,63 +0,0 @@ -本文主要是作者读安晓辉老师的《程序员程序员职场进阶 32 讲 》中关于“选择技术方向都要考虑哪些因素”这部分做的一些笔记和自己的思考。在这里分享给各位! - -### 选择一种技术可能会考虑到的决定因素 - -1. 就业机会 - - 选择一门就业面广的技术还是比较重要的。我的很多学PHP的同学现在都在培训班学Java,真的!!! -2. 难易程度 - - 我当时是在C/C++语言与Java中选择了Java,因为我感觉Java学起来确实要比C++简单一些。 -3. 个人兴趣 - - 兴趣是你能坚持下来的一个很重要的条件。 -4. 薪资水平 - - 薪资虽然不是人的唯一追求,但是一定是必备的追求。 -5. 发展前景 - - 你肯定不愿意看到这种情况发生:选择了一门技术,结果一年后它就没人用、没市场了。所以我们在选择时就要考虑这一点,做一些预判。 - - 选择技术时存在两种考虑:一种是选择稳定的、经典的技术;一种是卡位将来的市场缺口,选择将来可能需要用到的技术。 -6. 他人推荐 - - 我们在懵懵懂懂的时候,往往最容易听从别人的推荐,然后选择某种技术。 -7. 相近原则 - - 当我们已经掌握了一些技术,要学习新技术时,就可以根据一种新技术是否和自己已经掌握的技术比较接近来判断选择。相近的技术,学起来会更容易上手。 -8. 互补原则 - - 和相近性类似,互补性也常用在拓展我们技术能力的情景下。它指的是,有一些技术可以和你已经掌握的技术互相补充,组合在一起,形成更完整、更系统的技术图谱,给你带来更大的竞争力。关于相近原则与互补原则,我们也会在后面的文章里具体解读。 -9. 团队技术图谱 - - 我觉得这个可能就是团队开发过程中的需要。比如在做一个项目的时候,这个项目需要你去学习一下某个你没有接触过的新技术。 - -### 入行时如何选择技术方向 - - 为了明确自己的求职目标,可以问问自己下面的问题: -- 我想在哪个城市工作? -- 我想在哪些行业、领域发展? -- 我想去什么样的公司? -- 我想做什么样的产品? - -另外你要知道的是热门技术会有更多机会,相应竞争压力也会更大,并不能保证你找到合适的工作。 -冷门技术,机会相对较少,而且机会相对确定 。 - -### 构建技能树时如何选择技术方向 - -当我们过了专项能力提升的初级阶段之后,就应该开始构建自己的技能体系了。在为搭建技能树而选择技术时,通常考虑下面两个原则: -- 相近原则 -- 互补原则 - -“学习技术时一定要学对自己以后发展有用的技术”是我经常对自己强调的,另外我觉得很误导人同时也很错误的一个思想是:“只要是技术学了就会有用的”,这句话在我刚学编程时经常听到有人对我说。希望大家不要被误导,很多技术过时了就是过时了,没有必要再去花时间学。 - -我觉得相近原则和互补原则互补原则就是你主精和自己技术方向相同的的东西或者对自己技术领域有提升的东西。比如我目前暂时选择了Java为我的主要发展语言,所以我就要求自己大部分时间还是搞和Java相关的东西比如:Spring、SpingBoot、Dubbo、Mybatis等等。但是千万不要被语言所束缚,在业余时间我学的比较多的就是Python以及JS、C/C++/C#也会偶尔接触。因为我经常会接触前端另外我自己偶尔有爬虫需求或者需要用Python的一些第三库解决一些问题,所以我业余学Pyton以及JS就比较多一点,我觉得这两门技术也是对我现有技术的一个补充了。 - - -### 技术转型时的方向选择 - -我觉得对于技术转型主要有一下几点建议 - -- 与自己当前技术栈跨度不太大的领域,比如你做安卓的话转型可以选择做Java后端。 -- 真正适合自己去做的,并不是一味看着这个领域火了(比如人工智能),然后自己就不考虑实际的去转型到这个领域里去。 -- 技术转型方向尽量对自己以后的发展需要有帮助。 From 9faef98c4b8d55a96e0502dacbdfe3ac34a52aaa Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:51 +0800 Subject: [PATCH 044/232] =?UTF-8?q?Delete=20=E4=B8=AA=E4=BA=BA=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E4=B9=A6=E7=B1=8D=E6=B8=85=E5=8D=95.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...46\347\261\215\346\270\205\345\215\225.md" | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 "\345\205\266\344\273\226/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" diff --git "a/\345\205\266\344\273\226/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" "b/\345\205\266\344\273\226/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" deleted file mode 100644 index f14ee33a211..00000000000 --- "a/\345\205\266\344\273\226/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" +++ /dev/null @@ -1,89 +0,0 @@ -下面是个人阅读书籍的部分清单,我比较建议阅读的书籍前都加上了:thumbsup: 表情。 -> ### 核心基础知识 - -- :thumbsup: [《图解HTTP》](https://book.douban.com/subject/25863515/) - - 讲漫画一样的讲HTTP,很有意思,不会觉得枯燥,大概也涵盖也HTTP常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究HTTP相关知识的话,读这本书的话应该来说就差不多了。 - -> ### Java相关 - -- :thumbsup: [《Head First Java.第二版》](https://book.douban.com/subject/2000732/) - - 可以说是我的Java启蒙书籍了,特别适合新手读当然也适合我们用来温故Java知识点。 - -- [《Java多线程编程核心技术》](https://book.douban.com/subject/26555197/) - - Java多线程入门级书籍还不错,但是说实话,质量不是很高,很快就可以阅读完。 - -- [《JAVA网络编程 第4版》](https://book.douban.com/subject/26259017/) - - 可以系统的学习一下网络的一些概念以及网络编程在Java中的使用。 - -- :thumbsup: [《Java核心技术卷1+卷2》](https://book.douban.com/subject/25762168/) - - 很棒的两本书,建议有点Java基础之后再读,介绍的还是比较深入的,非常推荐。这两本书我一般也会用来巩固知识点,是两本适合放在自己身边的好书。 - -- :thumbsup: [《Java编程思想(第4版)》](https://book.douban.com/subject/2130190/) - - 这本书要常读,初学者可以快速概览,中等程序员可以深入看看java,老鸟还可以用之回顾java的体系。这本书之所以厉害,因为它在无形中整合了设计模式,这本书之所以难读,也恰恰在于他对设计模式的整合是无形的。 - -- :thumbsup: [《Java并发编程的艺术》](https://book.douban.com/subject/26591326/) - - 这本书不是很适合作为Java并发入门书籍,需要具备一定的JVM基础。我感觉有些东西讲的还是挺深入的,推荐阅读。 -- :thumbsup: [《实战Java高并发程序设计》](https://book.douban.com/subject/26663605/) - - 豆瓣评分 8.3 ,书的质量没的说,推荐大家好好看一下。 - -- [《Java程序员修炼之道》](https://book.douban.com/subject/24841235/) - - 很杂,我只看了前面几章,不太推荐阅读。 - -- :thumbsup: [《深入理解Java虚拟机(第2版)周志明》](https://book.douban.com/subject/24722612/) - - 神书!神书!神书!建议多刷几遍,书中的所有知识点可以通过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列完全。 - -> ### JavaWeb相关 - -- :thumbsup: [《深入分析Java Web技术内幕》](https://book.douban.com/subject/25953851/) - - 感觉还行,涉及的东西也蛮多,推荐阅读。 - -- :thumbsup: [《Spring实战(第4版)》](https://book.douban.com/subject/26767354/) - - 不建议当做入门书籍读,入门的话可以找点国人的书或者视频看。这本定位就相当于是关于Spring的新华字典,只有一些基本概念的介绍和示例,涵盖了Spring的各个方面,但都不够深入。就像作者在最后一页写的那样:“学习Spring,这才刚刚开始”。 - -- [《Java Web整合开发王者归来》](https://book.douban.com/subject/4189495/) - - 当时刚开始学的时候就是开的这本书,基本上是完完整整的看完了。不过,我不是很推荐大家看。这本书比较老了,里面很多东西都已经算是过时了。不过,这本书的一个很大优点是:基础知识点概括全面。 - -- :thumbsup: [《Redis实战》](https://book.douban.com/subject/26612779/) - - 如果你想了解Redis的一些概念性知识的话,这本书真的非常不错。 - -> ### 架构相关 - -- :thumbsup: [《大型网站技术架构:核心原理与案例分析+李智慧》](https://book.douban.com/subject/25723064/) - - 这本书我读过,基本不需要你有什么基础啊~读起来特别轻松,但是却可以学到很多东西,非常推荐了。另外我写过这本书的思维导图,关注我的微信公众号:“Java面试通关手册”回复“大型网站技术架构”即可领取思维导图。 - -- [《架构解密从分布式到微服务(Leaderus著)》](https://book.douban.com/subject/27081188/) - - 很一般的书籍,我就是当做课后图书来阅读的。 - -> ### 代码优化 - -- :thumbsup: [《重构_改善既有代码的设计》](https://book.douban.com/subject/4262627/) - - 豆瓣 9.1 分,重构书籍的开山鼻祖。 -> ### linux操作系统相关 -- :thumbsup:[<>](https://book.douban.com/subject/25900403/) :thumbsup: [<>](https://book.douban.com/subject/1500149/) - - 对于理解linux操作系统原理非常有用,同时可以打好个人的基本功力,面试中很多公司也会问到linux知识。 -> ### 课外书籍 - -《技术奇点》 :thumbsup:《追风筝的人》 :thumbsup:《穆斯林的葬礼》 :thumbsup:《三体》 《人工智能——李开复》 -:thumbsup:《活着——余华》 - - - - From a06e6d58abec88eb6b90d8edeb70e391611962ed Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:54 +0800 Subject: [PATCH 045/232] Create 2018 summary.md --- "\351\227\262\350\260\210/2018 summary.md" | 174 +++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 "\351\227\262\350\260\210/2018 summary.md" diff --git "a/\351\227\262\350\260\210/2018 summary.md" "b/\351\227\262\350\260\210/2018 summary.md" new file mode 100644 index 00000000000..8d82e40b876 --- /dev/null +++ "b/\351\227\262\350\260\210/2018 summary.md" @@ -0,0 +1,174 @@ +# 【2018总结】即使平凡,也要热爱自己的生活 + +2018 年于我而讲,虽然平凡,但是自己就是在这平凡的一年也收货了很多东西。不光是自己学到的知识,我觉得 2018 年最大的幸运有三:其一是自己拥有了一份爱情,一份甜蜜的初恋,我真的很幸运遇到我现在的女朋友,愿以后的日子都能有她;其一是在 2018 年,我拥有了一份自己还算满意的 offer,马上就要毕业了,自己也要正式进去社会了;其一是自己在 2018 年的实现了自己的经济独立,这是一件让我很高兴的事情,我觉得大在学生时代实现经济独立还算是一件很不错的事情,花了这么多年父母的辛苦钱,自己也终于能替他们分担一点了。2018 年,感恩父母,感恩老师,感恩朋友,感恩遇到的每个善良的人,同时感恩2018年那个还算努力的自己。2019 继续加油! + +## 一份甜蜜的初恋(分手) + +先说说爱情。我和我的女朋友在一起已经半年多了,准确的来说截止到今天也就是 2018-12-30 号已经 190 天了。 + +![我和傻欢](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/54482393.jpg) + +我俩是异地,我在荆州,她在三亚。相见一面不管是时间上还是经济上对于还是学生的我们来说都甚是不易。见过很多人议论异地恋的种种不好,但是,于我而言,一份好的感情是值得被等待的。“待每一天如初恋,互相尊重彼此生活,共同努力,等老了就退隐山林养老......”,这应该是我和她之间最好的承诺了。 + +## 还算不错的学习收获 + +再来说说学习。这一年还算是让人满意,虽然我也不知道这一年自己到底学到了什么。如果你要问我这一年在学习上做的最满意的事情是什么,我还真不好回答,下面就从下面几个维度来简单谈一谈。 + +### 开源 + +这一年自己在Github上还是挺活跃的,提交了很多的代码和文档,同时也收获了很多的star、follower、pr、issue以及fork。 + +![我的Github概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/41250517.jpg) + +![我的Github贡献概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/33580466.jpg) + +开源的Java学习/面试指南—JavaGuide 某种程度上让我挺满意的,3月份开源 ,到现在的18k+ star 也算是可以用厚积薄发来形容了。但是,JavaGuide 也有很多让我不满意的,在2019年以及以后我也会继续完善。JavaGuide 地址:[https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) + +![JavaGuide 概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-24/1352784.jpg) + +### 技术博客 + +我更新的博客主要都是关于Java方面的,也更新了几篇Python的,有一篇Python的文章竟然在我的CSDN上面阅读霸榜。 +![霸榜的 Python 文章](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/19527688.jpg) + +在这一年,我更新了挺多技术文章,这里就不一一列举了,我贴一下自己觉得不错的文章吧! + +#### 最常见面试题系列 + +- [最最最常见的Java面试题总结——第一周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484252&idx=1&sn=cb160d67fc1c0a95babc464b703df5e7&chksm=fd98553dcaefdc2b18f934957dd950aeaf04e90136099fa2817fffbd1e1df452b581e1caee17&token=1398134989&lang=zh_CN#rd) +- [最最最常见的Java面试题总结——第二周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484282&idx=1&sn=7f986dc3263b6ca0f9e182145fdd40a1&chksm=fd98551bcaefdc0d5aff9577692881dc79765a339ce97e55958e23e1956aa7092dfac44b68f1&token=1398134989&lang=zh_CN#rd) +- [这几道Java集合框架面试题在面试中几乎必问](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484308&idx=1&sn=e3607919aed604be629617f867f46844&chksm=fd9855f5caefdce3f1ee72cb33b9b3bf9899fa2b64bbb92f1e820c0ef3985245b1f7dfc05358&token=1398134989&lang=zh_CN#rd) +- [如果不会这几道多线程基础题,请自觉面壁!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484337&idx=1&sn=d5e953d4b2da7ed37a7f843bfb437ed8&chksm=fd9855d0caefdcc65cb2e5cc0c69d27f785fc41477bcf55fff2cdff3268b0b078eb1a5107726&token=1398134989&lang=zh_CN#rd) +- [值得立马保存的 synchronized 关键字总结](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484355&idx=1&sn=6da29974b6dd1a4aa0d032f44d5fa8de&chksm=fd9855a2caefdcb4c370814baafd4baca27dfccaf609c9edf82370637ba4856176ab143a375e&token=1398134989&lang=zh_CN#rd) +- [【面试必备】源码角度一步一步分析 ArrayList 扩容机制](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=1&sn=1b6155015fedfc9f78fabecc18da7b18&chksm=fd985591caefdc870cb018d27f92e1908b6c6e22816a77ead03c4e44b2f53caec00871172b1f&token=1398134989&lang=zh_CN#rd) +- [Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&token=1398134989&lang=zh_CN#rd) + +#### Github + +- [近几个月Github上最热门的Java项目一览](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484188&idx=1&sn=40037de4844f62316465bbe4e910c69c&chksm=fd98557dcaefdc6bedcaeb275aae7c340d46cf6ab0dc96e49c51982f9c53d6a44de283efc9a8&token=1398134989&lang=zh_CN#rd) +- [推荐10个Java方向最热门的开源项目(8月)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484333&idx=1&sn=8c97b029692877a537d55175a8c82977&chksm=fd9855cccaefdcdaffe0558ba5e8dca415495935b0ad1181e6b148b08e1c86ce5d841e9df901&token=1398134989&lang=zh_CN#rd) +- [Github上 Star 数相加超过 7w+ 的三个面试相关的仓库推荐](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484644&idx=1&sn=5016caaf97e498b76de2189e3f55e9dc&chksm=fd985285caefdb93f4e3c7545d30edac6ad31b99f1fcc4503350101f0b20bba9a9705ed7d124&token=1398134989&lang=zh_CN#rd) +- [11月 Github Trending 榜最热门的 10 个 Java 项目](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=1&sn=86e35dfea1478221b6d14a263e88ac89&chksm=fd98535bcaefda4d4f03bf0cd2e0a8fd9f44b1a2b118457a0c8b3de2ff8a1f4c4b7cd083f40e&token=1398134989&lang=zh_CN#rd) +- [盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484817&idx=1&sn=12f0c254a240c40c2ccab8314653216b&chksm=fd9853f0caefdae6d191e6bf085d44ab9c73f165e3323aa0362d830e420ccbfad93aa5901021&token=1398134989&lang=zh_CN#rd) + + +#### 备战面试系列 + +- [可能是一份最适合你的后端面试指南(部分内容前端同样适用)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484529&idx=1&sn=9c7a3d6ad124affcadc19b0ff49bf68a&chksm=fd985210caefdb0615a9643fa698cb6267e89562730423841d942cde17ec9c1280dfc3a2b933&token=1398134989&lang=zh_CN#rd) +- [【备战春招/秋招系列1】程序员的简历就该这样写](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484573&idx=1&sn=8c5965d4a3710d405d8e8cc10c7b0ce5&chksm=fd9852fccaefdbea8dfe0bc40188b7579f1cddb1e8905dc981669a3f21d2a04cadceafa9023f&token=1990180468&lang=zh_CN#rd) +- [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd) +- [【备战春招/秋招系列3】Java程序员必备书单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484592&idx=1&sn=6d9731ce7401be49e97c1af6ed384ecc&chksm=fd9852d1caefdbc720a361ae65a8ad9d53cfb4800b15a7c68cbdc630b313215c6c52e0934ec2&token=1990180468&lang=zh_CN#rd) +- [【备战春招/秋招系列】美团面经总结基础篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484601&idx=1&sn=4907b7fef0856791c565d49d788ba8cc&chksm=fd9852d8caefdbce88e51c0a10a4ec77c97f382fd2af4a840ea47cffc828bfd0f993f50d5f0d&token=1895808268&lang=zh_CN#rd) +- [【备战春招/秋招系列】美团面经总结进阶篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484625&idx=1&sn=9c4fa1f7d4291a5fbd7daa44bac2b012&chksm=fd9852b0caefdba6edcf9a827aa4a17ddc97bf6ad2e5ee6f7e1aa1b443b54444d05d2b76732b&token=1895808268&lang=zh_CN#rd) +- [【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484668&idx=1&sn=9d4631588393075d9c453f307410f0cd&chksm=fd98529dcaefdb8b5497d1f161834af6917c33ea3d305eb41872e522707fa94218769ca60101&token=1398134989&lang=zh_CN#rd) +- [GitHub 上四万 Star 大佬的求职回忆](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484739&idx=1&sn=25cf5b36090f69299150663bdccfeec2&chksm=fd985322caefda34df0734efa607114704d1937f083aee2230b797d1f5aa04f7d13bf2f81dc5&token=1398134989&lang=zh_CN#rd)(非原创) + + +#### 并发编程面试必备 + +- [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&scene=21#wechat_redirect) +- [并发编程面试必备:JUC 中的 Atomic 原子类总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484553&idx=1&sn=aca9fa19f723206eff7e33a10973a887&chksm=fd9852e8caefdbfe7180c34f83bbb422a1a0bef1ed44b1e84f56924244ea3fd2da720f25c6dd#rd) +- [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484559&idx=1&sn=28dae85c38c4c500201c39234d25d731&chksm=fd9852eecaefdbf80cc54a25204e7c7d81170ce659acf92b7fa4151799ca3d0d7df2225d4ff1#rd) +- [并发编程面试必备:BATJ都爱问的多线程面试题](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484564&idx=1&sn=d8467fdc5c1b3883e9b99485f7b0fb9a&chksm=fd9852f5caefdbe364d1c438865cff84acd8f40c1c9e2f9f5c8fef673b30f905b4c5f5255368&token=1398134989&lang=zh_CN#rd) + +#### 虚拟机 + +- [可能是把Java内存区域讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484303&idx=1&sn=af0fd436cef755463f59ee4dd0720cbd&chksm=fd9855eecaefdcf8d94ac581cfda4e16c8a730bda60c3b50bc55c124b92f23b6217f7f8e58d5&token=1398134989&lang=zh_CN#rd) +- [搞定 JVM 垃圾回收就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484328&idx=1&sn=214f5e18a6afa096eb552fd8627e0cea&chksm=fd9855c9caefdcdf70c746c74d31f65bbb109eedaea0cfe311a1e10af666047df59ff04c873b&token=1398134989&lang=zh_CN#rd) + +#### Spring Boot + +- [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个简单的分布式服务](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484706&idx=1&sn=d413fc17023482f67ca17cb6756b9ff8&chksm=fd985343caefda555969568fdf4734536e0a1745f9de337d434a7dbd04e893bd2d75f3641aab&token=1398134989&lang=zh_CN#rd) +- [基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=2&sn=9be4636dd9a416b46f9029df68fad232&chksm=fd98535bcaefda4dccf14a286a24fcd2b3d4ab0d0e4d89dfbc955df99d2b06a1e17392b3c10b&token=1398134989&lang=zh_CN#rd) +- [新手也能实现,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484737&idx=1&sn=e39693d845f022d689437ee58948ef6a&chksm=fd985320caefda36d5ab8abd52f5516c11cc5d1104608695bcea5909602b28dc40c132d6d46c&token=1398134989&lang=zh_CN#rd) +- [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484745&idx=1&sn=dbeec694916d204605929244d48a6b1c&chksm=fd985328caefda3e793170d81433c7c0b7dc1c4a4ae99395cce23b1d1a239482fd5bf1d89bc6&token=1398134989&lang=zh_CN#rd) + +#### 成长 + +- [结束了我短暂的秋招,说点自己的感受](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484516&idx=1&sn=4e2320613e76dd73a130c63beebbc3ca&chksm=fd985205caefdb13b4b611ed3c604d95314d28d567ec0c3b44585b89a7dc3142bcd52bc2d4cb&token=1398134989&lang=zh_CN#rd) +- [保研之路:从双非到南大](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484477&idx=1&sn=3b597e2431611aacca2b5d671a309d85&chksm=fd98525ccaefdb4a7e3742b5958244d453efe26f61f42f9f108190a0c18313f083189f10944e&token=1398134989&lang=zh_CN#rd)(非原创) +- [【周日闲谈】最近想说的几件小事](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484650&idx=1&sn=e97ea1eeebdb5def58bae1949bec9448&chksm=fd98528bcaefdb9d76ac62fd10544f058b1fee4a40ffd06ab9312b7eb3a62f86d67ea653b88a&token=1398134989&lang=zh_CN#rd) +- [这7个问题,可能大部分Java程序员都比较关心吧!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484836&idx=1&sn=a6ada99c9506af01dc3bb472f66c57be&chksm=fd9853c5caefdad3034dbed00cf04412ea990fc05b6168720e6828ae6c90c9a885793acd7a14&token=1398134989&lang=zh_CN#rd) + +#### Docker + +- [可能是把Docker的概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484127&idx=1&sn=70ee95619ec761da884c4f9af3e83194&chksm=fd9854becaefdda81a02bf6cf9bd07a2fc879efa7cefc79691a0d319b501d8572e8bad981d87&token=1398134989&lang=zh_CN#rd) + +#### Linux + +- [后端程序员必备的Linux基础知识](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484157&idx=1&sn=8b47e623e83fb3666bce7c680e4649b8&chksm=fd98549ccaefdd8ad815f3d8eaca86cc7e7245b4f8de1d23897af3017f5fdb3f152734c40f5e&token=1398134989&lang=zh_CN#rd) +- [快速入门大厂后端面试必备的 Shell 编程](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484696&idx=1&sn=d3c1ba5abc10c10ff844cae2109a2628&chksm=fd985379caefda6faff8e050b7dfa1e92fbfe2912e44150cb4ae349aea807836166355062970&token=1398134989&lang=zh_CN#rd) + +#### ZooKeeper + +- [可能是全网把 ZooKeeper 概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484379&idx=1&sn=036f5d3defa8a6979afb77acc82a9517&chksm=fd9855bacaefdcacc1462f781b634e5599f2ee9e806bd24297dae4af0e4196a70ca6bbd8c354&token=1398134989&lang=zh_CN#rd) + +#### Redis + +- [redis 总结——重构版](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484450&idx=1&sn=7ee03fa67aecd05c5becd2a8259d3631&chksm=fd985243caefdb554ebab9149e750ac0c819074c57bd208f2d7f097fbc461ed58223e71c05f1&token=1398134989&lang=zh_CN#rd) +- [史上最全Redis高可用技术解决方案大全](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484478&idx=1&sn=a1250d9b8025cd7cb6fc6a58238ab51e&chksm=fd98525fcaefdb499a027df0138c98d4b02d828f27bd6144a4d40a1c088d340c29dd53d4a026&token=1398134989&lang=zh_CN#rd)(非原创) + +#### 计算机网络 + +- [搞定计算机网络面试,看这篇就够了(补充版)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484289&idx=1&sn=6b556843c60aac9a17b0e7c2e3cd6bca&chksm=fd9855e0caefdcf6af4123b719448c81d90c5442d4052ae01a4698047e226c0c18c14b2cc54a&token=1398134989&lang=zh_CN#rd) + +#### 数据库 + +- [【思维导图-索引篇】搞定数据库索引就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484486&idx=1&sn=215450f11e042bca8a58eac9f4a97686&chksm=fd985227caefdb3117b8375f150676f5824aa20d1ebfdbcfb93ff06e23e26efbafae6cf6b48e&token=1398134989&lang=zh_CN#rd) + +#### 消息队列 + +- [新手也能看懂,消息队列其实很简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484789&idx=1&sn=ba972f0aac39e9a28b29ddf92fc15c18&chksm=fd985314caefda0278235427d43846b6374ff32f4149352dec063287cbf9733b888acbb79923&token=1398134989&lang=zh_CN#rd) +- [一文搞懂 RabbitMQ 的重要概念以及安装](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484796&idx=1&sn=bc56fecb634732669cfe7db8d1820ded&chksm=fd98531dcaefda0b07b8a9c13429ef225d36a6e287c96c53d7aa3dfd65c62ccd60d13b22ebbf&token=1398134989&lang=zh_CN#rd) + +### 读书 + +推荐一下 2018 年看过的书籍,小部分可能2017年也看过一些。 + +#### 已看完 + +- [《图解HTTP》](https://book.douban.com/subject/25863515/)(推荐,豆瓣评分 8.1 , 1.6K+人评价): 讲漫画一样的讲HTTP,很有意思,不会觉得枯燥,大概也涵盖也HTTP常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究HTTP相关知识的话,读这本书的话应该来说就差不多了。 +- [《大话数据结构》](https://book.douban.com/subject/6424904/)(推荐,豆瓣评分 7.9 , 1K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有数据结构基础或者说数据结构没学好的小伙伴用来入门数据结构。 +- [《算法图解》](https://book.douban.com/subject/26979890/)(推荐,豆瓣评分 8.4,0.6K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有算法基础或者说算法没学好的小伙伴用来入门。示例丰富,图文并茂,以让人容易理解的方式阐释了算法.读起来比较快,内容不枯燥! +- [《Java并发编程的艺术》](https://book.douban.com/subject/26591326/)(推荐,豆瓣评分 7.2,0.2K+人评价): 这本书不是很适合作为Java并发入门书籍,需要具备一定的JVM基础。我感觉有些东西讲的还是挺深入的,推荐阅读。 +- [《实战Java高并发程序设计》](https://book.douban.com/subject/26663605/)(推荐):豆瓣评分 8.3 ,书的质量没的说,推荐大家好好看一下。 +- [《深入理解Java虚拟机(第2版)周志明》](https://book.douban.com/subject/24722612/)(推荐,豆瓣评分 8.9,1.0K+人评价):建议多刷几遍,书中的所有知识点可以通过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列完全。 +- [《Netty实战》](https://book.douban.com/subject/27038538/)(推荐,豆瓣评分 7.8,92人评价):内容很细,如果想学Netty的话,推荐阅读这本书! +- [《从Paxos到Zookeeper》](https://book.douban.com/subject/26292004/)(推荐,豆瓣评分 7.8,0.3K人评价):简要介绍几种典型的分布式一致性协议,以及解决分布式一致性问题的思路,其中重点讲解了Paxos和ZAB协议。同时,本书深入介绍了分布式一致性问题的工业解决方案——ZooKeeper,并着重向读者展示这一分布式协调框架的使用方法、内部实现及运维技巧,旨在帮助读者全面了解ZooKeeper,并更好地使用和运维ZooKeeper。 +- [《Redis实战》](https://book.douban.com/subject/26612779/):如果你想了解Redis的一些概念性知识的话,这本书真的非常不错。 +- [《Redis设计与实现》](https://book.douban.com/subject/25900156/)(推荐,豆瓣评分 8.5,0.5K+人评价) +- [《大型网站技术架构:核心原理与案例分析+李智慧》](https://book.douban.com/subject/25723064/)(推荐):这本书我读过,基本不需要你有什么基础啊~读起来特别轻松,但是却可以学到很多东西,非常推荐了。另外我写过这本书的思维导图,关注我的微信公众号:“Java面试通关手册”回复“大型网站技术架构”即可领取思维导图。 + + +#### 未看完 + + +- [《鸟哥的Linux私房菜》](https://book.douban.com/subject/4889838/)(推荐,,豆瓣评分 9.1,0.3K+人评价):本书是最具知名度的Linux入门书《鸟哥的Linux私房菜基础学习篇》的最新版,全面而详细地介绍了Linux操作系统。全书分为5个部分:第一部分着重说明Linux的起源及功能,如何规划和安装Linux主机;第二部分介绍Linux的文件系统、文件、目录与磁盘的管理;第三部分介绍文字模式接口 shell和管理系统的好帮手shell脚本,另外还介绍了文字编辑器vi和vim的使用方法;第四部分介绍了对于系统安全非常重要的Linux账号的管理,以及主机系统与程序的管理,如查看进程、任务分配和作业管理;第五部分介绍了系统管理员(root)的管理事项,如了解系统运行状况、系统服务,针对登录文件进行解析,对系统进行备份以及核心的管理等。 +- [《亿级流量网站架构核心技术》](https://book.douban.com/subject/26999243/)(推荐):一书总结并梳理了亿级流量网站高可用和高并发原则,通过实例详细介绍了如何落地这些原则。本书分为四部分:概述、高可用原则、高并发原则、案例实战。从负载均衡、限流、降级、隔离、超时与重试、回滚机制、压测与预案、缓存、池化、异步化、扩容、队列等多方面详细介绍了亿级流量网站的架构核心技术,让读者看后能快速运用到实践项目中。 +- [《重构_改善既有代码的设计》](https://book.douban.com/subject/4262627/)(推荐):豆瓣 9.1 分,重构书籍的开山鼻祖。 +- [《深入剖析Tomcat》](https://book.douban.com/subject/10426640/)(推荐,豆瓣评分 8.4,0.2K+人评价):本书深入剖析Tomcat 4和Tomcat 5中的每个组件,并揭示其内部工作原理。通过学习本书,你将可以自行开发Tomcat组件,或者扩展已有的组件。 读完这本书,基本可以摆脱背诵面试题的尴尬。 +- [《高性能MySQL》](https://book.douban.com/subject/23008813/)(推荐,豆瓣评分 9.3,0.4K+人评价):mysql 领域的经典之作,拥有广泛的影响力。不但适合数据库管理员(dba)阅读,也适合开发人员参考学习。不管是数据库新手还是专家,相信都能从本书有所收获。 +- [深入理解Nginx(第2版)](https://book.douban.com/subject/26745255/):作者讲的非常细致,注释都写的都很工整,对于 Nginx 的开发人员非常有帮助。优点是细致,缺点是过于细致,到处都是代码片段,缺少一些抽象。 +- [《RabbitMQ实战指南》](https://book.douban.com/subject/27591386/):《RabbitMQ实战指南》从消息中间件的概念和RabbitMQ的历史切入,主要阐述RabbitMQ的安装、使用、配置、管理、运维、原理、扩展等方面的细节。如果你想浅尝RabbitMQ的使用,这本书是你最好的选择;如果你想深入RabbitMQ的原理,这本书也是你最好的选择;总之,如果你想玩转RabbitMQ,这本书一定是最值得看的书之一 +- [《Spring Cloud微服务实战》](https://book.douban.com/subject/27025912/):从时下流行的微服务架构概念出发,详细介绍了Spring Cloud针对微服务架构中几大核心要素的解决方案和基础组件。对于各个组件的介绍,《Spring Cloud微服务实战》主要以示例与源码结合的方式来帮助读者更好地理解这些组件的使用方法以及运行原理。同时,在介绍的过程中,还包含了作者在实践中所遇到的一些问题和解决思路,可供读者在实践中作为参考。 +- [《第一本Docker书》](https://book.douban.com/subject/26780404/):Docker入门书籍! +- [《Effective java 》](https://book.douban.com/subject/3360807/)(推荐,豆瓣评分 9.0,1.4K+人评价):本书介绍了在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案。通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰、健壮和高效的代码。本书中的每条规则都以简短、独立的小文章形式出现,并通过例子代码加以进一步说明。本书内容全面,结构清晰,讲解详细。可作为技术人员的参考用书。 +- [《算法 第四版》](https://book.douban.com/subject/10432347/)(推荐,豆瓣评分 9.3,0.4K+人评价):Java语言描述,算法领域经典的参考书,全面介绍了关于算法和数据结构的必备知识,并特别针对排序、搜索、图处理和字符串处理进行了论述。书的内容非常多,可以说是Java程序员的必备书籍之一了。 + +## 一些个人愚见 + +### 关于读书 + +不知道大家收藏栏是不是和我一样收藏了很多文章,但是有多少篇是你真真认真看的呢?或者那几篇你认真看之后,经过一个月之后还记得这篇文章的大概内容。现在这个社会真是一个信息爆炸的社会,我个人真的深有感触,就在刚刚我还取消关注了好多微信公众号,很多公众号给我推的文章都有好几十篇了,但是我一篇都没有看,所以索性取消关注,省个位置。我个人觉得遇到好的文章,我们不光要读,而且要记录下来。就拿我本人来说,我平时喜欢用 OneNote 来记录学习笔记以及其他我感觉重要的事情比如重要人的生日啦这些。每当遇到自己喜欢的文章的时候,我都先会把文章的地址保存到我分好类的笔记本上,我会先进行第一遍阅读,第一遍我会读的很仔细,如果晦涩难懂的话我会先快速把总体看一遍,然后在细细品读。一般第二遍的时候我就会在笔记本上记录这篇文章的一些要点,以便我日后看到这些要点可以快速回忆起整篇文章的内容。如果某篇文章的知识点太过庞大的话,我会去选择采用思维导图的方式展示要点。看视频一样,看教学视频的话,如果觉得老师讲的不错,我们不妨记录下来,Onenote 或者有道云笔记都行,记录大概,够我们日后回忆就好。 + +### 关于学习 + +做事不要有功利性,我最早在掘金写文章,其实也只是为了记录自己的学习,没想到会有人喜欢自己的文章,另外我课外学的很多东西,我自己也不清楚以后工作会不会用到,反正我自己感觉即然自己感兴趣,那么就去学吧。我相信,很多东西可能暂时带给你不了带多实质性的帮助,但是总有一天它会对你有帮助。如果感到迷茫的话,就做好眼前的事(拿我们班主任的话说,如果你感到迷茫,你就学好现在的专业知识就好了),我觉得没毛病。 + +### 关于个人 + +在生活中一定要保持谦虚,保持谦虚,保持谦虚,时刻都要有反省的准备,你要记住学无止境,永远不要满足现在的现状。另外,就是一定要掌控好自己的时间,多留点时间给父母亲人,以及那些自己在乎的人。如果对别人很在乎的话,不要去装作不在乎,因为这样真的不是太好,虽然我之前也会这样,很多时候撰写的消息,最后没发出去。 + +## 最后分享一句话 + +分享给大家,我笔记本里一直保存的杨绛老先生的一句话:“我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容……我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系!”。 From 46521dda8871db207691124d3e412497ff4ffe55 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:22:57 +0800 Subject: [PATCH 046/232] =?UTF-8?q?Create=202018=20=E7=A7=8B=E6=8B=9B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2018 \347\247\213\346\213\233.md" | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 "\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" diff --git "a/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" "b/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" new file mode 100644 index 00000000000..a2b47de8eee --- /dev/null +++ "b/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" @@ -0,0 +1,93 @@ + + +# 秋招历程流水账总结 + +笔主大四准毕业生,在秋招末流比较幸运地进入了一家自己非常喜欢一家公司——ThoughtWorks. + +![今天去签约在门外拍的照片](https://images.gitbook.cn/1433af10-d5f7-11e8-841a-4f0b0cc7be7b) + +从9-6号投递出去第一份简历,到10-18号左右拿到第一份 offer ,中间差不多有 1 个半月的时间了。可能自己比较随缘,而且自己所在的大学所处的位置并不是互联网比较发达的城市的原因。所以,很少会有公司愿意跑到我们学校那边来宣讲,来的公司也大多是一些自己没听过或者不太喜欢的公司。所以,在前期,我仅仅能够通过网上投递简历的方式来找工作。 + +零零总总算了一下,自己在网上投了大概有 10 份左右的简历,都是些自己还算喜欢的公司。简单说一下自己投递的一些公司:网上投递的公司有:ThoughtWorks、网易、小米、携程、爱奇艺、知乎、小红书、搜狐、欢聚时代、京东;直接邮箱投递的有:烽火、中电数据、蚂蚁金服花呗部门、今日头条;线下宣讲会投递的有:玄武科技。 + +网上投递的大部分简历都是在做完笔试之后就没有了下文了,即使有几场笔试自我感觉做的很不错的情况下,还是没有收到后续的面试邀请。还有些邮箱投递的简历,后面也都没了回应。所以,我总共也只参加了3个公司的面试,ThoughtWorks、玄武科技和中电数据,都算是拿到了 offer。拿到 ThoughtWorks 的 offer之后,后面的一些笔试和少部分面试都拒了。决定去 ThoughtWorks 了,春招的大部队会没有我的存在。 + + +我个人对 ThoughtWorks 最有好感,ThoughtWorks 也是我自己之前很想去的一家公司。不光是因为我投递简历的时候可以不用重新填一遍表格可以直接发送我已经编辑好的PDF格式简历的友好,这个公司的文化也让我很喜欢。每次投递一家公司几乎都要重新填写一遍简历真的很让人头疼,即使是用牛客网的简历助手也还是有很多东西需要自己重新填写。 + +说句实话,自己在拿到第一份 offer 之前心里还是比较空的,虽然说对自己还是比较自信。包括自己当时来到武汉的原因,也是因为自己没有 offer ,就感觉心里空空的,我相信很多人在这个时候与我也有一样的感觉。然后,我就想到武汉参加一下别的学校宣讲会。现在看来,这个决定也是不必要的,因为我最后去的公司 ThoughtWorks,虽然就在我租的房子的附近,但之前投递的时候,选择的还是远程面试。来到武汉,简单的修整了一下之后,我就去参加了玄武科技在武理工的宣讲会,顺便做了笔试,然后接着就是技术面、HR面、高管面。总体来说,玄武科技的 HR 真的很热情,为他们点个赞,虽然自己最后没能去玄武科技,然后就是技术面非常简单,HR面和高管面也都还好,不会有压抑的感觉,总体聊得很愉快。需要注意的是 玄武科技和很多公司一样都有笔试中有逻辑题,我之前没有做过类似的题,所以当时第一次做有点懵逼。高管面的时候,高管还专门在我做的逻辑题上聊了一会,让我重新做了一些做错的题,并且给他讲一些题的思路,可以看出高层对于应聘者的这项能力还是比较看重的。 + + + +中电数据的技术面试是电话进行的,花了1个多小时一点,个人感觉问的还是比较深的,感觉自己总体回答的还是比较不错的。 + +这里我着重说一下 ThoughtWorks,也算是给想去 ThoughtWorks 的同学一点小小的提示。我是 9.11 号在官网:https://join.thoughtworks.cn/ 投递的简历,9.20 日邮件通知官网下载作业,作业总体来说不难,9.21 号花了半天多的时间做完,然后就直接在9.21 号下午提交了。然后等了挺长时间的,可能是因为 ThoughtWorks 在管理方面比较扁平化的原因,所以总体来说效率可能不算高。因为我选的是远程面试,所以直接下载好 zoom 之后,等HR打电话过来告诉你一个房间号,你就可以直接进去面试就好,一般技术面试有几个人看着你。技术面试的内容,首先就是在面试官让你在你之前做的作业的基础上新增加一个或者两个功能(20分钟)。所以,你在技术面试之前一定要保证你的程序的扩展性是不错的,另外就是你在技术面试之前最好能重构一下自己写的程序。重构本身就是你自己对你写的程序的理解加强很好的一种方式,另外重构也能让你发现你的程序的一些小问题。然后,这一步完成之后,面试官可能会问你一些基础问题,比较简单,所以我觉得 ThoughtWorks 可能更看重你的代码质量。ThoughtWorks 的 HR 面和其他公司的唯一不同可能在于,他会让你用英语介绍一下自己或者说自己的技术栈啊这些。 + +![思特沃克可爱的招聘官网](https://images.gitbook.cn/83f765e0-d5f6-11e8-9c1a-919e09988420) + + +# 关于面试一些重要的问题总结 +另外,再给大家总结一些我个人想到一些关于面试非常重要的一些问题。 + +### 面试前 + +**如何准备** + + +运筹帷幄之后,决胜千里之外!不打毫无准备的仗,我觉得大家可以先从下面几个方面来准备面试: + +1. 自我介绍。(你可千万这样介绍:“我叫某某,性别,来自哪里,学校是那个,自己爱干什么”,记住:多说点简历上没有的,多说点自己哪里比别人强!) +2. 自己面试中可能涉及哪些知识点、那些知识点是重点。 +3. 面试中哪些问题会被经常问到、面试中自己改如何回答。(强烈不推荐背题,第一:通过背这种方式你能记住多少?能记住多久?第二:背题的方式的学习很难坚持下去!) +4. 自己的简历该如何写。 + + + +另外,如果你想去类似阿里巴巴、腾讯这种比较大的互联网公司的话,一定要尽早做打算。像阿里巴巴在7月份左右就开始了提前批招聘,到了9月份差不多就已经招聘完毕了。所以,秋招没有参加到阿里的面试还是很遗憾的,毕竟面试即使失败了,也能从阿里难度Max的面试中学到很多东西。 + +**关于着装** + +穿西装、打领带、小皮鞋?NO!NO!NO!这是互联网公司面试又不是去走红毯,所以你只需要穿的简单大方就好,不需要太正式。 + +**关于自我介绍** + +如果你简历上写的基本信息就不要说了,比如性别、年龄、学校。另外,你也不要一上来就说自己爱好什么这方面内容。因为,面试官根本不关心这些东西。你直接挑和你岗位相关的重要经历和自己最突出的特点讲就好了。 + + + +**提前准备** + +面试之前可以在网上找找有没有你要面试的公司的面经。在我面试 ThoughtWorks 的前几天我就在网上找了一些关于 ThoughtWorks 的技术面的一些文章。然后知道了 ThoughtWorks 的技术面会让我们在之前做的作业的基础上增加一个或两个功能,所以我提前一天就把我之前做的程序重新重构了一下。然后在技术面的时候,简单的改了几行代码之后写个测试就完事了。如果没有提前准备,我觉得 20 分钟我很大几率会完不成这项任务。 + + +### 面试中 + +面试的时候一定要自信,千万不要怕自己哪里会答不出来,或者说某个问题自己忘记怎么回答了。面试过程中,很多问题可能是你之前没有碰到过的,这个时候你就要通过自己构建的知识体系来思考这些问题。如果某些问题你回答不上来,你也可以让面试官给你简单的提示一下。总之,你要自信,你自信的前提是自己要做好充分的准备。下面给大家总结一些面试非常常见的问题: + +- SpringMVC 工作原理 +- 说一下自己对 IOC 、AOP 的理解 +- Spring 中用到了那些设计模式,讲一下自己对于这些设计模式的理解 +- Spring Bean 的作用域和生命周期了解吗 +- Spring 事务中的隔离级别 +- Spring 事务中的事务传播行为 +- 手写一个 LRU 算法 +- 知道那些排序算法,简单介绍一下快排的原理,能不能手写一下快排 +- String 为什么是不可变的?String为啥要设计为不可变的? +- Arraylist 与 LinkedList 异同 +- HashMap的底层实现 +- HashMap 的长度为什么是2的幂次方 +- ConcurrentHashMap 和 Hashtable 的区别 +- ConcurrentHashMap线程安全的具体实现方式/底层具体实现 +- 如果你的简历写了redis 、dubbo、zookeeper、docker的话,面试官还会问一下这些东西。比如redis可能会问你:为什么要用 redis、为什么要用 redis 而不用 map/guava 做缓存、redis 常见数据结构以及使用场景分析、 redis 设置过期时间、redis 内存淘汰机制、 redis 持久化机制、 缓存雪崩和缓存穿透问题、如何解决 Redis 的并发竞争 Key 问题、如何保证缓存与数据库双写时的数据一致性。 +- 一些简单的 Linux 命令。 +- 为什么要用 消息队列 +- 关于 Java多线程,在面试的时候,问的比较多的就是①悲观锁和乐观锁②synchronized 和 ReenTrantLock 区别以及 volatile 和 synchronized 的区别,③可重入锁与非可重入锁的区别、④多线程是解决什么问题的、⑤线程池解决什么问题,为什么要用线程池 ⑥Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 ReenTrantLock 对比;⑦线程池使用时的注意事项、⑧AQS 原理以及 AQS 同步组件:Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock、⑨ReentranLock源码,设计原理,整体过程 等等问题。 +- 关于 Java 虚拟机问的比较多的是:①Java内存区域、②虚拟机垃圾算法、③虚拟机垃圾收集器、④JVM内存管理、⑤JVM调优这些问题。 + + +### 面试后 + +如果失败,不要灰心;如果通过,切勿狂喜。面试和工作实际上是两回事,可能很多面试未通过的人,工作能力比你强的多,反之亦然。我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油! + + + From 4f9034af2ba19d4bfcae234484955d205e1b5bb1 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:00 +0800 Subject: [PATCH 047/232] Create 2018-12.md --- .../JavaGithubTrending/2018-12.md" | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 "\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" "b/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" new file mode 100644 index 00000000000..fc433c64f8e --- /dev/null +++ "b/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" @@ -0,0 +1,113 @@ +本文数据统计于 1.1 号凌晨,由 SnailClimb 整理。 + +### 1. JavaGuide + +- **Github地址**: [https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) +- **star**: 18.2k +- **介绍**: 【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。 + +![JavaGuide](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/96151465.jpg) + +概览: + + ![JavaGuide](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-24/1352784.jpg) + +### 2. mall + +- **Github地址**: [https://github.com/macrozheng/mall](https://github.com/macrozheng/mall) +- **star**: 3.3k +- **介绍**: mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。 + +![mall](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/11382760.jpg) + +概览: + +![mall](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/99819963.jpg) + +### 3. advanced-java + +- **Github地址**:[https://github.com/doocs/advanced-java](https://github.com/doocs/advanced-java) +- **star**: 3.3k +- **介绍**: 互联网 Java 工程师进阶知识完全扫盲 + +![advanced-java](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/95209476.jpg) + +概览: + +![advanced-java](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/18005792.jpg) + +### 4. matrix + +- **Github地址**:[https://github.com/Tencent/matrix](https://github.com/Tencent/matrix) +- **star**: 2.5k +- **介绍**: Matrix 是一款微信研发并日常使用的 APM(Application Performance Manage),当前主要运行在 Android 平台上。 Matrix 的目标是建立统一的应用性能接入框架,通过各种性能监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。 + +![matrix](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/8991895.jpg) + +### 5. miaosha + +- **Github地址**:[https://github.com/qiurunze123/miaosha](https://github.com/qiurunze123/miaosha) +- **star**: 2.4k +- **介绍**: 高并发大流量如何进行秒杀架构,我对这部分知识做了一个系统的整理,写了一套系统。 + +![miaosha](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/79382302.jpg) + +### 6. arthas + +- **Github地址**:[https://github.com/alibaba/arthas](https://github.com/alibaba/arthas) +- **star**: 8.2k +- **介绍**: Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。 + +![arthas](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/73394671.jpg) + +### 7 spring-boot + +- **Github地址**: [https://github.com/spring-projects/spring-boot](https://github.com/spring-projects/spring-boot) +- **star:** 32.6k +- **介绍**: 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置),不过Spring Boot 让这一切成为了过去。 另外Spring Cloud也是基于Spring Boot构建的,我个人非常有必要学习一下。 + + **关于Spring Boot官方的介绍:** + + > Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”…Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可) + +![spring-boot](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/29649807.jpg) + +### 8. tutorials + +- **Github地址**:[https://github.com/eugenp/tutorials](https://github.com/eugenp/tutorials) +- **star**: 10k +- **介绍**: 该项目是一系列小而专注的教程 - 每个教程都涵盖Java生态系统中单一且定义明确的开发领域。 当然,它们的重点是Spring Framework - Spring,Spring Boot和Spring Securiyt。 除了Spring之外,还有以下技术:核心Java,Jackson,HttpClient,Guava。 + +![tutorials](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/94425339.jpg) + +### 9. qmq + +- **Github地址**:[https://github.com/qunarcorp/qmq](https://github.com/qunarcorp/qmq) +- **star**: 1.1k +- **介绍**: QMQ是去哪儿网内部广泛使用的消息中间件,自2012年诞生以来在去哪儿网所有业务场景中广泛的应用,包括跟交易息息相关的订单场景; 也包括报价搜索等高吞吐量场景。 + +![arthas](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/73394671.jpg) + +### 10. symphony + +- **Github地址**:[https://github.com/b3log/symphony](https://github.com/b3log/symphony) +- **star**: 9k +- **介绍**: 一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)平台。 + +![symphony](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/11577890.jpg) + +### 11. incubator-dubbo + +- **Github地址**:[https://github.com/apache/incubator-dubbo](https://github.com/apache/incubator-dubbo) +- **star**: 23.6k +- **介绍**: 阿里开源的一个基于Java的高性能开源RPC框架。 + +![incubator-dubbo](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/53068060.jpg) + +### 12. apollo + +- **Github地址**:[https://github.com/ctripcorp/apollo](https://github.com/ctripcorp/apollo) +- **star**: 10k +- **介绍**: Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。 + +![apollo](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/89386993.jpg) \ No newline at end of file From df20c96cbb49b56bf08b1eebf0e4703f9db29601 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:02 +0800 Subject: [PATCH 048/232] Create 2019-1.md --- .../JavaGithubTrending/2019-1.md" | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 "\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" "b/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" new file mode 100644 index 00000000000..eecc4e2860e --- /dev/null +++ "b/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" @@ -0,0 +1,114 @@ +### 1. JavaGuide + +- **Github地址**: [https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) +- **star**: 22.8k +- **介绍**: 【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。 + +![JavaGuide](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/JavaGuide.png) + +**概览:** + + ![JavaGuide](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-24/1352784.jpg) + +### 2. advanced-java + +- **Github地址**:[https://github.com/doocs/advanced-java](https://github.com/doocs/advanced-java) +- **star**: 7.9k +- **介绍**: 互联网 Java 工程师进阶知识完全扫盲 + +![advanced-java](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/advanced-java.png) + +**概览:** + +![advanced-java](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/18005792.jpg) + +### 3. fescar + +- **Github地址**:[https://github.com/alibaba/fescar](https://github.com/alibaba/fescar) +- **star**: 4.6k +- **介绍**: 具有 **高性能** 和 **易用性** 的 **微服务架构** 的 **分布式事务** 的解决方案。(特点:高性能且易于使用,旨在实现简单并快速的事务提交与回滚。)关于 fescar 的更详细介绍可以查看:[Github 上日获 800多 star 的阿里微服务架构分布式事务解决方案 FESCAR开源啦](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484888&idx=2&sn=ff9fe077c95959ec777c866a425bddbe&chksm=fd9853b9caefdaaf52a1b7caecc697938c2c1c5f6916527d1309ef01aba70c6546bdba6a9657&token=96044853&lang=zh_CN#rd) + +![fescar](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/fescar.png) + +### 4. mall + +- **Github地址**: [https://github.com/macrozheng/mall](https://github.com/macrozheng/mall) +- **star**: 5.6 k +- **介绍**: mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。 + +![mall](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/mall.png) + +**概览:** + +![mall](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-1/99819963.jpg) + +### 5. miaosha + +- **Github地址**:[https://github.com/qiurunze123/miaosha](https://github.com/qiurunze123/miaosha) +- **star**: 4.4k +- **介绍**: 高并发大流量如何进行秒杀架构,我对这部分知识做了一个系统的整理,写了一套系统。 + +![miaosha](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/miaosha.png) + +### 6. flink + +- **Github地址**:[https://github.com/apache/flink](https://github.com/apache/flink) +- **star**: 7.1 k +- **介绍**: Apache Flink是一个开源流处理框架,具有强大的流和批处理功能。 + +![flink](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/flink.png) + +关于Flink 更加详细的介绍可以查看这篇文章:https://www.cnblogs.com/feiyudemeng/p/8998772.html + +### 7. cim + +- **Github地址**:[https://github.com/crossoverJie/cim](https://github.com/crossoverJie/cim) +- **star**: 1.8 k +- **介绍**: cim(cross IM) 适用于开发者的即时通讯系统。 + +![cim](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/cim.png) + +**系统架构:** + +![cim系统架构](https://camo.githubusercontent.com/16f644ac7e2ab8cf8b8784408b1c70baf15634f4/68747470733a2f2f7773312e73696e61696d672e636e2f6c617267652f303036744e6252776c793166796c646769697a68756a3331356f3072346e306b2e6a7067) + +### 8. symphony + +- **Github地址**:[https://github.com/b3log/symphony](https://github.com/b3log/symphony) +- **star**: 10k +- **介绍**: 一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)平台。 + +![symphony](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/symphony.png) + +### 9. spring-boot + +- **Github地址**: [https://github.com/spring-projects/spring-boot](https://github.com/spring-projects/spring-boot) +- **star:** 32.6k +- **介绍**: 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置),不过Spring Boot 让这一切成为了过去。 另外Spring Cloud也是基于Spring Boot构建的,我个人非常有必要学习一下。 + + **关于Spring Boot官方的介绍:** + + > Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”…Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可) + +![spring-boot](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/spring-boot.png) + +### 10. arthas + +- **Github地址**:[https://github.com/alibaba/arthas](https://github.com/alibaba/arthas) +- **star**: 9.5k +- **介绍**: Arthas 是Alibaba开源的Java诊断工具。 + +![arthas](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/arthas.png) + +**概览:** + +当你遇到以下类似问题而束手无策时,`Arthas`可以帮助你解决: + +0. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? +1. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? +2. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? +3. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! +4. 是否有一个全局视角来查看系统的运行状况? +5. 有什么办法可以监控到JVM的实时运行状态? + +`Arthas`支持JDK 6+,支持Linux/Mac/Winodws,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 \ No newline at end of file From 53f9754eb54fb653414bf257bde495ab2bfc0bf8 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:05 +0800 Subject: [PATCH 049/232] Create 2019-2.md --- .../JavaGithubTrending/2019-2.md" | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 "\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" "b/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" new file mode 100644 index 00000000000..51d34b32f78 --- /dev/null +++ "b/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" @@ -0,0 +1,64 @@ +### 1. JavaGuide + +- **Github地址**: [https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) +- **Star**: 27.2k (4,437 stars this month) +- **介绍**: 【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。 + +### 2.DoraemonKit + +- **Github地址**: +- **Star**: 5.2k (3,786 stars this month) +- **介绍**: 简称 "DoKit" 。一款功能齐全的客户端( iOS 、Android )研发助手,你值得拥有。 + +### 3.advanced-java + +- **Github地址**:[https://github.com/doocs/advanced-java](https://github.com/doocs/advanced-java) +- **Star**:11.2k (3,042 stars this month) +- **介绍**: 互联网 Java 工程师进阶知识完全扫盲。 + +### 4. spring-boot-examples + +- **Github地址**: +- **star**: 9.6 k (1,764 stars this month) +- **介绍**: Spring Boot 教程、技术栈示例代码,快速简单上手教程。 + +### 5. mall + +- **Github地址**: [https://github.com/macrozheng/mall](https://github.com/macrozheng/mall) +- **star**: 7.4 k (1,736 stars this month) +- **介绍**: mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。 + +### 6. fescar + +- **Github地址**:[https://github.com/alibaba/fescar](https://github.com/alibaba/fescar) +- **star**: 6.0 k (1,308 stars this month) +- **介绍**: 具有 **高性能** 和 **易用性** 的 **微服务架构** 的 **分布式事务** 的解决方案。(特点:高性能且易于使用,旨在实现简单并快速的事务提交与回滚。) + +### 7. h4cker + +- **Github地址**: +- **star**: 2.1 k (1,303 stars this month) +- **介绍**: 该仓库主要由Omar Santos维护,包括与道德黑客/渗透测试,数字取证和事件响应(DFIR),漏洞研究,漏洞利用开发,逆向工程等相关的资源。 + +### 8. spring-boot + +- **Github地址**: [https://github.com/spring-projects/spring-boot](https://github.com/spring-projects/spring-boot) +- **star:** 34.8k (1,073 stars this month) +- **介绍**: 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置),不过Spring Boot 让这一切成为了过去。 另外Spring Cloud也是基于Spring Boot构建的,我个人非常有必要学习一下。 + + **关于Spring Boot官方的介绍:** + + > Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”…Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可) + +### 9. arthas + +- **Github地址**:[https://github.com/alibaba/arthas](https://github.com/alibaba/arthas) +- **star**: 10.5 k (970 stars this month) +- **介绍**: Arthas 是Alibaba开源的Java诊断工具。 + +### 10. tutorials + +- **Github地址**:[https://github.com/eugenp/tutorials](https://github.com/eugenp/tutorials) +- **star**: 12.1 k (789 stars this month) +- **介绍**: 该项目是一系列小而专注的教程 - 每个教程都涵盖Java生态系统中单一且定义明确的开发领域。 当然,它们的重点是Spring Framework - Spring,Spring Boot和Spring Securiyt。 除了Spring之外,还有以下技术:核心Java,Jackson,HttpClient,Guava。 + From e63d58f5b5e40b8e7dc97203eb3d1487dda922ae Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:08 +0800 Subject: [PATCH 050/232] Create JavaGithubTrending.md --- .../JavaGithubTrending/JavaGithubTrending.md" | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 "\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" "b/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" new file mode 100644 index 00000000000..203710cb8af --- /dev/null +++ "b/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" @@ -0,0 +1,2 @@ +### 2019 年一月 + From cf17868c24b5d0e5066be77546771d1ca44edb99 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:10 +0800 Subject: [PATCH 051/232] =?UTF-8?q?Create=20=E4=B8=AA=E4=BA=BA=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E4=B9=A6=E7=B1=8D=E6=B8=85=E5=8D=95.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...46\347\261\215\346\270\205\345\215\225.md" | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 "\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" diff --git "a/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" "b/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" new file mode 100644 index 00000000000..f14ee33a211 --- /dev/null +++ "b/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" @@ -0,0 +1,89 @@ +下面是个人阅读书籍的部分清单,我比较建议阅读的书籍前都加上了:thumbsup: 表情。 +> ### 核心基础知识 + +- :thumbsup: [《图解HTTP》](https://book.douban.com/subject/25863515/) + + 讲漫画一样的讲HTTP,很有意思,不会觉得枯燥,大概也涵盖也HTTP常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究HTTP相关知识的话,读这本书的话应该来说就差不多了。 + +> ### Java相关 + +- :thumbsup: [《Head First Java.第二版》](https://book.douban.com/subject/2000732/) + + 可以说是我的Java启蒙书籍了,特别适合新手读当然也适合我们用来温故Java知识点。 + +- [《Java多线程编程核心技术》](https://book.douban.com/subject/26555197/) + + Java多线程入门级书籍还不错,但是说实话,质量不是很高,很快就可以阅读完。 + +- [《JAVA网络编程 第4版》](https://book.douban.com/subject/26259017/) + + 可以系统的学习一下网络的一些概念以及网络编程在Java中的使用。 + +- :thumbsup: [《Java核心技术卷1+卷2》](https://book.douban.com/subject/25762168/) + + 很棒的两本书,建议有点Java基础之后再读,介绍的还是比较深入的,非常推荐。这两本书我一般也会用来巩固知识点,是两本适合放在自己身边的好书。 + +- :thumbsup: [《Java编程思想(第4版)》](https://book.douban.com/subject/2130190/) + + 这本书要常读,初学者可以快速概览,中等程序员可以深入看看java,老鸟还可以用之回顾java的体系。这本书之所以厉害,因为它在无形中整合了设计模式,这本书之所以难读,也恰恰在于他对设计模式的整合是无形的。 + +- :thumbsup: [《Java并发编程的艺术》](https://book.douban.com/subject/26591326/) + + 这本书不是很适合作为Java并发入门书籍,需要具备一定的JVM基础。我感觉有些东西讲的还是挺深入的,推荐阅读。 +- :thumbsup: [《实战Java高并发程序设计》](https://book.douban.com/subject/26663605/) + + 豆瓣评分 8.3 ,书的质量没的说,推荐大家好好看一下。 + +- [《Java程序员修炼之道》](https://book.douban.com/subject/24841235/) + + 很杂,我只看了前面几章,不太推荐阅读。 + +- :thumbsup: [《深入理解Java虚拟机(第2版)周志明》](https://book.douban.com/subject/24722612/) + + 神书!神书!神书!建议多刷几遍,书中的所有知识点可以通过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列完全。 + +> ### JavaWeb相关 + +- :thumbsup: [《深入分析Java Web技术内幕》](https://book.douban.com/subject/25953851/) + + 感觉还行,涉及的东西也蛮多,推荐阅读。 + +- :thumbsup: [《Spring实战(第4版)》](https://book.douban.com/subject/26767354/) + + 不建议当做入门书籍读,入门的话可以找点国人的书或者视频看。这本定位就相当于是关于Spring的新华字典,只有一些基本概念的介绍和示例,涵盖了Spring的各个方面,但都不够深入。就像作者在最后一页写的那样:“学习Spring,这才刚刚开始”。 + +- [《Java Web整合开发王者归来》](https://book.douban.com/subject/4189495/) + + 当时刚开始学的时候就是开的这本书,基本上是完完整整的看完了。不过,我不是很推荐大家看。这本书比较老了,里面很多东西都已经算是过时了。不过,这本书的一个很大优点是:基础知识点概括全面。 + +- :thumbsup: [《Redis实战》](https://book.douban.com/subject/26612779/) + + 如果你想了解Redis的一些概念性知识的话,这本书真的非常不错。 + +> ### 架构相关 + +- :thumbsup: [《大型网站技术架构:核心原理与案例分析+李智慧》](https://book.douban.com/subject/25723064/) + + 这本书我读过,基本不需要你有什么基础啊~读起来特别轻松,但是却可以学到很多东西,非常推荐了。另外我写过这本书的思维导图,关注我的微信公众号:“Java面试通关手册”回复“大型网站技术架构”即可领取思维导图。 + +- [《架构解密从分布式到微服务(Leaderus著)》](https://book.douban.com/subject/27081188/) + + 很一般的书籍,我就是当做课后图书来阅读的。 + +> ### 代码优化 + +- :thumbsup: [《重构_改善既有代码的设计》](https://book.douban.com/subject/4262627/) + + 豆瓣 9.1 分,重构书籍的开山鼻祖。 +> ### linux操作系统相关 +- :thumbsup:[<>](https://book.douban.com/subject/25900403/) :thumbsup: [<>](https://book.douban.com/subject/1500149/) + + 对于理解linux操作系统原理非常有用,同时可以打好个人的基本功力,面试中很多公司也会问到linux知识。 +> ### 课外书籍 + +《技术奇点》 :thumbsup:《追风筝的人》 :thumbsup:《穆斯林的葬礼》 :thumbsup:《三体》 《人工智能——李开复》 +:thumbsup:《活着——余华》 + + + + From 96669987b0a3f1a4bbf9c06e5dc476db27d0fb87 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:23:14 +0800 Subject: [PATCH 052/232] =?UTF-8?q?Create=20=E9=80=89=E6=8B=A9=E6=8A=80?= =?UTF-8?q?=E6=9C=AF=E6=96=B9=E5=90=91=E9=83=BD=E8=A6=81=E8=80=83=E8=99=91?= =?UTF-8?q?=E5=93=AA=E4=BA=9B=E5=9B=A0=E7=B4=A0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...52\344\272\233\345\233\240\347\264\240.md" | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 "\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" diff --git "a/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" "b/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" new file mode 100644 index 00000000000..fa39c7c1150 --- /dev/null +++ "b/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" @@ -0,0 +1,63 @@ +本文主要是作者读安晓辉老师的《程序员程序员职场进阶 32 讲 》中关于“选择技术方向都要考虑哪些因素”这部分做的一些笔记和自己的思考。在这里分享给各位! + +### 选择一种技术可能会考虑到的决定因素 + +1. 就业机会 + + 选择一门就业面广的技术还是比较重要的。我的很多学PHP的同学现在都在培训班学Java,真的!!! +2. 难易程度 + + 我当时是在C/C++语言与Java中选择了Java,因为我感觉Java学起来确实要比C++简单一些。 +3. 个人兴趣 + + 兴趣是你能坚持下来的一个很重要的条件。 +4. 薪资水平 + + 薪资虽然不是人的唯一追求,但是一定是必备的追求。 +5. 发展前景 + + 你肯定不愿意看到这种情况发生:选择了一门技术,结果一年后它就没人用、没市场了。所以我们在选择时就要考虑这一点,做一些预判。 + + 选择技术时存在两种考虑:一种是选择稳定的、经典的技术;一种是卡位将来的市场缺口,选择将来可能需要用到的技术。 +6. 他人推荐 + + 我们在懵懵懂懂的时候,往往最容易听从别人的推荐,然后选择某种技术。 +7. 相近原则 + + 当我们已经掌握了一些技术,要学习新技术时,就可以根据一种新技术是否和自己已经掌握的技术比较接近来判断选择。相近的技术,学起来会更容易上手。 +8. 互补原则 + + 和相近性类似,互补性也常用在拓展我们技术能力的情景下。它指的是,有一些技术可以和你已经掌握的技术互相补充,组合在一起,形成更完整、更系统的技术图谱,给你带来更大的竞争力。关于相近原则与互补原则,我们也会在后面的文章里具体解读。 +9. 团队技术图谱 + + 我觉得这个可能就是团队开发过程中的需要。比如在做一个项目的时候,这个项目需要你去学习一下某个你没有接触过的新技术。 + +### 入行时如何选择技术方向 + + 为了明确自己的求职目标,可以问问自己下面的问题: +- 我想在哪个城市工作? +- 我想在哪些行业、领域发展? +- 我想去什么样的公司? +- 我想做什么样的产品? + +另外你要知道的是热门技术会有更多机会,相应竞争压力也会更大,并不能保证你找到合适的工作。 +冷门技术,机会相对较少,而且机会相对确定 。 + +### 构建技能树时如何选择技术方向 + +当我们过了专项能力提升的初级阶段之后,就应该开始构建自己的技能体系了。在为搭建技能树而选择技术时,通常考虑下面两个原则: +- 相近原则 +- 互补原则 + +“学习技术时一定要学对自己以后发展有用的技术”是我经常对自己强调的,另外我觉得很误导人同时也很错误的一个思想是:“只要是技术学了就会有用的”,这句话在我刚学编程时经常听到有人对我说。希望大家不要被误导,很多技术过时了就是过时了,没有必要再去花时间学。 + +我觉得相近原则和互补原则互补原则就是你主精和自己技术方向相同的的东西或者对自己技术领域有提升的东西。比如我目前暂时选择了Java为我的主要发展语言,所以我就要求自己大部分时间还是搞和Java相关的东西比如:Spring、SpingBoot、Dubbo、Mybatis等等。但是千万不要被语言所束缚,在业余时间我学的比较多的就是Python以及JS、C/C++/C#也会偶尔接触。因为我经常会接触前端另外我自己偶尔有爬虫需求或者需要用Python的一些第三库解决一些问题,所以我业余学Pyton以及JS就比较多一点,我觉得这两门技术也是对我现有技术的一个补充了。 + + +### 技术转型时的方向选择 + +我觉得对于技术转型主要有一下几点建议 + +- 与自己当前技术栈跨度不太大的领域,比如你做安卓的话转型可以选择做Java后端。 +- 真正适合自己去做的,并不是一味看着这个领域火了(比如人工智能),然后自己就不考虑实际的去转型到这个领域里去。 +- 技术转型方向尽量对自己以后的发展需要有帮助。 From 1eb877211f0bd9ed01df3510df05405eb7f7bfde Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 11:25:38 +0800 Subject: [PATCH 053/232] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b4c42d09edf..37796204be4 100644 --- a/README.md +++ b/README.md @@ -185,10 +185,11 @@ ## :art: 闲谈 -* [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/其他/选择技术方向都要考虑哪些因素.md) -* [结束了我短暂的秋招,说点自己的感受](https://github.com/Snailclimb/JavaGuide/blob/master/%E5%85%B6%E4%BB%96/2018%20%E7%A7%8B%E6%8B%9B.md) -* [这7个问题,可能大部分Java程序员都比较关心吧!](https://github.com/Snailclimb/JavaGuide/blob/master/%E9%9D%A2%E8%AF%95%E5%BF%85%E5%A4%87/java%20programmer%20need%20know.md) -* [【2018总结】即使平凡,也要热爱自己的生活](https://github.com/Snailclimb/JavaGuide/blob/master/%E5%85%B6%E4%BB%96/2018%20summary.md) +* [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) +* [这7个问题,可能大部分Java程序员都比较关心吧!](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/java%20programmer%20need%20know.md) +* [【2018总结】即使平凡,也要热爱自己的生活](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20summary.md) +* [Java项目 Github Trending 月榜](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/JavaGithubTrending.md) *** From cb8d1ab923f630faa820cfe9ae706a3351af91c5 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:30:12 +0800 Subject: [PATCH 054/232] Create JavaProgrammerNeedKnow.md --- .../JavaProgrammerNeedKnow.md" | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" new file mode 100644 index 00000000000..ef111f4cf15 --- /dev/null +++ "b/\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" @@ -0,0 +1,81 @@ +  身边的朋友或者公众号的粉丝很多人都向我询问过:“我是双非/三本/专科学校的,我有机会进入大厂吗?”、“非计算机专业的学生能学好吗?”、“如何学习Java?”、“Java学习该学那些东西?”、“我该如何准备Java面试?”......这些方面的问题。我会根据自己的一点经验对大部分人关心的这些问题进行答疑解惑。现在又刚好赶上考研结束,这篇文章也算是给考研结束准备往Java后端方向发展的朋友们指名一条学习之路。道理懂了如果没有实际行动,那这篇文章对你或许没有任何意义。 + +### Question1:我是双非/三本/专科学校的,我有机会进入大厂吗? + +  我自己也是非985非211学校的,结合自己的经历以及一些朋友的经历,我觉得让我回答这个问题再好不过。 + +  首先,我觉得学校歧视很正常,真的太正常了,如果要抱怨的话,你只能抱怨自己没有进入名校。但是,千万不要动不动说自己学校差,动不动拿自己学校当做自己进不了大厂的借口,学历只是筛选简历的很多标准中的一个而已,如果你够优秀,简历够丰富,你也一样可以和名校同学一起同台竞争。 + +  企业HR肯定是更喜欢高学历的人,毕竟985,211优秀人才比例肯定比普通学校高很多,HR团队肯定会优先在这些学校里选。这就好比相亲,你是愿意在很多优秀的人中选一个优秀的,还是愿意在很多普通的人中选一个优秀的呢? +   +  双非本科甚至是二本、三本甚至是专科的同学也有很多进入大厂的,不过比率相比于名校的低很多而已。从大厂招聘的结果上看,高学历人才的数量占据大头,那些成功进入BAT、美团,京东,网易等大厂的双非本科甚至是二本、三本甚至是专科的同学往往是因为具备丰富的项目经历或者在某个含金量比较高的竞赛比如ACM中取得了不错的成绩。**一部分学历不突出但能力出众的面试者能够进入大厂并不是说明学历不重要,而是学历的软肋能够通过其他的优势来弥补。** 所以,如果你的学校不够好而你自己又想去大厂的话,建议你可以从这几点来做:**①尽量在面试前最好有一个可以拿的出手的项目;②有实习条件的话,尽早出去实习,实习经历也会是你的简历的一个亮点(有能力在大厂实习最佳!);③参加一些含金量比较高的比赛,拿不拿得到名次没关系,重在锻炼。** + + +### Question2:非计算机专业的学生能学好Java后台吗?我能进大厂吗? + +  当然可以!现在非科班的程序员很多,很大一部分原因是互联网行业的工资比较高。我们学校外面的培训班里面90%都是非科班,我觉得他们很多人学的都还不错。另外,我的一个朋友本科是机械专业,大一开始自学安卓,技术贼溜,在我看来他比大部分本科是计算机的同学学的还要好。参考Question1的回答,即使你是非科班程序员,如果你想进入大厂的话,你也可以通过自己的其他优势来弥补。 + +  我觉得我们不应该因为自己的专业给自己划界限或者贴标签,说实话,很多科班的同学可能并不如你,你以为科班的同学就会认真听讲吗?还不是几乎全靠自己课下自学!不过如果你是非科班的话,你想要学好,那么注定就要舍弃自己本专业的一些学习时间,这是无可厚非的。 + +  建议非科班的同学,首先要打好计算机基础知识基础:①计算机网络、②操作系统、③数据机构与算法,我个人觉得这3个对你最重要。这些东西就像是内功,对你以后的长远发展非常有用。当然,如果你想要进大厂的话,这些知识也是一定会被问到的。另外,“一定学好数据机构与算法!一定学好数据机构与算法!一定学好数据机构与算法!”,重要的东西说3遍。 + + + +### Question3: 我没有实习经历的话找工作是不是特别艰难? + +  没有实习经历没关系,只要你有拿得出手的项目或者大赛经历的话,你依然有可能拿到大厂的 offer 。笔主当时找工作的时候就没有实习经历以及大赛获奖经历,单纯就是凭借自己的项目经验撑起了整个面试。 + +  如果你既没有实习经历,又没有拿得出手的项目或者大赛经历的话,我觉得在简历关,除非你有其他特别的亮点,不然,你应该就会被刷。 + +### Question4: 我该如何准备面试呢?面试的注意事项有哪些呢? + +下面是我总结的一些准备面试的Tips以及面试必备的注意事项: + +1. **准备一份自己的自我介绍,面试的时候根据面试对象适当进行修改**(突出重点,突出自己的优势在哪里,切忌流水账); +2. **注意随身带上自己的成绩单和简历复印件;** (有的公司在面试前都会让你交一份成绩单和简历当做面试中的参考。) +3. **如果需要笔试就提前刷一些笔试题,大部分在线笔试的类型是选择题+编程题,有的还会有简答题。**(平时空闲时间多的可以刷一下笔试题目(牛客网上有很多),但是不要只刷面试题,不动手code,程序员不是为了考试而存在的。)另外,注意抓重点,因为题目太多了,但是有很多题目几乎次次遇到,像这样的题目一定要搞定。 +4. **提前准备技术面试。** 搞清楚自己面试中可能涉及哪些知识点、那些知识点是重点。面试中哪些问题会被经常问到、自己改如何回答。(强烈不推荐背题,第一:通过背这种方式你能记住多少?能记住多久?第二:背题的方式的学习很难坚持下去!) +5. **面试之前做好定向复习。** 也就是专门针对你要面试的公司来复习。比如你在面试之前可以在网上找找有没有你要面试的公司的面经。 +6. **准备好自己的项目介绍。** 如果有项目的话,技术面试第一步,面试官一般都是让你自己介绍一下你的项目。你可以从下面几个方向来考虑:①对项目整体设计的一个感受(面试官可能会让你画系统的架构图;②在这个项目中你负责了什么、做了什么、担任了什么角色;③ 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用;④项目描述中,最好可以体现自己的综合素质,比如你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的又或者说你在这个项目用了什么技术实现了什么功能比如:用redis做缓存提高访问速度和并发量、使用消息队列削峰和降流等等。 +7. **面试之后记得复盘。** 面试遭遇失败是很正常的事情,所以善于总结自己的失败原因才是最重要的。如果失败,不要灰心;如果通过,切勿狂喜。 + + +**一些还算不错的 Java面试/学习相关的仓库,相信对大家准备面试一定有帮助:**[盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484817&idx=1&sn=12f0c254a240c40c2ccab8314653216b&chksm=fd9853f0caefdae6d191e6bf085d44ab9c73f165e3323aa0362d830e420ccbfad93aa5901021&token=766994974&lang=zh_CN#rd) + +### Question5: 我该自学还是报培训班呢? + +  我本人更加赞同自学(你要知道去了公司可没人手把手教你了,而且几乎所有的公司都对培训班出生的有偏见。为什么有偏见,你学个东西还要去培训班,说明什么,同等水平下,你的自学能力以及自律能力一定是比不上自学的人的)。但是如果,你连每天在寝室坚持学上8个小时以上都坚持不了,或者总是容易半途而废的话,我还是推荐你去培训班。观望身边同学去培训班的,大多是非计算机专业或者是没有自律能力以及自学能力非常差的人。 + +  另外,如果自律能力不行,你也可以通过结伴学习、参加老师的项目等方式来督促自己学习。 + +  总结:去不去培训班主要还是看自己,如果自己能坚持自学就自学,坚持不下来就去培训班。 + +### Question6: 没有项目经历/博客/Github开源项目怎么办? + +  从现在开始做! + +  网上有很多非常不错的项目视频,你就跟着一步一步做,不光要做,还要改进,改善。另外,如果你的老师有相关 Java 后台项目的话,你也可以主动申请参与进来。 + +  如果有自己的博客,也算是简历上的一个亮点。建议可以在掘金、Segmentfault、CSDN等技术交流社区写博客,当然,你也可以自己搭建一个博客(采用 Hexo+Githu Pages 搭建非常简单)。写一些什么?学习笔记、实战内容、读书笔记等等都可以。 + +  多用 Github,用好 Github,上传自己不错的项目,写好 readme 文档,在其他技术社区做好宣传。相信你也会收获一个不错的开源项目! + + +### Question7: 大厂到底青睐什么样的应届生? + +  从阿里、腾讯等大厂招聘官网对于Java后端方向/后端方向的应届实习生的要求,我们大概可以总结归纳出下面这 4 点能给简历增加很多分数: + +- 参加过竞赛(含金量超高的是ACM); +- 对数据结构与算法非常熟练; +- 参与过实际项目(比如学校网站); +- 参与过某个知名的开源项目或者自己的某个开源项目很不错; + +  除了我上面说的这三点,在面试Java工程师的时候,下面几点也提升你的个人竞争力: + +- 熟悉Python、Shell、Perl等脚本语言; +- 熟悉 Java 优化,JVM调优; +- 熟悉 SOA 模式; +- 熟悉自己所用框架的底层知识比如Spring; +- 了解分布式一些常见的理论; +- 具备高并发开发经验;大数据开发经验等等。 + From 01dceb162f7d57ed2abb48eff144ea854d4fc3a1 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:30:16 +0800 Subject: [PATCH 055/232] Delete java programmer need know.md --- .../java programmer need know.md" | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/java programmer need know.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/java programmer need know.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/java programmer need know.md" deleted file mode 100644 index ef111f4cf15..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/java programmer need know.md" +++ /dev/null @@ -1,81 +0,0 @@ -  身边的朋友或者公众号的粉丝很多人都向我询问过:“我是双非/三本/专科学校的,我有机会进入大厂吗?”、“非计算机专业的学生能学好吗?”、“如何学习Java?”、“Java学习该学那些东西?”、“我该如何准备Java面试?”......这些方面的问题。我会根据自己的一点经验对大部分人关心的这些问题进行答疑解惑。现在又刚好赶上考研结束,这篇文章也算是给考研结束准备往Java后端方向发展的朋友们指名一条学习之路。道理懂了如果没有实际行动,那这篇文章对你或许没有任何意义。 - -### Question1:我是双非/三本/专科学校的,我有机会进入大厂吗? - -  我自己也是非985非211学校的,结合自己的经历以及一些朋友的经历,我觉得让我回答这个问题再好不过。 - -  首先,我觉得学校歧视很正常,真的太正常了,如果要抱怨的话,你只能抱怨自己没有进入名校。但是,千万不要动不动说自己学校差,动不动拿自己学校当做自己进不了大厂的借口,学历只是筛选简历的很多标准中的一个而已,如果你够优秀,简历够丰富,你也一样可以和名校同学一起同台竞争。 - -  企业HR肯定是更喜欢高学历的人,毕竟985,211优秀人才比例肯定比普通学校高很多,HR团队肯定会优先在这些学校里选。这就好比相亲,你是愿意在很多优秀的人中选一个优秀的,还是愿意在很多普通的人中选一个优秀的呢? -   -  双非本科甚至是二本、三本甚至是专科的同学也有很多进入大厂的,不过比率相比于名校的低很多而已。从大厂招聘的结果上看,高学历人才的数量占据大头,那些成功进入BAT、美团,京东,网易等大厂的双非本科甚至是二本、三本甚至是专科的同学往往是因为具备丰富的项目经历或者在某个含金量比较高的竞赛比如ACM中取得了不错的成绩。**一部分学历不突出但能力出众的面试者能够进入大厂并不是说明学历不重要,而是学历的软肋能够通过其他的优势来弥补。** 所以,如果你的学校不够好而你自己又想去大厂的话,建议你可以从这几点来做:**①尽量在面试前最好有一个可以拿的出手的项目;②有实习条件的话,尽早出去实习,实习经历也会是你的简历的一个亮点(有能力在大厂实习最佳!);③参加一些含金量比较高的比赛,拿不拿得到名次没关系,重在锻炼。** - - -### Question2:非计算机专业的学生能学好Java后台吗?我能进大厂吗? - -  当然可以!现在非科班的程序员很多,很大一部分原因是互联网行业的工资比较高。我们学校外面的培训班里面90%都是非科班,我觉得他们很多人学的都还不错。另外,我的一个朋友本科是机械专业,大一开始自学安卓,技术贼溜,在我看来他比大部分本科是计算机的同学学的还要好。参考Question1的回答,即使你是非科班程序员,如果你想进入大厂的话,你也可以通过自己的其他优势来弥补。 - -  我觉得我们不应该因为自己的专业给自己划界限或者贴标签,说实话,很多科班的同学可能并不如你,你以为科班的同学就会认真听讲吗?还不是几乎全靠自己课下自学!不过如果你是非科班的话,你想要学好,那么注定就要舍弃自己本专业的一些学习时间,这是无可厚非的。 - -  建议非科班的同学,首先要打好计算机基础知识基础:①计算机网络、②操作系统、③数据机构与算法,我个人觉得这3个对你最重要。这些东西就像是内功,对你以后的长远发展非常有用。当然,如果你想要进大厂的话,这些知识也是一定会被问到的。另外,“一定学好数据机构与算法!一定学好数据机构与算法!一定学好数据机构与算法!”,重要的东西说3遍。 - - - -### Question3: 我没有实习经历的话找工作是不是特别艰难? - -  没有实习经历没关系,只要你有拿得出手的项目或者大赛经历的话,你依然有可能拿到大厂的 offer 。笔主当时找工作的时候就没有实习经历以及大赛获奖经历,单纯就是凭借自己的项目经验撑起了整个面试。 - -  如果你既没有实习经历,又没有拿得出手的项目或者大赛经历的话,我觉得在简历关,除非你有其他特别的亮点,不然,你应该就会被刷。 - -### Question4: 我该如何准备面试呢?面试的注意事项有哪些呢? - -下面是我总结的一些准备面试的Tips以及面试必备的注意事项: - -1. **准备一份自己的自我介绍,面试的时候根据面试对象适当进行修改**(突出重点,突出自己的优势在哪里,切忌流水账); -2. **注意随身带上自己的成绩单和简历复印件;** (有的公司在面试前都会让你交一份成绩单和简历当做面试中的参考。) -3. **如果需要笔试就提前刷一些笔试题,大部分在线笔试的类型是选择题+编程题,有的还会有简答题。**(平时空闲时间多的可以刷一下笔试题目(牛客网上有很多),但是不要只刷面试题,不动手code,程序员不是为了考试而存在的。)另外,注意抓重点,因为题目太多了,但是有很多题目几乎次次遇到,像这样的题目一定要搞定。 -4. **提前准备技术面试。** 搞清楚自己面试中可能涉及哪些知识点、那些知识点是重点。面试中哪些问题会被经常问到、自己改如何回答。(强烈不推荐背题,第一:通过背这种方式你能记住多少?能记住多久?第二:背题的方式的学习很难坚持下去!) -5. **面试之前做好定向复习。** 也就是专门针对你要面试的公司来复习。比如你在面试之前可以在网上找找有没有你要面试的公司的面经。 -6. **准备好自己的项目介绍。** 如果有项目的话,技术面试第一步,面试官一般都是让你自己介绍一下你的项目。你可以从下面几个方向来考虑:①对项目整体设计的一个感受(面试官可能会让你画系统的架构图;②在这个项目中你负责了什么、做了什么、担任了什么角色;③ 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用;④项目描述中,最好可以体现自己的综合素质,比如你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的又或者说你在这个项目用了什么技术实现了什么功能比如:用redis做缓存提高访问速度和并发量、使用消息队列削峰和降流等等。 -7. **面试之后记得复盘。** 面试遭遇失败是很正常的事情,所以善于总结自己的失败原因才是最重要的。如果失败,不要灰心;如果通过,切勿狂喜。 - - -**一些还算不错的 Java面试/学习相关的仓库,相信对大家准备面试一定有帮助:**[盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484817&idx=1&sn=12f0c254a240c40c2ccab8314653216b&chksm=fd9853f0caefdae6d191e6bf085d44ab9c73f165e3323aa0362d830e420ccbfad93aa5901021&token=766994974&lang=zh_CN#rd) - -### Question5: 我该自学还是报培训班呢? - -  我本人更加赞同自学(你要知道去了公司可没人手把手教你了,而且几乎所有的公司都对培训班出生的有偏见。为什么有偏见,你学个东西还要去培训班,说明什么,同等水平下,你的自学能力以及自律能力一定是比不上自学的人的)。但是如果,你连每天在寝室坚持学上8个小时以上都坚持不了,或者总是容易半途而废的话,我还是推荐你去培训班。观望身边同学去培训班的,大多是非计算机专业或者是没有自律能力以及自学能力非常差的人。 - -  另外,如果自律能力不行,你也可以通过结伴学习、参加老师的项目等方式来督促自己学习。 - -  总结:去不去培训班主要还是看自己,如果自己能坚持自学就自学,坚持不下来就去培训班。 - -### Question6: 没有项目经历/博客/Github开源项目怎么办? - -  从现在开始做! - -  网上有很多非常不错的项目视频,你就跟着一步一步做,不光要做,还要改进,改善。另外,如果你的老师有相关 Java 后台项目的话,你也可以主动申请参与进来。 - -  如果有自己的博客,也算是简历上的一个亮点。建议可以在掘金、Segmentfault、CSDN等技术交流社区写博客,当然,你也可以自己搭建一个博客(采用 Hexo+Githu Pages 搭建非常简单)。写一些什么?学习笔记、实战内容、读书笔记等等都可以。 - -  多用 Github,用好 Github,上传自己不错的项目,写好 readme 文档,在其他技术社区做好宣传。相信你也会收获一个不错的开源项目! - - -### Question7: 大厂到底青睐什么样的应届生? - -  从阿里、腾讯等大厂招聘官网对于Java后端方向/后端方向的应届实习生的要求,我们大概可以总结归纳出下面这 4 点能给简历增加很多分数: - -- 参加过竞赛(含金量超高的是ACM); -- 对数据结构与算法非常熟练; -- 参与过实际项目(比如学校网站); -- 参与过某个知名的开源项目或者自己的某个开源项目很不错; - -  除了我上面说的这三点,在面试Java工程师的时候,下面几点也提升你的个人竞争力: - -- 熟悉Python、Shell、Perl等脚本语言; -- 熟悉 Java 优化,JVM调优; -- 熟悉 SOA 模式; -- 熟悉自己所用框架的底层知识比如Spring; -- 了解分布式一些常见的理论; -- 具备高并发开发经验;大数据开发经验等等。 - From efe8d4770f1e117a6e447b886a251fb116db0ba3 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 11:30:54 +0800 Subject: [PATCH 056/232] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 37796204be4..54933109bb9 100644 --- a/README.md +++ b/README.md @@ -166,8 +166,9 @@ * [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) * [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) -* [【备战面试3】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) -* [【备战面试4】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团面试常见问题总结.md) +* [【备战面试3】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/JavaGuide/blob/master/面试必备/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) +* [【备战面试5】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团面试常见问题总结.md) ### 最最最常见的Java面试题总结 @@ -187,7 +188,6 @@ * [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) * [结束了我短暂的秋招,说点自己的感受](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [这7个问题,可能大部分Java程序员都比较关心吧!](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/java%20programmer%20need%20know.md) * [【2018总结】即使平凡,也要热爱自己的生活](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20summary.md) * [Java项目 Github Trending 月榜](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/JavaGithubTrending.md) From a37eec46726fbae16148f56976cfb5dc60f7f834 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 11:31:59 +0800 Subject: [PATCH 057/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54933109bb9..72f8601fc1b 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ * [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) * [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) -* [【备战面试3】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/JavaGuide/blob/master/面试必备/JavaProgrammerNeedKnow.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/面试必备/JavaProgrammerNeedKnow.md) * [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) * [【备战面试5】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团面试常见问题总结.md) From 8f1c6a107804697b6d8d5929b8057e08651db26a Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 11:36:02 +0800 Subject: [PATCH 058/232] Update JavaGithubTrending.md --- .../JavaGithubTrending/JavaGithubTrending.md" | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" "b/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" index 203710cb8af..229f6d2bdef 100644 --- "a/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" +++ "b/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" @@ -1,2 +1,4 @@ -### 2019 年一月 +- [2018 年 12 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2018-12.md) +- [2019 年 1 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2019-1.md) +- [2019 年 2 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2019-2.md) From 9f1fcc236aad537812c517f1171497bcac4c8f99 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 15:30:27 +0800 Subject: [PATCH 059/232] Update LinkedList.md --- "Java\347\233\270\345\205\263/LinkedList.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/LinkedList.md" "b/Java\347\233\270\345\205\263/LinkedList.md" index 15f67f88a00..31f5f4838e9 100644 --- "a/Java\347\233\270\345\205\263/LinkedList.md" +++ "b/Java\347\233\270\345\205\263/LinkedList.md" @@ -288,7 +288,7 @@ public int lastIndexOf(Object o) { return indexOf(o) != -1; } ``` -###删除方法 +### 删除方法 **remove()** ,**removeFirst(),pop():** 删除头节点 ``` public E pop() { From ddbb405b87b5e26c0821d0104a3fc67435f8acc8 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 15:43:15 +0800 Subject: [PATCH 060/232] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86->=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...272\347\241\200\347\237\245\350\257\206.md" | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 57fa9906fad..68549209747 100644 --- "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -412,9 +412,9 @@ final关键字主要用在三个地方:变量、方法、类。 ### 异常处理总结 -- try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。 -- catch 块:用于处理try捕获到的异常。 -- finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。 +- **try 块:**用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。 +- **catch 块:**用于处理try捕获到的异常。 +- **finally 块:**无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。 **在以下4种特殊情况下,finally块不会被执行:** @@ -423,6 +423,18 @@ final关键字主要用在三个地方:变量、方法、类。 3. 程序所在的线程死亡。 4. 关闭CPU。 +下面这部分内容来自issue:。 + +**关于返回值:** + +如果try语句里有return,返回的是try语句块中变量值。 +详细执行过程如下: + +1. 如果有返回值,就把返回值保存到局部变量中; +2. 执行jsr指令跳到finally语句里执行; +3. 执行完finally语句后,返回之前保存在局部变量表里的值。 +4. 如果try,finally语句里均有return,忽略try的return,而使用finally的return. + ## 33 Java序列化中如果有些字段不想进行序列化 怎么办 对于不想进行序列化的变量,使用transient关键字修饰。 From 940982ebffa5f376b6baddeaf9ed41c91217a6b6 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 15:45:25 +0800 Subject: [PATCH 061/232] =?UTF-8?q?Add=20=E8=AE=BE=E8=AE=A1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F->=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 72f8601fc1b..b85c09e1bd1 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ * [Java 多线程](#java-多线程) * [Java BIO,NIO,AIO](#java-bionioaio) * [Java 虚拟机 jvm](#java-虚拟机-jvm) + * [设计模式](#设计模式) * [:open_file_folder: 数据结构与算法](#open_file_folder-数据结构与算法) * [数据结构](#数据结构) * [算法](#算法) From 27c9cc2b18d08de60878c11de6b755da3af938fb Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 16:34:51 +0800 Subject: [PATCH 062/232] =?UTF-8?q?Update=20=E8=AE=BE=E8=AE=A1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E6=94=B9=E7=89=88=E4=B8=8E=E5=86=85=E5=AE=B9=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...76\350\256\241\346\250\241\345\274\217.md" | 106 ++++++------------ 1 file changed, 32 insertions(+), 74 deletions(-) diff --git "a/Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" "b/Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" index c36bb237ee5..e3e95860529 100644 --- "a/Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" +++ "b/Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" @@ -1,36 +1,28 @@ +# Java 设计模式 + 下面是自己学习设计模式的时候做的总结,有些是自己的原创文章,有些是网上写的比较好的文章,保存下来细细消化吧! -## 创建型模式: +**系列文章推荐:** + +## 创建型模式 -> ### 创建型模式概述: +### 创建型模式概述 - 创建型模式(Creational Pattern)对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共同的接口,而不清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。 - 创建型模式在创建什么(What),由谁创建(Who),何时创建(When)等方面都为软件设计者提供了尽可能大的灵活性。创建型模式隐藏了类的实例的创建细节,通过隐藏对象如何被创建和组合在一起达到使整个系统独立的目的。 ![创建型模式](https://user-gold-cdn.xitu.io/2018/6/16/1640641afcb7559b?w=491&h=241&f=png&s=51443) -> ### 创建型模式系列文章推荐: - -- **单例模式:** - -[深入理解单例模式——只有一个实例](https://blog.csdn.net/qq_34337272/article/details/80455972) - -- **工厂模式:** - -[深入理解工厂模式——由对象工厂生成对象](https://blog.csdn.net/qq_34337272/article/details/80472071) - -- **建造者模式:** - -[深入理解建造者模式 ——组装复杂的实例](http://blog.csdn.net/qq_34337272/article/details/80540059) - -- **原型模式:** +### 常见创建型模式详解 -[深入理解原型模式 ——通过复制生成实例](https://blog.csdn.net/qq_34337272/article/details/80706444) +- **单例模式:** [深入理解单例模式——只有一个实例](https://blog.csdn.net/qq_34337272/article/details/80455972) +- **工厂模式:** [深入理解工厂模式——由对象工厂生成对象](https://blog.csdn.net/qq_34337272/article/details/80472071) +- **建造者模式:** [深入理解建造者模式 ——组装复杂的实例](http://blog.csdn.net/qq_34337272/article/details/80540059) +- **原型模式:** [深入理解原型模式 ——通过复制生成实例](https://blog.csdn.net/qq_34337272/article/details/80706444) +## 结构型模式 -## 结构型模式: - -> ### 结构型模式概述: +### 结构型模式概述 - **结构型模式(Structural Pattern):** 描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构 ![结构型模式(Structural Pattern)](https://user-gold-cdn.xitu.io/2018/6/16/164064d6b3c205e3?w=719&h=233&f=png&s=270293) @@ -40,48 +32,25 @@ ![结构型模式](https://user-gold-cdn.xitu.io/2018/6/16/1640655459d766d2?w=378&h=266&f=png&s=59652) -> ### 结构型模式系列文章推荐: +### 常见结构型模式详解 - **适配器模式:** - -[深入理解适配器模式——加个“适配器”以便于复用](https://segmentfault.com/a/1190000011856448) - -[适配器模式原理及实例介绍-IBM](https://www.ibm.com/developerworks/cn/java/j-lo-adapter-pattern/index.html) - -- **桥接模式:** - -[设计模式笔记16:桥接模式(Bridge Pattern)](https://blog.csdn.net/yangzl2008/article/details/7670996) - -- **组合模式:** - -[大话设计模式—组合模式](https://blog.csdn.net/lmb55/article/details/51039781) - -- **装饰模式:** - -[java模式—装饰者模式](https://www.cnblogs.com/chenxing818/p/4705919.html) - -[Java设计模式-装饰者模式](https://blog.csdn.net/cauchyweierstrass/article/details/48240147) - -- **外观模式:** - -[java设计模式之外观模式(门面模式)](https://www.cnblogs.com/lthIU/p/5860607.html) - -- **享元模式:** - -[享元模式](http://www.jasongj.com/design_pattern/flyweight/) - + - [深入理解适配器模式——加个“适配器”以便于复用](https://segmentfault.com/a/1190000011856448) + - [适配器模式原理及实例介绍-IBM](https://www.ibm.com/developerworks/cn/java/j-lo-adapter-pattern/index.html) +- **桥接模式:** [设计模式笔记16:桥接模式(Bridge Pattern)](https://blog.csdn.net/yangzl2008/article/details/7670996) +- **组合模式:** [大话设计模式—组合模式](https://blog.csdn.net/lmb55/article/details/51039781) +- **装饰模式:** [java模式—装饰者模式](https://www.cnblogs.com/chenxing818/p/4705919.html)、[Java设计模式-装饰者模式](https://blog.csdn.net/cauchyweierstrass/article/details/48240147) +- **外观模式:** [java设计模式之外观模式(门面模式)](https://www.cnblogs.com/lthIU/p/5860607.html) +- **享元模式:** [享元模式](http://www.jasongj.com/design_pattern/flyweight/) - **代理模式:** - -[代理模式原理及实例讲解 (IBM出品,很不错)](https://www.ibm.com/developerworks/cn/java/j-lo-proxy-pattern/index.html) - -[轻松学,Java 中的代理模式及动态代理](https://blog.csdn.net/briblue/article/details/73928350) - -[Java代理模式及其应用](https://blog.csdn.net/justloveyou_/article/details/74203025) + - [代理模式原理及实例讲解 (IBM出品,很不错)](https://www.ibm.com/developerworks/cn/java/j-lo-proxy-pattern/index.html) + - [轻松学,Java 中的代理模式及动态代理](https://blog.csdn.net/briblue/article/details/73928350) + - [Java代理模式及其应用](https://blog.csdn.net/justloveyou_/article/details/74203025) ## 行为型模式 -> ### 行为型模式概述: +### 行为型模式概述 - 行为型模式(Behavioral Pattern)是对在不同的对象之间划分责任和算法的抽象化。 - 行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。 @@ -95,27 +64,16 @@ ![行为型模式](https://user-gold-cdn.xitu.io/2018/6/28/164467dd92c6172c?w=453&h=269&f=png&s=63270) - **职责链模式:** - -[Java设计模式之责任链模式、职责链模式](https://blog.csdn.net/jason0539/article/details/45091639) - -[责任链模式实现的三种方式](https://www.cnblogs.com/lizo/p/7503862.html) - -- **命令模式:** - - - -- **解释器模式:** +- [Java设计模式之责任链模式、职责链模式](https://blog.csdn.net/jason0539/article/details/45091639) +- [责任链模式实现的三种方式](https://www.cnblogs.com/lizo/p/7503862.html) +- **命令模式:** 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。 +- **解释器模式:** - **迭代器模式:** - **中介者模式:** - **备忘录模式:** -- **观察者模式:** - -观察者模式也是非常常用的设计模式,下面这个博客简单介绍了观察者模式的简单定义、解决了一个什么问题,用一个气象站和气象看板的例子去描述一对多的关系中观察者模式的应用,并且还介绍了jdk内置的观察者模式接口。 - -[Java设计模式之观察者模式](https://zhanglijun1217.github.io/blog/2018/12/24/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E2%80%94%E2%80%94%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F-md/) - -- **状态模式:** -- **策略模式:** +- **观察者模式:** +- **状态模式:** +- **策略模式:** 策略模式作为设计原则中开闭原则最典型的体现,也是经常使用的。下面这篇博客介绍了策略模式一般的组成部分和概念,并用了一个小demo去说明了策略模式的应用。 From ac8281c70eb058e989b17b33e768cf57ced8a4ff Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 16:54:13 +0800 Subject: [PATCH 063/232] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b85c09e1bd1..342a1586617 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ ## 待办 * [ ] Java 8 新特性总结 +* [ ] Java 多线程类别知识重构 * [x] BIO,NIO,AIO 总结 * [ ] Netty 总结 * [ ] 数据结构总结重构 From f96aaa0c805e6ecaaddf795be7bbe109bfb8a357 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 16:54:40 +0800 Subject: [PATCH 064/232] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 342a1586617..352c4659d68 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,6 @@ ### Java 多线程 -* [多线程系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/多线程系列.md) * [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/synchronized.md) * [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/面试必备之乐观锁与悲观锁.md) * [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/Atomic.md) From 24b1842fb4ebbdfee56c1ede0899b65349721e2e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 18:02:47 +0800 Subject: [PATCH 065/232] Update Atomic.md --- "Java\347\233\270\345\205\263/Multithread/Atomic.md" | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git "a/Java\347\233\270\345\205\263/Multithread/Atomic.md" "b/Java\347\233\270\345\205\263/Multithread/Atomic.md" index 5c794055b0c..33dd7ef3d9b 100644 --- "a/Java\347\233\270\345\205\263/Multithread/Atomic.md" +++ "b/Java\347\233\270\345\205\263/Multithread/Atomic.md" @@ -20,7 +20,7 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是 使用原子的方式更新基本类型 -- AtomicInteger:整形原子类 +- AtomicInteger:整型原子类 - AtomicLong:长整型原子类 - AtomicBoolean :布尔型原子类 @@ -29,8 +29,8 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是 使用原子的方式更新数组里的某个元素 -- AtomicIntegerArray:整形数组原子类 -- AtomicLongArray:长整形数组原子类 +- AtomicIntegerArray:整型数组原子类 +- AtomicLongArray:长整型数组原子类 - AtomicReferenceArray :引用类型数组原子类 **引用类型** @@ -41,8 +41,8 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是 **对象的属性修改类型** -- AtomicIntegerFieldUpdater:原子更新整形字段的更新器 -- AtomicLongFieldUpdater:原子更新长整形字段的更新器 +- AtomicIntegerFieldUpdater:原子更新整型字段的更新器 +- AtomicLongFieldUpdater:原子更新长整型字段的更新器 - AtomicStampedReference :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。 下面我们来详细介绍一下这些原子类。 @@ -53,7 +53,7 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是 使用原子的方式更新基本类型 -- AtomicInteger:整形原子类 +- AtomicInteger:整型原子类 - AtomicLong:长整型原子类 - AtomicBoolean :布尔型原子类 From 0df0d81e5e760116280e5b837db09a49bdd4630f Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 5 Mar 2019 18:04:31 +0800 Subject: [PATCH 066/232] =?UTF-8?q?Fix=20=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Java\347\233\270\345\205\263/Multithread/AQS.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/Multithread/AQS.md" "b/Java\347\233\270\345\205\263/Multithread/AQS.md" index 3717be6c260..f405db1f17d 100644 --- "a/Java\347\233\270\345\205\263/Multithread/AQS.md" +++ "b/Java\347\233\270\345\205\263/Multithread/AQS.md" @@ -37,7 +37,7 @@ AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效 ### 2 AQS 原理 -> 在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于AQS原理的理解”。下面给大家一个示例供大家参加,面试不是背题,大家一定要假如自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。 +> 在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于AQS原理的理解”。下面给大家一个示例供大家参加,面试不是背题,大家一定要加入自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。 下面大部分内容其实在AQS类注释上已经给出了,不过是英语看着比较吃力一点,感兴趣的话可以看看源码。 From 55f795eaa88f3eeee3edc53a8fc30c8026d0229e Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 5 Mar 2019 18:16:03 +0800 Subject: [PATCH 067/232] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86->=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 68549209747..6b73f6e6951 100644 --- "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -418,8 +418,8 @@ final关键字主要用在三个地方:变量、方法、类。 **在以下4种特殊情况下,finally块不会被执行:** -1. 在finally语句块中发生了异常。 -2. 在前面的代码中用了System.exit()退出程序。 +1. 在finally语句块第一行发生了异常。 因为在其他行,finally块还是会得到执行 +2. 在前面的代码中用了System.exit(int)已退出程序。 exit是带参函数 ;若该语句在异常语句之后,finally会执行 3. 程序所在的线程死亡。 4. 关闭CPU。 From eef1a519a8b0ead793128909f888f5947e8bbd17 Mon Sep 17 00:00:00 2001 From: forsweet Date: Wed, 6 Mar 2019 11:55:23 +0800 Subject: [PATCH 068/232] =?UTF-8?q?fix=20topic=E7=B1=BB=E5=9E=8B=E9=80=9A?= =?UTF-8?q?=E9=85=8D=E7=AC=A6=E5=8F=B7=E8=AF=B4=E6=98=8E=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rabbitmq.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" index 7b1508f456c..1ac6504c530 100644 --- "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" @@ -123,7 +123,7 @@ direct 类型常用在处理有优先级的任务,根据任务的优先级把 - RoutingKey 为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词),如 “com.rabbitmq.client”、“java.util.concurrent”、“com.hidden.client”; - BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串; -- BindingKey 中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“#”用于匹配一个单词,“#”用于匹配多规格单词(可以是零个)。 +- BindingKey 中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“.”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。 ![topic 类型交换器](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-16/73843.jpg) From ff4e445583bf777985a51efda033787ff10f9cc5 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Wed, 6 Mar 2019 13:38:35 +0800 Subject: [PATCH 069/232] =?UTF-8?q?Update=20Java=E5=86=85=E5=AD=98?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java内存区域图片我重新画了一遍! --- ...32\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index 5235ba73159..b208daf581e 100644 --- "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -115,7 +115,7 @@ HotSpot 虚拟机中方法区也常被称为 **“永久代”**,本质上两 ### 2.7 直接内存 -直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致OutOfMemoryError异常出现。 +直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 异常出现。 JDK1.4中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通道(Channel)** 与**缓存区(Buffer)** 的 I/O 方式,它可以直接使用Native函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为**避免了在 Java 堆和 Native 堆之间来回复制数据**。 @@ -139,7 +139,7 @@ JDK1.4中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通 选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是"标记-清除",还是"标记-整理"(也称作"标记-压缩"),值得注意的是,复制算法内存也是规整的 ![](https://user-gold-cdn.xitu.io/2018/8/22/16561e59a40a2c3d?w=1426&h=333&f=png&s=26346) - + **内存分配并发问题(补充内容,需要掌握)** 在创建对象的时候有一个很重要的问题,就是线程安全,因为在实际开发过程中,创建对象是很频繁的事情,作为虚拟机来说,必须要保证线程是安全的,通常来讲,虚拟机采用两种方式来保证线程安全: From d3bb1ffedc5b8b6f9c7a09fd68bb45dc6e1a176c Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Wed, 6 Mar 2019 13:40:53 +0800 Subject: [PATCH 070/232] =?UTF-8?q?Update=20Java=E5=86=85=E5=AD=98?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java内存区域图片我重新画了一遍! --- ...232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index b208daf581e..61d5e722174 100644 --- "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -21,7 +21,8 @@ ## 2 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 -![运行时数据区域](https://user-gold-cdn.xitu.io/2018/4/27/16306a34cd8a4354?w=513&h=404&f=png&s=132068) +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/JVM运行时数据区域.png) + 这些组成部分一些是线程私有的,其他的则是线程共享的。 **线程私有的:** From 09ef847fcd0e9241eb41b460449c74f2c65e360b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 6 Mar 2019 16:33:40 +0800 Subject: [PATCH 071/232] =?UTF-8?q?Add=20QQ=E7=BE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 352c4659d68..79c65f155b9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Java 学习/面试指南 +[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-959442351-blue.svg)](https://jq.qq.com/?_wv=1027&k=5tjF8vk). +

From 8e6c79940e5063d87ef44e93950ea0ccb0a94c4b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 6 Mar 2019 19:50:03 +0800 Subject: [PATCH 072/232] =?UTF-8?q?Update:QQ=E7=BE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79c65f155b9..17eeb6ed1c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Java 学习/面试指南 -[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-959442351-blue.svg)](https://jq.qq.com/?_wv=1027&k=5tjF8vk). +工作一年以上的朋友可以加这个群,群内有免费Java进阶架构师资料:[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-959442351-blue.svg)](https://jq.qq.com/?_wv=1027&k=5tjF8vk).
From 7368e2f7c4ff2cfd27fc0c464d71310a93e7e293 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Thu, 7 Mar 2019 13:20:43 +0800 Subject: [PATCH 073/232] =?UTF-8?q?Update=20=E7=BA=BF=E7=A8=8B=E6=9C=89?= =?UTF-8?q?=E5=93=AA=E4=BA=9B=E7=8A=B6=E6=80=81=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...272\347\241\200\347\237\245\350\257\206.md" | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 6b73f6e6951..8b438eb18f8 100644 --- "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -370,16 +370,26 @@ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返 ## 30. 线程有哪些基本状态? -参考《Java 并发编程艺术》4.1.4节。 - -Java 线程在运行的生命周期中的指定时刻只可能处于下面6种不同状态的其中一个状态。 +Java 线程在运行的生命周期中的指定时刻只可能处于下面6种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4节)。 ![Java线程的状态](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%E7%BA%BF%E7%A8%8B%E7%9A%84%E7%8A%B6%E6%80%81.png) -线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示: +线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4节): ![Java线程状态变迁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%20%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81.png) + + +由上图可以看出: + +线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 cpu 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。 + +> 操作系统隐藏 Java虚拟机(JVM)中的 RUNNABLE 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinjava.com/):[Java Thread Life Cycle and Thread States](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/)),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 + +![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png) + +当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)**状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的` run() `方法之后将会进入到 **TERMINATED(终止)** 状态。 + ## 31 关于 final 关键字的一些总结 final关键字主要用在三个地方:变量、方法、类。 From 893f4a5a801f4fe82cd067219ca9a22bdec42009 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 7 Mar 2019 14:58:16 +0800 Subject: [PATCH 074/232] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 17eeb6ed1c1..352c4659d68 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Java 学习/面试指南 -工作一年以上的朋友可以加这个群,群内有免费Java进阶架构师资料:[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-959442351-blue.svg)](https://jq.qq.com/?_wv=1027&k=5tjF8vk). -

From 47a005ca55143cf797e0b7e828b4a2884b6b9708 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 16:01:21 +0800 Subject: [PATCH 075/232] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 352c4659d68..8aef7455edf 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! +4. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 +5. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 4. **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 -为了优化大家的阅读体验,我重新进行了排版,并且增加了较为详细的[目录](#目录)供大家参考!对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。另外, 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 - ## 目录 * [:coffee: Java](#coffee-java) From 0701ac27b40cb3b1ed832e3c32b4251ca6319145 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:03:48 +0800 Subject: [PATCH 076/232] =?UTF-8?q?Create=20=E7=AC=AC=E4=B8=80=E5=91=A8?= =?UTF-8?q?=EF=BC=882018-8-7=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- ...21\250\357\274\2102018-8-7\357\274\211.md" | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" new file mode 100644 index 00000000000..4ca58dbfff6 --- /dev/null +++ "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" @@ -0,0 +1,253 @@ + + +## 一 为什么 Java 中只有值传递? + + +首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。**按值调用(call by value)表示方法接收的是调用者提供的值,而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。** 它用来描述各种程序设计语言(不只是Java)中方法参数传递方式。 + +**Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。** + +**下面通过 3 个例子来给大家说明** + +### example 1 + + +```java +public static void main(String[] args) { + int num1 = 10; + int num2 = 20; + + swap(num1, num2); + + System.out.println("num1 = " + num1); + System.out.println("num2 = " + num2); +} + +public static void swap(int a, int b) { + int temp = a; + a = b; + b = temp; + + System.out.println("a = " + a); + System.out.println("b = " + b); +} +``` + +**结果:** + +``` +a = 20 +b = 10 +num1 = 10 +num2 = 20 +``` + +**解析:** + +![example 1 ](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/22191348.jpg) + +在swap方法中,a、b的值进行交换,并不会影响到 num1、num2。因为,a、b中的值,只是从 num1、num2 的复制过来的。也就是说,a、b相当于num1、num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。 + +**通过上面例子,我们已经知道了一个方法不能修改一个基本数据类型的参数,而对象引用作为参数就不一样,请看 example2.** + + +### example 2 + +```java + public static void main(String[] args) { + int[] arr = { 1, 2, 3, 4, 5 }; + System.out.println(arr[0]); + change(arr); + System.out.println(arr[0]); + } + + public static void change(int[] array) { + // 将数组的第一个元素变为0 + array[0] = 0; + } +``` + +**结果:** + +``` +1 +0 +``` + +**解析:** + +![example 2](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/3825204.jpg) + +array 被初始化 arr 的拷贝也就是一个对象的引用,也就是说 array 和 arr 指向的时同一个数组对象。 因此,外部对引用对象的改变会反映到所对应的对象上。 + + +**通过 example2 我们已经看到,实现一个改变对象参数状态的方法并不是一件难事。理由很简单,方法得到的是对象引用的拷贝,对象引用及其他的拷贝同时引用同一个对象。** + +**很多程序设计语言(特别是,C++和Pascal)提供了两种参数传递的方式:值调用和引用调用。有些程序员(甚至本书的作者)认为Java程序设计语言对对象采用的是引用调用,实际上,这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题。** + + +### example 3 + +```java +public class Test { + + public static void main(String[] args) { + // TODO Auto-generated method stub + Student s1 = new Student("小张"); + Student s2 = new Student("小李"); + Test.swap(s1, s2); + System.out.println("s1:" + s1.getName()); + System.out.println("s2:" + s2.getName()); + } + + public static void swap(Student x, Student y) { + Student temp = x; + x = y; + y = temp; + System.out.println("x:" + x.getName()); + System.out.println("y:" + y.getName()); + } +} +``` + +**结果:** + +``` +x:小李 +y:小张 +s1:小张 +s2:小李 +``` + +**解析:** + +交换之前: + +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/88729818.jpg) + +交换之后: + +![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/34384414.jpg) + + +通过上面两张图可以很清晰的看出: **方法并没有改变存储在变量 s1 和 s2 中的对象引用。swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝** + +### 总结 + +Java程序设计语言对对象采用的不是引用调用,实际上,对象引用是按 +值传递的。 + +下面再总结一下Java中方法参数的使用情况: + +- 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型》 +- 一个方法可以改变一个对象参数的状态。 +- 一个方法不能让对象参数引用一个新的对象。 + + +### 参考: + +《Java核心技术卷Ⅰ》基础知识第十版第四章4.5小节 + +## 二 ==与equals(重要) + +**==** : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) + +**equals()** : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: + +- 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。 +- 情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。 + + +**举个例子:** + +```java +public class test1 { + public static void main(String[] args) { + String a = new String("ab"); // a 为一个引用 + String b = new String("ab"); // b为另一个引用,对象的内容一样 + String aa = "ab"; // 放在常量池中 + String bb = "ab"; // 从常量池中查找 + if (aa == bb) // true + System.out.println("aa==bb"); + if (a == b) // false,非同一对象 + System.out.println("a==b"); + if (a.equals(b)) // true + System.out.println("aEQb"); + if (42 == 42.0) { // true + System.out.println("true"); + } + } +} +``` + +**说明:** + +- String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。 +- 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。 + + + +## 三 hashCode与equals(重要) + +面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” + +### hashCode()介绍 +hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。 + +```java + /** + * Returns a hash code value for the object. This method is + * supported for the benefit of hash tables such as those provided by + * {@link java.util.HashMap}. + *

+ * As much as is reasonably practical, the hashCode method defined by + * class {@code Object} does return distinct integers for distinct + * objects. (This is typically implemented by converting the internal + * address of the object into an integer, but this implementation + * technique is not required by the + * Java™ programming language.) + * + * @return a hash code value for this object. + * @see java.lang.Object#equals(java.lang.Object) + * @see java.lang.System#identityHashCode + */ + public native int hashCode(); +``` + +散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象) + +### 为什么要有hashCode + + +**我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:** + +当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。 + + + +### hashCode()与equals()的相关规定 + +1. 如果两个对象相等,则hashcode一定也是相同的 +2. 两个对象相等,对两个对象分别调用equals方法都返回true +3. 两个对象有相同的hashcode值,它们也不一定是相等的 +4. **因此,equals方法被覆盖过,则hashCode方法也必须被覆盖** +5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据) + +### 为什么两个对象有相同的hashcode值,它们也不一定是相等的? + +在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 + +因为hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。 + +我们刚刚也提到了 HashSet,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。 + +参考: + +[https://blog.csdn.net/zhzhao999/article/details/53449504](https://blog.csdn.net/zhzhao999/article/details/53449504) + +[https://www.cnblogs.com/skywang12345/p/3324958.html](https://www.cnblogs.com/skywang12345/p/3324958.html) + +[https://www.cnblogs.com/skywang12345/p/3324958.html](https://www.cnblogs.com/skywang12345/p/3324958.html) + +[https://www.cnblogs.com/Eason-S/p/5524837.html](https://www.cnblogs.com/Eason-S/p/5524837.html) + From ea129c1dbd1d714bfd33d5051848f6471ba1b4da Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:03:53 +0800 Subject: [PATCH 077/232] =?UTF-8?q?Create=20=E7=AC=AC=E4=BA=8C=E5=91=A8(20?= =?UTF-8?q?18-8-13).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- ...254\344\272\214\345\221\250(2018-8-13).md" | 200 ++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" new file mode 100644 index 00000000000..426498cb2d9 --- /dev/null +++ "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" @@ -0,0 +1,200 @@ + +### String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? + +#### String和StringBuffer、StringBuilder的区别 + +**可变性** +  + +简单的来说:String 类中使用 final 关键字字符数组保存字符串,`private final char value[]`,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串`char[]value` 但是没有用 final 关键字修饰,所以这两种对象都是可变的。 + +StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现的,大家可以自行查阅源码。 + +AbstractStringBuilder.java + +```java +abstract class AbstractStringBuilder implements Appendable, CharSequence { + char[] value; + int count; + AbstractStringBuilder() { + } + AbstractStringBuilder(int capacity) { + value = new char[capacity]; + } +``` + + +**线程安全性** + +String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。 +   + +**性能** + +每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。 + +**对于三者使用的总结:** +1. 操作少量的数据 = String +2. 单线程操作字符串缓冲区下操作大量数据 = StringBuilder +3. 多线程操作字符串缓冲区下操作大量数据 = StringBuffer + +#### String为什么是不可变的吗? +简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下图所以: + +```java + /** The value is used for character storage. */ + private final char value[]; +``` + +#### String真的是不可变的吗? +我觉得如果别人问这个问题的话,回答不可变就可以了。 +下面只是给大家看两个有代表性的例子: + +**1) String不可变但不代表引用不可以变** +```java + String str = "Hello"; + str = str + " World"; + System.out.println("str=" + str); +``` +结果: +``` +str=Hello World +``` +解析: + +实际上,原来String的内容是不变的,只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已,也就是说多开辟了一块内存区域给"Hello World"字符串。 + +**2) 通过反射是可以修改所谓的“不可变”对象** + +```java + // 创建字符串"Hello World", 并赋给引用s + String s = "Hello World"; + + System.out.println("s = " + s); // Hello World + + // 获取String类中的value字段 + Field valueFieldOfString = String.class.getDeclaredField("value"); + + // 改变value属性的访问权限 + valueFieldOfString.setAccessible(true); + + // 获取s对象上的value属性的值 + char[] value = (char[]) valueFieldOfString.get(s); + + // 改变value所引用的数组中的第5个字符 + value[5] = '_'; + + System.out.println("s = " + s); // Hello_World +``` + +结果: + +``` +s = Hello World +s = Hello_World +``` + +解析: + +用反射可以访问私有成员, 然后反射出String对象中的value属性, 进而改变通过获得的value引用改变数组的结构。但是一般我们不会这么做,这里只是简单提一下有这个东西。 + +### 什么是反射机制?反射机制的应用场景有哪些? + +#### 反射机制介绍 + +JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 + +#### 静态编译和动态编译 + +- **静态编译:**在编译时确定类型,绑定对象 +- **动态编译:**运行时确定类型,绑定对象 + +#### 反射机制优缺点 + +- **优点:** 运行期类型的判断,动态加载类,提高代码灵活度。 +- **缺点:** 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。 + +#### 反射的应用场景 + +反射是框架设计的灵魂。 + +在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。 + +举例:①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML 或 Properties 配置文件加载入内存中; + 2)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息; 3)使用反射机制,根据这个字符串获得某个类的Class实例; 4)动态配置实例的属性 + +**推荐阅读:** + +- [Reflection:Java反射机制的应用场景](https://segmentfault.com/a/1190000010162647?utm_source=tuicool&utm_medium=referral) +- [Java基础之—反射(非常重要)](https://blog.csdn.net/sinat_38259539/article/details/71799078) +### 什么是JDK?什么是JRE?什么是JVM?三者之间的联系与区别 + +这几个是Java中很基本很基本的东西,但是我相信一定还有很多人搞不清楚!为什么呢?因为我们大多数时候在使用现成的编译工具以及环境的时候,并没有去考虑这些东西。 + +**JDK:** 顾名思义它是给开发者提供的开发工具箱,是给程序开发者用的。它除了包括完整的JRE(Java Runtime Environment),Java运行环境,还包含了其他供开发者使用的工具包。 + +**JRE:** 普通用户而只需要安装JRE(Java Runtime Environment)来运行Java程序。而程序开发者必须安装JDK来编译、调试程序。 + +**JVM:** 当我们运行一个程序时,JVM负责将字节码转换为特定机器代码,JVM提供了内存管理/垃圾回收和安全机制等。这种独立于硬件和操作系统,正是java程序可以一次编写多处执行的原因。 + +**区别与联系:** + + 1. JDK用于开发,JRE用于运行java程序 ; + 2. JDK和JRE中都包含JVM ; + 3. JVM是java编程语言的核心并且具有平台独立性。 + +### 什么是字节码?采用字节码的最大好处是什么? + +**先看下java中的编译器和解释器:**    + +Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做`字节码`(即扩展名为`.class`的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。这也就是解释了Java的编译与解释并存的特点。 + + Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器----->机器可执行的二进制机器码---->程序运行。 + +**采用字节码的好处:**    + +Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。 + +### Java和C++的区别 + +我知道很多人没学过C++,但是面试官就是没事喜欢拿咱们Java和C++比呀!没办法!!!就算没学过C++,也要记下来! + +- 都是面向对象的语言,都支持封装、继承和多态 +- Java不提供指针来直接访问内存,程序内存更加安全 +- Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。 +- Java有自动内存管理机制,不需要程序员手动释放无用内存 + + +### 接口和抽象类的区别是什么? + +1. 接口的方法默认是public,所有方法在接口中不能有实现,抽象类可以有非抽象的方法 +2. 接口中的实例变量默认是final类型的,而抽象类中则不一定 +3. 一个类可以实现多个接口,但最多只能实现一个抽象类 +4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定 +5. 接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。 + +注意:Java8 后接口可以有默认实现( default )。 + +### 成员变量与局部变量的区别有那些? + +1. 从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public,private,static等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰;但是,成员变量和局部变量都能被final所修饰; +2. 从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存 +3. 从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。 +4. 成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被final修饰但没有被static修饰的成员变量必须显示地赋值);而局部变量则不会自动赋值。 + +### 重载和重写的区别 + +**重载:** 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。    + +**重写:** 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。 + +### 字符型常量和字符串常量的区别 +1) 形式上: +字符常量是单引号引起的一个字符 +字符串常量是双引号引起的若干个字符 +2) 含义上: +字符常量相当于一个整形值(ASCII值),可以参加表达式运算 +字符串常量代表一个地址值(该字符串在内存中存放位置) +3) 占内存大小 +字符常量只占一个字节 +字符串常量占若干个字节(至少一个字符结束标志) From bc4cec733f38fe334223369ba8d2a6e3aea36e9e Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:03:58 +0800 Subject: [PATCH 078/232] =?UTF-8?q?Create=20=E7=AC=AC=E5=9B=9B=E5=91=A8(20?= =?UTF-8?q?18-8-30).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- ...254\345\233\233\345\221\250(2018-8-30).md" | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" new file mode 100644 index 00000000000..3cb02d73d5b --- /dev/null +++ "b/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" @@ -0,0 +1,195 @@ + +## 1. 简述线程,程序、进程的基本概念。以及他们之间关系是什么? + +**线程**与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。 + +**程序**是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。 + +**进程**是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 + +**线程** 是 **进程** 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。 + +**线程上下文的切换比进程上下文切换要快很多** + +- 进程切换时,涉及到当前进程的CPU环境的保存和新被调度运行进程的CPU环境的设置。 +- 线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。 + +## 2. 线程有哪些基本状态?这些状态是如何定义的? + +1. **新建(new)**:新创建了一个线程对象。 +2. **可运行(runnable)**:线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取cpu的使用权。 +3. **运行(running)**:可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。 +4. **阻塞(block)**:阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。阻塞的情况分三种: + - **(一). 等待阻塞**:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waiting queue)中。 + - **(二). 同步阻塞**:运行(running)的线程在获取对象的同步锁时,若该同步 锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。 + - **(三). 其他阻塞**: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。 +5. **死亡(dead)**:线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。 + +![](https://user-gold-cdn.xitu.io/2018/8/9/1651f19d7c4e93a3?w=876&h=492&f=png&s=128092) + +备注: 可以用早起坐地铁来比喻这个过程(下面参考自牛客网某位同学的回答): + +1. 还没起床:sleeping +2. 起床收拾好了,随时可以坐地铁出发:Runnable +3. 等地铁来:Waiting +4. 地铁来了,但要排队上地铁:I/O阻塞 +5. 上了地铁,发现暂时没座位:synchronized阻塞 +6. 地铁上找到座位:Running +7. 到达目的地:Dead + + +## 3. 何为多线程? + +多线程就是多个线程同时运行或交替运行。单核CPU的话是顺序执行,也就是交替运行。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行。 + + +## 4. 为什么多线程是必要的? + +1. 使用线程可以把占据长时间的程序中的任务放到后台去处理。 +2. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。 +3. 程序的运行速度可能加快。 + +## 5 使用多线程常见的三种方式 + +### ①继承Thread类 + +MyThread.java + +```java +public class MyThread extends Thread { + @Override + public void run() { + super.run(); + System.out.println("MyThread"); + } +} +``` +Run.java + +```java +public class Run { + + public static void main(String[] args) { + MyThread mythread = new MyThread(); + mythread.start(); + System.out.println("运行结束"); + } + +} + +``` +运行结果: +![结果](https://user-gold-cdn.xitu.io/2018/3/20/16243e80f22a2d54?w=161&h=54&f=jpeg&s=7380) +从上面的运行结果可以看出:线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法。 + +### ②实现Runnable接口 +推荐实现Runnable接口方式开发多线程,因为Java单继承但是可以实现多个接口。 + +MyRunnable.java + +```java +public class MyRunnable implements Runnable { + @Override + public void run() { + System.out.println("MyRunnable"); + } +} +``` + +Run.java + +```java +public class Run { + + public static void main(String[] args) { + Runnable runnable=new MyRunnable(); + Thread thread=new Thread(runnable); + thread.start(); + System.out.println("运行结束!"); + } + +} +``` +运行结果: +![运行结果](https://user-gold-cdn.xitu.io/2018/3/20/16243f4373c6141a?w=137&h=46&f=jpeg&s=7316) + +### ③使用线程池 + +**在《阿里巴巴Java开发手册》“并发处理”这一章节,明确指出线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。** + +**为什么呢?** + +> **使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源开销,解决资源不足的问题。如果不使用线程池,有可能会造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。** + +**另外《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险** + +> Executors 返回线程池对象的弊端如下: +> +> - **FixedThreadPool 和 SingleThreadExecutor** : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。 +> - **CachedThreadPool 和 ScheduledThreadPool** : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。 + +对于线程池感兴趣的可以查看我的这篇文章:[《Java多线程学习(八)线程池与Executor 框架》](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484042&idx=1&sn=541dbf2cb969a151d79f4a4f837ee1bd&chksm=fd9854ebcaefddfd1876bb96ab218be3ae7b12546695a403075d4ed22e5e17ff30ebdabc8bbf#rd) 点击阅读原文即可查看到该文章的最新版。 + + +## 6 线程的优先级 + +每个线程都具有各自的优先级,**线程的优先级可以在程序中表明该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态**。但这个并不意味着低 +优先级的线程得不到运行,而只是它运行的几率比较小,如垃圾回收机制线程的优先级就比较低。所以很多垃圾得不到及时的回收处理。 + +**线程优先级具有继承特性。** 比如A线程启动B线程,则B线程的优先级和A是一样的。 + +**线程优先级具有随机性。** 也就是说线程优先级高的不一定每一次都先执行完。 + +Thread类中包含的成员变量代表了线程的某些优先级。如**Thread.MIN_PRIORITY(常数1)**,**Thread.NORM_PRIORITY(常数5)**, +**Thread.MAX_PRIORITY(常数10)**。其中每个线程的优先级都在**Thread.MIN_PRIORITY(常数1)** 到**Thread.MAX_PRIORITY(常数10)** 之间,在默认情况下优先级都是**Thread.NORM_PRIORITY(常数5)**。 + +学过操作系统这门课程的话,我们可以发现多线程优先级或多或少借鉴了操作系统对进程的管理。 + + +## 7 Java多线程分类 + +### 用户线程 + +运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程 + +### 守护线程 + +运行在后台,为其他前台线程服务.也可以说守护线程是JVM中非守护线程的 **“佣人”**。 + + +- **特点:** 一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作 +- **应用:** 数据库连接池中的检测线程,JVM虚拟机启动后的检测线程 +- **最常见的守护线程:** 垃圾回收线程 + + +**如何设置守护线程?** + +可以通过调用 Thead 类的 `setDaemon(true)` 方法设置当前的线程为守护线程。 + +注意事项: + + 1. setDaemon(true)必须在start()方法前执行,否则会抛出IllegalThreadStateException异常 + 2. 在守护线程中产生的新线程也是守护线程 + 3. 不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑 + + +## 8 sleep()方法和wait()方法简单对比 + +- 两者最主要的区别在于:**sleep方法没有释放锁,而wait方法释放了锁** 。 +- 两者都可以暂停线程的执行。 +- Wait通常被用于线程间交互/通信,sleep通常被用于暂停执行。 +- wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒。 + + +## 9 为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法? + +这是另一个非常经典的java多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! + +new一个Thread,线程进入了新建状态;调用start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 +start()会执行线程的相应准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。 而直接执行run()方法,会把run方法当成一个mian线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。 + +**总结: 调用start方法方可启动线程并使线程进入就绪状态,而run方法只是thread的一个普通方法调用,还是在主线程里执行。** + + + + From 5a62e9024d9191092fc4b21172fa3470ad724950 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:04:10 +0800 Subject: [PATCH 079/232] =?UTF-8?q?Delete=20=E7=AC=AC=E4=B8=80=E5=91=A8?= =?UTF-8?q?=EF=BC=882018-8-7=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\250\357\274\2102018-8-7\357\274\211.md" | 253 ------------------ 1 file changed, 253 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" deleted file mode 100644 index 4ca58dbfff6..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" +++ /dev/null @@ -1,253 +0,0 @@ - - -## 一 为什么 Java 中只有值传递? - - -首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。**按值调用(call by value)表示方法接收的是调用者提供的值,而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。** 它用来描述各种程序设计语言(不只是Java)中方法参数传递方式。 - -**Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。** - -**下面通过 3 个例子来给大家说明** - -### example 1 - - -```java -public static void main(String[] args) { - int num1 = 10; - int num2 = 20; - - swap(num1, num2); - - System.out.println("num1 = " + num1); - System.out.println("num2 = " + num2); -} - -public static void swap(int a, int b) { - int temp = a; - a = b; - b = temp; - - System.out.println("a = " + a); - System.out.println("b = " + b); -} -``` - -**结果:** - -``` -a = 20 -b = 10 -num1 = 10 -num2 = 20 -``` - -**解析:** - -![example 1 ](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/22191348.jpg) - -在swap方法中,a、b的值进行交换,并不会影响到 num1、num2。因为,a、b中的值,只是从 num1、num2 的复制过来的。也就是说,a、b相当于num1、num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。 - -**通过上面例子,我们已经知道了一个方法不能修改一个基本数据类型的参数,而对象引用作为参数就不一样,请看 example2.** - - -### example 2 - -```java - public static void main(String[] args) { - int[] arr = { 1, 2, 3, 4, 5 }; - System.out.println(arr[0]); - change(arr); - System.out.println(arr[0]); - } - - public static void change(int[] array) { - // 将数组的第一个元素变为0 - array[0] = 0; - } -``` - -**结果:** - -``` -1 -0 -``` - -**解析:** - -![example 2](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/3825204.jpg) - -array 被初始化 arr 的拷贝也就是一个对象的引用,也就是说 array 和 arr 指向的时同一个数组对象。 因此,外部对引用对象的改变会反映到所对应的对象上。 - - -**通过 example2 我们已经看到,实现一个改变对象参数状态的方法并不是一件难事。理由很简单,方法得到的是对象引用的拷贝,对象引用及其他的拷贝同时引用同一个对象。** - -**很多程序设计语言(特别是,C++和Pascal)提供了两种参数传递的方式:值调用和引用调用。有些程序员(甚至本书的作者)认为Java程序设计语言对对象采用的是引用调用,实际上,这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题。** - - -### example 3 - -```java -public class Test { - - public static void main(String[] args) { - // TODO Auto-generated method stub - Student s1 = new Student("小张"); - Student s2 = new Student("小李"); - Test.swap(s1, s2); - System.out.println("s1:" + s1.getName()); - System.out.println("s2:" + s2.getName()); - } - - public static void swap(Student x, Student y) { - Student temp = x; - x = y; - y = temp; - System.out.println("x:" + x.getName()); - System.out.println("y:" + y.getName()); - } -} -``` - -**结果:** - -``` -x:小李 -y:小张 -s1:小张 -s2:小李 -``` - -**解析:** - -交换之前: - -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/88729818.jpg) - -交换之后: - -![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-27/34384414.jpg) - - -通过上面两张图可以很清晰的看出: **方法并没有改变存储在变量 s1 和 s2 中的对象引用。swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝** - -### 总结 - -Java程序设计语言对对象采用的不是引用调用,实际上,对象引用是按 -值传递的。 - -下面再总结一下Java中方法参数的使用情况: - -- 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型》 -- 一个方法可以改变一个对象参数的状态。 -- 一个方法不能让对象参数引用一个新的对象。 - - -### 参考: - -《Java核心技术卷Ⅰ》基础知识第十版第四章4.5小节 - -## 二 ==与equals(重要) - -**==** : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) - -**equals()** : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况: - -- 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。 -- 情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。 - - -**举个例子:** - -```java -public class test1 { - public static void main(String[] args) { - String a = new String("ab"); // a 为一个引用 - String b = new String("ab"); // b为另一个引用,对象的内容一样 - String aa = "ab"; // 放在常量池中 - String bb = "ab"; // 从常量池中查找 - if (aa == bb) // true - System.out.println("aa==bb"); - if (a == b) // false,非同一对象 - System.out.println("a==b"); - if (a.equals(b)) // true - System.out.println("aEQb"); - if (42 == 42.0) { // true - System.out.println("true"); - } - } -} -``` - -**说明:** - -- String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。 -- 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。 - - - -## 三 hashCode与equals(重要) - -面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” - -### hashCode()介绍 -hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。 - -```java - /** - * Returns a hash code value for the object. This method is - * supported for the benefit of hash tables such as those provided by - * {@link java.util.HashMap}. - *

- * As much as is reasonably practical, the hashCode method defined by - * class {@code Object} does return distinct integers for distinct - * objects. (This is typically implemented by converting the internal - * address of the object into an integer, but this implementation - * technique is not required by the - * Java™ programming language.) - * - * @return a hash code value for this object. - * @see java.lang.Object#equals(java.lang.Object) - * @see java.lang.System#identityHashCode - */ - public native int hashCode(); -``` - -散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象) - -### 为什么要有hashCode - - -**我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:** - -当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。 - - - -### hashCode()与equals()的相关规定 - -1. 如果两个对象相等,则hashcode一定也是相同的 -2. 两个对象相等,对两个对象分别调用equals方法都返回true -3. 两个对象有相同的hashcode值,它们也不一定是相等的 -4. **因此,equals方法被覆盖过,则hashCode方法也必须被覆盖** -5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据) - -### 为什么两个对象有相同的hashcode值,它们也不一定是相等的? - -在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。 - -因为hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。 - -我们刚刚也提到了 HashSet,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。 - -参考: - -[https://blog.csdn.net/zhzhao999/article/details/53449504](https://blog.csdn.net/zhzhao999/article/details/53449504) - -[https://www.cnblogs.com/skywang12345/p/3324958.html](https://www.cnblogs.com/skywang12345/p/3324958.html) - -[https://www.cnblogs.com/skywang12345/p/3324958.html](https://www.cnblogs.com/skywang12345/p/3324958.html) - -[https://www.cnblogs.com/Eason-S/p/5524837.html](https://www.cnblogs.com/Eason-S/p/5524837.html) - From 04f11194c62ff4c0dd161da077aecb239f21284b Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:04:16 +0800 Subject: [PATCH 080/232] =?UTF-8?q?Delete=20=E7=AC=AC=E4=BA=8C=E5=91=A8(20?= =?UTF-8?q?18-8-13).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- ...254\344\272\214\345\221\250(2018-8-13).md" | 200 ------------------ 1 file changed, 200 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\272\214\345\221\250(2018-8-13).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\272\214\345\221\250(2018-8-13).md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\272\214\345\221\250(2018-8-13).md" deleted file mode 100644 index 426498cb2d9..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\344\272\214\345\221\250(2018-8-13).md" +++ /dev/null @@ -1,200 +0,0 @@ - -### String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? - -#### String和StringBuffer、StringBuilder的区别 - -**可变性** -  - -简单的来说:String 类中使用 final 关键字字符数组保存字符串,`private final char value[]`,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串`char[]value` 但是没有用 final 关键字修饰,所以这两种对象都是可变的。 - -StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现的,大家可以自行查阅源码。 - -AbstractStringBuilder.java - -```java -abstract class AbstractStringBuilder implements Appendable, CharSequence { - char[] value; - int count; - AbstractStringBuilder() { - } - AbstractStringBuilder(int capacity) { - value = new char[capacity]; - } -``` - - -**线程安全性** - -String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。 -   - -**性能** - -每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。 - -**对于三者使用的总结:** -1. 操作少量的数据 = String -2. 单线程操作字符串缓冲区下操作大量数据 = StringBuilder -3. 多线程操作字符串缓冲区下操作大量数据 = StringBuffer - -#### String为什么是不可变的吗? -简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下图所以: - -```java - /** The value is used for character storage. */ - private final char value[]; -``` - -#### String真的是不可变的吗? -我觉得如果别人问这个问题的话,回答不可变就可以了。 -下面只是给大家看两个有代表性的例子: - -**1) String不可变但不代表引用不可以变** -```java - String str = "Hello"; - str = str + " World"; - System.out.println("str=" + str); -``` -结果: -``` -str=Hello World -``` -解析: - -实际上,原来String的内容是不变的,只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已,也就是说多开辟了一块内存区域给"Hello World"字符串。 - -**2) 通过反射是可以修改所谓的“不可变”对象** - -```java - // 创建字符串"Hello World", 并赋给引用s - String s = "Hello World"; - - System.out.println("s = " + s); // Hello World - - // 获取String类中的value字段 - Field valueFieldOfString = String.class.getDeclaredField("value"); - - // 改变value属性的访问权限 - valueFieldOfString.setAccessible(true); - - // 获取s对象上的value属性的值 - char[] value = (char[]) valueFieldOfString.get(s); - - // 改变value所引用的数组中的第5个字符 - value[5] = '_'; - - System.out.println("s = " + s); // Hello_World -``` - -结果: - -``` -s = Hello World -s = Hello_World -``` - -解析: - -用反射可以访问私有成员, 然后反射出String对象中的value属性, 进而改变通过获得的value引用改变数组的结构。但是一般我们不会这么做,这里只是简单提一下有这个东西。 - -### 什么是反射机制?反射机制的应用场景有哪些? - -#### 反射机制介绍 - -JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 - -#### 静态编译和动态编译 - -- **静态编译:**在编译时确定类型,绑定对象 -- **动态编译:**运行时确定类型,绑定对象 - -#### 反射机制优缺点 - -- **优点:** 运行期类型的判断,动态加载类,提高代码灵活度。 -- **缺点:** 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。 - -#### 反射的应用场景 - -反射是框架设计的灵魂。 - -在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。 - -举例:①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML 或 Properties 配置文件加载入内存中; - 2)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息; 3)使用反射机制,根据这个字符串获得某个类的Class实例; 4)动态配置实例的属性 - -**推荐阅读:** - -- [Reflection:Java反射机制的应用场景](https://segmentfault.com/a/1190000010162647?utm_source=tuicool&utm_medium=referral) -- [Java基础之—反射(非常重要)](https://blog.csdn.net/sinat_38259539/article/details/71799078) -### 什么是JDK?什么是JRE?什么是JVM?三者之间的联系与区别 - -这几个是Java中很基本很基本的东西,但是我相信一定还有很多人搞不清楚!为什么呢?因为我们大多数时候在使用现成的编译工具以及环境的时候,并没有去考虑这些东西。 - -**JDK:** 顾名思义它是给开发者提供的开发工具箱,是给程序开发者用的。它除了包括完整的JRE(Java Runtime Environment),Java运行环境,还包含了其他供开发者使用的工具包。 - -**JRE:** 普通用户而只需要安装JRE(Java Runtime Environment)来运行Java程序。而程序开发者必须安装JDK来编译、调试程序。 - -**JVM:** 当我们运行一个程序时,JVM负责将字节码转换为特定机器代码,JVM提供了内存管理/垃圾回收和安全机制等。这种独立于硬件和操作系统,正是java程序可以一次编写多处执行的原因。 - -**区别与联系:** - - 1. JDK用于开发,JRE用于运行java程序 ; - 2. JDK和JRE中都包含JVM ; - 3. JVM是java编程语言的核心并且具有平台独立性。 - -### 什么是字节码?采用字节码的最大好处是什么? - -**先看下java中的编译器和解释器:**    - -Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做`字节码`(即扩展名为`.class`的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。这也就是解释了Java的编译与解释并存的特点。 - - Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器----->机器可执行的二进制机器码---->程序运行。 - -**采用字节码的好处:**    - -Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。 - -### Java和C++的区别 - -我知道很多人没学过C++,但是面试官就是没事喜欢拿咱们Java和C++比呀!没办法!!!就算没学过C++,也要记下来! - -- 都是面向对象的语言,都支持封装、继承和多态 -- Java不提供指针来直接访问内存,程序内存更加安全 -- Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。 -- Java有自动内存管理机制,不需要程序员手动释放无用内存 - - -### 接口和抽象类的区别是什么? - -1. 接口的方法默认是public,所有方法在接口中不能有实现,抽象类可以有非抽象的方法 -2. 接口中的实例变量默认是final类型的,而抽象类中则不一定 -3. 一个类可以实现多个接口,但最多只能实现一个抽象类 -4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定 -5. 接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。 - -注意:Java8 后接口可以有默认实现( default )。 - -### 成员变量与局部变量的区别有那些? - -1. 从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public,private,static等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰;但是,成员变量和局部变量都能被final所修饰; -2. 从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存 -3. 从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。 -4. 成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被final修饰但没有被static修饰的成员变量必须显示地赋值);而局部变量则不会自动赋值。 - -### 重载和重写的区别 - -**重载:** 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。    - -**重写:** 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。 - -### 字符型常量和字符串常量的区别 -1) 形式上: -字符常量是单引号引起的一个字符 -字符串常量是双引号引起的若干个字符 -2) 含义上: -字符常量相当于一个整形值(ASCII值),可以参加表达式运算 -字符串常量代表一个地址值(该字符串在内存中存放位置) -3) 占内存大小 -字符常量只占一个字节 -字符串常量占若干个字节(至少一个字符结束标志) From 11dea93f0ef3173df10affa3cb7791e95caf2153 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:04:20 +0800 Subject: [PATCH 081/232] =?UTF-8?q?Delete=20=E7=AC=AC=E5=9B=9B=E5=91=A8(20?= =?UTF-8?q?18-8-30).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- ...254\345\233\233\345\221\250(2018-8-30).md" | 195 ------------------ 1 file changed, 195 deletions(-) delete mode 100644 "\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\345\233\233\345\221\250(2018-8-30).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\345\233\233\345\221\250(2018-8-30).md" "b/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\345\233\233\345\221\250(2018-8-30).md" deleted file mode 100644 index 3cb02d73d5b..00000000000 --- "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\234\200\346\234\200\346\234\200\345\270\270\350\247\201\347\232\204Java\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223/\347\254\254\345\233\233\345\221\250(2018-8-30).md" +++ /dev/null @@ -1,195 +0,0 @@ - -## 1. 简述线程,程序、进程的基本概念。以及他们之间关系是什么? - -**线程**与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。 - -**程序**是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。 - -**进程**是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 - -**线程** 是 **进程** 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。 - -**线程上下文的切换比进程上下文切换要快很多** - -- 进程切换时,涉及到当前进程的CPU环境的保存和新被调度运行进程的CPU环境的设置。 -- 线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。 - -## 2. 线程有哪些基本状态?这些状态是如何定义的? - -1. **新建(new)**:新创建了一个线程对象。 -2. **可运行(runnable)**:线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取cpu的使用权。 -3. **运行(running)**:可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。 -4. **阻塞(block)**:阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。阻塞的情况分三种: - - **(一). 等待阻塞**:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waiting queue)中。 - - **(二). 同步阻塞**:运行(running)的线程在获取对象的同步锁时,若该同步 锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。 - - **(三). 其他阻塞**: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。 -5. **死亡(dead)**:线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。 - -![](https://user-gold-cdn.xitu.io/2018/8/9/1651f19d7c4e93a3?w=876&h=492&f=png&s=128092) - -备注: 可以用早起坐地铁来比喻这个过程(下面参考自牛客网某位同学的回答): - -1. 还没起床:sleeping -2. 起床收拾好了,随时可以坐地铁出发:Runnable -3. 等地铁来:Waiting -4. 地铁来了,但要排队上地铁:I/O阻塞 -5. 上了地铁,发现暂时没座位:synchronized阻塞 -6. 地铁上找到座位:Running -7. 到达目的地:Dead - - -## 3. 何为多线程? - -多线程就是多个线程同时运行或交替运行。单核CPU的话是顺序执行,也就是交替运行。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行。 - - -## 4. 为什么多线程是必要的? - -1. 使用线程可以把占据长时间的程序中的任务放到后台去处理。 -2. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。 -3. 程序的运行速度可能加快。 - -## 5 使用多线程常见的三种方式 - -### ①继承Thread类 - -MyThread.java - -```java -public class MyThread extends Thread { - @Override - public void run() { - super.run(); - System.out.println("MyThread"); - } -} -``` -Run.java - -```java -public class Run { - - public static void main(String[] args) { - MyThread mythread = new MyThread(); - mythread.start(); - System.out.println("运行结束"); - } - -} - -``` -运行结果: -![结果](https://user-gold-cdn.xitu.io/2018/3/20/16243e80f22a2d54?w=161&h=54&f=jpeg&s=7380) -从上面的运行结果可以看出:线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法。 - -### ②实现Runnable接口 -推荐实现Runnable接口方式开发多线程,因为Java单继承但是可以实现多个接口。 - -MyRunnable.java - -```java -public class MyRunnable implements Runnable { - @Override - public void run() { - System.out.println("MyRunnable"); - } -} -``` - -Run.java - -```java -public class Run { - - public static void main(String[] args) { - Runnable runnable=new MyRunnable(); - Thread thread=new Thread(runnable); - thread.start(); - System.out.println("运行结束!"); - } - -} -``` -运行结果: -![运行结果](https://user-gold-cdn.xitu.io/2018/3/20/16243f4373c6141a?w=137&h=46&f=jpeg&s=7316) - -### ③使用线程池 - -**在《阿里巴巴Java开发手册》“并发处理”这一章节,明确指出线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。** - -**为什么呢?** - -> **使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源开销,解决资源不足的问题。如果不使用线程池,有可能会造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。** - -**另外《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险** - -> Executors 返回线程池对象的弊端如下: -> -> - **FixedThreadPool 和 SingleThreadExecutor** : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。 -> - **CachedThreadPool 和 ScheduledThreadPool** : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。 - -对于线程池感兴趣的可以查看我的这篇文章:[《Java多线程学习(八)线程池与Executor 框架》](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484042&idx=1&sn=541dbf2cb969a151d79f4a4f837ee1bd&chksm=fd9854ebcaefddfd1876bb96ab218be3ae7b12546695a403075d4ed22e5e17ff30ebdabc8bbf#rd) 点击阅读原文即可查看到该文章的最新版。 - - -## 6 线程的优先级 - -每个线程都具有各自的优先级,**线程的优先级可以在程序中表明该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态**。但这个并不意味着低 -优先级的线程得不到运行,而只是它运行的几率比较小,如垃圾回收机制线程的优先级就比较低。所以很多垃圾得不到及时的回收处理。 - -**线程优先级具有继承特性。** 比如A线程启动B线程,则B线程的优先级和A是一样的。 - -**线程优先级具有随机性。** 也就是说线程优先级高的不一定每一次都先执行完。 - -Thread类中包含的成员变量代表了线程的某些优先级。如**Thread.MIN_PRIORITY(常数1)**,**Thread.NORM_PRIORITY(常数5)**, -**Thread.MAX_PRIORITY(常数10)**。其中每个线程的优先级都在**Thread.MIN_PRIORITY(常数1)** 到**Thread.MAX_PRIORITY(常数10)** 之间,在默认情况下优先级都是**Thread.NORM_PRIORITY(常数5)**。 - -学过操作系统这门课程的话,我们可以发现多线程优先级或多或少借鉴了操作系统对进程的管理。 - - -## 7 Java多线程分类 - -### 用户线程 - -运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程 - -### 守护线程 - -运行在后台,为其他前台线程服务.也可以说守护线程是JVM中非守护线程的 **“佣人”**。 - - -- **特点:** 一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作 -- **应用:** 数据库连接池中的检测线程,JVM虚拟机启动后的检测线程 -- **最常见的守护线程:** 垃圾回收线程 - - -**如何设置守护线程?** - -可以通过调用 Thead 类的 `setDaemon(true)` 方法设置当前的线程为守护线程。 - -注意事项: - - 1. setDaemon(true)必须在start()方法前执行,否则会抛出IllegalThreadStateException异常 - 2. 在守护线程中产生的新线程也是守护线程 - 3. 不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑 - - -## 8 sleep()方法和wait()方法简单对比 - -- 两者最主要的区别在于:**sleep方法没有释放锁,而wait方法释放了锁** 。 -- 两者都可以暂停线程的执行。 -- Wait通常被用于线程间交互/通信,sleep通常被用于暂停执行。 -- wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒。 - - -## 9 为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法? - -这是另一个非常经典的java多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! - -new一个Thread,线程进入了新建状态;调用start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 -start()会执行线程的相应准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。 而直接执行run()方法,会把run方法当成一个mian线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。 - -**总结: 调用start方法方可启动线程并使线程进入就绪状态,而run方法只是thread的一个普通方法调用,还是在主线程里执行。** - - - - From a79c561a15d0d80f4fc7564297325db760a7a418 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:07:55 +0800 Subject: [PATCH 082/232] Update change file name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改文件夹名字 --- .../JavaInterviewGithub.md | 0 .../JavaProgrammerNeedKnow.md | 0 ...54\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" | 0 .../\347\254\254\344\272\214\345\221\250(2018-8-13).md" | 0 .../\347\254\254\345\233\233\345\221\250(2018-8-30).md" | 0 .../books.md" => EssentialContentForInterview/books.md | 0 .../interviewPrepare.md | 0 ...50\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" | 0 ...47\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" | 0 .../\347\256\200\345\216\206\346\250\241\346\235\277.md" | 0 ...50\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" | 0 ...51\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename "\351\235\242\350\257\225\345\277\205\345\244\207/JavaInterviewGithub.md" => EssentialContentForInterview/JavaInterviewGithub.md (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" => EssentialContentForInterview/JavaProgrammerNeedKnow.md (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" => "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" => "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" => "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/books.md" => EssentialContentForInterview/books.md (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/interviewPrepare.md" => EssentialContentForInterview/interviewPrepare.md (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" => "EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/\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" => "EssentialContentForInterview/\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" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/\347\256\200\345\216\206\346\250\241\346\235\277.md" => "EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/\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" => "EssentialContentForInterview/\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" (100%) rename "\351\235\242\350\257\225\345\277\205\345\244\207/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" => "EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" (100%) diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/JavaInterviewGithub.md" b/EssentialContentForInterview/JavaInterviewGithub.md similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/JavaInterviewGithub.md" rename to EssentialContentForInterview/JavaInterviewGithub.md diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" b/EssentialContentForInterview/JavaProgrammerNeedKnow.md similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/JavaProgrammerNeedKnow.md" rename to EssentialContentForInterview/JavaProgrammerNeedKnow.md diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" "b/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" rename to "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" "b/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" rename to "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" "b/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" rename to "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/books.md" b/EssentialContentForInterview/books.md similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/books.md" rename to EssentialContentForInterview/books.md diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/interviewPrepare.md" b/EssentialContentForInterview/interviewPrepare.md similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/interviewPrepare.md" rename to EssentialContentForInterview/interviewPrepare.md diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" "b/EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" rename to "EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/EssentialContentForInterview/\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" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/\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" rename to "EssentialContentForInterview/\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" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\347\256\200\345\216\206\346\250\241\346\235\277.md" "b/EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/\347\256\200\345\216\206\346\250\241\346\235\277.md" rename to "EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\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/EssentialContentForInterview/\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" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/\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" rename to "EssentialContentForInterview/\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" diff --git "a/\351\235\242\350\257\225\345\277\205\345\244\207/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" "b/EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" similarity index 100% rename from "\351\235\242\350\257\225\345\277\205\345\244\207/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" rename to "EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" From d62a018043df7b2df8ef733d5221e85f4a55a040 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:11:51 +0800 Subject: [PATCH 083/232] Update change file name --- .../{ => PreparingForInterview}/JavaProgrammerNeedKnow.md | 0 EssentialContentForInterview/{ => PreparingForInterview}/books.md | 0 .../{ => PreparingForInterview}/interviewPrepare.md | 0 ...47\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" | 0 ...50\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename EssentialContentForInterview/{ => PreparingForInterview}/JavaProgrammerNeedKnow.md (100%) rename EssentialContentForInterview/{ => PreparingForInterview}/books.md (100%) rename EssentialContentForInterview/{ => PreparingForInterview}/interviewPrepare.md (100%) rename "EssentialContentForInterview/\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" => "EssentialContentForInterview/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" (100%) rename "EssentialContentForInterview/\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" => "EssentialContentForInterview/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" (100%) diff --git a/EssentialContentForInterview/JavaProgrammerNeedKnow.md b/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md similarity index 100% rename from EssentialContentForInterview/JavaProgrammerNeedKnow.md rename to EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md diff --git a/EssentialContentForInterview/books.md b/EssentialContentForInterview/PreparingForInterview/books.md similarity index 100% rename from EssentialContentForInterview/books.md rename to EssentialContentForInterview/PreparingForInterview/books.md diff --git a/EssentialContentForInterview/interviewPrepare.md b/EssentialContentForInterview/PreparingForInterview/interviewPrepare.md similarity index 100% rename from EssentialContentForInterview/interviewPrepare.md rename to EssentialContentForInterview/PreparingForInterview/interviewPrepare.md diff --git "a/EssentialContentForInterview/\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/EssentialContentForInterview/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" similarity index 100% rename from "EssentialContentForInterview/\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" rename to "EssentialContentForInterview/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" diff --git "a/EssentialContentForInterview/\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/EssentialContentForInterview/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" similarity index 100% rename from "EssentialContentForInterview/\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" rename to "EssentialContentForInterview/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" From 75ee47edf8ee406f9ed6d1d653d0503d76c70f39 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 19:20:01 +0800 Subject: [PATCH 084/232] Update link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了文件夹的名字故修改链接地址 --- README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8aef7455edf..fda9aefffd9 100644 --- a/README.md +++ b/README.md @@ -161,25 +161,22 @@ * [8 张图读懂大型网站技术架构](https://github.com/Snailclimb/JavaGuide/blob/master/架构/8%20张图读懂大型网站技术架构.md) * [【面试精选】关于大型网站系统架构你不得不懂的10个问题](https://github.com/Snailclimb/JavaGuide/blob/master/架构/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) -## :musical_note: 面试必备 +## :musical_note: 面试必备(Essential content for the interview) ### 备战面试 -* [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/程序员的简历之道.md) -* [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/interviewPrepare.md) -* [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/面试必备/JavaProgrammerNeedKnow.md) -* [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/books.md) -* [【备战面试5】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/美团面试常见问题总结.md) +* [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/books.md) +* [【备战面试5】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +### 最常见的Java面试题总结 -### 最最最常见的Java面试题总结 - -这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。 - -* [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) -* [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) * [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) -* [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) +* [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) ### Java学习/面试开源仓库推荐 From 564a90c8b01263156d88e474530942cead383b07 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 19:31:41 +0800 Subject: [PATCH 085/232] Update Modify file name and directory address --- .../JavaInterviewLibrary.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EssentialContentForInterview/{JavaInterviewGithub.md => PreparingForInterview/JavaInterviewLibrary.md} (100%) diff --git a/EssentialContentForInterview/JavaInterviewGithub.md b/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md similarity index 100% rename from EssentialContentForInterview/JavaInterviewGithub.md rename to EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md From 40752e158e283534fa247aa8b5f2a0e3c5acbef2 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 19:32:23 +0800 Subject: [PATCH 086/232] Update README.md --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fda9aefffd9..ca7dee83a1b 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ * [Redis](#redis) * [:punch: 架构](#punch-架构) * [:musical_note: 面试必备](#musical_note-面试必备) - * [备战面试](#备战面试) - * [最最最常见的Java面试题总结](#最最最常见的java面试题总结) - * [Java学习/面试开源仓库推荐](#java学习面试开源仓库推荐) +* [:musical_note: 面试必备\(Essential content for the interview\)](#musical_note-面试必备essential-content-for-the-interview) + * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) + * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) * [:art: 闲谈](#art-闲谈) * [:envelope: 说明](#envelope-说明) @@ -163,25 +163,22 @@ ## :musical_note: 面试必备(Essential content for the interview) -### 备战面试 +### 备战面试(Preparing for an interview) * [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) * [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) * [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) * [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/books.md) -* [【备战面试5】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) -### 最常见的Java面试题总结 +### 最常见的Java面试题总结(Summary of the most common Java interview questions) * [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) * [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) * [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) * [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) -### Java学习/面试开源仓库推荐 - -* [盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/JavaInterviewGithub.md) - ## :art: 闲谈 * [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) From a51182bdd6f30c52d981222fc5156a06a4e53cdd Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 19:36:56 +0800 Subject: [PATCH 087/232] Update directory error --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ca7dee83a1b..520b34e30b7 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ * [MySQL](#mysql) * [Redis](#redis) * [:punch: 架构](#punch-架构) -* [:musical_note: 面试必备](#musical_note-面试必备) * [:musical_note: 面试必备\(Essential content for the interview\)](#musical_note-面试必备essential-content-for-the-interview) * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) From 8923dd0b2c1ff6b311f679a3933279df6531ebac Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 20:13:27 +0800 Subject: [PATCH 088/232] Update directory --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 520b34e30b7..b99489456e2 100644 --- a/README.md +++ b/README.md @@ -16,33 +16,33 @@ ## 目录 -* [:coffee: Java](#coffee-java) +* [Java](#java) * [Java/J2EE 基础](#javaj2ee-基础) * [Java 集合框架](#java-集合框架) * [Java 多线程](#java-多线程) * [Java BIO,NIO,AIO](#java-bionioaio) * [Java 虚拟机 jvm](#java-虚拟机-jvm) * [设计模式](#设计模式) -* [:open_file_folder: 数据结构与算法](#open_file_folder-数据结构与算法) +* [数据结构与算法](#数据结构与算法) * [数据结构](#数据结构) * [算法](#算法) -* [:computer: 计算机网络与数据通信](#computer-计算机网络与数据通信) +* [计算机网络与数据通信](#计算机网络与数据通信) * [网络相关](#网络相关) * [数据通信\(RESTful,RPC,消息队列\)总结](#数据通信restfulrpc消息队列总结) -* [:iphone: 操作系统](#iphone-操作系统) +* [操作系统](#操作系统) * [Linux相关](#linux相关) -* [:pencil2: 主流框架/软件](#pencil2-主流框架软件) +* [主流框架/软件](#主流框架软件) * [Spring](#spring) * [ZooKeeper](#zookeeper) -* [:floppy_disk: 数据存储](#floppy_disk-数据存储) +* [数据存储](#数据存储) * [MySQL](#mysql) * [Redis](#redis) -* [:punch: 架构](#punch-架构) -* [:musical_note: 面试必备\(Essential content for the interview\)](#musical_note-面试必备essential-content-for-the-interview) +* [架构](#架构) +* [面试必备\(Essential content for the interview\)](#面试必备essential-content-for-the-interview) * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) -* [:art: 闲谈](#art-闲谈) -* [:envelope: 说明](#envelope-说明) +* [闲谈](#闲谈) +* [说明](#说明) ## 待办 @@ -52,7 +52,7 @@ * [ ] Netty 总结 * [ ] 数据结构总结重构 -## :coffee: Java +## Java ### Java/J2EE 基础 @@ -94,7 +94,7 @@ * [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/设计模式.md) -## :open_file_folder: 数据结构与算法 +## 数据结构与算法 ### 数据结构 @@ -107,7 +107,7 @@ * [算法总结——几道常见的子符串算法题 ](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) * [算法总结——几道常见的链表算法题 ](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/Leetcode-LinkList1.md) -## :computer: 计算机网络与数据通信 +## 计算机网络与数据通信 ### 网络相关 @@ -122,13 +122,13 @@ * [消息队列总结:新手也能看懂,消息队列其实很简单](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/message-queue.md) * [一文搞懂 RabbitMQ 的重要概念以及安装](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/rabbitmq.md) -## :iphone: 操作系统 +## 操作系统 ### Linux相关 * [后端程序员必备的 Linux 基础知识](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/后端程序员必备的Linux基础知识.md) * [Shell 编程入门](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/Shell.md) -## :pencil2: 主流框架/软件 +## 主流框架/软件 ### Spring @@ -141,7 +141,7 @@ * [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/ZooKeeper.md) * [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/ZooKeeper数据模型和常见命令.md) -## :floppy_disk: 数据存储 +## 数据存储 ### MySQL @@ -154,13 +154,13 @@ * [Redlock分布式锁](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/Redis/Redlock分布式锁.md) * [如何做可靠的分布式锁,Redlock真的可行么](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) -## :punch: 架构 +## 架构 * [一文读懂分布式应该学什么](https://github.com/Snailclimb/Java_Guide/blob/master/架构/分布式.md) * [8 张图读懂大型网站技术架构](https://github.com/Snailclimb/JavaGuide/blob/master/架构/8%20张图读懂大型网站技术架构.md) * [【面试精选】关于大型网站系统架构你不得不懂的10个问题](https://github.com/Snailclimb/JavaGuide/blob/master/架构/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) -## :musical_note: 面试必备(Essential content for the interview) +## 面试必备(Essential content for the interview) ### 备战面试(Preparing for an interview) @@ -178,7 +178,7 @@ * [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) * [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) -## :art: 闲谈 +## 闲谈 * [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) * [结束了我短暂的秋招,说点自己的感受](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) @@ -187,7 +187,7 @@ *** -## :envelope: 说明 +## 说明 ### 介绍 From 852bf52cef0040573a27c14694851335da48de19 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 20:18:26 +0800 Subject: [PATCH 089/232] =?UTF-8?q?Create=205=E9=9D=A2=E9=98=BF=E9=87=8C,?= =?UTF-8?q?=E7=BB=88=E8=8E=B7offer.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\207\214,\347\273\210\350\216\267offer.md" | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 "EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" diff --git "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" new file mode 100644 index 00000000000..2a7a0431f35 --- /dev/null +++ "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" @@ -0,0 +1,79 @@ +# 联系方式 + +- 手机: +- Email: +- 微信: + +# 个人信息 + + - 姓名/性别/出生日期 + - 本科/xxx计算机系xxx专业/英语六级 + - 技术博客:[http://snailclimb.top/](http://snailclimb.top/) + - 荣誉奖励:获得了什么奖(获奖时间) + - Github:[https://github.com/Snailclimb ](https://github.com/Snailclimb) + - Github Resume: [http://resume.github.io/?Snailclimb](http://resume.github.io/?Snailclimb) + - 期望职位:Java 研发程序员/大数据工程师(Java后台开发为首选) + - 期望城市:xxx城市 + + +# 项目经历 + +## xxx项目 + +### 项目描述 + +介绍该项目是做什么的、使用到了什么技术以及你对项目整体设计的一个感受 + +### 责任描述 + +主要可以从下面三点来写: + +1. 在这个项目中你负责了什么、做了什么、担任了什么角色 +2. 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用 +3. 另外项目描述中,最好可以体现自己的综合素质,比如你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的。 + +# 开源项目和技术文章 + +## 开源项目 + +- [Java-Guide](https://github.com/Snailclimb/Java-Guide) :一份涵盖大部分Java程序员所需要掌握的核心知识。Star:3.9K; Fork:0.9k。 + + +## 技术文章推荐 + +- [可能是把Java内存区域讲的最清楚的一篇文章](https://juejin.im/post/5b7d69e4e51d4538ca5730cb) +- [搞定JVM垃圾回收就是这么简单](https://juejin.im/post/5b85ea54e51d4538dd08f601) +- [前端&后端程序员必备的Linux基础知识](https://juejin.im/post/5b3b19856fb9a04fa42f8c71) +- [可能是把Docker的概念讲的最清楚的一篇文章](https://juejin.im/post/5b260ec26fb9a00e8e4b031a) + + +# 校园经历(可选) + +## 2016-2017 + +担任学校社团-致深社副会长,主要负责团队每周活动的组建以及每周例会的主持。 + +## 2017-2018 + 担任学校传媒组织:“长江大学在线信息传媒”的副站长以及安卓组成员。主要负责每周例会主持、活动策划以及学校校园通APP的研发工作。 + + +# 技能清单 + +以下均为我熟练使用的技能 + +- Web开发:PHP/Hack/Node +- Web框架:ThinkPHP/Yaf/Yii/Lavarel/LazyPHP +- 前端框架:Bootstrap/AngularJS/EmberJS/HTML5/Cocos2dJS/ionic +- 前端工具:Bower/Gulp/SaSS/LeSS/PhoneGap +- 数据库相关:MySQL/PgSQL/PDO/SQLite +- 版本管理、文档和自动化部署工具:Svn/Git/PHPDoc/Phing/Composer +- 单元测试:PHPUnit/SimpleTest/Qunit +- 云和开放平台:SAE/BAE/AWS/微博开放平台/微信应用开发 + +# 自我评价(可选) + +自我发挥。切记不要过度自夸!!! + + +### 感谢您花时间阅读我的简历,期待能有机会和您共事。 + From 5814035bcf2e1254f8df050e2615fda5754d9b61 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Fri, 8 Mar 2019 20:21:51 +0800 Subject: [PATCH 090/232] =?UTF-8?q?Update=205=E9=9D=A2=E9=98=BF=E9=87=8C,?= =?UTF-8?q?=E7=BB=88=E8=8E=B7offer.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\207\214,\347\273\210\350\216\267offer.md" | 171 ++++++++++-------- 1 file changed, 92 insertions(+), 79 deletions(-) diff --git "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" index 2a7a0431f35..7772891d20d 100644 --- "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" +++ "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" @@ -1,79 +1,92 @@ -# 联系方式 - -- 手机: -- Email: -- 微信: - -# 个人信息 - - - 姓名/性别/出生日期 - - 本科/xxx计算机系xxx专业/英语六级 - - 技术博客:[http://snailclimb.top/](http://snailclimb.top/) - - 荣誉奖励:获得了什么奖(获奖时间) - - Github:[https://github.com/Snailclimb ](https://github.com/Snailclimb) - - Github Resume: [http://resume.github.io/?Snailclimb](http://resume.github.io/?Snailclimb) - - 期望职位:Java 研发程序员/大数据工程师(Java后台开发为首选) - - 期望城市:xxx城市 - - -# 项目经历 - -## xxx项目 - -### 项目描述 - -介绍该项目是做什么的、使用到了什么技术以及你对项目整体设计的一个感受 - -### 责任描述 - -主要可以从下面三点来写: - -1. 在这个项目中你负责了什么、做了什么、担任了什么角色 -2. 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用 -3. 另外项目描述中,最好可以体现自己的综合素质,比如你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的。 - -# 开源项目和技术文章 - -## 开源项目 - -- [Java-Guide](https://github.com/Snailclimb/Java-Guide) :一份涵盖大部分Java程序员所需要掌握的核心知识。Star:3.9K; Fork:0.9k。 - - -## 技术文章推荐 - -- [可能是把Java内存区域讲的最清楚的一篇文章](https://juejin.im/post/5b7d69e4e51d4538ca5730cb) -- [搞定JVM垃圾回收就是这么简单](https://juejin.im/post/5b85ea54e51d4538dd08f601) -- [前端&后端程序员必备的Linux基础知识](https://juejin.im/post/5b3b19856fb9a04fa42f8c71) -- [可能是把Docker的概念讲的最清楚的一篇文章](https://juejin.im/post/5b260ec26fb9a00e8e4b031a) - - -# 校园经历(可选) - -## 2016-2017 - -担任学校社团-致深社副会长,主要负责团队每周活动的组建以及每周例会的主持。 - -## 2017-2018 - 担任学校传媒组织:“长江大学在线信息传媒”的副站长以及安卓组成员。主要负责每周例会主持、活动策划以及学校校园通APP的研发工作。 - - -# 技能清单 - -以下均为我熟练使用的技能 - -- Web开发:PHP/Hack/Node -- Web框架:ThinkPHP/Yaf/Yii/Lavarel/LazyPHP -- 前端框架:Bootstrap/AngularJS/EmberJS/HTML5/Cocos2dJS/ionic -- 前端工具:Bower/Gulp/SaSS/LeSS/PhoneGap -- 数据库相关:MySQL/PgSQL/PDO/SQLite -- 版本管理、文档和自动化部署工具:Svn/Git/PHPDoc/Phing/Composer -- 单元测试:PHPUnit/SimpleTest/Qunit -- 云和开放平台:SAE/BAE/AWS/微博开放平台/微信应用开发 - -# 自我评价(可选) - -自我发挥。切记不要过度自夸!!! - - -### 感谢您花时间阅读我的简历,期待能有机会和您共事。 - +> 作者:ppxyn。本文来自读者投稿,同时也欢迎各位投稿,**对于不错的原创文章我根据你的选择给予现金(50-200)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 + +在接触 Java 之前我接触的比较多的是硬件方面,用的比较多的语言就是C和C++。到了大三我才正式选择 Java 方向,到目前为止使用Java到现在大概有一年多的时间,所以Java算不上很好。刚开始投递的时候,实习刚辞职,也没准备笔试面试,很多东西都忘记了。所以,刚开始我并没有直接就投递阿里,毕竟心里还是有一点点小害怕的。于是,我就先投递了几个不算大的公司来练手,就是想着刷刷经验而已或者说是练练手(ps:还是挺对不起那些公司的)。面了一个月其他公司后,我找了我实验室的学长内推我,后面就有了这5次面试。 + +下面简单的说一下我的这5次面试:4次技术面+1次HR面,希望我的经历能对你有所帮助。 + + + +- [一面\(技术面\)](#一面技术面) +- [二面\(技术面\)](#二面技术面) +- [三面\(技术面\)](#三面技术面) +- [四面\(半个技术面\)](#四面半个技术面) +- [五面\(HR面\)](#五面hr面) +- [总结](#总结) + + + + +### 一面(技术面) + +1. 自我介绍(主要讲自己会的技术细节,项目经验,经历那些就一语带过,后面面试官会问你的)。 +2. 聊聊项目(就是一个很普通的分布式商城,自己做了一些改进),让我画了整个项目的架构图,然后针对项目抛了一系列的提高性能的问题,还问了我做项目的过程中遇到了那些问题,如何解决的,差不读就这些吧。 +3. 可能是我前面说了我会数据库优化,然后面试官就开始问索引、事务隔离级别、悲观锁和乐观锁、索引、ACID、MVVC这些问题。 +4. 浏览器输入URL发生了什么? TCP和UDP区别? TCP如何保证传输可靠性? +5. 讲下跳表怎么实现的?哈夫曼编码是怎么回事?非递归且不用额外空间(不用栈),如何遍历二叉树 +6. 后面又问了很多JVM方面的问题,比如Java内存模型、常见的垃圾回收器、双亲委派模型这些 +7. 你有什么问题要问吗? + +### 二面(技术面) + +1. 自我介绍(主要讲自己会的技术细节,项目经验,经历那些就一语带过,后面面试官会问你的)。 +2. 操作系统的内存管理机制 +3. 进程和线程的区别 +4. 说下你对线程安全的理解 +5. volatile 有什么作用 ,sychronized和lock有什么区别 +6. ReentrantLock实现原理 +7. 用过CountDownLatch么?什么场景下用的? +8. AQS底层原理。 +9. 造成死锁的原因有哪些,如何预防? +10. 加锁会带来哪些性能问题。如何解决? +11. HashMap、ConcurrentHashMap源码。HashMap是线程安全的吗?Hashtable呢?ConcurrentHashMap有了解吗? +12. 是否可以实习? +13. 你有什么问题要问吗? + +### 三面(技术面) + +1. 有没有参加过 ACM 或者他竞赛,有没有拿过什么奖?( 我说我没参加过ACM,本科参加过数学建模竞赛,名次并不好,没拿过什么奖。面试官好像有点失望,然后我又赶紧补充说我和老师一起做过一个项目,目前已经投入使用。面试官还比较感兴趣,后面又和他聊了一下这个项目。) +2. 研究生期间,做过什么项目,发过论文吗?有什么成果吗? +3. 你觉得你有什么优点和缺点?你觉得你相比于那些比你更优秀的人欠缺什么? +4. 有读过什么源码吗?(我说我读过 Java 集合框架和 Netty 的,面试官说 Java 集合前几面一定问的差不多,就不问了,然后就问我 Netty的,我当时很慌啊!) +5. 介绍一下自己对 Netty 的认识,为什么要用。说说业务中,Netty 的使用场景。什么是TCP 粘包/拆包,解决办法。Netty线程模型。Dubbo 在使用 Netty 作为网络通讯时候是如何避免粘包与半包问题?讲讲Netty的零拷贝?巴拉巴拉问了好多,我记得有好几个我都没回答上来,心里想着凉凉了啊。 +6. 用到了那些开源技术、在开源领域做过贡献吗? +7. 常见的排序算法及其复杂度,现场写了快排。 +8. 红黑树,B树的一些问题。 +9. 讲讲算法及数据结构在实习项目中的用处。 +10. 自己的未来规划(就简单描述了一下自己未来的设想啊,说的还挺诚恳,面试官好像还挺满意的) +11. 你有什么问题要问吗? + +### 四面(半个技术面) + +三面面完当天,晚上9点接到面试电话,感觉像是部门或者项目主管。 这个和之前的面试不大相同,感觉面试官主要考察的是你解决问题的能力、学习能力和团队协作能力。 + +1. 让我讲一个自己觉得最不错的项目。然后就巴拉巴拉的聊,我记得主要是问了项目是如何进行协作的、遇到问题是如何解决的、与他人发生冲突是如何解决的这些。感觉聊了挺久。 +2. 出现 OOM 后你会怎么排查问题? +3. 自己平时是如何学习新技术的?除了 Java 还回去了解其他技术吗? +4. 上一段实习经历的收获。 +5. NginX如何做负载均衡、常见的负载均衡算法有哪些、一致性哈希的一致性是什么意思、一致性哈希是如何做哈希的 +6. 你有什么问题问我吗? +7. 还有一些其他的,想不起来了,感觉这一面不是偏向技术来问。 + +## 五面(HR面) + +1. 自我介绍(主要讲能突出自己的经历,会的编程技术一语带过)。 +2. 你觉得你有什么优点和缺点?如何克服这些缺点? +3. 说一件大学里你自己比较有成就感的一件事情,为此付出了那些努力。 +4. 你前面跟其他面试官讲过一些你做的项目吧?可以给我讲讲吗?你要考虑到我不是一个做技术的人,怎么让我也听得懂。项目中有什么问题,你怎么解决的?你最大的收获是什么? +5. 你目前有面试过其他公司吗?如果让你选,这些公司和阿里,你选哪个?(送分题,回答不好可能送命) +6. 你期望的工作地点是哪里? +7. 你有什么问题吗? + +### 总结 + +1. 可以看出面试官问我的很多问题都是比较常见的问题,所以记得一定要提前准备,还要深入准备,不要回答的太皮毛。很多时候一个问题可能会牵扯出很多问题,遇到不会的问题不要慌,冷静分析,如果你真的回答不上来,也不要担心自己是不是就要挂了,很可能这个问题本身就比较难。 +2. 表达能力和沟通能力太重要了,一定要提前练一下,我自身就是一个不太会说话的人,所以,面试前我对于自我介绍、项目介绍和一些常见问题都在脑子里练了好久,确保面试的时候能够很清晰和简洁的说出来。 +3. 等待面试的过程和面试的过程真的好熬人,那段时间我压力也比较大,好在我私下找到学长聊了很多,心情也好了很多。 +4. 面试之后及时总结,面的好的话,不要得意,尽快准备下一场面试吧! + +我觉得我还算是比较幸运的,最后也祝大家都能获得心仪的Offer。 + + + + \ No newline at end of file From 519ff1590a2af28fe3b7c51df190cf6c613af3ee Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 20:28:23 +0800 Subject: [PATCH 091/232] =?UTF-8?q?Add=20BATJ=E7=9C=9F=E5=AE=9E=E9=9D=A2?= =?UTF-8?q?=E7=BB=8F:5=E9=9D=A2=E9=98=BF=E9=87=8C,=E7=BB=88=E8=8E=B7offer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b99489456e2..03222e69ca6 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ * [架构](#架构) * [面试必备\(Essential content for the interview\)](#面试必备essential-content-for-the-interview) * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) + * [BATJ真实面经\(BATJ real interview experience\)](#batj真实面经batj-real-interview-experience) * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) * [闲谈](#闲谈) * [说明](#说明) @@ -60,7 +61,6 @@ * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/J2EE基础知识.md) * [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) - ### Java 集合框架 * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) @@ -171,6 +171,10 @@ * [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) * [【备战面试6】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +### BATJ真实面经(BATJ real interview experience) + +* [5面阿里,终获offer(2018年秋招)](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) + ### 最常见的Java面试题总结(Summary of the most common Java interview questions) * [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) From aec4e80a75e2b1b121eb8a8036484ff4f4c46e7f Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 8 Mar 2019 20:31:48 +0800 Subject: [PATCH 092/232] =?UTF-8?q?Update=205=E9=9D=A2=E9=98=BF=E9=87=8C,?= =?UTF-8?q?=E7=BB=88=E8=8E=B7offer.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...277\351\207\214,\347\273\210\350\216\267offer.md" | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" index 7772891d20d..9efac14f6d4 100644 --- "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" +++ "b/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" @@ -1,11 +1,10 @@ > 作者:ppxyn。本文来自读者投稿,同时也欢迎各位投稿,**对于不错的原创文章我根据你的选择给予现金(50-200)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 -在接触 Java 之前我接触的比较多的是硬件方面,用的比较多的语言就是C和C++。到了大三我才正式选择 Java 方向,到目前为止使用Java到现在大概有一年多的时间,所以Java算不上很好。刚开始投递的时候,实习刚辞职,也没准备笔试面试,很多东西都忘记了。所以,刚开始我并没有直接就投递阿里,毕竟心里还是有一点点小害怕的。于是,我就先投递了几个不算大的公司来练手,就是想着刷刷经验而已或者说是练练手(ps:还是挺对不起那些公司的)。面了一个月其他公司后,我找了我实验室的学长内推我,后面就有了这5次面试。 - -下面简单的说一下我的这5次面试:4次技术面+1次HR面,希望我的经历能对你有所帮助。 +**目录** +- [前言](#前言) - [一面\(技术面\)](#一面技术面) - [二面\(技术面\)](#二面技术面) - [三面\(技术面\)](#三面技术面) @@ -15,6 +14,11 @@ +### 前言 + +在接触 Java 之前我接触的比较多的是硬件方面,用的比较多的语言就是C和C++。到了大三我才正式选择 Java 方向,到目前为止使用Java到现在大概有一年多的时间,所以Java算不上很好。刚开始投递的时候,实习刚辞职,也没准备笔试面试,很多东西都忘记了。所以,刚开始我并没有直接就投递阿里,毕竟心里还是有一点点小害怕的。于是,我就先投递了几个不算大的公司来练手,就是想着刷刷经验而已或者说是练练手(ps:还是挺对不起那些公司的)。面了一个月其他公司后,我找了我实验室的学长内推我,后面就有了这5次面试。 + +下面简单的说一下我的这5次面试:4次技术面+1次HR面,希望我的经历能对你有所帮助。 ### 一面(技术面) @@ -89,4 +93,4 @@ - \ No newline at end of file + From 9dc44e6efa2ab107a708c864aca166552e80ba36 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sat, 9 Mar 2019 12:42:45 +0800 Subject: [PATCH 093/232] Update README.md --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 03222e69ca6..97dfe496f46 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ 3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! 4. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 5. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 -4. **【限时福利】** 极客时间[《Java 并发编程面试必备》](#Java并发编程专栏)专栏限时特惠,购买之后的小伙伴加 [我的微信](#联系我) 报上自己的极客时间大名可以找我会把24元返现退给大家,减轻各位学习成本。 ## 目录 @@ -221,12 +220,6 @@ ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) -### Java并发编程专栏 - -微信扫描下方二维码,购买之后我会将自己得到的24元返现都还给你,减轻各位的学习成本! - -![ Java并发编程专栏](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/Java并发编程实战.jpg) - ### Contributor 下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! From f1d9128962625affecbab2084d7a105af0fd205f Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 08:52:06 +0800 Subject: [PATCH 094/232] =?UTF-8?q?fix=20grow()=E6=96=B9=E6=B3=95=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E4=B8=8D=E5=A4=9F=E4=B8=A5=E8=B0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Java\347\233\270\345\205\263/ArrayList-Grow.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/ArrayList-Grow.md" "b/Java\347\233\270\345\205\263/ArrayList-Grow.md" index d763cb83492..87c695192f6 100644 --- "a/Java\347\233\270\345\205\263/ArrayList-Grow.md" +++ "b/Java\347\233\270\345\205\263/ArrayList-Grow.md" @@ -145,7 +145,7 @@ } ``` -**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!** 记清楚了!不是网上很多人说的 1.5 倍+1! +**int newCapacity = oldCapacity + (oldCapacity >> 1),所以在capacity是偶数的情况下,ArrayList 每次扩容之后容量都会变为原来的 1.5 倍,当capacity为奇数时(自己初始化容量时可能出现),第一次扩容容量变为oldCapacity + (oldCapacity - 1) / 2(在计算机运算的情况下减一除和直接除没有差别,对于整数会自动舍掉小数位),也就是说每次扩容相当于计算机中的1.5倍。 !** 记清楚了!不是网上很多人说的 1.5 倍+1!当然了,第一次扩容以后capacity会变为偶数,之后的每次扩容都会是原容量的1.5倍了。 > ">>"(移位运算符):>>1 右移一位相当于除2,右移n位相当于除以 2 的 n 次方。这里 oldCapacity 明显右移了1位所以相当于oldCapacity /2。对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源   From 89f31e168c1e5205d25c4b089b519bcb2b568464 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 10 Mar 2019 11:50:44 +0800 Subject: [PATCH 095/232] Update file name --- .../ArrayList-Grow.md" => Java/ArrayList-Grow.md | 0 "Java\347\233\270\345\205\263/ArrayList.md" => Java/ArrayList.md | 0 .../BIO,NIO,AIO summary.md" => Java/BIO,NIO,AIO summary.md | 0 "Java\347\233\270\345\205\263/HashMap.md" => Java/HashMap.md | 0 .../J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" | 0 .../Java IO\344\270\216NIO.md" | 0 .../Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 0 ...231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" | 0 ...51\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" | 0 .../LinkedList.md" => Java/LinkedList.md | 0 .../Multithread/AQS.md" => Java/Multithread/AQS.md | 0 .../Multithread/Atomic.md" => Java/Multithread/Atomic.md | 0 ...47\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" | 0 ...45\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" | 0 .../final\343\200\201static\343\200\201this\343\200\201super.md" | 0 .../synchronized.md" => Java/synchronized.md | 0 ...47\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 0 ...45\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" | 0 ...46\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" | 0 .../\350\256\276\350\256\241\346\250\241\345\274\217.md" | 0 ...51\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename "Java\347\233\270\345\205\263/ArrayList-Grow.md" => Java/ArrayList-Grow.md (100%) rename "Java\347\233\270\345\205\263/ArrayList.md" => Java/ArrayList.md (100%) rename "Java\347\233\270\345\205\263/BIO,NIO,AIO summary.md" => Java/BIO,NIO,AIO summary.md (100%) rename "Java\347\233\270\345\205\263/HashMap.md" => Java/HashMap.md (100%) rename "Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" => "Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" (100%) rename "Java\347\233\270\345\205\263/Java IO\344\270\216NIO.md" => "Java/Java IO\344\270\216NIO.md" (100%) rename "Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" => "Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" (100%) rename "Java\347\233\270\345\205\263/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" => "Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" (100%) rename "Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" => "Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" (100%) rename "Java\347\233\270\345\205\263/LinkedList.md" => Java/LinkedList.md (100%) rename "Java\347\233\270\345\205\263/Multithread/AQS.md" => Java/Multithread/AQS.md (100%) rename "Java\347\233\270\345\205\263/Multithread/Atomic.md" => Java/Multithread/Atomic.md (100%) rename "Java\347\233\270\345\205\263/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" => "Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" (100%) rename "Java\347\233\270\345\205\263/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" => "Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" (100%) rename "Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" => "Java/final\343\200\201static\343\200\201this\343\200\201super.md" (100%) rename "Java\347\233\270\345\205\263/synchronized.md" => Java/synchronized.md (100%) rename "Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" => "Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" (100%) rename "Java\347\233\270\345\205\263/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" => "Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" (100%) rename "Java\347\233\270\345\205\263/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" => "Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" (100%) rename "Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" => "Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" (100%) rename "Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" => "Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" (100%) diff --git "a/Java\347\233\270\345\205\263/ArrayList-Grow.md" b/Java/ArrayList-Grow.md similarity index 100% rename from "Java\347\233\270\345\205\263/ArrayList-Grow.md" rename to Java/ArrayList-Grow.md diff --git "a/Java\347\233\270\345\205\263/ArrayList.md" b/Java/ArrayList.md similarity index 100% rename from "Java\347\233\270\345\205\263/ArrayList.md" rename to Java/ArrayList.md diff --git "a/Java\347\233\270\345\205\263/BIO,NIO,AIO summary.md" b/Java/BIO,NIO,AIO summary.md similarity index 100% rename from "Java\347\233\270\345\205\263/BIO,NIO,AIO summary.md" rename to Java/BIO,NIO,AIO summary.md diff --git "a/Java\347\233\270\345\205\263/HashMap.md" b/Java/HashMap.md similarity index 100% rename from "Java\347\233\270\345\205\263/HashMap.md" rename to Java/HashMap.md diff --git "a/Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" similarity index 100% rename from "Java\347\233\270\345\205\263/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" rename to "Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" diff --git "a/Java\347\233\270\345\205\263/Java IO\344\270\216NIO.md" "b/Java/Java IO\344\270\216NIO.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Java IO\344\270\216NIO.md" rename to "Java/Java IO\344\270\216NIO.md" diff --git "a/Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" rename to "Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" diff --git "a/Java\347\233\270\345\205\263/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" "b/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" rename to "Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" diff --git "a/Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" "b/Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" rename to "Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" diff --git "a/Java\347\233\270\345\205\263/LinkedList.md" b/Java/LinkedList.md similarity index 100% rename from "Java\347\233\270\345\205\263/LinkedList.md" rename to Java/LinkedList.md diff --git "a/Java\347\233\270\345\205\263/Multithread/AQS.md" b/Java/Multithread/AQS.md similarity index 100% rename from "Java\347\233\270\345\205\263/Multithread/AQS.md" rename to Java/Multithread/AQS.md diff --git "a/Java\347\233\270\345\205\263/Multithread/Atomic.md" b/Java/Multithread/Atomic.md similarity index 100% rename from "Java\347\233\270\345\205\263/Multithread/Atomic.md" rename to Java/Multithread/Atomic.md diff --git "a/Java\347\233\270\345\205\263/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" "b/Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" rename to "Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" diff --git "a/Java\347\233\270\345\205\263/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" "b/Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" similarity index 100% rename from "Java\347\233\270\345\205\263/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" rename to "Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" diff --git "a/Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" "b/Java/final\343\200\201static\343\200\201this\343\200\201super.md" similarity index 100% rename from "Java\347\233\270\345\205\263/final\343\200\201static\343\200\201this\343\200\201super.md" rename to "Java/final\343\200\201static\343\200\201this\343\200\201super.md" diff --git "a/Java\347\233\270\345\205\263/synchronized.md" b/Java/synchronized.md similarity index 100% rename from "Java\347\233\270\345\205\263/synchronized.md" rename to Java/synchronized.md diff --git "a/Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" similarity index 100% rename from "Java\347\233\270\345\205\263/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" rename to "Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" diff --git "a/Java\347\233\270\345\205\263/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" "b/Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" similarity index 100% rename from "Java\347\233\270\345\205\263/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" rename to "Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" diff --git "a/Java\347\233\270\345\205\263/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" "b/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" similarity index 100% rename from "Java\347\233\270\345\205\263/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" rename to "Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" diff --git "a/Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" "b/Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" similarity index 100% rename from "Java\347\233\270\345\205\263/\350\256\276\350\256\241\346\250\241\345\274\217.md" rename to "Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" diff --git "a/Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" "b/Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" similarity index 100% rename from "Java\347\233\270\345\205\263/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" rename to "Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" From 4fa37666687eb84b10b96109b25718163cc084a4 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 10 Mar 2019 11:53:33 +0800 Subject: [PATCH 096/232] Update link --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 97dfe496f46..a86a23e1eee 100644 --- a/README.md +++ b/README.md @@ -56,33 +56,33 @@ ### Java/J2EE 基础 -* [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java基础知识.md) -* [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/J2EE基础知识.md) +* [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) +* [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) * [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) ### Java 集合框架 -* [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) -* [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java集合框架常见面试题总结.md) -* [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/ArrayList.md) -* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/ArrayList-Grow.md) -* [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) -* [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/HashMap.md) +* [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) +* [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java集合框架常见面试题总结.md) +* [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/ArrayList.md) +* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java/ArrayList-Grow.md) +* [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/LinkedList.md) +* [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/HashMap.md) ### Java 多线程 -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/并发容器总结.md) +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/并发容器总结.md) ### Java 虚拟机 jvm -* [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Java虚拟机(jvm).md) +* [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java虚拟机(jvm).md) ### Java BIO,NIO,AIO From d49e98a9221a990fc0bb2ed6a359136333e63de2 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 10 Mar 2019 11:54:31 +0800 Subject: [PATCH 097/232] Fix link error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a86a23e1eee..77133eaa8cf 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) -* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) +* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/final、static、this、super.md) ### Java 集合框架 From 64bd23ed2be89a56652780871dfe784d55a15683 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Sun, 10 Mar 2019 12:04:58 +0800 Subject: [PATCH 098/232] Update README.md --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 97dfe496f46..b446cbd00f5 100644 --- a/README.md +++ b/README.md @@ -62,12 +62,14 @@ ### Java 集合框架 -* [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) -* [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java集合框架常见面试题总结.md) -* [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/ArrayList.md) -* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/ArrayList-Grow.md) -* [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) -* [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/HashMap.md) +* **常见问题总结:** + * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java集合框架常见面试题总结.md) +* **源码分析:** + * [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/ArrayList-Grow.md) + * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) + * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/HashMap.md) ### Java 多线程 From 67f4458fa96d4af029f495135d0451945b6fa21f Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sun, 10 Mar 2019 14:38:21 +0800 Subject: [PATCH 099/232] Update link error --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index b446cbd00f5..35d96d7251c 100644 --- a/README.md +++ b/README.md @@ -56,44 +56,44 @@ ### Java/J2EE 基础 -* [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java基础知识.md) -* [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/J2EE基础知识.md) -* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/final、static、this、super.md) +* [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) +* [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) +* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/final、static、this、super.md) ### Java 集合框架 * **常见问题总结:** - * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) - * [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/Java集合框架常见面试题总结.md) + * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java集合框架常见面试题总结.md) * **源码分析:** - * [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/ArrayList.md) - * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/ArrayList-Grow.md) - * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) - * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/HashMap.md) + * [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java/ArrayList-Grow.md) + * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/HashMap.md) ### Java 多线程 -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Multithread/并发容器总结.md) +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/并发容器总结.md) ### Java 虚拟机 jvm -* [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Java虚拟机(jvm).md) +* [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java虚拟机(jvm).md) ### Java BIO,NIO,AIO -* [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/Java%20IO与NIO.md) +* [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java/BIO%2CNIO%2CAIO%20summary.md) +* [Java IO 与 NIO系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java%20IO与NIO.md) ### 设计模式 -* [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java相关/设计模式.md) +* [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/设计模式.md) ## 数据结构与算法 From 5053edca3ac5071f5e8f3db84f21d6acca795091 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 19:50:05 +0800 Subject: [PATCH 100/232] 0.0.1 Snapshot --- .../What's New in JDK8/README.md" | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 "Java\347\233\270\345\205\263/What's New in JDK8/README.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/README.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/README.md" new file mode 100644 index 00000000000..3206a31e4fd --- /dev/null +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/README.md" @@ -0,0 +1,24 @@ +JDK8新特性总结 +====== +总结了部分JDK8新特性,另外一些新特性可以通过Oracle的官方文档查看,毕竟是官方文档,各种新特性都会介绍,有兴趣的可以去看。
+[Oracle官方文档:What's New in JDK8](https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html) +----- +- [Java语言特性]() + - [Lambda表达式是一个新的语言特性,已经在JDK8中加入。它是一个可以传递的代码块,你也可以把它们当做方法参数。 + Lambda表达式允许您更紧凑地创建单虚方法接口(称为功能接口)的实例。]() + + - [方法引用为已经存在的具名方法提供易于阅读的Lambda表达式]() + + - [默认方法允许将新功能添加到库的接口,并确保与为这些接口的旧版本编写的代码的二进制兼容性。]() + + - [改进的类型推断。]() + + - [方法参数反射。]() + +- [流(stream)]() + - [新java.util.stream包中的类提供Stream API以支持对元素流的功能样式操作。流(stream)和I/O里的流不是同一个概念 + ,使用stream API可以更方便的操作集合。]() + +- [国际化]() + - 代办 +- 代办 From 2b204632274dc2119ab2d0d0a76e1ff3b83190e0 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 21:27:08 +0800 Subject: [PATCH 101/232] =?UTF-8?q?Create=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...da\350\241\250\350\276\276\345\274\217.md" | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 "Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" new file mode 100644 index 00000000000..0d1b89981f6 --- /dev/null +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -0,0 +1,64 @@ +JDK8--Lambda表达式 +=== +## 1.什么是Lambda表达式 +**Lambda表达式实质上是一个可传递的代码块,Lambda又称为闭包或者匿名函数,是函数式编程语法,让方法可以像普通参数一样传递** + +## 2.Lambda表达式语法 +```(参数列表) -> {执行代码块}``` +
参数列表可以为空```()->{}``` +
可以加类型声明比如```(String para1, int para2) -> {return para1 + para2;}```我们可以看到,lambda同样可以有返回值. +
在编译器可以推断出类型的时候,可以将类型声明省略,比如```(para1, para2) -> {return para1 + para2;}``` +
(lambda有点像动态类型语言,并且lambda在字节码层面是用invokedynamic实现的,而这条指令就是为了让JVM更好的支持运行在其上的动态类型语言) + +## 3.函数式接口 +在了解Lambda表达式之前,有必要先了解什么是函数式接口```(@FunctionalInterface)```
+**函数式接口指的是有且只有一个抽象(abstract)方法的接口**
+当需要一个函数式接口的对象时,就可以用Lambda表达式来实现,举个常用的例子: +
+``` + Thread thread = new Thread(() -> { + System.out.println("This is JDK8's Lambda!"); + }); +``` +这段代码和函数式接口有啥关系?我们回忆一下,Thread类的构造函数里是不是有一个以Runnable接口为参数的? +``` +public Thread(Runnable target) {...} + +/** + * Runnable Interface + */ +@FunctionalInterface +public interface Runnable { + public abstract void run(); +} +``` +到这里大家可能已经明白了,**Lambda表达式相当于一个匿名类或者说是一个匿名方法**。上面Thread的例子相当于 +``` + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + System.out.println("Anonymous class"); + } + }); +``` +也就是说,上面的lambda表达式相当于实现了这个run()方法,然后当做参数传入(个人感觉可以这么理解,lambda表达式就是一个函数,只不过它的返回值、参数列表都 +由编译器帮我们推断,因此可以减少很多代码量)。 +
至此大家应该明白什么是函数式接口以及函数式接口和lambda表达式之间的关系了。在JDK8中修改了接口的规范, +目的是为了在给接口添加新的功能时保持向前兼容(个人理解),比如一个已经定义了的函数式接口,某天我们想给它添加新功能,那么就不能保持向前兼容了, +因为在旧的接口规范下,添加新功能必定会破坏这个函数式接口[(JDK8中接口规范)]() +
+除了上面说的Runnable接口之外,JDK中已经存在了很多函数式接口 +比如(当然不止这些): +- ```java.util.concurrent.Callable``` +- ```java.util.Comparator``` +- ```java.io.FileFilter``` +
**关于JDK中的预定义的函数式接口** + +- JDK在```java.util.function```下预定义了很多函数式接口 + - ```Function {R apply(T t);}``` 接受一个T对象,然后返回一个R对象,就像普通的函数。 + - ```Consumer {void accept(T t);}``` 消费者 接受一个T对象,没有返回值。 + - ```Predicate {boolean test(T t);}``` 判断,接受一个T对象,返回一个布尔值。 + - ```Supplier {T get();} 提供者(工厂)``` 返回一个T对象。 + - 其他的跟上面的相似,大家可以看一下function包下的具体接口。 + +## 4.[方法引用]() From d1c564bb84bc4f6821f8c6ab1f38f1198c07be13 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 21:27:51 +0800 Subject: [PATCH 102/232] Update README.md --- "Java\347\233\270\345\205\263/What's New in JDK8/README.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/README.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/README.md" index 3206a31e4fd..b7612fa4183 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/README.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/README.md" @@ -5,7 +5,7 @@ JDK8新特性总结 ----- - [Java语言特性]() - [Lambda表达式是一个新的语言特性,已经在JDK8中加入。它是一个可以传递的代码块,你也可以把它们当做方法参数。 - Lambda表达式允许您更紧凑地创建单虚方法接口(称为功能接口)的实例。]() + Lambda表达式允许您更紧凑地创建单虚方法接口(称为功能接口)的实例。](https://github.com/Goose9527/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/What's%20New%20in%20JDK8/Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F.md) - [方法引用为已经存在的具名方法提供易于阅读的Lambda表达式]() From cfbc8c45cf4ec466c8bd8e79a547e3018c3ec09a Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:44:54 +0800 Subject: [PATCH 103/232] =?UTF-8?q?Create=20JDK8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A7=84=E8=8C=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...45\345\217\243\350\247\204\350\214\203.md" | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 "Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" new file mode 100644 index 00000000000..0332ecced69 --- /dev/null +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" @@ -0,0 +1,164 @@ +JDK8接口规范 +=== +在JDK8中引入了lambda表达式,因此出现了函数式接口的概念,为了保持向前兼容性(比如泛型也是为了保持兼容性而失去了在一些别的语言泛型拥有的功能), +Java接口规范发生了一些改变。 +--- +## 1.JDK8以前的接口规范 +- JDK8以前接口可以定义的变量和方法 + - 所有变量(Field)不论是否显式 的声明为```public static final```,它实际上都是```public static final```的。 + - 所有方法(Method)不论是否显示 的声明为```public abstract```,它实际上都是```public abstract```的。 +```java +public interface AInterfaceBeforeJDK8 { + int FIELD = 0; + void simpleMethod(); +} +``` +以上接口信息反编译以后可以看到字节码信息里Filed是public static final的,而方法是public abstract的,即是你没有显示的去声明它。 +```java +{ + public static final int FIELD; + descriptor: I + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + ConstantValue: int 0 + + public abstract void simpleMethod(); + descriptor: ()V + flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT +} +``` +## 2.JDK8之后的接口规范 +- JDK8之后接口可以定义的变量和方法 + - 变量(Field)仍然必须是 ```java public static final```的 + - 方法(Method)除了可以是public abstract之外,还可以是public static或者是default(相当于仅public修饰的实例方法)的。 +从以上改变不难看出,修改接口的规范主要是为了能在扩展接口时保持向前兼容。 +
下面是一个JDK8之后的接口例子 +```java +public interface AInterfaceInJDK8 { + int simpleFiled = 0; + static int staticField = 1; + + public static void main(String[] args) { + } + static void staticMethod(){} + + default void defaultMethod(){} + + void simpleMethod() throws IOException; + +} +``` +进行反编译(去除了一些没用信息) +```java +{ + public static final int simpleFiled; + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + + public static final int staticField; + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + + public static void main(java.lang.String[]); + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + + public static void staticMethod(); + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + + public void defaultMethod(); + flags: (0x0001) ACC_PUBLIC + + public abstract void simpleMethod() throws java.io.IOException; + flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT + Exceptions: + throws java.io.IOException +} +``` +可以看到 default关键字修饰的方法是像实例方法一样定义的,所以我们来定义一个只有default的方法并且实现一下试一试。 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} + +public class DefaultMethod implements Default { + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + //compile error : Non-static method 'defaultMethod()' cannot be referenced from a static context + //! DefaultMethod.defaultMethod(); + } +} +``` +可以看到default方法确实像实例方法一样,必须有实例对象才能调用,并且子类在实现接口时,可以不用实现default方法,也可以覆盖该方法。 +这有点像子类继承父类实例方法。 +
+接口静态方法就像是类静态方法,唯一的区别是**接口静态方法只能通过接口名调用,而类静态方法既可以通过类名调用也可以通过实例调用** +```java +interface Static { + static int staticMethod() { + return 4396; + } +} + ... main(String...args) + //!compile error: Static method may be invoked on containing interface class only + //!aInstanceOfStatic.staticMethod(); + ... +``` +另一个问题是多继承问题,大家知道Java中类是不支持多继承的,但是接口是多继承和多实现(implements后跟多个接口)的, +那么如果一个接口继承另一个接口,两个接口都有同名的default方法会怎么样呢?答案是会像类继承一样覆写(@Override),以下代码在IDE中可以顺利编译 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} +interface Default2 extends Default { + @Override + default int defaultMethod() { + return 9527; + } +} +public class DefaultMethod implements Default,Default2 { + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + } +} + +输出 : 9527 +``` +出现上面的情况时,会优先找继承树上近的方法,类似于“短路优先”。 +
+那么如果一个类实现了两个没有继承关系的接口,且这两个接口有同名方法的话会怎么样呢?IDE会要求你重写这个冲突的方法,让你自己选择去执行哪个方法,因为IDE它 +还没智能到你不告诉它,它就知道你想执行哪个方法。可以通过```java 接口名.super```指针来访问接口中定义的实例(default)方法。 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} + +interface Default2 { + default int defaultMethod() { + return 9527; + } +} +//如果不重写 +//compile error : defaults.DefaultMethod inherits unrelated defaults for defaultMethod() from types defaults.Default and defaults.Default2 +public class DefaultMethod implements Default,Default2 { +@Override + public int defaultMethod() { + System.out.println(Default.super.defaultMethod()); + System.out.println(Default2.super.defaultMethod()); + return 996; + } + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + } +} + +运行输出 : +4396 +9527 +996 +``` From 2fa0457b87a30b203064ffdf9551a01f41872d01 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:45:36 +0800 Subject: [PATCH 104/232] =?UTF-8?q?Update=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lambda\350\241\250\350\276\276\345\274\217.md" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index 0d1b89981f6..ab1c75be2e9 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -15,13 +15,13 @@ JDK8--Lambda表达式 **函数式接口指的是有且只有一个抽象(abstract)方法的接口**
当需要一个函数式接口的对象时,就可以用Lambda表达式来实现,举个常用的例子:
-``` +```java Thread thread = new Thread(() -> { System.out.println("This is JDK8's Lambda!"); }); ``` 这段代码和函数式接口有啥关系?我们回忆一下,Thread类的构造函数里是不是有一个以Runnable接口为参数的? -``` +```java public Thread(Runnable target) {...} /** @@ -33,7 +33,7 @@ public interface Runnable { } ``` 到这里大家可能已经明白了,**Lambda表达式相当于一个匿名类或者说是一个匿名方法**。上面Thread的例子相当于 -``` +```java Thread thread = new Thread(new Runnable() { @Override public void run() { From e929c8ba24a8df808febea51ee00f7ce7aa35ac7 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:51:13 +0800 Subject: [PATCH 105/232] =?UTF-8?q?Update=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lambda\350\241\250\350\276\276\345\274\217.md" | 2 -- 1 file changed, 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index ab1c75be2e9..bf27300f1bd 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -60,5 +60,3 @@ public interface Runnable { - ```Predicate {boolean test(T t);}``` 判断,接受一个T对象,返回一个布尔值。 - ```Supplier {T get();} 提供者(工厂)``` 返回一个T对象。 - 其他的跟上面的相似,大家可以看一下function包下的具体接口。 - -## 4.[方法引用]() From 36147197d7d5de1809b872d8a654719e26653df8 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:52:06 +0800 Subject: [PATCH 106/232] =?UTF-8?q?Update=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...da\350\241\250\350\276\276\345\274\217.md" | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index bf27300f1bd..a7ef7f93cd0 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -60,3 +60,29 @@ public interface Runnable { - ```Predicate {boolean test(T t);}``` 判断,接受一个T对象,返回一个布尔值。 - ```Supplier {T get();} 提供者(工厂)``` 返回一个T对象。 - 其他的跟上面的相似,大家可以看一下function包下的具体接口。 +## 4.变量作用域 +```java +public class VaraibleHide { + @FunctionalInterface + interface IInner { + void printInt(int x); + } + public static void main(String[] args) { + int x = 20; + IInner inner = new IInner() { + int x = 10; + @Override + public void printInt(int x) { + System.out.println(x); + } + }; + inner.printInt(30); + inner = (s) -> { + //!int x = 10; + //!x= 50; error + System.out.print(x); + }; + inner.printInt(30); + } +} +``` From 38e568cbe590866e2cf220bad0aafe9c34169df9 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:58:23 +0800 Subject: [PATCH 107/232] =?UTF-8?q?Update=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lambda\350\241\250\350\276\276\345\274\217.md" | 7 +++++++ 1 file changed, 7 insertions(+) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index a7ef7f93cd0..eb97bcc06ef 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -78,6 +78,7 @@ public class VaraibleHide { }; inner.printInt(30); inner = (s) -> { + //Variable used in lambda expression should be final or effectively final //!int x = 10; //!x= 50; error System.out.print(x); @@ -85,4 +86,10 @@ public class VaraibleHide { inner.printInt(30); } } +输出 : +30 +20 ``` +lambda表达式和内部类一样,对外部变量捕获时,外部变量必须为final或者是最终变量(effectively final)的,也就是说这个变量初始化后就不能为它赋新值, +同时lambda不像内部类/匿名类,lambda表达式与外围嵌套块有着相同的作用域,因此对变量命名的有关规则对lambda同样适用。 +## 5.[方法引用]() From a771278b56db2dfb96e1d1a766dab00ef870eda1 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Sun, 10 Mar 2019 22:59:10 +0800 Subject: [PATCH 108/232] =?UTF-8?q?Create=20=E6=96=B9=E6=B3=95=E5=BC=95?= =?UTF-8?q?=E7=94=A8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\346\226\271\346\263\225\345\274\225\347\224\250.md" | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 "Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" new file mode 100644 index 00000000000..e8f2fcb9f94 --- /dev/null +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" @@ -0,0 +1,2 @@ +JDK8-Lambda-方法引用 +=== From 8213beabc8d0a925f2777815646879b7fbb57521 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Mon, 11 Mar 2019 09:06:13 +0800 Subject: [PATCH 109/232] =?UTF-8?q?Create=20=E5=A6=82=E6=9E=9C=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E5=AE=98=E9=97=AE=E4=BD=A0=E2=80=9C=E4=BD=A0=E6=9C=89?= =?UTF-8?q?=E4=BB=80=E4=B9=88=E9=97=AE=E9=A2=98=E9=97=AE=E6=88=91=E5=90=97?= =?UTF-8?q?=EF=BC=9F=E2=80=9D=E6=97=B6=EF=BC=8C=E4=BD=A0=E8=AF=A5=E5=A6=82?= =?UTF-8?q?=E4=BD=95=E5=9B=9E=E7=AD=94.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...02\344\275\225\345\233\236\347\255\224.md" | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 "EssentialContentForInterview/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" diff --git "a/EssentialContentForInterview/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/EssentialContentForInterview/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" new file mode 100644 index 00000000000..d4d6b64b0a5 --- /dev/null +++ "b/EssentialContentForInterview/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" @@ -0,0 +1,64 @@ +我还记得当时我去参加面试的时候,几乎每一场面试,特别是HR面和高管面的时候,面试官总是会在结尾问我:“问了你这么多问题了,你有什么问题问我吗?”。这个时候很多人内心就会陷入短暂的纠结中:我该问吗?不问的话面试官会不会对我影响不好?问什么问题?问这个问题会不会让面试官对我的影响不好啊? + +![无奈](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/无奈.jpg) + +### 这个问题对最终面试结果的影响到底大不大? + +就技术面试而言,回答这个问题的时候,只要你不是触碰到你所面试的公司的雷区,那么我觉得这对你能不能拿到最终offer来说影响确实是不大的。我说这些并不代表你就可以直接对面试官说:“我没问题了。”,笔主当时面试的时候确实也说过挺多次“没问题要问了。”,最终也没有导致笔主被pass掉(可能是前面表现比较好,哈哈,自恋一下)。我现在回想起来,觉得自己当时做法其实挺不对的。面试本身就是一个双向选择的过程,你对这个问题的回答也会侧面反映出你对这次面试的上心程度,你的问题是否有价值,也影响了你最终的选择与公司是否选择你。 + +面试官在技术面试中主要考察的还是你这样个人到底有没有胜任这个工作的能力以及你是否适合公司未来的发展需要,很多公司还需要你认同它的文化,我觉得你只要不是太笨,应该不会栽在这里。除非你和另外一个人在能力上相同,但是只能在你们两个人中选一个,那么这个问题才对你能不能拿到offer至关重要。有准备总比没准备好,给面试官留一个好的影响总归是没错的。 + +但是,就非技术面试来说,我觉得好好回答这个问题对你最终的结果还是比较重要的。 + +总的来说不管是技术面试还是非技术面试,如果你想赢得公司的青睐和尊重,我觉得我们都应该重视这个问题。 + +### 真诚一点,不要问太 Low 的问题 + +回答这个问题很重要的一点就是你没有必要放低自己的姿态问一些很虚或者故意讨好面试官的问题,也不要把自己从面经上学到的东西照搬下来使用。面试官也不是傻子,特别是那种特别有经验的面试官,你是真心诚意的问问题,还是从别处照搬问题来讨好面试官,人家可能一听就听出来了。总的来说,还是要真诚。除此之外,不要问太Low的问题,会显得你整个人格局比较小或者说你根本没有准备(侧面反映你对这家公司不伤心,既然你不上心,为什么要要你呢)。举例几个比较 Low 的问题,大家看看自己有没有问过其中的问题: + +- 贵公司的主要业务是什么?(面试之前自己不知道提前网上查一下吗?) +- 贵公司的男女比例如何?(考虑脱单?记住你是来工作的!) +- 贵公司一年搞几次外出旅游?(你是来工作的,这些娱乐活动先别放在心上!) +- ...... + +### 有哪些有价值的问题值得问? + +针对这个问题。笔主专门找了几个专门做HR工作的小哥哥小姐姐们询问并且查阅了挺多前辈们的回答,然后结合自己的实际经历,我概括了下面几个比较适合问的问题。 + +#### 面对HR或者其他Level比较低的面试官时 + +1. **能不能谈谈你作为一个公司老员工对公司的感受?** (这个问题比较容易回答,不会让面试官陷入无话可说的尴尬境地。另外,从面试官的回答中你可以加深对这个公司的了解,让你更加清楚这个公司到底是不是你想的那样或者说你是否能适应这个公司的文化。除此之外,这样的问题在某种程度上还可以拉进你与面试官的距离。) +2. **能不能问一下,你当时因为什么原因选择加入这家公司的呢或者说这家公司有哪些地方吸引你?有什么地方你觉得还不太好或者可以继续完善吗?** (类似第一个问题,都是问面试官个人对于公司的看法,) +3. **我觉得我这次表现的不是太好,你有什么建议或者评价给我吗?**(这个是我常问的。我觉得说自己表现不好只是这个语境需要这样来说,这样可以显的你比较谦虚好学上进。) +4. **接下来我会有一段空档期,有什么值得注意或者建议学习的吗?** (体现出你对工作比较上心,自助学习意识比较强。) +5. **这个岗位为什么还在招人?** (岗位真实性和价值咨询) +6. **大概什么时候能给我回复呢?** (终面的时候,如果面试官没有说的话,可以问一下) +7. ...... + + + +#### 面对部门领导 + +1. **部门的主要人员分配以及对应的主要工作能简单介绍一下吗?** +2. **未来如果我要加入这个团队,你对我的期望是什么?** (部门领导一般情况下是你的直属上级了,你以后和他打交道的机会应该是最多的。你问这个问题,会让他感觉你是一个对他的部门比较上心,比较有团体意识,并且愿意倾听的候选人。) +3. **公司对新入职的员工的培养机制是什么样的呢?** (正规的公司一般都有培养机制,提前问一下是对你自己的负责也会显的你比较上心) +4. **以您来看,这个岗位未来在公司内部的发展如何?** (在我看来,问这个问题也是对你自己的负责吧,谁不想发展前景更好的岗位呢?) +5. **团队现在面临的最大挑战是什么?** (这样的问题不会暴露你对公司的不了解,并且也能让你对未来工作的挑战或困难有一个提前的预期。) + + + +#### 面对Level比较高的(比如总裁,老板) + +1. **贵公司的发展目标和方向是什么?** (看下公司的发展是否满足自己的期望) +2. **与同行业的竞争者相比,贵公司的核心竞争优势在什么地方?** (充分了解自己的优势和劣势) +3. **公司现在面临的最大挑战是什么?** + +### 来个补充,顺便送个祝福给大家 + +薪酬待遇和相关福利问题一般在终面的时候(最好不要在前面几面的时候就问到这个问题),面试官会提出来或者在面试完之后以邮件的形式告知你。一般来说,如果面试官很愿意为你回答问题,对你的问题也比较上心的话,那他肯定是觉得你就是他们要招的人。 + +大家在面试的时候,可以根据自己对于公司或者岗位的了解程度,对上面提到的问题进行适当修饰或者修改。上面提到的一些问题只是给没有经验的朋友一个参考,如果你还有其他比较好的问题的话,那当然也更好啦! + +金三银四。过了二月就到了面试高峰期或者说是黄金期。几份惊喜几份愁,愿各位能始终不忘初心!每个人都有每个人的难处。引用一句《阿甘正传》里面的台词:“生活就像一盒巧克力,你永远不知道下一块是什么味道“。 + +![加油!彩虹就要来了](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/生活就像一盒巧克力你永远不知道下一块是什么味道.JPEG) \ No newline at end of file From ab1e546f7afa852d0c2b5c3f1f076948bcda1a43 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 11 Mar 2019 09:10:17 +0800 Subject: [PATCH 110/232] =?UTF-8?q?Add=20=E5=A6=82=E6=9E=9C=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E5=AE=98=E9=97=AE=E4=BD=A0=E2=80=9C=E4=BD=A0=E6=9C=89?= =?UTF-8?q?=E4=BB=80=E4=B9=88=E9=97=AE=E9=A2=98=E9=97=AE=E6=88=91=E5=90=97?= =?UTF-8?q?=EF=BC=9F=E2=80=9D=E6=97=B6=EF=BC=8C=E4=BD=A0=E8=AF=A5=E5=A6=82?= =?UTF-8?q?=E4=BD=95=E5=9B=9E=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35d96d7251c..8968159cd4d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ * [数据通信\(RESTful,RPC,消息队列\)总结](#数据通信restfulrpc消息队列总结) * [操作系统](#操作系统) * [Linux相关](#linux相关) -* [主流框架/软件](#主流框架软件) +* [主流框架](#主流框架) * [Spring](#spring) * [ZooKeeper](#zookeeper) * [数据存储](#数据存储) @@ -129,7 +129,8 @@ * [后端程序员必备的 Linux 基础知识](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/后端程序员必备的Linux基础知识.md) * [Shell 编程入门](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/Shell.md) -## 主流框架/软件 + +## 主流框架 ### Spring @@ -170,7 +171,8 @@ * [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) * [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/books.md) * [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) -* [【备战面试6】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) ### BATJ真实面经(BATJ real interview experience) From 311b0bdc85e6a39e014c5457efc4a0d34bba0263 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Mon, 11 Mar 2019 09:53:20 +0800 Subject: [PATCH 111/232] =?UTF-8?q?Update=20JDK8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A7=84=E8=8C=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" "b/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" index 0332ecced69..ee1dd8c2448 100644 --- "a/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" +++ "b/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" @@ -1,7 +1,6 @@ JDK8接口规范 === -在JDK8中引入了lambda表达式,因此出现了函数式接口的概念,为了保持向前兼容性(比如泛型也是为了保持兼容性而失去了在一些别的语言泛型拥有的功能), -Java接口规范发生了一些改变。 +在JDK8中引入了lambda表达式,出现了函数式接口的概念,为了在扩展接口时保持向前兼容性(比如泛型也是为了保持兼容性而失去了在一些别的语言泛型拥有的功能),Java接口规范发生了一些改变。。 --- ## 1.JDK8以前的接口规范 - JDK8以前接口可以定义的变量和方法 From 2d5923274436535adc33b9d02822b5b3de15eb5a Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Mon, 11 Mar 2019 10:18:17 +0800 Subject: [PATCH 112/232] Update ArrayList-Grow.md --- "Java\347\233\270\345\205\263/ArrayList-Grow.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java\347\233\270\345\205\263/ArrayList-Grow.md" "b/Java\347\233\270\345\205\263/ArrayList-Grow.md" index 87c695192f6..d763cb83492 100644 --- "a/Java\347\233\270\345\205\263/ArrayList-Grow.md" +++ "b/Java\347\233\270\345\205\263/ArrayList-Grow.md" @@ -145,7 +145,7 @@ } ``` -**int newCapacity = oldCapacity + (oldCapacity >> 1),所以在capacity是偶数的情况下,ArrayList 每次扩容之后容量都会变为原来的 1.5 倍,当capacity为奇数时(自己初始化容量时可能出现),第一次扩容容量变为oldCapacity + (oldCapacity - 1) / 2(在计算机运算的情况下减一除和直接除没有差别,对于整数会自动舍掉小数位),也就是说每次扩容相当于计算机中的1.5倍。 !** 记清楚了!不是网上很多人说的 1.5 倍+1!当然了,第一次扩容以后capacity会变为偶数,之后的每次扩容都会是原容量的1.5倍了。 +**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!** 记清楚了!不是网上很多人说的 1.5 倍+1! > ">>"(移位运算符):>>1 右移一位相当于除2,右移n位相当于除以 2 的 n 次方。这里 oldCapacity 明显右移了1位所以相当于oldCapacity /2。对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源   From c336e45ead8b26b029891b2309994e4a11ceabf7 Mon Sep 17 00:00:00 2001 From: HaiQiang <540911185@qq.com> Date: Mon, 11 Mar 2019 10:28:27 +0800 Subject: [PATCH 113/232] Update --- .../JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" | 0 .../Lambda\350\241\250\350\276\276\345\274\217.md" | 0 .../README.md" => Java/What's New in JDK8/README.md | 0 .../\346\226\271\346\263\225\345\274\225\347\224\250.md" | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename "Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" => "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" (100%) rename "Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" => "Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" (100%) rename "Java\347\233\270\345\205\263/What's New in JDK8/README.md" => Java/What's New in JDK8/README.md (100%) rename "Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" => "Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" (100%) diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" "b/Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" similarity index 100% rename from "Java\347\233\270\345\205\263/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" rename to "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" similarity index 100% rename from "Java\347\233\270\345\205\263/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" rename to "Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/README.md" b/Java/What's New in JDK8/README.md similarity index 100% rename from "Java\347\233\270\345\205\263/What's New in JDK8/README.md" rename to Java/What's New in JDK8/README.md diff --git "a/Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" "b/Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" similarity index 100% rename from "Java\347\233\270\345\205\263/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" rename to "Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" From 70257619d65aca5262008f42e09a964c53efe977 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Mon, 11 Mar 2019 10:51:18 +0800 Subject: [PATCH 114/232] =?UTF-8?q?Update=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ambda\350\241\250\350\276\276\345\274\217.md" | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git "a/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index eb97bcc06ef..8351f9f8652 100644 --- "a/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -8,7 +8,7 @@ JDK8--Lambda表达式
参数列表可以为空```()->{}```
可以加类型声明比如```(String para1, int para2) -> {return para1 + para2;}```我们可以看到,lambda同样可以有返回值.
在编译器可以推断出类型的时候,可以将类型声明省略,比如```(para1, para2) -> {return para1 + para2;}``` -
(lambda有点像动态类型语言,并且lambda在字节码层面是用invokedynamic实现的,而这条指令就是为了让JVM更好的支持运行在其上的动态类型语言) +
(lambda有点像动态类型语言语法。lambda在字节码层面是用invokedynamic实现的,而这条指令就是为了让JVM更好的支持运行在其上的动态类型语言) ## 3.函数式接口 在了解Lambda表达式之前,有必要先了解什么是函数式接口```(@FunctionalInterface)```
@@ -43,6 +43,11 @@ public interface Runnable { ``` 也就是说,上面的lambda表达式相当于实现了这个run()方法,然后当做参数传入(个人感觉可以这么理解,lambda表达式就是一个函数,只不过它的返回值、参数列表都 由编译器帮我们推断,因此可以减少很多代码量)。 +
Lambda也可以这样用 : +```java + Runnable runnable = () -> {...}; +``` +其实这和上面的用法没有什么本质上的区别。
至此大家应该明白什么是函数式接口以及函数式接口和lambda表达式之间的关系了。在JDK8中修改了接口的规范, 目的是为了在给接口添加新的功能时保持向前兼容(个人理解),比如一个已经定义了的函数式接口,某天我们想给它添加新功能,那么就不能保持向前兼容了, 因为在旧的接口规范下,添加新功能必定会破坏这个函数式接口[(JDK8中接口规范)]() @@ -77,6 +82,7 @@ public class VaraibleHide { } }; inner.printInt(30); + inner = (s) -> { //Variable used in lambda expression should be final or effectively final //!int x = 10; @@ -90,6 +96,8 @@ public class VaraibleHide { 30 20 ``` -lambda表达式和内部类一样,对外部变量捕获时,外部变量必须为final或者是最终变量(effectively final)的,也就是说这个变量初始化后就不能为它赋新值, -同时lambda不像内部类/匿名类,lambda表达式与外围嵌套块有着相同的作用域,因此对变量命名的有关规则对lambda同样适用。 -## 5.[方法引用]() +对于lambda表达式```java inner = (s) -> {System.out.print(x);};```,变量x并不是在lambda表达式中定义的,像这样并不是在lambda中定义或者通过lambda的参数列表()获取的变量成为自由变量,它是被lambda表达式捕获的。 +
lambda表达式和内部类一样,对外部自由变量捕获时,外部自由变量必须为final或者是最终变量(effectively final)的,也就是说这个变量初始化后就不能为它赋新值, +同时lambda不像内部类/匿名类,lambda表达式与外围嵌套块有着相同的作用域,因此对变量命名的有关规则对lambda同样适用。大家阅读上面的代码对这些概念应该 +不难理解。 +## 5.[方法引用](../方法引用.md) From 72050e60a14e28cdf0281020380a750b7e5bc450 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Mon, 11 Mar 2019 10:54:49 +0800 Subject: [PATCH 115/232] =?UTF-8?q?Rename=20JDK8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A7=84=E8=8C=83.md=20to=20JDK8=E6=8E=A5=E5=8F=A3=E8=A7=84?= =?UTF-8?q?=E8=8C=83-=E9=9D=99=E6=80=81=E3=80=81=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=96=B9=E6=B3=95.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...43\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" => "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" (100%) diff --git "a/Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" "b/Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" similarity index 100% rename from "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203.md" rename to "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" From 98a085c9f0e1b458cb5aaf40d5aa0788ad9c4d0d Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Mon, 11 Mar 2019 14:49:31 +0800 Subject: [PATCH 116/232] =?UTF-8?q?JDK8=20Lambda=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.0.1 SNAPSHOT --- ...da\350\241\250\350\276\276\345\274\217.md" | 134 +++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git "a/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" index 8351f9f8652..359c4714473 100644 --- "a/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" +++ "b/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" @@ -100,4 +100,136 @@ public class VaraibleHide {
lambda表达式和内部类一样,对外部自由变量捕获时,外部自由变量必须为final或者是最终变量(effectively final)的,也就是说这个变量初始化后就不能为它赋新值, 同时lambda不像内部类/匿名类,lambda表达式与外围嵌套块有着相同的作用域,因此对变量命名的有关规则对lambda同样适用。大家阅读上面的代码对这些概念应该 不难理解。 -## 5.[方法引用](../方法引用.md) +## 5.方法引用 +**只需要提供方法的名字,具体的调用过程由Lambda和函数式接口来确定,这样的方法调用成为方法引用。** +
下面的例子会打印list中的每个元素: +```java +List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(System.out::println); +``` +其中```System.out::println```这个就是一个方法引用,等价于Lambda表达式 ```(para)->{System.out.println(para);}``` +
我们看一下List#forEach方法 ```default void forEach(Consumer action)```可以看到它的参数是一个Consumer接口,该接口是一个函数式接口 +```java +@FunctionalInterface +public interface Consumer { + void accept(T t); +``` +大家能发现这个函数接口的方法和```System.out::println```有什么相似的么?没错,它们有着相似的参数列表和返回值。 +
我们自己定义一个方法,看看能不能像标准输出的打印函数一样被调用 +```java +public class MethodReference { + public static void main(String[] args) { + List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(MethodReference::myPrint); + } + + static void myPrint(int i) { + System.out.print(i + ", "); + } +} + +输出: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +``` +可以看到,我们自己定义的方法也可以当做方法引用。 +
到这里大家多少对方法引用有了一定的了解,我们再来说一下方法引用的形式。 +- 方法引用 + - 类名::静态方法名 + - 类名::实例方法名 + - 类名::new (构造方法引用) + - 实例名::实例方法名 +可以看出,方法引用是通过(方法归属名)::(方法名)来调用的。通过上面的例子已经讲解了一个`类名::静态方法名`的使用方法了,下面再依次介绍其余的几种 +方法引用的使用方法。
+**类名::实例方法名**
+先来看一段代码 +```java + String[] strings = new String[10]; + Arrays.sort(strings, String::compareToIgnoreCase); +``` +**上面的String::compareToIgnoreCase等价于(x, y) -> {return x.compareToIgnoreCase(y);}**
+我们看一下`Arrays#sort`方法`public static void sort(T[] a, Comparator c)`, +可以看到第二个参数是一个Comparator接口,该接口也是一个函数式接口,其中的抽象方法是`int compare(T o1, T o2);`,再看一下 +`String#compareToIgnoreCase`方法,`public int compareToIgnoreCase(String str)`,这个方法好像和上面讲方法引用中`类名::静态方法名`不大一样啊,它 +的参数列表和函数式接口的参数列表不一样啊,虽然它的返回值一样? +
是的,确实不一样但是别忘了,String类的这个方法是个实例方法,而不是静态方法,也就是说,这个方法是需要有一个接收者的。所谓接收者就是 +instance.method(x)中的instance, +它是某个类的实例,有的朋友可能已经明白了。上面函数式接口的`compare(T o1, T o2)`中的第一个参数作为了实例方法的接收者,而第二个参数作为了实例方法的 +参数。我们再举一个自己实现的例子: +```java +public class MethodReference { + static Random random = new Random(47); + public static void main(String[] args) { + MethodReference[] methodReferences = new MethodReference[10]; + Arrays.sort(methodReferences, MethodReference::myCompare); + } + int myCompare(MethodReference o) { + return random.nextInt(2) - 1; + } +} +``` +上面的例子可以在IDE里通过编译,大家有兴趣的可以模仿上面的例子自己写一个程序,打印出排序后的结果。 +
**构造器引用**
+构造器引用仍然需要与特定的函数式接口配合使用,并不能像下面这样直接使用。IDE会提示String不是一个函数式接口 +```java + //compile error : String is not a functional interface + String str = String::new; +``` +下面是一个使用构造器引用的例子,可以看出构造器引用可以和这种工厂型的函数式接口一起使用的。 +```java + interface IFunctional { + T func(); +} + +public class ConstructorReference { + + public ConstructorReference() { + } + + public static void main(String[] args) { + Supplier supplier0 = () -> new ConstructorReference(); + Supplier supplier1 = ConstructorReference::new; + IFunctional functional = () -> new ConstructorReference(); + IFunctional functional1 = ConstructorReference::new; + } +} +``` +下面是一个JDK官方的例子 +```java + public static , DEST extends Collection> + DEST transferElements( + SOURCE sourceCollection, + Supplier collectionFactory) { + + DEST result = collectionFactory.get(); + for (T t : sourceCollection) { + result.add(t); + } + return result; + } + + ... + + Set rosterSet = transferElements( + roster, HashSet::new); +``` + +**实例::实例方法** +
+其实开始那个例子就是一个实例::实例方法的引用 +```java +List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(System.out::println); +``` +其中System.out就是一个实例,println是一个实例方法。相信不用再给大家做解释了。 +## 总结 +Lambda表达式是JDK8引入Java的函数式编程语法,使用Lambda需要直接或者间接的与函数式接口配合,在开发中使用Lambda可以减少代码量, +但是并不是说必须要使用Lambda(虽然它是一个很酷的东西)。有些情况下使用Lambda会使代码的可读性急剧下降,并且也节省不了多少代码, +所以在实际开发中还是需要仔细斟酌是否要使用Lambda。和Lambda相似的还有JDK10中加入的var类型推断,同样对于这个特性需要斟酌使用。 From bcb8ba35822827c04cf10b1bbcb254a58fa43bd9 Mon Sep 17 00:00:00 2001 From: HaiQiang <540911185@qq.com> Date: Mon, 11 Mar 2019 14:55:53 +0800 Subject: [PATCH 117/232] =?UTF-8?q?Delete=20=E6=96=B9=E6=B3=95=E5=BC=95?= =?UTF-8?q?=E7=94=A8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\346\226\271\346\263\225\345\274\225\347\224\250.md" | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 "Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" diff --git "a/Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" "b/Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" deleted file mode 100644 index e8f2fcb9f94..00000000000 --- "a/Java/What's New in JDK8/\346\226\271\346\263\225\345\274\225\347\224\250.md" +++ /dev/null @@ -1,2 +0,0 @@ -JDK8-Lambda-方法引用 -=== From 89e2be28e17f922f1dd7e5567299d44b3e52582a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E6=99=A8?= Date: Mon, 11 Mar 2019 15:01:24 +0800 Subject: [PATCH 118/232] Update Redis.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正参考文档链接格式 --- .../Redis/Redis.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" index 5732c156825..a53a6481a00 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" @@ -262,7 +262,7 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。 参考: -- https://blog.csdn.net/zeb_perfect/article/details/54135506[enter link description here](https://blog.csdn.net/zeb_perfect/article/details/54135506) +- [https://blog.csdn.net/zeb_perfect/article/details/54135506](https://blog.csdn.net/zeb_perfect/article/details/54135506) ### 如何解决 Redis 的并发竞争 Key 问题 From 9e07a4c7b98e4190c03b17e8c08505bcb3324351 Mon Sep 17 00:00:00 2001 From: yangzheng Date: Tue, 12 Mar 2019 11:52:42 +0800 Subject: [PATCH 119/232] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Java/LinkedList.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java/LinkedList.md b/Java/LinkedList.md index 31f5f4838e9..b8083232ab2 100644 --- a/Java/LinkedList.md +++ b/Java/LinkedList.md @@ -186,7 +186,7 @@ public void addLast(E e) { } ``` ### 根据位置取数据的方法 -**get(int index):**:根据指定索引返回数据 +**get(int index):** 根据指定索引返回数据 ```java public E get(int index) { //检查index范围是否在size之内 From 29cf2d235c6513372858c1fb8fa49753ed1d0ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=B3=E9=98=B3?= <260893248@qq.com> Date: Tue, 12 Mar 2019 12:51:08 +0800 Subject: [PATCH 120/232] =?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 错别字修改 --- Java/synchronized.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java/synchronized.md b/Java/synchronized.md index b0b0700ad8e..d415152ac48 100644 --- a/Java/synchronized.md +++ b/Java/synchronized.md @@ -12,7 +12,7 @@ Github 地址:[https://github.com/Snailclimb/JavaGuide/edit/master/Java相关/ 下面我已一个常见的面试题为例讲解一下 synchronized 关键字的具体使用。 -面试中面试官经常会说:“单例模式了解吗?来给我手写一下!给我解释一下双重检验锁方式实现单利模式的原理呗!” +面试中面试官经常会说:“单例模式了解吗?来给我手写一下!给我解释一下双重检验锁方式实现单例模式的原理呗!” From 056b37e3eae2d7932b2c13e07df4579de53a9f80 Mon Sep 17 00:00:00 2001 From: yangzheng Date: Tue, 12 Mar 2019 14:17:08 +0800 Subject: [PATCH 121/232] =?UTF-8?q?=E6=B7=BB=E5=8A=A0//=20=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Java/LinkedList.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Java/LinkedList.md b/Java/LinkedList.md index b8083232ab2..983c1fae0d0 100644 --- a/Java/LinkedList.md +++ b/Java/LinkedList.md @@ -220,7 +220,7 @@ public E peekFirst() { getFirst(),element(),peek(),peekFirst() 这四个获取头结点方法的区别在于对链表为空时的处理,是抛出异常还是返回null,其中**getFirst()** 和**element()** 方法将会在链表为空时,抛出异常 -element()方法的内部就是使用getFirst()实现的。它们会在链表为空时,抛出NoSuchElementException +element()方法的内部就是使用getFirst()实现的。它们会在链表为空时,抛出NoSuchElementException **获取尾节点(index=-1)数据方法:** ```java public E getLast() { @@ -359,7 +359,7 @@ E unlink(Node x) { //删除前驱指针 if (prev == null) { - first = next;如果删除的节点是头节点,令头节点指向该节点的后继节点 + first = next;//如果删除的节点是头节点,令头节点指向该节点的后继节点 } else { prev.next = next;//将前驱节点的后继节点指向后继节点 x.prev = null; From 3731f4d51401f320abb89cce1d91520fe731fff3 Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Tue, 12 Mar 2019 17:08:30 +0800 Subject: [PATCH 122/232] Create Java8Tutorial.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java8新特性总结,翻译自https://github.com/winterbe/java8-tutorial,在原文增加了一些内容 --- Java/What's New in JDK8/Java8Tutorial.md | 888 +++++++++++++++++++++++ 1 file changed, 888 insertions(+) create mode 100644 Java/What's New in JDK8/Java8Tutorial.md diff --git a/Java/What's New in JDK8/Java8Tutorial.md b/Java/What's New in JDK8/Java8Tutorial.md new file mode 100644 index 00000000000..80736282cfa --- /dev/null +++ b/Java/What's New in JDK8/Java8Tutorial.md @@ -0,0 +1,888 @@ +随着 Java 8 的普及度越来越高,很多人都提到面试中关于Java 8 也是非常常问的知识点。应各位要求和需要,我打算对这部分知识做一个总结。本来准备自己总结的,后面看到Github 上有一个相关的仓库,地址: +[https://github.com/winterbe/java8-tutorial](https://github.com/winterbe/java8-tutorial)。这个仓库是英文的,我对其进行了翻译并添加和修改了部分内容,下面是正文了。 + +# Java 8 + +欢迎阅读我对Java 8的介绍。本教程将逐步指导您完成所有新语言功能。 在简短的代码示例的基础上,您将学习如何使用默认接口方法,lambda表达式,方法引用和可重复注释。 在本文的最后,您将熟悉最新的 API 更改,如流,函数式接口(Functional Interfaces),Map 类的扩展和新的 Date API。 没有大段枯燥的文字,只有一堆注释的代码片段。 + + +### 接口的默认方法(Default Methods for Interfaces) + +Java 8使我们能够通过使用 `default` 关键字向接口添加非抽象方法实现。 此功能也称为[虚拟扩展方法](http://stackoverflow.com/a/24102730)。 + +第一个例子: + +```java +interface Formula{ + + double calculate(int a); + + default double sqrt(int a) { + return Math.sqrt(a); + } + +} +``` + +Formula 接口中除了抽象方法计算接口公式还定义了默认方法 `sqrt`。 实现该接口的类只需要实现抽象方法 `calculate`。 默认方法`sqrt` 可以直接使用。当然你也可以直接通过接口创建对象,然后实现接口中的默认方法就可以了,我们通过代码演示一下这种方式。 + +```java +public class Main { + + public static void main(String[] args) { + // TODO 通过匿名内部类方式访问接口 + Formula formula = new Formula() { + @Override + public double calculate(int a) { + return sqrt(a * 100); + } + }; + + System.out.println(formula.calculate(100)); // 100.0 + System.out.println(formula.sqrt(16)); // 4.0 + + } + +} +``` + + formula 是作为匿名对象实现的。该代码非常容易理解,6行代码实现了计算 `sqrt(a * 100)`。在下一节中,我们将会看到在 Java 8 中实现单个方法对象有一种更好更方便的方法。 + +**译者注:** 不管是抽象类还是接口,都可以通过匿名内部类的方式访问。不能通过抽象类或者接口直接创建对象。对于上面通过匿名内部类方式访问接口,我们可以这样理解:一个内部类实现了接口里的抽象方法并且返回一个内部类对象,之后我们让接口的引用来指向这个对象。 + +### Lambda表达式(Lambda expressions) + +首先看看在老版本的Java中是如何排列字符串的: + +```java +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); + } +}); +``` + +只需要给静态方法` Collections.sort` 传入一个 List 对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给 `sort` 方法。 + +在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式: + +```java +Collections.sort(names, (String a, String b) -> { + return b.compareTo(a); +}); +``` + +可以看出,代码变得更段且更具有可读性,但是实际上还可以写得更短: + +```java +Collections.sort(names, (String a, String b) -> b.compareTo(a)); +``` + +对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字,但是你还可以写得更短点: + +```java +names.sort((a, b) -> b.compareTo(a)); +``` + +List 类本身就有一个 `sort` 方法。并且Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看lambda表达式还有什么其他用法。 + +### 函数式接口(Functional Interfaces) + +**译者注:**原文对这部分解释不太清楚,故做了修改! + +Java 语言设计者们投入了大量精力来思考如何使现有的函数友好地支持Lambda。最终采取的方法是:增加函数式接口的概念。**“函数式接口”是指仅仅只包含一个抽象方法,但是可以有多个非抽象方法(也就是上面提到的默认方法)的接口。** 像这样的接口,可以被隐式转换为lambda表达式。`java.lang.Runnable` 与 `java.util.concurrent.Callable` 是函数式接口最典型的两个例子。Java 8增加了一种特殊的注解`@FunctionalInterface`,但是这个注解通常不是必须的(某些情况建议使用),只要接口只包含一个抽象方法,虚拟机会自动判断该接口为函数式接口。一般建议在接口上使用`@FunctionalInterface` 注解进行声明,这样的话,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的,如下图所示 + +![@FunctionalInterface 注解](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/@FunctionalInterface.png) + +示例: + +```java +@FunctionalInterface +public interface Converter { + T convert(F from); +} +``` + +```java + // TODO 将数字字符串转换为整数类型 + Converter converter = (from) -> Integer.valueOf(from); + Integer converted = converter.convert("123"); + System.out.println(converted.getClass()); //class java.lang.Integer +``` + +**译者注:**大部分函数式接口都不用我们自己写,Java8都给我们实现好了,这些接口都在java.util.function包里。 + +### 方法和构造函数引用(Method and Constructor References) + +前一节中的代码还可以通过静态方法引用来表示: + +```java + Converter converter = Integer::valueOf; + Integer converted = converter.convert("123"); + System.out.println(converted.getClass()); //class java.lang.Integer +``` +Java 8允许您通过`::`关键字传递方法或构造函数的引用。 上面的示例显示了如何引用静态方法。 但我们也可以引用对象方法: + +```java +class Something { + String startsWith(String s) { + return String.valueOf(s.charAt(0)); + } +} +``` + +```java +Something something = new Something(); +Converter converter = something::startsWith; +String converted = converter.convert("Java"); +System.out.println(converted); // "J" +``` + +接下来看看构造函数是如何使用`::`关键字来引用的,首先我们定义一个包含多个构造函数的简单类: + +```java +class Person { + String firstName; + String lastName; + + Person() {} + + Person(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } +} +``` +接下来我们指定一个用来创建Person对象的对象工厂接口: + +```java +interface PersonFactory

{ + P create(String firstName, String lastName); +} +``` + +这里我们使用构造函数引用来将他们关联起来,而不是手动实现一个完整的工厂: + +```java +PersonFactory personFactory = Person::new; +Person person = personFactory.create("Peter", "Parker"); +``` +我们只需要使用 `Person::new` 来获取Person类构造函数的引用,Java编译器会自动根据`PersonFactory.create`方法的参数类型来选择合适的构造函数。 + +### Lamda 表达式作用域(Lambda Scopes) + +#### 访问局部变量 + +我们可以直接在 lambda 表达式中访问外部的局部变量: + +```java +final int num = 1; +Converter stringConverter = + (from) -> String.valueOf(from + num); + +stringConverter.convert(2); // 3 +``` + +但是和匿名对象不同的是,这里的变量num可以不用声明为final,该代码同样正确: + +```java +int num = 1; +Converter stringConverter = + (from) -> String.valueOf(from + num); + +stringConverter.convert(2); // 3 +``` + +不过这里的 num 必须不可被后面的代码修改(即隐性的具有final的语义),例如下面的就无法编译: + +```java +int num = 1; +Converter stringConverter = + (from) -> String.valueOf(from + num); +num = 3;//在lambda表达式中试图修改num同样是不允许的。 +``` + +#### 访问字段和静态变量 + +与局部变量相比,我们对lambda表达式中的实例字段和静态变量都有读写访问权限。 该行为和匿名对象是一致的。 + +```java +class Lambda4 { + static int outerStaticNum; + int outerNum; + + void testScopes() { + Converter stringConverter1 = (from) -> { + outerNum = 23; + return String.valueOf(from); + }; + + Converter stringConverter2 = (from) -> { + outerStaticNum = 72; + return String.valueOf(from); + }; + } +} +``` + +#### 访问默认接口方法 + +还记得第一节中的 formula 示例吗? `Formula` 接口定义了一个默认方法`sqrt`,可以从包含匿名对象的每个 formula 实例访问该方法。 这不适用于lambda表达式。 + +无法从 lambda 表达式中访问默认方法,故以下代码无法编译: + +```java +Formula formula = (a) -> sqrt(a * 100); +``` + +### 内置函数式接口(Built-in Functional Interfaces) + +JDK 1.8 API包含许多内置函数式接口。 其中一些借口在老版本的 Java 中是比较常见的比如: `Comparator` 或`Runnable`,这些接口都增加了`@FunctionalInterface`注解以便能用在 lambda 表达式上。 + +但是 Java 8 API 同样还提供了很多全新的函数式接口来让你的编程工作更加方便,有一些接口是来自 [Google Guava](https://code.google.com/p/guava-libraries/) 库里的,即便你对这些很熟悉了,还是有必要看看这些是如何扩展到lambda上使用的。 + +#### Predicates + +Predicate 接口是只有一个参数的返回布尔类型值的 **断言型** 接口。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非): + +**译者注:**Predicate 接口源码如下 + +```java +package java.util.function; +import java.util.Objects; + +@FunctionalInterface +public interface Predicate { + + // 该方法是接受一个传入类型,返回一个布尔值.此方法应用于判断. + boolean test(T t); + + //and方法与关系型运算符"&&"相似,两边都成立才返回true + default Predicate and(Predicate other) { + Objects.requireNonNull(other); + return (t) -> test(t) && other.test(t); + } + // 与关系运算符"!"相似,对判断进行取反 + default Predicate negate() { + return (t) -> !test(t); + } + //or方法与关系型运算符"||"相似,两边只要有一个成立就返回true + default Predicate or(Predicate other) { + Objects.requireNonNull(other); + return (t) -> test(t) || other.test(t); + } + // 该方法接收一个Object对象,返回一个Predicate类型.此方法用于判断第一个test的方法与第二个test方法相同(equal). + static Predicate isEqual(Object targetRef) { + return (null == targetRef) + ? Objects::isNull + : object -> targetRef.equals(object); + } +``` + +示例: + +```java +Predicate predicate = (s) -> s.length() > 0; + +predicate.test("foo"); // true +predicate.negate().test("foo"); // false + +Predicate nonNull = Objects::nonNull; +Predicate isNull = Objects::isNull; + +Predicate isEmpty = String::isEmpty; +Predicate isNotEmpty = isEmpty.negate(); +``` + +#### Functions + +Function 接口接受一个参数并生成结果。默认方法可用于将多个函数链接在一起(compose, andThen): + +**译者注:**Function 接口源码如下 + +```java + +package java.util.function; + +import java.util.Objects; + +@FunctionalInterface +public interface Function { + + //将Function对象应用到输入的参数上,然后返回计算结果。 + R apply(T t); + //将两个Function整合,并返回一个能够执行两个Function对象功能的Function对象。 + default Function compose(Function before) { + Objects.requireNonNull(before); + return (V v) -> apply(before.apply(v)); + } + // + default Function andThen(Function after) { + Objects.requireNonNull(after); + return (T t) -> after.apply(apply(t)); + } + + static Function identity() { + return t -> t; + } +} +``` + + + +```java +Function toInteger = Integer::valueOf; +Function backToString = toInteger.andThen(String::valueOf); +backToString.apply("123"); // "123" +``` + +#### Suppliers + +Supplier 接口产生给定泛型类型的结果。 与 Function 接口不同,Supplier 接口不接受参数。 + +```java +Supplier personSupplier = Person::new; +personSupplier.get(); // new Person +``` + +#### Consumers + +Consumer 接口表示要对单个输入参数执行的操作。 + +```java +Consumer greeter = (p) -> System.out.println("Hello, " + p.firstName); +greeter.accept(new Person("Luke", "Skywalker")); +``` + +#### Comparators + +Comparator 是老Java中的经典接口, Java 8在此之上添加了多种默认方法: + +```java +Comparator comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName); + +Person p1 = new Person("John", "Doe"); +Person p2 = new Person("Alice", "Wonderland"); + +comparator.compare(p1, p2); // > 0 +comparator.reversed().compare(p1, p2); // < 0 +``` + +## Optionals + +Optionals不是函数式接口,而是用于防止 NullPointerException 的漂亮工具。这是下一节的一个重要概念,让我们快速了解一下Optionals的工作原理。 + +Optional 是一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是有时却什么也没有返回,而在Java 8中,你应该返回 Optional 而不是 null。 + +译者注:示例中每个方法的作用已经添加。 + +```java +//of():为非null的值创建一个Optional +Optional optional = Optional.of("bam"); +// isPresent(): 如果值存在返回true,否则返回false +optional.isPresent(); // true +//get():如果Optional有值则将其返回,否则抛出NoSuchElementException +optional.get(); // "bam" +//orElse():如果有值则将其返回,否则返回指定的其它值 +optional.orElse("fallback"); // "bam" +//ifPresent():如果Optional实例有值则为其调用consumer,否则不做处理 +optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b" +``` + +推荐阅读:[[Java8]如何正确使用Optional](https://blog.kaaass.net/archives/764) + +## Streams(流) + +`java.util.Stream` 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如` java.util.Collection` 的子类,List 或者 Set, Map 不支持。Stream 的操作可以串行执行或者并行执行。 + +首先看看Stream是怎么用,首先创建实例代码的用到的数据List: + +```java +List stringCollection = new ArrayList<>(); +stringCollection.add("ddd2"); +stringCollection.add("aaa2"); +stringCollection.add("bbb1"); +stringCollection.add("aaa1"); +stringCollection.add("bbb3"); +stringCollection.add("ccc"); +stringCollection.add("bbb2"); +stringCollection.add("ddd1"); +``` + +Java 8扩展了集合类,可以通过 Collection.stream() 或者 Collection.parallelStream() 来创建一个Stream。下面几节将详细解释常用的Stream操作: + +### Filter(过滤) + +过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于**中间操作**,所以我们可以在过滤后的结果来应用其他Stream操作(比如forEach)。forEach需要一个函数来对过滤后的元素依次执行。forEach是一个最终操作,所以我们不能在forEach之后来执行其他Stream操作。 + +```java + // 测试 Filter(过滤) + stringList + .stream() + .filter((s) -> s.startsWith("a")) + .forEach(System.out::println);//aaa2 aaa1 +``` + +forEach 是为 Lambda 而设计的,保持了最紧凑的风格。而且 Lambda 表达式本身是可以重用的,非常方便。 + +### Sorted(排序) + +排序是一个 **中间操作**,返回的是排序好后的 Stream。**如果你不指定一个自定义的 Comparator 则会使用默认排序。** + +```java + // 测试 Sort (排序) + stringList + .stream() + .sorted() + .filter((s) -> s.startsWith("a")) + .forEach(System.out::println);// aaa1 aaa2 +``` + +需要注意的是,排序只创建了一个排列好后的Stream,而不会影响原有的数据源,排序之后原数据stringCollection是不会被修改的: + +```java + System.out.println(stringList);// ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1 +``` + +### Map(映射) + +中间操作 map 会将元素根据指定的 Function 接口来依次将元素转成另外的对象。 + +下面的示例展示了将字符串转换为大写字符串。你也可以通过map来讲对象转换成其他类型,map返回的Stream类型是根据你map传递进去的函数的返回值决定的。 + +```java + // 测试 Map 操作 + stringList + .stream() + .map(String::toUpperCase) + .sorted((a, b) -> b.compareTo(a)) + .forEach(System.out::println);// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1" +``` + + + +### Match(匹配) + +Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是 **最终操作** ,并返回一个 boolean 类型的值。 + +```java + // 测试 Match (匹配)操作 + boolean anyStartsWithA = + stringList + .stream() + .anyMatch((s) -> s.startsWith("a")); + System.out.println(anyStartsWithA); // true + + boolean allStartsWithA = + stringList + .stream() + .allMatch((s) -> s.startsWith("a")); + + System.out.println(allStartsWithA); // false + + boolean noneStartsWithZ = + stringList + .stream() + .noneMatch((s) -> s.startsWith("z")); + + System.out.println(noneStartsWithZ); // true +``` + + + +### Count(计数) + +计数是一个 **最终操作**,返回Stream中元素的个数,**返回值类型是 long**。 + +```java + //测试 Count (计数)操作 + long startsWithB = + stringList + .stream() + .filter((s) -> s.startsWith("b")) + .count(); + System.out.println(startsWithB); // 3 +``` + +### Reduce(规约) + +这是一个 **最终操作** ,允许通过指定的函数来讲stream中的多个元素规约为一个元素,规约后的结果是通过Optional 接口表示的: + +```java + //测试 Reduce (规约)操作 + Optional reduced = + stringList + .stream() + .sorted() + .reduce((s1, s2) -> s1 + "#" + s2); + + reduced.ifPresent(System.out::println);//aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2 +``` + + + +**译者注:** 这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。例如 Stream 的 sum 就相当于`Integer sum = integers.reduce(0, (a, b) -> a+b);`也有没有起始值的情况,这时会把 Stream 的前面两个元素组合起来,返回的是 Optional。 + +```java +// 字符串连接,concat = "ABCD" +String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); +// 求最小值,minValue = -3.0 +double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); +// 求和,sumValue = 10, 有起始值 +int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum); +// 求和,sumValue = 10, 无起始值 +sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get(); +// 过滤,字符串连接,concat = "ace" +concat = Stream.of("a", "B", "c", "D", "e", "F"). + filter(x -> x.compareTo("Z") > 0). + reduce("", String::concat); +``` + +上面代码例如第一个示例的 reduce(),第一个参数(空白字符)即为起始值,第二个参数(String::concat)为 BinaryOperator。这类有起始值的 reduce() 都返回具体的对象。而对于第四个示例没有起始值的 reduce(),由于可能没有足够的元素,返回的是 Optional,请留意这个区别。更多内容查看: [IBM:Java 8 中的 Streams API 详解](https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html) + +## Parallel Streams(并行流) + +前面提到过Stream有串行和并行两种,串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。 + +下面的例子展示了是如何通过并行Stream来提升性能: + +首先我们创建一个没有重复元素的大表: + +```java +int max = 1000000; +List values = new ArrayList<>(max); +for (int i = 0; i < max; i++) { + UUID uuid = UUID.randomUUID(); + values.add(uuid.toString()); +} +``` + +我们分别用串行和并行两种方式对其进行排序,最后看看所用时间的对比。 + +### Sequential Sort(串行排序) + +```java +//串行排序 +long t0 = System.nanoTime(); +long count = values.stream().sorted().count(); +System.out.println(count); + +long t1 = System.nanoTime(); + +long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); +System.out.println(String.format("sequential sort took: %d ms", millis)); +``` + +``` +1000000 +sequential sort took: 709 ms//串行排序所用的时间 +``` + +### Parallel Sort(并行排序) + +```java +//并行排序 +long t0 = System.nanoTime(); + +long count = values.parallelStream().sorted().count(); +System.out.println(count); + +long t1 = System.nanoTime(); + +long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); +System.out.println(String.format("parallel sort took: %d ms", millis)); + +``` + +```java +1000000 +parallel sort took: 475 ms//串行排序所用的时间 +``` + +上面两个代码几乎是一样的,但是并行版的快了 50% 左右,唯一需要做的改动就是将 `stream()` 改为`parallelStream()`。 + +## Maps + +前面提到过,Map 类型不支持 streams,不过Map提供了一些新的有用的方法来处理一些日常任务。Map接口本身没有可用的 `stream()`方法,但是你可以在键,值上创建专门的流或者通过 `map.keySet().stream()`,`map.values().stream()`和`map.entrySet().stream()`。 + +此外,Maps 支持各种新的和有用的方法来执行常见任务。 + +```java +Map map = new HashMap<>(); + +for (int i = 0; i < 10; i++) { + map.putIfAbsent(i, "val" + i); +} + +map.forEach((id, val) -> System.out.println(val));//val0 val1 val2 val3 val4 val5 val6 val7 val8 val9 +``` + +`putIfAbsent` 阻止我们在null检查时写入额外的代码;`forEach`接受一个 consumer 来对 map 中的每个元素操作。 + +此示例显示如何使用函数在 map 上计算代码: + +```java +map.computeIfPresent(3, (num, val) -> val + num); +map.get(3); // val33 + +map.computeIfPresent(9, (num, val) -> null); +map.containsKey(9); // false + +map.computeIfAbsent(23, num -> "val" + num); +map.containsKey(23); // true + +map.computeIfAbsent(3, num -> "bam"); +map.get(3); // val33 +``` + +接下来展示如何在Map里删除一个键值全都匹配的项: + +```java +map.remove(3, "val3"); +map.get(3); // val33 +map.remove(3, "val33"); +map.get(3); // null +``` + +另外一个有用的方法: + +```java +map.getOrDefault(42, "not found"); // not found +``` + +对Map的元素做合并也变得很容易了: + +```java +map.merge(9, "val9", (value, newValue) -> value.concat(newValue)); +map.get(9); // val9 +map.merge(9, "concat", (value, newValue) -> value.concat(newValue)); +map.get(9); // val9concat +``` + +Merge 做的事情是如果键名不存在则插入,否则则对原键对应的值做合并操作并重新插入到map中。 + +## Data API(日期相关API) + +Java 8在 `java.time` 包下包含一个全新的日期和时间API。新的Date API与Joda-Time库相似,但它们不一样。以下示例涵盖了此新 API 的最重要部分。译者对这部分内容参考相关书籍做了大部分修改。 + +**译者注(总结):** + +- Clock 类提供了访问当前日期和时间的方法,Clock 是时区敏感的,可以用来取代 `System.currentTimeMillis()` 来获取当前的微秒数。某一个特定的时间点也可以使用 `Instant` 类来表示,`Instant` 类也可以用来创建旧版本的`java.util.Date` 对象。 + +- 在新API中时区使用 ZoneId 来表示。时区可以很方便的使用静态方法of来获取到。 抽象类`ZoneId`(在`java.time`包中)表示一个区域标识符。 它有一个名为`getAvailableZoneIds`的静态方法,它返回所有区域标识符。 + +- jdk1.8中新增了 LocalDate 与 LocalDateTime等类来解决日期处理方法,同时引入了一个新的类DateTimeFormatter 来解决日期格式化问题。可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。 + + + +### Clock + +Clock 类提供了访问当前日期和时间的方法,Clock 是时区敏感的,可以用来取代 `System.currentTimeMillis()` 来获取当前的微秒数。某一个特定的时间点也可以使用 `Instant` 类来表示,`Instant` 类也可以用来创建旧版本的`java.util.Date` 对象。 + +```java +Clock clock = Clock.systemDefaultZone(); +long millis = clock.millis(); +System.out.println(millis);//1552379579043 +Instant instant = clock.instant(); +System.out.println(instant); +Date legacyDate = Date.from(instant); //2019-03-12T08:46:42.588Z +System.out.println(legacyDate);//Tue Mar 12 16:32:59 CST 2019 +``` + +### Timezones(时区) + +在新API中时区使用 ZoneId 来表示。时区可以很方便的使用静态方法of来获取到。 抽象类`ZoneId`(在`java.time`包中)表示一个区域标识符。 它有一个名为`getAvailableZoneIds`的静态方法,它返回所有区域标识符。 + +```java +//输出所有区域标识符 +System.out.println(ZoneId.getAvailableZoneIds()); + +ZoneId zone1 = ZoneId.of("Europe/Berlin"); +ZoneId zone2 = ZoneId.of("Brazil/East"); +System.out.println(zone1.getRules());// ZoneRules[currentStandardOffset=+01:00] +System.out.println(zone2.getRules());// ZoneRules[currentStandardOffset=-03:00] +``` + +### LocalTime(本地时间) + +LocalTime 定义了一个没有时区信息的时间,例如 晚上10点或者 17:30:15。下面的例子使用前面代码创建的时区创建了两个本地时间。之后比较时间并以小时和分钟为单位计算两个时间的时间差: + +```java +LocalTime now1 = LocalTime.now(zone1); +LocalTime now2 = LocalTime.now(zone2); +System.out.println(now1.isBefore(now2)); // false + +long hoursBetween = ChronoUnit.HOURS.between(now1, now2); +long minutesBetween = ChronoUnit.MINUTES.between(now1, now2); + +System.out.println(hoursBetween); // -3 +System.out.println(minutesBetween); // -239 +``` + +LocalTime 提供了多种工厂方法来简化对象的创建,包括解析时间字符串. + +```java +LocalTime late = LocalTime.of(23, 59, 59); +System.out.println(late); // 23:59:59 +DateTimeFormatter germanFormatter = + DateTimeFormatter + .ofLocalizedTime(FormatStyle.SHORT) + .withLocale(Locale.GERMAN); + +LocalTime leetTime = LocalTime.parse("13:37", germanFormatter); +System.out.println(leetTime); // 13:37 +``` + +### LocalDate(本地日期) + +LocalDate 表示了一个确切的日期,比如 2014-03-11。该对象值是不可变的,用起来和LocalTime基本一致。下面的例子展示了如何给Date对象加减天/月/年。另外要注意的是这些对象是不可变的,操作返回的总是一个新实例。 + +```java +LocalDate today = LocalDate.now();//获取现在的日期 +System.out.println("今天的日期: "+today);//2019-03-12 +LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS); +System.out.println("明天的日期: "+tomorrow);//2019-03-13 +LocalDate yesterday = tomorrow.minusDays(2); +System.out.println("昨天的日期: "+yesterday);//2019-03-11 +LocalDate independenceDay = LocalDate.of(2019, Month.MARCH, 12); +DayOfWeek dayOfWeek = independenceDay.getDayOfWeek(); +System.out.println("今天是周几:"+dayOfWeek);//TUESDAY +``` + +从字符串解析一个 LocalDate 类型和解析 LocalTime 一样简单,下面是使用 `DateTimeFormatter` 解析字符串的例子: + +```java + String str1 = "2014==04==12 01时06分09秒"; + // 根据需要解析的日期、时间字符串定义解析所用的格式器 + DateTimeFormatter fomatter1 = DateTimeFormatter + .ofPattern("yyyy==MM==dd HH时mm分ss秒"); + + LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1); + System.out.println(dt1); // 输出 2014-04-12T01:06:09 + + String str2 = "2014$$$四月$$$13 20小时"; + DateTimeFormatter fomatter2 = DateTimeFormatter + .ofPattern("yyy$$$MMM$$$dd HH小时"); + LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2); + System.out.println(dt2); // 输出 2014-04-13T20:00 + +``` + +再来看一个使用 `DateTimeFormatter` 格式化日期的示例 + +```java +LocalDateTime rightNow=LocalDateTime.now(); +String date=DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(rightNow); +System.out.println(date);//2019-03-12T16:26:48.29 +DateTimeFormatter formatter=DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"); +System.out.println(formatter.format(rightNow));//2019-03-12 16:26:48 +``` + +### LocalDateTime(本地日期时间) + +LocalDateTime 同时表示了时间和日期,相当于前两节内容合并到一个对象上了。LocalDateTime 和 LocalTime还有 LocalDate 一样,都是不可变的。LocalDateTime 提供了一些能访问具体字段的方法。 + +```java +LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59); + +DayOfWeek dayOfWeek = sylvester.getDayOfWeek(); +System.out.println(dayOfWeek); // WEDNESDAY + +Month month = sylvester.getMonth(); +System.out.println(month); // DECEMBER + +long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY); +System.out.println(minuteOfDay); // 1439 +``` + +只要附加上时区信息,就可以将其转换为一个时间点Instant对象,Instant时间点对象可以很容易的转换为老式的`java.util.Date`。 + +```java +Instant instant = sylvester + .atZone(ZoneId.systemDefault()) + .toInstant(); + +Date legacyDate = Date.from(instant); +System.out.println(legacyDate); // Wed Dec 31 23:59:59 CET 2014 +``` + +格式化LocalDateTime和格式化时间和日期一样的,除了使用预定义好的格式外,我们也可以自己定义格式: + +```java +DateTimeFormatter formatter = + DateTimeFormatter + .ofPattern("MMM dd, yyyy - HH:mm"); +LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter); +String string = formatter.format(parsed); +System.out.println(string); // Nov 03, 2014 - 07:13 +``` + +和java.text.NumberFormat不一样的是新版的DateTimeFormatter是不可变的,所以它是线程安全的。 +关于时间日期格式的详细信息在[这里](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)。 + +## Annotations(注解) + +在Java 8中支持多重注解了,先看个例子来理解一下是什么意思。 +首先定义一个包装类Hints注解用来放置一组具体的Hint注解: + +```java +@interface Hints { + Hint[] value(); +} +@Repeatable(Hints.class) +@interface Hint { + String value(); +} +``` + +Java 8允许我们把同一个类型的注解使用多次,只需要给该注解标注一下`@Repeatable`即可。 + +例 1: 使用包装类当容器来存多个注解(老方法) + +```java +@Hints({@Hint("hint1"), @Hint("hint2")}) +class Person {} +``` + +例 2:使用多重注解(新方法) + +```java +@Hint("hint1") +@Hint("hint2") +class Person {} +``` + +第二个例子里java编译器会隐性的帮你定义好@Hints注解,了解这一点有助于你用反射来获取这些信息: + +```java +Hint hint = Person.class.getAnnotation(Hint.class); +System.out.println(hint); // null +Hints hints1 = Person.class.getAnnotation(Hints.class); +System.out.println(hints1.value().length); // 2 + +Hint[] hints2 = Person.class.getAnnotationsByType(Hint.class); +System.out.println(hints2.length); // 2 +``` + +即便我们没有在 `Person`类上定义 `@Hints`注解,我们还是可以通过 `getAnnotation(Hints.class) `来获取 `@Hints`注解,更加方便的方法是使用 `getAnnotationsByType` 可以直接获取到所有的`@Hint`注解。 +另外Java 8的注解还增加到两种新的target上了: + +```java +@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) +@interface MyAnnotation {} +``` + + + +## Whete to go from here? + +关于Java 8的新特性就写到这了,肯定还有更多的特性等待发掘。JDK 1.8里还有很多很有用的东西,比如`Arrays.parallelSort`, `StampedLock`和`CompletableFuture`等等。 + +### 参考 + +- https://www.jb51.net/article/48304.htm +- https://github.com/winterbe/java8-tutorial#predicates + From 51a958df288cb8ea56f54ddfc42a9682e0a77b24 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 17:12:50 +0800 Subject: [PATCH 123/232] Update ToDoList --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8968159cd4d..25248313c65 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,10 @@ * [闲谈](#闲谈) * [说明](#说明) -## 待办 +## ToDoList(待办清单) -* [ ] Java 8 新特性总结 +* [x] Java 8 新特性总结 +* [ ] Java 8 新特性详解 * [ ] Java 多线程类别知识重构 * [x] BIO,NIO,AIO 总结 * [ ] Netty 总结 From 31471256a869bcb3ede9cda899684f5efd2ce5ea Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 17:17:47 +0800 Subject: [PATCH 124/232] Update category --- README.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 25248313c65..c8e2bc5ecf1 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,12 @@ ## 目录 * [Java](#java) - * [Java/J2EE 基础](#javaj2ee-基础) - * [Java 集合框架](#java-集合框架) - * [Java 多线程](#java-多线程) - * [Java BIO,NIO,AIO](#java-bionioaio) - * [Java 虚拟机 jvm](#java-虚拟机-jvm) + * [基础](#基础) + * [集合框架](#集合框架) + * [多线程](#多线程) + * [BIO,NIO,AIO](#bionioaio) + * [JVM](#jvm) + * [Java8 New Features](#java8-new-features) * [设计模式](#设计模式) * [数据结构与算法](#数据结构与算法) * [数据结构](#数据结构) @@ -55,13 +56,13 @@ ## Java -### Java/J2EE 基础 +### 基础 * [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) * [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/final、static、this、super.md) -### Java 集合框架 +### 集合框架 * **常见问题总结:** * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) @@ -72,7 +73,7 @@ * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/LinkedList.md) * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/HashMap.md) -### Java 多线程 +### 多线程 * [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java/synchronized.md) * [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) @@ -81,17 +82,19 @@ * [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/BATJ都爱问的多线程面试题.md) * [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/并发容器总结.md) -### Java 虚拟机 jvm +### JVM * [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/可能是把Java内存区域讲的最清楚的一篇文章.md) * [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java/搞定JVM垃圾回收就是这么简单.md) * [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java虚拟机(jvm).md) -### Java BIO,NIO,AIO +### BIO,NIO,AIO * [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java/BIO%2CNIO%2CAIO%20summary.md) * [Java IO 与 NIO系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java%20IO与NIO.md) +### Java8 New Features + ### 设计模式 * [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/设计模式.md) From f432ca69a1f2c3ca7bd9ae7340ea2441524c1cee Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 17:38:20 +0800 Subject: [PATCH 125/232] Update Java8Tutorial.md --- Java/What's New in JDK8/Java8Tutorial.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Java/What's New in JDK8/Java8Tutorial.md b/Java/What's New in JDK8/Java8Tutorial.md index 80736282cfa..86a8750ee8b 100644 --- a/Java/What's New in JDK8/Java8Tutorial.md +++ b/Java/What's New in JDK8/Java8Tutorial.md @@ -881,8 +881,3 @@ System.out.println(hints2.length); // 2 关于Java 8的新特性就写到这了,肯定还有更多的特性等待发掘。JDK 1.8里还有很多很有用的东西,比如`Arrays.parallelSort`, `StampedLock`和`CompletableFuture`等等。 -### 参考 - -- https://www.jb51.net/article/48304.htm -- https://github.com/winterbe/java8-tutorial#predicates - From 2f846de80c743f7d55e08742b42a125c814ef9b0 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 17:41:20 +0800 Subject: [PATCH 126/232] =?UTF-8?q?Add=20Java8=E6=96=B0=E7=89=B9=E6=80=A7?= =?UTF-8?q?=E6=80=BB=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c8e2bc5ecf1..7f2b0773f43 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ ### Java8 New Features +* [Java 8 新特性总结](https://github.com/Snailclimb/JavaGuide/blob/master/Java/What's%20New%20in%20JDK8/Java8Tutorial.md) + ### 设计模式 * [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/设计模式.md) From 16987cfe4ccf9cffea6bf34d8f061febaa45a8d4 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 17:44:19 +0800 Subject: [PATCH 127/232] Add category --- Java/What's New in JDK8/Java8Tutorial.md | 83 ++++++++++++++++++------ 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/Java/What's New in JDK8/Java8Tutorial.md b/Java/What's New in JDK8/Java8Tutorial.md index 86a8750ee8b..3aa3901409c 100644 --- a/Java/What's New in JDK8/Java8Tutorial.md +++ b/Java/What's New in JDK8/Java8Tutorial.md @@ -1,7 +1,48 @@ 随着 Java 8 的普及度越来越高,很多人都提到面试中关于Java 8 也是非常常问的知识点。应各位要求和需要,我打算对这部分知识做一个总结。本来准备自己总结的,后面看到Github 上有一个相关的仓库,地址: [https://github.com/winterbe/java8-tutorial](https://github.com/winterbe/java8-tutorial)。这个仓库是英文的,我对其进行了翻译并添加和修改了部分内容,下面是正文了。 -# Java 8 + + +- [Java 8 Tutorial](#java-8-tutorial) + - [接口的默认方法\(Default Methods for Interfaces\)](#接口的默认方法default-methods-for-interfaces) + - [Lambda表达式\(Lambda expressions\)](#lambda表达式lambda-expressions) + - [函数式接口\(Functional Interfaces\)](#函数式接口functional-interfaces) + - [方法和构造函数引用\(Method and Constructor References\)](#方法和构造函数引用method-and-constructor-references) + - [Lamda 表达式作用域\(Lambda Scopes\)](#lamda-表达式作用域lambda-scopes) + - [访问局部变量](#访问局部变量) + - [访问字段和静态变量](#访问字段和静态变量) + - [访问默认接口方法](#访问默认接口方法) + - [内置函数式接口\(Built-in Functional Interfaces\)](#内置函数式接口built-in-functional-interfaces) + - [Predicates](#predicates) + - [Functions](#functions) + - [Suppliers](#suppliers) + - [Consumers](#consumers) + - [Comparators](#comparators) + - [Optionals](#optionals) + - [Streams\(流\)](#streams流) + - [Filter\(过滤\)](#filter过滤) + - [Sorted\(排序\)](#sorted排序) + - [Map\(映射\)](#map映射) + - [Match\(匹配\)](#match匹配) + - [Count\(计数\)](#count计数) + - [Reduce\(规约\)](#reduce规约) + - [Parallel Streams\(并行流\)](#parallel-streams并行流) + - [Sequential Sort\(串行排序\)](#sequential-sort串行排序) + - [Parallel Sort\(并行排序\)](#parallel-sort并行排序) + - [Maps](#maps) + - [Data API\(日期相关API\)](#data-api日期相关api) + - [Clock](#clock) + - [Timezones\(时区\)](#timezones时区) + - [LocalTime\(本地时间\)](#localtime本地时间) + - [LocalDate\(本地日期\)](#localdate本地日期) + - [LocalDateTime\(本地日期时间\)](#localdatetime本地日期时间) + - [Annotations\(注解\)](#annotations注解) + - [Whete to go from here?](#whete-to-go-from-here) + + + + +# Java 8 Tutorial 欢迎阅读我对Java 8的介绍。本教程将逐步指导您完成所有新语言功能。 在简短的代码示例的基础上,您将学习如何使用默认接口方法,lambda表达式,方法引用和可重复注释。 在本文的最后,您将熟悉最新的 API 更改,如流,函数式接口(Functional Interfaces),Map 类的扩展和新的 Date API。 没有大段枯燥的文字,只有一堆注释的代码片段。 @@ -29,19 +70,19 @@ Formula 接口中除了抽象方法计算接口公式还定义了默认方法 `s ```java public class Main { - public static void main(String[] args) { - // TODO 通过匿名内部类方式访问接口 - Formula formula = new Formula() { - @Override - public double calculate(int a) { - return sqrt(a * 100); - } - }; + public static void main(String[] args) { + // TODO 通过匿名内部类方式访问接口 + Formula formula = new Formula() { + @Override + public double calculate(int a) { + return sqrt(a * 100); + } + }; - System.out.println(formula.calculate(100)); // 100.0 - System.out.println(formula.sqrt(16)); // 4.0 + System.out.println(formula.calculate(100)); // 100.0 + System.out.println(formula.sqrt(16)); // 4.0 - } + } } ``` @@ -102,15 +143,15 @@ Java 语言设计者们投入了大量精力来思考如何使现有的函数友 ```java @FunctionalInterface public interface Converter { - T convert(F from); + T convert(F from); } ``` ```java - // TODO 将数字字符串转换为整数类型 - Converter converter = (from) -> Integer.valueOf(from); - Integer converted = converter.convert("123"); - System.out.println(converted.getClass()); //class java.lang.Integer + // TODO 将数字字符串转换为整数类型 + Converter converter = (from) -> Integer.valueOf(from); + Integer converted = converter.convert("123"); + System.out.println(converted.getClass()); //class java.lang.Integer ``` **译者注:**大部分函数式接口都不用我们自己写,Java8都给我们实现好了,这些接口都在java.util.function包里。 @@ -120,9 +161,9 @@ public interface Converter { 前一节中的代码还可以通过静态方法引用来表示: ```java - Converter converter = Integer::valueOf; - Integer converted = converter.convert("123"); - System.out.println(converted.getClass()); //class java.lang.Integer + Converter converter = Integer::valueOf; + Integer converted = converter.convert("123"); + System.out.println(converted.getClass()); //class java.lang.Integer ``` Java 8允许您通过`::`关键字传递方法或构造函数的引用。 上面的示例显示了如何引用静态方法。 但我们也可以引用对象方法: @@ -755,7 +796,7 @@ System.out.println("今天是周几:"+dayOfWeek);//TUESDAY 从字符串解析一个 LocalDate 类型和解析 LocalTime 一样简单,下面是使用 `DateTimeFormatter` 解析字符串的例子: ```java - String str1 = "2014==04==12 01时06分09秒"; + String str1 = "2014==04==12 01时06分09秒"; // 根据需要解析的日期、时间字符串定义解析所用的格式器 DateTimeFormatter fomatter1 = DateTimeFormatter .ofPattern("yyyy==MM==dd HH时mm分ss秒"); From 5e796c129c97f489a7fe66abca1973813dbf8806 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 19:07:17 +0800 Subject: [PATCH 128/232] Update Java8Tutorial.md --- Java/What's New in JDK8/Java8Tutorial.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Java/What's New in JDK8/Java8Tutorial.md b/Java/What's New in JDK8/Java8Tutorial.md index 3aa3901409c..4dd12ecf063 100644 --- a/Java/What's New in JDK8/Java8Tutorial.md +++ b/Java/What's New in JDK8/Java8Tutorial.md @@ -132,7 +132,7 @@ List 类本身就有一个 `sort` 方法。并且Java编译器可以自动推导 ### 函数式接口(Functional Interfaces) -**译者注:**原文对这部分解释不太清楚,故做了修改! +**译者注:** 原文对这部分解释不太清楚,故做了修改! Java 语言设计者们投入了大量精力来思考如何使现有的函数友好地支持Lambda。最终采取的方法是:增加函数式接口的概念。**“函数式接口”是指仅仅只包含一个抽象方法,但是可以有多个非抽象方法(也就是上面提到的默认方法)的接口。** 像这样的接口,可以被隐式转换为lambda表达式。`java.lang.Runnable` 与 `java.util.concurrent.Callable` 是函数式接口最典型的两个例子。Java 8增加了一种特殊的注解`@FunctionalInterface`,但是这个注解通常不是必须的(某些情况建议使用),只要接口只包含一个抽象方法,虚拟机会自动判断该接口为函数式接口。一般建议在接口上使用`@FunctionalInterface` 注解进行声明,这样的话,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的,如下图所示 @@ -154,7 +154,7 @@ public interface Converter { System.out.println(converted.getClass()); //class java.lang.Integer ``` -**译者注:**大部分函数式接口都不用我们自己写,Java8都给我们实现好了,这些接口都在java.util.function包里。 +**译者注:** 大部分函数式接口都不用我们自己写,Java8都给我们实现好了,这些接口都在java.util.function包里。 ### 方法和构造函数引用(Method and Constructor References) @@ -289,7 +289,7 @@ JDK 1.8 API包含许多内置函数式接口。 其中一些借口在老版本 Predicate 接口是只有一个参数的返回布尔类型值的 **断言型** 接口。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非): -**译者注:**Predicate 接口源码如下 +**译者注:** Predicate 接口源码如下 ```java package java.util.function; @@ -342,7 +342,7 @@ Predicate isNotEmpty = isEmpty.negate(); Function 接口接受一个参数并生成结果。默认方法可用于将多个函数链接在一起(compose, andThen): -**译者注:**Function 接口源码如下 +**译者注:** Function 接口源码如下 ```java From 2d8be9a186ef989943fe482346ab8dd6acfad136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=B3=E9=98=B3?= <260893248@qq.com> Date: Tue, 12 Mar 2019 20:01:35 +0800 Subject: [PATCH 129/232] =?UTF-8?q?=E7=9C=8B=E8=B5=B7=E6=9D=A5=E5=83=8F?= =?UTF-8?q?=E6=98=AF=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 看起来像是拼写错误 --- ...\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/EssentialContentForInterview/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/EssentialContentForInterview/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 422d9402f12..0efdd618688 100644 --- "a/EssentialContentForInterview/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/EssentialContentForInterview/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" @@ -238,7 +238,7 @@ HTTP响应报文主要由状态行、响应头部、响应正文3部分组成 1. 避免 where 子句中对字段施加函数,这会造成无法命中索引。 2. 在使用InnoDB时使用与业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。 3. 将打算加索引的列设置为 NOT NULL ,否则将导致引擎放弃使用索引而进行全表扫描 -4. 删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗 MySQL 5.7 可以通过查询 sys 库的 chema_unused_indexes 视图来查询哪些索引从未被使用 +4. 删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗 MySQL 5.7 可以通过查询 sys 库的 schema_unused_indexes 视图来查询哪些索引从未被使用 5. 在使用 limit offset 查询缓慢时,可以借助索引来提高性能 **Mysql索引主要使用的哪两种数据结构?** From 5fd6855a0ee82c39a723828a23ffd5e30652c4cc Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 12 Mar 2019 21:36:59 +0800 Subject: [PATCH 130/232] Add a contributor --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7f2b0773f43..65162db7d38 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,9 @@ + + + ### 公众号 From 46901e584de16f70bf6aeba5fc41961680d313af Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Tue, 12 Mar 2019 23:39:38 +0800 Subject: [PATCH 131/232] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在README.md添加部分特性总结 - 在README.md维护链接,本页面内跳转 --- Java/What's New in JDK8/README.md | 550 +++++++++++++++++++++++++++++- 1 file changed, 541 insertions(+), 9 deletions(-) diff --git a/Java/What's New in JDK8/README.md b/Java/What's New in JDK8/README.md index b7612fa4183..fa71e907410 100644 --- a/Java/What's New in JDK8/README.md +++ b/Java/What's New in JDK8/README.md @@ -3,22 +3,554 @@ JDK8新特性总结 总结了部分JDK8新特性,另外一些新特性可以通过Oracle的官方文档查看,毕竟是官方文档,各种新特性都会介绍,有兴趣的可以去看。
[Oracle官方文档:What's New in JDK8](https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html) ----- -- [Java语言特性]() +- [Java语言特性](#JavaProgrammingLanguage) - [Lambda表达式是一个新的语言特性,已经在JDK8中加入。它是一个可以传递的代码块,你也可以把它们当做方法参数。 - Lambda表达式允许您更紧凑地创建单虚方法接口(称为功能接口)的实例。](https://github.com/Goose9527/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/What's%20New%20in%20JDK8/Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F.md) + Lambda表达式允许您更紧凑地创建单虚方法接口(称为功能接口)的实例。](#LambdaExpressions) - - [方法引用为已经存在的具名方法提供易于阅读的Lambda表达式]() + - [方法引用为已经存在的具名方法提供易于阅读的Lambda表达式](#MethodReferences) - - [默认方法允许将新功能添加到库的接口,并确保与为这些接口的旧版本编写的代码的二进制兼容性。]() + - [默认方法允许将新功能添加到库的接口,并确保与为这些接口的旧版本编写的代码的二进制兼容性。](#DefaultMethods) - - [改进的类型推断。]() + - [改进的类型推断。](#ImprovedTypeInference) - - [方法参数反射。]() + - [方法参数反射(通过反射获得方法参数信息)](#MethodParameterReflection) -- [流(stream)]() +- [流(stream)](#stream) - [新java.util.stream包中的类提供Stream API以支持对元素流的功能样式操作。流(stream)和I/O里的流不是同一个概念 ,使用stream API可以更方便的操作集合。]() - [国际化]() - - 代办 -- 代办 + - 待办 +- 待办 +___ + + + + + + + +##              Lambda表达式 +### 1.什么是Lambda表达式 +**Lambda表达式实质上是一个可传递的代码块,Lambda又称为闭包或者匿名函数,是函数式编程语法,让方法可以像普通参数一样传递** + +### 2.Lambda表达式语法 +```(参数列表) -> {执行代码块}``` +
参数列表可以为空```()->{}``` +
可以加类型声明比如```(String para1, int para2) -> {return para1 + para2;}```我们可以看到,lambda同样可以有返回值. +
在编译器可以推断出类型的时候,可以将类型声明省略,比如```(para1, para2) -> {return para1 + para2;}``` +
(lambda有点像动态类型语言语法。lambda在字节码层面是用invokedynamic实现的,而这条指令就是为了让JVM更好的支持运行在其上的动态类型语言) + +### 3.函数式接口 +在了解Lambda表达式之前,有必要先了解什么是函数式接口```(@FunctionalInterface)```
+**函数式接口指的是有且只有一个抽象(abstract)方法的接口**
+当需要一个函数式接口的对象时,就可以用Lambda表达式来实现,举个常用的例子: +
+```java + Thread thread = new Thread(() -> { + System.out.println("This is JDK8's Lambda!"); + }); +``` +这段代码和函数式接口有啥关系?我们回忆一下,Thread类的构造函数里是不是有一个以Runnable接口为参数的? +```java +public Thread(Runnable target) {...} + +/** + * Runnable Interface + */ +@FunctionalInterface +public interface Runnable { + public abstract void run(); +} +``` +到这里大家可能已经明白了,**Lambda表达式相当于一个匿名类或者说是一个匿名方法**。上面Thread的例子相当于 +```java + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + System.out.println("Anonymous class"); + } + }); +``` +也就是说,上面的lambda表达式相当于实现了这个run()方法,然后当做参数传入(个人感觉可以这么理解,lambda表达式就是一个函数,只不过它的返回值、参数列表都 +由编译器帮我们推断,因此可以减少很多代码量)。 +
Lambda也可以这样用 : +```java + Runnable runnable = () -> {...}; +``` +其实这和上面的用法没有什么本质上的区别。 +
至此大家应该明白什么是函数式接口以及函数式接口和lambda表达式之间的关系了。在JDK8中修改了接口的规范, +目的是为了在给接口添加新的功能时保持向前兼容(个人理解),比如一个已经定义了的函数式接口,某天我们想给它添加新功能,那么就不能保持向前兼容了, +因为在旧的接口规范下,添加新功能必定会破坏这个函数式接口[(JDK8中接口规范)]() +
+除了上面说的Runnable接口之外,JDK中已经存在了很多函数式接口 +比如(当然不止这些): +- ```java.util.concurrent.Callable``` +- ```java.util.Comparator``` +- ```java.io.FileFilter``` +
**关于JDK中的预定义的函数式接口** + +- JDK在```java.util.function```下预定义了很多函数式接口 + - ```Function {R apply(T t);}``` 接受一个T对象,然后返回一个R对象,就像普通的函数。 + - ```Consumer {void accept(T t);}``` 消费者 接受一个T对象,没有返回值。 + - ```Predicate {boolean test(T t);}``` 判断,接受一个T对象,返回一个布尔值。 + - ```Supplier {T get();} 提供者(工厂)``` 返回一个T对象。 + - 其他的跟上面的相似,大家可以看一下function包下的具体接口。 +### 4.变量作用域 +```java +public class VaraibleHide { + @FunctionalInterface + interface IInner { + void printInt(int x); + } + public static void main(String[] args) { + int x = 20; + IInner inner = new IInner() { + int x = 10; + @Override + public void printInt(int x) { + System.out.println(x); + } + }; + inner.printInt(30); + + inner = (s) -> { + //Variable used in lambda expression should be final or effectively final + //!int x = 10; + //!x= 50; error + System.out.print(x); + }; + inner.printInt(30); + } +} +输出 : +30 +20 +``` +对于lambda表达式```java inner = (s) -> {System.out.print(x);};```,变量x并不是在lambda表达式中定义的,像这样并不是在lambda中定义或者通过lambda +的参数列表()获取的变量成为自由变量,它是被lambda表达式捕获的。 +
lambda表达式和内部类一样,对外部自由变量捕获时,外部自由变量必须为final或者是最终变量(effectively final)的,也就是说这个变量初始化后就不能为它赋新值,同时lambda不像内部类/匿名类,lambda表达式与外围嵌套块有着相同的作用域,因此对变量命名的有关规则对lambda同样适用。大家阅读上面的代码对这些概念应该不难理解。 + +### 5.方法引用 +**只需要提供方法的名字,具体的调用过程由Lambda和函数式接口来确定,这样的方法调用成为方法引用。** +
下面的例子会打印list中的每个元素: +```java +List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(System.out::println); +``` +其中```System.out::println```这个就是一个方法引用,等价于Lambda表达式 ```(para)->{System.out.println(para);}``` +
我们看一下List#forEach方法 ```default void forEach(Consumer action)```可以看到它的参数是一个Consumer接口,该接口是一个函数式接口 +```java +@FunctionalInterface +public interface Consumer { + void accept(T t); +``` +大家能发现这个函数接口的方法和```System.out::println```有什么相似的么?没错,它们有着相似的参数列表和返回值。 +
我们自己定义一个方法,看看能不能像标准输出的打印函数一样被调用 +```java +public class MethodReference { + public static void main(String[] args) { + List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(MethodReference::myPrint); + } + + static void myPrint(int i) { + System.out.print(i + ", "); + } +} + +输出: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +``` +可以看到,我们自己定义的方法也可以当做方法引用。 +
到这里大家多少对方法引用有了一定的了解,我们再来说一下方法引用的形式。 +- 方法引用 + - 类名::静态方法名 + - 类名::实例方法名 + - 类名::new (构造方法引用) + - 实例名::实例方法名 +可以看出,方法引用是通过(方法归属名)::(方法名)来调用的。通过上面的例子已经讲解了一个`类名::静态方法名`的使用方法了,下面再依次介绍其余的几种 +方法引用的使用方法。
+**类名::实例方法名**
+先来看一段代码 +```java + String[] strings = new String[10]; + Arrays.sort(strings, String::compareToIgnoreCase); +``` +**上面的String::compareToIgnoreCase等价于(x, y) -> {return x.compareToIgnoreCase(y);}**
+我们看一下`Arrays#sort`方法`public static void sort(T[] a, Comparator c)`, +可以看到第二个参数是一个Comparator接口,该接口也是一个函数式接口,其中的抽象方法是`int compare(T o1, T o2);`,再看一下 +`String#compareToIgnoreCase`方法,`public int compareToIgnoreCase(String str)`,这个方法好像和上面讲方法引用中`类名::静态方法名`不大一样啊,它 +的参数列表和函数式接口的参数列表不一样啊,虽然它的返回值一样? +
是的,确实不一样但是别忘了,String类的这个方法是个实例方法,而不是静态方法,也就是说,这个方法是需要有一个接收者的。所谓接收者就是 +instance.method(x)中的instance, +它是某个类的实例,有的朋友可能已经明白了。上面函数式接口的`compare(T o1, T o2)`中的第一个参数作为了实例方法的接收者,而第二个参数作为了实例方法的 +参数。我们再举一个自己实现的例子: +```java +public class MethodReference { + static Random random = new Random(47); + public static void main(String[] args) { + MethodReference[] methodReferences = new MethodReference[10]; + Arrays.sort(methodReferences, MethodReference::myCompare); + } + int myCompare(MethodReference o) { + return random.nextInt(2) - 1; + } +} +``` +上面的例子可以在IDE里通过编译,大家有兴趣的可以模仿上面的例子自己写一个程序,打印出排序后的结果。 +
**构造器引用**
+构造器引用仍然需要与特定的函数式接口配合使用,并不能像下面这样直接使用。IDE会提示String不是一个函数式接口 +```java + //compile error : String is not a functional interface + String str = String::new; +``` +下面是一个使用构造器引用的例子,可以看出构造器引用可以和这种工厂型的函数式接口一起使用的。 +```java + interface IFunctional { + T func(); +} + +public class ConstructorReference { + + public ConstructorReference() { + } + + public static void main(String[] args) { + Supplier supplier0 = () -> new ConstructorReference(); + Supplier supplier1 = ConstructorReference::new; + IFunctional functional = () -> new ConstructorReference(); + IFunctional functional1 = ConstructorReference::new; + } +} +``` +下面是一个JDK官方的例子 +```java + public static , DEST extends Collection> + DEST transferElements( + SOURCE sourceCollection, + Supplier collectionFactory) { + + DEST result = collectionFactory.get(); + for (T t : sourceCollection) { + result.add(t); + } + return result; + } + + ... + + Set rosterSet = transferElements( + roster, HashSet::new); +``` + +**实例::实例方法** +
+其实开始那个例子就是一个实例::实例方法的引用 +```java +List list = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + list.add(i); + } + list.forEach(System.out::println); +``` +其中System.out就是一个实例,println是一个实例方法。相信不用再给大家做解释了。 +### 总结 +Lambda表达式是JDK8引入Java的函数式编程语法,使用Lambda需要直接或者间接的与函数式接口配合,在开发中使用Lambda可以减少代码量, +但是并不是说必须要使用Lambda(虽然它是一个很酷的东西)。有些情况下使用Lambda会使代码的可读性急剧下降,并且也节省不了多少代码, +所以在实际开发中还是需要仔细斟酌是否要使用Lambda。和Lambda相似的还有JDK10中加入的var类型推断,同样对于这个特性需要斟酌使用。 + + +___ + + +##              JDK8接口规范 +### 在JDK8中引入了lambda表达式,出现了函数式接口的概念,为了在扩展接口时保持向前兼容性(JDK8之前扩展接口会使得实现了该接口的类必须实现添加的方法,否则会报错。为了保持兼容性而做出妥协的特性还有泛型,泛型也是为了保持兼容性而失去了在一些别的语言泛型拥有的功能),Java接口规范发生了一些改变。 +### 1.JDK8以前的接口规范 +- JDK8以前接口可以定义的变量和方法 + - 所有变量(Field)不论是否显式 的声明为```public static final```,它实际上都是```public static final```的。 + - 所有方法(Method)不论是否显示 的声明为```public abstract```,它实际上都是```public abstract```的。 +```java +public interface AInterfaceBeforeJDK8 { + int FIELD = 0; + void simpleMethod(); +} +``` +以上接口信息反编译以后可以看到字节码信息里Filed是public static final的,而方法是public abstract的,即是你没有显示的去声明它。 +```java +{ + public static final int FIELD; + descriptor: I + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + ConstantValue: int 0 + + public abstract void simpleMethod(); + descriptor: ()V + flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT +} +``` +### 2.JDK8之后的接口规范 +- JDK8之后接口可以定义的变量和方法 + - 变量(Field)仍然必须是 ```java public static final```的 + - 方法(Method)除了可以是public abstract之外,还可以是public static或者是default(相当于仅public修饰的实例方法)的。 +从以上改变不难看出,修改接口的规范主要是为了能在扩展接口时保持向前兼容。 +
下面是一个JDK8之后的接口例子 +```java +public interface AInterfaceInJDK8 { + int simpleFiled = 0; + static int staticField = 1; + + public static void main(String[] args) { + } + static void staticMethod(){} + + default void defaultMethod(){} + + void simpleMethod() throws IOException; + +} +``` +进行反编译(去除了一些没用信息) +```java +{ + public static final int simpleFiled; + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + + public static final int staticField; + flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL + + public static void main(java.lang.String[]); + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + + public static void staticMethod(); + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + + public void defaultMethod(); + flags: (0x0001) ACC_PUBLIC + + public abstract void simpleMethod() throws java.io.IOException; + flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT + Exceptions: + throws java.io.IOException +} +``` +可以看到 default关键字修饰的方法是像实例方法(就是普通类中定义的普通方法)一样定义的,所以我们来定义一个只有default方法的接口并且实现一下这个接口试一 +试。 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} + +public class DefaultMethod implements Default { + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + //compile error : Non-static method 'defaultMethod()' cannot be referenced from a static context + //! DefaultMethod.defaultMethod(); + } +} +``` +可以看到default方法确实像实例方法一样,必须有实例对象才能调用,并且子类在实现接口时,可以不用实现default方法,也可以选择覆盖该方法。 +这有点像子类继承父类实例方法。 +
+接口静态方法就像是类静态方法,唯一的区别是**接口静态方法只能通过接口名调用,而类静态方法既可以通过类名调用也可以通过实例调用** +```java +interface Static { + static int staticMethod() { + return 4396; + } +} + ... main(String...args) + //!compile error: Static method may be invoked on containing interface class only + //!aInstanceOfStatic.staticMethod(); + ... +``` +另一个问题是多继承问题,大家知道Java中类是不支持多继承的,但是接口是多继承和多实现(implements后跟多个接口)的, +那么如果一个接口继承另一个接口,两个接口都有同名的default方法会怎么样呢?答案是会像类继承一样覆写(@Override),以下代码在IDE中可以顺利编译 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} +interface Default2 extends Default { + @Override + default int defaultMethod() { + return 9527; + } +} +public class DefaultMethod implements Default,Default2 { + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + } +} + +输出 : 9527 +``` +出现上面的情况时,会优先找继承树上近的方法,类似于“短路优先”。 +
+那么如果一个类实现了两个没有继承关系的接口,且这两个接口有同名方法的话会怎么样呢?IDE会要求你重写这个冲突的方法,让你自己选择去执行哪个方法,因为IDE它还没智能到你不告诉它,它就知道你想执行哪个方法。可以通过```java 接口名.super```指针来访问接口中定义的实例(default)方法。 +```java +interface Default { + default int defaultMethod() { + return 4396; + } +} + +interface Default2 { + default int defaultMethod() { + return 9527; + } +} +//如果不重写 +//compile error : defaults.DefaultMethod inherits unrelated defaults for defaultMethod() from types defaults.Default and defaults.Default2 +public class DefaultMethod implements Default,Default2 { +@Override + public int defaultMethod() { + System.out.println(Default.super.defaultMethod()); + System.out.println(Default2.super.defaultMethod()); + return 996; + } + public static void main(String[] args) { + DefaultMethod defaultMethod = new DefaultMethod(); + System.out.println(defaultMethod.defaultMethod()); + } +} + +运行输出 : +4396 +9527 +996 +``` + + +___ + + +##              改进的类型推断 +### 1.什么是类型推断 +类型推断就像它的字面意思一样,编译器根据你显示声明的已知的信息 推断出你没有显示声明的类型,这就是类型推断。 +看过《Java编程思想 第四版》的朋友可能还记得里面讲解泛型一章的时候,里面很多例子是下面这样的: +```java + Map map = new Map(); +``` +而我们平常写的都是这样的: +```java + Map map = new Map<>(); +``` +这就是类型推断,《Java编程思想 第四版》这本书出书的时候最新的JDK只有1.6(JDK7推出的类型推断),在Java编程思想里Bruce Eckel大叔还提到过这个问题 +(可能JDK的官方人员看了Bruce Eckel大叔的Thinking in Java才加的类型推断,☺),在JDK7中推出了上面这样的类型推断,可以减少一些无用的代码。 +(Java编程思想到现在还只有第四版,是不是因为Bruce Eckel大叔觉得Java新推出的语言特性“然并卵”呢?/滑稽) +
+在JDK7中,类型推断只有上面例子的那样的能力,即只有在使用**赋值语句**时才能自动推断出泛型参数信息(即<>里的信息),下面的官方文档里的例子在JDK7里会编译 +错误 +```java + List stringList = new ArrayList<>(); + stringList.add("A"); + //error : addAll(java.util.Collection)in List cannot be applied to (java.util.List) + stringList.addAll(Arrays.asList()); +``` +但是上面的代码在JDK8里可以通过,也就说,JDK8里,类型推断不仅可以用于赋值语句,而且可以根据代码中上下文里的信息推断出更多的信息,因此我们需要些的代码 +会更少。加强的类型推断还有一个就是用于Lambda表达式了。 +
+大家其实不必细究类型推断,在日常使用中IDE会自动判断,当IDE自己无法推断出足够的信息时,就需要我们额外做一下工作,比如在<>里添加更多的类型信息, +相信随着Java的进化,这些便利的功能会越来越强大。 + + +____ + + +##              通过反射获得方法的参数信息 +JDK8之前 .class文件是不会存储方法参数信息的,因此也就无法通过反射获取该信息(想想反射获取类信息的入口是什么?当然就是Class类了)。即是是在JDK11里 +也不会默认生成这些信息,可以通过在javac加上-parameters参数来让javac生成这些信息(javac就是java编译器,可以把java文件编译成.class文件)。生成额外 +的信息(运行时非必须信息)会消耗内存并且有可能公布敏感信息(某些方法参数比如password,JDK文档里这么说的),并且确实很多信息javac并不会为我们生成,比如 +LocalVariableTable,javac就不会默认生成,需要你加上 -g:vars来强制让编译器生成,同样的,方法参数信息也需要加上 +-parameters来让javac为你在.class文件中生成这些信息,否则运行时反射是无法获取到这些信息的。在讲解Java语言层面的方法之前,先看一下javac加上该 +参数和不加生成的信息有什么区别(不感兴趣想直接看运行代码的可以跳过这段)。下面是随便写的一个类。 +```java +public class ByteCodeParameters { + public String simpleMethod(String canUGetMyName, Object yesICan) { + return "9527"; + } +} +``` +先来不加参数编译和反编译一下这个类javac ByteCodeParameters.java , javap -v ByteCodeParameters: +```java + //只截取了部分信息 + public java.lang.String simpleMethod(java.lang.String, java.lang.Object); + descriptor: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=3, args_size=3 + 0: ldc #2 // String 9527 + 2: areturn + LineNumberTable: + line 5: 0 + //这个方法的描述到这里就结束了 +``` +接下来我们加上参数javac -parameters ByteCodeParameters.java 再来看反编译的信息: +```java + public java.lang.String simpleMethod(java.lang.String, java.lang.Object); + descriptor: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=3, args_size=3 + 0: ldc #2 // String 9527 + 2: areturn + LineNumberTable: + line 8: 0 + MethodParameters: + Name Flags + canUGetMyName + yesICan +``` +可以看到.class文件里多了一个MethodParameters信息,这就是参数的名字,可以看到默认是不保存的。 +
下面看一下在Intelj Idea里运行的这个例子,我们试一下通过反射获取方法名 : +```java +public class ByteCodeParameters { + public String simpleMethod(String canUGetMyName, Object yesICan) { + return "9527"; + } + + public static void main(String[] args) throws NoSuchMethodException { + Class clazz = ByteCodeParameters.class; + Method simple = clazz.getDeclaredMethod("simpleMethod", String.class, Object.class); + Parameter[] parameters = simple.getParameters(); + for (Parameter p : parameters) { + System.out.println(p.getName()); + } + } +} +输出 : +arg0 +arg1 +``` +???说好的方法名呢????别急,哈哈。前面说了,默认是不生成参数名信息的,因此我们需要做一些配置,我们找到IDEA的settings里的Java Compiler选项,在 +Additional command line parameters:一行加上-parameters(Eclipse 也是找到Java Compiler选中Stoer information about method parameters),或者自 +己编译一个.class文件放在IDEA的out下,然后再来运行 : +```java +输出 : +canUGetMyName +yesICan +``` +这样我们就通过反射获取到参数信息了。想要了解更多的同学可以自己研究一下 [官方文档] +(https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html) +
+## 总结与补充 +在JDK8之后,可以通过-parameters参数来让编译器生成参数信息然后在运行时通过反射获取方法参数信息,其实在SpringFramework +里面也有一个LocalVariableTableParameterNameDiscoverer对象可以获取方法参数名信息,有兴趣的同学可以自行百度(这个类在打印日志时可能会比较有用吧,个人感觉)。 + +____ + + + + +___ From dfa077245bae741398de561fba402a024fb12f30 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Tue, 12 Mar 2019 23:42:34 +0800 Subject: [PATCH 132/232] =?UTF-8?q?Create=20=E6=94=B9=E8=BF=9B=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=8E=A8=E6=96=AD.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 与README.md同步 --- ...73\345\236\213\346\216\250\346\226\255.md" | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 "Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" diff --git "a/Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" "b/Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" new file mode 100644 index 00000000000..b5cff7bb0c0 --- /dev/null +++ "b/Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" @@ -0,0 +1,30 @@ +##              改进的类型推断 +### 1.什么是类型推断 +类型推断就像它的字面意思一样,编译器根据你显示声明的已知的信息 推断出你没有显示声明的类型,这就是类型推断。 +看过《Java编程思想 第四版》的朋友可能还记得里面讲解泛型一章的时候,里面很多例子是下面这样的: +```java + Map map = new Map(); +``` +而我们平常写的都是这样的: +```java + Map map = new Map<>(); +``` +这就是类型推断,《Java编程思想 第四版》这本书出书的时候最新的JDK只有1.6(JDK7推出的类型推断),在Java编程思想里Bruce Eckel大叔还提到过这个问题 +(可能JDK的官方人员看了Bruce Eckel大叔的Thinking in Java才加的类型推断,☺),在JDK7中推出了上面这样的类型推断,可以减少一些无用的代码。 +(Java编程思想到现在还只有第四版,是不是因为Bruce Eckel大叔觉得Java新推出的语言特性“然并卵”呢?/滑稽) +
+在JDK7中,类型推断只有上面例子的那样的能力,即只有在使用**赋值语句**时才能自动推断出泛型参数信息(即<>里的信息),下面的官方文档里的例子在JDK7里会编译 +错误 +```java + List stringList = new ArrayList<>(); + stringList.add("A"); + //error : addAll(java.util.Collection)in List cannot be applied to (java.util.List) + stringList.addAll(Arrays.asList()); +``` +但是上面的代码在JDK8里可以通过,也就说,JDK8里,类型推断不仅可以用于赋值语句,而且可以根据代码中上下文里的信息推断出更多的信息,因此我们需要些的代码 +会更少。加强的类型推断还有一个就是用于Lambda表达式了。 +
+大家其实不必细究类型推断,在日常使用中IDE会自动判断,当IDE自己无法推断出足够的信息时,就需要我们额外做一下工作,比如在<>里添加更多的类型信息, +相信随着Java的进化,这些便利的功能会越来越强大。 + + From 954966afc487932dccd0af066492285bb8066279 Mon Sep 17 00:00:00 2001 From: haiqiang <43314997+Goose9527@users.noreply.github.com> Date: Tue, 12 Mar 2019 23:43:39 +0800 Subject: [PATCH 133/232] =?UTF-8?q?Create=20=E9=80=9A=E8=BF=87=E5=8F=8D?= =?UTF-8?q?=E5=B0=84=E8=8E=B7=E5=BE=97=E6=96=B9=E6=B3=95=E7=9A=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=BF=A1=E6=81=AF.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 与README.md同步 --- ...02\346\225\260\344\277\241\346\201\257.md" | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 "Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" diff --git "a/Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" "b/Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" new file mode 100644 index 00000000000..a1d91c4b2fe --- /dev/null +++ "b/Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" @@ -0,0 +1,79 @@ +##              通过反射获得方法的参数信息 +JDK8之前 .class文件是不会存储方法参数信息的,因此也就无法通过反射获取该信息(想想反射获取类信息的入口是什么?当然就是Class类了)。即是是在JDK11里 +也不会默认生成这些信息,可以通过在javac加上-parameters参数来让javac生成这些信息(javac就是java编译器,可以把java文件编译成.class文件)。生成额外 +的信息(运行时非必须信息)会消耗内存并且有可能公布敏感信息(某些方法参数比如password,JDK文档里这么说的),并且确实很多信息javac并不会为我们生成,比如 +LocalVariableTable,javac就不会默认生成,需要你加上 -g:vars来强制让编译器生成,同样的,方法参数信息也需要加上 +-parameters来让javac为你在.class文件中生成这些信息,否则运行时反射是无法获取到这些信息的。在讲解Java语言层面的方法之前,先看一下javac加上该 +参数和不加生成的信息有什么区别(不感兴趣想直接看运行代码的可以跳过这段)。下面是随便写的一个类。 +```java +public class ByteCodeParameters { + public String simpleMethod(String canUGetMyName, Object yesICan) { + return "9527"; + } +} +``` +先来不加参数编译和反编译一下这个类javac ByteCodeParameters.java , javap -v ByteCodeParameters: +```java + //只截取了部分信息 + public java.lang.String simpleMethod(java.lang.String, java.lang.Object); + descriptor: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=3, args_size=3 + 0: ldc #2 // String 9527 + 2: areturn + LineNumberTable: + line 5: 0 + //这个方法的描述到这里就结束了 +``` +接下来我们加上参数javac -parameters ByteCodeParameters.java 再来看反编译的信息: +```java + public java.lang.String simpleMethod(java.lang.String, java.lang.Object); + descriptor: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String; + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=3, args_size=3 + 0: ldc #2 // String 9527 + 2: areturn + LineNumberTable: + line 8: 0 + MethodParameters: + Name Flags + canUGetMyName + yesICan +``` +可以看到.class文件里多了一个MethodParameters信息,这就是参数的名字,可以看到默认是不保存的。 +
下面看一下在Intelj Idea里运行的这个例子,我们试一下通过反射获取方法名 : +```java +public class ByteCodeParameters { + public String simpleMethod(String canUGetMyName, Object yesICan) { + return "9527"; + } + + public static void main(String[] args) throws NoSuchMethodException { + Class clazz = ByteCodeParameters.class; + Method simple = clazz.getDeclaredMethod("simpleMethod", String.class, Object.class); + Parameter[] parameters = simple.getParameters(); + for (Parameter p : parameters) { + System.out.println(p.getName()); + } + } +} +输出 : +arg0 +arg1 +``` +???说好的方法名呢????别急,哈哈。前面说了,默认是不生成参数名信息的,因此我们需要做一些配置,我们找到IDEA的settings里的Java Compiler选项,在 +Additional command line parameters:一行加上-parameters(Eclipse 也是找到Java Compiler选中Stoer information about method parameters),或者自 +己编译一个.class文件放在IDEA的out下,然后再来运行 : +```java +输出 : +canUGetMyName +yesICan +``` +这样我们就通过反射获取到参数信息了。想要了解更多的同学可以自己研究一下 [官方文档] +(https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html) +
+## 总结与补充 +在JDK8之后,可以通过-parameters参数来让编译器生成参数信息然后在运行时通过反射获取方法参数信息,其实在SpringFramework +里面也有一个LocalVariableTableParameterNameDiscoverer对象可以获取方法参数名信息,有兴趣的同学可以自行百度(这个类在打印日志时可能会比较有用吧,个人感觉)。 From 27b4a0e0c10564bc7642a71862ac9e15c96a5155 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 13 Mar 2019 11:03:26 +0800 Subject: [PATCH 134/232] Add SpecialSponsors --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 65162db7d38..2088aa851c5 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@

+

Special Sponsors

+
+ + + +
+
+ ## 阅读之前必看 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 From cba052bee31eaac76ec525dca5e6ea876c2fa4f0 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 13 Mar 2019 11:05:02 +0800 Subject: [PATCH 135/232] Update text location --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2088aa851c5..67ffe327692 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Java 学习/面试指南 +

Java 学习/面试指南

From 7d041649035ed8063c8f7ee96bd85039c1c5acc3 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 13 Mar 2019 12:26:03 +0800 Subject: [PATCH 136/232] Update logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67ffe327692..0622f592cdc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

Java 学习/面试指南

- +
From 4276462e3d5bb456f5e0e34a30a12a8f2c10959a Mon Sep 17 00:00:00 2001 From: Snailclimb Date: Thu, 14 Mar 2019 10:42:49 +0800 Subject: [PATCH 137/232] Update error link --- Java/synchronized.md | 2 -- README.md | 2 +- ...260\346\215\256\347\273\223\346\236\204.md" | 18 +++++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Java/synchronized.md b/Java/synchronized.md index d415152ac48..07cb3428d20 100644 --- a/Java/synchronized.md +++ b/Java/synchronized.md @@ -1,6 +1,4 @@ -以下内容摘自我的 Gitchat :[Java 程序员必备:并发知识系统总结](https://gitbook.cn/gitchat/activity/5bc2b6af56f0425673d299bb),欢迎订阅! -Github 地址:[https://github.com/Snailclimb/JavaGuide/edit/master/Java相关/synchronized.md](https://github.com/Snailclimb/JavaGuide/edit/master/Java相关/synchronized.md) ![Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/Java%20%E7%A8%8B%E5%BA%8F%E5%91%98%E5%BF%85%E5%A4%87%EF%BC%9A%E5%B9%B6%E5%8F%91%E7%9F%A5%E8%AF%86%E7%B3%BB%E7%BB%9F%E6%80%BB%E7%BB%93/%E4%BA%8C%20%20Synchronized%20%E5%85%B3%E9%94%AE%E5%AD%97%E4%BD%BF%E7%94%A8%E3%80%81%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86%E3%80%81JDK1.6%20%E4%B9%8B%E5%90%8E%E7%9A%84%E5%BA%95%E5%B1%82%E4%BC%98%E5%8C%96%E4%BB%A5%E5%8F%8A%20%E5%92%8CReenTrantLock%20%E7%9A%84%E5%AF%B9%E6%AF%94.png) diff --git a/README.md b/README.md index 0622f592cdc..35efd31200a 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ * [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) * [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) -* [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) * [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) ## 闲谈 diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" index 9889644f39c..1633da7412e 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" @@ -81,8 +81,8 @@ Set 继承于 Collection 接口,是一个不允许出现重复元素,并且 **Stack** 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out)。相关阅读:[java数据结构与算法之栈(Stack)设计与实现](https://blog.csdn.net/javazejian/article/details/53362993) ### ArrayList 和 LinkedList 源码学习 -- [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/ArrayList.md) -- [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java相关/LinkedList.md) +- [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/ArrayList.md) +- [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/LinkedList.md) ### 推荐阅读 @@ -112,7 +112,7 @@ Set 继承于 Collection 接口,是一个不允许出现重复元素,并且 完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树 * ### 3 满二叉树 - + [满二叉树](https://baike.baidu.com/item/%E6%BB%A1%E4%BA%8C%E5%8F%89%E6%A0%91)(百度百科,国内外的定义不同) 国内教程定义:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。 @@ -145,13 +145,13 @@ Set 继承于 Collection 接口,是一个不允许出现重复元素,并且 5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度) - 红黑树的应用: - + TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。 - 为什么要用红黑树 - + 简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。详细了解可以查看 [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐) - + - 推荐文章: - [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐) - [寻找红黑树的操作手册](http://dandanlove.com/2018/03/18/red-black-tree/)(文章排版以及思路真的不错) @@ -163,7 +163,7 @@ Set 继承于 Collection 接口,是一个不允许出现重复元素,并且 [《B-树,B+树,B*树详解》](https://blog.csdn.net/aqzwss/article/details/53074186) [《B-树,B+树与B*树的优缺点比较》](https://blog.csdn.net/bigtree_3721/article/details/73632405) - + B-树(或B树)是一种平衡的多路查找(又称排序)树,在文件系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance) 1. B+ 树的叶子节点链表结构相比于 B- 树便于扫库,和范围检索。 2. B+树支持range-query(区间查询)非常方便,而B树不支持。这是数据库选用B+树的最主要原因。 @@ -171,11 +171,11 @@ Set 继承于 Collection 接口,是一个不允许出现重复元素,并且 * ### 8 LSM 树 [[HBase] LSM树 VS B+树](https://blog.csdn.net/dbanote/article/details/8897599) - + B+树最大的性能问题是会产生大量的随机IO 为了克服B+树的弱点,HBase引入了LSM树的概念,即Log-Structured Merge-Trees。 - + [LSM树由来、设计思想以及应用到HBase的索引](http://www.cnblogs.com/yanghuahui/p/3483754.html) From dfe33588696e5fc93406b587696490aa0aa84ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Fri, 15 Mar 2019 11:19:50 +0800 Subject: [PATCH 138/232] =?UTF-8?q?Update=20=E8=AE=A1=E7=AE=97=E6=9C=BA?= =?UTF-8?q?=E7=BD=91=E7=BB=9C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix 拼写错误 --- ...1\347\256\227\346\234\272\347\275\221\347\273\234.md" | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" index ba5fb91ecc9..813ba89c983 100644 --- "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" @@ -69,7 +69,7 @@ #### 运输层主要使用以下两种协议 -1. **传输控制协议 TCP**(Transmisson Control Protocol)--提供**面向连接**的,**可靠的**数据传输服务。 +1. **传输控制协议 TCP**(Transmission Control Protocol)--提供**面向连接**的,**可靠的**数据传输服务。 2. **用户数据协议 UDP**(User Datagram Protocol)--提供**无连接**的,尽最大努力的数据传输服务(**不保证数据传输的可靠性**)。 #### UDP 的主要特点 @@ -97,7 +97,7 @@ 这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系结构模型中第三层的名称. -互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Prococol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP层**。 +互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Protocol)和许多路由选择协议,因此互联网的网络层也叫做**网际层**或**IP层**。 ### 4 数据链路层 **数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。** 在两个相邻节点之间传送数据时,**数据链路层将网络层交下来的 IP 数据报组装程帧**,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 @@ -187,7 +187,8 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接, 4. TCP 的接收端会丢弃重复的数据。 5. **流量控制:** TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) 6. **拥塞控制:** 当网络拥塞时,减少数据的发送。 -7. **停止等待协议** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 +7. **停止等待协议** 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 +8. **超时重传:** 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 @@ -221,7 +222,7 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接, 2. B收到重复的M1后,也直接丢弃重复的M1。 ### 自动重传请求 ARQ 协议 -停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重转时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为自动重传请求ARQ。 +停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为自动重传请求ARQ。 **优点:** 简单 From a224bafc6a7a6623efb6905f345e3200b7d6c25a Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 15 Mar 2019 12:58:59 +0800 Subject: [PATCH 139/232] Fix link-error --- ...346\234\272\357\274\210jvm\357\274\211.md" | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git "a/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" "b/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" index 238e7c8b5df..3c0380b1659 100644 --- "a/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" +++ "b/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" @@ -7,14 +7,14 @@ Java面试通关手册(Java学习指南)github地址(欢迎star和pull) > ### 常见面试题 -[深入理解虚拟机之Java内存区域:](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483910%26idx%3D1%26sn%3D246f39051a85fc312577499691fba89f%26chksm%3Dfd985467caefdd71f9a7c275952be34484b14f9e092723c19bd4ef557c324169ed084f868bdb%23rd) +[深入理解虚拟机之Java内存区域](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484960&idx=1&sn=ff3739fe849030178346bef28a4556c3&chksm=cea249ebf9d5c0fdbde7c86155d0d7ac8925153742aff472bcb79e5e9d400534a855bad38375&token=1082669959&lang=zh_CN#rd) 1. 介绍下Java内存区域(运行时数据区)。 2. 对象的访问定位的两种方式。 -[深入理解虚拟机之垃圾回收](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483914%26idx%3D1%26sn%3D9aa157d4a1570962c39783cdeec7e539%26chksm%3Dfd98546bcaefdd7d9f61cd356e5584e56b64e234c3a403ed93cb6d4dde07a505e3000fd0c427%23rd) +[深入理解虚拟机之垃圾回收](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484959&idx=1&sn=9ac740edba59981b7c89482043776280&chksm=cea249d4f9d5c0c21703382510a47d4bb387932bd814ac891fd214b92cead5d2cf0ee2dff797&token=1082669959&lang=zh_CN#rd) 1. 如何判断对象是否死亡(两种方法)。 @@ -32,15 +32,15 @@ Java面试通关手册(Java学习指南)github地址(欢迎star和pull) -[虚拟机性能监控和故障处理工具](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483922%26idx%3D1%26sn%3D0695ff4c2700ccebb8fbc39011866bd8%26chksm%3Dfd985473caefdd6583eb42dbbc7f01918dc6827c808292bb74a5b6333e3d526c097c9351e694%23rd) + [虚拟机性能监控和故障处理工具](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484957&idx=1&sn=713ed6003d23ef883ded14cb43e9ebb7&chksm=cea249d6f9d5c0c0ce0854a03f0d02fcacc8a46e29c2fd4f085a375b00e1cd1b632937a9895e&token=1082669959&lang=zh_CN#rd) 1. JVM调优的常见命令行工具有哪些? -[深入理解虚拟机之类文件结构](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483926%26idx%3D1%26sn%3D224413da998f7e024f7b8d87397934d9%26chksm%3Dfd985477caefdd61a2fe1a3f0be29e057082252e579332f5b6d9072a150b838cefe2c47b6e5a%23rd) + [深入理解虚拟机之类文件结构](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484956&idx=1&sn=05f46ccacacdbce7c43de594d3fe93db&chksm=cea249d7f9d5c0c1ef6d29b0fbbf0701acd28490deb0974ae71b4d23ae793bec0b0993a4c829&token=1082669959&lang=zh_CN#rd) 1. 简单介绍一下Class类文件结构(常量池主要存放的是那两大常量?Class文件的继承关系是如何确定的?字段表、方法表、属性表主要包含那些信息?) -[深入理解虚拟机之虚拟机类加载机制](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247483934&idx=1&sn=f247f9bee4e240f5e7fac25659da3bff&chksm=fd98547fcaefdd6996e1a7046e03f29df9308bdf82ceeffd111112766ffd3187892700f64b40#rd) +[深入理解虚拟机之虚拟机字节码执行引擎](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484952&idx=1&sn=d0ec9443600dc5b2a81782b7ae0691d5&chksm=cea249d3f9d5c0c50642f1829fd6fe9e35d155bbbb6718611330c7c46c7158279275b533181e&token=1082669959&lang=zh_CN#rd) 1. 简单说说类加载过程,里面执行了哪些操作? @@ -56,12 +56,7 @@ Java面试通关手册(Java学习指南)github地址(欢迎star和pull) > ### 推荐阅读 -[深入理解虚拟机之虚拟机字节码执行引擎](https://juejin.im/post/5aebcb076fb9a07a9a10b5f3) + [《深入理解 Java 内存模型》读书笔记](http://www.54tianzhisheng.cn/2018/02/28/Java-Memory-Model/) (非常不错的文章) + [全面理解Java内存模型(JMM)及volatile关键字 ](https://blog.csdn.net/javazejian/article/details/72772461) -[《深入理解 Java 内存模型》读书笔记](http://www.54tianzhisheng.cn/2018/02/28/Java-Memory-Model/) (非常不错的文章) -[全面理解Java内存模型(JMM)及volatile关键字 ](https://blog.csdn.net/javazejian/article/details/72772461) - -**欢迎关注我的微信公众号:"Java面试通关手册"(一个有温度的微信公众号,期待与你共同进步~~~坚持原创,分享美文,分享各种Java学习资源):** - -![微信公众号](https://user-gold-cdn.xitu.io/2018/3/19/1623c870135a3609?w=215&h=215&f=jpeg&s=29172) From ab26995f76bfbf3e8c0247cb3d2d04d078c5d2d8 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 15 Mar 2019 12:59:32 +0800 Subject: [PATCH 140/232] =?UTF-8?q?Update=20Java=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E6=9C=BA=EF=BC=88jvm=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" | 3 --- 1 file changed, 3 deletions(-) diff --git "a/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" "b/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" index 3c0380b1659..9be88bc89c3 100644 --- "a/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" +++ "b/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" @@ -1,6 +1,3 @@ -Java面试通关手册(Java学习指南)github地址(欢迎star和pull):[https://github.com/Snailclimb/Java_Guide](https://github.com/Snailclimb/Java_Guide) - - 下面是按jvm虚拟机知识点分章节总结的一些jvm学习与面试相关的一些东西。一般作为Java程序员在面试的时候一般会问的大多就是**Java内存区域、虚拟机垃圾算法、虚拟垃圾收集器、JVM内存管理**这些问题了。这些内容参考周的《深入理解Java虚拟机》中第二章和第三章就足够了对应下面的[深入理解虚拟机之Java内存区域:](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483910%26idx%3D1%26sn%3D246f39051a85fc312577499691fba89f%26chksm%3Dfd985467caefdd71f9a7c275952be34484b14f9e092723c19bd4ef557c324169ed084f868bdb%23rd)和[深入理解虚拟机之垃圾回收](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzU4NDQ4MzU5OA%3D%3D%26mid%3D2247483914%26idx%3D1%26sn%3D9aa157d4a1570962c39783cdeec7e539%26chksm%3Dfd98546bcaefdd7d9f61cd356e5584e56b64e234c3a403ed93cb6d4dde07a505e3000fd0c427%23rd)这两篇文章。 From 849345f3aae5edde0e878f5d11a51de0ffd6eec6 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 15 Mar 2019 15:32:20 +0800 Subject: [PATCH 141/232] =?UTF-8?q?Add=20RabbitMQ=20=E5=92=8C=20Erlang=20?= =?UTF-8?q?=E7=9A=84=E7=89=88=E6=9C=AC=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rabbitmq.md" | 4 ++++ 1 file changed, 4 insertions(+) diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" index 1ac6504c530..825f71239c6 100644 --- "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" @@ -145,6 +145,10 @@ headers 类型的交换器不依赖于路由键的匹配规则来路由消息, 前面提到了 RabbitMQ 是由 Erlang语言编写的,也正因如此,在安装RabbitMQ 之前需要安装 Erlang。 +注意:在安装 RabbitMQ 的时候需要注意 RabbitMQ 和 Erlang 的版本关系,如果不注意的话会导致出错,两者对应关系如下: + +![RabbitMQ 和 Erlang 的版本关系](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RabbitMQ-Erlang.png) + ### 2.1 安装 erlang **1 下载 erlang 安装包** From 38d5c501246aaa237148588ae8ffac57b20fd89e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sat, 16 Mar 2019 11:45:45 +0800 Subject: [PATCH 142/232] Fix link-error --- "Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 8b438eb18f8..cf6255b0265 100644 --- "a/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -356,7 +356,7 @@ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返 ## 28. 为什么Java中只有值传递 - [为什么Java中只有值传递?](https://github.com/Snailclimb/Java-Guide/blob/master/%E9%9D%A2%E8%AF%95%E5%BF%85%E5%A4%87/%E6%9C%80%E6%9C%80%E6%9C%80%E5%B8%B8%E8%A7%81%E7%9A%84Java%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93/%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%882018-8-7%EF%BC%89.md) + [为什么Java中只有值传递?](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%882018-8-7%EF%BC%89.md) ## 29. 简述线程,程序,进程的基本概念.以及他们之间关系是什么? From 35f733961c660be0420cf4e5e7462d426565d657 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sat, 16 Mar 2019 19:02:52 +0800 Subject: [PATCH 143/232] =?UTF-8?q?Add=20=E4=BB=8E=E9=9B=B6=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E5=AD=A6=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 35efd31200a..4d3418b2e77 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ ## 阅读之前必看 +[《从零开始学架构》](#从零开始学架构)。 + 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! @@ -238,6 +240,15 @@ ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) +### 从零开始学架构 + +极客时间的《从零开始学架构》正在拼团中,关注公众号的很多小伙伴 应该需要。原价99,拼团价79。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。 + +
+ +
+
+ ### Contributor 下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! From bcb14bb3958ce2fc589fc1fb7a7232444e1d4a84 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Sat, 16 Mar 2019 19:03:54 +0800 Subject: [PATCH 144/232] =?UTF-8?q?Update=20=E4=BB=8E=E9=9B=B6=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E5=AD=A6=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d3418b2e77..ed47b920651 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ ### 从零开始学架构 -极客时间的《从零开始学架构》正在拼团中,关注公众号的很多小伙伴 应该需要。原价99,拼团价79。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。 +极客时间的《从零开始学架构》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价79。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。
From 1f9698362844a442d9d5482dccea4efe73004371 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 12:06:01 +0800 Subject: [PATCH 145/232] =?UTF-8?q?Create=20=E4=B8=80=E5=8D=83=E8=A1=8CMyS?= =?UTF-8?q?QL=E5=91=BD=E4=BB=A4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\241\214MySQL\345\221\275\344\273\244.md" | 941 ++++++++++++++++++ 1 file changed, 941 insertions(+) create mode 100644 "\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" new file mode 100644 index 00000000000..005d635ad2d --- /dev/null +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" @@ -0,0 +1,941 @@ +### 基本操作 + +```mysql +/* Windows服务 */ +-- 启动MySQL + net start mysql +-- 创建Windows服务 + sc create mysql binPath= mysqld_bin_path(注意:等号与值之间有空格) +/* 连接与断开服务器 */ +mysql -h 地址 -P 端口 -u 用户名 -p 密码 +SHOW PROCESSLIST -- 显示哪些线程正在运行 +SHOW VARIABLES -- 显示系统变量信息 +``` + +### 数据库操作 + +```mysql +/* 数据库操作 */ ------------------ +-- 查看当前数据库 + SELECT DATABASE(); +-- 显示当前时间、用户名、数据库版本 + SELECT now(), user(), version(); +-- 创建库 + CREATE DATABASE[ IF NOT EXISTS] 数据库名 数据库选项 + 数据库选项: + CHARACTER SET charset_name + COLLATE collation_name +-- 查看已有库 + SHOW DATABASES[ LIKE 'PATTERN'] +-- 查看当前库信息 + SHOW CREATE DATABASE 数据库名 +-- 修改库的选项信息 + ALTER DATABASE 库名 选项信息 +-- 删除库 + DROP DATABASE[ IF EXISTS] 数据库名 + 同时删除该数据库相关的目录及其目录内容 +``` + +### 表的操作 + +```mysql +-- 创建表 + CREATE [TEMPORARY] TABLE[ IF NOT EXISTS] [库名.]表名 ( 表的结构定义 )[ 表选项] + 每个字段必须有数据类型 + 最后一个字段后不能有逗号 + TEMPORARY 临时表,会话结束时表自动消失 + 对于字段的定义: + 字段名 数据类型 [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'] +-- 表选项 + -- 字符集 + CHARSET = charset_name + 如果表没有设定,则使用数据库字符集 + -- 存储引擎 + ENGINE = engine_name + 表在管理数据时采用的不同的数据结构,结构不同会导致处理方式、提供的特性操作等不同 + 常见的引擎:InnoDB MyISAM Memory/Heap BDB Merge Example CSV MaxDB Archive + 不同的引擎在保存表的结构和数据时采用不同的方式 + MyISAM表文件含义:.frm表定义,.MYD表数据,.MYI表索引 + InnoDB表文件含义:.frm表定义,表空间数据和日志文件 + SHOW ENGINES -- 显示存储引擎的状态信息 + SHOW ENGINE 引擎名 {LOGS|STATUS} -- 显示存储引擎的日志或状态信息 + -- 自增起始数 + AUTO_INCREMENT = 行数 + -- 数据文件目录 + DATA DIRECTORY = '目录' + -- 索引文件目录 + INDEX DIRECTORY = '目录' + -- 表注释 + COMMENT = 'string' + -- 分区选项 + PARTITION BY ... (详细见手册) +-- 查看所有表 + SHOW TABLES[ LIKE 'pattern'] + SHOW TABLES FROM 表名 +-- 查看表机构 + SHOW CREATE TABLE 表名 (信息更详细) + DESC 表名 / DESCRIBE 表名 / EXPLAIN 表名 / SHOW COLUMNS FROM 表名 [LIKE 'PATTERN'] + SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] +-- 修改表 + -- 修改表本身的选项 + ALTER TABLE 表名 表的选项 + eg: ALTER TABLE 表名 ENGINE=MYISAM; + -- 对表进行重命名 + RENAME TABLE 原表名 TO 新表名 + RENAME TABLE 原表名 TO 库名.表名 (可将表移动到另一个数据库) + -- RENAME可以交换两个表名 + -- 修改表的字段机构(13.1.2. ALTER TABLE语法) + ALTER TABLE 表名 操作名 + -- 操作名 + ADD[ COLUMN] 字段定义 -- 增加字段 + AFTER 字段名 -- 表示增加在该字段名后面 + FIRST -- 表示增加在第一个 + ADD PRIMARY KEY(字段名) -- 创建主键 + ADD UNIQUE [索引名] (字段名)-- 创建唯一索引 + ADD INDEX [索引名] (字段名) -- 创建普通索引 + DROP[ COLUMN] 字段名 -- 删除字段 + MODIFY[ COLUMN] 字段名 字段属性 -- 支持对字段属性进行修改,不能修改字段名(所有原有属性也需写上) + CHANGE[ COLUMN] 原字段名 新字段名 字段属性 -- 支持对字段名修改 + DROP PRIMARY KEY -- 删除主键(删除主键前需删除其AUTO_INCREMENT属性) + DROP INDEX 索引名 -- 删除索引 + DROP FOREIGN KEY 外键 -- 删除外键 +-- 删除表 + DROP TABLE[ IF EXISTS] 表名 ... +-- 清空表数据 + TRUNCATE [TABLE] 表名 +-- 复制表结构 + CREATE TABLE 表名 LIKE 要复制的表名 +-- 复制表结构和数据 + CREATE TABLE 表名 [AS] SELECT * FROM 要复制的表名 +-- 检查表是否有错误 + CHECK TABLE tbl_name [, tbl_name] ... [option] ... +-- 优化表 + OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... +-- 修复表 + REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM] +-- 分析表 + ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... +``` + +### 数据操作 + +```mysql +/* 数据操作 */ ------------------ +-- 增 + INSERT [INTO] 表名 [(字段列表)] VALUES (值列表)[, (值列表), ...] + -- 如果要插入的值列表包含所有字段并且顺序一致,则可以省略字段列表。 + -- 可同时插入多条数据记录! + REPLACE 与 INSERT 完全一样,可互换。 + INSERT [INTO] 表名 SET 字段名=值[, 字段名=值, ...] +-- 查 + SELECT 字段列表 FROM 表名[ 其他子句] + -- 可来自多个表的多个字段 + -- 其他子句可以不使用 + -- 字段列表可以用*代替,表示所有字段 +-- 删 + DELETE FROM 表名[ 删除条件子句] + 没有条件子句,则会删除全部 +-- 改 + UPDATE 表名 SET 字段名=新值[, 字段名=新值] [更新条件] +``` + +### 字符集编码 + +```mysql +/* 字符集编码 */ ------------------ +-- MySQL、数据库、表、字段均可设置编码 +-- 数据编码与客户端编码不需一致 +SHOW VARIABLES LIKE 'character_set_%' -- 查看所有字符集编码项 + character_set_client 客户端向服务器发送数据时使用的编码 + character_set_results 服务器端将结果返回给客户端所使用的编码 + character_set_connection 连接层编码 +SET 变量名 = 变量值 + SET character_set_client = gbk; + SET character_set_results = gbk; + SET character_set_connection = gbk; +SET NAMES GBK; -- 相当于完成以上三个设置 +-- 校对集 + 校对集用以排序 + SHOW CHARACTER SET [LIKE 'pattern']/SHOW CHARSET [LIKE 'pattern'] 查看所有字符集 + SHOW COLLATION [LIKE 'pattern'] 查看所有校对集 + CHARSET 字符集编码 设置字符集编码 + COLLATE 校对集编码 设置校对集编码 +``` + +### 数据类型(列类型) + +```mysql +/* 数据类型(列类型) */ ------------------ +1. 数值类型 +-- a. 整型 ---------- + 类型 字节 范围(有符号位) + tinyint 1字节 -128 ~ 127 无符号位:0 ~ 255 + smallint 2字节 -32768 ~ 32767 + mediumint 3字节 -8388608 ~ 8388607 + int 4字节 + bigint 8字节 + int(M) M表示总位数 + - 默认存在符号位,unsigned 属性修改 + - 显示宽度,如果某个数不够定义字段时设置的位数,则前面以0补填,zerofill 属性修改 + 例:int(5) 插入一个数'123',补填后为'00123' + - 在满足要求的情况下,越小越好。 + - 1表示bool值真,0表示bool值假。MySQL没有布尔类型,通过整型0和1表示。常用tinyint(1)表示布尔型。 +-- b. 浮点型 ---------- + 类型 字节 范围 + float(单精度) 4字节 + double(双精度) 8字节 + 浮点型既支持符号位 unsigned 属性,也支持显示宽度 zerofill 属性。 + 不同于整型,前后均会补填0. + 定义浮点型时,需指定总位数和小数位数。 + float(M, D) double(M, D) + M表示总位数,D表示小数位数。 + M和D的大小会决定浮点数的范围。不同于整型的固定范围。 + M既表示总位数(不包括小数点和正负号),也表示显示宽度(所有显示符号均包括)。 + 支持科学计数法表示。 + 浮点数表示近似值。 +-- c. 定点数 ---------- + decimal -- 可变长度 + decimal(M, D) M也表示总位数,D表示小数位数。 + 保存一个精确的数值,不会发生数据的改变,不同于浮点数的四舍五入。 + 将浮点数转换为字符串来保存,每9位数字保存为4个字节。 +2. 字符串类型 +-- a. char, varchar ---------- + char 定长字符串,速度快,但浪费空间 + varchar 变长字符串,速度慢,但节省空间 + M表示能存储的最大长度,此长度是字符数,非字节数。 + 不同的编码,所占用的空间不同。 + char,最多255个字符,与编码无关。 + varchar,最多65535字符,与编码有关。 + 一条有效记录最大不能超过65535个字节。 + utf8 最大为21844个字符,gbk 最大为32766个字符,latin1 最大为65532个字符 + varchar 是变长的,需要利用存储空间保存 varchar 的长度,如果数据小于255个字节,则采用一个字节来保存长度,反之需要两个字节来保存。 + varchar 的最大有效长度由最大行大小和使用的字符集确定。 + 最大有效长度是65532字节,因为在varchar存字符串时,第一个字节是空的,不存在任何数据,然后还需两个字节来存放字符串的长度,所以有效长度是64432-1-2=65532字节。 + 例:若一个表定义为 CREATE TABLE tb(c1 int, c2 char(30), c3 varchar(N)) charset=utf8; 问N的最大值是多少? 答:(65535-1-2-4-30*3)/3 +-- b. blob, text ---------- + blob 二进制字符串(字节字符串) + tinyblob, blob, mediumblob, longblob + text 非二进制字符串(字符字符串) + tinytext, text, mediumtext, longtext + text 在定义时,不需要定义长度,也不会计算总长度。 + text 类型在定义时,不可给default值 +-- c. binary, varbinary ---------- + 类似于char和varchar,用于保存二进制字符串,也就是保存字节字符串而非字符字符串。 + char, varchar, text 对应 binary, varbinary, blob. +3. 日期时间类型 + 一般用整型保存时间戳,因为PHP可以很方便的将时间戳进行格式化。 + datetime 8字节 日期及时间 1000-01-01 00:00:00 到 9999-12-31 23:59:59 + date 3字节 日期 1000-01-01 到 9999-12-31 + timestamp 4字节 时间戳 19700101000000 到 2038-01-19 03:14:07 + time 3字节 时间 -838:59:59 到 838:59:59 + year 1字节 年份 1901 - 2155 +datetime YYYY-MM-DD hh:mm:ss +timestamp YY-MM-DD hh:mm:ss + YYYYMMDDhhmmss + YYMMDDhhmmss + YYYYMMDDhhmmss + YYMMDDhhmmss +date YYYY-MM-DD + YY-MM-DD + YYYYMMDD + YYMMDD + YYYYMMDD + YYMMDD +time hh:mm:ss + hhmmss + hhmmss +year YYYY + YY + YYYY + YY +4. 枚举和集合 +-- 枚举(enum) ---------- +enum(val1, val2, val3...) + 在已知的值中进行单选。最大数量为65535. + 枚举值在保存时,以2个字节的整型(smallint)保存。每个枚举值,按保存的位置顺序,从1开始逐一递增。 + 表现为字符串类型,存储却是整型。 + NULL值的索引是NULL。 + 空字符串错误值的索引值是0。 +-- 集合(set) ---------- +set(val1, val2, val3...) + create table tab ( gender set('男', '女', '无') ); + insert into tab values ('男, 女'); + 最多可以有64个不同的成员。以bigint存储,共8个字节。采取位运算的形式。 + 当创建表时,SET成员值的尾部空格将自动被删除。 +``` + +### 列属性(列约束) + +```mysql +/* 列属性(列约束) */ ------------------ +1. PRIMARY 主键 + - 能唯一标识记录的字段,可以作为主键。 + - 一个表只能有一个主键。 + - 主键具有唯一性。 + - 声明字段时,用 primary key 标识。 + 也可以在字段列表之后声明 + 例:create table tab ( id int, stu varchar(10), primary key (id)); + - 主键字段的值不能为null。 + - 主键可以由多个字段共同组成。此时需要在字段列表后声明的方法。 + 例:create table tab ( id int, stu varchar(10), age int, primary key (stu, age)); +2. UNIQUE 唯一索引(唯一约束) + 使得某字段的值也不能重复。 +3. NULL 约束 + null不是数据类型,是列的一个属性。 + 表示当前列是否可以为null,表示什么都没有。 + null, 允许为空。默认。 + not null, 不允许为空。 + insert into tab values (null, 'val'); + -- 此时表示将第一个字段的值设为null, 取决于该字段是否允许为null +4. DEFAULT 默认值属性 + 当前字段的默认值。 + insert into tab values (default, 'val'); -- 此时表示强制使用默认值。 + create table tab ( add_time timestamp default current_timestamp ); + -- 表示将当前时间的时间戳设为默认值。 + current_date, current_time +5. AUTO_INCREMENT 自动增长约束 + 自动增长必须为索引(主键或unique) + 只能存在一个字段为自动增长。 + 默认为1开始自动增长。可以通过表属性 auto_increment = x进行设置,或 alter table tbl auto_increment = x; +6. COMMENT 注释 + 例:create table tab ( id int ) comment '注释内容'; +7. FOREIGN KEY 外键约束 + 用于限制主表与从表数据完整性。 + alter table t1 add constraint `t1_t2_fk` foreign key (t1_id) references t2(id); + -- 将表t1的t1_id外键关联到表t2的id字段。 + -- 每个外键都有一个名字,可以通过 constraint 指定 + 存在外键的表,称之为从表(子表),外键指向的表,称之为主表(父表)。 + 作用:保持数据一致性,完整性,主要目的是控制存储在外键表(从表)中的数据。 + MySQL中,可以对InnoDB引擎使用外键约束: + 语法: + foreign key (外键字段) references 主表名 (关联字段) [主表记录删除时的动作] [主表记录更新时的动作] + 此时需要检测一个从表的外键需要约束为主表的已存在的值。外键在没有关联的情况下,可以设置为null.前提是该外键列,没有not null。 + 可以不指定主表记录更改或更新时的动作,那么此时主表的操作被拒绝。 + 如果指定了 on update 或 on delete:在删除或更新时,有如下几个操作可以选择: + 1. cascade,级联操作。主表数据被更新(主键值更新),从表也被更新(外键值更新)。主表记录被删除,从表相关记录也被删除。 + 2. set null,设置为null。主表数据被更新(主键值更新),从表的外键被设置为null。主表记录被删除,从表相关记录外键被设置成null。但注意,要求该外键列,没有not null属性约束。 + 3. restrict,拒绝父表删除和更新。 + 注意,外键只被InnoDB存储引擎所支持。其他引擎是不支持的。 + +``` + +### 建表规范 + +```mysql +/* 建表规范 */ ------------------ + -- Normal Format, NF + - 每个表保存一个实体信息 + - 每个具有一个ID字段作为主键 + - ID主键 + 原子表 + -- 1NF, 第一范式 + 字段不能再分,就满足第一范式。 + -- 2NF, 第二范式 + 满足第一范式的前提下,不能出现部分依赖。 + 消除符合主键就可以避免部分依赖。增加单列关键字。 + -- 3NF, 第三范式 + 满足第二范式的前提下,不能出现传递依赖。 + 某个字段依赖于主键,而有其他字段依赖于该字段。这就是传递依赖。 + 将一个实体信息的数据放在一个表内实现。 +``` + +### SELECT + +```mysql +/* SELECT */ ------------------ +SELECT [ALL|DISTINCT] select_expr FROM -> WHERE -> GROUP BY [合计函数] -> HAVING -> ORDER BY -> LIMIT +a. select_expr + -- 可以用 * 表示所有字段。 + select * from tb; + -- 可以使用表达式(计算公式、函数调用、字段也是个表达式) + select stu, 29+25, now() from tb; + -- 可以为每个列使用别名。适用于简化列标识,避免多个列标识符重复。 + - 使用 as 关键字,也可省略 as. + select stu+10 as add10 from tb; +b. FROM 子句 + 用于标识查询来源。 + -- 可以为表起别名。使用as关键字。 + SELECT * FROM tb1 AS tt, tb2 AS bb; + -- from子句后,可以同时出现多个表。 + -- 多个表会横向叠加到一起,而数据会形成一个笛卡尔积。 + SELECT * FROM tb1, tb2; + -- 向优化符提示如何选择索引 + USE INDEX、IGNORE INDEX、FORCE INDEX + SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3; + SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3; +c. WHERE 子句 + -- 从from获得的数据源中进行筛选。 + -- 整型1表示真,0表示假。 + -- 表达式由运算符和运算数组成。 + -- 运算数:变量(字段)、值、函数返回值 + -- 运算符: + =, <=>, <>, !=, <=, <, >=, >, !, &&, ||, + in (not) null, (not) like, (not) in, (not) between and, is (not), and, or, not, xor + is/is not 加上ture/false/unknown,检验某个值的真假 + <=>与<>功能相同,<=>可用于null比较 +d. GROUP BY 子句, 分组子句 + GROUP BY 字段/别名 [排序方式] + 分组后会进行排序。升序:ASC,降序:DESC + 以下[合计函数]需配合 GROUP BY 使用: + count 返回不同的非NULL值数目 count(*)、count(字段) + sum 求和 + max 求最大值 + min 求最小值 + avg 求平均值 + group_concat 返回带有来自一个组的连接的非NULL值的字符串结果。组内字符串连接。 +e. HAVING 子句,条件子句 + 与 where 功能、用法相同,执行时机不同。 + where 在开始时执行检测数据,对原数据进行过滤。 + having 对筛选出的结果再次进行过滤。 + having 字段必须是查询出来的,where 字段必须是数据表存在的。 + where 不可以使用字段的别名,having 可以。因为执行WHERE代码时,可能尚未确定列值。 + where 不可以使用合计函数。一般需用合计函数才会用 having + SQL标准要求HAVING必须引用GROUP BY子句中的列或用于合计函数中的列。 +f. ORDER BY 子句,排序子句 + order by 排序字段/别名 排序方式 [,排序字段/别名 排序方式]... + 升序:ASC,降序:DESC + 支持多个字段的排序。 +g. LIMIT 子句,限制结果数量子句 + 仅对处理好的结果进行数量限制。将处理好的结果的看作是一个集合,按照记录出现的顺序,索引从0开始。 + limit 起始位置, 获取条数 + 省略第一个参数,表示从索引0开始。limit 获取条数 +h. DISTINCT, ALL 选项 + distinct 去除重复记录 + 默认为 all, 全部记录 +``` + +### UNION + +```mysql +/* UNION */ ------------------ + 将多个select查询的结果组合成一个结果集合。 + SELECT ... UNION [ALL|DISTINCT] SELECT ... + 默认 DISTINCT 方式,即所有返回的行都是唯一的 + 建议,对每个SELECT查询加上小括号包裹。 + ORDER BY 排序时,需加上 LIMIT 进行结合。 + 需要各select查询的字段数量一样。 + 每个select查询的字段列表(数量、类型)应一致,因为结果中的字段名以第一条select语句为准。 +``` + +### 子查询 + +```mysql +/* 子查询 */ ------------------ + - 子查询需用括号包裹。 +-- from型 + from后要求是一个表,必须给子查询结果取个别名。 + - 简化每个查询内的条件。 + - from型需将结果生成一个临时表格,可用以原表的锁定的释放。 + - 子查询返回一个表,表型子查询。 + select * from (select * from tb where id>0) as subfrom where id>1; +-- where型 + - 子查询返回一个值,标量子查询。 + - 不需要给子查询取别名。 + - where子查询内的表,不能直接用以更新。 + select * from tb where money = (select max(money) from tb); + -- 列子查询 + 如果子查询结果返回的是一列。 + 使用 in 或 not in 完成查询 + exists 和 not exists 条件 + 如果子查询返回数据,则返回1或0。常用于判断条件。 + select column1 from t1 where exists (select * from t2); + -- 行子查询 + 查询条件是一个行。 + select * from t1 where (id, gender) in (select id, gender from t2); + 行构造符:(col1, col2, ...) 或 ROW(col1, col2, ...) + 行构造符通常用于与对能返回两个或两个以上列的子查询进行比较。 + -- 特殊运算符 + != all() 相当于 not in + = some() 相当于 in。any 是 some 的别名 + != some() 不等同于 not in,不等于其中某一个。 + all, some 可以配合其他运算符一起使用。 +``` + +### 连接查询(join) + +```mysql +/* 连接查询(join) */ ------------------ + 将多个表的字段进行连接,可以指定连接条件。 +-- 内连接(inner join) + - 默认就是内连接,可省略inner。 + - 只有数据存在时才能发送连接。即连接结果不能出现空行。 + on 表示连接条件。其条件表达式与where类似。也可以省略条件(表示条件永远为真) + 也可用where表示连接条件。 + 还有 using, 但需字段名相同。 using(字段名) + -- 交叉连接 cross join + 即,没有条件的内连接。 + select * from tb1 cross join tb2; +-- 外连接(outer join) + - 如果数据不存在,也会出现在连接结果中。 + -- 左外连接 left join + 如果数据不存在,左表记录会出现,而右表为null填充 + -- 右外连接 right join + 如果数据不存在,右表记录会出现,而左表为null填充 +-- 自然连接(natural join) + 自动判断连接条件完成连接。 + 相当于省略了using,会自动查找相同字段名。 + natural join + natural left join + natural right join +select info.id, info.name, info.stu_num, extra_info.hobby, extra_info.sex from info, extra_info where info.stu_num = extra_info.stu_id; +``` + +### TRUNCATE + +```mysql +/* TRUNCATE */ ------------------ +TRUNCATE [TABLE] tbl_name +清空数据 +删除重建表 +区别: +1,truncate 是删除表再创建,delete 是逐条删除 +2,truncate 重置auto_increment的值。而delete不会 +3,truncate 不知道删除了几条,而delete知道。 +4,当被用于带分区的表时,truncate 会保留分区 +``` + +### 备份与还原 + +```mysql +/* 备份与还原 */ ------------------ +备份,将数据的结构与表内数据保存起来。 +利用 mysqldump 指令完成。 +-- 导出 +mysqldump [options] db_name [tables] +mysqldump [options] ---database DB1 [DB2 DB3...] +mysqldump [options] --all--database +1. 导出一张表 +  mysqldump -u用户名 -p密码 库名 表名 > 文件名(D:/a.sql) +2. 导出多张表 +  mysqldump -u用户名 -p密码 库名 表1 表2 表3 > 文件名(D:/a.sql) +3. 导出所有表 +  mysqldump -u用户名 -p密码 库名 > 文件名(D:/a.sql) +4. 导出一个库 +  mysqldump -u用户名 -p密码 --lock-all-tables --database 库名 > 文件名(D:/a.sql) +可以-w携带WHERE条件 +-- 导入 +1. 在登录mysql的情况下: +  source 备份文件 +2. 在不登录的情况下 +  mysql -u用户名 -p密码 库名 < 备份文件 +``` + +### 视图 + +```mysql +什么是视图: + 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。 + 视图具有表结构文件,但不存在数据文件。 + 对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。 + 视图是存储在数据库中的查询的sql语句,它主要出于两种原因:安全原因,视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。 +-- 创建视图 +CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_list)] AS select_statement + - 视图名必须唯一,同时不能与表重名。 + - 视图可以使用select语句查询到的列名,也可以自己指定相应的列名。 + - 可以指定视图执行的算法,通过ALGORITHM指定。 + - column_list如果存在,则数目必须等于SELECT语句检索的列数 +-- 查看结构 + SHOW CREATE VIEW view_name +-- 删除视图 + - 删除视图后,数据依然存在。 + - 可同时删除多个视图。 + DROP VIEW [IF EXISTS] view_name ... +-- 修改视图结构 + - 一般不修改视图,因为不是所有的更新视图都会映射到表上。 + ALTER VIEW view_name [(column_list)] AS select_statement +-- 视图作用 + 1. 简化业务逻辑 + 2. 对客户端隐藏真实的表结构 +-- 视图算法(ALGORITHM) + MERGE 合并 + 将视图的查询语句,与外部查询需要先合并再执行! + TEMPTABLE 临时表 + 将视图执行完毕后,形成临时表,再做外层查询! + UNDEFINED 未定义(默认),指的是MySQL自主去选择相应的算法。 +``` + +### 事务(transaction) + +```mysql +事务是指逻辑上的一组操作,组成这组操作的各个单元,要不全成功要不全失败。 + - 支持连续SQL的集体成功或集体撤销。 + - 事务是数据库在数据晚自习方面的一个功能。 + - 需要利用 InnoDB 或 BDB 存储引擎,对自动提交的特性支持完成。 + - InnoDB被称为事务安全型引擎。 +-- 事务开启 + START TRANSACTION; 或者 BEGIN; + 开启事务后,所有被执行的SQL语句均被认作当前事务内的SQL语句。 +-- 事务提交 + COMMIT; +-- 事务回滚 + ROLLBACK; + 如果部分操作发生问题,映射到事务开启前。 +-- 事务的特性 + 1. 原子性(Atomicity) + 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 + 2. 一致性(Consistency) + 事务前后数据的完整性必须保持一致。 + - 事务开始和结束时,外部数据一致 + - 在整个事务过程中,操作是连续的 + 3. 隔离性(Isolation) + 多个用户并发访问数据库时,一个用户的事务不能被其它用户的事物所干扰,多个并发事务之间的数据要相互隔离。 + 4. 持久性(Durability) + 一个事务一旦被提交,它对数据库中的数据改变就是永久性的。 +-- 事务的实现 + 1. 要求是事务支持的表类型 + 2. 执行一组相关的操作前开启事务 + 3. 整组操作完成后,都成功,则提交;如果存在失败,选择回滚,则会回到事务开始的备份点。 +-- 事务的原理 + 利用InnoDB的自动提交(autocommit)特性完成。 + 普通的MySQL执行语句后,当前的数据提交操作均可被其他客户端可见。 + 而事务是暂时关闭“自动提交”机制,需要commit提交持久化数据操作。 +-- 注意 + 1. 数据定义语言(DDL)语句不能被回滚,比如创建或取消数据库的语句,和创建、取消或更改表或存储的子程序的语句。 + 2. 事务不能被嵌套 +-- 保存点 + SAVEPOINT 保存点名称 -- 设置一个事务保存点 + ROLLBACK TO SAVEPOINT 保存点名称 -- 回滚到保存点 + RELEASE SAVEPOINT 保存点名称 -- 删除保存点 +-- InnoDB自动提交特性设置 + SET autocommit = 0|1; 0表示关闭自动提交,1表示开启自动提交。 + - 如果关闭了,那普通操作的结果对其他客户端也不可见,需要commit提交后才能持久化数据操作。 + - 也可以关闭自动提交来开启事务。但与START TRANSACTION不同的是, + SET autocommit是永久改变服务器的设置,直到下次再次修改该设置。(针对当前连接) + 而START TRANSACTION记录开启前的状态,而一旦事务提交或回滚后就需要再次开启事务。(针对当前事务) + +``` + +### 锁表 + +```mysql +/* 锁表 */ +表锁定只用于防止其它客户端进行不正当地读取和写入 +MyISAM 支持表锁,InnoDB 支持行锁 +-- 锁定 + LOCK TABLES tbl_name [AS alias] +-- 解锁 + UNLOCK TABLES +``` + +### 触发器 + +```mysql +/* 触发器 */ ------------------ + 触发程序是与表有关的命名数据库对象,当该表出现特定事件时,将激活该对象 + 监听:记录的增加、修改、删除。 +-- 创建触发器 +CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt + 参数: + trigger_time是触发程序的动作时间。它可以是 before 或 after,以指明触发程序是在激活它的语句之前或之后触发。 + trigger_event指明了激活触发程序的语句的类型 + INSERT:将新行插入表时激活触发程序 + UPDATE:更改某一行时激活触发程序 + DELETE:从表中删除某一行时激活触发程序 + tbl_name:监听的表,必须是永久性的表,不能将触发程序与TEMPORARY表或视图关联起来。 + trigger_stmt:当触发程序激活时执行的语句。执行多个语句,可使用BEGIN...END复合语句结构 +-- 删除 +DROP TRIGGER [schema_name.]trigger_name +可以使用old和new代替旧的和新的数据 + 更新操作,更新前是old,更新后是new. + 删除操作,只有old. + 增加操作,只有new. +-- 注意 + 1. 对于具有相同触发程序动作时间和事件的给定表,不能有两个触发程序。 +-- 字符连接函数 +concat(str1,str2,...]) +concat_ws(separator,str1,str2,...) +-- 分支语句 +if 条件 then + 执行语句 +elseif 条件 then + 执行语句 +else + 执行语句 +end if; +-- 修改最外层语句结束符 +delimiter 自定义结束符号 + SQL语句 +自定义结束符号 +delimiter ; -- 修改回原来的分号 +-- 语句块包裹 +begin + 语句块 +end +-- 特殊的执行 +1. 只要添加记录,就会触发程序。 +2. Insert into on duplicate key update 语法会触发: + 如果没有重复记录,会触发 before insert, after insert; + 如果有重复记录并更新,会触发 before insert, before update, after update; + 如果有重复记录但是没有发生更新,则触发 before insert, before update +3. Replace 语法 如果有记录,则执行 before insert, before delete, after delete, after insert +``` + +### SQL编程 + +```mysql +/* SQL编程 */ ------------------ +--// 局部变量 ---------- +-- 变量声明 + declare var_name[,...] type [default value] + 这个语句被用来声明局部变量。要给变量提供一个默认值,请包含一个default子句。值可以被指定为一个表达式,不需要为一个常数。如果没有default子句,初始值为null。 +-- 赋值 + 使用 set 和 select into 语句为变量赋值。 + - 注意:在函数内是可以使用全局变量(用户自定义的变量) +--// 全局变量 ---------- +-- 定义、赋值 +set 语句可以定义并为变量赋值。 +set @var = value; +也可以使用select into语句为变量初始化并赋值。这样要求select语句只能返回一行,但是可以是多个字段,就意味着同时为多个变量进行赋值,变量的数量需要与查询的列数一致。 +还可以把赋值语句看作一个表达式,通过select执行完成。此时为了避免=被当作关系运算符看待,使用:=代替。(set语句可以使用= 和 :=)。 +select @var:=20; +select @v1:=id, @v2=name from t1 limit 1; +select * from tbl_name where @var:=30; +select into 可以将表中查询获得的数据赋给变量。 + -| select max(height) into @max_height from tb; +-- 自定义变量名 +为了避免select语句中,用户自定义的变量与系统标识符(通常是字段名)冲突,用户自定义变量在变量名前使用@作为开始符号。 +@var=10; + - 变量被定义后,在整个会话周期都有效(登录到退出) +--// 控制结构 ---------- +-- if语句 +if search_condition then + statement_list +[elseif search_condition then + statement_list] +... +[else + statement_list] +end if; +-- case语句 +CASE value WHEN [compare-value] THEN result +[WHEN [compare-value] THEN result ...] +[ELSE result] +END +-- while循环 +[begin_label:] while search_condition do + statement_list +end while [end_label]; +- 如果需要在循环内提前终止 while循环,则需要使用标签;标签需要成对出现。 + -- 退出循环 + 退出整个循环 leave + 退出当前循环 iterate + 通过退出的标签决定退出哪个循环 +--// 内置函数 ---------- +-- 数值函数 +abs(x) -- 绝对值 abs(-10.9) = 10 +format(x, d) -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46 +ceil(x) -- 向上取整 ceil(10.1) = 11 +floor(x) -- 向下取整 floor (10.1) = 10 +round(x) -- 四舍五入去整 +mod(m, n) -- m%n m mod n 求余 10%3=1 +pi() -- 获得圆周率 +pow(m, n) -- m^n +sqrt(x) -- 算术平方根 +rand() -- 随机数 +truncate(x, d) -- 截取d位小数 +-- 时间日期函数 +now(), current_timestamp(); -- 当前日期时间 +current_date(); -- 当前日期 +current_time(); -- 当前时间 +date('yyyy-mm-dd hh:ii:ss'); -- 获取日期部分 +time('yyyy-mm-dd hh:ii:ss'); -- 获取时间部分 +date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j'); -- 格式化时间 +unix_timestamp(); -- 获得unix时间戳 +from_unixtime(); -- 从时间戳获得时间 +-- 字符串函数 +length(string) -- string长度,字节 +char_length(string) -- string的字符个数 +substring(str, position [,length]) -- 从str的position开始,取length个字符 +replace(str ,search_str ,replace_str) -- 在str中用replace_str替换search_str +instr(string ,substring) -- 返回substring首次在string中出现的位置 +concat(string [,...]) -- 连接字串 +charset(str) -- 返回字串字符集 +lcase(string) -- 转换成小写 +left(string, length) -- 从string2中的左边起取length个字符 +load_file(file_name) -- 从文件读取内容 +locate(substring, string [,start_position]) -- 同instr,但可指定开始位置 +lpad(string, length, pad) -- 重复用pad加在string开头,直到字串长度为length +ltrim(string) -- 去除前端空格 +repeat(string, count) -- 重复count次 +rpad(string, length, pad) --在str后用pad补充,直到长度为length +rtrim(string) -- 去除后端空格 +strcmp(string1 ,string2) -- 逐字符比较两字串大小 +-- 流程函数 +case when [condition] then result [when [condition] then result ...] [else result] end 多分支 +if(expr1,expr2,expr3) 双分支。 +-- 聚合函数 +count() +sum(); +max(); +min(); +avg(); +group_concat() +-- 其他常用函数 +md5(); +default(); +--// 存储函数,自定义函数 ---------- +-- 新建 + CREATE FUNCTION function_name (参数列表) RETURNS 返回值类型 + 函数体 + - 函数名,应该合法的标识符,并且不应该与已有的关键字冲突。 + - 一个函数应该属于某个数据库,可以使用db_name.funciton_name的形式执行当前函数所属数据库,否则为当前数据库。 + - 参数部分,由"参数名"和"参数类型"组成。多个参数用逗号隔开。 + - 函数体由多条可用的mysql语句,流程控制,变量声明等语句构成。 + - 多条语句应该使用 begin...end 语句块包含。 + - 一定要有 return 返回值语句。 +-- 删除 + DROP FUNCTION [IF EXISTS] function_name; +-- 查看 + SHOW FUNCTION STATUS LIKE 'partten' + SHOW CREATE FUNCTION function_name; +-- 修改 + ALTER FUNCTION function_name 函数选项 +--// 存储过程,自定义功能 ---------- +-- 定义 +存储存储过程 是一段代码(过程),存储在数据库中的sql组成。 +一个存储过程通常用于完成一段业务逻辑,例如报名,交班费,订单入库等。 +而一个函数通常专注与某个功能,视为其他程序服务的,需要在其他语句中调用函数才可以,而存储过程不能被其他调用,是自己执行 通过call执行。 +-- 创建 +CREATE PROCEDURE sp_name (参数列表) + 过程体 +参数列表:不同于函数的参数列表,需要指明参数类型 +IN,表示输入型 +OUT,表示输出型 +INOUT,表示混合型 +注意,没有返回值。 +``` + +### 存储过程 + +```mysql +/* 存储过程 */ ------------------ +存储过程是一段可执行性代码的集合。相比函数,更偏向于业务逻辑。 +调用:CALL 过程名 +-- 注意 +- 没有返回值。 +- 只能单独调用,不可夹杂在其他语句中 +-- 参数 +IN|OUT|INOUT 参数名 数据类型 +IN 输入:在调用过程中,将数据输入到过程体内部的参数 +OUT 输出:在调用过程中,将过程体处理完的结果返回到客户端 +INOUT 输入输出:既可输入,也可输出 +-- 语法 +CREATE PROCEDURE 过程名 (参数列表) +BEGIN + 过程体 +END +``` + +### 用户和权限管理 + +```mysql +/* 用户和权限管理 */ ------------------ +-- root密码重置 +1. 停止MySQL服务 +2. [Linux] /usr/local/mysql/bin/safe_mysqld --skip-grant-tables & + [Windows] mysqld --skip-grant-tables +3. use mysql; +4. UPDATE `user` SET PASSWORD=PASSWORD("密码") WHERE `user` = "root"; +5. FLUSH PRIVILEGES; +用户信息表:mysql.user +-- 刷新权限 +FLUSH PRIVILEGES; +-- 增加用户 +CREATE USER 用户名 IDENTIFIED BY [PASSWORD] 密码(字符串) + - 必须拥有mysql数据库的全局CREATE USER权限,或拥有INSERT权限。 + - 只能创建用户,不能赋予权限。 + - 用户名,注意引号:如 'user_name'@'192.168.1.1' + - 密码也需引号,纯数字密码也要加引号 + - 要在纯文本中指定密码,需忽略PASSWORD关键词。要把密码指定为由PASSWORD()函数返回的混编值,需包含关键字PASSWORD +-- 重命名用户 +RENAME USER old_user TO new_user +-- 设置密码 +SET PASSWORD = PASSWORD('密码') -- 为当前用户设置密码 +SET PASSWORD FOR 用户名 = PASSWORD('密码') -- 为指定用户设置密码 +-- 删除用户 +DROP USER 用户名 +-- 分配权限/添加用户 +GRANT 权限列表 ON 表名 TO 用户名 [IDENTIFIED BY [PASSWORD] 'password'] + - all privileges 表示所有权限 + - *.* 表示所有库的所有表 + - 库名.表名 表示某库下面的某表 + GRANT ALL PRIVILEGES ON `pms`.* TO 'pms'@'%' IDENTIFIED BY 'pms0817'; +-- 查看权限 +SHOW GRANTS FOR 用户名 + -- 查看当前用户权限 + SHOW GRANTS; 或 SHOW GRANTS FOR CURRENT_USER; 或 SHOW GRANTS FOR CURRENT_USER(); +-- 撤消权限 +REVOKE 权限列表 ON 表名 FROM 用户名 +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 用户名 -- 撤销所有权限 +-- 权限层级 +-- 要使用GRANT或REVOKE,您必须拥有GRANT OPTION权限,并且您必须用于您正在授予或撤销的权限。 +全局层级:全局权限适用于一个给定服务器中的所有数据库,mysql.user + GRANT ALL ON *.*和 REVOKE ALL ON *.*只授予和撤销全局权限。 +数据库层级:数据库权限适用于一个给定数据库中的所有目标,mysql.db, mysql.host + GRANT ALL ON db_name.*和REVOKE ALL ON db_name.*只授予和撤销数据库权限。 +表层级:表权限适用于一个给定表中的所有列,mysql.talbes_priv + GRANT ALL ON db_name.tbl_name和REVOKE ALL ON db_name.tbl_name只授予和撤销表权限。 +列层级:列权限适用于一个给定表中的单一列,mysql.columns_priv + 当使用REVOKE时,您必须指定与被授权列相同的列。 +-- 权限列表 +ALL [PRIVILEGES] -- 设置除GRANT OPTION之外的所有简单权限 +ALTER -- 允许使用ALTER TABLE +ALTER ROUTINE -- 更改或取消已存储的子程序 +CREATE -- 允许使用CREATE TABLE +CREATE ROUTINE -- 创建已存储的子程序 +CREATE TEMPORARY TABLES -- 允许使用CREATE TEMPORARY TABLE +CREATE USER -- 允许使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。 +CREATE VIEW -- 允许使用CREATE VIEW +DELETE -- 允许使用DELETE +DROP -- 允许使用DROP TABLE +EXECUTE -- 允许用户运行已存储的子程序 +FILE -- 允许使用SELECT...INTO OUTFILE和LOAD DATA INFILE +INDEX -- 允许使用CREATE INDEX和DROP INDEX +INSERT -- 允许使用INSERT +LOCK TABLES -- 允许对您拥有SELECT权限的表使用LOCK TABLES +PROCESS -- 允许使用SHOW FULL PROCESSLIST +REFERENCES -- 未被实施 +RELOAD -- 允许使用FLUSH +REPLICATION CLIENT -- 允许用户询问从属服务器或主服务器的地址 +REPLICATION SLAVE -- 用于复制型从属服务器(从主服务器中读取二进制日志事件) +SELECT -- 允许使用SELECT +SHOW DATABASES -- 显示所有数据库 +SHOW VIEW -- 允许使用SHOW CREATE VIEW +SHUTDOWN -- 允许使用mysqladmin shutdown +SUPER -- 允许使用CHANGE MASTER, KILL, PURGE MASTER LOGS和SET GLOBAL语句,mysqladmin debug命令;允许您连接(一次),即使已达到max_connections。 +UPDATE -- 允许使用UPDATE +USAGE -- “无权限”的同义词 +GRANT OPTION -- 允许授予权限 +``` + +### 表维护 + +```mysql +/* 表维护 */ +-- 分析和存储表的关键字分布 +ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE 表名 ... +-- 检查一个或多个表是否有错误 +CHECK TABLE tbl_name [, tbl_name] ... [option] ... +option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED} +-- 整理数据文件的碎片 +OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... +``` + +### 杂项 + +```mysql +/* 杂项 */ ------------------ +1. 可用反引号(`)为标识符(库名、表名、字段名、索引、别名)包裹,以避免与关键字重名!中文也可以作为标识符! +2. 每个库目录存在一个保存当前数据库的选项文件db.opt。 +3. 注释: + 单行注释 # 注释内容 + 多行注释 /* 注释内容 */ + 单行注释 -- 注释内容 (标准SQL注释风格,要求双破折号后加一空格符(空格、TAB、换行等)) +4. 模式通配符: + _ 任意单个字符 + % 任意多个字符,甚至包括零字符 + 单引号需要进行转义 \' +5. CMD命令行内的语句结束符可以为 ";", "\G", "\g",仅影响显示结果。其他地方还是用分号结束。delimiter 可修改当前对话的语句结束符。 +6. SQL对大小写不敏感 +7. 清除已有语句:\c +``` + From 109db3a262a710f0ed5bb98d835cd776e5f03c6f Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 12:08:15 +0800 Subject: [PATCH 146/232] =?UTF-8?q?Update=20=E4=B8=80=E5=8D=83=E8=A1=8CMyS?= =?UTF-8?q?QL=E5=91=BD=E4=BB=A4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" | 5 +++++ 1 file changed, 5 insertions(+) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" index 005d635ad2d..fbcb4ceca92 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" @@ -1,3 +1,8 @@ +> 原文地址:https://shockerli.net/post/1000-line-mysql-note/ +> 作者:格物 + +非常不错的总结,强烈建议保存下来,需要的时候看一看。 + ### 基本操作 ```mysql From daf9c5f93ee530a2093db5ad7438ee4c831e33d9 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 12:09:22 +0800 Subject: [PATCH 147/232] =?UTF-8?q?Add=E4=B8=80=E5=8D=83=E8=A1=8CMySQL?= =?UTF-8?q?=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ed47b920651..9e8ed9417ca 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ * [MySQL 学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL.md) * [【思维导图-索引篇】搞定数据库索引就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL%20Index.md) +* [一千行MySQL命令](https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/一千行MySQL命令.md) ### Redis From 48f982a827c04ffc40baf36e70673f8a35856375 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 12:41:46 +0800 Subject: [PATCH 148/232] =?UTF-8?q?Add=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\241\214MySQL\345\221\275\344\273\244.md" | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" index fbcb4ceca92..5375f9c69fe 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" @@ -1,8 +1,35 @@ -> 原文地址:https://shockerli.net/post/1000-line-mysql-note/ +> 原文地址:https://shockerli.net/post/1000-line-mysql-note/ ,JavaGuide 对本文进行了简答排版,新增了目录。 > 作者:格物 非常不错的总结,强烈建议保存下来,需要的时候看一看。 + +- [基本操作](#基本操作) +- [数据库操作](#数据库操作) +- [表的操作](#表的操作) +- [数据操作](#数据操作) +- [字符集编码](#字符集编码) +- [数据类型(列类型)](#数据类型列类型) +- [列属性(列约束)](#列属性列约束) +- [建表规范](#建表规范) +- [SELECT](#select) +- [UNION](#union) +- [子查询](#子查询) +- [连接查询(join)](#连接查询join) +- [TRUNCATE](#truncate) +- [备份与还原](#备份与还原) +- [视图](#视图) +- [事务(transaction)](#事务transaction) +- [锁表](#锁表) +- [触发器](#触发器) +- [SQL编程](#sql编程) +- [存储过程](#存储过程) +- [用户和权限管理](#用户和权限管理) +- [表维护](#表维护) +- [杂项](#杂项) + + + ### 基本操作 ```mysql From a0e23e0c90bba2a3b5835ea236957edca73e8090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=B3=E9=98=B3?= <260893248@qq.com> Date: Mon, 18 Mar 2019 19:27:13 +0800 Subject: [PATCH 149/232] =?UTF-8?q?=E8=B2=8C=E4=BC=BC=E5=8D=95=E8=AF=8D?= =?UTF-8?q?=E6=9C=89=E7=82=B9=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 貌似单词有点错误 --- .../MySQL Index.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" index 27b82c8bc70..e8d968f2750 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" @@ -70,7 +70,7 @@ select * from user where city=xx; // 无法命中索引 冗余索引指的是索引的功能相同,能够命中 就肯定能命中 ,那么 就是冗余索引如(name,city )和(name )这两个索引就是冗余索引,能够命中后者的查询肯定是能够命中前者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。 -MySQLS.7 版本后,可以通过查询 sys 库的 `schemal_r dundant_indexes` 表来查看冗余索引 +MySQLS.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引 ### Mysql如何为表字段添加索引??? From cfd5ab8f0c537b4bce2e50d42985259645846d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=B3=E9=98=B3?= <260893248@qq.com> Date: Mon, 18 Mar 2019 19:38:36 +0800 Subject: [PATCH 150/232] =?UTF-8?q?=E4=BC=BC=E4=B9=8E=E6=98=AF=E6=A0=87?= =?UTF-8?q?=E7=82=B9=E6=89=93=E9=94=99=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 似乎是标点打错了 --- .../MySQL Index.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" index e8d968f2750..f18b4a077ee 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" @@ -55,7 +55,7 @@ MySQL的基本存储结构是页(记录都存在页里边): ### 最左前缀原则 -MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索引。如User表的name和city加联合索引就是(name,city)o而最左前缀原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以被用到。如下: +MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索引。如User表的name和city加联合索引就是(name,city),而最左前缀原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以被用到。如下: ``` select * from user where name=xx and city=xx ; //可以命中索引 From 2553b479e2567318f13e9e87b04cb7bc7f7cf26e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 20:07:23 +0800 Subject: [PATCH 151/232] =?UTF-8?q?Add=20=E6=B7=B1=E5=85=A5=E6=8B=86?= =?UTF-8?q?=E8=A7=A3Java=E8=99=9A=E6=8B=9F=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9e8ed9417ca..01868e1a88f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## 阅读之前必看 -[《从零开始学架构》](#从零开始学架构)。 +[《深入拆解Java虚拟机》](#深入拆解Java虚拟机)。 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 @@ -241,12 +241,12 @@ ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) -### 从零开始学架构 +### 深入拆解Java虚拟机 -极客时间的《从零开始学架构》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价79。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。 +极客时间的《深入拆解Java虚拟机》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价58。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。
- +
From f08f1e51131fa86a5b8bb0e730a2299d5ebd8f92 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 21:00:14 +0800 Subject: [PATCH 152/232] =?UTF-8?q?Update=20=E6=B7=B1=E5=85=A5=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E8=99=9A=E6=8B=9F=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01868e1a88f..8bc13033e36 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,7 @@ ### 深入拆解Java虚拟机 -极客时间的《深入拆解Java虚拟机》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价58。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得24元返现,减轻你们的学习成本。 +极客时间的《深入拆解Java虚拟机》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价58。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得18元返现,减轻你们的学习成本。
From 81b7848b3c18976c1502de2e487f324a87212980 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 18 Mar 2019 21:40:42 +0800 Subject: [PATCH 153/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bc13033e36..e4cc6d45170 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ * [MySQL 学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL.md) * [【思维导图-索引篇】搞定数据库索引就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL%20Index.md) -* [一千行MySQL命令](https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/一千行MySQL命令.md) +* [一千行MySQL学习笔记](https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/一千行MySQL命令.md) ### Redis From e145611d13dafcd590640fceb667596d255b5a8c Mon Sep 17 00:00:00 2001 From: Lemon Seven <43209747+JerrySeven@users.noreply.github.com> Date: Tue, 19 Mar 2019 10:47:56 +0800 Subject: [PATCH 154/232] Update ArrayList-Grow.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍! 记清楚了!不是网上很多人说的 1.5 倍+1!" 修改为 “所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!(JDK1.6版本以后)** JDk1.6版本时,扩容之后容量为 1.5 倍+1!” --- Java/ArrayList-Grow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java/ArrayList-Grow.md b/Java/ArrayList-Grow.md index d763cb83492..7b1e7afe443 100644 --- a/Java/ArrayList-Grow.md +++ b/Java/ArrayList-Grow.md @@ -145,7 +145,7 @@ } ``` -**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!** 记清楚了!不是网上很多人说的 1.5 倍+1! +**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!(JDK1.6版本以后)** JDk1.6版本时,扩容之后容量为 1.5 倍+1! > ">>"(移位运算符):>>1 右移一位相当于除2,右移n位相当于除以 2 的 n 次方。这里 oldCapacity 明显右移了1位所以相当于oldCapacity /2。对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源   From 2f5d45b73588c18ae07a6552727a3fcb5116dcf3 Mon Sep 17 00:00:00 2001 From: Lemon Seven <43209747+JerrySeven@users.noreply.github.com> Date: Tue, 19 Mar 2019 10:49:12 +0800 Subject: [PATCH 155/232] Update ArrayList-Grow.md --- Java/ArrayList-Grow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java/ArrayList-Grow.md b/Java/ArrayList-Grow.md index 7b1e7afe443..6dd4cc93daf 100644 --- a/Java/ArrayList-Grow.md +++ b/Java/ArrayList-Grow.md @@ -145,7 +145,7 @@ } ``` -**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!(JDK1.6版本以后)** JDk1.6版本时,扩容之后容量为 1.5 倍+1! +**int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!(JDK1.6版本以后)** JDk1.6版本时,扩容之后容量为 1.5 倍+1!详情请参考源码 > ">>"(移位运算符):>>1 右移一位相当于除2,右移n位相当于除以 2 的 n 次方。这里 oldCapacity 明显右移了1位所以相当于oldCapacity /2。对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源   From d76938c9fed8ed10b62297e92a26acbb58516d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Tue, 19 Mar 2019 14:05:39 +0800 Subject: [PATCH 156/232] Update Shell.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 转义符与双引号问题 --- "\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" "b/\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" index 4179f2702bb..9f3ae871ee4 100644 --- "a/\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" +++ "b/\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" @@ -210,7 +210,7 @@ expr length "$name"; expr 5+6 // 直接输出 5+6 expr 5 + 6 // 输出 11 ``` -对于某些运算符,还需要我们使用符号"\"进行转义,否则就会提示语法错误。 +对于某些运算符,还需要我们使用符号`\`进行转义,否则就会提示语法错误。 ```shell expr 5 * 6 // 输出错误 From 8a8fcb97f580f78bfd2f291d44a1f650cbe00f54 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 16:39:53 +0800 Subject: [PATCH 157/232] =?UTF-8?q?Update=20=E6=96=B9=E6=B3=95=E5=8C=BA+?= =?UTF-8?q?=E5=A0=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\257\207\346\226\207\347\253\240.md" | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git "a/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index 61d5e722174..e605225beaf 100644 --- "a/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -1,29 +1,36 @@ +## 写在前面(常见面试题) -## 写在前面(常见面试题) - -### 基本问题: +### 基本问题 - **介绍下 Java 内存区域(运行时数据区)** - **Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么)** - **对象的访问定位的两种方式(句柄和直接指针两种方式)** -### 拓展问题: +### 拓展问题 - **String类和常量池** - **8种基本类型的包装类和常量池** -## 1 概述 +## 一 概述 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。 -## 2 运行时数据区域 -Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 -![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/JVM运行时数据区域.png) +## 二 运行时数据区域 +Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK. 1.8 和之前的版本略有不同,下面会介绍到。 + +**JDK 1.8之前:** -这些组成部分一些是线程私有的,其他的则是线程共享的。 +
+ +
+**JDK 1.8 :** + +
+ +
**线程私有的:** @@ -48,11 +55,11 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成 1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。 2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。 -**注意:程序计数器是唯一一个不会出现OutOfMemoryError的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。** +**注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。** ### 2.2 Java 虚拟机栈 -**与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同,描述的是 Java 方法执行的内存模型。** +**与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同,描述的是 Java 方法执行的内存模型,每次方法调用的数据都是通过栈传递的。** **Java 内存可以粗糙的区分为堆内存(Heap)和栈内存(Stack),其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。** (实际上,Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。) @@ -65,6 +72,17 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成 Java 虚拟机栈也是线程私有的,每个线程都有各自的Java虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。 +**扩展:那么方法/函数如何调用?** + +Java 栈可用类比数据结构中栈,Java 栈中保存的主要内容是栈帧,每一次函数调用都会有一个对应的栈帧被压入Java栈,每一个函数调用结束后,都会有一个栈帧被弹出。 + +Java方法有两种返回方式: + +1. return 语句。 +2. 抛出异常。 + +不管哪种返回方式都会导致栈帧被弹出。 + ### 2.3 本地方法栈 和虚拟机栈所发挥的作用非常相似,区别是: **虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。** 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。 @@ -78,13 +96,11 @@ Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共 Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC堆(Garbage Collected Heap)**.从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以Java堆还可以细分为:新生代和老年代:再细致一点有:Eden空间、From Survivor、To Survivor空间等。**进一步划分的目的是更好地回收内存,或者更快地分配内存。** -![](https://user-gold-cdn.xitu.io/2018/8/25/16570344a29c3433?w=599&h=250&f=png&s=8946) +
+ +
-**在 JDK 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)。** - -推荐阅读: - -- 《Java8内存模型—永久代(PermGen)和元空间(Metaspace)》:[http://www.cnblogs.com/paddix/p/5309550.html](http://www.cnblogs.com/paddix/p/5309550.html) +上图所示的 eden区、s0区、s1区都属于新生代,tentired 区属于老年代。大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden区->Survivor 区后对象的初始年龄变为1),当它的年龄增加到一定程度(默认为15岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。 ### 2.5 方法区 @@ -92,9 +108,11 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC堆(Ga HotSpot 虚拟机中方法区也常被称为 **“永久代”**,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。 +**相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入方法区后就“永久存在”了。** +JDK 1.8 的时候,方法区被彻底移除了(JDK1.7就已经开始了),取而代之是元空间,元空间使用的是直接内存。 -**相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入方法区后就“永久存在”了。** +我们可以使用参数: `-XX:MetaspaceSize ` 来指定元数据区的大小。与永久区很大的不同就是,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。 ### 2.6 运行时常量池 @@ -107,23 +125,19 @@ HotSpot 虚拟机中方法区也常被称为 **“永久代”**,本质上两 ![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/26038433.jpg) ——图片来源:https://blog.csdn.net/wangbiao007/article/details/78545189 - - -推荐阅读: - -- 《Java 中几种常量池的区分》: [https://blog.csdn.net/qq_26222859/article/details/73135660](https://blog.csdn.net/qq_26222859/article/details/73135660) +推荐阅读:《Java 中几种常量池的区分》: [https://blog.csdn.net/qq_26222859/article/details/73135660](https://blog.csdn.net/qq_26222859/article/details/73135660) ### 2.7 直接内存 -直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 异常出现。 +**直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 异常出现。** -JDK1.4中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通道(Channel)** 与**缓存区(Buffer)** 的 I/O 方式,它可以直接使用Native函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为**避免了在 Java 堆和 Native 堆之间来回复制数据**。 +JDK1.4 中新加入的 **NIO(New Input/Output) 类**,引入了一种基于**通道(Channel)** 与**缓存区(Buffer)** 的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为**避免了在 Java 堆和 Native 堆之间来回复制数据**。 本机直接内存的分配不会收到 Java 堆的限制,但是,既然是内存就会受到本机总内存大小以及处理器寻址空间的限制。 -## 3 HotSpot 虚拟机对象探秘 +## 三 HotSpot 虚拟机对象探秘 通过上面的介绍我们大概知道了虚拟机的内存情况,下面我们来详细的了解一下 HotSpot 虚拟机在 Java 堆中对象分配、布局和访问的全过程。 ### 3.1 对象的创建 @@ -326,8 +340,7 @@ i4=i5+i6 true 语句i4 == i5 + i6,因为+这个操作符不适用于Integer对象,首先i5和i6进行自动拆箱操作,进行数值相加,即i4 == 40。然后Integer对象无法与数值进行直接比较,所以i4自动拆箱转为int值40,最终这条语句转为40 == 40进行数值比较。 - -**参考:** +## 参考 - 《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》 - 《实战java虚拟机》 From 657e7491452a0832dfcf1a8bcdde254313315dd7 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 16:41:40 +0800 Subject: [PATCH 158/232] =?UTF-8?q?Update=20=E5=A0=86=E7=9A=84=E4=BB=8B?= =?UTF-8?q?=E7=BB=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...277\231\344\271\210\347\256\200\345\215\225.md" | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git "a/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" "b/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" index 819d37faca2..4530f3d3b0e 100644 --- "a/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" +++ "b/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" @@ -28,11 +28,17 @@ Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java 自动内存管理最核心的功能是 **堆** 内存中对象的分配与回收。 -**JDK1.8之前的堆内存示意图:** +Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC堆(Garbage Collected Heap)**.从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden空间、From Survivor、To Survivor空间等。**进一步划分的目的是更好地回收内存,或者更快地分配内存。** + +**堆空间的基本结构:** + +
+ +
+ +上图所示的 eden区、s0区、s1区都属于新生代,tentired 区属于老年代。大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden区->Survivor 区后对象的初始年龄变为1),当它的年龄增加到一定程度(默认为15岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。 -![](https://user-gold-cdn.xitu.io/2018/8/25/16570344a29c3433?w=599&h=250&f=png&s=8946) -从上图可以看出堆内存分为新生代、老年代和永久代。新生代又被进一步分为:Eden 区+Survivor1 区+Survivor2 区。值得注意的是,在 JDK 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)。 ![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-27/89294547.jpg) @@ -306,7 +312,7 @@ Parallel Scavenge 收集器类似于ParNew 收集器。 **那么它有什么特 ### 4.5 Parallel Old收集器 **Parallel Scavenge收集器的老年代版本**。使用多线程和“标记-整理”算法。在注重吞吐量以及CPU资源的场合,都可以优先考虑 Parallel Scavenge收集器和Parallel Old收集器。 - + ### 4.6 CMS收集器 **CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它而非常符合在注重用户体验的应用上使用。** From 8d492eaa16792062b1bf2fb97510657a3b42cb7f Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 16:45:07 +0800 Subject: [PATCH 159/232] =?UTF-8?q?Update=20=E5=B8=B8=E9=87=8F=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...32\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git "a/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index e605225beaf..ac0e8322b67 100644 --- "a/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -42,7 +42,7 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成 - 堆 - 方法区 -- 直接内存 +- 直接内存(非运行时数据区的一部分) ### 2.1 程序计数器 @@ -125,8 +125,6 @@ JDK 1.8 的时候,方法区被彻底移除了(JDK1.7就已经开始了), ![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-14/26038433.jpg) ——图片来源:https://blog.csdn.net/wangbiao007/article/details/78545189 -推荐阅读:《Java 中几种常量池的区分》: [https://blog.csdn.net/qq_26222859/article/details/73135660](https://blog.csdn.net/qq_26222859/article/details/73135660) - ### 2.7 直接内存 From 8102a8515307fd2f21104290649a91d54eb322ab Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 16:58:36 +0800 Subject: [PATCH 160/232] Add link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4cc6d45170..8d3073808ef 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ ## ToDoList(待办清单) -* [x] Java 8 新特性总结 +* [x] [Java 8 新特性总结](https://github.com/Snailclimb/JavaGuide/blob/master/Java/What's%20New%20in%20JDK8/Java8Tutorial.md) * [ ] Java 8 新特性详解 * [ ] Java 多线程类别知识重构 -* [x] BIO,NIO,AIO 总结 +* [x] [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java/BIO%2CNIO%2CAIO%20summary.md) * [ ] Netty 总结 * [ ] 数据结构总结重构 From b1c17e19a1302ebcbfc0c301f757786face61bee Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 18:45:57 +0800 Subject: [PATCH 161/232] =?UTF-8?q?Add=20qq=E7=BE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8d3073808ef..a5648241951 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@

Java 学习/面试指南

+Java后端技术交流群(限工作一年及以上,群内有免费学习视频和面试资料,**非本仓库作者本人的群**) :[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-869815609-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=39f41ae604e3dc72a763279fea1dc6c5f14d5f19aef04e38065d0f173095d921) +

From 9ea8095f0109c48a6a1a78edbc0bce70b1367c9b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 19:05:11 +0800 Subject: [PATCH 162/232] =?UTF-8?q?Fix=20QQ=E7=BE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5648241951..00636fb4301 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Java 学习/面试指南

-Java后端技术交流群(限工作一年及以上,群内有免费学习视频和面试资料,**非本仓库作者本人的群**) :[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-869815609-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=39f41ae604e3dc72a763279fea1dc6c5f14d5f19aef04e38065d0f173095d921) +Java后端技术交流群(限工作一年及以上,群内有免费学习视频和面试资料,**非本仓库作者本人的群**) :[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-869815609-red.svg)](https://jq.qq.com/?_wv=1027&k=5QqyxIx)
From 5d47fb4827f7bb5b0ec73143ea271306e28e6dd0 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 19 Mar 2019 22:44:31 +0800 Subject: [PATCH 163/232] =?UTF-8?q?Delete=20=E6=B7=B1=E5=85=A5=E6=8B=86?= =?UTF-8?q?=E8=A7=A3Java=E8=99=9A=E6=8B=9F=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index 00636fb4301..502e2013447 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,6 @@ Java后端技术交流群(限工作一年及以上,群内有免费学习视频 ## 阅读之前必看 -[《深入拆解Java虚拟机》](#深入拆解Java虚拟机)。 - 1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! @@ -243,15 +241,6 @@ Java后端技术交流群(限工作一年及以上,群内有免费学习视频 ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) -### 深入拆解Java虚拟机 - -极客时间的《深入拆解Java虚拟机》正在拼团中(优惠活动马上结束),关注本仓库的很多小伙伴应该需要。原价99,拼团价58。大家使用微信扫描我的二维码购买的话,可以添加[我的微信](#联系我)然后获得18元返现,减轻你们的学习成本。 - -
- -
-
- ### Contributor 下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! From 4529a8feb483a2f12ce0d698e14876ff106077af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BB=E5=A2=83=E4=BA=91=E5=9B=BE?= <31980412+illusorycloud@users.noreply.github.com> Date: Wed, 20 Mar 2019 17:29:56 +0800 Subject: [PATCH 164/232] =?UTF-8?q?Update=20=E4=B8=80=E5=8D=83=E8=A1=8CMyS?= =?UTF-8?q?QL=E5=91=BD=E4=BB=A4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正一个错误 --- ...200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" index 5375f9c69fe..acbfda3d7ac 100644 --- "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" +++ "b/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" @@ -103,7 +103,7 @@ SHOW VARIABLES -- 显示系统变量信息 PARTITION BY ... (详细见手册) -- 查看所有表 SHOW TABLES[ LIKE 'pattern'] - SHOW TABLES FROM 表名 + SHOW TABLES FROM 库名 -- 查看表机构 SHOW CREATE TABLE 表名 (信息更详细) DESC 表名 / DESCRIBE 表名 / EXPLAIN 表名 / SHOW COLUMNS FROM 表名 [LIKE 'PATTERN'] From 740135dfd8f78b41673adf3697d3339523b9f624 Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 21 Mar 2019 11:19:48 +0800 Subject: [PATCH 165/232] Update synchronized.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- Java/synchronized.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Java/synchronized.md b/Java/synchronized.md index 07cb3428d20..0a1f4f2b073 100644 --- a/Java/synchronized.md +++ b/Java/synchronized.md @@ -46,7 +46,7 @@ uniqueInstance 采用 volatile 关键字修饰也是很有必要的, uniqueIns 2. 初始化 uniqueInstance 3. 将 uniqueInstance 指向分配的内存地址 -但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出先问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。 +但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。 使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。 @@ -139,7 +139,7 @@ JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、 **⑤ 锁粗化** -原则上,我们再编写代码的时候,总是推荐将同步快的作用范围限制得尽量小——只在共享数据的实际作用域才进行同步,这样是为了使得需要同步的操作数量尽可能变小,如果存在锁竞争,那等待线程也能尽快拿到锁。 +原则上,我们在编写代码的时候,总是推荐将同步块的作用范围限制得尽量小,——直在共享数据的实际作用域才进行同步,这样是为了使得需要同步的操作数量尽可能变小,如果存在锁竞争,那等待线程也能尽快拿到锁。 大部分情况下,上面的原则都是没有问题的,但是如果一系列的连续操作都对同一个对象反复加锁和解锁,那么会带来很多不必要的性能消耗。 From 1d651129505068afb381d1615c5d24cc8b9cd675 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 21 Mar 2019 11:43:19 +0800 Subject: [PATCH 166/232] Create GitIntroduce.md --- DevelopCommonTools/GitIntroduce.md | 258 +++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 DevelopCommonTools/GitIntroduce.md diff --git a/DevelopCommonTools/GitIntroduce.md b/DevelopCommonTools/GitIntroduce.md new file mode 100644 index 00000000000..e58f13b63aa --- /dev/null +++ b/DevelopCommonTools/GitIntroduce.md @@ -0,0 +1,258 @@ + + +- [版本控制](#版本控制) + - [什么是版本控制](#什么是版本控制) + - [为什么要版本控制](#为什么要版本控制) + - [本地版本控制系统](#本地版本控制系统) + - [集中化的版本控制系统](#集中化的版本控制系统) + - [分布式版本控制系统](#分布式版本控制系统) +- [认识 Git](#认识-git) + - [Git 简史](#git-简史) + - [Git 与其他版本管理系统的主要区别](#git-与其他版本管理系统的主要区别) + - [Git 的三种状态](#git-的三种状态) +- [Git 使用快速入门](#git-使用快速入门) + - [获取 Git 仓库](#获取-git-仓库) + - [记录每次更新到仓库](#记录每次更新到仓库) + - [推送改动到远程仓库](#推送改动到远程仓库) + - [远程仓库的移除与重命名](#远程仓库的移除与重命名) + - [查看提交历史](#查看提交历史) + - [撤销操作](#撤销操作) + - [分支](#分支) +- [推荐阅读](#推荐阅读) + + + +## 版本控制 + +### 什么是版本控制 + +版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 除了项目源代码,你可以对任何类型的文件进行版本控制。 + +### 为什么要版本控制 + +有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 + +### 本地版本控制系统 + +许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。 这么做唯一的好处就是简单,但是特别容易犯错。 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。 + +为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。 + +![本地版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/本地版本控制系统.png) + +### 集中化的版本控制系统 + +接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作? 于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 + +集中化的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 + +![集中化的版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/集中化的版本控制系统.png) + +这么做虽然解决了本地版本控制系统无法让在不同系统上的开发者协同工作的诟病,但也还是存在下面的问题: + +- **单点故障:** 中央服务器宕机,则其他人无法使用;如果中心数据库磁盘损坏有没有进行备份,你将丢失所有数据。本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。 +- **必须联网才能工作:** 受网络状况、带宽影响。 + +### 分布式版本控制系统 + +于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。 Git 就是一个典型的分布式版本控制系统。 + +这类系统,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。 + +![分布式版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/分布式版本控制系统.png) + +分布式版本控制系统可以不用联网就可以工作,因为每个人的电脑上都是完整的版本库,当你修改了某个文件后,你只需要将自己的修改推送给别人就可以了。但是,在实际使用分布式版本控制系统的时候,很少会直接进行推送修改,而是使用一台充当“中央服务器”的东西。这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。 + +分布式版本控制系统的优势不单是不必联网这么简单,后面我们还会看到 Git 极其强大的分支管理等功能。 + +## 认识 Git + +### Git 简史 + +Linux 内核项目组当时使用分布式版本控制系统 BitKeeper 来管理和维护代码。但是,后来开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统,而且对新的版本控制系统做了很多改进。 + +### Git 与其他版本管理系统的主要区别 + + Git 在保存和对待各种信息的时候与其它版本控制系统有很大差异,尽管操作起来的命令形式非常相近,理解这些差异将有助于防止你使用中的困惑。 + +下面我们主要说一个关于 Git 其他版本管理系统的主要差别:**对待数据的方式**。 + +**Git采用的是直接记录快照的方式,而非差异比较。我后面会详细介绍这两种方式的差别。** + +大部分版本控制系统(CVS、Subversion、Perforce、Bazaar 等等)都是以文件变更列表的方式存储信息,这类系统**将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。** + +具体原理如下图所示,理解起来其实很简单,每个我们对提交更新一个文件之后,系统记录都会记录这个文件做了哪些更新,以增量符号Δ(Delta)表示。 + +
+ +
+
+ +**我们怎样才能得到一个文件的最终版本呢?** + +很简单,高中数学的基本知识,我们只需要将这些原文件和这些增加进行相加就行了。 + +**这种方式有什么问题呢?** + +比如我们的增量特别特别多的话,如果我们要得到最终的文件是不是会耗费时间和性能。 + +Git 不按照以上方式对待或保存数据。 反之,Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 **快照流**。 + +
+ +
+
+ + +### Git 的三种状态 + +Git 有三种状态,你的文件可能处于其中之一: + +1. **已提交(committed)**:数据已经安全的保存在本地数据库中。 +2. **已修改(modified)**:已修改表示修改了文件,但还没保存到数据库中。 +3. **已暂存(staged)**:表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 + +由此引入 Git 项目的三个工作区域的概念:**Git 仓库(.git directoty) **、**工作目录(Working Directory)** 以及 **暂存区域(Staging Area)** 。 + +
+ +
+ +**基本的 Git 工作流程如下:** + +1. 在工作目录中修改文件。 +2. 暂存文件,将文件的快照放入暂存区域。 +3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。 + +## Git 使用快速入门 + +### 获取 Git 仓库 + +有两种取得 Git 项目仓库的方法。 + +1. 在现有目录中初始化仓库: 进入项目目录运行 `git init` 命令,该命令将创建一个名为 `.git` 的子目录。 +2. 从一个服务器克隆一个现有的 Git 仓库: `git clone [url]` 自定义本地仓库的名字: `git clone [url]` directoryname + +### 记录每次更新到仓库 + +1. **检测当前文件状态** : `git status` +2. **提出更改(把它们添加到暂存区**):`git add filename ` (针对特定文件)、`git add *`(所有文件)、`git add *.txt`(支持通配符,所有 .txt 文件) +3. **忽略文件**:`.gitignore` 文件 +4. **提交更新:** `git commit -m "代码提交信息"` (每次准备提交前,先用 `git status` 看下,是不是都已暂存起来了, 然后再运行提交命令 `git commit`) +5. **跳过使用暂存区域更新的方式** : `git commit -a -m "代码提交信息"`。 `git commit` 加上 `-a` 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 `git add` 步骤。 +6. **移除文件** :`git rm filename` (从暂存区域移除,然后提交。) +7. **对文件重命名** :`git mv README.md README`(这个命令相当于`mv README.md README`、`git rm README.md`、`git add README` 这三条命令的集合) + +### 推送改动到远程仓库 + +- 如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:·`git remote add origin ` ,比如我们要让本地的一个仓库和 Github 上创建的一个仓库关联可以这样`git remote add origin https://github.com/Snailclimb/test.git` +- 将这些改动提交到远端仓库:`git push origin master` (可以把 *master* 换成你想要推送的任何分支) + + 如此你就能够将你的改动推送到所添加的服务器上去了。 + +### 远程仓库的移除与重命名 + +- 将 test 重命名位 test1:`git remote rename test test1` +- 移除远程仓库 test1:`git remote rm test1` + +### 查看提交历史 + +在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 `git log` 命令。`git log` 会按提交时间列出所有的更新,最近的更新排在最上面。 + +**可以添加一些参数来查看自己希望看到的内容:** + +只看某个人的提交记录: + +```shell +git log --author=bob +``` + +### 撤销操作 + +有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 `--amend` 选项的提交命令尝试重新提交: + +```console +git commit --amend +``` + +取消暂存的文件 + +```console +git reset filename +``` + +撤消对文件的修改: + +``` +git checkout -- filename +``` + +假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它: + +``` +git fetch origin +git reset --hard origin/master +``` + + + +### 分支 + +分支是用来将特性开发绝缘开来的。在你创建仓库的时候,*master* 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。 + +我们通常在开发新功能、修复一个紧急 bug 等等时候会选择创建分支。单分支开发好还是多分支开发好,还是要看具体场景来说。 + +创建一个名字叫做 test 的分支 + +```console +git branch test +``` + +切换当前分支到 test(当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样) + +```console +git checkout test +``` + +
+ +
+ +你也可以直接这样创建分支并切换过去(上面两条命令的合写) + +```console +git checkout -b feature_x +``` + +切换到主分支 + +``` +git checkout master +``` + +合并分支(可能会有冲突) + +```java + git merge test +``` + +把新建的分支删掉 + +``` +git branch -d feature_x +``` + +将分支推送到远端仓库(推送成功后其他人可见): + +``` +git push origin +``` + + + +## 推荐阅读 + +- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html) +- [图解Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) +- [猴子都能懂得Git入门](https://backlog.com/git-tutorial/cn/intro/intro1_1.html) +- https://git-scm.com/book/en/v2 From ce29090d94f4443dcc883c0a22d58edf213ee82c Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 21 Mar 2019 11:57:18 +0800 Subject: [PATCH 167/232] =?UTF-8?q?Add=20=E5=BC=80=E5=8F=91=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=E5=B7=A5=E5=85=B7-Git?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 502e2013447..f69f12333ce 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ Java后端技术交流群(限工作一年及以上,群内有免费学习视频 * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) * [BATJ真实面经\(BATJ real interview experience\)](#batj真实面经batj-real-interview-experience) * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) +* [开发常用工具](#开发常用工具) + * [Git](#Git) * [闲谈](#闲谈) * [说明](#说明) @@ -202,6 +204,12 @@ Java后端技术交流群(限工作一年及以上,群内有免费学习视频 * [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) * [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) +## 开发常用工具 + +### Git + +* [Git入门看这一篇就够了](https://github.com/Snailclimb/JavaGuide/blob/master/DevelopCommonTools/GitIntroduce.md) + ## 闲谈 * [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) From e330aed6f4e5c83c539da85ca4bb91f21bbd98cd Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 21 Mar 2019 12:02:54 +0800 Subject: [PATCH 168/232] =?UTF-8?q?Fix=20=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...07\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" "b/\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" index 415661fdeaa..47ba541fb4d 100644 --- "a/\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" +++ "b/\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" @@ -24,7 +24,7 @@ ### 1. 你使用过哪些组件或者方法来提升网站性能,可用性以及并发量 1. **提高硬件能力、增加系统服务器**。(当服务器增加到某个程度的时候系统所能提供的并发访问量几乎不变,所以不能根本解决问题) -2. **使用缓存**(本地缓存:本地可以使用JDK自带的 Map、Guava Cache.分布式缓存:Redis、Memcache.本地缓存不适用于提高系统并发量,一般是用处用在程序中。比如Spring是如何实现单例的呢?大家如果看过源码的话,应该知道,Spiring把已经初始过的变量放在一个Map中,下次再要使用这个变量的时候,先判断Map中有没有,这也就是系统中常见的单例模式的实现。) +2. **使用缓存**(本地缓存:本地可以使用JDK自带的 Map、Guava Cache.分布式缓存:Redis、Memcache.本地缓存不适用于提高系统并发量,一般是用处用在程序中。比如Spring是如何实现单例的呢?大家如果看过源码的话,应该知道,S把已经初始过的变量放在一个Map中,下次再要使用这个变量的时候,先判断Map中有没有,这也就是系统中常见的单例模式的实现。) 3. **消息队列** (解耦+削峰+异步) 4. **采用分布式开发** (不同的服务部署在不同的机器节点上,并且一个服务也可以部署在多台机器上,然后利用 Nginx 负载均衡访问。这样就解决了单点部署(All In)的缺点,大大提高的系统并发量) 5. **数据库分库(读写分离)、分表(水平分表、垂直分表)** From bf5e0fc9817b842aab1f0dd062d0ba1b365ce4d1 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 21 Mar 2019 16:33:47 +0800 Subject: [PATCH 169/232] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index f69f12333ce..7cf0927a2b1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@

Java 学习/面试指南

- -Java后端技术交流群(限工作一年及以上,群内有免费学习视频和面试资料,**非本仓库作者本人的群**) :[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-869815609-red.svg)](https://jq.qq.com/?_wv=1027&k=5QqyxIx) -

From 848d328d457221bcb9e8688a2c2733548c4864be Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 09:48:05 +0800 Subject: [PATCH 170/232] =?UTF-8?q?Add=20Collections=E7=B1=BB=E5=92=8CArra?= =?UTF-8?q?ys=E7=B1=BB=E5=B8=B8=E8=A7=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Java/Basis/Arrays,CollectionsCommonMethods.md | 290 ++++++++++++++++++ ...tatic\343\200\201this\343\200\201super.md" | 0 2 files changed, 290 insertions(+) create mode 100644 Java/Basis/Arrays,CollectionsCommonMethods.md rename "Java/final\343\200\201static\343\200\201this\343\200\201super.md" => "Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" (100%) diff --git a/Java/Basis/Arrays,CollectionsCommonMethods.md b/Java/Basis/Arrays,CollectionsCommonMethods.md new file mode 100644 index 00000000000..492b656d056 --- /dev/null +++ b/Java/Basis/Arrays,CollectionsCommonMethods.md @@ -0,0 +1,290 @@ +# Collections 工具类和 Arrays 工具类常见方法 + +## Collections + +Collections 工具类常用方法: + +1. 排序 +2. 查找,替换操作 +3. 同步控制(不推荐,需要线程安全的集合类型时请考虑使用 JUC 包下的并发集合) + +### 排序操作 + +```java +void reverse(List list)//反转 +void shuffle(List list)//随机排序 +void sort(List list)//按自然排序的升序排序 +void sort(List list, Comparator c)//定制排序,由Comparator控制排序逻辑 +void swap(List list, int i , int j)//交换两个索引位置的元素 +void rotate(List list, int distance)//旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。 +``` + +**示例代码:** + +```java + ArrayList arrayList = new ArrayList(); + arrayList.add(-1); + arrayList.add(3); + arrayList.add(3); + arrayList.add(-5); + arrayList.add(7); + arrayList.add(4); + arrayList.add(-9); + arrayList.add(-7); + System.out.println("原始数组:"); + System.out.println(arrayList); + // void reverse(List list):反转 + Collections.reverse(arrayList); + System.out.println("Collections.reverse(arrayList):"); + System.out.println(arrayList); + + + Collections.rotate(arrayList, 4); + System.out.println("Collections.rotate(arrayList, 4):"); + System.out.println(arrayList); + + // void sort(List list),按自然排序的升序排序 + Collections.sort(arrayList); + System.out.println("Collections.sort(arrayList):"); + System.out.println(arrayList); + + // void shuffle(List list),随机排序 + Collections.shuffle(arrayList); + System.out.println("Collections.shuffle(arrayList):"); + System.out.println(arrayList); + + // 定制排序的用法 + Collections.sort(arrayList, new Comparator() { + + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + }); + System.out.println("定制排序后:"); + System.out.println(arrayList); +``` + +### 查找,替换操作 + +```java +int binarySearch(List list, Object key)//对List进行二分查找,返回索引,注意List必须是有序的 +int max(Collection coll)//根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll) +int max(Collection coll, Comparator c)//根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c) +void fill(List list, Object obj)//用指定的元素代替指定list中的所有元素。 +int frequency(Collection c, Object o)//统计元素出现次数 +int indexOfSubList(List list, List target)//统计targe在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target). +boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替换旧元素 +``` + +**示例代码:** + +```java + ArrayList arrayList = new ArrayList(); + arrayList.add(-1); + arrayList.add(3); + arrayList.add(3); + arrayList.add(-5); + arrayList.add(7); + arrayList.add(4); + arrayList.add(-9); + arrayList.add(-7); + ArrayList arrayList2 = new ArrayList(); + arrayList2.add(-3); + arrayList2.add(-5); + arrayList2.add(7); + System.out.println("原始数组:"); + System.out.println(arrayList); + + System.out.println("Collections.max(arrayList):"); + System.out.println(Collections.max(arrayList)); + + System.out.println("Collections.min(arrayList):"); + System.out.println(Collections.min(arrayList)); + + System.out.println("Collections.replaceAll(arrayList, 3, -3):"); + Collections.replaceAll(arrayList, 3, -3); + System.out.println(arrayList); + + System.out.println("Collections.frequency(arrayList, -3):"); + System.out.println(Collections.frequency(arrayList, -3)); + + System.out.println("Collections.indexOfSubList(arrayList, arrayList2):"); + System.out.println(Collections.indexOfSubList(arrayList, arrayList2)); + + System.out.println("Collections.binarySearch(arrayList, 7):"); + // 对List进行二分查找,返回索引,List必须是有序的 + Collections.sort(arrayList); + System.out.println(Collections.binarySearch(arrayList, 7)); +``` + +### 同步控制 + +Collectons提供了多个`synchronizedXxx()`方法·,该方法可以将指定集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题。 + +我们知道 HashSet,TreeSet,ArrayList,LinkedList,HashMap,TreeMap 都是线程不安全的。Collections提供了多个静态方法可以把他们包装成线程同步的集合。 + +**最好不要用下面这些方法,效率非常低,需要线程安全的集合类型时请考虑使用 JUC 包下的并发集合。** + +方法如下: + +```java +synchronizedCollection(Collection c) //返回指定 collection 支持的同步(线程安全的)collection。 +synchronizedList(List list)//返回指定列表支持的同步(线程安全的)List。 +synchronizedMap(Map m) //返回由指定映射支持的同步(线程安全的)Map。 +synchronizedSet(Set s) //返回指定 set 支持的同步(线程安全的)set。 +``` + +## Arrays类的常见操作 +1. 排序 : `sort()` +2. 查找 : `binarySearch()` +3. 比较: `equals()` +4. 填充 : `fill()` +5. 转列表: `asList()` +6. 转字符串 : `toString()` +7. + +### 排序 : `sort()` + +```java + // *************排序 sort**************** + int a[] = { 1, 3, 2, 7, 6, 5, 4, 9 }; + // sort(int[] a)方法按照数字顺序排列指定的数组。 + Arrays.sort(a); + System.out.println("Arrays.sort(a):"); + for (int i : a) { + System.out.print(i); + } + // 换行 + System.out.println(); + + // sort(int[] a,int fromIndex,int toIndex)按升序排列数组的指定范围 + int b[] = { 1, 3, 2, 7, 6, 5, 4, 9 }; + Arrays.sort(b, 2, 6); + System.out.println("Arrays.sort(b, 2, 6):"); + for (int i : b) { + System.out.print(i); + } + // 换行 + System.out.println(); + + int c[] = { 1, 3, 2, 7, 6, 5, 4, 9 }; + // parallelSort(int[] a) 按照数字顺序排列指定的数组。同sort方法一样也有按范围的排序 + Arrays.parallelSort(c); + System.out.println("Arrays.parallelSort(c):"); + for (int i : c) { + System.out.print(i); + } + // 换行 + System.out.println(); + + // parallelSort给字符数组排序,sort也可以 + char d[] = { 'a', 'f', 'b', 'c', 'e', 'A', 'C', 'B' }; + Arrays.parallelSort(d); + System.out.println("Arrays.parallelSort(d):"); + for (char d2 : d) { + System.out.print(d2); + } + // 换行 + System.out.println(); + +``` + +### 查找 : `binarySearch()` + +```java + // *************查找 binarySearch()**************** + char[] e = { 'a', 'f', 'b', 'c', 'e', 'A', 'C', 'B' }; + System.out.println("Arrays.binarySearch(e, 'c'):"); + int s = Arrays.binarySearch(e, 'c'); + System.out.println("字符c在数组的位置:" + s); +``` + +### 比较: `equals()` + +```java + // *************比较 equals**************** + char[] e = { 'a', 'f', 'b', 'c', 'e', 'A', 'C', 'B' }; + char[] f = { 'a', 'f', 'b', 'c', 'e', 'A', 'C', 'B' }; + /* + * 元素数量相同,并且相同位置的元素相同。 另外,如果两个数组引用都是null,则它们被认为是相等的 。 + */ + // 输出true + System.out.println("Arrays.equals(e, f):" + Arrays.equals(e, f)); +``` + +### 填充 : `fill()` + +```java + // *************填充fill(批量初始化)**************** + int[] g = { 1, 2, 3, 3, 3, 3, 6, 6, 6 }; + // 数组中所有元素重新分配值 + Arrays.fill(g, 3); + System.out.println("Arrays.fill(g, 3):"); + // 输出结果:333333333 + for (int i : g) { + System.out.print(i); + } + // 换行 + System.out.println(); + + int[] h = { 1, 2, 3, 3, 3, 3, 6, 6, 6, }; + // 数组中指定范围元素重新分配值 + Arrays.fill(h, 0, 2, 9); + System.out.println("Arrays.fill(h, 0, 2, 9);:"); + // 输出结果:993333666 + for (int i : h) { + System.out.print(i); + } +``` + +### 转列表 `asList()` + +```java + // *************转列表 asList()**************** + /* + * 返回由指定数组支持的固定大小的列表。 + * (将返回的列表更改为“写入数组”。)该方法作为基于数组和基于集合的API之间的桥梁,与Collection.toArray()相结合 。 + * 返回的列表是可序列化的,并实现RandomAccess 。 + * 此方法还提供了一种方便的方式来创建一个初始化为包含几个元素的固定大小的列表如下: + */ + List stooges = Arrays.asList("Larry", "Moe", "Curly"); + System.out.println(stooges); +``` + +### 转字符串 `toString()` + +```java + // *************转字符串 toString()**************** + /* + * 返回指定数组的内容的字符串表示形式。 + */ + char[] k = { 'a', 'f', 'b', 'c', 'e', 'A', 'C', 'B' }; + System.out.println(Arrays.toString(k));// [a, f, b, c, e, A, C, B] +``` + +### 复制 `copyOf()` + +```java + // *************复制 copy**************** + // copyOf 方法实现数组复制,h为数组,6为复制的长度 + int[] h = { 1, 2, 3, 3, 3, 3, 6, 6, 6, }; + int i[] = Arrays.copyOf(h, 6); + System.out.println("Arrays.copyOf(h, 6);:"); + // 输出结果:993333 + for (int j : i) { + System.out.print(j); + } + // 换行 + System.out.println(); + // copyOfRange将指定数组的指定范围复制到新数组中 + int j[] = Arrays.copyOfRange(h, 6, 11); + System.out.println("Arrays.copyOfRange(h, 6, 11):"); + // 输出结果66600(h数组只有9个元素这里是从索引6到索引11复制所以不足的就为0) + for (int j2 : j) { + System.out.print(j2); + } + // 换行 + System.out.println(); +``` + diff --git "a/Java/final\343\200\201static\343\200\201this\343\200\201super.md" "b/Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" similarity index 100% rename from "Java/final\343\200\201static\343\200\201this\343\200\201super.md" rename to "Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" From e56245b5e4bca156f4515f0bda951aa8158df32d Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 09:50:35 +0800 Subject: [PATCH 171/232] =?UTF-8?q?Add=20Collections=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=E5=92=8CArrays=E5=B7=A5=E5=85=B7=E7=B1=BB=E5=B8=B8?= =?UTF-8?q?=E8=A7=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cf0927a2b1..9fd9d3a5ea9 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ * [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) * [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) -* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/final、static、this、super.md) +* [Collections 工具类和 Arrays 工具类常见方法](https://github.com/Snailclimb/JavaGuide/blob/master/Java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Basis/final、static、this、super.md) ### 集合框架 From f748cfd355ef19825846b383a025175f73832c0e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 09:51:36 +0800 Subject: [PATCH 172/232] =?UTF-8?q?Add=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Java/Basis/Arrays,CollectionsCommonMethods.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Java/Basis/Arrays,CollectionsCommonMethods.md b/Java/Basis/Arrays,CollectionsCommonMethods.md index 492b656d056..140b6f050dd 100644 --- a/Java/Basis/Arrays,CollectionsCommonMethods.md +++ b/Java/Basis/Arrays,CollectionsCommonMethods.md @@ -1,3 +1,20 @@ + + +- [Collections 工具类和 Arrays 工具类常见方法](#collections-工具类和-arrays-工具类常见方法) + - [Collections](#collections) + - [排序操作](#排序操作) + - [查找,替换操作](#查找替换操作) + - [同步控制](#同步控制) + - [Arrays类的常见操作](#arrays类的常见操作) + - [排序 : `sort()`](#排序--sort) + - [查找 : `binarySearch()`](#查找--binarysearch) + - [比较: `equals()`](#比较-equals) + - [填充 : `fill()`](#填充--fill) + - [转列表 `asList()`](#转列表-aslist) + - [转字符串 `toString()`](#转字符串-tostring) + - [复制 `copyOf()`](#复制-copyof) + + # Collections 工具类和 Arrays 工具类常见方法 ## Collections From 19a0f088cd7d28ec7f33738bb60390aa3b415fbc Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 10:03:31 +0800 Subject: [PATCH 173/232] Update Arrays,CollectionsCommonMethods.md --- Java/Basis/Arrays,CollectionsCommonMethods.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Java/Basis/Arrays,CollectionsCommonMethods.md b/Java/Basis/Arrays,CollectionsCommonMethods.md index 140b6f050dd..5c7e705bac5 100644 --- a/Java/Basis/Arrays,CollectionsCommonMethods.md +++ b/Java/Basis/Arrays,CollectionsCommonMethods.md @@ -207,6 +207,14 @@ synchronizedSet(Set s) //返回指定 set 支持的同步(线程安全的 ``` +在做算法面试题的时候,我们还可能会经常遇到对字符串排序的情况,`Arrays.sort()` 对每个字符串的特定位置进行比较,然后按照升序排序。 + +```java +String[] strs = { "abcdehg", "abcdefg", "abcdeag" }; +Arrays.sort(strs); +System.out.println(Arrays.toString(strs));//[abcdeag, abcdefg, abcdehg] +``` + ### 查找 : `binarySearch()` ```java From 58e7c224b274386fdce62c3152262073068a924b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 14:47:29 +0800 Subject: [PATCH 174/232] =?UTF-8?q?Update=20=E5=B0=86=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=96=87=E7=AB=A0=E7=9A=84=E8=B7=AF=E5=BE=84=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 140 +++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 9fd9d3a5ea9..285cc555f42 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,10 @@ ## ToDoList(待办清单) -* [x] [Java 8 新特性总结](https://github.com/Snailclimb/JavaGuide/blob/master/Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) * [ ] Java 8 新特性详解 * [ ] Java 多线程类别知识重构 -* [x] [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java/BIO%2CNIO%2CAIO%20summary.md) +* [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) * [ ] Netty 总结 * [ ] 数据结构总结重构 @@ -67,153 +67,153 @@ ### 基础 -* [Java 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java基础知识.md) -* [J2EE 基础知识回顾](https://github.com/Snailclimb/Java-Guide/blob/master/Java/J2EE基础知识.md) -* [Collections 工具类和 Arrays 工具类常见方法](https://github.com/Snailclimb/JavaGuide/blob/master/Java/Basis/Arrays%2CCollectionsCommonMethods.md) -* [Java常见关键字总结:static、final、this、super](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Basis/final、static、this、super.md) +* [Java 基础知识回顾](./Java/Java基础知识.md) +* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) +* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) ### 集合框架 * **常见问题总结:** - * [这几道Java集合框架面试题几乎必问](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) - * [Java 集合框架常见面试题总结](https://github.com/Snailclimb/Java-Guide/blob/master/Java/Java集合框架常见面试题总结.md) + * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) * **源码分析:** - * [ArrayList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/ArrayList.md) - * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](https://github.com/Snailclimb/JavaGuide/blob/master/Java/ArrayList-Grow.md) - * [LinkedList 源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/LinkedList.md) - * [HashMap(JDK1.8)源码学习](https://github.com/Snailclimb/Java-Guide/blob/master/Java/HashMap.md) + * [ArrayList 源码学习](./Java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) + * [LinkedList 源码学习](./Java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) ### 多线程 -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://github.com/Snailclimb/Java_Guide/blob/master/Java/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Multithread/并发容器总结.md) +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](./Java/Multithread/并发容器总结.md) ### JVM -* [可能是把Java内存区域讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/Java/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java虚拟机(jvm).md) +* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) ### BIO,NIO,AIO -* [BIO,NIO,AIO 总结 ](https://github.com/Snailclimb/JavaGuide/blob/master/Java/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/Java%20IO与NIO.md) +* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) ### Java8 New Features -* [Java 8 新特性总结](https://github.com/Snailclimb/JavaGuide/blob/master/Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) ### 设计模式 -* [设计模式系列文章](https://github.com/Snailclimb/Java_Guide/blob/master/Java/设计模式.md) +* [设计模式系列文章](./Java/设计模式.md) ## 数据结构与算法 ### 数据结构 -* [数据结构知识学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/数据结构.md) +* [数据结构知识学习与面试](./数据结构与算法/数据结构.md) ### 算法 -* [算法学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/算法.md) -* [常见安全算法(MD5、SHA1、Base64等等)总结](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) -* [算法总结——几道常见的子符串算法题 ](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) -* [算法总结——几道常见的链表算法题 ](https://github.com/Snailclimb/Java_Guide/blob/master/数据结构与算法/Leetcode-LinkList1.md) +* [算法学习与面试](./数据结构与算法/算法.md) +* [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) +* [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) +* [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) ## 计算机网络与数据通信 ### 网络相关 -* [计算机网络常见面试题](https://github.com/Snailclimb/Java_Guide/blob/master/计算机网络与数据通信/计算机网络.md) -* [计算机网络基础知识总结](https://github.com/Snailclimb/Java_Guide/blob/master/计算机网络与数据通信/干货:计算机网络知识总结.md) -* [HTTPS中的TLS](https://github.com/Snailclimb/Java_Guide/blob/master/计算机网络与数据通信/HTTPS中的TLS.md) +* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) +* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) +* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) ### 数据通信(RESTful,RPC,消息队列)总结 -* [数据通信(RESTful、RPC、消息队列)相关知识点总结](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) -* [Dubbo 总结:关于 Dubbo 的重要知识点](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/dubbo.md) -* [消息队列总结:新手也能看懂,消息队列其实很简单](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/message-queue.md) -* [一文搞懂 RabbitMQ 的重要概念以及安装](https://github.com/Snailclimb/Java-Guide/blob/master/计算机网络与数据通信/rabbitmq.md) +* [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) +* [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) +* [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) +* [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) ## 操作系统 ### Linux相关 -* [后端程序员必备的 Linux 基础知识](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/后端程序员必备的Linux基础知识.md) -* [Shell 编程入门](https://github.com/Snailclimb/Java-Guide/blob/master/操作系统/Shell.md) +* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) +* [Shell 编程入门](./操作系统/Shell.md) ## 主流框架 ### Spring -* [Spring 学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/Spring学习与面试.md) -* [Spring中bean的作用域与生命周期](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/SpringBean.md) -* [SpringMVC 工作原理详解](https://github.com/Snailclimb/JavaGuide/blob/master/主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) +* [Spring 学习与面试](./主流框架/Spring学习与面试.md) +* [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) +* [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) ### ZooKeeper -* [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/ZooKeeper.md) -* [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](https://github.com/Snailclimb/Java_Guide/blob/master/主流框架/ZooKeeper数据模型和常见命令.md) +* [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) +* [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) ## 数据存储 ### MySQL -* [MySQL 学习与面试](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL.md) -* [【思维导图-索引篇】搞定数据库索引就是这么简单](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/MySQL%20Index.md) -* [一千行MySQL学习笔记](https://github.com/Snailclimb/JavaGuide/blob/master/数据存储/一千行MySQL命令.md) +* [MySQL 学习与面试](./数据存储/MySQL.md) +* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) +* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) ### Redis -* [Redis 总结](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/Redis/Redis.md) -* [Redlock分布式锁](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/Redis/Redlock分布式锁.md) -* [如何做可靠的分布式锁,Redlock真的可行么](https://github.com/Snailclimb/Java_Guide/blob/master/数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) +* [Redis 总结](./数据存储/Redis/Redis.md) +* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) +* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) ## 架构 -* [一文读懂分布式应该学什么](https://github.com/Snailclimb/Java_Guide/blob/master/架构/分布式.md) -* [8 张图读懂大型网站技术架构](https://github.com/Snailclimb/JavaGuide/blob/master/架构/8%20张图读懂大型网站技术架构.md) -* [【面试精选】关于大型网站系统架构你不得不懂的10个问题](https://github.com/Snailclimb/JavaGuide/blob/master/架构/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) +* [一文读懂分布式应该学什么](./架构/分布式.md) +* [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) +* [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) ## 面试必备(Essential content for the interview) ### 备战面试(Preparing for an interview) -* [【备战面试1】程序员的简历就该这样写](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) -* [【备战面试2】初出茅庐的程序员该如何准备面试?](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) -* [【备战面试3】7个大部分程序员在面试前很关心的问题](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) -* [【备战面试4】Java程序员必备书单](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/books.md) -* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) -* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) -* [【备战面试7】美团面试常见问题总结(附详解答案)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) ### BATJ真实面经(BATJ real interview experience) -* [5面阿里,终获offer(2018年秋招)](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) +* [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) ### 最常见的Java面试题总结(Summary of the most common Java interview questions) -* [第一周(2018-8-7)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) -* [第二周(2018-8-13)](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) -* [第三周(2018-08-22)](https://github.com/Snailclimb/Java-Guide/blob/master/Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) -* [第四周(2018-8-30).md](https://github.com/Snailclimb/Java-Guide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) +* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) ## 开发常用工具 ### Git -* [Git入门看这一篇就够了](https://github.com/Snailclimb/JavaGuide/blob/master/DevelopCommonTools/GitIntroduce.md) +* [Git入门看这一篇就够了](./DevelopCommonTools/GitIntroduce.md) ## 闲谈 -* [选择技术方向都要考虑哪些因素](https://github.com/Snailclimb/Java-Guide/blob/master/闲谈/选择技术方向都要考虑哪些因素.md) -* [结束了我短暂的秋招,说点自己的感受](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [【2018总结】即使平凡,也要热爱自己的生活](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/2018%20summary.md) -* [Java项目 Github Trending 月榜](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/JavaGithubTrending.md) +* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) +* [【2018总结】即使平凡,也要热爱自己的生活](./闲谈/2018%20summary.md) +* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) *** From f1ece6174eb9ba99a685bc688307fd1cd49aac09 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 15:21:28 +0800 Subject: [PATCH 175/232] =?UTF-8?q?Add=20=E7=A0=81=E4=BA=91=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 285cc555f42..804627e5f1a 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,21 @@

Java 学习/面试指南

-
+ +

-
-

+

+ +

+ 码云地址 + 公众号 +

Special Sponsors

-
+ +

-
-

+

## 阅读之前必看 From e8002413b0bfadc96284805cc456e9ccb24706ff Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 15:23:42 +0800 Subject: [PATCH 176/232] =?UTF-8?q?Update=20=E7=A0=81=E4=BA=91=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 804627e5f1a..cee6caef493 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- 码云地址 + 码云地址 公众号

From 43f52bf5772223bd1cc1dad2ed0feb6957b8fb27 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 15:35:27 +0800 Subject: [PATCH 177/232] =?UTF-8?q?Add=20=E5=BE=AE=E4=BF=A1=E7=BE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cee6caef493..eb88debaf72 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@

+ 微信群 码云地址 公众号

@@ -19,11 +20,10 @@ ## 阅读之前必看 -1. **加群:** 微信交流群添加 [我的微信](#联系我) 后回复关键字“加群”即可入群。 -2. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 -3. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! -4. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 -5. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 +1. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 +1. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! +1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 +1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 ## 目录 @@ -248,7 +248,7 @@ ### 联系我 -如果大家需要与我交流,可以扫描下方二维码添加我的微信获取关注[我的公众号](#公众号): +添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。 ![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) From 9128fadaf58dd21116a5c0f25f84f49426f46b23 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 15:44:46 +0800 Subject: [PATCH 178/232] =?UTF-8?q?Add=20PDF-Java=E9=9D=A2=E8=AF=95?= =?UTF-8?q?=E7=AA=81=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eb88debaf72..0c48ca35fbd 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ 微信群 码云地址 公众号 + 公众号 +

Special Sponsors

@@ -18,10 +20,7 @@

-## 阅读之前必看 -1. **Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 -1. **《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! 1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 @@ -290,4 +289,8 @@ 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 +**《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! + +**Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 + ![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334) From 22cfe972eb0097400fc533eccc7e22bf1d39ddc2 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 15:48:40 +0800 Subject: [PATCH 179/232] =?UTF-8?q?Update=20=E7=A0=81=E4=BA=91=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c48ca35fbd..643bfcd0c93 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@

+1. **码云地址:** 如果访问速度比较慢的话,可以考虑访问本仓库的码云地址: ,Gitee 和 都是同步更新的。 1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 From 37b4092c5c294fd18eac13f8a8ef180b5cd97838 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 16:25:44 +0800 Subject: [PATCH 180/232] =?UTF-8?q?Fix=20=E5=BE=AE=E4=BF=A1=E7=BE=A4?= =?UTF-8?q?=E9=93=BE=E6=8E=A5=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 643bfcd0c93..26366a59f70 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- 微信群 + 微信群 码云地址 公众号 公众号 From 17f7a9e98cb09b40756e225d5064355426d925ce Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 20:33:30 +0800 Subject: [PATCH 181/232] =?UTF-8?q?Delete=202018=E5=B9=B4=E6=80=BB?= =?UTF-8?q?=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 26366a59f70..b7592ac4da2 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,6 @@ * [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) * [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [【2018总结】即使平凡,也要热爱自己的生活](./闲谈/2018%20summary.md) * [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) *** From 53648bbb2b2b00c0ba867d045d3cce086cf55e72 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Fri, 22 Mar 2019 20:34:52 +0800 Subject: [PATCH 182/232] Delete 2018 summary.md --- "\351\227\262\350\260\210/2018 summary.md" | 174 --------------------- 1 file changed, 174 deletions(-) delete mode 100644 "\351\227\262\350\260\210/2018 summary.md" diff --git "a/\351\227\262\350\260\210/2018 summary.md" "b/\351\227\262\350\260\210/2018 summary.md" deleted file mode 100644 index 8d82e40b876..00000000000 --- "a/\351\227\262\350\260\210/2018 summary.md" +++ /dev/null @@ -1,174 +0,0 @@ -# 【2018总结】即使平凡,也要热爱自己的生活 - -2018 年于我而讲,虽然平凡,但是自己就是在这平凡的一年也收货了很多东西。不光是自己学到的知识,我觉得 2018 年最大的幸运有三:其一是自己拥有了一份爱情,一份甜蜜的初恋,我真的很幸运遇到我现在的女朋友,愿以后的日子都能有她;其一是在 2018 年,我拥有了一份自己还算满意的 offer,马上就要毕业了,自己也要正式进去社会了;其一是自己在 2018 年的实现了自己的经济独立,这是一件让我很高兴的事情,我觉得大在学生时代实现经济独立还算是一件很不错的事情,花了这么多年父母的辛苦钱,自己也终于能替他们分担一点了。2018 年,感恩父母,感恩老师,感恩朋友,感恩遇到的每个善良的人,同时感恩2018年那个还算努力的自己。2019 继续加油! - -## 一份甜蜜的初恋(分手) - -先说说爱情。我和我的女朋友在一起已经半年多了,准确的来说截止到今天也就是 2018-12-30 号已经 190 天了。 - -![我和傻欢](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/54482393.jpg) - -我俩是异地,我在荆州,她在三亚。相见一面不管是时间上还是经济上对于还是学生的我们来说都甚是不易。见过很多人议论异地恋的种种不好,但是,于我而言,一份好的感情是值得被等待的。“待每一天如初恋,互相尊重彼此生活,共同努力,等老了就退隐山林养老......”,这应该是我和她之间最好的承诺了。 - -## 还算不错的学习收获 - -再来说说学习。这一年还算是让人满意,虽然我也不知道这一年自己到底学到了什么。如果你要问我这一年在学习上做的最满意的事情是什么,我还真不好回答,下面就从下面几个维度来简单谈一谈。 - -### 开源 - -这一年自己在Github上还是挺活跃的,提交了很多的代码和文档,同时也收获了很多的star、follower、pr、issue以及fork。 - -![我的Github概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/41250517.jpg) - -![我的Github贡献概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/33580466.jpg) - -开源的Java学习/面试指南—JavaGuide 某种程度上让我挺满意的,3月份开源 ,到现在的18k+ star 也算是可以用厚积薄发来形容了。但是,JavaGuide 也有很多让我不满意的,在2019年以及以后我也会继续完善。JavaGuide 地址:[https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) - -![JavaGuide 概览](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-24/1352784.jpg) - -### 技术博客 - -我更新的博客主要都是关于Java方面的,也更新了几篇Python的,有一篇Python的文章竟然在我的CSDN上面阅读霸榜。 -![霸榜的 Python 文章](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-12-30/19527688.jpg) - -在这一年,我更新了挺多技术文章,这里就不一一列举了,我贴一下自己觉得不错的文章吧! - -#### 最常见面试题系列 - -- [最最最常见的Java面试题总结——第一周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484252&idx=1&sn=cb160d67fc1c0a95babc464b703df5e7&chksm=fd98553dcaefdc2b18f934957dd950aeaf04e90136099fa2817fffbd1e1df452b581e1caee17&token=1398134989&lang=zh_CN#rd) -- [最最最常见的Java面试题总结——第二周](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484282&idx=1&sn=7f986dc3263b6ca0f9e182145fdd40a1&chksm=fd98551bcaefdc0d5aff9577692881dc79765a339ce97e55958e23e1956aa7092dfac44b68f1&token=1398134989&lang=zh_CN#rd) -- [这几道Java集合框架面试题在面试中几乎必问](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484308&idx=1&sn=e3607919aed604be629617f867f46844&chksm=fd9855f5caefdce3f1ee72cb33b9b3bf9899fa2b64bbb92f1e820c0ef3985245b1f7dfc05358&token=1398134989&lang=zh_CN#rd) -- [如果不会这几道多线程基础题,请自觉面壁!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484337&idx=1&sn=d5e953d4b2da7ed37a7f843bfb437ed8&chksm=fd9855d0caefdcc65cb2e5cc0c69d27f785fc41477bcf55fff2cdff3268b0b078eb1a5107726&token=1398134989&lang=zh_CN#rd) -- [值得立马保存的 synchronized 关键字总结](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484355&idx=1&sn=6da29974b6dd1a4aa0d032f44d5fa8de&chksm=fd9855a2caefdcb4c370814baafd4baca27dfccaf609c9edf82370637ba4856176ab143a375e&token=1398134989&lang=zh_CN#rd) -- [【面试必备】源码角度一步一步分析 ArrayList 扩容机制](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=1&sn=1b6155015fedfc9f78fabecc18da7b18&chksm=fd985591caefdc870cb018d27f92e1908b6c6e22816a77ead03c4e44b2f53caec00871172b1f&token=1398134989&lang=zh_CN#rd) -- [Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&token=1398134989&lang=zh_CN#rd) - -#### Github - -- [近几个月Github上最热门的Java项目一览](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484188&idx=1&sn=40037de4844f62316465bbe4e910c69c&chksm=fd98557dcaefdc6bedcaeb275aae7c340d46cf6ab0dc96e49c51982f9c53d6a44de283efc9a8&token=1398134989&lang=zh_CN#rd) -- [推荐10个Java方向最热门的开源项目(8月)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484333&idx=1&sn=8c97b029692877a537d55175a8c82977&chksm=fd9855cccaefdcdaffe0558ba5e8dca415495935b0ad1181e6b148b08e1c86ce5d841e9df901&token=1398134989&lang=zh_CN#rd) -- [Github上 Star 数相加超过 7w+ 的三个面试相关的仓库推荐](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484644&idx=1&sn=5016caaf97e498b76de2189e3f55e9dc&chksm=fd985285caefdb93f4e3c7545d30edac6ad31b99f1fcc4503350101f0b20bba9a9705ed7d124&token=1398134989&lang=zh_CN#rd) -- [11月 Github Trending 榜最热门的 10 个 Java 项目](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=1&sn=86e35dfea1478221b6d14a263e88ac89&chksm=fd98535bcaefda4d4f03bf0cd2e0a8fd9f44b1a2b118457a0c8b3de2ff8a1f4c4b7cd083f40e&token=1398134989&lang=zh_CN#rd) -- [盘点一下Github上开源的Java面试/学习相关的仓库,看完弄懂薪资至少增加10k](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484817&idx=1&sn=12f0c254a240c40c2ccab8314653216b&chksm=fd9853f0caefdae6d191e6bf085d44ab9c73f165e3323aa0362d830e420ccbfad93aa5901021&token=1398134989&lang=zh_CN#rd) - - -#### 备战面试系列 - -- [可能是一份最适合你的后端面试指南(部分内容前端同样适用)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484529&idx=1&sn=9c7a3d6ad124affcadc19b0ff49bf68a&chksm=fd985210caefdb0615a9643fa698cb6267e89562730423841d942cde17ec9c1280dfc3a2b933&token=1398134989&lang=zh_CN#rd) -- [【备战春招/秋招系列1】程序员的简历就该这样写](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484573&idx=1&sn=8c5965d4a3710d405d8e8cc10c7b0ce5&chksm=fd9852fccaefdbea8dfe0bc40188b7579f1cddb1e8905dc981669a3f21d2a04cadceafa9023f&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列2】初出茅庐的程序员该如何准备面试?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484578&idx=1&sn=eea72d80a2325257f00aaed21d5b226f&chksm=fd9852c3caefdbd52dd8a537cc723ed1509314401b3a669a253ef5bc0360b6fddef48b9c2e94&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列3】Java程序员必备书单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484592&idx=1&sn=6d9731ce7401be49e97c1af6ed384ecc&chksm=fd9852d1caefdbc720a361ae65a8ad9d53cfb4800b15a7c68cbdc630b313215c6c52e0934ec2&token=1990180468&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团面经总结基础篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484601&idx=1&sn=4907b7fef0856791c565d49d788ba8cc&chksm=fd9852d8caefdbce88e51c0a10a4ec77c97f382fd2af4a840ea47cffc828bfd0f993f50d5f0d&token=1895808268&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团面经总结进阶篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484625&idx=1&sn=9c4fa1f7d4291a5fbd7daa44bac2b012&chksm=fd9852b0caefdba6edcf9a827aa4a17ddc97bf6ad2e5ee6f7e1aa1b443b54444d05d2b76732b&token=1895808268&lang=zh_CN#rd) -- [【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484668&idx=1&sn=9d4631588393075d9c453f307410f0cd&chksm=fd98529dcaefdb8b5497d1f161834af6917c33ea3d305eb41872e522707fa94218769ca60101&token=1398134989&lang=zh_CN#rd) -- [GitHub 上四万 Star 大佬的求职回忆](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484739&idx=1&sn=25cf5b36090f69299150663bdccfeec2&chksm=fd985322caefda34df0734efa607114704d1937f083aee2230b797d1f5aa04f7d13bf2f81dc5&token=1398134989&lang=zh_CN#rd)(非原创) - - -#### 并发编程面试必备 - -- [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484539&idx=1&sn=3500cdcd5188bdc253fb19a1bfa805e6&chksm=fd98521acaefdb0c5167247a1fa903a1a53bb4e050b558da574f894f9feda5378ec9d0fa1ac7&scene=21#wechat_redirect) -- [并发编程面试必备:JUC 中的 Atomic 原子类总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484553&idx=1&sn=aca9fa19f723206eff7e33a10973a887&chksm=fd9852e8caefdbfe7180c34f83bbb422a1a0bef1ed44b1e84f56924244ea3fd2da720f25c6dd#rd) -- [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](http://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484559&idx=1&sn=28dae85c38c4c500201c39234d25d731&chksm=fd9852eecaefdbf80cc54a25204e7c7d81170ce659acf92b7fa4151799ca3d0d7df2225d4ff1#rd) -- [并发编程面试必备:BATJ都爱问的多线程面试题](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484564&idx=1&sn=d8467fdc5c1b3883e9b99485f7b0fb9a&chksm=fd9852f5caefdbe364d1c438865cff84acd8f40c1c9e2f9f5c8fef673b30f905b4c5f5255368&token=1398134989&lang=zh_CN#rd) - -#### 虚拟机 - -- [可能是把Java内存区域讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484303&idx=1&sn=af0fd436cef755463f59ee4dd0720cbd&chksm=fd9855eecaefdcf8d94ac581cfda4e16c8a730bda60c3b50bc55c124b92f23b6217f7f8e58d5&token=1398134989&lang=zh_CN#rd) -- [搞定 JVM 垃圾回收就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484328&idx=1&sn=214f5e18a6afa096eb552fd8627e0cea&chksm=fd9855c9caefdcdf70c746c74d31f65bbb109eedaea0cfe311a1e10af666047df59ff04c873b&token=1398134989&lang=zh_CN#rd) - -#### Spring Boot - -- [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个简单的分布式服务](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484706&idx=1&sn=d413fc17023482f67ca17cb6756b9ff8&chksm=fd985343caefda555969568fdf4734536e0a1745f9de337d434a7dbd04e893bd2d75f3641aab&token=1398134989&lang=zh_CN#rd) -- [基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484730&idx=2&sn=9be4636dd9a416b46f9029df68fad232&chksm=fd98535bcaefda4dccf14a286a24fcd2b3d4ab0d0e4d89dfbc955df99d2b06a1e17392b3c10b&token=1398134989&lang=zh_CN#rd) -- [新手也能实现,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484737&idx=1&sn=e39693d845f022d689437ee58948ef6a&chksm=fd985320caefda36d5ab8abd52f5516c11cc5d1104608695bcea5909602b28dc40c132d6d46c&token=1398134989&lang=zh_CN#rd) -- [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484745&idx=1&sn=dbeec694916d204605929244d48a6b1c&chksm=fd985328caefda3e793170d81433c7c0b7dc1c4a4ae99395cce23b1d1a239482fd5bf1d89bc6&token=1398134989&lang=zh_CN#rd) - -#### 成长 - -- [结束了我短暂的秋招,说点自己的感受](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484516&idx=1&sn=4e2320613e76dd73a130c63beebbc3ca&chksm=fd985205caefdb13b4b611ed3c604d95314d28d567ec0c3b44585b89a7dc3142bcd52bc2d4cb&token=1398134989&lang=zh_CN#rd) -- [保研之路:从双非到南大](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484477&idx=1&sn=3b597e2431611aacca2b5d671a309d85&chksm=fd98525ccaefdb4a7e3742b5958244d453efe26f61f42f9f108190a0c18313f083189f10944e&token=1398134989&lang=zh_CN#rd)(非原创) -- [【周日闲谈】最近想说的几件小事](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484650&idx=1&sn=e97ea1eeebdb5def58bae1949bec9448&chksm=fd98528bcaefdb9d76ac62fd10544f058b1fee4a40ffd06ab9312b7eb3a62f86d67ea653b88a&token=1398134989&lang=zh_CN#rd) -- [这7个问题,可能大部分Java程序员都比较关心吧!](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484836&idx=1&sn=a6ada99c9506af01dc3bb472f66c57be&chksm=fd9853c5caefdad3034dbed00cf04412ea990fc05b6168720e6828ae6c90c9a885793acd7a14&token=1398134989&lang=zh_CN#rd) - -#### Docker - -- [可能是把Docker的概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484127&idx=1&sn=70ee95619ec761da884c4f9af3e83194&chksm=fd9854becaefdda81a02bf6cf9bd07a2fc879efa7cefc79691a0d319b501d8572e8bad981d87&token=1398134989&lang=zh_CN#rd) - -#### Linux - -- [后端程序员必备的Linux基础知识](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484157&idx=1&sn=8b47e623e83fb3666bce7c680e4649b8&chksm=fd98549ccaefdd8ad815f3d8eaca86cc7e7245b4f8de1d23897af3017f5fdb3f152734c40f5e&token=1398134989&lang=zh_CN#rd) -- [快速入门大厂后端面试必备的 Shell 编程](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484696&idx=1&sn=d3c1ba5abc10c10ff844cae2109a2628&chksm=fd985379caefda6faff8e050b7dfa1e92fbfe2912e44150cb4ae349aea807836166355062970&token=1398134989&lang=zh_CN#rd) - -#### ZooKeeper - -- [可能是全网把 ZooKeeper 概念讲的最清楚的一篇文章](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484379&idx=1&sn=036f5d3defa8a6979afb77acc82a9517&chksm=fd9855bacaefdcacc1462f781b634e5599f2ee9e806bd24297dae4af0e4196a70ca6bbd8c354&token=1398134989&lang=zh_CN#rd) - -#### Redis - -- [redis 总结——重构版](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484450&idx=1&sn=7ee03fa67aecd05c5becd2a8259d3631&chksm=fd985243caefdb554ebab9149e750ac0c819074c57bd208f2d7f097fbc461ed58223e71c05f1&token=1398134989&lang=zh_CN#rd) -- [史上最全Redis高可用技术解决方案大全](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484478&idx=1&sn=a1250d9b8025cd7cb6fc6a58238ab51e&chksm=fd98525fcaefdb499a027df0138c98d4b02d828f27bd6144a4d40a1c088d340c29dd53d4a026&token=1398134989&lang=zh_CN#rd)(非原创) - -#### 计算机网络 - -- [搞定计算机网络面试,看这篇就够了(补充版)](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484289&idx=1&sn=6b556843c60aac9a17b0e7c2e3cd6bca&chksm=fd9855e0caefdcf6af4123b719448c81d90c5442d4052ae01a4698047e226c0c18c14b2cc54a&token=1398134989&lang=zh_CN#rd) - -#### 数据库 - -- [【思维导图-索引篇】搞定数据库索引就是这么简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484486&idx=1&sn=215450f11e042bca8a58eac9f4a97686&chksm=fd985227caefdb3117b8375f150676f5824aa20d1ebfdbcfb93ff06e23e26efbafae6cf6b48e&token=1398134989&lang=zh_CN#rd) - -#### 消息队列 - -- [新手也能看懂,消息队列其实很简单](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484789&idx=1&sn=ba972f0aac39e9a28b29ddf92fc15c18&chksm=fd985314caefda0278235427d43846b6374ff32f4149352dec063287cbf9733b888acbb79923&token=1398134989&lang=zh_CN#rd) -- [一文搞懂 RabbitMQ 的重要概念以及安装](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484796&idx=1&sn=bc56fecb634732669cfe7db8d1820ded&chksm=fd98531dcaefda0b07b8a9c13429ef225d36a6e287c96c53d7aa3dfd65c62ccd60d13b22ebbf&token=1398134989&lang=zh_CN#rd) - -### 读书 - -推荐一下 2018 年看过的书籍,小部分可能2017年也看过一些。 - -#### 已看完 - -- [《图解HTTP》](https://book.douban.com/subject/25863515/)(推荐,豆瓣评分 8.1 , 1.6K+人评价): 讲漫画一样的讲HTTP,很有意思,不会觉得枯燥,大概也涵盖也HTTP常见的知识点。因为篇幅问题,内容可能不太全面。不过,如果不是专门做网络方向研究的小伙伴想研究HTTP相关知识的话,读这本书的话应该来说就差不多了。 -- [《大话数据结构》](https://book.douban.com/subject/6424904/)(推荐,豆瓣评分 7.9 , 1K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有数据结构基础或者说数据结构没学好的小伙伴用来入门数据结构。 -- [《算法图解》](https://book.douban.com/subject/26979890/)(推荐,豆瓣评分 8.4,0.6K+人评价):入门类型的书籍,读起来比较浅显易懂,适合没有算法基础或者说算法没学好的小伙伴用来入门。示例丰富,图文并茂,以让人容易理解的方式阐释了算法.读起来比较快,内容不枯燥! -- [《Java并发编程的艺术》](https://book.douban.com/subject/26591326/)(推荐,豆瓣评分 7.2,0.2K+人评价): 这本书不是很适合作为Java并发入门书籍,需要具备一定的JVM基础。我感觉有些东西讲的还是挺深入的,推荐阅读。 -- [《实战Java高并发程序设计》](https://book.douban.com/subject/26663605/)(推荐):豆瓣评分 8.3 ,书的质量没的说,推荐大家好好看一下。 -- [《深入理解Java虚拟机(第2版)周志明》](https://book.douban.com/subject/24722612/)(推荐,豆瓣评分 8.9,1.0K+人评价):建议多刷几遍,书中的所有知识点可以通过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列完全。 -- [《Netty实战》](https://book.douban.com/subject/27038538/)(推荐,豆瓣评分 7.8,92人评价):内容很细,如果想学Netty的话,推荐阅读这本书! -- [《从Paxos到Zookeeper》](https://book.douban.com/subject/26292004/)(推荐,豆瓣评分 7.8,0.3K人评价):简要介绍几种典型的分布式一致性协议,以及解决分布式一致性问题的思路,其中重点讲解了Paxos和ZAB协议。同时,本书深入介绍了分布式一致性问题的工业解决方案——ZooKeeper,并着重向读者展示这一分布式协调框架的使用方法、内部实现及运维技巧,旨在帮助读者全面了解ZooKeeper,并更好地使用和运维ZooKeeper。 -- [《Redis实战》](https://book.douban.com/subject/26612779/):如果你想了解Redis的一些概念性知识的话,这本书真的非常不错。 -- [《Redis设计与实现》](https://book.douban.com/subject/25900156/)(推荐,豆瓣评分 8.5,0.5K+人评价) -- [《大型网站技术架构:核心原理与案例分析+李智慧》](https://book.douban.com/subject/25723064/)(推荐):这本书我读过,基本不需要你有什么基础啊~读起来特别轻松,但是却可以学到很多东西,非常推荐了。另外我写过这本书的思维导图,关注我的微信公众号:“Java面试通关手册”回复“大型网站技术架构”即可领取思维导图。 - - -#### 未看完 - - -- [《鸟哥的Linux私房菜》](https://book.douban.com/subject/4889838/)(推荐,,豆瓣评分 9.1,0.3K+人评价):本书是最具知名度的Linux入门书《鸟哥的Linux私房菜基础学习篇》的最新版,全面而详细地介绍了Linux操作系统。全书分为5个部分:第一部分着重说明Linux的起源及功能,如何规划和安装Linux主机;第二部分介绍Linux的文件系统、文件、目录与磁盘的管理;第三部分介绍文字模式接口 shell和管理系统的好帮手shell脚本,另外还介绍了文字编辑器vi和vim的使用方法;第四部分介绍了对于系统安全非常重要的Linux账号的管理,以及主机系统与程序的管理,如查看进程、任务分配和作业管理;第五部分介绍了系统管理员(root)的管理事项,如了解系统运行状况、系统服务,针对登录文件进行解析,对系统进行备份以及核心的管理等。 -- [《亿级流量网站架构核心技术》](https://book.douban.com/subject/26999243/)(推荐):一书总结并梳理了亿级流量网站高可用和高并发原则,通过实例详细介绍了如何落地这些原则。本书分为四部分:概述、高可用原则、高并发原则、案例实战。从负载均衡、限流、降级、隔离、超时与重试、回滚机制、压测与预案、缓存、池化、异步化、扩容、队列等多方面详细介绍了亿级流量网站的架构核心技术,让读者看后能快速运用到实践项目中。 -- [《重构_改善既有代码的设计》](https://book.douban.com/subject/4262627/)(推荐):豆瓣 9.1 分,重构书籍的开山鼻祖。 -- [《深入剖析Tomcat》](https://book.douban.com/subject/10426640/)(推荐,豆瓣评分 8.4,0.2K+人评价):本书深入剖析Tomcat 4和Tomcat 5中的每个组件,并揭示其内部工作原理。通过学习本书,你将可以自行开发Tomcat组件,或者扩展已有的组件。 读完这本书,基本可以摆脱背诵面试题的尴尬。 -- [《高性能MySQL》](https://book.douban.com/subject/23008813/)(推荐,豆瓣评分 9.3,0.4K+人评价):mysql 领域的经典之作,拥有广泛的影响力。不但适合数据库管理员(dba)阅读,也适合开发人员参考学习。不管是数据库新手还是专家,相信都能从本书有所收获。 -- [深入理解Nginx(第2版)](https://book.douban.com/subject/26745255/):作者讲的非常细致,注释都写的都很工整,对于 Nginx 的开发人员非常有帮助。优点是细致,缺点是过于细致,到处都是代码片段,缺少一些抽象。 -- [《RabbitMQ实战指南》](https://book.douban.com/subject/27591386/):《RabbitMQ实战指南》从消息中间件的概念和RabbitMQ的历史切入,主要阐述RabbitMQ的安装、使用、配置、管理、运维、原理、扩展等方面的细节。如果你想浅尝RabbitMQ的使用,这本书是你最好的选择;如果你想深入RabbitMQ的原理,这本书也是你最好的选择;总之,如果你想玩转RabbitMQ,这本书一定是最值得看的书之一 -- [《Spring Cloud微服务实战》](https://book.douban.com/subject/27025912/):从时下流行的微服务架构概念出发,详细介绍了Spring Cloud针对微服务架构中几大核心要素的解决方案和基础组件。对于各个组件的介绍,《Spring Cloud微服务实战》主要以示例与源码结合的方式来帮助读者更好地理解这些组件的使用方法以及运行原理。同时,在介绍的过程中,还包含了作者在实践中所遇到的一些问题和解决思路,可供读者在实践中作为参考。 -- [《第一本Docker书》](https://book.douban.com/subject/26780404/):Docker入门书籍! -- [《Effective java 》](https://book.douban.com/subject/3360807/)(推荐,豆瓣评分 9.0,1.4K+人评价):本书介绍了在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案。通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰、健壮和高效的代码。本书中的每条规则都以简短、独立的小文章形式出现,并通过例子代码加以进一步说明。本书内容全面,结构清晰,讲解详细。可作为技术人员的参考用书。 -- [《算法 第四版》](https://book.douban.com/subject/10432347/)(推荐,豆瓣评分 9.3,0.4K+人评价):Java语言描述,算法领域经典的参考书,全面介绍了关于算法和数据结构的必备知识,并特别针对排序、搜索、图处理和字符串处理进行了论述。书的内容非常多,可以说是Java程序员的必备书籍之一了。 - -## 一些个人愚见 - -### 关于读书 - -不知道大家收藏栏是不是和我一样收藏了很多文章,但是有多少篇是你真真认真看的呢?或者那几篇你认真看之后,经过一个月之后还记得这篇文章的大概内容。现在这个社会真是一个信息爆炸的社会,我个人真的深有感触,就在刚刚我还取消关注了好多微信公众号,很多公众号给我推的文章都有好几十篇了,但是我一篇都没有看,所以索性取消关注,省个位置。我个人觉得遇到好的文章,我们不光要读,而且要记录下来。就拿我本人来说,我平时喜欢用 OneNote 来记录学习笔记以及其他我感觉重要的事情比如重要人的生日啦这些。每当遇到自己喜欢的文章的时候,我都先会把文章的地址保存到我分好类的笔记本上,我会先进行第一遍阅读,第一遍我会读的很仔细,如果晦涩难懂的话我会先快速把总体看一遍,然后在细细品读。一般第二遍的时候我就会在笔记本上记录这篇文章的一些要点,以便我日后看到这些要点可以快速回忆起整篇文章的内容。如果某篇文章的知识点太过庞大的话,我会去选择采用思维导图的方式展示要点。看视频一样,看教学视频的话,如果觉得老师讲的不错,我们不妨记录下来,Onenote 或者有道云笔记都行,记录大概,够我们日后回忆就好。 - -### 关于学习 - -做事不要有功利性,我最早在掘金写文章,其实也只是为了记录自己的学习,没想到会有人喜欢自己的文章,另外我课外学的很多东西,我自己也不清楚以后工作会不会用到,反正我自己感觉即然自己感兴趣,那么就去学吧。我相信,很多东西可能暂时带给你不了带多实质性的帮助,但是总有一天它会对你有帮助。如果感到迷茫的话,就做好眼前的事(拿我们班主任的话说,如果你感到迷茫,你就学好现在的专业知识就好了),我觉得没毛病。 - -### 关于个人 - -在生活中一定要保持谦虚,保持谦虚,保持谦虚,时刻都要有反省的准备,你要记住学无止境,永远不要满足现在的现状。另外,就是一定要掌控好自己的时间,多留点时间给父母亲人,以及那些自己在乎的人。如果对别人很在乎的话,不要去装作不在乎,因为这样真的不是太好,虽然我之前也会这样,很多时候撰写的消息,最后没发出去。 - -## 最后分享一句话 - -分享给大家,我笔记本里一直保存的杨绛老先生的一句话:“我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容……我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系!”。 From d22552594b9d586417e760f1766c8d73f48e03aa Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 10:57:55 +0800 Subject: [PATCH 183/232] =?UTF-8?q?Update=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按照建议,对目录进行了重新分类,详见ISSUE:https://github.com/Snailclimb/JavaGuide/issues/228 --- README.md | 160 +++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index b7592ac4da2..31ae53ded64 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ 码云地址 公众号 公众号 - +

Special Sponsors

@@ -27,47 +27,8 @@ ## 目录 -* [Java](#java) - * [基础](#基础) - * [集合框架](#集合框架) - * [多线程](#多线程) - * [BIO,NIO,AIO](#bionioaio) - * [JVM](#jvm) - * [Java8 New Features](#java8-new-features) - * [设计模式](#设计模式) -* [数据结构与算法](#数据结构与算法) - * [数据结构](#数据结构) - * [算法](#算法) -* [计算机网络与数据通信](#计算机网络与数据通信) - * [网络相关](#网络相关) - * [数据通信\(RESTful,RPC,消息队列\)总结](#数据通信restfulrpc消息队列总结) -* [操作系统](#操作系统) - * [Linux相关](#linux相关) -* [主流框架](#主流框架) - * [Spring](#spring) - * [ZooKeeper](#zookeeper) -* [数据存储](#数据存储) - * [MySQL](#mysql) - * [Redis](#redis) -* [架构](#架构) -* [面试必备\(Essential content for the interview\)](#面试必备essential-content-for-the-interview) - * [备战面试\(Preparing for an interview\)](#备战面试preparing-for-an-interview) - * [BATJ真实面经\(BATJ real interview experience\)](#batj真实面经batj-real-interview-experience) - * [最常见的Java面试题总结\(Summary of the most common Java interview questions\)](#最常见的java面试题总结summary-of-the-most-common-java-interview-questions) -* [开发常用工具](#开发常用工具) - * [Git](#Git) -* [闲谈](#闲谈) -* [说明](#说明) -## ToDoList(待办清单) -* [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) -* [ ] Java 8 新特性详解 -* [ ] Java 多线程类别知识重构 -* [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) -* [ ] Netty 总结 -* [ ] 数据结构总结重构 - ## Java ### 基础 @@ -77,7 +38,7 @@ * [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) * [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) -### 集合框架 +### 容器 * **常见问题总结:** * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) @@ -88,7 +49,7 @@ * [LinkedList 源码学习](./Java/LinkedList.md) * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) -### 多线程 +### 并发 * [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) * [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) @@ -103,47 +64,21 @@ * [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) * [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) -### BIO,NIO,AIO +### I/O * [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) * [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) -### Java8 New Features +### Java 8 * [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) -### 设计模式 - -* [设计模式系列文章](./Java/设计模式.md) - -## 数据结构与算法 - -### 数据结构 - -* [数据结构知识学习与面试](./数据结构与算法/数据结构.md) - -### 算法 - -* [算法学习与面试](./数据结构与算法/算法.md) -* [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) -* [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) -* [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) - -## 计算机网络与数据通信 - -### 网络相关 +## 网络 * [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) * [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) * [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) -### 数据通信(RESTful,RPC,消息队列)总结 - -* [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) -* [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) -* [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) -* [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) - ## 操作系统 ### Linux相关 @@ -151,19 +86,19 @@ * [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) * [Shell 编程入门](./操作系统/Shell.md) -## 主流框架 +## 数据结构与算法 -### Spring +### 数据结构 -* [Spring 学习与面试](./主流框架/Spring学习与面试.md) -* [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) -* [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) +- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) -### ZooKeeper +### 算法 + +- [算法学习与面试](./数据结构与算法/算法.md) +- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) +- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) -* [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) -* [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) - ## 数据存储 ### MySQL @@ -178,15 +113,41 @@ * [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) * [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) -## 架构 +## 系统设计 -* [一文读懂分布式应该学什么](./架构/分布式.md) -* [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) -* [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) +### 设计模式 -## 面试必备(Essential content for the interview) +- [设计模式系列文章](./Java/设计模式.md) -### 备战面试(Preparing for an interview) +### 常用框架 + +#### Spring + +- [Spring 学习与面试](./主流框架/Spring学习与面试.md) +- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) +- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) + +#### ZooKeeper + +- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) +- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) + +### 数据通信 + +- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) +- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) +- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) +- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) + +### 网站架构 + +- [一文读懂分布式应该学什么](./架构/分布式.md) +- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) + +## 面试指南 + +### 备战面试 * [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) * [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) @@ -196,23 +157,29 @@ * [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) * [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) -### BATJ真实面经(BATJ real interview experience) - -* [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) - -### 最常见的Java面试题总结(Summary of the most common Java interview questions) +### 常见面试题总结 * [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) * [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) * [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) * [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) -## 开发常用工具 +### 面经 + +- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) + +## 工具 ### Git * [Git入门看这一篇就够了](./DevelopCommonTools/GitIntroduce.md) +## 资料 + +### 书单 + +- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) + ## 闲谈 * [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) @@ -221,6 +188,15 @@ *** +## ToDoList(待办清单) + +- [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +- [ ] Java 8 新特性详解 +- [ ] Java 多线程类别知识重构 +- [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +- [ ] Netty 总结 +- [ ] 数据结构总结重构 + ## 说明 ### 介绍 From 3dbe3a38708bbf8d98af15d31725c58188f85a09 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 11:01:49 +0800 Subject: [PATCH 184/232] =?UTF-8?q?Add=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 31ae53ded64..5cfd0433530 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,8 @@ 码云地址 公众号 公众号 +

Special Sponsors

-

- -

Special Sponsors

@@ -27,6 +25,39 @@ ## 目录 +- [目录](#目录) +- [Java](#java) + - [基础](#基础) + - [容器](#容器) + - [并发](#并发) + - [JVM](#jvm) + - [I/O](#io) + - [Java 8](#java-8) +- [网络](#网络) +- [操作系统](#操作系统) + - [Linux相关](#linux相关) +- [数据结构与算法](#数据结构与算法) + - [数据结构](#数据结构) + - [算法](#算法) +- [数据存储](#数据存储) + - [MySQL](#mysql) + - [Redis](#redis) +- [系统设计](#系统设计) + - [设计模式](#设计模式) + - [常用框架](#常用框架) + - [数据通信](#数据通信) + - [网站架构](#网站架构) +- [面试指南](#面试指南) + - [备战面试](#备战面试) + - [常见面试题总结](#常见面试题总结) + - [面经](#面经) +- [工具](#工具) + - [Git](#git) +- [资料](#资料) + - [书单](#书单) +- [闲谈](#闲谈) +- [待办](#待办) +- [说明](#说明) ## Java @@ -188,7 +219,7 @@ *** -## ToDoList(待办清单) +## 待办 - [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) - [ ] Java 8 新特性详解 From 9ce72148b01c281376710c42c1d7f65d88d3eb98 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 11:25:23 +0800 Subject: [PATCH 185/232] Delete GitIntroduce.md --- DevelopCommonTools/GitIntroduce.md | 258 ----------------------------- 1 file changed, 258 deletions(-) delete mode 100644 DevelopCommonTools/GitIntroduce.md diff --git a/DevelopCommonTools/GitIntroduce.md b/DevelopCommonTools/GitIntroduce.md deleted file mode 100644 index e58f13b63aa..00000000000 --- a/DevelopCommonTools/GitIntroduce.md +++ /dev/null @@ -1,258 +0,0 @@ - - -- [版本控制](#版本控制) - - [什么是版本控制](#什么是版本控制) - - [为什么要版本控制](#为什么要版本控制) - - [本地版本控制系统](#本地版本控制系统) - - [集中化的版本控制系统](#集中化的版本控制系统) - - [分布式版本控制系统](#分布式版本控制系统) -- [认识 Git](#认识-git) - - [Git 简史](#git-简史) - - [Git 与其他版本管理系统的主要区别](#git-与其他版本管理系统的主要区别) - - [Git 的三种状态](#git-的三种状态) -- [Git 使用快速入门](#git-使用快速入门) - - [获取 Git 仓库](#获取-git-仓库) - - [记录每次更新到仓库](#记录每次更新到仓库) - - [推送改动到远程仓库](#推送改动到远程仓库) - - [远程仓库的移除与重命名](#远程仓库的移除与重命名) - - [查看提交历史](#查看提交历史) - - [撤销操作](#撤销操作) - - [分支](#分支) -- [推荐阅读](#推荐阅读) - - - -## 版本控制 - -### 什么是版本控制 - -版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 除了项目源代码,你可以对任何类型的文件进行版本控制。 - -### 为什么要版本控制 - -有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 - -### 本地版本控制系统 - -许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。 这么做唯一的好处就是简单,但是特别容易犯错。 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。 - -为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。 - -![本地版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/本地版本控制系统.png) - -### 集中化的版本控制系统 - -接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作? 于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 - -集中化的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 - -![集中化的版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/集中化的版本控制系统.png) - -这么做虽然解决了本地版本控制系统无法让在不同系统上的开发者协同工作的诟病,但也还是存在下面的问题: - -- **单点故障:** 中央服务器宕机,则其他人无法使用;如果中心数据库磁盘损坏有没有进行备份,你将丢失所有数据。本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。 -- **必须联网才能工作:** 受网络状况、带宽影响。 - -### 分布式版本控制系统 - -于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。 Git 就是一个典型的分布式版本控制系统。 - -这类系统,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。 - -![分布式版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/分布式版本控制系统.png) - -分布式版本控制系统可以不用联网就可以工作,因为每个人的电脑上都是完整的版本库,当你修改了某个文件后,你只需要将自己的修改推送给别人就可以了。但是,在实际使用分布式版本控制系统的时候,很少会直接进行推送修改,而是使用一台充当“中央服务器”的东西。这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。 - -分布式版本控制系统的优势不单是不必联网这么简单,后面我们还会看到 Git 极其强大的分支管理等功能。 - -## 认识 Git - -### Git 简史 - -Linux 内核项目组当时使用分布式版本控制系统 BitKeeper 来管理和维护代码。但是,后来开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统,而且对新的版本控制系统做了很多改进。 - -### Git 与其他版本管理系统的主要区别 - - Git 在保存和对待各种信息的时候与其它版本控制系统有很大差异,尽管操作起来的命令形式非常相近,理解这些差异将有助于防止你使用中的困惑。 - -下面我们主要说一个关于 Git 其他版本管理系统的主要差别:**对待数据的方式**。 - -**Git采用的是直接记录快照的方式,而非差异比较。我后面会详细介绍这两种方式的差别。** - -大部分版本控制系统(CVS、Subversion、Perforce、Bazaar 等等)都是以文件变更列表的方式存储信息,这类系统**将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。** - -具体原理如下图所示,理解起来其实很简单,每个我们对提交更新一个文件之后,系统记录都会记录这个文件做了哪些更新,以增量符号Δ(Delta)表示。 - -

- -**我们怎样才能得到一个文件的最终版本呢?** - -很简单,高中数学的基本知识,我们只需要将这些原文件和这些增加进行相加就行了。 - -**这种方式有什么问题呢?** - -比如我们的增量特别特别多的话,如果我们要得到最终的文件是不是会耗费时间和性能。 - -Git 不按照以上方式对待或保存数据。 反之,Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 **快照流**。 - -
- -
-
- - -### Git 的三种状态 - -Git 有三种状态,你的文件可能处于其中之一: - -1. **已提交(committed)**:数据已经安全的保存在本地数据库中。 -2. **已修改(modified)**:已修改表示修改了文件,但还没保存到数据库中。 -3. **已暂存(staged)**:表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 - -由此引入 Git 项目的三个工作区域的概念:**Git 仓库(.git directoty) **、**工作目录(Working Directory)** 以及 **暂存区域(Staging Area)** 。 - -
- -
- -**基本的 Git 工作流程如下:** - -1. 在工作目录中修改文件。 -2. 暂存文件,将文件的快照放入暂存区域。 -3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。 - -## Git 使用快速入门 - -### 获取 Git 仓库 - -有两种取得 Git 项目仓库的方法。 - -1. 在现有目录中初始化仓库: 进入项目目录运行 `git init` 命令,该命令将创建一个名为 `.git` 的子目录。 -2. 从一个服务器克隆一个现有的 Git 仓库: `git clone [url]` 自定义本地仓库的名字: `git clone [url]` directoryname - -### 记录每次更新到仓库 - -1. **检测当前文件状态** : `git status` -2. **提出更改(把它们添加到暂存区**):`git add filename ` (针对特定文件)、`git add *`(所有文件)、`git add *.txt`(支持通配符,所有 .txt 文件) -3. **忽略文件**:`.gitignore` 文件 -4. **提交更新:** `git commit -m "代码提交信息"` (每次准备提交前,先用 `git status` 看下,是不是都已暂存起来了, 然后再运行提交命令 `git commit`) -5. **跳过使用暂存区域更新的方式** : `git commit -a -m "代码提交信息"`。 `git commit` 加上 `-a` 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 `git add` 步骤。 -6. **移除文件** :`git rm filename` (从暂存区域移除,然后提交。) -7. **对文件重命名** :`git mv README.md README`(这个命令相当于`mv README.md README`、`git rm README.md`、`git add README` 这三条命令的集合) - -### 推送改动到远程仓库 - -- 如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:·`git remote add origin ` ,比如我们要让本地的一个仓库和 Github 上创建的一个仓库关联可以这样`git remote add origin https://github.com/Snailclimb/test.git` -- 将这些改动提交到远端仓库:`git push origin master` (可以把 *master* 换成你想要推送的任何分支) - - 如此你就能够将你的改动推送到所添加的服务器上去了。 - -### 远程仓库的移除与重命名 - -- 将 test 重命名位 test1:`git remote rename test test1` -- 移除远程仓库 test1:`git remote rm test1` - -### 查看提交历史 - -在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 `git log` 命令。`git log` 会按提交时间列出所有的更新,最近的更新排在最上面。 - -**可以添加一些参数来查看自己希望看到的内容:** - -只看某个人的提交记录: - -```shell -git log --author=bob -``` - -### 撤销操作 - -有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 `--amend` 选项的提交命令尝试重新提交: - -```console -git commit --amend -``` - -取消暂存的文件 - -```console -git reset filename -``` - -撤消对文件的修改: - -``` -git checkout -- filename -``` - -假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它: - -``` -git fetch origin -git reset --hard origin/master -``` - - - -### 分支 - -分支是用来将特性开发绝缘开来的。在你创建仓库的时候,*master* 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。 - -我们通常在开发新功能、修复一个紧急 bug 等等时候会选择创建分支。单分支开发好还是多分支开发好,还是要看具体场景来说。 - -创建一个名字叫做 test 的分支 - -```console -git branch test -``` - -切换当前分支到 test(当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样) - -```console -git checkout test -``` - -
- -
- -你也可以直接这样创建分支并切换过去(上面两条命令的合写) - -```console -git checkout -b feature_x -``` - -切换到主分支 - -``` -git checkout master -``` - -合并分支(可能会有冲突) - -```java - git merge test -``` - -把新建的分支删掉 - -``` -git branch -d feature_x -``` - -将分支推送到远端仓库(推送成功后其他人可见): - -``` -git push origin -``` - - - -## 推荐阅读 - -- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html) -- [图解Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) -- [猴子都能懂得Git入门](https://backlog.com/git-tutorial/cn/intro/intro1_1.html) -- https://git-scm.com/book/en/v2 From 352282fa0cebe1c14041140bde39ea072330cc85 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 11:25:27 +0800 Subject: [PATCH 186/232] Create Docker.md --- Tools/Docker.md | 220 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 Tools/Docker.md diff --git a/Tools/Docker.md b/Tools/Docker.md new file mode 100644 index 00000000000..b7dd4f50ffd --- /dev/null +++ b/Tools/Docker.md @@ -0,0 +1,220 @@ +**本文只是对Docker的概念做了较为详细的介绍,并不涉及一些像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 容器与虚拟机总结](#32-容器与虚拟机总结) + - [3.3 容器与虚拟机两者是可以共存的](#33-容器与虚拟机两者是可以共存的) +- [四 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 是世界领先的软件容器平台**,所以想要搞懂Docker的概念我们必须先从容器开始说起。 + +## 一 先从认识容器开始 + +### 1.1 什么是容器? + +#### 先来看看容器较为官方的解释 + +**一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。** + +- **容器镜像是轻量的、可执行的独立软件包** ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。 +- **容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。** +- **容器赋予了软件独立性** ,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。 + +#### 再来看看容器较为通俗的解释 + +**如果需要通俗的描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。** + +![认识容器](https://user-gold-cdn.xitu.io/2018/6/17/1640cae21c18e404?w=445&h=363&f=png&s=81473) + +### 1.2 图解物理机,虚拟机与容器 +关于虚拟机与容器的对比在后面会详细介绍到,这里只是通过网上的图片加深大家对于物理机、虚拟机与容器这三者的理解。 + +**物理机** +![物理机](https://user-gold-cdn.xitu.io/2018/6/18/1641129f0ecdf8ff?w=720&h=353&f=jpeg&s=55729) + +**虚拟机:** + +![虚拟机](https://user-gold-cdn.xitu.io/2018/6/18/164112a72a917f4a?w=720&h=321&f=jpeg&s=43096) + +**容器:** + +![容器](https://user-gold-cdn.xitu.io/2018/6/18/164112ac76e6f693?w=720&h=302&f=jpeg&s=41669) + +通过上面这三张抽象图,我们可以大概可以通过类比概括出: **容器虚拟化的是操作系统而不是硬件,容器之间是共享同一套操作系统资源的。虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统。因此容器的隔离级别会稍低一些。** + +--- + +> 相信通过上面的解释大家对于容器这个既陌生又熟悉的概念有了一个初步的认识,下面我们就来谈谈Docker的一些概念。 + +## 二 再来谈谈 Docker 的一些概念 + +![Docker的一些概念](https://user-gold-cdn.xitu.io/2018/6/18/16410734eb1ed373?w=1566&h=696&f=png&s=294564) + +### 2.1 什么是 Docker? + +说实话关于Docker是什么并太好说,下面我通过四点向你说明Docker到底是个什么东西。 + +- **Docker 是世界领先的软件容器平台。** +- **Docker** 使用 Google 公司推出的 **Go 语言** 进行开发实现,基于 **Linux 内核** 的cgroup,namespace,以及AUFS类的**UnionFS**等技术,**对进程进行封装隔离,属于操作系统层面的虚拟化技术。** 由于隔离的进程独立于宿主和其它的隔离的进 +程,因此也称其为容器。**Docke最初实现是基于 LXC.** +- **Docker 能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的事情上:构建杰出的软件。** +- **用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。** + +![什么是Docker](https://user-gold-cdn.xitu.io/2018/6/18/16411c3946dda762?w=971&h=629&f=jpeg&s=56655) + +### 2.2 Docker 思想 + +- **集装箱** +- **标准化:** ①运输方式 ② 存储方式 ③ API接口 +- **隔离** + +### 2.3 Docker 容器的特点 + +- #### 轻量 + + 在一台机器上运行的多个 Docker 容器可以共享这台机器的操作系统内核;它们能够迅速启动,只需占用很少的计算和内存资源。镜像是通过文件系统层进行构造的,并共享一些公共文件。这样就能尽量降低磁盘用量,并能更快地下载镜像。 +- #### 标准 + + Docker 容器基于开放式标准,能够在所有主流 Linux 版本、Microsoft Windows 以及包括 VM、裸机服务器和云在内的任何基础设施上运行。 +- #### 安全 + + Docker 赋予应用的隔离性不仅限于彼此隔离,还独立于底层的基础设施。Docker 默认提供最强的隔离,因此应用出现问题,也只是单个容器的问题,而不会波及到整台机器。 + +### 2.4 为什么要用 Docker ? + +- **Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码在我机器上没问题啊” 这类问题;——一致的运行环境** +- **可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。——更快速的启动时间** +- **避免公用的服务器,资源会容易受到其他用户的影响。——隔离性** +- **善于处理集中爆发的服务器使用压力;——弹性伸缩,快速扩展** +- **可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。——迁移方便** +- **使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。——持续交付和部署** + +--- + +> 每当说起容器,我们不得不将其与虚拟机做一个比较。就我而言,对于两者无所谓谁会取代谁,而是两者可以和谐共存。 + +## 三 容器 VS 虚拟机 + +  简单来说: **容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。** + +### 3.1 两者对比图 + +  传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便. + +![容器 VS 虚拟机](https://user-gold-cdn.xitu.io/2018/6/17/1640cb4abec9e902?w=1086&h=406&f=png&s=70264) + +### 3.2 容器与虚拟机总结 + +![容器与虚拟机 (VM) 总结](https://user-gold-cdn.xitu.io/2018/6/18/16410aa3b89ae481?w=801&h=206&f=png&s=37241) + +- **容器是一个应用层抽象,用于将代码和依赖资源打包在一起。** **多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行** 。与虚拟机相比, **容器占用的空间较少**(容器镜像大小通常只有几十兆),**瞬间就能完成启动** 。 + +- **虚拟机 (VM) 是一个物理硬件层抽象,用于将一台服务器变成多台服务器。** 管理程序允许多个 VM 在一台机器上运行。每个VM都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此 **占用大量空间** 。而且 VM **启动也十分缓慢** 。 + +  通过Docker官网,我们知道了这么多Docker的优势,但是大家也没有必要完全否定虚拟机技术,因为两者有不同的使用场景。**虚拟机更擅长于彻底隔离整个运行环境**。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而 **Docker通常用于隔离不同的应用** ,例如前端,后端以及数据库。 + +### 3.3 容器与虚拟机两者是可以共存的 + +就我而言,对于两者无所谓谁会取代谁,而是两者可以和谐共存。 + +![两者是可以共存的](https://user-gold-cdn.xitu.io/2018/6/17/1640cca26fc38f9e) + +--- + +> Docker中非常重要的三个基本概念,理解了这三个概念,就理解了 Docker 的整个生命周期。 + +## 四 Docker基本概念 + +Docker 包括三个基本概念 + +- **镜像(Image)** +- **容器(Container)** +- **仓库(Repository)** + +理解了这三个概念,就理解了 Docker 的整个生命周期 + +![Docker 包括三个基本概念](https://user-gold-cdn.xitu.io/2018/6/18/164109e4900357a9?w=1024&h=784&f=jpeg&s=127361) + +### 4.1 镜像(Image):一个特殊的文件系统 + +  **操作系统分为内核和用户空间**。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而Docker 镜像(Image),就相当于是一个 root 文件系统。 + +  **Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。** 镜像不包含任何动态数据,其内容在构建之后也不会被改变。 + +  Docker 设计时,就充分利用 **Union FS**的技术,将其设计为 **分层存储的架构** 。 镜像实际是由多层文件系统联合组成。 + +  **镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。** 比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。 + +  分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。 + +### 4.2 容器(Container):镜像运行时的实体 + +  镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,**容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等** 。 + +  **容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。前面讲过镜像使用的是分层存储,容器也是如此。** + +  **容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。** + +  按照 Docker 最佳实践的要求,**容器不应该向其存储层内写入任何数据** ,容器存储层要保持无状态化。**所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录**,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, **使用数据卷后,容器可以随意删除、重新 run ,数据却不会丢失。** + + +### 4.3仓库(Repository):集中存放镜像文件的地方 + +  镜像构建完成后,可以很容易的在当前宿主上运行,但是, **如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。** + +  一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说:**镜像仓库是Docker用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。** + +  通常,**一个仓库会包含同一个软件不同版本的镜像**,而**标签就常用于对应该软件的各个版本** 。我们可以通过```<仓库名>:<标签>```的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。 + +**这里补充一下Docker Registry 公开服务和私有 Docker Registry的概念:** + +  **Docker Registry 公开服务** 是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 + +  最常使用的 Registry 公开服务是官方的 **Docker Hub** ,这也是默认的 Registry,并拥有大量的高质量的官方镜像,网址为:[https://hub.docker.com/](https://hub.docker.com/) 。在国内访问**Docker Hub** 可能会比较慢国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像库](https://hub.tenxcloud.com/)、[网易云镜像服务](https://www.163yun.com/product/repo)、[DaoCloud 镜像市场](https://www.daocloud.io/)、[阿里云镜像库](https://www.aliyun.com/product/containerservice?utm_content=se_1292836)等。 + +  除了使用公开服务外,用户还可以在 **本地搭建私有 Docker Registry** 。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。 + +--- + +> Docker的概念基本上已经讲完,最后我们谈谈:Build, Ship, and Run。 + +## 五 最后谈谈:Build Ship and Run +如果你搜索Docker官网,会发现如下的字样:**“Docker - Build, Ship, and Run Any App, Anywhere”**。那么Build, Ship, and Run到底是在干什么呢? + +![build ship run](https://user-gold-cdn.xitu.io/2018/6/18/16411c521e79bd82?w=486&h=255&f=png&s=185903) + +- **Build(构建镜像)** : 镜像就像是集装箱包括文件以及运行环境等等资源。 +- **Ship(运输镜像)** :主机和仓库间运输,这里的仓库就像是超级码头一样。 +- **Run (运行镜像)** :运行的镜像就是一个容器,容器就是运行程序的地方。 + +**Docker 运行过程也就是去仓库把镜像拉到本地,然后用一条命令把镜像运行起来变成容器。所以,我们也常常将Docker称为码头工人或码头装卸工,这和Docker的中文翻译搬运工人如出一辙。** + +## 六 总结 + +本文主要把Docker中的一些常见概念做了详细的阐述,但是并不涉及Docker的安装、镜像的使用、容器的操作等内容。这部分东西,希望读者自己可以通过阅读书籍与官方文档的形式掌握。如果觉得官方文档阅读起来很费力的话,这里推荐一本书籍《Docker技术入门与实战第二版》。 + + + + + + + From 9958f281e2ffe6eef3fbf65482515c1bd2fb81b1 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 11:25:32 +0800 Subject: [PATCH 187/232] Create Git.md --- Tools/Git.md | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 Tools/Git.md diff --git a/Tools/Git.md b/Tools/Git.md new file mode 100644 index 00000000000..e58f13b63aa --- /dev/null +++ b/Tools/Git.md @@ -0,0 +1,258 @@ + + +- [版本控制](#版本控制) + - [什么是版本控制](#什么是版本控制) + - [为什么要版本控制](#为什么要版本控制) + - [本地版本控制系统](#本地版本控制系统) + - [集中化的版本控制系统](#集中化的版本控制系统) + - [分布式版本控制系统](#分布式版本控制系统) +- [认识 Git](#认识-git) + - [Git 简史](#git-简史) + - [Git 与其他版本管理系统的主要区别](#git-与其他版本管理系统的主要区别) + - [Git 的三种状态](#git-的三种状态) +- [Git 使用快速入门](#git-使用快速入门) + - [获取 Git 仓库](#获取-git-仓库) + - [记录每次更新到仓库](#记录每次更新到仓库) + - [推送改动到远程仓库](#推送改动到远程仓库) + - [远程仓库的移除与重命名](#远程仓库的移除与重命名) + - [查看提交历史](#查看提交历史) + - [撤销操作](#撤销操作) + - [分支](#分支) +- [推荐阅读](#推荐阅读) + + + +## 版本控制 + +### 什么是版本控制 + +版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 除了项目源代码,你可以对任何类型的文件进行版本控制。 + +### 为什么要版本控制 + +有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 + +### 本地版本控制系统 + +许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。 这么做唯一的好处就是简单,但是特别容易犯错。 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。 + +为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。 + +![本地版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/本地版本控制系统.png) + +### 集中化的版本控制系统 + +接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作? 于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 + +集中化的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 + +![集中化的版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/集中化的版本控制系统.png) + +这么做虽然解决了本地版本控制系统无法让在不同系统上的开发者协同工作的诟病,但也还是存在下面的问题: + +- **单点故障:** 中央服务器宕机,则其他人无法使用;如果中心数据库磁盘损坏有没有进行备份,你将丢失所有数据。本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。 +- **必须联网才能工作:** 受网络状况、带宽影响。 + +### 分布式版本控制系统 + +于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。 Git 就是一个典型的分布式版本控制系统。 + +这类系统,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。 + +![分布式版本控制系统](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/分布式版本控制系统.png) + +分布式版本控制系统可以不用联网就可以工作,因为每个人的电脑上都是完整的版本库,当你修改了某个文件后,你只需要将自己的修改推送给别人就可以了。但是,在实际使用分布式版本控制系统的时候,很少会直接进行推送修改,而是使用一台充当“中央服务器”的东西。这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。 + +分布式版本控制系统的优势不单是不必联网这么简单,后面我们还会看到 Git 极其强大的分支管理等功能。 + +## 认识 Git + +### Git 简史 + +Linux 内核项目组当时使用分布式版本控制系统 BitKeeper 来管理和维护代码。但是,后来开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统,而且对新的版本控制系统做了很多改进。 + +### Git 与其他版本管理系统的主要区别 + + Git 在保存和对待各种信息的时候与其它版本控制系统有很大差异,尽管操作起来的命令形式非常相近,理解这些差异将有助于防止你使用中的困惑。 + +下面我们主要说一个关于 Git 其他版本管理系统的主要差别:**对待数据的方式**。 + +**Git采用的是直接记录快照的方式,而非差异比较。我后面会详细介绍这两种方式的差别。** + +大部分版本控制系统(CVS、Subversion、Perforce、Bazaar 等等)都是以文件变更列表的方式存储信息,这类系统**将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。** + +具体原理如下图所示,理解起来其实很简单,每个我们对提交更新一个文件之后,系统记录都会记录这个文件做了哪些更新,以增量符号Δ(Delta)表示。 + +
+ +
+
+ +**我们怎样才能得到一个文件的最终版本呢?** + +很简单,高中数学的基本知识,我们只需要将这些原文件和这些增加进行相加就行了。 + +**这种方式有什么问题呢?** + +比如我们的增量特别特别多的话,如果我们要得到最终的文件是不是会耗费时间和性能。 + +Git 不按照以上方式对待或保存数据。 反之,Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 **快照流**。 + +
+ +
+
+ + +### Git 的三种状态 + +Git 有三种状态,你的文件可能处于其中之一: + +1. **已提交(committed)**:数据已经安全的保存在本地数据库中。 +2. **已修改(modified)**:已修改表示修改了文件,但还没保存到数据库中。 +3. **已暂存(staged)**:表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 + +由此引入 Git 项目的三个工作区域的概念:**Git 仓库(.git directoty) **、**工作目录(Working Directory)** 以及 **暂存区域(Staging Area)** 。 + +
+ +
+ +**基本的 Git 工作流程如下:** + +1. 在工作目录中修改文件。 +2. 暂存文件,将文件的快照放入暂存区域。 +3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。 + +## Git 使用快速入门 + +### 获取 Git 仓库 + +有两种取得 Git 项目仓库的方法。 + +1. 在现有目录中初始化仓库: 进入项目目录运行 `git init` 命令,该命令将创建一个名为 `.git` 的子目录。 +2. 从一个服务器克隆一个现有的 Git 仓库: `git clone [url]` 自定义本地仓库的名字: `git clone [url]` directoryname + +### 记录每次更新到仓库 + +1. **检测当前文件状态** : `git status` +2. **提出更改(把它们添加到暂存区**):`git add filename ` (针对特定文件)、`git add *`(所有文件)、`git add *.txt`(支持通配符,所有 .txt 文件) +3. **忽略文件**:`.gitignore` 文件 +4. **提交更新:** `git commit -m "代码提交信息"` (每次准备提交前,先用 `git status` 看下,是不是都已暂存起来了, 然后再运行提交命令 `git commit`) +5. **跳过使用暂存区域更新的方式** : `git commit -a -m "代码提交信息"`。 `git commit` 加上 `-a` 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 `git add` 步骤。 +6. **移除文件** :`git rm filename` (从暂存区域移除,然后提交。) +7. **对文件重命名** :`git mv README.md README`(这个命令相当于`mv README.md README`、`git rm README.md`、`git add README` 这三条命令的集合) + +### 推送改动到远程仓库 + +- 如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:·`git remote add origin ` ,比如我们要让本地的一个仓库和 Github 上创建的一个仓库关联可以这样`git remote add origin https://github.com/Snailclimb/test.git` +- 将这些改动提交到远端仓库:`git push origin master` (可以把 *master* 换成你想要推送的任何分支) + + 如此你就能够将你的改动推送到所添加的服务器上去了。 + +### 远程仓库的移除与重命名 + +- 将 test 重命名位 test1:`git remote rename test test1` +- 移除远程仓库 test1:`git remote rm test1` + +### 查看提交历史 + +在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 `git log` 命令。`git log` 会按提交时间列出所有的更新,最近的更新排在最上面。 + +**可以添加一些参数来查看自己希望看到的内容:** + +只看某个人的提交记录: + +```shell +git log --author=bob +``` + +### 撤销操作 + +有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 `--amend` 选项的提交命令尝试重新提交: + +```console +git commit --amend +``` + +取消暂存的文件 + +```console +git reset filename +``` + +撤消对文件的修改: + +``` +git checkout -- filename +``` + +假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它: + +``` +git fetch origin +git reset --hard origin/master +``` + + + +### 分支 + +分支是用来将特性开发绝缘开来的。在你创建仓库的时候,*master* 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。 + +我们通常在开发新功能、修复一个紧急 bug 等等时候会选择创建分支。单分支开发好还是多分支开发好,还是要看具体场景来说。 + +创建一个名字叫做 test 的分支 + +```console +git branch test +``` + +切换当前分支到 test(当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样) + +```console +git checkout test +``` + +
+ +
+ +你也可以直接这样创建分支并切换过去(上面两条命令的合写) + +```console +git checkout -b feature_x +``` + +切换到主分支 + +``` +git checkout master +``` + +合并分支(可能会有冲突) + +```java + git merge test +``` + +把新建的分支删掉 + +``` +git branch -d feature_x +``` + +将分支推送到远端仓库(推送成功后其他人可见): + +``` +git push origin +``` + + + +## 推荐阅读 + +- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html) +- [图解Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) +- [猴子都能懂得Git入门](https://backlog.com/git-tutorial/cn/intro/intro1_1.html) +- https://git-scm.com/book/en/v2 From f2f378eefbb0e4b79aeae4bda70c1eb569266df8 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 11:26:45 +0800 Subject: [PATCH 188/232] Add Docker --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5cfd0433530..9fa5e525ef1 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ ## 目录 -- [目录](#目录) - [Java](#java) - [基础](#基础) - [容器](#容器) @@ -53,6 +52,7 @@ - [面经](#面经) - [工具](#工具) - [Git](#git) + - [Docker](#Docker) - [资料](#资料) - [书单](#书单) - [闲谈](#闲谈) @@ -203,7 +203,11 @@ ### Git -* [Git入门看这一篇就够了](./DevelopCommonTools/GitIntroduce.md) +* [Git入门](./Tools/Git.md) + +### Docker + +* [Docker 入门](./Tools/Docker.md) ## 资料 @@ -291,6 +295,9 @@
+ + + ### 公众号 From a5c7492b6b9d28175980599c2d286a6bc9be29f9 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 15:19:05 +0800 Subject: [PATCH 189/232] =?UTF-8?q?Fix=20HTML=E6=A0=87=E7=AD=BE=E4=B8=8D?= =?UTF-8?q?=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fa5e525ef1..52f6ecb7452 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ 公众号 公众号

Special Sponsors

- +

From dd44b7f4bfc32dd14af6295e82712aadb6cf0e77 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 16:38:18 +0800 Subject: [PATCH 190/232] =?UTF-8?q?Add=20docsify=E6=90=AD=E5=BB=BA?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E7=BD=91=E7=AB=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nojekyll | 0 HomePage.md | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++ _coverpage.md | 10 +++ index.html | 27 ++++++++ 4 files changed, 221 insertions(+) create mode 100644 .nojekyll create mode 100644 HomePage.md create mode 100644 _coverpage.md create mode 100644 index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/HomePage.md b/HomePage.md new file mode 100644 index 00000000000..ba25479f367 --- /dev/null +++ b/HomePage.md @@ -0,0 +1,184 @@ +

Special Sponsors

+

+ + + +

+ +## Java + +### 基础 + +* [Java 基础知识回顾](./Java/Java基础知识.md) +* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) +* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) + +### 容器 + +* **常见问题总结:** + * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) +* **源码分析:** + * [ArrayList 源码学习](./Java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) + * [LinkedList 源码学习](./Java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) + +### 并发 + +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](./Java/Multithread/并发容器总结.md) + +### JVM + +* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) + +### I/O + +* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) + +### Java 8 + +* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) + +## 网络 + +* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) +* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) +* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) + +## 操作系统 + +### Linux相关 + +* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) +* [Shell 编程入门](./操作系统/Shell.md) + +## 数据结构与算法 + +### 数据结构 + +- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) + +### 算法 + +- [算法学习与面试](./数据结构与算法/算法.md) +- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) +- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) + +## 数据存储 + +### MySQL + +* [MySQL 学习与面试](./数据存储/MySQL.md) +* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) +* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) + +### Redis + +* [Redis 总结](./数据存储/Redis/Redis.md) +* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) +* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) + +## 系统设计 + +### 设计模式 + +- [设计模式系列文章](./Java/设计模式.md) + +### 常用框架 + +#### Spring + +- [Spring 学习与面试](./主流框架/Spring学习与面试.md) +- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) +- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) + +#### ZooKeeper + +- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) +- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) + +### 数据通信 + +- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) +- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) +- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) +- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) + +### 网站架构 + +- [一文读懂分布式应该学什么](./架构/分布式.md) +- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) + +## 面试指南 + +### 备战面试 + +* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) + +### 常见面试题总结 + +* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) + +### 面经 + +- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) + +## 工具 + +### Git + +* [Git入门看这一篇就够了](./DevelopCommonTools/GitIntroduce.md) + +## 资料 + +### 书单 + +- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) + +## 闲谈 + +* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) +* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) + +*** + +## 待办 + +- [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +- [ ] Java 8 新特性详解 +- [ ] Java 多线程类别知识重构 +- [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +- [ ] Netty 总结 +- [ ] 数据结构总结重构 + +## 公众号 + +- 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 +- 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本公众号后台回复 **"Java面试突击"** 即可免费领取! +- 一些Java工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 + +

+ +

\ No newline at end of file diff --git a/_coverpage.md b/_coverpage.md new file mode 100644 index 00000000000..612cd2160ec --- /dev/null +++ b/_coverpage.md @@ -0,0 +1,10 @@ +

+ +

+ +

Java 学习/面试指南

+ +[常用资源](https://shimo.im/docs/MuiACIg1HlYfVxrj/) +[GitHub]() +[开始阅读](#java) + diff --git a/index.html b/index.html new file mode 100644 index 00000000000..c09e6589b1f --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + Document + + + + + + + +
+ + + + + + From e8aeaef43cbfb2b8a9b71c7b7f462c48b4adb9a6 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 17:19:36 +0800 Subject: [PATCH 191/232] =?UTF-8?q?Update=20=E6=9B=B4=E6=94=B9=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 136 ++++---- .nojekyll => docs/.nojekyll | 0 HomePage.md => docs/HomePage.md | 0 docs/README.md | 310 ++++++++++++++++++ _coverpage.md => docs/_coverpage.md | 0 .../Leetcode-LinkList1.md | 0 .../source code/securityAlgorithm/.classpath | 0 .../source code/securityAlgorithm/.gitignore | 0 .../source code/securityAlgorithm/.project | 0 .../org.eclipse.core.resources.prefs | 0 .../.settings/org.eclipse.jdt.core.prefs | 0 .../.settings/org.eclipse.m2e.core.prefs | 0 .../source code/securityAlgorithm/pom.xml | 0 .../ks/securityAlgorithm/Base64Demo.java | 0 .../ks/securityAlgorithm/DesDemo.java | 0 .../ks/securityAlgorithm/IDEADemo.java | 0 .../snailclimb/ks/securityAlgorithm/MD5.java | 0 .../ks/securityAlgorithm/MD5Demo.java | 0 .../ks/securityAlgorithm/RSADemo.java | 0 .../ks/securityAlgorithm/SHA1Demo.java | 0 .../snailclimb/ks/securityAlgorithm/readme | 0 .../ks/securityAlgorithm/AppTest.java | 0 ...11\357\274\211\346\200\273\347\273\223.md" | 0 ...62\347\256\227\346\263\225\351\242\230.md" | 0 ...60\346\215\256\347\273\223\346\236\204.md" | 0 .../\347\256\227\346\263\225.md" | 0 ...347\274\226\347\250\213\351\242\2301-3.md" | 0 ...60\351\230\266\351\227\256\351\242\230.md" | 0 ...72\346\240\274\351\227\256\351\242\230.md" | 0 ...03\347\264\240\351\241\272\345\272\217.md" | 0 ...63\347\274\226\347\250\213\351\242\230.md" | 0 ...71\345\207\272\345\272\217\345\210\227.md" | 0 .../database/MySQL Index.md | 0 .../MySQL.md" => docs/database/MySQL.md | 0 .../Redis.md" => docs/database/Redis/Redis.md | 0 ...is\346\214\201\344\271\205\345\214\226.md" | 0 ...06\345\270\203\345\274\217\351\224\201.md" | 0 ...04\345\217\257\350\241\214\344\271\210.md" | 0 ...0\241\214MySQL\345\221\275\344\273\244.md" | 0 ...\207\214,\347\273\210\350\216\267offer.md" | 0 ...21\250\357\274\2102018-8-7\357\274\211.md" | 0 ...254\344\272\214\345\221\250(2018-8-13).md" | 0 ...254\345\233\233\345\221\250(2018-8-30).md" | 0 .../JavaInterviewLibrary.md | 0 .../JavaProgrammerNeedKnow.md | 0 .../PreparingForInterview/books.md | 0 .../PreparingForInterview/interviewPrepare.md | 0 ...02\344\275\225\345\233\236\347\255\224.md" | 0 ...00\345\216\206\344\271\213\351\201\223.md" | 0 ...56\351\242\230\346\200\273\347\273\223.md" | 0 ...17\347\232\204\347\256\200\345\216\206.md" | 0 ...00\345\216\206\346\250\241\346\235\277.md" | 0 ...16\346\202\262\350\247\202\351\224\201.md" | 0 index.html => docs/index.html | 0 {Java => docs/java}/ArrayList-Grow.md | 0 {Java => docs/java}/ArrayList.md | 0 {Java => docs/java}/BIO,NIO,AIO summary.md | 0 .../Basis/Arrays,CollectionsCommonMethods.md | 0 ...tatic\343\200\201this\343\200\201super.md" | 0 {Java => docs/java}/HashMap.md | 0 ...72\347\241\200\347\237\245\350\257\206.md" | 0 .../java/Java IO\344\270\216NIO.md" | 0 ...72\347\241\200\347\237\245\350\257\206.md" | 0 ...346\234\272\357\274\210jvm\357\274\211.md" | 0 ...25\351\242\230\346\200\273\347\273\223.md" | 0 {Java => docs/java}/LinkedList.md | 0 {Java => docs/java}/Multithread/AQS.md | 0 {Java => docs/java}/Multithread/Atomic.md | 0 ...13\351\235\242\350\257\225\351\242\230.md" | 0 ...72\347\241\200\347\237\245\350\257\206.md" | 269 +++++++++++++++ ...71\345\231\250\346\200\273\347\273\223.md" | 0 ...30\350\256\244\346\226\271\346\263\225.md" | 0 .../java}/What's New in JDK8/Java8Tutorial.md | 0 ...da\350\241\250\350\276\276\345\274\217.md" | 0 .../java}/What's New in JDK8/README.md | 0 docs/java/What's New in JDK8/Stream.md | 75 +++++ ...73\345\236\213\346\216\250\346\226\255.md" | 0 ...02\346\225\260\344\277\241\346\201\257.md" | 0 {Java => docs/java}/synchronized.md | 0 ...00\347\257\207\346\226\207\347\253\240.md" | 0 ...77\347\250\213\347\263\273\345\210\227.md" | 0 ...31\344\271\210\347\256\200\345\215\225.md" | 0 ...40\344\271\216\345\277\205\351\227\256.md" | 0 .../HTTPS\344\270\255\347\232\204TLS.md" | 0 ...45\350\257\206\346\200\273\347\273\223.md" | 0 ...27\346\234\272\347\275\221\347\273\234.md" | 0 .../operating-system/Shell.md | 0 ...72\347\241\200\347\237\245\350\257\206.md" | 0 .../system-design/data-communication/dubbo.md | 0 .../data-communication/message-queue.md | 0 .../data-communication/rabbitmq.md | 0 ...0\346\201\257\351\230\237\345\210\227).md" | 0 .../system-design/framework/SpringBean.md | 0 ...37\347\220\206\350\257\246\350\247\243.md" | 0 ...40\344\270\216\351\235\242\350\257\225.md" | 0 .../system-design/framework/ZooKeeper.md | 0 ...70\350\247\201\345\221\275\344\273\244.md" | 0 ...00\346\234\257\346\236\266\346\236\204.md" | 0 ...10\344\270\252\351\227\256\351\242\230.md" | 0 .../\345\210\206\345\270\203\345\274\217.md" | 0 ...76\350\256\241\346\250\241\345\274\217.md" | 0 {Tools => docs/tools}/Docker.md | 0 {Tools => docs/tools}/Git.md | 0 .../2018 \347\247\213\346\213\233.md" | 0 .../JavaGithubTrending/2018-12.md" | 0 .../JavaGithubTrending/2019-1.md" | 0 .../JavaGithubTrending/2019-2.md" | 0 .../JavaGithubTrending/JavaGithubTrending.md" | 0 ...46\347\261\215\346\270\205\345\215\225.md" | 0 ...52\344\272\233\345\233\240\347\264\240.md" | 0 110 files changed, 722 insertions(+), 68 deletions(-) rename .nojekyll => docs/.nojekyll (100%) rename HomePage.md => docs/HomePage.md (100%) create mode 100644 docs/README.md rename _coverpage.md => docs/_coverpage.md (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/Leetcode-LinkList1.md" => docs/dataStructures-algorithms/Leetcode-LinkList1.md (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.classpath" => docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.gitignore" => docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.project" => docs/dataStructures-algorithms/source code/securityAlgorithm/.project (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs" => docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs" => docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs" => docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/pom.xml" => docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java" => docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" => "docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" => "docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" => "docs/dataStructures-algorithms/\346\225\260\346\215\256\347\273\223\346\236\204.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" => "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" => docs/database/MySQL Index.md (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/MySQL.md" => docs/database/MySQL.md (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" => docs/database/Redis/Redis.md (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis\346\214\201\344\271\205\345\214\226.md" => "docs/database/Redis/Redis\346\214\201\344\271\205\345\214\226.md" (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" => "docs/database/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" => "docs/database/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" (100%) rename "\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" => "docs/database/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" (100%) rename "EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" => "docs/essential-content-for-interview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" (100%) rename "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" => "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" (100%) rename "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" => "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" (100%) rename "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" => "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" (100%) rename {EssentialContentForInterview => docs/essential-content-for-interview}/PreparingForInterview/JavaInterviewLibrary.md (100%) rename {EssentialContentForInterview => docs/essential-content-for-interview}/PreparingForInterview/JavaProgrammerNeedKnow.md (100%) rename {EssentialContentForInterview => docs/essential-content-for-interview}/PreparingForInterview/books.md (100%) rename {EssentialContentForInterview => docs/essential-content-for-interview}/PreparingForInterview/interviewPrepare.md (100%) rename "EssentialContentForInterview/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" => "docs/essential-content-for-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" (100%) rename "EssentialContentForInterview/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" => "docs/essential-content-for-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" (100%) rename "EssentialContentForInterview/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" => "docs/essential-content-for-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" (100%) rename "EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" => "docs/essential-content-for-interview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" (100%) rename "EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" => "docs/essential-content-for-interview/\347\256\200\345\216\206\346\250\241\346\235\277.md" (100%) rename "EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" => "docs/essential-content-for-interview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" (100%) rename index.html => docs/index.html (100%) rename {Java => docs/java}/ArrayList-Grow.md (100%) rename {Java => docs/java}/ArrayList.md (100%) rename {Java => docs/java}/BIO,NIO,AIO summary.md (100%) rename {Java => docs/java}/Basis/Arrays,CollectionsCommonMethods.md (100%) rename "Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" => "docs/java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" (100%) rename {Java => docs/java}/HashMap.md (100%) rename "Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" => "docs/java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" (100%) rename "Java/Java IO\344\270\216NIO.md" => "docs/java/Java IO\344\270\216NIO.md" (100%) rename "Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" => "docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" (100%) rename "Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" => "docs/java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" (100%) rename "Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" => "docs/java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" (100%) rename {Java => docs/java}/LinkedList.md (100%) rename {Java => docs/java}/Multithread/AQS.md (100%) rename {Java => docs/java}/Multithread/Atomic.md (100%) rename "Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" => "docs/java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" (100%) create mode 100644 "docs/java/Multithread/ConcurrentProgramming1-\345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\347\237\245\350\257\206.md" rename "Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" => "docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" (100%) rename "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" => "docs/java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" (100%) rename {Java => docs/java}/What's New in JDK8/Java8Tutorial.md (100%) rename "Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" => "docs/java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" (100%) rename {Java => docs/java}/What's New in JDK8/README.md (100%) create mode 100644 docs/java/What's New in JDK8/Stream.md rename "Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" => "docs/java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" (100%) rename "Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" => "docs/java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" (100%) rename {Java => docs/java}/synchronized.md (100%) rename "Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" => "docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" (100%) rename "Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" => "docs/java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" (100%) rename "Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" => "docs/java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" (100%) rename "Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" => "docs/java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/HTTPS\344\270\255\347\232\204TLS.md" => "docs/network/HTTPS\344\270\255\347\232\204TLS.md" (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" => "docs/network/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" => "docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" (100%) rename "\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" => docs/operating-system/Shell.md (100%) rename "\346\223\215\344\275\234\347\263\273\347\273\237/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" => "docs/operating-system/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/dubbo.md" => docs/system-design/data-communication/dubbo.md (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/message-queue.md" => docs/system-design/data-communication/message-queue.md (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" => docs/system-design/data-communication/rabbitmq.md (100%) rename "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" => "docs/system-design/data-communication/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" (100%) rename "\344\270\273\346\265\201\346\241\206\346\236\266/SpringBean.md" => docs/system-design/framework/SpringBean.md (100%) rename "\344\270\273\346\265\201\346\241\206\346\236\266/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/system-design/framework/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%) rename "\344\270\273\346\265\201\346\241\206\346\236\266/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" => "docs/system-design/framework/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" (100%) rename "\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper.md" => docs/system-design/framework/ZooKeeper.md (100%) rename "\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" => "docs/system-design/framework/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" (100%) rename "\346\236\266\346\236\204/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" => "docs/system-design/website-architecture/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" (100%) rename "\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" => "docs/system-design/website-architecture/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" (100%) rename "\346\236\266\346\236\204/\345\210\206\345\270\203\345\274\217.md" => "docs/system-design/website-architecture/\345\210\206\345\270\203\345\274\217.md" (100%) rename "Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" => "docs/system-design/\350\256\276\350\256\241\346\250\241\345\274\217.md" (100%) rename {Tools => docs/tools}/Docker.md (100%) rename {Tools => docs/tools}/Git.md (100%) rename "\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" => "docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" (100%) rename "\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" => "docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" (100%) rename "\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" => "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" (100%) rename "\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" => "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" (100%) rename "\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" => "docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" (100%) rename "\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" => "docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" (100%) rename "\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" => "docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" (100%) diff --git a/README.md b/README.md index 52f6ecb7452..cf1e591ed9d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ - [数据结构与算法](#数据结构与算法) - [数据结构](#数据结构) - [算法](#算法) -- [数据存储](#数据存储) +- [数据库](#数据库) - [MySQL](#mysql) - [Redis](#redis) - [系统设计](#系统设计) @@ -64,156 +64,156 @@ ### 基础 -* [Java 基础知识回顾](./Java/Java基础知识.md) -* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) -* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) -* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) +* [Java 基础知识回顾](docs/java/Java基础知识.md) +* [J2EE 基础知识回顾](docs/java/J2EE基础知识.md) +* [Collections 工具类和 Arrays 工具类常见方法](./java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](docs/java/Basis/final、static、this、super.md) ### 容器 * **常见问题总结:** - * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) - * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) + * [这几道Java集合框架面试题几乎必问](docs/java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](docs/java/Java集合框架常见面试题总结.md) * **源码分析:** - * [ArrayList 源码学习](./Java/ArrayList.md) - * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) - * [LinkedList 源码学习](./Java/LinkedList.md) - * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) + * [ArrayList 源码学习](docs/java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](docs/java/ArrayList-Grow.md) + * [LinkedList 源码学习](docs/java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](docs/java/HashMap.md) ### 并发 -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](./Java/Multithread/并发容器总结.md) +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](docs/java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](docs/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](docs/java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](docs/java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](docs/java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](docs/java/Multithread/并发容器总结.md) ### JVM -* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) +* [可能是把Java内存区域讲的最清楚的一篇文章](docs/java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](docs/java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](docs/java/Java虚拟机(jvm).md) ### I/O -* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) +* [BIO,NIO,AIO 总结 ](docs/java/BIO%2CNIO%2CAIO%20summary.md) +* [Java IO 与 NIO系列文章](docs/Java/Java%20IO与NIO.md) ### Java 8 -* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [Java 8 新特性总结](docs/java/What's%20New%20in%20JDK8/Java8Tutorial.md) ## 网络 -* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) -* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) -* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) +* [计算机网络常见面试题](docs/network/计算机网络.md) +* [计算机网络基础知识总结](docs/network/干货:计算机网络知识总结.md) +* [HTTPS中的TLS](docs/network/HTTPS中的TLS.md) ## 操作系统 ### Linux相关 -* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) -* [Shell 编程入门](./操作系统/Shell.md) +* [后端程序员必备的 Linux 基础知识](docs/operating-system/后端程序员必备的Linux基础知识.md) +* [Shell 编程入门](docs/operating-system/Shell.md) ## 数据结构与算法 ### 数据结构 -- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) +- [数据结构知识学习与面试](docs/dataStructures-algorithms/数据结构.md) ### 算法 -- [算法学习与面试](./数据结构与算法/算法.md) -- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) -- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) -- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) +- [算法学习与面试](docs/dataStructures-algorithms/算法.md) +- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/搞定BAT面试——几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/Leetcode-LinkList1.md) +- [常见安全算法(MD5、SHA1、Base64等等)总结](docs/dataStructures-algorithms/常见安全算法(MD5、SHA1、Base64等等)总结.md) -## 数据存储 +## 数据库 ### MySQL -* [MySQL 学习与面试](./数据存储/MySQL.md) -* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) -* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) +* [MySQL 学习与面试](docs/database/MySQL.md) +* [【思维导图-索引篇】搞定数据库索引就是这么简单](docs/database/MySQL%20Index.md) +* [一千行MySQL学习笔记](docs/database/一千行MySQL命令.md) ### Redis -* [Redis 总结](./数据存储/Redis/Redis.md) -* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) -* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) +* [Redis 总结](docs/database/Redis/Redis.md) +* [Redlock分布式锁](docs/database/Redis/Redlock分布式锁.md) +* [如何做可靠的分布式锁,Redlock真的可行么](docs/database/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) ## 系统设计 ### 设计模式 -- [设计模式系列文章](./Java/设计模式.md) +- [设计模式系列文章](docs/system-design/设计模式.md) ### 常用框架 #### Spring -- [Spring 学习与面试](./主流框架/Spring学习与面试.md) -- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) -- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) +- [Spring 学习与面试](docs/system-design/framework/Spring学习与面试.md) +- [Spring中bean的作用域与生命周期](docs/system-design/framework/SpringBean.md) +- [SpringMVC 工作原理详解](docs/system-design/framework/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) #### ZooKeeper -- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) -- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) +- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](docs/system-design/framework/ZooKeeper.md) +- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](docs/system-design/framework/ZooKeeper数据模型和常见命令.md) ### 数据通信 -- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) -- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) -- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) -- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) +- [数据通信(RESTful、RPC、消息队列)相关知识点总结](docs/system-design/data-communication/数据通信(RESTful、RPC、消息队列).md) +- [Dubbo 总结:关于 Dubbo 的重要知识点](docs/system-design/data-communication/dubbo.md) +- [消息队列总结:新手也能看懂,消息队列其实很简单](docs/system-design/data-communication/message-queue.md) +- [一文搞懂 RabbitMQ 的重要概念以及安装](docs/system-design/data-communication/rabbitmq.md) ### 网站架构 -- [一文读懂分布式应该学什么](./架构/分布式.md) -- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) -- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) +- [一文读懂分布式应该学什么](docs/system-design/website-architecture/分布式.md) +- [8 张图读懂大型网站技术架构](docs/system-design/website-architecture/8%20张图读懂大型网站技术架构.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](docs/system-design/website-architecture/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) ## 面试指南 ### 备战面试 -* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) -* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) -* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) -* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) -* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) -* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) -* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +* [【备战面试1】程序员的简历就该这样写](docs/essential-content-for-interview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](docs/essential-content-for-interview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](docs/essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](docs/essential-content-for-interview/PreparingForInterview/books.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](docs/essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](docs/essential-content-for-interview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](docs/essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md) ### 常见面试题总结 -* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) -* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) -* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) -* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) +* [第一周(2018-8-7)](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第三周(2018-08-22)](docs/java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第四周(2018-8-30).md](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) ### 面经 -- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) +- [5面阿里,终获offer(2018年秋招)](docs/essential-content-for-interview/BATJrealInterviewExperience/5面阿里,终获offer.md) ## 工具 ### Git -* [Git入门](./Tools/Git.md) +* [Git入门](docs/tools/Git.md) ### Docker -* [Docker 入门](./Tools/Docker.md) +* [Docker 入门](docs/tools/Docker.md) ## 资料 ### 书单 -- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) +- [Java程序员必备书单](docs/essential-content-for-interview//PreparingForInterview/books.md) ## 闲谈 diff --git a/.nojekyll b/docs/.nojekyll similarity index 100% rename from .nojekyll rename to docs/.nojekyll diff --git a/HomePage.md b/docs/HomePage.md similarity index 100% rename from HomePage.md rename to docs/HomePage.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000000..52f6ecb7452 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,310 @@ +

Java 学习/面试指南

+ +

+ +

+ +

+ 微信群 + 码云地址 + 公众号 + 公众号 +

Special Sponsors

+

+ +

+ + + +

+ + +1. **码云地址:** 如果访问速度比较慢的话,可以考虑访问本仓库的码云地址: ,Gitee 和 都是同步更新的。 +1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 +1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 + +## 目录 + +- [Java](#java) + - [基础](#基础) + - [容器](#容器) + - [并发](#并发) + - [JVM](#jvm) + - [I/O](#io) + - [Java 8](#java-8) +- [网络](#网络) +- [操作系统](#操作系统) + - [Linux相关](#linux相关) +- [数据结构与算法](#数据结构与算法) + - [数据结构](#数据结构) + - [算法](#算法) +- [数据存储](#数据存储) + - [MySQL](#mysql) + - [Redis](#redis) +- [系统设计](#系统设计) + - [设计模式](#设计模式) + - [常用框架](#常用框架) + - [数据通信](#数据通信) + - [网站架构](#网站架构) +- [面试指南](#面试指南) + - [备战面试](#备战面试) + - [常见面试题总结](#常见面试题总结) + - [面经](#面经) +- [工具](#工具) + - [Git](#git) + - [Docker](#Docker) +- [资料](#资料) + - [书单](#书单) +- [闲谈](#闲谈) +- [待办](#待办) +- [说明](#说明) + + +## Java + +### 基础 + +* [Java 基础知识回顾](./Java/Java基础知识.md) +* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) +* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) + +### 容器 + +* **常见问题总结:** + * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) +* **源码分析:** + * [ArrayList 源码学习](./Java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) + * [LinkedList 源码学习](./Java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) + +### 并发 + +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](./Java/Multithread/并发容器总结.md) + +### JVM + +* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) + +### I/O + +* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) + +### Java 8 + +* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) + +## 网络 + +* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) +* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) +* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) + +## 操作系统 + +### Linux相关 + +* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) +* [Shell 编程入门](./操作系统/Shell.md) + +## 数据结构与算法 + +### 数据结构 + +- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) + +### 算法 + +- [算法学习与面试](./数据结构与算法/算法.md) +- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) +- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) + +## 数据存储 + +### MySQL + +* [MySQL 学习与面试](./数据存储/MySQL.md) +* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) +* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) + +### Redis + +* [Redis 总结](./数据存储/Redis/Redis.md) +* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) +* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) + +## 系统设计 + +### 设计模式 + +- [设计模式系列文章](./Java/设计模式.md) + +### 常用框架 + +#### Spring + +- [Spring 学习与面试](./主流框架/Spring学习与面试.md) +- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) +- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) + +#### ZooKeeper + +- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) +- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) + +### 数据通信 + +- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) +- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) +- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) +- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) + +### 网站架构 + +- [一文读懂分布式应该学什么](./架构/分布式.md) +- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) + +## 面试指南 + +### 备战面试 + +* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) + +### 常见面试题总结 + +* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) + +### 面经 + +- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) + +## 工具 + +### Git + +* [Git入门](./Tools/Git.md) + +### Docker + +* [Docker 入门](./Tools/Docker.md) + +## 资料 + +### 书单 + +- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) + +## 闲谈 + +* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) +* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) + +*** + +## 待办 + +- [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +- [ ] Java 8 新特性详解 +- [ ] Java 多线程类别知识重构 +- [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) +- [ ] Netty 总结 +- [ ] 数据结构总结重构 + +## 说明 + +### 介绍 + +* **对于 Java 初学者来说:** 本文档倾向于给你提供一个比较详细的学习路径,让你对于Java整体的知识体系有一个初步认识。另外,本文的一些文章 +也是你学习和复习 Java 知识不错的实践; +* **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。 + +本文档 Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。 + +### 关于转载 + +如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。 + +### 如何对该开源文档进行贡献 + +1. 笔记内容大多是手敲,所以难免会有笔误,你可以帮我找错别字。 +2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。(**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!快提 pr 给我投稿吧!**) +3. 现有的知识点难免存在不完善或者错误,所以你可以对已有知识点的修改/补充。 + +### 为什么要做这个开源文档? + +初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。 + +### 联系我 + +添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。 + +![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) + +### Contributor + +下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! + + + + + + + + + + + + + + + + + +" + + + + + + + + + + + + + + + + +### 公众号 + +如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 + +**《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! + +**Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 + +![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334) diff --git a/_coverpage.md b/docs/_coverpage.md similarity index 100% rename from _coverpage.md rename to docs/_coverpage.md diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/Leetcode-LinkList1.md" b/docs/dataStructures-algorithms/Leetcode-LinkList1.md similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/Leetcode-LinkList1.md" rename to docs/dataStructures-algorithms/Leetcode-LinkList1.md diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.classpath" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.classpath" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.gitignore" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.gitignore" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.project" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.project similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.project" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.project diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs" b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/pom.xml" b/docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/pom.xml" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java" b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java" rename to docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" "b/docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" rename to "docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" "b/docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" rename to "docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" "b/docs/dataStructures-algorithms/\346\225\260\346\215\256\347\273\223\346\236\204.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\346\225\260\346\215\256\347\273\223\346\236\204.md" rename to "docs/dataStructures-algorithms/\346\225\260\346\215\256\347\273\223\346\236\204.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" rename to "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" b/docs/database/MySQL Index.md similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/MySQL Index.md" rename to docs/database/MySQL Index.md diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/MySQL.md" b/docs/database/MySQL.md similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/MySQL.md" rename to docs/database/MySQL.md diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" b/docs/database/Redis/Redis.md similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis.md" rename to docs/database/Redis/Redis.md diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis\346\214\201\344\271\205\345\214\226.md" "b/docs/database/Redis/Redis\346\214\201\344\271\205\345\214\226.md" similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redis\346\214\201\344\271\205\345\214\226.md" rename to "docs/database/Redis/Redis\346\214\201\344\271\205\345\214\226.md" diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" "b/docs/database/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" rename to "docs/database/Redis/Redlock\345\210\206\345\270\203\345\274\217\351\224\201.md" diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" "b/docs/database/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" rename to "docs/database/Redis/\345\246\202\344\275\225\345\201\232\345\217\257\351\235\240\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\357\274\214Redlock\347\234\237\347\232\204\345\217\257\350\241\214\344\271\210.md" diff --git "a/\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" "b/docs/database/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" similarity index 100% rename from "\346\225\260\346\215\256\345\255\230\345\202\250/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" rename to "docs/database/\344\270\200\345\215\203\350\241\214MySQL\345\221\275\344\273\244.md" diff --git "a/EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/docs/essential-content-for-interview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" similarity index 100% rename from "EssentialContentForInterview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" rename to "docs/essential-content-for-interview/BATJrealInterviewExperience/5\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" diff --git "a/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" "b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" similarity index 100% rename from "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" rename to "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\270\200\345\221\250\357\274\2102018-8-7\357\274\211.md" diff --git "a/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" "b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" similarity index 100% rename from "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" rename to "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\344\272\214\345\221\250(2018-8-13).md" diff --git "a/EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" "b/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" similarity index 100% rename from "EssentialContentForInterview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" rename to "docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/\347\254\254\345\233\233\345\221\250(2018-8-30).md" diff --git a/EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md b/docs/essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md similarity index 100% rename from EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md rename to docs/essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md diff --git a/EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md b/docs/essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md similarity index 100% rename from EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md rename to docs/essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md diff --git a/EssentialContentForInterview/PreparingForInterview/books.md b/docs/essential-content-for-interview/PreparingForInterview/books.md similarity index 100% rename from EssentialContentForInterview/PreparingForInterview/books.md rename to docs/essential-content-for-interview/PreparingForInterview/books.md diff --git a/EssentialContentForInterview/PreparingForInterview/interviewPrepare.md b/docs/essential-content-for-interview/PreparingForInterview/interviewPrepare.md similarity index 100% rename from EssentialContentForInterview/PreparingForInterview/interviewPrepare.md rename to docs/essential-content-for-interview/PreparingForInterview/interviewPrepare.md diff --git "a/EssentialContentForInterview/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/essential-content-for-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" similarity index 100% rename from "EssentialContentForInterview/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" rename to "docs/essential-content-for-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" diff --git "a/EssentialContentForInterview/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/essential-content-for-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" similarity index 100% rename from "EssentialContentForInterview/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" rename to "docs/essential-content-for-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" diff --git "a/EssentialContentForInterview/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/essential-content-for-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" similarity index 100% rename from "EssentialContentForInterview/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" rename to "docs/essential-content-for-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" diff --git "a/EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" "b/docs/essential-content-for-interview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" similarity index 100% rename from "EssentialContentForInterview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" rename to "docs/essential-content-for-interview/\346\211\213\346\212\212\346\211\213\346\225\231\344\275\240\347\224\250Markdown\345\206\231\344\270\200\344\273\275\351\253\230\350\264\250\351\207\217\347\232\204\347\256\200\345\216\206.md" diff --git "a/EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" "b/docs/essential-content-for-interview/\347\256\200\345\216\206\346\250\241\346\235\277.md" similarity index 100% rename from "EssentialContentForInterview/\347\256\200\345\216\206\346\250\241\346\235\277.md" rename to "docs/essential-content-for-interview/\347\256\200\345\216\206\346\250\241\346\235\277.md" diff --git "a/EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" "b/docs/essential-content-for-interview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" similarity index 100% rename from "EssentialContentForInterview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" rename to "docs/essential-content-for-interview/\351\235\242\350\257\225\345\277\205\345\244\207\344\271\213\344\271\220\350\247\202\351\224\201\344\270\216\346\202\262\350\247\202\351\224\201.md" diff --git a/index.html b/docs/index.html similarity index 100% rename from index.html rename to docs/index.html diff --git a/Java/ArrayList-Grow.md b/docs/java/ArrayList-Grow.md similarity index 100% rename from Java/ArrayList-Grow.md rename to docs/java/ArrayList-Grow.md diff --git a/Java/ArrayList.md b/docs/java/ArrayList.md similarity index 100% rename from Java/ArrayList.md rename to docs/java/ArrayList.md diff --git a/Java/BIO,NIO,AIO summary.md b/docs/java/BIO,NIO,AIO summary.md similarity index 100% rename from Java/BIO,NIO,AIO summary.md rename to docs/java/BIO,NIO,AIO summary.md diff --git a/Java/Basis/Arrays,CollectionsCommonMethods.md b/docs/java/Basis/Arrays,CollectionsCommonMethods.md similarity index 100% rename from Java/Basis/Arrays,CollectionsCommonMethods.md rename to docs/java/Basis/Arrays,CollectionsCommonMethods.md diff --git "a/Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" "b/docs/java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" similarity index 100% rename from "Java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" rename to "docs/java/Basis/final\343\200\201static\343\200\201this\343\200\201super.md" diff --git a/Java/HashMap.md b/docs/java/HashMap.md similarity index 100% rename from Java/HashMap.md rename to docs/java/HashMap.md diff --git "a/Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" similarity index 100% rename from "Java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" rename to "docs/java/J2EE\345\237\272\347\241\200\347\237\245\350\257\206.md" diff --git "a/Java/Java IO\344\270\216NIO.md" "b/docs/java/Java IO\344\270\216NIO.md" similarity index 100% rename from "Java/Java IO\344\270\216NIO.md" rename to "docs/java/Java IO\344\270\216NIO.md" diff --git "a/Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" similarity index 100% rename from "Java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" rename to "docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" diff --git "a/Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" "b/docs/java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" similarity index 100% rename from "Java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" rename to "docs/java/Java\350\231\232\346\213\237\346\234\272\357\274\210jvm\357\274\211.md" diff --git "a/Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" "b/docs/java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" similarity index 100% rename from "Java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" rename to "docs/java/Java\351\233\206\345\220\210\346\241\206\346\236\266\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230\346\200\273\347\273\223.md" diff --git a/Java/LinkedList.md b/docs/java/LinkedList.md similarity index 100% rename from Java/LinkedList.md rename to docs/java/LinkedList.md diff --git a/Java/Multithread/AQS.md b/docs/java/Multithread/AQS.md similarity index 100% rename from Java/Multithread/AQS.md rename to docs/java/Multithread/AQS.md diff --git a/Java/Multithread/Atomic.md b/docs/java/Multithread/Atomic.md similarity index 100% rename from Java/Multithread/Atomic.md rename to docs/java/Multithread/Atomic.md diff --git "a/Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" "b/docs/java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" similarity index 100% rename from "Java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" rename to "docs/java/Multithread/BATJ\351\203\275\347\210\261\351\227\256\347\232\204\345\244\232\347\272\277\347\250\213\351\235\242\350\257\225\351\242\230.md" diff --git "a/docs/java/Multithread/ConcurrentProgramming1-\345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java/Multithread/ConcurrentProgramming1-\345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\347\237\245\350\257\206.md" new file mode 100644 index 00000000000..0ae72071e0b --- /dev/null +++ "b/docs/java/Multithread/ConcurrentProgramming1-\345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -0,0 +1,269 @@ +# Java 并发基础知识 + +Java 并发的基础知识,可能会在笔试中遇到,技术面试中也可能以并发知识环节提问的第一个问题出现。比如面试官可能会问你:“谈谈自己对于进程和线程的理解,两者的区别是什么?” + +**本节思维导图:** + +![Java 并发基础知识](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-26/51390272.jpg) + +## 一 进程和线程 + +进程和线程的对比这一知识点由于过于基础,所以在面试中很少碰到,但是极有可能会在笔试题中碰到。 + +常见的提问形式是这样的:**“什么是线程和进程?,请简要描述线程与进程的关系、区别及优缺点? ”**。 + +### 1.1. 何为进程? + +进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 + +在Java中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。 + +如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe文件的运行)。 + +![进程](https://images.gitbook.cn/a0929b60-d133-11e8-88a4-5328c5b70145) + +### 1.2 何为线程? + +线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的**堆**和**方法区**资源,但每个线程有自己的**程序计数器**、**虚拟机栈**和**本地方法栈**,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。 + +Java 程序天生就是多线程程序,我们可以通过 JMX 来看一下一个普通的 Java 程序有哪些线程,代码如下。 + +```java +public class MultiThread { + public static void main(String[] args) { + // 获取Java线程管理MXBean + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + // 不需要获取同步的monitor和synchronizer信息,仅获取线程和线程堆栈信息 + ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false); + // 遍历线程信息,仅打印线程ID和线程名称信息 + for (ThreadInfo threadInfo : threadInfos) { + System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName()); + } + } +} +``` + +上述程序输出如下(输出内容可能不同,不用太纠结下面每个线程的作用,只用知道 main 线程执行main方法即可): + +``` +[5] Attach Listener //添加事件 +[4] Signal Dispatcher // 分发处理给JVM信号的线程 +[3] Finalizer //调用对象finalize方法的线程 +[2] Reference Handler //清除reference线程 +[1] main //main线程,程序入口 +``` + +从上面的输出内容可以看出:**一个 Java 程序的运行是 main 线程和多个其他线程同时运行**。 + +### 1.3 从 JVM 角度说进程和线程之间的关系(重要) + +#### 1.3.1 图解进程和线程的关系 + +下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。如果你对 Java 内存区域(运行时数据区)这部分知识不太了解的话可以阅读一下我的这篇文章:[《可能是把Java内存区域讲的最清楚的一篇文章》](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/可能是把Java内存区域讲的最清楚的一篇文章.md) + +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/JVM运行时数据区域.png) + +从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的**堆**和**方法区**资源,但是每个线程有自己的**程序计数器**、**虚拟机栈** 和 **本地方法栈**。 + +下面来思考这样一个问题:为什么**程序计数器**、**虚拟机栈**和**本地方法栈**是线程私有的呢?为什么堆和方法区是线程共享的呢? + +#### 1.3.2 程序计数器为什么是私有的? + +程序计数器主要有下面两个作用: + +1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。 +2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。 + +需要注意的是,如果执行的是native方法,那么程序计数器记录的是undefined地址,只有执行的是Java代码时程序计数器记录的才是下一条指令的地址。 + +所以,程序计数器私有主要是为了**线程切换后能恢复到正确的执行位置**。 + +#### 1.3.3 虚拟机栈和本地方法栈为什么是私有的? + +- **虚拟机栈:**每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 +- **本地方法栈:**和虚拟机栈所发挥的作用非常相似,区别是: **虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。** 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。 + +所以,为了**保证线程中的局部变量不被别的线程访问到**,虚拟机栈和本地方法栈是线程私有的。 + +#### 1.3.4 一句话简单了解堆和方法区 + +堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象(所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 + +## 二 多线程并发编程 + +### 2.1 并发与并行 + +- **并发:** 同一时间段,多个任务都在执行(单位时间内不一定同时执行); +- **并行:**单位时间内,多个任务同时执行。 + +### 2.1 多线程并发编程详解 + +单CPU时代多个任务共享一个CPU,某一特定时刻只能有一个任务被执行,CPU会分配时间片给当前要执行的任务。当一个任务占用CPU时,其他任务就会被挂起。当占用CPU的任务的时间片用完后,才会由 CPU 选择下一个需要执行的任务。所以说,在单核CPU时代,多线程编程没有太大意义,反而会因为线程间频繁的上下文切换而带来额外开销。 + +但现在 CPU 一般都是多核,如果这个CPU是多核的话,那么进程中的不同线程可以使用不同核心,实现了真正意义上的并行运行。**那为什么我们不直接叫做多线程并行编程呢?** + +**这是因为多线程在实际开发使用中,线程的个数往往多于CPU的个数,所以一般都称多线程并发编程而不是多线程并行编程。`** + +### 2.2 为什么要多线程并发编程? + +- **从计算机底层来说:**线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。 + +- **从当代互联网发展趋势来说:**现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。 + +## 三 线程的创建与运行 + +前两种实际上很少使用,一般都是用线程池的方式比较多一点。 + +### 3.1 继承 Thread 类的方式 + + +```java +public class MyThread extends Thread { + @Override + public void run() { + super.run(); + System.out.println("MyThread"); + } +} +``` +Run.java + +```java +public class Run { + + public static void main(String[] args) { + MyThread mythread = new MyThread(); + mythread.start(); + System.out.println("运行结束"); + } + +} + +``` +运行结果: +![结果](https://user-gold-cdn.xitu.io/2018/3/20/16243e80f22a2d54?w=161&h=54&f=jpeg&s=7380) + +从上面的运行结果可以看出:线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法。 + +### 3.2 实现Runnable接口的方式 + +推荐实现Runnable接口方式开发多线程,因为Java单继承但是可以实现多个接口。 + +MyRunnable.java + +```java +public class MyRunnable implements Runnable { + @Override + public void run() { + System.out.println("MyRunnable"); + } +} +``` + +Run.java + +```java +public class Run { + + public static void main(String[] args) { + Runnable runnable=new MyRunnable(); + Thread thread=new Thread(runnable); + thread.start(); + System.out.println("运行结束!"); + } + +} +``` +运行结果: +![运行结果](https://user-gold-cdn.xitu.io/2018/3/20/16243f4373c6141a?w=137&h=46&f=jpeg&s=7316) + +### 3.3 使用线程池的方式 + +使用线程池的方式也是最推荐的一种方式,另外,《阿里巴巴Java开发手册》在第一章第六节并发处理这一部分也强调到“线程资源必须通过线程池提供,不允许在应用中自行显示创建线程”。这里就不给大家演示代码了,线程池这一节会详细介绍到这部分内容。 + +## 四 线程的生命周期和状态 + +Java 线程在运行的生命周期中的指定时刻只可能处于下面6种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4节)。 + +![Java线程的状态](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%E7%BA%BF%E7%A8%8B%E7%9A%84%E7%8A%B6%E6%80%81.png) + +线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4节): + +![Java线程状态变迁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%20%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81.png) + + + +由上图可以看出: + +线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 cpu 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。 + +> 操作系统隐藏 Java虚拟机(JVM)中的 RUNNABLE 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinjava.com/):[Java Thread Life Cycle and Thread States](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/)),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。 + +![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png) + +当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)**状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的` run() `方法之后将会进入到 **TERMINATED(终止)** 状态。 + +## 五 线程优先级 + +**理论上**来说系统会根据优先级来决定首先使哪个线程进入运行状态。当 CPU 比较闲的时候,设置线程优先级几乎不会有任何作用,而且很多操作系统压根不会不会理会你设置的线程优先级,所以不要让业务过度依赖于线程的优先级。 + +另外,**线程优先级具有继承特性**比如A线程启动B线程,则B线程的优先级和A是一样的。**线程优先级还具有随机性** 也就是说线程优先级高的不一定每一次都先执行完。 + +Thread类中包含的成员变量代表了线程的某些优先级。如**Thread.MIN_PRIORITY(常数1)**,**Thread.NORM_PRIORITY(常数5)**,**Thread.MAX_PRIORITY(常数10)**。其中每个线程的优先级都在**1** 到**10** 之间,在默认情况下优先级都是**Thread.NORM_PRIORITY(常数5)**。 + +**一般情况下,不会对线程设定优先级别,更不会让某些业务严重地依赖线程的优先级别,比如权重,借助优先级设定某个任务的权重,这种方式是不可取的,一般定义线程的时候使用默认的优先级就好了。** + +**相关方法:** + +```java +public final void setPriority(int newPriority) //为线程设定优先级 +public final int getPriority() //获取线程的优先级 +``` +**设置线程优先级方法源码:** + +```java + public final void setPriority(int newPriority) { + ThreadGroup g; + checkAccess(); + //线程游戏优先级不能小于1也不能大于10,否则会抛出异常 + if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { + throw new IllegalArgumentException(); + } + //如果指定的线程优先级大于该线程所在线程组的最大优先级,那么该线程的优先级将设为线程组的最大优先级 + if((g = getThreadGroup()) != null) { + if (newPriority > g.getMaxPriority()) { + newPriority = g.getMaxPriority(); + } + setPriority0(priority = newPriority); + } + } + +``` + +## 六 守护线程和用户线程 + +**守护线程和用户线程简介:** + +- **用户(User)线程:**运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程 +- **守护(Daemon)线程:**运行在后台,为其他前台线程服务.也可以说守护线程是JVM中非守护线程的 **“佣人”**。一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作. + +main 函数所在的线程就是一个用户线程啊,main函数启动的同时在JVM内部同时还启动了好多守护线程,比如垃圾回收线程。 + +**那么守护线程和用户线程有什么区别呢?** + +比较明显的区别之一是用户线程结束,JVM退出,不管这个时候有没有守护线程运行。而守护线程不会影响 JVM 的退出。 + +**注意事项:** + +1. `setDaemon(true)`必须在`start()`方法前执行,否则会抛出 `IllegalThreadStateException` 异常 +2. 在守护线程中产生的新线程也是守护线程 +3. 不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑 +4. 守护(Daemon)线程中不能依靠 finally 块的内容来确保执行关闭或清理资源的逻辑。因为我们上面也说过了一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作,所以守护(Daemon)线程中的finally语句块可能无法被执行。 + + + +## 参考 + +- 《Java并发编程之美》 +- 《Java并发编程的艺术》 +- https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/ \ No newline at end of file diff --git "a/Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" "b/docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" similarity index 100% rename from "Java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" rename to "docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" diff --git "a/Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" "b/docs/java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" similarity index 100% rename from "Java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" rename to "docs/java/What's New in JDK8/JDK8\346\216\245\345\217\243\350\247\204\350\214\203-\351\235\231\346\200\201\343\200\201\351\273\230\350\256\244\346\226\271\346\263\225.md" diff --git a/Java/What's New in JDK8/Java8Tutorial.md b/docs/java/What's New in JDK8/Java8Tutorial.md similarity index 100% rename from Java/What's New in JDK8/Java8Tutorial.md rename to docs/java/What's New in JDK8/Java8Tutorial.md diff --git "a/Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" "b/docs/java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" similarity index 100% rename from "Java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" rename to "docs/java/What's New in JDK8/Lambda\350\241\250\350\276\276\345\274\217.md" diff --git a/Java/What's New in JDK8/README.md b/docs/java/What's New in JDK8/README.md similarity index 100% rename from Java/What's New in JDK8/README.md rename to docs/java/What's New in JDK8/README.md diff --git a/docs/java/What's New in JDK8/Stream.md b/docs/java/What's New in JDK8/Stream.md new file mode 100644 index 00000000000..de7c86e3f2e --- /dev/null +++ b/docs/java/What's New in JDK8/Stream.md @@ -0,0 +1,75 @@ +Stream API 旨在让编码更高效率、干净、简洁。 + +### 从迭代器到Stream操作 + +当使用 `Stream` 时,我们一般会通过三个阶段建立一个流水线: + +1. 创建一个 `Stream`; +2. 进行一个或多个中间操作; +3. 使用终止操作产生一个结果,`Stream` 就不会再被使用了。 + +**案例1:统计 List 中的单词长度大于6的个数** + +```java +/** +* 案例1:统计 List 中的单词长度大于6的个数 +*/ +ArrayList wordsList = new ArrayList(); +wordsList.add("Charles"); +wordsList.add("Vincent"); +wordsList.add("William"); +wordsList.add("Joseph"); +wordsList.add("Henry"); +wordsList.add("Bill"); +wordsList.add("Joan"); +wordsList.add("Linda"); +int count = 0; +``` +Java8之前我们通常用迭代方法来完成上面的需求: + +```java +//迭代(Java8之前的常用方法) +//迭代不好的地方:1. 代码多;2 很难被并行运算。 +for (String word : wordsList) { + if (word.length() > 6) { + count++; + } +} +System.out.println(count);//3 +``` +Java8之前我们使用 `Stream` 一行代码就能解决了,而且可以瞬间转换为并行执行的效果: + +```java +//Stream +//将stream()改为parallelStream()就可以瞬间将代码编程并行执行的效果 +long count2=wordsList.stream() + .filter(w->w.length()>6) + .count(); +long count3=wordsList.parallelStream() + .filter(w->w.length()>6) + .count(); +System.out.println(count2); +System.out.println(count3); +``` + +### `distinct()` + +去除 List 中重复的 String + +```java +List list = list.stream() + .distinct() + .collect(Collectors.toList()); +``` + +### `map` + +map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数: + +```java +List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); +// 获取 List 中每个元素对应的平方数并去重 +List squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList()); +System.out.println(squaresList.toString());//[9, 4, 49, 25] +``` + diff --git "a/Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" "b/docs/java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" similarity index 100% rename from "Java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" rename to "docs/java/What's New in JDK8/\346\224\271\350\277\233\347\232\204\347\261\273\345\236\213\346\216\250\346\226\255.md" diff --git "a/Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" "b/docs/java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" similarity index 100% rename from "Java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" rename to "docs/java/What's New in JDK8/\351\200\232\350\277\207\345\217\215\345\260\204\350\216\267\345\276\227\346\226\271\346\263\225\347\232\204\345\217\202\346\225\260\344\277\241\346\201\257.md" diff --git a/Java/synchronized.md b/docs/java/synchronized.md similarity index 100% rename from Java/synchronized.md rename to docs/java/synchronized.md diff --git "a/Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" similarity index 100% rename from "Java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" rename to "docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" diff --git "a/Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" "b/docs/java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" similarity index 100% rename from "Java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" rename to "docs/java/\345\244\232\347\272\277\347\250\213\347\263\273\345\210\227.md" diff --git "a/Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" "b/docs/java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" similarity index 100% rename from "Java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" rename to "docs/java/\346\220\236\345\256\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\260\261\346\230\257\350\277\231\344\271\210\347\256\200\345\215\225.md" diff --git "a/Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" "b/docs/java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" similarity index 100% rename from "Java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" rename to "docs/java/\350\277\231\345\207\240\351\201\223Java\351\233\206\345\220\210\346\241\206\346\236\266\351\235\242\350\257\225\351\242\230\345\207\240\344\271\216\345\277\205\351\227\256.md" diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/HTTPS\344\270\255\347\232\204TLS.md" "b/docs/network/HTTPS\344\270\255\347\232\204TLS.md" similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/HTTPS\344\270\255\347\232\204TLS.md" rename to "docs/network/HTTPS\344\270\255\347\232\204TLS.md" diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" "b/docs/network/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" rename to "docs/network/\345\271\262\350\264\247\357\274\232\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\347\237\245\350\257\206\346\200\273\347\273\223.md" diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" "b/docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" rename to "docs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" diff --git "a/\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" b/docs/operating-system/Shell.md similarity index 100% rename from "\346\223\215\344\275\234\347\263\273\347\273\237/Shell.md" rename to docs/operating-system/Shell.md diff --git "a/\346\223\215\344\275\234\347\263\273\347\273\237/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/operating-system/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" similarity index 100% rename from "\346\223\215\344\275\234\347\263\273\347\273\237/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" rename to "docs/operating-system/\345\220\216\347\253\257\347\250\213\345\272\217\345\221\230\345\277\205\345\244\207\347\232\204Linux\345\237\272\347\241\200\347\237\245\350\257\206.md" diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/dubbo.md" b/docs/system-design/data-communication/dubbo.md similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/dubbo.md" rename to docs/system-design/data-communication/dubbo.md diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/message-queue.md" b/docs/system-design/data-communication/message-queue.md similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/message-queue.md" rename to docs/system-design/data-communication/message-queue.md diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" b/docs/system-design/data-communication/rabbitmq.md similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/rabbitmq.md" rename to docs/system-design/data-communication/rabbitmq.md diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" "b/docs/system-design/data-communication/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" similarity index 100% rename from "\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\270\216\346\225\260\346\215\256\351\200\232\344\277\241/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" rename to "docs/system-design/data-communication/\346\225\260\346\215\256\351\200\232\344\277\241(RESTful\343\200\201RPC\343\200\201\346\266\210\346\201\257\351\230\237\345\210\227).md" diff --git "a/\344\270\273\346\265\201\346\241\206\346\236\266/SpringBean.md" b/docs/system-design/framework/SpringBean.md similarity index 100% rename from "\344\270\273\346\265\201\346\241\206\346\236\266/SpringBean.md" rename to docs/system-design/framework/SpringBean.md diff --git "a/\344\270\273\346\265\201\346\241\206\346\236\266/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/system-design/framework/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" similarity index 100% rename from "\344\270\273\346\265\201\346\241\206\346\236\266/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" rename to "docs/system-design/framework/SpringMVC \345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" diff --git "a/\344\270\273\346\265\201\346\241\206\346\236\266/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" "b/docs/system-design/framework/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" similarity index 100% rename from "\344\270\273\346\265\201\346\241\206\346\236\266/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" rename to "docs/system-design/framework/Spring\345\255\246\344\271\240\344\270\216\351\235\242\350\257\225.md" diff --git "a/\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper.md" b/docs/system-design/framework/ZooKeeper.md similarity index 100% rename from "\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper.md" rename to docs/system-design/framework/ZooKeeper.md diff --git "a/\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" "b/docs/system-design/framework/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" similarity index 100% rename from "\344\270\273\346\265\201\346\241\206\346\236\266/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" rename to "docs/system-design/framework/ZooKeeper\346\225\260\346\215\256\346\250\241\345\236\213\345\222\214\345\270\270\350\247\201\345\221\275\344\273\244.md" diff --git "a/\346\236\266\346\236\204/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" "b/docs/system-design/website-architecture/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" similarity index 100% rename from "\346\236\266\346\236\204/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" rename to "docs/system-design/website-architecture/8 \345\274\240\345\233\276\350\257\273\346\207\202\345\244\247\345\236\213\347\275\221\347\253\231\346\212\200\346\234\257\346\236\266\346\236\204.md" diff --git "a/\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" "b/docs/system-design/website-architecture/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" similarity index 100% rename from "\346\236\266\346\236\204/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" rename to "docs/system-design/website-architecture/\343\200\220\351\235\242\350\257\225\347\262\276\351\200\211\343\200\221\345\205\263\344\272\216\345\244\247\345\236\213\347\275\221\347\253\231\347\263\273\347\273\237\346\236\266\346\236\204\344\275\240\344\270\215\345\276\227\344\270\215\346\207\202\347\232\20410\344\270\252\351\227\256\351\242\230.md" diff --git "a/\346\236\266\346\236\204/\345\210\206\345\270\203\345\274\217.md" "b/docs/system-design/website-architecture/\345\210\206\345\270\203\345\274\217.md" similarity index 100% rename from "\346\236\266\346\236\204/\345\210\206\345\270\203\345\274\217.md" rename to "docs/system-design/website-architecture/\345\210\206\345\270\203\345\274\217.md" diff --git "a/Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" "b/docs/system-design/\350\256\276\350\256\241\346\250\241\345\274\217.md" similarity index 100% rename from "Java/\350\256\276\350\256\241\346\250\241\345\274\217.md" rename to "docs/system-design/\350\256\276\350\256\241\346\250\241\345\274\217.md" diff --git a/Tools/Docker.md b/docs/tools/Docker.md similarity index 100% rename from Tools/Docker.md rename to docs/tools/Docker.md diff --git a/Tools/Git.md b/docs/tools/Git.md similarity index 100% rename from Tools/Git.md rename to docs/tools/Git.md diff --git "a/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" "b/docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" similarity index 100% rename from "\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" rename to "docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" "b/docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" similarity index 100% rename from "\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" rename to "docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" "b/docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" similarity index 100% rename from "\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" rename to "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" "b/docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" similarity index 100% rename from "\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" rename to "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" diff --git "a/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" "b/docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" similarity index 100% rename from "\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" rename to "docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" diff --git "a/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" "b/docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" similarity index 100% rename from "\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" rename to "docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" diff --git "a/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" "b/docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" similarity index 100% rename from "\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" rename to "docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" From e584bdf2fec8fdb5d1b42dca5e2f218b504375ce Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 17:22:18 +0800 Subject: [PATCH 192/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf1e591ed9d..8a9350c5f3c 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ - [一文读懂分布式应该学什么](docs/system-design/website-architecture/分布式.md) - [8 张图读懂大型网站技术架构](docs/system-design/website-architecture/8%20张图读懂大型网站技术架构.md) -- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](docs/system-design/website-architecture/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](docs/system-design/website-architecture/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) ## 面试指南 From 1b356af175c92f65d36003cc3e8caae4c055d086 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 17:22:51 +0800 Subject: [PATCH 193/232] Update README.md From 19bd7cd3588f93b1113cebfe1c41314b29df0057 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 17:31:51 +0800 Subject: [PATCH 194/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- docs/java/{BIO,NIO,AIO summary.md => BIO-NIO-AIO.md} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename docs/java/{BIO,NIO,AIO summary.md => BIO-NIO-AIO.md} (100%) diff --git a/README.md b/README.md index 8a9350c5f3c..53cf12fadcb 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ * [Java 基础知识回顾](docs/java/Java基础知识.md) * [J2EE 基础知识回顾](docs/java/J2EE基础知识.md) -* [Collections 工具类和 Arrays 工具类常见方法](./java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Collections 工具类和 Arrays 工具类常见方法](docs/java/Basis/Arrays%2CCollectionsCommonMethods.md) * [Java常见关键字总结:static、final、this、super](docs/java/Basis/final、static、this、super.md) ### 容器 @@ -83,7 +83,7 @@ ### 并发 * [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](docs/java/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](docs/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:乐观锁与悲观锁](docs/essential-content-for-interview/面试必备之乐观锁与悲观锁.md) * [并发编程面试必备:JUC 中的 Atomic 原子类总结](docs/java/Multithread/Atomic.md) * [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](docs/java/Multithread/AQS.md) * [BATJ都爱问的多线程面试题](docs/java/Multithread/BATJ都爱问的多线程面试题.md) @@ -97,8 +97,8 @@ ### I/O -* [BIO,NIO,AIO 总结 ](docs/java/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](docs/Java/Java%20IO与NIO.md) +* [BIO,NIO,AIO 总结 ](docs/java/BIO-NIO-AIO.md) +* [Java IO 与 NIO系列文章](docs/java/Java%20IO与NIO.md) ### Java 8 diff --git a/docs/java/BIO,NIO,AIO summary.md b/docs/java/BIO-NIO-AIO.md similarity index 100% rename from docs/java/BIO,NIO,AIO summary.md rename to docs/java/BIO-NIO-AIO.md From 434d3a095c6f99a306f4fabc9c3f8fdda267cbf4 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 18:09:29 +0800 Subject: [PATCH 195/232] =?UTF-8?q?Update=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HomePage.md | 136 +++++++++++---------- docs/README.md | 310 ----------------------------------------------- 2 files changed, 70 insertions(+), 376 deletions(-) delete mode 100644 docs/README.md diff --git a/docs/HomePage.md b/docs/HomePage.md index ba25479f367..23cdaa1e320 100644 --- a/docs/HomePage.md +++ b/docs/HomePage.md @@ -9,152 +9,156 @@ ### 基础 -* [Java 基础知识回顾](./Java/Java基础知识.md) -* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) -* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) -* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) +* [Java 基础知识回顾](./java/Java基础知识.md) +* [J2EE 基础知识回顾](./java/J2EE基础知识.md) +* [Collections 工具类和 Arrays 工具类常见方法](./java/Basis/Arrays%2CCollectionsCommonMethods.md) +* [Java常见关键字总结:static、final、this、super](./java/Basis/final、static、this、super.md) ### 容器 * **常见问题总结:** - * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) - * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) + * [这几道Java集合框架面试题几乎必问](./java/这几道Java集合框架面试题几乎必问.md) + * [Java 集合框架常见面试题总结](./java/Java集合框架常见面试题总结.md) * **源码分析:** - * [ArrayList 源码学习](./Java/ArrayList.md) - * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) - * [LinkedList 源码学习](./Java/LinkedList.md) - * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) + * [ArrayList 源码学习](./java/ArrayList.md) + * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./java/ArrayList-Grow.md) + * [LinkedList 源码学习](./java/LinkedList.md) + * [HashMap(JDK1.8)源码学习](./java/HashMap.md) ### 并发 -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](./Java/Multithread/并发容器总结.md) +* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./java/synchronized.md) +* [并发编程面试必备:乐观锁与悲观锁](./essential-content-for-interview/面试必备之乐观锁与悲观锁.md) +* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./java/Multithread/Atomic.md) +* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./java/Multithread/AQS.md) +* [BATJ都爱问的多线程面试题](./java/Multithread/BATJ都爱问的多线程面试题.md) +* [并发容器总结](./java/Multithread/并发容器总结.md) ### JVM -* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) +* [可能是把Java内存区域讲的最清楚的一篇文章](./java/可能是把Java内存区域讲的最清楚的一篇文章.md) +* [搞定JVM垃圾回收就是这么简单](./java/搞定JVM垃圾回收就是这么简单.md) +* [《深入理解Java虚拟机》第2版学习笔记](./java/Java虚拟机(jvm).md) ### I/O -* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) +* [BIO,NIO,AIO 总结 ](./java/BIO-NIO-AIO.md) +* [Java IO 与 NIO系列文章](./java/Java%20IO与NIO.md) ### Java 8 -* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [Java 8 新特性总结](./java/What's%20New%20in%20JDK8/Java8Tutorial.md) ## 网络 -* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) -* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) -* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) +* [计算机网络常见面试题](./network/计算机网络.md) +* [计算机网络基础知识总结](./network/干货:计算机网络知识总结.md) +* [HTTPS中的TLS](./network/HTTPS中的TLS.md) ## 操作系统 ### Linux相关 -* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) -* [Shell 编程入门](./操作系统/Shell.md) +* [后端程序员必备的 Linux 基础知识](./operating-system/后端程序员必备的Linux基础知识.md) +* [Shell 编程入门](./operating-system/Shell.md) ## 数据结构与算法 ### 数据结构 -- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) +- [数据结构知识学习与面试](./dataStructures-algorithms/数据结构.md) ### 算法 -- [算法学习与面试](./数据结构与算法/算法.md) -- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) -- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) -- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) +- [算法学习与面试](./dataStructures-algorithms/算法.md) +- [算法总结——几道常见的子符串算法题 ](./dataStructures-algorithms/搞定BAT面试——几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](./dataStructures-algorithms/Leetcode-LinkList1.md) +- [常见安全算法(MD5、SHA1、Base64等等)总结](./dataStructures-algorithms/常见安全算法(MD5、SHA1、Base64等等)总结.md) -## 数据存储 +## 数据库 ### MySQL -* [MySQL 学习与面试](./数据存储/MySQL.md) -* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) -* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) +* [MySQL 学习与面试](./database/MySQL.md) +* [【思维导图-索引篇】搞定数据库索引就是这么简单](./database/MySQL%20Index.md) +* [一千行MySQL学习笔记](./database/一千行MySQL命令.md) ### Redis -* [Redis 总结](./数据存储/Redis/Redis.md) -* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) -* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) +* [Redis 总结](./database/Redis/Redis.md) +* [Redlock分布式锁](./database/Redis/Redlock分布式锁.md) +* [如何做可靠的分布式锁,Redlock真的可行么](./database/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) ## 系统设计 ### 设计模式 -- [设计模式系列文章](./Java/设计模式.md) +- [设计模式系列文章](./system-design/设计模式.md) ### 常用框架 #### Spring -- [Spring 学习与面试](./主流框架/Spring学习与面试.md) -- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) -- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) +- [Spring 学习与面试](./system-design/framework/Spring学习与面试.md) +- [Spring中bean的作用域与生命周期](./system-design/framework/SpringBean.md) +- [SpringMVC 工作原理详解](./system-design/framework/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) #### ZooKeeper -- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) -- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) +- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./system-design/framework/ZooKeeper.md) +- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./system-design/framework/ZooKeeper数据模型和常见命令.md) ### 数据通信 -- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) -- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) -- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) -- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) +- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./system-design/data-communication/数据通信(RESTful、RPC、消息队列).md) +- [Dubbo 总结:关于 Dubbo 的重要知识点](./system-design/data-communication/dubbo.md) +- [消息队列总结:新手也能看懂,消息队列其实很简单](./system-design/data-communication/message-queue.md) +- [一文搞懂 RabbitMQ 的重要概念以及安装](./system-design/data-communication/rabbitmq.md) ### 网站架构 -- [一文读懂分布式应该学什么](./架构/分布式.md) -- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) -- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) +- [一文读懂分布式应该学什么](./system-design/website-architecture/分布式.md) +- [8 张图读懂大型网站技术架构](./system-design/website-architecture/8%20张图读懂大型网站技术架构.md) +- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./system-design/website-architecture/【面试精选】关于大型网站系统架构你不得不懂的10个问题.md) ## 面试指南 ### 备战面试 -* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) -* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) -* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) -* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) -* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) -* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) -* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) +* [【备战面试1】程序员的简历就该这样写](./essential-content-for-interview/PreparingForInterview/程序员的简历之道.md) +* [【备战面试2】初出茅庐的程序员该如何准备面试?](./essential-content-for-interview/PreparingForInterview/interviewPrepare.md) +* [【备战面试3】7个大部分程序员在面试前很关心的问题](./essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md) +* [【备战面试4】Java程序员必备书单](./essential-content-for-interview/PreparingForInterview/books.md) +* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md) +* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./essential-content-for-interview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) +* [【备战面试7】美团面试常见问题总结(附详解答案)](./essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md) ### 常见面试题总结 -* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) -* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) -* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) -* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) +* [第一周(2018-8-7)](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) +* [第二周(2018-8-13)](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) +* [第三周(2018-08-22)](./java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) +* [第四周(2018-8-30).md](./essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) ### 面经 -- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) +- [5面阿里,终获offer(2018年秋招)](./essential-content-for-interview/BATJrealInterviewExperience/5面阿里,终获offer.md) ## 工具 ### Git -* [Git入门看这一篇就够了](./DevelopCommonTools/GitIntroduce.md) +* [Git入门](./tools/Git.md) + +### Docker + +* [Docker 入门](./tools/Docker.md) ## 资料 ### 书单 -- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) +- [Java程序员必备书单](./essential-content-for-interview//PreparingForInterview/books.md) ## 闲谈 diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 52f6ecb7452..00000000000 --- a/docs/README.md +++ /dev/null @@ -1,310 +0,0 @@ -

Java 学习/面试指南

- -

- -

- -

- 微信群 - 码云地址 - 公众号 - 公众号 -

Special Sponsors

-

- -

- - - -

- - -1. **码云地址:** 如果访问速度比较慢的话,可以考虑访问本仓库的码云地址: ,Gitee 和 都是同步更新的。 -1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 -1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 - -## 目录 - -- [Java](#java) - - [基础](#基础) - - [容器](#容器) - - [并发](#并发) - - [JVM](#jvm) - - [I/O](#io) - - [Java 8](#java-8) -- [网络](#网络) -- [操作系统](#操作系统) - - [Linux相关](#linux相关) -- [数据结构与算法](#数据结构与算法) - - [数据结构](#数据结构) - - [算法](#算法) -- [数据存储](#数据存储) - - [MySQL](#mysql) - - [Redis](#redis) -- [系统设计](#系统设计) - - [设计模式](#设计模式) - - [常用框架](#常用框架) - - [数据通信](#数据通信) - - [网站架构](#网站架构) -- [面试指南](#面试指南) - - [备战面试](#备战面试) - - [常见面试题总结](#常见面试题总结) - - [面经](#面经) -- [工具](#工具) - - [Git](#git) - - [Docker](#Docker) -- [资料](#资料) - - [书单](#书单) -- [闲谈](#闲谈) -- [待办](#待办) -- [说明](#说明) - - -## Java - -### 基础 - -* [Java 基础知识回顾](./Java/Java基础知识.md) -* [J2EE 基础知识回顾](./Java/J2EE基础知识.md) -* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md) -* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md) - -### 容器 - -* **常见问题总结:** - * [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md) - * [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md) -* **源码分析:** - * [ArrayList 源码学习](./Java/ArrayList.md) - * [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md) - * [LinkedList 源码学习](./Java/LinkedList.md) - * [HashMap(JDK1.8)源码学习](./Java/HashMap.md) - -### 并发 - -* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md) -* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md) -* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md) -* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md) -* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md) -* [并发容器总结](./Java/Multithread/并发容器总结.md) - -### JVM - -* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md) -* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md) -* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md) - -### I/O - -* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) -* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md) - -### Java 8 - -* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) - -## 网络 - -* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md) -* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md) -* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md) - -## 操作系统 - -### Linux相关 - -* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md) -* [Shell 编程入门](./操作系统/Shell.md) - -## 数据结构与算法 - -### 数据结构 - -- [数据结构知识学习与面试](./数据结构与算法/数据结构.md) - -### 算法 - -- [算法学习与面试](./数据结构与算法/算法.md) -- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md) -- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md) -- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md) - -## 数据存储 - -### MySQL - -* [MySQL 学习与面试](./数据存储/MySQL.md) -* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md) -* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md) - -### Redis - -* [Redis 总结](./数据存储/Redis/Redis.md) -* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md) -* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md) - -## 系统设计 - -### 设计模式 - -- [设计模式系列文章](./Java/设计模式.md) - -### 常用框架 - -#### Spring - -- [Spring 学习与面试](./主流框架/Spring学习与面试.md) -- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md) -- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md) - -#### ZooKeeper - -- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md) -- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md) - -### 数据通信 - -- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md) -- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md) -- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md) -- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md) - -### 网站架构 - -- [一文读懂分布式应该学什么](./架构/分布式.md) -- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md) -- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md) - -## 面试指南 - -### 备战面试 - -* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md) -* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md) -* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md) -* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) -* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md) -* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md) -* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md) - -### 常见面试题总结 - -* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals) -* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) -* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结) -* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。) - -### 面经 - -- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md) - -## 工具 - -### Git - -* [Git入门](./Tools/Git.md) - -### Docker - -* [Docker 入门](./Tools/Docker.md) - -## 资料 - -### 书单 - -- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md) - -## 闲谈 - -* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) -* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) - -*** - -## 待办 - -- [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md) -- [ ] Java 8 新特性详解 -- [ ] Java 多线程类别知识重构 -- [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md) -- [ ] Netty 总结 -- [ ] 数据结构总结重构 - -## 说明 - -### 介绍 - -* **对于 Java 初学者来说:** 本文档倾向于给你提供一个比较详细的学习路径,让你对于Java整体的知识体系有一个初步认识。另外,本文的一些文章 -也是你学习和复习 Java 知识不错的实践; -* **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。 - -本文档 Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。 - -### 关于转载 - -如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。 - -### 如何对该开源文档进行贡献 - -1. 笔记内容大多是手敲,所以难免会有笔误,你可以帮我找错别字。 -2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。(**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!快提 pr 给我投稿吧!**) -3. 现有的知识点难免存在不完善或者错误,所以你可以对已有知识点的修改/补充。 - -### 为什么要做这个开源文档? - -初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。 - -### 联系我 - -添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。 - -![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg) - -### Contributor - -下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后! - - - - - - - - - - - - - - - - - -" - - - - - - - - - - - - - - - - -### 公众号 - -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 - -**《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取! - -**Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。 - -![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334) From f7ce596dde75b5c677979e945fd2a6aefad651ad Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 18:16:39 +0800 Subject: [PATCH 196/232] =?UTF-8?q?Add=20=E5=9C=A8=E7=BA=BF=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53cf12fadcb..3f9604daf6f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@

-1. **码云地址:** 如果访问速度比较慢的话,可以考虑访问本仓库的码云地址: ,Gitee 和 都是同步更新的。 +1. **如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。 1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 From 0f121f1ddd3cd9b3c745c3b05d6b1f2ec0117a87 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 18:25:59 +0800 Subject: [PATCH 197/232] Add docsify --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f9604daf6f..1cdf1f22aa3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@

-1. **如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。 +1. **如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 @@ -240,7 +240,9 @@ 也是你学习和复习 Java 知识不错的实践; * **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。 -本文档 Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。 +Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)。 + +利用 docsify 生成文档部署在 Github pages: [docsify 官网介绍](https://docsify.js.org/#/) ### 关于转载 From a6274b4774c41c4e4ed8b0fc65493c90ed68e947 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 19:12:32 +0800 Subject: [PATCH 198/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\221\345\256\271\345\231\250\346\200\273\347\273\223.md" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" "b/docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" index 96a9fe23176..22873b3d9fd 100644 --- "a/docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" +++ "b/docs/java/Multithread/\345\271\266\345\217\221\345\256\271\345\231\250\346\200\273\347\273\223.md" @@ -37,10 +37,10 @@ JDK提供的这些容器大部分在 `java.util.concurrent` 包中。 所以就有了 HashMap 的线程安全版本—— ConcurrentHashMap 的诞生。在ConcurrentHashMap中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时(几乎)不需要加锁,而在写操作时通过锁分段技术只对所操作的段加锁而不影响客户端对其它段的访问。 -关于 ConcurrentHashMap 相关问题,我在 [《这几道Java集合框架面试题几乎必问》](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md) 这篇文章中已经提到过。下面梳理一下关于 ConcurrentHashMap 比较重要的问题: +关于 ConcurrentHashMap 相关问题,我在 [《这几道Java集合框架面试题几乎必问》](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93.md) 这篇文章中已经提到过。下面梳理一下关于 ConcurrentHashMap 比较重要的问题: -- [ConcurrentHashMap 和 Hashtable 的区别](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md#concurrenthashmap-%E5%92%8C-hashtable-%E7%9A%84%E5%8C%BA%E5%88%AB) -- [ConcurrentHashMap线程安全的具体实现方式/底层具体实现](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md#concurrenthashmap%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%E5%BA%95%E5%B1%82%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0) +- [ConcurrentHashMap 和 Hashtable 的区别](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md#concurrenthashmap-%E5%92%8C-hashtable-%E7%9A%84%E5%8C%BA%E5%88%AB) +- [ConcurrentHashMap线程安全的具体实现方式/底层具体实现](https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md#concurrenthashmap%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%E5%BA%95%E5%B1%82%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0) From 0eeb1146b2d417f81a90c612877a042e614f76f5 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 19:17:14 +0800 Subject: [PATCH 199/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cdf1f22aa3..018dbd13e6f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

Java 学习/面试指南

- +

由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) 。

From 9a9c4966870165f4d1ec8155f1c3d59e88130c2d Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 21:28:14 +0800 Subject: [PATCH 200/232] =?UTF-8?q?Fix=20=E6=A0=BC=E5=BC=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 018dbd13e6f..a6e5cc28e82 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@

Java 学习/面试指南

-

由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) 。

+由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) +

微信群 码云地址 From 61437ed3627b1972ddd4a45440bdb3f329a988ec Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 21:35:14 +0800 Subject: [PATCH 201/232] =?UTF-8?q?Add=20=E9=98=85=E8=AF=BB=E5=9B=BE?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a6e5cc28e82..2fd114fcf86 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ 由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我)

+ 阅读 微信群 码云地址 公众号 From 3d53e3456055e50c058a4fc793dafcbb1589d089 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 21:45:10 +0800 Subject: [PATCH 202/232] =?UTF-8?q?Add=20=20=E6=8A=95=E7=A8=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2fd114fcf86..8aaa0eda41b 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@

阅读 微信群 - 码云地址 公众号 公众号 + 投稿

Special Sponsors

@@ -21,9 +21,10 @@

-1. **如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 -1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。 -1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。 +**如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 + + + ## 目录 @@ -260,6 +261,10 @@ Markdown 格式参考:[Github Markdown格式](https://guides.github.com/featur 初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。 +### 投稿 + +由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。大家也可以对自己的文章进行自荐,对于不错的文章不仅可以成功在本仓库展示出来更可以获得作者送出的 50 元左右的任意书籍进行奖励。 + ### 联系我 添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。 From 4de1484045bb0453b4839916b99dae7b91f37396 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 22:10:17 +0800 Subject: [PATCH 203/232] =?UTF-8?q?Add=20=E3=80=8A=E8=B6=A3=E8=B0=88Linux?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=B3=BB=E7=BB=9F=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8aaa0eda41b..3feda07c2d5 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@

-由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) -

阅读 微信群 @@ -20,11 +18,11 @@

+由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) -**如何阅读:** 推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 - - +对于复习 Linux 的朋友,推荐一下刘超(网易杭州研究院云计算技术部首席架构师)老师的《趣谈Linux操作系统——像故事一样的操作系统入门课》,这门课程是刚上新的,目前正在优惠,看过这位老师的《趣谈网络协议》的朋友应该都知道他,非常厉害,课程内容非常棒。[点击了解详情](https://shimo.im/docs/Jp998jwxhHwTp3sq/)。 +推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 ## 目录 From f3c2df095e1a92f56f651cbafcfc1838d11fba53 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 22:39:26 +0800 Subject: [PATCH 204/232] =?UTF-8?q?Add=20=E3=80=8A=E8=B6=A3=E8=B0=88Linux?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=B3=BB=E7=BB=9F=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HomePage.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/HomePage.md b/docs/HomePage.md index 23cdaa1e320..e99b338bcfb 100644 --- a/docs/HomePage.md +++ b/docs/HomePage.md @@ -1,3 +1,6 @@ + +对于复习 Linux 的朋友,推荐一下刘超(网易杭州研究院云计算技术部首席架构师)老师的《趣谈Linux操作系统——像故事一样的操作系统入门课》,这门课程是刚上新的,目前正在优惠,看过这位老师的《趣谈网络协议》的朋友应该都知道他,非常厉害,课程内容非常棒。[点击了解详情](https://shimo.im/docs/Jp998jwxhHwTp3sq/)。 +

Special Sponsors

@@ -185,4 +188,4 @@

-

\ No newline at end of file +

From 1065e45e83dadf620a12c60df4e2e3bd9e7e3732 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 22:40:32 +0800 Subject: [PATCH 205/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3feda07c2d5..84fb25b64f4 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ 对于复习 Linux 的朋友,推荐一下刘超(网易杭州研究院云计算技术部首席架构师)老师的《趣谈Linux操作系统——像故事一样的操作系统入门课》,这门课程是刚上新的,目前正在优惠,看过这位老师的《趣谈网络协议》的朋友应该都知道他,非常厉害,课程内容非常棒。[点击了解详情](https://shimo.im/docs/Jp998jwxhHwTp3sq/)。 -推荐使用 在线阅读(访问速度慢的话,请使用),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 +推荐使用 在线阅读(访问速度慢的话,请使用 ),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 ## 目录 From 2029d908d1ff7af190b3f2a1e32d2081c3bc5a3e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 22:51:09 +0800 Subject: [PATCH 206/232] Update index.html --- docs/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.html b/docs/index.html index c09e6589b1f..61fe8f7b03a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -18,6 +18,8 @@ maxLevel: 3,//最大支持渲染的标题层级 homepage: 'HomePage.md', coverpage: true,//封面,_coverpage.md + auto2top: true,//切换页面后是否自动跳转到页面顶部 + //logo: 'https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3logo-透明.png' , } From c3bb7d8ba0e5188687f80995cc5e1560d833c4de Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 22:58:05 +0800 Subject: [PATCH 207/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HomePage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/HomePage.md b/docs/HomePage.md index e99b338bcfb..30b3d5ed324 100644 --- a/docs/HomePage.md +++ b/docs/HomePage.md @@ -161,7 +161,7 @@ ### 书单 -- [Java程序员必备书单](./essential-content-for-interview//PreparingForInterview/books.md) +- [Java程序员必备书单](./essential-content-for-interview/PreparingForInterview/books.md) ## 闲谈 From 4f494252a936fa20a0a499094050276d33152451 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 23:13:04 +0800 Subject: [PATCH 208/232] =?UTF-8?q?Update=20=E9=97=B2=E8=B0=88->chat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/2018 \347\247\213\346\213\233.md" | 0 .../2018-12.md" => docs/chat/GithubTrending/2018-12.md | 0 .../2019-1.md" => docs/chat/GithubTrending/2019-1.md | 0 .../2019-2.md" => docs/chat/GithubTrending/2019-2.md | 0 .../chat/GithubTrending/JavaGithubTrending.md | 0 ...50\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" | 0 ...50\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename "docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" => "docs/chat/2018 \347\247\213\346\213\233.md" (100%) rename "docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" => docs/chat/GithubTrending/2018-12.md (100%) rename "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" => docs/chat/GithubTrending/2019-1.md (100%) rename "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" => docs/chat/GithubTrending/2019-2.md (100%) rename "docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" => docs/chat/GithubTrending/JavaGithubTrending.md (100%) rename "docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" => "docs/chat/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" (100%) rename "docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" => "docs/chat/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" (100%) diff --git "a/docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" "b/docs/chat/2018 \347\247\213\346\213\233.md" similarity index 100% rename from "docs/\351\227\262\350\260\210/2018 \347\247\213\346\213\233.md" rename to "docs/chat/2018 \347\247\213\346\213\233.md" diff --git "a/docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" b/docs/chat/GithubTrending/2018-12.md similarity index 100% rename from "docs/\351\227\262\350\260\210/JavaGithubTrending/2018-12.md" rename to docs/chat/GithubTrending/2018-12.md diff --git "a/docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" b/docs/chat/GithubTrending/2019-1.md similarity index 100% rename from "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-1.md" rename to docs/chat/GithubTrending/2019-1.md diff --git "a/docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" b/docs/chat/GithubTrending/2019-2.md similarity index 100% rename from "docs/\351\227\262\350\260\210/JavaGithubTrending/2019-2.md" rename to docs/chat/GithubTrending/2019-2.md diff --git "a/docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" b/docs/chat/GithubTrending/JavaGithubTrending.md similarity index 100% rename from "docs/\351\227\262\350\260\210/JavaGithubTrending/JavaGithubTrending.md" rename to docs/chat/GithubTrending/JavaGithubTrending.md diff --git "a/docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" "b/docs/chat/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" similarity index 100% rename from "docs/\351\227\262\350\260\210/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" rename to "docs/chat/\344\270\252\344\272\272\351\230\205\350\257\273\344\271\246\347\261\215\346\270\205\345\215\225.md" diff --git "a/docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" "b/docs/chat/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" similarity index 100% rename from "docs/\351\227\262\350\260\210/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" rename to "docs/chat/\351\200\211\346\213\251\346\212\200\346\234\257\346\226\271\345\220\221\351\203\275\350\246\201\350\200\203\350\231\221\345\223\252\344\272\233\345\233\240\347\264\240.md" From fd66900303013a70638ecd07e701544b6a832e6e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 23:15:14 +0800 Subject: [PATCH 209/232] =?UTF-8?q?Update=20=E6=96=87=E4=BB=B6=E5=A4=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/{chat/GithubTrending => github-trending}/2018-12.md | 0 docs/{chat/GithubTrending => github-trending}/2019-1.md | 0 docs/{chat/GithubTrending => github-trending}/2019-2.md | 0 .../GithubTrending => github-trending}/JavaGithubTrending.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename docs/{chat/GithubTrending => github-trending}/2018-12.md (100%) rename docs/{chat/GithubTrending => github-trending}/2019-1.md (100%) rename docs/{chat/GithubTrending => github-trending}/2019-2.md (100%) rename docs/{chat/GithubTrending => github-trending}/JavaGithubTrending.md (100%) diff --git a/docs/chat/GithubTrending/2018-12.md b/docs/github-trending/2018-12.md similarity index 100% rename from docs/chat/GithubTrending/2018-12.md rename to docs/github-trending/2018-12.md diff --git a/docs/chat/GithubTrending/2019-1.md b/docs/github-trending/2019-1.md similarity index 100% rename from docs/chat/GithubTrending/2019-1.md rename to docs/github-trending/2019-1.md diff --git a/docs/chat/GithubTrending/2019-2.md b/docs/github-trending/2019-2.md similarity index 100% rename from docs/chat/GithubTrending/2019-2.md rename to docs/github-trending/2019-2.md diff --git a/docs/chat/GithubTrending/JavaGithubTrending.md b/docs/github-trending/JavaGithubTrending.md similarity index 100% rename from docs/chat/GithubTrending/JavaGithubTrending.md rename to docs/github-trending/JavaGithubTrending.md From 4096452a728058bd63f66c57b65d59e27a98d60b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 23:28:34 +0800 Subject: [PATCH 210/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++++++--- docs/github-trending/JavaGithubTrending.md | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 84fb25b64f4..51dd38fb7ba 100644 --- a/README.md +++ b/README.md @@ -216,11 +216,14 @@ - [Java程序员必备书单](docs/essential-content-for-interview//PreparingForInterview/books.md) +### Github榜单 + +- [Java 项目月榜单](docs/github-trending/JavaGithubTrending.md) + ## 闲谈 -* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) -* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) +* [选择技术方向都要考虑哪些因素](docs/chat/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](docs/chat/2018%20%E7%A7%8B%E6%8B%9B.md) *** diff --git a/docs/github-trending/JavaGithubTrending.md b/docs/github-trending/JavaGithubTrending.md index 229f6d2bdef..806dc36e1ac 100644 --- a/docs/github-trending/JavaGithubTrending.md +++ b/docs/github-trending/JavaGithubTrending.md @@ -1,4 +1,4 @@ -- [2018 年 12 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2018-12.md) -- [2019 年 1 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2019-1.md) -- [2019 年 2 月](https://github.com/Snailclimb/JavaGuide/blob/master/闲谈/JavaGithubTrending/2019-2.md) +- [2018 年 12 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2018-12.md) +- [2019 年 1 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2019-1.md) +- [2019 年 2 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2019-2.md) From aa5ca1235e97ed8764cda11e79586124c7f94eea Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 23:31:46 +0800 Subject: [PATCH 211/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/github-trending/JavaGithubTrending.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/github-trending/JavaGithubTrending.md b/docs/github-trending/JavaGithubTrending.md index 806dc36e1ac..0639622212f 100644 --- a/docs/github-trending/JavaGithubTrending.md +++ b/docs/github-trending/JavaGithubTrending.md @@ -1,4 +1,4 @@ -- [2018 年 12 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2018-12.md) -- [2019 年 1 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2019-1.md) -- [2019 年 2 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/JavaGithubTrending/2019-2.md) +- [2018 年 12 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/2018-12.md) +- [2019 年 1 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/2019-1.md) +- [2019 年 2 月](https://github.com/Snailclimb/JavaGuide/blob/master/docs/github-trending/2019-2.md) From 48db5737998a8461bde83f38666fea1cf8ee5950 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 25 Mar 2019 23:33:57 +0800 Subject: [PATCH 212/232] Update HomePage.md --- docs/HomePage.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/HomePage.md b/docs/HomePage.md index 30b3d5ed324..7e080ca6b88 100644 --- a/docs/HomePage.md +++ b/docs/HomePage.md @@ -161,13 +161,16 @@ ### 书单 -- [Java程序员必备书单](./essential-content-for-interview/PreparingForInterview/books.md) +- [Java程序员必备书单](./essential-content-for-interview//PreparingForInterview/books.md) + +### Github榜单 + +- [Java 项目月榜单](./github-trending/JavaGithubTrending.md) ## 闲谈 -* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md) -* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md) -* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md) +* [选择技术方向都要考虑哪些因素](./chat/选择技术方向都要考虑哪些因素.md) +* [结束了我短暂的秋招,说点自己的感受](./chat/2018%20%E7%A7%8B%E6%8B%9B.md) *** From d42ae433fa65be988ae0e69529708f74c3145afd Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 10:22:25 +0800 Subject: [PATCH 213/232] =?UTF-8?q?Add=20Github=E6=A6=9C=E5=8D=95=E5=88=B0?= =?UTF-8?q?=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51dd38fb7ba..a3c0fa67b09 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ - [Docker](#Docker) - [资料](#资料) - [书单](#书单) + - [Github榜单](#Github榜单) - [闲谈](#闲谈) - [待办](#待办) - [说明](#说明) From f63372a7c291f9c60a6955c0392c2a59dd4156e6 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 11:48:01 +0800 Subject: [PATCH 214/232] =?UTF-8?q?Fix=20=E6=A0=BC=E5=BC=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...7\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index ac0e8322b67..66a15333a0c 100644 --- "a/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -26,6 +26,7 @@ Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成
+ **JDK 1.8 :**
From 1c72710e7627bb39a49b26188cdf2691161408b2 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 12:08:12 +0800 Subject: [PATCH 215/232] =?UTF-8?q?Update=20=E3=80=8A=E8=B6=A3=E8=B0=88Lin?= =?UTF-8?q?ux=E6=93=8D=E4=BD=9C=E7=B3=BB=E7=BB=9F=E2=80=94=E2=80=94?= =?UTF-8?q?=E5=83=8F=E6=95=85=E4=BA=8B=E4=B8=80=E6=A0=B7=E7=9A=84=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=B3=BB=E7=BB=9F=E5=85=A5=E9=97=A8=E8=AF=BE=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a3c0fa67b09..5fca4046984 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ 由于对文件目录结构进行了大幅度修改,所以如果遇到文章中有 Github 404 链接请 [联系我](#联系我) -对于复习 Linux 的朋友,推荐一下刘超(网易杭州研究院云计算技术部首席架构师)老师的《趣谈Linux操作系统——像故事一样的操作系统入门课》,这门课程是刚上新的,目前正在优惠,看过这位老师的《趣谈网络协议》的朋友应该都知道他,非常厉害,课程内容非常棒。[点击了解详情](https://shimo.im/docs/Jp998jwxhHwTp3sq/)。 +对于复习 Linux 的朋友,推荐一下刘超(网易杭州研究院云计算技术部首席架构师)老师的《趣谈Linux操作系统——像故事一样的操作系统入门课》,这门课程是刚上新的,目前正在优惠,看过这位老师的《趣谈网络协议》的朋友应该都知道他,非常厉害,课程内容非常棒。[点击了解详情](https://shimo.im/docs/Jp998jwxhHwTp3sq/) 有福利哦!。 推荐使用 在线阅读(访问速度慢的话,请使用 ),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。 From d0da5742f4097249a8f95312a67ebc3c56510f59 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 14:23:20 +0800 Subject: [PATCH 216/232] =?UTF-8?q?Create=20Java8=E6=95=99=E7=A8=8B?= =?UTF-8?q?=E6=8E=A8=E8=8D=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...25\231\347\250\213\346\216\250\350\215\220.md" | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 "docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" diff --git "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" new file mode 100644 index 00000000000..948f56ee6c5 --- /dev/null +++ "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" @@ -0,0 +1,15 @@ +- **《Java8 In Action》:** PDF版本链接:https://pan.baidu.com/s/1SRibgnCb8iercf4Cca2pFQ + 提取码:g96r 。书中所有的代码在这里: + 复制这段内容后打开百度网盘手机App,操作更方便哦 + +- **【译】Java 8 简明教程**: + +- **30 seconds of java8:** + +- **《写给大忙人看的Java SE 8》:** PDF版本 链接: + 提取码:ay6r ; 京东购买链接: + + + + + From dc70dec4c9a0aef7594dc33c4e18d311115216ab Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 14:23:51 +0800 Subject: [PATCH 217/232] =?UTF-8?q?Update=20Java8=E6=95=99=E7=A8=8B?= =?UTF-8?q?=E6=8E=A8=E8=8D=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" | 4 ---- 1 file changed, 4 deletions(-) diff --git "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" index 948f56ee6c5..85f0abfdec2 100644 --- "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" +++ "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" @@ -1,11 +1,7 @@ - **《Java8 In Action》:** PDF版本链接:https://pan.baidu.com/s/1SRibgnCb8iercf4Cca2pFQ 提取码:g96r 。书中所有的代码在这里: - 复制这段内容后打开百度网盘手机App,操作更方便哦 - - **【译】Java 8 简明教程**: - - **30 seconds of java8:** - - **《写给大忙人看的Java SE 8》:** PDF版本 链接: 提取码:ay6r ; 京东购买链接: From 7aba0a2dc8a86d93bd35d6be86ae99a204ef69d5 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 14:52:19 +0800 Subject: [PATCH 218/232] =?UTF-8?q?Update=20Java8=E6=95=99=E7=A8=8B?= =?UTF-8?q?=E6=8E=A8=E8=8D=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...31\347\250\213\346\216\250\350\215\220.md" | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" index 85f0abfdec2..fd85f9242cf 100644 --- "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" +++ "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" @@ -1,11 +1,20 @@ -- **《Java8 In Action》:** PDF版本链接:https://pan.baidu.com/s/1SRibgnCb8iercf4Cca2pFQ - 提取码:g96r 。书中所有的代码在这里: + + +### 书籍 + +- **《Java8 In Action》** +- **《写给大忙人看的Java SE 8》** + +上述书籍的PDF版本见 https://shimo.im/docs/CPB0PK05rP4CFmI2/ + +### 开源文档 + - **【译】Java 8 简明教程**: - **30 seconds of java8:** -- **《写给大忙人看的Java SE 8》:** PDF版本 链接: - 提取码:ay6r ; 京东购买链接: - +### 视频 +- **尚硅谷 Java 8 新特性** +视频资源见: https://shimo.im/docs/CPB0PK05rP4CFmI2/ 。 From 8e1d69abacfe25a88e722ec1ca0451f13365bb46 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 14:58:15 +0800 Subject: [PATCH 219/232] =?UTF-8?q?Update=20Java8=E6=95=99=E7=A8=8B?= =?UTF-8?q?=E6=8E=A8=E8=8D=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" index fd85f9242cf..43e4539ccac 100644 --- "a/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" +++ "b/docs/java/What's New in JDK8/Java8\346\225\231\347\250\213\346\216\250\350\215\220.md" @@ -5,7 +5,7 @@ - **《Java8 In Action》** - **《写给大忙人看的Java SE 8》** -上述书籍的PDF版本见 https://shimo.im/docs/CPB0PK05rP4CFmI2/ +上述书籍的PDF版本见 https://shimo.im/docs/CPB0PK05rP4CFmI2/ 中的 “Java 书籍推荐”。 ### 开源文档 From 08ceeb0d016e8f3c1fb5df91af56ca597edc2a61 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 14:58:41 +0800 Subject: [PATCH 220/232] =?UTF-8?q?Add=20Java=208=20=E5=AD=A6=E4=B9=A0?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E6=8E=A8=E8=8D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5fca4046984..19bcbd4ccc9 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ ### Java 8 * [Java 8 新特性总结](docs/java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [Java 8 学习资源推荐](docs/java/What's%20New%20in%20JDK8/Java8教程推荐.md) ## 网络 From 0f631567047bd1fbe58464b67422fd89d702c140 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 15:05:34 +0800 Subject: [PATCH 221/232] =?UTF-8?q?Create=20Java=E7=BC=96=E7=A8=8B?= =?UTF-8?q?=E8=A7=84=E8=8C=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Java\347\274\226\347\250\213\350\247\204\350\214\203.md" | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 "docs/java/Java\347\274\226\347\250\213\350\247\204\350\214\203.md" diff --git "a/docs/java/Java\347\274\226\347\250\213\350\247\204\350\214\203.md" "b/docs/java/Java\347\274\226\347\250\213\350\247\204\350\214\203.md" new file mode 100644 index 00000000000..b96a6726d77 --- /dev/null +++ "b/docs/java/Java\347\274\226\347\250\213\350\247\204\350\214\203.md" @@ -0,0 +1,6 @@ + + +根据各位建议加上了这部分内容,我暂时只是给出了两个资源,后续可能会对重要的点进行总结,然后更新在这里,如果你总结过这类东西,欢迎与我联系! + +- **阿里巴巴Java开发手册(详尽版)** +- **Google Java编程风格指南:** \ No newline at end of file From 89d9e37ff93c93030a1faa7730c21d0b1f259044 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 15:11:00 +0800 Subject: [PATCH 222/232] =?UTF-8?q?Add=20Java=E7=BC=96=E7=A8=8B=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 19bcbd4ccc9..fcd3467d668 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ - [JVM](#jvm) - [I/O](#io) - [Java 8](#java-8) + - [编程规范](#编程规范) - [网络](#网络) - [操作系统](#操作系统) - [Linux相关](#linux相关) @@ -107,6 +108,10 @@ * [Java 8 新特性总结](docs/java/What's%20New%20in%20JDK8/Java8Tutorial.md) * [Java 8 学习资源推荐](docs/java/What's%20New%20in%20JDK8/Java8教程推荐.md) +### 编程规范 + +[Java 编程规范](docs/java/Java编程规范.md) + ## 网络 * [计算机网络常见面试题](docs/network/计算机网络.md) From 7f506299280b4664303acb0d28676266a7f80f77 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 15:11:54 +0800 Subject: [PATCH 223/232] =?UTF-8?q?Fix=20=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fcd3467d668..a422976cba9 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ ### 编程规范 -[Java 编程规范](docs/java/Java编程规范.md) +- [Java 编程规范](docs/java/Java编程规范.md) ## 网络 From 63cca039c11997ec48e5c7b0c0c2a42e3b97809d Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:05:50 +0800 Subject: [PATCH 224/232] =?UTF-8?q?Update=20=E5=AF=B9=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E9=83=A8=E5=88=86=E8=BF=9B=E8=A1=8C=E5=A4=A7=E5=B9=85=E5=BA=A6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../source code/securityAlgorithm/.classpath | 26 - .../source code/securityAlgorithm/.gitignore | 1 - .../source code/securityAlgorithm/.project | 23 - .../org.eclipse.core.resources.prefs | 4 - .../.settings/org.eclipse.jdt.core.prefs | 5 - .../.settings/org.eclipse.m2e.core.prefs | 4 - .../source code/securityAlgorithm/pom.xml | 37 - .../ks/securityAlgorithm/Base64Demo.java | 49 - .../ks/securityAlgorithm/DesDemo.java | 100 --- .../ks/securityAlgorithm/IDEADemo.java | 46 - .../snailclimb/ks/securityAlgorithm/MD5.java | 160 ---- .../ks/securityAlgorithm/MD5Demo.java | 50 -- .../ks/securityAlgorithm/RSADemo.java | 249 ----- .../ks/securityAlgorithm/SHA1Demo.java | 45 - .../snailclimb/ks/securityAlgorithm/readme | 3 - .../ks/securityAlgorithm/AppTest.java | 38 - ...54\345\217\270\347\234\237\351\242\230.md" | 42 +- ...62\347\256\227\346\263\225\351\242\230.md" | 0 ...50\347\256\227\346\263\225\351\242\230.md" | 0 ...06\347\274\226\347\250\213\351\242\230.md" | 686 ++++++++++++++ ...11\357\274\211\346\200\273\347\273\223.md" | 849 ------------------ .../\347\256\227\346\263\225.md" | 90 -- ...04\346\272\220\346\216\250\350\215\220.md" | 52 ++ ...60\351\230\266\351\227\256\351\242\230.md" | 127 --- ...72\346\240\274\351\227\256\351\242\230.md" | 64 -- ...03\347\264\240\351\241\272\345\272\217.md" | 113 --- ...63\347\274\226\347\250\213\351\242\230.md" | 189 ---- ...71\345\207\272\345\272\217\345\210\227.md" | 111 --- 28 files changed, 758 insertions(+), 2405 deletions(-) delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.project delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme delete mode 100644 docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java rename "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" => "docs/dataStructures-algorithms/\345\205\254\345\217\270\347\234\237\351\242\230.md" (93%) rename "docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" => "docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" (100%) rename docs/dataStructures-algorithms/Leetcode-LinkList1.md => "docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\351\223\276\350\241\250\347\256\227\346\263\225\351\242\230.md" (100%) create mode 100644 "docs/dataStructures-algorithms/\345\211\221\346\214\207offer\351\203\250\345\210\206\347\274\226\347\250\213\351\242\230.md" delete mode 100644 "docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225.md" create mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2104\357\274\211\351\223\276\350\241\250\347\233\270\345\205\263\347\274\226\347\250\213\351\242\230.md" delete mode 100644 "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2105\357\274\211\346\240\210\345\217\230\351\230\237\345\210\227\345\222\214\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.md" diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath b/docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath deleted file mode 100644 index 0a1daddd3e8..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.classpath +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore b/docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore deleted file mode 100644 index b83d22266ac..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.project b/docs/dataStructures-algorithms/source code/securityAlgorithm/.project deleted file mode 100644 index 7b9c539d09c..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - securityAlgorithm - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index f9fe34593fc..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/test/java=UTF-8 -encoding/=UTF-8 diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index abec6ca389a..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs b/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb2..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml b/docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml deleted file mode 100644 index 39d693b84b0..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - 4.0.0 - - com.snailclimb.ks - securityAlgorithm - 0.0.1-SNAPSHOT - jar - - securityAlgorithm - http://maven.apache.org - - - UTF-8 - - - - - junit - junit - 4.12 - test - - - - commons-codec - commons-codec - 1.8 - - - org.bouncycastle - bcprov-jdk15on - 1.56 - - - - diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java deleted file mode 100644 index 1c6fd6df0ea..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import java.io.UnsupportedEncodingException; -import java.util.Base64; - -public class Base64Demo { - - public static void main(String[] args) throws UnsupportedEncodingException { - // TODO Auto-generated method stub - CommonsCodecDemo(); - bouncyCastleDemo(); - jdkDemo(); - } - - static String str = "你若安好,便是晴天"; - - /** - * commons codec实现Base64加密解密 - */ - public static void CommonsCodecDemo() { - // 加密: - byte[] encodeBytes = org.apache.commons.codec.binary.Base64.encodeBase64(str.getBytes()); - System.out.println("commons codec实现base64加密: " + new String(encodeBytes)); - // 解密: - byte[] decodeBytes = org.apache.commons.codec.binary.Base64.decodeBase64(encodeBytes); - System.out.println("commons codec实现base64解密: " + new String(decodeBytes)); - } - - /** - * bouncy castle实现Base64加密解密 - */ - public static void bouncyCastleDemo() { - // 加密 - byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(str.getBytes()); - System.out.println("bouncy castle实现base64加密: " + new String(encodeBytes)); - // 解密 - byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes); - System.out.println("bouncy castle实现base64解密:" + new String(decodeBytes)); - } - - public static void jdkDemo() throws UnsupportedEncodingException { - // 加密 - String encodeBytes = Base64.getEncoder().encodeToString(str.getBytes("UTF-8")); - System.out.println("JDK实现的base64加密: " + encodeBytes); - //解密 - byte[] decodeBytes = Base64.getDecoder().decode(encodeBytes.getBytes("UTF-8")); - System.out.println("JDK实现的base64解密: "+new String(decodeBytes)); - } -} diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java deleted file mode 100644 index ce8b09ee1da..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import java.io.UnsupportedEncodingException; -import java.security.SecureRandom; -import javax.crypto.spec.DESKeySpec; -import javax.crypto.SecretKeyFactory; -import javax.crypto.SecretKey; -import javax.crypto.Cipher; - -/** - * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究, - * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力, - * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。 - * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数 - */ -public class DesDemo { - public DesDemo() { - } - - // 测试 - public static void main(String args[]) { - // 待加密内容 - String str = "cryptology"; - // 密码,长度要是8的倍数 - String password = "95880288"; - - byte[] result; - try { - result = DesDemo.encrypt(str.getBytes(), password); - System.out.println("加密后:" + result); - byte[] decryResult = DesDemo.decrypt(result, password); - System.out.println("解密后:" + decryResult); - } catch (UnsupportedEncodingException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - - // 直接将如上内容解密 - - /** - * 加密 - * - * @param datasource - * byte[] - * @param password - * String - * @return byte[] - */ - public static byte[] encrypt(byte[] datasource, String password) { - try { - SecureRandom random = new SecureRandom(); - DESKeySpec desKey = new DESKeySpec(password.getBytes()); - // 创建一个密匙工厂,然后用它把DESKeySpec转换成 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey securekey = keyFactory.generateSecret(desKey); - // Cipher对象实际完成加密操作 - Cipher cipher = Cipher.getInstance("DES"); - // 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量 - cipher.init(Cipher.ENCRYPT_MODE, securekey, random); - // 现在,获取数据并加密 - // 正式执行加密操作 - return cipher.doFinal(datasource); // 按单部分操作加密或解密数据,或者结束一个多部分操作 - } catch (Throwable e) { - e.printStackTrace(); - } - return null; - } - - /** - * 解密 - * - * @param src - * byte[] - * @param password - * String - * @return byte[] - * @throws Exception - */ - public static byte[] decrypt(byte[] src, String password) throws Exception { - // DES算法要求有一个可信任的随机数源 - SecureRandom random = new SecureRandom(); - // 创建一个DESKeySpec对象 - DESKeySpec desKey = new DESKeySpec(password.getBytes()); - // 创建一个密匙工厂 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的 - // Cipher - // 对象 - // 将DESKeySpec对象转换成SecretKey对象 - SecretKey securekey = keyFactory.generateSecret(desKey); - // Cipher对象实际完成解密操作 - Cipher cipher = Cipher.getInstance("DES"); - // 用密匙初始化Cipher对象 - cipher.init(Cipher.DECRYPT_MODE, securekey, random); - // 真正开始解密操作 - return cipher.doFinal(src); - } -} \ No newline at end of file diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java deleted file mode 100644 index 5ce251df0fa..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import java.security.Key; -import java.security.Security; - -import javax.crypto.Cipher; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -public class IDEADemo { - public static void main(String args[]) { - bcIDEA(); - } - public static void bcIDEA() { - String src = "www.xttblog.com security idea"; - try { - Security.addProvider(new BouncyCastleProvider()); - - //生成key - KeyGenerator keyGenerator = KeyGenerator.getInstance("IDEA"); - keyGenerator.init(128); - SecretKey secretKey = keyGenerator.generateKey(); - byte[] keyBytes = secretKey.getEncoded(); - - //转换密钥 - Key key = new SecretKeySpec(keyBytes, "IDEA"); - - //加密 - Cipher cipher = Cipher.getInstance("IDEA/ECB/ISO10126Padding"); - cipher.init(Cipher.ENCRYPT_MODE, key); - byte[] result = cipher.doFinal(src.getBytes()); - System.out.println("bc idea encrypt : " + Base64.encodeBase64String(result)); - - //解密 - cipher.init(Cipher.DECRYPT_MODE, key); - result = cipher.doFinal(result); - System.out.println("bc idea decrypt : " + new String(result)); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java deleted file mode 100644 index 2b8e31f83f5..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -public class MD5{ - /* - *四个链接变量 - */ - private final int A=0x67452301; - private final int B=0xefcdab89; - private final int C=0x98badcfe; - private final int D=0x10325476; - /* - *ABCD的临时变量 - */ - private int Atemp,Btemp,Ctemp,Dtemp; - - /* - *常量ti - *公式:floor(abs(sin(i+1))×(2pow32) - */ - private final int K[]={ - 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, - 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8, - 0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193, - 0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51, - 0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, - 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905, - 0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681, - 0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60, - 0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, - 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244, - 0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92, - 0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314, - 0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391}; - /* - *向左位移数,计算方法未知 - */ - private final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7, - 12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, - 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10, - 15,21,6,10,15,21,6,10,15,21,6,10,15,21}; - - - /* - *初始化函数 - */ - private void init(){ - Atemp=A; - Btemp=B; - Ctemp=C; - Dtemp=D; - } - /* - *移动一定位数 - */ - private int shift(int a,int s){ - return(a<>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位 - } - /* - *主循环 - */ - private void MainLoop(int M[]){ - int F,g; - int a=Atemp; - int b=Btemp; - int c=Ctemp; - int d=Dtemp; - for(int i = 0; i < 64; i ++){ - if(i<16){ - F=(b&c)|((~b)&d); - g=i; - }else if(i<32){ - F=(d&b)|((~d)&c); - g=(5*i+1)%16; - }else if(i<48){ - F=b^c^d; - g=(3*i+5)%16; - }else{ - F=c^(b|(~d)); - g=(7*i)%16; - } - int tmp=d; - d=c; - c=b; - b=b+shift(a+F+K[i]+M[g],s[i]); - a=tmp; - } - Atemp=a+Atemp; - Btemp=b+Btemp; - Ctemp=c+Ctemp; - Dtemp=d+Dtemp; - - } - /* - *填充函数 - *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64) - *填充方式为先加一个0,其它位补零 - *最后加上64位的原来长度 - */ - private int[] add(String str){ - int num=((str.length()+8)/64)+1;//以512位,64个字节为一组 - int strByte[]=new int[num*16];//64/4=16,所以有16个整数 - for(int i=0;i>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序 - } - strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1 - /* - *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位 - */ - strByte[num*16-2]=str.length()*8; - return strByte; - } - /* - *调用函数 - */ - public String getMD5(String source){ - init(); - int strByte[]=add(source); - for(int i=0;i>i*8)%(1<<8))&0xff)).replace(' ', '0'); - - } - return str; - } - /* - *单例 - */ - private static MD5 instance; - public static MD5 getInstance(){ - if(instance==null){ - instance=new MD5(); - } - return instance; - } - - private MD5(){}; - - public static void main(String[] args){ - String str=MD5.getInstance().getMD5("你若安好,便是晴天"); - System.out.println(str); - } -} \ No newline at end of file diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java deleted file mode 100644 index 3a8635d1e69..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import java.security.MessageDigest; - -public class MD5Demo { - - // test - public static void main(String[] args) { - System.out.println(getMD5Code("你若安好,便是晴天")); - } - - private MD5Demo() { - } - - // md5加密 - public static String getMD5Code(String message) { - String md5Str = ""; - try { - //创建MD5算法消息摘要 - MessageDigest md = MessageDigest.getInstance("MD5"); - //生成的哈希值的字节数组 - byte[] md5Bytes = md.digest(message.getBytes()); - md5Str = bytes2Hex(md5Bytes); - }catch(Exception e) { - e.printStackTrace(); - } - return md5Str; - } - - // 2进制转16进制 - public static String bytes2Hex(byte[] bytes) { - StringBuffer result = new StringBuffer(); - int temp; - try { - for (int i = 0; i < bytes.length; i++) { - temp = bytes[i]; - if(temp < 0) { - temp += 256; - } - if (temp < 16) { - result.append("0"); - } - result.append(Integer.toHexString(temp)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return result.toString(); - } -} diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java deleted file mode 100644 index 5234028ece4..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java +++ /dev/null @@ -1,249 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import org.apache.commons.codec.binary.Base64; - -import java.security.*; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.Cipher; - -/** - * Created by humf.需要依赖 commons-codec 包 - */ -public class RSADemo { - - public static void main(String[] args) throws Exception { - Map keyMap = initKey(); - String publicKey = getPublicKey(keyMap); - String privateKey = getPrivateKey(keyMap); - - System.out.println(keyMap); - System.out.println("-----------------------------------"); - System.out.println(publicKey); - System.out.println("-----------------------------------"); - System.out.println(privateKey); - System.out.println("-----------------------------------"); - byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey); - byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey); - System.out.println(encryptByPrivateKey); - System.out.println("-----------------------------------"); - System.out.println(encryptByPublicKey); - System.out.println("-----------------------------------"); - String sign = sign(encryptByPrivateKey, privateKey); - System.out.println(sign); - System.out.println("-----------------------------------"); - boolean verify = verify(encryptByPrivateKey, publicKey, sign); - System.out.println(verify); - System.out.println("-----------------------------------"); - byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey); - byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey); - System.out.println(decryptByPublicKey); - System.out.println("-----------------------------------"); - System.out.println(decryptByPrivateKey); - - } - - public static final String KEY_ALGORITHM = "RSA"; - public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; - - private static final String PUBLIC_KEY = "RSAPublicKey"; - private static final String PRIVATE_KEY = "RSAPrivateKey"; - - public static byte[] decryptBASE64(String key) { - return Base64.decodeBase64(key); - } - - public static String encryptBASE64(byte[] bytes) { - return Base64.encodeBase64String(bytes); - } - - /** - * 用私钥对信息生成数字签名 - * - * @param data - * 加密数据 - * @param privateKey - * 私钥 - * @return - * @throws Exception - */ - public static String sign(byte[] data, String privateKey) throws Exception { - // 解密由base64编码的私钥 - byte[] keyBytes = decryptBASE64(privateKey); - // 构造PKCS8EncodedKeySpec对象 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - // KEY_ALGORITHM 指定的加密算法 - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - // 取私钥匙对象 - PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 用私钥对信息生成数字签名 - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initSign(priKey); - signature.update(data); - return encryptBASE64(signature.sign()); - } - - /** - * 校验数字签名 - * - * @param data - * 加密数据 - * @param publicKey - * 公钥 - * @param sign - * 数字签名 - * @return 校验成功返回true 失败返回false - * @throws Exception - */ - public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { - // 解密由base64编码的公钥 - byte[] keyBytes = decryptBASE64(publicKey); - // 构造X509EncodedKeySpec对象 - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - // KEY_ALGORITHM 指定的加密算法 - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - // 取公钥匙对象 - PublicKey pubKey = keyFactory.generatePublic(keySpec); - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initVerify(pubKey); - signature.update(data); - // 验证签名是否正常 - return signature.verify(decryptBASE64(sign)); - } - - public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得私钥 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 对数据解密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - return cipher.doFinal(data); - } - - /** - * 解密
- * 用私钥解密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptByPrivateKey(String data, String key) throws Exception { - return decryptByPrivateKey(decryptBASE64(data), key); - } - - /** - * 解密
- * 用公钥解密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得公钥 - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicKey = keyFactory.generatePublic(x509KeySpec); - // 对数据解密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, publicKey); - return cipher.doFinal(data); - } - - /** - * 加密
- * 用公钥加密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPublicKey(String data, String key) throws Exception { - // 对公钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得公钥 - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicKey = keyFactory.generatePublic(x509KeySpec); - // 对数据加密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - return cipher.doFinal(data.getBytes()); - } - - /** - * 加密
- * 用私钥加密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得私钥 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 对数据加密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, privateKey); - return cipher.doFinal(data); - } - - /** - * 取得私钥 - * - * @param keyMap - * @return - * @throws Exception - */ - public static String getPrivateKey(Map keyMap) throws Exception { - Key key = (Key) keyMap.get(PRIVATE_KEY); - return encryptBASE64(key.getEncoded()); - } - - /** - * 取得公钥 - * - * @param keyMap - * @return - * @throws Exception - */ - public static String getPublicKey(Map keyMap) throws Exception { - Key key = keyMap.get(PUBLIC_KEY); - return encryptBASE64(key.getEncoded()); - } - - /** - * 初始化密钥 - * - * @return - * @throws Exception - */ - public static Map initKey() throws Exception { - KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); - keyPairGen.initialize(1024); - KeyPair keyPair = keyPairGen.generateKeyPair(); - Map keyMap = new HashMap(2); - keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 - keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 - return keyMap; - } - -} \ No newline at end of file diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java deleted file mode 100644 index ab19e3d0cf9..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class SHA1Demo { - - public static void main(String[] args) { - // TODO Auto-generated method stub - System.out.println(getSha1("你若安好,便是晴天")); - - } - - public static String getSha1(String str) { - if (null == str || 0 == str.length()) { - return null; - } - char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - try { - //创建SHA1算法消息摘要对象 - MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); - //使用指定的字节数组更新摘要。 - mdTemp.update(str.getBytes("UTF-8")); - //生成的哈希值的字节数组 - byte[] md = mdTemp.digest(); - //SHA1算法生成信息摘要关键过程 - int j = md.length; - char[] buf = new char[j * 2]; - int k = 0; - for (int i = 0; i < j; i++) { - byte byte0 = md[i]; - buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; - buf[k++] = hexDigits[byte0 & 0xf]; - } - return new String(buf); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return "0"; - - } -} diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme deleted file mode 100644 index 5c2d452dd23..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme +++ /dev/null @@ -1,3 +0,0 @@ -Des算法参考:http://blog.csdn.net/super_cui/article/details/70820983 -IDEA算法参考:https://www.xttblog.com/?p=1121 -RSA算法实现参考:https://www.cnblogs.com/xlhan/p/7120488.html \ No newline at end of file diff --git a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java b/docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java deleted file mode 100644 index 932254515a0..00000000000 --- a/docs/dataStructures-algorithms/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.snailclimb.ks.securityAlgorithm; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" "b/docs/dataStructures-algorithms/\345\205\254\345\217\270\347\234\237\351\242\230.md" similarity index 93% rename from "docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" rename to "docs/dataStructures-algorithms/\345\205\254\345\217\270\347\234\237\351\242\230.md" index d929d20046c..c78ed8f3e5a 100644 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\205\254\345\217\270\347\234\237\351\242\230/\347\275\221\346\230\2232018\346\240\241\346\213\233\347\274\226\347\250\213\351\242\2301-3.md" +++ "b/docs/dataStructures-algorithms/\345\205\254\345\217\270\347\234\237\351\242\230.md" @@ -1,9 +1,10 @@ +# 网易 2018 + 下面三道编程题来自网易2018校招编程题,这三道应该来说是非常简单的编程题了,这些题目大家稍微有点编程和数学基础的话应该没什么问题。看答案之前一定要自己先想一下如果是自己做的话会怎么去做,然后再对照这我的答案看看,和你自己想的有什么区别?那一种方法更好? -![问题](https://user-gold-cdn.xitu.io/2018/7/7/1647557d5a1474d7?w=1024&h=1024&f=jpeg&s=638271) -> # 问题 +## 问题 -## 一 获得特定数量硬币问题 +### 一 获得特定数量硬币问题 小易准备去魔法王国采购魔法神器,购买魔法神器需要使用魔法币,但是小易现在一枚魔法币都没有,但是小易有两台魔法机器可以通过投入x(x可以为0)个魔法币产生更多的魔法币。 @@ -15,33 +16,30 @@ **输入描述:** 输入包括一行,包括一个正整数n(1 ≤ n ≤ 10^9),表示小易需要的魔法币数量。 - **输出描述:** 输出一个字符串,每个字符表示该次小易选取投入的魔法机器。其中只包含字符'1'和'2'。 **输入例子1:** 10 **输出例子1:** 122 -## 二 求“相反数”问题 +### 二 求“相反数”问题 为了得到一个数的"相反数",我们将这个数的数字顺序颠倒,然后再加上原先的数得到"相反数"。例如,为了得到1325的"相反数",首先我们将该数的数字顺序颠倒,我们得到5231,之后再加上原先的数,我们得到5231+1325=6556.如果颠倒之后的数字有前缀零,前缀零将会被忽略。例如n = 100, 颠倒之后是1. **输入描述:** 输入包括一个整数n,(1 ≤ n ≤ 10^5) - **输出描述:** 输出一个整数,表示n的相反数 **输入例子1:** 1325 **输出例子1:** 6556 -## 三 字符串碎片的平均长度 +### 三 字符串碎片的平均长度 一个由小写字母组成的字符串可以看成一些同一字母的最大碎片组成的。例如,"aaabbaaac"是由下面碎片组成的:'aaa','bb','c'。牛牛现在给定一个字符串,请你帮助计算这个字符串的所有碎片的平均长度是多少。 **输入描述:** 输入包括一个字符串s,字符串s的长度length(1 ≤ length ≤ 50),s只含小写字母('a'-'z') - **输出描述:** 输出一个整数,表示所有碎片的平均长度,四舍五入保留两位小数。 **如样例所示:** s = "aaabbaaac" @@ -51,19 +49,18 @@ **输出例子1:** 2.25 -![答案](https://user-gold-cdn.xitu.io/2018/7/7/16475582faddc9b2?w=1024&h=1024&f=jpeg&s=531663) - -> # 答案 +## 答案 -## 一 获得特定数量硬币问题 +### 一 获得特定数量硬币问题 -### 分析: +#### 分析: 作为该试卷的第一题,这道题应该只要思路正确就很简单了。 解题关键:明确魔法机器1只能产生奇数,魔法机器2只能产生偶数即可。我们从后往前一步一步推回去即可。 -### 示例代码 +#### 示例代码 + 注意:由于用户的输入不确定性,一般是为了程序高可用性使需要将捕获用户输入异常然后友好提示用户输入类型错误并重新输入的。所以下面我给了两个版本,这两个版本都是正确的。这里只是给大家演示如何捕获输入类型异常,后面的题目中我给的代码没有异常处理的部分,参照下面两个示例代码,应该很容易添加。(PS:企业面试中没有明确就不用添加异常处理,当然你有的话也更好) **不带输入异常处理判断的版本:** @@ -141,32 +138,33 @@ public class Main { ``` +### 二 求“相反数”问题 -## 二 求“相反数”问题 - -### 分析: +#### 分析: 解决本道题有几种不同的方法,但是最快速的方法就是利用reverse()方法反转字符串然后再将字符串转换成int类型的整数,这个方法是快速解决本题关键。我们先来回顾一下下面两个知识点: **1)String转int;** 在 Java 中要将 String 类型转化为 int 类型时,需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换. + ```java String str = "123"; int a = Integer.parseInt(str); ``` + 或 + ```java String str = "123"; int a = Integer.valueOf(str).intValue(); ``` - **2)next()和nextLine()的区别** 在Java中输入字符串有两种方法,就是next()和nextLine().两者的区别就是:nextLine()的输入是碰到回车就终止输入,而next()方法是碰到空格,回车,Tab键都会被视为终止符。所以next()不会得到带空格的字符串,而nextLine()可以得到带空格的字符串。 -### 示例代码: +#### 示例代码: ```java import java.util.Scanner; @@ -192,15 +190,15 @@ public class Main { } ``` -## 三 字符串碎片的平均长度 +### 三 字符串碎片的平均长度 -### 分析: +#### 分析: 这道题的意思也就是要求:(字符串的总长度)/(相同字母团构成的字符串的个数)。 这样就很简单了,就变成了字符串的字符之间的比较。如果需要比较字符串的字符的话,我们可以利用charAt(i)方法:取出特定位置的字符与后一个字符比较,或者利用toCharArray()方法将字符串转换成字符数组采用同样的方法做比较。 -### 示例代码 +#### 示例代码 **利用charAt(i)方法:** diff --git "a/docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" "b/docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" similarity index 100% rename from "docs/dataStructures-algorithms/\346\220\236\345\256\232BAT\351\235\242\350\257\225\342\200\224\342\200\224\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" rename to "docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\345\255\220\347\254\246\344\270\262\347\256\227\346\263\225\351\242\230.md" diff --git a/docs/dataStructures-algorithms/Leetcode-LinkList1.md "b/docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\351\223\276\350\241\250\347\256\227\346\263\225\351\242\230.md" similarity index 100% rename from docs/dataStructures-algorithms/Leetcode-LinkList1.md rename to "docs/dataStructures-algorithms/\345\207\240\351\201\223\345\270\270\350\247\201\347\232\204\351\223\276\350\241\250\347\256\227\346\263\225\351\242\230.md" diff --git "a/docs/dataStructures-algorithms/\345\211\221\346\214\207offer\351\203\250\345\210\206\347\274\226\347\250\213\351\242\230.md" "b/docs/dataStructures-algorithms/\345\211\221\346\214\207offer\351\203\250\345\210\206\347\274\226\347\250\213\351\242\230.md" new file mode 100644 index 00000000000..51de35eac44 --- /dev/null +++ "b/docs/dataStructures-algorithms/\345\211\221\346\214\207offer\351\203\250\345\210\206\347\274\226\347\250\213\351\242\230.md" @@ -0,0 +1,686 @@ +### 一 斐波那契数列 + +#### **题目描述:** + +大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 +n<=39 + +#### **问题分析:** + +可以肯定的是这一题通过递归的方式是肯定能做出来,但是这样会有一个很大的问题,那就是递归大量的重复计算会导致内存溢出。另外可以使用迭代法,用fn1和fn2保存计算过程中的结果,并复用起来。下面我会把两个方法示例代码都给出来并给出两个方法的运行时间对比。 + +#### **示例代码:** + +**采用迭代法:** + +```java + int Fibonacci(int number) { + if (number <= 0) { + return 0; + } + if (number == 1 || number == 2) { + return 1; + } + int first = 1, second = 1, third = 0; + for (int i = 3; i <= number; i++) { + third = first + second; + first = second; + second = third; + } + return third; + } +``` + +**采用递归:** + +```java + public int Fibonacci(int n) { + + if (n <= 0) { + return 0; + } + if (n == 1||n==2) { + return 1; + } + + return Fibonacci(n - 2) + Fibonacci(n - 1); + + } +``` + +#### **运行时间对比:** + +假设n为40我们分别使用迭代法和递归法计算,计算结果如下: + +1. 迭代法 + ![迭代法](https://ws1.sinaimg.cn/large/006rNwoDgy1fpydt5as85j308a025dfl.jpg) +2. 递归法 + ![递归法](https://ws1.sinaimg.cn/large/006rNwoDgy1fpydt2d1k3j30ed02kt8i.jpg) + +### 二 跳台阶问题 + +#### **题目描述:** + +一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 + +#### **问题分析:** + +**正常分析法:** +a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1); +b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2) +c.由a,b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2) +d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2 +**找规律分析法:** +f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5, 可以总结出f(n) = f(n-1) + f(n-2)的规律。 +但是为什么会出现这样的规律呢?假设现在6个台阶,我们可以从第5跳一步到6,这样的话有多少种方案跳到5就有多少种方案跳到6,另外我们也可以从4跳两步跳到6,跳到4有多少种方案的话,就有多少种方案跳到6,其他的不能从3跳到6什么的啦,所以最后就是f(6) = f(5) + f(4);这样子也很好理解变态跳台阶的问题了。 + +**所以这道题其实就是斐波那契数列的问题。** +代码只需要在上一题的代码稍做修改即可。和上一题唯一不同的就是这一题的初始元素变为 1 2 3 5 8.....而上一题为1 1 2 3 5 .......。另外这一题也可以用递归做,但是递归效率太低,所以我这里只给出了迭代方式的代码。 + +#### **示例代码:** + +```java + int jumpFloor(int number) { + if (number <= 0) { + return 0; + } + if (number == 1) { + return 1; + } + if (number == 2) { + return 2; + } + int first = 1, second = 2, third = 0; + for (int i = 3; i <= number; i++) { + third = first + second; + first = second; + second = third; + } + return third; + } +``` + +### 三 变态跳台阶问题 + +#### **题目描述:** + +一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 + +#### **问题分析:** + +假设n>=2,第一步有n种跳法:跳1级、跳2级、到跳n级 +跳1级,剩下n-1级,则剩下跳法是f(n-1) +跳2级,剩下n-2级,则剩下跳法是f(n-2) +...... +跳n-1级,剩下1级,则剩下跳法是f(1) +跳n级,剩下0级,则剩下跳法是f(0) +所以在n>=2的情况下: +f(n)=f(n-1)+f(n-2)+...+f(1) +因为f(n-1)=f(n-2)+f(n-3)+...+f(1) +所以f(n)=2*f(n-1) 又f(1)=1,所以可得**f(n)=2^(number-1)** + +#### **示例代码:** + +```java + int JumpFloorII(int number) { + return 1 << --number;//2^(number-1)用位移操作进行,更快 + } +``` + +#### **补充:** + +**java中有三种移位运算符:** + +1. “<<” : **左移运算符**,等同于乘2的n次方 +2. “>>”: **右移运算符**,等同于除2的n次方 +3. “>>>” **无符号右移运算符**,不管移动前最高位是0还是1,右移后左侧产生的空位部分都以0来填充。与>>类似。 + 例: + int a = 16; + int b = a << 2;//左移2,等同于16 * 2的2次方,也就是16 * 4 + int c = a >> 2;//右移2,等同于16 / 2的2次方,也就是16 / 4 + +### 四 二维数组查找 + +#### **题目描述:** + +在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 + +#### **问题解析:** + +这一道题还是比较简单的,我们需要考虑的是如何做,效率最快。这里有一种很好理解的思路: + +> 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增, +> 因此从左下角开始查找,当要查找数字比左下角数字大时。右移 +> 要查找数字比左下角数字小时,上移。这样找的速度最快。 + +#### **示例代码:** + +```java + public boolean Find(int target, int [][] array) { + //基本思路从左下角开始找,这样速度最快 + int row = array.length-1;//行 + int column = 0;//列 + //当行数大于0,当前列数小于总列数时循环条件成立 + while((row >= 0)&& (column< array[0].length)){ + if(array[row][column] > target){ + row--; + }else if(array[row][column] < target){ + column++; + }else{ + return true; + } + } + return false; + } +``` + +### 五 替换空格 + +#### **题目描述:** + +请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 + +#### **问题分析:** + +这道题不难,我们可以通过循环判断字符串的字符是否为空格,是的话就利用append()方法添加追加“%20”,否则还是追加原字符。 + +或者最简单的方法就是利用: replaceAll(String regex,String replacement)方法了,一行代码就可以解决。 + +#### **示例代码:** + +**常规做法:** + +```java + public String replaceSpace(StringBuffer str) { + StringBuffer out=new StringBuffer(); + for (int i = 0; i < str.toString().length(); i++) { + char b=str.charAt(i); + if(String.valueOf(b).equals(" ")){ + out.append("%20"); + }else{ + out.append(b); + } + } + return out.toString(); + } +``` + +**一行代码解决:** + +```java + public String replaceSpace(StringBuffer str) { + //return str.toString().replaceAll(" ", "%20"); + //public String replaceAll(String regex,String replacement) + //用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串。 + //\ 转义字符. 如果你要使用 "\" 本身, 则应该使用 "\\". String类型中的空格用“\s”表示,所以我这里猜测"\\s"就是代表空格的意思 + return str.toString().replaceAll("\\s", "%20"); + } + +``` + +### 六 数值的整数次方 + +#### **题目描述:** + +给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 + +#### **问题解析:** + +这道题算是比较麻烦和难一点的一个了。我这里采用的是**二分幂**思想,当然也可以采用**快速幂**。 +更具剑指offer书中细节,该题的解题思路如下: +1.当底数为0且指数<0时,会出现对0求倒数的情况,需进行错误处理,设置一个全局变量; +2.判断底数是否等于0,由于base为double型,所以不能直接用==判断 +3.优化求幂函数(二分幂)。 +当n为偶数,a^n =(a^n/2)*(a^n/2); +当n为奇数,a^n = a^[(n-1)/2] * a^[(n-1)/2] * a。时间复杂度O(logn) + +**时间复杂度**:O(logn) + +#### **示例代码:** + +```java +public class Solution { + boolean invalidInput=false; + public double Power(double base, int exponent) { + //如果底数等于0并且指数小于0 + //由于base为double型,不能直接用==判断 + if(equal(base,0.0)&&exponent<0){ + invalidInput=true; + return 0.0; + } + int absexponent=exponent; + //如果指数小于0,将指数转正 + if(exponent<0) + absexponent=-exponent; + //getPower方法求出base的exponent次方。 + double res=getPower(base,absexponent); + //如果指数小于0,所得结果为上面求的结果的倒数 + if(exponent<0) + res=1.0/res; + return res; + } + //比较两个double型变量是否相等的方法 + boolean equal(double num1,double num2){ + if(num1-num2>-0.000001&&num1-num2<0.000001) + return true; + else + return false; + } + //求出b的e次方的方法 + double getPower(double b,int e){ + //如果指数为0,返回1 + if(e==0) + return 1.0; + //如果指数为1,返回b + if(e==1) + return b; + //e>>1相等于e/2,这里就是求a^n =(a^n/2)*(a^n/2) + double result=getPower(b,e>>1); + result*=result; + //如果指数n为奇数,则要再乘一次底数base + if((e&1)==1) + result*=b; + return result; + } +} +``` + +当然这一题也可以采用笨方法:累乘。不过这种方法的时间复杂度为O(n),这样没有前一种方法效率高。 + +```java + // 使用累乘 + public double powerAnother(double base, int exponent) { + double result = 1.0; + for (int i = 0; i < Math.abs(exponent); i++) { + result *= base; + } + if (exponent >= 0) + return result; + else + return 1 / result; + } +``` + +### 七 调整数组顺序使奇数位于偶数前面 + +#### **题目描述:** + +输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 + +#### **问题解析:** + +这道题有挺多种解法的,给大家介绍一种我觉得挺好理解的方法: +我们首先统计奇数的个数假设为n,然后新建一个等长数组,然后通过循环判断原数组中的元素为偶数还是奇数。如果是则从数组下标0的元素开始,把该奇数添加到新数组;如果是偶数则从数组下标为n的元素开始把该偶数添加到新数组中。 + +#### **示例代码:** + +时间复杂度为O(n),空间复杂度为O(n)的算法 + +```java +public class Solution { + public void reOrderArray(int [] array) { + //如果数组长度等于0或者等于1,什么都不做直接返回 + if(array.length==0||array.length==1) + return; + //oddCount:保存奇数个数 + //oddBegin:奇数从数组头部开始添加 + int oddCount=0,oddBegin=0; + //新建一个数组 + int[] newArray=new int[array.length]; + //计算出(数组中的奇数个数)开始添加元素 + for(int i=0;i stack1 = new Stack(); + Stack stack2 = new Stack(); + + //当执行push操作时,将元素添加到stack1 + public void push(int node) { + stack1.push(node); + } + + public int pop() { + //如果两个队列都为空则抛出异常,说明用户没有push进任何元素 + if(stack1.empty()&&stack2.empty()){ + throw new RuntimeException("Queue is empty!"); + } + //如果stack2不为空直接对stack2执行pop操作, + if(stack2.empty()){ + while(!stack1.empty()){ + //将stack1的元素按后进先出push进stack2里面 + stack2.push(stack1.pop()); + } + } + return stack2.pop(); + } +} +``` + +### 十二 栈的压入,弹出序列 + +#### **题目描述:** + +输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) + +#### **题目分析:** + +这道题想了半天没有思路,参考了Alias的答案,他的思路写的也很详细应该很容易看懂。 +作者:Alias +https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106 +来源:牛客网 + +【思路】借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。 + +举例: + +入栈1,2,3,4,5 + +出栈4,5,3,2,1 + +首先1入辅助栈,此时栈顶1≠4,继续入栈2 + +此时栈顶2≠4,继续入栈3 + +此时栈顶3≠4,继续入栈4 + +此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3 + +此时栈顶3≠5,继续入栈5 + +此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3 + +…. +依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。 + + + +#### **考察内容:** + +栈 + +#### **示例代码:** + +```java +import java.util.ArrayList; +import java.util.Stack; +//这道题没想出来,参考了Alias同学的答案:https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106 +public class Solution { + public boolean IsPopOrder(int [] pushA,int [] popA) { + if(pushA.length == 0 || popA.length == 0) + return false; + Stack s = new Stack(); + //用于标识弹出序列的位置 + int popIndex = 0; + for(int i = 0; i< pushA.length;i++){ + s.push(pushA[i]); + //如果栈不为空,且栈顶元素等于弹出序列 + while(!s.empty() &&s.peek() == popA[popIndex]){ + //出栈 + s.pop(); + //弹出序列向后一位 + popIndex++; + } + } + return s.empty(); + } +} +``` \ No newline at end of file diff --git "a/docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" "b/docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" deleted file mode 100644 index 8dddb1b9f4b..00000000000 --- "a/docs/dataStructures-algorithms/\345\270\270\350\247\201\345\256\211\345\205\250\347\256\227\346\263\225\357\274\210MD5\343\200\201SHA1\343\200\201Base64\347\255\211\347\255\211\357\274\211\346\200\273\347\273\223.md" +++ /dev/null @@ -1,849 +0,0 @@ -本文主要对消息摘要算法和加密算法做了整理,包括MD5、SHA、DES、AES、RSA等,并且提供了相应算法的Java实现和测试。 - -# 一 消息摘要算法 - -## **1. 简介:** - -- **消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密** -- **只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。** -- **消息摘要算法主要应用在“数字签名”领域,作为对明文的摘要算法。** -- **著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体**。 - -## **2. 特点:** - -1. **无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。** -2. **消息摘要看起来是“伪随机的”。也就是说对相同的信息求摘要结果相同。** -3. **消息轻微改变生成的摘要变化会很大** -4. **只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息** - -## **3. 应用:** - -消息摘要算法最常用的场景就是数字签名以及数据(密码)加密了。(一般平时做项目用的比较多的就是使用MD5对用户密码进行加密) - -## **4. 何谓数字签名:** - -数字签名主要用到了非对称密钥加密技术与数字摘要技术。数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。 -如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过. - -因此数字签名能够验证信息的完整性。 -数字签名是个加密的过程,数字签名验证是个解密的过程。 - -## **5. 常见消息/数字摘要算法:** - -### [**MD5:**](https://baike.baidu.com/item/MD5/212708?fr=aladdin) - -#### 简介: - -MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式 - (也就是把一个任意长度的字节串变换成一定长的十六进制数字串)。 - -#### 特点: - -1. **压缩性:** 任意长度的数据,算出的MD5值长度都是固定的。 -2. **容易计算:** 从原数据计算出MD5值很容易。 -3. **抗修改性:** 对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。 -4. **强抗碰撞:** 已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。 - -#### 代码实现: - -**利用JDK提供java.security.MessageDigest类实现MD5算法:** - -```java -package com.snailclimb.ks.securityAlgorithm; - -import java.security.MessageDigest; - -public class MD5Demo { - - // test - public static void main(String[] args) { - System.out.println(getMD5Code("你若安好,便是晴天")); - } - - private MD5Demo() { - } - - // md5加密 - public static String getMD5Code(String message) { - String md5Str = ""; - try { - //创建MD5算法消息摘要 - MessageDigest md = MessageDigest.getInstance("MD5"); - //生成的哈希值的字节数组 - byte[] md5Bytes = md.digest(message.getBytes()); - md5Str = bytes2Hex(md5Bytes); - }catch(Exception e) { - e.printStackTrace(); - } - return md5Str; - } - - // 2进制转16进制 - public static String bytes2Hex(byte[] bytes) { - StringBuffer result = new StringBuffer(); - int temp; - try { - for (int i = 0; i < bytes.length; i++) { - temp = bytes[i]; - if(temp < 0) { - temp += 256; - } - if (temp < 16) { - result.append("0"); - } - result.append(Integer.toHexString(temp)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return result.toString(); - } -} - -``` - -**结果:** -``` -6bab82679914f7cb480a120b532ffa80 - -``` - -**注意MessageDigest类的几个方法:** - -```java -static MessageDigest getInstance(String algorithm)//返回实现指定摘要算法的MessageDigest对象 -``` -```java -byte[] digest(byte[] input)//使用指定的字节数组对摘要执行最终更新,然后完成摘要计算。 -``` - -#### 不利用Java提供的java.security.MessageDigest类实现MD5算法: - -```java -package com.snailclimb.ks.securityAlgorithm; - -public class MD5{ - /* - *四个链接变量 - */ - private final int A=0x67452301; - private final int B=0xefcdab89; - private final int C=0x98badcfe; - private final int D=0x10325476; - /* - *ABCD的临时变量 - */ - private int Atemp,Btemp,Ctemp,Dtemp; - - /* - *常量ti - *公式:floor(abs(sin(i+1))×(2pow32) - */ - private final int K[]={ - 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, - 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8, - 0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193, - 0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51, - 0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, - 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905, - 0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681, - 0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60, - 0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, - 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244, - 0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92, - 0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314, - 0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391}; - /* - *向左位移数,计算方法未知 - */ - private final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7, - 12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, - 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10, - 15,21,6,10,15,21,6,10,15,21,6,10,15,21}; - - - /* - *初始化函数 - */ - private void init(){ - Atemp=A; - Btemp=B; - Ctemp=C; - Dtemp=D; - } - /* - *移动一定位数 - */ - private int shift(int a,int s){ - return(a<>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位 - } - /* - *主循环 - */ - private void MainLoop(int M[]){ - int F,g; - int a=Atemp; - int b=Btemp; - int c=Ctemp; - int d=Dtemp; - for(int i = 0; i < 64; i ++){ - if(i<16){ - F=(b&c)|((~b)&d); - g=i; - }else if(i<32){ - F=(d&b)|((~d)&c); - g=(5*i+1)%16; - }else if(i<48){ - F=b^c^d; - g=(3*i+5)%16; - }else{ - F=c^(b|(~d)); - g=(7*i)%16; - } - int tmp=d; - d=c; - c=b; - b=b+shift(a+F+K[i]+M[g],s[i]); - a=tmp; - } - Atemp=a+Atemp; - Btemp=b+Btemp; - Ctemp=c+Ctemp; - Dtemp=d+Dtemp; - - } - /* - *填充函数 - *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64) - *填充方式为先加一个0,其它位补零 - *最后加上64位的原来长度 - */ - private int[] add(String str){ - int num=((str.length()+8)/64)+1;//以512位,64个字节为一组 - int strByte[]=new int[num*16];//64/4=16,所以有16个整数 - for(int i=0;i>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序 - } - strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1 - /* - *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位 - */ - strByte[num*16-2]=str.length()*8; - return strByte; - } - /* - *调用函数 - */ - public String getMD5(String source){ - init(); - int strByte[]=add(source); - for(int i=0;i>i*8)%(1<<8))&0xff)).replace(' ', '0'); - - } - return str; - } - /* - *单例 - */ - private static MD5 instance; - public static MD5 getInstance(){ - if(instance==null){ - instance=new MD5(); - } - return instance; - } - - private MD5(){}; - - public static void main(String[] args){ - String str=MD5.getInstance().getMD5("你若安好,便是晴天"); - System.out.println(str); - } -} -``` - -### [**SHA1:**](https://baike.baidu.com/item/MD5/212708?fr=aladdin) -对于长度小于2^64位的消息,SHA1会产生一个160位(40个字符)的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。 - -SHA1有如下特性: - -- 不可以从消息摘要中复原信息; -- 两个不同的消息不会产生同样的消息摘要,(但会有1x10 ^ 48分之一的机率出现相同的消息摘要,一般使用时忽略)。 - -#### 代码实现: - -**利用JDK提供java.security.MessageDigest类实现SHA1算法:* - -```java -package com.snailclimb.ks.securityAlgorithm; - -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class SHA1Demo { - - public static void main(String[] args) { - // TODO Auto-generated method stub - System.out.println(getSha1("你若安好,便是晴天")); - - } - - public static String getSha1(String str) { - if (null == str || 0 == str.length()) { - return null; - } - char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - try { - //创建SHA1算法消息摘要对象 - MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); - //使用指定的字节数组更新摘要。 - mdTemp.update(str.getBytes("UTF-8")); - //生成的哈希值的字节数组 - byte[] md = mdTemp.digest(); - //SHA1算法生成信息摘要关键过程 - int j = md.length; - char[] buf = new char[j * 2]; - int k = 0; - for (int i = 0; i < j; i++) { - byte byte0 = md[i]; - buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; - buf[k++] = hexDigits[byte0 & 0xf]; - } - return new String(buf); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return "0"; - - } -} - -``` - -**结果:** - -``` -8ce764110a42da9b08504b20e26b19c9e3382414 -``` - - - -# 二 加密算法 - -## **1. 简介:** - -- **加密技术包括两个元素:加密算法和密钥。** -- **加密算法是将普通的文本(或者可以理解的信息)与一串数字(密钥)的结合,产生不可理解的密文的步骤。** -- **密钥是用来对数据进行编码和解码的一种算法。** -- **在安全保密中,可通过适当的密钥加密技术和管理机制来保证网络的信息通讯安全。** - -## **2. 分类:** - -**密钥加密技术的密码体制分为对称密钥体制和非对称密钥体制两种。相应地,对数据加密的技术分为两类,即对称加密(私人密钥加密)和非对称加密(公开密钥加密)。** - -**对称加密以数据加密标准(DES,Data Encryption Standard)算法为典型代表,非对称加密通常以RSA(Rivest Shamir Adleman)算法为代表。** - -**对称加密的加密密钥和解密密钥相同。非对称加密的加密密钥和解密密钥不同,加密密钥可以公开而解密密钥需要保密** -## **3. 应用:** - -常被用在电子商务或者其他需要保证网络传输安全的范围。 - -## **4. 对称加密:** - -加密密钥和解密密钥相同的加密算法。 - -对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准(DES), -另一个对称密钥加密系统是国际数据加密算法(IDEA),它比DES的加密性好,而且对计算机功能要求也没有那么高。IDEA加密标准由PGP(Pretty Good Privacy)系统使用。 -### [**DES:**](https://baike.baidu.com/item/DES) - -DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,现在已经过时。 - -#### 代码实现: - -DES算法实现 : - -```java -package com.snailclimb.ks.securityAlgorithm; - -import java.io.UnsupportedEncodingException; -import java.security.SecureRandom; -import javax.crypto.spec.DESKeySpec; -import javax.crypto.SecretKeyFactory; -import javax.crypto.SecretKey; -import javax.crypto.Cipher; - -/** - * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究, - * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力, - * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。 - * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数 - */ -public class DesDemo { - public DesDemo() { - } - - // 测试 - public static void main(String args[]) { - // 待加密内容 - String str = "cryptology"; - // 密码,长度要是8的倍数 - String password = "95880288"; - - byte[] result; - try { - result = DesDemo.encrypt(str.getBytes(), password); - System.out.println("加密后:" + result); - byte[] decryResult = DesDemo.decrypt(result, password); - System.out.println("解密后:" + new String(decryResult)); - } catch (UnsupportedEncodingException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - - // 直接将如上内容解密 - - /** - * 加密 - * - * @param datasource - * byte[] - * @param password - * String - * @return byte[] - */ - public static byte[] encrypt(byte[] datasource, String password) { - try { - SecureRandom random = new SecureRandom(); - DESKeySpec desKey = new DESKeySpec(password.getBytes()); - // 创建一个密匙工厂,然后用它把DESKeySpec转换成 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey securekey = keyFactory.generateSecret(desKey); - // Cipher对象实际完成加密操作 - Cipher cipher = Cipher.getInstance("DES"); - // 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量 - cipher.init(Cipher.ENCRYPT_MODE, securekey, random); - // 现在,获取数据并加密 - // 正式执行加密操作 - return cipher.doFinal(datasource); // 按单部分操作加密或解密数据,或者结束一个多部分操作 - } catch (Throwable e) { - e.printStackTrace(); - } - return null; - } - - /** - * 解密 - * - * @param src - * byte[] - * @param password - * String - * @return byte[] - * @throws Exception - */ - public static byte[] decrypt(byte[] src, String password) throws Exception { - // DES算法要求有一个可信任的随机数源 - SecureRandom random = new SecureRandom(); - // 创建一个DESKeySpec对象 - DESKeySpec desKey = new DESKeySpec(password.getBytes()); - // 创建一个密匙工厂 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的 - // Cipher - // 对象 - // 将DESKeySpec对象转换成SecretKey对象 - SecretKey securekey = keyFactory.generateSecret(desKey); - // Cipher对象实际完成解密操作 - Cipher cipher = Cipher.getInstance("DES"); - // 用密匙初始化Cipher对象 - cipher.init(Cipher.DECRYPT_MODE, securekey, random); - // 真正开始解密操作 - return cipher.doFinal(src); - } -} -``` - -结果: - -``` -加密后:[B@50cbc42f -解密后:cryptology -``` - -### [**IDEA:**](https://baike.baidu.com/item/%E5%9B%BD%E9%99%85%E6%95%B0%E6%8D%AE%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/11048972?fr=aladdin) - -- **这种算法是在DES算法的基础上发展出来的,类似于三重DES。** -- **发展IDEA也是因为感到DES具有密钥太短等缺点。** -- **IDEA的密钥为128位,这么长的密钥在今后若干年内应该是安全的。** -- **在实际项目中用到的很少了解即可。** - -#### 代码实现: - -IDEA算法实现 - -```java -package com.snailclimb.ks.securityAlgorithm; - -import java.security.Key; -import java.security.Security; - -import javax.crypto.Cipher; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -public class IDEADemo { - public static void main(String args[]) { - bcIDEA(); - } - public static void bcIDEA() { - String src = "www.xttblog.com security idea"; - try { - Security.addProvider(new BouncyCastleProvider()); - - //生成key - KeyGenerator keyGenerator = KeyGenerator.getInstance("IDEA"); - keyGenerator.init(128); - SecretKey secretKey = keyGenerator.generateKey(); - byte[] keyBytes = secretKey.getEncoded(); - - //转换密钥 - Key key = new SecretKeySpec(keyBytes, "IDEA"); - - //加密 - Cipher cipher = Cipher.getInstance("IDEA/ECB/ISO10126Padding"); - cipher.init(Cipher.ENCRYPT_MODE, key); - byte[] result = cipher.doFinal(src.getBytes()); - System.out.println("bc idea encrypt : " + Base64.encodeBase64String(result)); - - //解密 - cipher.init(Cipher.DECRYPT_MODE, key); - result = cipher.doFinal(result); - System.out.println("bc idea decrypt : " + new String(result)); - } catch (Exception e) { - e.printStackTrace(); - } - } -} - -``` - -## **5. 非对称加密:** - -- 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。 -- 公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密; -- 如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。 -- 因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 -### [**RAS:**](https://baike.baidu.com/item/DES) - -RSA是目前最有影响力和最常用的公钥加密算法。它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。 - -#### 代码实现: - -RAS算法实现: - -```java -package com.snailclimb.ks.securityAlgorithm; - -import org.apache.commons.codec.binary.Base64; - -import java.security.*; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.Cipher; - -/** - * Created by humf.需要依赖 commons-codec 包 - */ -public class RSADemo { - - public static void main(String[] args) throws Exception { - Map keyMap = initKey(); - String publicKey = getPublicKey(keyMap); - String privateKey = getPrivateKey(keyMap); - - System.out.println(keyMap); - System.out.println("-----------------------------------"); - System.out.println(publicKey); - System.out.println("-----------------------------------"); - System.out.println(privateKey); - System.out.println("-----------------------------------"); - byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey); - byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey); - System.out.println(encryptByPrivateKey); - System.out.println("-----------------------------------"); - System.out.println(encryptByPublicKey); - System.out.println("-----------------------------------"); - String sign = sign(encryptByPrivateKey, privateKey); - System.out.println(sign); - System.out.println("-----------------------------------"); - boolean verify = verify(encryptByPrivateKey, publicKey, sign); - System.out.println(verify); - System.out.println("-----------------------------------"); - byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey); - byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey); - System.out.println(decryptByPublicKey); - System.out.println("-----------------------------------"); - System.out.println(decryptByPrivateKey); - - } - - public static final String KEY_ALGORITHM = "RSA"; - public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; - - private static final String PUBLIC_KEY = "RSAPublicKey"; - private static final String PRIVATE_KEY = "RSAPrivateKey"; - - public static byte[] decryptBASE64(String key) { - return Base64.decodeBase64(key); - } - - public static String encryptBASE64(byte[] bytes) { - return Base64.encodeBase64String(bytes); - } - - /** - * 用私钥对信息生成数字签名 - * - * @param data - * 加密数据 - * @param privateKey - * 私钥 - * @return - * @throws Exception - */ - public static String sign(byte[] data, String privateKey) throws Exception { - // 解密由base64编码的私钥 - byte[] keyBytes = decryptBASE64(privateKey); - // 构造PKCS8EncodedKeySpec对象 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - // KEY_ALGORITHM 指定的加密算法 - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - // 取私钥匙对象 - PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 用私钥对信息生成数字签名 - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initSign(priKey); - signature.update(data); - return encryptBASE64(signature.sign()); - } - - /** - * 校验数字签名 - * - * @param data - * 加密数据 - * @param publicKey - * 公钥 - * @param sign - * 数字签名 - * @return 校验成功返回true 失败返回false - * @throws Exception - */ - public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { - // 解密由base64编码的公钥 - byte[] keyBytes = decryptBASE64(publicKey); - // 构造X509EncodedKeySpec对象 - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - // KEY_ALGORITHM 指定的加密算法 - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - // 取公钥匙对象 - PublicKey pubKey = keyFactory.generatePublic(keySpec); - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initVerify(pubKey); - signature.update(data); - // 验证签名是否正常 - return signature.verify(decryptBASE64(sign)); - } - - public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得私钥 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 对数据解密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - return cipher.doFinal(data); - } - - /** - * 解密
- * 用私钥解密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptByPrivateKey(String data, String key) throws Exception { - return decryptByPrivateKey(decryptBASE64(data), key); - } - - /** - * 解密
- * 用公钥解密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得公钥 - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicKey = keyFactory.generatePublic(x509KeySpec); - // 对数据解密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, publicKey); - return cipher.doFinal(data); - } - - /** - * 加密
- * 用公钥加密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPublicKey(String data, String key) throws Exception { - // 对公钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得公钥 - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicKey = keyFactory.generatePublic(x509KeySpec); - // 对数据加密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - return cipher.doFinal(data.getBytes()); - } - - /** - * 加密
- * 用私钥加密 - * - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { - // 对密钥解密 - byte[] keyBytes = decryptBASE64(key); - // 取得私钥 - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); - // 对数据加密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, privateKey); - return cipher.doFinal(data); - } - - /** - * 取得私钥 - * - * @param keyMap - * @return - * @throws Exception - */ - public static String getPrivateKey(Map keyMap) throws Exception { - Key key = (Key) keyMap.get(PRIVATE_KEY); - return encryptBASE64(key.getEncoded()); - } - - /** - * 取得公钥 - * - * @param keyMap - * @return - * @throws Exception - */ - public static String getPublicKey(Map keyMap) throws Exception { - Key key = keyMap.get(PUBLIC_KEY); - return encryptBASE64(key.getEncoded()); - } - - /** - * 初始化密钥 - * - * @return - * @throws Exception - */ - public static Map initKey() throws Exception { - KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); - keyPairGen.initialize(1024); - KeyPair keyPair = keyPairGen.generateKeyPair(); - Map keyMap = new HashMap(2); - keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 - keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 - return keyMap; - } - -} -``` - -结果: - -``` -{RSAPublicKey=Sun RSA public key, 1024 bits - modulus: 115328826086047873902606456571034976538836553998745367981848911677968062571831626674499650854318207280419960767020601253071739555161388135589487284843845439403614883967713749605268831336418001722701924537624573180276356615050309809260289965219855862692230362893996010057188170525719351126759886050891484226169 - public exponent: 65537, RSAPrivateKey=sun.security.rsa.RSAPrivateCrtKeyImpl@93479} ------------------------------------ -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkO9PBTOFJQTkzznALN62PU7ixd9YFjXrt2dPOGj3wwhymbOU8HLoCztjwpLXHgbpBUJlGmbURV955M1BkZ1kr5dkZYR5x1gO4xOnu8rEipy4AAMcpFttfiarIZrtzL9pKEvEOxABltVN4yzFDr3IjBqY46aHna7YjwhXI0xHieQIDAQAB ------------------------------------ -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKQ708FM4UlBOTPOcAs3rY9TuLF31gWNeu3Z084aPfDCHKZs5TwcugLO2PCktceBukFQmUaZtRFX3nkzUGRnWSvl2RlhHnHWA7jE6e7ysSKnLgAAxykW21+Jqshmu3Mv2koS8Q7EAGW1U3jLMUOvciMGpjjpoedrtiPCFcjTEeJ5AgMBAAECgYAK4sxOa8IjEOexv2U92Rrv/SSo3sCY7Z/QVDft2V9xrewoO9+V9HF/7iYDDWffKYInAiimvVl7JM/iSLxza0ZFv29VMpyDcr4TigYmWwBlk7ZbxSTkqLdNwxxldMmEoTn1py53MUm+1V1K3rzNvJjuZaZFAevU7vUnwQwD+JGQYQJBAM9HBaC+dF3PJ2mkXekHpDS1ZPaSFdrdzd/GvHFi/cJAMM+Uz6PmpkosNXRtOpSYWwlOMRamLZtrHhfQoqSk3S8CQQDK1qL1jGvVdqw5OjqxktR7MmOsWUVZdWiBN+6ojxBgA0yVn0n7vkdAAgEZBj89WG0VHPEu3hd4AgXFZHDfXeDXAkBvSn7nE9t/Et7ihfI2UHgGJO8UxNMfNMB5Skebyb7eMYEDs67ZHdpjMOFypcMyTatzj5wjwQ3zyMvblZX+ONbZAkAX4ysRy9WvL+icXLUo0Gfhkk+WrnSyUldaUGH0y9Rb2kecn0OxN/lgGlxSvB+ac910zRHCOTl+Uo6nbmq0g3PFAkAyqA4eT7G9GXfncakgW1Kdkn72w/ODpozgfhTLNX0SGw1ITML3c4THTtH5h3zLi3AF9zJO2O+K6ajRbV0szHHI ------------------------------------ -[B@387c703b ------------------------------------ -[B@224aed64 ------------------------------------ -la4Hc4n/UbeBu0z9iLRuwKVv014SiOJMXkO5qdJvKBsw0MlnsrM+89a3p73yMrb1dAnCU/2kgO0PtFpvmG8pzxTe1u/5nX/25iIyUXALlwVRptJyjzFE83g2IX0XEv/Dxqr1RCRcrMHOLQM0oBoxZCaChmyw1Ub4wsSs6Ndxb9M= ------------------------------------ -true ------------------------------------ -[B@c39f790 ------------------------------------ -[B@71e7a66b - -``` - diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225.md" deleted file mode 100644 index ec53e7002f9..00000000000 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225.md" +++ /dev/null @@ -1,90 +0,0 @@ - -## LeetCode -[LeetCode(中国)官网](https://leetcode-cn.com/) - -[如何高效地使用 LeetCode](https://leetcode-cn.com/articles/%E5%A6%82%E4%BD%95%E9%AB%98%E6%95%88%E5%9C%B0%E4%BD%BF%E7%94%A8-leetcode/) - - -## 牛客网: - -[牛客网首页](https://www.nowcoder.com) - - -> ### **[剑指offer编程题](https://www.nowcoder.com/ta/coding-interviews)** - -**分类解析:** -- [(1)斐波那契数列问题和跳台阶问题](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/剑指offer/(1)斐波那契数列问题和跳台阶问题.md) -- [(2)二维数组查找和替换空格问题](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/剑指offer/(2)二维数组查找和替换空格问题.md) -- [(3)数值的整数次方和调整数组元素顺序](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/剑指offer/(3)数值的整数次方和调整数组元素顺序.md) -- [(4)链表相关编程题](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/剑指offer/(4)链表相关编程题.md) -- [(5)栈变队列和栈的压入、弹出序列](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/剑指offer/(5)栈变队列和栈的压入、弹出序列.md) - -> ### [2017校招真题](https://www.nowcoder.com/ta/2017test) - -> ### [华为机试题](https://www.nowcoder.com/ta/huawei) - - -## 公司真题 - -> [ 网易2018校园招聘编程题真题集合](https://www.nowcoder.com/test/6910869/summary) - -**解析:** -- [ 网易2018校招编程题1-3](https://github.com/Snailclimb/Java-Guide/tree/master/数据结构与算法/算法题解析/公司真题/网易2018校招编程题1-3.md) - -> [ 网易2018校招内推编程题集合](https://www.nowcoder.com/test/6291726/summary) - -> [2017年校招全国统一模拟笔试(第五场)编程题集合](https://www.nowcoder.com/test/5986669/summary) - - > [2017年校招全国统一模拟笔试(第四场)编程题集合](https://www.nowcoder.com/test/5507925/summary) - -> [2017年校招全国统一模拟笔试(第三场)编程题集合](https://www.nowcoder.com/test/5217106/summary) - -> [2017年校招全国统一模拟笔试(第二场)编程题集合](https://www.nowcoder.com/test/4546329/summary) - -> [ 2017年校招全国统一模拟笔试(第一场)编程题集合](https://www.nowcoder.com/test/4236887/summary) - - -> [百度2017春招笔试真题编程题集合](https://www.nowcoder.com/test/4998655/summary) - -> [网易2017春招笔试真题编程题集合](https://www.nowcoder.com/test/4575457/summary) - - > [网易2017秋招编程题集合](https://www.nowcoder.com/test/2811407/summary) - - > [网易有道2017内推编程题](https://www.nowcoder.com/test/2385858/summary) - - > [ 滴滴出行2017秋招笔试真题-编程题汇总](https://www.nowcoder.com/test/3701760/summary) - -> [腾讯2017暑期实习生编程题](https://www.nowcoder.com/test/1725829/summary) - - > [今日头条2017客户端工程师实习生笔试题](https://www.nowcoder.com/test/1649301/summary) - - > [今日头条2017后端工程师实习生笔试题](https://www.nowcoder.com/test/1649268/summary) - - - -## 排序算法: -[图解排序算法(一)之3种简单排序(选择,冒泡,直接插入)](http://www.cnblogs.com/chengxiao/p/6103002.html) - -[图解排序算法(二)之希尔排序](https://www.cnblogs.com/chengxiao/p/6104371.html) - -[图解排序算法(三)之堆排序](http://www.cnblogs.com/chengxiao/p/6129630.html) - -[图解排序算法(四)之归并排序](http://www.cnblogs.com/chengxiao/p/6194356.html) - -[图解排序算法(五)之快速排序——三数取中法](http://www.cnblogs.com/chengxiao/p/6262208.html) - - - - - - - - - - - - - - - - diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" new file mode 100644 index 00000000000..12033ede64d --- /dev/null +++ "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" @@ -0,0 +1,52 @@ +我比较推荐大家可以刷一下 Leetcode ,我自己平时没事也会刷一下,我觉得刷 Leetcode 不仅是为了能让你更从容地面对面试中的手撕算法问题,更可以提高你的编程思维能力、解决问题的能力以及你对某门编程语言 API 的熟练度。当然牛客网也有一些算法题,我下面也整理了一些。 + +## LeetCode + +- [LeetCode(中国)官网](https://leetcode-cn.com/) + +- [如何高效地使用 LeetCode](https://leetcode-cn.com/articles/%E5%A6%82%E4%BD%95%E9%AB%98%E6%95%88%E5%9C%B0%E4%BD%BF%E7%94%A8-leetcode/) + + +## 牛客网: + +- [牛客网官网](https://www.nowcoder.com) +- [剑指offer编程题](https://www.nowcoder.com/ta/coding-interviews) + +- [2017校招真题](https://www.nowcoder.com/ta/2017test) +- [华为机试题](https://www.nowcoder.com/ta/huawei) + + +## 公司真题 + +- [ 网易2018校园招聘编程题真题集合](https://www.nowcoder.com/test/6910869/summary) +- [ 网易2018校招内推编程题集合](https://www.nowcoder.com/test/6291726/summary) +- [2017年校招全国统一模拟笔试(第五场)编程题集合](https://www.nowcoder.com/test/5986669/summary) +- [2017年校招全国统一模拟笔试(第四场)编程题集合](https://www.nowcoder.com/test/5507925/summary) +- [2017年校招全国统一模拟笔试(第三场)编程题集合](https://www.nowcoder.com/test/5217106/summary) +- [2017年校招全国统一模拟笔试(第二场)编程题集合](https://www.nowcoder.com/test/4546329/summary) +- [ 2017年校招全国统一模拟笔试(第一场)编程题集合](https://www.nowcoder.com/test/4236887/summary) +- [百度2017春招笔试真题编程题集合](https://www.nowcoder.com/test/4998655/summary) +- [网易2017春招笔试真题编程题集合](https://www.nowcoder.com/test/4575457/summary) +- [网易2017秋招编程题集合](https://www.nowcoder.com/test/2811407/summary) +- [网易有道2017内推编程题](https://www.nowcoder.com/test/2385858/summary) +- [ 滴滴出行2017秋招笔试真题-编程题汇总](https://www.nowcoder.com/test/3701760/summary) +- [腾讯2017暑期实习生编程题](https://www.nowcoder.com/test/1725829/summary) +- [今日头条2017客户端工程师实习生笔试题](https://www.nowcoder.com/test/1649301/summary) +- [今日头条2017后端工程师实习生笔试题](https://www.nowcoder.com/test/1649268/summary) + + + + + + + + + + + + + + + + + diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" deleted file mode 100644 index 87a51d9083e..00000000000 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2101\357\274\211\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227\351\227\256\351\242\230\345\222\214\350\267\263\345\217\260\351\230\266\351\227\256\351\242\230.md" +++ /dev/null @@ -1,127 +0,0 @@ -### 一 斐波那契数列 -#### **题目描述:** -大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 -n<=39 - -#### **问题分析:** -可以肯定的是这一题通过递归的方式是肯定能做出来,但是这样会有一个很大的问题,那就是递归大量的重复计算会导致内存溢出。另外可以使用迭代法,用fn1和fn2保存计算过程中的结果,并复用起来。下面我会把两个方法示例代码都给出来并给出两个方法的运行时间对比。 - -#### **示例代码:** -**采用迭代法:** - -```java - - int Fibonacci(int number) { - if (number <= 0) { - return 0; - } - if (number == 1 || number == 2) { - return 1; - } - int first = 1, second = 1, third = 0; - for (int i = 3; i <= number; i++) { - third = first + second; - first = second; - second = third; - } - return third; - } -``` -**采用递归:** -```java - public int Fibonacci(int n) { - - if (n <= 0) { - return 0; - } - if (n == 1||n==2) { - return 1; - } - - return Fibonacci(n - 2) + Fibonacci(n - 1); - - } -``` - -#### **运行时间对比:** -假设n为40我们分别使用迭代法和递归法计算,计算结果如下: -1. 迭代法 -![迭代法](https://ws1.sinaimg.cn/large/006rNwoDgy1fpydt5as85j308a025dfl.jpg) -2. 递归法 - ![递归法](https://ws1.sinaimg.cn/large/006rNwoDgy1fpydt2d1k3j30ed02kt8i.jpg) - - -### 二 跳台阶问题 -#### **题目描述:** -一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 -#### **问题分析:** -**正常分析法:** -a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1); -b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2) -c.由a,b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2) -d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2 -**找规律分析法:** -f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5, 可以总结出f(n) = f(n-1) + f(n-2)的规律。 -但是为什么会出现这样的规律呢?假设现在6个台阶,我们可以从第5跳一步到6,这样的话有多少种方案跳到5就有多少种方案跳到6,另外我们也可以从4跳两步跳到6,跳到4有多少种方案的话,就有多少种方案跳到6,其他的不能从3跳到6什么的啦,所以最后就是f(6) = f(5) + f(4);这样子也很好理解变态跳台阶的问题了。 - -**所以这道题其实就是斐波那契数列的问题。** -代码只需要在上一题的代码稍做修改即可。和上一题唯一不同的就是这一题的初始元素变为 1 2 3 5 8.....而上一题为1 1 2 3 5 .......。另外这一题也可以用递归做,但是递归效率太低,所以我这里只给出了迭代方式的代码。 -#### **示例代码:** -```java - - int jumpFloor(int number) { - if (number <= 0) { - return 0; - } - if (number == 1) { - return 1; - } - if (number == 2) { - return 2; - } - int first = 1, second = 2, third = 0; - for (int i = 3; i <= number; i++) { - third = first + second; - first = second; - second = third; - } - return third; - } -``` - - -### 三 变态跳台阶问题 -#### **题目描述:** -一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 - -#### **问题分析:** -假设n>=2,第一步有n种跳法:跳1级、跳2级、到跳n级 -跳1级,剩下n-1级,则剩下跳法是f(n-1) -跳2级,剩下n-2级,则剩下跳法是f(n-2) -...... -跳n-1级,剩下1级,则剩下跳法是f(1) -跳n级,剩下0级,则剩下跳法是f(0) -所以在n>=2的情况下: -f(n)=f(n-1)+f(n-2)+...+f(1) -因为f(n-1)=f(n-2)+f(n-3)+...+f(1) -所以f(n)=2*f(n-1) 又f(1)=1,所以可得**f(n)=2^(number-1)** - -#### **示例代码:** - -```java - int JumpFloorII(int number) { - return 1 << --number;//2^(number-1)用位移操作进行,更快 - } -``` -#### **补充:** -**java中有三种移位运算符:** - -1. “<<” : **左移运算符**,等同于乘2的n次方 -2. “>>”: **右移运算符**,等同于除2的n次方 -3. “>>>” **无符号右移运算符**,不管移动前最高位是0还是1,右移后左侧产生的空位部分都以0来填充。与>>类似。 -例: - int a = 16; - int b = a << 2;//左移2,等同于16 * 2的2次方,也就是16 * 4 - int c = a >> 2;//右移2,等同于16 / 2的2次方,也就是16 / 4 - - diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" deleted file mode 100644 index 964ed6c9892..00000000000 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2102\357\274\211\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\347\251\272\346\240\274\351\227\256\351\242\230.md" +++ /dev/null @@ -1,64 +0,0 @@ -### 一 二维数组查找 -#### **题目描述:** -在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 -#### **问题解析:** -这一道题还是比较简单的,我们需要考虑的是如何做,效率最快。这里有一种很好理解的思路: - -> 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增, - 因此从左下角开始查找,当要查找数字比左下角数字大时。右移 - 要查找数字比左下角数字小时,上移。这样找的速度最快。 - -#### **示例代码:** -```java - public boolean Find(int target, int [][] array) { - //基本思路从左下角开始找,这样速度最快 - int row = array.length-1;//行 - int column = 0;//列 - //当行数大于0,当前列数小于总列数时循环条件成立 - while((row >= 0)&& (column< array[0].length)){ - if(array[row][column] > target){ - row--; - }else if(array[row][column] < target){ - column++; - }else{ - return true; - } - } - return false; - } -``` -### 二 替换空格 -#### **题目描述:** -请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 -#### **问题分析:** -这道题不难,我们可以通过循环判断字符串的字符是否为空格,是的话就利用append()方法添加追加“%20”,否则还是追加原字符。 - -或者最简单的方法就是利用: replaceAll(String regex,String replacement)方法了,一行代码就可以解决。 - -#### **示例代码:** -**常规做法:** -```java - public String replaceSpace(StringBuffer str) { - StringBuffer out=new StringBuffer(); - for (int i = 0; i < str.toString().length(); i++) { - char b=str.charAt(i); - if(String.valueOf(b).equals(" ")){ - out.append("%20"); - }else{ - out.append(b); - } - } - return out.toString(); - } -``` -**一行代码解决:** -```java - public String replaceSpace(StringBuffer str) { - //return str.toString().replaceAll(" ", "%20"); - //public String replaceAll(String regex,String replacement) - //用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串。 - //\ 转义字符. 如果你要使用 "\" 本身, 则应该使用 "\\". String类型中的空格用“\s”表示,所以我这里猜测"\\s"就是代表空格的意思 - return str.toString().replaceAll("\\s", "%20"); - } - -``` diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" deleted file mode 100644 index 291569c0375..00000000000 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\351\242\230\350\247\243\346\236\220/\345\211\221\346\214\207offer/\357\274\2103\357\274\211\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271\345\222\214\350\260\203\346\225\264\346\225\260\347\273\204\345\205\203\347\264\240\351\241\272\345\272\217.md" +++ /dev/null @@ -1,113 +0,0 @@ -### 一 数值的整数次方 -#### **题目描述:** -给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 -#### **问题解析:** -这道题算是比较麻烦和难一点的一个了。我这里采用的是**二分幂**思想,当然也可以采用**快速幂**。 -更具剑指offer书中细节,该题的解题思路如下: -1.当底数为0且指数<0时,会出现对0求倒数的情况,需进行错误处理,设置一个全局变量; -2.判断底数是否等于0,由于base为double型,所以不能直接用==判断 -3.优化求幂函数(二分幂)。 -当n为偶数,a^n =(a^n/2)*(a^n/2); -当n为奇数,a^n = a^[(n-1)/2] * a^[(n-1)/2] * a。时间复杂度O(logn) - -**时间复杂度**:O(logn) -#### **示例代码:** -```java -public class Solution { - boolean invalidInput=false; - public double Power(double base, int exponent) { - //如果底数等于0并且指数小于0 - //由于base为double型,不能直接用==判断 - if(equal(base,0.0)&&exponent<0){ - invalidInput=true; - return 0.0; - } - int absexponent=exponent; - //如果指数小于0,将指数转正 - if(exponent<0) - absexponent=-exponent; - //getPower方法求出base的exponent次方。 - double res=getPower(base,absexponent); - //如果指数小于0,所得结果为上面求的结果的倒数 - if(exponent<0) - res=1.0/res; - return res; - } - //比较两个double型变量是否相等的方法 - boolean equal(double num1,double num2){ - if(num1-num2>-0.000001&&num1-num2<0.000001) - return true; - else - return false; - } - //求出b的e次方的方法 - double getPower(double b,int e){ - //如果指数为0,返回1 - if(e==0) - return 1.0; - //如果指数为1,返回b - if(e==1) - return b; - //e>>1相等于e/2,这里就是求a^n =(a^n/2)*(a^n/2) - double result=getPower(b,e>>1); - result*=result; - //如果指数n为奇数,则要再乘一次底数base - if((e&1)==1) - result*=b; - return result; - } -} -``` - -当然这一题也可以采用笨方法:累乘。不过这种方法的时间复杂度为O(n),这样没有前一种方法效率高。 -```java - // 使用累乘 - public double powerAnother(double base, int exponent) { - double result = 1.0; - for (int i = 0; i < Math.abs(exponent); i++) { - result *= base; - } - if (exponent >= 0) - return result; - else - return 1 / result; - } -``` -### 二 调整数组顺序使奇数位于偶数前面 -#### **题目描述:** -输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 - -#### **问题解析:** -这道题有挺多种解法的,给大家介绍一种我觉得挺好理解的方法: -我们首先统计奇数的个数假设为n,然后新建一个等长数组,然后通过循环判断原数组中的元素为偶数还是奇数。如果是则从数组下标0的元素开始,把该奇数添加到新数组;如果是偶数则从数组下标为n的元素开始把该偶数添加到新数组中。 - -#### **示例代码:** -时间复杂度为O(n),空间复杂度为O(n)的算法 -```java -public class Solution { - public void reOrderArray(int [] array) { - //如果数组长度等于0或者等于1,什么都不做直接返回 - if(array.length==0||array.length==1) - return; - //oddCount:保存奇数个数 - //oddBegin:奇数从数组头部开始添加 - int oddCount=0,oddBegin=0; - //新建一个数组 - int[] newArray=new int[array.length]; - //计算出(数组中的奇数个数)开始添加元素 - for(int i=0;i stack1 = new Stack(); - Stack stack2 = new Stack(); - - //当执行push操作时,将元素添加到stack1 - public void push(int node) { - stack1.push(node); - } - - public int pop() { - //如果两个队列都为空则抛出异常,说明用户没有push进任何元素 - if(stack1.empty()&&stack2.empty()){ - throw new RuntimeException("Queue is empty!"); - } - //如果stack2不为空直接对stack2执行pop操作, - if(stack2.empty()){ - while(!stack1.empty()){ - //将stack1的元素按后进先出push进stack2里面 - stack2.push(stack1.pop()); - } - } - return stack2.pop(); - } -} -``` - -### 二 栈的压入、弹出序列 -#### **题目描述:** -输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) -#### **题目分析:** -这道题想了半天没有思路,参考了Alias的答案,他的思路写的也很详细应该很容易看懂。 -作者:Alias -https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106 -来源:牛客网 - -【思路】借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。 - -举例: - -入栈1,2,3,4,5 - -出栈4,5,3,2,1 - -首先1入辅助栈,此时栈顶1≠4,继续入栈2 - -此时栈顶2≠4,继续入栈3 - -此时栈顶3≠4,继续入栈4 - -此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3 - -此时栈顶3≠5,继续入栈5 - -此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3 - -…. -依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。 - - - -#### **考察内容:** -栈 - -#### **示例代码:** -```java -import java.util.ArrayList; -import java.util.Stack; -//这道题没想出来,参考了Alias同学的答案:https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106 -public class Solution { - public boolean IsPopOrder(int [] pushA,int [] popA) { - if(pushA.length == 0 || popA.length == 0) - return false; - Stack s = new Stack(); - //用于标识弹出序列的位置 - int popIndex = 0; - for(int i = 0; i< pushA.length;i++){ - s.push(pushA[i]); - //如果栈不为空,且栈顶元素等于弹出序列 - while(!s.empty() &&s.peek() == popA[popIndex]){ - //出栈 - s.pop(); - //弹出序列向后一位 - popIndex++; - } - } - return s.empty(); - } -} -``` \ No newline at end of file From fcd77a2f095929660b8899e6645e7d5448eed087 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:10:52 +0800 Subject: [PATCH 225/232] =?UTF-8?q?Fix=20=E6=A0=87=E7=82=B9=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" index 12033ede64d..4c5df56a862 100644 --- "a/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" +++ "b/docs/dataStructures-algorithms/\347\256\227\346\263\225\345\255\246\344\271\240\350\265\204\346\272\220\346\216\250\350\215\220.md" @@ -7,7 +7,7 @@ - [如何高效地使用 LeetCode](https://leetcode-cn.com/articles/%E5%A6%82%E4%BD%95%E9%AB%98%E6%95%88%E5%9C%B0%E4%BD%BF%E7%94%A8-leetcode/) -## 牛客网: +## 牛客网 - [牛客网官网](https://www.nowcoder.com) - [剑指offer编程题](https://www.nowcoder.com/ta/coding-interviews) From ed500f9c3c10c6bb655cc6424bc64b2ff74d0c47 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:11:09 +0800 Subject: [PATCH 226/232] =?UTF-8?q?Update=20=E7=AE=97=E6=B3=95=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a422976cba9..4bd7255c783 100644 --- a/README.md +++ b/README.md @@ -133,10 +133,11 @@ ### 算法 -- [算法学习与面试](docs/dataStructures-algorithms/算法.md) -- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/搞定BAT面试——几道常见的子符串算法题.md) -- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/Leetcode-LinkList1.md) -- [常见安全算法(MD5、SHA1、Base64等等)总结](docs/dataStructures-algorithms/常见安全算法(MD5、SHA1、Base64等等)总结.md) +- [算法学习与面试](docs/dataStructures-algorithms/算法学习资源推荐.md) +- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/几道常见的字符串算法题.md) +- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/几道常见的子符串算法题.md) +- [剑指offer部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) +- [公司真题](docs/dataStructures-algorithms/公司真题.md) ## 数据库 From 49c266c638736c1618a238cad911b029f518990a Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:13:47 +0800 Subject: [PATCH 227/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4bd7255c783..f15f75667dd 100644 --- a/README.md +++ b/README.md @@ -134,8 +134,8 @@ ### 算法 - [算法学习与面试](docs/dataStructures-algorithms/算法学习资源推荐.md) -- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/几道常见的字符串算法题.md) -- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/几道常见的子符串算法题.md) +- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/几道常见的链表算法题.md) - [剑指offer部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) - [公司真题](docs/dataStructures-algorithms/公司真题.md) From c511ac5b0a3b2881cbb6007c88ae03be48a76ed5 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:14:35 +0800 Subject: [PATCH 228/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f15f75667dd..5fe2a82dd57 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ ### 算法 -- [算法学习与面试](docs/dataStructures-algorithms/算法学习资源推荐.md) +- [算法学习资源推荐](docs/dataStructures-algorithms/算法学习资源推荐.md) - [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/几道常见的子符串算法题.md) - [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/几道常见的链表算法题.md) - [剑指offer部分编程题](docs/dataStructures-algorithms/剑指offer部分编程题.md) From b21fc29c3ef7584d72a7e4688ff2aea048de62fc Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:20:41 +0800 Subject: [PATCH 229/232] =?UTF-8?q?Fix=20=E9=93=BE=E6=8E=A5=E5=A4=B1?= =?UTF-8?q?=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index cf6255b0265..76c5ad88c5f 100644 --- "a/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -356,7 +356,7 @@ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返 ## 28. 为什么Java中只有值传递 - [为什么Java中只有值传递?](https://github.com/Snailclimb/JavaGuide/blob/master/EssentialContentForInterview/MostCommonJavaInterviewQuestions/%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%882018-8-7%EF%BC%89.md) + [为什么Java中只有值传递?](https://github.com/Snailclimb/JavaGuide/blob/master/docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%882018-8-7%EF%BC%89.md) ## 29. 简述线程,程序,进程的基本概念.以及他们之间关系是什么? From 62a7db4151da36cd4ab10d07d7030b35ceb4872a Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:30:10 +0800 Subject: [PATCH 230/232] =?UTF-8?q?Add=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\257\207\346\226\207\347\253\240.md" | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git "a/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" "b/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" index 66a15333a0c..01b59724850 100644 --- "a/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" +++ "b/docs/java/\345\217\257\350\203\275\346\230\257\346\212\212Java\345\206\205\345\255\230\345\214\272\345\237\237\350\256\262\347\232\204\346\234\200\346\270\205\346\245\232\347\232\204\344\270\200\347\257\207\346\226\207\347\253\240.md" @@ -1,4 +1,29 @@ + + +- [写在前面(常见面试题)](#写在前面常见面试题) + - [基本问题](#基本问题) + - [拓展问题](#拓展问题) +- [一 概述](#一-概述) +- [二 运行时数据区域](#二-运行时数据区域) + - [2.1 程序计数器](#21-程序计数器) + - [2.2 Java 虚拟机栈](#22-java-虚拟机栈) + - [2.3 本地方法栈](#23-本地方法栈) + - [2.4 堆](#24-堆) + - [2.5 方法区](#25-方法区) + - [2.6 运行时常量池](#26-运行时常量池) + - [2.7 直接内存](#27-直接内存) +- [三 HotSpot 虚拟机对象探秘](#三-hotspot-虚拟机对象探秘) + - [3.1 对象的创建](#31-对象的创建) + - [3.2 对象的内存布局](#32-对象的内存布局) + - [3.3 对象的访问定位](#33-对象的访问定位) +- [四 重点补充内容](#四--重点补充内容) + - [String 类和常量池](#string-类和常量池) + - [String s1 = new String("abc");这句话创建了几个对象?](#string-s1--new-stringabc这句话创建了几个对象) + - [8种基本类型的包装类和常量池](#8种基本类型的包装类和常量池) +- [参考](#参考) + + ## 写在前面(常见面试题) ### 基本问题 From 6e72218966a57421c98176a5a272f03c6f9c568e Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:34:03 +0800 Subject: [PATCH 231/232] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E7=9F=A5=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java\345\237\272\347\241\200\347\237\245\350\257\206.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" index 76c5ad88c5f..d45865aac96 100644 --- "a/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" +++ "b/docs/java/Java\345\237\272\347\241\200\347\237\245\350\257\206.md" @@ -110,7 +110,7 @@ JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有 ## 4. Oracle JDK 和 OpenJDK 的对比 -可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么Oracle和OpenJDK之间是否存在重大差异?下面通过我通过我收集到一些资料对你解答这个被很多人忽视的问题。 +可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么Oracle和OpenJDK之间是否存在重大差异?下面我通过收集到的一些资料,为你解答这个被很多人忽视的问题。 对于Java 7,没什么关键的地方。OpenJDK项目主要基于Sun捐赠的HotSpot源代码。此外,OpenJDK被选为Java 7的参考实现,由Oracle工程师维护。关于JVM,JDK,JRE和OpenJDK之间的区别,Oracle博客帖子在2012年有一个更详细的答案: From 6d75966b49ae37397a72e3f54b69a85ca6cf8471 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 26 Mar 2019 20:38:21 +0800 Subject: [PATCH 232/232] Update HomePage.md --- docs/HomePage.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/HomePage.md b/docs/HomePage.md index 7e080ca6b88..c49cdb117d9 100644 --- a/docs/HomePage.md +++ b/docs/HomePage.md @@ -51,6 +51,11 @@ ### Java 8 * [Java 8 新特性总结](./java/What's%20New%20in%20JDK8/Java8Tutorial.md) +* [Java 8 学习资源推荐](./java/What's%20New%20in%20JDK8/Java8教程推荐.md) + +### 编程规范 + +- [Java 编程规范](./java/Java编程规范.md) ## 网络 @@ -73,10 +78,11 @@ ### 算法 -- [算法学习与面试](./dataStructures-algorithms/算法.md) -- [算法总结——几道常见的子符串算法题 ](./dataStructures-algorithms/搞定BAT面试——几道常见的子符串算法题.md) -- [算法总结——几道常见的链表算法题 ](./dataStructures-algorithms/Leetcode-LinkList1.md) -- [常见安全算法(MD5、SHA1、Base64等等)总结](./dataStructures-algorithms/常见安全算法(MD5、SHA1、Base64等等)总结.md) +- [算法学习资源推荐](./dataStructures-algorithms/算法学习资源推荐.md) +- [算法总结——几道常见的子符串算法题 ](./dataStructures-algorithms/几道常见的子符串算法题.md) +- [算法总结——几道常见的链表算法题 ](./dataStructures-algorithms/几道常见的链表算法题.md) +- [剑指offer部分编程题](./dataStructures-algorithms/剑指offer部分编程题.md) +- [公司真题](./dataStructures-algorithms/公司真题.md) ## 数据库