From f4b662ae3883f9b5b1c1ffaf996d68f982427348 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 14:35:24 +0800 Subject: [PATCH 01/73] Create ArrayList_25.md --- week_01/ 25/ArrayList_25.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 week_01/ 25/ArrayList_25.md diff --git a/week_01/ 25/ArrayList_25.md b/week_01/ 25/ArrayList_25.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week_01/ 25/ArrayList_25.md @@ -0,0 +1 @@ + From a23096144ab74ee30204096afda9f832de4bb989 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 14:35:45 +0800 Subject: [PATCH 02/73] commit --- week_01/25/ArrayList_25.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 week_01/25/ArrayList_25.md diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week_01/25/ArrayList_25.md @@ -0,0 +1 @@ + From 0ed48def0d0118db3d286349d84278c702afb657 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:24:00 +0800 Subject: [PATCH 03/73] commit --- week_01/25/ArrayList_25.md | 386 +++++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md index 8b13789..f80743c 100644 --- a/week_01/25/ArrayList_25.md +++ b/week_01/25/ArrayList_25.md @@ -1 +1,387 @@ +在分析动态数组ArrayList的源码之前先对其底层数据结构——数组进行分析 +# 数组 +数组是一种最基本的数据结构,采用了一组连续的内存空间按顺序存储对象或基本数据类型。其访问的时间复杂度为O(1),插入以及删除由于涉及到元素的移动时间复杂度为O(n),在Java中声明一个数组需要事先指定数组的大小,那么就可能会造成空间浪费以及扩容问题,为了解决这些问题,动态数组ArrayList就诞生了。 +# ArrayList +```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable +``` +(1)实现了RandomAccess接口,标识其具备随机访问功能 +(2)实现了List,提供了List基础的增,删,改,查等操作 +(3)实现了Cloneable,可以被克隆 +(4)实现了Serializable,可以被序列化 + +### 属性 +```java + /** + * 默认的容量大小为10 + * Lazy-load: 只有在ArrayList真正添加元素的时候才会通过DEFAULT_CAPACITY创建数组, + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * 当指定ArrayList容量为0的时候, 底层使用的空数组 + */ + private static final Object[] EMPTY_ELEMENTDATA = {}; + + /** + * 调用默认构造函数ArrayList()时,使用这个空数组作为elementData + * 与EMPTY_ELEMENTDATA的区别在于: DEFAULTCAPACITY_EMPTY_ELEMENTDATA在第一次添加元素时会变为长度为DEFAULT_CAPACITY的数组 + */ + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + /** + * 真正存储元素的数组 + * 标记了transient,此字段不会被序列化 + */ + transient Object[] elementData; // non-private to simplify nested class access + + /** + * 容器中元素的个数 + */ + private int size; +``` + +### 构造函数 +```java + /** + * 1. 指定容器大小初始化ArrayList + */ + public ArrayList(int initialCapacity) { + //若传入初始Capacity > 0, 那么就根据Capacity创建对应长度的Object数组 + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + //若传入初始Capacity = 0, 那么就将EMPTY_ELEMENTDATA这个空数组赋给elementData + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + //若传入初始Capacity < 0, throw Exception + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + + /** + * 2. 默认构造函数 + */ + public ArrayList() { + //将DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个空数组赋给elementData + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + + /** + * 3. 通过传入一个集合初始化ArrayList + */ + public ArrayList(Collection c) { + //把传入的集合元素转换为数组拷贝给elementData + elementData = c.toArray(); + //检查拷贝之后, elementData的长度是否为0 + if ((size = elementData.length) != 0) { + // c.toArray或许不能正确地转换为Object数组 + if (elementData.getClass() != Object[].class) + //若没有正确转换为Object[], 重新拷贝成Object[].class类型再赋给elementData + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // 若拷贝之后elementData长度为0, 那么直接将EMPTY_ELEMENTDATA赋给elementData + this.elementData = EMPTY_ELEMENTDATA; + } + } +``` + +### add(E e) 添加元素到数组末尾 +因为添加元素到数组末尾并不涉及到其他元素的移动,因此时间复杂度为O(1) +```java + /** + * 添加元素到数组末尾, 时间复杂度为O(1) + */ + public boolean add(E e) { + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //把元素插入到elementData的末尾元素之后 + elementData[size++] = e; + return true; + } + + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + + private static int calculateCapacity(Object[] elementData, int minCapacity) { + //如果当前ArrayList处于刚初始化的状态, 就返回默认长度10 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + return Math.max(DEFAULT_CAPACITY, minCapacity); + } + //如果ArrayList已经处于正在使用的状态(已经进行了添加操作), 直接返回传入的minCapacity + return minCapacity; + } + + + private void ensureExplicitCapacity(int minCapacity) { + modCount++;//modCount用于记录操作ArrayList的次数 + + // 如果elementData的长度小于添加元素所需要的minCapacity, 需要对原数组进行扩容操作 + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + + private void grow(int minCapacity) { + //原数组长度 + int oldCapacity = elementData.length; + //新数组的长度 = 原数组长度的1.5倍 + int newCapacity = oldCapacity + (oldCapacity >> 1); + //如果新数组的长度依然小于minCapacity, 那么以minCapacity为准进行数组扩容 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + //若新数组长度已经超过ArrayList规定的最大长度, 则使用最大长度 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + //底层是根据newCapacity创建了一个新的数组, 然后在这个新数组之上添加原数组的元素 + //将新数组赋值给elementData + elementData = Arrays.copyOf(elementData, newCapacity); + } +``` + +### add(int index, E element) 在指定位置添加元素 +(1)检查index是否越界 +(2)检查是否需要扩容 +(3)右移index以及后续所有元素 +(4)index位置插入新元素 +(5)size++ +```java + /** + * 在指定位置插入元素, 并将原本在该位置的元素以及右边的所有元素向右移动一位 + */ + public void add(int index, E element) { + //检查index是否越界 + rangeCheckForAdd(index); + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //移动原本在该位置的元素以及右边的所有元素 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + //在index位置插入元素 + elementData[index] = element; + size++; + } + + /** + * 确保index合法 + */ + private void rangeCheckForAdd(int index) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } +``` + +### addAll(Collection c) 在末尾追加集合c中的所有元素 +(1)将集合c转换为Object数组 +(2)检查是否需要扩容 +(3)将集合c中的元素全部拷贝到原数组末尾 +```java + public boolean addAll(Collection c) { + //将集合c转换为Object[] + Object[] a = c.toArray(); + int numNew = a.length; + //检查是否需要扩容 + ensureCapacityInternal(size + numNew); // Increments modCount + //将集合c中的元素全部拷贝到原数组末尾 + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + //若c不为空return true, else return false + return numNew != 0; + } +``` + +### addAll(int index, Collection c) 指定位置添加集合c的所有元素 +(1)检查index是否越界 +(2)将集合c转换为Object数组 +(3)检查是否需要扩容 +(4)移动index以及右边的所有元素,挪出空间存放集合c的所有元素 +(5)index位置添加集合c的所有元素 +```java + public boolean addAll(int index, Collection c) { + //检查index是否合法 + rangeCheckForAdd(index); + //这里的几个步骤都和addAll(Collection c)相同 + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount + //需要移动的元素个数 + int numMoved = size - index; + //若需要移动的元素个数大于0, 那么需要进行元素移动操作 + if (numMoved > 0) + //右移index以及右边的所有元素, 挪出空间用于存放集合c的元素 + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved); + //在index位置将集合c的所有元素拷贝至elementData + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; + return numNew != 0; + } +``` + +### get(int index) 获取指定位置上的元素 +(1)检查index是否越界 +(2)返回index位置上的元素 +```java + public E get(int index) { + rangeCheck(index); + return elementData(index); + } + + /** + * 这里只检查是否越上界, 如果越下界会抛出ArrayIndexOutOfBoundsException + */ + private void rangeCheck(int index) { + if (index >= size) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + E elementData(int index) { + return (E) elementData[index]; + } +``` + +### remove(int index) 删除指定位置上的元素并返回 +(1)检查index是否越界 +(2)获取index位置上的元素 +(3)若index不指向末尾元素,index后面的元素前移一位 +(4)末尾元素置为null,便于GC回收 +(5)返回删除元素 +```java + public E remove(int index) { + //检查index是否越界 + rangeCheck(index); + + modCount++; + //获取index位置上的元素 + E oldValue = elementData(index); + //如果index并不指向最后一个元素, 那么就前移index后面的元素 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + //elementData最后一位置为null, 消除引用便于GC回收 + elementData[--size] = null; + return oldValue; + } +``` + +### remove(Object o) 删除指定元素值 +(1)遍历整个数组找到指定元素 +(2)fastRemove +```java + /** + 删除数组中第一次出现的指定元素, 删除成功return true, else return false + */ + public boolean remove(Object o) { + //遍历整个数组, 删除第一个出现的null元素 (这里使用"=="进行比较) + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else {//遍历整个数组, 删除第一个出现的指定元素 (这里使用"equals()"进行比较) + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; + } + + /* + * 删除指定位置的元素 + * 与remove()相比, 该方法略去了越界检查以及返回删除元素, 其他步骤都是一样的 + * 之所以这样做是因为, 省去了不必要的检查操作, 提升了性能 + */ + private void fastRemove(int index) { + modCount++; + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work + } +``` + +### retainAll(Collection c) 求与集合c的交集部分 +(1)集合c检查是否为空 +(2)遍历element,保留与集合c相交的部分,删除不相交的部分(写指针之后的所有元素置为空) +(3)若成功批量删除return true,else return false +```java + public boolean retainAll(Collection c) { + //要求集合c不为空 + Objects.requireNonNull(c); + //调用批量删除方法, 此时boolean complement = true, 表示删除不包含在c中的元素 + return batchRemove(c, true); + } + + /** + * 批量删除元素 + * complement = true: 删除c中不包含的元素 + * complement = false: 删除c中包含的元素 + */ + private boolean batchRemove(Collection c, boolean complement) { + final Object[] elementData = this.elementData; + //初始化读指针r, 写指针w + int r = 0, w = 0; + //是否成功修改的返回值, 默认false + boolean modified = false; + try { + //遍历整个数组, 如果集合c中包含读指针指向的元素, 且complement = ture, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList相交的部分, 删除了不相交的元素 + //如果集合c中不包含读指针指向的元素, 且complement = false, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList不相交的部分, 删除了相交的元素 + //整个操作都在原数组上完成, 不需要额外空间 + //这个操作有点类似LeetCode上移动零那道题, 比较典型的双指针解法 + for (; r < size; r++) + if (c.contains(elementData[r]) == complement) + elementData[w++] = elementData[r]; + } finally { + //正常情况下, 读指针最后一定是指向size的, 除非c.contains()抛出了异常 + if (r != size) { + //若c.contains抛出异常, 则把未读元素都拷贝到写指针之后 + System.arraycopy(elementData, r, + elementData, w, + size - r); + //写指针指向相应的位置 + w += size - r; + } + //若写指针不指向末尾元素, 那么写指针后序的元素都需要置为空 + if (w != size) { + // clear to let GC do its work + for (int i = w; i < size; i++) + elementData[i] = null; + modCount += size - w; + //此时删除后的size等于写指针所指的位置 + size = w; + //标识完成了整个批量删除 + modified = true; + } + } + return modified; + } +``` + +### removeAll(Collection c) 求与集合c的差集 +```java + /** + * 保留当前集合中不与c相交的元素 + */ + public boolean removeAll(Collection c) { + Objects.requireNonNull(c); + //同样调用了批量删除方法, complement = false意味着删除包含在c中的元素 + return batchRemove(c, false); + } +``` + +# 总结 +(1)ArrayList底层采用Object数组进行数据存储,每次添加时都会检查是否需要扩容,若容量不足则通过创建一个新的长度为原长度1.5倍的数组,并将原数组拷贝至新数组并返回。 +(2)ArrayList随机访问时间复杂度为O(1) +(3)ArrayList添加元素到末尾的时间复杂度为O(1),添加元素到中间位置的时间复杂度为O(n) +(4)ArrayList删除末尾元素的时间复杂度为O(1),删除中间位置元素的时间复杂度为O(n) +(5)ArrayList支持求并集,调用addAll(Collection c) +(6)ArrayList支持求交集,调用retainAll(Collection c) +(7)ArrayList支持求单向差集,调用removeAll(Collection c) From 5935de236b986d3efba2eb2ec020297482194503 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:31:11 +0800 Subject: [PATCH 04/73] Update ArrayList_25.md --- week_01/25/ArrayList_25.md | 403 ++++++++++++++++++++++++++++++++++++- 1 file changed, 399 insertions(+), 4 deletions(-) diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md index f80743c..8d5b66a 100644 --- a/week_01/25/ArrayList_25.md +++ b/week_01/25/ArrayList_25.md @@ -7,10 +7,14 @@ public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable ``` -(1)实现了RandomAccess接口,标识其具备随机访问功能 -(2)实现了List,提供了List基础的增,删,改,查等操作 -(3)实现了Cloneable,可以被克隆 -(4)实现了Serializable,可以被序列化 +(1)实现了RandomAccess接口,标识其具备随机访问功能 + +(2)实现了List,提供了List基础的增,删,改,查等操作 + +(3)实现了Cloneable,可以被克隆 + +(4)实现了Serializable,可以被序列化 + ### 属性 ```java @@ -385,3 +389,394 @@ public class ArrayList extends AbstractList (5)ArrayList支持求并集,调用addAll(Collection c) (6)ArrayList支持求交集,调用retainAll(Collection c) (7)ArrayList支持求单向差集,调用removeAll(Collection c) +在分析动态数组ArrayList的源码之前先对其底层数据结构——数组进行分析 +# 数组 +数组是一种最基本的数据结构,采用了一组连续的内存空间按顺序存储对象或基本数据类型。其访问的时间复杂度为O(1),插入以及删除由于涉及到元素的移动时间复杂度为O(n),在Java中声明一个数组需要事先指定数组的大小,那么就可能会造成空间浪费以及扩容问题,为了解决这些问题,动态数组ArrayList就诞生了。 + +# ArrayList +```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable +``` +(1)实现了RandomAccess接口,标识其具备随机访问功能 +(2)实现了List,提供了List基础的增,删,改,查等操作 +(3)实现了Cloneable,可以被克隆 +(4)实现了Serializable,可以被序列化 + +### 属性 +```java + /** + * 默认的容量大小为10 + * Lazy-load: 只有在ArrayList真正添加元素的时候才会通过DEFAULT_CAPACITY创建数组, + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * 当指定ArrayList容量为0的时候, 底层使用的空数组 + */ + private static final Object[] EMPTY_ELEMENTDATA = {}; + + /** + * 调用默认构造函数ArrayList()时,使用这个空数组作为elementData + * 与EMPTY_ELEMENTDATA的区别在于: DEFAULTCAPACITY_EMPTY_ELEMENTDATA在第一次添加元素时会变为长度为DEFAULT_CAPACITY的数组 + */ + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + /** + * 真正存储元素的数组 + * 标记了transient,此字段不会被序列化 + */ + transient Object[] elementData; // non-private to simplify nested class access + + /** + * 容器中元素的个数 + */ + private int size; +``` + +### 构造函数 +```java + /** + * 1. 指定容器大小初始化ArrayList + */ + public ArrayList(int initialCapacity) { + //若传入初始Capacity > 0, 那么就根据Capacity创建对应长度的Object数组 + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + //若传入初始Capacity = 0, 那么就将EMPTY_ELEMENTDATA这个空数组赋给elementData + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + //若传入初始Capacity < 0, throw Exception + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + + /** + * 2. 默认构造函数 + */ + public ArrayList() { + //将DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个空数组赋给elementData + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + + /** + * 3. 通过传入一个集合初始化ArrayList + */ + public ArrayList(Collection c) { + //把传入的集合元素转换为数组拷贝给elementData + elementData = c.toArray(); + //检查拷贝之后, elementData的长度是否为0 + if ((size = elementData.length) != 0) { + // c.toArray或许不能正确地转换为Object数组 + if (elementData.getClass() != Object[].class) + //若没有正确转换为Object[], 重新拷贝成Object[].class类型再赋给elementData + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // 若拷贝之后elementData长度为0, 那么直接将EMPTY_ELEMENTDATA赋给elementData + this.elementData = EMPTY_ELEMENTDATA; + } + } +``` + +### add(E e) 添加元素到数组末尾 +(1)明确添加元素后数组所需要的最小长度minCapacity +(2)如果minCapacity > elementData.length,需要进行数组扩容 +(3)在末尾处添加元素 +(4)添加成功return true + +```java + /** + * 添加元素到数组末尾, 时间复杂度为O(1) + */ + public boolean add(E e) { + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //把元素插入到elementData的末尾元素之后 + elementData[size++] = e; + return true; + } + + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + + private static int calculateCapacity(Object[] elementData, int minCapacity) { + //如果当前ArrayList处于刚初始化的状态, 就返回默认长度10 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + return Math.max(DEFAULT_CAPACITY, minCapacity); + } + //如果ArrayList已经处于正在使用的状态(已经进行了添加操作), 直接返回传入的minCapacity + return minCapacity; + } + + + private void ensureExplicitCapacity(int minCapacity) { + modCount++;//modCount用于记录操作ArrayList的次数 + + // 如果elementData的长度小于添加元素所需要的minCapacity, 需要对原数组进行扩容操作 + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + + private void grow(int minCapacity) { + //原数组长度 + int oldCapacity = elementData.length; + //新数组的长度 = 原数组长度的1.5倍 + int newCapacity = oldCapacity + (oldCapacity >> 1); + //如果新数组的长度依然小于minCapacity, 那么以minCapacity为准进行数组扩容 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + //若新数组长度已经超过ArrayList规定的最大长度, 则使用最大长度 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + //底层是根据newCapacity创建了一个新的数组, 然后在这个新数组之上添加原数组的元素 + //将新数组赋值给elementData + elementData = Arrays.copyOf(elementData, newCapacity); + } +``` + +### add(int index, E element) 在指定位置添加元素 +(1)检查index是否越界 +(2)检查是否需要扩容 +(3)右移index以及后续所有元素 +(4)index位置插入新元素 +(5)size++ +```java + /** + * 在指定位置插入元素, 并将原本在该位置的元素以及右边的所有元素向右移动一位 + */ + public void add(int index, E element) { + //检查index是否越界 + rangeCheckForAdd(index); + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //移动原本在该位置的元素以及右边的所有元素 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + //在index位置插入元素 + elementData[index] = element; + size++; + } + + /** + * 确保index合法 + */ + private void rangeCheckForAdd(int index) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } +``` + +### addAll(Collection c) 在末尾追加集合c中的所有元素 +(1)将集合c转换为Object数组 +(2)检查是否需要扩容 +(3)将集合c中的元素全部拷贝到原数组末尾 +```java + public boolean addAll(Collection c) { + //将集合c转换为Object[] + Object[] a = c.toArray(); + int numNew = a.length; + //检查是否需要扩容 + ensureCapacityInternal(size + numNew); // Increments modCount + //将集合c中的元素全部拷贝到原数组末尾 + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + //若c不为空return true, else return false + return numNew != 0; + } +``` + +### addAll(int index, Collection c) 指定位置添加集合c的所有元素 +(1)检查index是否越界 +(2)将集合c转换为Object数组 +(3)检查是否需要扩容 +(4)移动index以及右边的所有元素,挪出空间存放集合c的所有元素 +(5)index位置添加集合c的所有元素 +```java + public boolean addAll(int index, Collection c) { + //检查index是否合法 + rangeCheckForAdd(index); + //这里的几个步骤都和addAll(Collection c)相同 + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount + //需要移动的元素个数 + int numMoved = size - index; + //若需要移动的元素个数大于0, 那么需要进行元素移动操作 + if (numMoved > 0) + //右移index以及右边的所有元素, 挪出空间用于存放集合c的元素 + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved); + //在index位置将集合c的所有元素拷贝至elementData + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; + return numNew != 0; + } +``` + +### get(int index) 获取指定位置上的元素 +(1)检查index是否越界 +(2)返回index位置上的元素 +```java + public E get(int index) { + rangeCheck(index); + return elementData(index); + } + + /** + * 这里只检查是否越上界, 如果越下界会抛出ArrayIndexOutOfBoundsException + */ + private void rangeCheck(int index) { + if (index >= size) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + E elementData(int index) { + return (E) elementData[index]; + } +``` + +### remove(int index) 删除指定位置上的元素并返回 +(1)检查index是否越界 +(2)获取index位置上的元素 +(3)若index不指向末尾元素,index后面的元素前移一位 +(4)末尾元素置为null,便于GC回收 +(5)返回删除元素 +```java + public E remove(int index) { + //检查index是否越界 + rangeCheck(index); + + modCount++; + //获取index位置上的元素 + E oldValue = elementData(index); + //如果index并不指向最后一个元素, 那么就前移index后面的元素 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + //elementData最后一位置为null, 消除引用便于GC回收 + elementData[--size] = null; + return oldValue; + } +``` + +### remove(Object o) 删除指定元素值 +(1)遍历整个数组找到指定元素 +(2)fastRemove +```java + /** + 删除数组中第一次出现的指定元素, 删除成功return true, else return false + */ + public boolean remove(Object o) { + //遍历整个数组, 删除第一个出现的null元素 (这里使用"=="进行比较) + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else {//遍历整个数组, 删除第一个出现的指定元素 (这里使用"equals()"进行比较) + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; + } + + /* + * 删除指定位置的元素 + * 与remove()相比, 该方法略去了越界检查以及返回删除元素, 其他步骤都是一样的 + * 之所以这样做是因为, 省去了不必要的检查操作, 提升了性能 + */ + private void fastRemove(int index) { + modCount++; + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work + } +``` + +### retainAll(Collection c) 求与集合c的交集部分 +(1)集合c检查是否为空 +(2)遍历element,保留与集合c相交的部分,删除不相交的部分(写指针之后的所有元素置为空) +(3)若成功批量删除return true,else return false +```java + public boolean retainAll(Collection c) { + //要求集合c不为空 + Objects.requireNonNull(c); + //调用批量删除方法, 此时boolean complement = true, 表示删除不包含在c中的元素 + return batchRemove(c, true); + } + + /** + * 批量删除元素 + * complement = true: 删除c中不包含的元素 + * complement = false: 删除c中包含的元素 + */ + private boolean batchRemove(Collection c, boolean complement) { + final Object[] elementData = this.elementData; + //初始化读指针r, 写指针w + int r = 0, w = 0; + //是否成功修改的返回值, 默认false + boolean modified = false; + try { + //遍历整个数组, 如果集合c中包含读指针指向的元素, 且complement = ture, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList相交的部分, 删除了不相交的元素 + //如果集合c中不包含读指针指向的元素, 且complement = false, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList不相交的部分, 删除了相交的元素 + //整个操作都在原数组上完成, 不需要额外空间 + //这个操作有点类似LeetCode上移动零那道题, 比较典型的双指针解法 + for (; r < size; r++) + if (c.contains(elementData[r]) == complement) + elementData[w++] = elementData[r]; + } finally { + //正常情况下, 读指针最后一定是指向size的, 除非c.contains()抛出了异常 + if (r != size) { + //若c.contains抛出异常, 则把未读元素都拷贝到写指针之后 + System.arraycopy(elementData, r, + elementData, w, + size - r); + //写指针指向相应的位置 + w += size - r; + } + //若写指针不指向末尾元素, 那么写指针后序的元素都需要置为空 + if (w != size) { + // clear to let GC do its work + for (int i = w; i < size; i++) + elementData[i] = null; + modCount += size - w; + //此时删除后的size等于写指针所指的位置 + size = w; + //标识完成了整个批量删除 + modified = true; + } + } + return modified; + } +``` + +### removeAll(Collection c) 求与集合c的差集 +```java + /** + * 保留当前集合中不与c相交的元素 + */ + public boolean removeAll(Collection c) { + Objects.requireNonNull(c); + //同样调用了批量删除方法, complement = false意味着删除包含在c中的元素 + return batchRemove(c, false); + } +``` + +# 总结 +(1)ArrayList底层采用Object数组进行数据存储,每次添加时都会检查是否需要扩容,若容量不足则通过创建一个新的长度为原长度1.5倍的数组,并将原数组拷贝至新数组并返回。 +(2)ArrayList随机访问时间复杂度为O(1) +(3)ArrayList添加元素到末尾的时间复杂度为O(1),添加元素到中间位置的时间复杂度为O(n) +(4)ArrayList删除末尾元素的时间复杂度为O(1),删除中间位置元素的时间复杂度为O(n) +(5)ArrayList支持求并集,调用addAll(Collection c) +(6)ArrayList支持求交集,调用retainAll(Collection c) +(7)ArrayList支持求单向差集,调用removeAll(Collection c) From eb8142c3fd5b9c048ea8acc8dd4151dd67858e35 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:32:24 +0800 Subject: [PATCH 05/73] Update ArrayList_25.md --- week_01/25/ArrayList_25.md | 391 ------------------------------------- 1 file changed, 391 deletions(-) diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md index 8d5b66a..4f0be75 100644 --- a/week_01/25/ArrayList_25.md +++ b/week_01/25/ArrayList_25.md @@ -2,397 +2,6 @@ # 数组 数组是一种最基本的数据结构,采用了一组连续的内存空间按顺序存储对象或基本数据类型。其访问的时间复杂度为O(1),插入以及删除由于涉及到元素的移动时间复杂度为O(n),在Java中声明一个数组需要事先指定数组的大小,那么就可能会造成空间浪费以及扩容问题,为了解决这些问题,动态数组ArrayList就诞生了。 -# ArrayList -```java -public class ArrayList extends AbstractList - implements List, RandomAccess, Cloneable, java.io.Serializable -``` -(1)实现了RandomAccess接口,标识其具备随机访问功能 - -(2)实现了List,提供了List基础的增,删,改,查等操作 - -(3)实现了Cloneable,可以被克隆 - -(4)实现了Serializable,可以被序列化 - - -### 属性 -```java - /** - * 默认的容量大小为10 - * Lazy-load: 只有在ArrayList真正添加元素的时候才会通过DEFAULT_CAPACITY创建数组, - */ - private static final int DEFAULT_CAPACITY = 10; - - /** - * 当指定ArrayList容量为0的时候, 底层使用的空数组 - */ - private static final Object[] EMPTY_ELEMENTDATA = {}; - - /** - * 调用默认构造函数ArrayList()时,使用这个空数组作为elementData - * 与EMPTY_ELEMENTDATA的区别在于: DEFAULTCAPACITY_EMPTY_ELEMENTDATA在第一次添加元素时会变为长度为DEFAULT_CAPACITY的数组 - */ - private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; - - /** - * 真正存储元素的数组 - * 标记了transient,此字段不会被序列化 - */ - transient Object[] elementData; // non-private to simplify nested class access - - /** - * 容器中元素的个数 - */ - private int size; -``` - -### 构造函数 -```java - /** - * 1. 指定容器大小初始化ArrayList - */ - public ArrayList(int initialCapacity) { - //若传入初始Capacity > 0, 那么就根据Capacity创建对应长度的Object数组 - if (initialCapacity > 0) { - this.elementData = new Object[initialCapacity]; - //若传入初始Capacity = 0, 那么就将EMPTY_ELEMENTDATA这个空数组赋给elementData - } else if (initialCapacity == 0) { - this.elementData = EMPTY_ELEMENTDATA; - //若传入初始Capacity < 0, throw Exception - } else { - throw new IllegalArgumentException("Illegal Capacity: "+ - initialCapacity); - } - } - - /** - * 2. 默认构造函数 - */ - public ArrayList() { - //将DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个空数组赋给elementData - this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; - } - - /** - * 3. 通过传入一个集合初始化ArrayList - */ - public ArrayList(Collection c) { - //把传入的集合元素转换为数组拷贝给elementData - elementData = c.toArray(); - //检查拷贝之后, elementData的长度是否为0 - if ((size = elementData.length) != 0) { - // c.toArray或许不能正确地转换为Object数组 - if (elementData.getClass() != Object[].class) - //若没有正确转换为Object[], 重新拷贝成Object[].class类型再赋给elementData - elementData = Arrays.copyOf(elementData, size, Object[].class); - } else { - // 若拷贝之后elementData长度为0, 那么直接将EMPTY_ELEMENTDATA赋给elementData - this.elementData = EMPTY_ELEMENTDATA; - } - } -``` - -### add(E e) 添加元素到数组末尾 -因为添加元素到数组末尾并不涉及到其他元素的移动,因此时间复杂度为O(1) -```java - /** - * 添加元素到数组末尾, 时间复杂度为O(1) - */ - public boolean add(E e) { - //确保ArrayList有足够的Capacity添加新的元素 - ensureCapacityInternal(size + 1); - //把元素插入到elementData的末尾元素之后 - elementData[size++] = e; - return true; - } - - private void ensureCapacityInternal(int minCapacity) { - ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); - } - - private static int calculateCapacity(Object[] elementData, int minCapacity) { - //如果当前ArrayList处于刚初始化的状态, 就返回默认长度10 - if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { - return Math.max(DEFAULT_CAPACITY, minCapacity); - } - //如果ArrayList已经处于正在使用的状态(已经进行了添加操作), 直接返回传入的minCapacity - return minCapacity; - } - - - private void ensureExplicitCapacity(int minCapacity) { - modCount++;//modCount用于记录操作ArrayList的次数 - - // 如果elementData的长度小于添加元素所需要的minCapacity, 需要对原数组进行扩容操作 - if (minCapacity - elementData.length > 0) - grow(minCapacity); - } - - private void grow(int minCapacity) { - //原数组长度 - int oldCapacity = elementData.length; - //新数组的长度 = 原数组长度的1.5倍 - int newCapacity = oldCapacity + (oldCapacity >> 1); - //如果新数组的长度依然小于minCapacity, 那么以minCapacity为准进行数组扩容 - if (newCapacity - minCapacity < 0) - newCapacity = minCapacity; - //若新数组长度已经超过ArrayList规定的最大长度, 则使用最大长度 - if (newCapacity - MAX_ARRAY_SIZE > 0) - newCapacity = hugeCapacity(minCapacity); - //底层是根据newCapacity创建了一个新的数组, 然后在这个新数组之上添加原数组的元素 - //将新数组赋值给elementData - elementData = Arrays.copyOf(elementData, newCapacity); - } -``` - -### add(int index, E element) 在指定位置添加元素 -(1)检查index是否越界 -(2)检查是否需要扩容 -(3)右移index以及后续所有元素 -(4)index位置插入新元素 -(5)size++ -```java - /** - * 在指定位置插入元素, 并将原本在该位置的元素以及右边的所有元素向右移动一位 - */ - public void add(int index, E element) { - //检查index是否越界 - rangeCheckForAdd(index); - //确保ArrayList有足够的Capacity添加新的元素 - ensureCapacityInternal(size + 1); - //移动原本在该位置的元素以及右边的所有元素 - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - //在index位置插入元素 - elementData[index] = element; - size++; - } - - /** - * 确保index合法 - */ - private void rangeCheckForAdd(int index) { - if (index > size || index < 0) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } -``` - -### addAll(Collection c) 在末尾追加集合c中的所有元素 -(1)将集合c转换为Object数组 -(2)检查是否需要扩容 -(3)将集合c中的元素全部拷贝到原数组末尾 -```java - public boolean addAll(Collection c) { - //将集合c转换为Object[] - Object[] a = c.toArray(); - int numNew = a.length; - //检查是否需要扩容 - ensureCapacityInternal(size + numNew); // Increments modCount - //将集合c中的元素全部拷贝到原数组末尾 - System.arraycopy(a, 0, elementData, size, numNew); - size += numNew; - //若c不为空return true, else return false - return numNew != 0; - } -``` - -### addAll(int index, Collection c) 指定位置添加集合c的所有元素 -(1)检查index是否越界 -(2)将集合c转换为Object数组 -(3)检查是否需要扩容 -(4)移动index以及右边的所有元素,挪出空间存放集合c的所有元素 -(5)index位置添加集合c的所有元素 -```java - public boolean addAll(int index, Collection c) { - //检查index是否合法 - rangeCheckForAdd(index); - //这里的几个步骤都和addAll(Collection c)相同 - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - //需要移动的元素个数 - int numMoved = size - index; - //若需要移动的元素个数大于0, 那么需要进行元素移动操作 - if (numMoved > 0) - //右移index以及右边的所有元素, 挪出空间用于存放集合c的元素 - System.arraycopy(elementData, index, elementData, index + numNew, - numMoved); - //在index位置将集合c的所有元素拷贝至elementData - System.arraycopy(a, 0, elementData, index, numNew); - size += numNew; - return numNew != 0; - } -``` - -### get(int index) 获取指定位置上的元素 -(1)检查index是否越界 -(2)返回index位置上的元素 -```java - public E get(int index) { - rangeCheck(index); - return elementData(index); - } - - /** - * 这里只检查是否越上界, 如果越下界会抛出ArrayIndexOutOfBoundsException - */ - private void rangeCheck(int index) { - if (index >= size) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - E elementData(int index) { - return (E) elementData[index]; - } -``` - -### remove(int index) 删除指定位置上的元素并返回 -(1)检查index是否越界 -(2)获取index位置上的元素 -(3)若index不指向末尾元素,index后面的元素前移一位 -(4)末尾元素置为null,便于GC回收 -(5)返回删除元素 -```java - public E remove(int index) { - //检查index是否越界 - rangeCheck(index); - - modCount++; - //获取index位置上的元素 - E oldValue = elementData(index); - //如果index并不指向最后一个元素, 那么就前移index后面的元素 - int numMoved = size - index - 1; - if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, - numMoved); - //elementData最后一位置为null, 消除引用便于GC回收 - elementData[--size] = null; - return oldValue; - } -``` - -### remove(Object o) 删除指定元素值 -(1)遍历整个数组找到指定元素 -(2)fastRemove -```java - /** - 删除数组中第一次出现的指定元素, 删除成功return true, else return false - */ - public boolean remove(Object o) { - //遍历整个数组, 删除第一个出现的null元素 (这里使用"=="进行比较) - if (o == null) { - for (int index = 0; index < size; index++) - if (elementData[index] == null) { - fastRemove(index); - return true; - } - } else {//遍历整个数组, 删除第一个出现的指定元素 (这里使用"equals()"进行比较) - for (int index = 0; index < size; index++) - if (o.equals(elementData[index])) { - fastRemove(index); - return true; - } - } - return false; - } - - /* - * 删除指定位置的元素 - * 与remove()相比, 该方法略去了越界检查以及返回删除元素, 其他步骤都是一样的 - * 之所以这样做是因为, 省去了不必要的检查操作, 提升了性能 - */ - private void fastRemove(int index) { - modCount++; - int numMoved = size - index - 1; - if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, - numMoved); - elementData[--size] = null; // clear to let GC do its work - } -``` - -### retainAll(Collection c) 求与集合c的交集部分 -(1)集合c检查是否为空 -(2)遍历element,保留与集合c相交的部分,删除不相交的部分(写指针之后的所有元素置为空) -(3)若成功批量删除return true,else return false -```java - public boolean retainAll(Collection c) { - //要求集合c不为空 - Objects.requireNonNull(c); - //调用批量删除方法, 此时boolean complement = true, 表示删除不包含在c中的元素 - return batchRemove(c, true); - } - - /** - * 批量删除元素 - * complement = true: 删除c中不包含的元素 - * complement = false: 删除c中包含的元素 - */ - private boolean batchRemove(Collection c, boolean complement) { - final Object[] elementData = this.elementData; - //初始化读指针r, 写指针w - int r = 0, w = 0; - //是否成功修改的返回值, 默认false - boolean modified = false; - try { - //遍历整个数组, 如果集合c中包含读指针指向的元素, 且complement = ture, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList相交的部分, 删除了不相交的元素 - //如果集合c中不包含读指针指向的元素, 且complement = false, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList不相交的部分, 删除了相交的元素 - //整个操作都在原数组上完成, 不需要额外空间 - //这个操作有点类似LeetCode上移动零那道题, 比较典型的双指针解法 - for (; r < size; r++) - if (c.contains(elementData[r]) == complement) - elementData[w++] = elementData[r]; - } finally { - //正常情况下, 读指针最后一定是指向size的, 除非c.contains()抛出了异常 - if (r != size) { - //若c.contains抛出异常, 则把未读元素都拷贝到写指针之后 - System.arraycopy(elementData, r, - elementData, w, - size - r); - //写指针指向相应的位置 - w += size - r; - } - //若写指针不指向末尾元素, 那么写指针后序的元素都需要置为空 - if (w != size) { - // clear to let GC do its work - for (int i = w; i < size; i++) - elementData[i] = null; - modCount += size - w; - //此时删除后的size等于写指针所指的位置 - size = w; - //标识完成了整个批量删除 - modified = true; - } - } - return modified; - } -``` - -### removeAll(Collection c) 求与集合c的差集 -```java - /** - * 保留当前集合中不与c相交的元素 - */ - public boolean removeAll(Collection c) { - Objects.requireNonNull(c); - //同样调用了批量删除方法, complement = false意味着删除包含在c中的元素 - return batchRemove(c, false); - } -``` - -# 总结 -(1)ArrayList底层采用Object数组进行数据存储,每次添加时都会检查是否需要扩容,若容量不足则通过创建一个新的长度为原长度1.5倍的数组,并将原数组拷贝至新数组并返回。 -(2)ArrayList随机访问时间复杂度为O(1) -(3)ArrayList添加元素到末尾的时间复杂度为O(1),添加元素到中间位置的时间复杂度为O(n) -(4)ArrayList删除末尾元素的时间复杂度为O(1),删除中间位置元素的时间复杂度为O(n) -(5)ArrayList支持求并集,调用addAll(Collection c) -(6)ArrayList支持求交集,调用retainAll(Collection c) -(7)ArrayList支持求单向差集,调用removeAll(Collection c) -在分析动态数组ArrayList的源码之前先对其底层数据结构——数组进行分析 -# 数组 -数组是一种最基本的数据结构,采用了一组连续的内存空间按顺序存储对象或基本数据类型。其访问的时间复杂度为O(1),插入以及删除由于涉及到元素的移动时间复杂度为O(n),在Java中声明一个数组需要事先指定数组的大小,那么就可能会造成空间浪费以及扩容问题,为了解决这些问题,动态数组ArrayList就诞生了。 - # ArrayList ```java public class ArrayList extends AbstractList From c9cf91b7da8fd27021e5e7d165bcfeb75922980c Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:42:12 +0800 Subject: [PATCH 06/73] Update ArrayList_25.md --- week_01/25/ArrayList_25.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md index 4f0be75..6e5c143 100644 --- a/week_01/25/ArrayList_25.md +++ b/week_01/25/ArrayList_25.md @@ -389,3 +389,5 @@ public class ArrayList extends AbstractList (5)ArrayList支持求并集,调用addAll(Collection c) (6)ArrayList支持求交集,调用retainAll(Collection c) (7)ArrayList支持求单向差集,调用removeAll(Collection c) + +一个比较重要的点写在末尾:不难发现ArrayList如果一开始通过默认构造函数创建,那么过多的添加操作就会导致过多的扩容操作,并且每一次扩容操作都会进行一次arraycopy,这个操作是非常耗时的,因此为了尽可能的避免扩容带来的性能开销,可以在事先就指定好ArrayList的容量进行创建。 From 4b84eb0a0a4861370f7892529c71fa851095bcf0 Mon Sep 17 00:00:00 2001 From: whl <313576743@qq.com> Date: Wed, 11 Dec 2019 15:46:39 +0800 Subject: [PATCH 07/73] commit --- week_01/25/ArrayList_25.md | 420 +++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 week_01/25/ArrayList_25.md diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md new file mode 100644 index 0000000..a28d973 --- /dev/null +++ b/week_01/25/ArrayList_25.md @@ -0,0 +1,420 @@ +在分析动态数组ArrayList的源码之前先对其底层数据结构——数组进行分析 +# 数组 +数组是一种最基本的数据结构,采用了一组连续的内存空间按顺序存储对象或基本数据类型。其访问的时间复杂度为O(1),插入以及删除由于涉及到元素的移动时间复杂度为O(n),在Java中声明一个数组需要事先指定数组的大小,那么就可能会造成空间浪费以及扩容问题,为了解决这些问题,动态数组ArrayList就诞生了。 + +# ArrayList +```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable +``` +(1)实现了RandomAccess接口,标识其具备随机访问功能 +(2)实现了List,提供了List基础的增,删,改,查等操作 +(3)实现了Cloneable,可以被克隆 +(4)实现了Serializable,可以被序列化 + +### 属性 +```java + /** + * 默认的容量大小为10 + * Lazy-load: 只有在ArrayList真正添加元素的时候才会通过DEFAULT_CAPACITY创建数组, + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * 当指定ArrayList容量为0的时候, 底层使用的空数组 + */ + private static final Object[] EMPTY_ELEMENTDATA = {}; + + /** + * 调用默认构造函数ArrayList()时,使用这个空数组作为elementData + * 与EMPTY_ELEMENTDATA的区别在于: DEFAULTCAPACITY_EMPTY_ELEMENTDATA在第一次添加元素时会变为长度为DEFAULT_CAPACITY的数组 + */ + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + /** + * 真正存储元素的数组 + * 标记了transient,此字段不会被序列化 + */ + transient Object[] elementData; // non-private to simplify nested class access + + /** + * 容器中元素的个数 + */ + private int size; +``` + +### 构造函数 +```java + /** + * 1. 指定容器大小初始化ArrayList + */ + public ArrayList(int initialCapacity) { + //若传入初始Capacity > 0, 那么就根据Capacity创建对应长度的Object数组 + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + //若传入初始Capacity = 0, 那么就将EMPTY_ELEMENTDATA这个空数组赋给elementData + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + //若传入初始Capacity < 0, throw Exception + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + + /** + * 2. 默认构造函数 + */ + public ArrayList() { + //将DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个空数组赋给elementData + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + + /** + * 3. 通过传入一个集合初始化ArrayList + */ + public ArrayList(Collection c) { + //把传入的集合元素转换为数组拷贝给elementData + elementData = c.toArray(); + //检查拷贝之后, elementData的长度是否为0 + if ((size = elementData.length) != 0) { + // c.toArray或许不能正确地转换为Object数组 + if (elementData.getClass() != Object[].class) + //若没有正确转换为Object[], 重新拷贝成Object[].class类型再赋给elementData + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // 若拷贝之后elementData长度为0, 那么直接将EMPTY_ELEMENTDATA赋给elementData + this.elementData = EMPTY_ELEMENTDATA; + } + } +``` + +针对c.toArray不能正确转换为Object数组,可以参考如下实例: +```java + String[] str = new String[]{"wang", "han", "lin"}; + List asListTemp = Arrays.asList("wang", "han", "lin"); + //asListTemp.remove(0); // UnsupportedOperationException + //str[0] = "wang1998"; // 那么temp.get(0)也会随之被修改 + List temp = new ArrayList<>(asListTemp); +``` +这是因为asListTemp仍然是Arrays的内部类对象,asList()并没有实现对集合的修改,这里只是转换了接口,但后台数据仍然是String数组。因此在遇到```if (elementData.getClass() != Object[].class)```这段代码时必须要通过Arrays.copyOf进行赋值。 +顺便一提,使用Arrays.asList()转换的集合并不能对其进行修改相关的操作,这类操作会抛出UnsupportedOperationException异常,但是在原数组之上进行修改是可行的。这里体现的是适配器模式,只是转换接口,后台数据不变。 + + +### add(E e) 添加元素到数组末尾 +(1)明确添加元素后数组所需要的最小长度minCapacity +(2)如果minCapacity > elementData.length,需要进行数组扩容 +(3)在末尾处添加元素 +(4)添加成功return true + +```java + /** + * 添加元素到数组末尾, 时间复杂度为O(1) + */ + public boolean add(E e) { + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //把元素插入到elementData的末尾元素之后 + elementData[size++] = e; + return true; + } + + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + + private static int calculateCapacity(Object[] elementData, int minCapacity) { + //如果当前ArrayList处于刚初始化的状态, 就返回默认长度10 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + return Math.max(DEFAULT_CAPACITY, minCapacity); + } + //如果ArrayList已经处于正在使用的状态(已经进行了添加操作), 直接返回传入的minCapacity + return minCapacity; + } + + + private void ensureExplicitCapacity(int minCapacity) { + modCount++;//modCount用于记录操作ArrayList的次数 + + // 如果elementData的长度小于添加元素所需要的minCapacity, 需要对原数组进行扩容操作 + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + + private void grow(int minCapacity) { + //原数组长度 + int oldCapacity = elementData.length; + //新数组的长度 = 原数组长度的1.5倍 + int newCapacity = oldCapacity + (oldCapacity >> 1); + //如果新数组的长度依然小于minCapacity, 那么以minCapacity为准进行数组扩容 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + //若新数组长度已经超过ArrayList规定的最大长度, 则使用最大长度 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + //底层是根据newCapacity创建了一个新的数组, 然后在这个新数组之上添加原数组的元素 + //将新数组赋值给elementData + elementData = Arrays.copyOf(elementData, newCapacity); + } +``` + +### add(int index, E element) 在指定位置添加元素 +(1)检查index是否越界 +(2)检查是否需要扩容 +(3)右移index以及后续所有元素 +(4)index位置插入新元素 +(5)size++ +```java + /** + * 在指定位置插入元素, 并将原本在该位置的元素以及右边的所有元素向右移动一位 + */ + public void add(int index, E element) { + //检查index是否越界 + rangeCheckForAdd(index); + //确保ArrayList有足够的Capacity添加新的元素 + ensureCapacityInternal(size + 1); + //移动原本在该位置的元素以及右边的所有元素 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + //在index位置插入元素 + elementData[index] = element; + size++; + } + + /** + * 确保index合法 + */ + private void rangeCheckForAdd(int index) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } +``` + +### addAll(Collection c) 在末尾追加集合c中的所有元素 +(1)将集合c转换为Object数组 +(2)检查是否需要扩容 +(3)将集合c中的元素全部拷贝到原数组末尾 +```java + public boolean addAll(Collection c) { + //将集合c转换为Object[] + Object[] a = c.toArray(); + int numNew = a.length; + //检查是否需要扩容 + ensureCapacityInternal(size + numNew); // Increments modCount + //将集合c中的元素全部拷贝到原数组末尾 + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + //若c不为空return true, else return false + return numNew != 0; + } +``` + +### addAll(int index, Collection c) 指定位置添加集合c的所有元素 +(1)检查index是否越界 +(2)将集合c转换为Object数组 +(3)检查是否需要扩容 +(4)移动index以及右边的所有元素,挪出空间存放集合c的所有元素 +(5)index位置添加集合c的所有元素 +```java + public boolean addAll(int index, Collection c) { + //检查index是否合法 + rangeCheckForAdd(index); + //这里的几个步骤都和addAll(Collection c)相同 + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount + //需要移动的元素个数 + int numMoved = size - index; + //若需要移动的元素个数大于0, 那么需要进行元素移动操作 + if (numMoved > 0) + //右移index以及右边的所有元素, 挪出空间用于存放集合c的元素 + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved); + //在index位置将集合c的所有元素拷贝至elementData + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; + return numNew != 0; + } +``` + +### get(int index) 获取指定位置上的元素 +(1)检查index是否越界 +(2)返回index位置上的元素 +```java + public E get(int index) { + rangeCheck(index); + return elementData(index); + } + + /** + * 这里只检查是否越上界, 如果越下界会抛出ArrayIndexOutOfBoundsException + */ + private void rangeCheck(int index) { + if (index >= size) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + E elementData(int index) { + return (E) elementData[index]; + } +``` + +### remove(int index) 删除指定位置上的元素并返回 +(1)检查index是否越界 +(2)获取index位置上的元素 +(3)若index不指向末尾元素,index后面的元素前移一位 +(4)末尾元素置为null,便于GC回收 +(5)返回删除元素 +```java + public E remove(int index) { + //检查index是否越界 + rangeCheck(index); + + modCount++; + //获取index位置上的元素 + E oldValue = elementData(index); + //如果index并不指向最后一个元素, 那么就前移index后面的元素 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + //elementData最后一位置为null, 消除引用便于GC回收 + elementData[--size] = null; + return oldValue; + } +``` + +### remove(Object o) 删除指定元素值 +(1)遍历整个数组找到指定元素 +(2)fastRemove +```java + /** + 删除数组中第一次出现的指定元素, 删除成功return true, else return false + */ + public boolean remove(Object o) { + //遍历整个数组, 删除第一个出现的null元素 (这里使用"=="进行比较) + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else {//遍历整个数组, 删除第一个出现的指定元素 (这里使用"equals()"进行比较) + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; + } + + /* + * 删除指定位置的元素 + * 与remove()相比, 该方法略去了越界检查以及返回删除元素, 其他步骤都是一样的 + * 之所以这样做是因为, 省去了不必要的检查操作, 提升了性能 + */ + private void fastRemove(int index) { + modCount++; + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work + } +``` + +### retainAll(Collection c) 求与集合c的交集部分 +(1)集合c检查是否为空 +(2)遍历element,保留与集合c相交的部分,删除不相交的部分(写指针之后的所有元素置为空) +(3)若成功批量删除return true,else return false +```java + public boolean retainAll(Collection c) { + //要求集合c不为空 + Objects.requireNonNull(c); + //调用批量删除方法, 此时boolean complement = true, 表示删除不包含在c中的元素 + return batchRemove(c, true); + } + + /** + * 批量删除元素 + * complement = true: 删除c中不包含的元素 + * complement = false: 删除c中包含的元素 + */ + private boolean batchRemove(Collection c, boolean complement) { + final Object[] elementData = this.elementData; + //初始化读指针r, 写指针w + int r = 0, w = 0; + //是否成功修改的返回值, 默认false + boolean modified = false; + try { + //遍历整个数组, 如果集合c中包含读指针指向的元素, 且complement = ture, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList相交的部分, 删除了不相交的元素 + //如果集合c中不包含读指针指向的元素, 且complement = false, 就将读指针指向的元素放在写指针指向的位置, 这样就留下了集合c与ArrayList不相交的部分, 删除了相交的元素 + //整个操作都在原数组上完成, 不需要额外空间 + //这个操作有点类似LeetCode上移动零那道题, 比较典型的双指针解法 + for (; r < size; r++) + if (c.contains(elementData[r]) == complement) + elementData[w++] = elementData[r]; + } finally { + //正常情况下, 读指针最后一定是指向size的, 除非c.contains()抛出了异常 + if (r != size) { + //若c.contains抛出异常, 则把未读元素都拷贝到写指针之后 + System.arraycopy(elementData, r, + elementData, w, + size - r); + //写指针指向相应的位置 + w += size - r; + } + //若写指针不指向末尾元素, 那么写指针后序的元素都需要置为空 + if (w != size) { + // clear to let GC do its work + for (int i = w; i < size; i++) + elementData[i] = null; + modCount += size - w; + //此时删除后的size等于写指针所指的位置 + size = w; + //标识完成了整个批量删除 + modified = true; + } + } + return modified; + } +``` + +### removeAll(Collection c) 求与集合c的差集 +```java + /** + * 保留当前集合中不与c相交的元素 + */ + public boolean removeAll(Collection c) { + Objects.requireNonNull(c); + //同样调用了批量删除方法, complement = false意味着删除包含在c中的元素 + return batchRemove(c, false); + } +``` + +# 总结 +(1)ArrayList底层采用Object数组进行数据存储,每次添加时都会检查是否需要扩容,若容量不足则通过创建一个新的长度为原长度1.5倍的数组,并将原数组拷贝至新数组并返回。 +(2)ArrayList随机访问时间复杂度为O(1) +(3)ArrayList添加元素到末尾的时间复杂度为O(1),添加元素到中间位置的时间复杂度为O(n) +(4)ArrayList删除末尾元素的时间复杂度为O(1),删除中间位置元素的时间复杂度为O(n) +(5)ArrayList支持求并集,调用addAll(Collection c) +(6)ArrayList支持求交集,调用retainAll(Collection c) +(7)ArrayList支持求单向差集,调用removeAll(Collection c) + +一些需要注意的点写在末尾: +### 1. 扩容导致的问题 +不难发现ArrayList如果一开始通过默认构造函数创建,那么过多的添加操作就会导致过多的扩容操作,并且每一次扩容操作都会进行一次arraycopy,这个操作是非常耗时的,因此为了尽可能的避免扩容带来的性能开销,可以在事先就指定好ArrayList的容量进行创建,这也是阿里巴巴开发手册中明确指出的,同理针对HashMap这类需要指定初始容量的集合都需要考虑扩容造成的性能影响。 + +### 2. 使用集合转数组方法必须使用集合的toArray(T[] array) +使用附带参数的toArray(T[] array)方法,其目的是为了确保了转换后的数组类型,直接使用toArray()的无参方法返回值只能是Object类型,且强制转换其他类型的数组会出现ClassCastException错误。下面是测试代码: + +```java + String[] str1 = new String[2]; + String[] str2 = new String[2]; + List temp = new ArrayList<>(); + temp.add("w"); + temp.add("h"); + temp.toArray(str1);//success + str2 = (String[])temp.toArray();//ClassCastException +``` \ No newline at end of file From 3d29f6016948b79375c204c290f307c389e301ca Mon Sep 17 00:00:00 2001 From: whl <313576743@qq.com> Date: Wed, 11 Dec 2019 15:51:09 +0800 Subject: [PATCH 08/73] commit --- week_01/ 25/ArrayList_25.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 week_01/ 25/ArrayList_25.md diff --git a/week_01/ 25/ArrayList_25.md b/week_01/ 25/ArrayList_25.md deleted file mode 100644 index 8b13789..0000000 --- a/week_01/ 25/ArrayList_25.md +++ /dev/null @@ -1 +0,0 @@ - From 5c5bc743e40a04573cc20b8c24d17d7e562336e9 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Wed, 11 Dec 2019 15:54:24 +0800 Subject: [PATCH 09/73] Update ArrayList_25.md --- week_01/25/ArrayList_25.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/week_01/25/ArrayList_25.md b/week_01/25/ArrayList_25.md index a28d973..ac334f7 100644 --- a/week_01/25/ArrayList_25.md +++ b/week_01/25/ArrayList_25.md @@ -410,11 +410,11 @@ public class ArrayList extends AbstractList 使用附带参数的toArray(T[] array)方法,其目的是为了确保了转换后的数组类型,直接使用toArray()的无参方法返回值只能是Object类型,且强制转换其他类型的数组会出现ClassCastException错误。下面是测试代码: ```java - String[] str1 = new String[2]; + String[] str1 = new String[2]; String[] str2 = new String[2]; List temp = new ArrayList<>(); temp.add("w"); temp.add("h"); temp.toArray(str1);//success str2 = (String[])temp.toArray();//ClassCastException -``` \ No newline at end of file +``` From dd6a8bf6bd0b8ab1130caad39b5f7287cc48cbf2 Mon Sep 17 00:00:00 2001 From: whl <313576743@qq.com> Date: Wed, 11 Dec 2019 17:47:40 +0800 Subject: [PATCH 10/73] commit --- week_01/25/HashMap_25.md | 506 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 week_01/25/HashMap_25.md diff --git a/week_01/25/HashMap_25.md b/week_01/25/HashMap_25.md new file mode 100644 index 0000000..c0572a1 --- /dev/null +++ b/week_01/25/HashMap_25.md @@ -0,0 +1,506 @@ +# HashMap +HashMap采用key-value的存储结构,每个唯一key对应一个唯一的value,通常情况下HashMap的查询和修改时间复杂度为O(1),因为是散列存储,HashMap不能保证元素存储的顺序,且线程不安全。 + +```java +public class HashMap extends AbstractMap + implements Map, Cloneable, Serializable { + ``` + (1)继承了AbstractMap,实现了Map接口,具备Map的所有功能 + (2)实现了Cloneable,可以被克隆 + (3)实现了Serializable,可以被序列化 + +### 属性 +```java +/** + * 默认初始容量为16 + * 容量必须指定为2的n次方, 目的是为了使hash函数能够更加有效的获取散列值 + * index = hashCode & (capacity - 1) + */ + static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 + + /** + * 最大容量 = 2^30 + */ + static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * 默认负载因子 + * 意味着当HashMap的容量被使用75%的时候会进行扩容 + */ + static final float DEFAULT_LOAD_FACTOR = 0.75f; + + /** + * 当一个桶中的链表长度大于等于8时转化为红黑树 + */ + static final int TREEIFY_THRESHOLD = 8; + + /** + * 当一个桶中的链表长度小于等于6时转化为链表 + */ + static final int UNTREEIFY_THRESHOLD = 6; + + /** + * 当桶的个数到达64个才能够进行树化 + */ + static final int MIN_TREEIFY_CAPACITY = 64; + + /* ---------------- Fields -------------- */ + + /** + * 位桶数组 + */ + transient Node[] table; + + /** + * 作为entrySet()的缓存 + */ + transient Set> entrySet; + + /** + * Map中的元素个数 + */ + transient int size; + + /** + * 修改次数 + */ + transient int modCount; + + /** + * 当位桶数组的数量到达多少时可以进行扩容 , shreshold = (capacity * load factor). + */ + int threshold; + + /** + * 负载因子 + */ + final float loadFactor; +``` + +### Node内部类 +```java + /** + * 典型的单链表节点 + */ + static class Node implements Map.Entry { + final int hash;//用于存储通过hash函数处理后的key.hashCode() + final K key; + V value; + Node next; + .... + } +``` + +### TreeNode内部类 +```java + static final class TreeNode extends LinkedHashMap.Entry { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; +``` + +### 构造方法 +```java + /** + * 1. 指定初始容量和负载因子的构造方法 + */ + public HashMap(int initialCapacity, float loadFactor) { + //判断初始Capacity是否合法 + if (initialCapacity < 0) + throw new IllegalArgumentException("Illegal initial capacity: " + + initialCapacity); + if (initialCapacity > MAXIMUM_CAPACITY) + initialCapacity = MAXIMUM_CAPACITY; + //检查负载因子是否合法 + if (loadFactor <= 0 || Float.isNaN(loadFactor)) + throw new IllegalArgumentException("Illegal load factor: " + + loadFactor); + this.loadFactor = loadFactor; + //计算容量门槛 + this.threshold = tableSizeFor(initialCapacity); + } + + /** + * 将Capacity转换为往上取最近的2的n次方 + * 该算法的思想就是将Capacity的有效二进制位转换为全1, 然后加1取到二进制位 + * 例如(14)2 = 1100, 1100低位全部转换为1, 1100 -> 1111, 1111 + 1 = 100000 + * 如果日常需要类似的算法场景, 就可以直接从这里照搬了(●'◡'●) + */ + static final int tableSizeFor(int cap) { + int n = cap - 1;//-1是为了避免一个二进制数被转换为更大的二进制数 + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /** + * 2. 只指定初始容量的构造方法, 底层调用了第一个构造方法, 对其设置了默认负载因子 + */ + public HashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); + } + + /** + * 3. 空构造方法, 使用默认负载因子 + */ + public HashMap() { + this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted + } +``` + +### put(K key, V value) 添加键值对 +(1)计算节点key的hash值 +(2)如果是刚初始化的map,调用resize()初始化位桶数组 +(3)hash&(n - 1)计算出newNode存放的下标值 +(4)如果下标位置桶为空,那么直接放入newNode即可,跳转到步骤(7) +(5)如果下标位置桶不为空: +  (5.1)观察桶上第一个节点的key与newNode.key是否相同,若相同保存该节点,跳转到步骤(6) +  (5.2)若不相同,且第一个节点为TreeNode,则按照红黑树的方式进行添加 +  (5.3)若不相同,且第一个节点不为红黑树,则遍历链表寻找具有相同key的节点,若找到了保存该节点,跳转到步骤(6);若未找到则在末尾添加newNode +  (5.4)观察添加newNode后是否需要树化 +(6)将保存的具有相同key的节点value进行更新,并返回oldValue +(7)观察是否需要扩容,若需要调用resize() +(8)因为寻找到相同key的结果会在步骤(6)中return,这里只可能存在未找到相同key的情况,return null + +```java + public V put(K key, V value) { + //调用hash方法计算key的hash值, 然后进行putVal + //如果替换了相同key节点的value, 那么return oldValue, else return null + + return putVal(hash(key), key, value, false, true); + } + + static final int hash(Object key) { + int h; + //if key = null, return 0, else return (key的32位hashCode异或key的高16位) + //目的时为了让hash更加分散 + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + } + + final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { + Node[] tab; + Node p; + int n, i; + //如果桶数组为空, 则初始化位桶数组(Lazy-load) + if ((tab = table) == null || (n = tab.length) == 0) + //调用resize()初始化, 将初始化后的位桶数组长度赋给n + n = (tab = resize()).length; + //-------------------------important---------------------------// + //这里就是HashMap非常经典的计算下标算法了 + //(n - 1) & hash这个算法充分利用了位桶数组的长度n和hash值计算出更加散列的下标 + //观察该下标是否存在元素, 如果为空就直接把newNode放入 + if ((p = tab[i = (n - 1) & hash]) == null) + tab[i] = newNode(hash, key, value, null); + //如果该位置上已经存在了节点 + else { + Node e; + K k; + //如果桶中第一个节点的key与待插入节点的key相同, 保存该结点为e, 用于后续修改value + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + e = p; + //如果桶中第一个节点的key与待插入节点的key不相同, 且第一个节点是树化的节点 + else if (p instanceof TreeNode) + //此时调用putTreeVal方法将node插入 + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + //如果桶中第一个节点的key与待插入节点的key不相同, 且第一个节点是链表节点 + else { + //那么就需要遍历这个链表, 寻找相同key的节点 + for (int binCount = 0; ; ++binCount) { + //如果链表遍历完了都没有找到相同key的节点, 则在末尾追加新节点 + if ((e = p.next) == null) { + p.next = newNode(hash, key, value, null); + //如果插入新节点之后, 链表节点的长度大于等于8, 则需要进行链表树化 + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + treeifyBin(tab, hash); + break; + } + //如果找到了相同的key的节点, 则退出循环 + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + break; + p = e; + } + } + //e != null, 说明找到了相同key的节点, 那么需要进行value替换 + if (e != null) { // existing mapping for key + //记录旧值 + V oldValue = e.value; + //判断是否需要替换旧值 + if (!onlyIfAbsent || oldValue == null) + //替换旧值为新值 + e.value = value; + //在节点被访问后需要做点什么事, LinkedListHashMap中用到 + afterNodeAccess(e); + //返回旧值 + return oldValue; + } + } + //下面这些代码会处理没有寻找到相同key节点的情况 + ++modCount; + //观察放入Node之后的size是否需要扩容 + if (++size > threshold) + resize(); + //在节点被访问后做点什么事, 在LinkedHashMap中用到 + afterNodeInsertion(evict); + //未替换相同key节点的value, return null + return null; + } +``` + +### resize()方法 +(1)如果使用默认构造方法,则第一次插入元素时初始化容量为16,扩容门槛为12 +(2)如果使用非默认构造方法,则第一次插入元素时初始化容量等于扩容门槛(初始容量往上取2的n次方) +(3)如果旧容量大于0,设置新容量和新扩容门槛 +(4)创建新容量的桶 +(5)搬迁元素 +```java + /** + * 对位桶数组的扩容方法 + * 这里是创建了一个新的位桶数组, 并将老的位桶数组搬家到新数组中 + */ + final Node[] resize() { + Node[] oldTab = table; + int oldCap = (oldTab == null) ? 0 : oldTab.length; + int oldThr = threshold; + int newCap, newThr = 0; + //如果oldCapacity > 0 + if (oldCap > 0) { + //且oldCapacity已经到达最大容量, 那么不再进行扩容, 直接返回oldTable + if (oldCap >= MAXIMUM_CAPACITY) { + threshold = Integer.MAX_VALUE; + return oldTab; + } + //oldCapacity*2 < 最大容量, 并且oldCapacity >= 默认初始容量(16) + //那么新容量 = oldCapacity*2, 新扩容门槛 = oldThreshold*2 + else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && + oldCap >= DEFAULT_INITIAL_CAPACITY) + newThr = oldThr << 1; // double threshold + } + //使用非默认构造方法指定initialCapacity创建的map, 第一次put时会进入这里, capa + //如果旧容量为0, 且旧扩容门槛大于0, 则把oldThreShold = 往上取2^n 赋值给新容量 + else if (oldThr > 0) + newCap = oldThr; + //调用默认构造方法创建的map, 第一次put会进入这里 + else { // zero initial threshold signifies using defaults + //newCapacity = 16 + newCap = DEFAULT_INITIAL_CAPACITY; + //newThreshold = 0.75 * 16 + newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); + } + //如果新扩容门槛为0, 在保证不超过最大容量的情况下, 设置新扩容门槛为newCapacity*负载因子 + if (newThr == 0) { + float ft = (float)newCap * loadFactor; + newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? + (int)ft : Integer.MAX_VALUE); + } + //将新扩容门槛赋值给HashMap.threshold + threshold = newThr; + //根据新容量新建一个位桶数组 + @SuppressWarnings({"rawtypes","unchecked"}) + Node[] newTab = (Node[])new Node[newCap]; + //将新数组赋值给HashMap.table + table = newTab; + //如果旧数组不为空, 那么需要把原来的元素搬到新的位桶数组中 + if (oldTab != null) { + //遍历旧数组 + for (int j = 0; j < oldCap; ++j) { + Node e; + //如果旧数组的当前位置不为空, + if ((e = oldTab[j]) != null) { + //清空旧数组便于GC回收 + oldTab[j] = null; + //若当前位置的桶只存在一个元素 + if (e.next == null) + //只需要计算该元素在新桶中的位置然后搬到新桶中即可 + newTab[e.hash & (newCap - 1)] = e; + //若当前位置的桶下, 第一个节点为TreeNode + else if (e instanceof TreeNode) + //那么把这棵树打散成两棵树搬到新桶中 + ((TreeNode)e).split(this, newTab, j, oldCap); + else { + //将链表分化为两个链表存放到新位桶数组中 + Node loHead = null, loTail = null; + Node hiHead = null, hiTail = null; + Node next; + do {//遍历链表所有节点 + next = e.next; + //当前节点的hash对oldCapacity取余 == 0, 将其归为lowLinkedList + if ((e.hash & oldCap) == 0) { + //若lowLinkedList为空, 头节点为该节点 + if (loTail == null) + loHead = e; + else + //否则尾部追加 + loTail.next = e; + loTail = e; + } + else {//若不满足取余==0的条件, 则以同样的操作将该节点赋给highLinkedList + if (hiTail == null) + hiHead = e; + else + hiTail.next = e; + hiTail = e; + } + } while ((e = next) != null); + //遍历完成后就将原链表分化为2个链表了 + //低位链表在新桶中的位置还是与旧桶一样 + if (loTail != null) { + loTail.next = null; + newTab[j] = loHead; + } + //高位链表在新桶中的位置刚好实在原位置之上加上旧容量 + if (hiTail != null) { + hiTail.next = null; + newTab[j + oldCap] = hiHead; + } + } + } + } + } + return newTab; + } +``` + + + +### get(Object key) 获取map中key对应的value +(1)计算key的hash值 +(2)通过计算找到key所在的桶数组下标 +(3)如果第一个节点就是要查找的key节点,return +(4)如果第一个节点不是,且第一个节点是TreeNode,那么通过红黑树的方式查找 +(5)如果第一个节点不是,且第一个节点是链表,那么遍历链表查找 +```java + public V get(Object key) { + Node e; + //根据传入的key计算其hash, 并下到位桶数组中寻找对应桶的位置 + return (e = getNode(hash(key), key)) == null ? null : e.value; + } + + final Node getNode(int hash, Object key) { + Node[] tab; + Node first, e; + int n; + K k; + //若位桶数组不为空且长度>0, 且根据hash值计算出的下标对应的桶下存在节点 + if ((tab = table) != null && (n = tab.length) > 0 && + (first = tab[(n - 1) & hash]) != null) { + //检查第一个节点是否是要查的元素, if true, return value + if (first.hash == hash && // always check first node + ((k = first.key) == key || (key != null && key.equals(k)))) + return first; + //若第一个节点不是, 且下一个节点不为空 + if ((e = first.next) != null) { + //下一个节点若是TreeNode, 则按红黑树的方式查找 + if (first instanceof TreeNode) + return ((TreeNode)first).getTreeNode(hash, key); + //否则遍历整个链表查找相同key的节点 + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + return e; + } while ((e = e.next) != null); + } + } + return null; + } +``` + +### remove(Object key) 根据传入key删除节点 +(1)计算key的hash值 +(2)计算下标,看下标对应的桶上第一个节点是否是我们要删除的 +(3)若是,保存该结点 +(4)若不是,且头结点是TreeNode,按照红黑树的方式遍历获取到该节点 +(5)若不是,且头结点是链表,则遍历链表获取到该结点 +(6)观察保存的结点是否是TreeNode,如果是则按照红黑树的方式删除 +(7)若不是TreeNode,则按照链表的方式删除 + +```java + public V remove(Object key) { + Node e; + //计算出key的hash值, 然后下到removeNode方法进行删除 + return (e = removeNode(hash(key), key, null, false, true)) == null ? + null : e.value; + } + + final Node removeNode(int hash, Object key, Object value, + boolean matchValue, boolean movable) { + Node[] tab; Node p; int n, index; + //如果桶数组不为空且长度>0, 并且计算出下标对应的桶上存在节点 + if ((tab = table) != null && (n = tab.length) > 0 && + (p = tab[index = (n - 1) & hash]) != null) { + Node node = null, e; K k; V v; + //如果桶上第一个节点恰好是要删除的, 赋值给node后续删除使用 + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + node = p; + //如果桶上第一个节点不是我们寻找的, 且该节点的next节点不为空 + else if ((e = p.next) != null) { + //如果桶上第一个节点是TreeNode + if (p instanceof TreeNode) + //按照红黑树的方式遍历获取到该节点 + node = ((TreeNode)p).getTreeNode(hash, key); + //否则遍历链表查找要删除的节点 + else { + do { + if (e.hash == hash && + ((k = e.key) == key || + (key != null && key.equals(k)))) { + node = e; + break; + } + p = e; + } while ((e = e.next) != null); + } + } + //如果找到了要删除的节点, 则看参数是否需要匹配value值, 如果不需要匹配value值则直接删除, 否则判断value是否相同 + if (node != null && (!matchValue || (v = node.value) == value || + (value != null && value.equals(v)))) { + if (node instanceof TreeNode) + //如果该节点是TreeNode, 按照红黑树的方式删除 + ((TreeNode)node).removeTreeNode(this, tab, movable); + //如果删除的元素是第一个节点, 把next节点移动到头节点位置 + else if (node == p) + tab[index] = node.next; + else//否则删除node节点 + p.next = node.next; + ++modCount; + --size; + //删除节点的后续处理 + afterNodeRemoval(node); + //成功删除, 返回删除节点 + return node; + } + } + //若删除失败, 返回null + return null; + } +``` + +### 总结 +(1)HashMap是一种散列表,采用数组 + 链表 + 红黑树存储结构 +(2)若未预先指定,HashMap的初始容量是16,负载因子是0.75 +(3)若预先指定,HashMap的初始容量必须是2的n次方 +(4)HashMap除了通过默认构造创建时扩容门槛是16*0.75,其余情况下每次扩容容量为原来的两倍,扩容门槛也为原来的两倍 +(5)当桶数组的数量<64时不会进行树化,只会扩容 +(6)当桶数组的数量>64,且桶中元素个数大于8,进行树化 +(7)当桶中元素小于6,进行反树化 +(8)非线程安全 +(9)通常情况下,查找和添加元素的时间复杂度都是O(1) + +一些需要注意的点写在末尾: +### 1. 扩容导致的性能影响 +因为每一次调用resize()方法,都会创建一次新的位桶数组,并且将旧数组中的元素移动到新数组中,整个过程非常耗时,因此推荐使用HashMap(int initialCapacity)这个构造器,并在最初就尽量指定好容量大小。 + +### 2. 为什么HashMap要树化 +HashMap在大多数情况下,查询的时间复杂度为O(1),且HashMap的扰动函数和散列处理也足够高效了,可以理解为即便存在链表,这个链表也不会太长。那么为什么要大费周折添加一个红黑树的结构呢? +其本质是一个安全问题,在现实环境下,构建冲突的数据并不是非常复杂的事,恶意代码就可以利用这些数据大量与服务端进行交互,导致服务端CPU大量被占用,这就构成了hash碰撞拒接服务攻击。树化可以一定程度上减少碰撞攻击带来的性能损失。 + +### 3. 线程不安全 +HashMap是线程不安全的,并发场景下很可能出现两个线程同时对HashMap进行操作导致死锁问题,在并发场景下建议使用ConcurrentHashMap。 \ No newline at end of file From 8d3064dcd14317b0a5203e27f3437e62e8463d41 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Wed, 11 Dec 2019 17:49:51 +0800 Subject: [PATCH 11/73] Update HashMap_25.md --- week_01/25/HashMap_25.md | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/week_01/25/HashMap_25.md b/week_01/25/HashMap_25.md index c0572a1..ab389dc 100644 --- a/week_01/25/HashMap_25.md +++ b/week_01/25/HashMap_25.md @@ -5,9 +5,9 @@ HashMap采用key-value的存储结构,每个唯一key对应一个唯一的valu public class HashMap extends AbstractMap implements Map, Cloneable, Serializable { ``` - (1)继承了AbstractMap,实现了Map接口,具备Map的所有功能 - (2)实现了Cloneable,可以被克隆 - (3)实现了Serializable,可以被序列化 + (1)继承了AbstractMap,实现了Map接口,具备Map的所有功能 + (2)实现了Cloneable,可以被克隆 + (3)实现了Serializable,可以被序列化 ### 属性 ```java @@ -157,15 +157,15 @@ public class HashMap extends AbstractMap (1)计算节点key的hash值 (2)如果是刚初始化的map,调用resize()初始化位桶数组 (3)hash&(n - 1)计算出newNode存放的下标值 -(4)如果下标位置桶为空,那么直接放入newNode即可,跳转到步骤(7) +(4)如果下标位置桶为空,那么直接放入newNode即可,跳转到步骤(7) (5)如果下标位置桶不为空: -  (5.1)观察桶上第一个节点的key与newNode.key是否相同,若相同保存该节点,跳转到步骤(6) -  (5.2)若不相同,且第一个节点为TreeNode,则按照红黑树的方式进行添加 -  (5.3)若不相同,且第一个节点不为红黑树,则遍历链表寻找具有相同key的节点,若找到了保存该节点,跳转到步骤(6);若未找到则在末尾添加newNode -  (5.4)观察添加newNode后是否需要树化 -(6)将保存的具有相同key的节点value进行更新,并返回oldValue -(7)观察是否需要扩容,若需要调用resize() -(8)因为寻找到相同key的结果会在步骤(6)中return,这里只可能存在未找到相同key的情况,return null +  (5.1)观察桶上第一个节点的key与newNode.key是否相同,若相同保存该节点,跳转到步骤(6) +  (5.2)若不相同,且第一个节点为TreeNode,则按照红黑树的方式进行添加 +  (5.3)若不相同,且第一个节点不为红黑树,则遍历链表寻找具有相同key的节点,若找到了保存该节点,跳转到步骤(6);若未找到则在末尾添加newNode +  (5.4)观察添加newNode后是否需要树化 +(6)将保存的具有相同key的节点value进行更新,并返回oldValue +(7)观察是否需要扩容,若需要调用resize() +(8)因为寻找到相同key的结果会在步骤(6)中return,这里只可能存在未找到相同key的情况,return null ```java public V put(K key, V value) { @@ -371,11 +371,11 @@ public class HashMap extends AbstractMap ### get(Object key) 获取map中key对应的value -(1)计算key的hash值 -(2)通过计算找到key所在的桶数组下标 -(3)如果第一个节点就是要查找的key节点,return -(4)如果第一个节点不是,且第一个节点是TreeNode,那么通过红黑树的方式查找 -(5)如果第一个节点不是,且第一个节点是链表,那么遍历链表查找 +(1)计算key的hash值 +(2)通过计算找到key所在的桶数组下标 +(3)如果第一个节点就是要查找的key节点,return +(4)如果第一个节点不是,且第一个节点是TreeNode,那么通过红黑树的方式查找 +(5)如果第一个节点不是,且第一个节点是链表,那么遍历链表查找 ```java public V get(Object key) { Node e; @@ -413,13 +413,13 @@ public class HashMap extends AbstractMap ``` ### remove(Object key) 根据传入key删除节点 -(1)计算key的hash值 -(2)计算下标,看下标对应的桶上第一个节点是否是我们要删除的 -(3)若是,保存该结点 -(4)若不是,且头结点是TreeNode,按照红黑树的方式遍历获取到该节点 -(5)若不是,且头结点是链表,则遍历链表获取到该结点 -(6)观察保存的结点是否是TreeNode,如果是则按照红黑树的方式删除 -(7)若不是TreeNode,则按照链表的方式删除 +(1)计算key的hash值 +(2)计算下标,看下标对应的桶上第一个节点是否是我们要删除的 +(3)若是,保存该结点 +(4)若不是,且头结点是TreeNode,按照红黑树的方式遍历获取到该节点 +(5)若不是,且头结点是链表,则遍历链表获取到该结点 +(6)观察保存的结点是否是TreeNode,如果是则按照红黑树的方式删除 +(7)若不是TreeNode,则按照链表的方式删除 ```java public V remove(Object key) { @@ -503,4 +503,4 @@ HashMap在大多数情况下,查询的时间复杂度为O(1),且HashMap的 其本质是一个安全问题,在现实环境下,构建冲突的数据并不是非常复杂的事,恶意代码就可以利用这些数据大量与服务端进行交互,导致服务端CPU大量被占用,这就构成了hash碰撞拒接服务攻击。树化可以一定程度上减少碰撞攻击带来的性能损失。 ### 3. 线程不安全 -HashMap是线程不安全的,并发场景下很可能出现两个线程同时对HashMap进行操作导致死锁问题,在并发场景下建议使用ConcurrentHashMap。 \ No newline at end of file +HashMap是线程不安全的,并发场景下很可能出现两个线程同时对HashMap进行操作导致死锁问题,在并发场景下建议使用ConcurrentHashMap。 From 494d9bf40ec48021183eae6aa8043d59d4b04bd8 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Wed, 11 Dec 2019 17:53:07 +0800 Subject: [PATCH 12/73] Update HashMap_25.md --- week_01/25/HashMap_25.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/week_01/25/HashMap_25.md b/week_01/25/HashMap_25.md index ab389dc..0832b2c 100644 --- a/week_01/25/HashMap_25.md +++ b/week_01/25/HashMap_25.md @@ -11,7 +11,7 @@ public class HashMap extends AbstractMap ### 属性 ```java -/** + /** * 默认初始容量为16 * 容量必须指定为2的n次方, 目的是为了使hash函数能够更加有效的获取散列值 * index = hashCode & (capacity - 1) @@ -79,7 +79,7 @@ public class HashMap extends AbstractMap ### Node内部类 ```java - /** + /** * 典型的单链表节点 */ static class Node implements Map.Entry { @@ -93,7 +93,7 @@ public class HashMap extends AbstractMap ### TreeNode内部类 ```java - static final class TreeNode extends LinkedHashMap.Entry { + static final class TreeNode extends LinkedHashMap.Entry { TreeNode parent; // red-black tree links TreeNode left; TreeNode right; @@ -103,7 +103,7 @@ public class HashMap extends AbstractMap ### 构造方法 ```java - /** + /** * 1. 指定初始容量和负载因子的构造方法 */ public HashMap(int initialCapacity, float loadFactor) { @@ -122,7 +122,7 @@ public class HashMap extends AbstractMap this.threshold = tableSizeFor(initialCapacity); } - /** + /** * 将Capacity转换为往上取最近的2的n次方 * 该算法的思想就是将Capacity的有效二进制位转换为全1, 然后加1取到二进制位 * 例如(14)2 = 1100, 1100低位全部转换为1, 1100 -> 1111, 1111 + 1 = 100000 @@ -161,21 +161,20 @@ public class HashMap extends AbstractMap (5)如果下标位置桶不为空:   (5.1)观察桶上第一个节点的key与newNode.key是否相同,若相同保存该节点,跳转到步骤(6)   (5.2)若不相同,且第一个节点为TreeNode,则按照红黑树的方式进行添加 -  (5.3)若不相同,且第一个节点不为红黑树,则遍历链表寻找具有相同key的节点,若找到了保存该节点,跳转到步骤(6);若未找到则在末尾添加newNode +  (5.3)若不相同,且第一个节点不为红黑树,则遍历链表寻找具有相同key的节点,若找到了保存该节点,跳转到步骤(6),若未找到则在末尾添加newNode   (5.4)观察添加newNode后是否需要树化 (6)将保存的具有相同key的节点value进行更新,并返回oldValue (7)观察是否需要扩容,若需要调用resize() (8)因为寻找到相同key的结果会在步骤(6)中return,这里只可能存在未找到相同key的情况,return null ```java - public V put(K key, V value) { - //调用hash方法计算key的hash值, 然后进行putVal - //如果替换了相同key节点的value, 那么return oldValue, else return null - + public V put(K key, V value) { + //调用hash方法计算key的hash值, 然后进行putVal + //如果替换了相同key节点的value, 那么return oldValue, else return null return putVal(hash(key), key, value, false, true); } - static final int hash(Object key) { + static final int hash(Object key) { int h; //if key = null, return 0, else return (key的32位hashCode异或key的高16位) //目的时为了让hash更加分散 @@ -261,7 +260,7 @@ public class HashMap extends AbstractMap (4)创建新容量的桶 (5)搬迁元素 ```java - /** + /** * 对位桶数组的扩容方法 * 这里是创建了一个新的位桶数组, 并将老的位桶数组搬家到新数组中 */ @@ -377,7 +376,7 @@ public class HashMap extends AbstractMap (4)如果第一个节点不是,且第一个节点是TreeNode,那么通过红黑树的方式查找 (5)如果第一个节点不是,且第一个节点是链表,那么遍历链表查找 ```java - public V get(Object key) { + public V get(Object key) { Node e; //根据传入的key计算其hash, 并下到位桶数组中寻找对应桶的位置 return (e = getNode(hash(key), key)) == null ? null : e.value; @@ -422,7 +421,7 @@ public class HashMap extends AbstractMap (7)若不是TreeNode,则按照链表的方式删除 ```java - public V remove(Object key) { + public V remove(Object key) { Node e; //计算出key的hash值, 然后下到removeNode方法进行删除 return (e = removeNode(hash(key), key, null, false, true)) == null ? From cd240b7d75ee838ec74fb5e0353e844630401499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=9E=97=E8=BE=89?= Date: Wed, 11 Dec 2019 18:29:41 +0800 Subject: [PATCH 13/73] 007-Week 01 --- week_01/07/ArrayList-007.md | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 week_01/07/ArrayList-007.md diff --git a/week_01/07/ArrayList-007.md b/week_01/07/ArrayList-007.md new file mode 100644 index 0000000..355a787 --- /dev/null +++ b/week_01/07/ArrayList-007.md @@ -0,0 +1,86 @@ +ArrayList源码解析 +前言:ArrayList是我们开发中比较常用的一个集合类,底层是基于数组实现的,现在就来看一看里面是怎么实现的 +1.首先看一下定义的成员变量 + int DEFAULT_CAPACITY = 10; //默认初始化数组的大小 + Object[] EMPTY_ELEMENTDATA = {}; //空数组对象 + Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认大小空数组对象,跟上面变量的区别在于,新建一个集合对象时,没有指定大小,就用这个对象 + transient Object[] elementData; //集合CRUD时操作的数组,不可序列化 + int size; //集合的大小 + int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //最大的数组大小,为啥要-8,我也没搞懂 +2.成员变量之后来看一下几个构造方法 + //带容量参数的构造方法 + public ArrayList(int initialCapacity) { + if (initialCapacity > 0) { //容量大于0,直接新建一个Object数组 + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { //容量等于0,直接用之前声明的空数组对象 + this.elementData = EMPTY_ELEMENTDATA; + } else { //如果小于0,参数是不合法的,抛出异常 + throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); + } + } + //不带参数的构造方法 + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //默认大小空数组对象 + } + //带集合参数的构造方法 + public ArrayList(Collection c) { + elementData = c.toArray(); //先把集合转换为数组,下面会分析toArray()这个方法 + if ((size = elementData.length) != 0) { //把集合的大小赋值给size,如果传入集合的长度不为0,再进去判断数组的Class对象是不是Object[].class + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) //如果不是Object[].class,那就得复制整个数组里面的元素 + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { //如果集合大小等于0(不可能小于0,因为小于0都会抛异常),赋值为空数组对象 + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } + } +3.构造方法说完之后,再来看几个重要的方法,其它方法就不一一分析了 + //首先看一下add方法,有两个add方法,一个是向数组添加元素,一个是向数组指定位置添加元素 + public boolean add(E e) { + ensureCapacityInternal(size + 1); // Increments modCount!! + elementData[size++] = e; + return true; + } + //这个方法是确保数组的容量,让新加的元素能加到数组中去 + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + private void ensureExplicitCapacity(int minCapacity) { + modCount++; + // overflow-conscious code + if (minCapacity - elementData.length > 0) //如果最小容量大于数组的大小,扩容数组 + grow(minCapacity); + } + //扩容方法 + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); //先把数组扩容1.5倍 + if (newCapacity - minCapacity < 0) //如果扩容后的大小还小于minCapacity,那就直接把大小改成minCapacity + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) //如果扩容后大小大于最大数组大小,看minCapacity大小是否大于最大数组大小,如果大于返回Integer.MAX_VALUE,否则返回MAX_ARRAY_SIZE + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); //把数组复制一份返回 + } + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? //这个地方返回Integer.MAX_VALUE,和上面最大数组大小,会不会有问题? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } + //计算容量大小 + private static int calculateCapacity(Object[] elementData, int minCapacity) { + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //如果数组为空,取默认大小和最小容量大小中的最大值 + return Math.max(DEFAULT_CAPACITY, minCapacity); + } //否则返回最小容量大小 + return minCapacity; + } + + + + + + + From 6f9bf0952e5f1a4f1231b6a80b5f345da2b885e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=9E=97=E8=BE=89?= Date: Wed, 11 Dec 2019 18:37:02 +0800 Subject: [PATCH 14/73] 007-Week 01 --- week_01/07/ArrayList-007.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/week_01/07/ArrayList-007.md b/week_01/07/ArrayList-007.md index 355a787..8a78f65 100644 --- a/week_01/07/ArrayList-007.md +++ b/week_01/07/ArrayList-007.md @@ -78,6 +78,14 @@ ArrayList源码解析 return minCapacity; } + //在指定位置插入数据 + public void add(int index, E element) { + rangeCheckForAdd(index); + ensureCapacityInternal(size + 1); // Increments modCount!! //跟上面的方法一样,判断是否要扩容,如果要扩容,扩容后返回新数组 + System.arraycopy(elementData, index, elementData, index + 1, size - index); //在指定位置插入元素后,把指定位置后的元素全部向后移一位 + elementData[index] = element; + size++; + } From 402f069abb9cae63a19a69540bcef0da8bed271a Mon Sep 17 00:00:00 2001 From: dbcxyxd <43689452+dbcxyxd@users.noreply.github.com> Date: Wed, 11 Dec 2019 20:25:41 +0800 Subject: [PATCH 15/73] 2019/12/11 ArrayList.md --- week_01/51/ArrayList-51.md | 256 +++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 week_01/51/ArrayList-51.md diff --git a/week_01/51/ArrayList-51.md b/week_01/51/ArrayList-51.md new file mode 100644 index 0000000..8d10fb3 --- /dev/null +++ b/week_01/51/ArrayList-51.md @@ -0,0 +1,256 @@ +# ArrayList + +ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可称之为动态数组。 + +## 继承体系 + +![img](https://mmbiz.qpic.cn/mmbiz_png/C91PV9BDK3yUT9hffoWkuTicrshhl1d9JkxvvXoUmvsSzErEeTCcxTnYkYAgWexziaCbpcclHf0ocGhxBJdxlXqA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1) + +ArrayList实现了List, RandomAccess, Cloneable, java.io.Serializable等接口。 + +ArrayList实现了List,提供了基础的添加、删除、遍历等操作。 + +ArrayList实现了RandomAccess,提供了随机访问的能力。 + +ArrayList实现了Cloneable,可以被克隆。 + +ArrayList实现了Serializable,可以被序列化。 + +## 源码解析 + +### 属性 + +``` +/** * 默认容量 */ +private static final int DEFAULT_CAPACITY = 10; +/** * 空数组,如果传入的容量为0时使用 */ +private static final Object[] EMPTY_ELEMENTDATA = {}; +/** * 空数组,传传入容量时使用,添加第一个元素的时候会重新初始为默认容量大小 */ +private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; +/** * 存储元素的数组 */ +transient Object[] elementData; // non-private to simplify nested class access +/** * 集合中元素的个数 */ +private int size; +``` + +(1)DEFAULT_CAPACITY + +默认容量为10,也就是通过new ArrayList()创建时的默认容量。 + +(2)EMPTY_ELEMENTDATA + +空的数组,这种是通过new ArrayList(0)创建时用的是这个空数组。 + +(3)DEFAULTCAPACITY_EMPTY_ELEMENTDATA + +也是空数组,这种是通过new ArrayList()创建时用的是这个空数组,与EMPTY_ELEMENTDATA的区别是在添加第一个元素时使用这个空数组的会初始化为DEFAULT_CAPACITY(10)个元素。 + +(4)elementData + +真正存放元素的地方,使用transient是为了不序列化这个字段。 + +至于没有使用private修饰,后面注释是写的“为了简化嵌套类的访问”,但是楼主实测加了private嵌套类一样可以访问。 + +private表示是类私有的属性,只要是在这个类内部都可以访问,嵌套类或者内部类也是在类的内部,所以也可以访问类的私有成员。 + +(5)size + +真正存储元素的个数,而不是elementData数组的长度。 + +### ArrayList(int initialCapacity)构造方法 + +传入初始容量,如果大于0就初始化elementData为对应大小,如果等于0就使用EMPTY_ELEMENTDATA空数组,如果小于0抛出异常。 + +``` +public ArrayList(int initialCapacity) { if (initialCapacity > 0) { // 如果传入的初始容量大于0,就新建一个数组存储元素 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { // 如果传入的初始容量等于0,使用空数组EMPTY_ELEMENTDATA this.elementData = EMPTY_ELEMENTDATA; } else { // 如果传入的初始容量小于0,抛出异常 throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); }} +``` + +### ArrayList()构造方法 + +不传初始容量,初始化为DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组,会在添加第一个元素的时候扩容为默认的大小,即10。 + +``` +public ArrayList() { +// 如果没有传入初始容量,则使用空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA +// 使用这个数组是在添加第一个元素的时候会扩容到默认大小10 +this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;} +``` + +### ArrayList(Collection c)构造方法 + +传入集合并初始化elementData,这里会使用拷贝把传入集合的元素拷贝到elementData数组中,如果元素个数为0,则初始化为EMPTY_ELEMENTDATA空数组。 + +``` +/*** 把传入集合的元素初始化到ArrayList中*/ +public ArrayList(Collection c) { +// 集合转数组 +elementData = c.toArray(); +if ((size = elementData.length) != 0) { +// 检查c.toArray()返回的是不是Object[]类型,如果不是,重新拷贝成Object[].class类型 +if (elementData.getClass() != Object[].class) +elementData = Arrays.copyOf(elementData, size, Object[].class); } +else { // 如果c的空集合,则初始化为空数组EMPTY_ELEMENTDATA +this.elementData = EMPTY_ELEMENTDATA; }} +``` + +为什么 `c.toArray();`返回的有可能不是Object[]类型呢?请看下面的代码: + +``` +public class ArrayTest { public static void main(String[] args) { Father[] fathers = new Son[]{}; // 打印结果为class [Lcom.coolcoding.code.Son; System.out.println(fathers.getClass()); List strList = new MyList(); // 打印结果为class [Ljava.lang.String; System.out.println(strList.toArray().getClass()); }}class Father {}class Son extends Father {}class MyList extends ArrayList { /** * 子类重写父类的方法,返回值可以不一样 * 但这里只能用数组类型,换成Object就不行 * 应该算是java本身的bug */ @Override public String[] toArray() { // 为了方便举例直接写死 return new String[]{"1", "2", "3"}; }} +``` + +### add(E e)方法 + +添加元素到末尾,平均时间复杂度为O(1)。 + +``` +public boolean add(E e) { // 检查是否需要扩容 ensureCapacityInternal(size + 1); // 把元素插入到最后一位 elementData[size++] = e; return true;}private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) { // 如果是空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA,就初始化为默认大小10 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity;}private void ensureExplicitCapacity(int minCapacity) { modCount++; if (minCapacity - elementData.length > 0) // 扩容 grow(minCapacity);}private void grow(int minCapacity) { int oldCapacity = elementData.length; // 新容量为旧容量的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); // 如果新容量发现比需要的容量还小,则以需要的容量为准 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; // 如果新容量已经超过最大容量了,则使用最大容量 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 以新容量拷贝出来一个新数组 elementData = Arrays.copyOf(elementData, newCapacity);} +``` + +(1)检查是否需要扩容; + +(2)如果elementData等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA则初始化容量大小为DEFAULT_CAPACITY; + +(3)新容量是老容量的1.5倍(oldCapacity + (oldCapacity >> 1)),如果加了这么多容量发现比需要的容量还小,则以需要的容量为准; + +(4)创建新容量的数组并把老数组拷贝到新数组; + +### add(int index, E element)方法 + +添加元素到指定位置,平均时间复杂度为O(n)。 + +``` +public void add(int index, E element) { // 检查是否越界 rangeCheckForAdd(index); // 检查是否需要扩容 ensureCapacityInternal(size + 1); // 将inex及其之后的元素往后挪一位,则index位置处就空出来了 System.arraycopy(elementData, index, elementData, index + 1, size - index); // 将元素插入到index的位置 elementData[index] = element; // 大小增1 size++;}private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index));} +``` + +(1)检查索引是否越界; + +(2)检查是否需要扩容; + +(3)把插入索引位置后的元素都往后挪一位; + +(4)在插入索引位置放置插入的元素; + +(5)大小加1; + +### addAll(Collection c)方法 + +求两个集合的并集。 + +``` +/*** 将集合c中所有元素添加到当前ArrayList中*/public boolean addAll(Collection c) { // 将集合c转为数组 Object[] a = c.toArray(); int numNew = a.length; // 检查是否需要扩容 ensureCapacityInternal(size + numNew); // 将c中元素全部拷贝到数组的最后 System.arraycopy(a, 0, elementData, size, numNew); // 大小增加c的大小 size += numNew; // 如果c不为空就返回true,否则返回false return numNew != 0;} +``` + +(1)拷贝c中的元素到数组a中; + +(2)检查是否需要扩容; + +(3)把数组a中的元素拷贝到elementData的尾部; + +### get(int index)方法 + +获取指定索引位置的元素,时间复杂度为O(1)。 + +``` +public E get(int index) { // 检查是否越界 rangeCheck(index); // 返回数组index位置的元素 return elementData(index);}private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}E elementData(int index) { return (E) elementData[index];} +``` + +(1)检查索引是否越界,这里只检查是否越上界,如果越上界抛出IndexOutOfBoundsException异常,如果越下界抛出的是ArrayIndexOutOfBoundsException异常。 + +(2)返回索引位置处的元素; + +### remove(int index)方法 + +删除指定索引位置的元素,时间复杂度为O(n)。 + +``` +public E remove(int index) { // 检查是否越界 rangeCheck(index); modCount++; // 获取index位置的元素 E oldValue = elementData(index); // 如果index不是最后一位,则将index之后的元素往前挪一位 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 将最后一个元素删除,帮助GC elementData[--size] = null; // clear to let GC do its work // 返回旧值 return oldValue;} +``` + +(1)检查索引是否越界; + +(2)获取指定索引位置的元素; + +(3)如果删除的不是最后一位,则其它元素往前移一位; + +(4)将最后一位置为null,方便GC回收; + +(5)返回删除的元素。 + +可以看到,ArrayList删除元素的时候并没有缩容。 + +### remove(Object o)方法 + +删除指定元素值的元素,时间复杂度为O(n)。 + +``` +public boolean remove(Object o) { if (o == null) { // 遍历整个数组,找到元素第一次出现的位置,并将其快速删除 for (int index = 0; index < size; index++) // 如果要删除的元素为null,则以null进行比较,使用== if (elementData[index] == null) { fastRemove(index); return true; } } else { // 遍历整个数组,找到元素第一次出现的位置,并将其快速删除 for (int index = 0; index < size; index++) // 如果要删除的元素不为null,则进行比较,使用equals()方法 if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false;}private void fastRemove(int index) { // 少了一个越界的检查 modCount++; // 如果index不是最后一位,则将index之后的元素往前挪一位 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 将最后一个元素删除,帮助GC elementData[--size] = null; // clear to let GC do its work} +``` + +(1)找到第一个等于指定元素值的元素; + +(2)快速删除; + +fastRemove(int index)相对于remove(int index)少了检查索引越界的操作,可见jdk将性能优化到极致。 + +### retainAll(Collection c)方法 + +求两个集合的交集。 + +``` +public boolean retainAll(Collection c) { // 集合c不能为null Objects.requireNonNull(c); // 调用批量删除方法,这时complement传入true,表示删除不包含在c中的元素 return batchRemove(c, true);}/*** 批量删除元素* complement为true表示删除c中不包含的元素* complement为false表示删除c中包含的元素*/private boolean batchRemove(Collection c, boolean complement) { final Object[] elementData = this.elementData; // 使用读写两个指针同时遍历数组 // 读指针每次自增1,写指针放入元素的时候才加1 // 这样不需要额外的空间,只需要在原有的数组上操作就可以了 int r = 0, w = 0; boolean modified = false; try { // 遍历整个数组,如果c中包含该元素,则把该元素放到写指针的位置(以complement为准) for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // 正常来说r最后是等于size的,除非c.contains()抛出了异常 if (r != size) { // 如果c.contains()抛出了异常,则把未读的元素都拷贝到写指针之后 System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // 将写指针之后的元素置为空,帮助GC for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; // 新大小等于写指针的位置(因为每写一次写指针就加1,所以新大小正好等于写指针的位置) size = w; modified = true; } } // 有修改返回true return modified;} +``` + +(1)遍历elementData数组; + +(2)如果元素在c中,则把这个元素添加到elementData数组的w位置并将w位置往后移一位; + +(3)遍历完之后,w之前的元素都是两者共有的,w之后(包含)的元素不是两者共有的; + +(4)将w之后(包含)的元素置为null,方便GC回收; + +### removeAll(Collection c) + +求两个集合的单方向差集,只保留当前集合中不在c中的元素,不保留在c中不在当前集体中的元素。 + +``` +public boolean removeAll(Collection c) { // 集合c不能为空 Objects.requireNonNull(c); // 同样调用批量删除方法,这时complement传入false,表示删除包含在c中的元素 return batchRemove(c, false);} +``` + +与retainAll(Collection c)方法类似,只是这里保留的是不在c中的元素。 + +## 总结 + +(1)ArrayList内部使用数组存储元素,当数组长度不够时进行扩容,每次加一半的空间,ArrayList不会进行缩容; + +(2)ArrayList支持随机访问,通过索引访问元素极快,时间复杂度为O(1); + +(3)ArrayList添加元素到尾部极快,平均时间复杂度为O(1); + +(4)ArrayList添加元素到中间比较慢,因为要搬移元素,平均时间复杂度为O(n); + +(5)ArrayList从尾部删除元素极快,时间复杂度为O(1); + +(6)ArrayList从中间删除元素比较慢,因为要搬移元素,平均时间复杂度为O(n); + +(7)ArrayList支持求并集,调用addAll(Collection c)方法即可; + +(8)ArrayList支持求交集,调用retainAll(Collection c)方法即可; + +(7)ArrayList支持求单向差集,调用removeAll(Collection c)方法即可; + +## 彩蛋 + +elementData设置成了transient,那ArrayList是怎么把元素序列化的呢? + +``` +private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // 防止序列化期间有修改 int expectedModCount = modCount; // 写出非transient非static属性(会写出size属性) s.defaultWriteObject(); // 写出元素个数 s.writeInt(size); // 依次写出元素 for (int i=0; i 0) { // 计算容量 int capacity = calculateCapacity(elementData, size); SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); // 检查是否需要扩容 ensureCapacityInternal(size); Object[] a = elementData; // 依次读取元素到数组中 for (int i=0; i Date: Thu, 12 Dec 2019 00:51:30 +0800 Subject: [PATCH 16/73] arrayList-008 --- week_01/08/ArrayList-008.md | 251 ++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 week_01/08/ArrayList-008.md diff --git a/week_01/08/ArrayList-008.md b/week_01/08/ArrayList-008.md new file mode 100644 index 0000000..06f5493 --- /dev/null +++ b/week_01/08/ArrayList-008.md @@ -0,0 +1,251 @@ +# 读源码--ArrayList + +1. ## 继承结构 + + 1. ### 继承类 + + - #### AbstractList + + 2. ### 实现接口 + + - List + - RandomAcces--可随机访问 + - Cloneable--可拷贝 + - java.io.Serializable--可序列化 + +2. ## 属性和方法 + + 1. ### 属性 + + - #### 默认空间(static):DEFAULT_CAPACITY--10 + + - #### 初始化数组(static) + + - ##### EMPTY_ELEMENTDATA: + + - ##### DEFAULTCAPACITY_EMPTY_ELEMENTDATA + + - #### 瞬态对象:elementData(用来干嘛) + + 2. ### 常用方法 + + 1. #### 构造器 + + - ArrayList(int size) + - ArrayList(Collections c):任意集合转ArrayList。底层实现为数组 + + 2. #### trimToSize():去除空值生成新的集合 + + 3. #### int size() + + 4. #### isEmpty() + + 5. #### contains(Object o) + + 6. #### indexOf(Object o) + + - 若为null,则返回第一个null所在的索引 + - 无则返回-1 + + 7. #### lastIndexOf(Object o) + + 8. #### toArray():转数组 + + 9. #### clear():将数组所有元素置空,便于GC回收 + +3. ### 扩容(调试) + + 1. #### 添加元素add + + 2. #### 最小容量minCapacity(添加元素后的数组长度)与数组容量element.length + + - ##### 初始化时为均为0 + + - ##### 首次添加单个元素后为element.length变为10 + + ``` + private static int calculateCapacity(Object[] elementData, int minCapacity) { + // 首次增加元素容量扩展为默认容量10 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + return Math.max(DEFAULT_CAPACITY, minCapacity); + } + return minCapacity; + } + ``` + + ``` + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + ``` + + ``` + // 精确扩容 + private void ensureExplicitCapacity(int minCapacity) { + modCount++; + + // overflow-conscious code + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + ``` + + - ##### 后面超过element.length后依次1.5增长 + + ``` + // 真正执行扩容的方法grow + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); + } + ``` + + + + - ###### 注:非1.5倍扩容的情况 + + - ##### add()首次添加单个元素扩容至10 + + - ##### addAll()批量增加后的数组长度大于扩容1.5倍容量时,直接扩容至数组长度 + + ``` + public static void main(String[] args) { + ArrayList list = new ArrayList(); + ArrayList list1 = new ArrayList(); + int count = 10; + int count1 = 8; + for (int i = 0; i < count1; i++) { + list1.add(i); + } + for (int i = 0; i < count; i++) { + list.add(i); + System.out.println(i+":"+list); + } + // 当增加的数组长度大于1.5倍容量的扩容情况 + list.addAll(list1); + } + ``` + + 1. ### 增删改查 + + 1. #### 通用方法 + + - #### System.arraycopy()方法 + + ``` + public static native void arraycopy(Object src, int srcPos, + Object dest, int destPos, + int length); + ``` + + 2. #### 增加 + + - ##### 末尾增加:boolean add(E e) + + - ##### 指定位置增加 + + ``` + public void add(int index, E element) { + rangeCheckForAdd(index); + + ensureCapacityInternal(size + 1); // Increments modCount!! + // 后续元素依次往后移,添加缓慢,删除同理 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + elementData[index] = element; + size++; + } + ``` + + - ##### 批量添加 + + ``` + public boolean addAll(Collection c) { + Object[] a = c.toArray(); + int numNew = a.length; + // 此时的容量(size + numNew)可能超过扩容后1.5倍,则扩容后的容量为(size + numNew) + ensureCapacityInternal(size + numNew); // Increments modCount + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + return numNew != 0; + } + ``` + + ``` + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); + + // 需求容量minCapacity大于扩容后的容量newCapacity + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); + } + ``` + + - ##### 指定位置批量添加 + + 3. #### 删除 + + - ##### 指定下标 + + ``` + public E remove(int index) { + rangeCheck(index); + + modCount++; + E oldValue = elementData(index); + // 下标为index的元素,实际是数组的第index+1个元素 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work + + return oldValue; + } + ``` + + - ##### 指定对象 + + ``` + public boolean remove(Object o) { + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else { + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; + } + ``` + + - ##### 指定下标范围批量移除 + + + + ##### + + + + + + \ No newline at end of file From cbf543ca3d74282ad12ea3e32a517cb08ba311a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=9E=97=E8=BE=89?= Date: Thu, 12 Dec 2019 11:26:10 +0800 Subject: [PATCH 17/73] 007-Week 01 --- week_01/07/ArrayList-007.md | 58 +++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/week_01/07/ArrayList-007.md b/week_01/07/ArrayList-007.md index 8a78f65..c512c70 100644 --- a/week_01/07/ArrayList-007.md +++ b/week_01/07/ArrayList-007.md @@ -1,5 +1,5 @@ ArrayList源码解析 -前言:ArrayList是我们开发中比较常用的一个集合类,底层是基于数组实现的,现在就来看一看里面是怎么实现的 +前言:源码都是基于JDK1.8。ArrayList是我们开发中比较常用的一个集合类,底层是基于数组实现的,现在就来看一看里面是怎么实现的 1.首先看一下定义的成员变量 int DEFAULT_CAPACITY = 10; //默认初始化数组的大小 Object[] EMPTY_ELEMENTDATA = {}; //空数组对象 @@ -80,15 +80,69 @@ ArrayList源码解析 //在指定位置插入数据 public void add(int index, E element) { - rangeCheckForAdd(index); + rangeCheckForAdd(index); //判断添加元素的位置是否越界 ensureCapacityInternal(size + 1); // Increments modCount!! //跟上面的方法一样,判断是否要扩容,如果要扩容,扩容后返回新数组 System.arraycopy(elementData, index, elementData, index + 1, size - index); //在指定位置插入元素后,把指定位置后的元素全部向后移一位 elementData[index] = element; size++; } + //批量增加的方法 + public boolean addAll(int index, Collection c) { + rangeCheckForAdd(index); //判断添加元素的位置是否越界 + Object[] a = c.toArray(); //把要添加的集合转换为Object[] + int numNew = a.length; + //判断是否需要扩容,如果需要的话,大小为size + numNew + ensureCapacityInternal(size + numNew); // Increments modCount + int numMoved = size - index; + if (numMoved > 0) //判断原数组里面的元素是否需要移动,如果需要,移动到index + numNew,为什么是这个长度呢?因为index + numNew的长度要放批量新加的集合 + System.arraycopy(elementData, index, elementData, index + numNew, numMoved); + //把新加的集合添加到数组中 + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; //把size变成添加集合后的大小 + return numNew != 0; + } + //get方法 + public E get(int index) { + rangeCheck(index); //判断元素下标是否大于size + return elementData(index); //从数组中取元素返回 + } + //删除方法,这里有两个,一个是根据下标删除,并返回删除的元素,时间复杂度为O(1)。还有一个是根据元素删除,返回是否删除成功,需要循环数组中的元素,最好时间复杂度为O(1),最坏时间复杂度为O(n),平均时间复杂度为O(n) + public E remove(int index) { + rangeCheck(index); //判断元素下标是否大于size + modCount++; + E oldValue = elementData(index); //取出要删除的元素,最后返回 + int numMoved = size - index - 1; //得到要移动元素的长度 + if (numMoved > 0) //如果元素大于0,移动数组 + System.arraycopy(elementData, index+1, elementData, index, numMoved); + elementData[--size] = null; // clear to let GC do its work //把最后一个元素置为空 + return oldValue; + } + + //截取集合 + public List subList(int fromIndex, int toIndex) { + subListRangeCheck(fromIndex, toIndex, size); //检查边界,是否合法 + return new SubList(this, 0, fromIndex, toIndex); //每次截取集合,会返回一个新的SubList,这个新的SubList又实现了集合中的大部分方法。这里就不贴代码了,太长了 + } + + //1.8新增的循环集合方法 + @Override + public void forEach(Consumer action) { + Objects.requireNonNull(action); //判断传的函数式对象是否为空 + final int expectedModCount = modCount; //操作次数 + @SuppressWarnings("unchecked") + final E[] elementData = (E[]) this.elementData; //底层数组 + final int size = this.size; //数组大小 + for (int i=0; modCount == expectedModCount && i < size; i++) { //这里多一个判断是因为在集合循环的时候,不能去增、删、改里面的元素 + action.accept(elementData[i]); + } + if (modCount != expectedModCount) { //如果有增、删、改操作的话,就抛异常 + throw new ConcurrentModificationException(); + } + } +4.总结:ArrayList就分析到这了,如有错误请指正,或者有建议也欢迎提出来一起讨论 From fed57ee318c058daa62afc9c9d8d81a98766632b Mon Sep 17 00:00:00 2001 From: "t.tian" <32661975+HeoPeach@users.noreply.github.com> Date: Thu, 12 Dec 2019 23:29:04 +0800 Subject: [PATCH 18/73] ArrayList About ArrayList notes --- week_01/09/ArrayList-009.md | 215 ++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 week_01/09/ArrayList-009.md diff --git a/week_01/09/ArrayList-009.md b/week_01/09/ArrayList-009.md new file mode 100644 index 0000000..206ac3c --- /dev/null +++ b/week_01/09/ArrayList-009.md @@ -0,0 +1,215 @@ +##关于ArrayList小笔记 + + +###1、认识ArrayList + +1)ArrayList就是动态数组 + + ```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable + ``` + +2)实现了List,提供了基础的添加、删除等操作; + +3)实现Cloneable; + +4)实现java.io.Serializable,可被序列化; + +5)实现RandomAccess,可随机访问。 + +###2、属性概览 + +```java +/** + * 默认初始化大小. + */ + private static final int DEFAULT_CAPACITY = 10; + /** + * 空数组 当创建实例数量为空时使用. + */ + private static final Object[] EMPTY_ELEMENTDATA = {}; + /** + * 存储元素的数组. + */ + transient Object[] elementData;// non-private to simplify nested class access + /** + * 数组大小. + */ + private int size; + +``` + +###3、构造器 +```java +/** + * 创建指定大小数组 + * @param 数组大小 + */ +public ArrayList(int initialCapacity) { + super(); + // 如果传入大小小于0,抛出异常 + if (initialCapacity < 0) + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + // 创建指定容量大小新数组 + this.elementData = new Object[initialCapacity]; +} + +/** + * 默认构造器为空数组,使用时按默认大小 + */ + public ArrayList() { + super(); + this.elementData = EMPTY_ELEMENTDATA; +} + +/** + * 将传入的集合转成数组 + */ + public ArrayList(Collection c) { + elementData = c.toArray(); + size = elementData.length; + // c.toArray might (incorrectly) not return Object[] (see 6260652) + //see 6260652为bug编号 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652 + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); +} + +``` +ps:针对最后一类创建数组方式为什么返回不一定是一个对象,测试如下: + +```java +//第一种方式 +List test1 = new ArrayList( ); +test1.add("123"); +System.out.println(test1.toArray()); +//返回结果:[Ljava.lang.Object;@a74868d + +//第二种方式 +List test2 = Arrays.asList("123"); +System.out.println(test2.toArray()); +//返回结果:[Ljava.lang.String;@12c8a2c0 +``` + +### 4、add +1)add(E e) + +```java +/** + * 添加数组,从末尾开始添加 + */ +public boolean add(E e) { + //检查是否需要扩容 + ensureCapacityInternal(size + 1); // Increments modCount!! + //将元素添加到数组最后一位 + elementData[size++] = e; + return true; +} + +private void ensureCapacityInternal(int minCapacity) { + //如果是空数组,则初始化默认大小10 + if (elementData == EMPTY_ELEMENTDATA) { + minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); + } + ensureExplicitCapacity(minCapacity); +} + +private void ensureExplicitCapacity(int minCapacity) { + //用于统计list被修改的次数 + modCount++; + // overflow-conscious code + if (minCapacity - elementData.length > 0) + //扩容 + grow(minCapacity); +} + +private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + //扩容1.5倍 + int newCapacity = oldCapacity + (oldCapacity >> 1); + //如果新容量小于需要最小容量,则以需要容量为准 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + //如果新容量大于最大容量,则以最大容量为准 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + //以新容量拷贝一个新数组出来 + elementData = Arrays.copyOf(elementData, newCapacity); +} +``` +2)add(int index, E element) + +``` java +/** + * 添加元素到指定位置 + */ +public void add(int index, E element) { + //检查是否越界 + rangeCheckForAdd(index); + //检查是否需要扩容 + ensureCapacityInternal(size + 1); // Increments modCount!! + //将数组index之后的元素往后移动一位 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + //再将index设置为需要添加的元素 + elementData[index] = element; + //数组长度+1 + size++; +} +``` + +###5、get + +``` java +/** + * 获得指定位置该元素 + */ +public E get(int index) { + ///检查是否越界 + rangeCheck(index); + //返回元素 + return elementData(index); +} + + +private void rangeCheck(int index) { + if (index < 0 || index >= this.size) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); +} + +private void checkForComodification() { + //保证操作为同一list(考虑并发情况下) + if (ArrayList.this.modCount != this.modCount) + throw new ConcurrentModificationException(); +} + +``` + +###6、remove + +``` java +/** + * 删除指定位置元素 + */ +public E remove(int index) { + //检查是否越界 + rangeCheck(index); + + modCount++; + //获取index位置元素 + E oldValue = elementData(index); + //如果index不是最后一位,则把index之后的元素往前挪一位 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + //// 将最后一个元素删除,帮助GC + elementData[--size] = null; // clear to let GC do its work + //返回删除旧值 + return oldValue; +} + +``` From 00798a9e1f9fea3d28866fa9539f8e7b8d09ab86 Mon Sep 17 00:00:00 2001 From: Qylningque Date: Fri, 13 Dec 2019 15:07:34 +0800 Subject: [PATCH 19/73] =?UTF-8?q?060-week=2001=2001-ArrayList=E6=80=9D?= =?UTF-8?q?=E7=BB=B4=E5=AF=BC=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week_01/60/ArrayList-060.png | Bin 0 -> 66168 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 week_01/60/ArrayList-060.png diff --git a/week_01/60/ArrayList-060.png b/week_01/60/ArrayList-060.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9dffee6a61fc5e2a0c8819ec7d414b21433875 GIT binary patch literal 66168 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 YXa=V8+nhuT;j`709zQI9@ci}v0T6=CmjD0& literal 0 HcmV?d00001 From 083cce5e64c4281e8193ec5ed4920a4f7f1d4445 Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Fri, 13 Dec 2019 23:39:00 +0800 Subject: [PATCH 20/73] me. --- week_01/01/README.md | 47 ------- week_01/02/README.md | 47 ------- week_01/03/README.md | 47 ------- week_01/04/README.md | 47 ------- week_01/05/README.md | 47 ------- week_01/06/README.md | 47 ------- week_01/07/README.md | 47 ------- week_01/08/README.md | 47 ------- week_01/09/README.md | 47 ------- week_01/1/README.md | 47 ------- week_01/10/README.md | 47 ------- week_01/11/README.md | 47 ------- week_01/12/README.md | 47 ------- week_01/13/README.md | 47 ------- week_01/14/README.md | 47 ------- week_01/15/README.md | 47 ------- week_01/16/README.md | 47 ------- week_01/17/README.md | 47 ------- week_01/18/README.md | 47 ------- week_01/19/README.md | 47 ------- week_01/20/README.md | 47 ------- week_01/21/README.md | 47 ------- week_01/22/README.md | 47 ------- week_01/23/README.md | 47 ------- week_01/24/README.md | 47 ------- week_01/25/README.md | 47 ------- week_01/26/README.md | 47 ------- week_01/27/README.md | 47 ------- week_01/28/README.md | 47 ------- week_01/29/README.md | 47 ------- week_01/30/README.md | 47 ------- week_01/31/README.md | 47 ------- week_01/32/README.md | 47 ------- week_01/33/README.md | 47 ------- week_01/34/README.md | 47 ------- week_01/35/ArrayList-035.md | 45 +++++++ week_01/35/HashMap-035.md | 119 ++++++++++++++++++ week_01/35/com.dans.demo/ArrayListDemo.java | 33 +++++ week_01/35/com.dans.demo/HashMapDemo.java | 54 ++++++++ week_01/35/com.dans.demo/LinkedListDemo.java | 24 ++++ .../production/JavaStudy/ArrayListDemo.class | Bin 0 -> 1931 bytes .../production/JavaStudy/HashMapDemo$1.class | Bin 0 -> 1253 bytes .../production/JavaStudy/HashMapDemo.class | Bin 0 -> 2108 bytes .../production/JavaStudy/LinkedListDemo.class | Bin 0 -> 1643 bytes .../META-INF/JavaStudy.kotlin_module | Bin 0 -> 16 bytes week_01/36/README.md | 47 ------- week_01/37/README.md | 47 ------- week_01/38/README.md | 47 ------- week_01/39/README.md | 47 ------- week_01/40/README.md | 47 ------- week_01/41/README.md | 47 ------- week_01/42/README.md | 47 ------- week_01/43/README.md | 47 ------- week_01/44/README.md | 47 ------- week_01/45/README.md | 47 ------- week_01/46/README.md | 47 ------- week_01/46/test.txt | 1 - week_01/47/README.md | 47 ------- week_01/48/README.md | 47 ------- week_01/49/README.md | 47 ------- week_01/50/README.md | 47 ------- week_01/51/README.md | 47 ------- week_01/52/README.md | 47 ------- week_01/53/README.md | 47 ------- week_01/54/README.md | 47 ------- week_01/55/README.md | 47 ------- week_01/56/README.md | 47 ------- week_01/57/README.md | 47 ------- week_01/58/README.md | 47 ------- week_01/59/README.md | 47 ------- week_01/60/README.md | 47 ------- week_01/61/README.md | 47 ------- week_01/62/README.md | 47 ------- week_01/63/README.md | 47 ------- week_01/64/README.md | 47 ------- week_01/65/README.md | 47 ------- week_01/66/README.md | 47 ------- week_01/67/README.md | 47 ------- week_01/68/README.md | 47 ------- week_01/69/README.md | 47 ------- week_01/70/README.md | 47 ------- 81 files changed, 275 insertions(+), 3291 deletions(-) delete mode 100644 week_01/01/README.md delete mode 100644 week_01/02/README.md delete mode 100644 week_01/03/README.md delete mode 100644 week_01/04/README.md delete mode 100644 week_01/05/README.md delete mode 100644 week_01/06/README.md delete mode 100644 week_01/07/README.md delete mode 100644 week_01/08/README.md delete mode 100644 week_01/09/README.md delete mode 100644 week_01/1/README.md delete mode 100644 week_01/10/README.md delete mode 100644 week_01/11/README.md delete mode 100644 week_01/12/README.md delete mode 100644 week_01/13/README.md delete mode 100644 week_01/14/README.md delete mode 100644 week_01/15/README.md delete mode 100644 week_01/16/README.md delete mode 100644 week_01/17/README.md delete mode 100644 week_01/18/README.md delete mode 100644 week_01/19/README.md delete mode 100644 week_01/20/README.md delete mode 100644 week_01/21/README.md delete mode 100644 week_01/22/README.md delete mode 100644 week_01/23/README.md delete mode 100644 week_01/24/README.md delete mode 100644 week_01/25/README.md delete mode 100644 week_01/26/README.md delete mode 100644 week_01/27/README.md delete mode 100644 week_01/28/README.md delete mode 100644 week_01/29/README.md delete mode 100644 week_01/30/README.md delete mode 100644 week_01/31/README.md delete mode 100644 week_01/32/README.md delete mode 100644 week_01/33/README.md delete mode 100644 week_01/34/README.md create mode 100644 week_01/35/ArrayList-035.md create mode 100644 week_01/35/HashMap-035.md create mode 100644 week_01/35/com.dans.demo/ArrayListDemo.java create mode 100644 week_01/35/com.dans.demo/HashMapDemo.java create mode 100644 week_01/35/com.dans.demo/LinkedListDemo.java create mode 100644 week_01/35/targert/production/JavaStudy/ArrayListDemo.class create mode 100644 week_01/35/targert/production/JavaStudy/HashMapDemo$1.class create mode 100644 week_01/35/targert/production/JavaStudy/HashMapDemo.class create mode 100644 week_01/35/targert/production/JavaStudy/LinkedListDemo.class create mode 100644 week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module delete mode 100644 week_01/36/README.md delete mode 100644 week_01/37/README.md delete mode 100644 week_01/38/README.md delete mode 100644 week_01/39/README.md delete mode 100644 week_01/40/README.md delete mode 100644 week_01/41/README.md delete mode 100644 week_01/42/README.md delete mode 100644 week_01/43/README.md delete mode 100644 week_01/44/README.md delete mode 100644 week_01/45/README.md delete mode 100644 week_01/46/README.md delete mode 100644 week_01/46/test.txt delete mode 100644 week_01/47/README.md delete mode 100644 week_01/48/README.md delete mode 100644 week_01/49/README.md delete mode 100644 week_01/50/README.md delete mode 100644 week_01/51/README.md delete mode 100644 week_01/52/README.md delete mode 100644 week_01/53/README.md delete mode 100644 week_01/54/README.md delete mode 100644 week_01/55/README.md delete mode 100644 week_01/56/README.md delete mode 100644 week_01/57/README.md delete mode 100644 week_01/58/README.md delete mode 100644 week_01/59/README.md delete mode 100644 week_01/60/README.md delete mode 100644 week_01/61/README.md delete mode 100644 week_01/62/README.md delete mode 100644 week_01/63/README.md delete mode 100644 week_01/64/README.md delete mode 100644 week_01/65/README.md delete mode 100644 week_01/66/README.md delete mode 100644 week_01/67/README.md delete mode 100644 week_01/68/README.md delete mode 100644 week_01/69/README.md delete mode 100644 week_01/70/README.md diff --git a/week_01/01/README.md b/week_01/01/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/01/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/02/README.md b/week_01/02/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/02/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/03/README.md b/week_01/03/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/03/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/04/README.md b/week_01/04/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/04/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/05/README.md b/week_01/05/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/05/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/06/README.md b/week_01/06/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/06/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/07/README.md b/week_01/07/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/07/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/08/README.md b/week_01/08/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/08/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/09/README.md b/week_01/09/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/09/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/1/README.md b/week_01/1/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/1/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/10/README.md b/week_01/10/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/10/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/11/README.md b/week_01/11/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/11/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/12/README.md b/week_01/12/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/12/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/13/README.md b/week_01/13/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/13/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/14/README.md b/week_01/14/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/14/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/15/README.md b/week_01/15/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/15/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/16/README.md b/week_01/16/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/16/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/17/README.md b/week_01/17/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/17/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/18/README.md b/week_01/18/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/18/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/19/README.md b/week_01/19/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/19/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/20/README.md b/week_01/20/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/20/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/21/README.md b/week_01/21/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/21/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/22/README.md b/week_01/22/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/22/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/23/README.md b/week_01/23/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/23/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/24/README.md b/week_01/24/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/24/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/25/README.md b/week_01/25/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/25/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/26/README.md b/week_01/26/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/26/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/27/README.md b/week_01/27/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/27/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/28/README.md b/week_01/28/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/28/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/29/README.md b/week_01/29/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/29/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/30/README.md b/week_01/30/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/30/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/31/README.md b/week_01/31/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/31/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/32/README.md b/week_01/32/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/32/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/33/README.md b/week_01/33/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/33/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/34/README.md b/week_01/34/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/34/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/35/ArrayList-035.md b/week_01/35/ArrayList-035.md new file mode 100644 index 0000000..0a64198 --- /dev/null +++ b/week_01/35/ArrayList-035.md @@ -0,0 +1,45 @@ +ArrayList +基于数组实现 +继承抽象类AbstractList +实现了List(接口->Collection、Iterable) +RandomAccess(随机访问) +Cloneable(可克隆) +Serializable(可序列化) + +主要参数: +DEFAULT_CAPACITY(默认初始化大小) +EMPTY_ELEMENTDATA(指定list为空时使用的数组) +DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) +elementData(存放元素的数组) +size(数组大小) + +madCount(全局变量) +madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, +当进行next()、remove()、previous()、set()、add()等操作时, +如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。 + +ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; +在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同, +不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException。 + +1、三个构造方法 + 1)无参 + 初始大小10 + 2)int参数 + 大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException + 3)Collection参数 + 定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 + if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 + 不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. + 源码: + public static T[] copyOf(U[] original, int newLength, Class newType) { + @SuppressWarnings("unchecked") + T[] copy = ((Object)newType == (Object)Object[].class) + ? (T[]) new Object[newLength] + : (T[]) Array.newInstance(newType.getComponentType(), newLength); + System.arraycopy(original, 0, copy, 0, + Math.min(original.length, newLength)); + return copy; + } + + \ No newline at end of file diff --git a/week_01/35/HashMap-035.md b/week_01/35/HashMap-035.md new file mode 100644 index 0000000..6211670 --- /dev/null +++ b/week_01/35/HashMap-035.md @@ -0,0 +1,119 @@ +继承AbstractMap +实现Map, Cloneable, Serializable +JDK版本 实现方式 节点数>=8 节点数<=6 +1.8以前 数组+单向链表 数组+单向链表 数组+单向链表 +1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 + +主要参数: +DEFAULT_INITIAL_CAPACITY(1 << 4 -> 初始容量大小) +MAXIMUM_CAPACITY(1 << 30 -> 容量极限大小) +DEFAULT_LOAD_FACTOR(负载因子默认大小) +TREEIFY_THRESHOLD(节点数大于8时会转为红黑树存储) +UNTREEIFY_THRESHOLD(节点数小于6时会转为单向链表存储) +MIN_TREEIFY_CAPACITY(红黑树最小长度为64) +Node(实现Map.Entry , 单向链表) + Node是Map.Entry接口的实现类,存储数据的Node数组容量是2次幂,每个Node本质都是一个单向链表 +TreeNode(extends LinkedHashMap.Entry , 红黑树) +size(HashMap大小,代表HashMap保存的键值对的大小) +modCount(被改变的次数) +threshold(下一次HashMap扩容的大小->put时根据oldCap和newCap比较确定下一次扩容大小) +loadFactor(存储负载因子的常量) + +1、hash的计算: +//将传入的参数key本身的hashCode与h无符号右移16位进行二进制异或运算得出一个新的hash值 +static final int hash(Object key) { + int h; + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); +} +那为什么要这么做呢?直接通过key.hashCode()获取hash不得了吗? 为什么在右移16位后进行异或运算? + 与HashMap的table数组下计算标有关系 + //put函数代码块中 + tab[i = (n - 1) & hash]) + //get函数代码块中 + tab[(n - 1) & hash]) + 根据索引得到tab中节点数据,key.hashCode()>>>16经过^异或运算和经过&与运算后得到的二进制是一致的 + 当发生较大碰撞时也用树形存储降低了冲突。减少了系统的开销 +1.1、put方法 + 1、首先获取Node数组table对象和长度,若table为null或长度为0,则调用resize()扩容方法获取table最新对象,并通过此对象获取长度大小 + if ((tab = table) == null || (n = tab.length) == 0) + n = (tab = resize()).length; + 2、判定数组中指定索引下的节点是否为Null,若为Null则new出一个单向链表赋给table中索引下的这个节点 + if ((p = tab[i = (n - 1) & hash]) == null) + tab[i] = newNode(hash, key, value, null) + 3、若判定不为Null,我们的判断再做分支 + 3.1、首先对hash和key进行匹配,若判定成功直接赋予e + if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) + e = p; + 3.2、若匹配判定失败,则进行类型匹配是否为TreeNode 若判定成功则在红黑树中查找符合条件的节点并将其回传赋给e + else if (p instanceof TreeNode) + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + 3.3、若以上判定全部失败则进行最后操作,向单向链表中添加数据若单向链表的长度大于等于8, + 则将其转为红黑树保存,记录下一个节点,对e进行判定若成功则返回旧值 + for (int binCount = 0; ; ++binCount) { + if ((e = p.next) == null) { + p.next = newNode(hash, key, value, null); + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + treeifyBin(tab, hash); + break; + } + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + break; + p = e; + } + 综合以上判断得出: + if (e != null) { // existing mapping for key + V oldValue = e.value; + if (!onlyIfAbsent || oldValue == null) + e.value = value; + afterNodeAccess(e); + return oldValue; + } + 4、最后判定数组大小需不需要扩容 + if (++size > threshold) + resize() +1.2、get方法 + 1、判定三个条件 table不为Null & table的长度大于0 & table指定的索引值不为Null + if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) + 2、判定 匹配hash值 & 匹配key值 成功则返回该值 + if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) + return first + 3、若first节点的下一个节点不为Null + if ((e = first.next) != null) + 3.1、若first的类型为TreeNode红黑树,通过红黑树查找匹配值并返回查询值 + if (first instanceof TreeNode) + return ((TreeNode)first).getTreeNode(hash, key) + 3.2、若上面判定不成功则认为下一个节点为单向链表,通过循环匹配值 + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + return e; + } while ((e = e.next) != null); + + +2、三个构造方法 +//指定容量大小 +public HashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); +} + //指定容量大小和负载因子大小 +public HashMap(int initialCapacity, float loadFactor) { + //指定的容量大小不可以小于0,否则将抛出IllegalArgumentException异常 + if (initialCapacity < 0) + throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); + //判定指定的容量大小是否大于HashMap的容量极限 + if (initialCapacity > MAXIMUM_CAPACITY) + initialCapacity = MAXIMUM_CAPACITY; + //指定的负载因子不可以小于0或为Null,若判定成立则抛出IllegalArgumentException异常 + if (loadFactor <= 0 || Float.isNaN(loadFactor)) + throw new IllegalArgumentException("Illegal load factor: " + loadFactor); + this.loadFactor = loadFactor; + //设置HashMap阈值,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 + this.threshold = tableSizeFor(initialCapacity); +} +//传入Map集合,将Map集合中元素Map.Entry全部添加进HashMap实例中 +public HashMap(Map m) { + this.loadFactor = DEFAULT_LOAD_FACTOR; + //此构造方法主要实现了Map.putAll() + putMapEntries(m, false); +} \ No newline at end of file diff --git a/week_01/35/com.dans.demo/ArrayListDemo.java b/week_01/35/com.dans.demo/ArrayListDemo.java new file mode 100644 index 0000000..e74656d --- /dev/null +++ b/week_01/35/com.dans.demo/ArrayListDemo.java @@ -0,0 +1,33 @@ +import java.util.ArrayList; +import java.util.List; + +/** + * @ProjectName: JavaStudy + * @Package: com.dans.demo + * @ClassName: ArrayListDemo + * @Author: dans + * @Description: demo + * @Date: 2019/12/12 21:53 + */ +public class ArrayListDemo { + + public static void main(String[] arg0) { + List demo = new ArrayList<>(); + demo.add("0"); + demo.add("1"); + + //指定位置插入数据(返回该下标的老数据) + String oldVal = demo.set(0, "2"); + System.out.println("oldVal: " + oldVal); + //根据内容移出(返回boolean类型; + // 若传入为null,则循环找到空值,执行fastRemove方法,根据下标移出,内部调用了System.arraycopy(); + // 不为空,则循环用equals做比较,再执行fastRemove方法,根据下标移出,内部调用System.arraycopy()) +// demo.remove("2"); +// 指定下标移出(返回移出数据) + demo.remove(0); + + demo.stream().forEach(str -> { + System.out.println(str); + }); + } +} diff --git a/week_01/35/com.dans.demo/HashMapDemo.java b/week_01/35/com.dans.demo/HashMapDemo.java new file mode 100644 index 0000000..c1551dc --- /dev/null +++ b/week_01/35/com.dans.demo/HashMapDemo.java @@ -0,0 +1,54 @@ +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.BiConsumer; + +/** + * @ProjectName: JavaStudy + * @Package: com.dans.demo + * @ClassName: HashMapDemo + * @Author: dans + * @Description: demo + * @Date: 2019/12/13 21:30 + */ +public class HashMapDemo { + + public static void main(String[] arg0) { + Map map = new HashMap<>(); + map.put(0, 1); + map.put(1, 2); + map.put(2, 3); + map.put(3, 4); + + //HashMap中modCount和expectedModCount不相等,则会抛出异常 + //遍历时禁止执行有modCount++相关的操作 + + //1.8之后新方法 + map.forEach(new BiConsumer() { + @Override + public void accept(Integer key, Integer val) { + System.out.println("foreach--------->key:" + key + "--------val:" + val); + //执行remove,抛出错误(ConcurrentModificationException) + /*if (key == 1) { + map.remove(key); + }*/ + } + }); + + Iterator iterator = map.entrySet().iterator(); + Entry entry = null; + while (iterator.hasNext()) { + entry = (Entry) iterator.next(); + if (entry.getKey() == 1) + iterator.remove(); + System.out.println("iterator------>key:" + entry.getKey() + "--------val:" + entry.getValue()); + } + + for (Entry entry1 : map.entrySet()) { + //执行remove()抛错(ConcurrentModificationException) +// map.remove(entry.getKey()); + System.out.println("entry1------->key:" + entry1.getKey() + "--------val:" + entry1.getValue()); + } + } +} diff --git a/week_01/35/com.dans.demo/LinkedListDemo.java b/week_01/35/com.dans.demo/LinkedListDemo.java new file mode 100644 index 0000000..e51e9dc --- /dev/null +++ b/week_01/35/com.dans.demo/LinkedListDemo.java @@ -0,0 +1,24 @@ +import java.util.LinkedList; +import java.util.List; + +/** + * @ProjectName: JavaStudy + * @Package: com.dans.demo + * @ClassName: LinkedListemo + * @Author: dans + * @Description: demo + * @Date: 2019/12/13 23:30 + */ +public class LinkedListDemo { + + public static void main(String[] arg0) { + List list = new LinkedList<>(); + list.add(1); + list.add(2); + list.add(3); + + list.stream().forEach(i -> { + System.out.println(i); + }); + } +} diff --git a/week_01/35/targert/production/JavaStudy/ArrayListDemo.class b/week_01/35/targert/production/JavaStudy/ArrayListDemo.class new file mode 100644 index 0000000000000000000000000000000000000000..98f8536d93eb00eeb3c2743d6a3b5aa70e4b6e9b GIT binary patch literal 1931 zcmbVNZBr9h7(F+^?2@b!BcRn*k;amM7^K#=hEgTIKpT8%XcX<+O?H8W&2DD1VTPa8 ze!z*&bo!-VI{i%@&)p3sA&eh7ncUZN&vTx0pPT&i-u}!>Wcgfy9#S z+QG6wJeRKujFddn5*RDnuJyRxs9FAotT|lCl)buis?xXByt_CO?AR@ZzUTY$plr8- z`&Pp%lBOYTS70*ts=O=rWxj#4v3%V>iV51L0Zv&Wd0hEFe({j?(+HB)Al_AJ#+`cfVT<{f$~TLcncP~Rtw-C# zO9K%r2d%(rkiu(|Vj@D@Ug0S#Dqvk%vZ2aDHk+191@kA}TwjQ&61)EKpdNV9lE8Q_ zKLjKqy2inX0$NkWcUb8OpC;||olNA``U$%E5kTXqQsB~2fUqW_RrNGf3Q3pQNO16kh@nCe;;qJ~NG zRSnw)cHkJuAull9t3un|_x7wpIeaxNDY+%@6xyZ?WiQOFOU?Z4Y@*phUdiXB)* z4SXiohWt4xAA!ps#^EY&dy>D_KpebDTwwbVX9f0x{i)g45WjN}!$r1Q=3B%zUn5?g%ZzkzDu(BCnM8LG&uAU!ar}kR^*@k&ixiPY z=JX-XT<7-?V~0r3#XC5wj&+a`c!P652jej)LGe(~G<1%~*rsuopNkmB40F0miK`U$ z0#l*bsYnoKSBcm04Ac0Oa%ZrJEUq!V&$zBqiuPt8(n(c{-IQ(Z(x$tdt9bW_SwRW+-vO9W=#T&a literal 0 HcmV?d00001 diff --git a/week_01/35/targert/production/JavaStudy/HashMapDemo$1.class b/week_01/35/targert/production/JavaStudy/HashMapDemo$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0ead94943a96655aab222f15b9475f17120f9b8a GIT binary patch literal 1253 zcmaJ=>rN9v6#k|yY+1Hk%FPQXN|Bb^f}*I!DpZXmMNMi*h`)yI&@OIwo4t_mD!zsO zD2W>5Z(qhYFrL|N(h93uuA`)w$YSwM;2QGDT z5JNn-Dez58KMHKaHyvBwG0Tqa1x?{@#Wq|~bBP*Nt4`n=;BKM? zgP^a*W!x&wC{9K8OHO43yFj{7AkSRLI$NJ>$RxqiOVY7#~Qu9A<#Xb zx0|G&PMv01@^rF{Y~SJ;*cWmV7^AU23{GR5e65p!2~5$9$y1|IZWaV4;pV;~@g2#7 zGo-S8ZS*g-p=8tKER)m5KpScgS|tkLHtr%9!q0XfB6tGB4crVV=P*rPVq}{rXClhY vh%&Rd^b3Q_^tYk)z%SOFiGWkMMYIVbo(=6CDga0kT@I7vsYH+=3#9)6Nxdn0 literal 0 HcmV?d00001 diff --git a/week_01/35/targert/production/JavaStudy/HashMapDemo.class b/week_01/35/targert/production/JavaStudy/HashMapDemo.class new file mode 100644 index 0000000000000000000000000000000000000000..f97b55efcba806682bcb66ccb82d436ebe475cd4 GIT binary patch literal 2108 zcmb7FO;;OL7=CWPW=Muo!k1{(Qc(jmq*!Vzq_jf8Vgs~IrM4Au2tyc1CUG*sqOM%| z7wXEL3y;U63oz2-aqUlV>kn}6@l>BXGa(ZX8*@(Xec$&!@ArG}{PyhUUjR(v^Eh5Y zR>9RcLdeF^g_#7d;ktsiyP3LXh)iolX`Bk1f@Kyi3N!v+c(Heo2((r^Jqdeg8CQ^O8+S@@Q{<1%O{$s^BI zuoxQ3uryRKq@b$dW3T}Ou7N=RXX|EZ)8I*8vrB3BH?wQ(|M~PQ4K+A&sSBL)PSWW; zz2qM4VOPT^c&uPw!>9O+{q+XP2l_Sy5`ipPtX2#w8#_k9VHw);;&8Y4=9ma5^jkMp zw&Wl$j-1eGj$pM;YgbZ%L(fHUFnmeSf-j*4FnTU$4jeoPvO6E4Nzr#ns(94V< zrdO+mwJDGe7O(k61nTLD{IQ{88~%jS{ui$@ct2*8i)%l ziRJSRBm|z|E(uNGS9C6?8#pDYt^=Hoe2osCbPN25%%4V^RsydcUZ+W)^Qype9J~*V+>#5JibI4hkWIJ$3>xHQY5G$doYP8W#dGT zkz&P(O;fIl2&J-#Yxtge6KwA~zQY^Dg>jLHv)nyRX~V-`BHlwy^7Kuj1`&NGAK}Xi lt|)jbHU2j=l7BIY5T*zSVHz)UPm*HG`BVA%zJ}3Q$G_mp0!sh@ literal 0 HcmV?d00001 diff --git a/week_01/35/targert/production/JavaStudy/LinkedListDemo.class b/week_01/35/targert/production/JavaStudy/LinkedListDemo.class new file mode 100644 index 0000000000000000000000000000000000000000..a025e2f8fb889774f11868cc052d49266e521cfb GIT binary patch literal 1643 zcmbVNU31e$6g_JvR-%Z+B*e5(zCr?aLNTS30!|@dz5;>(PD6pGjlD@kWXU7RnaTg? zAE6JWff;^4hu_3-Rx%?Q3=h2Q>fXKgoOAEpwg3O{<{f|w_{)Ta83QLxqTQ{8rSTc-LeKdTj6*oSd}16lQ-+GF5%3zu-& zz!eKMEL!*jY<}^E??+)2$j$>5ZTYQmqJV2fEOEPD#1RWOP&aVX!Y$l3aL2-3EE~9I z;XalG#`{GOF75fs`b*VhGxw*iUOxnk9qD$}%7$*ka%Et# zbEpCbQ;B^%tZ%~)Zpr4B!112mSk0Fpdf=I!HFm>Dv536irGn|CF^*q-#OoXNis0yD z-hMYZJ37eq46ImqgjEYa;fTOY+J48|@wZjgjxQp|EjMH{@`GK0v36=1pr(TD``g`) zfVJ#-DyX|M3>6>T`)vDrc*(`NE4`Mh!r3ITmYFGa>&KVz^d+wHEq&i%Liz37?B(jw z)}`we+hw8F%57@}zEo7Gcz zky*ODk$*5c|1Zq6Lj8XLR$>q_t#X9C$LP=FIM*E8*5Gau<1zlk6Eaq4Yrc8LEZ_`& F{s<|cocI6$ literal 0 HcmV?d00001 diff --git a/week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module b/week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module new file mode 100644 index 0000000000000000000000000000000000000000..a49347afef10a9b5f95305e1058ba36adec7d6dd GIT binary patch literal 16 RcmZQzU|?ooU|@t|0RRA102TlM literal 0 HcmV?d00001 diff --git a/week_01/36/README.md b/week_01/36/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/36/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/37/README.md b/week_01/37/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/37/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/38/README.md b/week_01/38/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/38/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/39/README.md b/week_01/39/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/39/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/40/README.md b/week_01/40/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/40/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/41/README.md b/week_01/41/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/41/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/42/README.md b/week_01/42/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/42/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/43/README.md b/week_01/43/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/43/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/44/README.md b/week_01/44/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/44/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/45/README.md b/week_01/45/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/45/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/46/README.md b/week_01/46/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/46/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/46/test.txt b/week_01/46/test.txt deleted file mode 100644 index 30d74d2..0000000 --- a/week_01/46/test.txt +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/week_01/47/README.md b/week_01/47/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/47/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/48/README.md b/week_01/48/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/48/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/49/README.md b/week_01/49/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/49/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/50/README.md b/week_01/50/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/50/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/51/README.md b/week_01/51/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/51/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/52/README.md b/week_01/52/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/52/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/53/README.md b/week_01/53/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/53/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/54/README.md b/week_01/54/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/54/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/55/README.md b/week_01/55/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/55/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/56/README.md b/week_01/56/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/56/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/57/README.md b/week_01/57/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/57/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/58/README.md b/week_01/58/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/58/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/59/README.md b/week_01/59/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/59/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/60/README.md b/week_01/60/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/60/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/61/README.md b/week_01/61/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/61/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/62/README.md b/week_01/62/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/62/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/63/README.md b/week_01/63/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/63/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/64/README.md b/week_01/64/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/64/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/65/README.md b/week_01/65/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/65/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/66/README.md b/week_01/66/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/66/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/67/README.md b/week_01/67/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/67/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/68/README.md b/week_01/68/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/68/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/69/README.md b/week_01/69/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/69/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/70/README.md b/week_01/70/README.md deleted file mode 100644 index 5bb53d0..0000000 --- a/week_01/70/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## 源码刻意学习小组 - -[TOC] - - - -### 一、学习周期(2个月) - -| 时间 | 内容 | -| :------------------------------- | ------- | -| 第一周 (2019/12/09-2019/12.15) | jdk || -| 第二周 (2019/12/16-2019/12.22) | jdk || -| 第三周 (2019/12/23-2019/12.29) | jdk || -| 第四周 (2019/12/30-2020/01/05) | jdk || -| 第五周 (2020/01/06-2020/01/12) | Spring || -| 第六周 (2020/01/13-2020/01/19) | Spring || -| 第七周 (2020/01/20-2020/01/26) | MyBatis || -| 第八周 (2020/01/27-2020/02/02) | MyBatis || - - - -### 二、作业 - -#### 1、源码学习笔记(必做) - -​ 至少提交2个类的源码分析笔记 - -#### 2、本周学习总结(可选) - -​ 学习总结直接在GitHub的issue上发布即可。 - -#### 3、review5名其他的学习笔记或学习总结 - -​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 - - - -###三、源码提交流程 -- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 -- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 -- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 -- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) -- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 - - - -ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file From d9c9dd3440b085305ab550ba65b123dd4c4fb2ef Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Fri, 13 Dec 2019 23:53:27 +0800 Subject: [PATCH 21/73] me. --- week_01/35/ArrayList-035.md | 77 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/week_01/35/ArrayList-035.md b/week_01/35/ArrayList-035.md index 0a64198..8612f66 100644 --- a/week_01/35/ArrayList-035.md +++ b/week_01/35/ArrayList-035.md @@ -1,45 +1,44 @@ -ArrayList -基于数组实现 -继承抽象类AbstractList -实现了List(接口->Collection、Iterable) -RandomAccess(随机访问) -Cloneable(可克隆) -Serializable(可序列化) +>ArrayList + 基于数组实现 + 继承抽象类AbstractList + 实现了List(接口->Collection、Iterable) + RandomAccess(随机访问) + Cloneable(可克隆) + Serializable(可序列化) -主要参数: -DEFAULT_CAPACITY(默认初始化大小) -EMPTY_ELEMENTDATA(指定list为空时使用的数组) -DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) -elementData(存放元素的数组) -size(数组大小) + 主要参数: + *DEFAULT_CAPACITY(默认初始化大小) + *EMPTY_ELEMENTDATA(指定list为空时使用的数组) + *DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) + *elementData(存放元素的数组) + *size(数组大小) -madCount(全局变量) -madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, -当进行next()、remove()、previous()、set()、add()等操作时, -如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。 + madCount(全局变量) + *madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用 + *当进行next()、remove()、previous()、set()、add()等操作时 + *如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常 -ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; -在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同, -不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException。 + ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; + 在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同; + 不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException. -1、三个构造方法 - 1)无参 - 初始大小10 - 2)int参数 - 大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException - 3)Collection参数 - 定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 - if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 - 不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. - 源码: - public static T[] copyOf(U[] original, int newLength, Class newType) { - @SuppressWarnings("unchecked") - T[] copy = ((Object)newType == (Object)Object[].class) - ? (T[]) new Object[newLength] - : (T[]) Array.newInstance(newType.getComponentType(), newLength); - System.arraycopy(original, 0, copy, 0, - Math.min(original.length, newLength)); - return copy; - } + 1、三个构造方法 + *1、无参 + >初始大小10 + *2、int参数 + >大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException + *3、Collection参数 + >定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 + >if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 + >不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. + >源码: + >public static T[] copyOf(U[] original, int newLength, Class newType) { + >> T[] copy = ((Object)newType == (Object)Object[].class) + >>>> ? (T[]) new Object[newLength] + >>>> : (T[]) Array.newInstance(newType.getComponentType(), newLength); + >> System.arraycopy(original, 0, copy, 0, + >>>> Math.min(original.length, newLength)); + >> return copy; + >} \ No newline at end of file From 26b393086d71aa422ccfb73d2cd2a10e239e06f7 Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Fri, 13 Dec 2019 23:55:56 +0800 Subject: [PATCH 22/73] me. --- week_01/35/ArrayList-035.md | 75 +++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/week_01/35/ArrayList-035.md b/week_01/35/ArrayList-035.md index 8612f66..2f7f5c2 100644 --- a/week_01/35/ArrayList-035.md +++ b/week_01/35/ArrayList-035.md @@ -1,44 +1,45 @@ >ArrayList - 基于数组实现 - 继承抽象类AbstractList - 实现了List(接口->Collection、Iterable) - RandomAccess(随机访问) - Cloneable(可克隆) - Serializable(可序列化) +>>基于数组实现 +>>继承抽象类AbstractList +>>实现了List(接口->Collection、Iterable) +>>RandomAccess(随机访问) +>>Cloneable(可克隆) +>>Serializable(可序列化) - 主要参数: - *DEFAULT_CAPACITY(默认初始化大小) - *EMPTY_ELEMENTDATA(指定list为空时使用的数组) - *DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) - *elementData(存放元素的数组) - *size(数组大小) +>>主要参数: +DEFAULT_CAPACITY(默认初始化大小) +*EMPTY_ELEMENTDATA(指定list为空时使用的数组) +*DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) +*elementData(存放元素的数组) +*size(数组大小) - madCount(全局变量) - *madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用 - *当进行next()、remove()、previous()、set()、add()等操作时 - *如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常 +madCount(全局变量) +madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, +当进行next()、remove()、previous()、set()、add()等操作时, +如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。 - ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; - 在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同; - 不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException. +ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; +在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同, +不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException。 - 1、三个构造方法 - *1、无参 - >初始大小10 - *2、int参数 - >大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException - *3、Collection参数 - >定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 - >if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 - >不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. - >源码: - >public static T[] copyOf(U[] original, int newLength, Class newType) { - >> T[] copy = ((Object)newType == (Object)Object[].class) - >>>> ? (T[]) new Object[newLength] - >>>> : (T[]) Array.newInstance(newType.getComponentType(), newLength); - >> System.arraycopy(original, 0, copy, 0, - >>>> Math.min(original.length, newLength)); - >> return copy; - >} +1、三个构造方法 + 1)无参 + 初始大小10 + 2)int参数 + 大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException + 3)Collection参数 + 定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 + if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 + 不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. + 源码: + public static T[] copyOf(U[] original, int newLength, Class newType) { + @SuppressWarnings("unchecked") + T[] copy = ((Object)newType == (Object)Object[].class) + ? (T[]) new Object[newLength] + : (T[]) Array.newInstance(newType.getComponentType(), newLength); + System.arraycopy(original, 0, copy, 0, + Math.min(original.length, newLength)); + return copy; + } \ No newline at end of file From ee227a177dcf29ff6f430d5360173e2f28e909b7 Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Sat, 14 Dec 2019 00:02:56 +0800 Subject: [PATCH 23/73] me. --- week_01/35/ArrayList-035.md | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/week_01/35/ArrayList-035.md b/week_01/35/ArrayList-035.md index 2f7f5c2..1f435c7 100644 --- a/week_01/35/ArrayList-035.md +++ b/week_01/35/ArrayList-035.md @@ -1,45 +1,45 @@ ->ArrayList ->>基于数组实现 ->>继承抽象类AbstractList ->>实现了List(接口->Collection、Iterable) ->>RandomAccess(随机访问) ->>Cloneable(可克隆) ->>Serializable(可序列化) + ArrayList + * 基于数组实现 + * 继承抽象类AbstractList + * -->List(接口->Collection、Iterable) + * -->RandomAccess(随机访问) + * -->Cloneable(可克隆) + * -->Serializable(可序列化) ->>主要参数: -DEFAULT_CAPACITY(默认初始化大小) -*EMPTY_ELEMENTDATA(指定list为空时使用的数组) -*DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) -*elementData(存放元素的数组) -*size(数组大小) + 主要参数: + * DEFAULT_CAPACITY(默认初始化大小) + * EMPTY_ELEMENTDATA(指定list为空时使用的数组) + * DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) + * elementData(存放元素的数组) + * size(数组大小) -madCount(全局变量) -madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, -当进行next()、remove()、previous()、set()、add()等操作时, -如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。 + madCount(全局变量): + * madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, + * 当进行next()、remove()、previous()、set()、add()等操作时, + * 如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。 -ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; -在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同, -不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException。 + ArrayList中就继承了AbstractList并在每个结构性改变的方法中让madCount变量自增1,并且实现了自己的迭代器; + 在next()方法中,判断了当前的modCount跟初始化Itr时的expectedModCount是否相同, + 不同则说明列表数据进行了结构性改变,此时就会抛出ConcurrentModificationException。 -1、三个构造方法 - 1)无参 - 初始大小10 - 2)int参数 - 大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException - 3)Collection参数 - 定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 - if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 - 不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. - 源码: - public static T[] copyOf(U[] original, int newLength, Class newType) { - @SuppressWarnings("unchecked") - T[] copy = ((Object)newType == (Object)Object[].class) - ? (T[]) new Object[newLength] - : (T[]) Array.newInstance(newType.getComponentType(), newLength); - System.arraycopy(original, 0, copy, 0, - Math.min(original.length, newLength)); - return copy; - } + 1、三个构造方法 + * 无参 + 初始大小10 + * int参数 + 大于0初始化传入值,新建数组对象;等于0等于空实例数组;否则抛出IllegalArgumentException + * Collection参数 + 定义为空集合时,初始化大小10;否则获取toArry的length进行初始化 + if (elementData.getClass() != Object[].class)->调用toArray方法返回的不一定是Object[]类型 + 不一致时,调用Arrays.copyof()定义了一个新的数组,将原数组的数据拷贝到了新的数组中去. + 源码: + public static T[] copyOf(U[] original, int newLength, Class newType) { + @SuppressWarnings("unchecked") + T[] copy = ((Object)newType == (Object)Object[].class) + ? (T[]) new Object[newLength] + : (T[]) Array.newInstance(newType.getComponentType(), newLength); + System.arraycopy(original, 0, copy, 0, + Math.min(original.length, newLength)); + return copy; + } \ No newline at end of file From 54808186b5eec9ee9e6d50490ca357af406ba0c5 Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Sat, 14 Dec 2019 00:09:11 +0800 Subject: [PATCH 24/73] me. --- week_01/35/HashMap-035.md | 230 +++++++++++++++++++------------------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/week_01/35/HashMap-035.md b/week_01/35/HashMap-035.md index 6211670..7b68b75 100644 --- a/week_01/35/HashMap-035.md +++ b/week_01/35/HashMap-035.md @@ -1,119 +1,119 @@ -继承AbstractMap -实现Map, Cloneable, Serializable -JDK版本 实现方式 节点数>=8 节点数<=6 -1.8以前 数组+单向链表 数组+单向链表 数组+单向链表 -1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 + 继承AbstractMap + >实现Map, Cloneable, Serializable + >JDK版本 实现方式 节点数>=8 节点数<=6 + >1.8以前 数组+单向链表 数组+单向链表 数组+单向链表 + >1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 -主要参数: -DEFAULT_INITIAL_CAPACITY(1 << 4 -> 初始容量大小) -MAXIMUM_CAPACITY(1 << 30 -> 容量极限大小) -DEFAULT_LOAD_FACTOR(负载因子默认大小) -TREEIFY_THRESHOLD(节点数大于8时会转为红黑树存储) -UNTREEIFY_THRESHOLD(节点数小于6时会转为单向链表存储) -MIN_TREEIFY_CAPACITY(红黑树最小长度为64) -Node(实现Map.Entry , 单向链表) - Node是Map.Entry接口的实现类,存储数据的Node数组容量是2次幂,每个Node本质都是一个单向链表 -TreeNode(extends LinkedHashMap.Entry , 红黑树) -size(HashMap大小,代表HashMap保存的键值对的大小) -modCount(被改变的次数) -threshold(下一次HashMap扩容的大小->put时根据oldCap和newCap比较确定下一次扩容大小) -loadFactor(存储负载因子的常量) - -1、hash的计算: -//将传入的参数key本身的hashCode与h无符号右移16位进行二进制异或运算得出一个新的hash值 -static final int hash(Object key) { - int h; - return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); -} -那为什么要这么做呢?直接通过key.hashCode()获取hash不得了吗? 为什么在右移16位后进行异或运算? - 与HashMap的table数组下计算标有关系 - //put函数代码块中 - tab[i = (n - 1) & hash]) - //get函数代码块中 - tab[(n - 1) & hash]) - 根据索引得到tab中节点数据,key.hashCode()>>>16经过^异或运算和经过&与运算后得到的二进制是一致的 - 当发生较大碰撞时也用树形存储降低了冲突。减少了系统的开销 -1.1、put方法 - 1、首先获取Node数组table对象和长度,若table为null或长度为0,则调用resize()扩容方法获取table最新对象,并通过此对象获取长度大小 - if ((tab = table) == null || (n = tab.length) == 0) - n = (tab = resize()).length; - 2、判定数组中指定索引下的节点是否为Null,若为Null则new出一个单向链表赋给table中索引下的这个节点 - if ((p = tab[i = (n - 1) & hash]) == null) - tab[i] = newNode(hash, key, value, null) - 3、若判定不为Null,我们的判断再做分支 - 3.1、首先对hash和key进行匹配,若判定成功直接赋予e - if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) - e = p; - 3.2、若匹配判定失败,则进行类型匹配是否为TreeNode 若判定成功则在红黑树中查找符合条件的节点并将其回传赋给e - else if (p instanceof TreeNode) - e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); - 3.3、若以上判定全部失败则进行最后操作,向单向链表中添加数据若单向链表的长度大于等于8, - 则将其转为红黑树保存,记录下一个节点,对e进行判定若成功则返回旧值 - for (int binCount = 0; ; ++binCount) { - if ((e = p.next) == null) { - p.next = newNode(hash, key, value, null); - if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st - treeifyBin(tab, hash); - break; + 主要参数: + * DEFAULT_INITIAL_CAPACITY(1 << 4 -> 初始容量大小) + * MAXIMUM_CAPACITY(1 << 30 -> 容量极限大小) + * DEFAULT_LOAD_FACTOR(负载因子默认大小) + * TREEIFY_THRESHOLD(节点数大于8时会转为红黑树存储) + * UNTREEIFY_THRESHOLD(节点数小于6时会转为单向链表存储) + * MIN_TREEIFY_CAPACITY(红黑树最小长度为64) + * Node(实现Map.Entry , 单向链表) + Node是Map.Entry接口的实现类,存储数据的Node数组容量是2次幂,每个Node本质都是一个单向链表 + * TreeNode(extends LinkedHashMap.Entry , 红黑树) + * size(HashMap大小,代表HashMap保存的键值对的大小) + * modCount(被改变的次数) + * threshold(下一次HashMap扩容的大小->put时根据oldCap和newCap比较确定下一次扩容大小) + * loadFactor(存储负载因子的常量) + + 1、hash的计算: + //将传入的参数key本身的hashCode与h无符号右移16位进行二进制异或运算得出一个新的hash值 + static final int hash(Object key) { + int h; + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + } + 那为什么要这么做呢?直接通过key.hashCode()获取hash不得了吗? 为什么在右移16位后进行异或运算? + 与HashMap的table数组下计算标有关系 + //put函数代码块中 + tab[i = (n - 1) & hash]) + //get函数代码块中 + tab[(n - 1) & hash]) + 根据索引得到tab中节点数据,key.hashCode()>>>16经过^异或运算和经过&与运算后得到的二进制是一致的 + 当发生较大碰撞时也用树形存储降低了冲突。减少了系统的开销 + 1.1、put方法 + 1、首先获取Node数组table对象和长度,若table为null或长度为0,则调用resize()扩容方法获取table最新对象,并通过此对象获取长度大小 + if ((tab = table) == null || (n = tab.length) == 0) + n = (tab = resize()).length; + 2、判定数组中指定索引下的节点是否为Null,若为Null则new出一个单向链表赋给table中索引下的这个节点 + if ((p = tab[i = (n - 1) & hash]) == null) + tab[i] = newNode(hash, key, value, null) + 3、若判定不为Null,我们的判断再做分支 + 3.1、首先对hash和key进行匹配,若判定成功直接赋予e + if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) + e = p; + 3.2、若匹配判定失败,则进行类型匹配是否为TreeNode 若判定成功则在红黑树中查找符合条件的节点并将其回传赋给e + else if (p instanceof TreeNode) + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + 3.3、若以上判定全部失败则进行最后操作,向单向链表中添加数据若单向链表的长度大于等于8, + 则将其转为红黑树保存,记录下一个节点,对e进行判定若成功则返回旧值 + for (int binCount = 0; ; ++binCount) { + if ((e = p.next) == null) { + p.next = newNode(hash, key, value, null); + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + treeifyBin(tab, hash); + break; + } + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + break; + p = e; } + 综合以上判断得出: + if (e != null) { // existing mapping for key + V oldValue = e.value; + if (!onlyIfAbsent || oldValue == null) + e.value = value; + afterNodeAccess(e); + return oldValue; + } + 4、最后判定数组大小需不需要扩容 + if (++size > threshold) + resize() + 1.2、get方法 + 1、判定三个条件 table不为Null & table的长度大于0 & table指定的索引值不为Null + if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) + 2、判定 匹配hash值 & 匹配key值 成功则返回该值 + if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) + return first + 3、若first节点的下一个节点不为Null + if ((e = first.next) != null) + 3.1、若first的类型为TreeNode红黑树,通过红黑树查找匹配值并返回查询值 + if (first instanceof TreeNode) + return ((TreeNode)first).getTreeNode(hash, key) + 3.2、若上面判定不成功则认为下一个节点为单向链表,通过循环匹配值 + do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) - break; - p = e; - } - 综合以上判断得出: - if (e != null) { // existing mapping for key - V oldValue = e.value; - if (!onlyIfAbsent || oldValue == null) - e.value = value; - afterNodeAccess(e); - return oldValue; - } - 4、最后判定数组大小需不需要扩容 - if (++size > threshold) - resize() -1.2、get方法 - 1、判定三个条件 table不为Null & table的长度大于0 & table指定的索引值不为Null - if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) - 2、判定 匹配hash值 & 匹配key值 成功则返回该值 - if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) - return first - 3、若first节点的下一个节点不为Null - if ((e = first.next) != null) - 3.1、若first的类型为TreeNode红黑树,通过红黑树查找匹配值并返回查询值 - if (first instanceof TreeNode) - return ((TreeNode)first).getTreeNode(hash, key) - 3.2、若上面判定不成功则认为下一个节点为单向链表,通过循环匹配值 - do { - if (e.hash == hash && - ((k = e.key) == key || (key != null && key.equals(k)))) - return e; - } while ((e = e.next) != null); - - -2、三个构造方法 -//指定容量大小 -public HashMap(int initialCapacity) { - this(initialCapacity, DEFAULT_LOAD_FACTOR); -} - //指定容量大小和负载因子大小 -public HashMap(int initialCapacity, float loadFactor) { - //指定的容量大小不可以小于0,否则将抛出IllegalArgumentException异常 - if (initialCapacity < 0) - throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); - //判定指定的容量大小是否大于HashMap的容量极限 - if (initialCapacity > MAXIMUM_CAPACITY) - initialCapacity = MAXIMUM_CAPACITY; - //指定的负载因子不可以小于0或为Null,若判定成立则抛出IllegalArgumentException异常 - if (loadFactor <= 0 || Float.isNaN(loadFactor)) - throw new IllegalArgumentException("Illegal load factor: " + loadFactor); - this.loadFactor = loadFactor; - //设置HashMap阈值,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 - this.threshold = tableSizeFor(initialCapacity); -} -//传入Map集合,将Map集合中元素Map.Entry全部添加进HashMap实例中 -public HashMap(Map m) { - this.loadFactor = DEFAULT_LOAD_FACTOR; - //此构造方法主要实现了Map.putAll() - putMapEntries(m, false); -} \ No newline at end of file + return e; + } while ((e = e.next) != null); + + + 2、三个构造方法 + //指定容量大小 + public HashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); + } + //指定容量大小和负载因子大小 + public HashMap(int initialCapacity, float loadFactor) { + //指定的容量大小不可以小于0,否则将抛出IllegalArgumentException异常 + if (initialCapacity < 0) + throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); + //判定指定的容量大小是否大于HashMap的容量极限 + if (initialCapacity > MAXIMUM_CAPACITY) + initialCapacity = MAXIMUM_CAPACITY; + //指定的负载因子不可以小于0或为Null,若判定成立则抛出IllegalArgumentException异常 + if (loadFactor <= 0 || Float.isNaN(loadFactor)) + throw new IllegalArgumentException("Illegal load factor: " + loadFactor); + this.loadFactor = loadFactor; + //设置HashMap阈值,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 + this.threshold = tableSizeFor(initialCapacity); + } + //传入Map集合,将Map集合中元素Map.Entry全部添加进HashMap实例中 + public HashMap(Map m) { + this.loadFactor = DEFAULT_LOAD_FACTOR; + //此构造方法主要实现了Map.putAll() + putMapEntries(m, false); + } \ No newline at end of file From 7230acda360ae09ed0c98bbf7741059a523130bb Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Sat, 14 Dec 2019 00:18:07 +0800 Subject: [PATCH 25/73] me. --- week_01/35/HashMap-035.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/week_01/35/HashMap-035.md b/week_01/35/HashMap-035.md index 7b68b75..5742c8d 100644 --- a/week_01/35/HashMap-035.md +++ b/week_01/35/HashMap-035.md @@ -1,8 +1,9 @@ + ~~HashMap~~ 继承AbstractMap >实现Map, Cloneable, Serializable >JDK版本 实现方式 节点数>=8 节点数<=6 >1.8以前 数组+单向链表 数组+单向链表 数组+单向链表 - >1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 + >1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 主要参数: * DEFAULT_INITIAL_CAPACITY(1 << 4 -> 初始容量大小) From 9258cf2398f56e78ec835f1a88e46f8a123dc0b8 Mon Sep 17 00:00:00 2001 From: Qylningque Date: Sat, 14 Dec 2019 01:24:21 +0800 Subject: [PATCH 26/73] =?UTF-8?q?060-week=2001=2001-ArrayList=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E5=8E=9F=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week_01/60/01_ArrayList/01-ArrayList.md | 278 ++++++++++++++++++ week_01/60/01_ArrayList/01-ArrayList.xmind | Bin 0 -> 207868 bytes ...3\347\263\273\347\261\273\345\233\276.png" | Bin 0 -> 13042 bytes week_01/60/ArrayList-060.png | Bin 66168 -> 0 bytes 4 files changed, 278 insertions(+) create mode 100644 week_01/60/01_ArrayList/01-ArrayList.md create mode 100644 week_01/60/01_ArrayList/01-ArrayList.xmind create mode 100644 "week_01/60/01_ArrayList/01-ArrayList\345\205\263\347\263\273\347\261\273\345\233\276.png" delete mode 100644 week_01/60/ArrayList-060.png diff --git a/week_01/60/01_ArrayList/01-ArrayList.md b/week_01/60/01_ArrayList/01-ArrayList.md new file mode 100644 index 0000000..a75d9ec --- /dev/null +++ b/week_01/60/01_ArrayList/01-ArrayList.md @@ -0,0 +1,278 @@ +[TOC] + +# 1.ArrayList底层原理 + +## 1.1 ArrayList的UML + +![01-ArrayList关系类图](01-ArrayList关系类图.png) + +```java +public class ArrayList extends AbstractList + implements List, RandomAccess, Cloneable, java.io.Serializable{...} +``` + +- 继承了AbstractList; +- 实现了List接口; +- 实现了RandomAccess接口,支持快速随机访问,通过下标序号进行快速访问; +- 实现了Cloneable接口,支持克隆; +- 实现了Serializable接口,支持序列化; + +## 1.2 ArrayList的数据结构 + +```java +/** + * Resizable-array implementation of the List interface. Implements + * all optional list operations, and permits all elements, including + * null. +``` + +​ 如上,通过ArrayList的源码文档可知,ArrayList是可动态调整容量的数组(`Resizable-array`),ArrayList实现了List的所有操作并允许包括null在内的所有元素(ArrayList中存放的是Object[]数组,意味着ArrayList可以存放任何继承自Object的对象)。 + +## 1.3 ArrayList中定义的常量、变量以及构造函数 + +```java + //序列版本号 + private static final long serialVersionUID = 8683452581122892189L; + + /** + * 默认初始化容量 + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * 用于空实例的共享空数组实例。 + */ + private static final Object[] EMPTY_ELEMENTDATA = {}; + + /** + * JDK 1.8中添加的,也是一个空数组,与EMPTY_ELEMENTDATA区分开来 + * (当调用无参构造方法时默认复制这个空数组) + */ + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + /** + * 保存添加到数组中的元素; + * elementData是一个动态数组; + * 通过public ArrayList(int initialCapacity){}构造函数时elementData=initialCapacity; + * 通过public ArrayList(){}构造函数时elementData=DEFAULT_CAPACITY=10; + */ + transient Object[] elementData; // 非私有以简化嵌套类访问 + + /** + * 数组中元素的大小 + * + * @serial + */ + private int size; + + /** + * 指定初始化容量大小的构造函数 + * + * @param initialCapacity 数组的初始化容量大小 + * @throws IllegalArgumentException 输入参数为负数时抛出异常 + */ + public ArrayList(int initialCapacity) { + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + + /** + * 无参构造函数构造,初始化容量为10 + */ + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + + /** + * 构造一个包含指定集合的元素的列表,其顺序由集合的迭代器返回 + * + * @param c 将其元素放入此列表的集合 + * @throws NullPointerException 传入集合参数为null时抛出异常 + */ + public ArrayList(Collection c) { + elementData = c.toArray(); + if ((size = elementData.length) != 0) { + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } + } +``` + +### 1.3.1 ArrayList的默认容量是多少? + +```java + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } +``` + +​ 通过ArrayList的无参构造函数可以看出,初始化时ArrayList的默认容量是一个空数组,相当于默认容量为0; + +注:JDK1.8之前默认容量是10. + +### 1.3.2 elementData为什么要用transient修饰? + +​ 首先说一下transient关键字:Java的serialization提供了一种持久化对象的机制,当持久化对象时,可能有一个特殊的对象数据成员,不想用serialization机制来保存,为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化时,transient型变量的值不包括在序列化的表示中,非transient型的变量是被包括进去的。(HashMap、ArrayList中都使用了transient关键字) + +- transient修饰的变量不能被序列化; + +- transient只作用于实现 Serializable 接口; + +- transient只能用来修饰普通成员变量字段; + +- 不管有没有 transient 修饰,静态变量都不能被序列化; + +​ ArrayList是可序列化的类,elementdata是ArrayList用来存储元素的成员,用transient关键字修饰elementdata,真的就意味着elementdata不能序列化了吗?而且这样反序列化后的ArrayList也会把原来存储的元素弄丢? + + 如果继续看ArrayList的源码,会发现ArrayList会调用自己实现的writeObject()和readObject()方法进行序列化和反序列化,之所以这样,是因为elementdata是一个缓存数组,通常会预留一些容量,等到容量不足时再扩容,这些预留的容量空间里没有实际存储元素。所以采用transient关键字保证elementdata不会被serialization提供的持久化机制保存(序列化),再加上ArrayList自己实现的序列化和反序列方法,这样就可以保证ArrayList序列化时只会序列化实际存储的那些元素,而不包含预留容量中空的存储空间,从而节省序列化反序列化的时间和空间。 + +参考:[ArrayList中elementData为什么被transient修饰?](https://blog.csdn.net/zero__007/article/details/52166306) + +### 1.3.3 DEFAULTCAPACITY_EMPTY_ELEMENTDATA和EMPTY_ELEMENTDATA的区别? + +//TODO + +### 1.3.4 ArrayList三种构造函数 + +1.无参构造函数:无参构造函数时,创建一个容量为0的数组; + +```java + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } +``` + +```java + ArrayList arrayList = new ArrayList(); +``` + +2.指定容量构造函数 + +```java + public ArrayList(int initialCapacity) { + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } +``` + +``` + ArrayList arrayList = new ArrayList(20); +``` + +- `initialCapacity > 0`时,ArrayList容量为给定的`initialCapacity`; +- `initialCapacity == 0` 时,ArrayList容量为`EMPTY_ELEMENTDATA = 0`; +- `initialCapacity < 0` 时,抛出异常:`"Illegal Capacity: "+ initialCapacity`; + +3.构造一个包含指定集合的元素的列表,按集合的迭代器返回元素的顺序排列。 + +```java +public ArrayList(Collection c) { + elementData = c.toArray(); + if ((size = elementData.length) != 0) { + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } + } +``` + +``` + ArrayList arrayList = new ArrayList(Arrays.asList(new String[]{"1","2","3"})); +``` + +1. 将传入集合`c`拷贝给`elementData`。 + +```java + elementData = c.toArray(); + | + ↓ + 根据toArray()进入Arrays查看该方法源码 + @Override + public Object[] toArray() { + return a.clone(); + } +``` + +​ 2. 对得到 `c` 拷贝后的`elementData`进行判断: + +​ 2.1传入集合为空时:指定ArrayList容量为`EMPTY_ELEMENTDATA = 0`; + +​ 2.2传入集合不为空时且类型与Object[]不相同时,进行一次`Arrays.copyOf()`,将源数组中的元素类型向上转型后将复制的新数组返回给elementData; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/week_01/60/01_ArrayList/01-ArrayList.xmind b/week_01/60/01_ArrayList/01-ArrayList.xmind new file mode 100644 index 0000000000000000000000000000000000000000..a429e4fec05e073b157f9584c631e2584bbaa40f GIT binary patch literal 207868 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�c??2gkX2+7VLU@_vEh2%?OFdP~~Btq(SGW zNF4Of{Zk%>1NQ60qtzW=+e@X+VySqW)djEY&X;dm>|T%Y&kU^zZDz)E=?AwckX;Ab*>9Rh_`Ecs>*nxmyC zPw)eZ0#)eBA_pOrIJ^Q?Z7tL4`Qh^`(w> zaIbX+mki4FyGM$+8$7n{*M_RmrYQmkibbO;kbRLM7Izc{AM{E(F!hJ>tJ60EuxleI z>-ehAF@$Ib>ghg*Wcfyk2v~pMvWaAxEzy7|3Ro<^qL`vO^%uX*^ix-*>R`hXqe$wA zym1^wQ{;5}`&lN#bow|30mLGB-;>H7zIY%z`pQH-v>9$P%FAF@w0+oKrtTNweX7(y z>H*N2)q+)ydp8k{R5>^*W1Vc!SEBVWCDtP4>}=7NA4JGyF2454 zc13IWr$39bh!se{h{!lM;MMZ49T#J=PbIJEosxz$W1M6j6(~qrrF1#g(gdbn*v0B& z8O<9RP~Tp*LlCG7K~roL3brtk9(@^ht(xz(zsp!r6yZ@qZ+?d>^q0peI| zOhFj}Y3$Bc#D$#4|K7PC%&RQ)DUyHqH*gtXJmok~KRs)u`lp}s^z$d#e>lW{Unj#p zRr3D*$bt6H;V91Iy5Hd-k3`Kwwg6Er;1XPTLSBC=z_=)p-DzZO+<9}p^Xl|&2=@U+ z1e8`Eds06<22os2zRcQpduZ_lZ7gsOV_QdE2Z37YwlHlsV59JMm(N))*vnzYB+Aah zf0`K82n3-8d5Tmcj0A=%5XVh?HOXDdSm|hln1~jk_eVb4{%}z;wB7hKfQaQO@DOBp z2=qVEt`LyPi@lPQG75WV-c|U{3ZXKY^%FcD4jJ@?zPNgS4XRJhd7jlKpD6^RVioGZ z6BOh@(I1H{+@pT9N%Ol<7c0c?&?R})1E93`)5_H=J-&p(!Nb@JswR@`9Lg>vq}%u8 zXJaqzyt;HN`6(q1v0PiJ9{mZ_vx5iIoG`X}0XO3Oih<=!G4;5+;C*$Olhdvc3AHo0 z;^jKaFi1+Zy~$1l(*YcZ3Mo_9_jZZJZzzCmD9{xAzyH=0Y9fog%d4wk0{Y$UUzg6T zP>67Ls8?jl5hrR~ko|4uEyI`h%6SzAUuc=b0K7@cqV=->sx^+MV0Gl~kDbsXPc$%! zhyz)bGmc+Alq0d+|B*rfRB7QJ<~ENp5@BaMgF)k>@7&bnPK&hLZ7JRj8Kk5b)8|@4 zNSI9BMLY&?x~+vIW+j2ILi{)bDirK@T!?0Uz_&oXLgHoo*GDdAbnS}nGj6z5WdBtr2SE7euYO=HJzQCj3r_{Xte*p?Urtdu zQ?sk-8#7QBbPgm6205!RW(XNlqdKkKc($t=E!664*)iD#bA^61K~I-}(D0E9{D@1o zkT26Fl_L-SmBZ$$3p6E8e17M61D(D63(V}0qiu@rNJkx&vsACBPY$2M5un&@IX`MH z+T~Jc-Ii5XFgE@T!V{t2s=ed@)$1?ISa0gkNs-eIH#C4lf&Ps!ulstbCY`gQqv0mu z%-DxK4n?>_CQY#}MH0$(#`bq%{B(h-dBkH!_%dik$l7Q|`IH>sib2p6F@fYyg0Y{x zsd5TAzyzKt{M%TfA8Rdn#NXnKE2=O0CUF7GNs3h1U>SM0&)3-5KA3nW-$;Ccozk2! zLi%mgjNyRKxr|U1VWaK+r>3wHrL zc`;4_)Y%z26RjfAzv;o7aD{N`w8RTMN5xUSN*1*5!T}fbZJSK|LE9aqRgX|jk>v_b zr66qUbW>zKcv?P!k30HQyNg4W1bPC4o=N^@ZYGW`sWn`eex;Qr-02_rWdk)W;$NZ{ ziMyS$?gO&DVKB<4)l4)Y_<&3g3+}R-YHpxExWlNOafOdYB4jZ2qi0+=SKe73>qUZ= zhBt0`awnWZ`Bp$#W1W)8+|yrWcnV;m`5R+m_gxn>{kWkp!_dpk(~X93RsuafFquQp?*UGbkD~Rdhk>bPFNkzu|1AWIe;gRw=hL5_W>EXp zldagi41ob%JmK@p`ku-;f(yc1JVg-r$KT}OdvZ^C+GPrKkDoxoo_ygCJHtRCXJCGS z3j+V&XJmmyCjUO8efsS27yf^JW-GRt;rhN<@Y79{{!y9?5GnyC2B0it@kmPhan#!Xt<0_cX%p8eY7yjvv02&phH~WKP!Q{q1d70U>ZQrTSs1J-sa1}dG zX^r`Y__HiOBEyI0wrR+RH%h%lBx8U_GU+LRowAFcP3@%p*b_aZ1*-qFPR315cK}yI z`@tUO4c&DF9NEwG0BYW>0)0sEI4Br-Dqq_nXDtJ)Dnr0L@?c@4PZRts&m3TJ0ICy! zKoKxn=Dv3j;MpP~L)vQbON@`^Q)-!SqTWMwo(mw%Y_fYth)n}hTQ4Auv3NbJ!{LVVleq#3 zPcxY2O0_VVt^r%k1WA+pa%{O=a)mT%6M#(QElh6)N&S5F`=1eYW~nfha;ghM*q>NF zHMLLJp0C<~IcA3A7;yr)OrV{%O+xqYS!)2Ai( zxgCcva^>I}GBS`quKUbfbwp%SdSl_LFbs)T9^>`2e-S*LWuFi>%4CI#aECVEqto%M zgfWK(e=$5pG3q3WH%JhKp!EbestEKb0wjsXQ;ZphHJs_fS+|mQ#l0-O7;M8-KWqFK zH~0ZAeFS-f#bwW9ink_Z8WIt;d0~GS3@nJ(W{laZjQzl;vQbO`Uqtr7Ek>hx5)ias zTu3BHQ^Bd-zlc7)+i2TD4g)Z?&1ZJSk)imm3YjB^gG+aI>(IcSRH~E znnRaLYcnBp4`D()7onr(SETtHE4ypya`E9EJKVj{Aj&iExc&FZe zjXv_Ocjr9<14?puLt+J>j1W0yxGR6V<9qUZiGf}qglI}E+P4gnF7O@iVDa$qJ%K!L z10b2x6u-pToLpdwSstisus8p?EX4)CfOH~qWZZZtJo4w;+jyumIT+GJh8qibrUD?C zvH-gLoHAd9^F2%z#mykh+0~82s-=($v~)sSIGy%4w#9g zmPhf3*BIy(sAK=SvDVvVF2#B!y!L^|-t!ih3|bM+yE!pyIZ>3Bh=IO%XPRJF9F%53)vFO0*87581Wm z{3NGhEfugmsJjUCPRcn@kK1{s=$a& zGZj@u=x5fLc9R8@9Jz}re>NO>=n>g+`;B84=dR0M3nkFH=!fak~62Q(q~>xT^$FzrG>+{$3wS8vyA`l=*HJE77AZ@o>-cu zw1!3;j05(OQYGDzn4tVln^k6v9xh{6`Cc}}hPoltW?GqWGI+ELrVaHoCs%>LBhy{a zXye!_Q>CU5y(vqUTHoujy2WlRQ#JSB^Fxla0dEb(FXi46Fd{OxZvt6qkvge#9oaQ+ zuU-b3M~~&wc|bF8#4OQXJ`9c=E?2BB6;z#*R?brKIS(@&{$cFA+ojliNJ0K-uh3gE z-08I{yTAiogB=ihf*?;JBUfZ2fy|C4<|4#TnLL2V9l=PDKKdV*nh)Tv=I>4$uO)4> zKDLg9RX-&Y04h5|W{n_8V{;@R5Q)q-ZWv(gSZ3UXQKw2=dE%~O76vjTncx83Xgok( zQhlwy6yS*W&KQ&27K7HmU(W%17Q0!Gbfc6_6g}v@T}7(JN4T*y7br(DA=`46%^z0Id{9IOP+nr|1Sc_}t3g7& za_KuFQ&1E^Z=C*iyDitZ_x)a{ zSI0djSW=U)rUVu-BE*Hb*Op>H1*$qK;Y$SZY~OBJYcLs$go#BD()TNv zFr5}1?3402Vi`14n3B9MYtYGpXC^^E*7nw&77MJxPc$o#QB_&HaT8Gfr*n&Hp7c`6 zT)BqAOe-1={W25HT}Z+AW)i~ILA7y)buqXZTPO7C z20r}fH^s(vjM>&_fkd9$qXu_}b?#x2)YeN*KrRuNO^&$GzyPfw9 z4bbwEmHexcD|$^hgB0OtQB0*LqUs`p~PcI`VbtPfz_uV))a8}bATwb}2l2G;7d`VhSzwVInF zr+OcSJt&rKL0guyyrOThz+VyH)AGH~&U+g`6dT_YrHj-UFJw?J`pRG5)Y8z(&|C@` z#~ku;)j6L$e~rTknUjamih%uaDVobmYEe=ak3&+{{DtmU-Cy9mAk zs?ok5BZ>V(Sw&8y(8g?`_7#BlQ59%vC-4mRDRo5c0%#SckOJlhwPeXSe40mWaO+j< zd;;D9v2J5@R#V*1%L8JkrSHd?*)fP?<8|(t>>mPn5e85Iyt;|e>lYSp*f(fM%bJDs$MR~oir6r50!dGe>r_fxoRk(`Nix=k2Ty7`NYCJO>DcP zO$dPn6raauK^3h;s!|!Mr4laJ>nS*gqk^!{Fhj3H*fG+Z`MQop8LDWR(QgsZ5w(sf z9W^(ycfWple-d?nw(NVkk=c@blMA3ZED)J+mHaXQ>_RwjDu)on&2%eZ^jG*j6xEY%BVB>8!j#TMOLeTydT$|DGgWfRr4`Pub1c|*@2vQNstkRd=*6oZ#)TW~S z*_k_|mN$9R^&!OgRY$~nu`I|e=->gl9uta4*RJc>L zGC2r&U!4>h;@?4J$^_ZURl@>w4f1c0DjHd0M=fl+<9Pc9dwB|aX4j~6UJbBCw@1Q8 zeKa=7I{8_ff{Z@+RvhQ;jnYL7F1{26#jh}xsnWD)^c=e&I6p&la#znwBPHjNpk)Lp zktM%*T$>}QL)SnZ$e4dwM?EfH?RKtWm~pHg%QLShizm&!s*&pnJhbKltcdt}%RaXD zYC_D@pr}jhBcMT-3DyOO7e_Z}Pg)BYg=m8&xu5A~co&SRRW7f{%Rt{!mnXjYeW=)$ zGo;3%5Bu<~N(2E*J>dr>Vq9|i@RC$Q$qy~Y%xK-UPjr$vuGea7u_=3ehWF!hu`+wd za%7FzQo{H}tNnPwuVN6!#mpgSeo-1Veo}`R!2?Jb8}GTf6XKPlCKZf?bg1-FGL=Na zu~fv0k3Qc_iCK@TOevT^K6jFmBia0?kCSm#GyL=XXmW8I&LuJTbySp2f2=l;}6wQXL;vU4w7aT@&a69pYX3&u4A;5$Gi7ChPVlcO9Py);|jV8K8))O=^C8ea)jZ zL)1LWBRlABtr(z(m?NFrZYwxlPMg&24(nBp4v-i=>g2f1gTt(MALz`@sv(R|HK0%b z^cT3SOn18v7OifTJLhFC+nWG1RAR&vCnsVJ>3+fP_;1;DjdNAg4N{B}wWeXFhSm}@ zPmx}~TJK~2S}sfSP!W0d-varRqgFF)G_nS1ouAoZ0nP&uxZRgDGY+gQOKzDpMnO1{8UKD0j`aW!|=hPzu8v(7MZOQYXPU6MR%Mq|`i}dQ#P)`hRZu z$I0A&2pGh@mVj-`2jNsef2!}d&qG2J>%49+CMCYjT=t;&!R0#&s0U1tL{V5r>vKNo zJv_sEs+}}JbYEncb_Z2^Dg5N+D%aI@1C_|Hr z2RuUu*MU9%6bbxZ<9sK9@-X$LJQcK_{U`S)|8c%?(T1PRYBp!s5hKThY5NJHs4{tz zuXr4fcW^6Z2pEcjXUjotYHCQ+1V&T*>|uStqT5Fz)XOKnu(^+!C z862zmBH(t|-p0x!B-h_&xg7S^fT|g-)m@QcP3^068^c;9*mLZjJ$|%Di(y;-S_*LC z0U?~W9pF4D;37qTESwoMDA7V#rx*6a7!x^?24oYy<}U$$webAt8cUQZp3`>@*Nc|O zig76k@mz~9c8QFuzby>d0Szn6%CDZZTt=S)2gvt%lJej-EnhpBtAS$vX5SwQUY#~J z0=2$tIR=U$xb#?qB*9W8kA}B^1spuFQ}tJ2XkHNS5#3Dt@5l-R&{M_KhE*+hDDX?F zcJ242JXGiJ$z}ggtT$&s3OF%v9QXPVXZikB+@pYtqG$143}g_HUfN412u;@2@cA2G z+T5Wn@%XC$DgW6D=Nq7WO0{Mo`C?~)nHfIAnw~mILzB`v{BybYy;8_(Zp2xuM)0_Z z{w0Qo#oqyz59_i6ww*{Xf>aHJ$7!ML5S&36KC-E1UQqPq@Mud6$V81 z{Rn3&`uk=4DC*>)_f77*{YziIMb;>L9z;PT!RROQAAlH8uT-i(gLB(Lsmp5>xSc_ufh6$t|y!nOiywd;e>EDgx{ zQO?Xbj?FH0M!)%L7*On%qJ64WpFUMi6>`6YZ!|qW7AthG9MVbr!l;jN;xu7`P;jQ_ z;|nD8O0esko`cKJpNz5I)X>~@Zca|b@N_J4Y#IJ{PuSCzB`C&X$T>YR&brZJ`+anr zc}?yOpTHy;9mc5gSc_6_n3EV*mvO3t!_f-1mR7>+BH04+npZsMa8B0Tx{@x0Q!yXJ zwN>9}?-fqG&6@xXFA}+jUlm869y#DlmHaLYnicoT%u2;j6hdi`R?3&qy6#@=As}f3 zgiUG#vP6sRYY|SJqJF(;mu_K&LzBDC7`0x$6G!&Bb5l7U)I9NOgq&lOe4}r6L)-75_$%a(A z#QGVvh}=+o7Gs4+jqJrrI_3B_-~JLehr&gcqqJMC^<;}GOknmN9Ff~aB{~%BJ9p8- zS#?iC@s5u9BCWI5XT071=UT7_#+}o^QCZWAB9Qt574EZv(I;vNJA%NI`jC$&ps52? zBePJ41{Tf+av$_A!iRgQUCKM)!QYQk8cjq_=*yGnwHXQj@5U4 z(LU_Hvp?#7QW&u2NYf7Ao352eQGu<`xV>gg0b9#)YcXz4-%BC`x6_?*kn|@uxpCs{ zkx?2|NN<^O@=tpcImoNier4Ic{)G+;!`#u2W>W3L0tISf8D{On+qM;y?J_w8&))~V ztt1m=`eqme*X8#23)b)ogDP8NZ~QUC03XX;W>Br%WH$D6jPxs!G~mpL`* zN)RAIM9}b}$WLS2<^QOCfW2-8fPEYD1wL_^c-IxM_~KhKj<8QYoMPrsMy9BS{BFM0|o_OpJ*q);Zi{I39D{llCKk ziYx-o1WFdo1rNs;>JLJeoclwu*STNft1gh{w3FhoRkCCE`yjqZ$CWRIM^$%E+IPcq zN2R9vnww=@|4yIv>*7n@frwgDgWANJ-EBK$2=_v@Tm#|Y-_~jlv^_g%PeMMt3Wf!59&>z=rwBmfX!i zy$^?NEU>jrDvb$x?m9KBNT_Ro? zs2k4dpA!C!d~9yUz7!s`w^z_OmJKe{R@>bq4E%XTR&HdV=pEkw65jg2cJ*^Am6^hl z_#t)yQj$v+p-|`#$NI^a1@4yd4$r$b0&>=l(d`{A1Wk@hiJ6r3+yT>KS3Ld5QiHZA#1H;t_?X9xb^qVmZC50P`;0Wyg|-EAi` z#0x3TuN-9)lh_EqBW1q(;E*V8ZpzF2h5?_O?HT>rEqCNw7{Rbjn}{=UN+#;LPt$8T zaPpjZ2{lt6J{v{~p2(em^ZW@3o1a;|#PHwYPzOQZyuc4&p{)rBo&|P%K^61BRCHaL z$afu)Vc|Q4Wy&kh*|Sm8WolF;_X`>#L-bEi^u?|9 zR$+mqdN;22mY6BjiY^pipq$fEY)|?{FLkelB%o|}WX&b#-+D=A=^`b^cPGGW%I}fW z3-Bw|OIP4qETkpF;8nRp86>waV$+fYkm4 zyqaKhpZkzod$THUGw)MNX#Zt~J^S;N(Cz17eOE0NF3 zN{;0M*lDL}k)JcB9L-k~WK;nfQlE+$Q(EPYb-S466wbA-9M^A<3j#zo2K#44Wyw)VP}`y?OI}&H`mqpzOHWA~I;cz-6+b z%_|fC1&GpO^ffpem6j%c(p~-Cl&Yb*MUTT5tEIS6X_98E_~Z^Y=CfE&1#jB|m?^>z zFZ;`_&*iEMy3q5t4Yeh3P&VH;MRVecNJUk-MS5^F`{8}21Ksy{?JjYdsy(s9yRy*v z4hwD?r_wUk8qNCnxbI^9t79*3BWTq}XyeM}R+^biHlc1?!)1J`0#bI)N#4$amE?mCx9Ds>jZi`zwOUB?qmQ|?`BwZ>sB4)ah zvF|l5s{4*nt#Uh`AWKKGZ*x+r?eDCfk?I@Vs+O=)jCPy$vtyPfAIVt>=qu$ChDJId zrBYg~Sf|G&wY>o823M0<4GA4IXq+=k_D`g3U9Tt66*LeGYiQ$BiCA|d*TI03gy9N> z5uiKf1vRWam;Kw4>AiEoir3=W1&0KZjQPO@yT0)nM3us|zptUsO0JHDYhBiHs?*yC z2)xhC1mq!sF50YVPVicK<{qC?u~sn4DO%PO4*CpgV7u8sx zNxATCx<|uM07mUcM(Z#m2sb9^Ompfzt0QjqEl<{^RaRl6f>=Q|II@$MuuiWe0-?nJ^U&>I;Z!=kdnHPfRZh2Mfm zP}=i^l9ilDc+h~YFE=@=2l+g)kspDJfx48JvumKrd#c4#;*Yg%#&Ke%Je>AyWls5M z&L^$e9g!&2W*OF`rgsS%)fXdwsXK~IP1y?9u_1V#wOB7en?yzRxkUAi8}}c$_+xi^ zL>p62Kc^nkcVd6@QB`M0g_w%%A?97hrXoQ4r!fGNVi9N^hW{7_`P$?9+XakOe@iqi zPh=ErxDm$6Vx>VH_iG za}+J)Tcv%a=L=XQ7l36h!|-Iyx2}QvoT`mwb}6fR%rmhmz4dLGxM)GF*t4%&C`DBjPoqIDaS^o# zMj1A}OYgi#eW)VR`+w0w*>txYi}LT^FUp}kjR4~yjgfTPPF1>zdQABFhH~W&#|%$# zaQKeUhXb4*bM=y72u*w=Ixq|%5%15sr@uorxXp0Utrmp)W zmg+AH0@2g@Qfl1K-==rJ1lH1~**!3$K*OwIdnq=`XaUQ{gC_D3m(x%Q3Qpc7I zS2m>^U*xbbmRk+tLgKDTr;EA*nA4bhyfA-}_RRZRJuIva>L#z%yjk^2v2kyio7=uo zUy(rRZ2(G(vTU-4^i2T$=oL;FweivFqKq#OVP9sIWgZqdi2$Nth+}0yeNS_&Xc+H& zS3MDM3Ii?~-#rHjaDR2bXuW4-L@7gX0&J$4*s}x@b`#nLc)uMEI?v*2ns^SX5^v5j z)FX!0tcMf@q?3vTrmR+IyL1tSRcLgKJ{sKw&k`f%2)NZ0q?S8MC+D+Oosy=+M*h`%E57+NhwaO6=&nss3}-gzT- ze8~a>mO`iPatvyf;}`MW&iFhBoFcA&YGn~Fj^vA4MPfBU-87%)Fq=(3a>^VaiXr|j0T0Qkfw*S4$K?B5A{FS~EG{XZ&Wu)s+KtRG5cdEr>83ue6B@^9R0^U_y zHDCYABM>vbM465Sw(8EkTP_M*auJUQwT{;6N9b~sSj1lhPENduv{Vn|7PaX+_AKtG zW@0>Fx45e^4hx-P-kpw?CYYVyD4ES~Z!rW9R;2NzBqX35Sb75k3sJ&{g;tS$`Aex5 zoBj61{DNrfz*QX0 zj>DuHI_p!G#<%79?Q%E%Kki?yC>m0qX=6}JZ4)~`SV-hOpT*bH_LKZW)~he?AC{FK zan)jB+~oTE9;XTK9S*%?IZWv7W`6$eQt)iKQT8(M{zH1duVpB11R}bAJDdGk0a-IZ52)wXOTUjTgMgBflpDPFDo? z);-LQOMltydkkvnJ6Ps8BsE0c+W!zgy%b3WAY84(RktreE^{!G;whZZv?F;P>TD&A zJL+e4#0-MZ6qeqNm9Nz=4SAL5R@c=`x*L@(`}CQusI{=Y1|O#`OfOXZnjLz+y9syx z{q=}9b6VJ1j8pcY-OjwLA{zkD{B-tkcRLQNfQq;gmI zjR*h?26;Ha{h44wcS#D#)mb4A_=~;-pLeT9*0k$JbzS9I@rPZ_-I=Hm1V^WiKoXZq zujw?`pMOgWf633cn4?h32nPXCa#<=WfMxzPnl*Fa>f@Nzyp5xmz|Zc}%~fc#8QRuW z4VyN6u`3RRl)Ux*NXuENUODR+*A72lnAy;K9fPSS2hmu^(CZ_zmgYnung04J#rwd{}E zfI00JwkGJ~MR`sG-o;&B_SLS+5Fr5Xr3)PM{_K;(BRm1rBEPjWRU2RVK zlTFuYw-ccUzD&hLR~rlE1L8Y&^F!e;rzZpINL|Z7rKt-m50?4YrW8(DULsgJZP(+t zqu!b`2`mEKjP2pD>Sq=zJBwPI)Z#m7_GGc%e+va}hq9H5To!eIPN$oO*W%Fv z9MJ*-8M8;z(bYT~vwBWBX{Zc~gS?mEo4BYE1*?a3WcxU8VlKWMtgf483k^N*v(otg zoNd+WlJLd4yVdTWEi|&5HStg|_Ih(C2{g%9uFrj|{+TQ|ZD>Ho{jqpfKAwP&`+n{B zVOMe@70JW=DUv>bf06K-ob8rYyvP}NJ-L{f?NhWlntaU91$=%>T-zbbYmP`W>)frV z*ool`+GZ6M68R*hG&ogWS0*ZW;7C}mL;@on+sAKl_n;+-`u1V`6k33}Tu2{c<9czT z?t7)}v6p6P>*Zc@0G#<-b+F;wzO##lvu4k@#viiH**s_11LkLAxfdg^AV|)n-t;~0 zZaZY%O!jpK9x)&gI1l;RBu(<~FR8q9f3os`*??5~&YAj;Ne7?lx|PNV*VR8HGBgaD zBQ|$aOk~ian+oFp>Lf@n+PN7zMap73<^k<$8x7XT}e+LwbR4=Lg!Z zh8wYG!uH2CF3R)`!g+)Vfl&tDe$t)>yE^4k6MQlHMuL<;=OfioojT5E(qVm{Dwz` zOw}m677%xw1MQ+e1P?O?OPba^cW(OjTMlne2R7p1z3Ix%p#rk`$;u~ob~47^CB4C> zrTnD}pLVVN!zJ*t7FLPI%hd4Em7zhvW_(U_Tll>HKrRxG^9M&5b|jb&cV@aR$w;!B z$=#rq$WVCeHTb#}v#t;Y^%^tIwW4IFZ)1|rljazV4RS@yhvNey_GILF)eI48TZa|4 z)Ga~)Gyl~6Fe1-duxHeOj!@944#&u0*{kwSX@o*`A?}p1^x!>`*^PVe&beMIj$!k? z9>}^&q4UQ6JoL^cr~FQo(T7ac?LFYATkRLQG%m9LR^*S=)4kEtn=&yZr25i2tY4(| zC4X(S2vd(+uJXI(WocvKzUHnZJJRH9@GlQgd05G4ZXe}xb~-$08S6ooE+Fb*^<4m= z=nr7McU4c7;hzwqBoFaHfD^<5eLHx5E_$v`5BT?2%wMMh`SI0WyeE_gv}8mb#aOgh zQtKpJ?Z(RLvvC829=Dq$i{3|j7YAni=?N`du6trxZ;G+=BtOIySCMMM_lkX8pD#L5 zsU8nn!I%zv9>W?}$YBo){nizCR4b*PS~CfE#6_ZrJQGt5HuzfyH)R=}o}Xm(_K|~@_(0%-m>8|GD<6Q6 z0}%hg4|`VL9+;!>j8?X~?ri;_$)%-1zXRZvUd}A5(1L^6#Bm|@OB!8K~ zuZ-1)QM|8J7l>@MXCsC>&jnO`fgS5L5>$tr$26PjqcVE=4wokL=h*H*55!Q09*raj zeU&*R-<--u`Nm~jqh5^wOM5X_=`$CNK$ILZ^ecH>yKp|W?iIAMu3<^jDAD=Fvrq3H zR}?44Of!K7tUKc~fmOrejX^HOvb1WS+mH(S7T$Oe#CCpNEZt>>$v}-d`8Sm7?)>EH z_KK&@HW4HJ?Rjg-$qBoziynJUES1~eb3~A|+m}@S9Ry2>A`P^6ufbMtraFth&CsAM z#3HZoY>TYxR7q;p+sSKe^5oUlRQ&qc_-v!HGq)76mSN1e@pZ@%5AVzi z<_{=0WH34*LD%Mldq}76?tCasS-&i*8goAw{9D0?E&s$!z2w|Gv3G-`!>PP?Y1$ zMBWL64Xrvz3FVEvL>j5V;IMsHR*3c5YPvyGZ-bnG4k|Mg)|QUn!VRW9pCyD`?(hL_ zNA%$t*s#^?U41z)JpLDZZygrp+Vu@%A|e=wC@Cc(-O?xu(gM;A(p^KBf{K*1G)VW* z9g@-#Ll11FhZ#Up`a7?|`@Wz1dB692@9#a1{ogakp1s|dbM|?z^;^HS)_G~F-Dvvc ze$dP@&==1=_e@GJOnAqi*(HaeDTB3Of6vBp_{P#btHBk+^e@2+1$p!^-2r%hs1D0O z=zXh#;MhWDPT6zR1m1nRe_Y+-5^&P_VfJ8@`8B$`-7`w zSNxFkALhuBx1NK;9}1nQoLf~x!YNceLcy;eqkK*We&ssOy4j3o++&bVp0%V%R*G4` zYE`~92gl|EH=1SpGciV3OY&yxLs`r1`j(=N1Ww@qPE7u73RKUUHlfCZBHsLb5B2Vo zE*hS#)~lU}OR=HWmKqk3Gr&DuNd+y${lM(vU2l7#FXgOf@Qs;fwjg^q;2O?5prYNYOTM0 zO}QzooFO6?Z}quk%`~!Hc-=q9GHJB6J@tJ&7TK8)>>%BwX@zr(Krgf?pkBZUybclI zV86It;>xv^z(;s6;c%w1L&~`#fDtr<_a5N$(owFC1{(s6e3Y1`=s}}w+pyZ|_)UO7 z1TR9h25K;91-=w-AXQ0WZEwv3+gu*mSx>Ml&^unSU8(T!u0;R-T{F@U zopY#M7Ewt#7VN$A`5|v?iBcU(@UI!4WQ%?tupygOpMibZ+|T2De7H7X0@N+2VnSx@ zWc4`g$STgw)n!a_;2Dw%!Nzl{IM1PI^%XLK6gvn1nBBEqU~l8VGa=amCo*pPjWo!PzJ@1`M;D!*q8Dv?;~7$==qoGaWz4?HP~W3aCnL^n&cM25dER zz#iN4^e(`=UYOtgn(7Fp;L~IC`_V&?QuXq8V69BvjLmAnoV{~0QTvR-_;c9K$0VUz zxO?3i5~>4h`@qYBvsq!@4zB?*okh9byAQP1{&e-3rIB$wxV&Cw^0U94lBj*L3|K!` zPe(I1Se<-$m1i5laK<|zDGq`?v4@q*buB21;BBEhP=UY~Ai_5T6n@-$7g|hMN6*_) zkNAChp$8vXss~LKNVJMurZ|#o)%Vt*YGSa}oN!*JLTe?40n9$%QX3JlprvE$z3e#G zUXj^P^fr7~a(w{k+qa$1N-jYddvx{(khv{~O24bt?m%;U3>iD{zV=}?z=UzSuW08B zYyb$_RzFKq8kpaSyLfub+-E!MK>-PFVo(FaN8}3)H9=DT&9;j5%XcC|%0V5z*6*N= zV$EdFgxuOMX=Ec}Vg5_H80oRSb3r6K;o;pgi;e~pF%zhHa*gLAl&&H_IZSNEa zbM!e31RCP6U7Hdm_=8x(u>-t5aP$7cCiZQx^EZ*Yz+EKi+$ zQOHxbWcWhU_Oyks&cSP4Q~@Kh+jIfHYc~)jo$M(n;(~d1ig{0R{kHd))v)&r0tJ?g zOFxgY#cTFC!n}OQ%d>;5Wq~b?o*(RO#U-c&vdOm)NcQG_*7MM9NkZ))#e z6NX#X%Xqut!o0OOj7=6k$oX8l$`o+nG9EhSfn;7EPdwv0BYSJ-<*8yA)#2<6Td0E0 zsYt?>V7~Y;GxID8*zjU?+lk)vzl?fJ$|~IJ3d`baXdU#zmK3hJqdja#r9JxOeq7*! zW}%q|egXcLc&oOHew{i#gz7;=b5SF8i68@fxXmJSj<_hMT1=EqRoTE)D8xh>sl{|j z0J7BfyTVJDmb4xp=Vt?E2Esj)#z5%2rkn}M5uG_WEQqUiw1=1z_>|GC=cqKM^wfGB z2(b9t6R$Z8*p>RLP{Yd6TLN;s%9@{;CG>S@yBzXfk#lPj*jwz&b5z(rP(Umaq(zlh z^G=t>^8_+R)cWM!kj=SnS>7VAsqL+Zc}s1;MDVbPG81-Hx`jSD$csYwg5W-dy^}a; ze4f;B#s|5(?ge=J=LrIL?C+(A*H-ZYfeC0405~(|e$V3Gi2%5YiP@@ua5YA^ZVzCK zQnGWX6L1{bZm~Tdqqk+duDQPQuA;~k?ZzO4TrOL)*lbJ%lA%qW()zUOE*QojH5i3B z-bx7R{B7N!>x^1?bS@P;h}nD|Z3|yz%VEi zXUF?dp|@?`wh-KqhC(LBKLR<2mUSSc%NCU;pF629mHzrUQ5etowa6__@q_tW;B5@r zW6Ph^bwHl0@dDq%t=u_rONRN!JYyI5VSKu8?}OL)(hThgZ&Qs&M|4Z1= zg=D=i+e8>PE30)nL!qj-%hDgFYk{0Q0{#821f&>@PVyN8p`ePY1t;zPO^2tv^mKNV zX;A{zuSnfcwWexlB9sr5NzyzHFiLNgo8XN57| zb0UVd>skJaFc>#^?3Z+;E-c4vs!R0y9xUdisM({BBiiH!k}GK*Yh0Zl6?jK3!4{PR zGFJPplf>9wnxuEO&77NCqCth}#oj5*7O1e?B*}K*@@UZd7OYvd^VVXuxfN(W92he| zYl2~{4;=2LJ+fU3UY}nojP3}kC0X9r)>hD0%O~ZE@(bXiQzdNa{T0U=b8YvUV5=c8 z_-xR5Frob4-up>T=WS3-#R=8!p86+jirWmn;Pq6Wy&VFN`U0kLIo9t`vTBZPhwFI( z#8D@jFi{l!8MMm|9f7%JWg2QX;ICHhu#~(DZ{dJlFW^gU6UQQR=daZ;5D zeSl1^A(7WNReASIbwG@?LUUYJ520E_b8Yil-A(frHS>%D>PTkY#0>Kb6%z8^n9ud% zc<3()Him+^>Gk~vBFxVF>W_U`Z4K#~Bmk1cK0l3*y#ElHj+p-Vy^;s{ z>X!Thydpw8&oB4;m2*1xccRBC+Cgmx?&w?wr_IjGn@bG!THpF7lokA~Au=mBD2)#= z#lE``{G+x|)Wt1-U)!@f`STo%o{dmlnP`%yX1@d|oJLYSk5>ilXI`~y0J!?UV|-T9 zitX>f1@zUE>H&9g(NrGDdR#7cS_9NJQRPrZ3844IZSR38#6Zxab=dO0qo{CAx|-^TLlBbMqddYCEYQJ>u{#Wf~Gs9oehgwhnul;jgwu$ zlf&&2Z+n5+qd!FpvAiL9bzleNL3fXxER~3ib$(9zVNFF+^Ji>N~@WV#k294Quqi-vBFa zL{6=OnN)C6A5%I|aT!in|6P=DXg+-~$nNv}g>)QpIw>KX5=v_ClZ0A9?Y$?`Blbqk zG&E4^s|}4ACCPtQo%BN@%Zp(S_dH%%iIAx_m4k9XRA)#6>?0P59kW2@*qZRcfgifV z1j$l92JIineB&&<#twW?wPUq>Wb(zmr8Rv(Ro(W!+Vsqe8MMib3r%m%FkqtE*)mAY z(=edXjZUvovh=LznwlRiVY6AISq0GzX-?h4pv8fuP5}249HBh=XCEQ^afBAQemr&+ z_=cVeiZmDfRmic5pdRi%T5z?g9k5m2FNmHb-pLuys}bY_7;p0hu>E|keX%9e&x8@r zpOPCF&Bhm2>6Q;=3UjQ(f_yh9)YLQ?!&;zg(pgH_g-tm5bD7%E}$)saj zoFE3~N2v&;BHqZ-|5`_mX07|O(E(Ho5Oxb1TfuE?1&c0RDPi;jfE)*YKJ}lOFAs0Yw$HjU52EF-U?=!D@Qk4W_yYckjsz6o zrhj%y^lX0_nz9z{>YvYkWz#hEStEqZYZQ4yss8||k;6MnV5U2U)wB>`KjB<_3T>;S ztH$gF#$luNb>MY$q_zx?2G%Q1S8aTDt$uL^EyK9qa@6G6RN$Pv5ax0D3eDN^B=%*K zYLHdYtOZN};Q5p__9o1%@Y`>a)fT3dRt|Ty?CnSQLTKQ7`45Tra#td5i`P7`ZfCa5-3}_b6l?M^SL1C-9JtThk&t`nkag(=>DX zuwe8I3kD!G=^8cQyKU3F>I36pCHQ%n$_mvVvWp3s>C$D_xSuF-uyaZ}wR4sa;b*=p z(o|PF$b=gd1}I%hp`M92&t7MLcsKk3EbS7k7V!!)46!yd4qqJl?QFe0djpKE;Ibqe z#iYxR2DoNWn?;9vFKt*E!^dMr;(`g@&+aWcJT<`gF}~66Bd2rfZLkA#?Hjw?ruvl5 zNMG&hN}it%Pu(ra7S%hW-iR2a`T2b58TyPj71sFp(voc4D&2h%k;jOL^30#>(oQ+# z6{Oks4Efybe|^rpoOCXex)M-u{+D+uoabGDop=emu6<`LfI&agq~k$!TNt%04_RR+ zY@#Gd!^Xt+vUt1kC7pd>_ zat_Tdu)*^ib1EMcI$eZ4mCb$tTaa!>MOZkf>4?&hm)B?B>glTR(*+c?l!Maafm$YX z6cNk^4+m$G7+QYzKLipr?`PenvO}sSf|9Q}=)j2!Mtu%jM*9lL2U*`OvvV1a66zcs ze@?mpRs({~Lj$y@v$zm)-X1=l=tXxs4@mgmE+i#gxljiHYU|{q_2!~oS%I`S1NQ7c z9@d6eA!56~YZ%q52!Dtw3Vgpyh$iRpo|HQhi7A39<^o-$--Fdi?v7(N=n2szR)J%U}YwoL@9U%$thg(8#`#Nm zhB>Bb1$ab<>1;MHY+Brm`_#PSG13(n)WhS|pMIAKEyNI)32vA1wZ=+QvkXpA(S4Xu zo8(yZc9I)QqY#NrLb$8jcX!)q>$f2V!s~4kymmbpft_dDALBIb3-TKe`pCxv@5PD0 znL5-h#+-tMGwVdgn_tzauj7*R2BsB> z|Kq&ccp&C+G8tcP(vFIS3W`HHr@rv9WEB(I_BI<-(L7+=JcuQXVYJX zRg_lJ%e`jc%^3KaH!SH2LSrYDDw1wrx=LhRO(8FTMY7y2b$0@GusGtVdiB=Ma~Pc~ zaH9%inN7EaIW9niq?@^Itnzg#b19aSHWtEAq$nTPC zxghrP<^^ZC!{Ccr!8S0 zQj|b^opYs+ut``5lH(dJ-&@sj#Q8?ns$ZquF*aP>{*r1)5|b&1(p&}l9fjreZ_tuK zOg&B%3-c_Xy}eVIJ#?MNEi1hfTE%y>2oIegyE35tdt9iT^apQpDn% zd^fo0_(i>tSp(l%qtwab)3vwiNtmUwQ3RnSm(J1}(1_!W*b;-F1o1UC%7;hK+&^qI za9AAMr!1)^_#ll7O;JK^!1a(nb6yzy-bxRWUTEz;snx57XT+9Q)F+DM(&X9I8Wq-= z1O>O?M4m5TvT$$&us?k%C$p-wrz#-g&5BC*Uq>e*rZ6=sHa688%BPACOTonWUVwI| zpyJWfJbrVXugjU@hphEu{uctQc#MQAdmQtRlxSRXvQN@M@N$!jR*gF@0w8{UL1 zJNJRd8Mw1X6U&QI4@cIQ*0inqOP=nIvkF!^R)tqk8C8WBo<6*djsJ$QYcpX)mk0xCSdfBSBwkVCL+t30`c%4jV0 z5YMv4uZsyP7lJL96q3S!3dnZ(-YS#+_g*A3WDQO^^zR8fWv3~LSH;1CpP01n*z+9} z)XmV^K};}Y7Bt_9g&@du=>@`@X~3HaxU~}yC$@O~ZQYP*D}gck^-t)3^rm3UIuFUpz4s3pKnPwfwCDff}H$cANJa`oOY2^B{Lrpaj|Q6 z8A|e4#zbX(w9XId$u?X6l32RLZ^rwuezk&rmqlNIw(devhz!fhm?fc&=U7`G(-iSR zu}yK!wRc?3S9W700Z?6^Xbl8NaX_bTu*HVXTWAa@%R8|97xV9}a_AZ9Y{kyinCn%z zQbHaD0$d+3G2xbzjne8Z~@Y+RXIA(vrYHwR?1?O_Z_Ue~GN z%5zyyBc-+J3t;&1798Ir9ykp@_dsO%3rQ0_=rWHM@fhCezS$*JXKuuMJlIeKKWX6D z>*ryQo4#`AinlZn z*rxy@-z;;;#e?JAMjnI3wz@P&bn%Dp8cizNKZDIY{cmMyvR7da58q;xaeb1;HXc(+ zCeks8Y%-077dq%Kx$(4BI{77yXuDY(Q1Kg;^4WDLEF4D(ssy3|?-H7-kN`8^WUK43 zIM!bYjxPJO?zVqRrr5uqpJuS-s%cpkUs?b$EQpVbO*Z8Kk#e%z-D%1>fy=V;_F;kt z9AM$Ar^lX&VfYR_c=wc zLGT5DzvZ%REnG-{VlOOwOc9 zqk5TN`UhI4&o2s|RquhRR{H$PQa$zyUSE{A+#Tg?2giy}IWk>o%xQGp6YVG-hwY|m z3-ehAQ~$S`4w))EhDxC?g)g=4gp=SO7bk~Bbn@?!%#c_bG< z0%BM5ut1tBq+H{;>@~WD&tYvu4xXe}n(U_T1y`~u@$n}DIG6Cry zkRqD++hX8k<@Bf(ysC=g6zCm5XKqh6xNBLz`x9%1Xt>e^5t?(3Q`2e5KyM|2*A0*E ze69$;n#}`-X~lRECKgl;!l|!`GvYeRZTWwa%SqZ&Gcdh^ws?Po@P3FoA|%wgGB0L? zU;KvhvnBGF{CxT-*3V@cHJp8SaZ#Eqo#M4M_B(2-H7{$eB;AR*;Y`ITvfUnn=H~@X z1Cl5G?S$y73$3j`rfqv6Qa+w^3)X&_CW~)<+}U__idil+N=eXk*NpNvYPwnRf~F;7 zB6W#Tmm|O>v2SWlU3Usw6hLTYOw17o5&?m9-)yW7EOU1R6t1xr@hssb4c5h!CNFQ) zSVQ`oXfkb`p}@FFgBpyilIXl(s><{tzZqcMd%DQ&6SVlWFVsmphFZz%++l`0%EUQQ zf8h2U1>)lJ9_nW`ih9B5(EVM~cP5OwezxJaaZzBuWIiy7*^0h9&finrR^3BSHuO9N zgzelC5m=)c{-n+kkGKd6UGC++uPUrI?8PXQGI+#jPj*YIhJHs)eOmB^zG;f%59Bs^ zfmYS4#U&+S|g9;zzyH53S4I8!95S< zTR*8UZM>2xOO5$*&xq^TZ~8*rQ2x!OY51;D*GNH|p8iqOJ@9sdD zxJ^9Hf2R%?mKhR|$YB?dl!<&**1r&En|UO4??5~FW`K}dgVD84d=>B z7QRy8m>uOxqYy}`D01dxzXO0!HUPVtFBmVD1Np%jvD=Vk&H8R(1p_s6=D?D&}6@-SNm86W~|{M+8Jx zISBQpb76|E(e>u=|ISlHiJeBgw(nmUm=N&~@=CF@$-PT^P+5>G7F_ ztDQdtz`^Rv{$7K+tkgp*W%?qU>3u;%L}-2MM|35^iAaU*`lMs~L1Y3|kB`7@2V9%= zGR}1BDqvLm@&deRCA{`rCz=KJN>1UvO;|sE$Pbn)ng&a;Vwgun&5Sg+32%X^-Jvm_LG9P)P_-zl4wX>Y_ zhicl45jvPs+H7SNFxKUYXU(12T6VFnDUqtaS?zCLH}GpN>=y_dp~Zb#9U%0#18|#G zn5n*`?ot+`8wH%JJ$4DiwvM87pXooa+1cBl6{>1#Jzykupel9TZ65dJoi_pHz5}Pd zZ(%1boc5E$^LV^x*=I2W;7s{JPVI9a7th%Amh}!0Qe4V+ge~NaEkr&Zje8+N(!6WH z<-(2900a|=S1eq6&aKKdYE*Y*o7_Y`Acvdt4c`}=qlvx-Sq=9uiqF;y!uDT)7UDWx zK!RNpSuu!%BEA0?{vrs);v3O0gSrJ;09H@>(5ee$UnF>ZM}(W<4oka~4NFkqrHI|{|raO!2P~D?30^(_P2-zx3hkZ zesVT_JSh$YYbr6e8^^F`ZaQ6TZ;#cKp-^iR+h<<6HC(b-rXL#%;d_Ajuvr_CEr1aa zJRRkNJd?bo;m$cf``L}4TQVx|LB{0E?1|{IhQYpoNt=U1G{eNDaKVvCJ?Uq|WD~&1 zb458U6ZMG1~4*)FQo z@>!a~5>^%|pirQj*r;>AKejbkCdWd^BY}%#3qQ<8nDNjibIbzc^_4R%!ArV0|pnlAPm~7+huy>`;){j z?IgdXlBxg|2g^`vOlTBeuCZH%Yf-6-L7;oEg>ry1YhapXt(w5B)Nwm|V&Zorb3r2s z^J)-#eV+zPQx>23ysHomW=S$ZqsluY-4zb63YM1wv)W&T9OtQ8lZtB0eh@>mCKk;O1O*baDU!g5$8W_hlx5(MRpaj`A@sj-*C8WkxBkYLpHuUT=&Q6?F+?9 zujoRr71C=s&?4@CzcJ1jWQllkh_rzQ&yGgkMO}oBWS-wk4(FkE?~0#X5P*lGh?T5qKU<8O zK2&r}j2fU3>ugpbX>TjMdnew7(fC6&r({Koyo=^!v%LKBQSc<#rPNqnY^GM>*c*iT zsqTFtII>R>RfII+O z5S**UA4pY~4B^D2GWWXGDIPx2m{X^R(`)5aUUI5UpX_Qb!ut1BC^(XC>+XBJ(8}$Zs); zSbl=2rCqEWX?nY#V4x_`+L>*#1Gpuu)RGQoWxQLzZ7k_^W{YZEZAEym_GIxrEIj?H2yBu;tc;}XB&kmpY zb0a^U3V45hOK2PekcU`ll?v1*5lGVdU4@`9=YsM!P}h)W(G{&2c`^=pYQ_BME!THR zFW;)h&%W{^O`fj*Y=LKFi!f&^&$Ng(otp4?<*p*|%&qcLYz@2NP#gZx{Rz}OLI1hZ z?r4X54y4MIwQ90LI!2|bU_E(%33o@|1fI$>U+#A(edTATBhVm+xh`MSrzBuo#dTLt z-%X|^wRBG7@4TFQw3Sh!(|$`dljggkiCWLOd@_|XY2}{Gw6e7e`T=)`3K@A4xKzdi z)AfXDA5-rH%|j$8AtV~bjJAi;0O1BS$>h)v#?}3U{P{m1Xtl5ZCWsvXIwTa*-M$v! ztN|PUwc~Y7WO(Iv-9#g(n13mq$@iksve9BH z^9;Xf+!7EY0w@PVhf)fe@kT(H16e_;WSI>=%Y&ek*dg4aZv@UYS!`&atV)^3*XEQjy> z-l5%fDk1phC7dkEaaR>M!2To{!qbf%uS0^!U%sJjePJA+7G zoGGkJUQi7jN{~$12OSg1%2X2Eg51E%Q{Q|9q7ta^)A_&;$5o-p7*FH8zP_929Z+5* zZyTafOvp3&4Y>{2hSp{1>V?X4VU%`1u(^b=FGI{k!TyD_kg-1O%2l({2)y)XadU!@ zjMVScP;YpuIhF$gbjFK161vz176@T{Ghm{yrY?vEipgDNr~{M2Zy>($?7cG!0#tL| za6ciWPY-AtUkntrR2dENtlAdNY?WL^8>-v@b$Se(@MD3h75=f;sO*(=4T!{CY3!H+ zrJ5_B=#wO8cAXRzg=Z{2Z@sGbQQWHVxJE}qv16di~>CM!N9bhdf9 z>}4(WBj8jkC%KN_T<@GYpXit?llBkas<3J|W5Jce93|WR-7q$iu^4E1Kn%C4%WJaz zIg!5k?9dz$Ym_@;O>Jt@oCZkvYh}*`l@}_QQ81_o?mS zp^mtO^{0ioyB#Xhp6NA>i>f=ek}@C_znw%?Af0(>aV~Z-{d>#$$r>F`L?qu}_OpZJQ8H&01-W6t&PA<_tCq2rwp5tK3X*=&ji+jd43R^( zJPZzx+bJ8I9>%zuL#oZ?wMSgw)N`1@H@(E}J~TllBUm}B3m0LU?Jr&&eat@n$&Akf z$4|7YNM4Kz=xq*v{!MFN`kX~!EEz0UJAZwWWY+XBp-P6&iQ~zyk>2cOa79T$dyx5C zV(XI|-0-bd=K&l)WJJ8p-GPx3;}ZIvRosWOgtsvoJSEaJ-BxMrfZgI~w z=$K3F_k5Wa7r7wVnxs~ffGmRl4&Njhw=QHV7^sM}C`=iz^&A>v>RbV75}rCa58`$B z$zcJY&c&c+Yyy(=uC&HcGE1tHDy{KoVWb}VVPVD`w4`X@n` z)4NQqA9v~#!-ht)Hd?)@FX7c%$q*R(ONbMq{l!Um@7~M3Z4CmfcycyVOuuQxu)d$; zj4f6&*2;9=-^2}z%v(i9u$2%pHB+EI%#TC}dg*5qYFi7D-*V3u9xf_$3wS#%5>HWo zQWQ1UGUPj3WEf}7^T9f@xrm$CYJHl$?5o6bi4HjQ2H*O^7DOqoo=v^;MHpf7tas9i zc%X+q!voUL63b0KrTqzo=;E%>;?EVN@vfRylprna3D=DR_czIi zhom!p$e|3)WA#<}48J6E|FjfChJjjsN#X30?uRvWF?uyw7yOve^X)AZS{7PD_?VM( zOlY(UtD1y|4NNA!q_h75o#k8>(k4&eK4Ske(PjC|b>c`%7rD9@xHpQ^X2ZlVHo8hE zDVafK%=yROLhzRi(>X7gtN0_RNZ>cj+<`N9LfpJBpQvST zcd{gEM(&Xw4MBcpqd+aIq^opZj#N=SlOMS_!eaJQbpPeMI4H^e+CV&itqOf-vR_Zb z%x3F0BXGd7Ms%}H>PvoTXp3qd&x3a`!6R)aq<$?DSiUIm6n9Zk{#x|;^OHjX27{6f z`RL*}j(&864g3?Tsa&mP+GVV{pZ-IVll%~MfSutGYRN`*#-j@4-|PI)uL^UV3>iA< zm@cgRvKw2k*`aozQ9jxTeys2cMAn{&jG%rwDH`>Q$P(LXKZ_WXAd>&N}g{l9b&`EBw|GbJN#c)eYwH{RWrIv%xl z#|wafbqO-#Rt9Vfq=a*zqF&R-A^Dy}79Y_5o z4aPZl6G~^XQ1+*2*Ow1)VWWa=Eh>+`@xv=S&bt9I7`};P4#T z!To5;RnN2&0qc-j_%z}caSqjVemYG_pP|C=w@gNdQ}mXLmBlqQd0bM`7=5HtjB&M@ z);csY?t~8{>UsuC?l)Rn@Y-dy8rQ69_nlQ3b^)A-wNPEbI7ft8?&S(4W_fp$5Sk60-0{+ zc}b$lpmHx|REpDE)19T)-cv}CzJ=XxqAMdxX6EXzSzd1Gof6LzvQ+6&>M{Cwe%zwH zD~dv3u1$RM#^N@X$4!k>TZ`J(s$}Sbz{WT@o{jj3& zapYsN8zwDjJzdYn?H zr=`py8F5|t@WFbp6kuj18+wUhhR8^DSK8a0=1oUzc-Kjl`(Fs|KX>NpB(dG97URjh z#psb+!QD;b(#P{l%~`GSb`kMw%DM#0`uaCA1_i0^cBXAF-G&p1L;CN2B_C&8kU<=& z_8K|!saIt5NTww)!nu%FI-2|WSNx5LB%RRXrJnDDGIOMt=a?;-lin@G!r?n z7}7P5`esuX9}m|hzf#o&C@K&lZb{o4UI}gAr&rK7?#Yd09adW81m=5n@|p+_nQ+v+ z8!WspF{{RSXcu^`9Pb?md^pM3IPOLSsS&aAYr~^8ws-b@__&Wq)I&DbB)G=up3INhMcM}^VKn^`cxdo~AV3b6eAnv3W+QWN zL#!~I{>C` z1w+lvA;0b4QCwaavv1>eGCzMINT53xG_k7_JTq~OtAqsX1$PEW+we( zEz5D;MRPUo1t~ZmVs(H1vLb5dndCF;r2&QcumB-^7BH)m#-ZJBr}ZcL(g>7>pB@HEMj=z2P!k z^Ap+q(_+_R#emoeMLLQWvtI$)=j7;_lcah)I;`DL z2jW$4mM4=35{J_T{6H{zZ31DFy&!AQgS;~CUkSOmCl~5a0+L6n{j28-pfbR#1G>0T{*wdt#nXa! z&)alu)!vep%&@GHhUdb10h=qS`l`Y&zLI1cx)oBOiT5*Z)&CsC1CuFsh+X$9Dom6{ z3>pK_O&hx|ARepbBW98hK3osOL;I^iQK(o45FnWHRE0a_?fH^UoxX))7T;}Ek&v0a zaHrFzS1;qLly-}cdf$a_nSggFeO2p9v`uD%h2-rwLXr;{vMkzb`9=M7IBPO=46y7q z>}=BV?uc~suhUD!dk7Aoy`G-U~4YRE>3;Mi<@OsMMT!rcrIooZco1Nn| z-Qb1{HhO>`2rj}lA5UlwAygP0^TX#Jn}4#Zc`m8X5E@x%WpWLDwP{b`!Eyhso(#Y^ z=rf&7u2zCj2dhwjx$NDeylZ9{5{YbqvDI%z<`_kI{OkVPJVh(es71ndIYm z#2$z{P}5=_Scdb8mX>e_>ow`;37mueT%U+&tHC9nrOwv8c;fnM-anH*l}fqkSO?td zIh$2%PQ#5#h~Q2tTzmF8qg=LkL>d8Wk43${IrN|i@3Z~t=5LKX>Jr2yrK3f4#k@90 zJanQQIA3S9uGq!oWq47hCNl8*XA|R!$Rf>YRS%J*xo{_)(14hFU9OzUd?7#o!%yRr zZyYEYvaO?uTP{D<=hF~UjTJD9fdouB);A({QI{N^^#D|qB+eyT0GA*k5vVM@6tH%| z6*Tq*n-+1yuT^<;%R>tZe2h3&QrNS9Q@u|;3}fL85i@Xl?16li4*VN}V<>s>=ubf8 zhYsk55b*!^?_;;W8K60XAo1Yqi(NMwEE$MAD-wjA$q&6)k&`b7n)hWnJJFmBCWWT% zf7<83wjZuBpb5_TDU`h7iIr6!lzdWnh-}Y#6pdxzpP5^=xhDr81!o(=5Y*&`3zX?Hg`A_@GeIR<-6&5aU7u<)ap8bi>fzpi5?_IC10g?w*i zEks$319%Gl^Q9A8^F|0Xx%b_{#aAUd!5=~Ye6e>@;mG|u(p}wn^=Dw%ER0k}aOH=O z-oHNr3>*=~sB|sj7*r}&haH<)jN1Exs*bacmJ4F%(q!M{>m-pScD&!$uw95ZQ|Jwa zaxrnRmkRklaJTHGybF9$IG?dA#62iIne1*TJcaTG&r-e49*#lj({qJufD*)+#Aa-W zIdbek|EGQS10B6EXMsWNBBjcmJwk#Y{q;X>XJOmc{P7F9dl5Kt{)AVGF=6k18aXRQ zfh|_v;y&vB1sj@ncGnJ0`IYC8disuCdb68Y>n>Fska;-Y1+XEM&Dc=sROkN^xG5%s z4gZ`vs~H=Xh*Lh9{CTJE>Df%eu&egnVwQOvN+H5|31wH|e82o>r$f8A{1SE!dExOT z$*9-6&?9y1@?+jiKwJ7x5nhnT(+PEOd;&Yj$qwmB6s8h7cuxoD>%U3X1GE&R5#h>bgHQRhhJm~h{~+n^{}eulbN?x}W$Tspb9Ey{1ay+M zwY3rv9XlY8TFJr4*4EbMRL}H_^0>gAAY$H!$6web#STV$DPR+oLr>fkJ>DtowiC?o zc(BE~$X4xStYLD7cvaB}CLx>scc#`HDkqXj$bn`!o0FnR>N2Jd`{RSxS>M8)@yr!j zdh*{rM!-%^ch{&oLpVd{HdG#;mw%2&VJr_{N=+AIq9ct8B|`I(Oem|G+JoraKf9_pADFd9Q!k);zM$Tt;@F{J|-4(*A~;m z(PM_uFNk3cOoHuA^xB?ElC_I)PpoN)Lk*`(>oRYbUHiIVb>mw-Dx8N`z=VG-(zR*Y zN1X~DmC#fuJ2A}NDYL3=u%SV=e_hk2BJ=c~&FofxEKnh`PvJg|+8CR7z0Xa_@l<`a zX}KT`<|FqWe^uXQ_k7eL>7_agmp2qRvQVuPx?Xk1n`Ib1ACW`9)mz-^FEoQ4SaMDF z8h_A@RpP_)#U14+NGl5-?7u3p+1D4o$0x0V+_ShkDxOd7eVo00`>PFiT(yU>@HmTP zp=jN`+m&)n`6e+6@C&}#G(i8h9WE?kf)rrsFk4;GDUL(mk&uZbi$0O2>9xp-%6wto$OYZu{r7}%$|>|`}=&m0)LshX=a@= z{z2s{+IX;?MPuV%O3k%Gwa?1!jq{nNO>Rix1{4ZpDql|OMdHD5HuRt&uD|s;nF*O} z`2BhhXJXdds}nbWEm5^UMrGfO$|i=RDAJ_gqAd4vbAMQ_j(c7C@v|9(N_bbt`h;4= zv6OE4-SSCo&mWaJDtee7J90aN!!kWPRxl;)aQrtqUOToQ$tyV*VMpta$1y(RtAm{L z(fVrT!|(s%y$0(;&;J;^iN^U$@uDD(?_OuZ*c4UctoN^#qUnYs&qL%`o#;T$XioBq z-dNSK5n+6LDrR-hr>dst^F9iH41qwD+#wi9o1QSMUHcMP7tI&EZZKB7$s9j#vJiIi zR5m3`kTQd*sb^omYDh4luYEnoUu@U)}NIujR?2L2cyv$-zP1s%z^qm#ibnw2TcU z`ki@xmtm`43vU;}gQ?4wAA+7V(FYU1*X;32Z=fV;-j%#JV_}C0yxFJxgtCDSR<*xa z+2DWdQL8_uuzU`O2@D>`T3wdaf!OmP6TOq3r@8vIsHQ|$`JzIkS8ID!AN?A5eS}Xg>ik-<1mZax0c`bp z(p}+x!yF+K$KS1SO{>|M^Ud#{K&}H5;qmAJ$Ge{MpSFr@*Voo4H|3N!P529DkPq>T z+=KAy20bL0UiMfI>yOo|v!r-kaXyxw4tk?gZXOqY@OjaYJ+?9#5}Y8{n8;@M;)uDS-THDEPKD|S69p> zi;8Mz8I1&zd?$pDXL*gfcl`3KsY&*FTLD z=$*%*_zE18aT;*4%p61QwQcQ;C3FS}oLmkMJq*PT@PR4f1Zi`N}7=d>zPOp=She$5ztb=$DtAi-Ns2q)S;Yln%_SKYv8-&^i}8F zIp44ZNYxA&!R_wiq(U1JsPG%mk8yC`K*tk+^Jn1aKuO*QLJ52>f+GVy_dh`8aB!YL z`v+tnLek`aivG_u{m+&FGw?qr=l@DdoSt91zo$uM?=A!85J&2{{IjB``fpy!;9j{l zZ`YPgc@8HGd|%330I2=Sl`A-I=R+ay{69a$;7@YTUp--wl9yn!Hn1@_F?Mufb+xuS z$A7hBM@SU>=|0TZ!O`5-Mwo_!m7V6kv5k@KYjYb@VH%ZJ5-g8t?mIde*t|Bdvb8Z5 zrm?Z55fu^oM?LpJX&Xmj8fOO^0at5to7dpq26o_I;Hkhrek6dc)y}}t(Z$x`HH(?K zjgv49jfjwmxs@@Cv5k|1+kF#fD=QW|11B?K8UrUM10yqQ@Z6D&=DxM@YjXn@CpSCL zG!5H-Qik2mz=7Y$1_ra^GBC4qwC8f>;Cb!%+JN1d)y~HB-)l6tHZV12gC75Ht2VN= zaRPmTChXtKIvKk;GQxKPd2znft$K)!Nv};Qywak}=F2+64dktpBS7 zuagzbhTV>z-_DWU*ul=h&K|~XW$R#IZ}%TB;eS+_gE5SSgN1{KkC&5^os)}$pPlP} z9qRvne*g0}*v}f_;^gDv<>ul4dm8yO5-!fi99$f{kN=)VIL}7H&BM#V$^H0mYJ}@g zBfNZkJnWo2f6qv`|JevX?_&C!#lbe(8ZyE{jKO5oZ1)slXBz$L$@Nn_- zv-5ELJtO(Exj5OmIlw=E&*u8Gw>ZHL<^cowTPEwz)&gztbF;H^|1E9&*;$-C?0oE8 z+<(t{{MlHXKtA$u^87vH__MD#AM-!v z^=Sw7{1+_t-wRgZP5Ca7;o$rPUnr;dU!Skw$-k!czn5bVyYaj28n_!Be4#ta{`L6_ z1c?5pfZ<;Y{om_PW4o-d2P)nK-$(zd9Q^6xa~z!iigo|LaqEAtH)WhBjTg8rIKWrv z-|AI%{m=XT{|2W1drR|s3Xdv*5m5rZ!vEINR?z>Smj0h%X;PtEwOjB}6Udr17*>fa zBE>2!4J&l3UNXMAqant?pbW&QzB1TBid9&eSLjyl%}$mO7iVA)0%BCF4xb~%DlCmG zbgTXzn+%*OVqlO2VpOYKpOIn}mZlcERkzpi7=TXN+=OA(xqqZsg{8rTZq?#aZ4W14 zfnW>5C@JuRI3v+{RM!wovkTp-38JFAVC4_0RdWqVu?kD$3*D-+MDZZ(Iry|U307fg zf}z`F(7faEM&Oj*8X!h3E3$!0&WSDKbg?wV&}}NcUhpjsn0YgS7}ch>5)y2}(i}s# zY5MCBDOmnRwJ8o*;}Gp9ER8aBn_gXyNm&c@&k77beON$(O<0;{=r-MQi3>UbwB;~{ zP3+rAun9{84c(?UGatL|0@|__!zRnKB-n(dnTBpt(mIwW2Y|Nh#;_^&F$p$dX{@2! zgghDsER&Ex`%gv&Tx}h6Q;?f9Kqn)CYzb!U<7ffitiTIR85ksh@E5SD^F|3YGXMa% C_CVwS literal 0 HcmV?d00001 diff --git "a/week_01/60/01_ArrayList/01-ArrayList\345\205\263\347\263\273\347\261\273\345\233\276.png" "b/week_01/60/01_ArrayList/01-ArrayList\345\205\263\347\263\273\347\261\273\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..24717214a699759e35e78d43de6eccf2480fcc18 GIT binary patch literal 13042 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 D)^|7p literal 0 HcmV?d00001 diff --git a/week_01/60/ArrayList-060.png b/week_01/60/ArrayList-060.png deleted file mode 100644 index 5a9dffee6a61fc5e2a0c8819ec7d414b21433875..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66168 zcmdSB^;?u(+cu1siV6ZEC9R^s(2X>Lh_om^8o$^b)$%+Q@fDygJ&gLH#* z!@FkYe(vx2w)Zc1`H5}jT<3YLV;#Bg$2lRdm1PO=sPJ%ba0ujHy->r!!JWgw`KR&r zKj0IRSBlLz*Zz@^d+}V|BWYvGz=m`=W!rnWTh+<+&)lmQ!W0i_ErSnRN0;Ay5u%Xh zsI2@F$+u(`>>}`3xBo5*Zu5Ir<}thNXWTFgm(N<6-Ou8`?>rW%jAr{De&_I+>B=?D ziMsqhY@FZ8*;d|MCm{T7_zZa=pX#^mmEx7Vma~>yxORBN5Hvcap(185WH5EGeg&=I zxDF&k|E23vxZT43i<9r#0{hRuQZE(nVE=vi_W!L9sU-7l4LbYi`54bgtPvrTSEW;37eqKXKZ7CHz)o*44_7MlO1Ln@5r;aa#=-l& zQs%@^J$h}QLpcgaL}H>Cov&!v*~=bif-@yCkw+`%$FD_ScBf2jF=xfq!4MPUZ;x!l zAsvqpu#y5bbqF&0ggUY^<{h(n3CiTxx5ZsK=)B3ss=pULjwCGu@&>rUJ^1+pbNBcR za(iyX4w1}Lg!-BVf3Aq2kx*551=)OiM>AB)Dtdj^)CPo|_YijPN=sg*HgGRZ#5ZQ`PUX&U6e!cKK({7v^ zjJf^$0sj*8g)}PtIE(9d4Nqo`OiiCKQa#ze-$4)3%+|xU5Qbvgxiu^3{M_uR0y{hV zh_;^IWusK>V%XvX6&F9`Lt6UhC>2-VzQVQM?h&(&bjX=G?^}Gn7yf)DyLo7lxl!OJ@Qf>|~!kpJ729 zLuvNxo?T-^>ld#Dc3XvG=8pKEkg8kdcg>DIYU@^ZFCA8|3gj)`pi4B1V|ULgeH&K0 zd!#dIRzX^OD|-rNkea{jP;$BNJ->M;I=NHE9@c$wkqH|gFfh(tE+KP|8khaB$ub+BWJfU4@X;VR}k_&B8tFuTN4PDguj(AEf&w}sEmR$ce6R7kKx7m$F@v<64 zO&{%dha?3~UrwfPxFsc8Pa$_EpI7#nyC)9ui%psC-7dxFqQ%|Ursajl8TWh-g#__z z{8X_$V_x{1_1i^gT6Hqh5D`$;Qc!cCAD9#)eCeI#F>g-WH%4IBTY{a=%?d5mL`#kEQT@FP;I7Ox z%vc?!YK2jr#4pWhFAPOYlWRKTu6OMReqmc zd)Rd?)hcGRd}&u`Nu3lz9I9SnDxbxnEpEJEj*wQ2w}(ia7NN>l*;C$$Z|jt&sPyQ) z^v$=k8m)P>Szzg*6jV~nwQchepTwFJ`f0y%k)+${&BF&xOb-eK)56btjQPWsnGPcs z1`1M>#&_4JZDp@2R{hTpyQ3OulD+gB1Y6*0j;p{ae>((27?A4E)z_h+GK@&lUb$tb z-|j;0TsQCSmRjG3vd|^^@grJ4$U4tXs?QbMIlBi+wMd%CPxN$(w!yX(hQbFDnFc)n zwB8<_%~^B(UF91!^d%EyLl zIFhE|3}QRJs|;N;+Idr~4$~55BenY#{82G*uN^YM8u2V9DhUx7n#>mXG3Hth6{XV2 ze3`*9JoyP-6!ic>RI}XPg@CwEt(*Q5;gWIP*wc!ty!Jy)uO+YF?mNTCjMBq%=9>RX#nhJ|qo&`mJ*v1*;Qt*KFC47*}~P^o`8i z?IIwgs#8U@-Kt~v;njHt!nokF6}A?X=XVj(D&97`-jrKRJ8WkNTU>Ich9>9|TDTjh z7;H7Jk}ryjGAw=Qw{9Or?K;z8$&hi_V7 zUra>BlIQ;9I1CgTnEZV@ZPLLM@UUO~@slU|!rTaLkNfsjHL@2gEUB#pR?%JfMN2rP zqK(_!2unWq#dNaLYkABqOAlWd`Ug5>q3Y|W?sda<|7m?5lIz}}1=Uo;5u$l5$~Qmz z)htNkz;+Rl{Vzk}9-*d|k`BCfG^Bdypo>;dtqo?F!nJ$n;igH4e36oh3xs=L1X;cn zKWhe?l7q~@lAZ}TRei+3tC;A`4YN`p>$UFXMvTTMw7~)c2A@?7iPw=D34|p=eH{8b zY{}iuOsK34-EuBE!uSQf%_hj0xEk|qrYjX^z9=1)Q%^t7-@0GRSYdr2@b=>H?ep8e zulZ;8hmr6?Hh%?1y^I`!^~V_=Rvg-;PJ|4G6}4Xt?o0U9X6~k5HS%6PIOA~JeuU0B zw@JCpV8KB}OV_26^`3nCtSbJVG;+noR6dc7=Qq6HI6Fu9pVGzxmmmmp{sQ5r6jU$- zf2cs?<@2`YBQ-&F>1LQtQgg?_qn!Q+$+jEu>+pWQoOXEsWzJ)k?mQAr6wUtT&K*-9 zIiXfq>r6gytjQXdR%PX*jjyTq+L)~M$zlKKX6EC< zufzprn!hG4Ydh)qBUSVgXQv-}{SNa~1ZXzAmh+4^QB$q3UB&+7Ar0sj^#jWblfT<4 zSMB}%{i{C`ug()Y15-D)$Mi0@dwcCJ{cC5$hp!qpt|$ZxKv`EUtw{N3_d|S6N1M-E zJ8naz+Xn#|j5{9-O14^9esH(L$e~`55L?34`UPKktN0Y0rC-T;kg`VRbt9ToE`(-) z<4;W@BhL*g_nPuAMmOIg$OLKa1&3-Ey)~H$%0n6WP3569dWO>ElogBQJoN$}XAI!x zMQlAZ*QsKSy()iJY$EQk_CEE@X%bdL{@X-~JnY`)a$*2#6GyYD2& zarm}=`gZRNiM{Xm(QK6#uDuFb+lyKTKWnqHfy!_QFIAPbi2u=#%5PV>`ADB5b+$7P z-n*x`I5^ipxC-yb5rZZ@iXh}8_{i6)M*blf_4nnorYhl@XmaDb`duI3Q|+dky>m)U z!S8xMBnU4$q*U&5&m0HCP#+;Z%*u%PLg8=;4Kd10o;#@PZ3XuJsAU`zd6^hZoFP~% zQ&dfYQ;q2E*w&qQUa_I^!N2c>nOD429E-Lu7vpF&tVrQ%)k=m9#OB^cDB10q=M=0} zRVP%tb8Wm?5QCC&BTm-ImhX1?8XA0@k}-2Lc7`9;3!FKaDe5E{P}Wk~m!GI9yz-lB zfkoQu2^gmh7zlLh))VM7is`U5Z)?f4PbHo)HTGV<^`}hqU9z7KhBfGgbO+VWh>=ly z@0aI(V)4dzY&5&7S9rs1#!`R0)NZ6KmKwv;f!dck++kc^;{BfxrJ64Omc-sQ5~5Tg zq*k`bVCnqi4cS{}!lk?IpK~j1>5Lc4stq^QE=k;@hP8X7loEPiX5>LQZ9f_pd22&_ zIh2ihzGcF?*NUZ22O!;iQC?*8ACO2!=i+a-$^OkpvZW|0J6gOYfvy=!$=X$DXAeOm zQJZw}bE*kz(Fz0cUnx7|K3_U3R#3X6a_!9Bwvth_JXb0i;Ia?)nGj3qRJ4sZ+H0eT zl0g-m-zbiPY+A9g613Aco_tPqI`P!+p7V7#*0oj&{V*g|Xnt^`JPZ=!{RYa9xbP02 zfUC{hb}sq;m@sHkYsvb&xyj!bS7#IqIhw8>cA4!u{V_e9S2BI;$Z7)r2CI-@DLLtFK|YWXL6R0Gv%DlGycPTD9C5tvasqQ$ za{9-N_=8WN{;G|Krh=`&)Ax*@NUkWM1x<3-10QNWNVndwG=>!=@ymVqr2S`JT}fxn zKOLu6UwiZkNS!r0esu}l2&D%F>JQ?qf(c^CG&wpw`f@>-X7n zRax}}D@pNVIF<|QI$eAdJr>JrHSMJZ>{Zq{ zPQ_Oy89S?u2P-)5*f5 z&vH!SSkNRfecam15P%6trh&rp#}?PP10RAI8Y(@F*WQivQBV!cs*#j^>P$>T&Uz=3 zWnF#Ja4mMHxZ(kh5(OuZNnPze%HY*EHq9?n3A~K5i(BzgsLplyicnJ2$Mj&R-|M!S z7@|B;VGYXWT*$E1iO?gv>85U{_Re>y?!$}jvfqSka+-8p6@ylfvN?zIs3aQIB z6E6grrsWf>xt85{dIWBrxG~Qfyp%6QIFOs}TduN~MTNM*5Z z)O_1sxm6eO?=30R6PcDbcQ^8nW(m2?UQS9R9^PB@(kNH%WT7H zk5DW>aG|LaxN~f0^O%tpN?)C`zHYZitNB)s!Cuvv({bT>kK&HkYqHQpi8{)gs%kVR zaGv4H!o?LLW$1-NIlEvVk*wah$>NondH011oXuZ$i>|D{eAfmM-;&so%yUVIgQFM> z8KL2ffeu9n$t9>5Xo_3$g{$!^&i{QrN!qRBCtP*6@vbjPw1iBdddT+f7=~7$OlcDkf=R-qtmyrw9@K*?bCx-ccK(R@4BWq$7IP_1`012lObeaf)NLA z`lXI+Sg+BJe427rBz{=q*95aKtizQjxt&<>i*yFo$-h|J;R{`OVOQCZ(^W88yfcPi z9;wjQ3e_qpKByPvWnFjH+6t9ll+m^=eB(~>{>Pu_Tfn9w#gslx5wFN|7HzE1t{pkU zbJ^26T=eU*xpR1gsz}T>+lF8MbqAI+D}$y- zdyD-jav`<+6d|O`+6%}RzL=MxWYO%hQJR-_)@AufzP6Z9%i)Uh3Jp7ZAu6ci;*sz* zoU{gFXd(M-08ElL{Vt*8_x?Oq?>5fu)N}ET$nQUDvrG&|?!ay)YuPo7`1c*yobdG; zAhTOd6?M+{EX1X4AcR*OQ|1p^Yz>qk)0{AMmRv{}zNWew3nMPh8(RjXJ}Z(eZU7*5 zv!fCxVsd7%`Vs$Dt)X}i<;wG?z(!lq=CWU98uHN#&AxlVyV2Se6O0J!)ozEijmtX|n>}T9sp)smp;4>psGMY) zf97nO75cHkxo=TbD1fguY}b-eftS9Uh&!%`(a^)}mogbsI&-Yx2Sn@=UB)P8Mz^N}4TfYO>>HWN)ZW!{x z)R-+_cRk#^^xZ7(+@i{v*)aWq7;O$EeSiznHe{@w#s*R%!S5{LJXW`3z4Lz zN@34uT5C5r$v{k!$DXvnsn5HKpRc`Q_8xtDXTmt-vv4CTGyK^Q!m*C8RJli-z|nXy zcRt3eojyMo(#eMFOX1J20ZZUf$HDn5jmFLIHAq*rOTeq?+&G6hK6#H^OCKf%=+Q%r z_^(CSw*XmPQ?**Cp*8rS-Vf(0Im;+ z#GD*U4RULPE-Yv&tYUErT2iP^KBS{wGV?Zx7IxbwVdP8yU}_JAK$9`A~iuxTQ|Yi zp%}GfJgq3NUOZm~si9b;|7U+EE9lRemY15hZvXe1$651R-SvWnfm2~GhyQ1P;M>>F zF=~-fqUZ_l7RRrphzLPL!S8QBM&sbY84U{;Al(#u_raMF=nt@(3eHI5xeZeTyL&-` zF{~F6-Qw0Y4vgTespQeHeMSgI@EYBsw$rai&08|_X)v^TmtrLj`&ZuI)gTq!%wYB@ z`2llzzb*$6k+|nQH%_V-pdkYI*rzFcASLrXDEe7cap#8$GX*V?Tj?0(;qYUWmp%V= zrorP(+ka!a`TzI%HxO#UJp|~5h}}5BZQfvnN+YzP5|4+cg3Y?x%zS?(>m!Ph;ro5e zR%lnMy`8rstc{N{3=wf!)5j}&>R#L%kzoD*T=9yX-Hzr|xW4ATo9vp}$iXjnl~(M5 zY+wW(3<8>Vovf#H<6Kkw-}@MSgw|>{k!e|P0!PxFT8e`pG@y+$coVacnm#8_kH5b@ z7JI9jS9<`nmo#{YSwQXk>#RV_6o{0P8K)&czop#M9W(_j7w6f3E?6CkQEFz2#^-F_ zdNs8|+qegc0<8JI9`!cmRU@A=5VWsJSsIeaS1$b^+Ao{@4dR!P8kHU=zfhzw105AzI7l=79 z3+zUDa}cc&(neWYT1{K8GL^bA(WNu?hzu}pabUjePT@^I3C`k++n>pb4VBS)aQF8d z7=4`b9xpuaT$}|d#1d`NYMfZnU9h63?yq&Ur58aJ!i?RYWW3CxYdo+t!mh{1+}+jk zNW0E@O?k9FI2%ar1U7(uI0aTGY8#eLAe?}&nP2(7H_8q(R*`RlW*S!I@U}QZ109Lc#0$ZV$N;wby3*Mql6ntsC^Q;PJsf}5f0Z6()IFTuHr`;;IX0XiuO7vH#Kt_Or(@AT zG*oaeSy45fZ0VhP@A5M5Fe7r%M%}$*@@s;kdfB@ySnUE_jjGCic--fj_4vtDD`;Jt zwq$;u+C6o1apr%tULSrT8cG2Vvsc+~aCyDW9e(UajPt$%kV}$VzaIyfUZ*!<3o?CN zl&L;7tznE ztmK+BSvcR-$SMaV8(HtT8DEc9A74qRDf6}|xFx!MV6;)^#Jgem;{A?my#FjSrBURX z@2A}go98?C-B;o#KtPwA2L$5lpD(?v#H7ZB+no9WHg}>&9(Hsa>(E+cZ?d-P4h)3e zD?8^>Qo$+t)UQNi+e4oGxNd{S=}m%Osb^QkZ1!ZYdA>ujy;eh}ZkpdOMBS4_I*qM9 zITf~H>5ui#E@E_b^(98B-8iKxfjvAvcnswE;i96_TW(pDHqIJ@)Y`nqI`H#IghEEQ zE-42cKiq;LANY$%BdX;YeIylis0k{3X$2!36Im-8g|Y^H{$I`04ewYKrWxA!amEj z_NmpQd=)Ld)o?9))9SUpFy+heFBVYb>`91ICHiXGN>`9u>y0?=-%5t~KN~kmQak1K zZx;U6R6nLS5lO`uQ2}^VrF$gy7M)6}b@j)MHiE4=q_hre^^@=8TRVP=mCkilb_csB z(B+60v`&pFGYh%XTcmSo*@3k z1;k`pQfu~C{2bcGgo8FXc`lwJPmQ^1m*Cr)9~}3sk~Y_qR4IpJ7v~Em84p{^-yz)c zq979!WK&g5rTy6Zb+{ULYEIQ!ymfNLNa{uOjJZFsP7C3=`7_*? z;6ImFoKH2x-fo#?G262#GBU+A8BQH%#2jff&E&#Me`)e_FGh@+OEh{Ma`qftxSr2k z?n<0iB}s^#`m}jFKSdRH$lzuDx>v0c`>pB$B#n33by1Rg#84=Zb@KG%J@vve`)r5k z&-N^gxtZ^s#I4Bq0q{vsUupfark4X*9;Qtel5d4tVtOSslRv2+B6{J^aZOShMC0LS zrk80yaqt8;$DhhDHL>rG%_jt=$y@Y#Y-G@yhREvfxaD~#jql{?n5JZlmX{^ScF~iW z%acZ(uz1Ef%EXNKZP-cM8nv4=H+7V-DwT`a5QziWE3tofFw#%lw7v!A#?)Ni&}*t_ zssFsmt$5Aml2YcCrM=Ce&Ojh9D9rgl6F^%hM&`zu(X=mL8VXVHf6((qPgFY4govrW zG%ViK?{w8;RgBSHII@YbqOxdoJLT$_V)>M#TU3|j#B^=7moufHrsWw0yyE8r1M!`JEnB|20&Fx*K{RVFTY&bTRRq#kP*`s(I z-jAX@`G78@3*Hd2(dI!qS;t4mCL=yYXuzMj4SpsdQUB*Xfr$;8NR#0l{qF1cRFWFhcZt<3UJ3)1xm_Pl%3g#oOVifqn9yG?y3sLz`0$Xpf6+R96 zB;O7HS27RY|13Q>SFJ2TO+W3oS*xa-pcEa>FdfjD(jHgZsL3dTD_o(@spR!jvwYlv zs1i10z5sH6IA4&QNk0GXyUIGKa1SfduRxq6l zY>m~oQ-Qy0euB5s#gfX@T>phnY+z)~`VY7I1aoFP@pU>}o>6ZTM!?;1okh!Yo{l^G zJPbG5Qd9)7=-%DwlySdv8<6*Ko2v->ImTI#q+t;EgMHGYM;!wix%Q+Du4NZea?^J@ zMeOWnWPOg#+Z)fLE}zCUqMRByJ!cfY2_fLWKKGJAbH3TeSV_&Qn39>G!X1-8KV7;k z1$}DBynJWj6Gz!VIFA+=C9i-nFuFYv(-qAGDHdVa`Z->5*DYrh(mBM;@dKi`U~;Ix zfc#o!^@A{0}!>Y*BW{I;}sqw8JXz=QOa+$|I&kc>%O)H50Pp2u~`k7$?W z3Oj|ImCcVOarV-f#Vx7IMf7REN6rWdE4KkILb6lv~ z#OSk`&?;MK)z|D8UbTX9!Q3D4Hm87n_q_OSJ~jgocM*rJaR5H}$7v}1PdWPd1_*i} z^nt=u_g7%t7<;wYs`n6iT=LI0zRpZ^ybv^FPcOnX`MvA#_sx59)q{VTUsSC*DqgwbN} zoU3^NioiIA`&hjlmaFShGb*h|Wl zS=WER*0fAi6Bs0S4+Ad$jwD}K#=M)oLa+p zUusQc$Qh0jQreWi8XAU7d5^mK?tVvEqgf%qq`A2exf-J4lM;yvR8lgvw1$ZeHThdA z#QEukxDQt>N9+G)b9(xNz6Bs))6e!@*M~+ge{F-(de7};>)e<<>vBAE!wV%&jb?&R z6#0(gK~<>!t)C4)4GwOqJsg59`}^#V?D#`9p<8re?n+ZT{n>EVkon|RzFt!C_`*0f z!lJH5_ynZOR&|A$=#*nxFH}0_TYl%Nxk4gLFZ6?M`a3lrW~6ZQoJ$*2I5zAqXwAY} ze|CPsCq=kw=zE)->pfUWX&e(rl2*a%4l`xVT65p_*Ch1Ugp*>L(0m=udFH?gep9v+ zMfD{T@-{LVFAftn*LjV0SPDqm0!SB{0bO|Q)MwE}k$4G5cq_5Nbvq;H$L}O+e#4*% zmHDPQX#_!d5?OGyp_`zrQ{&6NV&264^iHvtHH;$6q0A%lA2SG|bd*(nbuk9;NJpof z4Lg0ypqch+-yZCfBdUtHtKr-ISr`NqyJw>yQR!3rikF$6?_w#G$XY?BrFXv8;}sfMSb#&oz->wSmRpE^;Y{6XTcYl*F5S zdY2>{@22@uLyPhL+RYe-{Ka;QT%&T8`v~C|LgE}QleyW0hw?Kf!d7DGwk^zn31!N? zfwKa-!eN&6w_P4lZE0^F;U~lvnHwZEJ8VGXRXE#t4EwZ&`<-4L*+|oGcYB#qLs>rk zY;Ap1Jdlg;BN!hv9@1%DzM02TRL)ulq4A)OHmJR|?o@mB07{idcj48hNxs79CTP!Z zrf4Zl{Q*S_L9%H@j>lH%-iVoV%dZEjb#I{Z1DzyMQmrNhQ|Y9{iSHrPhT)+4_Hput z0A4Kxhl|qG7@v>RI^qN9r>r3FnPRFtRX16OiezW?NPuc;h$9 zQ{%6G!Bx?=Ia$A2BIEeR0jV}U+1TghK2=Jg7Bx z%n<=G;qpu({PHNIaW!sSz6Iw%@j}+vH=$W;d?~H{zv8f@nnY#@~Z>H4R`dl7DD+X$Dccc19An7FgBf1*4jTkmYs# zRebTiF|}=-KGt!(kbmFp7(&DyHmV#8oeC}4ip#Yhsor^70B{eGXaEX8U*jNF+WdVW zkCi&8fiUwWXKtz9lP_KX;i1_VudcE@UYMpHsUwthYj&uwU|gio?eF>Fg6#01)r6A2 z)v`A?ak^SKqII{&O}tra4t=@xu=WO+wr}ml=`;n?xD)b(Sq6A)BF(Ti4tpc;pZ22>$I9y^fOx;4{hM z+u-rHCq_>5m;M(3q*|?W+N-||Gd_}Hudn$!bx)6z zAY454PA#YA;7s4(+9b?6aISv}z)t|=k$kNlr}upR&DlTk=QrKZ_)T9`DFEQ;UG2Sbz!L!;W4z z$bo(M=1btoEh1;5LrzdYs(dhsz@XM3e7x{uSm8QBV-vtV|B*rO;!hTU48f&aB_5_x z;*mWekXxyu7WGu~Z_#7i8W?Q#uMX+gj!zO|W*{hncnMA(^JN1DIs0q0B4^f|n&O1T zCnv=}tAZUL2V+pud+AIu5x!m>OAJg+1zHheN|pL_jNgFH|KekSpVwcV_dwM^F>Gc? zb-WMD*`NFL(cqEW8=J#1po+nMlVD#Ug#{M|M7k!QX$WW~BPY9t!!Wx)15hwVi>{uv z6;yy;>iItFdr)ek=g_IJ@Mv)xotQ7cT3HO%J8E&o#TGv}kCaNJvjLcD6ad)Qqmba@ z+gL&VU@#k^AwSgmEpKY4H@g$Xua= z^g|J#c+dzma7lnrzEoRn1&XrroZTKBSg8DR4>$2vE}*4A_8<00ALAc$@_bfbqc*a+O?Pl!keSZ;fO&?N@Eq!KJgJ_u~r4KOgWR@^SWTXr9wxO z0E~`-R&U5DB_UPwJ_|1nXQv;loJ zfq)eqK-Cj4OQi1A9{mM!^J~9$nq36QsC9AL_%nws-NP(_PLM7@R6%>KKo~IV|8Qqb z=xV=*wcm_5DBDc8xa2#^ZZc+CS_I_fprzPQAs`3(dyg5h zf6w)Fd1(d&BFS4k09iIXTMGL#UK9`LKiZw|D&#@}XEy7IYlT|`KonEV?H{dU1KtOY z4Df8+YLf%3A>!7<+O)NR6s}mB#Ru3=xR@7}{#kANoB{L)A$!q>5h9;hL&D0RCB{AT z==kK0)rKIbxdF2Oqhcl=KFRARRDEdua76cAyUCl#fi zpq;=KgC;*@!D3GTSowf5s&AS18o%Ln;P!&T2hXYx*L^R*m4hM}0dC*f(iJ`s&k*{( zzP$f*yUH-)=HN5%wF{P3d4;7^9_ntPkxn+c7oGg~Rt}s2SBQ&q!W$f=e7Q6vIQOe}u_QFAQbOn|~Cld-WZ? z1O6vSkeWY$2L%>^i>38sKn?=I=G?YSxhNz0RsE<>wMcO6x?mMx$t*-MMxaXi;<;I} zp$t=6w5yst+Cm|i&xy%eo;I%Uum}ULauHCL4T1^~G*_C5RgU^Sjer9WvgC(tjZn-g ze$1-AMepZkVzKwo9mFq`r~ibgi}(4*J6EiLDaN3Z;0`V)hOfsk<}uce`!N>NRV>;k z{+Ft`utj^<5Qf1C=JUsAS>Iw22GlYbecZNB#Ok$sMgZLK^?wX$uPP0s!QF8|qvIi6 z0`Q*35kdIz=tBfLtMq|d6>Q29G&dkG`HBk7gYE+~EEiVn79bY_wr#)UM-BBMpp}YW zV)vHZNERs4SUY<5C&j4XX7^FpZGMAiyaH!k?YQV&;A4y@8$7hMfy3znG@+$LGeyII z&jS(Q+zR*?jyNWjWnaghaswYfhOjXQLY<(6 z%wbjJsG9`c>cQrqBqk5;va1%<<|Tm$m5)81gCFf-zienuYdAPuFF@@?Xzma)GZ5bZ5iw1#0iMt7#$X&Tg*6vNmpb)31r_~J$y6$WL zPK^)7_-02&k!tKX-f#iz(hnvgA4`_kSa@<#0SbT&V5vwgUy*KL2RP^Gj84E17i9Uw zM4YoMCr1wT)5qQiZyF|-YJ2!D7~;$;7-Cb4h+ZYjViklZiZ`;5ZfXg0?!V9$Jn{V4 z3CWt@tW8RxYJ>Ak^fBTK*e=jb7amq0NPkWs5PxK+=x1=~1=@CS+?q4WzX9Fo+{i(L z33^eSO8hhhMbO;jUsk6Z)3WyNf7+`cz`y!I3`%8O zm}@BIIBJWD(e}m&SdmFCF|iEaizU|)p5vI}Y=bS%uuQRPsGYjpNU?5Xc?%nX8#}5g z=Bx#8c60{84(p?;s2P7sINzobU8xa20oBmKCc35urRY!4rR?^6k=u{{2i|2{tkl`QAf?R>yP1jn-P^k# z%)GtDE7%I&2?^ai_=ofS-;HZL0MTOXYhD}ZenLBQ0R`L{)=iKEsWI>Q; z15x1hRZD*HJ$1Q7+sLX{cOQLAdU2;D!%opMTE;63f*+@L&qNb~wBbpSD{zoZ?7fX2 zlB7P8vr=cEz2Xy}Amy2%!H+;`EN0mB5L=eK&O5N6@Fw31i$glx6}C;W)MdKHe1nEm zLLy zco!TJT=O>_S;Vy7!gS}WuTySZ{3w{&Xt-RzAejnGEj(*3p>M~R_!YR^z`?=-SO$Ba zea{$T!0XVDsN;{9RcwUt;Nxjt_Uo1$X1pCr47{$ zP^t`~)b27-4F57G=Dj7qMk1SFD*s65tCY;<^O>d)P9@nwI$U3cJu2mFO&T@ZU`Rws zuCpR!e^PiR?=g}s)nwol@4g0oKp1O}&`tg}SkDkFG=dSi7#nw5cuDmfkHmSv;3%k* zdvR;Mar&^92w#HwYP0d3zwXN;b9;K9-LsZ+5`PNXj5W?oUT(qK#dFKX)A?F#)mhMx z4El?btY2#rA+d`uma-bU_AcVHym_N4$^4O(Z?_6rFW+7bKCXk?O1*3zVGA6Pt`3Ln z*^|d`e%|k8*2!*+MIxA~L4ARa{s&41NsQBLG|&W&2Mqjr;-C5HQC1+DCWdk+W!OGF zgR9-Xh4`{+Xey7A(7a;==A$jAj&cIt{9 zgXw;A)n}|MkT1C~2p~!bn=B=!>J0``ekG*R7rcKd-TKHxg z-*Vb@p%mXkxeDrJ+EA#_iifm*Z><)px?9CoU6QT@uRS)7$B9Hn1CACUbCfDe}SM_pTYlmstn8=?!_CjHr zB5beA{z3n=CEf(5RKt+5HGb*&jKDXzD+evBfn2r&BE^J3>?E|q(lo<7J2`(LK9=cS zbYxZDgERI5yaOEwLUC;Jn&l8g#I#}KtK|Vz;X^~FulT(pmo8odRgKwk#ZIzEuV)GZ zmdDWG2TF9q$lYhY)2!i}J}ZlNp9ama!GKGt zI!kntfpvy(dA&J}L{@YD)mE}RKWsX#P+Y_(a-Yp;reHs)at4)VCA#(NX~KhixHlxD z9dBsp2{7(FN}77VV!;aaq0zO6n2O-4HCOkQ;udA&hL-=i79n%$76Bx!Yt%0Sz{A6M zL!egAXGixCBDtNbIM%O(^3VSa+m|*5P0`T4lNHkUrpXd7BDaXRV!@WE&BVzoW}`jMzNpUR(V z@SX<a;&B?d!D~$2{+oweu>N38=`4b<7BuxG z6fNAC)3*IdqDx*_E;mS8oyw*eBigiCF1=k_u3 z^^21X)(t-(#o#S;tAi5-%(v=dt9kks1(;V`0_58mz5U)x+u(ihMw`U>Vd(N0=sXp> zdQV2_qf)jI!RXzC;t(v|?#~Mo@xM~>zS15-k>&|v*!h9*#3}Xdj1OGOP891jvo#x8mpd@?g205ma)uUPL*e~KU-(W zb72>C4xmcH)Az!&G-+=5f2-V%qV&xU-!?+VPE4k{4OfMOAeZ|<`lB?#Ixz&uP& z)IEwizH~NU>Z_a#wg<~SFc|Hh#KC?QblMv6-KNMbYyHnaExSYXBO)}}1a=J46@V=PWegwgqH-6EO|Z$915r(oh8jH)YD zIfJ21)X}H7ynwSU%sAtY6IlY7j#TODKAol)d5i9|8!)bOTi(mH1f16orpBVN`}GF@ zA~6=v_I|7S5STlttL&B&;E7XCmoE1%N?yD~pR^#RpT-$_mZQj7R0n{Aoc)YElvMDE z`u!XVz-$0bU_5Q+%rqn%jiX>khkxWcs-0ksN5A{4p@AnrR{mLwYQR=H2VC?2X|T7W zs3<{HkmSM~@jqZ_ZxU2ZvZ*6;Jp9-|c!2PhdRFyKPSyvIO2HGT`+Lry(**|>NPqP9 za#H7;8StfiZgg&?p z+RNTl5ofeUasI_j6TfEo*2{$Uqy5}k5?QZeY#=IpH-?5h4MyT_AH@aPncGrRhKebH zhyUo*W*qzK8AIsv9Nfa140AT%r|2r9R_A^+=nHNQ(ko$SL4h)` zqj0bNSz<}hMn0te2Orphb~8o;R%;*i8iicWsy=WuH9sxGB%zJd@K|y1W=NgiA6{_U zfQ1wzC(4i@E9#FA(&NQ9{lNiJ`I~OckAP%X#P(f0H#$DUSc0SKh1LLmU-nz?#Lcn^ zlv`A5EppOec(S6sAU^fJRz7GmOMQPDEke22T%bQr4UjtkWPrn$Dm#iwbv<8ok&M^|FVED*IP}F+j|gwo z;N$t0|IayE);PQaV_gsHJ!5(d#=R{cf5u>cnAmVH0c2k2#>IPOwK31dCD3>pD5hc% z(%_U82k-7wFjosEf^Q8aVoZ)weI7{v8iNYm9vI!2DxmO>H$1o!<^u000)*%w3l#cb zh_!fo>i0hQ*^@b|Q$S||boPUbnIBiQ&7Dj$uwEN;Ubn|CL$)?l?y=XhsDc=c=5$^N z(wK?FZ|3IdV7Vl*tJ>19T?9uxmjHWyKaTa}8E{xMzT&IiWmpvJbfEFDn_^XiLThTL z^Ur1u_-T=v1hb1b_Ex{H?hkfFC&!} z_*@q2WtaO{Z2WH{J!cIMZ|#LW8uX*WX!~(GFL&`Wk?grG?|-Ihjk;H{==#OxN5U$N zRLtA2$CDw8FYKz1a>F{0!P@WGX=K$to*MtZzqT)I_WYW3EaQ}qpsl4g{D3B<-^Qazul5BW$5QtV-ZSrrIMreciX3nU0hjV*jeQX2ri zUovLizR9;|A6Zcuk-quv*(iU5Es{IM-gv#@9O zM@Ja=xhHr*45Q`#$s%CB`$*9Fp2Xo*L2MX4z+VR6*#njiHR5@Q< zq_{KaWYy7~4?@Fnnhg||$r9%gC0(qlZCOx@9m2r<^yBO5xZU$#34Z?9e&Z0bFL1NjE<0D&q0u(zfqg3Zjls_oj(nHn$lws(i#Vb7t@*JF zBU4ub&}$FydzA8u>}%u&281sm)v{4!Vj67=XsbTynt^?|Ue~>dWxo=wNbcj}j(17= zw_@O#nP+%xOO;D@5Gdmuh0pdU45U1U;xPeLoUJ(hj{6Gk9)x0@Ut1H|;xH8rGcbdK zoD2>c@WWZg&==sQuY3ohR$KlVFmR}tybTRij_GUcm1tyfs%F9XA~8M^ucral9QCwg zZ~pSKb09qae{}o%rYCJ7<%H}yE;q8&?8-nJVR1=V_uiSlE!4 zm+z2T_JDdl&q{lI#<~|Y6)K*W;(jlAm!^$1E6i~4M&skxe3mNt2Iuj-5+)u~-UDa6 z@H`7Hj%tnton<%L6wd2)kS3e4R~p4SfpUuU9x()SHq#1nG z%k&D_9)r~5(&&{Uwd70i^4G8Q zH+6GD)Ujn5$YI=N-6l)?b;G9L?v~he(@bYGkMxDVC=Q8-teDW+3hfI@P{<&+a=5dG zUWxq=?YAV)FxoyG0=%jd3UAZMBc}7AxDe3Xm&|E>gSh!)bc8{9`mv;;sBEQnX()(Y z|IB>-5zRb}-Q?ClMuc1oLGGS^%B<}JnC;pXuQ1D@DOv+@Z>vSD)LU^xe5f4Oa0m?* z)^^02v-&?l_QsD3Jm+j#i(7nnv1p`~uu2r|bCc_~(y7{dW@!g!c+NidsiMiudH_-d zDxYw9jCSSNtwPTgH*du5I>zVkP3>euhO>PHf`JxdrK(>Q^=%R2QY`zM4GfwoG`+ed=`@yGBv?_ER1O>HB z-m3fM>q3^*7>mj;q*6W|=z=Lpy#mWL;>xCU*3PIG!Yyx6|M~=>xooHsZrFp^+zI2E z6osYcxY7DuzuRiuOw9z&WVzCMW1BsoB!rXpOFm?Cv5M|}n7-r?Jqa%=?||YpOg83L z48TA@4ul*IdcLqb@7u8J4e8s*1ol+1?8e{XVW_OXdujy5}} zyX=D}!)B@851@ubyaCL?y)6C+=Z#1S8yeg84=f*HCrARp^lq$S)E-bHzVQqZah~nFcmONFtaL~`;YO}Xq z&usK~V#<}O;|J_~u{-32BjpM=jXGjlXVJhM$D+76W5iAtz+1ig@~t`M!`Zybv5Nn~ z%cwF#O4}XCZv0-SYvJ#Ga6-i^1={69rUbw0Gf4>vyJLMaVU}tG%&c$Y7C8C=ho}J zFn>+?_L25?+$hh|eS755iflwarwjy|+bU=hJE%wFoF&JR>D+K^(J5>t4Xchg19!`G zI&AKVG#*8^(4iFxV&6E$Dr+-iUnfVpNZK9bvS+a5G;NlKqR0SLaf;uPeK+{lXS=R^ zd*=j30!L~J69-mvlzFR(0Mb4y!S&V86UU;02SgkwenAe-clWnEHOftMLIxty$a&Xwj+S{rcjeyUH$W6C)yC(f$ygSzdv=I3xg z>IcXkz$X%ykRH}OwTlB=z4P`tuU5E&Ntz=)xYM9-w~|f%b@JOq_4{wa$Re7rkGqOSCzjYzQ>1K5#8(@wD8Vn@a-h+Fnl@g;t^6X1^h3y&a7@sJ)y@56i+Q;|Dg> zGxE!(awQHpFHeD`emV=Z@=T(yIq9vh)H!ayNUk+;+rHF1+0ZvTlE|$;{a9M>bWlEN zFVQN9cFgMpS}2X`g~#f=8---&akM!3hbk+(Rw`8Nh8ZoYi<6n0K*VA~RyD%jj{dx- ze!j}5Bmr#ZWmytt-^xW=qfv7RNb!>5gJs1X_Y?&-p#*Wpo67PQrxuxx^#^8hfm{|o z5_#)+4gyHTNKH$0%OqV{-56>R+8liHMbm~LZaA6|>XOIDZ}%r3XhW6=dDsR}-Ph)I z3SMUbZQv}YH94BjO8pQ{u%x9`+s7_6eb#cCkIPx?gN)}^ratnZriS6NoR^leT&-sk zBP-sQtt7me?ldnerX>24&UXa2@N}*T#p0{F%Hk(vlBKce_lJxf${^x!vQQ~j`RtM#-XVQ4(3|^nx-$N+d!Xs$fQxU7mL1Tc>Ms*2k3->T zjn^rM(c6FJ`}fLeDpUT$z_7Eh3IIe~bUE}4=N_FIvC~gY)hKBM4<4?Xj)K=2fNc(D zBCxcoemQD+Ict0*!EUCdf1X{i-7K@*d$-k;GvC)*GdZiKc0lgpeJA^;|CZcOXy!P zHKUgme;<-X<=Av+D;;QRYFyeRD;yqSX`z;J1v#e}!|9wuX$5KbD(TQz?H6Bpkm=(p zTz}4vm6o@h$$dLVfL>J_-N;zQNCTH1q5qp84$DSX;7Wp@o^AnEK z81+8|@o49N$(!9>tIKvyi^E-Gx$QGL6UUR*?3YD$ODUr(yR8l$_T^_k`CPUo7FH@> zhKLR(J7c;PBvAaDW_d>7gBitm_48X1PhlMAmf@gj@*m?h9%EZ1G@F2DclquKqXq!L zlqb_ZD5sL;vhcwFZdJD?pB8t>7k$?ft1|%!FquSmVk)O9K|Z?+=jvjKlcXIn%u(Fe zX2{u-+aT0Y*01D^m+S>vWJf>nn8;DaS*H+a9cb3n_C2d)s>j|RA~6K#F^y#V@6d;F zD=$rD$k4YVF5i`P?q|#SQIk-$z=SHfD@WEGv8#%h9!+7*Kh0ykrc$7YpeC4P`HYcl za7Ee%#zg|mhg`KpsD=8Pn#PT0+1hG}j5{TOeui1dxIV;09Mgu3y|ge|-azRXyV<-b z{(IthpA~ClX444lL}H&Z zJTW;ry)H!utd8@rin!Oau_+wZn>$wWwsc`-D%K$d>?il&^fmBxUEu@$*k#jDDwF(h z?dosZ*^ioJl#_-*v@sNAJn|~ZBhf2MAryNHl}lA}d;8>WsYWSbAd`!uDG6z0%h~_@ zQotBl5mk7uQ;YkZ*-vGy-6`&<7?vPt5`Eo^FkVj{FJHDPB#rzrDOAKWmXx4B{_FeB z(iQ$fs2s+*e}Lefg^8tJ&zSd`thI=k>O1E~Kql@H1R^|1eJd2rP%hi6al~U1t^+dK zd~Fw%&3@V1n^TJwo*~f=-ut?zORE2R}+>IY!xC*2KVi%w|Q+dv>nnVg|#P!@^*~n~nelkhK zjqY_`%mJ-UD7LR(_c`45UeXuL_wL_cl{l;e-w)`I=$NVAWeNi5EK;;jt=u!Y*Ao{; z^tZ-aqlv{pK9sBqTa2T2cN(bAfTaMhfw1pJZitUmXs%TO`B~w5{v;-cJG(3C#?f)? z@Lat<)yYF%VwrMX^3QACk zs&C^YF)bbUc-a~q3#DZ2PfphPX;d8j9Zu6`7ADqQkViUe9OUcZZxLFEN?X-$7Q6%7 zw{7y@$bT79_A>d8x7Y36fI3upxV(!1Gw%U0NLNYe@62Wf}R`@t3vwFzwcbBDy+L zR>jBu0(UnBuV$_`B>-1wMmPJDAo6*9F zqy5aNJQ{ihgGVtgX>Fck{C*L0KIz>fJGOH(JzF=f4FkosvkVb2qR(sziXpde+Oqwi zxqp!&XnL{Z`%j;?W~<+PEymYog&LrxoV49V+>Hb%#Kc~@QuXWq5^0O^Shdrj#DNKY zx%--GSS=PhyJ}mG_O28VD)M+r=Io**#P}HU<_jA5EgW6<*9%04rzfkr<_SqPUpY&| zW*GASRWLVg@|R+W2&&iDsPqAD`hL#z&1B(#465GIZMP}7EL*yja8h+sQ=xqBIl7;6 zDy-^{(7bZX$o0>wxU%9HTjA_KAE#rkhDMB9`zta{(tCyD**_|R{c@yDK2H{W;JI8p8^ zZ5n0NgBOf69-(sXPbl}eo#*|=2>v4ytS}-lCor1$T)pO8d8vxl%Dp&}*gMZ^PRY+v z&CRXK&GoKTLl0R_E7h-*C6-T=G;c}@uv2+WP1YhHMs#F!l~XXf@qC@yTH*@t}-|@<&Plf;fhI$=l}Q`PR0>jU5YbWAed2BEC2p236Cz9E^AM z@tn&qKg`p!=cWrj3|E}&>hoGMoIF~oC94`L=(Z(NLH|P9Dk5*gAq3QegaUlK0Oeg0 ziATTfEx;Z>Wf*ibMX;YwX+ErEC)EZm-WVR5N$BK!%tTcN(TC|Sz68_vKq zm^lIU5JDQMLII%f^D2%n@j%kqF$vla9(_A{(I~AON9?M#SXnC_$km;NdT-lIqbPdc zaiOBe7eU3yQWvjLv+=V@ny0qa#py$D7!r8Y9w*f*M!-T!@qNeQPbx;HvPjUy zk$F~9s8~~=+3i6|8=|$>j6Ns3a0!Y1;rnHcX(v}m;)6JZI3mjRIMpU=Ry(MCvh*EU z)7SC$(Wf*6<(X`{WWZfg|pnZ`xV)lH>^mgyU$`nnXw{Aobt{|+8iQLzPjqgbI; z2)2z^{{+-uKHb?)K9yRxeLTKB{C6zL|3!}4;+S9YiH_qFZ=f@(gut4N2{P~b{#;F~ z2%8#!H+*)&_ouQ7#2%Q&#IX(j%0HNN@i6q=T=A*1b^RL{Z@D^Bpm;c2LH(xmzI%_} z*}{(~K|WVlLnZYnL9dKDGlc@TT!whii$vg{2+2=4kb!A?+Amp!SS>YZwrM`*!@j`L zo=XzttlfH^rRC|6>nIb6P_^T;;;JsNDpV{YCFD~BB$3lC5CG*oqGvilD2J=t=RF7J?EojNNo~S< zbiT?`@LWaKkC{%hZ5c$Rz%F56>;K$AkGv9M28Aou5lYd#`#Bh_8z-q};1U7w%+{zIeTO)>&%cUDDIwX5Yll^8?Ig$W}v>ymnMtt7XmL(d^4PQ-xFV@UYCl^zwOw;STXf8&&+{;sTpFsg974VT?~KJ&xQ#g>xd& z>Xnfl7c?wodajd8U5fPwcAgfRA{J|-ET^_QM7e6U3xj}X%0anPO03uvhRe@B1^3Bov4GW!nJxXy4BT;m-1Q3Gf*j!q zH>~(ZS@$qo!+M<7B&gzT%; z?3C0Hr}6F|>&avg^Yi9kt(YY%Pgi=eBM-Hm{kPt z=nRHg{0iOG7ThDY2Hc|M=qwak!9EMJz~fWme_zWX-I+}*t!Vn_vQG>lQAimmzgPS%#09*dNjUQpc@Xh3-ep5pxHgCX! z9_UvtyqsL~&8(JYSz@~HL#|)RP{UlQmiH?Guw znz)rdoWb9Sx!)BgkTQ*VIVl^MR=W_X7FEj^r_KD{SAC&bQ5ws_Ez2@YbihI{{z;>b z-^eqwMFg^W`z_#LB{BG4Pk<_;D|x0E0q5l;t>1QLA%Vz&9`>Duq4;{jc<8Lh9iF=% zpbk#Pb|L3&uUD29J;hL?Fn5C{Eevg@p-EW@x)Okg$ zkigB5ss%IZ+&d~+J>Yqrz1fvVdpS91>qV=tRVIE3825Gd)DB5Lc&`+2Uv#nh=KY%; z6h|y#(<#*Vg^#X=vBghxPQAKEDO1xfwZetPdbqJ4ZTiY-0D<>6&6EQCeqD5!?cc;# zeI(0bjosZI8c1v0EfnF5xdXW#({s)A>T}evfAI^&B zr^|VAL?C1gzs;Vy0q?v1INMmsR{gxl`XF4f-jS6pHzs7q&88d{l>Y=K1ooPY5}%<~ zvjArM4!)b76JhC^3$S|`b?yoB$#qRnoNca*tNC>tL_2=W2D*2QW!NnWpuoKKY7 zP0a&_h{SbakAAEt5K>kbd`RYYCmqZmCD1HYw)_Nh7b)@Hzq&8H#(KD#A88%r$Gdve zcjk{OBtCUZ93@ntOZ2LWGZ(->1>0{axG)M)W>rOvy486rBbP z^8nv!QEPj}+1llfkeM8ceu&QN>0V~{tAST`<`?e=soKTZr#%kOzZ52<t)ezw;{L5rryX|}#_E?bb1Hq}YKwlUd zZ{Q74L4hQz0an!?GaqT?akaS<4gf*!${U)%D<;hxjuMjfur;uR;?2KbQyyL!CTDaA zstjMR|Jik$`z0pqC{Ga=>XJ-yI+v?!-!ZuPbHCx8rO%CLE5INsoH!erC`4=0(B9E_ zKR;JnmCilZl}f#S8uZM=tAIbYqS{V9<=|?=o2-kwf2qq~ud02|pb0T_5wJg{v272G zqQr8st5}8S*omfjvSF3skF)sg{$eC6SR7{ssEydrVa$1*ugvAk?;-=V zzpnI-(WJOnF7K8u?@=K7k;;13tM7cl0QWFLo&qnO&Hl_%17Z8C@}sN+w?JNX<`SBR zJ}?gVXt|B-(amPxs}=;GA@~^q?b+47UNTI*9nhb`LZi6xE8(@sn9E+}KgqMIdI2C0 z0qoe)tIj4%Vn<1A-8D_NdV13~>{j;9=Dx(lf8@Z*`V7HQzp@0joYt(_ZhZK^@7nS< z=HqM+UCA&n(xihl*^xfhEMK{r;h?-F5m=WXCj69&;igopIC98ay+A1Ue(KIp_`lw$ zoa})=b+{<-483{qXK*@wel=j(mOts?C?r~8RR|?V0Hz$gG?xt{*mwr;mp}6Y*_G1W z;?pwgnJHl{e}A+?dJ>|11HpNwKI_(pv4Oa` zRSu4Q&9r`X7YtOX5BZ?&N1lQnI$87EvG z*Tp4k)I18RL&4eT)+c}Nq@y`K!rv9l0CW0J%DY;(UdZHH_Oosb1Hsqm&raQ&57g(2 zLrS@CZZ%U7FU0Eq1R{D8pjjhZr0_wP-fEnH`rW6f{h6s%yC4v!Hh@-*ChruTd=;`` z*NdqPrA8Y3yaI+iVFkIxe8t?;&EX>(PsVx6sI+gv?*>pqtFnBYd&v%GC#0LJWJ0vt zUin_sFllgaew%VC`gsq==P<6L=6hqJZ28Hpt2GZ~MV2{Ezqarp6jnPfb;XZ6Z4~-t*~+ z7OfWaHgIgyRAkIwoy)0ZzB4Az4!_=TgDqnO<|RLJAIjp#rQzGLTr5hk+@bY#VeTcWQ6*;WR{nJw*@hPp)Fa=qm`u^X!3nQguOcxH-T zuYcEC^7JSstr%Dpr2xv3MSb%7H`JKyYf)45yj%UeUSI@F4g<>Cr@OfXVG{~vSF+Zl zIQUhQQ_7Md3)=l)2&M@?=4Sd@u{o+({VcEq+Rc~#wg!vXsX&mpm z06YCS3nUh6wz`-5EglVg#EqWZ2e7>h;Gm6gBA`m($xW=iwih^j4JeW_I8D(qics%t&m{`qx)qNVP4k zqFmM-$Rag2Ls;uW`D)w)#a)(z$GbFj-j%(_#5!Ik3|P6;{tE7%AKAz1Ih}77Sq*(S z?B=L`jWh;nf-Ul^5bQ8W2l!53DsR~mHiswyVc$x=Z@$d!^Ly8pZO;6FofDwy&aUAu+PVYc<8AEGTG`Qg^1 z@^R94Y`$Wnz)>?J=a94n1$NqG9B+jKY-o?8u95;dc(jZDWFW< z0_?A2_kt>K7frpS=cum0UkRfL)3BC-Fuou}HxFvxGfvfy1u#CW5qE3s3Not2)Z6{g ziw6^ucx(t9pE6qdA!Id3zFZ+$naiP8&x3TYDviVI^OhpxMXZ1N0k+Zd^GNh&apP~$ zGhj>js0%pa9N&{JZMlvqv1cz5i$dZaj?i{A%hby=Lw4f_>U5KzE0iXUpSh#Yzx)60 zgIY9{9ReqNRn9ydNw8i5!^vzYEXMRtOkL=;q2QTBLHUpSbOj_yP$C}WT5t4uzPb(K z;})P*jr*0>pr$(+oRsv2uw#7u>@b{iA`vcu?y%C*aS%*jY^ePDAAgn=l~3kTRgH`h zwYbnk1i!_fIYCi-OjV$r@*5G`HY&I&- zUC`KEYpFXx*5sVzjclBC#8k&W2C6_nqN#F=2mQ;jq*RZ9)m{8P($kVX1C*y-<6q}) z(Wq}2cHWAr6N^a>Bd4FJbzN{;;@!mbfez zjh61?!@^e@dPh@W@W^;+3U^d^X##mh$jkLqE`% zup7lKckSB9Q^1(-WhuOG-cyC`KHHjo9+VrJdENl3S}VJYy3m}50~G+o-}VoB-v$p0 z0f1h#xWXcsyVbRF5y@}hQ56A_XByuC%O;fZUR2QrO$3}dE|6FJL&g&}9DG7z0h9+NS7&|s@Jlz^HrVz}N~ zW5fH6E2$af6r6gkO?*It_+R02x^cxpwlllThReZ3P09{wK+ik`gp0WZ+CR0BPQS4cK9ydnd~tjbH6bDKv%JO0 z`uzMCTq4bcBu3yU%Yl@a!YFC`??gcmov2~qq z3jH5D?Cg(pCMAdd310J9^dE!|I0=~*c%>z2L*3U5Hh{B0#kYR3cbkZ8xR9+8^66!2 zmIan8%-)V&)!;HG?4>T|)8seRts?$~1`#E+XLF6emK>wquP&#_ z)4Uuzcn-Ahbjr|-5V+hm=4z!iA4s9y(z}%Bon0H5G2bgU#|L|uj8Otbmk0&w6uXL_ z84bAD9JV@}ge!pRS4!q7$THRBOL=(0A*Ks$Z_nLto>+#^zr1kv1^$D|r+jT=%L$w^ zw+?a5bG^Smxald6 zF_8luQk5MdsAF{4UB7{r{HqD`bjZy((Z0jy@dDmc>Tm1?~zF;2v zJaqiPkK~Un0sG9cm*$-U?Psv0WL;Al-I?SZ$6IepBZnrN+~ku+9OVwOZ4}2P+}v6V zi(AZY&yP;lQA|pSxMP&~f%JDLAsZ>R^kNn$E9j(;sv09B%1xcC>P>Pd{CUvz>WXOy znh?81cI|^ZynAQaS@mTldgx9DH3#XEdHwLDx@Pyvb8KO~eDT>Dct)xCefS?haR#Im zDsYkPU$#|D5lZ*Ze=r)Z%$D*^TSpe_mg{ES=aWg}RW$3;6AjY3{f}}(rPV#z)cG4Q zE6i4kvU4M7PAZQkZ*_3~vei+w|M_O5p!*JRxY12iEP}T~JA{>ch2KJHSpY>UxQwmB<7Mee3?ouH;~~e1)rxy>u(8Vat$93koLAAFzF{ zDgCHA<<4|VbR%W71zbI<4;}z+JCgA$;4(3Yr&fW46qR!SF5pS|ekK#qSesD5F%~TY8hfPIn2l z3_HAv1V+^4K(5h4+B(UWie8WUX|#xK)dV7TAp~S-phW0&zvp0N$6R=t0YoCGc{J)Kwqy;tD zR8?YHgEE#-C{2-yc9cg52rWbxJh?ZOCfH+=59f-7Ar3It_jcZ)1|CTkq`5n5z zujgc`70m26Eh_W62VSk%J!Af}>KxZ1WySlg)!Yb0!3^ZB2Q~JoGPe3B6=5{tyYUfg zL5s294o~GLHn}!LH(x2KjVYN@-w{9<4mmN>u60XH^X`=ePC^ec@X zQQR%bkm<{J?c+4C_US2Z`d&Np=rZj1>S)C}S;xC)=ALhfok<&^TOHMw2OP@`8sP{@ zlUw0vA&+X{e7UH5y(l}iF7&9{J}v``KofBSzSRPlW9*8h2HCaG9biVULZQ<7r%tIn zVl-$+Yo%f!L#KRMKb>k89f)PuMXWZH3MX*BrqeHdSE4T~Fh+t{rHU&H6moZC zgIFxpGhKdbjp&xQ#;t3Ad2s#O{(hlXqqk7-dL+{tz@|%~QhQQCFMpA*7XhMp9Fq?e z;3QRX>E<>^?Ta7O=3pWl6Uk4kUPI|55qo+<*RS9#d@WuanR$AJan)^PJ4z{;aD`gP z6JhTN-@Ga~=i@NGo4+DIFxbj(*nXG=Jd&!?Ex`V`w@|mmvaiZd_~Q@&dU?x0t2VnX zp~@GaR>+MLtm1AI80K1P1Frmb^-%>^hq?On`5x{DuRban;8Ojok8JpJs)0|E{nV-Ld4zbR>h`#_U_m zeZt9JEN|eh;$(a8Rqe8sUzj+cD@TPNX#?L_={3du{zZR7R&^R-rmOE>L$2xsXpA{^}l6n z1QfnocfHXkj|XXz!|@>6FVI;SX`to(-GFgy6A^7z(Nv>Y+%g>?|)jn?R0B1mG$l?E#nXfOoioJ02xUI<50-Mjvg zl?VCizY>`z`aZe|klQqGq^EhI%F^~%RszRq%9NhbLcwkdnso}ZhD0i_Goa~8J3XCWr|}KkWho{_vX8G;Y=(Fsr*H0~cQF!v8Ph zm73|=F%AX#+*d)ld{wdgj+-S($s*DB16QZ~T+_onmp!zj$%q~MlL9J-CMxaY2o^CK9IDRtA5!3 zNVf#_?)@n81`*38e<{B^dWbxe@a!4r-~(BITopwO*!ebg3`-vWdIo) za02EwiwQSp^vI|Q!*ao5nd(VxOin5_6O^Qii|*Sy{d5ul?D(HVG2i4y$J)UJTF_cR z4>OUPBhT3_n0N;5JQginIsuOYcb0k^H#ZfMl6Upp3nGRXJQ98ZQ}+8IU~f-ofkK#& zOSo3@WSOFPWYc<`b%zC$5tLz2u9AYW?s;v`yzKolF7@H>18YU&rbG!C=Uj%3(8ck( z3^`7n`gtcSlQ*Z8s?}v*K0m5^s0NtX%PaG|sVuj7uMoZnV&BW?x@6=H@IQbc_wFRV z5o-O{r^Huy0kqZ9qGDzrF=-=ch9h!qXrSbyxo{KblH&Lq+G?x39z$!t&<;af8!EMD zP6h(W)z_E8z8%U&h<_x0ASakN?#B(N?+ZwRPjS$d#AA!|Gz0QY+b(mTN@;U zN@H3!eTw2w8IQfx`pMWR>RV^kqWOWC$2@ z_{r^@g?zm)WU7)^m0K7!Z8J)vpf{PySz_J^@KPR(RF3U>wyNj@kA-Lv!P+K%cvYj0 zp%!MRh1wtawlM&t+Q2i%@mfB))+W!!+D8Ix>}RpiW9jxWpN$W71ccgee~bi$w1MOD z_>ZEoh*n-Hh)~Sg*G=cRh4ON*+QnW_FDogm6den-x18b5Y0|6$s`xFfGX#n6%7wgK zIrml`D_TXURdGoMU0L>jN{$92z2%(KRSqkE100SUIG92}{#MJT~ zbR+849|J56DC6@dPxPNJ%w;22&+p#?`bq`98+^$8N#EqhNqORT58hlGWk&BC!K*faX2J7F<(A*%CC8l+c!3TU>ZgthyWCC zB5DBsRNyh2$*|euS-HIdphnkB?&N!oWn>zNuMEEBkD7lq9xbn?K$c;X;9l)M96QQ6 zdB0g5o}k65-bPVdzxk$cKq}@`zMv7l(SJ4r>WX)J!<}6*dT(h}Rz{ssJbMg%LgwKb z7TK^=`a+>>nxgp;A(-vh;!L!{XDNw?0;TPVo3quy*DIf0Uiqj|ERJQ&9IsbNq77VKgs7 zcE)mWnYxr+@t-vdg;ojj;=pdU-Pp3!X*V?D7J%rP&=1G}z7}A>pfXJjCno9i)PG>h zSj2=(-B)KmUwo&6*Z2D@25?iYgc*hp zdAeW^hv1M3uTE169wb7SBLu|h^ceQoTh5~XNbJ;mXQDpwxc5?Um*Entdg^nzJKWX( z%%Sg4HBtdSuVGIF1OEhz?}na)7sNyKk)3CKH(=N$5tQTOCrf(Sp6SbGLfjU~>eTTv z<>iia37`N^{_3<+4&eNH6SKB6%}`LW57qoIibP_{MuBsBNP4V=K})b?$$!F1b`8uq zm~`mh`9dRds50TtwpCsJ_$6U3XOH?6n%GuoAyX<;Kgs32_tNrtu1seXL5V+AFnh7p z=YNNgv)@84P_q`Pp}r~~Z6?5qsO}Qh13;r$%X=X8g^BYl zdhiUUZ&H@pp}pD0YoKZnPh9ijI0kqaY^e2%ollc44Drb#Lj|=(!)t6fV6I9|k@H~f zREpW1ea6*&Y>lm?v_@c0%acRH+OTs^tnd#|kY5Y0`-O2`1IR39&hPeD+QFlpK5_{u zJTCEoB9w9a`t#Gh__L2>Z?K!3cnUzDhF2l<&L>8$f>wU6n?=gT`50VE@XYV z-M9f$G-bgQ>YCOXc13%2Jb2i#W?FB1k7<#5Uzbnr69shHMTuv=B(L8Z27U|9A^v>8 zgzhFL!sPTp26QMWPT#1S$cjz98-f);4|+HQz8~_K?7w|0s)hkGb^q|UHlDs7+y&jK zE44~4^`VhSGGxvv=s#1p={W53k?gx#yss%I(UcQi8rave9*Ase*0vP(lUmSd?6eu% zpzCz}Mhn-WE`J${v{+0EY<@am%!ABK9$LPg+5zK5oTu z+u2HzFcwEx(YifLV~HFU{CBBm-k+kssvlRGq0C#VC1L*p0B>816gSr8pEG=5DfK?h zAA|4K+H8ag7UX_NS_7w83W=5S{@em3biuM|R(sDdPMlN#!_L!iGdAKDP~I4@0ubFR z9MjdZ^>N@OdTud=R}^WKWBbvD1G{I;%QS1pG%tjrL-U6%5$hf*2j@B7222qky2CnxBX#wQr6!-``h$7~csED)D1(P^-;Y0}M4G&8 znYX=R4j~T{U!h7e%y%!*s(-Xm{|=q7p&Wz0crZZvJwiow>8t!K=+j-VOmEVWas}7rgtJp3(jx5k88~%d;78HsiPUIc?=F@7Xk*1UAj)9bMpnqm9Be3aYGQ_v1TzTH*z=tY=>X2jZqdlir~S+E z!Loxg1EB(*tB{io1i#OnpPo5XmsQL1R70?aw(b?pXDSeYVq|&IGT7L!ZC3#6A5r!N z$5;uSg=g0Rs~SL=U3Wu#eCD_7O)mQRM}D~R?)|G3e{>G~edpl46C6QYk2rY0(lHV} zlJ3X9Pwiy4C%p$AeXkQ+8bLu~e&VF1W|{vD`kRIQjT5EHE!A-YByv0z$&;GF^Rra6 zL42X(+@!&8|Ih3TyESr zag;kQ;NgCRxJ^z`Z#s&Z^h|kgbT(8%E<~QrQ(J00q~RxkQZca#ATptVlJou2`5Moy zKJ!O!AV(qLNI>8&&(fhzc;$%au*%#rS(x0?u@u{O!328`PcWP)Ls95> zrVDR|OyzSZD3u{N{K^LCV!dV_h|zRBrj`f)Cqq@8_=-Vx_0O8t--Pk&{zvu(KRwrV zJRS6k>wcdh^dCZ3eS|b2TGjCbW1j~U^VhEEUB4wPj#X>aI+M0TR?b^;`?^n<1r_2% zE;i*YqO0?Yh=xLWkYk3tartnre}2rQZ>G#02-yZZl^yvg3fgJ)t4paOvL`EE@d_N0 zkP3!X#x3SqW^KLLVprd1jfHXCb@?Ab*yxW?L`v@~6)51#pUlwj43nelN7uA~f+s*+ z+!0OKfdDOX*@$v{2&BXH>t|;O#_((_V;pAKRMtSns2L}mR37?Y<(bvVe(j8mdVxR!|w4Px@* z*mdxjI<+~_V{kK>_o?OGi3=oQpr@}o9*yWRW=QZcOFpUZxvU3*0gvVM+Ksi#f^CBW zAPku^{|L1g{}^d1fQtU`ty(-34xA!Sp=Z=#7;O|vJ(^>7FS#r1vW%jby)Y?3_&B;X zy68zKYOtK=Qu(%+{fShJMG_N=qlax~Ksh--K`f zoB90^_~g}8cioHnpNn4OCO?0c?nZ{{wJl0mX;ss$99r4rPk`Tive868$ClMd%M~wI zr6U?`pyoOM_R%h{h4}lT+v=2qd635WecCElC5*3Br52>$2^aDxC?cyFL`qO4$;}>^ z{Un47zfi?z>t0(Yxk_gf8%suz-uG|nZw-r;ckVho`1b%hVfrPq9Z(03qkir4a=fMu zdU0$6PAD|#{Q-~z2V{0)L;*@A!Ol1Zykz06-e@F%noU%<7ky>6*3=tnn%`&(;;zYO z%JtdZ4M_<<)^@J#C@Uxt2NK~n!QYOW3ZLVP`dW0nXqrCp$&vt&tvYpieN8CX#veov zjhXiLKY$PNV-(eMm_6VasV;XgU2lTOJ$*Yz1Nn0y=7b(>P$l6LIPO#Jzdh(2M8BJhQqPl8i&eCjSuc`#V}m~ z87+@!I*jf|9HID8!mHYJU_+@+Rwn;dtxE$==>bNCY0P9v0#MC*4&w_@Z85d75%F3< z5Wx-qcvgStq~E27E^G1RxC9yA`aeW{bwJe1_cr!b5DXdw6%m${ZV*xFkfl>vy1Oj8 zap@9)B^RU{u1L3Zuhim_QcJ@-yL-RC_y7IOPMkS&=A7qwhQ;kHSuw=Cv@-7r8|iq4 zebbtgA*FYB%45+?|60JaB)vn8Jf=rof4~yS#xQ%?E^zIxj$LuweLhk*cK?fC>uzjK z*B3tt4GzM!=TAz}U@w%xYuaF=7L`)BpRpcX(qad#1Yh_`NQbv#9(XP$SqTp2uzbyaPDV?Ab?f7fQ6QjT8iwHz(MwbEb(=PpAKh9V@_`Fdi(| zD8F;~1Fmij2F^Wd0-Tx8OC`cZN}ipk11a3P12J#|tp>4R?@&YZ8xAq8VzASEmLofM zT#mLSQ;p^7U)$|OcKV6<7Eakt0=97P$W-uVj%?$tv5Q1n zjdIh@^+SsoYIs@_YD1@LXH_Em68Va?TAYSUE(I!0x3`4N&bNtZQeT`8`mCr}D_Gj9 zryvdJbv8w4u&=SJW%+2-D*v;+gn*QXQrt_+0u>F}bktKg=>mVINqnVFKLWCUvPX!3 z94vFZ3B8+_sZ-DsRe7DE_#|HTeCt{LU)XAaf~x?Z`fMvIgBrocI&e@kaa^WpZ#U`u zl24tx*S+0d;N7m@CUxzUtTv23ZE>TKN;vQ4TvhPMV67hs>W8x5eUHd!wE=#zGso*vBc2{A5j+oT1g41rmh!J+F z!>L6{o4fC{U+$1u9~P@2DPJCHRM<(aL7u-P@;L*Jqp&eMS;;b!4X$@GG``hsr9IX$ zcL2X=54qUgyU^28qU7n0-*%rtwoA5yD21m!eDJ0^^=K!JskU83qP-vX4K8YZa-BHv zEY4`YmmLFGDc4*6HdNG>&h+YTALRY zH+V8ogtEqC=7ZwBpUYLh_xWNqmelK7873T;@$wOT#NN%)cQM7dTW`wh53T)lavAAC zE;jl3`H}z1%hJVEKP5Zyg8^|{OVzgkYhdmW3htRg0oKURbXH6_KbeIJC9;^|n=S?i z3L?#|3d)QfdzsOs0N@N@&Zmg5>v1`6M59f2WvzD-O(G!?H&jb+A5UF!uPDE|=ujI0 zS?=JipBSoZ*guhv7ZSdz9vHvJPn9QFze8m*N+z+F)Jz{LU{z7&SHVl#J2p}gpkB{K zBj{zRXc^9}K3fXprb9Op@{Z&Ug;M69{t9qEpE`x_uZ%C5YDY%TfBLmO`$ler-i+bIC(9Lp&7FWR@ogBR_A#jSCxHC~EC%Nm&=~^@`e| zHjVdf*VqThKB@jh+=`Qodkp7o@MxQT);9LB4HJX1P{P-KjrAeWiZ zCuzb(F*0EfT_mgO3#P*sFu;xEzmweUFnZL1ogIZxV6@xpu`f1}cJ+&dHK!Y0k3OmP z=00QnXNPs~98SjO^Jr1snt!5sk9!oWVJ32urU*!wv-VHf;kLFS*K8Z9##Z%CDo%7; z@Ti~EtIyuM6gr+BwTJYs)FuKF+$v~ctCp092M!~tuTv~>TqU8_)DX+&!h`DK5vG{E zkG0hvESYVqYP;9@6h+vH zklk(70f}?3*N@{0<@tPOhAx#>!rz+ZsQN&jnY4XASTK8IU2L&P`=uyJ2+S~?3DHEg_JJE z$+u@=WgT^cLQ}jYl@GoP)APn)yzd;HW|LGaY!tH)+jj$UNg#ok$bfVe6sn#?V>Sh!> zfTdQt%;;a3C298Omam@kjcMPs0MyRW^TEGTVe_5LnApB@x9h~a|1MBMLnYH4L-$aD zI$Xbo4G)V3OX{CFRSe#LzV99D8PI=2-2`DnEsa`zsH*yA%4G|;K6}HVjW9Wj_%t;he&$}lC1r*?7LGWC0N9-^k|gMWqqo!K>jx5D&Wy21s$#rAda64-@+knFE49h8mF)oCv{vw$ZFvEsn>4p zyXbrTo2y}rn^?Npb=_uPO&`n#@!7n*RfEV`6#w>Qo83nIa#us^&l|2%XXhFTe1E0Z zkHjx-D`A^b!WX5O-a@;z7B&HGk)Nl+_uzwR>%<0PO1ir}3Nti(mj45>P~Icu)ofq+ zo)elSiS7LczC6bzR*D|$;`tya=)D~!tu)m;h+~LJ`nc(q^9%mAk3dhpTYa8&xNfCK z|4JIMak2|2OUJq<8hfjK0H1pmD=GLtW|KT%+W;%tjysXO<%#F^^%2DyHSr`<@BL^x zJ7SEVf^vF_YvktKD+u^_U^}kYpas5GyMn7g>I~uYX;;X1M*8Po?tHK+@JZYXM~+(a zaAg$g$rhbgD(#&1U1!e^7ypt!3WBrV3~|jmbK}i1l)D6pDk#|ybic>d3C*$8w&NX# zg-mWE7w~991-2o7VwcsL;{>KkY1wVW+ox&A3(7e~?So|d#KFlypdv}{I_nl|QN0W+I-STy_=i6>4;j-`x>h@TBT z>cN=^AHI?2+?7*+XbEl)@0VNexeIKrmS;$d_a5ZujoDBYOoxs99@}$i#x+Bg(j+Qc zSwU$!sy)yo@r-{LipSyK!dVF4Ls-**mr&N15|Z>PY!mMOB^WFDX!YESU-8si@e1D` ztczs%S~aW*DRTD-(kX-RHqyZ*pYv!rB1fuY@1DI*!K4?lXIq2)j5gBtR>=L)1Qz=C&x~udNKws^tWgk!Q_6#?>DOC0 zY=K&3<`E4*TfTr4;4W3dq>S_+nutS8J?cqgY?Q$wuT9;nU8vV}2|4pdXKb;>SQtHS z^X|)u`rHxPer4kcfejf5lWsi7z)#C-=PdD1B?9y`G{3Q|v}H@WQYh$$rtQ9mXE8ZT#$_hMmQtn0I(L_Xrll`*4zPGzeo(*V8cuZZ@I1Y0b7Yx!A}w^V{TU;y$K4S|l` zp~bbv7g{od+*_VkX^-fd!V|c2 zWU>604Jh&cL8~H#2X?w{<6F8_z5TWw(2tbapRBJ?CDK@n*F(AIhhP}*Nn1uSxd-nQ z23|AX$C7|JPRw%S$pw5N^_FnMF6qJ~+k5gew@U%Eli(1)w_NK=^lVPfeS)vG<4oE) z6|pw-0Yfhys~|`=8Z>y5jjx7JjJ>{XNwt~3dDL+mI2EIar!YSL-Qn^rk%|Sdj?X=D zwP3Y`{G2v$u?C*!PR}}Bnvd__ibWe;&W2h4#m}ZMa5nzeD*Hbh_YlnK6RaM?{`Wy# z*pEV^B{-)j=+}R4BlHQhFy_9Y0y}%4?mC$JZ<_YP{Z-&LHZoLX+5$jH0~83AEtgvTO!{`crJIdG}8+j=8FgRSZ_;!5Z$ukZ&_kghqv2BWLRmBgLi zr6(zfVe^6s%HDw3qC9qMC<{=^_P&2pM*-g^WZvw-U0G*zSbisntUHvGUE<`NKmd!> z$z#Lsox8{EkaDk%Tti_}*Hl~MZMi4M$v#u8x|LF8-f~_rz{MwK-gG>2E(Aqplbbog zj+K=uYT)A3%GGrZOxu5)yZ}H{0EF3}jf`gTJ#A5G_| z0_(U-?^u<`YMoi9`KUT6Y#nU01kMl0m1c6|qkrwtSYY|TgK<8)1uP+)hvAp*wkqkI zGiCvRMO}C-7V{tc${>3*D-q;2l-B`cz1j6y?L`>mo;xq1>u}KkouQ zXTd#~_cd0I*G5T$&Cz|aSX{taiM`KGc#b8*%}4=|Ph@cXxHm@?8OfF2SL|*<^qaTB z0Vl6~i{we{qbMfuI2-|9Y?*A>e-Uun_4hk5xofS5ktPAOKd3bRTP-L0BN^-~I;ZtM^WLa7;MxaD6M^aww=L>&)FL=V|Vu?CxGK$6G zVao6zr}rUk(}2?&&zqI1BO_Yw-Q1G|D&K)9&d%JkTK(x+G7W?(5|gdo*aIqFeANO! z{!G$J#;Y+HqmA!#%a04ALs znO7feIQ=y!j-x_3!d+iAT%L~Zpb>>V4esDvi*{Rl0yv5j>KOm$U}n@Uo6aYCy1V)! zrt;ruRm$P`|IAGFbgy!W&YH^IXhqhfV5#bO7o-EWZgH_0Yv}`M=KFT`Y-Sv|zn4a z8;g~JYXIt>DV-VdFW}6?W?%d=I!&z>*^|ywU7Q7?3J@l5s#i=|c*68&D^D&i_ci z*YC<5mZpjZkg%QGzO`-)><9m*@k7)5Vbu&wO~G@a3I3x{!Vn9$t%C{~faSkOvISuh z5U|SqcFCF%EB=8InCP3wwg{q3Dsb$1}(F(9_ zL2wsZbcUn$ec4=zVjlptwn@84r2Wv16XNm4!&M~zL?1YN=k}*7G5OoY@^l8SHQY3( zK$7Hs*Us%2Fzw$taM8|Zh9n)^B+A+2{Vr}~c$wA*=|Ui=0%C|+&V^@wO6?^XBO0-i z*5;*Cw%+7kxl;Z${FN0ofKY#_khFC$CkYH{;8gnu)>)3=>Zu6_@|*t;-KWBqc7dEpjWt6ewGFffC? zem%P+%G+9nzkv~0Y5?rqZ`}JL@BP6(0e;F&!5@ka{ew742Qnum@AY79z9jy7~afmUF|Fn<&CdeS^jBr;7=yuil{^vvoXtdn_9-!)=2p3?;)h4xK0 z0L`t#m1{)Vxl275@A>xGMIO{u3QS#Amw)72Am&=!V@He~ZG}=gIz;hCfrdw&Qn>xh z=(vP-R|;s9V1yiNeFOsl#V_FNSp&jm>f|jm+nG@c`I-F+nXUa8koQ|hd1NUnv&cW( zw^cs&D4eAY;n;Ai&*kpeWaIVWqs-IE1m}D6A-WTsAmM$dYB>1o2m!8T5_mj0h@S;A z!rJ2#So9OVWy2J8Lcn(8uHv))G?&a<2g6a|)=@R|qbTY|@_Mk?WX)1}Z*5Sy z;2`nX9=@y0@EvSA(LkI{>dA`w3<8}BMMJvc_241ZfrHy5r+0Si)bMPLdZDV9628x7fAtv84j#_|8WYNX+grpuXK*E5g~Ouw#<ux3V8Sz*6U=B-2t`-NPMW6Ql$ zv&=+{hi`Lhe1ZE)6F*q6fxg`&L_?Y(lgTLiJ~ikj#u0y~cx3 z`<9l?xYw6Zq=PjiiuGo;AFap&uce|OW34sOv-~$9@QMbHp8Io;t6Fr3)Nk$%FPWc_ z5nb&I>Ta>-kVcRea=e<4t+vYvIHhA+(vwceMOkgbc#qM9Hf+29rL>Oj(6My1~r*_EFCoH+^sMGm&y}#%T zX7+}gGY}Q>Ywq&zOU=gE$syCrQWot>ss2xM9GDCPzNyiLS(wYc zaA>rYNz4sq`iRC%xD>&1s&bRS;}ljl?EdKccOgYC#WI5-S&p6T73Kiz%rd{2pgYjI znow6k$zPg`jhJ$j-73qGJq0w0y@Us4WF{Q)rKtT7#&y(lAyV%fPH1-j)VNT3jl0%g z*C6`z%v|Z|=c^+aUuXcxiz3<+cEIZ}lQo7j@ojtgpDW9BD>>r@qK;LxAC;L0J!r8V({v+S{eXv0T(%(6a(DHvArI` z#WfWi-q;dD$48tPMZ{zuki_x+;RZ{2i_NM{M9RnX30{yho7^L^HhMu_ux9ly3INbq7r zd<<*v2i_@eY*Xp*O%a!Z@@zYaxcjo%2-X+AK#IAtRxBg7!pmHqlMaxv+rM8(;X$r< zqI`tuO=_$mmU^{0l5jRSTQ6!xj#UIY-<+~5PbCFiJZ-rl*pR52tQxN#U@Rx~NpN}T z-e|YcXp_twnY!BtwJGoWq;pLMLk0j}P+t}y&1h&yUW?S>U(qQpBxVSF6?%KdnhQ=_ zUk=_v!`@hWGeE4tqW?fMHcA8diCqeN+rtz31y!N09l%-y#5-W<7U=b0Q(ThVwZ!zpJ3hiK_dnpWAFe`Z`1pV%#lf>nR)16T^9P z?fd!1vJ1ReXt>uPyjG3G~6)bzI_;MhVY)?62uN!B!!veHf-9Pn&w!$Lm zGloVBcr#`?MB%)1wg2ieJUYp^-#h*Nkl}0J=`kC?Uv2R^sW83v+b5ro z6bgK`FuXY*Y@olRZ?}4v3mPxwjNn7Z_2_EW*${ZCY^EDkT^o(P%CW}mLA zQ3K~NmI|9;rLK0dv<&9J^B56z;jy$dm_tSHd-Rjx!turNr*BIa#2woEj?ZJHr$igY zsaYp3ylf}0(Iu;rHNw%9wsFOxEh(kR3glAr01nDx)|4ERCkjTA)kORm0V#Mp}>DnaRnW za_u43H;a)xZSHwi5dSsqUTvR&PH}jk@>w3sU6;8Ro7Op9#C)qOvrSpECGvivZ)jP{ z8Ff>>5RTWzD!**n8Pa5#=7XEg>PSrneitFAn>aD3wN=c2cMlDJ3EY>pys1gI_BQiE zL9J3;2MmZ}fU_7xlr|vk2QpNEd1>4uPgeYe6RU8BOuKzzp9&DLwn0e-w!eM!G^X8P!`U=7(>!q2vOeaEW~4a;^wGNjH(}at+aEQgKW86vfCmlbDdHAqF^Le*BgP1`46!Q18;hpHY zuS4~~mHI8c^;vGpNLK#>Vj2*s%>p%;Nsjs1tS?Dt22G>7N&)LiE;|=owD(Q>NZI5Q z2TGQ2{9|d|y+5M$LtVQ}D0QH<6R@-@vwXOg#kD)GHbSKTO&s!xj}{xa6Z@pY;)%Mz zb>kMZy7}&r*_)w#Q8_tb5JeLNYiJcBP@g%;`bP!XH{n&4D>Rz^y}7N(lXxb$0$c;=m+2=w1=>pBGU5Rw{y_Q|h=Wkom#ajM zCd`4$*cFM^Q+Aq=CjL^7HX}GT!y?|}zHH#LZ%;#ul4abRh93WyML%QL4FHG*tdJwU zXd}4t_L}GjZrf{UXnnw||65Hu@7aWI;t$bs z5BR(|T&^a%g&T1m(Z%eIUuAB!ZdlnR26V>h&V?Q|H zF3HIQBH<}WN+`9ix>qRV6V&IjsGrWL{57ovzFVvY4YCrQ^KGypoqS@x(3RQO*6Cw8 z`C#7b&28Pp=&JSp)+s{z3SmubyWAMAoZU-0LkLQ;dsz{8lRf|_Urjta)#g_JF)b3Wg1S8@;dumt+3Iy6Y#jqT z?LbZ~{pbJ`ijtVhBRI;V9$Mdp%KeN|A4=pt`9ZIqnwDoGhj2*bUWr6~{XXMPCbh3$kS9~PWsU5a(kOw*KMZ?9<)a5>T$Kp=EC0k#znlBd-V<(3v zyJdR)eNtz`dyaj^3TSh}m$cHyRWSSM$L)HzQ+R((B_CR>MkMWevSI-#@H|WuPX+XHU?b4v#)(wWUnfkMT zgetuEj?4hns*EgnKzB|He%NxLv6@z!+DDI-M*z_1!#tW*e_-?=*_-4KyolKkudpoRL5-lN?>bd%FBWEr1@ z@g}xFHMfn%-t+kDdd1Iy>e1(*HScSQ#EJX>3b)dGT5><#q)lwPnIQsVOUP_$2n4=8=PYa$)JoY)IvG9*48+`6_S1nzl8d~0 z^?0F=YQv=a&GzDB%PVG`W-}eIh4!-BlDikZaoVY>^FW)%yIqejH^--lwIOjxh;6Up z8fg&q(JpZzrj}y>0SQQbV-Q>@8z9$ZEa!S#zrv@Kj)0X8$`VEN@${Q`Gu!7x)k^YR z68(Y!P>p9c_Sk4_Nn&5L<<$My|eh zn?)@UxSDC~YT^*Tm5QOV+)wUpg`VW82)TZ1z4Wh?NrWVGvp><@!&>3f0PSQHv8(3M z(_k=l1@nb@>$5BUVa0D9Lv7? zRg!T_SGWu71kC*0aw`V+$^Y&(oE7*M_dpf2YtG3YLtTrk1t0>GWx|;b0Bp8RKEiBJg)Jn;7aNZ%*$!>NU#bW^iI<`fZTq z8r58pC#lZn#0dB9F~ju_kj4LLogOT7J|I81Ssesa36qJ9yA!#+9X3e)Bx(AhE^~nA zh|aniNF&H>41&)M_uaqkQrrMD_06+B9>NctJhGO-idZnePbGT}id z3*7Kam3NAkd1cEZ;wKooKJv#;!)r5bKC?`iNA+`=ZL3O-3d=XRb*>=Nj*Pk^^3ARp z%dH&r>fCNU2=7ycA5@*V3SCuyQC)dzt_J@EmwXdeD4_OB5up}Dogx(tX0=HE3++SN z*T)=oKEpO+St=IW45T5!jh7=JSx5Rtea3Cn!upk=jGuwTN?45l`i4YFpj7}Vv_O|T zzxacC=_kI+{7rGS4j6V&qYeiYq$hN9&WV=p378c(WT69u4Nq%6hZ^j*2 zHMbslrS)W_Yc+eyLG6m00qay<8v_(f6p+ZPafpM>~?KOv(&iVe^+A z9uR*e`E=GUPpj1@GjUpP2hO@f-5p8VedViZ)Vuh`t*C|2QGW$XulALM001ZBA8>Q<_)m7ft(Z5|`RTMDqq@TW>V}9dHR{&xD_#GosxU~7#n#c|)-Of6ceZ3+EXS;su#V`}SA$dADUYvJ0 z_gki{9R<`wek(%$ODOd3HV$S#pxov3>H zpzX-#)jRqoB^p*4CpEMV>>Z#u=Q%P)Le#lpwh8MUs2|n7h4>6pbJVf?9o7BSV}Jy~ z3L?U4H@qzq8IIl?6V_#h0l=Rom8x5W?X5C zgK6GiX=At{EAhO&QTmH0ij(`IrOd>mfQGBGItE*lylt>od_VH0ZT5tD^aE0AXuOVN z<>Wta4rklonY1rD?$WI3{)NM+_B#wB*#|@h4pM||x$c_2;y}37i#&)JwS-*khp=-3 z%}57svUkH`<~Dw34#AM|n1U0H`FJWIGaQjP6uC~!$9$ve)MUVmrij{PbEaFQ)~8_e zLEC_S3xu0Q2C5SWO}fhlb)o0?oYS{*%{S(rN0U{8gc!*CJ!Jgt_|yFs0f8C5 z#Czq1rQClKUMojUDT5-u39nY4n|SfBiXzj9&+b0Q0SP3j)mm=*ao-^L`WTm>w0e#m z3J|IWs+^AL_72ad$7mh&Iqd6_dE0R># zB)b;Bv4>I--Dbho;>mG^DRqF!5ij@l2YteRvi;(Vn-4Sg6D+P^W*xw$Q zD+OXm0nxuwY#u_m-vc3woc!O`F3Smt;uF<0Mlc9?g+fMIqkc9mCeYElJN$olCcl53z-Rx7PO`-LRMZ{K4&;*G`w_O| zVA7qGh!Jt`qmhc8s)zVa>o4{_vr|q2L_$!ARKCuMElNMamlRdOmDZhBghuWSot=Uw zO95ZdVD(hv$aAPLYEvT-+snf3J%>FFQM|_GEnJ<&iqueN4%D~~JB75tXOqan##OsN z8`1cDj=*;hnd;nLpp*`@abGdN0(1C~6hGmA@EWl}>d8Sg(5Bf;iEd`sVpiXR+0mj$ zv*54rfTBQEQqaMVxGGbgFwn*Z(ephGOYl!g+ju3@LN^AiXzI+W+h#NvSPV!W4<`gs z;m{y*|3LwkvM!n%y+a}v1xLiv>vv}@oiDLBynW9`>cP_;iV2c0MDc8l&pE+c%-nsTHaySt=Tn7yWeq z;r@=w1)E9eq~p2*?~}>uT#9)64)wRegwU})x3Dm0 zNA(Avn?!Td{t(ygwI|ky(Q1w^#<5BzoZr*51OtAD4GIXJH-+~Z97iP$n6N!-4S-mu zPqJzZH&*xljN5R>T-Wz-mYiX0)AB^0N)yt!8?#}xF@NDkywutKNm@d}$++=Yu$}wB z=k)aWOV9`M*`mrq$iPI@!jTs_|Jw~1`y&I%-K>7uKYo1Z8&*a>T=GonFHz& z(RgK1JuT0_?=DjOi_Qe*jJ-K%S&((4E@+0Vh00IZ2F_-_^GlGspb?=pb7b~c;F`q; zzS@!1SOCdq9PS{R@ZzK~O4+dSu6>gF#&&vCM#-7LpIaqFAtsC4RgeDJSaUpER|zI7 zcBe8jD@r^Daw`A*^SWZMA$H)U6uM2W`714%cUbrKg9*0&}-P!Gy<2lPs`fADzC0E5Vr-mHAz)NGqvTSDA1g{ax6e%DBTSTCQ1C+&V{Oc%1fX zqtW+~hKC@#U+@KW^71sRSVo7BtqS=5Dh{3yU3x`YIj;Fa^B!YDHz%i!9%0>{xw`0? z+P%JijJ?@rnil+RjOA@SXLb&s*cW^VQ* z*Dye9e)XFNM{jhymZfxkYolB+S-f{^)bd2io6#!y6$u@m?{~esz~BGHdFAM&faU3d zCb6_um#yTGwG86^3y#)XJj2Eh&yz+jSq?XPExQDhjY+qqy|j}PcXvmu?DD9y$54Pu zI{^!BJ5T1>*-D&X_F8r}K6h_5AGVM5?ScVYD>MkFs+jnoErKdae$J3tU`>{BB=M)_ zxyH#Cm3i=eG|u^SwqJC~( zq@s213nd{#8qx!%dzKM*!1C2yh?bWfnY>uW)}HY%5!fzoUF}EA{25mUvc>8N0?>2eaYVWGL%F0CKv-TZtJM2k8N%F??$bS zc7%+nvNSh*cVut9m7>1A2Myt4lDRTgees=XhGnYmaK#`~^NVG)QG=7&pCQ9oR(dcD zMchQ9wSlxeW&_<;x&P8yd$IultD0|B_m95Xo@p{ozCVHy@oxJW=di|h5KP|_QUN!@ znS=b_d)Q*rGn_GIuOxH~DERBj*2Vv~mNUZGwfu2&MDiVz_g;=ujVpF7qXp(}<`>u= zoG%aWY(yVHKm#vuiy_mMsoX>IlXpC#8ZiIw3 zslYw@tN(vH#1{WUK=4)o=c#3Wj^y~CPW$^Mzj*b3`*6kzyAK~RwA5G{My^t{Nau{# zw`wq+k4>=K%%IPAiK>TzMavN5Jl_J!?$qJ;pZu5h8?(HPqT>f`YnhsBYj-KSx2vBL zoz+`zs2zr^xD!)Do4*J&IyG+fINc%xpReO#uU$G?O}^msZ0zTP7xf`)^Fg-aU_YAs z9KAa0|AsL*q?(b4kDx(kFZ_*b9zD;7VzC=`QdpIi=&vxI?qo4~iRSYqqZ(KKv9+?b~KigP8jr}#LZKZmYH!db+95! zf5Cup&&vAK!uiYfh&PY0I1`!6xB)&M8eq02_Vc#cTkRSw^nJ!?unv^!GVy!u&nTTj z$f(-1GS;~6h~SLt5EvJBhXKzH8K2(oB8-zR%+wU&W-%c258Jr54fIbQ8sJQdtFQ!%NO!Wtw8_l6$c;Ubuqp48Z$}qUk%}%QhjCA$PlXTM2uW0nFCsyj#<} zuDd6j5(7mx=ZWfI-xGvJ;vi=1D8;=V(tfWFutgWFwMuee<}p>50@B* zxJYDdkeST6yOHy6!utKyPV571!RO3?zyvS^e}J+6U7sE%?5QrdeZBn4YMhDlrQXq~ z(e{{DQJ-a)-~3n1^1If!1gr}d)V)8{jf$G}Pfw~l^2Im9jB6(N^}qnVpqJJ1kE|k^ z$FED$MGrShgIOhzto`QBveJ;VZW#YCz2ma?;(|sygH+*^8<>PeI2N~Iga?9D)l{8> zegughJuaj{3BJtO*53`|aLl@AVLg>q!VYHQadGN?!xkL)-?5VfU$Hxlc9mM4O5SeNCR3Imvv!`UQs=Y7JkTE7ZAwuB`TPSUz0yqQ;kO*{$FFdr zMR(NZuD?nChFq*i?R*rx(?(}qi$4Oi1J!|1UB!PO13uv2z}v<` zH@!j#MV7%o++0&GB?cj0wF*O3z3G=|z&zP!27u^dtg;o68RO1!kp8I_@})s*I{yA;UTEP|O0 z`ZexfilkIY;+Yy>Jf7sYn>c&hEyJ>FvAL-OqJf|O7okGGLBn=n!+n?Uja*04>qe5- z^sDASK{(~|ab0z+bdn=~9U>A}2dNf?zkW&yecDW;F4Bjnji}`J61AR&wVT9Jup*zL zN={EZLqu=D;En#rqur?4KWp^NR0+AgRKA`{BEM$akJU})s;lS>!;GP$RUO5?!~5t9 zhN51ogPV^RW72Mn+&E0LXlOD%EgU=G=O9MULR}wpjE_=CbXLr^|2h~abUjC+bIww;Y4i3 zhzr!ZrulPi?dA+u=gU;77qhMV%2_4;u5U!EIh#EIB5wy@>&!{jf)dI50{ zT={!0h!UQ}z^;3zcev^bZN5+^5ib14?Fp}mN{>Lg%d164>4phW4%RZAtlNkiWYg1^ zH2)G1kYZi<`sIjXjj3_bUS>Fq_zLL7JtzmeqFf*}X@e>;)m3y1!j+SxbPg7CDr3qp z^q$Hsh9$3tmBkh7iwJ|(-U`Y;VI{8|hm>5_dYo;^wg(!Gy&2)CCwWvFn2Y`L{1oK) zdD1IZ;WZnL&R?*2hPaK?-u_aXq4UiobE5tntFIbPvkJB zc~awVkM1RcVC)6LrD;r!Pg_ZQV4RI&!b#%s`uJlT@<%lNM)^{+7cN0weIMxhE;wJRBOr@Y5g0L3x8RhXNpoSH!ub7D zAipM5qo`tbc0RG5V=kO@aWrdpe_Y~0>V>}UD_SbP&Al}FXzq2AX;ZIh?6Bo*RncK^oIOwu_TXgD;p2fN&svvfVYjIzcU zpw@#|snAuU)E45I$z0vqO- zrdG6^yZm@Rx~#5J|NPt#1k@KB5)x-eG500THnuMkj~ar}rqF=^DPZ_hERPeakN7Qj zO^$2lt3oFVg4gu9_?X1{8l1M0E~xbq(+q0UU*x2@@v|x@SXx&#zE&4pNq?@-+P^gg zD{fJ{fqK10UEgm(X}%lqPVbwLNSx&)dxIbviy`~tf>HW<^6^ZP&hh&m zU7DDVZZ+$>i(!VBg#0`cbWk}FC&xBe|2$(vXbPbSk6f3-OWhx_KSCq_3IxnD6FTW% zc|mqtMUPgI3VOXx(UypOe5?m~QHWU)uxLJB-sZs#>L|sXgjUS;&lgTO$63}OIy-;o zUFF&riYazR?D)`e!&5Fmjf?Gok|LiCzRwiJWOtgi)w83l)Hr^&l9Va$PgSA^K`I$j zdv~Pug*p&En0zO5^xd&dC^vc>9`2PB?T|2AkuF|VvJ5oIo9~M%V=fWg!9H8`$DyCJ zm&;9g4CE7!%k>kHbOV#uDPQ-DlgfLoSVt7v%D#pQ7wb?hX4`wNtq#c9y=Cuvg!uG9 zFM`m=wmZ=+%jus2U*_m?W7h#B16;xMH5x>$g4h@bod4dZ{td_RM=RhymPm3AyuvV2 zeH0yQPu4wqz??7E{%BS?9$)n z=#A7rf%|y3ot7WIW$;4R&)dY)M}^6FEr-9cj`R~+1QkoqWh339qDV;GqQFhoO9ZkY zh!AVc;?4V+0gFI0k+rr=; z!uEIFwAKgaNIoxhH4Np&1{+8MJheN;-VgVE{Mt{;x0)qRyYdfuCAbL_|{D@&Q$qqqiIr+2r?b*PX)c$5twhefA_cfINoL^|NMsjsXwS_C^ z?6OgOKm)&|kUrN7g-IXgCA*4dr(#0sf-iF3?m{XGAs#S${nc8ByjfN8MDAk6BonTg zbx^q-q=eR{fB=os*ug9)qtA*AE>1c*tUi8ehI)6hN!Z=4%47)^dF%_9VeKDdu40h+ zYn4IEnX$K#_tWVRTM}Ku0y|xvjb7EAUc6)?ccfK6*1UF*>*hiywPd~1G93c>v~RE& z0ip4C&URnb=;XYj8R|m#z=O@LLS?pjX3%( z$(C)N#2VPU=%Y3|C_kOMo=+dw*EV5H8^*>2^%f=@bJyL(B-eAZXfo!*)V=QRfCh`r z^~U#Nt#XiyoYtJWQSo{^Xone|FGWZoPJr#Wf;(ni^hexByVFYiR&_Mq{a z!nIi`K^kfP756BgyewZ2)VisdjccS6k%y@b4;)5nGA(3)P(hOXL+~CO+CT4b!rVi! zS-y#$^r_-v+ZXKdOyll)Co)-Cr!(BQuFv}_s^4!`w#)o#4L^_@;D19+^%(9FREx2U z>$m&rx*LH;$I2pQH(w(mp?0zFq^QXR37^8lfBqT$a-&&{TuO3avps`v!B4->x6JLJ%iTLK<8!E?#BmjY=^PDYyv06zsA}m4&3G7HlS>DQ8HEo?B)dX`^1d^i5ebFZ~*QzHI!N5q*O!>K}qmCTwFaWrWd} zWV#nV<@j0zEkM?Amlx4jjIt5}MSUG3{V9wLMK8$(Q$Wh+Bc9_CIN!4s>3d)#Y98c~2}2qt+Z5%MX}ZbuL|xcBAY!zeMouZ77-0t>nrtbsGk7^6zVKml@K3C*0|Y4gCbt%QQ4wc^qdXMXu?NZXi3{ zrFZIsA|ybx-N^`gPVoNn1ju+HY~~_zi^_8&WRcf08>^L@%PEz$r&-(I%QaFfTY?`4 zeYd@A+8$7ml{^SXRD8DNIXjNap9rlNW8=T&umwWp_xd>M(Zemd($u(O3vhaa0i<5Cw3gz6b=p)@DPtRR6%u#L}rRt7{^=j`-2#vjgzJMzITN4kcw z7i6v6yo*65I;9S6&@RCOPJA}n+Sjl_yit@w*AXO#T!8S1>f6f1o!O=$~S0pw}6ooEZxNA68zdkVP&X^8V@t({>xu- z6%SV9hCx3Zrf?a~_oDa?=Kr5#=+ORC_;UgAaduS)x4N_D*VVw)Y>5chn$m4UKlk-| z5)+P!YF)i>R}b@@Jyz(Hf`4xS_g8FI0slPa4s%QU*qS-9P^C|_Y)HQ zPliCoXjoRkfjpqWKT;N(yHiFLBokpvKAksk6H6=Wz-(r;m0>bbV0U4peCqy->uk{C zGj;%-_!p)k_w)qSnp`2^f4s5(<0oq;WL+E=;hibP6OqFy_PwN zj_eGok>(_s0vFs+Oe3)Qg@+UcQ;Vuc%WXI0Wz|(CPF4~tj=0Wd98`1c)mtNcUvMr3 zh=AOcFjl{e;5kRQ@4@`vW%v6La%OpGw~9% z)x+k92()p#xpShWy%KcMbj`!8Q-+05NkSysH|?(mF3s45eXf;&3O8%vuKt)caO;jm zEI#i78i5YS0{4%Tet_@FnC;?g60p3bW84at!4A`$t@sPu&zwV*aSL#MD`f^-mw5=Z z>ap{eFRC-^?#BE>WF?WKKV5i++sjq>aL?DAIpBg4fEc)X?Wy-0N3e z!vnXicTFruD)^Z zMF^%{4gce>pfmu|%b=Z74! zZKxM=qhM6)#<=-H=UYX|1BXPz$kas*%YtP%L?kbze9R z+C#B33S?rPr}!vKhM$~`n_4TJbHI|R4vN@0|LnMkm2!WA{~=?(LF|wVHf@=sV{!}R zIsGS~C-wz#bJX_^+Mx(AS#J~Yc}^*Ol5?ndAHlV46}p=>{4MRzSi*`bLbZh2{j3w827{4h z##SNgkUeYPJLdC!JihDM2IS*NxHiePt)>?7f3EKS$~q4|L%N;YrM7oNy*o4 zAx}AYu#NUV8?Ks_4Yn(*x$j1SkPk(k3HfDFx08{MgIR0rYf>IJKh8d~n`-}T9^4gA zx4t+=)^!poNYE5RhG#$iB@K`yW?MLWpt<@;Yn14Qyzv=^Ox!^tus^%zzNXC%G|;mL znXAK6(+ZrBjDT^Bhg zS4aKZ5=0kvwx-%@6zl%kOw*;YGIArPc-+1G)Jt}sSf2lz+_mE<)lO|GZ^x@Wj_&xp zc|YzLyC?Tp>F^6!^zR7$zACO?vrC4_=!Se_Q0xwrr_9Q&v+?J_tNV3o?|DC5h`hb&EffS!T!)PU1J`MbVZ%Gpnc5&oLjiw>qk~TPEoC9u1sKe3twa*hB>~d|)LKZ;B{4 zb?ac3IMYZt~2Smo*|h7bRMwsoO34Ii~XRuBY*NX)=GJSlC0&)nvWR>PVTNJ;fGC zA}%5O*n^BgYAiz(Jq&eTc3;!Qv1*-~vZbi{h1S?eyqKUU2HCr^HMJkxx`-0yIVkFB zzP&mOU)AE^Ful{Zu{H!uVr<=)L5)ylokqv`^({CJtEKW&Kanhrx9YSPpHNYHFGPLx zQi_1ElT$4plx6YU1V=Yy3A;xWq34&jm~~jb)b{Jey=!-RZ!m>f&ax{k(P>G5uq0Agn{)nE* zqPm>t;<$%btGnUVeJ(QLCe5_5#f~r6>a(c{8u{Z>u&irEe)v*ZijJ-cISP+2*-w-k zEv|@4<_c`MB$YW=8)fD;ttrX^Un}h8M0uO-Z`q>(ud-d)Tm5oWZmx*Rv8k2kYW2_b zix%k3H@+AyvX$)T8E7sC$7UGU&n5{&kmFAh@L>X&A1L~3M(Q3k-*zIAYX+o$DF5K% zAu3jke>>qEM?HoybEBIymjf&K?M38|k-g=^I4T*FRosK&+oJg!7t}P81jIX?%;#`J z;=fl%QBz@8o~gS1P4uF<liN&Q+dq07ZT;??W1oQ=fnhj@T$2xXV6?%vryax3aLjYjX!s7IQahgrR9%o zTlh_Z4rtYwcb1Y`-fH>xJ=L;Hed?(LI}^#VwxONyy|VZ0PoQ(R;?F}ZP+1DUKfjdt zQoVDxHEhC=-1!zOYz!u|Uq^br2advnb4qbnb5cec^|xXm>^~pCokj2FbXcmlJMTn+ zc}?i-HqhrNi!+5bZmek+9dG$s-`e2j%a~zdsGzZ(j;LMO--5dUe`J*ZU!y_kUUc|~ zDAQW+4*P5nhC!8HOXh7w-zLwmIEb|^)u`yg+WhA{kLUGgdiVl3ul>;((6F%)7bh*z zr;#4#Y}w0h3#w|`XB*m-DJ5wdRTrHMxJ5?Y(0cL_%p8s}NiwkHPf%w^qbLTtTx|5@ zwNkBbl%_hY@D1;@d`Yh+LocB0QBt7ogzPYQ@#q1*DQOwVP99vwM5G zPPIT_>WfEZdb<2t6>Gy80p^Q)J|_O@mS92{@83hJ?rwcfgJD72BHoY zWLVFYglFWgXpyvJTQ1~61pUby*x#mO3-!4PvD@11 zjwY5n&Et8lw$K>D5*G*iyIuC|Xwe-V2_<+w$lqt)R`@5AJ1kMZ72{sH-tYeLoz=2A)W0Deld9Edfx1zYn$n6dPp__eHxTk47@7;J zmg)u@Sj(-p8vED~-JdWG(<#^^M?G!2iM7pU?$rEg;FP;tB6=5vGP zd0A`2X(%wk9_ZZHJ%%N{yqTXy^P?cF;pdNd0c@+wzJd=w^O~r_fbwE{#*oaT)rasj zW?(hAH>dtw&@e|nAND9XNqm-6sVKC;PR8=VqEPWb+)y<_ANm%h}?%7Ypa4i zb^8NiCRL4&JcDa!g?;g3q)c(;m8%K}2_00HqtRvFTKqk=XQsVP^w^=_G~=gM(^37{ zcDWO@k&?pCD@ft^^lG>J8spFXmg`^6mquD+yUhp%llTb1YEjWp-T>Q=jKMMiB4{hO zZ+^D4_B#zD(+M<g0?c)@HD^QlS)h}l53PV<^%0zaObz?QcRf9p#h4rr5OET zjegPdAZfcC5(Q;G#=%jBJ@Z-2_n^*m6oV-l@$i!kQcEb1OF1^u-Um zL5|?Z>P*h~E-d|`gr?f_=d5!@Gj@aN7#*iPXE$o$I-cdd`cAYCIA_4!%2>9BF?#Eq ztvZG)BS1(2zy!6~S&+qdmS_HP;f|zfMH_v)9uM;2u54xQOdCx}ew?npLvWg#LH(zf z*Xn-p8gf{*o2FQuuVN-|4ELH~f~kn3ansQkA|b2iiUjhD!hSf6M+2Pd zim}UEW#5~4SC90>+9#l2Mxn3DnI~isdv&JjhGRwk7p9FdY_^Mq($6%DOuuNJl!m@} zmgDUB=~FHy$-3NUJ{@!TCeWyUwK@iAppux!YF%t;J!pdQpAqx9vxB5?l={(zeC7N! zHK-6Sj;KXsq4g(cnoMPR?svuk0}b;WEW9K)Kh%JU&(RI}o`?U%*XTQcctNFSFab8w ztsFl)I}VW+OZELIkSdD~SPt{Adoq7fM0Xe{2Vhb<#{v@QRbWOHp|{wx3pF)X&GQ{- z(-qyE8>=1jKHfCa8&IxScEmhsT4yX{$Twjwu|%|uKe|2D=;0WT?G}1FovOUb+L-Hj zqwXj_@$K;M?_P^!hPLq~GZbj3qPD&7nJezaT}^~YdYc%r?j|B#bESGa43BeGsTg5R z@drrm3JFAJsezDeue%fIqzs{x4=TUMz{P~$t*OP&eA3cnMzRc2V4jqfC}CEqpUQ8y zjeFF_r|Rt`d1Y2}$<}+<7sFLUQ=2+qcN?bqjZ@J*GMcB4+S~gm5rCHufRUAO@xF!l15`sL z?<*S59Kl2XYL|y&QsaPV!*^30VfB|A2n-7lm}h@z&{oo~?q69``)JwftuGB8&kqU1?9#Vv#(P%2;0BI%+bmY{DKtsw{HLM4|JqaiAPA2g- z#`JxFm}<+MIs09m(6-TrS%Po+zh^V-|K006X#>tr6fx^kx_@(5S7Rw_q8TxiTnZxF zBriXnd9qXy%(KD7=Lw!Y??PwH1_|-P4dR6z0Oxp#t}4%G5g9mRWuQ0rh>c1fZs>;F zJjY8uOm+Kv*3(p=>Ay4BLR*5sQv(H~>F^Kh+xla}KnoQyeW12f$**^<7M9Re?<=81 z*zs)OJ`+>NwNl@6TN1AHbmiqOAR4gV9zC*n(WcHix?cFygQ( zoPA7`rB_$_X6)@9l)ZD4H1U~43b0$t{{*QkmmPn3pPzV_DRBraYWRbPtuGZmRK*>q z2fN4+ZzLSOBDr_}#dc;dNBK2U{>DV$2j7b$qUsL`^erG?QBkbR;KSyL`QYfEnbMJ~ z8%lrrypvz;T}>3pd&Epe6s9a!U<{ybqIO^75clA06kihWTQ4iWCOwFq$3!{*R3-p3 zenhY(pn@j4z8grwrn4R(+1;7fC%nv$$aQrEpmz=QQhv+@QUYe@PUNu8&aj9p!?>6L z#_zKiHLzPc3ED^qu?dowY?Gxd2KmpdKe#&)=skDDmk9Tr3EhpJYwFC+;R4-^{PpP% zX#oT%ayI#XUD_zC+h=%n_}O4>MdiRL&F>M0=JZS;=P}()zAo1lAq=0)WD0|1-+Kvw z7Y-4jD~$>o)?7$pLRqos$1P6CZEzQ{{@VQDN|c)(>X8i(uWH8ikwMV{4zPGdh_6^o z;dFDlv#RVVM+CBozzzC;gKJ?h)SfZ+c$X+_*UoNn|9$V9Dt{ss-YULL7k##vh#W)sAC1I?aG5K= z&zYI+E)l)mcx9_-2rkkz-1IqR4W4uyP%wt@uAj8CAKP%-x2ffzY>K>(R6JCm-2NSD z9#Vozk=8`2;X~*gq8rnqmRqlE)>xJr@u#dglDp_snWfpeYD}Il3n}z@+uZr3vxjxH z+u1`{#A=$R*QuOUZGokNu+ID=AQ$bt^Q`DwNHdHy8yR|eFjZ&_+NA<7ve7Wy{NHYr zhDMD%HruMciy2m|agk$bRQ#%k>tEryfg04jC92zzzf8V-{{=q;YrVU{02ECL?)CEoxo0_J((FmZBp>{3a7jE`){Y4g!9PsoTp4 z+RK!e`D0V0A=?H)w;KLST*>}kxGg`&JlHTcZSzh4>DQjaN*OuVZA z;+au(NP%>ld09!r-Nsw-T4{&RKRM++`OzDpwZd{zn|UB0H!XgRGK(&DXL4xDqpiI` zH-PWmhz%(7M-O9)`1i7yWR;g57WV#jW{7F~0^>g#1EYkLmS6?sQL$1srSm^E{ASoC zb{N0IMM+vHI$i8`#rQa`NIdnuQ)}q}aI&!%<#G4LbYIw#WID2G)cpA2`n-ojx6?c| z-zcOG&`8Y>RAsTL7Y=WzCO@AP)@@6(I>OBjUHe&MS$1C*)xcnu_QzGjAo+EzQe8}t z$o$5|m95uqP<1iXrv`&zU|Y;SvYn=h{IN(Anw?k$caDa9HPhzqq&3)P9dUn}R(|c| zIJ|P+uE@p;d}GR*|2MRoiBo3?U-N($CYzZn=aYaXPb(;^IKMs(YfwE}8UdJLlCBJ&;?e{V4n&hxWILAVS%xeYG z)(gjZjwdm=Arh#SO0A*mHhPJD^1N&e!>k58{<24qLIKPIzbiYya_Hl(u z$#E*BcHJk9XJ$`RA6`I1NMmC%vdZ=utTejEzPaGJG};)QZoV781Hn?neVk@g(QK5k zKaq6pbMrQh!wK-X7CDHha6DR`pHm1wuDQYnU z^7!ZF1X1gun)*Gf(QT{Q(i006`oR#1RTejsbuPEaOu9N3_wA)6b{HAf#ZdFzF=4dW zfKub?t+*IaKQ{ey8ys+rZszwq<}iKFR(0xKC&Vv;tuf#89oA24-NDjhwOAL#UhS!s zg|9NgdP6}X&78&b8!9{~k&T3hRG2=N${Lq$rxuO2>c8&+_r zG#QwTL>BEOh(||qBXrv-li40Yun|0lMtRpvERF|Eo8-${dt$7Z8O>Z z>*~?SrcQvQV83lo;P);6gIEL{Sy5O4O4jBJymp0d1hLgZCuP_qY3O!&Yc`m#vx4oD z0hlz%bIv2cFh0sJ4c7~k@v%Fpl-GX}#5ZMYNERdSiD+09Wfckhl;JOnyk zs#nf(b6)gTkzx5(&B(L-D`JQ>IAKA$BSp`RGUnA*E5|EKm_{T8c&20T4mt=fbT`R} z0kf0Glv(UFj;2y?RD^9R*tSB-=jokiYK>c}i!^U{?m?g?IdUd=>GzoFepQc>ptwhg zT78BgXw_hyW-TL)$Ci^Tm2Z;QTb-v5Z$6Gd<=%@=cekxaDrZfm)~>l%kcPMy43Ln# zxPcI)_?NE3!iUx0j)Cx$7zZ=?A>az4)=Od7=+Z^)4|nZ!`~E96N>b_#xe(w|2jB8( z>Y;TTJeMBl@t3|=s=&(>s@-uao<7xnzZC#Kq|K#M)8Z;iKRGPvycMT5%)62lTtj&# z=V1mH7w+!mZ^*<~iKETw#}GK2ZH0@y{Wr#uqqhc8>*4u7t|{XUahKOZe_Vy}%bUgy zq_msmXD7eNX78!#ut3rHnLKD08u;&?99M}#wOUoQ@mq2^{(=SNu4@Vh7VW+^6~6cz z2A|gM(Hhh?e#H$7J0r|Mpm3_>jnF+wh2gnmN#@O|oNc@3LSw7-s^4jKzbA;fYc6{j zp{t_vY=iQ=wvdB5>-lPfY*2{b8)2sM*!k07uCuw{wp%1L% zmgRy$CtssmAZfN*4M{}QmY?!XhYS@N`42lm>Ub}?g*9k z9Z~1N;(z>!`1-{rBIhmzdU~lr;*EbUyjA|7kL9q&Qo`x8`ykoE;sa4tOPZ=! zzt9s_<}z8SI$FZ8`=$_|&B1B8JzJK1&)gEF`#9qq$&Y)QhS!2+^J~r6T_mjk+`t@R zNqCOp5w$1$)p>;|Z`IUD-8u=xCAs;5#)#_08-~W1)TKH478afgZ00*QK8D?R$n<8$ zxSe{zVYU3*{w9~%WtS#dRvgExT4k9|dYII8_g2c25r_RY3OX2nSnRjiv>89`)dQQ3 z;qVIe=IgQ0kz-O&`ck+?t@zEkV@5{?#&*kkE9(yMD^;3;5vm6kD2YmmqUjsncrLcE{8X=?jW3laT z!-9Pei;bFOJ8EtoUH(9dKMv!U9qj25SMEKj8QltPP{0ZJAL9fifK)%8{eCynSR~uR zwuc#J#9GKAk@K`oG$v>CtNk8@6Z?m;c)!u17Mn+7WQPm)$6~ka91{|otJizb!j)t% zOq)B}q4WwAW5EgYk8IvuS@TChKff6B2z>r$@Uf-*`PNL+sKcg*fyOw6n$&SsMwq&~ zhaSUt2SYDpLuBC)du7@7v;Q9IZ=`Ia6?KcCnHk4&T8$7UyZF^0sC$mM6m+T>Ojmbz zQ`p~p`oC}NTKCj?C@^%Ol+t3jb*zNe|0IYHd9)*W-SN(kW6Fho zNvI`C`DZn!{ni(iHAdNxCck6kw*Au@(cL0`48sEQfi4&(+)1c@>cfN6Uwe;rPnwQ7 z!-OxK;x~+15)&I8H`O>p`$aC&1vLa0%9*ljKrpeMJwGuns+T}U5Nf6yid6FNb+9V1 zIOa>qUjWcXP>K3(2|(Td$8@aW@-C>&$GHt_471l zQ0i85V>m;Ta(OR*l5^@>72owYJj=B%2Gcm~AP~CRmi&arU*+t<2w3S|XI(p)c>;{J+Q{2B}F`wj{@lqjq{Fn=)+FuWK zCE~B%P#@r4P{Iv!{kBxQ;)24J%FK6J=v^tc3MYCWVlr+QGsIJ1i?l> zH8Hzq!a1qaW1AN{`1nnFwTEdMg{wy2ZQ+B-y3=9rtlw2B8x5JS1p;p%9;$2}>y(o_ zl+$``!?1E{bH_XNj4(N!vXAY$7EuuV-P>0#7@>X0BOuPkR&km>vtBCI`M{R+l4|wS z^w7N`jMzEOdZKFj zPRhE~rf^Y|FHh7<^w5^~p(fU_LSw1ky2N{9n{H42Je%6H_g_)&?$^k1S8OmotChd` zJG_qVgQIv3((nf%XA YXa=V8+nhuT;j`709zQI9@ci}v0T6=CmjD0& From 46bc813803aca4b0e672ecdce4a23d0f5b1d563a Mon Sep 17 00:00:00 2001 From: whl <313576743@qq.com> Date: Sat, 14 Dec 2019 17:01:54 +0800 Subject: [PATCH 27/73] commit --- week_01/25/LinkedHashMap_25.md | 331 +++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 week_01/25/LinkedHashMap_25.md diff --git a/week_01/25/LinkedHashMap_25.md b/week_01/25/LinkedHashMap_25.md new file mode 100644 index 0000000..2514229 --- /dev/null +++ b/week_01/25/LinkedHashMap_25.md @@ -0,0 +1,331 @@ +# LinkedHashMap +LinkedHashMap结合了HashMap查询时间复杂度为O(1)和LinkedList增删时间复杂度为O(1)的特性,使其相比起LinkedList的随机访问更加高效,并且相比起HashMap拥有了有序的特性,但由于每一次对元素操作之后需要同时维护HashMap和LinkedList中的存储,性能上相较于HashMap稍慢。 + +LinkedHashMap也可以用来实现LRU缓存策略,且只需要将accessOrder设置为true即可,若需要设置缓存淘汰策略,重写removeEldestEntry()方法即可。 + +```java +public class LinkedHashMap extends HashMap implements Map + ``` +继承了HashMap,实现了Map接口,拥有HashMap的所有特性,并且额外增加了一定按顺序访问的特性 + +### 属性 +```java + /** + * HashMap.Node subclass for normal LinkedHashMap entries. + */ + static class Entry extends HashMap.Node { + Entry before, after; + Entry(int hash, K key, V value, Node next) { + super(hash, key, value, next); + } + } + /** + * 双向链表的头节点, 旧数据存在头节点 + */ + transient LinkedHashMap.Entry head; + + /** + * 双向链表的尾节点, 新数据存在尾结点 + */ + transient LinkedHashMap.Entry tail; + + /** + * 标识是否按访问顺序排序 + * true: 按照访问顺序存储元素 + * false: 按照插入顺序存储元素 + */ + final boolean accessOrder; +``` + +### 链表节点 +```java + /** + * 位于LinkedHashMap中的Node节点, 也就是LinkedList + HashMap中属于链表的节点 + */ + static class Entry extends HashMap.Node { + Entry before, after; + Entry(int hash, K key, V value, Node next) { + super(hash, key, value, next); + } + } +``` + +### 构造方法 +```java + /** + * 1. 指定初始容量与扩容因子的构造方法 + * 内部是通过HashMap.HashMap(int initialCapacity, float loadFactor)这个构造方法创建的map + * 并且默认按照元素插入顺序进行排序 + */ + public LinkedHashMap(int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); + accessOrder = false; + } + + /** + * 2. 指定初始容量的构造方法 + * 内部是通过HashMap.HashMap(int initialCapacity)这个构造方法创建的默认扩容因子为0.75的map + * 并且默认按照元素插入顺序进行排序 + */ + public LinkedHashMap(int initialCapacity) { + super(initialCapacity); + accessOrder = false; + } + + /** + * 3. 默认构造方法 + * 内部是通过HashMap.HashMap()这个构造方法创建的默认初始容量为16且默认扩容因子为0.75的map + * 并且默认按照元素插入顺序进行排序 + */ + public LinkedHashMap() { + super(); + accessOrder = false; + } + + /** + * 4. 通过传入一个Map进行构建LinkedHashMap, 底层调用了HashMap(Map m) + * 并且默认按照元素插入顺序进行排序 + */ + public LinkedHashMap(Map m) { + super(); + accessOrder = false; + putMapEntries(m, false); + } + + /** + * 5. 通过指定初始容量, 扩容因子, 插入顺序进行构建LinkedHashMap + * 底层先通过HashMap(initialCapacity, loadFactor)这个构造方法创建map, 并指定排序顺序 + * 这个构造方法也是实现LRU缓存的关键 + */ + public LinkedHashMap(int initialCapacity, + float loadFactor, + boolean accessOrder) { + super(initialCapacity, loadFactor); + this.accessOrder = accessOrder; + } +``` + +### afterNodeInsertion(boolean evict) +指定LinkedHashMap在完成put操作之后还需做什么,这个方法在HashMap中putVal()方法被调用,但是实现为空 +```java + void afterNodeInsertion(boolean evict) { // possibly remove eldest + LinkedHashMap.Entry first; + //如果evict = true, 并且双向链表的头节点不为空, 且确定移除最老的元素 + if (evict && (first = head) != null && removeEldestEntry(first)) { + K key = first.key; + //调用removeNode方法移除头节点 + //在removeNode方法内部移除节点之后会调用afterNodeRemoval()方法用于修改双向链表 + removeNode(hash(key), key, null, false, true); + } + } + + //是否移除最老的元素, 默认为false + protected boolean removeEldestEntry(Map.Entry eldest) { + return false; + } +``` + +### afterNodeAcces(Node e) +指定LinkedHashMap在完成访问操作之后还需做什么,这个方法在HashMap中调用put()方法时,更新相同key节点的value时有调用,但实现也为空。在LinkedHashMap中调用put()、get()方法时会用到,若指定为true,则调用这个方法把最近访问过的节点移动到双端链表末尾。 + +(1)若指定accessOrder = true,且访问的节点不是末尾节点 +(2)双向链表中移除该结点并再次添加到链表末尾 +```java + void afterNodeAccess(Node e) { // move node to last + LinkedHashMap.Entry last; + //若指定accessOrder = true, 也就是需要按访问顺序进行排序, 且访问的不是末尾节点 + if (accessOrder && (last = tail) != e) { + LinkedHashMap.Entry p = + (LinkedHashMap.Entry)e, b = p.before, a = p.after; + p.after = null; + //将节点p从双端链表中删除 + if (b == null) + head = a; + else + b.after = a; + if (a != null) + a.before = b; + else + last = b; + //把节点p放在双端链表末尾 + if (last == null) + head = p; + else { + p.before = last; + last.after = p; + } + //尾结点等于p + tail = p; + ++modCount; + } + } +``` + +### afterNodeRemoval(Node e) +在HashMap中将该节点删除之后,在双端链表也将该节点进行删除 +```java +void afterNodeRemoval(Node e) { // unlink + LinkedHashMap.Entry p = + (LinkedHashMap.Entry)e, b = p.before, a = p.after; + p.before = p.after = null; + if (b == null) + head = a; + else + b.after = a; + if (a == null) + tail = b; + else + a.before = b; + } +``` + +### get(Object key) 通过传入key获取指定节点的value +(1)调用HashMap的getNode方法检索节点e +(2)若节点e不为空,且指定按访问顺序排序,更新该节点到链表末尾 +```java + public V get(Object key) { + Node e; + //若未查找到对应节点 return null + if ((e = getNode(hash(key), key)) == null) + return null; + //若找到了对应节点, 且accessOrder = true + if (accessOrder) + //更新该节点为最近访问节点, 移动到双端链表末尾 + afterNodeAccess(e); + return e.value; + } +``` + +### 总结: +(1)LinkedHashMap继承自HashMap,具有HashMap的所有特性 +(2)LinkedHashMap内部维护了一个双端链表存储所有的元素 +(3)若accessOrder = false,则按插入元素的顺序进行排序 +(4)若accessOrder = true,则按访问元素的顺序进行排序 +(5)默认的LinkedHashMap并不会移除旧元素,如果需要移除达到某个条件的最久未使用的旧元素,则需要重写removeEldestEntry()方法设置淘汰策略 + + +### LRU基于LinkedHashMap的实现 +```java +public class LRUCache extends LinkedHashMap { + int capacity; + + public LRUCache(int capacity) { + super(capacity, 0.75f, true); + this.capacity = capacity; + } + + public int get(int key) { + return super.getOrDefault(key, -1); + } + + public void put(int key, int value) { + super.put(key, value); + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > capacity; + } +} +``` + +### LRU基于HashMap + LinkedList的实现 +```java +class LRUCache { + HashMap map; + DoubleLinkedList list; + int capacity; + + public LRUCache(int capacity) { + this.map = new HashMap<>(); + this.list = new DoubleLinkedList(); + this.capacity = capacity; + } + + public int get(int key) { + //if exist, get and update + if (map.containsKey(key)) { + int v = map.get(key).value; + put(key, v); + return v; + } + return -1; + } + + public void put(int key, int value) { + DoubleLinkedList.ListNode x = new DoubleLinkedList.ListNode(key, value); + //if key is already exist in cache + if (map.containsKey(key)) { + //update cache + DoubleLinkedList.ListNode temp = map.get(key); + list.remove(temp); + list.addEnd(x); + map.put(key, x); + } else { + if (list.size >= capacity) { + //remove oldest, then add + DoubleLinkedList.ListNode rmv = list.removeFirst(); + map.remove(rmv.key); + } + list.addEnd(x); + map.put(key, x); + } + } +} + +class DoubleLinkedList { + private ListNode head; + private ListNode tail; + int size; + + public DoubleLinkedList() { + this.head = new ListNode(0, 0); + this.tail = new ListNode(0, 0); + this.head.next = tail; + this.tail.prev = head; + this.size = 0; + + } + + public void remove(ListNode node) { + if (node == head || node == tail) throw new RuntimeException("node is can't to be head or tail"); + ListNode prev = node.prev; + ListNode next = node.next; + prev.next = next; + next.prev = prev; + size--; + } + + + public ListNode removeFirst() { + if (head.next != null) { + ListNode deleteHead = head.next; + remove(deleteHead); + return deleteHead; + } + return null; + } + + public void addEnd(ListNode node) { + if (node == null) throw new RuntimeException("node is can't to be null"); + ListNode tailPrev = tail.prev; + tailPrev.next = node; + node.prev = tailPrev; + node.next = tail; + tail.prev = node; + size++; + } + + static class ListNode { + int key; + int value; + ListNode prev; + ListNode next; + + public ListNode(int key, int value) { + this.key = key; + this.value = value; + } + } +} +``` \ No newline at end of file From 6a0f4b733daae7798bcc473c1811a2417eb63240 Mon Sep 17 00:00:00 2001 From: DanGZ <365223296@qq.com> Date: Sat, 14 Dec 2019 17:04:32 +0800 Subject: [PATCH 28/73] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../target}/ArrayListDemo.class | Bin .../target}/HashMapDemo$1.class | Bin .../JavaStudy => 35/target}/HashMapDemo.class | Bin 35/target/LinkedListDemo.class | Bin 0 -> 1698 bytes week_01/35/ArrayList-035.md | 10 +-- week_01/35/HashMap-035.md | 24 ++++---- week_01/35/LinkedList-035.md | 57 ++++++++++++++++++ week_01/35/com.dans.demo/ArrayListDemo.java | 2 + week_01/35/com.dans.demo/HashMapDemo.java | 2 + week_01/35/com.dans.demo/LinkedListDemo.java | 3 + .../production/JavaStudy/LinkedListDemo.class | Bin 1643 -> 0 bytes .../META-INF/JavaStudy.kotlin_module | Bin 16 -> 0 bytes 12 files changed, 81 insertions(+), 17 deletions(-) rename {week_01/35/targert/production/JavaStudy => 35/target}/ArrayListDemo.class (100%) rename {week_01/35/targert/production/JavaStudy => 35/target}/HashMapDemo$1.class (100%) rename {week_01/35/targert/production/JavaStudy => 35/target}/HashMapDemo.class (100%) create mode 100644 35/target/LinkedListDemo.class create mode 100644 week_01/35/LinkedList-035.md delete mode 100644 week_01/35/targert/production/JavaStudy/LinkedListDemo.class delete mode 100644 week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module diff --git a/week_01/35/targert/production/JavaStudy/ArrayListDemo.class b/35/target/ArrayListDemo.class similarity index 100% rename from week_01/35/targert/production/JavaStudy/ArrayListDemo.class rename to 35/target/ArrayListDemo.class diff --git a/week_01/35/targert/production/JavaStudy/HashMapDemo$1.class b/35/target/HashMapDemo$1.class similarity index 100% rename from week_01/35/targert/production/JavaStudy/HashMapDemo$1.class rename to 35/target/HashMapDemo$1.class diff --git a/week_01/35/targert/production/JavaStudy/HashMapDemo.class b/35/target/HashMapDemo.class similarity index 100% rename from week_01/35/targert/production/JavaStudy/HashMapDemo.class rename to 35/target/HashMapDemo.class diff --git a/35/target/LinkedListDemo.class b/35/target/LinkedListDemo.class new file mode 100644 index 0000000000000000000000000000000000000000..e2aa6f60afa6730dbd81f0e699dd663f3574feb7 GIT binary patch literal 1698 zcmbVNU31$+6g_JvR-!1e(=;xn;FdN4JAt}|Qa&64jnj{S+7uj8N_pAXn?#K)c_cYA z`8WIpc%Y=r@B!0U;0=R*nOw8hnfh7|KTrshX zcW3Y(>UwDCVdV_{uFc>&KAgr!xMAXB+%)isflmcWYmVnc>jK4kV^?6J?e~;G*>*hj zVA$VN!H(Q>X*py2UFq)1z|s5EI1wE>p+Lo^`;qF|P8e;fzTYBFUpk&Zwf@9@DvxE; zmEJ+K69tZU(299vaBxjvVazduT>@#?ICK~}Zc{@OwmPcfWbi`C@_&5SaXy#Y7VheL93!KfXe^DL- zpIP`EEdy&7zQDSLFY%RyTi9T}8@?ZfQ6LBRRdne0!g2}i3N|_2uApY&4(=MbXJHFp z8~Db8jr#^3SlGsA`F zJ%Po1?GlPs<43ksz#ceeaTZ4bQx`fgNhSLN7wRcte8-7ZcL@($CLZG3{~_5mVc|Oh z$!=E-DCpt{(EiZtMvm__+rAeL`@DLAb6E}}JS@PzAKaGRLxD?aLa~~cL3CT>irP5| zBgG_&{*Ve5lgc@M^C6o&N|RuN#Jrlx@+*uf7L-bPK}a&|wCckCajrX9B{ z`$6u@ZsZ3i0yF(=XF%86_Wh&bK)~AaJQcKE8HS3_^6&ipqF zQ07?SuE|+&o?Lkb@e3CP%yTToMhp5oY9$U>z*+95v4|=yI{0UL7dUVHfx_cwDB7zN zzhmMQlLb6loy?Y{Y{}D-K0SpY@ElXXDW(h1%*B|w27~J|Pby@bM~xa9WWG+;TR0yp zswS*Bhd1au#jneGyh%+LxYKGA%Uci?Q+HXa_9mlrs#CwhT=@+%S+@E&0-_nj%QBwA jMO>o2$l~d`T*f2LCNaLpW9*W1m3z(iK7BsGRW$zv`>U!z literal 0 HcmV?d00001 diff --git a/week_01/35/ArrayList-035.md b/week_01/35/ArrayList-035.md index 1f435c7..9c0ea9b 100644 --- a/week_01/35/ArrayList-035.md +++ b/week_01/35/ArrayList-035.md @@ -7,11 +7,11 @@ * -->Serializable(可序列化) 主要参数: - * DEFAULT_CAPACITY(默认初始化大小) - * EMPTY_ELEMENTDATA(指定list为空时使用的数组) - * DEFAULTCAPACITY_EMPTY_ELEMENTDATA(当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY) - * elementData(存放元素的数组) - * size(数组大小) + * DEFAULT_CAPACITY:默认初始化大小 + * EMPTY_ELEMENTDATA:指定list为空时使用的数组 + * DEFAULTCAPACITY_EMPTY_ELEMENTDATA:当使用默认无参构造器创建的空list数组,在扩容时会考虑使用默认的扩容方案DEFAULT_CAPACITY + * elementData:存放元素的数组 + * size:数组大小 madCount(全局变量): * madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用, diff --git a/week_01/35/HashMap-035.md b/week_01/35/HashMap-035.md index 5742c8d..fcc7da4 100644 --- a/week_01/35/HashMap-035.md +++ b/week_01/35/HashMap-035.md @@ -6,19 +6,19 @@ >1.8以后 数组+单向链表+红黑树(提高查找效率) 数组+红黑树 数组+单向链表 主要参数: - * DEFAULT_INITIAL_CAPACITY(1 << 4 -> 初始容量大小) - * MAXIMUM_CAPACITY(1 << 30 -> 容量极限大小) - * DEFAULT_LOAD_FACTOR(负载因子默认大小) - * TREEIFY_THRESHOLD(节点数大于8时会转为红黑树存储) - * UNTREEIFY_THRESHOLD(节点数小于6时会转为单向链表存储) - * MIN_TREEIFY_CAPACITY(红黑树最小长度为64) - * Node(实现Map.Entry , 单向链表) + * DEFAULT_INITIAL_CAPACITY:1 << 4 -> 初始容量大小 + * MAXIMUM_CAPACITY:1 << 30 -> 容量极限大小 + * DEFAULT_LOAD_FACTOR:负载因子默认大小 + * TREEIFY_THRESHOLD:节点数大于8时会转为红黑树存储 + * UNTREEIFY_THRESHOLD:节点数小于6时会转为单向链表存储 + * MIN_TREEIFY_CAPACITY:红黑树最小长度为64 + * Node:实现Map.Entry , 单向链表 Node是Map.Entry接口的实现类,存储数据的Node数组容量是2次幂,每个Node本质都是一个单向链表 - * TreeNode(extends LinkedHashMap.Entry , 红黑树) - * size(HashMap大小,代表HashMap保存的键值对的大小) - * modCount(被改变的次数) - * threshold(下一次HashMap扩容的大小->put时根据oldCap和newCap比较确定下一次扩容大小) - * loadFactor(存储负载因子的常量) + * TreeNode:extends LinkedHashMap.Entry , 红黑树) + * size:HashMap大小,代表HashMap保存的键值对的大小 + * modCount:被改变的次数 + * threshold:下一次HashMap扩容的大小->put时根据oldCap和newCap比较确定下一次扩容大小 + * loadFactor:存储负载因子的常量 1、hash的计算: //将传入的参数key本身的hashCode与h无符号右移16位进行二进制异或运算得出一个新的hash值 diff --git a/week_01/35/LinkedList-035.md b/week_01/35/LinkedList-035.md new file mode 100644 index 0000000..6a1c1f6 --- /dev/null +++ b/week_01/35/LinkedList-035.md @@ -0,0 +1,57 @@ + LinkedList继承AbstractSequentialList的双向循环链表。它也可以被当作堆栈、队列或双端队列进行操作 + 实现List, Deque(双端队列), Cloneable, Serializable接口,非同步的 + + 主要参数: + size:集合的长度 + first:双向链表头部节点 + last:双向链表尾部节点 + + 与ArrayList比较: + * 内部使用链表实现,相比于ArrayList更加耗费空间。 + * 插入,删除节点不用大量copy原来元素,效率更高。 + * 查找元素使用遍历,效率一般。 + * 双向队列的实现 + + + 构造函数: + * 构造一个空的LinkedList + public LinkedList() { + //将header节点的前一节点和后一节点都设置为自身 + header.next = header. previous = header ; + } + + * 构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列 + public LinkedList(Collection c) { + this(); + addAll(c); + } + + 新增元素 + public boolean add(E e) { + linkLast(e); + return true; + } + + 在指定位置插入新元素 + public void add(int index, E element) { + checkPositionIndex(index);//index位置检查(不能小于0,大于size)-->index >= 0 && index <= size,否则抛出异常IndexOutOfBoundsException + if (index == size) //如果index==size,直接在链表最后插入,相当于调用add(E e)方法 + linkLast(element); //size++,没有扩容机制 + else + linkBefore(element, node(index)); + } + + //判断index在链表的哪边。遍历查找index或者size,找出对应节点 + //相比于数组的直接索引获取,遍历获取节点效率不高 + public E get(int index) { + checkElementIndex(index); + return node(index).item; + } + + //检查index位置 + // 调用node方法获取节点,接着调用unlink(E e) + //相比于ArrayList的copy数组覆盖原来节点,效率同样更高 + public E remove(int index) { + checkElementIndex(index); + return unlink(node(index)); + } \ No newline at end of file diff --git a/week_01/35/com.dans.demo/ArrayListDemo.java b/week_01/35/com.dans.demo/ArrayListDemo.java index e74656d..9a6b39b 100644 --- a/week_01/35/com.dans.demo/ArrayListDemo.java +++ b/week_01/35/com.dans.demo/ArrayListDemo.java @@ -1,3 +1,5 @@ +package com.dans.demo; + import java.util.ArrayList; import java.util.List; diff --git a/week_01/35/com.dans.demo/HashMapDemo.java b/week_01/35/com.dans.demo/HashMapDemo.java index c1551dc..c517d7a 100644 --- a/week_01/35/com.dans.demo/HashMapDemo.java +++ b/week_01/35/com.dans.demo/HashMapDemo.java @@ -1,3 +1,5 @@ +package com.dans.demo; + import java.util.HashMap; import java.util.Iterator; import java.util.Map; diff --git a/week_01/35/com.dans.demo/LinkedListDemo.java b/week_01/35/com.dans.demo/LinkedListDemo.java index e51e9dc..463dfd8 100644 --- a/week_01/35/com.dans.demo/LinkedListDemo.java +++ b/week_01/35/com.dans.demo/LinkedListDemo.java @@ -1,3 +1,4 @@ +package com.dans.demo; import java.util.LinkedList; import java.util.List; @@ -17,6 +18,8 @@ public static void main(String[] arg0) { list.add(2); list.add(3); + list.remove(1); + list.stream().forEach(i -> { System.out.println(i); }); diff --git a/week_01/35/targert/production/JavaStudy/LinkedListDemo.class b/week_01/35/targert/production/JavaStudy/LinkedListDemo.class deleted file mode 100644 index a025e2f8fb889774f11868cc052d49266e521cfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1643 zcmbVNU31e$6g_JvR-%Z+B*e5(zCr?aLNTS30!|@dz5;>(PD6pGjlD@kWXU7RnaTg? zAE6JWff;^4hu_3-Rx%?Q3=h2Q>fXKgoOAEpwg3O{<{f|w_{)Ta83QLxqTQ{8rSTc-LeKdTj6*oSd}16lQ-+GF5%3zu-& zz!eKMEL!*jY<}^E??+)2$j$>5ZTYQmqJV2fEOEPD#1RWOP&aVX!Y$l3aL2-3EE~9I z;XalG#`{GOF75fs`b*VhGxw*iUOxnk9qD$}%7$*ka%Et# zbEpCbQ;B^%tZ%~)Zpr4B!112mSk0Fpdf=I!HFm>Dv536irGn|CF^*q-#OoXNis0yD z-hMYZJ37eq46ImqgjEYa;fTOY+J48|@wZjgjxQp|EjMH{@`GK0v36=1pr(TD``g`) zfVJ#-DyX|M3>6>T`)vDrc*(`NE4`Mh!r3ITmYFGa>&KVz^d+wHEq&i%Liz37?B(jw z)}`we+hw8F%57@}zEo7Gcz zky*ODk$*5c|1Zq6Lj8XLR$>q_t#X9C$LP=FIM*E8*5Gau<1zlk6Eaq4Yrc8LEZ_`& F{s<|cocI6$ diff --git a/week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module b/week_01/35/targert/production/JavaStudy/META-INF/JavaStudy.kotlin_module deleted file mode 100644 index a49347afef10a9b5f95305e1058ba36adec7d6dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16 RcmZQzU|?ooU|@t|0RRA102TlM From 27e79bf9cf438e8dcba1109a8c0689a439c32c52 Mon Sep 17 00:00:00 2001 From: whl-1998 <39116602+whl-1998@users.noreply.github.com> Date: Sat, 14 Dec 2019 17:06:14 +0800 Subject: [PATCH 29/73] Update LinkedHashMap_25.md --- week_01/25/LinkedHashMap_25.md | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/week_01/25/LinkedHashMap_25.md b/week_01/25/LinkedHashMap_25.md index 2514229..4ed0231 100644 --- a/week_01/25/LinkedHashMap_25.md +++ b/week_01/25/LinkedHashMap_25.md @@ -10,15 +10,6 @@ public class LinkedHashMap extends HashMap implements Map ### 属性 ```java - /** - * HashMap.Node subclass for normal LinkedHashMap entries. - */ - static class Entry extends HashMap.Node { - Entry before, after; - Entry(int hash, K key, V value, Node next) { - super(hash, key, value, next); - } - } /** * 双向链表的头节点, 旧数据存在头节点 */ @@ -119,8 +110,8 @@ public class LinkedHashMap extends HashMap implements Map } } - //是否移除最老的元素, 默认为false - protected boolean removeEldestEntry(Map.Entry eldest) { + //是否移除最老的元素, 默认为false + protected boolean removeEldestEntry(Map.Entry eldest) { return false; } ``` @@ -128,8 +119,8 @@ public class LinkedHashMap extends HashMap implements Map ### afterNodeAcces(Node e) 指定LinkedHashMap在完成访问操作之后还需做什么,这个方法在HashMap中调用put()方法时,更新相同key节点的value时有调用,但实现也为空。在LinkedHashMap中调用put()、get()方法时会用到,若指定为true,则调用这个方法把最近访问过的节点移动到双端链表末尾。 -(1)若指定accessOrder = true,且访问的节点不是末尾节点 -(2)双向链表中移除该结点并再次添加到链表末尾 +(1)若指定accessOrder = true,且访问的节点不是末尾节点 +(2)双向链表中移除该结点并再次添加到链表末尾 ```java void afterNodeAccess(Node e) { // move node to last LinkedHashMap.Entry last; @@ -164,7 +155,7 @@ public class LinkedHashMap extends HashMap implements Map ### afterNodeRemoval(Node e) 在HashMap中将该节点删除之后,在双端链表也将该节点进行删除 ```java -void afterNodeRemoval(Node e) { // unlink + void afterNodeRemoval(Node e) { // unlink LinkedHashMap.Entry p = (LinkedHashMap.Entry)e, b = p.before, a = p.after; p.before = p.after = null; @@ -201,9 +192,10 @@ void afterNodeRemoval(Node e) { // unlink (2)LinkedHashMap内部维护了一个双端链表存储所有的元素 (3)若accessOrder = false,则按插入元素的顺序进行排序 (4)若accessOrder = true,则按访问元素的顺序进行排序 -(5)默认的LinkedHashMap并不会移除旧元素,如果需要移除达到某个条件的最久未使用的旧元素,则需要重写removeEldestEntry()方法设置淘汰策略 +(5)默认的LinkedHashMap并不会移除旧元素,如果需要移除达到某个条件的最久未使用的旧元素,则需要重写removeEldestEntry()方法设置淘汰策略 +下面是LRU基于LinkedHashMap和手写HashMap+双端链表的两种实现: ### LRU基于LinkedHashMap的实现 ```java public class LRUCache extends LinkedHashMap { @@ -328,4 +320,4 @@ class DoubleLinkedList { } } } -``` \ No newline at end of file +``` From 50bd6d4735f556faa2909e09313b95c7c017fd31 Mon Sep 17 00:00:00 2001 From: Qylningque Date: Sun, 15 Dec 2019 02:30:30 +0800 Subject: [PATCH 30/73] =?UTF-8?q?060-week=2001=2001-ArrayList=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=85=83=E7=B4=A0=E3=80=81=E6=89=A9=E5=AE=B9=E3=80=81?= =?UTF-8?q?=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week_01/60/01_ArrayList/01-ArrayList.md | 221 +++++++++++++++++- week_01/60/01_ArrayList/01-ArrayList.xmind | Bin 207868 -> 0 bytes ...1\345\256\271\346\265\201\347\250\213.png" | Bin 0 -> 90295 bytes 3 files changed, 220 insertions(+), 1 deletion(-) delete mode 100644 week_01/60/01_ArrayList/01-ArrayList.xmind create mode 100644 "week_01/60/01_ArrayList/02_ArrayList\347\232\204grow\346\226\271\346\263\225\346\211\251\345\256\271\346\265\201\347\250\213.png" diff --git a/week_01/60/01_ArrayList/01-ArrayList.md b/week_01/60/01_ArrayList/01-ArrayList.md index a75d9ec..1c4a42c 100644 --- a/week_01/60/01_ArrayList/01-ArrayList.md +++ b/week_01/60/01_ArrayList/01-ArrayList.md @@ -1,5 +1,8 @@ [TOC] +- *本文对于`ArrayList`的源码阅读记录基于`JDK1.8`,个人浅见,如有不妥,敬请指正。* +- *文中 "`//TODO`"处代表个人暂时未懂或标示之后会学习的地方,如有高见,敬请指教。* + # 1.ArrayList底层原理 ## 1.1 ArrayList的UML @@ -83,7 +86,7 @@ public class ArrayList extends AbstractList } /** - * 无参构造函数构造,初始化容量为10 + * 无参构造函数构造,初始化容量为0 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; @@ -106,6 +109,12 @@ public class ArrayList extends AbstractList this.elementData = EMPTY_ELEMENTDATA; } } + + /** + * 数组最大容量限定; + * 预留容量空间,避免内存溢出;为什么要预留?后面会说 + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; ``` ### 1.3.1 ArrayList的默认容量是多少? @@ -220,39 +229,249 @@ public ArrayList(Collection c) { ​ 2.2传入集合不为空时且类型与Object[]不相同时,进行一次`Arrays.copyOf()`,将源数组中的元素类型向上转型后将复制的新数组返回给elementData; +### 1.3.5 ArrayList为什么规定MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 ? +```java + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; +``` +​ 数组对象也是标准的JAVA对象,在JVM(HotSpot)的堆内存中的实际存储方式和格式也满足oop-class二分模型。之所以`MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8` 是因为需要预留一定长度来保存对象元数据的信息,在ArrayList中预留的8字节是用来存储数组长度,因为ArrayList不能计算自己的长度。 +​ 那为什么是`Integer.MAX_VALUE - 8`呢?是因为JVM要求对象的大小必须是8字节的整数倍,因此当“对象头+实例数据”大小不满足8字节的整数倍时,就需要补齐满足前述条件。 +> “ +> +> 按照8字节对齐,是底层CPU数据总线读取内存数据的要求。 +> +> 通常CPU按照字长来读取数据,一个数据若不对齐则可能需要CPU读取两次; +> +> 若进行了对齐,则一次性即可读出目标数据,这将会大大节省CPU资源,因此对象大小需要补齐。 +> +> ” +//TODO *JAVA对象在堆内存中的详情?* +参考: +- [Why the maximum array size of ArrayList is Integer.MAX_VALUE - 8?](https://stackoverflow.com/questions/35756277/why-the-maximum-array-size-of-arraylist-is-integer-max-value-8) +- [如何计算Java对象占堆内存中的大小 ](http://www.sohu.com/a/306845134_505779) +# 2.ArrayList如何添加元素? +​ 向ArrayList中添加元素,在所难免会涉及到ArrayList扩容的情况,在记录添加元素方法前先看看ArrayList的扩容机制。 +## 2.1 ArrayList的扩容机制? +#### 2.1.1 初始判断扩容 +```java + /** + * 比较传入容量的大小 + * 这个方法只有在首次调用时会用到 + **/ + private static int calculateCapacity(Object[] elementData, int minCapacity) { + // 判断ArrayList是否刚初始化 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + return Math.max(DEFAULT_CAPACITY, minCapacity); + } + return minCapacity; + } + // 校验容量的大小 + private void ensureCapacityInternal(int minCapacity) { + ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); + } + private void ensureExplicitCapacity(int minCapacity) { + modCount++;//记录修改,modCount的作用是在List迭代器遍历时用作线程安全检查 + // 如果传入的值大于初始长度,则调用grow()方法进行扩容 + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } +``` +- 初始化判断会判断ArrayList是否刚初始化,如果成立,则将ArrayList扩容为默认容量`DEFAULT_CAPACITY = 10`; +- 若判断 `minCapacity` 和 `DEFAULT_CAPACITY` 的大小,在二者的最大值内还有可用空间,则取二者中的最大值为ArrayList的容量; +- 当`minCapacity` 和`DEFAULT_CAPACITY`的最大值容量都没有可用空间了,则调用`grow()`进行扩容; +#### 2.1.2 调用`grow()`扩容 +```java + /** + * 对列表进行扩容,以确保它至少可以容纳最小容量参数指定的元素。 + * + * @param minCapacity 传入所需的最小容量 + */ + private void grow(int minCapacity) { + // 记录原容量的大小 + int oldCapacity = elementData.length; + // 设置新容量,新容量大小为原容量的1.5倍(右移一位就是1/2) + int newCapacity = oldCapacity + (oldCapacity >> 1); + // 判断新容量是否满足需求,若扩容后仍不够用,将传入最小容量大小复制给新容量 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + // 判断新容量是否超出最大长度限制,如果超出,进入hugeCapacity()处理 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // 将原数组的数据复制至新数组, ArrayList的底层数组引用指向新数组 + elementData = Arrays.copyOf(elementData, newCapacity); + } + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } +``` +- ArrayList调用grow()扩容后容量变为原来1.5倍; +![02_ArrayList的grow方法扩容流程](02_ArrayList的grow方法扩容流程.png) +//TODO *`Arrays.copyOf()`详情?* +## 2.2 将指定元素添加到列表的尾部 +```java + /** + * Appends the specified element to the end of this list. + * + * @param e element to be appended to this list + * @return true (as specified by {@link Collection#add}) + */ + public boolean add(E e) { + ensureCapacityInternal(size + 1); // Increments modCount!! + elementData[size++] = e; + return true; + } +``` +​ 按照前文的ArrayList初始化扩容,的到一个容量为10的ArrayList集合。 +## 2.3 将指定元素添加到列表的指定位置 +```java + /** + * 将指定的元素插入指定位置中。 + * 将当前在该位置的元素(如果有的话)和任何后续元素向右移动(向其索引添加一个) + * @param index 指定元素插入的索引 + * @param element 指定元素 + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public void add(int index, E element) { + rangeCheckForAdd(index);//判断索引是否异常 + + ensureCapacityInternal(size + 1); // 判断是否需要扩容 + //将指定下标空出 具体作法就是index及其后的所有元素后移一位 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + // 将要添加元素赋值到空出来的指定索引处 + elementData[index] = element; + // 长度+1 + size++; + } + /** + * A version of rangeCheck used by add and addAll. + * add和addAll使用的rangeCheck版本。 + */ + private void rangeCheckForAdd(int index) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } +``` + +​ 值得注意的是,对索引处及其后的元素使用了`System.arraycopy()`方法,该方法源码如下: + +```java + /** + * 从指定的源数组开始复制一个数组,该数组从指定位置开始复制到目标数组的指定位置。 + * Object src 源数组对象 + * int srcPos 源数组的起始位置 + * Object dest 目标数组对象 + * int destPos 目标数组的起始位置 + * int length 要复制的元素数量 + **/ + public static native void arraycopy(Object src, int srcPos, + Object dest, int destPos, + int length); +``` + +​ 该方法是一个数组拷贝的方法,使用`native`修饰,一般是由其它语言实现的(如C、C++)。 + +# 3.ArrayList的数组拷贝是怎么实现的? + +```java + /** + * Returns a shallow copy of this ArrayList instance. (The + * elements themselves are not copied.) + * + * @return a clone of this ArrayList instance + */ + public Object clone() { + try { + ArrayList v = (ArrayList) super.clone(); + v.elementData = Arrays.copyOf(elementData, size);//传入源数组对象、目标数组长度 + v.modCount = 0; + return v; + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(e); + } + } +``` +​ 从源码可看出其实ArrayList的拷贝最关键是调用了`Arrays.copyOf()`方法,该方法源码如下: + +```java + public static T[] copyOf(T[] original, int newLength) { + return (T[]) copyOf(original, newLength, original.getClass()); + } + public static T[] copyOf(U[] original, int newLength, Class newType) { + @SuppressWarnings("unchecked") + T[] copy = ((Object)newType == (Object)Object[].class) + ? (T[]) new Object[newLength] + : (T[]) Array.newInstance(newType.getComponentType(), newLength); + System.arraycopy(original, 0, copy, 0, + Math.min(original.length, newLength)); + return copy; + } +``` +- 首先,创建一个和**源数组元素**相同类型的新数组; +- 然后调用`System.arraycopy()`,并且在该方法最后一个参数(要复制的元素数量)中对**源数组长度**和**目标数组长度**进行取最小值判断; +## 3.1 ArrayList中的拷贝是深拷贝还是浅拷贝呢? +```java + ArrayList v = (ArrayList) super.clone(); +``` + +​ 是浅拷贝:在ArrayList的clone()方法中,第一句可以看到调用了`super.clone()`方法复制了一个全新的对象并将其赋值给`V`。由于`java.lang.Object.clone()`只是一种浅拷贝,所以V的`elementData`引用的还是当前ArrayList的`elementData`引用,这就意味着在`V`上进行操作,会影响原来的ArrayList值。 + +## 3.2 如何复制某个ArrayList到另一个ArrayList中去? + +- 浅拷贝 + - 调用`ArrayList.clone()`; + - 使用ArrayList构造方法; + +```java + ArrayList newArray = oldArray.clone(); + + ArrayList newArray = new ArrayList(oldArray); +``` +- 深拷贝 + - 使用Collection的copy方法; diff --git a/week_01/60/01_ArrayList/01-ArrayList.xmind b/week_01/60/01_ArrayList/01-ArrayList.xmind deleted file mode 100644 index a429e4fec05e073b157f9584c631e2584bbaa40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207868 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�c??2gkX2+7VLU@_vEh2%?OFdP~~Btq(SGW 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 C_CVwS diff --git "a/week_01/60/01_ArrayList/02_ArrayList\347\232\204grow\346\226\271\346\263\225\346\211\251\345\256\271\346\265\201\347\250\213.png" "b/week_01/60/01_ArrayList/02_ArrayList\347\232\204grow\346\226\271\346\263\225\346\211\251\345\256\271\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..881664f12cebba19377c58cfda8ea3f014a71b4d GIT binary patch literal 90295 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%0DR~m7^ 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 Date: Sun, 15 Dec 2019 11:41:46 +0800 Subject: [PATCH 31/73] update-ArrayList --- week_01/54/ArrayList-054.md | 464 ++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 week_01/54/ArrayList-054.md diff --git a/week_01/54/ArrayList-054.md b/week_01/54/ArrayList-054.md new file mode 100644 index 0000000..be6a1f3 --- /dev/null +++ b/week_01/54/ArrayList-054.md @@ -0,0 +1,464 @@ +ArrayList底层是基于数组实现的 + +**成员** +/** +* Default initial capacity. 默认的初始容量大小 +*/ +private static final int DEFAULT_CAPACITY = 10; + +/** +* Shared empty array instance used for empty instances.(用于空实例的共享空数组实例)实际上就是空数组对象 +*/ +private static final Object[] EMPTY_ELEMENTDATA = {}; + +/** + * Shared empty array instance used for default sized empty instances. We + * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when + * first element is added. + * 用于默认大小的空实例的共享空数组实例。我们将其与空的元素数据区分开来,以了解何时 + * 添加第一个元素 + */ +private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + +transient Object[] elementData; //用于增删改查的数组 + +/** + * The size of the ArrayList (the number of elements it contains). + * + * @serial + */ +private int size;//元素的大小 默认为0 + + +/** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ +private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//最大数组容量,如果数组过长,会抛出OOM错误 + +**构造方法** + + /** + * Constructs an empty list with the specified initial capacity. + * + * @param initialCapacity the initial capacity of the list + * @throws IllegalArgumentException if the specified initial capacity + * is negative + */ +public ArrayList(int initialCapacity) { +//带初始容量的构造方法 + if (initialCapacity > 0) { + //大于0 新建一个Object数组 + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + //等于0 使用上面的空数组对象 + this.elementData = EMPTY_ELEMENTDATA; + } else { + //其他的 抛出IllegalArgumentException + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } +} + + /** + * Constructs an empty list with an initial capacity of ten. + */ +public ArrayList() { +//无参构造方法,默认上面的数组对象 + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; +} + +/** + * Constructs a list containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. + * + * @param c the collection whose elements are to be placed into this list + * @throws NullPointerException if the specified collection is null + */ +public ArrayList(Collection c) { +//集合的构造方法 + elementData = c.toArray();//把集合转换为数组 + if ((size = elementData.length) != 0) { + //先把集合大小给size,如果集合大小不为0,就会去判断是否为Object[].class + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class);//复制所有元素 + } else { + //集合大小为0 使用上面的空数组对象 + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } +} +**主要方法** + +add方法 +/** + * Appends the specified element to the end of this list.(添加一个特定的元素到list的末尾) + * + * @param e element to be appended to this list + * @return true (as specified by {@link Collection#add}) + */ +public boolean add(E e) { +//向数组中添加元素 + ensureCapacityInternal(size + 1); // Increments modCount!! 确定内部容量是否足够 + //在数据中size++位置放入元素 + elementData[size++] = e; + return true; +} + +private void ensureCapacityInternal(int minCapacity) { + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + //判断传入进来的数组是否为空,因为如果是空的话,minCapacity=size+1; + //其实就是等于1,空的数组没有长度就存放不了,所以就将minCapacity变成10,也就是默认大小, + //但是在这里,还没有真正的初始化这个elementData的大小 + minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); + } + + ensureExplicitCapacity(minCapacity); +} + +private void ensureExplicitCapacity(int minCapacity) { + modCount++; + + // overflow-conscious code + if (minCapacity - elementData.length > 0) + grow(minCapacity);//ArrayList自动扩展大小 +} + +/** + * Increases the capacity to ensure that it can hold at least the + * number of elements specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity + */ +private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length;//先定义一个oldCapacity 存放扩充前的elementData大小 + int newCapacity = oldCapacity + (oldCapacity >> 1);//新的容量为1.5倍的oldCapacity + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity;//当所有为0时,默认为10 + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity);//超出最大容量限制,调用hugeCapacity,就是将能给的最大值给newCapacity + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity);//改变elementData大小 +} + +private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError();//传入的参数必须大于0,否则报OOM错误 + //如果minCapacity 大于MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)(2147483639)就返回Integer.MAX_VALUE( 2的31次方减一)(2147483647) 否则就直接给MAX_ARRAY_SIZE + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } + +/** + * Inserts the specified element at the specified position in this + * list. Shifts the element currently at that position (if any) and + * any subsequent elements to the right (adds one to their indices). + * + * @param index index at which the specified element is to be inserted + * @param element element to be inserted + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public void add(int index, E element) { +//在指定位置插入元素 + + //检查index位置是否合理 + rangeCheckForAdd(index); + + ensureCapacityInternal(size + 1); // Increments modCount!! + + //插入元素之前需要把index之后的元素往后移动一位 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + //index位置元素复制 + elementData[index] = element; + //size增加1 + size++; +} + +/** + * A version of rangeCheck used by add and addAll. + */ +private void rangeCheckForAdd(int index) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));//判断index位置是否超过size和小于0 抛出数组越界异常 +} + +/** + * Appends all of the elements in the specified collection to the end of + * this list, in the order that they are returned by the + * specified collection's Iterator. The behavior of this operation is + * undefined if the specified collection is modified while the operation + * is in progress. (This implies that the behavior of this call is + * undefined if the specified collection is this list, and this + * list is nonempty.) + * + * @param c collection containing elements to be added to this list + * @return true if this list changed as a result of the call + * @throws NullPointerException if the specified collection is null + */ +public boolean addAll(Collection c) { + //向当前集合添加一个集合 + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount //确定容量 + System.arraycopy(a, 0, elementData, size, numNew);//扩容数组长度 + size += numNew; + return numNew != 0;//返回新长度和size是否相等的boolean +} + +/** + * Inserts all of the elements in the specified collection into this + * list, starting at the specified position. Shifts the element + * currently at that position (if any) and any subsequent elements to + * the right (increases their indices). The new elements will appear + * in the list in the order that they are returned by the + * specified collection's iterator. + * + * @param index index at which to insert the first element from the + * specified collection + * @param c collection containing elements to be added to this list + * @return true if this list changed as a result of the call + * @throws IndexOutOfBoundsException {@inheritDoc} + * @throws NullPointerException if the specified collection is null + */ +public boolean addAll(int index, Collection c) { +//将指定集合中的所有元素插入集合,从指定位置开始。移动元素目前处于该位置(如有)以及 +//右边(增加他们的指数)。新的元素将出现在集合中按指定集合的迭代器。 + rangeCheckForAdd(index); + + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount + + int numMoved = size - index; + if (numMoved > 0) + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved); + + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; + return numNew != 0; +} + +remove方法 + +/** + * Removes the element at the specified position in this list. + * Shifts any subsequent elements to the left (subtracts one from their + * indices). + * + * @param index the index of the element to be removed + * @return the element that was removed from the list + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E remove(int index) { +//移除指定位置元素 + + //判断index是否合理 + rangeCheck(index); + + modCount++; + E oldValue = elementData(index);//直接通过索引找到该元素 + + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved);//移动元素 + 赋值为null 让GC更快回收 + elementData[--size] = null; // clear to let GC do its work + + return oldValue; +} + +@SuppressWarnings("unchecked") +E elementData(int index) { + //通过index查找所在对应位置元素 + return (E) elementData[index]; +} + + /** + * Removes the first occurrence of the specified element from this list, + * if it is present. If the list does not contain the element, it is + * unchanged. More formally, removes the element with the lowest index + * i such that + * (o==null ? get(i)==null : o.equals(get(i))) + * (if such an element exists). Returns true if this list + * contained the specified element (or equivalently, if this list + * changed as a result of the call). + * + * @param o element to be removed from this list, if present + * @return true if this list contained the specified element + */ +public boolean remove(Object o) { +//循环所有找到对应的元素 + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else { + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; +} + +/* + * Private remove method that skips bounds checking and does not + * return the value removed. + */ +private void fastRemove(int index) { + //其实就跟remove(int index)方法一样 + modCount++; + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work +} + +/** + * Removes all of the elements from this list. The list will + * be empty after this call returns. + */ +public void clear() { +//把所有元素置换成null 让GC快速回收 + modCount++; + + // clear to let GC do its work + for (int i = 0; i < size; i++) + elementData[i] = null; + + size = 0; +} + +/** + * Removes from this list all of the elements whose index is between + * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. + * Shifts any succeeding elements to the left (reduces their index). + * This call shortens the list by {@code (toIndex - fromIndex)} elements. + * (If {@code toIndex==fromIndex}, this operation has no effect.) + * + * @throws IndexOutOfBoundsException if {@code fromIndex} or + * {@code toIndex} is out of range + * ({@code fromIndex < 0 || + * fromIndex >= size() || + * toIndex > size() || + * toIndex < fromIndex}) + */ +protected void removeRange(int fromIndex, int toIndex) { +//移除一个区间内的元素 + modCount++; + int numMoved = size - toIndex; + System.arraycopy(elementData, toIndex, elementData, fromIndex, + numMoved); + // clear to let GC do its work + int newSize = size - (toIndex-fromIndex); + for (int i = newSize; i < size; i++) { + elementData[i] = null; + } + size = newSize; +} + +/** + * Removes from this list all of its elements that are contained in the + * specified collection. + * + * @param c collection containing elements to be removed from this list + * @return {@code true} if this list changed as a result of the call + * @throws ClassCastException if the class of an element of this list + * is incompatible with the specified collection + * (optional) + * @throws NullPointerException if this list contains a null element and the + * specified collection does not permit null elements + * (optional), + * or if the specified collection is null + * @see Collection#contains(Object) + */ +public boolean removeAll(Collection c) { + Objects.requireNonNull(c);//判断是否为Null + return batchRemove(c, false); +} + +//Objects里面的方法 +public static T requireNonNull(T obj) { + if (obj == null) + throw new NullPointerException(); + return obj; +} + +private boolean batchRemove(Collection c, boolean complement) { + final Object[] elementData = this.elementData;//记录原集合为elementData + int r = 0, w = 0; + boolean modified = false; + try { + for (; r < size; r++) + if (c.contains(elementData[r]) == complement) + elementData[w++] = elementData[r];//判断集合是否有,有就给elementData + } finally { + // Preserve behavioral compatibility with AbstractCollection, + // even if c.contains() throws. + if (r != size) { + //如果数量不相等 则把剩下的元素给elementData + System.arraycopy(elementData, r, + elementData, w, + size - r); + w += size - r; + } + if (w != size) { + // clear to let GC do its work + for (int i = w; i < size; i++) + elementData[i] = null; + modCount += size - w; + size = w; + modified = true; + } + } + return modified; +} + +修改 + +/** + * Replaces the element at the specified position in this list with + * the specified element. + * + * @param index index of the element to replace + * @param element element to be stored at the specified position + * @return the element previously at the specified position + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E set(int index, E element) { +//修改指定index位置下的元素 + rangeCheck(index); + + E oldValue = elementData(index); + elementData[index] = element; + return oldValue;//返回旧的元素 +} + +查询 + +/** + * Returns the element at the specified position in this list. + * + * @param index index of the element to return + * @return the element at the specified position in this list + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E get(int index) { +//查询指定位置下的元素 + rangeCheck(index); + + return elementData(index); +} From f45ebdd26165bdeed9de0bf2473037f97a3e3d88 Mon Sep 17 00:00:00 2001 From: duxin <673036378@qq.com> Date: Sun, 15 Dec 2019 12:34:03 +0800 Subject: [PATCH 32/73] HashMap --- week_01/54/HashMap-054.md | 569 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 569 insertions(+) create mode 100644 week_01/54/HashMap-054.md diff --git a/week_01/54/HashMap-054.md b/week_01/54/HashMap-054.md new file mode 100644 index 0000000..9114760 --- /dev/null +++ b/week_01/54/HashMap-054.md @@ -0,0 +1,569 @@ +###### 基于jdk1.8的HashMap源码分析 + +**成员** +/** + * The default initial capacity - MUST be a power of two. + */ +static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 初始容量默认16 必须为2的n次方 + +/** + * The maximum capacity, used if a higher value is implicitly specified + * by either of the constructors with arguments. + * MUST be a power of two <= 1<<30. + */ +static final int MAXIMUM_CAPACITY = 1 << 30; 最大容量 2的30次方 + +/** + * The load factor used when none specified in constructor. + */ +static final float DEFAULT_LOAD_FACTOR = 0.75f; 加载因子默认0.75 + +/** + * The bin count threshold for using a tree rather than list for a + * bin. Bins are converted to trees when adding an element to a + * bin with at least this many nodes. The value must be greater + * than 2 and should be at least 8 to mesh with assumptions in + * tree removal about conversion back to plain bins upon + * shrinkage. + */ +static final int TREEIFY_THRESHOLD = 8;//链表转换成红黑树的阈值为8 + +/** + * The bin count threshold for untreeifying a (split) bin during a + * resize operation. Should be less than TREEIFY_THRESHOLD, and at + * most 6 to mesh with shrinkage detection under removal. + */ +static final int UNTREEIFY_THRESHOLD = 6;//当红黑树数量小于6会转换为链表 + +/** + * The smallest table capacity for which bins may be treeified. + * (Otherwise the table is resized if too many nodes in a bin.) + * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts + * between resizing and treeification thresholds. + */ +static final int MIN_TREEIFY_CAPACITY = 64;//当hashmap元素数量大于64也会转换为红黑树 + +/** + * The table, initialized on first use, and resized as + * necessary. When allocated, length is always a power of two. + * (We also tolerate length zero in some operations to allow + * bootstrapping mechanics that are currently not needed.) + */ +transient Node[] table;//不能被序列化的数组 + +/** + * Holds cached entrySet(). Note that AbstractMap fields are used + * for keySet() and values(). + */ +transient Set> entrySet;//数据转为set的存储方式,主要用于迭代功能 + +/** + * The number of key-value mappings contained in this map. + */ +transient int size;//元素数量 + + +/** + * The number of times this HashMap has been structurally modified + * Structural modifications are those that change the number of mappings in + * the HashMap or otherwise modify its internal structure (e.g., + * rehash). This field is used to make iterators on Collection-views of + * the HashMap fail-fast. (See ConcurrentModificationException). + */ +transient int modCount;//修改的次数 + +/** + * The next size value at which to resize (capacity * load factor). + * + * @serial + */ +// (The javadoc description is true upon serialization. +// Additionally, if the table array has not been allocated, this +// field holds the initial array capacity, or zero signifying +// DEFAULT_INITIAL_CAPACITY.) +int threshold;//临界值 + +/** + * The load factor for the hash table. + * + * @serial + */ +final float loadFactor;//加载因子(变量) + +**构造方法** + +/** + * Constructs an empty HashMap with the specified initial + * capacity and load factor. + * + * @param initialCapacity the initial capacity + * @param loadFactor the load factor + * @throws IllegalArgumentException if the initial capacity is negative + * or the load factor is nonpositive + */ +public HashMap(int initialCapacity, float loadFactor) { + //传入初始容量和加载因子 + if (initialCapacity < 0) + //初始容量小于0 抛出IllegalArgumentException + throw new IllegalArgumentException("Illegal initial capacity: " + + initialCapacity); + if (initialCapacity > MAXIMUM_CAPACITY) + //初始容量大于最大值,就设定为MAXIMUM_CAPACITY + initialCapacity = MAXIMUM_CAPACITY; + if (loadFactor <= 0 || Float.isNaN(loadFactor)) + //加载因子小于等于0 或者为NaN 抛出IllegalArgumentException + throw new IllegalArgumentException("Illegal load factor: " + + loadFactor); + this.loadFactor = loadFactor; + this.threshold = tableSizeFor(initialCapacity); +} + +/** + * Returns a power of two size for the given target capacity.返回给定目标容量的二次幂 + */ +static final int tableSizeFor(int cap) { + int n = cap - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; +} + +/** + * Constructs an empty HashMap with the specified initial + * capacity and the default load factor (0.75). + * + * @param initialCapacity the initial capacity. + * @throws IllegalArgumentException if the initial capacity is negative. + */ +public HashMap(int initialCapacity) { +//传入初始容量 使用0.75默认加载因子 + this(initialCapacity, DEFAULT_LOAD_FACTOR); +} + +/** + * Constructs an empty HashMap with the default initial capacity + * (16) and the default load factor (0.75). + */ +public HashMap() { + this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted +} + +/** + * Constructs a new HashMap with the same mappings as the + * specified Map. The HashMap is created with + * default load factor (0.75) and an initial capacity sufficient to + * hold the mappings in the specified Map. + * + * @param m the map whose mappings are to be placed in this map + * @throws NullPointerException if the specified map is null + */ +public HashMap(Map m) { + // 把一个Map集合转换为HashMap集合 + this.loadFactor = DEFAULT_LOAD_FACTOR; + putMapEntries(m, false); +} + +/** + * Implements Map.putAll and Map constructor 实现Map.putAll和Map构造函数 + * + * @param m the map + * @param evict false when initially constructing this map, else + * true (relayed to method afterNodeInsertion). + */ +final void putMapEntries(Map m, boolean evict) { + int s = m.size();//获取集合大小 + if (s > 0) { + if (table == null) { // pre-size + float ft = ((float)s / loadFactor) + 1.0F;//需要的容量 + //判断容量是否超出最大容量,若超出则给最大容量 + int t = ((ft < (float)MAXIMUM_CAPACITY) ? + (int)ft : MAXIMUM_CAPACITY); + if (t > threshold) //初始化临界值 + threshold = tableSizeFor(t); + } + else if (s > threshold) + //如果table进行了初始化 则进行扩容 + resize(); + //遍历元素通过putval方法放入map里面 + for (Map.Entry e : m.entrySet()) { + K key = e.getKey(); + V value = e.getValue(); + putVal(hash(key), key, value, false, evict); + } + } +} + +**核心方法** + +hash计算 + +/** + * Computes key.hashCode() and spreads (XORs) higher bits of hash + * to lower. Because the table uses power-of-two masking, sets of + * hashes that vary only in bits above the current mask will + * always collide. (Among known examples are sets of Float keys + * holding consecutive whole numbers in small tables.) So we + * apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed (so don't benefit from + * spreading), and because we use trees to handle large sets of + * collisions in bins, we just XOR some shifted bits in the + * cheapest possible way to reduce systematic lossage, as well as + * to incorporate impact of the highest bits that would otherwise + * never be used in index calculations because of table bounds. + */ +static final int hash(Object key) { + int h; + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//根据传入的key的hashcode,进行一次异或运算,为了减少hash冲突 +} + +put方法 + +/** + * Associates the specified value with the specified key in this map. + * If the map previously contained a mapping for the key, the old + * value is replaced. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with key, or + * null if there was no mapping for key. + * (A null return can also indicate that the map + * previously associated null with key.) + */ +public V put(K key, V value) { + return putVal(hash(key), key, value, false, true);//实际上使用putVal方法 +} + +/** + * Implements Map.put and related methods + * + * @param hash hash for key + * @param key the key + * @param value the value to put + * @param onlyIfAbsent if true, don't change existing value + * @param evict if false, the table is in creation mode. + * @return previous value, or null if none + */ +final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { + Node[] tab; Node p; int n, i; + if ((tab = table) == null || (n = tab.length) == 0) + //判断table是否初始化,没有就进行扩容 + n = (tab = resize()).length; + if ((p = tab[i = (n - 1) & hash]) == null) + //判断当前hash有没有值,没有值就新建一个node + tab[i] = newNode(hash, key, value, null); + + //hash冲突的情况 + else { + Node e; K k; + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + //第一种情况key与当前节点相等 + e = p; + else if (p instanceof TreeNode) + //第二种情况 判断是否为红黑树的节点 + //如果为红黑树的节点,则在红黑树里面进行添加,若存在则返回null + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + else { + //第三种为链表 + for (int binCount = 0; ; ++binCount) { + //遍历链表 + if ((e = p.next) == null) { + //如果没有重复,在尾部直接添加 + p.next = newNode(hash, key, value, null); + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + //判断是否转换成红黑树结构 + treeifyBin(tab, hash); + break; + } + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + //如果有重复的则结束循环 + break; + p = e; + } + } + if (e != null) { // existing mapping for key + //如果有重复的key,替换新值 返回旧值 + V oldValue = e.value; + if (!onlyIfAbsent || oldValue == null) + e.value = value; + afterNodeAccess(e); + return oldValue; + } + } + ++modCount;//修改次数++ + if (++size > threshold)//判断是否大于临界值 + resize();//扩容 + afterNodeInsertion(evict); + return null; +} + +/** + * Copies all of the mappings from the specified map to this map. + * These mappings will replace any mappings that this map had for + * any of the keys currently in the specified map. + * + * @param m mappings to be stored in this map + * @throws NullPointerException if the specified map is null + */ +public void putAll(Map m) { + //插入map集合直接调用putMapEntries方法 + putMapEntries(m, true); +} + +扩容 + +/** + * Initializes or doubles table size. If null, allocates in + * accord with initial capacity target held in field threshold. + * Otherwise, because we are using power-of-two expansion, the + * elements from each bin must either stay at same index, or move + * with a power of two offset in the new table. + * + * @return the table + */ +final Node[] resize() { + Node[] oldTab = table; + //old长度 + int oldCap = (oldTab == null) ? 0 : oldTab.length; + //old临界值 + int oldThr = threshold; + //初始化new的长度和临界值 + int newCap, newThr = 0; + if (oldCap > 0) { + //不是首次初始化 + if (oldCap >= MAXIMUM_CAPACITY) { + //如果超出最大容量 设置阈值为int的最大 + threshold = Integer.MAX_VALUE; + return oldTab; + } + else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && + oldCap >= DEFAULT_INITIAL_CAPACITY) + //扩容为原来的2倍 + newThr = oldThr << 1; // double threshold + } + else if (oldThr > 0) // initial capacity was placed in threshold + newCap = oldThr;//已经初始化 判断临界值>0 newCap为以前的临界值 + else { // zero initial threshold signifies using defaults + //其他情况 + newCap = DEFAULT_INITIAL_CAPACITY;//newCap使用默认的初始化容量 + newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);//默认的加载因子*默认的初始化容量 + } + if (newThr == 0) { + //如果传入cap为小于16 newThr没有值 + //新的临界值 + float ft = (float)newCap * loadFactor; + //判断新的容量是否小于最大值和临界值是否小于最大容量,否则返回Int最大值 + newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? + (int)ft : Integer.MAX_VALUE); + } + threshold = newThr; + @SuppressWarnings({"rawtypes","unchecked"}) + Node[] newTab = (Node[])new Node[newCap]; + table = newTab; + if (oldTab != null) { + for (int j = 0; j < oldCap; ++j) { + //遍历oldCap元素 + Node e; + //当前数组下标有值 + if ((e = oldTab[j]) != null) { + //方便gc回收 + oldTab[j] = null; + if (e.next == null) + //没有下一个元素,把值放入newTab中 + newTab[e.hash & (newCap - 1)] = e; + else if (e instanceof TreeNode) + //红黑树情况,转移到newTab中 + ((TreeNode)e).split(this, newTab, j, oldCap); + else { // preserve order + //链表结构,遍历值转到newTab中 + Node loHead = null, loTail = null; + Node hiHead = null, hiTail = null; + Node next; + do { + next = e.next; + if ((e.hash & oldCap) == 0) { + if (loTail == null) + loHead = e; + else + loTail.next = e; + loTail = e; + } + else { + if (hiTail == null) + hiHead = e; + else + hiTail.next = e; + hiTail = e; + } + } while ((e = next) != null); + if (loTail != null) { + loTail.next = null; + newTab[j] = loHead; + } + if (hiTail != null) { + hiTail.next = null; + newTab[j + oldCap] = hiHead; + } + } + } + } + } + return newTab; +} + +删除 + +/** + * Removes the mapping for the specified key from this map if present. + * + * @param key key whose mapping is to be removed from the map + * @return the previous value associated with key, or + * null if there was no mapping for key. + * (A null return can also indicate that the map + * previously associated null with key.) + */ +public V remove(Object key) { +//根据key删除元素,调用removeNode方法,返回null 或者被删除的value + Node e; + return (e = removeNode(hash(key), key, null, false, true)) == null ? + null : e.value; +} + +/** + * Implements Map.remove and related methods + * + * @param hash hash for key + * @param key the key + * @param value the value to match if matchValue, else ignored + * @param matchValue if true only remove if value is equal + * @param movable if false do not move other nodes while removing + * @return the node, or null if none + */ +final Node removeNode(int hash, Object key, Object value, + boolean matchValue, boolean movable) { + Node[] tab; Node p; int n, index; + if ((tab = table) != null && (n = tab.length) > 0 && + (p = tab[index = (n - 1) & hash]) != null) { + //数组不为null tab的长度大于0 删除的节点在数组的下标位置 + Node node = null, e; K k; V v; + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + //如果数组下面的变量刚好是要删除的元素,赋值给临时变量node + node = p; + else if ((e = p.next) != null) {//要删除的key在链表或者红黑树上面 + if (p instanceof TreeNode) + //从红黑树里面获取值 + node = ((TreeNode)p).getTreeNode(hash, key); + else { + //循环链表 + do { + if (e.hash == hash && + ((k = e.key) == key || + (key != null && key.equals(k)))) { + //找到值并且复制给临时node + node = e; + break; + } + p = e; + } while ((e = e.next) != null); + } + } + if (node != null && (!matchValue || (v = node.value) == value || + (value != null && value.equals(v)))) { + if (node instanceof TreeNode) + //如果实在红黑树里面 removeTreeNode方法 + ((TreeNode)node).removeTreeNode(this, tab, movable); + else if (node == p) + //为链表且为头节点直接把node.next赋值给tab + tab[index] = node.next; + else + //如果为链表某一节点,复制给上一个p.next为node.next + p.next = node.next; + ++modCount;//修改次数++ + --size;//数量-- + afterNodeRemoval(node); + return node; + } + } + return null; +} + +/** + * Removes all of the mappings from this map. + * The map will be empty after this call returns. + */ +public void clear() { +//清空 + Node[] tab; + modCount++; + if ((tab = table) != null && size > 0) { + //循环table所有置为null + size = 0; + for (int i = 0; i < tab.length; ++i) + tab[i] = null; + } +} + +查询 + +/** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + *

More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code (key==null ? k==null : + * key.equals(k))}, then this method returns {@code v}; otherwise + * it returns {@code null}. (There can be at most one such mapping.) + * + *

A return value of {@code null} does not necessarily + * indicate that the map contains no mapping for the key; it's also + * possible that the map explicitly maps the key to {@code null}. + * The {@link #containsKey containsKey} operation may be used to + * distinguish these two cases. + * + * @see #put(Object, Object) + */ +public V get(Object key) { +//获取相应key的value通过getNode方法实现 + Node e; + return (e = getNode(hash(key), key)) == null ? null : e.value; +} + +/** + * Implements Map.get and related methods + * + * @param hash hash for key + * @param key the key + * @return the node, or null if none + */ +final Node getNode(int hash, Object key) { + Node[] tab; Node first, e; int n; K k; + if ((tab = table) != null && (n = tab.length) > 0 && + (first = tab[(n - 1) & hash]) != null) { + if (first.hash == hash && // always check first node + ((k = first.key) == key || (key != null && key.equals(k)))) + //判断是否为头节点 + return first; + if ((e = first.next) != null) { + if (first instanceof TreeNode) + //从红黑树里面查找 + return ((TreeNode)first).getTreeNode(hash, key); + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + //循环整个链表 + return e; + } while ((e = e.next) != null); + } + } + //没有则返回null + return null; +} \ No newline at end of file From d6847cc2e3736e6417d3eac1eecec2a381438bd7 Mon Sep 17 00:00:00 2001 From: duxin <673036378@qq.com> Date: Sun, 15 Dec 2019 13:05:20 +0800 Subject: [PATCH 33/73] LinkedList --- week_01/54/LinkedList-054.md | 265 +++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 week_01/54/LinkedList-054.md diff --git a/week_01/54/LinkedList-054.md b/week_01/54/LinkedList-054.md new file mode 100644 index 0000000..3a51d0f --- /dev/null +++ b/week_01/54/LinkedList-054.md @@ -0,0 +1,265 @@ +###### LinkedList基于jdk1.8源码分析 + +**成员** + +transient int size = 0;//list节点个数 + +/** + * Pointer to first node.指向头节点 + * Invariant: (first == null && last == null) || + * (first.prev == null && first.item != null) + */ +transient Node first; + +/** + * Pointer to last node.//指向尾节点 + * Invariant: (first == null && last == null) || + * (last.next == null && last.item != null) + */ +transient Node last; + +**构造函数** + +/** + * Constructs an empty list.//创建一个空list + */ +public LinkedList() { +} + +/** + * Constructs a list containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. + * + * @param c the collection whose elements are to be placed into this list + * @throws NullPointerException if the specified collection is null + */ +public LinkedList(Collection c) { +//把一个Collection变为LinkedList + this(); + addAll(c); +} + +**核心方法** + +添加 + +/** + * Appends the specified element to the end of this list. + * + *

This method is equivalent to {@link #addLast}. + * + * @param e element to be appended to this list + * @return {@code true} (as specified by {@link Collection#add}) + */ +public boolean add(E e) { +//添加一个元素,通过linkLast方法 + linkLast(e); + return true; +} + +/** + * Links e as last element.向尾部添加一个元素 + */ +void linkLast(E e) { + final Node l = last; + final Node newNode = new Node<>(l, e, null);以尾部元素为前面节点next创建一个新节点 + last = newNode; + if (l == null) + //判断是否为空链表 + first = newNode;//头节点为newNode + else + l.next = newNode;//将原来的尾部next插入需要插入的节点 + //更新链表的次数以及大小 + size++; + modCount++; +} + +/** + * Inserts the specified element at the specified position in this list. + * Shifts the element currently at that position (if any) and any + * subsequent elements to the right (adds one to their indices). + * + * @param index index at which the specified element is to be inserted + * @param element element to be inserted + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public void add(int index, E element) { +//指定位置插入元素 + checkPositionIndex(index);//检查位置是否合理 + + if (index == size) + linkLast(element);//如果位置是在最后一位采用尾插法 + else + linkBefore(element, node(index)); +} + +/** + * Inserts element e before non-null Node succ. + */ +void linkBefore(E e, Node succ) { + // assert succ != null; + final Node pred = succ.prev;//插入位置的前节点 + final Node newNode = new Node<>(pred, e, succ);//新建节点为succ的前节点 + succ.prev = newNode;succ的前节点为newNode + if (pred == null) + //前节点为null 表示为头节点 ,直接first为newNode + first = newNode; + else + //插入位置的前节点的next为newNode + pred.next = newNode; + size++; + modCount++; +} + +/** + * Appends all of the elements in the specified collection to the end of + * this list, in the order that they are returned by the specified + * collection's iterator. The behavior of this operation is undefined if + * the specified collection is modified while the operation is in + * progress. (Note that this will occur if the specified collection is + * this list, and it's nonempty.) + * + * @param c collection containing elements to be added to this list + * @return {@code true} if this list changed as a result of the call + * @throws NullPointerException if the specified collection is null + */ +public boolean addAll(Collection c) { +//在size后面添加一个Collection集合 + return addAll(size, c); +} + +/** + * Inserts all of the elements in the specified collection into this + * list, starting at the specified position. Shifts the element + * currently at that position (if any) and any subsequent elements to + * the right (increases their indices). The new elements will appear + * in the list in the order that they are returned by the + * specified collection's iterator. + * + * @param index index at which to insert the first element + * from the specified collection + * @param c collection containing elements to be added to this list + * @return {@code true} if this list changed as a result of the call + * @throws IndexOutOfBoundsException {@inheritDoc} + * @throws NullPointerException if the specified collection is null + */ +public boolean addAll(int index, Collection c) { + checkPositionIndex(index);//检查位置是否合理 + + Object[] a = c.toArray();//转换为数组 + int numNew = a.length; + if (numNew == 0)//数组大小为0 + return false; + + Node pred, succ; + if (index == size) {//如果size和index相等,初始化succ为null,pred为尾节点 + succ = null; + pred = last; + } else { + //否则 采用折半查找index元素,并设置succ为当前index的数据,pred为当前元素的prev + succ = node(index); + pred = succ.prev; + } + + for (Object o : a) { + //循环object数组,链表循环添加 + @SuppressWarnings("unchecked") E e = (E) o; + Node newNode = new Node<>(pred, e, null); + if (pred == null) + first = newNode; + else + pred.next = newNode; + pred = newNode; + } + //循环结束后,判断如果succ是null, 说明此时是在队尾添加的,设置一下队列尾节点last, + //如果不是在队尾,则更新之前插入位置节点的前节点和当前要插入节点的尾节点 + if (succ == null) { + last = pred; + } else { + pred.next = succ; + succ.prev = pred; + } + + size += numNew; + modCount++; + return true; +} + +删除 +/** + * Removes the element at the specified position in this list. Shifts any + * subsequent elements to the left (subtracts one from their indices). + * Returns the element that was removed from the list. + * + * @param index the index of the element to be removed + * @return the element previously at the specified position + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E remove(int index) { +//删除指定位置的元素 + checkElementIndex(index); + return unlink(node(index)); +} + +/** + * Unlinks non-null node x. + */ +E unlink(Node x) { + // assert x != null; + final E element = x.item; + final Node next = x.next;//获取当前next赋值给临时node next + final Node prev = x.prev;//获取当前prev赋值给临时node prev + + if (prev == null) { + //头节点 + first = next;//直接赋值 + } else { + prev.next = next;//把next给prev的next + x.prev = null;//设置为null + } + + if (next == null) { + //尾节点 + last = prev; + } else { + next.prev = prev; + x.next = null; + } + + x.item = null; + size--; + modCount++; + return element; +} + +查询 +/** + * Returns the element at the specified position in this list. + * + * @param index index of the element to return + * @return the element at the specified position in this list + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E get(int index) { + checkElementIndex(index);//判断位置是否合理 + return node(index).item;//折半查找 +} + +修改 +/** + * Replaces the element at the specified position in this list with the + * specified element. + * + * @param index index of the element to replace + * @param element element to be stored at the specified position + * @return the element previously at the specified position + * @throws IndexOutOfBoundsException {@inheritDoc} + */ +public E set(int index, E element) { + checkElementIndex(index);//判断位置是否合理 + Node x = node(index);//折半查找 + E oldVal = x.item;//获取旧元素 + x.item = element;//替换成新的元素 + return oldVal;//返回旧元素 +} \ No newline at end of file From 848b96cddc9385e38fc30316ba6ef3cb7ec18235 Mon Sep 17 00:00:00 2001 From: dans <365223296@qq.com> Date: Sun, 15 Dec 2019 14:56:41 +0800 Subject: [PATCH 34/73] me. --- week_01/01/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/02/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/03/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/04/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/05/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/06/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/07/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/08/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/09/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/10/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/11/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/12/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/13/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/14/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/15/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/16/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/17/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/18/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/19/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/20/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/21/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/22/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/23/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/24/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/25/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/26/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/27/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/28/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/29/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/30/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/31/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/32/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/33/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/34/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/36/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/37/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/38/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/39/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/40/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/41/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/42/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/43/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/44/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/45/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/46/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/47/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/48/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/49/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/50/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/51/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/52/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/53/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/54/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/55/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/56/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/57/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/58/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/59/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/60/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/61/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/62/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/63/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/64/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/65/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/66/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/67/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/68/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/69/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ week_01/70/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ 69 files changed, 3243 insertions(+) create mode 100644 week_01/01/README.md create mode 100644 week_01/02/README.md create mode 100644 week_01/03/README.md create mode 100644 week_01/04/README.md create mode 100644 week_01/05/README.md create mode 100644 week_01/06/README.md create mode 100644 week_01/07/README.md create mode 100644 week_01/08/README.md create mode 100644 week_01/09/README.md create mode 100644 week_01/10/README.md create mode 100644 week_01/11/README.md create mode 100644 week_01/12/README.md create mode 100644 week_01/13/README.md create mode 100644 week_01/14/README.md create mode 100644 week_01/15/README.md create mode 100644 week_01/16/README.md create mode 100644 week_01/17/README.md create mode 100644 week_01/18/README.md create mode 100644 week_01/19/README.md create mode 100644 week_01/20/README.md create mode 100644 week_01/21/README.md create mode 100644 week_01/22/README.md create mode 100644 week_01/23/README.md create mode 100644 week_01/24/README.md create mode 100644 week_01/25/README.md create mode 100644 week_01/26/README.md create mode 100644 week_01/27/README.md create mode 100644 week_01/28/README.md create mode 100644 week_01/29/README.md create mode 100644 week_01/30/README.md create mode 100644 week_01/31/README.md create mode 100644 week_01/32/README.md create mode 100644 week_01/33/README.md create mode 100644 week_01/34/README.md create mode 100644 week_01/36/README.md create mode 100644 week_01/37/README.md create mode 100644 week_01/38/README.md create mode 100644 week_01/39/README.md create mode 100644 week_01/40/README.md create mode 100644 week_01/41/README.md create mode 100644 week_01/42/README.md create mode 100644 week_01/43/README.md create mode 100644 week_01/44/README.md create mode 100644 week_01/45/README.md create mode 100644 week_01/46/README.md create mode 100644 week_01/47/README.md create mode 100644 week_01/48/README.md create mode 100644 week_01/49/README.md create mode 100644 week_01/50/README.md create mode 100644 week_01/51/README.md create mode 100644 week_01/52/README.md create mode 100644 week_01/53/README.md create mode 100644 week_01/54/README.md create mode 100644 week_01/55/README.md create mode 100644 week_01/56/README.md create mode 100644 week_01/57/README.md create mode 100644 week_01/58/README.md create mode 100644 week_01/59/README.md create mode 100644 week_01/60/README.md create mode 100644 week_01/61/README.md create mode 100644 week_01/62/README.md create mode 100644 week_01/63/README.md create mode 100644 week_01/64/README.md create mode 100644 week_01/65/README.md create mode 100644 week_01/66/README.md create mode 100644 week_01/67/README.md create mode 100644 week_01/68/README.md create mode 100644 week_01/69/README.md create mode 100644 week_01/70/README.md diff --git a/week_01/01/README.md b/week_01/01/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/01/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/02/README.md b/week_01/02/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/02/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/03/README.md b/week_01/03/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/03/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/04/README.md b/week_01/04/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/04/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/05/README.md b/week_01/05/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/05/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/06/README.md b/week_01/06/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/06/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/07/README.md b/week_01/07/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/07/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/08/README.md b/week_01/08/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/08/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/09/README.md b/week_01/09/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/09/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/10/README.md b/week_01/10/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/10/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/11/README.md b/week_01/11/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/11/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/12/README.md b/week_01/12/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/12/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/13/README.md b/week_01/13/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/13/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/14/README.md b/week_01/14/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/14/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/15/README.md b/week_01/15/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/15/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/16/README.md b/week_01/16/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/16/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/17/README.md b/week_01/17/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/17/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/18/README.md b/week_01/18/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/18/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/19/README.md b/week_01/19/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/19/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/20/README.md b/week_01/20/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/20/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/21/README.md b/week_01/21/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/21/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/22/README.md b/week_01/22/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/22/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/23/README.md b/week_01/23/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/23/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/24/README.md b/week_01/24/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/24/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/25/README.md b/week_01/25/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/25/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/26/README.md b/week_01/26/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/26/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/27/README.md b/week_01/27/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/27/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/28/README.md b/week_01/28/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/28/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/29/README.md b/week_01/29/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/29/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/30/README.md b/week_01/30/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/30/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/31/README.md b/week_01/31/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/31/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/32/README.md b/week_01/32/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/32/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/33/README.md b/week_01/33/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/33/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/34/README.md b/week_01/34/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/34/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/36/README.md b/week_01/36/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/36/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/37/README.md b/week_01/37/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/37/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/38/README.md b/week_01/38/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/38/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/39/README.md b/week_01/39/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/39/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/40/README.md b/week_01/40/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/40/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/41/README.md b/week_01/41/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/41/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/42/README.md b/week_01/42/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/42/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/43/README.md b/week_01/43/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/43/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/44/README.md b/week_01/44/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/44/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/45/README.md b/week_01/45/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/45/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/46/README.md b/week_01/46/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/46/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/47/README.md b/week_01/47/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/47/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/48/README.md b/week_01/48/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/48/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/49/README.md b/week_01/49/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/49/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/50/README.md b/week_01/50/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/50/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/51/README.md b/week_01/51/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/51/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/52/README.md b/week_01/52/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/52/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/53/README.md b/week_01/53/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/53/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/54/README.md b/week_01/54/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/54/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/55/README.md b/week_01/55/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/55/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/56/README.md b/week_01/56/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/56/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/57/README.md b/week_01/57/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/57/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/58/README.md b/week_01/58/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/58/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/59/README.md b/week_01/59/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/59/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/60/README.md b/week_01/60/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/60/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/61/README.md b/week_01/61/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/61/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/62/README.md b/week_01/62/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/62/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/63/README.md b/week_01/63/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/63/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/64/README.md b/week_01/64/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/64/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/65/README.md b/week_01/65/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/65/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/66/README.md b/week_01/66/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/66/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/67/README.md b/week_01/67/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/67/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/68/README.md b/week_01/68/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/68/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/69/README.md b/week_01/69/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/69/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file diff --git a/week_01/70/README.md b/week_01/70/README.md new file mode 100644 index 0000000..5bb53d0 --- /dev/null +++ b/week_01/70/README.md @@ -0,0 +1,47 @@ +## 源码刻意学习小组 + +[TOC] + + + +### 一、学习周期(2个月) + +| 时间 | 内容 | +| :------------------------------- | ------- | +| 第一周 (2019/12/09-2019/12.15) | jdk || +| 第二周 (2019/12/16-2019/12.22) | jdk || +| 第三周 (2019/12/23-2019/12.29) | jdk || +| 第四周 (2019/12/30-2020/01/05) | jdk || +| 第五周 (2020/01/06-2020/01/12) | Spring || +| 第六周 (2020/01/13-2020/01/19) | Spring || +| 第七周 (2020/01/20-2020/01/26) | MyBatis || +| 第八周 (2020/01/27-2020/02/02) | MyBatis || + + + +### 二、作业 + +#### 1、源码学习笔记(必做) + +​ 至少提交2个类的源码分析笔记 + +#### 2、本周学习总结(可选) + +​ 学习总结直接在GitHub的issue上发布即可。 + +#### 3、review5名其他的学习笔记或学习总结 + +​ 在项目的`Pull requests`可以看到其他人的Pull requests记录,并进行review。 + + + +###三、源码提交流程 +- 先将[xxx]仓库 `fork` 到自己的 GitHub 账号下。 +- 将 `fork` 后的仓库 `clone` 到本地,然后在本地新建、修改自己的源码学习笔记,**注意:** 仅允许在和自己编号对应的目录下新建或修改自己的源码学习笔记。完成后,将相关修改部分 `push` 到自己的 GitHub 远程仓库。 +- 当完成本周作业,提交 `Pull Request`申请给[xxx]仓库,Pull 作业时,必须备注自己的编号和提交第几周的作业,如`007-week 02`,是指编号为`007`的成员提交的`第二周`的源码学习笔记。 +- 源码学习笔记的命名规则:**`内容标题-编号`**,比如学号为 `007` 的成员完成`ArrayList`类后,请将源码学习笔记名保存为 `ArrayList-007 `。(内容标题自定义) +- 务必按照Pull Request的备注形式和作业文件的命名进行提交,这样方便统计。 + + + +ps:任何学习上的问题可以发布issure求助,其他同学有时间就帮忙看看哈。 \ No newline at end of file From 756de099af9ecf59666c00838aa84261d13d8417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E9=A1=BA=E5=B9=B3?= <1078094401@qq.com> Date: Sun, 15 Dec 2019 15:35:43 +0800 Subject: [PATCH 35/73] 059-week 01 --- week_01/59/week01/ArrayList.md | 103 +++++++++++++++++++++++++++++ week_01/59/week01/HashMap.md | 26 ++++++++ week_01/59/week01/LinkedList.md | 111 ++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 week_01/59/week01/ArrayList.md create mode 100644 week_01/59/week01/HashMap.md create mode 100644 week_01/59/week01/LinkedList.md diff --git a/week_01/59/week01/ArrayList.md b/week_01/59/week01/ArrayList.md new file mode 100644 index 0000000..f9bc358 --- /dev/null +++ b/week_01/59/week01/ArrayList.md @@ -0,0 +1,103 @@ +一.ArrayList概述 + 1.ArrayList是可以动态增长和缩减的索引序列,它是基于数组实现的List类 + 2.ArrayList封装了一个动态分配的Object[]数组(elementData)初始化长度是10,和一个size属性代表当前ArrayList内元素的数量。 + 3.ArrayList是线程不安全的,当多条线程访问同一个ArrayList集合时,程序需要手动保证该集合的同步性。 +二.ArrayList继承结构 + 1.ArrayList先继承AbstractList类,让AbstractList去实现下面几个类,从而减少ArrayList的代码量。 + 1.AbstractList实现List,提供一些基本的属性和方法,方便对ArrayList进行元素的操作和判断。 + 2.AbstractList实现RandomAccess,可以随机访问List元素。 + 3.AbstractList实现Cloneable,可以克隆。 + 4.AbstractList实现Serializable,可以被序列化,能够从类变成字节流传输,然后还能从字节流变成原来的类。 +三.构造方法 + 1.初始化一个长度的构造方法 + public ArrayList(int initialCapacity) { + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + } else { + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + 2.无参构造方法会初始化一个长度为10的list + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + 3.传入一个集合的构造方法 + public ArrayList(Collection c) { + elementData = c.toArray();//转化成数组赋值 + if ((size = elementData.length) != 0) { + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + //每个集合的toarray()的实现方法不一样,所以需要判断一下, + //如果不是Object[].class类型,那么久需要使用ArrayList中的方法去改造一下。 + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } + } +四.核心方法 + 1.4个add方法 + public boolean add(E e) { //数组内加一个元素,size熟悉加1 + ensureCapacityInternal(size + 1); // Increments modCount!! + elementData[size++] = e; + return true; + } + + public void add(int index, E element) {//在一个特定的位置加一个元素 + + // 检查是否越界 + rangeCheckForAdd(index); + //检查是否需要扩容 + ensureCapacityInternal(size + 1); // Increments modCount!! + //把当前elementData的index位置到结尾长度的值,移到index+1往后的位置。空出index位置 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + elementData[index] = element; + size++; + } + public boolean addAll(Collection c) {//在当前list末尾加上一个集合 + Object[] a = c.toArray(); + int numNew = a.length; + ensureCapacityInternal(size + numNew); // Increments modCount + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + return numNew != 0; + } + public boolean addAll(int index, Collection c) { + rangeCheckForAdd(index);//检查是否超出范围 + + Object[] a = c.toArray(); + int numNew = a.length; + //检查是否需要扩容 + ensureCapacityInternal(size + numNew); // Increments modCount + + int numMoved = size - index; + if (numMoved > 0) + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved);//同理拷贝数组 + //拷贝中间数组 + System.arraycopy(a, 0, elementData, index, numNew); + size += numNew; + return numNew != 0; + } + 2.扩容数组 + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + //右移相当于 除以2,扩大1.5倍 + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0)//当list为空时,满足条件 + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) //超过最大限制时 要给能给的最大值 + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity);//copy数组,并改变容量 + } + 3.其他核心方法类似 +五.总结 + 1.arrayList区别于数组的地方在于能够自动扩展大小,其中关键的方法就是gorw()方法,每次扩容可以扩大1.5倍。 + 2.arrayList由于本质是数组,所以它在数据的查询方面会很快,而在插入删除这些方面,性能下降很多,有移动很多数据才能达到应有的效果。 + 3.arrayList实现了RandomAccess,所以在遍历它的时候推荐使用for循环。 \ No newline at end of file diff --git a/week_01/59/week01/HashMap.md b/week_01/59/week01/HashMap.md new file mode 100644 index 0000000..34fda08 --- /dev/null +++ b/week_01/59/week01/HashMap.md @@ -0,0 +1,26 @@ +一.HashMap 概述 + HashMap是一个键对应一个值的Map集合,它在查找和插入时的效率极高,理论上可以达到O(1). + HashMap是利用hash函数对所需要存入的值进行计算存储位置。 + Hash函数会计算不通值之间的时候,会发生冲突,就叫hash冲突。 + 哈希冲突的解决方案有多种:开放定址法(发生冲突,继续寻找下一块未被占用的存储地址)(顺序寻找下一个未被占用地址,效率低), + 再散列函数法(利用值的平方,再散列寻找未被占用的地址),链地址法,而HashMap即是采用了链地址法,也就是数组+链表的方式。 +二.HashMap 继承结构 + 1.HashMap继承了AbstractMap + 2.HashMap实现了Map,(可以使用一些Map的操作) + 3.HashMAp实现了 Cloneable, (可被克隆) + 4.HashMap实现了Serializable,(可序列化) +三.构造方法 + // 1.无参构造方法、 + // 构造一个空的HashMap,初始容量为16,负载因子为0.75 + public HashMap() { + this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted + } +// 2.构造一个初始容量为initialCapacity,负载因子为0.75的空的HashMap, + public HashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); + } + /// 等待更新 +四.核心方法 + +五.总结 + \ No newline at end of file diff --git a/week_01/59/week01/LinkedList.md b/week_01/59/week01/LinkedList.md new file mode 100644 index 0000000..dee990d --- /dev/null +++ b/week_01/59/week01/LinkedList.md @@ -0,0 +1,111 @@ +一.LinkedList概述 + 1.LinkedList基于双向链表适用于增删频繁且查询不频繁的场景. + 2.线程不安全的且适用于单线程(这点和ArrayList很像)。 + 3.可以用LinkedList来实现栈和队列. +二.LinkedList继承结构 + 1.LinkedList继承了AbstractSequentialList + 2.LinkedList实现了List,(集合功能) + 3.LinkedList实现了Deque (双端队列功能,模拟栈和队列) + 4.LinkedList实现了Cloneable(克隆数组) + 5.LinkedList实现了Serializable(序列化) +三.构造方法 + transient int size = 0; + transient Node first; + transient Node last; + private static class Node { //内部类,定义一个节点 + E item;//当前元素的value + Node next;//下一个元素。null代表尾元素 + Node prev;//上一个元素。null代表首原素 + //定义一个节点 + Node(Node prev, E element, Node next) { + this.item = element; + this.next = next; + this.prev = prev; + } + } + //无参构造函数 + public LinkedList() { + } + //添加一个集合 + public LinkedList(Collection c) { + this(); + addAll(c); + } + +四.核心方法 + //在头部增加一个节点 + private void linkFirst(E e) { + final Node f = first; + final Node newNode = new Node<>(null, e, f); + first = newNode; + if (f == null) + last = newNode; + else + f.prev = newNode; + size++; + modCount++; + } + //在尾部增加一个节点 + void linkLast(E e) { + final Node l = last; + final Node newNode = new Node<>(l, e, null); + last = newNode; + if (l == null) + first = newNode; + else + l.next = newNode; + size++; + modCount++; + } + //在节点succ之前加入一个节点 + void linkBefore(E e, Node succ) { + // assert succ != null; + final Node pred = succ.prev; + //在pred和succ之间插入newNode + final Node newNode = new Node<>(pred, e, succ); + succ.prev = newNode; + if (pred == null) //是否是头元素 + first = newNode; + else + pred.next = newNode; + size++; //计数加1 + modCount++; + } + //删除头元素,并返回头元素的值 + private E unlinkFirst(Node f) { + // assert f == first && f != null; + final E element = f.item; + final Node next = f.next; + f.item = null; + f.next = null; // help GC + first = next; + if (next == null) + last = null; + else + next.prev = null; + size--; + modCount++; + return element; + } + //索引第index个节点 + Node node(int index) { + //assert isElementIndex(index); + if (index < (size >> 1)) { + Node x = first; + for (int i = 0; i < index; i++) + x = x.next; + return x; + } else { + Node x = last; + for (int i = size - 1; i > index; i--) + x = x.prev; + return x; + } + } + 2.其他方法类似 +五.总结 + 1.LinkedList方法内部实现是链表,且内部有fist与last指针操作数据 + 2.LinkedList线程不安全的,因为其内部添加、删除、等操作,没有进行同步操作。 + 3.LinkedList增删元素速度较快。 + 4.遍历效率(快-慢): + Iterator迭代 > for循环 \ No newline at end of file From fbe800455822b634a7c6d6d807ae7e8103c74261 Mon Sep 17 00:00:00 2001 From: A-b Date: Sun, 15 Dec 2019 16:14:56 +0800 Subject: [PATCH 36/73] =?UTF-8?q?17=E5=8F=B7=E7=AC=AC=E4=B8=80=E5=91=A8?= =?UTF-8?q?=E6=BA=90=E7=A0=81=E5=AD=A6=E4=B9=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week_01/17/List/ArrayList-17 | 48 +++++++++++++++++ week_01/17/List/HashMap-17 | 102 +++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 week_01/17/List/ArrayList-17 create mode 100644 week_01/17/List/HashMap-17 diff --git a/week_01/17/List/ArrayList-17 b/week_01/17/List/ArrayList-17 new file mode 100644 index 0000000..f1f1c98 --- /dev/null +++ b/week_01/17/List/ArrayList-17 @@ -0,0 +1,48 @@ +##ArrayList + + ##接口实现 + List, + 标记接口 RandomAccess, --可快速访问,即访问速度为1次。 + 标记接口 Cloneable, ----可克隆。 + 标记接口 java.io.Serializable--可序列化。 + + + ##底层实现 + 1.ArrayList底层是数组,可以根据Size动态增长。 + ##扩容 + 1.ArrayList的默认长度为10。 + 2.每一次扩容为当前长度的50%。 + 依据 int newCapacity = oldCapacity + (oldCapacity >> 1); + 3.copy,新起一个数组,再将原始数据放到新的数组里去。 + ##遍历 + 1.因为实现 RandomAccess 该接口,则 for循环的速度比Iterator迭代器快,出处RandomAccess文档。 + 2.关于For,ForEach 循环。 + for在遍历数组结构的数据快。 + forEach在遍历链表数据比较快。 + ##线程安全 + 1.否 + ##属性 + private static final long serialVersionUID = 8683452581122892189L; + //默认长度 + private static final int DEFAULT_CAPACITY = 10; + //空数组 + private static final Object[] EMPTY_ELEMENTDATA = {}; + //transient 不会被序列化(如实现Externalizable,并且手动序列化了)该修饰符将没有作用 + transient Object[] elementData; + //构造一个空集合的时候,返回该属性 + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + + ##构造方法 + 1.public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + 2.ArrayList(int i){ + i==返回 EMPTY_ELEMENTDATA。 + i>0返回一个i长度的Object的数组 + + } + 3.ArrayList(Collection c){ + c.长度为0 返回空数组。 + c.长度不为0 返回一个C长度的Object[]数组。 + + } \ No newline at end of file diff --git a/week_01/17/List/HashMap-17 b/week_01/17/List/HashMap-17 new file mode 100644 index 0000000..5c7b0ba --- /dev/null +++ b/week_01/17/List/HashMap-17 @@ -0,0 +1,102 @@ +##HashMap + + ##接口 + 1.Map + 2.Cloneable --可拷贝 + 3.Serializable-可序列化 + ##属性 + //默认长度16, 必须是2的幂 + static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; + + static final int MAXIMUM_CAPACITY = 1 << 30; + //扩容因子(数据量到75%,则扩容一次) + static final float DEFAULT_LOAD_FACTOR = 0.75f; + //变成树的一个阀值 + static final int TREEIFY_THRESHOLD = 8; + //取消树的一个阀值 + static final int UNTREEIFY_THRESHOLD = 6; + + static final int MIN_TREEIFY_CAPACITY = 64; + ##构造函数 + 1.public HashMap() { + this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted + } + 则当前Map 长度16,扩容因子75% + 2.HashMap(int i){ + HashMap(int initialCapacity, float loadFactor) + } + + 3.public HashMap(Map m) { + this.loadFactor = DEFAULT_LOAD_FACTOR; + putMapEntries(m, false); + } + + + 4.方法 + /** + * Implements Map.put and related methods. + * + * @param hash hash for key + * @param key the key + * @param value the value to put + * @param onlyIfAbsent if true, don't change existing value + * @param evict if false, the table is in creation mode. + * @return previous value, or null if none + */ + final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { + Node[] tab; + Node p; + int n, i; + //如果表是空的则从表新计算 + if ((tab = table) == null || (n = tab.length) == 0) + //获取表新计算的长度 + n = (tab = resize()).length; + //没有Hahs碰撞,直接在该角标插入新值 + if ((p = tab[i = (n - 1) & hash]) == null) + //新增一个桶到指定表中 + tab[i] = newNode(hash, key, value, null); + //有哈希碰撞 + else { + Node e; K k; + //如果在原来的找到了一个相同的桶,则把之前的桶赋值过来 + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + e = p; + //看下 P 是不是是个树,拷贝一个树 + else if (p instanceof TreeNode) + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + //如果不是一个树 + else { + for (int binCount = 0; ; ++binCount) { + //该节点后面没有值,当前Hash只有这一个值 + if ((e = p.next) == null) { + //新建一个节点赋值给表当前的位置 + p.next = newNode(hash, key, value, null); + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + treeifyBin(tab, hash); + break; + } + //如果是同一个值,则不对此节点做操作 + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + break; + p = e; + } + } + if (e != null) { // existing mapping for key + V oldValue = e.value; + if (!onlyIfAbsent || oldValue == null) + e.value = value; + afterNodeAccess(e); + return oldValue; + } + } + //记录该Map修改的次数 + ++modCount; + if (++size > threshold) + resize(); + afterNodeInsertion(evict); + return null; + } + ##HashMap源码还需要看,请各位大佬,指导一下,第一次看,懵逼中。。。。。。。。。。。。。。。 \ No newline at end of file From 5fa81d55c82d156d9350891e536369429ec0421f Mon Sep 17 00:00:00 2001 From: AlexanderTUO <1599961496@qq.com> Date: Sun, 15 Dec 2019 17:00:26 +0800 Subject: [PATCH 37/73] 008-ArrayList,HashMap --- week_01/08/ArrayList-008.md | 261 ++++++++------ week_01/08/ArrayList-008.xmind | Bin 0 -> 53478 bytes week_01/08/HashMap-008.md | 341 ++++++++++++++++++ week_01/08/HashMap-008.xmind | Bin 0 -> 90746 bytes ...3\347\244\272\346\204\217\345\233\276.jpg" | Bin 0 -> 45052 bytes week_01/08/README.md | 13 +- 6 files changed, 497 insertions(+), 118 deletions(-) create mode 100644 week_01/08/ArrayList-008.xmind create mode 100644 week_01/08/HashMap-008.md create mode 100644 week_01/08/HashMap-008.xmind create mode 100644 "week_01/08/HashMap-put\346\211\247\350\241\214\346\265\201\347\250\213\347\244\272\346\204\217\345\233\276.jpg" diff --git a/week_01/08/ArrayList-008.md b/week_01/08/ArrayList-008.md index 06f5493..90a5697 100644 --- a/week_01/08/ArrayList-008.md +++ b/week_01/08/ArrayList-008.md @@ -25,7 +25,7 @@ - ##### DEFAULTCAPACITY_EMPTY_ELEMENTDATA - - #### 瞬态对象:elementData(用来干嘛) + - #### 瞬态对象:elementData 2. ### 常用方法 @@ -53,7 +53,7 @@ 9. #### clear():将数组所有元素置空,便于GC回收 -3. ### 扩容(调试) +3. ## 扩容(调试) 1. #### 添加元素add @@ -133,119 +133,152 @@ } ``` - 1. ### 增删改查 - - 1. #### 通用方法 - - - #### System.arraycopy()方法 - - ``` - public static native void arraycopy(Object src, int srcPos, - Object dest, int destPos, - int length); - ``` - - 2. #### 增加 - - - ##### 末尾增加:boolean add(E e) - - - ##### 指定位置增加 - - ``` - public void add(int index, E element) { - rangeCheckForAdd(index); - - ensureCapacityInternal(size + 1); // Increments modCount!! - // 后续元素依次往后移,添加缓慢,删除同理 - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - elementData[index] = element; - size++; - } - ``` - - - ##### 批量添加 - - ``` - public boolean addAll(Collection c) { - Object[] a = c.toArray(); - int numNew = a.length; - // 此时的容量(size + numNew)可能超过扩容后1.5倍,则扩容后的容量为(size + numNew) - ensureCapacityInternal(size + numNew); // Increments modCount - System.arraycopy(a, 0, elementData, size, numNew); - size += numNew; - return numNew != 0; - } - ``` - - ``` - private void grow(int minCapacity) { - // overflow-conscious code - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + (oldCapacity >> 1); - - // 需求容量minCapacity大于扩容后的容量newCapacity - if (newCapacity - minCapacity < 0) - newCapacity = minCapacity; - if (newCapacity - MAX_ARRAY_SIZE > 0) - newCapacity = hugeCapacity(minCapacity); - // minCapacity is usually close to size, so this is a win: - elementData = Arrays.copyOf(elementData, newCapacity); - } - ``` - - - ##### 指定位置批量添加 - - 3. #### 删除 - - - ##### 指定下标 - - ``` - public E remove(int index) { - rangeCheck(index); - - modCount++; - E oldValue = elementData(index); - // 下标为index的元素,实际是数组的第index+1个元素 - int numMoved = size - index - 1; - if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, - numMoved); - elementData[--size] = null; // clear to let GC do its work - - return oldValue; - } - ``` - - - ##### 指定对象 - - ``` - public boolean remove(Object o) { - if (o == null) { - for (int index = 0; index < size; index++) - if (elementData[index] == null) { - fastRemove(index); - return true; - } - } else { - for (int index = 0; index < size; index++) - if (o.equals(elementData[index])) { - fastRemove(index); - return true; - } - } - return false; - } - ``` - - - ##### 指定下标范围批量移除 - - - - ##### +4. ## 增删改查 - + 1. ### 通用方法 + + - #### System.arraycopy()方法 + + ``` + public static native void arraycopy(Object src, int srcPos, + Object dest, int destPos, + int length); + ``` + + 2. ### 增 + + - ##### 末尾增加:boolean add(E e) + + - ##### 指定位置增加 + + ``` + public void add(int index, E element) { + rangeCheckForAdd(index); + + ensureCapacityInternal(size + 1); // Increments modCount!! + // 后续元素依次往后移,添加缓慢,删除同理 + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + elementData[index] = element; + size++; + } + ``` + + - ##### 批量添加 + + ``` + public boolean addAll(Collection c) { + Object[] a = c.toArray(); + int numNew = a.length; + // 此时的容量(size + numNew)可能超过扩容后1.5倍,则扩容后的容量为(size + numNew) + ensureCapacityInternal(size + numNew); // Increments modCount + System.arraycopy(a, 0, elementData, size, numNew); + size += numNew; + return numNew != 0; + } + ``` + + ``` + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); + + // 需求容量minCapacity大于扩容后的容量newCapacity + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); + } + ``` + + - ##### 指定位置批量添加 + 3. ### 删除 + + - ##### 指定下标 + + ``` + public E remove(int index) { + rangeCheck(index); + + modCount++; + E oldValue = elementData(index); + // 下标为index的元素,实际是数组的第index+1个元素 + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + elementData[--size] = null; // clear to let GC do its work + + return oldValue; + } + ``` + + - ##### 指定对象 + + ``` + public boolean remove(Object o) { + if (o == null) { + for (int index = 0; index < size; index++) + if (elementData[index] == null) { + fastRemove(index); + return true; + } + } else { + for (int index = 0; index < size; index++) + if (o.equals(elementData[index])) { + fastRemove(index); + return true; + } + } + return false; + } + ``` + + - ##### 指定下标范围批量移除 + 4. ### 改 + + 1. #### set(int index, E element):替换指定位置的元素 + + 5. ### 查 + + 1. #### get(int index) + + 2. #### 迭代方法 + + - ##### ListIterator listIterator(int index):类似String的subString + + - ##### ListIterator listIterator() + + 3. #### List subList(int fromIndex, int toIndex): + + - ##### 返回的是ArrayList的内部类--SubList + + - ##### 该SubList无法转换为ArrayList,只是ArrayList的一个视图 + + - ###### 对父子类做的非结构性修改,都会影响到彼此 + + - ###### 对子List做结构性修改,操作会反映到父List上 + + - ###### 对父List做结构性修改,会抛出异常ConcurrentModificationException + + - 若需要对subList进行修改,有不想动原list,那么可以创建subList的一个拷贝 + + ``` + subList = Lists.newArrayList(subList); + list.stream().skip(strart).limit(end).collect(Collectors.toList()); + ``` + + + + 4. + + - + + - \ No newline at end of file + \ No newline at end of file diff --git a/week_01/08/ArrayList-008.xmind b/week_01/08/ArrayList-008.xmind new file mode 100644 index 0000000000000000000000000000000000000000..8d522a9ec19fb234ab2f5930635c3081f2010902 GIT binary patch literal 53478 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