diff --git a/algorithm/位运算.md b/algorithm/1、位运算.md similarity index 96% rename from algorithm/位运算.md rename to algorithm/1、位运算.md index 6220d80..99502c3 100644 --- a/algorithm/位运算.md +++ b/algorithm/1、位运算.md @@ -1,34 +1,34 @@ -一个数的相反数为取反加1. -取反的结果和原来的数相加结果为2^32^-1,再加1则进位为0。 - -2^32^-1二进制为 - -```shell -11111111 11111111 11111111 11111111 -``` - -```shell -# 例如 int a = 1024;二进制为 -00000000 00000000 00001000 00000000 -# 取反后 -11111111 11111111 11110111 11111111 -# 相加为 -11111111 11111111 11111111 11111111 -a+~a+1=0;则-a=~a+1; -``` - -```Java -# 打印int类型二进制字符串方法 -private static void printCompleteBinaryStr(int num){ - for (int i = 31; i >= 0; i--) { - System.out.print((num & (1 << i)) == 0 ? "0" : "1"); - if (i < 31 && (i + 1) % 8 == 0) { - System.out.print(" "); - } - } - System.out.println(); -} -``` - -Integer.MIN_VALUE取反加一后仍然为Integer.MIN_VALUE,这不是bug。 -Integer.MAX_VALUE加1后溢出为Integer.MIN_VALUE,Integer.MIN_VALUE减一则溢出为Integer.MAX_VALUE。 +一个数的相反数为取反加1. +取反的结果和原来的数相加结果为2^32^-1,再加1则进位为0。 + +2^32^-1二进制为 + +```shell +11111111 11111111 11111111 11111111 +``` + +```shell +# 例如 int a = 1024;二进制为 +00000000 00000000 00001000 00000000 +# 取反后 +11111111 11111111 11110111 11111111 +# 相加为 +11111111 11111111 11111111 11111111 +a+~a+1=0;则-a=~a+1; +``` + +```Java +# 打印int类型二进制字符串方法 +private static void printCompleteBinaryStr(int num){ + for (int i = 31; i >= 0; i--) { + System.out.print((num & (1 << i)) == 0 ? "0" : "1"); + if (i < 31 && (i + 1) % 8 == 0) { + System.out.print(" "); + } + } + System.out.println(); +} +``` + +Integer.MIN_VALUE取反加一后仍然为Integer.MIN_VALUE,这不是bug。 +Integer.MAX_VALUE加1后溢出为Integer.MIN_VALUE,Integer.MIN_VALUE减一则溢出为Integer.MAX_VALUE。 diff --git a/algorithm/算法.md b/algorithm/2、算法.md similarity index 95% rename from algorithm/算法.md rename to algorithm/2、算法.md index 19be663..3cd53e2 100644 --- a/algorithm/算法.md +++ b/algorithm/2、算法.md @@ -1,94 +1,94 @@ -# 算法的5个特点 - -1.有穷性 -2.确定性(确定的执行流程或者确定的尝试流程) -3.可行性 -4.输入 -5.输出 - -# 选择排序 - -双层循环,内层循环完成后获取最小值,内层循环每次将最小值放到i位置。 -0-i之间认为是有序,i-n之间是原始数据,从i-n之间选择最小的元素放到index为i的地方。 - -不稳定的排序 - -```Java -private static void selectionSort(int[] arr) { - if (arr == null || arr.length < 2) { - return; - } - - int length = arr.length; - int tmp; - for (int i = 0; i < length; i++) { - int index = i; - for (int j = i; j < length; j++) { - // 小于号避免位置交换 - index = arr[j] < arr[index] ? j : index; - } - if (index == i) { - continue; - } - tmp = arr[i]; - arr[i] = arr[index]; - arr[index] = tmp; - } -} -``` - -# 冒泡排序 - -双层循环,内层循环两两交换,内层循环完成后将最大值冒泡到最右边。 -外层循环index从大到小,内层循环index从小到大。 - -稳定排序 - -```Java -private static void bubbleSort(int[] arr){ - int length = arr.length; - if (arr == null || length < 2) { - return; - } - - int tmp; - for (int i = length - 1; i >= 0; i--) { - for (int j = 0; j < i; j++) { - if (arr[j + 1] < arr[j]) { - tmp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = tmp; - } - } - } -} -``` - -# 插入排序 - -每次获取原始数据最前面的那个元素交换到左侧已经有序的数组。 -双层循环,外层循环每次递增并获取i,内层循环使用i挨个和0-1的数据比较并交换。如果i比i-1大或者内层循环到了最左侧则终止循环。 - -稳定排序 - -```Java -private static void insertSort(int[] arr){ - int length = arr.length; - if (arr == null || length < 2) { - return; - } - int tmp; - for (int i = 0; i < length; i++) { - for (int j = i; j > 0; j--) { - if (arr[j - 1] > arr[j]) { - tmp = arr[j - 1]; - arr[j - 1] = arr[j]; - arr[j] = tmp; - } else { - break; - } - - } - } -} -``` +# 算法的5个特点 + +1.有穷性 +2.确定性(确定的执行流程或者确定的尝试流程) +3.可行性 +4.输入 +5.输出 + +# 选择排序 + +双层循环,内层循环完成后获取最小值,内层循环每次将最小值放到i位置。 +0-i之间认为是有序,i-n之间是原始数据,从i-n之间选择最小的元素放到index为i的地方。 + +不稳定的排序 + +```Java +private static void selectionSort(int[] arr) { + if (arr == null || arr.length < 2) { + return; + } + + int length = arr.length; + int tmp; + for (int i = 0; i < length; i++) { + int index = i; + for (int j = i; j < length; j++) { + // 小于号避免位置交换 + index = arr[j] < arr[index] ? j : index; + } + if (index == i) { + continue; + } + tmp = arr[i]; + arr[i] = arr[index]; + arr[index] = tmp; + } +} +``` + +# 冒泡排序 + +双层循环,内层循环两两交换,内层循环完成后将最大值冒泡到最右边。 +外层循环index从大到小,内层循环index从小到大。 + +稳定排序 + +```Java +private static void bubbleSort(int[] arr){ + int length = arr.length; + if (arr == null || length < 2) { + return; + } + + int tmp; + for (int i = length - 1; i >= 0; i--) { + for (int j = 0; j < i; j++) { + if (arr[j + 1] < arr[j]) { + tmp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = tmp; + } + } + } +} +``` + +# 插入排序 + +每次获取原始数据最前面的那个元素交换到左侧已经有序的数组。 +双层循环,外层循环每次递增并获取i,内层循环使用i挨个和0-1的数据比较并交换。如果i比i-1大或者内层循环到了最左侧则终止循环。 + +稳定排序 + +```Java +private static void insertSort(int[] arr){ + int length = arr.length; + if (arr == null || length < 2) { + return; + } + int tmp; + for (int i = 0; i < length; i++) { + for (int j = i; j > 0; j--) { + if (arr[j - 1] > arr[j]) { + tmp = arr[j - 1]; + arr[j - 1] = arr[j]; + arr[j] = tmp; + } else { + break; + } + + } + } +} +``` diff --git a/algorithm/数据结构.md b/algorithm/3、数据结构.md similarity index 100% rename from algorithm/数据结构.md rename to algorithm/3、数据结构.md diff --git a/algorithm/时间复杂度.md b/algorithm/4、时间复杂度.md similarity index 100% rename from algorithm/时间复杂度.md rename to algorithm/4、时间复杂度.md diff --git a/algorithm/5、单链表.md b/algorithm/5、单链表.md new file mode 100644 index 0000000..27e6b40 --- /dev/null +++ b/algorithm/5、单链表.md @@ -0,0 +1,56 @@ +#### 单链表反转 + +使用while循环,保存next节点,设置当前节点的next,保存pre,移动head,最后返回pre + +```Java +private static Node reverseLinkedList(Node head) { + Node pre = null; + Node next = null; + while (head != null) { + next = head.getNext(); + head.setNext(pre); + pre = head; + head = next; + } + return pre; +} +``` + +#### 双链表反转 + +使用while循环,保存next节点,设置当前节点的last和pre,保存pre,移动head,最后返回pre + +```Java +private static Node reverDoubleLinkedList(Node head) { + Node pre = null; + Node next = null; + while (head != null) { + next = head.getLast(); + head.setLast(pre); + head.setPre(next); + pre = head; + head = next; + } + return pre; +} +``` + +单链表实现队列和栈 + +### 使用双链表实现双端队列 + +单链表和双链表的新增、删除,主要注意处理好前驱和后继指针,必要的时候添加中间变量保存。双链表注意处理头尾重合、为空的边界条件。 + +#### K个节点的组内逆序调整 LeetCode25 + +#### 两个链表相加 LeetCode2、LeetCode445 + +根据链表长度分三段处理,第一段处理短链表,第二段处理长链表多出的部分,第三段处理长链表最后的进位 + +#### 合并两个有序链表 LeetCode21 + +### 位图 + +位图的功能 +位图的好处 +位图的用法 diff --git a/algorithm/单链表.md b/algorithm/单链表.md deleted file mode 100644 index a9c1840..0000000 --- a/algorithm/单链表.md +++ /dev/null @@ -1,326 +0,0 @@ -单链表反转 -使用while循环,保存next节点,设置当前节点的next,保存pre,移动head,最后返回pre - -```Java -private static Node reverseLinkedList(Node head) { - Node pre = null; - Node next = null; - while (head != null) { - next = head.getNext(); - head.setNext(pre); - pre = head; - head = next; - } - return pre; -} -``` - -双链表反转 -使用while循环,保存next节点,设置当前节点的last和pre,保存pre,移动head,最后返回pre - -```Java -private static Node reverDoubleLinkedList(Node head) { - Node pre = null; - Node next = null; - while (head != null) { - next = head.getLast(); - head.setLast(pre); - head.setPre(next); - pre = head; - head = next; - } - return pre; -} -``` - -单链表实现队列和栈 - -```Java -public class CustomQueue { - - private Node head; - private Node tail; - private int size; - - public boolean isEmpty(){ - return size == 0; - } - - public void offer(V value) { - Node node = new Node<>(value); - if (tail == null) { - head = node; - tail = node; - } else { - tail.setNext(node); - tail = node; - } - size++; - } - - public V poll(){ - if (head == null) { - return null; - } - V ans = head.getValue(); - head = head.getNext(); - size--; - return ans; - } - - public V peek() { - if (head == null) { - return null; - } - return head.getValue(); - } - - private class Node { - private V value; - private Node next; - - public V getValue() { - return value; - } - - public void setValue(V value) { - this.value = value; - } - - public Node getNext() { - return next; - } - - public void setNext(Node next) { - this.next = next; - } - - public Node(V value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Node node = (Node) o; - return value.equals(node.value) && - next.equals(node.next); - } - - @Override - public int hashCode() { - return Objects.hash(value, next); - } - } -} -``` - -```Java -public class CustomStack { - private Node head; - private int size; - - public boolean isEmpty(){ - return size == 0; - } - - public void push(V value){ - Node node = new Node<>(value); - if (head == null) { - head = node; - } else { - node.setNext(head); - head = node; - } - size++; - } - - public V pop(){ - if (head == null) { - return null; - } - V ans = null; - ans = head.getValue(); - head.setNext(head.getNext()); - size--; - return ans; - } - - public V peek() { - return head == null ? null : head.getValue(); - } - - - class Node{ - private V value; - private Node next; - - public V getValue() { - return value; - } - - public void setValue(V value) { - this.value = value; - } - - public Node getNext() { - return next; - } - - public void setNext(Node next) { - this.next = next; - } - - public Node(V value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Node node = (Node) o; - return Objects.equals(value, node.value) && - Objects.equals(next, node.next); - } - - @Override - public int hashCode() { - return Objects.hash(value, next); - } - } -} -``` - -### 使用双链表实现双端队列 - -```Java -public class CustomDeque { - private Node head; - private Node tail; - private int size; - - public boolean isEmpty() { - return size == 0; - } - - public void pushHead(V value){ - Node node = new Node<>(value); - if (head == null) { - head = node; - tail = node; - } else { - node.setLast(head); - head.setPre(node); - head = node; - } - size++; - } - - public void pushTail(V value){ - Node node = new Node<>(value); - if (head == null) { - head = node; - tail = node; - } else { - tail.setLast(node); - node.setPre(tail); - tail = node; - } - size++; - } - - public V pollHead(){ - if (head == null) { - return null; - } - V ans = head.getValue(); - if (head.equals(tail)) { - head = null; - tail = null; - } else { - head = head.getLast(); - head.setPre(null); - } - size--; - return ans; - } - - public V pollTail(){ - if (tail == null) { - return null; - } - V ans = tail.getValue(); - if (head.equals(tail)) { - head = null; - tail = null; - } else { - tail = tail.getPre(); - tail.setLast(null); - } - size--; - return ans; - } - - public V peekHead(){ - return head == null ? null : head.getValue(); - } - - public V peekTail(){ - return tail == null ? null : tail.getValue(); - } - - class Node{ - private V value; - private Node last; - private Node pre; - - public Node(V value) { - this.value = value; - } - - public V getValue() { - return value; - } - - public void setValue(V value) { - this.value = value; - } - - public Node getLast() { - return last; - } - - public void setLast(Node last) { - this.last = last; - } - - public Node getPre() { - return pre; - } - - public void setPre(Node pre) { - this.pre = pre; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Node node = (Node) o; - return Objects.equals(value, node.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - } -} -``` - -单链表和双链表的新增、删除,主要注意处理好前驱和后继指针,必要的时候添加中间变量保存。双链表注意处理头尾重合、为空的边界条件。 - -K个节点的组内逆序调整 diff --git a/framework-source-code/Spring启动流程.md b/framework-source-code/Spring启动流程.md new file mode 100644 index 0000000..9965e21 --- /dev/null +++ b/framework-source-code/Spring启动流程.md @@ -0,0 +1,63 @@ +## Spring启动流程 + +### prepareRefresh() + +记录时间、active标记、获取environment(系统环境变量和System.setProperty()设置的)、初始化监听器和事件集合。 + +### obtainFreshBeanFactory() + +关闭以前的BeanFactory,创建一个新的BeanFactory供上下文生命周期的各阶段使用。 +父beanDefinition、bean可覆盖、循环引用, +loadBeanDefinitions()通过inputStream读取并解析xml文档,拿到beanDefinition。 + +### prepareBeanFactory() + +准备BeanFactory,设置ClassLoader、SPEL解析器、propertyEditor、BeanPostProcessor(ApplicationContextAwareProcessor)、ignoreDependencyInterface(各种Aware接口)、registerResolvableDependency、BeanPostProcessor(ApplicationListenerDetector)、environment单例。 + +### postProcessBeanFactory(beanFactory) + +继承ClassPathXmlApplicationContext的子类可以修改beanFactory,用于实现一些自定义的功能。 + +### invokeBeanFactoryPostProcessors(beanFactory) + +BeanDefinitionRegistryPostProcessors和BeanFactoryPostProcessors按照实现PriorityOrdered、Ordered接口、没有实现这两个接口的PostProcessors处理执行顺序,@Order注解在这里是不考虑的。 + +// Register bean processors that intercept bean creation. + +### registerBeanPostProcessors(beanFactory) + +BeanPostProcessor按照实现PriorityOrdered、Ordered接口、没有实现这两个接口的PostProcessors处理执行顺序,@Order注解在这里是不考虑的。 +BeanPostProcessorChecker用来记录日志。 + +### initMessageSource() + +初始化MessageSource,MessageSource是格式化字符串的? + +### initApplicationEventMulticaster() + +初始化应用事件监听器,SimpleApplicationEventMulticaster通过线程池往各种监听器添加事件。 + +### onRefresh() + +由子类实现,比如Spring Boot创建web server。 + +### registerListeners() + +注册所有实现了ApplicationListener接口的监听器,并发布早起应用事件。 + +### finishBeanFactoryInitialization(beanFactory) + +实例化所有非懒加载的单例。 +ConversionService(转换系统的一个入口,可用于常见的日期格式转换?)、添加EmbeddedValueResolver、BeanFactory方式获取LoadTimeWeaverAware、置空temporary ClassLoader、冻结配置、预实例化单例。 +preInstantiateSingletons() +遍历beanNames,触发所有非懒加载bean实例化。 +遍历beanNames,触发所有适用 bean 的初始化后回调。 +getBean(beanName) -> doGetBean -> getSingleton(三级缓存) -> createBean -> doCreateBean -> 代理和反射创建bean(三级缓存) -> populateBean -> initializeBean + +### finishRefresh() + +清理资源缓存、初始化LifecycleProcessor、发布最终事件 + +### resetCommonCaches() + +### contextRefresh.end() diff --git a/framework-source-code/spring/BeanFactory相关类图.png b/framework-source-code/spring/BeanFactory相关类图.png new file mode 100644 index 0000000..a903a2b Binary files /dev/null and b/framework-source-code/spring/BeanFactory相关类图.png differ