From 8d90b1721bb92d034b12d37f33f72eaf7cbf2e48 Mon Sep 17 00:00:00 2001 From: CyC2018 <1029579233@qq.com> Date: Tue, 20 Feb 2018 10:40:05 +0800 Subject: [PATCH] auto commit --- README.md | 96 +- .../2016 校招真题题解.md | 160 +- notes/HTTP.md | 399 ++++ notes/JVM.md | 673 +++++++ notes/Java IO.md | 406 ++++ notes/Java 基础语法.md | 140 ++ Leetocde题解.md => notes/Leetcode 题解.md | 1264 ++++++------ notes/Linux.md | 1071 ++++++++++ notes/MySQL.md | 444 +++++ notes/SQL 语法.md | 734 +++++++ 剑指offer题解.md => notes/剑指 offer 题解.md | 1151 ++++++----- notes/算法.md | 1632 +++++++++++++++ notes/计算机操作系统.md | 739 +++++++ notes/计算机网络.md | 841 ++++++++ notes/设计模式.md | 1744 +++++++++++++++++ notes/面向对象思想.md | 307 +++ 16 files changed, 10602 insertions(+), 1199 deletions(-) rename 2016校招真题题解.md => notes/2016 校招真题题解.md (75%) create mode 100644 notes/HTTP.md create mode 100644 notes/JVM.md create mode 100644 notes/Java IO.md create mode 100644 notes/Java 基础语法.md rename Leetocde题解.md => notes/Leetcode 题解.md (65%) create mode 100644 notes/Linux.md create mode 100644 notes/MySQL.md create mode 100644 notes/SQL 语法.md rename 剑指offer题解.md => notes/剑指 offer 题解.md (64%) create mode 100644 notes/算法.md create mode 100644 notes/计算机操作系统.md create mode 100644 notes/计算机网络.md create mode 100644 notes/设计模式.md create mode 100644 notes/面向对象思想.md diff --git a/README.md b/README.md index 5340691e..0c149345 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,95 @@ -# 笔记 +# 数据结构与算法 -- [Leetocde题解](https://github.com/CyC2018/CodeInterview/blob/master/Leetocde%E9%A2%98%E8%A7%A3.md) +> [算法](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/算法.md) -- [剑指offer题解](https://github.com/CyC2018/CodeInterview/blob/master/%E5%89%91%E6%8C%87offer%E9%A2%98%E8%A7%A3.md) +整理自《算法 第四版》,主要整理了排序和树。 -- [2016校招真题题解-未完成](https://github.com/CyC2018/CodeInterview/blob/master/2016%E6%A0%A1%E6%8B%9B%E7%9C%9F%E9%A2%98%E9%A2%98%E8%A7%A3.md) +> [Leetcode 题解](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/Leetcode%20题解.md) -# OJ 地址 +对题目做了一个分类,并对每种题型的解题思想做了总结。 -- 牛客网 : https://www.nowcoder.com/activity/oj +已经整理了 300+ 的题目,基本涵盖所有经典题目,持续整理中。 -- Leetcode : https://leetcode.com/problemset/algorithms/ +> [剑指 offer 题解](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/剑指%20offer%20题解.md) + +目录按《剑指 Offer 第二版》编排,在牛客网的在线编程中出现的题目都已经 AC。 + +> [2016 校招真题题解](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/2016%20校招真题题解.md) + +未完成 + +# 网络 + +> [计算机网络](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/计算机网络.md) + +整理自《计算机网络 第七版》 + +> [HTTP](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/HTTP.md) + +整理自《图解 HTTP》 + +# 操作系统 + +> [计算机操作系统](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/计算机操作系统.md) + +整理自《现代操作系统》 + +> [Linux](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/Linux.md) + +整理自《鸟哥的 Linux 私房菜》 + +# 面向对象 + +> [设计模式](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/设计模式.md) + +整理自《Head First 设计模式》,这本书内容废话太多,笔记内容提取了重点部分。 + +> [面向对象思想](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/面向对象思想.md) + +一些面向对象思想和原则 + +# 数据库 + +> [SQL 语法](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/SQL%20语法.md) + +整理自《SQL 必知必会》,原书内容不多,笔记内容会更简洁。 + +> [MySQL](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/MySQL.md) + +整理自《高性能 MySQL》,重点整理。 + +# Java + +> [JVM](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/JVM.md) + +整理自《深入理解 Java 虚拟机》,包括内存模型、垃圾回收和类加载机制。 + +> [Java IO](https://github.com/CyC2018/InnterviewNotes/blob/master/notes/Java%20IO.md) + +File、InputStream 和 OutputStream、Reader 和 Writer、Serializable、Socket 以及 NIO + +# 资料下载 + +> [百度网盘](https://pan.baidu.com/s/1o9oD1s2#list/path=%2F) + +一些 PDF 书籍 + +# 后记 + +原文发表在 [牛客网:计算机基础重点整理](https://www.nowcoder.com/discuss/66985) + +楼主在牛客网上看了挺多面经,面经里提到的面试重点对楼主的学习帮助很大。但是很少有面经给了比较系统的知识整理,大部分都比较零散,这也是楼主整理这个仓库的原因,希望对大家有所帮助。 + +笔记开源在 Github 上,包括数据结构与算法、网络、操作系统、面向对象。数据结构与算法的笔记之前也在牛客网发布过了,包括了算法、Leetcode 题解、剑指 Offer 题解。网络部分除了整理本科学过的计算机网络之外,还特别整理了 HTTP 的内容。操作系统也是,除了整理计算机操作系统课程的内容之外,也特别整理了 Linux 的内容。至于面向对象,重点部分是设计模式笔记,还有就是一些面向对象思想。 + +之后会继续整理其它笔记,例如 Java、数据库、系统设计等,可能也会整理一些编码实践相关的笔记,例如重构、代码风格。 + +提供一些 PDF 资源的下载,除了一两本不是很清楚,其它都是高清的。 + +楼主作为一个轻度强迫症患者,笔记内容会尽量保证排版美观,可读性好。有时候为了加个好看的图,会使用一些画图软件自己画,可见楼主的强迫症多严重,不过应该算还好。为了让笔记内容更整洁,前前后后做了很多次修改,也写了一个为中英混排文档进行排版的脚本,来提高笔记的可读性。 + +为了上传笔记到 Github 上,也花了一点时间。楼主使用的笔记软件是为知笔记,怎么把笔记内容提取成文本文档,并且提取笔记中的图片就是一个问题。还有就是 Github 使用的是 GFM 来渲染 md 文档,和普通的 Markdown 不太一样,例如 GFM 不支持 MathJax 公式,也不支持 TOC 标记,为此需要替换 MathJax 公式为 codecogs 的云服务和重新生成 TOC 目录。楼主实现了脚本解决了上述的问题,并且整个过程可以一键进行,包括 git 同步到仓库中,因此把为知笔记的内容同步到仓库中的速度非常快。 + +大部分笔记都是楼主一个字一个字打上去的,少数有摘抄其它文章的内容,这些文章都可以在后面的参考链接中找到。笔记内容可随意使用,转载请注明出处,毕竟写了这么久没那么轻松~ + +想要支持楼主的话,在 Github 仓库点个 Star 即可。 \ No newline at end of file diff --git a/2016校招真题题解.md b/notes/2016 校招真题题解.md similarity index 75% rename from 2016校招真题题解.md rename to notes/2016 校招真题题解.md index ad4ddf29..0285debe 100644 --- a/2016校招真题题解.md +++ b/notes/2016 校招真题题解.md @@ -1,33 +1,33 @@ -* [前言](#前言) -* [1. 小米-小米Git](#1-小米-小米git) -* [2. 小米-懂二进制](#2-小米-懂二进制) -* [3. 小米-中国牛市](#3-小米-中国牛市) -* [4. 微软-LUCKY STRING](#4-微软-lucky-string) -* [5. 微软-Numeric Keypad](#5-微软-numeric-keypad) -* [6. 微软-Spring Outing](#6-微软-spring-outing) -* [7. 微软-S-expression](#7-微软-s-expression) -* [8. 华为-最高分是多少](#8-华为-最高分是多少) -* [9. 华为-简单错误记录](#9-华为-简单错误记录) -* [10. 华为-扑克牌大小](#10-华为-扑克牌大小) -* [11. 去哪儿-二分查找](#11-去哪儿-二分查找) -* [12. 去哪儿-首个重复字符](#12-去哪儿-首个重复字符) -* [13. 去哪儿-寻找Coder](#13-去哪儿-寻找coder) -* [14. 美团-最大差值](#14-美团-最大差值) -* [15. 美团-棋子翻转](#15-美团-棋子翻转) -* [16. 美团-拜访](#16-美团-拜访) -* [17. 美团-直方图内最大矩形](#17-美团-直方图内最大矩形) -* [18. 美团-字符串计数](#18-美团-字符串计数) -* [19. 美团-平均年龄](#19-美团-平均年龄) -* [20. 百度-罪犯转移](#20-百度-罪犯转移) -* [22. 百度-裁减网格纸](#22-百度-裁减网格纸) -* [23. 百度-钓鱼比赛](#23-百度-钓鱼比赛) -* [24. 百度-蘑菇阵](#24-百度-蘑菇阵) +* [ǰ](#ǰ) +* [1. С-СGit](#1-С-Сgit) +* [2. С-](#2-С-) +* [3. С-йţ](#3-С-йţ) +* [4. ΢-LUCKY STRING](#4-΢-lucky-string) +* [5. ΢-Numeric Keypad](#5-΢-numeric-keypad) +* [6. ΢-Spring Outing](#6-΢-spring-outing) +* [7. ΢-S-expression](#7-΢-s-expression) +* [8. Ϊ-߷Ƕ](#8-Ϊ-߷Ƕ) +* [9. Ϊ-򵥴¼](#9-Ϊ-򵥴¼) +* [10. Ϊ-˿ƴС](#10-Ϊ-˿ƴС) +* [11. ȥĶ-ֲ](#11-ȥĶ-ֲ) +* [12. ȥĶ-׸ظַ](#12-ȥĶ-׸ظַ) +* [13. ȥĶ-ѰCoder](#13-ȥĶ-Ѱcoder) +* [14. -ֵ](#14--ֵ) +* [15. -ӷת](#15--ӷת) +* [16. -ݷ](#16--ݷ) +* [17. -ֱͼ](#17--ֱͼ) +* [18. -ַ](#18--ַ) +* [19. -ƽ](#19--ƽ) +* [20. ٶ-ﷸת](#20-ٶ-ﷸת) +* [22. ٶ-üֽ](#22-ٶ-üֽ) +* [23. ٶ-](#23-ٶ-) +* [24. ٶ-Ģ](#24-ٶ-Ģ) -# 前言 +# ǰ -省略的代码: +ʡԵĴ룺 ```java import java.util.*; @@ -48,10 +48,10 @@ public class Main { } ``` -# 1. 小米-小米Git +# 1. С-СGit -- 重建多叉树 -- 使用 LCA +- ؽ +- ʹ LCA ```java private class TreeNode { @@ -65,7 +65,7 @@ private class TreeNode { public int getSplitNode(String[] matrix, int indexA, int indexB) { int n = matrix.length; - boolean[][] linked = new boolean[n][n]; // 重建邻接矩阵 + boolean[][] linked = new boolean[n][n]; // ؽڽӾ for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { linked[i][j] = matrix[i].charAt(j) == '1'; @@ -80,7 +80,7 @@ private TreeNode constructTree(boolean[][] linked, int root) { TreeNode tree = new TreeNode(root); for (int i = 0; i < linked[root].length; i++) { if (linked[root][i]) { - linked[i][root] = false; // 因为题目给的邻接矩阵是双向的,在这里需要把它转为单向的 + linked[i][root] = false; // ΪĿڽӾ˫ģҪתΪ tree.childs.add(constructTree(links, i)); } } @@ -102,9 +102,9 @@ private TreeNode LCA(TreeNode root, TreeNode p, TreeNode q) { } ``` -# 2. 小米-懂二进制 +# 2. С- -对两个数进行异或,结果的二进制表示为 1 的那一位就是两个数不同的位。 +򣬽ĶƱʾΪ 1 һλͬλ ```java public int countBitDiff(int m, int n) { @@ -112,11 +112,11 @@ public int countBitDiff(int m, int n) { } ``` -# 3. 小米-中国牛市 +# 3. С-йţ -背包问题,可以设一个大小为 2 的背包。 +⣬һСΪ 2 ı -状态转移方程如下: +״̬תƷ£ ```html dp[i, j] = max(dp[i, j-1], prices[j] - prices[jj] + dp[i-1, jj]) { jj in range of [0, j-1] } = max(dp[i, j-1], prices[j] + max(dp[i-1, jj] - prices[jj])) @@ -137,10 +137,10 @@ public int calculateMax(int[] prices) { } ``` -# 4. 微软-LUCKY STRING +# 4. ΢-LUCKY STRING -- 斐波那契数列可以预计算; -- 从头到尾遍历字符串的过程,每一轮循环都使用一个 Set 来保存从 i 到 j 出现的字符,并且 Set 保证了字符都不同,因此 Set 的大小就是不同字符的个数。 +- 쳲пԤ㣻 +- ͷβַḶ́ÿһѭʹһ Set i j ֵַ Set ַ֤ͬ Set ĴСDzַͬĸ ```java Set fibSet = new HashSet<>(Arrays.asList(1, 2, 3, 5, 8, 13, 21, 34, 55, 89)); @@ -165,7 +165,7 @@ for (String s : arr) { } ``` -# 5. 微软-Numeric Keypad +# 5. ΢-Numeric Keypad ```java private static int[][] canReach = { @@ -209,17 +209,17 @@ public static void main(String[] args) { } ``` -# 6. 微软-Spring Outing +# 6. ΢-Spring Outing -下面以 N = 3,K = 4 来进行讨论。 + N = 3K = 4 ۡ -初始时,令第 0 个地方成为待定地点,也就是呆在家里。 +ʼʱ 0 طΪص㣬ҲǴڼ -从第 4 个地点开始投票,每个人只需要比较第 4 个地方和第 0 个地方的优先级,里,如果超过半数的人选择了第 4 个地方,那么更新第 4 个地方成为待定地点。 +ӵ 4 ص㿪ʼͶƱÿֻҪȽϵ 4 ط͵ 0 طȼѡ˵ 4 طôµ 4 طΪص㡣 -从后往前不断重复以上步骤,不断更新待定地点,直到所有地方都已经投票。 +Ӻǰظϲ裬ϸ´ص㣬ֱеطѾͶƱ -上面的讨论中,先令第 0 个地点成为待定地点,是因为这样的话第 4 个地点就只需要和这个地点进行比较,而不用考虑其它情况。如果最开始先令第 1 个地点成为待定地点,那么在对第 2 个地点进行投票时,每个人不仅要考虑第 2 个地点与第 1 个地点的优先级,也要考虑与其后投票地点的优先级。 +У 0 صΪص㣬ΪĻ 4 صֻҪصбȽϣÿʼ 1 صΪص㣬ôڶԵ 2 صͶƱʱÿ˲Ҫǵ 2 ص 1 صȼҲҪͶƱصȼ ```java int N = in.nextInt(); @@ -246,9 +246,9 @@ for (int place = K; place > 0; place--) { System.out.println(ret == 0 ? "otaku" : ret); ``` -# 7. 微软-S-expression +# 7. ΢-S-expression -# 8. 华为-最高分是多少 +# 8. Ϊ-߷Ƕ ```java int N = in.nextInt(); @@ -280,7 +280,7 @@ for (int i = 0; i < M; i++) { } ``` -# 9. 华为-简单错误记录 +# 9. Ϊ-򵥴¼ ```java HashMap map = new LinkedHashMap<>(); @@ -300,7 +300,7 @@ for (int i = 0; i < 8 && i < list.size(); i++) { } ``` -# 10. 华为-扑克牌大小 +# 10. Ϊ-˿ƴС ```java public class Main { @@ -391,12 +391,12 @@ public class Main { } ``` -# 11. 去哪儿-二分查找 +# 11. ȥĶ-ֲ -对于有重复元素的有序数组,二分查找需要注意以下要点: +ظԪص飬ֲҪעҪ㣺 - if (val <= A[m]) h = m; -- 因为 h 的赋值为 m 而不是 m - 1,因此 while 循环的条件也就为 l < h。(如果是 m - 1 循环条件为 l <= h) +- Ϊ h ĸֵΪ m m - 1 while ѭҲΪ l < h m - 1 ѭΪ l <= h ```java public int getPos(int[] A, int n, int val) { @@ -410,7 +410,7 @@ public int getPos(int[] A, int n, int val) { } ``` -# 12. 去哪儿-首个重复字符 +# 12. ȥĶ-׸ظַ ```java public char findFirstRepeat(String A, int n) { @@ -424,7 +424,7 @@ public char findFirstRepeat(String A, int n) { } ``` -# 13. 去哪儿-寻找Coder +# 13. ȥĶ-ѰCoder ```java public String[] findCoder(String[] A, int n) { @@ -450,7 +450,7 @@ public String[] findCoder(String[] A, int n) { return ret; } -// 牛客网无法导入 javafx.util.Pair,这里就自己实现一下 Pair 类 +// ţ޷ javafx.util.PairԼʵһ Pair private class Pair { T t; K k; @@ -470,9 +470,9 @@ private class Pair { } ``` -# 14. 美团-最大差值 +# 14. -ֵ -贪心策略。 +̰IJԡ ```java public int getDis(int[] A, int n) { @@ -486,7 +486,7 @@ public int getDis(int[] A, int n) { } ``` -# 15. 美团-棋子翻转 +# 15. -ӷת ```java public int[][] flipChess(int[][] A, int[][] f) { @@ -502,7 +502,7 @@ public int[][] flipChess(int[][] A, int[][] f) { } ``` -# 16. 美团-拜访 +# 16. -ݷ ```java private Set paths; @@ -554,7 +554,7 @@ private void backtracking(int[][] map, int n, int m, int r, int c, int[][] direc } ``` -# 17. 美团-直方图内最大矩形 +# 17. -ֱͼ ```java public int countArea(int[] A, int n) { @@ -570,15 +570,15 @@ public int countArea(int[] A, int n) { } ``` -# 18. 美团-字符串计数 +# 18. -ַ -字符串都是小写字符,可以把字符串当成是 26 进制。但是字典序的比较和普通的整数比较不同,是从左往右进行比较,例如 "ac" 和 "abc",字典序的比较结果为 "ac" > "abc",如果按照整数方法比较,因为 "abc" 是三位数,显然更大。 +ַСдַ԰ַ 26 ơֵıȽϺͨȽϲͬǴҽбȽϣ "ac" "abc"ֵıȽϽΪ "ac" > "abc"ȽϣΪ "abc" λȻ -由于两个字符串的长度可能不想等,在 s1 空白部分和 s2 对应部分进行比较时,应该把 s1 的空白部分看成是 'a' 字符进行填充的。 +ַijȿܲȣ s1 հײֺ s2 ӦֽбȽʱӦð s1 Ŀհײֿ 'a' ַġ -还有一点要注意的是,s1 到 s2 长度为 leni 的字符串个数只比较前面 i 个字符。例如 'aaa' 和 'bbb' ,长度为 2 的个数为 'aa' 到 'bb' 的字符串个数,不需要考虑后面部分的字符。 +һҪעǣs1 s2 Ϊ leni ַֻȽǰ i ַ 'aaa' 'bbb' Ϊ 2 ĸΪ 'aa' 'bb' ַҪǺ沿ֵַ -在统计个数时,从 len1 开始一直遍历到最大合法长度,每次循环都统计长度为 i 的子字符串个数。 +ͳƸʱ len1 ʼһֱϷȣÿѭͳƳΪ i ַ ```java String s1 = in.next(); @@ -601,7 +601,7 @@ for (int i = len1; i <= len; i++) { System.out.println(ret - 1); ``` -# 19. 美团-平均年龄 +# 19. -ƽ ```java int W = in.nextInt(); @@ -609,15 +609,15 @@ double Y = in.nextDouble(); double x = in.nextDouble(); int N = in.nextInt(); while (N-- > 0) { - Y++; // 老员工每年年龄都要加 1 + Y++; // Աÿ䶼Ҫ 1 Y += (21 - Y) * x; } System.out.println((int) Math.ceil(Y)); ``` -# 20. 百度-罪犯转移 +# 20. ٶ-ﷸת -部分和问题,将每次求的部分和缓存起来。 +ֺ⣬ÿIJֺͻ ```java int n = in.nextInt(); @@ -640,7 +640,7 @@ for (int s = 0, e = c - 1; e < n; s++, e++) { System.out.println(cnt); ``` -# 22. 百度-裁减网格纸 +# 22. ٶ-üֽ ```java int n = in.nextInt(); @@ -658,11 +658,11 @@ for (int i = 0; i < n; i++) { System.out.println((int) Math.pow(Math.max(maxX - minX, maxY - minY), 2)); ``` -# 23. 百度-钓鱼比赛 +# 23. ٶ- -P ( 至少钓一条鱼 ) = 1 - P ( 一条也钓不到 ) +P ( ٵһ ) = 1 - P ( һҲ ) -坑:读取概率矩阵的时候,需要一行一行进行读取,而不能直接用 in.nextDouble()。 +ӣȡʾʱҪһһнжȡֱ in.nextDouble() ```java public static void main(String[] args) { @@ -673,11 +673,11 @@ public static void main(String[] args) { int x = in.nextInt(); int y = in.nextInt(); int t = in.nextInt(); - in.nextLine(); // 坑 + in.nextLine(); // double pcc = 0.0; double sum = 0.0; for (int i = 1; i <= n; i++) { - String[] token = in.nextLine().split(" "); // 坑 + String[] token = in.nextLine().split(" "); // for (int j = 1; j <= m; j++) { double p = Double.parseDouble(token[j - 1]); // double p = in.nextDouble(); @@ -701,13 +701,13 @@ private static double computePOfIRT(double p, int t) { } ``` -# 24. 百度-蘑菇阵 +# 24. ٶ-Ģ -这题用回溯会超时,需要用 DP。 +ûݻᳬʱҪ DP -dp[i][j] 表示到达 (i,j) 位置不会触碰蘑菇的概率。对于 N\*M 矩阵,如果 i == N || j == M,那么 (i,j) 只能有一个移动方向;其它情况下能有两个移动方向。 +dp[i][j] ʾ (i,j) λòᴥĢĸʡ N\*M i == N || j == Mô (i,j) ֻһƶƶ -考虑以下矩阵,其中第 3 行和第 3 列只能往一个方向移动,而其它位置可以有两个方向移动。 +¾е 3 к͵ 3 ֻһƶλÿƶ ```java diff --git a/notes/HTTP.md b/notes/HTTP.md new file mode 100644 index 00000000..f17b79c6 --- /dev/null +++ b/notes/HTTP.md @@ -0,0 +1,399 @@ + +* [](#) + * [Web](#web) + * [URL](#url) + * [Ӧ](#Ӧ) +* [HTTP ](#http-) + * [GETȡԴ](#getȡԴ) + * [POSTʵ](#postʵ) + * [HEADȡײ](#headȡײ) + * [PUTϴļ](#putϴļ) + * [DELETEɾļ](#deleteɾļ) + * [OPTIONSѯֵ֧ķ](#optionsѯֵ֧ķ) + * [RACE׷·](#race׷·) + * [CONNECTҪЭӴ](#connectҪЭӴ) +* [HTTP ״̬](#http-״̬) + * [2XX ɹ](#2xx-ɹ) + * [3XX ض](#3xx-ض) + * [4XX ͻ˴](#4xx-ͻ˴) + * [5XX ](#5xx-) +* [HTTPײ](#httpײ) + * [ͨײֶ](#ͨײֶ) + * [ײֶ](#ײֶ) + * [Ӧײֶ](#Ӧײֶ) + * [ʵײֶ](#ʵײֶ) +* [Ӧ](#Ӧ) + * [Cookie](#cookie) + * [](#) + * [־](#־) + * [](#) + * [ֿ鴫](#ֿ鴫) + * [ಿֶ󼯺](#ಿֶ󼯺) + * [Χ](#Χ) + * [Э](#Э) + * [](#) + * [ͨת](#ͨת) +* [HTTPs](#https) + * [](#) + * [֤](#֤) + * [](#) + + +# + +## Web + +HTTPHyperText Transfer ProtocolΪЭ飩 + +WWWWord Wide WebּHTMLHTTPURL + +RFCRequest for Comments飩ĵ + +## URL + +URIUniform Resource IndentifierͳһԴʶURLUniform Resource LocatorͳһԴλURNUniform Resource NameͳһԴƣ urn:isbn:0-486-27557-4 URI URL URNĿǰ WEB ֻ URL ȽУԼĻ URL + +URLʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4102b7d0-39b9-48d8-82ae-ac4addb7ebfb.jpg) + +## Ӧ + +**** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9dbb5fc2-936b-4c6d-b3a7-9617aae45080.jpg) + +**Ӧ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c634b5ed-a14b-4302-b40e-3ee387dd3c8a.jpg) + +# HTTP + +ͻ˷͵ĵһΪУ˷ֶΡ + +## GETȡԴ + +## POSTʵ + +POST ҪĿIJǻȡԴǴʵݡ + +GET POST ʹöIJ GET IJԲѯַ URLУ POST IJ洢ʵ岿֡ + +``` +GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1 +``` +``` +POST /test/demo_form.asp HTTP/1.1 +Host: w3schools.com +name1=value1&name2=value2 +``` + +GET Ĵηʽ POST ȫԽϲΪ GET IJ URL ǿɼģܻй¶˽Ϣ GET ֻ֧ ASCII ַΪܻ룬 POST ֱ֧׼ַ + +## HEADȡײ + + GET һDzرʵ岿֡ + +Ҫȷ URL ЧԼԴµʱȡ + +## PUTϴļ + +֤ƣκ˶ϴļ˴ڰȫ⣬һ WEB վʹø÷ + +## DELETEɾļ + + PUT ෴֤ͬơ + +## OPTIONSѯֵ֧ķ + +ѯָ URL ֵܹ֧ķ + +᷵ Allow: GET, POST, HEAD, OPTIONS ݡ + +## RACE׷· + +Ὣͨ·ظͻˡ + +ʱ Max-Forwards ײֵֶÿһͻ 1ֵΪ 0 ʱֹͣ䡣 + +TRACE һ㲻ʹãܵ XST Cross-Site Tracingվ׷٣˸ȥʹ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ca711108-e937-4d7d-99aa-61b325c61f1a.jpg) + +## CONNECTҪЭӴ + +Э TCP ͨš + +Ҫʹ SSLSecure Sokets Layerȫ׽֣ TLSTransport Layer Security㰲ȫЭͨݼܺ䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d8355d56-aa2b-4452-8001-8475cc095af1.jpg) + +# HTTP ״̬ + +صӦеһΪ״̬У״̬Լԭ֪ͻĽ + +| ״̬ | | ԭ | +| --- | --- | --- | +| 1XX | InformationalϢ״̬룩 | յڴ | +| 2XX | Successɹ״̬룩 | | +| 3XX | Redirectionض״̬룩 | ҪиӲ | +| 4XX | Client Errorͻ˴״̬룩 | ޷ | +| 5XX | Server Error״̬룩 | | + +## 2XX ɹ + +**200 OK** + +**204 No Content**ѾɹǷصӦIJʵ岿֡һֻҪӿͻϢҪʱʹá + +**206 Partial Content** + +## 3XX ض + +**301 Moved Permanently**ض + +**302 Found**ʱض + +**303 See Other** + +עȻ HTTP Э涨 301302 ״̬ضʱ POST ij GET Ǵ 301302 303 ״̬µض POST ij GET + +**304 Not Modified**ײһЩ磺If-MatchIf-ModifiedSinceIf-None-MatchIf-RangeIf-Unmodified-SinceDz᷵ 304 ״̬롣 + +**307 Temporary Redirect**ʱض 302 ĺƣ 307 Ҫض POST ij GET + +## 4XX ͻ˴ + +**400 Bad Request**д﷨ + +**401 Unauthorized**״̬ʾ͵Ҫͨ HTTP ֤BASIC ֤DIGEST ֤֤Ϣ֮ǰѽйһʾû֤ʧܡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b1b4cf7d-c54a-4ff1-9741-cd2eea331123.jpg) + +**403 Forbidden**󱻾ܾûбҪܾϸɡ + +**404 Not Found** + +## 5XX + +**500 Internal Server Error**ִʱ + +**503 Service Unavilable**״̬ʱڳػڽͣά޷ + +# HTTPײ + +HTTP İײ֡ 4 ͵ײֶΣͨײֶΡײֶΡӦײֶκʵײֶΡײֶμ京£Ҫȫǣģ + +## ͨײֶ + +| ײֶ | ˵ | +| -- | -- | +| Cache-Control | ƻΪ | +| Connection | ײ ӵĹ | +| Date | ĵʱ | +| Pragma | ָ | +| Trailer | ĩ˵ײһ | +| Transfer-Encoding | ָĴ뷽ʽ | +| Upgrade | ΪЭ | +| Via | Ϣ | +| Warning | ֪ͨ | + +## ײֶ + +| ײֶ | ˵ | +| -- | -- | +| Accept | ûɴý | +| Accept-Charset | ȵַ | +| Accept-Encoding | ȵݱ | +| Accept-Language | ȵԣȻԣ | +| Authorization | Web֤Ϣ | +| Expect | ڴضΪ | +| From | ûĵַ | +| Host | Դڷ | +| If-Match | ȽʵǣETag | +| If-Modified-Since | ȽԴĸʱ | +| If-None-Match | Ƚʵǣ If-Match ෴ | +| If-Range | Դδʱʵ Byte ķΧ | +| If-Unmodified-Since | ȽԴĸʱ䣨If-Modified-Since෴ | +| Max-Forwards | | +| Proxy-Authorization | Ҫͻ˵֤Ϣ | +| Range | ʵֽڷΧ | +| Referer | URI ԭʼȡ | +| TE | ȼ | +| User-Agent | HTTP ͻ˳Ϣ | + +## Ӧײֶ + +| ײֶ | ˵ | +| -- | -- | +| Accept-Ranges | ǷֽڷΧ | +| Age | Դʱ | +| ETag | ԴƥϢ | +| Location | ͻضָURI | +| Proxy-Authenticate | Կͻ˵֤Ϣ | +| Retry-After | ٴηʱҪ | +| Server | HTTPİװϢ | +| Vary | ĹϢ | +| WWW-Authenticate | Կͻ˵֤Ϣ | + +## ʵײֶ + +| ײֶ | ˵ | +| -- | -- | +| Allow | Դֵ֧HTTP | +| Content-Encoding | ʵõı뷽ʽ | +| Content-Language | ʵȻ | +| Content-Length | ʵĴСλ ֽڣ | +| Content-Location | ӦԴURI | +| Content-MD5 | ʵıժҪ | +| Content-Range | ʵλ÷Χ | +| Content-Type | ʵý | +| Expires | ʵڵʱ | +| Last-Modified | Դ޸ʱ | + +# Ӧ + +## Cookie + +HTTP Э״̬ģҪΪ HTTP Э龡ܼ򵥣ʹܹHTTP/1.1 Cookie ״̬Ϣ + +ᷢ͵Ӧİ Set-Cookie ֶΣͻ˵õӦ Cookie ݱ浽С´ٷʱж Cookie ֵа Cookie ֶΣ֪ͻ˵״̬ϢˡCookie ״̬ϢڿͻУǷϡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ff17c103-750a-4bb8-9afa-576327023af9.png) + +Set-Cookie ֶԣ + +| | ˵ | +| -- | -- | +| NAME=VALUE | Cookie ƺֵ | +| expires=DATE | Cookie ЧڣȷָĬΪرǰΪֹ | +| path=PATH | ϵļĿ¼Ϊ Cookie öָĬΪĵڵļĿ¼ | +| domain= | Ϊ Cookie öָĬΪ Cookie ķ | +| Secure | HTTPS ȫͨʱŻᷢ Cookie | +| HttpOnly | ƣʹ Cookie ܱ JavaScript ű | + +**Session Cookie ** + +Session ǷûһֶΣÿ Session һΨһʶSession IDһ Session ʱͻ˷͵ӦľͰ Set-Cookie ֶΣһΪ sid ļֵԣֵԾ Session IDͻյͰ Cookie У֮͵Ķ Session IDHTTP Session Cookie ַʽһʵָû״̬ģ Session ڷˣCookie ڿͻˡ + +** Cookie ** + +ʹ URL д URL sid=xxx + +**ʹ Cookie ʵûԶд** + +վűԶ Cookie жȡû룬ӶʵԶд + +## + +ֻ淽ôлÿͻл档 + +Cache-Control ڿƻΪ + +Cache-Control: no-cache ֺ壬ǿͻ򻺴͵киָʾͻ˲ҪԴԴ򻺴͵ӦкиָʾܶԴл档 + +Expires ֶοڸ֪Դʲôʱڡײֶ Cache-Control ָ max-age ָʱײֶ Expiresȴ max-age ָ + +## ־ + +һͼƬ HTML ҳʱ HTML ҳԴͼƬԴÿһ HTTP ͨžҪϿһ TCP ӣӽͶϿĿܴ**־** ֻҪһ TCP Ӿܽж HTTP ͨšHTTP/1.1ʼеĬ϶dz־ӡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c73a0b78-5f46-4d2d-a009-dab2a999b5d8.jpg) + +־Ҫʹ Connection ײֶνйHTTP/1.1 ʼHTTP Ĭdz־ûӵģҪϿ TCP ӣҪɿͻ˻߷Ͽʹ Connection: close HTTP/1.1֮ǰĬǷdz־ûӵģҪάֳӣҪʹ Keep-Alive + +߻ʽͬʱͶӦҪһȻȴӦ֮ٷһ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6943e2af-5a70-4004-8bee-b33d60f39da3.jpg) + +## + +루EncodingҪΪ˶ʵѹõıУgzipcompressdeflateidentity identity ʾִѹıʽ + +## ֿ鴫 + +ֿ鴫䣨Chunked Transfer Coding԰ݷָɶ飬ʾҳ档 + +## ಿֶ󼯺 + +һݱڿɺж͵ʵͬʱͣÿ֮ boundary ֶζķָзָÿֶײֶΡ + +磬ϴʱʹ·ʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/decb0936-e83c-4a55-840a-fe8aa101ac61.png) + +## Χ + +жϣֻһݣΧʹÿͻֻܹδ͵DzݣӶ·ݡ + +ײ Range ֶΣȻָķΧ Range : bytes = 5001-10000ɹĻ 206 Partial Content ״̬ + +## Э + +ͨЭ̷ʵݣĬѡ񷵻Ľ滹ӢĽ档 + +漰ײֶΣAcceptAccept-CharsetAccept-EncodingAccept-LanguageContent-Language + +## + +ʹʹһ̨ӵж߼ϿԿɶ + +## ͨת + +**** + +ܿͻ˵󣬲תһ͸ģı URL + +ʹôҪĿǣ桢ʿԼ¼־ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c07035c3-a9ba-4508-8e3c-d8ae4c6ee9ee.jpg) + +**** + +ͬǣطὫ HTTP תΪЭͨţӶ HTTP ķ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/81375888-6be1-476f-9521-42eea3e3154f.jpg) + +**** + +ʹ SSL ȼֶΣΪͻ˺ͷ֮佨һȫͨ· + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/64b95403-d976-421a-8b45-bac89c0b5185.jpg) + +# HTTPs + +HTTP °ȫ⣺ + +1. ͨʹģݿܻᱻ +2. ֤ͨŷݣпαװ +3. ޷֤ĵԣп۸ġ + +HTTPs Э飬 HTTP Ⱥ SSLSecure Socket Layerͨţ SSL TCP ͨšͨʹ SSLHTTPs ṩ˼ܡ֤Ա + +## + +ּܷʽԳԿܺ͹ԿܡԳԿܵļܺͽʹͬһԿԿʹһԿڼܺͽܣֱΪԿ˽ԿԿ˶ԻãͨŷͷýշĹԿ֮󣬾ͿʹùԿмܣշյͨݺʹ˽Կܡ + +ԳԿܵȱ㣺޷ȫԿԿܵȱ㣺˵ʱ + +HTTPs **ϵļܻ**ʹùԿڴԳԿ֮ʹöԳԿܽͨšͼУԿԳԿ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/110b1a9b-87cd-45c3-a21d-824623715b33.jpg) + +## ֤ + +ͨʹ **֤** ͨŷ֤֤йԿݣ֤ԿȷͨŷģôͿȷͨŷǿɿġ + +֤֤CACertificate +Authority䷢ĹԿ֤飬ͨ CA ֤ + + HTTPs ͨʱ֤鷢͸ͻˣͻȡеĹԿ֮󣬾ͿԿʼ̡ܹ + +ʹ OpenSSL ׿Դÿ˶ԹһԼ֤ӶԼԼ䷢֤顣ڷʸ÷ʱʾ޷ȷӰȫԡ򡰸վİȫ֤⡱ȾϢ + +ͻ֤ҪûаװֻҵҪdz߰ȫʱʹÿͻ֤飬С + +## + +SSL ṩժҪ֤ԡ + diff --git a/notes/JVM.md b/notes/JVM.md new file mode 100644 index 00000000..597eda7c --- /dev/null +++ b/notes/JVM.md @@ -0,0 +1,673 @@ + +* [ڴģ](#ڴģ) + * [1. ](#1-) + * [2. Java ջ](#2-java-ջ) + * [3. طջ](#3-طջ) + * [4. Java ](#4-java-) + * [5. ](#5-) + * [6. ʱ](#6-ʱ) + * [7. ֱڴ](#7-ֱڴ) +* [ռ](#ռ) + * [1. жһǷɻ](#1-жһǷɻ) + * [1.1 ü](#11-ü) + * [1.2 ɴ](#12-ɴ) + * [1.3 ](#13-) + * [1.3.1 ǿ](#131-ǿ) + * [1.3.2 ](#132-) + * [1.3.3 ](#133-) + * [1.3.4 ](#134-) + * [1.3 Ļ](#13-Ļ) + * [1.4 finalize()](#14-finalize) + * [2. ռ㷨](#2-ռ㷨) + * [2.1 - 㷨](#21----㷨) + * [2.2 㷨](#22-㷨) + * [2.3 - 㷨](#23----㷨) + * [2.4 ִռ㷨](#24-ִռ㷨) + * [3. ռ](#3-ռ) + * [3.1 Serial ռ](#31-serial-ռ) + * [3.2 ParNew ռ](#32-parnew-ռ) + * [3.3 Parallel Scavenge ռ](#33-parallel-scavenge-ռ) + * [3.4 Serial Old ռ](#34-serial-old-ռ) + * [3.5 Parallel Old ռ](#35-parallel-old-ռ) + * [3.6 CMS ռ](#36-cms-ռ) + * [3.7 G1 ռ](#37-g1-ռ) + * [3.8 ռıȽ](#38-ռıȽ) + * [4. ڴղ](#4-ڴղ) + * [4.1 Eden ](#41--eden-) + * [4.2 ֱӽ](#42-ֱӽ) + * [4.3 ڴĶ](#43-ڴĶ) + * [4.4 ̬ж](#44-̬ж) + * [4.5 ռ䵣](#45-ռ䵣) + * [4.6 Full GC Ĵ](#46-full-gc-Ĵ) + * [4.6.1 System.gc()](#461--systemgc) + * [4.6.2 ռ䲻](#462-ռ䲻) + * [4.6.3 ռ䵣ʧ](#463-ռ䵣ʧ) + * [4.6.4 JDK 1.7 ǰôռ䲻](#464-jdk-17-ǰôռ䲻) + * [4.6.5 Concurrent Mode Failure](#465-concurrent-mode-failure) +* [ػ](#ػ) + * [1 ](#1-) + * [2. ʼʱ](#2-ʼʱ) + * [3. ع](#3-ع) + * [3.1 ](#31-) + * [3.2 ֤](#32-֤) + * [3.3 ׼](#33-׼) + * [3.4 ](#34-) + * [3.5 ʼ](#35-ʼ) + * [4. ](#4-) + * [4.1 ](#41-) + * [4.2 ](#42-) + * [4.3 ˫ίģ](#43-˫ίģ) +* [JVM ](#jvm-) + * [GC Ż](#gc-Ż) + * [GC ](#gc-) + + +# ڴģ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dc695f48-4189-4fc7-b950-ed25f6c80f82.jpg) + +עɫΪ߳˽еģɫΪ̹߳ġ + +## 1. + +¼ִеָֽĵִַе Native Ϊգ + +## 2. Java ջ + +ÿ Java ִеͬʱᴴһջ֡ڴ洢ֲջ̬ӡڵϢÿһӵֱִɵḶ́ͶӦһջ֡ Java ջջͳջĹ̡ + +׳쳣 + +1. ߳ջȳֵ׳ StackOverflowError 쳣 +2. ջж̬չʱ޷뵼㹻ڴ棬׳ OutOfMemoryError 쳣 + +## 3. طջ + + Java ջƣֻ֮DZطջΪط + +## 4. Java + +жʵڴ档 + +ռҪ"GC "ռDz÷ִռ㷨Java ѻԷֳɣԷֳ Eden ռ䡢From Survivor ռ䡢To Survivor ռȣ + +Ҫڴ棬ͨ -Xmx -Xms ƶ̬չڴС̬չʧܻ׳ OutOfMemoryError 쳣 + +## 5. + +ڴѱصϢ̬ʱĴݡ + + Java һҪڴ棬ҿԶ̬չ̬չʧһ׳ OutOfMemoryError 쳣 + +յҪĿǶԳصĻպͶжأһȽʵ֣HotSpot ôա + +## 6. ʱ + +ʱǷһ֡ + +غClass ļеijأڴűɵĸͷãͻᱻŵ + +ڼҲù String intern() µij + +## 7. ֱڴ + + JDK 1.4 ¼ NIO ࣬һֻͨChannel뻺Buffer I/O ʽʹ Native ֱӷڴ棬Ȼͨһ洢 Java DirectByteBuffer ΪڴýвһЩܣΪ Java Ѻ Native ظݡ + +# ռ + +ջͱطջ߳˽еģ̵ֻ߳ڣ֮߳̽Ҳʧ˲Ҫա + +Ҫ Java ѺͷС + +## 1. жһǷɻ + +### 1.1 ü + +һüһʱ 1ʧЧʱ 1 + +üΪ 0 Ķɱա + +ѭ⣬ʱüԶΪ 0 GC ռ޷ա + +```java +objA.instance = objB; +objB.instance = objA; +``` + +### 1.2 ɴ + +ͨ GC Roots ΪʼܹﵽĶǶǿõģɴĶɱա + +GC Roots һݣ + +1. ջõĶ +2. ྲ̬õĶ +3. еijõĶ +4. طջõĶ + +### 1.3 + +ͨü㷨ж϶ͨɴԷ㷨ж϶ǷɴжǷ롰áйء + +#### 1.3.1 ǿ + +ֻҪǿôڣԶյõĶ + +```java +Object obj = new Object(); +``` + +#### 1.3.2 + + +DZãڴ֮ǰлա + +```java +Object obj = new Object(); +SoftReference sf = new SoftReference(obj); +obj = null; +sf.get(); +``` + +sf Ƕ obj һãͨ sf.get() ȡ󣬵Ȼ󱻱ΪҪյĶʱ򷵻 null + +ҪûʵƻĹܣڴ㹻ֱͨȡֵӷæʵԴѯݣٶȣڴ治ʱԶɾⲿֻݣԴѯЩݡ + + +#### 1.3.3 + +ֻ浽һռ֮ǰռʱ۵ǰڴǷ㹻ᱻա + +```java +Object obj = new Object(); +WeakReference wf = new WeakReference(obj); +obj = null; +wf.get(); +wf.isEnQueued(); +``` + +#### 1.3.4 + +ֳΪû߻ӰãһǷõĴڣȫʱ乹Ӱ죬Ҳ޷ͨȡһʵΪһùΨһĿľռʱյһϵͳ֪ͨ + +```java +Object obj = new Object(); +PhantomReference pf = new PhantomReference(obj); +obj=null; +pf.get(); +pf.isEnQueued(); +``` + +### 1.3 Ļ + +ڷҪǶԳصĻպͶжء + +صĻպͶжơ + +жܶ࣬ҪҲһᱻжأ + +1. еʵѾգҲ Java вڸκʵ +2. ظ ClassLoader Ѿա +3. Ӧ java.lang.Class ûκεطãҲ޷κεطͨʸ෽ + +ͨ -Xnoclassgc Ƿжء + +ڴʹ÷䡢̬CGLib ByteCode ܡ̬ JSP Լ OSGo ƵԶ ClassLoader ijҪ߱жعܣԱ֤ڴ + +### 1.4 finalize() + +һɱʱöбҪִ finalize() ôпܿͨڸ÷ö±ãӶʵԾȡ + +finalize() C++ 鹹رⲿԴȹ try-finally ȷʽĸãҸ÷д۸߰ȷԴ޷֤ĵ˳òҪʹá + +## 2. ռ㷨 + +### 2.1 - 㷨 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg) + +ҪյĶбǣȻ + +㣺 + +1. ǺЧʶ +2. Ƭ + +֮㷨ǻڸ㷨иĽ + +### 2.2 㷨 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e6b733ad-606d-4028-b3e8-83c3a73a3797.jpg) + +ڴ滮ΪСȵ飬ÿֻʹһ飬һڴ˾ͽĶƵһ棬Ȼٰʹùڴռһ + +Ҫֻʹڴһ롣 + +ڵҵռ㷨Dzǽڴ滮ΪСȵ飬ǷΪһϴ Eden ռС Survior ռ䣬ÿʹ Eden ռһ Survivorڻʱ Eden Survivor лŵĶһԸƵһ Survivor ռϣ Eden SurvivorHotSpot Eden Survivor ĴСĬΪ 8:1֤ڴʴﵽ 90 %ÿλж 10% Ķôһ Survivor ռͲˣҪз䵣ҲǽĿռ䡣 + +### 2.3 - 㷨 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/902b83ab-8054-4bd2-898f-9a4a0fe52830.jpg) + +дĶһƶȻֱ˱߽ڴ档 + +### 2.4 ִռ㷨 + +ڵҵ÷ִռ㷨ʹǰܵļռ㷨ݶڽڴ滮Ϊ飬ͬʵռ㷨 + +һ㽫 Java ѷΪ + +1. ʹã㷨 +2. ʹã - - 㷨 + +## 3. ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg) + + HotSpot е 7 ռ߱ʾռʹá + +### 3.1 Serial ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg) + +ǵ̵߳ռζֻʹһ߳̽ռҪڽռʱ̣ͣ߳ɹĵȴʱ䡣 + +ŵǼ򵥸Чڵ CPU ˵û߳̽Ŀӵߵĵ߳ռЧʡ + + Client ӦóУڴһ˵ܴ󣬸ռռʮһ׵ͣʱԿһٶڣֻҪ̫ƵͣǿԽܵġ + +### 3.2 ParNew ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg) + + Serial ռĶ̰߳汾 + + Server ģʽµѡռԭ⣬ҪΪ Serial ռֻ CMS ռϹ + +ĬϿʼ߳ CPU ͬʹ -XX:ParallelGCThreads ߳ + +### 3.3 Parallel Scavenge ռ + +DzеĶ߳ռ + +ռעǾռʱû̵߳ͣʱ䣬ĿǴﵽһɿƵΪȡռָ CPU ûʱռʱıֵ + +ͣʱԽ̾ԽʺҪûijõӦٶû顣ԸЧʵ CPU ʱ䣬ɳҪʺں̨Ҫཻ̫ + +ṩھȷֱǿռͣʱ -XX:MaxGCPauseMillis ԼֱС -XX:GCTimeRatio ֵΪ 0 С 100 ͣʱռȡģռСձƵ½ + +ṩһ -XX:+UseAdaptiveSizePolicyһز򿪲󣬾ͲҪָֹĴС-XmnEden Survivor ı-XX:SurvivorRatio䣨-XX:PretenureSizeThresholdϸڲˣݵǰϵͳռܼϢ̬ЩṩʵͣʱַʽΪ GC ӦĵڲԣGC ErgonomicsӦڲҲ ParNew ռһҪ + +### 3.4 Serial Old ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg) + +Serial Old Serial ռ汾ҲǸ Client ģʽµʹá Server ģʽ£; + +1. JDK 1.5 Լ֮ǰ汾Parallel Old ǰ Parallel Scavenge ռʹá +2. Ϊ CMS ռĺԤڲռ Concurrent Mode Failure ʱʹá + +### 3.5 Parallel Old ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/278fe431-af88-4a95-a895-9c3b80117de3.jpg) + + Parallel Scavenge ռ汾 + +עԼ CPU Դеijϣȿ Parallel Scavenge Parallel Old ռ + +### 3.6 CMS ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg) + +CMSConcurrent Mark Sweep Mark Sweep ֪ǻ - 㷨ʵֵġ + +ص㣺ռͣ١ + +Ϊĸ̣ + +1. ʼǣֻDZһ GC Roots ֱӹĶٶȺܿ죬Ҫͣ١ +2. ǣ GC Roots Tracing Ḷ́չкʱҪͣ١ +3. ±ǣΪڼû±Dz䶯һֶıǼ¼Ҫͣ١ +4. Ҫͣ١ + +кʱIJǺͲУռ̶߳û߳һҪͣ١ + +ȱ㣺 + +1. CPU ԴСCMS ĬĻ߳ (CPU + 3) / 4 CPU 4 ʱCMS ûӰͿܱúܴ CPU ؾͱȽϴ󣬻Ҫֳһȥִռ̣߳ͿܵûִٶȺȻ 50%ʵҲ޷ܡҵͣʱΪ۵ģ CPU ʱ͡ + +2. ޷ڲ׶û̻߳ţȻͻµϲһڱǹ֮CMS ޷ڵռдǣֻһ GC ʱһͱΪҲռ׶û̻߳ҪУҲͻҪԤ㹻ڴռû߳ʹãռȵȫٽռҪԤһֿռṩռʱijʹáʹ -XX:CMSInitiatingOccupancyFraction ֵı䴥ռڴռðٷֱȣJDK 1.5 Ĭ¸ֵΪ 68Ҳǵʹ 68% Ŀռ֮ᴥռֵõ̫ߣ¸޷棬ôͻ Concurrent Mode FailureʱԤʱ Serial Old ռ½ռ + +3. - 㷨µĿռƬܴ鷳ռʣ࣬޷ҵ㹻ռ䵱ǰ󣬲òǰһ Full GC + +### 3.7 G1 ռ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg) + +G1Garbage-Firstռǵռչǰصijɹ֮һһӦõռHotSpot ŶӸʹǣڱȽϳڵģδ滻 JDK 1.5 з CMS ռ + +߱ص㣺 + +- 벢ܳö CPU µӲƣʹö CPU ͣʱ䣻 +- ִռִȻԱȻҪռϾܶ GC ѣܹòͬʽȥ´ĶѴһʱ䡢 GC ľɶȡõռЧ +- ռϣǻڡ - 㷨ʵֵռӾֲ Region ֮䣩ǻڡơ㷨ʵֵģζڼ䲻ڴռƬ +- Ԥͣ٣ CMS һƣͣʱ G1 CMS ͬĹע㣬 G1 ˽ͣ⣬ܽԤͣʱģͣʹȷָһΪ M ʱƬڣ GC ϵʱ䲻ó N 룬⼸Ѿʵʱ JavaRTSJռˡ + + G1 ֮ǰռռķΧ G1 Java ѵڴ沼ռкܴ𣬽 Java ѻΪСȵĶRegionȻĸˣһ RegionҪļϡ + +֮ܽԤͣʱģͣΪмƻر Java нȫռٸ Region ѻļֵСõĿռСԼʱľֵں̨άһбÿθռʱ䣬Ȼռֵ RegionҲ Garbage-First Ƶɣʹ Region ڴռԼȼշʽ֤޵ʱڿԻȡܸߵռЧʡ + +Region ǹģһij Region У Java ĶùϵɴԷȷǷʱҪɨ Java Ѳܱ֤׼ȷԣȻǶ GC Чʵļ˺Ϊ˱ȫɨķÿ Region άһ֮Ӧ Remembered Setֳڶ Reference ͵ݽдʱһ Write Barrier ʱжд Reference õĶǷڲͬ Region ֮Уǣͨ CardTable Ϣ¼ö Region Remembered Set ֮Сڴʱ GC ڵöٷΧм Remembered Set ɱ֤ȫɨҲ© + +ά Remembered Set IJG1 ռ¿ɻΪ¼裺 + +1. ʼ +2. +3. ձǣΪڲڼû±Dz䶯һֱǼ¼ʱ仯¼̵߳ Remembered Set Logs 棬ձǽ׶Ҫ Remembered Set Logs ݺϲ Remembered Set С׶Ҫ̣ͣ߳ǿɲִС +4. ɸѡգȶԸ Region еĻռֵͳɱ򣬸û GC ͣʱƶռƻ˽׶ʵҲûһ𲢷ִУΪֻһ RegionʱûɿƵģͣû߳̽ռЧʡ + +### 3.8 ռıȽ + +| ռ | С or | / | 㷨 | Ŀ | ó | +| --- | --- | --- | --- | --- | --- | +| **Serial** | | | 㷨 | Ӧٶ | CPU µ Client ģʽ | +| **Serial Old** | | | - | Ӧٶ | CPU µ Client ģʽCMS ĺԤ | +| **ParNew** | | | 㷨 | Ӧٶ | CPU ʱ Server ģʽ CMS | +| **Parallel Scavenge** | | | 㷨 | | ں̨Ҫཻ̫ | +| **Parallel Old** | | | - | | ں̨Ҫཻ̫ | +| **CMS** | | | - | Ӧٶ | ڻվ B/S ϵͳϵ Java Ӧ | +| **G1** | | both | - + 㷨 | Ӧٶ | Ӧã滻 CMS | + +## 4. ڴղ + +### 4.1 Eden + +£ Eden 䣬 Eden ռ䲻ʱ Minor GC + +### 4.2 ֱӽ + +ṩ -XX:PretenureSizeThreshold ڴֵĶֱ䣬 Eden Survivor ֮Ĵڴ渴ƣ +### 4.3 ڴĶ + +JVM Ϊ Minor GC Ȼұ Survivor ɵģƶ Survivor 1ÿһ Minor GC 1ӵһƶĬ 15 ꣬ͨ -XX:MaxTenuringThreshold ã + + +### 4.4 ̬ж + + Survivor ͬжСܺʹ Survivor ռһ룬ڵڸĶֱӽ + +### 4.5 ռ䵣 + +ڷ Minor GC ֮ǰJVM ȼռǷжܿռ䣬Ļ Minor GC ȷǰȫģռǷνƽСڵĻ Minor GCСڵĻ Full GC + +## 4.6 Full GC Ĵ + + Minor GC䴥dz򵥣 Eden ռʱͽһ Minor GC Full GC Ըӣ + +### 4.6.1 System.gc() + +˷ĵǽ JVM Full GCȻֻǽһܶᴥ Full GCӶ Full GC ƵʣҲ˼ЪͣٵĴǿҽܲʹô˷ͲҪʹãԼȥڴ棬ͨ -XX:+ DisableExplicitGC ֹ RMI System.gc() + +### 4.6.2 ռ䲻 + +ռ䲻ijΪǰĴֱӽڴĶȣִ Full GC ռȻ㣬׳´ Java.lang.OutOfMemoryError: Java heap space Ϊ״ Full GCʱӦö Minor GC ׶αաöһʱ估ҪĶ顣 + +### 4.6.3 ռ䵣ʧ + +ʹø㷨 Minor GC Ҫڴռ HandlePromotionFailure ʧܣᴥ Full GC + +### 4.6.4 JDK 1.7 ǰôռ䲻 + + JDK 1.7 ǰHotSpot еķôʵֵģôдŵΪһЩ class Ϣ̬ݣϵͳҪصࡢ͵õķ϶ʱPermanet Generation ܻᱻռδΪ CMS GC Ҳִ Full GC Full GC Ȼղˣô JVM ׳´Ϣjava.lang.OutOfMemoryError: PermGen space Ϊ PermGen ռ Full GC 󣬿ɲõķΪ PermGen ռתΪʹ CMS GC + + JDK 1.8 Ԫռ滻ôΪʵ֣ԪռDZڴ棬˼һ Full GC Ŀԡ + +### 4.6.5 Concurrent Mode Failure + +ִ CMS GC ĹͬʱжҪʱռ䲻㣨ʱ򡰿ռ䲻㡱 CMS GC ʱǰĸർʱԵĿռ䲻㴥 Full GCᱨ Concurrent Mode Failure 󣬲 Full GC + +# ػ + +ڼ䶯̬صġ + +## 1 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/32b8374a-e822-4720-af0b-c0f485095ea2.jpg) + + 7 ׶Σ + +- **أLoading** +- **֤Verification** +- **׼Preparation** +- **Resolution** +- **ʼInitialization** +- ʹãUsing +- жأUnloading + +нijЩ¿ڳʼ׶֮ٿʼΪ֧ Java Ķ̬󶨡 + +## 2. ʼʱ + +淶вûǿԼʱмأǹ淶ϸ涨ֻгʼ( ء֤׼ŷ ) + +1. newgetstaticputstaticinvokestatic ָֽʱûнйʼȴʼ 4 ָijǣʹ new ؼʵʱ򣻶ȡһľֶ̬Σ final Ρڱѽ볣صľֶ̬γ⣩ʱԼһľ̬ʱ + +2. ʹ java.lang.reflect ķзõʱûнгʼҪȴʼ + +3. ʼһʱ丸໹ûнйʼҪȴ丸ijʼ + +4. ʱûҪָһҪִеࣨ main() Ǹࣩȳʼࣻ + +5. ʹ jdk1.7 Ķ̬֧ʱһ java.lang.invoke.MethodHandle ʵĽΪ REF_getStatic, REF_putStatic, REF_invokeStatic ķӦûнйʼҪȴʼ + + 5 ֳеΪΪһá֮⣬ķʽᴥʼΪáõijӰ + +1\. ͨøľֶ̬Σᵼʼ + +```java +System.out.println(SubClass.value); // value ֶ SuperClass ж +``` + +2\. ͨ鶨࣬ᴥijʼù̻гʼһԶɵġֱӼ̳ Object ࣬аԺͷ + +```java +SuperClass[] sca = new SuperClass[10]; +``` + +3\. ڱ׶λijУϲûֱõ峣࣬˲ᴥ峣ijʼ + +```java +System.out.println(ConstClass.HELLOWORLD); +``` + +## 3. ع + +˼ء֤׼ͳʼ 5 ׶Ρ + +### 3.1 + +صһ׶ΣעⲻҪ + +ع£ + +1. ͨһȫ޶ȡĶֽ +2. ֽľ̬洢ṹתΪʱ洢ṹ +3. ڴһ Class Ϊĸݵķڡ + +жֽԴ·ʽлȡ + +- ZIP ȡܳճΪպ JAREARWAR ʽĻ +- лȡֳ͵Ӧ Applet +- ʱɣֳʹõþǶ̬ java.lang.reflect.Proxy У ProxyGenerator.generateProxyClass ĴĶֽ +- ļɣͳ JSP Ӧã JSP ļɶӦ Class ࡣ +- ݿȡֳټЩм SAP NetweaverѡѳװݿɳڼȺķַ +... + +### 3.2 ֤ + +ȷ Class ļֽаϢϵǰҪ󣬲ҲΣİȫ + +Ҫ 4 ׶Σ + +1. ļʽ֤ +2. Ԫֽ֤Ϣ +3. ֽ֤ͨͿȷǺϷ߼ģķУ +4. ֤ + +### 3.3 ׼ + +DZ static εı׼׶Ϊڴ沢óʼֵʹõǷڴ档 + +ʵ׶ηڴ棬ڶʵʱŶһ Java С + +ʼֵһΪ 0 ֵ value ʼΪ 0 123 + +```java +public static int value = 123; +``` + +dzôᰴձʽгʼǸֵΪ 0 + +```java +public static final int value = 123; +``` + +### 3.4 + +صķ滻ΪֱõĹ̡ + +### 3.5 ʼ + +ʼ׶μִ๹ <clinit>() Ĺ̡ + +׼׶ΣѾһϵͳҪijʼֵڳʼ׶ΣݳԱͨƶۼƻȥʼԴ + +<clinit>() ص㣺 + +- ɱԶռĸֵ;̬飨static{} 飩еϲģռ˳Դļгֵ˳رעǣֻ̬ܷʵ֮ǰֵֻܸܷ֮ʡ´룺 + +```java +public class Test { + static { + i = 0; // ֵͨ + System.out.print(i); // ʾǷǰá + } + static int i = 1; +} +``` + +- Ĺ캯˵ʵ <init>()ͬҪʽĵøĹԶ֤ <clinit>() ֮ǰ <clinit>() Ѿִнеһִ <clinit>() ϶Ϊ java.lang.Object + +- ڸ <clinit>() ִУҲζŸжľ̬Ҫıֵ´룺 + +```java +static class Parent { + public static int A = 1; + static { + A = 2; + } +} + +static class Sub extends Parent { + public static int B = A; +} + +public static void main(String[] args) { + System.out.println(Sub.B); // Ǹеľֵ̬ AҲ 2 +} +``` + +- <clinit>() ӿڲDZģһв̬飬ҲûжĸֵԲΪ <clinit>() + +- ӿвʹþ̬飬Ȼʼĸֵ˽ӿһ <clinit>() ӿ಻ͬǣִнӿڵ <clinit>() Ҫִиӿڵ <clinit>() ֻеӿжıʹʱӿڲŻʼ⣬ӿڵʵڳʼʱҲһִнӿڵ <clinit>() + +- ᱣ֤һ <clinit>() ڶ̻߳±ȷļͬ߳ͬʱʼһֻ࣬һִ߳ <clinit>() ̶߳ȴֱִ߳ <clinit>() ϡһ <clinit>() кʱIJͿɶʵʹдΡ + +## 4. + +ŶӰؽ׶еġͨһȫ޶ȡĶֽ ( ֽ )ŵ Java ⲿȥʵ֣ԱӦóԼȥȡҪࡣʵĴģΪ + +### 4.1 + +һ࣬Ҫɼ౾һͬȷ Java еΨһԣÿһӵһƿռ䡣ͨ׶ԣȽǷȡָġȡ Class equals() isAssignableFrom() isInstance() ķؽҲʹ instanceof() ؼֶϵжֻʱͬһصǰ²壬򣬼ʹԴͬһ Class ļͬһأֻҪǵͬͱضȡ + +### 4.2 + + Java ĽǶֲֻͬ + +һBootstrap ClassLoader C++ ʵ֣һ֣һ־ļЩ Java ʵ֣ⲿȫ̳Գ java.lang.ClassLoader + + Java ԱĽǶȿԻֵøϸһЩ + +- Bootstrap ClassLoader 𽫴 \lib Ŀ¼еģ߱ -Xbootclasspath ָ·еģʶģļʶ rt.jarֲϵ⼴ʹ lib Ŀ¼ҲᱻأصڴС ޷ Java ֱãûڱдԶʱҪѼίɸֱʹ null 漴ɡ + +- չExtension ClassLoader ExtClassLoadersun.misc.Launcher$ExtClassLoaderʵֵġ /lib/ext ߱ java.ext.dir ϵͳָ·еصڴУ߿ֱʹչ + +- ӦóApplication ClassLoader AppClassLoadersun.misc.Launcher$AppClassLoaderʵֵġ ClassLoader е getSystemClassLoader() ķֵһΪϵͳû·ClassPathָ⣬߿ֱʹӦóûԶԼһdzĬϵ + +### 4.3 ˫ίģ + +Ӧó໥ϽмصģбҪԼԼͼչʾ֮IJιϵΪ˫ίģͣParents Delegation ModelģҪ˶⣬ӦԼĸ֮ĸӹϵһͨϣCompositionϵʵ֣̳ͨУInheritanceĹϵʵ֡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2cdc3ce2-fa82-4c22-baaa-000c07d10473.jpg) + +**** + +һյصȲԼȥԼأǰίɸÿһεļˣεݹ飬еļնӦô͵УֻеԼ޷ɴ˼ΧûҵࣩʱӼŻ᳢Լء + +**ô** + +ʹ˫ίģ֮֯Ĺϵʹ Java һ߱һִȼIJιϵ java.lang.Object rt.jar УĸҪ࣬նίɸģ˵мأ Object ڳĸжͬһࡣ෴û˫ίģͣɸмصĻûдһΪjava.lang.Object ࣬ڳ ClassPath Уϵͳнֶͬ Object ࣬򽫱һƬҡ߳Աдһ rt.jar Java ֿ࣬ᷢ룬Զ޷С + +**ʵ** + +```java +protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException{ + //check the class has been loaded or not + Class c = findLoadedClass(name); + if(c == null) { + try{ + if(parent != null) { + c = parent.loadClass(name, false); + } else{ + c = findBootstrapClassOrNull(name); + } + } catch(ClassNotFoundException e) { + //if throws the exception , the father can not complete the load + } + if(c == null) { + c = findClass(name); + } + } + if(resolve) { + resolveClass(c); + } + return c; +} +``` + +# JVM + +## GC Ż + +| | | +| --- | --- | +| -Xms | ʼڴС | +| -Xmx | ڴֵ | +| -Xmn | С | +| -XX:PermSize | ʼôС | +| -XX:MaxPermSize | ô | + +## GC + +| | | +| --- | --- | +| -XX:+UseSerialGC | | +| -XX:+UseParallelGC | | +| -XX:+UseConcMarkSweepGC | ɨ | +| -XX:ParallelCMSThreads= | ɨ = Ϊʹõ߳ | +| -XX:+UseG1GC | G1 | + +```java +java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseSerialGC -jar java-application.jar +``` diff --git a/notes/Java IO.md b/notes/Java IO.md new file mode 100644 index 00000000..c4aa5d39 --- /dev/null +++ b/notes/Java IO.md @@ -0,0 +1,406 @@ + +* [](#) +* [̲](#̲) +* [ֽڲ](#ֽڲ) +* [ַ](#ַ) +* [](#) +* [](#) + * [1. InetAddress](#1-inetaddress) + * [2. URL](#2-url) + * [3. Sockets](#3-sockets) + * [4. Datagram](#4-datagram) +* [NIO](#nio) + * [1. ](#1-) + * [2. ͨ뻺](#2-ͨ뻺) + * [2.1 ͨ](#21-ͨ) + * [2.2 ](#22-) + * [3. ״̬](#3-״̬) + * [4. дļʵ](#4-дļʵ) + * [5. ](#5-) + * [5.1 ʽ I/O](#51-ʽ-io) + * [5.2 ʽ I/O](#52-ʽ-io) + * [6. ׽ʵ](#6-׽ʵ) + * [6.1 ServerSocketChannel](#61-serversocketchannel) + * [6.2 Selectors](#62-selectors) + * [6.3 ѭ](#63-ѭ) + * [6.4 ](#64-) + * [6.5 µ](#65-µ) + * [6.6 ɾ SelectionKey](#66-ɾ-selectionkey) + * [6.7 I/O](#67--io) +* [ο](#ο) + + +# + +Java I/O ſԷֳ¼ + +1. ̲File +2. ֽڲInputStream OutputStream +3. ַReader Writer +4. Serializable +5. Socket +6. ʽ IONIO + +# ̲ + +File ڱʾļĿ¼ֻڱʾļϢʾļݡ + +# ֽڲ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8143787f-12eb-46ea-9bc3-c66d22d35285.jpg) + +Java I/O ʹװģʽʵ֡ InputStream ΪInputStream dzFileInputStream InputStream ࣬ھṩֽFilterInputStream ڳװߣװװΪṩĹܣ BufferedInputStream Ϊ FileInputStream ṩĹܡʵһл湦ֽܵʱֻҪ FileInputStream һ BufferedInputStream 󼴿ɡ + +```java +BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); +``` + +DataInputStream װṩ˶ԸͽIJ intdouble Ȼ͡ + +ļеݵֽ + +```java +byte[] buf = new byte[20*1024]; +int bytes = 0; +// ȡ buf.length ֽڣصʵʶȡĸ -1 ʱʾ eofļβ +while((bytes = in.read(buf, 0 , buf.length)) != -1) { + // ... +} +``` + +# ַ + +Ǵ̻紫䣬СĴ洢Ԫֽڣַ I/O ĶֽڶַڳвַͨʽҪṩַвķ + +InputStreamReader ʵִıļַֽOutputStreamWriter ʵַΪıļֽǶ̳ Reader Writer + +ǰַתΪֽڣǰֽϳַ + +```java +byte[] bytes = str.getBytes(encoding); // +String str = new String(bytes, encoding) // +``` + +GBK Уռ 2 ֽڣӢռ 1 ֽڣUTF-8 Уռ 3 ֽڣӢռ 1 ֽڣJava ʹ˫ֽڱ UTF-16beĺӢĶռ 2 ֽڡ + +ͽʹòͬı뷽ʽôͳ롣 + +# + +лǽһתֽУ洢ʹ䡣 + +лObjectOutputStream.writeObject() + +лObjectInputStream.readObject() + +лҪʵ Serializable ӿڣֻһ׼ûκηҪʵ֡ + +transient ؼֿʹһЩԲᱻл + +**ArrayList лͷлʵ**ArrayList д洢ݵ transient εģΪǶ̬չģеĿռ䶼ʹã˾ͲҪеݶлͨдлͷлʹÿֻлݵDzݡ + +``` +private transient Object[] elementData; +``` + +# + +Java е֧֣ + +1. InetAddressڱʾϵӲԴ IP ַ +2. URLͳһԴλͨ URL ֱӶȡдϵݣ +3. Socketsʹ TCP Эʵͨţ +4. Datagramʹ UDP Эʵͨš + +## 1. InetAddress + +ûйй캯ֻ̬ͨʵ InetAddress.getByName(String host)InetAddress.getByAddress(byte[] addr) + +## 2. URL + +ֱӴ URL жȡֽ + +```java +URL url = new URL("http://www.baidu.com"); +InputStream is = url.openStream(); // ֽ +InputStreamReader isr = new InputStreamReader(is, "utf-8"); // ַ +BufferedReader br = new BufferedReader(isr); +String line = br.readLine(); +while (line != null) { + System.out.println(line); + line = br.readLine(); +} +br.close(); +isr.close(); +is.close(); +``` + +## 3. Sockets + +Socket ͨģ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/fa4101d7-19ce-4a69-a84f-20bbe64320e5.jpg) + +- ServerSocket +- Socketͻ + +Ϳͻͨ InputStream OutputStream + +## 4. Datagram + +- DatagramPacketݰ +- DatagramSocketͨ + +# NIO + +NIO ʱ I/O ( ȡ ) תƻزϵͳ ҪԱȥƾͿԼٶȡ + +## 1. + +I/O NIO ҪݴʹķʽǰᵽģI/O ķʽݣ NIO Կķʽݡ + + I/O һһֽڽдݣһһֽڵݣһһֽڵݡΪʽݴdzףӼԱÿֻ𵥸ӴƵһ֣ҲԼ򵥵ġһǣ I/O ͨ൱ + +һ I/O ϵͳԿʽݣÿһһвһݿ顣鴦ݱȰҪöࡣ I/O ȱһЩ I/O еԺͼԡ + +I/O NIO Ѿܺõؼˣjava.io.\* Ѿ NIO Ϊʵˣ NIO һЩԡ磬 java.io.\* еһЩԿʽдݵķʹüʹڸϵͳУٶҲ졣 + +## 2. ͨ뻺 + +### 2.1 ͨ + +ͨ Channel Ƕԭ I/O еģ⣬ͨȡдݡ + +ͨIJ֮ͬڣֻһƶ(һ InputStream OutputStream ) ͨ˫ģڶдͬʱڶд + +ͨͣ + +- FileChannelļждݣ +- DatagramChannelͨ UDP дݣ +- SocketChannelͨ TCP дݣ +- ServerSocketChannelԼ½ TCP ӣÿһ½Ӷᴴһ SocketChannel + +### 2.2 + +͸һͨж󶼱ȷŵУͬأͨжȡκݶҪСҲ˵ֱӶͨждݣȾ + +ʵһ飬һ顣ṩ˶ݵĽṹʣһԸϵͳĶ/д̡ + +ͣ + +- ByteBuffer +- CharBuffer +- ShortBuffer +- IntBuffer +- LongBuffer +- FloatBuffer +- DoubleBuffer + + +## 3. ״̬ + +- capacity +- positionǰѾдֽ +- limitԶдֽ + +״̬ĸı̣ + +1\. ½һСΪ 8 ֽڵĻʱ position Ϊ 0 limit == capacity == 9capacity ı䣬ۻ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png) + +2\. ͨжȡ 3 ֽд뻺Уʱ position ƶΪ 3limit ֲ䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4628274c-25b6-4053-97cf-d1239b44c43d.png) + +3\. ڽд֮ͨǰҪȵ flip() limit Ϊǰ position position Ϊ 0 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png) + +4\. ӻȡ 4 ֽڵУʱ position Ϊ 4 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png) + +5\. Ҫ clear() ջʱ position limit Ϊλá + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png) + +## 4. дļʵ + +1\. ΪҪȡļ FileInputStream֮ͨ FileInputStream ȡ FileChannel + +```java +FileInputStream fin = new FileInputStream("readandshow.txt"); +FileChannel fic = fin.getChannel(); +``` + +2\. һΪ 1024 Buffer + +```java +ByteBuffer buffer = ByteBuffer.allocate(1024); +``` + +3\. ݴ FileChannel д뵽 Buffer УûݵĻ read() ᷵ -1 + +```java +int r = fcin.read(buffer); +if (r == -1) { + break; +} +``` + +4\. ΪҪдļ FileOutputStream֮ͨ FileOutputStream ȡ FileChannel + +```java +FileOutputStream fout = new FileOutputStream("writesomebytes.txt"); +FileChannel foc = fout.getChannel(); +``` + +5\. flip() лд + +```java +buffer.flip(); +``` + +6\. Buffer еݶȡ FileChannel + +```java +foc.write(buffer); +``` + +7\. clear() û + +```java +buffer.clear(); +``` + +## 5. + +Ӧע⣬FileChannel лģʽ׽ Channel ԡ + +### 5.1 ʽ I/O + +ʽ I/O ڵ InputStream.read() ʱһֱȵݵʱʱŻ᷵أڵ ServerSocket.accept() ʱҲһֱпͻӲŻ᷵أÿͻӹ󣬷˶һ߳ȥÿͻ˵ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/edc23f99-c46c-4200-b64e-07516828720d.jpg) + +### 5.2 ʽ I/O + +һרŵ߳е I/O ¼ַ + +¼ƣ¼ʱ򴥷ͬȥ¼ + +߳ͨţ֮߳ͨ wait()notify() ȷʽͨţ֤ÿлģν߳л + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7fcb2fb0-2cd9-4396-bc2d-282becf963c3.jpg) + +## 6. ׽ʵ + +### 6.1 ServerSocketChannel + +ÿһ˿ڶҪһ ServerSocketChannel ӡ + +```java +ServerSocketChannel ssc = ServerSocketChannel.open(); +ssc.configureBlocking(false); // Ϊ + +ServerSocket ss = ssc.socket(); +InetSocketAddress address = new InetSocketAddress(ports[i]); +ss.bind(address); // 󶨶˿ں +``` + +### 6.2 Selectors + +첽 I/O ͨ Selector עض I/O ¼Ȥ D ɶݵĵµ׽ӵȵȣڷ¼ʱϵͳ֪ᷢͨ + + Selectors ֮󣬾ͿԶԲͬͨ register() register() ĵһ Selectorڶ OP_ACCEPTָҪ accept ¼Ҳµӽʱ¼ + +SelectionKey ͨڴ Selector ϵעᡣij Selector ֪ͨij¼ʱͨṩӦڸ¼ SelectionKey еġSelectionKey ȡͨעᡣ + +```java +Selector selector = Selector.open(); +SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT); +``` + +### 6.3 ѭ + +ȣǵ Selector select() ֱһע¼һ߸¼ʱ select() ¼ + +ǵ Selector selectedKeys() ط¼ SelectionKey һ + +ͨ SelectionKeys δÿ SelectionKey ¼ÿһ SelectionKeyȷʲô I/O ¼Լ¼ӰЩ I/O + +```java +int num = selector.select(); + +Set selectedKeys = selector.selectedKeys(); +Iterator it = selectedKeys.iterator(); + +while (it.hasNext()) { + SelectionKey key = (SelectionKey)it.next(); + // ... deal with I/O event ... +} +``` + +### 6.4 + +ִеǽע ServerSocketChannelҽעǡա¼Ϊȷһ㣬Ƕ SelectionKey readyOps() 鷢ʲô͵¼ + +```java +if ((key.readyOps() & SelectionKey.OP_ACCEPT) + == SelectionKey.OP_ACCEPT) { + // Accept the new connection + // ... +} +``` + +Կ϶˵ readOps() Ǹ¼µӡ + +### 6.5 µ + +Ϊ֪׽һڵȴԿ԰ȫؽҲ˵õ accept() + +```java +ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); +SocketChannel sc = ssc.accept(); +``` + +һǽӵ SocketChannel ΪġڽӵĿΪ˶ȡ׽ֵݣǻ뽫 SocketChannel עᵽ Selectorϣʾ + +```java +sc.configureBlocking( false ); +SelectionKey newKey = sc.register( selector, SelectionKey.OP_READ ); +``` + +עʹ register() OP_READ SocketChannel ע ȡ ӡ + +### 6.6 ɾ SelectionKey + +ڴ SelectionKey ֮ǼԷѭˡDZȽ SelectionKey ѡļɾûɾļôȻһļ֣ᵼdzٴδǵõ remove() ɾ SelectionKey + +```java +it.remove(); +``` + +ǿԷѭܴһ׽д(һ I/O ¼)ˡ + +### 6.7 I/O + +һ׽ֵݵʱᴥһ I/O ¼ᵼѭе Selector.select()һ߶ I/O ¼һΣ SelectionKey Ϊ OP_READ ¼ʾ + +```java +} else if ((key.readyOps() & SelectionKey.OP_READ) + == SelectionKey.OP_READ) { + // Read the data + SocketChannel sc = (SocketChannel)key.channel(); + // ... +} +``` + + +# ο + +- Eckel B, ˶ , , . Java ˼ [M]. еҵ , 2002. +- [IBM: NIO ](https://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html) +- [ Java I/O Ĺ ](https://www.ibm.com/developerworks/cn/java/j-lo-javaio/index.html) +- [NIO 봫ͳ IO ](http://blog.csdn.net/shimiso/article/details/24990499) diff --git a/notes/Java 基础语法.md b/notes/Java 基础语法.md new file mode 100644 index 00000000..87fc192b --- /dev/null +++ b/notes/Java 基础语法.md @@ -0,0 +1,140 @@ + +* [](#) + * [ final](#-final) + * [ʼ˳](#ʼ˳) + * [Ȩ](#Ȩ) +* [](#) + * [Set](#set) + * [Queue](#queue) + * [Map](#map) +* [](#) +* [쳣](#쳣) +* [ο](#ο) + + +# + +## final + +**final ** + +ΪDZʱҲʱʼܱıij + +ڻͣfinal ʹֵ䣻öfinal ʹò䣬ҲͲ󣬵DZõĶǿ޸ĵġ + +**final ** + +ܱาǡ + +private ʽرָΪ finalжķͻеһ private ǩͬʱķǸǻ෽ˡ + +**final ** + +಻̳С + +## ʼ˳ + +static ľ̬ڴֻһݣֻһʵʱʼһΣݵijʼ + +```java +public static String staticField = "̬"; +``` + +static static һһʵʱһΣĸȡڴе˳ + +```java +static { + System.out.println("̬ʼ"); +} +``` + +ͨݺͨijʼھ̬ݺ;̬ʼ֮ + +```java +public String field = ""; +``` + +```java +{ + System.out.println("ʼ"); +} +``` + +ǹ캯еݽгʼ + +```java +public InitialOrderTest() +{ + System.out.println(""); +} +``` + +ڼ̳е£ʼ˳Ϊ + +1. ̬ࣨݡ̬飩 +2. ̬ࣨݡ̬飩 +3. ࣨݡ飩 +4. ࣨ +5. ࣨݡ飩 +6. ࣨ + +## Ȩ + +Java Ȩηprivateprotected Լ publicӷηʾɼ + +ԶеijԱֶԼϷηԱɼʾóԱĶʵóԱɼʾഴ󣬿԰൱еһԱȻʾһ࣬ͺˡ + +protected γԱʾڼ̳ϵгԱɼηû壬Ϊûм̳ϵ + +# + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/114c49a6-72e3-4264-ae07-c564127094ac.png) + +Ҫ Collection Map ֣Collection ְ ListSet Լ Queue + +## Set + +- HashSetʹ Hash ʵֿ֣֧ٲңʧȥԣ + +- TreeSetʹʵ֣򣬵DzЧʲ HashSet + +- LinkedListHashSet HashSet IJЧʣڲʹάԪصIJ˳˾ԡ + +## Queue + +ֻʵ֣LinkedList PriorityQueue LinkedList ֧˫С + +## Map + +- HashMapʹ Hash ʵ + +- LinkedHashMap˳Ϊ˳ʹãLRU˳ + +- TreeMapںʵ + +- ConcurrentHashMap̰߳ȫ Map漰ͬ + +# + +ÿ඼һ **Class** 󣬰йصϢһʱһͬ .class ļļݱ Class + +൱ Class ļءڵһʹʱŶ̬ص JVM Уʹ Class.forName('com.mysql.jdbc.Driver.class') ַʽļأ÷᷵һ Class + +ṩʱϢʱżؽڱʱڸ .class ҲԼؽ + +Class java.lang.reflect һԷṩ֧֣java.lang.reflect **Field****Method** Լ **Constructor** ࡣʹ get() set() ȡ޸ Field ֶΣʹ invoke() Method ķ Constructor µĶ + +IDE ʹ÷ƻȡϢʹһĶʱֶܹΡ͹캯Ϣгûѡ + +# 쳣 + +Throwable ʾκοΪ쳣׳࣬Ϊ֣**Error** **Exception** Error ʾʱϵͳ + +Exception Ϊ֣**ܼ쳣** **ܼ쳣**ܼ쳣Ҫ try...catch... 䲶񲢽дҿԴ쳣лָܼ쳣dzʱ 0 Arithmetic Exceptionʱ޷ָ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/48f8f98e-8dfd-450d-8b5b-df4688f0d377.jpg) + +# ο + +- Eckel B, ˶ , , . Java ˼ [M]. еҵ , 2002. +- [Java ʼ˳ ](https://segmentfault.com/a/1190000004527951) diff --git a/Leetocde题解.md b/notes/Leetcode 题解.md similarity index 65% rename from Leetocde题解.md rename to notes/Leetcode 题解.md index 203e2e8f..0727747e 100644 --- a/Leetocde题解.md +++ b/notes/Leetcode 题解.md @@ -1,69 +1,67 @@ -* [算法思想](#算法思想) - * [二分查找](#二分查找) - * [贪心思想](#贪心思想) - * [双指针](#双指针) - * [排序](#排序) - * [快速选择](#快速选择) - * [堆排序](#堆排序) - * [桶排序](#桶排序) - * [搜索](#搜索) +* [㷨˼](#㷨˼) + * [ֲ](#ֲ) + * [̰˼](#̰˼) + * [˫ָ](#˫ָ) + * [](#) + * [ѡ](#ѡ) + * [](#) + * [Ͱ](#Ͱ) + * [](#) * [BFS](#bfs) * [DFS](#dfs) * [Backtracking](#backtracking) - * [分治](#分治) - * [递归](#递归) - * [动态规划](#动态规划) - * [分割整数](#分割整数) - * [矩阵路径](#矩阵路径) - * [斐波那契数列](#斐波那契数列) - * [最长递增子序列](#最长递增子序列) - * [最长公共子系列](#最长公共子系列) - * [0-1 背包](#0-1-背包) - * [数组区间](#数组区间) - * [字符串编辑](#字符串编辑) - * [其它问题](#其它问题) - * [数学](#数学) - * [素数](#素数) - * [最大公约数](#最大公约数) - * [进制转换](#进制转换) - * [阶乘](#阶乘) - * [字符串加法减法](#字符串加法减法) - * [相遇问题](#相遇问题) - * [多数投票问题](#多数投票问题) - * [其它](#其它) -* [数据结构相关](#数据结构相关) - * [栈和队列](#栈和队列) - * [哈希表](#哈希表) - * [字符串](#字符串) - * [数组与矩阵](#数组与矩阵) - * [有序矩阵](#有序矩阵) - * [链表](#链表) - * [树](#树) - * [递归](#递归) - * [层次遍历](#层次遍历) - * [前中后序遍历](#前中后序遍历) + * [](#) + * [ݹ](#ݹ) + * [̬滮](#̬滮) + * [ָ](#ָ) + * [·](#·) + * [쳲](#쳲) + * [](#) + * [ϵ](#ϵ) + * [0-1 ](#0-1-) + * [](#) + * [ַ༭](#ַ༭) + * [](#) + * [ѧ](#ѧ) + * [](#) + * [Լ](#Լ) + * [ת](#ת) + * [׳](#׳) + * [ַӷ](#ַӷ) + * [](#) + * [ͶƱ](#ͶƱ) + * [](#) +* [ݽṹ](#ݽṹ) + * [ջͶ](#ջͶ) + * [ϣ](#ϣ) + * [ַ](#ַ) + * [](#) + * [](#) + * [](#) + * [](#) + * [ݹ](#ݹ) + * [α](#α) + * [ǰк](#ǰк) * [BST](#bst) * [Trie](#trie) - * [图](#图) - * [位运算](#位运算) -* [其它](#其它) - * [注意细节](#注意细节) -* [参考资料](#参考资料) + * [ͼ](#ͼ) + * [λ](#λ) +* [ο](#ο) -# 算法思想 +# 㷨˼ -## 二分查找 +## ֲ -二分查找思想简单,但是在实现时有一些需要注意的细节: +ֲ˼򵥣ʵʱһЩҪעϸڣ -1. 在计算 mid 时不能使用 mid = (l + h) / 2 这种方式,因为 l + h 可能会导致加法溢出,应该使用 mid = l + (h - l) / 2 。 +1. ڼ mid ʱʹ mid = (l + h) / 2 ַʽΪ l + h ܻᵼ¼ӷӦʹ mid = l + (h - l) / 2 -2. 对 h 的赋值和循环条件有关,当循环条件为 l <= h 时,h = mid - 1;当循环条件为 l < h 时,h = mid。 -解释如下:在循环条件为 l <= h 时,如果 h = mid,会出现循环无法退出的情况,例如 l = 1,h = 1,此时 mid 也等于 1,如果此时继续执行 h = mid ,那么就会无限循环;在循环条件为 l < h ,如果 h = mid - 1,会错误跳过查找的数,例如对于数组 1,2,3 ,要查找 1 ,最开始 l = 0,h = 2,mid = 1,判断 key < arr[mid] 执行 h = mid - 1 = 0,此时循环退出,直接把查找的数跳过了。 +2. h ĸֵѭйأѭΪ l <= h ʱh = mid - 1ѭΪ l < h ʱh = mid +£ѭΪ l <= h ʱ h = midѭ޷˳ l = 1h = 1ʱ mid Ҳ 1ʱִ h = mid ôͻѭѭΪ l < h h = mid - 1ҵ 1,2,3 Ҫ 1 ʼ l = 0h = 2mid = 1ж key < arr[mid] ִ h = mid - 1 = 0ʱѭ˳ֱӰѲҵˡ -3. l 的赋值一般都为 l = mid + 1。 +3. l ĸֵһ㶼Ϊ l = mid + 1 ```java public int search(int key, int[] arr) { @@ -78,11 +76,11 @@ public int search(int key, int[] arr) { } ``` -**求开方** +**󿪷** [Leetcode : 69. Sqrt(x) (Easy)](https://leetcode.com/problems/sqrtx/description/) -一个数 x 的开方 sqrt 一定在 0 \~ x 之间,并且满足 sqrt == x / sqrt 。可以利用二分查找在 0 \~ x 之间查找 sqrt。 +һ x Ŀ sqrt һ 0 \~ x ֮䣬 sqrt == x / sqrt öֲ 0 \~ x ֮ sqrt ```java public int mySqrt(int x) { @@ -99,7 +97,7 @@ public int mySqrt(int x) { } ``` -**摆硬币** +**Ӳ** [Leetcode : 441. Arranging Coins (Easy)](https://leetcode.com/problems/arranging-coins/description/) @@ -107,17 +105,17 @@ public int mySqrt(int x) { n = 8 The coins can form the following rows: -¤ -¤ ¤ -¤ ¤ ¤ -¤ ¤ + + + + Because the 4th row is incomplete, we return 3. ``` -题目描述:第 i 行摆 i 个,统计能够排列的行数。 +Ŀ i а i ͳܹе -返回 h 而不是 l,因为摆的硬币最后一行不能算进去。 + h lΪڵӲһвȥ ```java public int arrangeCoins(int n) { @@ -133,7 +131,7 @@ public int arrangeCoins(int n) { } ``` -可以不用二分查找,更直观的解法如下: +Բöֲңֱ۵Ľⷨ£ ```java public int arrangeCoins(int n) { @@ -146,18 +144,18 @@ public int arrangeCoins(int n) { } ``` -**有序数组的 Single Element** +** Single Element** [Leetcode : 540. Single Element in a Sorted Array (Medium)](https://leetcode.com/problems/single-element-in-a-sorted-array/description/) -题目描述:一个有序数组只有一个数不出现两次,找出这个数。 +ĿһֻһΣҳ ```java public int singleNonDuplicate(int[] nums) { int l = 0, h = nums.length - 1; while(l < h) { int m = l + (h - l) / 2; - if(m % 2 == 1) m--; // 保证 l/h/m 都在偶数位,使得查找区间大小一直都是 奇数 + if(m % 2 == 1) m--; // ֤ l/h/m żλʹòСһֱ if(nums[m] == nums[m + 1]) l = m + 2; else h = m; } @@ -165,19 +163,19 @@ public int singleNonDuplicate(int[] nums) { } ``` -## 贪心思想 +## ̰˼ -贪心思想保证每次操作都是局部最优的,并且最后得到的结果是全局最优的。 +̰˼뱣֤ÿβǾֲŵģõĽȫŵġ -**分配饼干** +**** [Leetcode : 455. Assign Cookies (Easy)](https://leetcode.com/problems/assign-cookies/description/) -题目描述:每个孩子都有一个满足度,每个饼干都有一个大小,只有饼干的大小大于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。 +ĿÿӶһȣÿɶһСֻбɵĴСһӵȣúӲŻ㡣Իĺ -因为最小的孩子最容易得到满足,因此先满足最小孩子。给一个孩子的饼干应当尽量小又能满足该孩子,这样大饼干就能拿来给满足度比较大的孩子。 +ΪСĺ׵õ㣬СӡһӵıӦСúӣɾȱȽϴĺӡ -证明:假设在某次选择中,贪心策略选择给第 i 个孩子分配第 m 个饼干,并且第 i 个孩子满足度最小,第 m 个饼干为可以满足第 i 个孩子的最小饼干,利用贪心策略最终可以满足 k 个孩子。假设最优策略在这次选择中给 i 个孩子分配第 n 个饼干,并且这个饼干大于第 m 个饼干,那么最优策略最终需要满足大于 k 个孩子。我们发现使用第 m 个饼干去替代第 n 个饼干完全不影响后续的结果,因此贪心策略就是最优策略,因此贪心策略是最优的。 +֤ijѡУ̰IJѡ i ӷ m ɣҵ i С m Ϊ i ӵСɣ̰IJտ k ӡŲѡи i ӷ n ɣɴڵ m ɣôŲҪ k ӡǷʹõ m ȥ n ȫӰĽ̰IJԾŲԣ̰IJŵġ ```java public int findContentChildren(int[] g, int[] s) { @@ -192,7 +190,7 @@ public int findContentChildren(int[] g, int[] s) { } ``` -**投飞镖刺气球** +**Ͷڴ** [Leetcode : 452. Minimum Number of Arrows to Burst Balloons (Medium)](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/description/) @@ -204,7 +202,7 @@ Output: 2 ``` -题目描述:气球在一个水平数轴上摆放,可以重叠,飞镖垂直射向坐标轴,使得路径上的气球都会刺破,求解最小的投飞镖次数。 +Ŀһˮƽϰڷţصڴֱᣬʹ·ϵ򶼻ƣСͶڴ ```java public int findMinArrowShots(int[][] points) { @@ -223,13 +221,13 @@ public int findMinArrowShots(int[][] points) { } ``` -**股票的最大收益** +**Ʊ** [Leetcode : 122. Best Time to Buy and Sell Stock II (Easy)](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/) -先买入股票,然后出售股票,从而获得差价带来的收益。 +ƱȻ۹ƱӶò۴档 -对于一个交易 [a, b, c, d],如果有 a <= b <= c <= d ,那么最大收益为 d - a = (d - c) + (c - b) + (b - a) 。当访问到一个 prices[i] 且 prices[i] - prices[i-1] ,那么就把 prices[i] - prices[i-1] 加到收益中,从而在局部最优的情况下也保证全局最优。 +һ [a, b, c, d] a <= b <= c <= d ôΪ d - a = (d - c) + (c - b) + (b - a) ʵһ prices[i] prices[i] - prices[i-1] ôͰ prices[i] - prices[i-1] ӵУӶھֲŵҲ֤ȫš ```java public int maxProfit(int[] prices) { @@ -241,7 +239,7 @@ public int maxProfit(int[] prices) { } ``` -**种植花朵** +**ֲ** [Leetcode : 605. Can Place Flowers (Easy)](https://leetcode.com/problems/can-place-flowers/description/) @@ -250,7 +248,7 @@ Input: flowerbed = [1,0,0,0,1], n = 1 Output: True ``` -题目描述:花朵之间至少需要一个单位的间隔。 +Ŀ֮Ҫһλļ ```java public boolean canPlaceFlowers(int[] flowerbed, int n) { @@ -268,15 +266,15 @@ public boolean canPlaceFlowers(int[] flowerbed, int n) { } ``` -**修改一个数成为非递减数组** +**޸һΪǵݼ** [Leetcode : 665. Non-decreasing Array (Easy)](https://leetcode.com/problems/non-decreasing-array/description/) -题目描述:判断一个数组能不能只修改一个数就成为非递减数组。 +Ŀжһֻܲ޸һͳΪǵݼ顣 -在 nums[i] < nums[i - 1] 的情况下,会优先考虑令 nums[i - 1] = nums[i],因为如果修改 nums[i] = nums[i - 1] 的话,那么 nums[i] 这个数会变大,那么就有可能比 nums[i + 1] 大,我们要尽量使 nums[i] 更小。 + nums[i] < nums[i - 1] £ȿ nums[i - 1] = nums[i]Ϊ޸ nums[i] = nums[i - 1] Ļô nums[i] ôпܱ nums[i + 1] Ҫʹ nums[i] С -但是在 nums[i] < nums[i - 2] 的情况下,只修改 nums[i - 1] 不能令数组成为非递减,只能通过修改 nums[i] = nums[i - 1] 才行。 + nums[i] < nums[i - 2] £ֻ޸ nums[i - 1] Ϊǵݼֻͨ޸ nums[i] = nums[i - 1] С ```java public boolean checkPossibility(int[] nums) { @@ -292,7 +290,7 @@ public boolean checkPossibility(int[] nums) { } ``` -**判断是否为子串** +**жǷΪӴ** [Leetcode : 392. Is Subsequence (Medium)](https://leetcode.com/problems/is-subsequence/description/) @@ -311,7 +309,7 @@ public boolean isSubsequence(String s, String t) { } ``` -**分隔字符串使同种字符出现在一起** +**ַָʹַͬһ** [Leetcode : 763. Partition Labels (Medium)](https://leetcode.com/problems/partition-labels/description/) @@ -335,7 +333,7 @@ public List partitionLabels(String S) { } ``` -**根据身高和序号重组队列** +**ߺ** ```html Input: @@ -345,9 +343,9 @@ Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] ``` -一个学生用两个分量 (h, k) 描述,h 表示身高,k 表示排在前面的有 k 个学生的身高比他高或者和他一样高。 +һѧ (h, k) h ʾߣk ʾǰ k ѧ߱߻ߺһߡ -先排序:身高降序、k 值升序,然后按排好序的顺序插入队列的第 k 个位置中。 +߽k ֵȻź˳еĵ k λС ```java public int[][] reconstructQueue(int[][] people) { @@ -376,17 +374,17 @@ public int[][] reconstructQueue(int[][] people) { ``` -## 双指针 +## ˫ָ -双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。 +˫ָҪڱ飬ָָͬԪأӶЭͬ -**从一个已经排序的数组中查找出两个数,使它们的和为 0** +**һѾвҳʹǵĺΪ 0** -[Leetcode :167. Two Sum II - Input array is sorted (Easy)](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/) +[Leetcode 167. Two Sum II - Input array is sorted (Easy)](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/) -使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。 +ʹ˫ָ룬һָָԪؽСֵһָָԪؽϴֵָСԪصָͷβָϴԪصָβͷ -如果两个指针指向元素的和 sum == target,那么得到要求的结果;如果 sum > target,移动较大的元素,使 sum 变小一些;如果 sum < target,移动较小的元素,使 sum 变大一些。 +ָָԪصĺ sum == targetôõҪĽ sum > targetƶϴԪأʹ sum СһЩ sum < targetƶСԪأʹ sum һЩ ```java public int[] twoSum(int[] numbers, int target) { @@ -401,21 +399,21 @@ public int[] twoSum(int[] numbers, int target) { } ``` -此问题可扩展成三个元素和为 0 的问题:[程序员代码面试指南 P351](#) +չԪغΪ 0 ⣺[Աָ P351](#) -**数组中累加和为给定值的最长子数组长度** +**ۼӺΪֵ鳤** -[程序员代码面试指南 P354/P355/P358](#) +[Աָ P354/P355/P358](#) -**在行和列都排好序的矩阵中查找元素** +**кжźľвԪ** -[程序员代码面试指南 P347](#) +[Աָ P347](#) -**反转字符串中的元音字符** +**תַеԪַ** [Leetcode : 345. Reverse Vowels of a String (Easy)](https://leetcode.com/problems/reverse-vowels-of-a-string/description/) -使用双指针,指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。 +ʹ˫ָ룬ָתԪַһָͷβһָβͷ ```java private HashSet vowels = new HashSet<>(Arrays.asList('a','e','i','o','u','A','E','I','O','U')); @@ -444,11 +442,11 @@ public String reverseVowels(String s) { } ``` -**两数平方和** +**ƽ** [Leetcode : 633. Sum of Square Numbers (Easy)](https://leetcode.com/problems/sum-of-square-numbers/description/) -判断一个数是否为两个数的平方和,例如 5 = 12 + 22。 +жһǷΪƽͣ 5 = 12 + 22 ```java public boolean judgeSquareSum(int c) { @@ -463,7 +461,7 @@ public boolean judgeSquareSum(int c) { } ``` -**字符串回文数(可删除一个字符)** +**ַɾһַ** [Leetcode : 680. Valid Palindrome II (Easy)](https://leetcode.com/problems/valid-palindrome-ii/description/) @@ -491,15 +489,15 @@ private boolean isPalindrome(String s, int l, int r){ } ``` -**归并两个有序数组** +**鲢** [Leetcode : 88. Merge Sorted Array (Easy)](https://leetcode.com/problems/merge-sorted-array/description/) -把归并结果存到第一个数组上。 +ѹ鲢浽һϡ ```java public void merge(int[] nums1, int m, int[] nums2, int n) { - int i = m - 1, j = n - 1; // 需要从尾开始遍历,否则在 nums1 上归并得到的值会覆盖还未进行归并比较的值 + int i = m - 1, j = n - 1; // Ҫβʼ nums1 Ϲ鲢õֵḲǻδй鲢Ƚϵֵ int idx = m + n - 1; while(i >= 0 || j >= 0){ if(i < 0) nums1[idx] = nums2[j--]; @@ -511,11 +509,11 @@ public void merge(int[] nums1, int m, int[] nums2, int n) { } ``` -**判断链表是否存在环** +**жǷڻ** [Leetcode : 141. Linked List Cycle (Easy)](https://leetcode.com/problems/linked-list-cycle/description/) -使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定会相遇。 +ʹ˫ָ룬һָÿƶһڵ㣬һָÿƶڵ㣬ڻôָһ ```java public boolean hasCycle(ListNode head) { @@ -531,7 +529,7 @@ public boolean hasCycle(ListNode head) { } ``` -**最长子序列** +**** [Leetcode : 524. Longest Word in Dictionary through Deleting (Medium)](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/description/) @@ -561,40 +559,40 @@ public String findLongestWord(String s, List d) { } ``` -## 排序 +## -### 快速选择 +### ѡ -一般用于求解 **Kth Element** 问题,可以在 O(n) 时间复杂度,O(1) 空间复杂度完成求解工作。 +һ **Kth Element** ⣬ O(n) ʱ临ӶȣO(1) ռ临Ӷ⹤ -与快速排序一样,快速选择一般需要先打乱数组,否则最坏情况下时间复杂度为 O(n2)。 +һѡһҪȴ飬ʱ临ӶΪ O(n2) -### 堆排序 +### -堆排序用于求解 **TopK Elements** 问题,通过维护一个大小为 K 的堆,堆中的元素就是 TopK Elements。当然它也可以用于求解 Kth Element 问题,因为最后出堆的那个元素就是 Kth Element。快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题,只是有可能需要间接求解。 + **TopK Elements** ⣬ͨάһСΪ K ĶѣеԪؾ TopK ElementsȻҲ Kth Element ⣬ΪѵǸԪؾ Kth ElementѡҲ TopK Elements ⣬Ϊҵ Kth Element ֮ٱһ飬Сڵ Kth Element Ԫض TopK ElementsԿѡͶ򶼿 Kth Element TopK Elements ⣬ֻпҪ⡣ **Kth Element** [Leetocde : 215. Kth Largest Element in an Array (Medium)](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) -解题参考:[Solution explained](https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60294/Solution-explained) +ο[Solution explained](https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60294/Solution-explained) -- 时间复杂度 O(nlgn),空间复杂度 O(1) 解法:排序 -- 时间复杂度 O(nlgk),空间复杂度 O(k) 解法:堆排序 -- 时间复杂度 O(n),空间复杂度 O(1) 解法:QuickSelect +- ʱ临Ӷ O(nlgn)ռ临Ӷ O(1) ⷨ +- ʱ临Ӷ O(nlgk)ռ临Ӷ O(k) ⷨ +- ʱ临Ӷ O(n)ռ临Ӷ O(1) ⷨQuickSelect **ToK Elements** -[程序员代码面试指南 P336](#) +[Աָ P336](#) -### 桶排序 +### Ͱ -**找出出现频率最多的 k 个数** +**ҳƵ k ** [Leetcode : 347. Top K Frequent Elements (Medium)](https://leetcode.com/problems/top-k-frequent-elements/description/) -桶排序 +Ͱ ```java public List topKFrequent(int[] nums, int k) { @@ -621,29 +619,29 @@ public List topKFrequent(int[] nums, int k) { } ``` -## 搜索 +## -深度优先搜索和广度优先搜索广泛运用于树和图中,但是它们的应用远远不止如此。 +͹㷺ͼУǵӦԶԶֹˡ ### BFS -![](https://github.com/00000H/notes/blob/master/pics/4ff355cf-9a7f-4468-af43-e5b02038facc.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4ff355cf-9a7f-4468-af43-e5b02038facc.jpg) -广度优先搜索的搜索过程有点像一层一层地进行遍历:从节点 0 出发,遍历到 6、2、1 和 5 这四个新节点。 +еһһؽбӽڵ 0 621 5 ĸ½ڵ㡣 -继续从 6 开始遍历,得到节点 4 ;从 2 开始遍历,没有下一个节点;从 1 开始遍历,没有下一个节点;从 5 开始遍历,得到 3 和 4 节点。这一轮总共得到两个新节点:4 和 3 。 + 6 ʼõڵ 4 2 ʼûһڵ㣻 1 ʼûһڵ㣻 5 ʼõ 3 4 ڵ㡣һܹõ½ڵ㣺4 3 -反复从新节点出发进行上述的遍历操作。 +½ڵı -可以看到,每一轮遍历的节点都与根节点路径长度相同。设 di 表示第 i 个节点与根节点的路径长度,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di<=dj。利用这个结论,可以求解最短路径 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径,如果继续遍历,之后再遍历到目的节点,所经过的路径就不是最短路径。 +ԿÿһֱĽڵ㶼ڵ·ͬ di ʾ i ڵڵ·ȣƵһۣȱĽڵ i Ľڵ j di<=djۣ· **Ž** ⣺һαĿĽڵ㣬·Ϊ·֮ٱĿĽڵ㣬·Ͳ· -在程序实现 BFS 时需要考虑以下问题: +ڳʵ BFS ʱҪ⣺ -- 队列:用来存储每一轮遍历的节点 -- 标记:对于遍历过得节点,应该将它标记,防止重复遍历; +- У洢ÿһֱĽڵ +- ǣڱýڵ㣬Ӧýǣֹظ -**计算在网格中从原点到特定点的最短路径长度** +**дԭ㵽ض·** ```html [[1,1,0,1], @@ -685,19 +683,19 @@ private class Position { ### DFS -![](https://github.com/00000H/notes/blob/master/pics/f7f7e3e5-7dd4-4173-9999-576b9e2ac0a2.png) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f7f7e3e5-7dd4-4173-9999-576b9e2ac0a2.png) -广度优先搜索一层一层遍历,每一层遍历到的所有新节点,要用队列先存储起来以备下一层遍历的时候再遍历;而深度优先搜索在遍历到一个新节点时立马对新节点进行遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到根节点 0 的情况是,继续对根节点 0 进行遍历,得到新节点 2,然后继续以上步骤。 +һһÿһ½ڵ㣬Ҫöȴ洢Աһʱٱڱһ½ڵʱ½ڵбӽڵ 0 ʼõ½ڵ 6 ʱ½ڵ 6 бõ½ڵ 4˷ַʽ½ڵ㣬ֱû½ڵˣʱءصڵ 0 ǣԸڵ 0 бõ½ڵ 2Ȼϲ衣 -从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种 **可达性** 问题。 +һڵʹ DFS һͼбʱܹĽڵ㶼ǴӳʼڵɴģDFS **ɴ** ⡣ -在程序实现 DFS 时需要考虑以下问题: +ڳʵ DFS ʱҪ⣺ -- 栈:用栈来保存当前节点信息,当遍历新节点返回时能够继续遍历当前节点。也可以使用递归栈。 -- 标记:和 BFS 一样同样需要对已经遍历过得节点进行标记。 +- ջջ浱ǰڵϢ½ڵ㷵ʱܹǰڵ㡣Ҳʹõݹջ +- ǣ BFS һͬҪѾýڵбǡ -**查找最大的连通面积** +**ͨ** [Leetcode : 695. Max Area of Island (Easy)](https://leetcode.com/problems/max-area-of-island/description/) @@ -733,7 +731,7 @@ private int dfs(int[][] grid, int i, int j){ } ``` -**图的连通分量** +**ͼͨ** [Leetcode : 547. Friend Circles (Medium)](https://leetcode.com/problems/friend-circles/description/) @@ -773,7 +771,7 @@ private void dfs(int[][] M, int i, boolean[] hasFind) { } ``` -**矩阵中的连通区域数量** +**еͨ** [Leetcode : 200. Number of Islands (Medium)](https://leetcode.com/problems/number-of-islands/description/) @@ -814,7 +812,7 @@ private void dfs(char[][] grid, int i, int j) { } ``` -**输出二叉树中所有从根到叶子的路径** +**дӸҶӵ·** [Leetcode : 257. Binary Tree Paths (Easy)](https://leetcode.com/problems/binary-tree-paths/description/) @@ -849,7 +847,7 @@ private void dfs(TreeNode root, String prefix, List ret){ } ``` -**填充封闭区域** +**** [Leetcode : 130. Surrounded Regions (Medium)](https://leetcode.com/problems/surrounded-regions/description/) @@ -867,9 +865,9 @@ X X X X X O X X ``` -题目描述:使得被 'X' 的 'O' 转换为 'X'。 +Ŀʹñ 'X' 'O' תΪ 'X' -可以选择先填充最外侧,剩下的就是里侧了。 +ѡ࣬ʣµľˡ ```java private int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; @@ -904,7 +902,7 @@ private void dfs(char[][] board, int r, int c) { } ``` -**从两个方向都能到达的区域** +**ܵ** [Leetcode : 417. Pacific Atlantic Water Flow (Medium)](https://leetcode.com/problems/pacific-atlantic-water-flow/description/) @@ -923,7 +921,7 @@ Return: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix). ``` -题目描述:左边和上边是太平洋,右边和下边是大西洋,内部的数字代表海拔,海拔高的地方的水能够流到低的地方,求解水能够流到太平洋和大西洋的所有地方。 +Ŀߺϱ̫ƽұߺ±ǴڲִΣθߵĵطˮܹ͵ĵطˮܹ̫ƽʹеط ```java private int m, n; @@ -969,23 +967,23 @@ private void dfs(int r, int c, boolean[][] canReach) { } ``` -**N 皇后** +**N ʺ** [Leetcode : 51. N-Queens (Hard)](https://leetcode.com/problems/n-queens/description/) -![](https://github.com/00000H/notes/blob/master/pics/1f080e53-4758-406c-bb5f-dbedf89b63ce.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1f080e53-4758-406c-bb5f-dbedf89b63ce.jpg) -题目描述:在 n\*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,要求解所有的 n 皇后解。 +Ŀ n\*n ľаڷ n ʺ󣬲ÿʺͬһУͬһУͬһԽϣҪе n ʺ⡣ -一行一行地摆放,在确定一行中的那个皇后应该摆在哪一列时,需要用三个标记数组来确定某一列是否合法,这三个标记数组分别为:列标记数组、45 度对角线标记数组和 135 度对角线标记数组。 +һһеذڷţȷһеǸʺӦðһʱҪȷijһǷϷֱΪб顢45 ȶԽ߱ 135 ȶԽ߱顣 -45 度对角线标记数组的维度为 2\*n - 1,通过下图可以明确 (r,c) 的位置所在的数组下标为 r + c。 +45 ȶԽ߱άΪ 2\*n - 1ͨͼȷ (r,c) λڵ±Ϊ r + c -![](https://github.com/00000H/notes/blob/master/pics/85583359-1b45-45f2-9811-4f7bb9a64db7.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/85583359-1b45-45f2-9811-4f7bb9a64db7.jpg) -135 度对角线标记数组的维度也是 2\*n - 1,(r,c) 的位置所在的数组下标为 n - 1 - (r - c)。 +135 ȶԽ߱άҲ 2\*n - 1(r,c) λڵ±Ϊ n - 1 - (r - c) -![](https://github.com/00000H/notes/blob/master/pics/9e80f75a-b12b-4344-80c8-1f9ccc2d5246.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9e80f75a-b12b-4344-80c8-1f9ccc2d5246.jpg) ```java private List> ret; @@ -1034,15 +1032,15 @@ private void backstracking(int row) { ### Backtracking -回溯是 DFS 的一种,它不是用在遍历图的节点上,而是用于求解 **排列组合** 问题,例如有 { 'a','b','c' } 三个字符,求解所有由这三个字符排列得到的字符串。 + DFS һ֣ڱͼĽڵϣ **** ⣬ { 'a','b','c' } ַַеõַ -在程序实现时,回溯需要注意对元素进行标记的问题。使用递归实现的回溯,在访问一个新元素进入新的递归调用,此时需要将新元素标记为已经访问,这样才能在继续递归调用时不用重复访问该元素;但是在递归返回时,需要将该元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,而在不同的递归链是可以访问已经访问过但是不在当前递归链中的元素。 +ڳʵʱҪעԪؽбǵ⡣ʹõݹʵֵĻݣڷһԪؽµĵݹãʱҪԪرΪѾʣڼݹʱظʸԪأڵݹ鷵ʱҪԪرΪδʣΪֻҪ֤һݹвͬʱһԪأڲͬĵݹǿԷѾʹDzڵǰݹеԪء -**数字键盘组合** +**ּ** [Leetcode : 17. Letter Combinations of a Phone Number (Medium)](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) -![](https://github.com/00000H/notes/blob/master/pics/a3f34241-bb80-4879-8ec9-dff2d81b514e.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a3f34241-bb80-4879-8ec9-dff2d81b514e.jpg) ```html Input:Digit string "23" @@ -1072,7 +1070,7 @@ private void combination(String prefix, String digits, int offset, List } ``` -**在矩阵中寻找字符串** +**ھѰַ** [Leetcode : 79. Word Search (Medium)](https://leetcode.com/problems/word-search/description/) @@ -1127,7 +1125,7 @@ private boolean dfs(char[][] board, String word, int start, int r, int c) { } ``` -**IP 地址划分** +**IP ַ** [Leetcode : 93. Restore IP Addresses(Medium)](https://leetcode.com/problems/restore-ip-addresses/description/) @@ -1162,11 +1160,11 @@ private void doRestore(int k, String path, String s) { } ``` -**排列** +**** [Leetcode : 46. Permutations (Medium)](https://leetcode.com/problems/permutations/description/) -题目描述:找出一组数的所有排列。 +ĿҳһС ```java public List> permute(int[] nums) { @@ -1194,7 +1192,7 @@ private void backtracking(List permuteList, boolean[] visited, int[] nu } ``` -**不能重复的排列** +**ظ** [Leetcode : 47. Permutations II (Medium)](https://leetcode.com/problems/permutations-ii/description/) @@ -1203,7 +1201,7 @@ private void backtracking(List permuteList, boolean[] visited, int[] nu [[1,1,2], [1,2,1], [2,1,1]] ``` -在实现上,和 Permutations 不同的是要先排序,然后在添加一个元素时,判断这个元素是否等于前一个元素,如果等于,并且前一个元素还未访问,那么就跳过这个元素。 +ʵϣ Permutations ͬҪȻһԪʱжԪǷǰһԪأڣǰһԪػδʣôԪء ```java public List> permuteUnique(int[] nums) { @@ -1233,11 +1231,11 @@ private void backtracking(List permuteList, boolean[] visited, int[] nu } ``` -**组合** +**** [Leetcode : 77. Combinations (Medium)](https://leetcode.com/problems/combinations/description/) -题目描述:找出从 1 \~ n 中取出 k 个元素的所有可能的组合。 +Ŀҳ 1 \~ n ȡ k Ԫصпܵϡ ```java public List> combine(int n, int k) { @@ -1249,20 +1247,20 @@ public List> combine(int n, int k) { private void backtracking(int start, int n, int k, List combineList, List> ret){ if(k == 0){ - ret.add(new ArrayList(combineList)); // 这里要重新构造一个 List + ret.add(new ArrayList(combineList)); // Ҫ¹һ List return; } - for(int i = start; i <= n - k + 1; i++){ // 剪枝 + for(int i = start; i <= n - k + 1; i++){ // ֦ - combineList.add(i); // 把 i 标记为已访问 + combineList.add(i); // i Ϊѷ backtracking(i + 1, n, k - 1, combineList, ret); - combineList.remove(combineList.size() - 1); // 把 i 标记为未访问 + combineList.remove(combineList.size() - 1); // i Ϊδ } } ``` -**组合求和** +**** [Leetcode : 39. Combination Sum (Medium)](https://leetcode.com/problems/combination-sum/description/) @@ -1297,7 +1295,7 @@ A solution set is: } ``` -**不能重复的组合求和** +**ظ** [Leetcode : 40. Combination Sum II (Medium)](https://leetcode.com/problems/combination-sum-ii/description/) @@ -1341,11 +1339,11 @@ private void doCombination(int[] candidates, int target, int start, List> ret; @@ -1368,13 +1366,13 @@ private void backtracking(int startIdx, int size, int[] nums) { for (int i = startIdx; i < nums.length; i++) { subsetList.add(nums[i]); - backtracking(i + 1, size, nums); // startIdx 设为下一个元素,使 subset 中的元素都递增排序 + backtracking(i + 1, size, nums); // startIdx ΪһԪأʹ subset еԪض subsetList.remove(subsetList.size() - 1); } } ``` -**不能重复的子集** +**ظӼ** [Leetcode : 90. Subsets II (Medium)](https://leetcode.com/problems/subsets-ii/description/) @@ -1425,7 +1423,7 @@ private void backtracking(int startIdx, int size, int[] nums) { } ``` -**分割字符串使得每部分都是回文数** +**ַָʹÿֶǻ** [Leetcode : 131. Palindrome Partitioning (Medium)](https://leetcode.com/problems/palindrome-partitioning/description/) @@ -1460,11 +1458,11 @@ private boolean isPalindrome(String s, int begin, int end) { } ``` -**数独** +**** [Leetcode : 37. Sudoku Solver (Hard)](https://leetcode.com/problems/sudoku-solver/description/) -![](https://github.com/00000H/notes/blob/master/pics/1ca52246-c443-48ae-b1f8-1cafc09ec75c.png) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1ca52246-c443-48ae-b1f8-1cafc09ec75c.png) ```java private boolean[][] rowsUsed = new boolean[9][10]; @@ -1516,9 +1514,9 @@ private int cubeNum(int i, int j) { } ``` -## 分治 +## -**给表达式加括号** +**ʽ** [Leetcode : 241. Different Ways to Add Parentheses (Medium)](https://leetcode.com/problems/different-ways-to-add-parentheses/description/) @@ -1556,21 +1554,21 @@ public List diffWaysToCompute(String input) { } ``` -## 递归 +## ݹ -将原始问题分解成较小的问题来求解。 +ԭʼֽɽС⡣ -## 动态规划 +## ̬滮 -将原问题拆解成多个子问题,在求解子问题的时候保存子问题的解,使得子问题只求解一次。 +ԭɶ⣬ʱ򱣴Ľ⣬ʹֻһΡ -### 分割整数 +### ָ -**分割整数的最大乘积** +**ָ˻** [Leetcode : 343. Integer Break (Medim)](https://leetcode.com/problems/integer-break/description/) -题目描述:For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4). +ĿFor example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4). ```java public int integerBreak(int n) { @@ -1585,15 +1583,15 @@ public int integerBreak(int n) { } ``` -**按平方数来分割整数** +**ƽָ** [Leetcode : 279. Perfect Squares(Medium)](https://leetcode.com/problems/perfect-squares/description/) -题目描述:For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9. +ĿFor example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9. ```java public int numSquares(int n) { - List squares = new ArrayList<>(); // 存储小于 n 的平方数 + List squares = new ArrayList<>(); // 洢С n ƽ int diff = 3; while(square <= n) { squares.add(square); @@ -1613,11 +1611,11 @@ public int numSquares(int n) { } ``` -**分割整数构成字母字符串** +**ָĸַ** [Leetcode : 91. Decode Ways (Medium)](https://leetcode.com/problems/decode-ways/description/) -题目描述:Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). +ĿGiven encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). ```java public int numDecodings(String s) { @@ -1637,13 +1635,13 @@ public int numDecodings(String s) { } ``` -### 矩阵路径 +### · -**矩阵的总路径数** +**·** [Leetcode : 62. Unique Paths (Medium)](https://leetcode.com/problems/unique-paths/description/) -题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向左和向下移动。 +ĿͳƴӾϽǵ½ǵ·ÿֻƶ ```java public int uniquePaths(int m, int n) { @@ -1658,11 +1656,11 @@ public int uniquePaths(int m, int n) { } ``` -**矩阵的最小路径和** +**С·** [Leetcode : 64. Minimum Path Sum (Medium)](https://leetcode.com/problems/minimum-path-sum/description/) -题目描述:求从矩阵的左上角到右下角的最小路径和,每次只能向左和向下移动。 +ĿӾϽǵ½ǵС·ͣÿֻƶ ```java public int minPathSum(int[][] grid) { @@ -1680,29 +1678,29 @@ public int minPathSum(int[][] grid) { } ``` -### 斐波那契数列 +### 쳲 -程序员代码面试指南第 4 章的方法将求斐波那契第 N 项问题转换为矩阵乘法运算,从而将时间复杂度缩小为 O(lgN)。 +Աָϵ 4 µķ쳲 N תΪ˷㣬Ӷʱ临ӶСΪ O(lgN) -**爬楼梯** +**¥** [Leetcode : 70. Climbing Stairs (Easy)](https://leetcode.com/problems/climbing-stairs/description/) -题目描述:有 N 阶楼梯,每次可以上一阶或者两阶,求有多少种上楼梯的方法。 +Ŀ N ¥ݣÿοһ׻ףж¥ݵķ -定义一个数组 dp 存储上楼梯的方法数(为了方便讨论,数组下标从 1 开始),dp[i] 表示走到第 i 个楼梯的方法数目。第 i 个楼梯可以从第 i-1 和 i-2 个楼梯再走一步到达,走到第 i 个楼梯的方法数为走到第 i-1 和第 i-2 个楼梯的方法数之和。 +һ dp 洢¥ݵķΪ˷ۣ± 1 ʼdp[i] ʾߵ i ¥ݵķĿ i ¥ݿԴӵ i-1 i-2 ¥һߵ i ¥ݵķΪߵ i-1 ͵ i-2 ¥ݵķ֮͡
dp[i] = dp[i-1] + dp[i-2]
-dp[N] 即为所求。 +dp[N] Ϊ -考虑到 dp[i] 只与 dp[i - 1] 和 dp[i - 2] 有关,因此可以只用两个变量来存储 dp[i - 1] 和 dp[i - 2] 即可,使得原来的 O(n) 空间复杂度优化为 O(1) 复杂度。 +ǵ dp[i] ֻ dp[i - 1] dp[i - 2] йأ˿ֻ洢 dp[i - 1] dp[i - 2] ɣʹԭ O(n) ռ临ӶŻΪ O(1) Ӷȡ ```java public int climbStairs(int n) { if(n == 1) return 1; if(n == 2) return 2; - // 前一个楼梯、后一个楼梯 + // ǰһ¥ݡһ¥ int pre1 = 2, pre2 = 1; for(int i = 2; i < n; i++){ int cur = pre1 + pre2; @@ -1713,27 +1711,27 @@ public int climbStairs(int n) { } ``` -**母牛生产** +**ĸţ** -[程序员代码面试指南-P181](#) +[Աָ-P181](#) -题目描述:假设农场中成熟的母牛每年都会生 1 头小母牛,并且永远不会死。第一年有 1 只小母牛,从第二年开始,母牛开始生小母牛。每只小母牛 3 年之后成熟又可以生小母牛。给定整数 N,求 N 年后牛的数量。 +Ŀũгĸţÿ궼 1 ͷСĸţԶһ 1 ֻСĸţӵڶ꿪ʼĸţʼСĸţÿֻСĸţ 3 ֿ֮Сĸţ N N ţ -第 i 年成熟的牛的数量为: + i ţΪ
dp[i] = dp[i-1] + dp[i-3]
-**强盗抢劫** +**ǿ** [Leetcode : 198. House Robber (Easy)](https://leetcode.com/problems/house-robber/description/) -题目描述:抢劫一排住户,但是不能抢邻近的住户,求最大抢劫量。 +ĿһסDzڽס -定义 dp 数组用来存储最大的抢劫量,其中 dp[i] 表示抢到第 i 个住户时的最大抢劫量。由于不能抢劫邻近住户,因此如果抢劫了第 i 个住户那么只能抢劫 i - 2 和 i - 3 的住户,所以 + dp 洢 dp[i] ʾ i סʱڲڽס˵ i סôֻ i - 2 i - 3 ס ![](http://latex.codecogs.com/gif.latex?\\\\dp[i]=max(dp[i-2],dp[i-3])+nums[i]) -O(n) 空间复杂度实现方法: +O(n) ռ临Ӷʵַ ```java public int rob(int[] nums) { @@ -1752,7 +1750,7 @@ public int rob(int[] nums) { } ``` -O(1) 空间复杂度实现方法: +O(1) ռ临Ӷʵַ ```java public int rob(int[] nums) { @@ -1771,7 +1769,7 @@ public int rob(int[] nums) { } ``` -**强盗在环形街区抢劫** +**ǿڻν** [Leetcode : 213. House Robber II (Medium)](https://leetcode.com/problems/house-robber-ii/description/) @@ -1799,39 +1797,39 @@ private int rob(int[] nums, int s, int e) { ``` -**信件错排** +**ż** -题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信的方式数量。 +Ŀ N ŷ⣬DZңװŵķʽ -定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况: +һ dp 洢ʽdp[i] ʾǰ i źŷĴʽ i װ j ŷ棬 j װ k ŷ档 i k Ƿȣ -① i==k,交换 i 和 k 的信后,它们的信和信封在正确的位置,但是其余 i-2 封信有 dp[i-2] 种错误装信的方式。由于 j 有 i-1 种取值,因此共有 (i-1)\*dp[i-2] 种错误装信方式。 + i==k i k źǵźŷȷλã i-2 dp[i-2] ִװŵķʽ j i-1 ȡֵ˹ (i-1)\*dp[i-2] ִװŷʽ -② i != k,交换 i 和 j 的信后,第 i 个信和信封在正确的位置,其余 i-1 封信有 dp[i-1] 种错误装信方式。由于 j 有 i-1 种取值,因此共有 (n-1)\*dp[i-1] 种错误装信方式。 + i != k i j ź󣬵 i źŷȷλã i-1 dp[i-1] ִװŷʽ j i-1 ȡֵ˹ (n-1)\*dp[i-1] ִװŷʽ -综上所述,错误装信数量方式数量为: +װʽΪ
dp[i] = (i-1) \* dp[i-2] + (i-1) \* dp[i-1]
-dp[N] 即为所求。 +dp[N] Ϊ -和上楼梯问题一样,dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此也可以只用两个变量来存储 dp[i-1] 和 dp[i-2]。 +¥һdp[i] ֻ dp[i-1] dp[i-2] йأҲֻ洢 dp[i-1] dp[i-2] -### 最长递增子序列 +###  -已知一个序列 {S1, S2,...,Sn} ,取出若干数组成新的序列 {Si1, Si2,..., Sim},其中 i1、i2 ... im 保持递增,即新序列中各个数仍然保持原数列中的先后顺序,称新序列为原序列的一个**子序列**。 +֪һ {S1, S2,...,Sn} ȡµ {Si1, Si2,..., Sim} i1i2 ... im ֵиȻԭеȺ˳򣬳Ϊԭеһ**** -如果在子序列中,当下标 ix > iy 时,Six > Siy,称子序列为原序列的一个**递增子序列**。 +У± ix > iy ʱSix > SiyΪԭеһ**** -定义一个数组 dp 存储最长递增子序列的长度,dp[n] 表示以 Sn 结尾的序列的最长递增子序列长度。对于一个递增子序列 {Si1, Si2,...,Sim},如果 im < n 并且 Sim < Sn ,此时 {Si1, Si2,..., Sim, Sn} 为一个递增子序列,递增子序列的长度增加 1。满足上述条件的递增子序列中,长度最长的那个递增子序列就是要找的,在长度最长的递增子序列上加上 Sn 就构成了以 Sn 为结尾的最长递增子序列。因此 dp[n] = max{ dp[i]+1 | Si < Sn && i < n} 。 +һ dp 洢еijȣdp[n] ʾ Sn βегȡһ {Si1, Si2,...,Sim} im < n Sim < Sn ʱ {Si1, Si2,..., Sim, Sn} ΪһУеij 1ĵУǸоҪҵģڳĵϼ Sn ͹ Sn ΪβС dp[n] = max{ dp[i]+1 | Si < Sn && i < n} -因为在求 dp[n] 时可能无法找到一个满足条件的递增子序列,此时 {Sn} 就构成了递增子序列,因此需要对前面的求解方程做修改,令 dp[n] 最小为 1,即: +Ϊ dp[n] ʱ޷ҵһĵУʱ {Sn} ͹˵УҪǰⷽ޸ģ dp[n] СΪ 1 ![](http://latex.codecogs.com/gif.latex?\\\\dp[n]=max\{1,dp[i]+1|S_iN 为结尾,因此 dp[N] 不是序列的最长递增子序列的长度,需要遍历 dp 数组找出最大值才是所要的结果,即 max{ dp[i] | 1 <= i <= N} 即为所求。 +һΪ N Увһ SN Ϊβ dp[N] ееijȣҪ dp ҳֵҪĽ max{ dp[i] | 1 <= i <= N} Ϊ -**最长递增子序列** +**** [Leetcode : 300. Longest Increasing Subsequence (Medium)](https://leetcode.com/problems/longest-increasing-subsequence/description/) @@ -1854,7 +1852,7 @@ public int lengthOfLIS(int[] nums) { } ``` -以上解法的时间复杂度为 O(n2) ,可以使用二分查找使得时间复杂度降低为 O(nlogn)。定义一个 tails 数组,其中 tails[i] 存储长度为 i + 1 的最长递增子序列的最后一个元素,例如对于数组 [4,5,6,3],有 +Ͻⷨʱ临ӶΪ O(n2) ʹöֲʹʱ临ӶȽΪ O(nlogn)һ tails 飬 tails[i] 洢Ϊ i + 1 еһԪأ [4,5,6,3] ```html len = 1 : [4], [5], [6], [3] => tails[0] = 3 @@ -1862,9 +1860,9 @@ len = 2 : [4, 5], [5, 6] => tails[1] = 5 len = 3 : [4, 5, 6] => tails[2] = 6 ``` -对于一个元素 x,如果它大于 tails 数组所有的值,那么把它添加到 tails 后面;如果 tails[i-1] < x <= tails[i],那么更新 tails[i] = x 。 +һԪ x tails еֵôӵ tails 棻 tails[i-1] < x <= tails[i]ô tails[i] = x -可以看出 tails 数组保持有序,因此在查找 Si 位于 tails 数组的位置时就可以使用二分查找。 +Կ tails 鱣ڲ Si λ tails λʱͿʹöֲҡ ```java public int lengthOfLIS(int[] nums) { @@ -1890,13 +1888,13 @@ private int binarySearch(int[] nums, int sIdx, int eIdx, int key){ } ``` -**最长摆动子序列** +**ڶ** [Leetcode : 376. Wiggle Subsequence (Medium)](https://leetcode.com/problems/wiggle-subsequence/description/) -要求:使用 O(n) 时间复杂度求解。 +Ҫʹ O(n) ʱ临Ӷ⡣ -使用两个状态 up 和 down。 +ʹ״̬ up down ```java public int wiggleMaxLength(int[] nums) { @@ -1911,17 +1909,17 @@ public int wiggleMaxLength(int[] nums) { } ``` -### 最长公共子系列 +### ϵ -对于两个子序列 S1 和 S2,找出它们最长的公共子序列。 + S1 S2ҳĹС -定义一个二维数组 dp 用来存储最长公共子序列的长度,其中 dp[i][j] 表示 S1 的前 i 个字符与 S2 的前 j 个字符最长公共子序列的长度。考虑 S1i 与 S2j 值是否相等,分为两种情况: +һά dp 洢еijȣ dp[i][j] ʾ S1 ǰ i ַ S2 ǰ j ַеijȡ S1i S2j ֵǷȣΪ -① 当 S1i==S2j 时,那么就能在 S1 的前 i-1 个字符与 S2 的前 j-1 个字符最长公共子序列的基础上再加上 S1i 这个值,最长公共子序列长度加 1 ,即 dp[i][j] = dp[i-1][j-1] + 1。 + S1i==S2j ʱô S1 ǰ i-1 ַ S2 ǰ j-1 ַеĻټ S1i ֵгȼ 1 dp[i][j] = dp[i-1][j-1] + 1 -② 当 S1i != S2j 时,此时最长公共子序列为 S1 的前 i-1 个字符和 S2 的前 j 个字符最长公共子序列,与 S1 的前 i 个字符和 S2 的前 j-1 个字符最长公共子序列,它们的最大者,即 dp[i][j] = max{ dp[i-1][j], dp[i][j-1] }。 + S1i != S2j ʱʱΪ S1 ǰ i-1 ַ S2 ǰ j ַУ S1 ǰ i ַ S2 ǰ j-1 ַУǵߣ dp[i][j] = max{ dp[i-1][j], dp[i][j-1] } -综上,最长公共子系列的状态转移方程为: +ϣϵе״̬תƷΪ ![](http://latex.codecogs.com/gif.latex?\\\\ dp[i][j]=\left\{ @@ -1931,13 +1929,13 @@ max(dp[i-1][j],dp[i][j-1])&&{S1_i<>S2_j} \end{array}\right. ) -对于长度为 N 的序列 S1 和 长度为 M 的序列 S2,dp[N][M] 就是序列 S1 和序列 S2 的最长公共子序列长度。 +ڳΪ N S1 Ϊ M S2dp[N][M] S1 S2 гȡ -与最长递增子序列相比,最长公共子序列有以下不同点: +ȣ²ͬ㣺 -① 针对的是两个序列,求它们的最长公共子序列。 -② 在最长递增子序列中,dp[i] 表示以 Si 为结尾的最长递增子序列长度,子序列必须包含 Si ;在最长公共子序列中,dp[i][j] 表示 S1 中前 i 个字符与 S2 中前 j 个字符的最长公共子序列长度,不一定包含 S1i 和 S2j 。 -③ 由于 2 ,在求最终解时,最长公共子序列中 dp[N][M] 就是最终解,而最长递增子序列中 dp[N] 不是最终解,因为以 SN 为结尾的最长递增子序列不一定是整个序列最长递增子序列,需要遍历一遍 dp 数组找到最大者。 + ԵУǵС + Уdp[i] ʾ Si Ϊβгȣб Si Уdp[i][j] ʾ S1 ǰ i ַ S2 ǰ j ַгȣһ S1i S2j + 2 սʱ dp[N][M] ս⣬ dp[N] ս⣬Ϊ SN ΪβвһУҪһ dp ҵߡ ```java public int lengthOfLCS(int[] nums1, int[] nums2) { @@ -1953,18 +1951,18 @@ public int lengthOfLCS(int[] nums1, int[] nums2) { } ``` -### 0-1 背包 +### 0-1 -有一个容量为 N 的背包,要用这个背包装下物品的价值最大,这些物品有两个属性:体积 w 和价值 v。 +һΪ N ıҪװƷļֵЩƷԣ w ͼֵ v -定义一个二维数组 dp 存储最大价值,其中 dp[i][j] 表示体积不超过 j 的情况下,前 i 件物品能达到的最大价值。设第 i 件物品体积为 w,价值为 v,根据第 i 件物品是否添加到背包中,可以分两种情况讨论: +һά dp 洢ֵ dp[i][j] ʾ j £ǰ i Ʒܴﵽֵ i ƷΪ wֵΪ vݵ i ƷǷӵУԷۣ -① 第 i 件物品没添加到背包,总体积不超过 j 的前 i 件物品的最大价值就是总体积不超过 j 的前 i-1 件物品的最大价值,dp[i][j] = dp[i-1][j]。 -② 第 i 件物品添加到背包中,dp[i][j] = dp[i-1][j-w] + v。 + i Ʒûӵ j ǰ i Ʒֵ j ǰ i-1 Ʒֵdp[i][j] = dp[i-1][j] + i ƷӵУdp[i][j] = dp[i-1][j-w] + v -第 i 件物品可添加也可以不添加,取决于哪种情况下最大价值更大。 + i ƷҲԲӣȡֵ -综上,0-1 背包的状态转移方程为: +ϣ0-1 ״̬תƷΪ ![](http://latex.codecogs.com/gif.latex?\\\\dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)) @@ -1986,42 +1984,42 @@ public int knapsack(int W, int N, int[] weights, int[] values) { } ``` -**空间优化** +**ռŻ** -在程序实现时可以对 0-1 背包做优化。观察状态转移方程可以知道,前 i 件物品的状态仅由前 i-1 件物品的状态有关,因此可以将 dp 定义为一维数组,其中 dp[j] 既可以表示 dp[i-1][j] 也可以表示 dp[i][j]。此时, +ڳʵʱԶ 0-1 Ż۲״̬תƷ֪̿ǰ i Ʒ״̬ǰ i-1 Ʒ״̬йأ˿Խ dp Ϊһά飬 dp[j] ȿԱʾ dp[i-1][j] ҲԱʾ dp[i][j]ʱ ![](http://latex.codecogs.com/gif.latex?\\\\dp[j]=max(dp[j],dp[j-w]+v)) -因为 dp[j-w] 表示 dp[i-1][j-w],因此不能先求 dp[i][j-w] 防止将 dp[i-1][j-w] 覆盖。也就是说要先计算 dp[i][j] 再计算 dp[i][j-w],在程序实现时需要按倒序来循环求解。 +Ϊ dp[j-w] ʾ dp[i-1][j-w]˲ dp[i][j-w] ֹ dp[i-1][j-w] ǡҲ˵Ҫȼ dp[i][j] ټ dp[i][j-w]ڳʵʱҪѭ⡣ -**无法使用贪心算法的解释** +**޷ʹ̰㷨Ľ** -0-1 背包问题无法使用贪心算法来求解,也就是说不能按照先添加性价比最高的物品来达到最优,这是因为这种方式可能造成背包空间的浪费,从而无法达到最优。考虑下面的物品和一个容量为 5 的背包,如果先添加物品 0 再添加物品 1,那么只能存放的价值为 16,浪费了大小为 2 的空间。最优的方式是存放物品 1 和物品 2,价值为 22. +0-1 ޷ʹ̰㷨⣬Ҳ˵ܰԼ۱ߵƷﵽţΪַʽɱռ˷ѣӶ޷ﵽšƷһΪ 5 ıƷ 0 Ʒ 1ôֻܴŵļֵΪ 16˷˴СΪ 2 Ŀռ䡣ŵķʽǴƷ 1 Ʒ 2ֵΪ 22. - id | w | v | v/w - --- | --- | --- | --- - 0 | 1 | 6 | 6 - 1 | 2 | 10 | 5 - 2 | 3 | 12 | 4 +| id | w | v | v/w | +| --- | --- | --- | --- | +| 0 | 1 | 6 | 6 | +| 1 | 2 | 10 | 5 | +| 2 | 3 | 12 | 4 | -**变种** +**** -完全背包:物品可以无限个,可以转换为 0-1 背包,令每种物品的体积和价值变为 1/2/4... 倍数,把它们都当成一个新物品,然后一种物品只能添加一次。 +ȫƷ޸תΪ 0-1 ÿƷͼֵΪ 1/2/4... ǶһƷȻһƷֻһΡ -多重背包:物品数量有限制,同样可以转换为 0-1 背包。 +رƷƣͬתΪ 0-1 -多维费用背包:物品不仅有重量,还有体积,同时考虑这两种限制。 +άñƷͬʱơ -其它:物品之间相互约束或者依赖。 +Ʒ֮໥Լ -**划分数组为和相等的两部分** +**Ϊȵ** [Leetcode : 416. Partition Equal Subset Sum (Medium)](https://leetcode.com/problems/partition-equal-subset-sum/description/) -可以看成一个背包大小为 sum/2 的 0-1 背包问题,但是也有不同的地方,这里没有价值属性,并且背包必须被填满。 +ԿһСΪ sum/2 0-1 ⣬Ҳвͬĵطûмֵԣұ뱻 -以下实现使用了空间优化。 +ʵʹ˿ռŻ ```java public boolean canPartition(int[] nums) { @@ -2048,7 +2046,7 @@ public boolean canPartition(int[] nums) { } ``` -**字符串按单词列表分割** +**ַбָ** [Leetcode : 139. Word Break (Medium)](https://leetcode.com/problems/word-break/description/) @@ -2075,7 +2073,7 @@ public boolean wordBreak(String s, List wordDict) { } ``` -**改变一组数的正负号使得它们的和为一给定数** +**ıһʹǵĺΪһ** [Leetcode : 494. Target Sum (Medium)](https://leetcode.com/problems/target-sum/description/) @@ -2093,7 +2091,7 @@ Explanation: There are 5 ways to assign symbols to make the sum of nums be target 3. ``` -该问题可以转换为 subset sum 问题,从而使用 0-1 背包的方法来求解。可以将这组数看成两部分,P 和 N,其中 P 使用正号,N 使用负号,有以下推导: +תΪ subset sum ⣬Ӷʹ 0-1 ķ⡣Խ֣P N P ʹţN ʹøţƵ ```html sum(P) - sum(N) = target @@ -2101,7 +2099,7 @@ sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N) 2 * sum(P) = target + sum(nums) ``` -因此只要找到一个子集,令它们都取正号,并且和等于 (target + sum(nums))/2,就证明存在解。 +ֻҪҵһӼǶȡţҺ͵ (target + sum(nums))/2֤ڽ⡣ ```java public int findTargetSumWays(int[] nums, int S) { @@ -2129,7 +2127,7 @@ private int subsetSum(int[] nums, int targetSum) { } ``` -**01字符构成最多的字符串** +**01ַַ** [Leetcode : 474. Ones and Zeroes (Medium)](https://leetcode.com/problems/ones-and-zeroes/description/) @@ -2137,10 +2135,10 @@ private int subsetSum(int[] nums, int targetSum) { Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 -Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0” +Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are 10,0001,1,0 ``` -这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。 +һάõ 0-1 ⣬С0 1 ```java public int findMaxForm(String[] strs, int m, int n) { @@ -2166,13 +2164,13 @@ public int findMaxForm(String[] strs, int m, int n) { } ``` -**找零钱** +**Ǯ** [Leetcode : 322. Coin Change (Medium)](https://leetcode.com/problems/coin-change/description/) -题目描述:给一些面额的硬币,要求用这些硬币来组成给定面额的钱数,并且使得硬币数量最少。硬币可以重复使用。 +ĿһЩӲңҪЩӲɸǮʹӲ١Ӳҿظʹá -这是一个完全背包问题,完全背包问题和 0-1背包问题在实现上唯一的不同是,第二层循环是从 0 开始的,而不是从尾部开始。 +һȫ⣬ȫ 0-1ʵΨһIJͬǣڶѭǴ 0 ʼģǴβʼ ```java public int coinChange(int[] coins, int amount) { @@ -2190,7 +2188,7 @@ public int coinChange(int[] coins, int amount) { } ``` -**组合总和** +**ܺ** [Leetcode : 377. Combination Sum IV (Medium)](https://leetcode.com/problems/combination-sum-iv/description/) @@ -2227,7 +2225,7 @@ public int combinationSum4(int[] nums, int target) { } ``` -**只能进行两次的股票交易** +**ֻܽεĹƱ** [Leetcode : 123. Best Time to Buy and Sell Stock III (Hard)](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/) @@ -2245,7 +2243,7 @@ public int maxProfit(int[] prices) { } ``` -**只能进行 k 次的股票交易** +**ֻܽ k εĹƱ** [Leetcode : 188. Best Time to Buy and Sell Stock IV (Hard)](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/description/) @@ -2276,13 +2274,13 @@ public int maxProfit(int k, int[] prices) { } ``` -### 数组区间 +### -**数组区间和** +**** [Leetcode : 303. Range Sum Query - Immutable (Easy)](https://leetcode.com/problems/range-sum-query-immutable/description/) -求区间 i \~ j 的和,可以转换为 sum[j] - sum[i-1],其中 sum[i] 为 0 \~ j 的和。 + i \~ j ĺͣתΪ sum[j] - sum[i-1] sum[i] Ϊ 0 \~ j ĺ͡ ```java class NumArray { @@ -2301,11 +2299,11 @@ class NumArray { } ``` -**子数组最大的和** +**ĺ** [Leetcode : 53. Maximum Subarray (Easy)](https://leetcode.com/problems/maximum-subarray/description/) -令 sum[i] 为以 num[i] 为结尾的子数组最大的和,可以由 sum[i-1] 得到 sum[i] 的值,如果 sum[i-1] 小于 0,那么以 num[i] 为结尾的子数组不能包含前面的内容,因为加上前面的部分,那么和一定会比 num[i] 还小。 + sum[i] Ϊ num[i] Ϊβĺͣ sum[i-1] õ sum[i] ֵ sum[i-1] С 0ô num[i] Ϊβ鲻ܰǰݣΪǰIJ֣ôһ num[i] С ```java public int maxSubArray(int[] nums) { @@ -2321,7 +2319,7 @@ public int maxSubArray(int[] nums) { } ``` -**数组中等差递增子区间的个数** +**еȲĸ** [Leetcode : 413. Arithmetic Slices (Medium)](https://leetcode.com/problems/arithmetic-slices/description/) @@ -2331,7 +2329,7 @@ A = [1, 2, 3, 4] return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself. ``` -对于 (1,2,3,4),它有三种组成递增子区间的方式,而对于 (1,2,3,4,5),它组成递增子区间的方式除了 (1,2,3,4) 的三种外还多了一种,即 (1,2,3,4,5),因此 dp[i] = dp[i - 1] + 1。 + (1,2,3,4)ɵķʽ (1,2,3,4,5)ɵķʽ (1,2,3,4) ⻹һ֣ (1,2,3,4,5) dp[i] = dp[i - 1] + 1 ```java public int numberOfArithmeticSlices(int[] A) { @@ -2350,13 +2348,13 @@ public int numberOfArithmeticSlices(int[] A) { } ``` -### 字符串编辑 +### ַ༭ -**删除两个字符串的字符使它们相等** +**ɾַַʹ** [Leetcode : 583. Delete Operation for Two Strings (Medium)](https://leetcode.com/problems/delete-operation-for-two-strings/description/) -可以转换为求两个字符串的最长公共子序列问题。 +תΪַ⡣ ```java public int minDistance(String word1, String word2) { @@ -2374,23 +2372,23 @@ public int minDistance(String word1, String word2) { ``` -**修改一个字符串称为另一个字符串** // TODO +**޸һַΪһַ** // TODO [Leetcode : 72. Edit Distance (Hard)](https://leetcode.com/problems/edit-distance/description/) -**修改一个字符串使它成为回文字符串**// TODO +**޸һַʹΪַ**// TODO -[程序员代码面试指南-字符串](#) +[Աָ-ַ](#) -### 其它问题 +### -**需要冷却期的股票交易** +**ҪȴڵĹƱ** [Leetcode : 309. Best Time to Buy and Sell Stock with Cooldown(Medium)](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/) -题目描述:交易之后需要有一天的冷却时间。 +Ŀ֮Ҫһȴʱ䡣 -![](https://github.com/00000H/notes/blob/master/pics/ac9b31ec-cef1-4880-a875-fc4571ca10e1.png) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ac9b31ec-cef1-4880-a875-fc4571ca10e1.png) ```html s0[i] = max(s0[i - 1], s2[i - 1]); // Stay at s0, or rest from s2 @@ -2419,11 +2417,11 @@ public int maxProfit(int[] prices) { ``` -**统计从 0 \~ n 每个数的二进制表示中 1 的个数** +**ͳƴ 0 \~ n ÿĶƱʾ 1 ĸ** [Leetcode : 338. Counting Bits (Medium)](https://leetcode.com/problems/counting-bits/description/) -对于数字 6(110),它可以看成是数字 2(10) 前面加上一个 1 ,因此 dp[i] = dp[i&(i-1)] + 1; + 6(110)Կ 2(10) ǰһ 1 dp[i] = dp[i&(i-1)] + 1; ```java public int[] countBits(int num) { @@ -2435,11 +2433,11 @@ public int maxProfit(int[] prices) { } ``` -**一组整数对能够构成的最长链** +**һܹɵ** [Leetcode : 646. Maximum Length of Pair Chain (Medium)](https://leetcode.com/problems/maximum-length-of-pair-chain/description/) -对于 (a, b) 和 (c, d) ,如果 b < c,则它们可以构成一条链。 + (a, b) (c, d) b < cǿԹһ ```java public int findLongestChain(int[][] pairs) { @@ -2466,13 +2464,13 @@ public int findLongestChain(int[][] pairs) { } ``` -**买入和售出股票最大的收益** +**۳Ʊ** [Leetcode : 121. Best Time to Buy and Sell Stock (Easy)](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/) -只进行一次交易。 +ֻһνס -只要记录前面的最小价格,将这个最小价格作为买入价格,然后将当前的价格作为售出价格,查看这个价格是否是当前的最大价格。 +ֻҪ¼ǰС۸񣬽С۸Ϊ۸Ȼ󽫵ǰļ۸Ϊ۳۸񣬲鿴۸Ƿǵǰ۸ ```java public int maxProfit(int[] prices) { @@ -2488,7 +2486,7 @@ public int maxProfit(int[] prices) { } ``` -**复制粘贴字符** +**ճַ** [Leetcode : 650. 2 Keys Keyboard (Medium)](https://leetcode.com/problems/2-keys-keyboard/description/) @@ -2518,30 +2516,30 @@ public int minSteps(int n) { } ``` -## 数学 +## ѧ -### 素数 +### -**素数分解** +**ֽ** -每一个数都可以分解成素数的乘积,例如 84 = 22 \* 31 \* 50 \* 71 \* 110 \* 130 \* 170 \* … +ÿһԷֽij˻ 84 = 22 \* 31 \* 50 \* 71 \* 110 \* 130 \* 170 \* -**整除** +**** -令 x = 2m0 \* 3m1 \* 5m2 \* 7m3 \* 11m4 \* … -令 y = 2n0 \* 3n1 \* 5n2 \* 7n3 \* 11n4 \* … + x = 2m0 \* 3m1 \* 5m2 \* 7m3 \* 11m4 \* + y = 2n0 \* 3n1 \* 5n2 \* 7n3 \* 11n4 \* -如果 x 整除 y(y mod x == 0),则对于所有 i,mi <= ni。 + x yy mod x == 0 imi <= ni -x 和 y 的 **最大公约数** 为:gcd(x,y) = 2min(m0,n0) \* 3min(m1,n1) \* 5min(m2,n2) \* ... +x y **Լ** Ϊgcd(x,y) = 2min(m0,n0) \* 3min(m1,n1) \* 5min(m2,n2) \* ... -x 和 y 的 **最小公倍数** 为:lcm(x,y) = 2max(m0,n0) \* 3max(m1,n1) \* 5max(m2,n2) \* ... +x y **С** Ϊlcm(x,y) = 2max(m0,n0) \* 3max(m1,n1) \* 5max(m2,n2) \* ... -**生成素数序列** +**** [Leetcode : 204. Count Primes (Easy)](https://leetcode.com/problems/count-primes/description/) -埃拉托斯特尼筛法在每次找到一个素数时,将能被素数整除的数排除掉。 +˹ɸÿҵһʱܱų ```java public int countPrimes(int n) { @@ -2550,7 +2548,7 @@ public int countPrimes(int n) { for(int i = 2; i < n; i++){ if(notPrimes[i]) continue; cnt++; - // 从 i * i 开始,因为如果 k < i,那么 k * i 在之前就已经被去除过了 + // i * i ʼΪ k < iô k * i ֮ǰѾȥ for(long j = (long) i * i; j < n; j += i){ notPrimes[(int) j] = true; } @@ -2559,7 +2557,7 @@ public int countPrimes(int n) { } ``` -### 最大公约数 +### Լ ```java int gcd(int a, int b) { @@ -2568,7 +2566,7 @@ int gcd(int a, int b) { } ``` -最大公倍数为两数的乘积除以最大公约数。 +󹫱Ϊij˻Լ ```java int lcm(int a, int b){ @@ -2576,22 +2574,22 @@ int lcm(int a, int b){ } ``` -对于最大公约数问题,因为需要计算 a % b ,而这个操作是比较耗时的,可以使用 [ 编程之美:2.7]() 的方法,利用减法和移位操作来替换它。 +Լ⣬ΪҪ a % b DZȽϺʱģʹ [ ֮2.7]() ķüλ滻 -对于 a 和 b 的最大公约数 f(a, b),有: + a b Լ f(a, b)У -1\. 如果 a 和 b 均为偶数,f(a, b) = 2\*f(a/2, b/2); -2\. 如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b); -3\. 如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2); -4\. 如果 a 和 b 均为奇数,f(a, b) = f(a, a-b); +1\. a b Ϊżf(a, b) = 2\*f(a/2, b/2); +2\. a ż b f(a, b) = f(a/2, b); +3\. b ż a f(a, b) = f(a, b/2); +4\. a b Ϊf(a, b) = f(a, a-b); -乘 2 和除 2 都可以转换为移位操作。 + 2 ͳ 2 תΪλ -### 进制转换 +### ת -Java 中 static String toString(int num, int radix) 可以将一个整数装换为 redix 进制表示的字符串。 +Java static String toString(int num, int radix) ԽһװΪ redix Ʊʾַ -**7 进制** +**7 ** [Leetcode : 504. Base 7 (Easy)](https://leetcode.com/problems/base-7/description/) @@ -2607,7 +2605,7 @@ public String convertToBase7(int num) { } ``` -**16 进制** +**16 ** [Leetcode : 405. Convert a Number to Hexadecimal (Easy)](https://leetcode.com/problems/convert-a-number-to-hexadecimal/description/) @@ -2624,15 +2622,15 @@ public String toHex(int num) { } ``` -### 阶乘 +### ׳ -**统计阶乘尾部有多少个 0** +**ͳƽ׳βжٸ 0** [Leetcode : 172. Factorial Trailing Zeroes (Easy)](https://leetcode.com/problems/factorial-trailing-zeroes/description/) -尾部的 0 由 2 * 5 得来,2 的数量明显多于 5 的数量,因此只要统计有多少个 5 即可。 +β 0 2 * 5 2 Զ 5 ֻҪͳжٸ 5 ɡ -对于一个数 N,它所包含 5 的个数为:N/5 + N/52 + N/53 + ...,其中 N/5 表示不大于 N 的数中 5 的倍数贡献一个 5,N/52 表示不大于 N 的数中 52 的倍数再贡献一个 5 ...。 +һ N 5 ĸΪN/5 + N/52 + N/53 + ... N/5 ʾ N 5 ıһ 5N/52 ʾ N 52 ıٹһ 5 ... ```java public int trailingZeroes(int n) { @@ -2640,11 +2638,11 @@ public int trailingZeroes(int n) { } ``` -如果统计的是 N! 的二进制表示中最低位 1 的位置,只要统计有多少个 2 即可,该题目出自 [ 编程之美:2.2](#) 。和求解有多少个 5 一样,2 的个数为 N/2 + N/22 + N/23 + ... +ͳƵ N! ĶƱʾλ 1 λãֻҪͳжٸ 2 ɣĿ [ ֮2.2](#) жٸ 5 һ2 ĸΪ N/2 + N/22 + N/23 + ... -### 字符串加法减法 +### ַӷ -**二进制加法** +**Ƽӷ** [Leetcode : 67. Add Binary (Easy)](https://leetcode.com/problems/add-binary/description/) @@ -2663,11 +2661,11 @@ public String addBinary(String a, String b) { } ``` -**字符串加法** +**ַӷ** [Leetcode : 415. Add Strings (Easy)](https://leetcode.com/problems/add-strings/description/) -题目描述:字符串的值为非负整数 +ĿֵַΪǸ ```java public String addStrings(String num1, String num2) { @@ -2683,23 +2681,23 @@ public String addStrings(String num1, String num2) { } ``` -### 相遇问题 +### -**改变数组元素使所有的数组元素都相等** +**ıԪʹеԪض** [Leetcode : 462. Minimum Moves to Equal Array Elements II (Medium)](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/description/) -题目描述:每次可以对一个数组元素加一或者减一,求最小的改变次数。 +ĿÿοԶһԪؼһ߼һСĸı -这是个典型的相遇问题,移动距离最小的方式是所有元素都移动到中位数。理由如下: +Ǹ͵⣬ƶСķʽԪضƶλ£ -设 m 为中位数。a 和 b 是 m 两边的两个元素,且 b > a。要使 a 和 b 相等,它们总共移动的次数为 b - a,这个值等于 (b - m) + (m - a),也就是把这两个数移动到中位数的移动次数。 + m Ϊλa b m ߵԪأ b > aҪʹ a b ȣܹƶĴΪ b - aֵ (b - m) + (m - a)Ҳǰƶλƶ -设数组长度为 N,则可以找到 N/2 对 a 和 b 的组合,使它们都移动到 m 的位置。 +鳤Ϊ Nҵ N/2 a b ϣʹǶƶ m λá -**解法 1** +**ⷨ 1** -先排序,时间复杂度:O(NlgN) +ʱ临ӶȣO(NlgN) ```java public int minMoves2(int[] nums) { @@ -2715,9 +2713,9 @@ public int minMoves2(int[] nums) { } ``` -**解法 2** +**ⷨ 2** -使用快速排序找到中位数,时间复杂度 O(N) +ʹÿҵλʱ临Ӷ O(N) ```java public int minMoves2(int[] nums) { @@ -2749,13 +2747,13 @@ private void swap(int[] nums, int i, int j) { } ``` -### 多数投票问题 +### ͶƱ -**数组中出现次数多于 n / 2 的元素** +**гִ n / 2 Ԫ** [Leetcode : 169. Majority Element (Easy)](https://leetcode.com/problems/majority-element/description/) -先对数组排序,最中间那个数出现次数一定多于 n / 2 +ȶмǸִһ n / 2 ```java public int majorityElement(int[] nums) { @@ -2764,7 +2762,7 @@ public int majorityElement(int[] nums) { } ``` -可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(n)。可以这么理解该算法:使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素不想等时,令 cnt--。如果前面查找了 i 个元素,且 cnt == 0 ,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目多于 (n - i) / 2,因此继续查找就能找出 majority。 + Boyer-Moore Majority Vote Algorithm ⣬ʹʱ临ӶΪ O(n)ô㷨ʹ cnt ͳһԪسֵĴԪغͳԪزʱ cnt--ǰ i Ԫأ cnt == 0 ˵ǰ i Ԫû majority majoritydzֵĴ i / 2 Ϊ i / 2 Ļ cnt һΪ 0 ʱʣµ n - i ԪУmajority Ŀ (n - i) / 2˼Ҿҳ majority ```java public int majorityElement(int[] nums) { @@ -2781,22 +2779,22 @@ public int majorityElement(int[] nums) { } ``` -**数组中出现次数多于 n / k 的元素** +**гִ n / k Ԫ** -[程序员代码面试指南 P343](#) +[Աָ P343](#) -选 k - 1 个候选 +ѡ k - 1 ѡ -### 其它 +### -**平方数** +**ƽ** [Leetcode : 367. Valid Perfect Square (Easy)](https://leetcode.com/problems/valid-perfect-square/description/) -平方序列:1,4,9,16,.. -间隔:3,5,7,... +ƽУ1,4,9,16,.. +3,5,7,... -间隔为等差数列,使用这个特性可以得到从 1 开始的平方序列。 +ΪȲУʹԿԵõ 1 ʼƽС ```java public boolean isPerfectSquare(int num) { @@ -2809,7 +2807,7 @@ public boolean isPerfectSquare(int num) { } ``` -**3 的 n 次方** +**3 n η** [Leetcode : 326. Power of Three (Easy)](https://leetcode.com/problems/power-of-three/description/) @@ -2819,7 +2817,7 @@ public boolean isPowerOfThree(int n) { } ``` -**找出数组中的乘积最大的三个数** +**ҳеij˻** [Leetcode : 628. Maximum Product of Three Numbers (Easy)](https://leetcode.com/problems/maximum-product-of-three-numbers/description/) @@ -2849,13 +2847,13 @@ public int maximumProduct(int[] nums) { } ``` -**乘积数组** +**˻** [Leetcode : 238. Product of Array Except Self (Medium)](https://leetcode.com/problems/product-of-array-except-self/description/) -题目描述:给定一个数组,创建一个新数组,新数组的每个元素为原始数组中除了该位置上的元素之外所有元素的乘积。 +Ŀһ飬һ飬ÿԪΪԭʼг˸λϵԪ֮Ԫصij˻ -题目要求:时间复杂度为 O(n),并且不能使用除法。 +ĿҪʱ临ӶΪ O(n)Ҳʹó ```java public int[] productExceptSelf(int[] nums) { @@ -2874,13 +2872,13 @@ public int[] productExceptSelf(int[] nums) { } ``` -# 数据结构相关 +# ݽṹ -## 栈和队列 +## ջͶ -**用栈实现队列** +**ջʵֶ** -一个栈实现: +һջʵ֣ ```java class MyQueue { @@ -2911,7 +2909,7 @@ class MyQueue { } ``` -两个栈实现: +ջʵ֣ ```java class MyQueue { @@ -2946,7 +2944,7 @@ class MyQueue { } ``` -**用队列实现栈** +**öʵջ** [Leetcode : 225. Implement Stack using Queues (Easy)](https://leetcode.com/problems/implement-stack-using-queues/description/) @@ -2961,7 +2959,7 @@ class MyStack { public void push(int x) { queue.add(x); - for(int i = 1; i < queue.size(); i++){ // 翻转 + for(int i = 1; i < queue.size(); i++){ // ת queue.add(queue.remove()); } } @@ -2980,11 +2978,11 @@ class MyStack { } ``` -**最小值栈** +**Сֵջ** [Leetcode : 155. Min Stack (Easy)](https://leetcode.com/problems/min-stack/description/) -用两个栈实现,一个存储数据,一个存储最小值。 +ջʵ֣һ洢ݣһ洢Сֵ ```java class MinStack { @@ -3027,9 +3025,9 @@ class MinStack { } ``` -对于实现最小值队列问题,可以先将队列使用栈来实现,然后就将问题转换为最小值栈,这个问题出现在 编程之美:3.7。 +ʵСֵ⣬Ƚʹջʵ֣ȻͽתΪСֵջ ֮3.7 -**用栈实现括号匹配** +**ջʵƥ** [Leetcode : 20. Valid Parentheses (Easy)](https://leetcode.com/problems/valid-parentheses/description/) @@ -3059,7 +3057,7 @@ public boolean isValid(String s) { } ``` -**数组中比当前元素大的下一个数组元素的距离** +**бȵǰԪشһԪصľ** ```html Input: [73, 74, 75, 71, 69, 72, 76, 73] @@ -3068,7 +3066,7 @@ Output: [1, 1, 4, 2, 1, 1, 0, 0] [Leetcode : 739. Daily Temperatures (Medium)](https://leetcode.com/problems/daily-temperatures/description/) -使用栈来存储还未计算的元素。可以保证从栈顶向下元素递增,否则上面有一个比下面某个元素大的元素进入栈中,下面那个元素已经找到比它大的元素,因此会出栈。 +ʹջ洢δԪءԱ֤ջԪصһijԪشԪؽջУǸԪѾҵԪأ˻ջ ```java public int[] dailyTemperatures(int[] temperatures) { @@ -3086,7 +3084,7 @@ public int[] dailyTemperatures(int[] temperatures) { } ``` -**数组中下一个比当前数大的数** +**һȵǰ** [Leetcode : 496. Next Greater Element I (Easy)](https://leetcode.com/problems/next-greater-element-i/description/) @@ -3095,7 +3093,7 @@ Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. Output: [-1,3,-1] ``` -在遍历数组时用 Stack 把数组中的数存起来,如果当前遍历的数比栈顶元素来的大,说明栈顶元素的下一个比它大的数就是当前元素。 +ڱʱ Stack еǰջԪĴ˵ջԪصһǵǰԪء ```java public int[] nextGreaterElement(int[] nums1, int[] nums2) { @@ -3116,7 +3114,7 @@ public int[] nextGreaterElement(int[] nums1, int[] nums2) { } ``` -**循环数组中下一个比当前元素大的数** +**ѭһȵǰԪش** [Leetcode : 503. Next Greater Element II (Medium)](https://leetcode.com/problems/next-greater-element-ii/description/) @@ -3136,28 +3134,28 @@ public int[] nextGreaterElements(int[] nums) { ``` -## 哈希表 +## ϣ -利用 Hash Table 可以快速查找一个元素是否存在等问题,但是需要一定的空间来存储。在优先考虑时间复杂度的情况下,可以利用 Hash Table 这种空间换取时间的做法。 + Hash Table ԿٲһԪǷڵ⣬ҪһĿռ洢ȿʱ临Ӷȵ£ Hash Table ֿռ任ȡʱ -Java 中的 **HashSet** 用于存储一个集合,并以 O(1) 的时间复杂度查找元素是否在集合中。 +Java е **HashSet** ڴ洢һϣ O(1) ʱ临ӶȲԪǷڼС -如果元素有穷,并且范围不大,那么可以用一个布尔数组来存储一个元素是否存在,例如对于只有小写字符的元素,就可以用一个长度为 26 的布尔数组来存储一个字符集合,使得空间复杂度降低为 O(1)。 +ԪҷΧôһ洢һԪǷڣֻСдַԪأͿһΪ 26 IJ洢һַϣʹÿռ临ӶȽΪ O(1) -Java 中的 **HashMap** 主要用于映射关系,从而把两个元素联系起来。 +Java е **HashMap** ҪӳϵӶԪϵ -在对一个内容进行压缩或者其它转换时,利用 HashMap 可以把原始内容和转换后的内容联系起来。例如在一个简化 url 的系统中([Leetcdoe : 535. Encode and Decode TinyURL (Medium)](https://leetcode.com/problems/encode-and-decode-tinyurl/description/)),利用 HashMap 就可以存储精简后的 url 到原始 url 的映射,使得不仅可以显示简化的 url,也可以根据简化的 url 得到原始 url 从而定位到正确的资源。 +ڶһݽѹתʱ HashMap ԰ԭʼݺתϵһ url ϵͳУ[Leetcdoe : 535. Encode and Decode TinyURL (Medium)](https://leetcode.com/problems/encode-and-decode-tinyurl/description/) HashMap ͿԴ洢 url ԭʼ url ӳ䣬ʹòʾ򻯵 urlҲԸݼ򻯵 url õԭʼ url ӶλȷԴ -HashMap 也可以用来对元素进行计数统计,此时键为元素,值为计数。和 HashSet 类似,如果元素有穷并且范围不大,可以用整型数组来进行统计。 +HashMap ҲԪؽмͳƣʱΪԪأֵΪ HashSet ƣԪҷΧ󣬿ͳơ -**数组中的两个数和为给定值** +**еΪֵ** [Leetcode : 1. Two Sum (Easy)](https://leetcode.com/problems/two-sum/description/) -可以先对数组进行排序,然后使用双指针方法或者二分查找方法。这样做的时间复杂度为 O(nlgn),空间复杂度为 O(1)。 +ȶȻʹ˫ָ뷽߶ֲҷʱ临ӶΪ O(nlgn)ռ临ӶΪ O(1) -用 HashMap 存储数组元素和索引的映射,在访问到 nums[i] 时,判断 HashMap 中是否存在 target - nums[i] ,如果存在说明 target - nums[i] 所在的索引和 i 就是要找的两个数。该方法的时间复杂度为 O(n),空间复杂度为 O(n),使用空间来换取时间。 + HashMap 洢Ԫغӳ䣬ڷʵ nums[i] ʱж HashMap Ƿ target - nums[i] ˵ target - nums[i] ڵ i Ҫҵ÷ʱ临ӶΪ O(n)ռ临ӶΪ O(n)ʹÿռȡʱ䡣 ```java public int[] twoSum(int[] nums, int target) { @@ -3170,9 +3168,9 @@ public int[] twoSum(int[] nums, int target) { } ``` -**最长和谐序列** +**г** -和谐序列中最大数和最小数只差正好为 1 +гСֻΪ 1 [Leetcode : 594. Longest Harmonious Subsequence (Easy)](https://leetcode.com/problems/longest-harmonious-subsequence/description/) @@ -3192,15 +3190,15 @@ public int findLHS(int[] nums) { } ``` -## 字符串 +## ַ -**两个字符串的包含的字符是否完全相同** +**ַİַǷȫͬ** [Leetcode : 242. Valid Anagram (Easy)](https://leetcode.com/problems/valid-anagram/description/) -字符串只包含小写字符,总共有 26 个小写字符。可以用 Hash Table 来映射字符与出现次数,因为键值范围很小,因此可以用数组来进行映射。 +ַֻСдַܹ 26 Сдַ Hash Table ӳִַΪֵΧС˿ӳ䡣 -使用长度为 26 的整型数组对字符串出现的字符进行统计,比较两个字符串出现的字符数量是否相同。 +ʹóΪ 26 ֵַַͳƣȽֵַַǷͬ ```java public boolean isAnagram(String s, String t) { @@ -3212,13 +3210,13 @@ public boolean isAnagram(String s, String t) { } ``` -**字符串同构** +**ַͬ** [Leetcode : 205. Isomorphic Strings (Easy)](https://leetcode.com/problems/isomorphic-strings/description/) -例如 "egg" 和 "add" 就属于同构字符串。 + "egg" "add" ַͬ -记录一个字符上次出现的位置,如果两个字符串中某个字符上次出现的位置一样,那么就属于同构。 +¼һַϴγֵλãַijַϴγֵλһôͬ ```java public boolean isIsomorphic(String s, String t) { @@ -3235,30 +3233,30 @@ public boolean isIsomorphic(String s, String t) { } ``` -**计算一组字符集合可以组成的回文字符串的最大长度** +**һַϿɵĻַ󳤶** [Leetcode : 409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/description/) -使用长度为 128 的整型数组来统计每个字符出现的个数,每个字符有偶数个可以用来构成回文字符串。因为回文字符串最中间的那个字符可以单独出现,所以如果有单独的字符就把它放到最中间。 +ʹóΪ 128 ͳÿֵַĸÿַżɻַΪַмǸַԵ֣еַͰŵм䡣 ```java public int longestPalindrome(String s) { - int[] cnts = new int[128]; // ascii 码总共 128 个 + int[] cnts = new int[128]; // ascii ܹ 128 for(char c : s.toCharArray()) cnts[c]++; int ret = 0; for(int cnt : cnts) ret += (cnt / 2) * 2; - if(ret < s.length()) ret ++; // 这个条件下 s 中一定有单个未使用的字符存在,可以把这个字符放到回文的最中间 + if(ret < s.length()) ret ++; // s һеδʹõַڣ԰ַŵĵм return ret; } ``` -**判断一个整数是否是回文数** +**жһǷǻ** [Leetcode : 9. Palindrome Number (Easy)](https://leetcode.com/problems/palindrome-number/description/) -要求不能使用额外空间,也就不能将整数转换为字符串进行判断。 +Ҫʹöռ䣬ҲͲܽתΪַжϡ -将整数分成左右两部分,右边那部分需要转置,然后判断这两部分是否相等。 +ֳ֣ұDzҪתãȻжǷȡ ```java public boolean isPalindrome(int x) { @@ -3274,18 +3272,18 @@ public boolean isPalindrome(int x) { } ``` -**回文子字符串** +**ַ** [Leetcode : 647. Palindromic Substrings (Medium)](https://leetcode.com/problems/palindromic-substrings/description/) -解决方案是从字符串的某一位开始,尝试着去扩展子字符串。 +Ǵַijһλʼȥչַ ```java private int cnt = 0; public int countSubstrings(String s) { for(int i = 0; i < s.length(); i++) { - extendSubstrings(s, i, i); // 奇数长度 - extendSubstrings(s, i, i + 1); // 偶数长度 + extendSubstrings(s, i, i); // + extendSubstrings(s, i, i + 1); // ż } return cnt; } @@ -3299,7 +3297,7 @@ private void extendSubstrings(String s, int start, int end) { } ``` -**统计二进制字符串中连续 1 和 连续 0 数量相同的子字符串个数** +**ͳƶַ 1 0 ַͬ** ```html Input: "00110011" @@ -3325,48 +3323,48 @@ public int countBinarySubstrings(String s) { } ``` -**字符串循环移位包含** +**ַѭλ** -[ 编程之美:3.1](#) +[ ֮3.1](#) -给定两个字符串 s1 和 s2 ,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。 +ַ s1 s2 Ҫж s2 Ƿܹ s1 ѭλõַ ```html s1 = AABCD, s2 = CDAA Return : true ``` -s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。 +s1 ѭλĽ s1s1 ַֻҪж s2 Ƿ s1s1 ַɡ -**字符串循环移位** +**ַѭλ** -[ 编程之美:2.17](#) +[ ֮2.17](#) -将字符串向右循环移动 k 位。 +ַѭƶ k λ -例如 abcd123 向右移动 3 位 得到 123abcd + abcd123 ƶ 3 λ õ 123abcd -将 abcd123 中的 abcd 和 123 单独逆序,得到 dcba321,然后对整个字符串进行逆序,得到123abcd。 + abcd123 е abcd 123 򣬵õ dcba321Ȼַ򣬵õ123abcd -**字符串中单词的翻转** +**ַеʵķת** -[程序员代码面试指南](#) +[Աָ](#) -例如将 "I am a student" 翻转成 "student a am I" +罫 "I am a student" ת "student a am I" -将每个单词逆序,然后将整个字符串逆序。 +ÿȻַ -## 数组与矩阵 +## -**矩阵旋转** // TODO +**ת** // TODO -[程序员面试金典 P114](#) +[ԱԽ P114](#) -**之字型打印** //TODO +**֮ʹӡ** //TODO -[程序员代码面试指南 P335](#) +[Աָ P335](#) -**把数组中的 0 移到末尾** +**е 0 Ƶĩβ** [Leetcode : 283. Move Zeroes (Easy)](https://leetcode.com/problems/move-zeroes/description/) @@ -3383,20 +3381,20 @@ s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 } ``` -**一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出丢失的数和重复的数** +**һԪ [1, n] ֮䣬һ滻Ϊһҳʧظ** [Leetcode : 645. Set Mismatch (Easy)](https://leetcode.com/problems/set-mismatch/description/) -最直接的方法是先对数组进行排序,这种方法时间复杂度为 O(nlogn),本题可以以 O(n) 的时间复杂度、O(1) 空间复杂度来求解。 +ֱӵķȶַʱ临ӶΪ O(nlogn) O(n) ʱ临ӶȡO(1) ռ临Ӷ⡣ -主要思想是让通过交换数组元素,使得数组上的元素在正确的位置上。 +Ҫ˼ͨԪأʹϵԪȷλϡ -遍历数组,如果第 i 位上的元素不是 i + 1 ,那么就交换第 i 位 和 nums[i] - 1 位上的元素,使得 num[i] - 1 的元素为 nums[i] ,也就是该位的元素是正确的。交换操作需要循环进行,因为一次交换没办法使得第 i 位上的元素是正确的。但是要交换的两个元素可能就是重复元素,那么循环就可能永远进行下去,终止循环的方法是加上 nums[i] != nums[nums[i] - 1 条件。 +飬 i λϵԪز i + 1 ôͽ i λ nums[i] - 1 λϵԪأʹ num[i] - 1 ԪΪ nums[i] ҲǸλԪȷġҪѭУΪһνû취ʹõ i λϵԪȷġҪԪؿܾظԪأôѭͿԶȥֹѭķǼ nums[i] != nums[nums[i] - 1 -类似题目: +Ŀ -- [Leetcode :448. Find All Numbers Disappeared in an Array (Easy)](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/),寻找所有丢失的元素 -- [Leetcode : 442. Find All Duplicates in an Array (Medium)](https://leetcode.com/problems/find-all-duplicates-in-an-array/description/),寻找所有重复的元素。 +- [Leetcode :448. Find All Numbers Disappeared in an Array (Easy)](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/)ѰжʧԪ +- [Leetcode : 442. Find All Duplicates in an Array (Medium)](https://leetcode.com/problems/find-all-duplicates-in-an-array/description/)ѰظԪء ```java public int[] findErrorNums(int[] nums) { @@ -3418,11 +3416,11 @@ private void swap(int[] nums, int i, int j){ } ``` -**找出数组中重复的数,数组值在 [0, n-1] 之间** +**ҳظֵ [0, n-1] ֮** [Leetcode : 287. Find the Duplicate Number (Medium)](https://leetcode.com/problems/find-the-duplicate-number/description/) -二分查找解法: +ֲҽⷨ ```java public int findDuplicate(int[] nums) { @@ -3440,7 +3438,7 @@ public int findDuplicate(int[] nums) { } ``` -双指针解法,类似于有环链表中找出环的入口: +˫ָⷨлҳڣ ```java public int findDuplicate(int[] nums) { @@ -3459,11 +3457,11 @@ public int findDuplicate(int[] nums) { } ``` -### 有序矩阵 +### -有序矩阵指的是行和列分别有序的矩阵。 +ָкзֱľ -一般可以利用有序性使用二分查找方法。 +һʹöֲҷ ```html [ @@ -3473,7 +3471,7 @@ public int findDuplicate(int[] nums) { ] ``` -**有序矩阵查找** +**** [Leetocde : 240. Search a 2D Matrix II (Medium)](https://leetcode.com/problems/search-a-2d-matrix-ii/description/) @@ -3491,7 +3489,7 @@ public boolean searchMatrix(int[][] matrix, int target) { } ``` -**有序矩阵的 Kth Element** +** Kth Element** [Leetcode : 378. Kth Smallest Element in a Sorted Matrix ((Medium))](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/) @@ -3506,9 +3504,9 @@ k = 8, return 13. ``` -解题参考:[Share my thoughts and Clean Java Code](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/discuss/85173) +ο[Share my thoughts and Clean Java Code](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/discuss/85173) -二分查找解法: +ֲҽⷨ ```java public int kthSmallest(int[][] matrix, int k) { @@ -3529,14 +3527,14 @@ public int kthSmallest(int[][] matrix, int k) { } ``` -堆解法: +ѽⷨ ```java public int kthSmallest(int[][] matrix, int k) { int m = matrix.length, n = matrix[0].length; PriorityQueue pq = new PriorityQueue(); for(int j = 0; j < n; j++) pq.offer(new Tuple(0, j, matrix[0][j])); - for(int i = 0; i < k - 1; i++) { // 小根堆,去掉 k - 1 个堆顶元素,此时堆顶元素就是第 k 的数 + for(int i = 0; i < k - 1; i++) { // Сѣȥ k - 1 ѶԪأʱѶԪؾǵ k Tuple t = pq.poll(); if(t.x == m - 1) continue; pq.offer(new Tuple(t.x + 1, t.y, matrix[t.x + 1][t.y])); @@ -3557,25 +3555,25 @@ class Tuple implements Comparable { } ``` -## 链表 +## -**判断两个链表的交点** +**жĽ** [Leetcode : 160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) ```html -A: a1 → a2 - ↘ - c1 → c2 → c3 - ↗ -B: b1 → b2 → b3 +A: a1 a2 + K + c1 c2 c3 + J +B: b1 b2 b3 ``` -要求:时间复杂度为 O(n) 空间复杂度为 O(1) +Ҫʱ临ӶΪ O(n) ռ临ӶΪ O(1) -设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。 + A ijΪ a + cB ijΪ b + c c Ϊβֳȣ֪ a + c + b = b + c + a -当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。 + A ָʵβʱ B ͷʼ Bͬأ B ָʵβʱ A ͷʼ AܿƷ A B ָͬʱʵ㡣 ```java public ListNode getIntersectionNode(ListNode headA, ListNode headB) { @@ -3589,19 +3587,19 @@ public ListNode getIntersectionNode(ListNode headA, ListNode headB) { } ``` -如果只是判断是否存在交点,那么就是另一个问题,即 编程之美:3.6 的问题。有两种解法:把第一个链表的结尾连接到第二个链表的开头,看第二个链表是否存在环;或者直接比较第一个链表最后一个节点和第二个链表最后一个节点是否相同。 +ֻжǷڽ㣬ôһ⣬ ֮3.6 ⡣ֽⷨѵһĽβӵڶĿͷڶǷڻֱӱȽϵһһڵ͵ڶһڵǷͬ -**链表反转** +**ת** [Leetcode : 206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) -头插法能够按逆序构建链表。 +ͷ巨ܹ򹹽 ```java public ListNode reverseList(ListNode head) { - ListNode newHead = null; // 设为 null ,作为新链表的结尾 + ListNode newHead = null; // Ϊ null ΪĽβ while(head != null){ ListNode nextNode = head.next; head.next = newHead; @@ -3612,11 +3610,11 @@ public ListNode reverseList(ListNode head) { } ``` -**归并两个有序的链表** +**鲢** [Leetcode : 21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) -链表和树一样,可以用递归方式来定义:链表是空节点,或者有一个值和一个指向下一个链表的指针,因此很多链表问题可以用递归来处理。 +һõݹ鷽ʽ壺ǿսڵ㣬һֵһָһָ룬˺ܶõݹ ```java public ListNode mergeTwoLists(ListNode l1, ListNode l2) { @@ -3634,7 +3632,7 @@ public ListNode mergeTwoLists(ListNode l1, ListNode l2) { } ``` -**从有序链表中删除重复节点** +**ɾظڵ** [Leetcode : 83. Remove Duplicates from Sorted List (Easy)](https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/) @@ -3646,11 +3644,11 @@ public ListNode deleteDuplicates(ListNode head) { } ``` -**回文链表** +**** [Leetcode : 234. Palindrome Linked List (Easy)](https://leetcode.com/problems/palindrome-linked-list/description/) -切成两半,把后半段反转,然后比较两半是否相等。 +г룬ѺηתȻȽǷȡ ```java public boolean isPalindrome(ListNode head) { @@ -3661,11 +3659,11 @@ public boolean isPalindrome(ListNode head) { fast = fast.next.next; } - if(fast != null){ // 偶数节点,让 slow 指向下一个节点 + if(fast != null){ // żڵ㣬 slow ָһڵ slow = slow.next; } - cut(head, slow); // 切成两个链表 + cut(head, slow); // г ListNode l1 = head, l2 = slow; l2 = reverse(l2); return isEqual(l1, l2); @@ -3697,18 +3695,18 @@ private boolean isEqual(ListNode l1, ListNode l2){ } ``` -**从链表中删除节点** +**ɾڵ** -[编程之美:3.4]() +[֮3.4]() -![](https://github.com/00000H/notes/blob/master/pics/2c968ec5-0967-49ce-ac06-f8f5c9ab33bc.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2c968ec5-0967-49ce-ac06-f8f5c9ab33bc.jpg) ```java B.val = C.val; B.next = C.next; ``` -**链表元素按奇偶聚集** +**Ԫذżۼ** [Leetcode : 328. Odd Even Linked List (Medium)](https://leetcode.com/problems/odd-even-linked-list/description/) @@ -3729,13 +3727,13 @@ public ListNode oddEvenList(ListNode head) { } ``` -## 树 +## -### 递归 +### ݹ -一棵树要么是空树,要么有两个指针,每个指针指向一棵树。树是一种递归结构,很多树的问题可以使用递归来处理。 +һҪôǿҪôָ룬ÿָָһһֵݹṹܶʹõݹ -**树的高度** +**ĸ߶** [Leetcode : 104. Maximum Depth of Binary Tree (Easy)](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) @@ -3746,21 +3744,21 @@ public int maxDepth(TreeNode root) { } ``` -**翻转树** +**ת** [Leetcode : 226. Invert Binary Tree (Easy)](https://leetcode.com/problems/invert-binary-tree/description/) ```java public TreeNode invertTree(TreeNode root) { if(root == null) return null; - TreeNode left = root.left; // 后面的操作会改变 left 指针,因此先保存下来 + TreeNode left = root.left; // IJı left ָ룬ȱ root.left = invertTree(root.right); root.right = invertTree(left); return root; } ``` -**归并两棵树** +**鲢** [Leetcode : 617. Merge Two Binary Trees (Easy)](https://leetcode.com/problems/merge-two-binary-trees/description/) @@ -3776,11 +3774,11 @@ public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { } ``` -**判断路径和是否等于一个数** +**ж·Ƿһ** [Leetcdoe : 112. Path Sum (Easy)](https://leetcode.com/problems/path-sum/description/) -题目描述:路径和定义为从 root 到 leaf 的所有节点的和 +Ŀ·ͶΪ root leaf нڵĺ ```java public boolean hasPathSum(TreeNode root, int sum) { @@ -3790,13 +3788,13 @@ public boolean hasPathSum(TreeNode root, int sum) { } ``` -**统计路径和等于一个数的路径数量** +**ͳ·͵һ·** [Leetcode : 437. Path Sum III (Easy)](https://leetcode.com/problems/path-sum-iii/description/) -题目描述:路径不一定以 root 开头并以 leaf 结尾,但是必须连续 +Ŀ·һ root ͷ leaf βDZ -pathSumStartWithRoot() 方法统计以某个节点开头的路径个数。 +pathSumStartWithRoot() ͳijڵ㿪ͷ· ```java public int pathSum(TreeNode root, int sum) { @@ -3814,7 +3812,7 @@ private int pathSumStartWithRoot(TreeNode root, int sum){ } ``` -**树的对称** +**ĶԳ** [Leetcode : 101. Symmetric Tree (Easy)](https://leetcode.com/problems/symmetric-tree/description/) @@ -3832,11 +3830,11 @@ private boolean isSymmetric(TreeNode t1, TreeNode t2){ } ``` -**平衡树** +**ƽ** [Leetcode : 110. Balanced Binary Tree (Easy)](https://leetcode.com/problems/balanced-binary-tree/description/) -题目描述:左右子树高度差是否都小于等于 1 +Ŀ߶ȲǷСڵ 1 ```java private boolean result = true; @@ -3855,11 +3853,11 @@ public int maxDepth(TreeNode root) { } ``` -**最小路径** +**С·** [Leetcode : 111. Minimum Depth of Binary Tree (Easy)](https://leetcode.com/problems/minimum-depth-of-binary-tree/description/) -题目描述:树的根节点到叶子节点的最小长度 +Ŀĸڵ㵽ҶӽڵС ```java public int minDepth(TreeNode root) { @@ -3871,7 +3869,7 @@ public int minDepth(TreeNode root) { } ``` -**统计左叶子节点的和** +**ͳҶӽڵĺ** [Leetcode : 404. Sum of Left Leaves (Easy)](https://leetcode.com/problems/sum-of-left-leaves/description/) @@ -3888,11 +3886,11 @@ private boolean isLeaf(TreeNode node){ } ``` -**修剪一棵树** +**޼һ** [Leetcode : 669. Trim a Binary Search Tree (Easy)](https://leetcode.com/problems/trim-a-binary-search-tree/description/) -题目描述:只保留值在 L \~ R 之间的节点 +Ŀֵֻ L \~ R ֮Ľڵ ```java public TreeNode trimBST(TreeNode root, int L, int R) { @@ -3905,7 +3903,7 @@ public TreeNode trimBST(TreeNode root, int L, int R) { } ``` -**子树** +**** [Leetcode : 572. Subtree of Another Tree (Easy)](https://leetcode.com/problems/subtree-of-another-tree/description/) @@ -3925,11 +3923,11 @@ private boolean isSame(TreeNode s, TreeNode t){ } ``` -**从有序数组中构造二叉查找树** +**й** [Leetcode : 108. Convert Sorted Array to Binary Search Tree (Easy)](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) -二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。 +BSTڵڵнڵ㣬Сڵнڵ㡣 ```java public TreeNode sortedArrayToBST(int[] nums) { @@ -3946,7 +3944,7 @@ private TreeNode toBST(int[] nums, int sIdx, int eIdx){ } ``` -**两节点的最长路径** +**ڵ·** ```html 1 @@ -3977,7 +3975,7 @@ private int depth(TreeNode root) { } ``` -**找出二叉树中第二小的节点** +**ҳеڶСĽڵ** [Leetcode : 671. Second Minimum Node In a Binary Tree (Easy)](https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/description/) @@ -3992,7 +3990,7 @@ Input: Output: 5 ``` -一个节点要么具有 0 个或 2 个子节点,如果有子节点,那么根节点是最小的节点。 +һڵҪô 0 2 ӽڵ㣬ӽڵ㣬ôڵСĽڵ㡣 ```java public int findSecondMinimumValue(TreeNode root) { @@ -4008,7 +4006,7 @@ public int findSecondMinimumValue(TreeNode root) { } ``` -**寻找两个节点的最近公共祖先** +**Ѱڵ** [Leetcode : 235. Lowest Common Ancestor of a Binary Search Tree (Easy)](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/) @@ -4020,7 +4018,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { } ``` -**最近公共祖先** +**** [Leetcode : 236. Lowest Common Ancestor of a Binary Tree (Medium) ](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/) @@ -4033,7 +4031,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { } ``` -**最大相同节点值的路径长度** +**ͬڵֵ·** [Leetcode : 687. Longest Univalue Path (Easy)](https://pomotodo.com/app/) @@ -4065,7 +4063,7 @@ private int dfs(TreeNode root){ } ``` -**间隔遍历** +**** [Leetcode : 337. House Robber III (Medium)](https://leetcode.com/problems/house-robber-iii/description/) @@ -4084,11 +4082,11 @@ public int rob(TreeNode root) { } ``` -### 层次遍历 +### α -使用 BFS,不需要使用两个队列来分别存储当前层的节点和下一层的节点, 因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 +ʹ BFSҪʹֱ洢ǰĽڵһĽڵ㣬 ΪڿʼһĽڵʱǰеĽڵǵǰĽڵֻҪƱôڵܱ֤αĶǵǰĽڵ㡣 -**计算一棵树每层节点的平均数** +**һÿڵƽ** [637. Average of Levels in Binary Tree (Easy)](https://leetcode.com/problems/average-of-levels-in-binary-tree/description/) @@ -4113,7 +4111,7 @@ public List averageOfLevels(TreeNode root) { } ``` -**得到左下角的节点** +**õ½ǵĽڵ** [Leetcode : 513. Find Bottom Left Tree Value (Easy)](https://leetcode.com/problems/find-bottom-left-tree-value/description/) @@ -4130,7 +4128,7 @@ public int findBottomLeftValue(TreeNode root) { } ``` -### 前中后序遍历 +### ǰк ```html 1 @@ -4140,16 +4138,16 @@ public int findBottomLeftValue(TreeNode root) { 4 5 6 ``` -层次遍历顺序:[1 2 3 4 5 6] -前序遍历顺序:[1 2 4 5 3 6] -中序遍历顺序:[4 2 5 1 3 6] -后序遍历顺序:[4 5 2 6 3 1] +α˳[1 2 3 4 5 6] +ǰ˳[1 2 4 5 3 6] +˳[4 2 5 1 3 6] +˳[4 5 2 6 3 1] -层次遍历使用 BFS 实现,利用的就是 BFS 一层一层遍历的特性;而前序、中序、后序遍历利用了 DFS 实现。 +αʹ BFS ʵ֣õľ BFS һһԣǰ򡢺 DFS ʵ֡ -前序、中序、后序遍只是在对节点访问的顺序有一点不同,其它都相同。 +ǰ򡢺ֻڶԽڵʵ˳һ㲻ͬͬ -① 前序 + ǰ ```java void dfs(TreeNode root){ @@ -4159,7 +4157,7 @@ void dfs(TreeNode root){ } ``` -② 中序 + ```java void dfs(TreeNode root){ @@ -4169,7 +4167,7 @@ void dfs(TreeNode root){ } ``` -③ 后序 + ```java void dfs(TreeNode root){ @@ -4179,7 +4177,7 @@ void dfs(TreeNode root){ } ``` -**非递归实现二叉树的前序遍历** +**ǵݹʵֶǰ** [Leetcode : 144. Binary Tree Preorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-preorder-traversal/description/) @@ -4193,17 +4191,17 @@ public List preorderTraversal(TreeNode root) { TreeNode node = stack.pop(); ret.add(node.val); if (node.right != null) stack.push(node.right); - if (node.left != null) stack.push(node.left); // 先添加右子树再添加左子树,这样是为了让左子树在栈顶 + if (node.left != null) stack.push(node.left); // Ϊջ } return ret; } ``` -**非递归实现二叉树的后续遍历** +**ǵݹʵֶĺ** [Leetcode : ### 145. Binary Tree Postorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-postorder-traversal/description/) -前序遍历为 root -> left -> right,后序遍历为 left -> right -> root,可以修改前序遍历成为 root -> right -> left,那么这个顺序就和后序遍历正好相反。 +ǰΪ root -> left -> rightΪ left -> right -> root޸ǰΪ root -> right -> leftô˳ͺͺ෴ ```java public List postorderTraversal(TreeNode root) { @@ -4222,7 +4220,7 @@ public List postorderTraversal(TreeNode root) { } ``` -**非递归实现二叉树的中序遍历** +**ǵݹʵֶ** [Leetcode : 94. Binary Tree Inorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-inorder-traversal/description/) @@ -4232,7 +4230,7 @@ public List inorderTraversal(TreeNode root) { Stack stack = new Stack<>(); TreeNode cur = root; while(cur != null || !stack.isEmpty()) { - while(cur != null) { // 模拟递归栈的不断深入 + while(cur != null) { // ģݹջIJ stack.add(cur); cur = cur.left; } @@ -4244,19 +4242,19 @@ public List inorderTraversal(TreeNode root) { } ``` -**使用中序遍历和前序遍历序列重建二叉树** //TODO +**ʹǰؽ** //TODO ### BST -主要利用 BST 中序遍历有序的特点。 +Ҫ BST ص㡣 -**在 BST 中寻找两个节点,使它们的和为一个给定值。** +** BST Ѱڵ㣬ʹǵĺΪһֵ** [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/) -使用中序遍历得到有序数组之后,再利用双指针对数组进行查找。 +ʹõ֮˫ָвҡ -应该注意到,这一题不能用分别在左右子树两部分来处理这种思想,因为两个待求的节点可能分别在左右子树中。 +Ӧע⵽һⲻ÷ֱ˼룬ΪĽڵֱܷС ```java public boolean findTarget(TreeNode root, int k) { @@ -4280,11 +4278,11 @@ private void inOrder(TreeNode root, List nums){ } ``` -**在 BST 中查找最小的两个节点之差的绝对值** +** BST вСڵ֮ľֵ** [Leetcode : 530. Minimum Absolute Difference in BST (Easy)](https://leetcode.com/problems/minimum-absolute-difference-in-bst/description/) -利用 BST 的中序遍历为有序的性质,计算中序遍历中临近的两个节点之差的绝对值,取最小值。 + BST Ϊʣٽڵ֮ľֵȡСֵ ```java private int minDiff = Integer.MAX_VALUE; @@ -4304,11 +4302,11 @@ private void inorder(TreeNode node){ } ``` -**把 BST 每个节点的值都加上比它大的节点的值** +** BST ÿڵֵϱĽڵֵ** [Leetcode : Convert BST to Greater Tree (Easy)](https://leetcode.com/problems/convert-bst-to-greater-tree/description/) -先遍历右子树。 +ȱ ```java private int sum = 0; @@ -4333,7 +4331,7 @@ private void traver(TreeNode root) { } ``` -**寻找 BST 中出现次数最多的节点** +**Ѱ BST гִĽڵ** ```java private int cnt = 1; @@ -4371,11 +4369,11 @@ private void inorder(TreeNode node){ } ``` -**寻找 BST 的第 k 个元素** +**Ѱ BST ĵ k Ԫ** [Leetcode : 230. Kth Smallest Element in a BST (Medium)](https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/) -递归解法: +ݹⷨ ```java public int kthSmallest(TreeNode root, int k) { @@ -4391,7 +4389,7 @@ private int count(TreeNode node) { } ``` -中序遍历解法: +ⷨ ```java private int cnt = 0; @@ -4417,11 +4415,11 @@ private void inorder(TreeNode node, int k) { ### Trie -![](https://github.com/00000H/notes/blob/master/pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg) -Trie,又称前缀树或字典树,用于判断字符串是否存在或者是否具有某种字符串前缀。 +Trieֳǰ׺ֵжַǷڻǷijַǰ׺ -**实现一个 Trie** +**ʵһ Trie** [Leetcode : 208. Implement Trie (Prefix Tree) (Medium)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) @@ -4481,7 +4479,7 @@ class Trie { } ``` -**实现一个 Trie,用来求前缀和** +**ʵһ Trieǰ׺** [Leetcode : 677. Map Sum Pairs (Medium)](https://leetcode.com/problems/map-sum-pairs/description/) @@ -4538,13 +4536,13 @@ class MapSum { } ``` -## 图 +## ͼ -## 位运算 +## λ -**1. 基本原理** +**1. ԭ** -0s 表示 一串 0 ,1s 表示一串 1。 +0s ʾ һ 0 1s ʾһ 1 ``` x ^ 0s = x x & 0s = 0 x | 0s = x @@ -4552,33 +4550,33 @@ x ^ 1s = \~x x & 1s = x x | 1s = 1s x ^ x = 0 x & x = x x | x = x ``` -① 利用 x ^ 1s = \~x 的特点,可以将位级表示翻转;利用 x ^ x = 0 的特点,可以将三个数中重复的两个数去除,只留下另一个数; -② 利用 x & 0s = 0 和 x & 1s = x 的特点,可以实现掩码操作。一个数 num 与 mask :00111100 进行位与操作,只保留 num 中与 mask 的 1 部分相对应的位; -③ 利用 x | 0s = x 和 x | 1s = 1s 的特点,可以实现设置操作。一个数 num 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1 。 + x ^ 1s = \~x ص㣬Խλʾת x ^ x = 0 ص㣬Խظȥֻһ + x & 0s = 0 x & 1s = x ص㣬ʵһ num mask 00111100 λֻ num mask 1 Ӧλ + x | 0s = x x | 1s = 1s ص㣬ʵòһ num mask00111100 λ num mask 1 ӦλΪ 1 -\>\> n 为算术右移,相当于除以 2n; -\>\>\> n 为无符号右移,左边会补上 0。 -<< n 为算术左移,相当于乘以 2n。 +\>\> n Ϊƣ൱ڳ 2n +\>\>\> n Ϊ޷ƣ߻Ჹ 0 +<< n Ϊƣ൱ڳ 2n -n&(n-1) 该位运算是去除 n 的位级表示中最低的那一位。例如对于二进制表示 10110**100**,减去 1 得到 10110**011**,这两个数相与得到 10110**000**。 +n&(n-1) λȥ n λʾ͵һλڶƱʾ 10110**100**ȥ 1 õ 10110**011**õ 10110**000** -n-n&(\~n+1) 概运算是去除 n 的位级表示中最高的那一位。 +n-n&(\~n+1) ȥ n λʾߵһλ -n&(-n) 该运算得到 n 的位级表示中最低的那一位。-n 得到 n 的反码加 1,对于二进制表示 10110**100**,-n 得到 01001**100**,相与得到 00000**100** +n&(-n) õ n λʾ͵һλ-n õ n ķ 1ڶƱʾ 10110**100**-n õ 01001**100**õ 00000**100** -**2. mask 计算** +**2. mask ** -要获取 111111111,将 0 取反即可,\~0。 +Ҫȡ 111111111 0 ȡɣ\~0 -要得到只有第 i 位为 1 的 mask,将 1 向左移动 i 位即可,1<<i 。例如 1<<5 得到只有第 5 位为 1 的 mask :00010000。 +Ҫõֻе i λΪ 1 mask 1 ƶ i λɣ1<<i 1<<5 õֻе 5 λΪ 1 mask 00010000 -要得到 1 到 i 位为 1 的 mask,1<<(i+1)-1 即可,例如将 1<<(4+1)-1 = 00010000-1 = 00001111。 +Ҫõ 1 i λΪ 1 mask1<<(i+1)-1 ɣ罫 1<<(4+1)-1 = 00010000-1 = 00001111 -要得到 1 到 i 位为 0 的 mask,只需将 1 到 i 位为 1 的 mask 取反,即 \~(1<<(i+1)-1)。 +Ҫõ 1 i λΪ 0 maskֻ轫 1 i λΪ 1 mask ȡ \~(1<<(i+1)-1) -**3. 位操作举例** +**3. λ** -① 获取第 i 位 + ȡ i λ num & 00010000 != 0 @@ -4586,7 +4584,7 @@ num & 00010000 != 0 (num & (1 << i)) != 0; ``` -② 将第 i 位设置为 1 + i λΪ 1 num | 00010000 @@ -4594,7 +4592,7 @@ num | 00010000 num | (1 << i); ``` -③ 将第 i 位清除为 0 + i λΪ 0 num & 11101111 @@ -4602,7 +4600,7 @@ num & 11101111 num & (\~(1 << i)) ``` -④ 将最高位到第 i 位清除为 0 + λ i λΪ 0 num & 00001111 @@ -4610,7 +4608,7 @@ num & 00001111 num & ((1 << i) - 1); ``` -⑤ 将第 0 位到第 i 位清除为 0 + 0 λ i λΪ 0 num & 11110000 @@ -4618,27 +4616,27 @@ num & 11110000 num & (\~((1 << (i+1)) - 1)); ``` -⑥ 将第 i 位设置为 0 或者 1 + i λΪ 0 1 -先将第 i 位清零,然后将 v 左移 i 位,执行“位或”运算。 +Ƚ i λ㣬Ȼ v i λִСλ㡣 ```java (num & (1 << i)) | (v << i); ``` -**4. Java 中的位操作** +**4. Java еλ** ```html -static int Integer.bitCount() // 统计 1 的数量 -static int Integer.highestOneBit() // 获得最高位 -static String toBinaryString(int i) // 转换位二进制表示的字符串 +static int Integer.bitCount() // ͳ 1 +static int Integer.highestOneBit() // λ +static String toBinaryString(int i) // תλƱʾַ ``` -**统计两个数的二进制表示有多少位不同** +**ͳĶƱʾжλͬ** [Leetcode : 461. Hamming Distance (Easy)](https://leetcode.com/problems/hamming-distance/) -对两个数进行异或操作,不同的那一位结果为 1 ,统计有多少个 1 即可。 +ͬһλΪ 1 ͳжٸ 1 ɡ ```java public int hammingDistance(int x, int y) { @@ -4652,7 +4650,7 @@ public int hammingDistance(int x, int y) { } ``` -可以使用 Integer.bitcount() 来统计 1 个的个数。 +ʹ Integer.bitcount() ͳ 1 ĸ ```java public int hammingDistance(int x, int y) { @@ -4660,7 +4658,7 @@ public int hammingDistance(int x, int y) { } ``` -**翻转一个数的比特位** +**תһıλ** [Leetcode : 190. Reverse Bits (Easy)](https://leetcode.com/problems/reverse-bits/description/) @@ -4676,9 +4674,9 @@ public int reverseBits(int n) { } ``` -**不用额外变量交换两个整数** +**ö** -[程序员代码面试指南 :P317](#) +[Աָ P317](#) ```java a = a ^ b; @@ -4686,13 +4684,13 @@ b = a ^ b; a = a ^ b; ``` -将 c = a ^ b,那么 b ^ c = b ^ b ^ a = a,a ^ c = a ^ a ^ b = b。 + c = a ^ bô b ^ c = b ^ b ^ a = aa ^ c = a ^ a ^ b = b -**判断一个数是不是 4 的 n 次方** +**жһDz 4 n η** [Leetcode : 342. Power of Four (Easy)](https://leetcode.com/problems/power-of-four/) -该数二进制表示有且只有一个奇数位为 1 ,其余的都为 0 ,例如 16 : 10000。可以每次把 1 向左移动 2 位,就能构造出这种数字,然后比较构造出来的数与要判断的数是否相同。 +ƱʾֻһλΪ 1 ĶΪ 0 16 10000ÿΰ 1 ƶ 2 λܹ֣ȻȽϹҪжϵǷͬ ```java public boolean isPowerOfFour(int num) { @@ -4705,7 +4703,7 @@ public boolean isPowerOfFour(int num) { } ``` -也可以用 Java 的 Integer.toString() 方法将该数转换为 4 进制形式的字符串,然后判断字符串是否以 1 开头。 +Ҳ Java Integer.toString() תΪ 4 ʽַȻжַǷ 1 ͷ ```java public boolean isPowerOfFour(int num) { @@ -4713,11 +4711,11 @@ public boolean isPowerOfFour(int num) { } ``` -**判断一个数是不是 2 的 n 次方** +**жһDz 2 n η** [Leetcode : 231. Power of Two (Easy)](https://leetcode.com/problems/power-of-two/description/) -同样可以用 Power of Four 的方法,但是 2 的 n 次方更特殊,它的二进制表示只有一个 1 存在。 +ͬ Power of Four ķ 2 n η⣬ĶƱʾֻһ 1 ڡ ```java public boolean isPowerOfTwo(int n) { @@ -4725,7 +4723,7 @@ public boolean isPowerOfTwo(int n) { } ``` -利用 1000 & 0111 == 0 这种性质,得到以下解法: + 1000 & 0111 == 0 ʣõ½ⷨ ```java public boolean isPowerOfTwo(int n) { @@ -4733,13 +4731,13 @@ public boolean isPowerOfTwo(int n) { } ``` -**数组中唯一一个不重复的元素** +**ΨһһظԪ** [Leetcode : 136. Single Number (Easy)](https://leetcode.com/problems/single-number/description/) -两个相同的数异或的结果为 0,对所有数进行异或操作,最后的结果就是单独出现的那个数。 +ͬĽΪ 0ĽǵֵǸ -类似的有:[Leetcode : 389. Find the Difference (Easy)](https://leetcode.com/problems/find-the-difference/description/),两个字符串仅有一个字符不相同,使用异或操作可以以 O(1) 的空间复杂度来求解,而不需要使用 HashSet。 +ƵУ[Leetcode : 389. Find the Difference (Easy)](https://leetcode.com/problems/find-the-difference/description/)ַһַͬʹ O(1) Ŀռ临Ӷ⣬Ҫʹ HashSet ```java public int singleNumber(int[] nums) { @@ -4749,22 +4747,22 @@ public int singleNumber(int[] nums) { } ``` -**数组中不重复的两个元素** +**вظԪ** [Leetcode : 260. Single Number III (Medium)](https://leetcode.com/problems/single-number-iii/description/) -两个不相等的元素在位级表示上必定会有一位存在不同。 +ȵԪλʾϱضһλڲͬ -将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。 +ԪõĽΪظԪĽ -diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。 +diff &= -diff õ diff Ҳ಻Ϊ 0 λҲDzظԪλʾҲ಻ͬһλһλͿԽԪֿ ```java public int[] singleNumber(int[] nums) { int diff = 0; for(int num : nums) diff ^= num; - // 得到最右一位 + // õһλ diff &= -diff; int[] ret = new int[2]; for(int num : nums) { @@ -4775,11 +4773,11 @@ public int[] singleNumber(int[] nums) { } ``` -**判断一个数的位级表示是否不会出现连续的 0 和 1** +**жһλʾǷ񲻻 0 1** [Leetcode : 693. Binary Number with Alternating Bits (Easy)](https://leetcode.com/problems/binary-number-with-alternating-bits/description/) -对于 10101 这种位级表示的数,把它向右移动 1 位得到 1010 ,这两个数每个位都不同,因此异或得到的结果为 11111。 + 10101 λʾƶ 1 λõ 1010 ÿλͬõĽΪ 11111 ```java public boolean hasAlternatingBits(int n) { @@ -4788,13 +4786,13 @@ public boolean hasAlternatingBits(int n) { } ``` -**求一个数的补码** +**һIJ** [Leetcode : 476. Number Complement (Easy)](https://leetcode.com/problems/number-complement/description/) -不考虑二进制表示中的首 0 部分 +ǶƱʾе 0 -对于 00000101,要求补码可以将它与 00000111 进行异或操作。那么问题就转换为求掩码 00000111。 + 00000101ҪԽ 00000111 ôתΪ 00000111 ```java public int findComplement(int num) { @@ -4806,7 +4804,7 @@ public int findComplement(int num) { } ``` -可以利用 Java 的 Integer.highestOneBit() 方法来获得含有首 1 的数。 + Java Integer.highestOneBit() ú 1 ```java public int findComplement(int num) { @@ -4817,7 +4815,7 @@ public int findComplement(int num) { } ``` -对于 10000000 这样的数要扩展成 11111111,可以利用以下方法: + 10000000 Ҫչ 11111111· ```html mask |= mask >> 1 11000000 @@ -4837,11 +4835,11 @@ public int findComplement(int num) { } ``` -**实现整数的加法** +**ʵļӷ** [Leetcode : 371. Sum of Two Integers (Easy)](https://leetcode.com/problems/sum-of-two-integers/description/) -a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。 +a ^ b ʾûпǽλĺͣ(a & b) << 1 ǽλݹֹԭ (a & b) << 1 ұ߻һ 0ôݹ飬λұߵ 0 ࣬λΪ 0ݹֹ ```java public int getSum(int a, int b) { @@ -4849,17 +4847,17 @@ public int getSum(int a, int b) { } ``` -**实现整数乘法** +**ʵ˷** -[程序员代码面试指南 P319](#) +[Աָ P319](#) -**字符串数组最大乘积** +**ַ˻** [Leetcode : 318. Maximum Product of Word Lengths (Medium)](https://leetcode.com/problems/maximum-product-of-word-lengths/description/) -题目描述:字符串数组的字符串只含有小写字符。求解字符串数组中两个字符串长度的最大乘积,要求这两个字符串不能含有相同字符。 +ĿַַֻСдַַַȵ˻Ҫַַܺͬ -解题思路:本题主要问题是判断两个字符串是否含相同字符,由于字符串只含有小写字符,总共 26 位,因此可以用一个 32 位的整数来存储每个字符是否出现过。 +˼·ҪжַǷַַֻͬСдַܹ 26 λ˿һ 32 λ洢ÿַǷֹ ```java public int maxProduct(String[] words) { @@ -4883,26 +4881,14 @@ public int maxProduct(String[] words) { } ``` -# 其它 - -## 注意细节 - -- 从功能测试、边界测试和负面测试来考虑输入。 - -- 两个浮点数比较是否相等不直接使用 == - -```java -Math.abs(a - b) <= 0; -``` - -# 参考资料 +# ο - [Leetcode](https://leetcode.com/problemset/algorithms/?status=Todo) -- 剑指 Offer -- 程序员面试金典 -- 编程之美 -- 程序员代码面试指南 -- 数据结构与算法分析 -- 算法 -- 王道论坛计算机考研机试指南 +- ָ Offer +- ԱԽ +- ֮ +- Աָ +- ݽṹ㷨 +- 㷨 +- ̳лָ diff --git a/notes/Linux.md b/notes/Linux.md new file mode 100644 index 00000000..dc817fd6 --- /dev/null +++ b/notes/Linux.md @@ -0,0 +1,1071 @@ + +* [òԼ](#òԼ) + * [](#) + * [ػ](#ػ) + * [鿴](#鿴) + * [鿴˿](#鿴˿) + * [PATH](#path) + * [еȼ](#еȼ) + * [sudo](#sudo) + * [GNU](#gnu) + * [](#) + * [а汾](#а汾) +* [](#) + * [̵ļ](#̵ļ) + * [](#) + * [1. MBR](#1-mbr) + * [2. GPT](#2-gpt) + * [](#) + * [1. BIOS](#1-bios) + * [2. UEFI](#2-uefi) + * [](#) +* [ļȨĿ¼](#ļȨĿ¼) + * [ļȨ޸](#ļȨ޸) + * [ļԼȨ޵޸](#ļԼȨ޵޸) + * [1. ޸ļȺ](#1-޸ļȺ) + * [2. ޸ļӵ](#2-޸ļӵ) + * [3. ޸Ȩ](#3-޸Ȩ) + * [Ŀ¼Ȩ](#Ŀ¼Ȩ) + * [ļĬȨ](#ļĬȨ) + * [Ŀ¼](#Ŀ¼) +* [ļĿ¼](#ļĿ¼) + * [ļʱ](#ļʱ) + * [ļĿ¼Ļ](#ļĿ¼Ļ) + * [1. ls](#1-ls) + * [2. cp](#2-cp) + * [3. rm](#3-rm) + * [4. mv](#4-mv) + * [ȡļ](#ȡļ) + * [1. cat](#1-cat) + * [2. tac](#2-tac) + * [3. more](#3-more) + * [4. less](#4-less) + * [5. head](#5-head) + * [6. tail](#6-tail) + * [7. od](#7-od) + * [8. touch](#8-touch) + * [ָļ](#ָļ) + * [1. which](#1-which) + * [2. whereis](#2-whereis) + * [3. locate](#3-locate) + * [4. find](#4-find) + * [4.1 ʱйصѡ](#41-ʱйصѡ) + * [4.2 ļӵߺȺйصѡ](#42-ļӵߺȺйصѡ) + * [4.3 ļȨ޺йصѡ](#43-ļȨ޺йصѡ) +* [ļϵͳ](#ļϵͳ) + * [ļϵͳ](#ļϵͳ) + * [inode](#inode) + * [Ŀ¼ inode block](#Ŀ¼-inode--block) + * [ʵ](#ʵ) + * [1. ʵ](#1-ʵ) + * [2. ](#2-) +* [ѹ](#ѹ) + * [ѹ](#ѹ) + * [1. gzip](#1-gzip) + * [2. bzip2](#2-bzip2) + * [3. xz](#3-xz) + * [](#) +* [BASH](#bash) + * [Bash](#bash) + * [](#) + * [ָ˳](#ָ˳) + * [ض](#ض) + * [ָ](#ָ) + * [1. ȡָcut](#1-ȡָcut) + * [2. sortuniq](#2-sortuniq) + * [3. ˫ضtee](#3-˫ضtee) + * [4. ַתָtrcolexpandjoinpaste](#4-ַתָtrcolexpandjoinpaste) + * [5. ָsplit](#5-ָsplit) +* [ʾļʽ](#ʾļʽ) + * [grep](#grep) + * [printf](#printf) + * [awk](#awk) +* [vim ģʽ](#vim-ģʽ) +* [ο](#ο) + + +# òԼ + +## + +**1. --help** + +ָĻ÷ѡܡ + +**2. man** + +man manual дָľϢʾ + +ִ man date ʱ DATE(1) ֣еִָͣõּ£ + +| | | +| -- | -- | +| 1 | û shell пԲָ߿ִļ | +| 5 | ļ | +| 8 | ϵͳԱʹõĹָ | + +**3. info** + +info man ƣ info ĵֳһҳ棬ÿҳԽת + +## ػ + +**1. ͬд sync** + +Ϊ˼ӿԴļĶдٶȣλڴеļݲͬϣ˹ػ֮ǰҪȽ sync ͬ + +**2. shutdown** + +```html +# /sbin/shutdown [-krhc] [ʱ] [ѶϢ] +-k ػֻǷ;ѶϢ֪ͨߵû +-r ϵͳķͣ +-h ϵͳķͣػ +-c ȡѾڽе shutdown ָ +``` + +**3. ػָ** + +reboothaltpoweroff + +## 鿴 + +ps ָ + +鿴 theadx Ϣ + +```html +ps aux | grep threadx +``` + +## 鿴˿ + +netstat ָ + +鿴˿ 80 Ƿռã + +```html +netstat -anp | grep 80 +``` + +## PATH + +ڻ PATH ִļ··֮ : ָ + +```html +/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin +``` + +## еȼ + +0ػģʽ +1ûģʽƽroot룩 +2ֵ֧Ķûģʽ +3ֵ֧Ķûģʽıģʽõģʽ +4δʹ +5ֵ֧ X-windows ֶ֧ûģʽ棩 +6ϵͳ + +## sudo + +ʹ sudo һûʹ root ִеû /etc/sudoers вʹøָ + +## GNU + +GNU ƻΪūƻĿǴһȫɵIJϵͳΪ GNUȫ GPL ʽ GPL ȫΪ GNU ͨùЭ飬ݣ + +- κĿд˳ɣ +- ٸƵɣ +- Ľ˳򣬲Ľɡ + +## + +RPM DPKG ΪߡRPM ȫΪ Redhat Package Manager Red Hat ˾ƶʵʩ GNU ԴϵͳܲΪܶ Linux ϵͳ (RHEL) ļȶ׼ RPM оǻ Debian ϵͳ (UBUNTU) DEB ߣ DPKGȫΪ Debian Packageܷ RPM ơ + +YUM RPM ߣָܹԴռ䣨Ŀ¼ȣԶĿ RPM ҰװܣԶϵءװ뷱ֶءװÿһҪ⣬YUM һǽϵͳ + +## а汾 + +Linux аԤȼɺõ Linux ں˼Ӧ + +** DPKG** + +ҵа + +- Ubuntu + +а + +- Debian + +** RPM** + +ҵа + +- Red Hat + +а + +- Fedora +- CentOS + +# + +## ̵ļ + +Linux ÿӲһļ + +̵ļ + +- SCSI/SATA/USB ̣/dev/sd[a-p] +- IDE ̣/dev/hd[a-d] + +ļŵȷ̲˳йأIJλ޹ء + +## + +̷Ҫָʽһƽ϶ MBR һǽƽٵ GPT + +### 1. MBR + +MBR УһҪУҪ¼Master boot record, MBRpartition table MBR ռ 446 bytespartition table ռ 64 bytes + +ֻ 64 bytesֻܴ洢 4 4 ΪPrimaryչExtendedչֻһռ¼Լ¼ķͨչԷֳ֣ЩΪ߼ + +Linux ҲѷļļʽΪļ+ţ /dev/sda1ע⣬߼ıŴ 5 ʼ + +### 2. GPT + +ͬĴвͬС 512bytes ´̵ 4kGPT Ϊ˼д̣ڶʹ߼ַLogical Block Address, LBA + +GPT 1 ¼ MBR 33 ¼Ϣ 33 ڶԷϢбݡ + +GPT ûչԷ 128 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a5c25452-6fa5-49e7-9322-823077442775.jpg) + +## + +### 1. BIOS + +BIOS ǿʱִеĵһ֪ԿĴ̣ȡ̵һ MBR MBR ִеĿĻزϵͳĺļ + +MBR еĿṩ¹ܣѡļԼתתܿʵ˶ֻҪһϵͳĿװϣ MBR еĿʱͿѡǰIJϵͳתӶһϵͳ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f900f266-a323-42b2-bc43-218fdb8811a8.jpg) + +װȰװ Windows ٰװ LinuxΪװ Windows ʱḲǵ MBR Linux ѡ񽫿װ MBR ҿÿѡ + +### 2. UEFI + +UEFI BIOS ˵ܸΪȫ棬ҲΪȫ + +## + +Ŀ¼ΪĽ㣬Ҳ˵Ŀ¼֮ͿԶȡݡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/249f3bb1-feee-4805-a259-a72699d638ca.jpg) + +# ļȨĿ¼ + +## ļȨ޸ + +ûΪ֣ļӵߡȺԼˣԲͬûвͬļȨޡ + +ʹ ls 鿴һļʱһļϢ drwxr-xr-x. 3 root root 17 May 6 00:14 .configݵĽ£ + +- drwxr-xr-xļԼȨޣ 1 λΪļֶΣ 9 λΪļȨֶΡ +- 3 +- rootļӵߣ +- rootȺ飻 +- 17ļС +- May 6 00:14ļ޸ĵʱ䣻 +- .configļ + +ļͼ京У + +- dĿ¼ +- -ļ +- lļ + +9 λļȨֶУÿ 3 Ϊһ飬 3 飬ÿһֱļӵߡȺԼ˵ļȨޡһȨе 3 λֱΪ rwx ȨޣʾɶдִС + +## ļԼȨ޵޸ + +### 1. ޸ļȺ + +```html +# chgrp [-R] groupname dirname/filename +-Rݹ޸ +``` + +### 2. ޸ļӵ + +޸ļӵߣҲ޸ļȺ顣 + +```html +# chown [-R] û:Ⱥ dirname/filename +``` + +### 3. ޸Ȩ + +ԽһȨʾʱһȨ޵ 3 λֵλÿλȨֵΪ 421ÿȨ޶ӦȨֵΪ r4w2x1 + +```html +# chmod [-R] xyz dirname/filename +``` + + .bashrc ļȨ޸Ϊ -rwxr-xr-- + +```html +# chmod 754 .bashrc +``` + +Ҳʹ÷趨Ȩޡ + +```html +# chmod [ugoa] [+-=] [rwx] dirname/filename +- uӵ +- gȺ +- o +- a +- +Ȩ +- -ƳȨ +- =趨Ȩ +``` + +Ϊ .bashrc ļûдȨޡ + +```html +# chmod a+w .bashrc +``` + +## Ŀ¼Ȩ + +ļǴ洢һļУǴ洢һļڵĿ¼Сˣӵļ w Ȩ޲ܶļ޸ġ + +Ŀ¼洢ļбһĿ¼ȨҲǶļбȨޡˣĿ¼ r ȨޱʾԶȡļбw Ȩޱʾ޸ļб˵ɾļļ޸ģx Ȩ޿øĿ¼ΪĿ¼x Ȩ r w Ȩ޵ĻʹһĿ¼ΪĿ¼Ҳû취ȡļбԼļб޸ˡ + +## ļĬȨ + +ļĬȨޣļĬûпִȨޣΪ 666 Ҳ -rw-rw-rw- +Ŀ¼ĬȨޣĿ¼Ҫܹ룬ҲDZӵпִȨޣΪ 777 Ҳ drwxrwxrwx + +ͨ umask û߲鿴ļĬȨޣͨʽʾ 002 ʾûȨȥһ 2 ȨޣҲдȨޣ˽ļʱĬϵȨΪ -rw-rw-r-- + +## Ŀ¼ + +Ϊʹͬ Linux а汾Ŀ¼ṹһԣFilesystem Hierarchy Standard (FHS) 涨 Linux Ŀ¼ṹĿ¼£ + +- / (root, Ŀ¼) +- /usr (unix software resource)ϵͳĬᰲװĿ¼ +- /var (variable)ϵͳйеļ + +Ŀ¼£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/27ace615-558f-4dfb-8ad4-7ac769c10118.jpg) + +# ļĿ¼ + +## ļʱ + +1. modification time (mtime)ļݸ¾ͻ£ +2. status time (ctime)ļ״̬Ȩޡԣ¾ͻ£ +3. access time (atime)ȡļʱͻ¡ + +## ļĿ¼Ļ + +### 1. ls + +гļĿ¼ϢĿ¼Ϣаļ + +```html +# ls [-aAdfFhilnrRSt] file|dir +-a гȫļ +-d гĿ¼ +-l ԳݴгļȨ޵ȵ +``` + +### 2. cp + +Ʋ + +ԴļϣĿļһҪĿ¼С + +```html +cp [-adfilprsu] source destination +-a ൱ -dr --preserve=all ˼ dr ο˵ +-d ԴļΪļļԶļ +-i ĿļѾʱڸǰѯ +-p ͬļһƹȥ +-r ݹ +-u destination source ɲŸ destination destination ڵ²Ÿ +--preserve=all -p Ȩز⣬ SELinux , links, xattr Ҳ +``` + +### 3. rm + +Ƴ + +```html +# rm [-fir] ļĿ¼ +-r ݹɾ +``` + +### 4. mv + +ƶ + +```html +# mv [-fiu] source destination +# mv [options] source1 source2 source3 .... directory +-f force ǿƵ˼ĿļѾڣѯʶֱӸ +``` + +## ȡļ + +### 1. cat + +ȡļݡ + +```html +# cat [-AbEnTv] filename +-n ӡкţ ͬհҲкţ -b ѡͬ +``` + +### 2. tac + + cat ķһпʼӡ + +### 3. more + +һҳһҳ鿴ļݣı༭ơ + +### 4. less + + more ơ + +### 5. head + +ȡļǰС + +```html +# head [-n number] filename +-n ֣ʾе˼ +``` + +### 6. tail + + head ķֻȡǺС + +### 7. od + +ַʮƵʽʾļ + +### 8. touch + +޸ļʱ߽ļ + +```html +# touch [-acdmt] filename +-a atime +-c ctimeļ򲻽ļ +-m mtime +-d ԽµڶĿǰڣҲʹ --date="ڻʱ" +-t ԽµʱĿǰʱ䣬ʽΪ[YYYYMMDDhhmm] +``` + +## ָļ + +### 1. which + +ָ + +```html +# which [-a] command +-a ָгֻеһ +``` + +### 2. whereis + +whereis ļٶȱȽϿ죬ΪֻضĿ¼ + +```html +# whereis [-bmsu] dirname/filename +``` + +### 3. locate + +locate ùؼֻʽ + +locate ʹ /var/lib/mlocate/ ݿ洢ڴУÿһΣ޷ locate ½ļʹ updatedb ݿ⡣ + +```html +# locate [-ir] keyword +-rʽ +``` + +### 4. find + +find ʹļԺȨ޽ + +```html +# find filename [option] +``` + +#### 4.1 ʱйصѡ + +```html +-mtime n г n ǰһ޸Ĺݵļ +-mtime +n г n ֮ǰ( n 챾)޸Ĺݵļ +-mtime -n г n ֮( n 챾)޸Ĺݵļ +-newer file г file µļ +``` + ++44 -4 ָʾʱ䷶Χ£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/658fc5e7-79c0-4247-9445-d69bf194c539.png) + +#### 4.2 ļӵߺȺйصѡ + +```html +-uid n +-gid n +-user name +-group name +-nouser ӵ߲ /etc/passwd ļ +-nogroupȺ鲻 /etc/group ļ +``` + +#### 4.3 ļȨ޺йصѡ + +```html +-name filename +-size [+-]SIZEѰ SIZE Ҫ(+)С(-)ļ SIZE ĹУc: bytek: 1024bytesԣҪұ 50KBҪļ -size +50k +-type TYPE +-perm mode Ȩ޵ mode ļ +-perm -mode Ȩް mode ļ +-perm /mode Ȩްһ mode ļ +``` + +# ļϵͳ + +## ļϵͳ + +ԷиʽΪڷϽļϵͳһֻܸͨʽΪһļϵͳǴеȼԽһʽΪļϵͳֻļϵͳܱأܱء + +ļϵͳṹ + +1. superblock¼ļϵͳϢ inode block ʹʣԼļϵͳĸʽϢȣ +2. inodeһļռһ inode¼ļԣͬʱ¼ļڵ block 룻 +3. block¼ļݣļ̫ʱռö block + +Ҫȡһļʱ inode ȥļڵ blockȻ block ݶ + +Ƭָһļڵ block ڷɢ + +Ext2 ļϵͳʹļṹڴ֮ϼ block ȺĸҲǽһļϵͳΪ block Ⱥ飬 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1974a836-aa6b-4fb8-bce1-6eb11969284a.jpg) + +## inode + +Ext2 ļϵͳֵ֧ block С 1k2k 4k ֣ͬ block С˵һļĴСÿ inode Сǹ̶Ϊ 128 bytes + +inode м¼ļڵ blockÿ block dzСһļ㶼Ҫʮ blockһ inode Сޣ޷ֱô block˼ӡ˫ӡãʹ block СҲ block ¼ļ block + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/89091427-7b2b-4923-aff6-44681319a8aa.jpg) + +inode Ϣ + +- ļĴȡģʽ(read/write/excute) +- ļӵȺ(owner/group) +- ļ +- ļ״̬ıʱ(ctime) +- һεĶȡʱ(atime) +- ޸ĵʱ(mtime) +- ļԵ(flag) SetUID... +- ļݵָ (pointer) + +## Ŀ¼ inode block + +һĿ¼ʱһ inode һ blockblock ¼Ŀ¼ļ inode ԼļԿļ inode ¼ļļ¼Ŀ¼УļɾļļЩĿ¼ w Ȩйء + +## ʵ + +```html +# ln [-sf] source_filename dist_filename +-s Ĭ hard link -s Ϊ symbolic link +-f Ŀ5ļʱɾĿļ +``` + +### 1. ʵ + +hard link ֻijĿ¼һĿʹĿӵļ inode ϡɾһĿļǴڣֻҪΪ 0 + +ƣܿԽ FilesystemܶĿ¼ӡ + +```html +# ln /etc/crontab . +# ll -i /etc/crontab crontab +34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 crontab +34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab +``` + +### 2. + +symbolic link Ϊ Windows ĿݷʽͨһļļݵĶȡָӵǸļԴļɾˣļʹ򲻿ˡ + +symbolic link ΪĿ¼ӡ + +```html +# ll -i /etc/crontab /root/crontab2 +34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab +53745909 lrwxrwxrwx. 1 root root 12 Jun 23 22:31 /root/crontab2 -> /etc/crontab +``` + +# ѹ + +## ѹ + +Linux кܶѹļչ£ + +| չ | ѹ | +| -- | -- | +| \*.Z | compress | +|\*.zip | zip | +|\*.gz | gzip| +|\*.bz2 | bzip2 | +|\*.xz | xz | +|\*.tar | tar ݣûоѹ | +|\*.tar.gz | tar ļ gzip ѹ | +|\*.tar.bz2 | tar ļ bzip2 ѹ | +|\*.tar.xz | tar ļ xz ѹ | + +### 1. gzip + +gzip Linux ʹѹָԽ⿪ compresszip gzip ѹļ + + gzip ѹԴļͲˡ + + 9 ͬѹȼʹá + +ʹ zcatzmorezless ȡѹļݡ + +```html +$ gzip [-cdtv#] filename +-c ѹĻ +-d ѹ +-t ѹļǷ +-v ʾѹȵϢ +-# # Ϊֵ˼ѹȼԽѹԽߣĬΪ6 +``` + +### 2. bzip2 + +ṩ gzip ߵѹȡ + +鿴bzcatbzmorebzlessbzgrep + +```html +$ bzip2 [-cdkzv#] filename +-k Դļ +``` + +### 3. xz + +ṩ bzip2 ѵѹȡ + +Կgzipbzip2xz ѹȲŻҪע⣬ѹԽߣѹʱҲԽ + +鿴xzcatxzmorexzlessxzgrep + +```html +$ xz [-dtlkc#] filename +``` + +## + +ѹָֻܶһļѹܹļһļtar ڴҲʹ gipbzip2xz ļѹ + +```html +$ tar [-z|-j|-J] [cv] [-f ½tarļ] filename... ==ѹ +$ tar [-z|-j|-J] [tv] [-f еtarļ] ==鿴 +$ tar [-z|-j|-J] [xv] [-f еtarļ] [-C Ŀ¼] ==ѹ +-z ʹzip +-j ʹbzip2 +-J ʹxz +-c ½ļ +-t 鿴ļЩļ +-x ѹĹܣ +-v ѹ/ѹĹУʾڴļ +-f : filenameҪļ +-C Ŀ¼ ضĿ¼ѹ +``` + +õķʽ£ + +ѹ tar -jcv -f filename.tar.bz2 ҪѹļĿ¼ +         tar -jtv -f filename.tar.bz2 +ѹ     tar -jxv -f filename.tar.bz2 -C ҪѹĿ¼ + +# BASH + +ͨ shell ںṩBash shell һ֡ + +## Bash + +**1. ʷ** + +¼ʹùε¼ִеʱŵڴУ \~/.bash_history ļм¼ǰһε¼ִй + +**2. ļȫ** + +ݼtab + +**3. ** + + lm ls -al ı + +**4. shell scripts** + +**5. ͨ** + + ls -l /usr/bin/X\* г /usr/bin X ͷļ + +## + +һֱֵʹ = ԱȡҪڱǰ \$ Ҳ \${} ʽʹ echo  + +```bash +$ var=abc +$ echo $var +$ echo ${var} +``` + +пոҪʹ˫Żߵš˫ڵַԱԭԣvar="lang is \$LANG"varֵΪ lang is zh_TW.UTF-8ڵַַ var='lang is \$LANG' var ֵΪ lang is \$LANG + + +ʹ \`ָ\` \$(ָ) ķʽִָнֵ version=\$(uname -r) version ֵΪ 3.10.0-229.el7.x86_64 + +ʹ export Զתɻӳʹãνӳɵǰ Bash Bash + +Bash ıΪ֡עûиĬַ͡ʹ declare  + +```html +$ declare [-aixr] variable +-a Ϊ +-i Ϊ +-x Ϊ +-r Ϊreadonly +``` + +ʹ [ ] в + +```bash +$ array[1]=a +$ array[2]=b +$ echo ${array[1]} +``` + +## ָ˳ + +1. ԾԻ·ִָ /bin/ls ./ls +2. ɱҵִָУ +3. Bash ڽִָУ +4. \$PATH ָ·˳ҵһִָС + +## ض + +ضʹļ׼롢׼ͱ׼ + +1. ׼ (stdin)      Ϊ 0 ʹ < << +2. ׼ (stdout)    Ϊ 1 ʹ > >> +3. ׼(stderr)Ϊ 2 ʹ 2> 2>> + +УһͷıʾԸǵķʽض򣬶ͷıʾ׷ӵķʽض + +ԽҪı׼Լ׼ض /dev/null ൱ӽ䡣 + +Ҫ׼Լ׼ͬʱضһļҪijתΪһ 2>&1 ʾ׼תΪ׼ + +```bash +$ find /home -name .bashrc > list 2>&1 +``` + +## ָ + +ǽһı׼Ϊһı׼룬ҪĴ֮ܵõҪĸʽʱͿʹùߡ֮ʹ | ָ + +```bash +$ ls -al /etc | less +``` + +### 1. ȡָcut + +ȡһһеؽС + +cut ݽз֣ȡҪIJ֡ + +```html +$ cut +-d ָ +-f -d ָʹ -f n ȡ n +-c ַΪλȡ +``` + +1last ʾĵߵϢҪʾû + +```html +$ last +root pts/1 192.168.201.101 Sat Feb 7 12:35 still logged in +root pts/1 192.168.201.101 Fri Feb 6 12:13 - 18:46 (06:33) +root pts/1 192.168.201.254 Thu Feb 5 22:37 - 23:53 (01:16) + +$ last | cut -d ' ' -f 1 +``` + +2 export ѶϢȡõ 12 ַԺַ + +```html +$ export +declare -x HISTCONTROL="ignoredups" +declare -x HISTSIZE="1000" +declare -x HOME="/home/dmtsai" +declare -x HOSTNAME="study.centos.vbird" +.....(ʡ)..... + +$ export | cut -c 12 +``` + +### 2. sortuniq + +**sort** + +```html +$ sort [-fbMnrtuk] [file or stdin] +-f ԴСд +-b ǰĿո +-M ·ݵ JAN, DEC +-n ʹ +-r +-u ൱ unique ظֻһ +-t ָĬΪtab +-k ָ +``` + +/etc/passwd : ָģԵ + +```html +$ cat /etc/passwd | sort -t ':' -k 3 +root:x:0:0:root:/root:/bin/bash +dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash +alex:x:1001:1002::/home/alex:/bin/bash +arod:x:1002:1003::/home/arod:/bin/bash +``` + +**uniq** Խظֻȡһ + +```html +$ uniq [-ic] +-i ԴСд +-c м +``` + +ȡÿ˵ĵ¼ܴ + +```html +$ last | cut -d ' ' -f 1 | sort | uniq -c +1 +6 (unknown +47 dmtsai +4 reboot +7 root +1 wtmp +``` + +### 3. ˫ضtee + +ضὫضļУ **tee** ܹܣܱĻϵҲ˵ʹ tee ָһͬʱ͵ļĻϡ + +```html +$ tee [-a] file +``` + +### 4. ַתָtrcolexpandjoinpaste + + **tr** ɾһеַ߶ַ滻 + +```html +$ tr [-ds] SET1 ... +-d ɾ SET1 ַ +``` + + last ϢСдתΪд + +```html +$ last | tr '[a-z]' '[A-Z]' +``` + + **col** tab ַתΪոַ + +```html +$ col [-xb] +-x tab תɶԵȵĿո +``` + +**expand** tab תһĿոĬ 8 + +```html +$ expand [-t] file +-t tab תΪո +``` + +**join** ͬݵһкϲһ + +```html +$ join [-ti12] file1 file2 +-t ָĬΪո +-i ԴСдIJ +-1 һļõıȽֶ +-2 ڶļõıȽֶ +``` + +**paste** ֱӽճһ + +```html +$ paste [-d] file1 file2 +-d ָĬΪ tab +``` + +### 5. ָsplit + +**split** һļֳɶļ + +```html +$ split [-bl] file PREFIX +-b ԴСзɼӵλ b, k, m +-l з +- PREFIX ļǰ +``` + +# ʾļʽ + +## grep + +ʹʾʽƥȡ + +```html +$ grep [-acinv] [--color=auto] Ѱַ filename +-a binary ļ text ļķʽѰ +-c ҵ +-i ԴСд +-n к +-v ѡ༴ʾû Ѱַ ݵһ +--color=auto ҵĹؼּɫʾ +``` + +Ѻ the ַȡעĬϻ --color=auto ѡ Linux ɫʾ the ַ + +```html +$ grep -n 'the' regular_express.txt +8:I can't finish the test. +12:the symbol '*' is represented as start. +15:You are the best is mean you are the no. 1. +16:The world Happy is the same with "glad". +18:google is the best tools for search keyword +``` + +Ϊ { } ķ shell ģ˱Ҫʹʹתַת塣 + +```html +$ grep -n 'go\{2,5\}g' regular_express.txt +``` + +ʽο [ʽ](https://github.com/00000H/notes/blob/master/notes/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.md). + +## printf + +ڸʽ + +ڹܵڸ printf ʱҪʹ $( ) ʽ + +```html +$ printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt) + DmTsai 80 60 92 77.33 + VBird 75 55 80 70.00 + Ken 60 90 70 73.33 +``` + +## awk + +```html +$ awk ' 1{ 1} 2{ 2} ...' filename +``` + +awk ÿδһУСλֶΣÿֶεʽΪ\$nn Ϊֶκţ 1 ʼ\$0 ʾһС + + 1ȡ¼ûû ip + +```html +$ last -n 5 +dmtsai pts/0 192.168.1.100 Tue Jul 14 17:32 still logged in +dmtsai pts/0 192.168.1.100 Thu Jul 9 23:36 - 02:58 (03:22) +dmtsai pts/0 192.168.1.100 Thu Jul 9 17:23 - 23:36 (06:12) +dmtsai pts/0 192.168.1.100 Thu Jul 9 08:02 - 08:17 (00:14) +dmtsai tty1 Fri May 29 11:55 - 12:11 (00:15) + +$ last -n 5 | awk '{print $1 "\t" $3} +``` + +awk + +| | | +| -- | -- | +| NF | ÿһӵеֶ | +| NR | Ŀǰǵڼ | +| FS | ĿǰķַָĬǿո | + + 2ڴкţʾÿһжֶ + +```html +$ last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}' +dmtsai lines: 1 columns: 10 +dmtsai lines: 2 columns: 10 +dmtsai lines: 3 columns: 10 +dmtsai lines: 4 columns: 10 +dmtsai lines: 5 columns: 9 +``` + +ʹôڵ߼еʹ == + + 3/etc/passwd ļֶΪ UID UID С 10 ݽд + +```text +cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}' +root 0 +bin 1 +daemon 2 +``` + +# vim ģʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/341c632a-1fc1-4068-9b9f-bf7ef68ebb4c.jpg) + +ָģʽ£뿪ߴ洢ļ + +| | | +| -- | -- | +| :w | д| +| :w! | ļΪֻʱǿд̡ܲд룬ûԸļȨй | +| :q | 뿪| +| :q! | ǿ뿪| +| :wq | д̺뿪| +| :wq!| ǿд̺뿪| + + +# ο + +- . Linux ˽ ƪ [J]. 2009. +- [Linux ƽ̨ϵ](https://www.ibm.com/developerworks/cn/linux/l-cn-rpmdpkg/index.html) + diff --git a/notes/MySQL.md b/notes/MySQL.md new file mode 100644 index 00000000..f0fe5704 --- /dev/null +++ b/notes/MySQL.md @@ -0,0 +1,444 @@ + +* [Ĵ](#Ĵ) + * [1. ԭ](#1-ԭ) + * [2. һ](#2-һ) + * [3. ](#3-) + * [4. ־](#4-־) +* [洢](#洢) + * [1. InnoDB](#1-innodb) + * [2. MyISAM](#2-myisam) + * [3. InnoDB MyISAM ıȽ](#3-innodb--myisam-ıȽ) +* [](#) + * [1. ](#1-) + * [2. ](#2-) + * [3. ַ](#3-ַ) + * [4. ʱ](#4-ʱ) +* [](#) + * [1. ](#1-) + * [1.1 B-Tree ](#11-b-tree-) + * [1.2 ϣ](#12-ϣ) + * [1.3. ռݣR-Tree](#13-ռݣr-tree) + * [1.4 ȫ](#14-ȫ) + * [2. ŵ](#2-ŵ) + * [3. Ż](#3-Ż) + * [3.1 ](#31-) + * [3.2 ǰ׺](#32-ǰ׺) + * [3.3 ](#33-) + * [3.4 е˳](#34-е˳) + * [3.5 ۴](#35-۴) + * [3.6 ](#36-) + * [4. B-Tree B+Tree ԭ](#4-b-tree--b+tree-ԭ) + * [4. 1 B-Tree](#4-1-b-tree) + * [4.2 B+Tree](#42-b+tree) + * [4.3 ˳ָ B+Tree](#43-˳ָ-b+tree) + * [4.4 Ϊʲôʹ B-Tree B+Tree](#44-Ϊʲôʹ-b-tree--b+tree) +* [ѯŻ](#ѯŻ) + * [1. Explain](#1-explain) + * [2. ٷص](#2-ٷص) + * [3. ٷص](#3-ٷص) + * [4. ִ DELETE INSERT ](#4-ִ-delete--insert-) +* [ֱֿ](#ֱֿ) +* [תƺ͹ϻָ](#תƺ͹ϻָ) + * [1. ת](#1-ת) + * [2. ϻָ](#2-ϻָ) +* [ο](#ο) + + +# Ĵ + +## 1. ԭ + +ҪôִУҪôִС + +## 2. һ + +ִǰ󶼱һ״̬ + +## 3. + +񵥶ִУӰ졣 + +## 4. ־ + +ʹϵͳϣִеĽҲܶʧ + +# 洢 + +## 1. InnoDB + +InnoDB MySQL Ĭ棬ֻҪ InnoDB ֵ֧ʱſʹ洢档 + + MVCC ָ֧߲ʵĸ׼ĸ뼶Ĭϼǿظ + +ǻھ۴ģIJѯкܸߵ + +ڲ˺ܶŻӴ̶ȡʱõĿԤԶܹԶڴд hash ԼٶӦϣԼܹٲIJ뻺ȡ + +ͨһЩƺ͹֧ȱݡ + +## 2. MyISAM + +MyISAM ṩ˴ԣȫѹռ亯GISȡ MyISAM ֧мұ޷ȫָ + +ֻܶűС + +ֹԶִм޸ǺָԼָͬܵһЩݶʧ޸Ƿdzġ + +԰̬߾̬С + +ָ DELAY_KEY_WRITE ѡÿ޸ִʱ޸ĵд̣ǻдڴеļֻ߹رձʱŻὫӦдַ̡ʽԼдܣݿʱ𻵣Ҫִ޸ + +ڴԺ󣬲ٽ޸IJôıʺϲ MyISAM ѹ + +ֻݣ߱ȽС޸ȻԼʹ MyISAM + +MyISAM Ƽ򵥣Խܸʽ洢ijЩܺܺá + +## 3. InnoDB MyISAM ıȽ + +**** + +InnoDB ͵ġ + +**** + +InnoDB ֧ȱݡ + +**ָ** + +MyISAM 𻵵ĸʱ InnoDB ߺܶ࣬һָٶҲ + +**** + +MyISAM ֱֻ֧ InnoDB ֧м + +**** + +MyISAM ֧ȫռ + +# + +## 1. + +TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT ֱʹ 8, 16, 24, 64 λ洢ռ䣬һԽСԽá + +INT(11) еֻǹ涨˽ʾַĸڴ洢ͼ˵ûġ + +## 2. + +FLOAT DOUBLE ΪͣDECIMAL Ϊ߾С͡CPU ԭָ֧㣬Dz֧ DECIMAl ͵ļ㣬 DECIMAL ļȸҪߵĴۡ + +FLOATDOUBLE DECIMAL ָп DECIMAL(18, 9) ʾܹ 18 λȡ 9 λ洢С֣ʣ 9 λ洢֡ + +## 3. ַ + +Ҫ CHAR VARCHAR ͣһǶģһDZ䳤ġ + +VARCHAR ֱ䳤ܹʡռ䣬ΪֻҪ洢Ҫݡִ UPDATE ʱܻʹбñԭһҳɵĴСʱҪִжIJMyISAM ὫвɲͬƬδ洢 InnoDB ҪҳʹзŽҳڡ + +VARCHAR ᱣַĩβĿո񣬶 CHAR ɾ + +## 4. ʱ + +MySQL ṩƵʱͣDATATIME TIMESTAMP + +**DATATIME** + +ܹ 1001 굽 9999 ںʱ䣬Ϊ룬ʹ 8 ֽڵĴ洢ռ䡣 + +ʱ޹ء + +Ĭ£MySQL һֿġĸʽʾ DATATIME ֵ硰2008-01016 22:37:08 ANSI ׼ںʱʾ + +**TIMESTAMP** + + UNIX ʱͬ 1970 1 1 ҹʱ䣩ʹ 4 ֽڣֻܱʾ 1970 2038 ꡣ + +ʱйء + +MySQL ṩ FROM_UNIXTIME() Unxi ʱתΪڣṩ UNIX_TIMESTAMP() תΪ Unix ʱ + +Ĭ£ʱûָ TIMESTAMP еֵὫֵΪǰʱ䡣 + +Ӧþʹ TIMESTAMPΪ DATETIME ռЧʸߡ + +# + +ڴ洢ʵֵģڷʵֵģԲͬ洢вͬͺʵ֡ + +ܹ׽ѯ + +ڷdzСı󲿷¼򵥵ȫɨȽЧе͵ıͷdzЧǶش͵ıʹĴ۽֮£ҪõһֱֳּҪѯһݣһ¼һ¼ƥ䣬ʹ÷ + +## 1. + +### 1.1 B-Tree + +B-Tree Ǵ MySQL 洢Ĭ͡ + +ΪҪȫɨ裬ֻҪɣ˲ٶȿܶࡣ + +ָΪУйͬɼB-Tree ȫֵֵΧͼǰ׺ңмǰ׺ֻǰ׺ҡ + +ڲңͷ顣 + +ǰе˳вң޷ʹ + +### 1.2 ϣ + +ڹϣʵ֣ŵDzҷdz졣 + + MySQL ֻ Memory ʽֹ֧ϣ + +InnoDB һĹܽСӦϣijֵʹõķdzƵʱ B-Tree ֮ٴһϣ B-Tree йϣһЩŵ㣬ٵĹϣҡ + +ƣϣֻϣֵָ룬洢ֵֶԲʹеֵȡСڴееٶȺܿ죬Դ󲿷һӰ첢ԣ޷ڷֻ֧־ȷң޷ڲֲҺͷΧңϣͻܶ࣬ٶȻú + +### 1.3. ռݣR-Tree + +MyISAM 洢ֿ֧ռڵݴ洢 + +ռάݣЧʹάϲѯ + +### 1.4 ȫ + +MyISAM 洢֧ȫڲıеĹؼʣֱӱȽеֵ + +ʹ MATCH AGAINSTͨ WHERE + +## 2. ŵ + +- ˷Ҫɨ + +- ʹʱ + +- I/O Ϊ˳ I/O + +## 3. Ż + +### 3.1 + +ڽвѯʱвDZʽһ֣ҲǺIJ޷ʹ + +IJѯʹ actor_id е + +```sql +SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; +``` + +### 3.2 ǰ׺ + + BLOBTEXT VARCHAR ͵Уʹǰ׺ֻʼIJַ + +ǰ׺ȵѡȡҪ **ѡ** ȷظֵͼ¼ıֵѡԽߣѯЧҲԽߡֵΪ 1 ʱÿ¼ΨһӦ + +### 3.3 + +ҪʹöΪвѯʱʹöʹöܸáУð actor_id file_id Ϊ + +```sql +SELECT file_id, actor_ id FROM sakila.film_actor +WhERE actor_id = 1 OR film_id = 1; +``` + +### 3.4 е˳ + +ѡǿзǰ棬ʾĽ customer_id ѡԱ staff_id ߣð customer_id зڶǰ档 + +```sql +SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_selectivity, +COUNT(DISTINCT customer_id)/COUNT(*) AS customer_id_selectivity, +COUNT(*) +FROM payment; +``` + +```html + staff_id_selectivity: 0.0001 +customer_id_selectivity: 0.0373 + COUNT(*): 16049 +``` + +### 3.5 ۴ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b9e9ae8c-e216-4c01-b267-a50dbeb98fa4.jpg) + +۴һͣһݴ洢ʽ + +۴ءʾкڵļֵܵش洢һInnoDB ľ۴д B-Tree ҶҳС + +Ϊ޷дͬĵطһֻһ۴ + +**ŵ** + +1. ԰ݱһ𣬼 I/O +2. Ϊݱ B-Tree Уݷʸ졣 + +**ȱ** + +1. ۴޶ I/O ܼӦõܣȫڴ棬ûҪþ۴ +2. ٶڲ˳򣬰˳ġ +3. ²ۺܸߣΪÿµжƶµλá +4. 뵽ijҳУ洢ὫҳѳҳɸУҳѻᵼ±ռøĴ̿ռ䡣 +5. бȽϡ裬ҳѵݴ洢ʱ۴ܵȫɨٶȱ + +### 3.6 + +Ҫѯֶεֵ + +## 4. B-Tree B+Tree ԭ + +### 4. 1 B-Tree + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5ed71283-a070-4b21-85ae-f2cbfd6ba6e1.jpg) + +Ϊ B-Treeȶһݼ¼ΪһԪ [key, data]key Ϊ¼ļdata Ϊݼ¼ key ݡ + +B-Tree ݽṹ + +- ҶڵͬȣҲ˵ B-Tree ƽģ +- һڵе key ҷǵݼУ +- ijָ key ֱ keyi keyi+1ҲΪ nullָָڵ key keyi С keyi+1 + + B-Tree а key ݵ㷨dzֱۣȴӸڵжֲңҵ򷵻ضӦڵ dataӦָָĽڵݹвңֱҵڵҵ null ָ룬ǰ߲ҳɹ߲ʧܡ + +ڲɾµݼ¼ƻ B-Tree ʣڲɾʱҪһѡϲתƵȲԱ B-Tree ʡ + +### 4.2 B+Tree + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/63cd5b50-d6d8-4df6-8912-ef4a1dd5ba13.jpg) + + B-Tree ȣB+Tree ²ͬ㣺 + +- ÿڵָΪ 2d 2d+1 +- ڽڵ㲻洢 dataֻ洢 keyҶӽڵ㲻洢ָ롣 + +### 4.3 ˳ָ B+Tree + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1ee5f0a5-b8df-43b9-95ab-c516c54ec797.jpg) + +һݿϵͳļϵͳʹõ B+Tree ṹھ B+Tree ϽŻҶӽڵ˳ָ룬ŻĿΪʵܡ + +### 4.4 Ϊʲôʹ B-Tree B+Tree + +ݽṹҲʵļϵͳݿϵͳձ B-/+Tree Ϊṹ + +ҳǼ洢߼飬Ӳϵͳʹ̴洢ָΪĴСȵĿ飬ÿ洢ΪһҳϵͳУҳôСͨΪ 4kʹҳΪλݡ + +һ˵Ҳܴ󣬲ȫ洢ڴУļʽ洢ĴϡΪ˼ٴ I/OϸȡÿζԤǼѧľֲԭһݱõʱ丽Ҳͨϱʹáݿϵͳ˴ԤԭһڵĴСΪһҳÿڵֻҪһ I/O Ϳȫ롣B-Tree һμҪ h-1 I/Oڵ㳣פڴ棩ӶΪ O(h)=O(logdN)һʵӦУ d Ƿdz֣ͨ 100 h dzСͨ 3ֽṹh ҪĶࡣ߼ϺܽĽڵ㣨ӣϿܺԶ޷þֲԣЧԱ B-Tree ܶࡣ + +B+Tree ʺԭڽڵ d йء B+Tree ڽڵȥ data ˿ӵиijȣӵиõܡ + +# ѯŻ + +## 1. Explain + + SQL 䣬бȽҪֶУ + +- select_type : ѯͣм򵥲ѯϲѯӲѯ + +- key : ʹõ + +- rows : ɨ + +## 2. ٷص + +ѯҪΪ˹ݣ˷ʹ֮⣬ҲʹС + +òҪʹ SELECT * 䣬ҪҪѡѯС + +## 3. ٷص + +ʹ LIMIT ȡҪЩС + +Խȫɨ衣䣬Ҫȫɨ裬ʹֻҪɨ輸м¼ɣʹ Explain ͨ۲ rows ֲֶ졣 + +```sql +SELECT * FROM sakila.film_actor WHERE film_id = 1; +``` + +## 4. ִ DELETE INSERT + +һִеĻһסܶݡռ־ľϵͳԴܶСĵҪIJѯ + +```sql +DELEFT FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH); +``` +```sql +rows_affected = 0 +do { + rows_affected = do_query( + "DELETE FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 10000") +} while rows_affected > 0 +``` + +# ֱֿ + +**1. ֱIJͬ** + +ֱǽһűֳɶСЩСӵвͬıǽһűݷΪ飬ЩԴ洢ͬһϣҲԴ洢ڲͬĴϣַʽ±Ȼֻһ + +**2. ʹ÷ֱֿԭ** + +ʱҵķչݿеıԽԽ࣬ұеҲԽԽôдĿҲ + +**3. ֱз** + +ģ顢ϵг̶Ȼֳ𵽲ͬĿϡ磬ǻὨƷݿ payDBûݿ userDB ȣֱ洢ĿƷйصıûйصı + +**4. ˮƽз** + +ѱеݰijֹ洢ṹͬıУ簴 id ɢֵԱȽл֣ + +**5. ֱзˮƽзֵѡ** + +ݿеı̫࣬Ŀҵ߼ôֱзѡ + +ݿı࣬ǵܴӦѡˮƽз֡ + +**6. ˮƽзֵʵַʽ** + +򵥵ʹ merge 洢档 + +**7. ֱֿڵ** + +(1) + +ִзֱֿ֮ݴ洢˲ͬĿϣݿѡݿⱾķֲʽȥִ񣬽ܴۣ߰ӦóȥЭƣγɳ߼ϵֻɱ̷ĸ + +(2) + +ִ˷ֱֿ֮ԱὫԭ߼ԺǿݻֵͬıͬĿϡʱӲܵƣ޷λڲֿͬıҲ޷ӷֱȲͬıԭֻҪһβѯܹɵҵҪжβɡ + +# תƺ͹ϻָ + +תҲлֹʱл⣬ʹΪ⡣ϻָ˼Ǵӹлָұ֤ݵȷԡ + +## 1. ת + +**1.1 лɫ** + +һ̨Ϊ⣬һ-ƽṹеͱɫ + +**1.2 IP ַ IP й** + +Ϊ MySQL ʵָһ߼ IP ַ MySQL ʵʧЧʱԽ IP ַתƵһ̨ MySQL ϡ + +**1.3 м** + +ͨ·ʹõķϡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/fabd5fa0-b75e-48d0-9e2c-31471945ceb9.jpg) + +**1.4 Ӧдת** + +תϵӦпܵӦñ̫׾ + +## 2. ϻָ + + +# ο + +- MySQL +- [MySQL ݽṹ㷨ԭ ](http://blog.codinglabs.org/articles/theory-of-mysql-index.html) +- [MySQL Żȫ ](http://www.runoob.com/w3cnote/mysql-index.html) +- [20+ MySQL ŻѾ ](https://www.jfox.info/20-tiao-mysql-xing-nen-you-hua-de-zui-jia-jing-yan.html) diff --git a/notes/SQL 语法.md b/notes/SQL 语法.md new file mode 100644 index 00000000..b128542b --- /dev/null +++ b/notes/SQL 语法.md @@ -0,0 +1,734 @@ + +* [](#) +* [ѯ](#ѯ) +* [](#) +* [](#) +* [ͨ](#ͨ) +* [ֶ](#ֶ) +* [](#) + * [ı](#ı) + * [ںʱ䴦](#ںʱ䴦) + * [ֵ](#ֵ) + * [](#) +* [](#) +* [Ӳѯ](#Ӳѯ) +* [](#) + * [](#) + * [](#) + * [Ȼ](#Ȼ) + * [](#) +* [ϲѯ](#ϲѯ) +* [](#) +* [](#) +* [ɾ](#ɾ) +* [](#) +* [޸ı](#޸ı) +* [ͼ](#ͼ) +* [洢](#洢) +* [α](#α) +* [](#) +* [](#) +* [ַ](#ַ) +* [Ȩ޹](#Ȩ޹) + + +# + +ģʽδ洢洢ʲôԼηֽϢݿͱģʽ + +ֵ޸ģҲãʹѾɾֵе + +SQLStructured Query Language)׼ SQL ANSI ׼ίԱӶΪ ANSI SQL DBMS Լʵ֣ PL/SQLTransact-SQL ȡ + +# ѯ + +SQL 䲻ִСдݿֵǷھ DBMS Լá + +**DISTINCT** + +ֵֻͬһΡУҲ˵еֵͬͬ + +```sql +SELECT DISTINCT col1, col2 +FROM mytable; +``` + +**LIMIT** + +ƷصһΪʼУ 0 ʼڶΪص + +ǰ 5 е SQL + +```sql +SELECT * +FROM mytable +LIMIT 5; +``` + +```sql +SELECT * +FROM mytable +LIMIT 0, 5; +``` + +ص 3 \~ 5 У + +```sql +SELECT * +FROM mytable +LIMIT 2, 3; +``` + +**ע** + +```sql +# ע +SELECT * +FROM mytable -- ע +/* ע1 + ע2 */ +``` + +# + +**ASC**Ĭϣ +**DESC** + +԰н + +```sql +SELECT * +FROM mytable +ORDER BY col1 DESC, col2 ASC; +``` + +# + +ӦòҲԹݣDzڷ˽й˵ݷdz󣬵ͨ紫˺ܶݣӶ˷ + +```sql +SELECT * +FROM mytable +WHERE col IS NULL; +``` + +±ʾ WHERE ӾõIJ + +| | ˵ | +| ------------ | ------------ | +| = < > | С | +| <> != | | +| <= !> | Сڵ | +| >= !< | ڵ | +| BETWEEN | ֵ֮ | +| IS NULL | ΪNULLֵ | + +Ӧע⵽NULL 0 ַͬ + +**AND OR** Ӷȴ AND˵һ˱ʽ漰 AND OR ʱӦʹ () ȼ + +**IN** ƥһֵҲԽһ SELECT Ӿ䣬ӶƥӲѯõһֵ + +**NOT** ڷһ + +# ͨ + +ͨҲڹУֻıֶΡ + +- **%** ƥ >=0 ַ \* + +- **\_** ƥ ==1 ַ \. + +- **[ ]** ƥ伯ڵַַ ^ Զз + +ʹ Like ͨƥ䡣 + +```sql +SELECT * +FROM mytable +WHERE col LIKE '[^AB]%' -- ABͷı +``` + +Ҫͨͨλڿͷƥdz + +# ֶ + +ݿݵת͸ʽĹȿͻϿö࣬ת͸ʽٵĻԼͨ + +ֶͨҪʹ **AS** ȡʱֶΪʽ + +```sql +SELECT col1*col2 AS alias +FROM mytable +``` + +**Concat()** ֶΡݿʹÿոһֵΪпӵĽһЩҪĿոʹ **TRIM()** ȥβո + +```sql +SELECT Concat(TRIM(col1), ' (', TRIM(col2), ')') +FROM mytable +``` + +# + + DBMS ĺDzͬģ˲ֲ + +## ı + +| | ˵ | +| ------------ | ------------ | +| LEFT() RIGHT() | ߻ұߵַ | +| LOWER() UPPER() | תΪСдߴд | +| LTRIM() RTIM() | ȥ߻ұߵĿո | +| LENGTH() | | +| SUNDEX() | תΪֵ | + +У**SOUNDEX()** ǽһַתΪʾĸģʽ㷨ǸݷĸȽϡ + +```sql +SELECT * +FROM mytable +WHERE SOUNDEX(col1) = SOUNDEX('apple') +``` +## ںʱ䴦 + +ڸʽYYYY-MM-DD + +ʱʽHH:MM:SS + +| | ˵ | +| --- | --- | +| AddDate() | һڣ졢ܵȣ| +| AddTime() | һʱ䣨ʱֵȣ| +| CurDate() | صǰ | +| CurTime() | صǰʱ | +|Date() |ʱڲ| +|DateDiff() |֮| +|Date_Add() |߶㺯| +|Date_Format() |һʽڻʱ䴮| +|Day()| һڵ| +|DayOfWeek() |һڣضӦڼ| +|Hour() |һʱСʱ| +|Minute() |һʱķӲ| +|Month() |һڵ·ݲ| +|Now() |صǰںʱ| +|Second() |һʱ벿| +|Time() |һʱʱ䲿| +|Year() |һڵݲ| + +```sql +mysql> SELECT NOW(); + -> '2017-06-28 14:01:52' +``` + +## ֵ + +| | ˵ | +| --- | --- | +| SIN() | | +|COS() | | +| TAN() | | +| ABS() | ֵ | +| SQRT() | ƽ| +| MOD() | | +| EXP() | ָ| +| PI() | Բ| +|RAND() | | + +## + +| |˵ | +| --- | --- | +|AVG() |ijеƽֵ| +|COUNT()| ijе| +|MAX()| ijеֵ| +|MIN()| ijеСֵ| +|SUM() |ijֵ֮| + +AVG() NULL С + +DISTINCT ؼֵֻֻܲͬ + +```sql +SELECT AVG(DISTINCT col1) AS avg_col +FROM mytable +``` + +# + +ǰͬݷͬһС + +Զÿʹûܺдÿƽֵȡ + + col 򲢷ݣ + +```sql +SELECT col, COUNT(*) AS num +FROM mytable +GROUP BY col; +``` + +WHERE УHAVING ˷飬йӦˣ + +```sql +SELECT col, COUNT(*) AS num +FROM mytable +WHERE col > 2 +GROUP BY col +HAVING COUNT(*) >= 2; +``` + +GROUP BY ΪֶΣ ORDER BY ҲԾۼֶ + +```sql +SELECT col, COUNT(*) AS num +FROM mytable +GROUP BY col +ORDER BY num; +``` + +涨 + +1. GROUP BY Ӿ WHERE Ӿ֮ORDER BY Ӿ֮ǰ +2. ˻ܼ֮⣬SELECT еÿһж GROUP BY Ӿи +3. NULL лᵥΪһ飻 +4. SQL ʵֲ֧ GROUP BY опɱ䳤ȵ͡ + +# Ӳѯ + +ӲѯֻܷһС + +ԽӲѯĽΪ WHRER Ĺ + +``` +SELECT * +FROM mytable1 +WHERE col1 IN (SELECT col2 + FROM mytable2); +``` + +ԼͻĶӲѯԼÿͻִһΣ + +```sql +SELECT cust_name, (SELECT COUNT(*) + FROM Orders + WHERE Orders.cust_id = Customers.cust_id) + AS orders_num +FROM Customers +ORDER BY cust_name; +``` + +# + +Ӷʹ JOIN ؼ֣ʹ ON + +ӿ滻ӲѯұӲѯЧһ졣 + + AS ֶκͱȡȡΪ˼ SQL Լͬ + +## + +ֳƵֵӣʹ INNER JOIN ؼ֡ + +``` +select a, b, c +from A inner join B +on A.key = B.key +``` + +Բȷʹ INNER JOINʹͨѯ WHERE нҪӵõֵ + +``` +select a, b, c +from A, B +where A.key = B.key +``` + +û·صѿ + +## + +ӿԿӵһֻ֣ӵıѡ + +һԱԱԱţҪҳ Jim ͬһŵԱ + +**Ӳѯ汾** + +``` +select name +from employee +where department = ( + select department + from employee + where name = "Jim"); +``` + +**Ӱ汾** + +``` +select name +from employee as e1, employee as e2 +where e1.department = e2.department + and e1.name = "Jim"; +``` + +һӲѯЧʸߡ + +## Ȼ + +Ȼǰֵͬͨģͬпж + +ӺȻӵṩӵУȻԶͬУȻӡ + +``` +select * +from employee natural join department; +``` + +## + +ӱûйЩСΪӣԼȫӣӾDZС + +й˿͵ĶϢûжϢĹ˿͡ + +``` +select Customers.cust_id, Orders.order_num + from Customers left outer join Orders + on Customers.cust_id = Orders.curt_id +``` + +Ҫͳƹ˿͵Ķʹþۼ + +``` +select Customers.cust_id, + COUNT(Orders.order_num) as num_ord +from Customers left outer join Orders +on Customers.cust_id = Orders.curt_id +group by Customers.cust_id +``` + +# ϲѯ + +ʹ **UNION** ѯÿѯͬСʽ߾ۼ + +ĬϻȥͬУҪͬУʹ UNION ALL + +ֻܰһ ORDER BY Ӿ䣬ұλ + +```sql +SELECT col +FROM mytable +WHERE col = 1 +UNION +SELECT col +FROM mytable +WHERE col =2; +``` + +# + +**ͨ** + +```sql +INSERT INTO mytable(col1, col2) +VALUES(val1, val2); +``` + +**** + +```sql +INSERT INTO mytable1(col1, col2) +SELECT col1, col2 +FROM mytable2; +``` + +**һݸƵһ±** + +```sql +CREATE TABLE newtable AS +SELECT * FROM mytable; +``` + +# + +```sql +UPDATE mytable +SET col = val +WHERE id = 1; +``` + +# ɾ + +```sql +DELETE FROM mytable +WHERE id = 1; +``` + +**TRUNCATE TABLE** ձҲɾС + +ʹøºɾʱһҪ WHERE Ӿ䣬Ȼűݶƻ SELECT вԣֹɾ + +# + +```sql +CREATE TABLE mytable ( + id INT NOT NULL AUTO_INCREMENT, + col1 INT NOT NULL DEFAULT 1, + col2 VARCHAR(45) NULL, + col3 DATE NULL, + PRIMARY KEY (`id`)); +``` + +# ޸ı + +**** + +```sql +ALTER TABLE mytable +ADD col CHAR(20); +``` + +**ɾ** + +```sql +ALTER TABLE mytable +DROP COLUMN col; +``` + +**ɾ** + +```sql +DROP TABLE mytable; +``` + +# ͼ + +ͼıݣҲͲܶͼIJͶͨIJһ + +ͼºô + +1. 򻯸ӵ SQL 縴ӵ᣻ +2. ֻʹʵʱһݣ +3. ֻͨûͼȨޣ֤ݵİȫԣ +4. ݸʽͱʾ + +```sql +CREATE VIEW myview AS +SELECT Concat(col1, col2) AS concat_col, col3*col4 AS count_col +FROM mytable +WHERE col5 = val; +``` + +# 洢 + +洢̿ԿǶһϵ SQL + +**ʹô洢̵ĺô** + +1. ʵַװ˴洢У򵥣Ҳ֤˰ȫԣ +2. Ըô룻 +3. Ԥȱ룬˾кܸߵܡ + +**洢** + +д洢ҪԶָΪ ; Ϊ洢Ҳ˷ֺţ˻ⲿַֺŵǽ﷨ + + inout inout ֲ + +ֵҪ select into 䡣 + +ÿֻܸһֵּ֧ϵIJ + +```sql +delimiter // + +create procedure myprocedure( out ret int ) + begin + declare y int; + select sum(col1) + from mytable + into y; + select y*y into ret; + end // +delimiter ; +``` + +```sql +call myprocedure(@ret); +select @ret; +``` + +# α + +ڴ洢ʹαԶһƶ + +αҪڽʽӦãûҪݼен޸ġ + +**ʹαĸ裺** + +1. α꣬ûʵʼݣ +2. αꣻ +3. ȡݣ +4. رαꣻ + +```sql +delimiter // +create procedure myprocedure(out ret int) + begin + declare done boolean default 0; + + declare mycursor cursor for + select col1 from mytable; + # һcontinue handler sqlstate '02000' ʱִ set done = 1 + declare continue handler for sqlstate '02000' set done = 1; + + open mycursor; + + repeat + fetch mycursor into ret; + select ret; + until done end repeat; + + close mycursor; + end // + delimiter ; +``` + +# + +ijִʱԶִУDELETEINSERTUPDATE + +ִָ֮ǰ֮ԶִУ֮ǰִʹ BEFORE ؼִ֣֮ʹ AFTER ؼ֡BEFORE ֤; + +INSERT һΪ NEW + +```sql +CREATE TRIGGER mytrigger AFTER INSERT ON mytable +FOR EACH ROW SELECT NEW.col; +``` + +DELETE һΪ OLD ֻġ + +UPDATE һΪ NEW һΪ OLD NEW ǿԱ޸ĵأ OLD ֻġ + +ʹôƸ٣޸ļ¼һűС + +MySQL ڴʹ CALL ҲDzܵô洢̡ + +# + +**** + +1. transactionָһ SQL 䣻 +2. ˣrollbackָָ SQL Ḷ́ +3. ύcommitָδ洢 SQL дݿ +4. 㣨savepointָõʱռλplaceholderԶˣͬ + +ܻ SELECT 䣬 SELECT Ҳû壻Ҳܻ CRETE DROP 䡣 + +MySQL ύĬʽύҲÿִһͻύһΡ START TRANSACTION ʱرʽύ COMMIT ROLLBACK ִкԶرգ»ָʽύ + +ͨ autocommit Ϊ 0 ȡԶύֱ autocommit Ϊ 1 Żύautocommit ÿӶԷġ + +ûñ㣬ROLLBACK ˵ START TRANSACTION 䴦˱㣬 ROLLBACK ָñ㣬˵ñ㡣 + +```sql +START TRANSACTION +// ... +SAVEPOINT delete1 +// ... +ROLLBACK TO delete1 +// ... +COMMIT +``` + +# ַ + +**** + +1. ַΪĸͷŵļϣ +2. ΪijַԱڲʾ +3. УַָαȽϣҪͷ顣 + +˸ַָУ⣬ҲԸָ + +```sql +CREATE TABLE mytable +(col VARCHAR(10) CHARACTER SET latin COLLATE latin1_general_ci ) +DEFAULT CHARACTER SET hebrew COLLATE hebrew_general_ci; +``` + +򡢷ʱָУԣ + +```sql +SELECT * +FROM mytable +ORDER BY col COLLATE latin1_general_ci; +``` + +# Ȩ޹ + +MySQL ˻Ϣ mysql ݿС + +```sql +USE mysql; +SELECT user FROM user; +``` + +**˻** + +```sql +CREATE USER myuser IDENTIFIED BY 'mypassword'; +``` + +´˻ûκȨޡ + +**޸˻** + +```sql +RENAME myuser TO newuser; +``` + +**ɾ˻** + +```sql +DROP USER myuser; +``` + +**鿴Ȩ** + +```sql +SHOW GRANTS FOR myuser; +``` +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c73aa08e-a987-43c9-92be-adea4a884c25.png) + +˻ username@host ʽ壬username@% ʹõĬ + +**Ȩ** + +```sql +GRANT SELECT, INSERT ON mydatabase.* TO myuser; +``` + +**ɾȨ** + +```sql +REVOKE SELECT, INSERT ON mydatabase.* FROM myuser; +``` + +GRANT REVOKE ڼϿƷȨޣ + +- ʹ GRANT ALL REVOKE ALL +- ݿ⣬ʹ ON database.\* +- ضıʹ ON database.table +- ضУ +- ضĴ洢̡ + +**** + +ʹ Password() + +```sql +SET PASSWROD FOR myuser = Password('newpassword'); +``` + diff --git a/剑指offer题解.md b/notes/剑指 offer 题解.md similarity index 64% rename from 剑指offer题解.md rename to notes/剑指 offer 题解.md index 0813cb93..e0ce3e39 100644 --- a/剑指offer题解.md +++ b/notes/剑指 offer 题解.md @@ -1,90 +1,160 @@ -* [第二章 面试需要的基础知识](#第二章-面试需要的基础知识) - * [3. 数组中重复的数字](#3-数组中重复的数字) - * [4. 二维数组中的查找](#4-二维数组中的查找) - * [5. 替换空格](#5-替换空格) - * [6. 从尾到头打印链表](#6-从尾到头打印链表) - * [7. 重建二叉树](#7-重建二叉树) - * [8. 二叉树的下一个结点](#8-二叉树的下一个结点) - * [9. 用两个栈实现队列](#9-用两个栈实现队列) - * [10.1 斐波那契数列](#101-斐波那契数列) - * [10.2 跳台阶](#102-跳台阶) - * [10.3 变态跳台阶](#103-变态跳台阶) - * [10.4 矩形覆盖](#104-矩形覆盖) - * [11. 旋转数组的最小数字](#11-旋转数组的最小数字) - * [12. 矩阵中的路径](#12-矩阵中的路径) - * [13. 机器人的运动范围](#13-机器人的运动范围) - * [15. 二进制中 1 的个数](#15-二进制中-1-的个数) -* [第三章 高质量的代码](#第三章-高质量的代码) - * [16. 数值的整数次方](#16-数值的整数次方) - * [19. 正则表达式匹配](#19-正则表达式匹配) - * [20. 表示数值的字符串](#20-表示数值的字符串) - * [21. 调整数组顺序使奇数位于偶数前面](#21-调整数组顺序使奇数位于偶数前面) - * [22. 链表中倒数第 k 个结点](#22-链表中倒数第-k-个结点) - * [23. 链表中环的入口结点](#23-链表中环的入口结点) - * [24. 反转链表](#24-反转链表) - * [25. 合并两个排序的链表](#25-合并两个排序的链表) - * [26. 树的子结构](#26-树的子结构) -* [第四章 解决面试题的思路](#第四章-解决面试题的思路) - * [27. 二叉树的镜像](#27-二叉树的镜像) - * [28. 对称的二叉树](#28-对称的二叉树) - * [29. 顺时针打印矩阵](#29-顺时针打印矩阵) - * [30. 包含 min 函数的栈](#30-包含-min-函数的栈) - * [31. 栈的压入、弹出序列](#31-栈的压入弹出序列) - * [32. 从上往下打印二叉树](#32-从上往下打印二叉树) - * [33. 二叉搜索树的后序遍历序列](#33-二叉搜索树的后序遍历序列) - * [34. 二叉树中和为某一值的路径](#34-二叉树中和为某一值的路径) - * [35. 复杂链表的复制](#35-复杂链表的复制) - * [36. 二叉搜索树与双向链表](#36-二叉搜索树与双向链表) - * [37. 序列化二叉树](#37-序列化二叉树) - * [38. 字符串的排列](#38-字符串的排列) -* [第五章 优化时间和空间效率](#第五章-优化时间和空间效率) - * [39. 数组中出现次数超过一半的数字](#39-数组中出现次数超过一半的数字) - * [40. 最小的 K 个数](#40-最小的-k-个数) - * [42. 连续子数组的最大和](#42-连续子数组的最大和) - * [43. 从 1 到 n 整数中 1 出现的次数](#43-从-1-到-n-整数中-1-出现的次数) - * [45. 把数组排成最小的数](#45-把数组排成最小的数) - * [49. 丑数](#49-丑数) - * [50. 第一个只出现一次的字符位置](#50-第一个只出现一次的字符位置) - * [51. 数组中的逆序对](#51-数组中的逆序对) - * [52. 两个链表的第一个公共结点](#52-两个链表的第一个公共结点) -* [第六章 面试中的各项能力](#第六章-面试中的各项能力) - * [53 数字在排序数组中出现的次数](#53-数字在排序数组中出现的次数) - * [54. 二叉搜索树的第 k 个结点](#54-二叉搜索树的第-k-个结点) - * [55 二叉树的深度](#55-二叉树的深度) - * [56. 数组中只出现一次的数字](#56-数组中只出现一次的数字) - * [57. 和为 S 的两个数字](#57-和为-s-的两个数字) - * [58.1 翻转单词顺序列](#581-翻转单词顺序列) - * [58.2 左旋转字符串](#582-左旋转字符串) - * [61. 扑克牌顺子](#61-扑克牌顺子) - * [62. 圆圈中最后剩下的数](#62-圆圈中最后剩下的数) - * [64. 求 1+2+3+...+n](#64-求-123n) - * [65. 不用加减乘除做加法](#65-不用加减乘除做加法) - * [66. 构建乘积数组](#66-构建乘积数组) -* [第七章 两个面试案例](#第七章-两个面试案例) - * [67. 把字符串转换成整数](#67-把字符串转换成整数) -* [未分类](#未分类) - * [平衡二叉树](#平衡二叉树) - * [和为 S 的连续正数序列](#和为-s-的连续正数序列) - * [ 字符流中第一个不重复的字符](#-字符流中第一个不重复的字符) - * [ 删除链表中重复的结点](#-删除链表中重复的结点) - * [按之字形顺序打印二叉树](#按之字形顺序打印二叉树) - * [ 把二叉树打印成多行](#-把二叉树打印成多行) - * [ 二叉搜索树的第 k 个结点](#-二叉搜索树的第-k-个结点) - * [滑动窗口的最大值](#滑动窗口的最大值) +* [ǰ](#ǰ) +* [ڶ ҪĻ֪ʶ](#ڶ-ҪĻ֪ʶ) + * [2. ʵ Singleton](#2-ʵ-singleton) + * [3. ظ](#3-ظ) + * [4. άеIJ](#4-άеIJ) + * [5. 滻ո](#5-滻ո) + * [6. βͷӡ](#6-βͷӡ) + * [7. ؽ](#7-ؽ) + * [8. һ](#8-һ) + * [9. ջʵֶ](#9-ջʵֶ) + * [10.1 쳲](#101-쳲) + * [10.2 ̨](#102-̨) + * [10.3 ̨̬](#103-̨̬) + * [10.4 θ](#104-θ) + * [11. תС](#11-תС) + * [12. е·](#12-е·) + * [13. ˵˶Χ](#13-˵˶Χ) + * [14. ](#14-) + * [15. 1 ĸ](#15--1-ĸ) +* [ Ĵ](#-Ĵ) + * [16. ֵη](#16-ֵη) + * [18. ɾظĽ](#18-ɾظĽ) + * [19. ʽƥ](#19-ʽƥ) + * [20. ʾֵַ](#20-ʾֵַ) + * [21. ˳ʹλżǰ](#21-˳ʹλżǰ) + * [22. е k ](#22-е-k-) + * [23. лڽ](#23-лڽ) + * [24. ת](#24-ת) + * [25. ϲ](#25-ϲ) + * [26. ӽṹ](#26-ӽṹ) +* [ ˼·](#-˼·) + * [27. ľ](#27-ľ) + * [28.1 ԳƵĶ](#281-ԳƵĶ) + * [28.2 ƽ](#282-ƽ) + * [29. ˳ʱӡ](#29-˳ʱӡ) + * [30. min ջ](#30--min-ջ) + * [31. ջѹ롢](#31-ջѹ뵯) + * [32.1 ´ӡ](#321-´ӡ) + * [32.3 Ѷӡɶ](#323--Ѷӡɶ) + * [32.3 ֮˳ӡ](#323-֮˳ӡ) + * [33. ĺ](#33-ĺ) + * [34. кΪijһֵ·](#34-кΪijһֵ·) + * [35. ĸ](#35-ĸ) + * [36. ˫](#36-˫) + * [37. л](#37-л) + * [38. ַ](#38-ַ) +* [ ŻʱͿռЧ](#-ŻʱͿռЧ) + * [39. гִһ](#39-гִһ) + * [40. С K ](#40-С-k-) + * [41.1 еλ](#411-еλ) + * [14.2 ַеһظַ](#142-ַеһظַ) + * [42. ](#42-) + * [43. 1 n 1 ֵĴ](#43--1--n--1-ֵĴ) + * [45. ųС](#45-ųС) + * [49. ](#49-) + * [50. һֻһεַλ](#50-һֻһεַλ) + * [51. е](#51-е) + * [52. ĵһ](#52-ĵһ) +* [ еĸ](#-еĸ) + * [53 гֵĴ](#53-гֵĴ) + * [54. ĵ k ](#54-ĵ-k-) + * [55 ](#55-) + * [56. ֻһε](#56-ֻһε) + * [57.1 Ϊ S ](#571-Ϊ-s-) + * [57.2 Ϊ S ](#572-Ϊ-s-) + * [58.1 ת˳](#581-ת˳) + * [58.2 תַ](#582-תַ) + * [59. ڵֵ](#59-ڵֵ) + * [61. ˿˳](#61-˿˳) + * [62. ԲȦʣµ](#62-ԲȦʣµ) + * [63. Ʊ](#63-Ʊ) + * [64. 1+2+3+...+n](#64--1+2+3++n) + * [65. üӼ˳ӷ](#65-üӼ˳ӷ) + * [66. ˻](#66-˻) +* [ ԰](#-԰) + * [67. ַת](#67-ַת) + * [68. ڵ͹](#68-ڵ͹) -# 第二章 面试需要的基础知识 +# ǰ -## 3. 数组中重复的数字 +ĺܶĿ Leetcode гֹһЩ˼·ͲظˡԿָ Offer鱾Ľ˼·߿ [Leetcode ](https://github.com/CyC2018/InterviewNotes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3.md)ȽƼȿ Leetcode ⣬ΪȽϵͳ֮ٿĿͺܼˡ -**题目描述** +# ڶ ҪĻ֪ʶ -在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为 7 的数组 {2, 3, 1, 0, 2, 5, 3},那么对应的输出是第一个重复的数字 2。 +## 2. ʵ Singleton -**解题思路** +**ʵ** -这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素放到第 i 个位置上。 +ʵУ˽о̬ӳٻʵĺôǣûõ࣬ôͲᴴ˽о̬ӶԼԴʵڶ̻߳DzȫģΪܹ߳ͬʱ if(uniqueInstance == null) ڵ飬ôͻʵ uniqueInstance ˽о̬ + +```java +public class Singleton { + private static Singleton uniqueInstance; + private Singleton() { + } + public static Singleton getUniqueInstance() { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + return uniqueInstance; + } +} +``` + +**̲߳ȫĽһ** + +ֻҪ getUniqueInstance() ø÷һֻһ̷߳ʣӶ˶ uniqueInstance жʵ⡣һһֻһ߳̽룬ϻһ˷ѡ + +```java +public static synchronized Singleton getUniqueInstance() { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + return uniqueInstance; +} +``` +**̲߳ȫĽ** + +ӳʵֱʵ + +```java +private static Singleton uniqueInstance = new Singleton(); +``` + +**̲߳ȫĽ** + +ǵһֱӶ getUniqueInstance() мʵֻҪ uniqueInstance = new Singleton(); ɡʹж uniqueInstance ǷѾʵûʵҪ + +```java +public class Singleton { + private volatile static Singleton uniqueInstance; + private Singleton() { + } + public static synchronized Singleton getUniqueInstance() { + if (uniqueInstance == null) { + synchronized (Singleton.class) { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + } + } + return uniqueInstance; + } +} +``` + +## 3. ظ + +**Ŀ** + +һΪ n ֶ 0 n-1 ķΧڡ ijЩظģ֪мظġҲ֪ÿظΡҳһظ֡ 磬볤Ϊ 7 {2, 3, 1, 0, 2, 5, 3}ôӦǵһظ 2 + +**˼·** + +Ԫ [0, n-1] Χڵ⣬ԽֵΪ i Ԫطŵ i λϡ ```java public boolean duplicate(int numbers[], int length, int[] duplication) { @@ -107,11 +177,11 @@ private void swap(int[] numbers, int i, int j) { } ``` -## 4. 二维数组中的查找 +## 4. άеIJ -**题目描述** +**Ŀ** -在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 +һάУÿһжմҵ˳ÿһжմϵµ˳һһάһжǷи ```java public boolean Find(int target, int [][] array) { @@ -127,21 +197,21 @@ public boolean Find(int target, int [][] array) { } ``` -## 5. 替换空格 +## 5. 滻ո -**题目描述** +**Ŀ** -请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 +ʵһһַеĿո滻ɡ%20磬ַΪ We Are Happy. 򾭹滻ַ֮Ϊ We%20Are%20Happy -**题目要求** +**ĿҪ** -以 O(1) 的空间复杂度来求解。 + O(1) Ŀռ临Ӷ⡣ ```java public String replaceSpace(StringBuffer str) { int n = str.length(); for (int i = 0; i < n; i++) { - if (str.charAt(i) == ' ') str.append(" "); // 尾部填充两个 + if (str.charAt(i) == ' ') str.append(" "); // β } int idxOfOriginal = n - 1; @@ -160,9 +230,9 @@ public String replaceSpace(StringBuffer str) { } ``` -## 6. 从尾到头打印链表 +## 6. βͷӡ -正向遍历然后调用 Collections.reverse(). +Ȼ Collections.reverse(). ```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -176,7 +246,7 @@ public ArrayList printListFromTailToHead(ListNode listNode) { } ``` -递归 +ݹ ```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -189,11 +259,11 @@ public ArrayList printListFromTailToHead(ListNode listNode) { } ``` -不使用库函数,并且不使用递归的迭代实现,利用链表的头插法为逆序的特性。 +ʹÿ⺯Ҳʹõݹĵʵ֣ͷ巨Ϊԡ ```java public ArrayList printListFromTailToHead(ListNode listNode) { - ListNode head = new ListNode(-1); // 头结点 + ListNode head = new ListNode(-1); // ͷ ListNode cur = listNode; while (cur != null) { ListNode next = cur.next; @@ -211,11 +281,11 @@ public ArrayList printListFromTailToHead(ListNode listNode) { } ``` -## 7. 重建二叉树 +## 7. ؽ -**题目描述** +**Ŀ** -输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 +ݶǰĽؽö ```java public TreeNode reConstructBinaryTree(int[] pre, int[] in) { @@ -235,11 +305,11 @@ private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int[] in, } ``` -## 8. 二叉树的下一个结点 +## 8. һ -**题目描述** +**Ŀ** -给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 +һеһ㣬ҳ˳һ㲢ҷءע⣬еĽ㲻ӽ㣬ͬʱָ򸸽ָ롣 ```java public TreeLinkNode GetNext(TreeLinkNode pNode) { @@ -260,7 +330,7 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) { } ``` -## 9. 用两个栈实现队列 +## 9. ջʵֶ ```java Stack stack1 = new Stack(); @@ -280,7 +350,7 @@ public int pop() { } ``` -## 10.1 斐波那契数列 +## 10.1 쳲 ```java private int[] fib = new int[40]; @@ -298,7 +368,7 @@ public int Fibonacci(int n) { } ``` -## 10.2 跳台阶 +## 10.2 ̨ ```java public int JumpFloor(int target) { @@ -313,7 +383,7 @@ public int JumpFloor(int target) { } ``` -## 10.3 变态跳台阶 +## 10.3 ̨̬ ```java public int JumpFloorII(int target) { @@ -328,11 +398,11 @@ public int JumpFloorII(int target) { } ``` -## 10.4 矩形覆盖 +## 10.4 θ -**题目描述** +**Ŀ** -我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? +ǿ 2\*1 СκŻȥǸľΡ n 2\*1 Сصظһ 2\*n ĴΣܹжַ ```java public int RectCover(int target) { @@ -342,11 +412,11 @@ public int RectCover(int target) { ``` -## 11. 旋转数组的最小数字 +## 11. תС -**题目描述** +**Ŀ** -把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 +һʼɸԪذᵽĩβdz֮Ϊת һǵݼһתתСԪء {3, 4, 5, 1, 2} Ϊ {1, 2, 3, 4, 5} һתСֵΪ 1 NOTEԪض 0СΪ 0뷵 0 ```java public int minNumberInRotateArray(int[] array) { @@ -358,11 +428,11 @@ public int minNumberInRotateArray(int[] array) { } ``` -## 12. 矩阵中的路径 +## 12. е· -**题目描述** +**Ŀ** -请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。 +һжһǷһijַַ··ԴӾеһӿʼÿһھңϣƶһӡһ·˾еijһӣ·ٽøӡ a b c e s f c s a d e e аһַ "bcced" ·Ǿв "abcb" ·Ϊַĵһַ b ռ˾еĵһеڶ֮·ٴνøӡ ```java private int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; @@ -398,11 +468,12 @@ private boolean backtracking(char[][] m, int rows, int cols, char[] str, boolean } ``` -## 13. 机器人的运动范围 -**题目描述** +## 13. ˵˶Χ -地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子? +**Ŀ** + +һ m к n еķһ˴ 0, 0 ĸӿʼƶÿһֻңϣĸƶһ񣬵Dzܽλ֮ʹ k ĸӡ 磬 k Ϊ 18 ʱܹ뷽35, 37Ϊ 3+5+3+7 = 18ǣܽ뷽35, 38Ϊ 3+5+3+8 = 19ʸûܹﵽٸӣ ```java private int cnt = 0; @@ -444,7 +515,29 @@ private void initDigitSum(int rows, int cols) { } ``` -## 15. 二进制中 1 的个数 +## 14. + +**Ŀ** + +һӼɶΣʹÿεijȳ˻ + +**˼·** + +ܶüΪ 3 ӣҲгΪ 1 ӳ֣ˣʹѾкóΪ 3 óһ볤Ϊ 1 ϣгγΪ 2 ӡ + +```java +int maxProductAfterCuttin(int length) { + if (length < 2) return 0; + if (length == 2) return 1; + if (length == 3) return 2; + int timesOf3 = length / 3; + if (length - timesOf3 * 3 == 1) timesOf3--; + int timesOf2 = (length - timesOf3 * 3) / 2; + return (int) (Math.pow(3, timesOf3)) * (int) (Math.pow(2, timesOf2)); +} +``` + +## 15. 1 ĸ ```java public int NumberOf1(int n) { @@ -452,7 +545,7 @@ public int NumberOf1(int n) { } ``` -n&(n-1) 该位运算是去除 n 的位级表示中最低的那一位。例如对于二进制表示 10110100,减去 1 得到 10110011,这两个数相与得到 10110000。 +n&(n-1) λȥ n λʾ͵һλڶƱʾ 10110100ȥ 1 õ 10110011õ 10110000 ```java public int NumberOf1(int n) { @@ -466,9 +559,9 @@ public int NumberOf1(int n) { ``` -# 第三章 高质量的代码 +# Ĵ -## 16. 数值的整数次方 +## 16. ֵη ```java public double Power(double base, int exponent) { @@ -485,11 +578,30 @@ public double Power(double base, int exponent) { } ``` -## 19. 正则表达式匹配 +## 18. ɾظĽ -**题目描述** +```java +public ListNode deleteDuplication(ListNode pHead) { + if (pHead == null) return null; + if (pHead.next == null) return pHead; + if (pHead.val == pHead.next.val) { + ListNode next = pHead.next; + while (next != null && pHead.val == next.val) { + next = next.next; + } + return deleteDuplication(next); + } else { + pHead.next = deleteDuplication(pHead.next); + return pHead; + } +} +``` -请实现一个函数用来匹配包括'.'和'\*'的正则表达式。模式中的字符'.'表示任意一个字符,而'\*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab\*ac\*a"匹配,但是与"aa.a"和"ab\*a"均不匹配 +## 19. ʽƥ + +**Ŀ** + +ʵһƥ '.' '\*' ʽģʽеַ '.' ʾһַ '\*' ʾǰַԳΣ 0 Σ ڱУƥַַָƥģʽ磬ַ "aaa" ģʽ "a.a" "ab\*ac\*a" ƥ䣬 "aa.a" "ab\*a" ƥ ```java public boolean match(char[] str, char[] pattern) { @@ -512,7 +624,11 @@ public boolean match(char[] str, char[] pattern) { } ``` -## 20. 表示数值的字符串 +## 20. ʾֵַ + +**Ŀ** + +ʵһжַǷʾֵС磬ַ "+100","5e2","-123","3.1416" "-1E-16" ʾֵ "12e","1a3.14","1.2.3","+-5" "12e+4.3" ǡ ```java public boolean isNumeric(char[] str) { @@ -521,10 +637,10 @@ public boolean isNumeric(char[] str) { } ``` -## 21. 调整数组顺序使奇数位于偶数前面 +## 21. ˳ʹλżǰ -时间复杂度 : O(n2) -空间复杂度 : O(1) +ʱ临Ӷ : O(n2) +ռ临Ӷ : O(1) ```java public void reOrderArray(int[] array) { @@ -544,7 +660,23 @@ public void reOrderArray(int[] array) { } ``` -## 22. 链表中倒数第 k 个结点 +ʱ临Ӷ : O(n) +ռ临Ӷ : O(n) + +```java +public void reOrderArray(int[] array) { + int oddCnt = 0; + for (int num : array) if (num % 2 == 1) oddCnt++; + int[] copy = array.clone(); + int i = 0, j = oddCnt; + for (int num : copy) { + if (num % 2 == 1) array[i++] = num; + else array[j++] = num; + } +} +``` + +## 22. е k ```java public ListNode FindKthToTail(ListNode head, int k) { @@ -561,23 +693,9 @@ public ListNode FindKthToTail(ListNode head, int k) { } ``` -时间复杂度 : O(n) -空间复杂度 : O(n) -```java -public void reOrderArray(int[] array) { - int oddCnt = 0; - for (int num : array) if (num % 2 == 1) oddCnt++; - int[] copy = array.clone(); - int i = 0, j = oddCnt; - for (int num : copy) { - if (num % 2 == 1) array[i++] = num; - else array[j++] = num; - } -} -``` -## 23. 链表中环的入口结点 +## 23. лڽ ```java public ListNode EntryNodeOfLoop(ListNode pHead) { @@ -599,7 +717,7 @@ public ListNode EntryNodeOfLoop(ListNode pHead) { } ``` -## 24. 反转链表 +## 24. ת ```java public ListNode ReverseList(ListNode head) { @@ -614,7 +732,7 @@ public ListNode ReverseList(ListNode head) { } ``` -## 25. 合并两个排序的链表 +## 25. ϲ ```java public ListNode Merge(ListNode list1, ListNode list2) { @@ -636,7 +754,7 @@ public ListNode Merge(ListNode list1, ListNode list2) { } ``` -## 26. 树的子结构 +## 26. ӽṹ ```java public boolean HasSubtree(TreeNode root1, TreeNode root2) { @@ -653,9 +771,9 @@ private boolean isSubtree(TreeNode root1, TreeNode root2) { } ``` -# 第四章 解决面试题的思路 +# ˼· -## 27. 二叉树的镜像 +## 27. ľ ```java public void Mirror(TreeNode root) { @@ -668,7 +786,7 @@ public void Mirror(TreeNode root) { } ``` -## 28. 对称的二叉树 +## 28.1 ԳƵĶ ```java boolean isSymmetrical(TreeNode pRoot) { @@ -684,7 +802,26 @@ boolean isSymmetrical(TreeNode t1, TreeNode t2) { } ``` -## 29. 顺时针打印矩阵 +## 28.2 ƽ + +```java +private boolean isBalanced = true; + +public boolean IsBalanced_Solution(TreeNode root) { + height(root); + return isBalanced; +} + +private int height(TreeNode root) { + if (root == null) return 0; + int left = height(root.left); + int right = height(root.right); + if (Math.abs(left - right) > 1) isBalanced = false; + return 1 + Math.max(left, right); +} +``` + +## 29. ˳ʱӡ ```java public ArrayList printMatrix(int[][] matrix) { @@ -701,7 +838,7 @@ public ArrayList printMatrix(int[][] matrix) { } ``` -## 30. 包含 min 函数的栈 +## 30. min ջ ```java private Stack stack = new Stack<>(); @@ -729,7 +866,7 @@ public int min() { } ``` -## 31. 栈的压入、弹出序列 +## 31. ջѹ롢 ```java public boolean IsPopOrder(int[] pushA, int[] popA) { @@ -746,7 +883,7 @@ public boolean IsPopOrder(int[] pushA, int[] popA) { } ``` -## 32. 从上往下打印二叉树 +## 32.1 ´ӡ ```java public ArrayList PrintFromTopToBottom(TreeNode root) { @@ -767,7 +904,61 @@ public ArrayList PrintFromTopToBottom(TreeNode root) { } ``` -## 33. 二叉搜索树的后序遍历序列 +## 32.3 Ѷӡɶ + +```java +ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + if (pRoot == null) return ret; + Queue queue = new LinkedList<>(); + queue.add(pRoot); + while (!queue.isEmpty()) { + int cnt = queue.size(); + ArrayList list = new ArrayList<>(); + for (int i = 0; i < cnt; i++) { + TreeNode node = queue.poll(); + list.add(node.val); + if (node.left != null) queue.add(node.left); + if (node.right != null) queue.add(node.right); + } + ret.add(list); + } + return ret; +} +``` + +## 32.3 ֮˳ӡ + +```java +public ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + if (pRoot == null) return ret; + Queue queue = new LinkedList<>(); + queue.add(pRoot); + boolean reverse = false; + while (!queue.isEmpty()) { + int cnt = queue.size(); + ArrayList list = new ArrayList<>(); + for (int i = 0; i < cnt; i++) { + TreeNode node = queue.poll(); + list.add(node.val); + if (node.left != null) queue.add(node.left); + if (node.right != null) queue.add(node.right); + } + if (reverse) { + Collections.reverse(list); + reverse = false; + } else { + reverse = true; + } + ret.add(list); + } + return ret; +} +``` + + +## 33. ĺ ```java public boolean VerifySquenceOfBST(int[] sequence) { @@ -790,7 +981,7 @@ private boolean verify(int[] sequence, int start, int end) { } ``` -## 34. 二叉树中和为某一值的路径 +## 34. кΪijһֵ· ```java private ArrayList> ret = new ArrayList<>(); @@ -814,25 +1005,29 @@ private void dfs(TreeNode node, int target, int curSum, ArrayList path) } ``` -## 35. 复杂链表的复制 +## 35. ĸ -第一步,在每个节点的后面插入复制的节点。 +**Ŀ** -![](https://github.com/00000H/notes/blob/master/pics/f8b12555-967b-423d-a84e-bc9eff104b8b.jpg) +һÿڵнڵֵԼָ룬һָһڵ㣬һָָһڵ㣩ؽΪƺ headע⣬벻ҪزеĽڵãֱӷؿգ -第二步,对复制节点的 random 链接进行赋值。 +һÿڵĺ븴ƵĽڵ㡣 -![](https://github.com/00000H/notes/blob/master/pics/7b877a2a-8fd1-40d8-a34c-c445827300b8.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f8b12555-967b-423d-a84e-bc9eff104b8b.jpg) -第三步,拆分。 +ڶԸƽڵ random ӽиֵ -![](https://github.com/00000H/notes/blob/master/pics/b2b6253c-c701-4b30-aff4-bc3c713542a7.jpg) +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7b877a2a-8fd1-40d8-a34c-c445827300b8.jpg) + +֡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b2b6253c-c701-4b30-aff4-bc3c713542a7.jpg) ```java public RandomListNode Clone(RandomListNode pHead) { if (pHead == null) return null; - // 插入新节点 + // ½ڵ RandomListNode cur = pHead; while (cur != null) { RandomListNode node = new RandomListNode(cur.label); @@ -840,7 +1035,7 @@ public RandomListNode Clone(RandomListNode pHead) { cur.next = node; cur = node.next; } - // 建立 random 链接 + // random cur = pHead; while (cur != null) { RandomListNode clone = cur.next; @@ -849,7 +1044,7 @@ public RandomListNode Clone(RandomListNode pHead) { } cur = clone.next; } - // 拆分 + // RandomListNode pCloneHead = pHead.next; cur = pHead; while (cur.next != null) { @@ -861,7 +1056,11 @@ public RandomListNode Clone(RandomListNode pHead) { } ``` -## 36. 二叉搜索树与双向链表 +## 36. ˫ + +**Ŀ** + +һööתһ˫ҪܴκµĽ㣬ֻܵнָָ ```java private TreeNode pre = null; @@ -882,7 +1081,7 @@ private void inOrder(TreeNode node) { } ``` -## 37. 序列化二叉树 +## 37. л ```java private String serizeString = ""; @@ -915,7 +1114,11 @@ private TreeNode Deserialize() { } ``` -## 38. 字符串的排列 +## 38. ַ + +**Ŀ** + +һַ , ֵӡַַСַ abc, ӡַ a, b, c гַ abc, acb, bac, bca, cab cba ```java private ArrayList ret = new ArrayList<>(); @@ -935,7 +1138,7 @@ private void backtracking(char[] chars, boolean[] used, String s) { } for (int i = 0; i < chars.length; i++) { if (used[i]) continue; - if (i != 0 && chars[i] == chars[i - 1] && !used[i - 1]) continue; // 保证不重复 + if (i != 0 && chars[i] == chars[i - 1] && !used[i - 1]) continue; // ֤ظ used[i] = true; backtracking(chars, used, s + chars[i]); used[i] = false; @@ -943,9 +1146,9 @@ private void backtracking(char[] chars, boolean[] used, String s) { } ``` -# 第五章 优化时间和空间效率 +# ŻʱͿռЧ -## 39. 数组中出现次数超过一半的数字 +## 39. гִһ ```java public int MoreThanHalfNum_Solution(int[] array) { @@ -967,12 +1170,12 @@ public int MoreThanHalfNum_Solution(int[] array) { ``` -## 40. 最小的 K 个数 +## 40. С K -构建大小为 k 的小顶堆。 +СΪ k Сѡ -时间复杂度:O(nlgk) -空间复杂度:O(k) +ʱ临ӶȣO(nlgk) +ռ临ӶȣO(k) ```java public ArrayList GetLeastNumbers_Solution(int[] input, int k) { @@ -989,10 +1192,10 @@ public ArrayList GetLeastNumbers_Solution(int[] input, int k) { } ``` -利用快速选择 +ÿѡ -时间复杂度:O(n) -空间复杂度:O(1) +ʱ临ӶȣO(n) +ռ临ӶȣO(1) ```java public ArrayList GetLeastNumbers_Solution(int[] input, int k) { @@ -1047,7 +1250,68 @@ private boolean less(int v, int w) { } ``` -## 42. 连续子数组的最大和 +## 41.1 еλ + + +**Ŀ** + +εõһеλжֵôλֵ֮λмֵжżֵôλֵ֮мƽֵ + +```java +private PriorityQueue maxHeap = new PriorityQueue<>((o1, o2) -> o2-o1); // ʵ߲ +private PriorityQueue minHeep = new PriorityQueue<>(); // ʵұ߲֣ұ߲Ԫش߲ +private int cnt = 0; + +public void Insert(Integer num) { + // Ҫ֤Ѵƽ״̬ + if(cnt % 2 == 0) { + // Ϊż²뵽СѣȾɸѡܱ֤еԪضССеԪ + maxHeap.add(num); + minHeep.add(maxHeap.poll()); + } else { + minHeep.add(num); + maxHeap.add(minHeep.poll()); + } + cnt++; +} + +public Double GetMedian() { + if(cnt % 2 == 0) { + return (maxHeap.peek() + minHeep.peek()) / 2.0; + } else { + return (double) minHeep.peek(); + } +} +``` + +## 14.2 ַеһظַ + +**Ŀ** + +ʵһҳַеһֻһεַ磬ַֻǰַ "go" ʱһֻһεַ "g"Ӹַжǰַgoogle" ʱһֻһεַ "l" + +```java +//Insert one char from stringstream +private int[] cnts = new int[256]; +private Queue queue = new LinkedList<>(); + +public void Insert(char ch) { + cnts[ch]++; + queue.add(ch); + while (!queue.isEmpty() && cnts[queue.peek()] > 1) { + queue.poll(); + } +} + +//return the first appearence once char in current stringstream +public char FirstAppearingOnce() { + if (queue.isEmpty()) return '#'; + return queue.peek(); +} +``` + + +## 42. ```java public int FindGreatestSumOfSubArray(int[] array) { @@ -1063,9 +1327,9 @@ public int FindGreatestSumOfSubArray(int[] array) { } ``` -## 43. 从 1 到 n 整数中 1 出现的次数 +## 43. 1 n 1 ֵĴ -解题参考:[Leetcode : 233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython) +ο[Leetcode : 233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython) ```java public int NumberOf1Between1AndN_Solution(int n) { @@ -1078,7 +1342,11 @@ public int NumberOf1Between1AndN_Solution(int n) { } ``` -## 45. 把数组排成最小的数 +## 45. ųС + +**Ŀ** + +һ飬ƴųһӡƴӳСһ {332321}ӡųɵСΪ 321323 ```java public String PrintMinNumber(int[] numbers) { @@ -1092,7 +1360,11 @@ public String PrintMinNumber(int[] numbers) { } ``` -## 49. 丑数 +## 49. + +**Ŀ** + +ֻ 23 5 Ugly Number 68 dz 14 ǣΪ 7 ϰǰ 1 ǵһ󰴴С˳ĵ N ```java public int GetUglyNumber_Solution(int index) { @@ -1113,7 +1385,7 @@ public int GetUglyNumber_Solution(int index) { } ``` -## 50. 第一个只出现一次的字符位置 +## 50. һֻһεַλ ```java public int FirstNotRepeatingChar(String str) { @@ -1124,7 +1396,7 @@ public int FirstNotRepeatingChar(String str) { } ``` -## 51. 数组中的逆序对 +## 51. е ```java private long cnt = 0; @@ -1151,7 +1423,7 @@ private void merge(int[] a, int start, int mid, int end) { else if (a[i] < a[j]) tmp[k] = a[i++]; else { tmp[k] = a[j++]; - this.cnt += mid - i + 1; // a[i] > a[j] ,说明 a[i...mid] 都大于 a[j] + this.cnt += mid - i + 1; // a[i] > a[j] ˵ a[i...mid] a[j] } k++; } @@ -1162,7 +1434,7 @@ private void merge(int[] a, int start, int mid, int end) { } ``` -## 52. 两个链表的第一个公共结点 +## 52. ĵһ ```java public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { @@ -1177,9 +1449,11 @@ public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { } ``` -# 第六章 面试中的各项能力 +# еĸ + +## 53 гֵĴ + -## 53 数字在排序数组中出现的次数 ```java public int GetNumberOfK(int[] array, int k) { @@ -1195,7 +1469,7 @@ public int GetNumberOfK(int[] array, int k) { } ``` -## 54. 二叉搜索树的第 k 个结点 +## 54. ĵ k ```java TreeNode ret; @@ -1216,7 +1490,7 @@ private void inorder(TreeNode root, int k) { } ``` -## 55 二叉树的深度 +## 55 ```java public int TreeDepth(TreeNode root) { @@ -1225,19 +1499,25 @@ public int TreeDepth(TreeNode root) { } ``` -## 56. 数组中只出现一次的数字 +## 56. ֻһε -两个不相等的元素在位级表示上必定会有一位存在不同。 +**Ŀ** -将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。 +һ֮⣬ֶΣҳ -diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。 +**˼·** + +ȵԪλʾϱضһλڲͬ + +ԪõĽΪظԪĽ + +diff &= -diff õ diff Ҳ಻Ϊ 0 λҲDzظԪλʾҲ಻ͬһλһλͿԽԪֿ ```java public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) { int diff = 0; for (int num : array) diff ^= num; - // 得到最右一位 + // õһλ diff &= -diff; for (int num : array) { if ((num & diff) == 0) num1[0] ^= num; @@ -1246,7 +1526,11 @@ public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) { } ``` -## 57. 和为 S 的两个数字 +## 57.1 Ϊ S + +**Ŀ** + +һһ Sвǵǵĺ Sжֵĺ͵ Sij˻Сġ ```java public ArrayList FindNumbersWithSum(int[] array, int sum) { @@ -1261,181 +1545,11 @@ public ArrayList FindNumbersWithSum(int[] array, int sum) { } ``` -## 58.1 翻转单词顺序列 +## 57.2 Ϊ S -```java -public String ReverseSentence(String str) { - if (str.length() == 0) return str; - int n = str.length(); - char[] chars = str.toCharArray(); - int start = 0, end = 0; - while (end <= n) { - if (end == n || chars[end] == ' ') { - reverse(chars, start, end - 1); - start = end + 1; - } - end++; - } - reverse(chars, 0, n - 1); - return new String(chars); -} +**Ŀ** -private void reverse(char[] c, int start, int end) { - while (start < end) { - char t = c[start]; - c[start] = c[end]; - c[end] = t; - start++; - end--; - } -} -``` - -## 58.2 左旋转字符串 - -```java -public String LeftRotateString(String str, int n) { - if (str.length() == 0) return ""; - char[] c = str.toCharArray(); - reverse(c, 0, n - 1); - reverse(c, n, c.length - 1); - reverse(c, 0, c.length - 1); - return new String(c); -} - -private void reverse(char[] c, int i, int j) { - while (i < j) { - char t = c[i]; - c[i] = c[j]; - c[j] = t; - i++; - j--; - } -} -``` - -## 61. 扑克牌顺子 - -```java -public boolean isContinuous(int[] numbers) { - if (numbers.length < 5) return false; - Arrays.sort(numbers); - int cnt = 0; - for (int num : numbers) if (num == 0) cnt++; - for (int i = cnt; i < numbers.length - 1; i++) { - if (numbers[i + 1] == numbers[i]) return false; - int cut = numbers[i + 1] - numbers[i] - 1; - if (cut > cnt) return false; - cnt -= cut; - } - return true; -} -``` - -## 62. 圆圈中最后剩下的数 - -**题目描述** - -让小朋友们围成一个大圈。然后 , 他随机指定一个数 m, 让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌 , 然后可以在礼品箱中任意的挑选礼物 , 并且不再回到圈中 , 从他的下一个小朋友开始 , 继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友 , 可以不用表演 , - -**解题思路** - -约瑟夫环 - -```java -public int LastRemaining_Solution(int n, int m) { - if (n == 0) return -1; - if (n == 1) return 0; - return (LastRemaining_Solution(n - 1, m) + m) % n; -} -``` - -## 64. 求 1+2+3+...+n - -```java -public int Sum_Solution(int n) { - if(n == 0) return 0; - return n + Sum_Solution(n - 1); -} -``` - -## 65. 不用加减乘除做加法 - -a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。 - -```java -public int Add(int num1, int num2) { - if(num2 == 0) return num1; - return Add(num1 ^ num2, (num1 & num2) << 1); -} -``` - -## 66. 构建乘积数组 - -```java -public int[] multiply(int[] A) { - int n = A.length; - int[][] dp = new int[n][n]; - for (int i = 0; i < n; i++) { - dp[i][i] = A[i]; - } - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n; j++) { - dp[i][j] = dp[i][j - 1] * A[j]; - } - } - - int[] B = new int[n]; - Arrays.fill(B, 1); - for (int i = 0; i < n; i++) { - if (i != 0) B[i] *= dp[0][i - 1]; - if (i != n - 1) B[i] *= dp[i + 1][n - 1]; - } - return B; -} -``` - -# 第七章 两个面试案例 - -## 67. 把字符串转换成整数 - -```java -public int StrToInt(String str) { - if (str.length() == 0) return 0; - char[] chars = str.toCharArray(); - boolean isNegative = chars[0] == '-'; - int ret = 0; - for (int i = 0; i < chars.length; i++) { - if (i == 0 && (chars[i] == '+' || chars[i] == '-')) continue; - if (chars[i] < '0' || chars[i] > '9') return 0; - ret = ret * 10 + (chars[i] - '0'); - } - return isNegative ? -ret : ret; -} -``` - -# 未分类 - -## 平衡二叉树 - -```java -private boolean isBalanced = true; - -public boolean IsBalanced_Solution(TreeNode root) { - height(root); - return isBalanced; -} - -private int height(TreeNode root) { - if (root == null) return 0; - int left = height(root.left); - int right = height(root.right); - if (Math.abs(left - right) > 1) isBalanced = false; - return 1 + Math.max(left, right); -} -``` - -## 和为 S 的连续正数序列 +Ϊ 100 18, 19, 20, 21, 22 ```java public ArrayList> FindContinuousSequence(int sum) { @@ -1466,130 +1580,80 @@ public ArrayList> FindContinuousSequence(int sum) { } ``` -## 字符流中第一个不重复的字符 +## 58.1 ת˳ + +**Ŀ** + +룺"I am a student." + +"student. a am I" ```java -//Insert one char from stringstream -private int[] cnts = new int[256]; -private Queue queue = new LinkedList<>(); - -public void Insert(char ch) { - cnts[ch]++; - queue.add(ch); - while (!queue.isEmpty() && cnts[queue.peek()] > 1) { - queue.poll(); - } -} - -//return the first appearence once char in current stringstream -public char FirstAppearingOnce() { - if (queue.isEmpty()) return '#'; - return queue.peek(); -} -``` - - - -## 删除链表中重复的结点 - -```java -public ListNode deleteDuplication(ListNode pHead) { - if (pHead == null) return null; - if (pHead.next == null) return pHead; - if (pHead.val == pHead.next.val) { - ListNode next = pHead.next; - while (next != null && pHead.val == next.val) { - next = next.next; +public String ReverseSentence(String str) { + if (str.length() == 0) return str; + int n = str.length(); + char[] chars = str.toCharArray(); + int start = 0, end = 0; + while (end <= n) { + if (end == n || chars[end] == ' ') { + reverse(chars, start, end - 1); + start = end + 1; } - return deleteDuplication(next); - } else { - pHead.next = deleteDuplication(pHead.next); - return pHead; + end++; + } + reverse(chars, 0, n - 1); + return new String(chars); +} + +private void reverse(char[] c, int start, int end) { + while (start < end) { + char t = c[start]; + c[start] = c[end]; + c[end] = t; + start++; + end--; } } ``` -## 按之字形顺序打印二叉树 +## 58.2 תַ + +**Ŀ** + +һַ Sѭ K λ磬ַ S=abcXYZdef, Ҫѭ 3 λĽXYZdefabc ```java -public ArrayList> Print(TreeNode pRoot) { - ArrayList> ret = new ArrayList<>(); - if (pRoot == null) return ret; - Queue queue = new LinkedList<>(); - queue.add(pRoot); - boolean reverse = false; - while (!queue.isEmpty()) { - int cnt = queue.size(); - ArrayList list = new ArrayList<>(); - for (int i = 0; i < cnt; i++) { - TreeNode node = queue.poll(); - list.add(node.val); - if (node.left != null) queue.add(node.left); - if (node.right != null) queue.add(node.right); - } - if (reverse) { - Collections.reverse(list); - reverse = false; - } else { - reverse = true; - } - ret.add(list); +public String LeftRotateString(String str, int n) { + if (str.length() == 0) return ""; + char[] c = str.toCharArray(); + reverse(c, 0, n - 1); + reverse(c, n, c.length - 1); + reverse(c, 0, c.length - 1); + return new String(c); +} + +private void reverse(char[] c, int i, int j) { + while (i < j) { + char t = c[i]; + c[i] = c[j]; + c[j] = t; + i++; + j--; } - return ret; } ``` -## 把二叉树打印成多行 +## 59. ڵֵ -```java -ArrayList> Print(TreeNode pRoot) { - ArrayList> ret = new ArrayList<>(); - if (pRoot == null) return ret; - Queue queue = new LinkedList<>(); - queue.add(pRoot); - while (!queue.isEmpty()) { - int cnt = queue.size(); - ArrayList list = new ArrayList<>(); - for (int i = 0; i < cnt; i++) { - TreeNode node = queue.poll(); - list.add(node.val); - if (node.left != null) queue.add(node.left); - if (node.right != null) queue.add(node.right); - } - ret.add(list); - } - return ret; -} -``` +**Ŀ** -## 二叉搜索树的第 k 个结点 - -```java -TreeNode ret; -int cnt = 0; -TreeNode KthNode(TreeNode pRoot, int k) -{ - inorder(pRoot, k); - return ret; -} - -private void inorder(TreeNode root, int k) { - if(root == null) return; - if(cnt > k) return; - inorder(root.left, k); - cnt++; - if(cnt == k) ret = root; - inorder(root.right, k); -} -``` - -## 滑动窗口的最大值 +һͻڵĴСҳлֵֵ磬 {2, 3, 4, 2, 6, 2, 5, 1} ڵĴС 3ôһ 6 ڣǵֱֵΪ {4, 4, 6, 6, 6, 5} ```java public ArrayList maxInWindows(int[] num, int size) { ArrayList ret = new ArrayList<>(); - PriorityQueue heap = new PriorityQueue((o1, o2) -> o2 - o1); if (size > num.length || size < 1) return ret; + PriorityQueue heap = new PriorityQueue((o1, o2) -> o2 - o1); for (int i = 0; i < size; i++) heap.add(num[i]); ret.add(heap.peek()); for (int i = 1; i + size - 1 < num.length; i++) { @@ -1601,5 +1665,146 @@ public ArrayList maxInWindows(int[] num, int size) { } ``` +## 61. ˿˳ +**Ŀ** +ƣдСΪӣСΪ 0жǷ˳ӡ + +```java +public boolean isContinuous(int[] numbers) { + if (numbers.length < 5) return false; + Arrays.sort(numbers); + int cnt = 0; + for (int num : numbers) if (num == 0) cnt++; + for (int i = cnt; i < numbers.length - 1; i++) { + if (numbers[i + 1] == numbers[i]) return false; + int cut = numbers[i + 1] - numbers[i] - 1; + if (cut > cnt) return false; + cnt -= cut; + } + return true; +} +``` + +## 62. ԲȦʣµ + +**Ŀ** + +СΧһȦȻ , ָһ m, ñΪ 0 Сѿʼÿκ m-1 ǸСҪг׸ , ȻƷѡ , ҲٻصȦ , һСѿʼ , 0...m-1 .... ȥ .... ֱʣһС , Բñݡ + +**˼·** + +Լɪ + +```java +public int LastRemaining_Solution(int n, int m) { + if (n == 0) return -1; + if (n == 1) return 0; + return (LastRemaining_Solution(n - 1, m) + m) % n; +} +``` + +## 63. Ʊ + +**Ŀ** + +һһǰ档 + +```java +public int maxProfit(int[] prices) { + int n = prices.length; + if(n == 0) return 0; + int soFarMin = prices[0]; + int max = 0; + for(int i = 1; i < n; i++) { + if(soFarMin > prices[i]) soFarMin = prices[i]; + else max = Math.max(max, prices[i] - soFarMin); + } + return max; +} +``` + +## 64. 1+2+3+...+n + +**Ŀ** + + 1+2+3+...+nҪʹó˳forwhileifelseswitchcase ȹؼּж䣨A?B:C + +```java +public int Sum_Solution(int n) { + if(n == 0) return 0; + return n + Sum_Solution(n - 1); +} +``` + +## 65. üӼ˳ӷ + +a ^ b ʾûпǽλĺͣ(a & b) << 1 ǽλݹֹԭ (a & b) << 1 ұ߻һ 0ôݹ飬λұߵ 0 ࣬λΪ 0ݹֹ + +```java +public int Add(int num1, int num2) { + if(num2 == 0) return num1; + return Add(num1 ^ num2, (num1 & num2) << 1); +} +``` + +## 66. ˻ + +**Ŀ** + +һ A[0, 1,..., n-1], 빹һ B[0, 1,..., n-1], B еԪ B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]ʹó + +```java +public int[] multiply(int[] A) { + int n = A.length; + int[][] dp = new int[n][n]; + for (int i = 0; i < n; i++) { + dp[i][i] = A[i]; + } + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + dp[i][j] = dp[i][j - 1] * A[j]; + } + } + + int[] B = new int[n]; + Arrays.fill(B, 1); + for (int i = 0; i < n; i++) { + if (i != 0) B[i] *= dp[0][i - 1]; + if (i != n - 1) B[i] *= dp[i + 1][n - 1]; + } + return B; +} +``` + +# ԰ + +## 67. ַת + +```java +public int StrToInt(String str) { + if (str.length() == 0) return 0; + char[] chars = str.toCharArray(); + boolean isNegative = chars[0] == '-'; + int ret = 0; + for (int i = 0; i < chars.length; i++) { + if (i == 0 && (chars[i] == '+' || chars[i] == '-')) continue; + if (chars[i] < '0' || chars[i] > '9') return 0; + ret = ret * 10 + (chars[i] - '0'); + } + return isNegative ? -ret : ret; +} +``` + +## 68. ڵ͹ + +Ƕ͹⣺ + +```java +public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); + if(root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); + return root; +} +``` diff --git a/notes/算法.md b/notes/算法.md new file mode 100644 index 00000000..c2d4fa60 --- /dev/null +++ b/notes/算法.md @@ -0,0 +1,1632 @@ + +* [](#) + * [ջ](#ջ) + * [1. ʵ](#1-ʵ) + * [2. ʵ](#2-ʵ) + * [](#) + * [㷨](#㷨) + * [1. ת](#1-ת) + * [2. ѧģ](#2-ѧģ) + * [3. ThreeSum](#3-threesum) + * [4. ʵ](#4-ʵ) + * [5. ע](#5-ע) + * [union-find](#union-find) + * [1. quick-find 㷨](#1-quick-find-㷨) + * [2. quick-union 㷨](#2-quick-union-㷨) + * [3. Ȩ quick-union 㷨](#3-Ȩ-quick-union-㷨) + * [4. ·ѹļȨ quick-union 㷨](#4-·ѹļȨ-quick-union-㷨) + * [5. union-find 㷨ıȽ](#5--union-find-㷨ıȽ) +* [ڶ ](#ڶ-) + * [㷨](#㷨) + * [Լ](#Լ) + * [ѡ](#ѡ) + * [](#) + * [ѡͲıȽ](#ѡͲıȽ) + * [ϣ](#ϣ) + * [鲢](#鲢) + * [鲢](#鲢) + * [Զ¹鲢](#Զ¹鲢) + * [ԵϹ鲢](#ԵϹ鲢) + * [](#) + * [㷨](#㷨) + * [з](#з) + * [ܷ](#ܷ) + * [㷨Ľ](#㷨Ľ) + * [л](#л) + * [ȡ](#ȡ) + * [з](#з) + * [ȶ](#ȶ) + * [](#) + * [ϸ³](#ϸ³) + * [Ԫ](#Ԫ) + * [ɾԪ](#ɾԪ) + * [](#) + * [](#) + * [Ӧ](#Ӧ) + * [㷨ıȽ](#㷨ıȽ) + * [Java 㷨ʵ](#java-㷨ʵ) + * [зֵĿѡ㷨](#зֵĿѡ㷨) +* [ ](#-) + * [ű](#ű) + * [API](#api) + * [ű](#ű) + * [ʵ](#ʵ) + * [Ķֲ](#Ķֲ) + * [Զֲҵķ](#Զֲҵķ) + * [](#) + * [get()](#get) + * [put()](#put) + * [](#) + * [floor()](#floor) + * [rank()](#rank) + * [min()](#min) + * [deleteMin()](#deletemin) + * [delete()](#delete) + * [keys()](#keys) + * [ܷ](#ܷ) + * [ƽ](#ƽ) + * [2-3 ](#2-3-) + * [](#) + * [](#) + * [ڶ](#ڶ) + * [ת](#ת) + * [ת](#ת) + * [ɫת](#ɫת) + * [](#) + * [ɾС](#ɾС) + * [](#) + * [ɢб](#ɢб) + * [ɢк](#ɢк) + * [ɢб](#ɢб) + * [̽ⷨɢб](#̽ⷨɢб) + * [](#) + * [](#) + * [ɾ](#ɾ) + * [С](#С) + * [Ӧ](#Ӧ) + * [ַűʵֵıȽ](#ַűʵֵıȽ) + * [Java ķűʵ](#java-ķűʵ) + * [](#) + * [ϡ˷](#ϡ˷) + + +# + +## ջ + +### 1. ʵ + +```java +public class ResizeArrayStack implements Iterable { + + // Ҫ Object Ȼתֱͣʹ new Item[1]; + private Item[] a = (Item[]) new Object[1]; + // ջеԪظ + private int N = 0; + + public void push(Item item) { + if (N >= a.length) { + resize(2 * a.length); + } + a[N++] = item; + } + + public Item pop() { + Item item = a[--N]; + if (N <= a.length / 4) { + resize(a.length / 2); + } + return item; + } + + // Сʹջ + private void resize(int size) { + Item[] tmp = (Item[]) new Object[size]; + for (int i = 0; i < N; i++) { + tmp[i] = a[i]; + } + a = tmp; + } + + public boolean isEmpty() { + return N == 0; + } + + public int size() { + return N; + } + + @Override + public Iterator iterator() { + // Ҫĵ + return new ReverseArrayIterator(); + } + + private class ReverseArrayIterator implements Iterator { + private int i = N; + + @Override + public boolean hasNext() { + return i > 0; + } + + @Override + public Item next() { + return a[--i]; + } + } +} +``` + +### 2. ʵ + +Ҫʹͷ巨ʵ֣Ϊͷ巨ѹջԪĿͷ next ָָǰһѹջԪأڵԪʹͿǰһѹջԪسΪջԪء + +```java +public class Stack { + + private Node top = null; + private int N = 0; + + private class Node { + Item item; + Node next; + } + + public boolean isEmpty() { + return N == 0; + } + + public int size() { + return N; + } + + public void push(Item item) { + Node newTop = new Node(); + newTop.item = item; + newTop.next = top; + top = newTop; + N++; + } + + public Item pop() { + Item item = top.item; + top = top.next; + N--; + return item; + } +} +``` + +## + +Ƕеʵ֣Ҫά first last ڵָ룬ֱָ׺Ͷβ + +Ҫĸָָͷڵ㣬ĸָָβڵ㡣ΪвҪöԪصһԪسΪףҪ׻ȡһԪأͷڵ next ָָһԪأöָ first ָĿͷ + +```java +public class Queue { + private Node first; + private Node last; + int N = 0; + private class Node{ + Item item; + Node next; + } + + public boolean isEmpty(){ + return N == 0; + } + + public int size(){ + return N; + } + + // + public void enqueue(Item item){ + Node newNode = new Node(); + newNode.item = item; + newNode.next = null; + if(isEmpty()){ + last = newNode; + first = newNode; + } else{ + last.next = newNode; + last = newNode; + } + N++; + } + + // + public Item dequeue(){ + Node node = first; + first = first.next; + N--; + return node.item; + } +} +``` + +## 㷨 + +### 1. ת + +ָתΪԺӶںͼʾĸֱۡ + +T(N)=aN3 תΪ lg(T(N))=3lgN+lga + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5510045a-8f32-487f-a756-463e51a6dab0.png) + +### 2. ѧģ + +**** + +ʹ \~f(N) ʾ N f(N) Ľ 1 ĺ , N3/6-N2/2+N/3 \~ N3/6 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ca3a793e-06e5-4ff3-b28e-a9c20540d164.png) + +**** + +㷨ʵָ뿪һ㷨Ϊ N3 Ƿ Java ʵ֣Ƿض޹ء + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1ea4dc9a-c4dd-46b5-bb11-49f98d57ded1.png) + +**ѭ** + +ִƵָ˳ִеʱ䣬ЩָΪѭ + +**ɱģ** + +ʹóɱģ㷨ķʴһֳɱģ͡ + +### 3. ThreeSum + +ThreeSum ͳһԪĺΪ 0 + +```java +public class ThreeSum { + public static int count(int[] a) { + int N = a.length; + int cnt = 0; + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + for (int k = j + 1; k < N; k++) { + if (a[i] + a[j] + a[k] == 0) { + cnt++; + } + } + } + } + return cnt; + } +} +``` + +óѭΪ if (a[i] + a[j] + a[k] == 0) 䣬ִܹеĴΪ N3/6-N2/2+N/3ĽִдΪ \~N3/6Ϊ N3 + +**Ľ** + +ͨ򣬶ԪͣöֲҷǷڸú͵෴ڣ˵ԪĺΪ 0 + +÷Խ ThreeSum 㷨Ϊ N2logN + +```java +public class ThreeSumFast { + public static int count(int[] a) { + Arrays.sort(a); + int N = a.length; + int cnt = 0; + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + for (int k = j + 1; k < N; k++) { + // rank() Ԫе±꣬Ԫزڣ᷵ -1Ӧע± jͲظͳˡ + if (BinarySearch.rank(-a[i] - a[j], a) > j) { + cnt++; + } + } + } + } + return cnt; + } +} +``` + +### 4. ʵ + + T(N) \~ aNblgNô T(2N)/T(N) \~ 2bڱ ThreeSum 㷨ʱΪ \~N3/6бʵõ½ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6f5ed46f-86d7-4852-a34f-c1cf1b6343a0.png) + +ɼ T(2N)/T(N)\~23Ҳ b Ϊ 3 + +### 5. ע + +**** + +ʱͼijϵܴôƵĽǴġ + +**** + +ϵͳʹû漼֯ڴ棬ڵԪػȷʲڵԪؿܶࡣ + +**µܵı֤** + +ں˷ӦѡɲеµʮҪġ + +**㷨** + +ͨ룬ȥ㷨 + +**̯** + +вܳɱԲɱ̯һջ N push() ҪԪΪ N+4+8+16+...+2N=5N-4N дԪأĶǵСʱиҪķ̯ÿβƽΪ + +## union-find + +**** + +ڽ̬ͨ⣬̬ܶ㣬жǷӡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5d387d02-6f96-44d6-b5d0-4538349f868e.png) + +**API** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a9b91b7d-65d7-4aa3-8ef6-21876b05ad16.png) + +**ݽṹ** + +```java +public class UF { + // ʹ id ͨϢ + private int[] id; + + public UF(int N) { + id = new int[N]; + for (int i = 0; i < N; i++) { + id[i] = i; + } + } + + public boolean connected(int p, int q) { + return find(p) == find(q); + } +} +``` + +### 1. quick-find 㷨 + +֤ͬһͨд id ֵȡ + +ַԿȡһ id ֵжǷͨ union IJȴܸߣҪһͨенڵ id ֵ޸Ϊһڵ id ֵ + +```java + public int find(int p) { + return id[p]; + } + public void union(int p, int q) { + int pID = find(p); + int qID = find(q); + + if (pID == qID) return; + for (int i = 0; i < id.length; i++) { + if (id[i] == pID) id[i] = qID; + } + } +``` + +### 2. quick-union 㷨 + + union ʱֻ id ֵָһ id ֱֵ id 洢ͨ͹һõνṹڵҪָԼڽвһڵͨʱҪһֱϲֱڵ㣬ʹøڵ id ֵΪͨ idֵ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9192dc0a-a7cd-4030-8df6-e388600644cf.jpg) + +```java + public int find(int p) { + while (p != id[p]) p = id[p]; + return p; + } + + public void union(int p, int q) { + int pRoot = find(p); + int qRoot = find(q); + if (pRoot == qRoot) return; + id[pRoot] = qRoot; + } +``` + +ַԿٽ union find ߳ȣĸ߶ΪĿ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d206d090-d911-4263-a1fe-d6f63f5d1776.png) + +### 3. Ȩ quick-union 㷨 + +Ϊ˽ quick-union ܸͨߵ⣬Ȩ quick-union union ʱýСӽϴ档 + +о֤Ȩ quick-union 㷨಻ lgN + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8d6af5ac-74eb-4e07-99aa-654b9f21f1d3.jpg) + +```java +public class WeightedQuickUnionUF { + private int[] id; + // ڵϢ + private int[] sz; + + public WeightedQuickUnionUF(int N) { + id = new int[N]; + sz = new int[N]; + for (int i = 0; i < N; i++) { + id[i] = i; + sz[i] = 1; + } + } + + public boolean connected(int p, int q) { + return find(p) == find(q); + } + + public int find(int p) { + while (p != id[p]) p = id[p]; + return p; + } + + public void union(int p, int q) { + int i = find(p); + int j = find(q); + if (i == j) return; + if (sz[i] < sz[j]) { + id[i] = j; + sz[j] += sz[i]; + } else { + id[j] = i; + sz[i] += sz[j]; + } + } +} +``` + +### 4. ·ѹļȨ quick-union 㷨 + +ڼڵͬʱֱӵڵ㣬ֻҪ find һѭɡ + +### 5. union-find 㷨ıȽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e5baeb38-0ec9-4ad7-8374-1cdb0dba74a6.jpg) + +# ڶ + +## 㷨 + +### Լ + +ԪҪʵ Java Comparable ӿڣýӿ compareTo() + +о㷨ijɱģʱDZȽϺͽĴ + +ʹø less() exch() бȽϺͽIJʹôĿɶԺͿֲԸá + +```java +private static boolean less(Comparable v, Comparable w){ + return v.compareTo(w) < 0; +} + +private void exch(Comparable[] a, int i, int j){ + Comparable t = a[i]; + a[i] = a[j]; + a[j] = t; +} +``` + +### ѡ + +ҵеСԪأȻĵһԪؽλáȻٴʣµԪҵСԪأĵڶԪؽλáϽIJֱ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/222768a7-914f-4d64-b874-d98f3b926fb6.jpg) + +```java +public class Selection { + public static void sort(Comparable[] a) { + int N = a.length; + for (int i = 0; i < N; i++) { + int min = i; + for (int j = i + 1; j < N; j++) { + if (less(a[j], a[min])) min = j; + } + exch(a, i, min); + } + } +} +``` + +ѡҪ \~N2/2 αȽϺ \~N νʱ޹أصʹһѾҲҪôıȽϺͽ + +### + +һԪز뵽Уʹò֮ҲġҲÿԪأÿβ֮󲿵ġ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/065c3bbb-3ea0-4dbf-8f26-01d0e0ba7db7.png) + +```java +public class Insertion { + public static void sort(Comparable[] a) { + int N = a.length; + for (int i = 1; i < N; i++) { + for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) { + exch(a, j, j - 1); + } + } + } +} +``` + +ĸӶȡijʼ˳Ѿˣôܿ졣ƽ²Ҫ \~N2/4 ȽԼ \~N2/4 νҪ \~N2/2 ȽԼ \~N2/2 νģõҪ N-1 αȽϺ 0 νõѾˡ + +ڲСģرЧ + +### ѡͲıȽ + +ظ飬ѡʱƽģ֮һСij + +### ϣ + +ڴģ飬ΪֻܽڵԪأҪԪشһƵһˣҪܶβ + +ϣij־Ϊ˸Ľ־ԣͨڵԪأʹԪظƵȷλϡ + +ϣʹòԼ h н h ܴôԪؾܺܿƵԶĵطͨϼС h h=1Ϳʹġ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8320bad6-3f91-4a15-8e3d-68e8f39649b5.png) + +```java +public class Shell { + public static void sort(Comparable[] a) { + int N = a.length; + int h = 1; + while (h < N / 3) { + h = 3 * h + 1;// 1, 4, 13, 40, ... + } + while (h >= 1) { + for (int i = h; i < N; i++) { + for (int j = i; j >= h && less(a[j], a[j - h]); j -= h) { + exch(a, j, j - h); + } + } + h = h / 3; + } + } +} +``` + +ϣʱﲻƽʹõ 1, 4, 13, 40, ... ϣҪıȽϴᳬ N ɱڵеijȡܵĸ߼㷨ֻϣҡ + +## 鲢 + +鲢˼ǽֱֳ֣Ȼ鲢 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dcf265ad-fe35-424d-b4b7-d149cdf239f4.png) + +### 鲢 + +```java +public class MergeSort { + private static Comparable[] aux; + + private static void merge(Comparable[] a, int lo, int mid, int hi) { + int i = lo, j = mid + 1; + + for (int k = lo; k <= hi; k++) { + aux[k] = a[k]; // ݸƵ + } + + for (int k = lo; k <= hi; k++) { + if (i > mid) a[k] = aux[j++]; + else if (j > hi) a[k] = aux[i++]; + else if (aux[i].compareTo(a[j]) < 0) a[k] = aux[i++]; // Ƚһ֤ȶ + else a[k] = aux[j++]; + } + } +} +``` + +### Զ¹鲢 + +```java + public static void sort(Comparable[] a) { + aux = new Comparable[a.length]; + sort(a, 0, a.length - 1); + } + + private static void sort(Comparable[] a, int lo, int hi) { + if (hi <= lo) return; + int mid = lo + (hi - lo) / 2; + sort(a, lo, mid); + sort(a, mid + 1, hi); + merge(a, lo, mid, hi); + } +``` + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6468a541-3a9a-4008-82b6-03a0fe941d2a.png) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c7665f73-c52f-4ce4-aed3-592bbd76265b.png) + +׿㷨ʱ临ӶΪ O(NlgN) + +ΪСĵݹƵʹòС齫øߵܡ + +### ԵϹ鲢 + +ȹ鲢Щ΢飬ȻɶԹ鲢õ顣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c7b9b4c8-83d1-4eb0-8408-ea6576a9ed90.png) + +```java + public static void busort(Comparable[] a) { + int N = a.length; + aux = new Comparable[N]; + for (int sz = 1; sz < N; sz += sz) { + for (int lo = 0; lo < N - sz; lo += sz + sz) { + merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1)); + } + } + } +``` + +## + +### 㷨 + +鲢Ϊֱ򣬲鲢ʹ򣻿ͨһзԪؽΪ飬СڵзԪأڵзԪأҲͽˡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/61b4832d-71f3-413c-84b6-237e219b9fdc.png) + +```java +public class QuickSort { + public static void sort(Comparable[] a) { + shuffle(a); + sort(a, 0, a.length - 1); + } + + private static void sort(Comparable[] a, int lo, int hi) { + if (hi <= lo) return; + int j = partition(a, lo, hi); + sort(a, lo, j - 1); + sort(a, j + 1, hi); + } +} +``` + +### з + +ȡ a[lo] ΪзԪأȻɨֱҵһڵԪأٴҶɨҵһСڵԪأԪأϼ̣ͿԱָ֤ԪضзԪأָ j ҲԪضСзԪءָʱзԪ a[lo] ҲԪ a[j] Ȼ󷵻 j ɡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e198c201-f386-4491-8ad6-f7e433bf992d.png) + +```java + private static int partition(Comparable[] a, int lo, int hi) { + int i = lo, j = hi + 1; + Comparable v = a[lo]; + while (true) { + while (less(a[++i], v)) if (i == hi) break; + while (less(v, a[--j])) if (j == lo) break; + if (i >= j) break; + exch(a, i, j); + } + exch(a, lo, j); + return j; + } +``` + +### ܷ + +ԭ򣬲Ҫ飬ǵݹҪջ + +õÿζܽ԰֣ݹôٵġ±ȽϴΪ CN=2CN/2+NҲǸӶΪ O(NlgN) + +£һδСԪз֣ڶδӵڶСԪз֣㡣ҪȽ N2/2Ϊ˷ֹʼģڽпʱҪ顣 + +### 㷨Ľ + +#### л + +ΪСҲԼС飬ȿܸãСпл + +#### ȡ + +õÿζȡλΪзԪأǼλĴۺܸߡǷȡ 3 ԪزСеԪΪзԪصЧá + +#### з + +дظԪص飬ԽзΪֱ֣ӦСڡںʹзԪء + +зֻֿɲͬʱ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9d2226dc-c4a3-40ec-9b3e-a46bf86af499.png) + +```java +public class Quick3Way { + public static void sort(Comparable[] a, int lo, int hi) { + if (hi <= lo) return; + int lt = lo, i = lo + 1, gt = hi; + Comparable v = a[lo]; + while (i <= gt) { + int cmp = a[i].compareTo(v); + if (cmp < 0) exch(a, lt++, i++); + else if (cmp > 0) exch(a, i, gt--); + else i++; + } + sort(a, lo, lt - 1); + sort(a, gt + 1, hi); + } +} +``` + +## ȶ + +ȶҪڴԪء + +### + +壺һŶÿڵ㶼ڵӽڵ㡣 + +ѿʾΪһȫȫ׾ʹ洢Сλ k ĽڵĸڵλΪ k/2ӽڵλ÷ֱΪ 2k 2k+1DzʹΪ 0 λãΪ˸ڵĹϵ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a9b6c1db-0f4a-4e91-8ac8-6b19bd106b51.png) + +```java +public class MaxPQ { + private Key[] pq; + private int N = 0; + + public MaxPQ(int maxN) { + pq = (Key[]) new Comparable[maxN + 1]; + } + + public boolean isEmpty() { + return N == 0; + } + + public int size() { + return N; + } + + private boolean less(int i, int j) { + return pq[i].compareTo(pq[j]) < 0; + } + + private void exch(int i, int j) { + Key t = pq[i]; + pq[i] = pq[j]; + pq[j] = t; + } +} +``` + +### ϸ³ + +ڶУһڵȸڵôҪڵ㡣󻹿ܱµĸڵҪϵؽбȽϺͽֲΪϸ + +```java +private void swim(int k) { + while (k > 1 && less(k / 2, k)) { + exch(k / 2, k); + k = k / 2; + } +} +``` + +ƵأһڵӽڵСҲҪϵ±ȽϺͽֲΪ³һڵӽڵ㣬Ӧӽڵôڵн + +```java +private void sink(int k) { + while (2 * k <= N) { + int j = 2 * k; + if (j < N && less(j, j + 1)) j++; + if (!less(k, j)) break; + exch(k, j); + k = j; + } +} +``` + +### Ԫ + +ԪطŵĩβȻϸʵλá + +```java +public void insert(Key v) { + pq[++N] = v; + swim(N); +} +``` + +### ɾԪ + +鶥ɾԪأһԪطŵˣԪ³ʵλá + +```java +public Key delMax() { + Key max = pq[1]; + exch(1, N--); + pq[N + 1] = null; + sink(1); + return max; +} +``` + +### + +ڶѿԺ׵õԪزɾϵؽֲԵõһݼСԪغ͵ǰһԪؽλãҲɾôͿԵõһβͷĵݼУһС˺ʹö򣬲Ҷԭ򣬲ռöռ䡣 + +Ҫ׶Σһ׶ǰ齨һѣڶ׶ǽԪغ͵ǰѵһԪأҽ³άֶѵ״̬ + +齨ֱӵķǴұ飬ȻϸһЧķǴ³һڵڵ㶼ѾǶô³ʹڵΪڵĶҶӽڵ㲻Ҫ³˿ԺҶӽڵԪأֻҪһԪؼɡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a2670745-a7b1-497b-90a4-dbddc4e2006d.jpg) + +```java +public static void sort(Comparable[] a){ + int N = a.length; + for(int k = N/2; k >= 1; k--){ + sink(a, k, N); + } + while(N > 1){ + exch(a, 1, N--); + sink(a, 1, N); + } +} +``` + +### + +һѵĸ߶Ϊ lgNڶвԪغɾԪصĸӶȶΪ lgN + +ڶҪ N ڵ³˸ӶΪ NlgN + +ʱһԭûöĿռ䡣 + +ִϵͳʹöΪ޷û棬ҲԪغٺڵԪؽбȽϡ + +## Ӧ + +### 㷨ıȽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/be53c00b-2534-4dc6-ad03-c55995c47db9.jpg) + +ʱͨ㷨ѭָ٣û棬Ϊ˳طݡʱΪ $\~cNlgN$ c Զ㷨ҪСʹз֮ʵӦпֵܳijЩֲܹﵽ Լ𣬶㷨ȻҪԶʱ䡣 + +### Java 㷨ʵ + +Java ϵͳеҪ򷽷Ϊ java.util.Arrays.sort()ԭʼʹзֵĿ򣬶ʹù鲢 + +### зֵĿѡ㷨 + + partition() Ὣ a[lo] a[hi] 򲢷һ j ʹ a[lo..j-1] Сڵ a[j] a[j+1..hi] ڵ a[j]ô j=ka[j] ǵ k + +㷨ԼģΪÿý֣ôȽϵܴΪ (N+N/2+N/4+..)ֱҵ k ԪأȻС 2N + +```java + public static Comparable select(Comparable[] a, int k) { + int lo = 0, hi = a.length - 1; + while (hi > lo) { + int j = partion(a, lo, hi); + if (j == k) return a[k]; + else if (j > k) hi = j - 1; + else lo = j + 1; + } + return a[k]; + } +``` + + +# + +ʹ־ʵָЧķűɢб + +## ű + +### API + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b69d7184-ab62-4957-ba29-fb4fa25f9b65.jpg) + +һֵΪ null ʱʾ˿ʹ put(key, null) Ϊ delete(key) һӳʵ֡ + +### ű + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ba6ae411-82da-4d86-a434-6776d1731e8e.jpg) + +űļҪʵ Comparable ӿڡ + +ҵijɱģͣıȽϴڲбȽʱʹķʴ + +### ʵ + +Ӷȣһձв N ͬļҪ \~N2/2 αȽϡ + +### Ķֲ + +ʹһƽ飬һ洢һ洢ֵ + +Ҫһ Key ͵ Comparable һ Value ͵ Object 顣 + +rank() Ҫڱʱܹ֪üλãڱʱҲ֪ںδ¼ + +```java +public class BinarySearchST, Value> { + private Key[] keys; + private Value[] values; + private int N; + + public BinarySearchST(int capacity) { + keys = (Key[]) new Comparable[capacity]; + values = (Value[]) new Object[capacity]; + } + + public int size() { + return N; + } + + public Value get(Key key) { + int i = rank(key); + if (i < N && keys[i].compareTo(key) == 0) { + return values[i]; + } + return null; + } + + public int rank(Key key) { + int lo = 0, hi = N - 1; + while (lo <= hi) { + int mid = lo + (hi - lo) / 2; + int cmp = key.compareTo(keys[mid]); + if (cmp == 0) return mid; + else if (cmp < 0) hi = mid - 1; + else lo = mid + 1; + } + return lo; + } + + public void put(Key key, Value value) { + int i = rank(key); + if (i < N && keys[i].compareTo(key) == 0) { + values[i] = value; + return; + } + for (int j = N; j > i; j--) { + keys[j] = keys[j - 1]; + values[j] = values[j - 1]; + } + keys[i] = key; + values[i] = value; + N++; + } + + public Key ceiling(Key key){ + int i = rank(key); + return keys[i]; + } +} +``` + +### Զֲҵķ + +ӶȣֲҪ lgN+1 αȽϣʹöֲʵֵķűIJҲҪʱǶġDzҪƶԪأԼġ + +## + +壺ΪһӣһӵĽڵ㣬ÿӶָһӶBSTһŶÿڵļеڵļСڵļ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/25226bb2-92cc-40cb-9e7f-c44e79fbb64a.jpg) + +IJҲÿεһ룬Ͷֲơ + +```java +public class BST, Value> { + private Node root; + + private class Node { + private Key key; + private Value val; + private Node left, right; + private int N; // ԸýڵΪнڵ + + public Node(Key key, Value val, int N) { + this.key = key; + this.val = val; + this.N = N; + } + } + + public int size() { + return size(root); + } + + private int size(Node x) { + if (x == null) return 0; + return x.N; + } +} +``` + +### get() + +ǿյģδУҵļ͸ڵļȣУݹвңҵļСвңϴвҡ + +```java +public Value get(Key key) { + return get(root, key); +} +private Value get(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp == 0) return x.val; + else if (cmp < 0) return get(x.left, key); + else return get(x.right, key); +} +``` + +### put() + +ļУҪһ½ڵ㣬ҸϲڵʹøýڵȷӵС + +```java +public void put(Key key, Value val) { + root = put(root, key, val); +} +private Node put(Node x, Key key, Value val) { + if (x == null) return new Node(key, val, 1); + int cmp = key.compareTo(x.key); + if (cmp == 0) x.val = val; + else if (cmp < 0) x.left = put(x.left, key, val); + else x.right = put(x.right, key, val); + x.N = size(x.left) + size(x.right) + 1; + return x; +} +``` + +### + +㷨ʱȡ״״ȡڼȺ˳õȫƽģÿӺ͸ڵľ붼Ϊ lgN£ĸ߶Ϊ N + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/73a3983d-dd18-4373-897e-64b706a7e370.jpg) + +ӶȣҺͲΪ + +### floor() + + key Сڸڵ keyôСڵ key ڵһУ key ڸڵ keyֻеڵдСڵ key Ľڵ㣬Сڵ key ڵУڵСڵ key ڵ㡣 + +```java +public Key floor(Key key) { + Node x = floor(root, key); + if (x == null) return null; + return x.key; +} +private Node floor(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp == 0) return x; + if (cmp < 0) return floor(x.left, key); + Node t = floor(x.right, key); + if (t != null) { + return t; + } else { + return x; + } +} +``` + +### rank() + +```java +public int rank(Key key) { + return rank(key, root); +} +private int rank(Key key, Node x) { + if (x == null) return 0; + int cmp = key.compareTo(x.key); + if (cmp == 0) return size(x.left); + else if (cmp < 0) return rank(key, x.left); + else return 1 + size(x.left) + rank(key, x.right); +} +``` + +### min() + +```java +private Node min(Node x) { + if (x.left == null) return x; + return min(x.left); +} +``` + +### deleteMin() + +ָСڵָСڵ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6e2cb20a-8d2a-46fe-9ac7-68a2126b7bd5.jpg) + +```java +public void deleteMin() { + root = deleteMin(root); +} +public Node deleteMin(Node x) { + if (x.left == null) return x.right; + x.left = deleteMin(x.left); + x.N = size(x.left) + size(x.right) + 1; + return x; +} +``` + +### delete() + +ɾĽڵֻôֻҪָڵָΨһɣСڵ滻ýڵ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b488282d-bfe0-464f-9e91-1f5b83a975bd.jpg) + +```java +public void delete(Key key) { + root = delete(root, key); +} +private Node delete(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp < 0) x.left = delete(x.left, key); + else if (cmp > 0) x.right = delete(x.right, key); + else { + if (x.right == null) return x.left; + if (x.left == null) return x.right; + Node t = x; + x = min(t.right); + x.right = deleteMin(t.right); + x.left = t.left; + } + x.N = size(x.left) + size(x.right) + 1; + return x; +} +``` + +### keys() + +öĽΪеص㡣 + +```java +public Iterable keys(Key lo, Key hi) { + Queue queue = new LinkedList<>(); + keys(root, queue, lo, hi); + return queue; +} +private void keys(Node x, Queue queue, Key lo, Key hi) { + if (x == null) return; + int cmpLo = lo.compareTo(x.key); + int cmpHi = hi.compareTo(x.key); + if (cmpLo < 0) keys(x.left, queue, lo, hi); + if (cmpLo <= 0 && cmpHi >= 0) queue.add(x.key); + if (cmpHi > 0) keys(x.right, queue, lo, hi); +} +``` + +### ܷ + +ӶȣвҪʱ䶼ĸ߶ȳȡ + +## ƽ + +### 2-3 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2548f2ec-7b00-4ec7-b286-20fc3022e084.jpg) + +һƽ 2-3 пӵڵľӦͬġ + +#### + +֮һʱ 4- ڵʱҪ 4- ڵѳ 3 2- ڵ㣬м 2- ڵƵϲڵУƲʱ 4- ڵһֱзƣֱʱ 4- ڵ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/912174d8-0786-4222-b7ef-a611d36e5db9.jpg) + +#### + +2-3 ı任ǾֲģصĽڵ֮ⲻ޸Ļ߼֣Щֲ任ӰȫԺƽԡ + +2-3 IJҺͲӶȺͲ˳޹أ²ҺͲʵĽڵȻ logN 10 ڸڵ 2-3 ֻҪ 30 ڵܽIJҺͲ + +### ڶ + +2-3 Ҫõ 2- ڵ 3- ڵ㣬ʹúʵ 3- ڵ㡣ָһڵɫΪɫôڵϲڵʾһ 3- ڵ㣬ɫͨӡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7080a928-06ba-4e10-9792-b8dd190dc8e2.jpg) + +ʣ + +1. ӶΪӣ +2. ɫƽ⣬ӵڵ·ϵĺͬ + +ʱԽӻƽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/62077f5d-a06d-4129-9b43-78715b82cb03.png) + +```java +public class RedBlackBST, Value> { + private Node root; + private static final boolean RED = true; + private static final boolean BLACK = false; + + private class Node { + Key key; + Value val; + Node left, right; + int N; + boolean color; + + Node(Key key, Value val, int n, boolean color) { + this.key = key; + this.val = val; + N = n; + this.color = color; + } + } + + private boolean isRed(Node x) { + if (x == null) return false; + return x.color == RED; + } +} +``` + +#### ת + +ΪϷĺӶΪӣΪӣôҪת + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/33a4e822-2dd0-481e-ac89-7f6161034402.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5e0cef33-4087-4f21-a428-16d5fddda671.jpg) + +```java +public Node rotateLeft(Node h) { + Node x = h.right; + h.right = x.left; + x.left = h; + x.color = h.color; + h.color = RED; + x.N = h.N; + h.N = 1 + size(h.left) + size(h.right); + return x; +} +``` + +#### ת + +תΪתӣ֮IJ̽֡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dfd078b2-aa4f-4c50-8319-232922d822b8.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/3f8d8c9d-a9a9-4d7a-813c-2de05ee5a97e.jpg) + +```java +public Node rotateRight(Node h) { + Node x = h.left; + h.left = x.right; + x.color = h.color; + h.color = RED; + x.N = h.N; + h.N = 1 + size(h.left) + size(h.right); + return x; +} +``` + +#### ɫת + +һ 4- ڵںбΪһڵӽڵ㶼Ǻɫġ 4- ڵҪӽڵɫɺ֮⣬ͬʱҪڵɫɺڱ죬 2-3 ĽǶȿǽмڵƵϲڵ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/de7c5a31-55f5-4e9d-92ec-4ed5b2ec3828.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e5ad625e-729d-4a8d-923a-7c3df5773e1c.jpg) + +```java +void flipColors(Node h){ + h.color = RED; + h.left.color = BLACK; + h.right.color = BLACK; +} +``` + +#### + +㷨 + +- ӽڵǺɫĶӽڵǺɫģת +- ӽڵǺɫӽڵҲǺɫģת +- ӽڵΪɫģɫת + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/40639782-5df2-4e96-a4f3-f9dd664d0ca1.jpg) + +```java +public void put(Key key, Value val) { + root = put(root, key, val); + root.color = BLACK; +} + +private Node put(Node x, Key key, Value val) { + if (x == null) return new Node(key, val, 1, RED); + int cmp = key.compareTo(x.key); + if (cmp == 0) x.val = val; + else if (cmp < 0) x.left = put(x.left, key, val); + else x.right = put(x.right, key, val); + + if (isRed(x.right) && !isRed(x.left)) x = rotateLeft(x); + if (isRed(x.left) && isRed(x.left.left)) x = rotateRight(x); + if (isRed(x.left) && isRed(x.right)) flipColors(x); + + x.N = size(x.left) + size(x.right) + 1; + return x; +} +``` + +Կò BST IJƣֻתɫ任ɡ + +ڵһΪɫΪڵûϲڵ㣬Ҳûϲڵָڵ㡣flipColors() пܻʹøڵɫΪɫÿڵɺɫɺɫʱĺӸ߶ȼ 1. + +#### ɾС + +Сһ 2- ڵУôɾüһӣƻƽԣҪȷС 2- ڵС 2- ڵת 3- ڵ 4- ڵַһϲڵһ keyֵܽڵһ keyϲڵ 2- ڵ㣬ôû취ϲڵ key ˣҪ֤ɾ·ϵнڵ㶼 2- ڵ㡣ɾĹУ֤֮һ + +1. ǰڵӽڵ㲻 2- ڵ㣬ɣ +2. ǰڵӽڵ 2- ڵֵܽڵ㲻 2- ڵ㣬ֵܽڵһ key +3. ǰڵӽڵֵܽڵ㶼 2- ڵ㣬ӽڵ㡢ڵеСֵܽڵϲΪһ 4- ڵ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b001fa64-307c-49af-b4b2-2043fc26154e.png) + +õһС 3- ڵ 4- ڵ㣬ֱӴɾȻٴͷֽʱ 4- ڵ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/70b66757-755c-4e17-a7b7-5ce808023643.png) + +#### + +һŴСΪ N ĺĸ߶Ȳᳬ 2lgNӦ 2-3 йߵ·ڵȫ 3- ڵ඼ 2- ڵ㡣 + +IJҪʱ䶼Ƕġ + +## ɢб + +ɢб飬԰ɢбɢֵֵɢбͷԪһ٣ڳʱʵֲҺͲķű + +޷ͨɢֵ֪ĴСϵɢб޷ʵԲ + +### ɢк + +һСΪ M ɢбɢкܹתΪ [0, M-1] ڵΪ hash ֵ + +ɢбгͻĴڣҲͬļͬ hash ֵ + +ɢкӦ + +1. һԣȵļӦȵ hash ֵ +2. ЧԣӦ㣬бҪĻ԰ hash ֵڵ hash ʱֱӷء +3. ԣм hash ֵӦȵطֲ [0, M-1] ֮䣬ҪֱӰ쵽ɢбܡ + +Խɢе [0, M-1] ֮䣬һ k k%M ȿɵõһ [0, M-1] ֮ hash ֵע M һ޷üϢ M Ϊ 10kôֻüĺ k λ + +ԽתʽȻóڸԽʾɶʽȻʹöʽֵг + +жಿϵļÿֶҪ hash ֵϲʱҪÿ hash ֵͬҪĵλԽü R ƵÿֶвͬȨֵ + +磬ַɢкʵ + +```java +int hash = 0; +for(int i = 0; i < s.length(); i++) + hash = (R * hash + s.charAt(i)) % M; +``` + +ٱ磬ӵжԱԶĹϣ + +```java +int hash = (((day * R + month) % M) * R + year) % M; +``` + +R ֵǺҪͨȡ 31 + +Java е hashCode() ʵ hash Ĭʹöڴֵַʹ hashCode() ʱӦϳʹáΪڴַ 32 λֻҪ 31 λķǸӦηλ֮ʹó + +```java +int hash = (x.hashCode() & 0x7fffffff) % M; +``` + +ʹ Java Դ HashMap ԴĹϣʵʱֻҪȥʵ Key ͵ hashCode() ɣҲͲҪ M ĴСȡJava 涨 hashCode() ܹȷֲе 32 λJava е StringInteger ȶ hashCode() ʵһ㡣չʾԶʵ hashCode() + +```java +public class Transaction{ + private final String who; + private final Date when; + private final double amount; + + public int hashCode(){ + int hash = 17; + hash = 31 * hash + who.hashCode(); + hash = 31 * hash + when.hashCode(); + hash = 31 * hash + ((Double) amount).hashCode(); + return hash; + } +} +``` + +### ɢб + +ʹ洢 hash ֵͬļӶͻʱҪȲ Key ڵȻ˳ҡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/540133af-aaaf-4208-8f7f-33cb89ac9621.png) + + N M (N>M)ϣܹԵÿĴС N/MδеIJҺͲҪıȽϴΪ \~N/M + +### ̽ⷨɢб + +̽ⷨʹÿλͻͻʱǰ̽һλ洢ͻļʹ߳̽ⷨĴС M Ӧڼĸ NM>N) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2b3410f1-9559-4dd1-bc3d-e3e572247be2.png) + +```java +public class LinearProbingHashST { + private int N; + private int M = 16; + private Key[] keys; + private Value[] vals; + + public LinearProbingHashST() { + init(); + } + + public LinearProbingHashST(int M) { + this.M = M; + init(); + } + + private void init() { + keys = (Key[]) new Object[M]; + vals = (Value[]) new Object[M]; + } + + private int hash(Key key) { + return (key.hashCode() & 0x7fffffff) % M; + } +} +``` + +#### + +```java +public Value get(Key key) { + for (int i = hash(key); keys[i] != null; i = (i + 1) % M) { + if (keys[i].equals(key)) { + return vals[i]; + } + } + return null; +} +``` + +#### + +```java +public void put(Key key, Value val) { + int i; + for (i = hash(key); keys[i] != null; i = (i + 1) % M) { + if (keys[i].equals(key)) { + vals[i] = val; + return; + } + } + keys[i] = key; + vals[i] = val; + N++; + resize(); +} +``` + +#### ɾ + +ɾӦҲڵļֵ²ɢбС + +```java +public void delete(Key key) { + if (!contains(key)) return; + int i = hash(key); + while (!key.equals(keys[i])) { + i = (i + 1) % M; + } + keys[i] = null; + vals[i] = null; + i = (i + 1) % M; + while (keys[i] != null) { + Key keyToRedo = keys[i]; + Value valToRedo = vals[i]; + keys[i] = null; + vals[i] = null; + N--; + put(keyToRedo, valToRedo); + i = (i + 1) % M; + } + N--; + resize(); +} +``` + +#### С + +̽ⷨijɱȡĿijȣĿҲо۴ء۴غܳʱڲҺͲʱҲҪкܶ̽⡣ + + = N/M Ϊʡ֤ С 1/2 ʱ̽Ԥƴֻ 1.5 2.5 ֮䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/0ddebc5c-7c24-46b1-98db-4fa5e54db16b.png) + +Ϊ˱֤ɢбܣӦĴСʹ [1/4, 1/2] ֮䡣 + +```java +private void resize() { + if (N >= M / 2) resize(2 * M); + else if (N <= M / 8) resize(M / 2); +} + +private void resize(int cap) { + LinearProbingHashST t = new LinearProbingHashST<>(cap); + for (int i = 0; i < M; i++) { + if (keys[i] != null) { + t.put(keys[i], vals[i]); + } + } + keys = t.keys; + vals = t.vals; + M = t.M; +} +``` + +Ȼÿµ鶼Ҫ°ÿֵԲ뵽ɢбǴ̯ĽǶҪĴȴǺСġͼԿÿ鳤ȼӱۼƽֵ 1ΪÿҪ¼ɢֵƽֵ½ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/01658047-0d86-4a7a-a8ca-7ea20fa1fdde.png) + +## Ӧ + +### ַűʵֵıȽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9ee83c8c-1165-476c-85a6-e6e434e5307a.jpg) + +ӦȿɢбҪԲʱʹú + +### Java ķűʵ + +Java java.util.TreeMap java.util.HashMap ֱǻںɢбķűʵ֡ + +### + +˷űҲʹãֻмûֵü洢һϵеļȻжһǷڼС + +### ϡ˷ + +漰 N γ˷Ϊϡʱʹ÷ű洢еķ 0 ֵʹó˷ֻҪЩ 0 Ԫؽмɡ + +```java +import java.util.HashMap; + +public class SparseVector { + private HashMap hashMap; + + public SparseVector(double[] vector) { + hashMap = new HashMap<>(); + for (int i = 0; i < vector.length; i++) { + if (vector[i] != 0) { + hashMap.put(i, vector[i]); + } + } + } + + public double get(int i) { + return hashMap.getOrDefault(i, 0.0); + } + + public double dot(SparseVector other) { + double sum = 0; + for (int i : hashMap.keySet()) { + sum += this.get(i) * other.get(i); + } + return sum; + } +} +``` diff --git a/notes/计算机操作系统.md b/notes/计算机操作系统.md new file mode 100644 index 00000000..ffaf6390 --- /dev/null +++ b/notes/计算机操作系统.md @@ -0,0 +1,739 @@ + +* [һ ](#һ-) + * [ϵͳ](#ϵͳ) + * [1. ](#1-) + * [2. ](#2-) + * [3. ](#3-) + * [4. 첽](#4-첽) + * [ϵͳ](#ϵͳ) + * [жϷ](#жϷ) + * [1. ж](#1-ж) + * [2. 쳣](#2-쳣) + * [3. ](#3-) + * [ں˺΢ں](#ں˺΢ں) + * [1. ں](#1-ں) + * [2. ΢ں](#2-΢ں) +* [ڶ ̹](#ڶ-̹) + * [߳](#߳) + * [1. ](#1-) + * [2. ߳](#2-߳) + * [3. ](#3-) + * [״̬л](#״̬л) + * [㷨](#㷨) + * [1. ϵͳеĵ](#1-ϵͳеĵ) + * [1.1 ȷFCFS](#11-ȷfcfs) + * [1.2 ҵȣSJF](#12-ҵȣsjf) + * [1.3 ʣʱȣSRTN](#13-ʣʱȣsrtn) + * [2. ʽϵͳеĵ](#2-ʽϵͳеĵ) + * [2.1 Ȩ](#21-Ȩ) + * [2.2 ʱƬת](#22-ʱƬת) + * [2.3 ༶](#23-༶) + * [2.4 ̽](#24-̽) + * [3. ʵʱϵͳеĵ](#3-ʵʱϵͳеĵ) + * [ͬ](#ͬ) + * [1. ٽ](#1-ٽ) + * [2. ͬ뻥](#2-ͬ뻥) + * [3. ź](#3-ź) + * [4. ܳ](#4-ܳ) + * [ͨ](#ͨ) + * [1. ܵ](#1-ܵ) + * [2. ź](#2-ź) + * [3. Ϣ](#3-Ϣ) + * [4. ź](#4-ź) + * [5. ڴ](#5-ڴ) + * [6. ׽](#6-׽) + * [ͬ](#ͬ) + * [1. -д](#1--д) + * [2. ѧҽ](#2-ѧҽ) +* [ ](#-) + * [](#) + * [Ĵ](#Ĵ) + * [1. ](#1-) + * [2. Ԥ](#2-Ԥ) + * [2.1 ƻ](#21-ƻ) + * [2.2 ƻ뱣](#22-ƻ뱣) + * [2.3 ƻռ](#23-ƻռ) + * [2.4 ƻ·ȴ](#24-ƻ·ȴ) + * [3. ](#3-) + * [3.1 ȫ״̬](#31-ȫ״̬) + * [3.2 Դм㷨](#32-Դм㷨) + * [3.3 Դм㷨](#33-Դм㷨) + * [4. ָ](#4-ָ) + * [4.1 㷨](#41-㷨) + * [4.2 ָ](#42-ָ) +* [ 洢](#-洢) + * [ڴ](#ڴ) + * [ҳֶ](#ҳֶ) + * [1. ҳ](#1-ҳ) + * [2. ֶ](#2-ֶ) + * [3. ҳʽ](#3-ҳʽ) + * [4. ҳֶ](#4-ҳֶ) + * [ҳû㷨](#ҳû㷨) + * [1. ѣOptimal](#1-ѣoptimal) + * [2. ȽȳFIFO](#2-Ƚȳfifo) + * [3. δʹãLRULeast Recently Used](#3-δʹãlruleast-recently-used) + * [4. ʱӣClock](#4-ʱӣclock) +* [ 豸](#-豸) + * [̵㷨](#̵㷨) + * [1. ȷFCFSFirst Come First Serverd](#1-ȷfcfsfirst-come-first-serverd) + * [2. ѰʱȣSSTFShortest Seek Time First](#2-Ѱʱȣsstfshortest-seek-time-first) + * [3. ɨ㷨SCAN](#3-ɨ㷨scan) + * [4. ѭɨ㷨CSCAN](#4-ѭɨ㷨cscan) +* [ο](#ο) + + +# һ + +## ϵͳ + +### 1. + +ָһʱͬʱж򣬶ָͬһʱжָ + +ҪӲ֧֣ˮ߻߶ദ + +ϵͳ̺̣ͨ߳ʹóܹС + +### 2. + +ָϵͳеԴԹĽ̹ͬʹá + +ֹʽ⹲ͬʱ + +⹲ԴΪٽԴӡȣͬһʱֻһ̷ʣִҪͬʵֶٽԴķʡ + +### 3. + +⼼һʵתΪ߼ʵ塣Ҫ⼼ʱָüͿշָüͬһϲִʹʱָüÿռдÿִֻһСʱƬлͺжд + +### 4. 첽 + +첽ָ̲һִϣͣͣԲ֪ٶǰƽ + +## ϵͳ + +һû̬ҪõϵͳһЩܣҪʹϵͳôӶںˣɲϵͳΪɡ + +ϵͳĹ豸ļ̹ͨš洢ȡ + +## жϷ + +### 1. ж + + CPU ִָ¼ I/O жϣʾ豸/Ѿɣܹһ/󡣴⻹ʱжϡ̨жϵȡ + +### 2. 쳣 + + CPU ִָڲ¼Ƿ롢ַԽ硢ȡ + +### 3. + +ûʹϵͳá + +## ں˺΢ں + +### 1. ں + +ںǽϵͳΪһܽϵŵںˣڸģ鹲Ϣкܸߵܡ + +### 2. ΢ں + +ڲϵͳϸӣ˽һֲϵͳƳںˣӶں˵ĸԡƳIJָݷֲԭ򻮷ֳɷ໥ҪƵû̬ͺ̬֮лһʧ + +# ڶ ̹ + +## ߳ + +### 1. + +DzϵͳԴĻλ + +̿ƿ (Process Control Block, PCB) ̵ĻϢ״̬νĴ̺ͳָ̣ PCB IJ + +### 2. ߳ + +һ߳пж̣߳ǶȵĻλͬһеĶ֮߳ԲִУǹԴ + +### 3. + + ӵԴԴĻλ̲߳ӵԴ߳̿Է̵Դ + + ȣ߳ǶȵĻλͬһУ̵߳ллһڵ߳лһе߳ʱл + + ϵͳڴʱϵͳҪΪ֮Դڴռ䡢I/O 豸ȣ˲ϵͳĿԶڴ߳ʱĿƵأڽнлʱ漰ǰִн CPU ı漰µȽ CPU á߳лʱֻ豣ĴݣС⣬ͬһڵĶ̵̹߳ĵַռ䣬ˣЩ֮߳ͬͨŷdzʵ֣ϵͳĸԤ + + ͨŷ棺̼ͨ (IPC) ҪͬͻֶεĸԱ֤ݵһԣֱ̼߳ͨӶ/дݶΣȫֱͨš + +QQ ̣к̣ܶ߳ http ̡߳¼Ӧ̡߳Ⱦ̵߳ȵȣ̵߳IJִʹеһӴӶ http ʱӦû¼ + +## ״̬л + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1706ce58-a081-4fed-9b36-c3c0d7e22b3a.jpg) + +״̬ȱҪԴӶ״̬תǸԴ CPUȱ CPU ý̴̬תΪ̬ + +ֻо̬̬໥תĶǵת״̬Ľͨ㷨Ӷ CPU ʱ䣬תΪ״̬״̬Ḷ̌ڷ CPU ʱƬ֮ͻתΪ״̬ȴһεȡ + +## 㷨 + +ҪԲͬ۵㷨 + +### 1. ϵͳеĵ + +#### 1.1 ȷFCFS + +first-come first-serverd + +Ƚеҵ + +ڳҵڶҵΪҵһֱȴǰijҵִϲִУҵҪִкܳʱ䣬˶ҵȴʱ + +#### 1.2 ҵȣSJF + +shortest job first + +ȹʱ̵ҵ + +ҵпܻһֱȴҵִϵ״̬һֱжҵôҵԶòȡ + +#### 1.3 ʣʱȣSRTN + +shortest remaining time next + +### 2. ʽϵͳеĵ + +#### 2.1 Ȩ + +˿ֶȨ֮⣬԰ӦΪȨֵȷʽӦȵ㷨 + +Ӧ = (ȴʱ + Ҫʱ) / Ҫʱ = Ӧʱ / Ҫʱ + +ֵ㷨ҪΪ˽ SJF гҵܻ⣬ΪŵȴʱӦҲԽԽߡ + +#### 2.2 ʱƬת + +о̰ FCFS ԭųһУÿεʱ CPU ׽̣ýִ̿һʱƬʱƬʱɼʱʱжϣȳֹͣý̵ִУеĩβͬʱ CPU ׵Ľ̡ + +ʱƬת㷨ЧʺʱƬкܴϵΪÿνлҪ̵Ϣ½̵ϢʱƬ̫̣л̫ƵڽлϾͻỨʱ䡣 + +#### 2.3 ༶ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/042cf928-3c8e-4815-ae9c-f2780202c68f.png) + + öУΪи費ͬȼһеȼߣڶд֮еȨ͡㷨нִʱƬĴСҲͬȨԽߵĶУΪÿ涨ִʱƬԽС + + һ½̽ڴȽһеĩβ FCFS ԭŶӵȴȡֵýִʱڸʱƬɣ׼ϵͳһʱƬʱδɣȳ㽫ýתһеĶβ + + ǰ i -1 оʱŻȵ i еĽС + +ŵ㣺ʵʱԺãҲʺжҵͳҵ + +#### 2.4 ̽ + +### 3. ʵʱϵͳеĵ + +ʵʱϵͳҪһһȷʱڵõӦ + +ΪӲʵʱʵʱǰ߱ԵĽֹʱ䣬߿һijʱ + +## ͬ + +### 1. ٽ + +ٽԴзʵǶδΪٽ + +Ϊ˻ٽԴÿڽٽ֮ǰҪȽм顣 + +```html +// entry section +// critical section; +// exit section +``` + +### 2. ͬ뻥 + +ָ̰ͬһ˳ִУָͬһʱֻһܽٽ + +ͬڶٽʵĻϣͨʵʵġ + +### 3. ź + +**źSamaphore**һͱԶִ down up Ҳdz P V + +- **down** : ź 0 ִ - 1 ź 0˯ߣȴź 0 +- **up**źִ + 1 һ˯ߵḶ̌ý down + +down up ҪƳԭɷָִͨЩʱжϡ + +źȡֵֻΪ 0 1ôͳΪ**Mutex**0 ʾٽѾ1 ʾٽ + +```c +typedef int samaphore; +samaphore mutex = 1; +void P1() { + down(mutex); + // ٽ + up(mutex); +} + +void P2() { + down(mutex); + // ٽ + up(mutex); +} +``` + +**ʹźʵ-** + +ʹһ mutex ٽԴзʣempty ¼ջfull ¼ + +ע⣬ִ down ûٽȶٽȻִ down ߶ٽִ down(empty) empty = 0ʱ˯ߡߴʱܽٽΪ߶ٽˣҲ޷ִ up(empty) ôߺ߾ͻһֱȴȥ + +```c +#define N 100 +typedef int samaphore; +samaphore mutex = 1; +samaphore empty = N; +samaphore full = 0; + +void producer() { + while(TRUE){ + int item = produce_item; + down(empty); + down(mutex); + insert_item(item); + up(mutex); + up(full); + } +} + +void consumer() { + while(TRUE){ + down(full); + down(mutex); + int item = remove_item(item); + up(mutex); + up(empty); + consume_item(item); + } +} +``` + +### 4. ܳ + +ʹźʵֵҪͻ˴ܶƣ̰ܳѿƵĴ׳Ҳʹÿͻ˴øס + +c Բֹ֧̣ܳʾʹ Pascal ̡ܳʾеĹܳṩ insert() remove() ͻ˴ͨ-⡣ + +```html +monitor ProducerConsumer + integer i; + condition c; + + procedure insert(); + begin + + end; + + procedure remove(); + begin + + end; +end monitor; +``` + +ܳһҪԣһʱֻһʹù̡ܳ޷ִеʱһֱռụ̀ܳ뽫Զʹù̡ܳ + +ܳ **** ԼصIJ**wait()** **signal()** ʵִͬ wait() ᵼµýѹܳóһ̳Сsignal() ڻѱĽ̡ + +**ʹùܳʵ-** + +```html +monitor ProducerConsumer + condition full, empty; + integer count := 0; + condition c; + + procedure insert(item: integer); + begin + if count = N then wait(full); + insert_item(item); + count := count + 1; + if count = 1 ten signal(empty); + end; + + function remove: integer; + begin + if count = 0 then wait(empty); + remove = remove_item; + count := count - 1; + if count = N -1 then signal(full); + end; +end monitor; + +procedure producer +begin + while true do + begin + item = produce_item; + ProducerConsumer.insert(item); + end +end; + +procedure consumer +begin + while true do + begin + item = ProducerConsumer.remove; + consume_item(item); + end +end; +``` + +## ͨ + +ͨſԿDz̼ͬ߳ͨţͬһ̵߳ͨŷʽҪʹźͬơ + +### 1. ܵ + +ܵǵġȽȳġ޽ṹġ̶Сֽһ̵ı׼һ̵ı׼һдڹܵβдݣڹܵ׶˶ݡݶ󽫴ӹܵߣ̶ٶЩݡ + +ܵṩ˼򵥵ƻƣͼչܵʱдܵǰ̽һֱͬأܵѾʱͼд̴ܵӹ֮ܵǰд̽һֱ + +Linux йܵͨļʵ֡ + +֣ܵ + + ͨܵƣһְֻ֧˫ͨŷʽֻܵ䣻ֻڸӽ֮ʹã + + ܵȥһƣ֧˫䣻 + + ܵȥڶƣڲؽ֮ͨš + +### 2. ź + +źһƶ̶ԹԴķʡΪһƣֹijڷʹԴʱҲʸԴˣҪΪ̼Լͬһڲֶ֮ͬ߳ͬΡ + +### 3. Ϣ + +Ϣп˷źŴϢ١ֻܵܳ޸ʽֽԼС޵ȱ㡣 + +### 4. ź + +źһֱȽϸӵͨŷʽ֪ͨսij¼Ѿ + +### 5. ڴ + +ڴӳһܱʵڴ棬ιڴһ̴̶Էʡڴ IPC ʽ̼ͨŷʽЧʵͶרƵġͨŻƣźʹãʵֽ̼ͬͨš + +### 6. ׽ + +׽Ҳһֽ̼ͨŻƣͨŻƲͬǣڲͬĽͨš + +## ͬ + +ߺǰѾ۹ + +### 1. -д + +ͬʱݽжDzдԼддͬʱ + +һͱ count ¼ڶݽжĽһ count_mutex ڶ count һ data_mutex ڶԶдݼ + +```c +typedef int semaphore; +semaphore count_mutex = 1; +semaphore data_mutex = 1; +int count = 0; + +void reader() { + while(TRUE) { + down(count_mutex); + count++; + if(count == 1) down(data_mutex); // һҪݽмֹд̷ + up(count_mutex); + read(); + down(count_mutex); + count--; + if(count == 0) up(data_mutex); + up(count_mutex); + } +} + +void writer() { + while(TRUE) { + down(data_mutex); + write(); + up(data_mutex); + } +} +``` + +### 2. ѧҽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a9077f06-7584-4f2b-8c20-3a8e46928820.jpg) + +ѧΧһԲܣÿѧǰŷѧҵֽԷԼ˼һѧҳԷʱҪһһߵĿӡ + +һִĽⷨǵÿѧͬʱֱߵĿӣô޷ֱߵĿӣ + +```c +#define N 5 +#define LEFT (i + N - 1) % N +#define RIGHT (i + N) % N +typedef int semaphore; +semaphore chopstick[N]; + +void philosopher(int i) { + while(TURE){ + think(); + down(chopstick[LEFT[i]]); + down(chopstick[RIGHT[i]]); + eat(); + up(chopstick[RIGHT[i]]); + up(chopstick[LEFT[i]]); + } +} +``` + +Ϊ˷ֹķԼһƣֻͬʱߵĿӣһӵǶδ + +```c +semaphore mutex = 1; + +void philosopher(int i) { + while(TURE){ + think(); + down(mutex); + down(chopstick[LEFT[i]]); + down(chopstick[RIGHT[i]]); + up(mutex); + eat(); + down(mutex); + up(chopstick[RIGHT[i]]); + up(chopstick[LEFT[i]]); + up(mutex); + } +} +``` + +# + +## + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png) + +1. +2. 뱣֣һԴʱѻõԴֲš +3. ռ +4. ·ȴ + +## Ĵ + +### 1. + +ͷɳװû⡣ + +ֲԲȡ + +### 2. Ԥ + +ڳ֮ǰԤ + +#### 2.1 ƻ + +ѻӡɸͬʱΨһӡĽǴӡػ̡ + +#### 2.2 ƻ뱣 + +һʵַʽǹ涨нڿʼִǰҪȫԴ + +#### 2.3 ƻռ + +#### 2.4 ƻ·ȴ + +Դͳһţֻܰ˳Դ + +### 3. + +ڳʱⷢ + +#### 3.1 ȫ״̬ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ed523051-608f-4c3f-b343-383e2d194470.png) + +ͼ a ĵڶ has ʾӵеԴ max ʾܹҪԴfree ʾпʹõԴͼ a ʼ B ӵԴнͷ Bʱ free Ϊ 4ͬķʽ C Aʹн̶ܳɹУ˿Գͼ a ʾ״̬ʱȫġ + +壺ûҼʹнͻȻԴҲȻijֵȴܹʹÿһϣƸ״̬ǰȫġ + +#### 3.2 Դм㷨 + +һСмңһȺͻֱŵһĴȣ㷨Ҫж϶Ƿ벻ȫ״̬ǣ;ܾ󣻷Է䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png) + +ͼ c Ϊȫ״̬㷨ܾ֮ǰ󣬴Ӷͼ c е״̬ + +#### 3.3 Դм㷨 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png) + +ͼ̣ĸԴߵͼʾѾԴұߵͼʾҪԴұߵ EP Լ A ֱʾԴѷԴԼԴעΪǾֵ A=(1020)ʾ 4 Դֱʣ 1/0/2/0 + +һ״̬Ƿȫ㷨£ + + ұߵľǷһСڵ AУôϵͳᷢ״̬Dzȫġ + + ҵһУý̱ΪֹѷԴӵ A С + + ظֱн̶Ϊֹ״̬ʱȫġ + +### 4. ָ + +ͼ֯ǵ⵽ʱȡʩлָ + +#### 4.1 㷨 + +Ļ˼ǣһԴܹ㣬ôִУͷӵеԴȻĽִС + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png) + +ͼУĸԴÿݴĺ£ + +E Դ +A Դʣ +C ÿӵеԴÿһжһӵԴ +R ÿԴ + + P1 P2 Դò㣬ֻн P3 ԣ P3 ִУ֮ͷ P3 ӵеԴʱ A = (2 2 2 0)P1 ִУִкͷ P1 ӵеԴ A = (4 2 2 2) P2 ҲִСн̶˳ִУû + +㷨ܽ£ + +ÿʼʱǣִйпܱǡ㷨ʱκûбǵĽ̶̡ + + ѰһûбǵĽ PiԴСڵ A + ҵһ̣ô C ĵ i ӵ A УǸỵ́ת ١ + ûһ̣㷨ֹ + +#### 4.2 ָ + + ռָ + ɱ + +# 洢 + +## ڴ + +ÿӵԼĵַռ䣬ַռ䱻ָɶ飬ÿһΪһ ҳЩҳӳ䵽ڴ棬Ҫӳ䵽ڴ棬ҲҪҳڴС + +õһڴеĵַռʱӲִбҪӳ䡣õһֲڴеĵַռʱɲϵͳȱʧIJװڴ沢ִʧָܵ + +## ҳֶ + +### 1. ҳ + +ûĵַռ䱻Ϊɹ̶С򣬳ΪҳӦأڴռֳɸ飬ҳͿĴСȡɽûһҳڴһУʵɢ䣬һҳά֮ӳϵ + +### 2. ֶ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png) + +ͼΪһڱнĶ 4 Ƕ̬ģʹ÷ҳϵͳһάַռ䣬̬صᵼ¸ij֡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png) + +ֶεǰÿֳɶΣһιһĵַռ䡣ÿεijȿԲͬԶ̬ı䡣 + +ÿζҪԱ֡ + +### 3. ҳʽ + +÷ֶη͹洢ĵַռ䰴߼λֳɻĶΣÿһԼĶٰÿηֳɹ̶Сҳ + +÷ҳ͹ʵ档ֳҳСȵĴ洢飬װҵκһҳڴĵǰҳеġֿɰʵֹͱ + +### 4. ҳֶ + + ԳԱ͸ԣҳ͸ǷֶҪԱʾÿΡ + + ַռάȣҳһάַռ䣬ֶǶάġ + + СǷԸı䣺ҳĴСɱ䣬εĴСԶ̬ı䡣 + + ֵԭ򣺷ҳҪʵڴ棬Ӷøĵַռ䣻ֶҪΪʹݿԱΪ߼϶ĵַռ䲢ڹͱ + +## ҳû㷨 + +ڳйУҪʵҳ治ڴҪǵڴ棬ڴ޿пռʱϵͳڴеһҳ浽̶ԻУҽҪҳڴСҳû㷨ҪĿʹҳûƵͣҲ˵ȱҳͣ + +### 1. ѣOptimal + +ѡıҳ潫ʱڲٱʣͨԱ֤͵ȱҳʡ + +һϵ㷨Ϊ޷֪һҳ೤ʱᱻٷʵ + +һϵͳΪij̷飬ҳУ + +70120304230321201701 + +ʱȽ 7,0,1 ҳװڴ档Ҫҳ 2 ʱȱҳжϣὫҳ 7 Ϊҳ 7 ٴαʵʱ + +### 2. ȽȳFIFO + +ѡ񻻳ҳȽҳ档 + +㷨ὫЩʵҳҲӶʹȱҳߡ + +### 3. δʹãLRULeast Recently Used + +Ȼ޷֪Ҫʹõҳǿ֪ȥʹҳLRU δʹõҳ滻 + +ջʵָ㷨ջд洢ҳҳš̷һҳʱҳҳŴջƳѹջʵҳҳջδʹõҳҳջס + +47071012126 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/eb859228-c0f2-4bce-910d-d9f76929352b.png) + +### 4. ʱӣClock + +Clock ҳû㷨Ҫõһλһҳ汻ʱΪΪ 1 + +ȣڴеҳӳһѭУȱҳжϷʱ鵱ǰָָҳķλλΪ 0ͽҳ滻򽫸ҳķλΪ 0ҳڶεĻᣬƶָ顣 + +# 豸 + +## ̵㷨 + +ͬʱʴʱҪд̵ƶԴ̵ķʡ̵ȵҪĿʹ̵ƽѰʱ١ + +### 1. ȷFCFSFirst Come First Serverd + +ݽʴ̵Ⱥеȡŵǹƽͼ򵥣ȱҲԣΪδѰκŻʹƽѰʱܽϳ + +### 2. ѰʱȣSSTFShortest Seek Time First + +ҪʵĴŵ뵱ǰͷڴŵȽеȡ㷨ܱ֤ƽѰʱ̣DZ FCFS úܶࡣ + +### 3. ɨ㷨SCAN + +SSTF ֽм󡣿½ʵĴŵͷڴŵľDZһڵȴĽĽôȴĽ̻һֱȴȥ + +SCAN 㷨 SSTF 㷨֮Ͽ˴ͷƶҪʵĴŵڴͷǰƶϲܹõȡΪƶôһʵĴŵһõȡ + +һͷƶʱƵıƶΪƶĹڵݵУֳ SCAN 㷨Ϊݵ㷨 + +### 4. ѭɨ㷨CSCAN + +CSCAN SCAN ˸ĶҪͷʼһƶ + +# ο + +- Tanenbaum A S, Bos H. Modern operating systems[M]. Prentice Hall Press, 2014. + +- , ܷ, С. ϵͳ[M]. ӿƼѧ, 2001. + +- Bryant, R. E., & OHallaron, D. R. (2004). ϵͳ. + +- [Сˢʼ](http://wdxtub.com/interview/index.html) + +- [̼ļͨŷʽ](http://blog.csdn.net/yufaw/article/details/7409596) diff --git a/notes/计算机网络.md b/notes/计算机网络.md new file mode 100644 index 00000000..f84f1792 --- /dev/null +++ b/notes/计算机网络.md @@ -0,0 +1,841 @@ + +* [һ ](#һ-) + * [](#) + * [ISP](#isp) + * [](#) + * [֮ͨŷʽ](#֮ͨŷʽ) + * [·齻](#·齻) + * [1. ·](#1-·) + * [2. Ľ](#2-Ľ) + * [3. 齻](#3-齻) + * [ʱ](#ʱ) + * [1. ʱ](#1-ʱ) + * [2. ʱ](#2-ʱ) + * [3. ʱ](#3-ʱ) + * [4. Ŷʱ](#4-Ŷʱ) + * [ϵṹ](#ϵṹ) + * [1. ߲Э](#1-߲Э) + * [2. Э](#2-Э) + * [3. ڸ֮Ĵݹ](#3-ڸ֮Ĵݹ) + * [4. TCP/IP ϵṹ](#4-tcpip-ϵṹ) +* [ڶ ](#ڶ-) + * [ͨŷʽ](#ͨŷʽ) + * [ͨ](#ͨ) + * [ŵü](#ŵü) + * [1. Ƶָáʱָ](#1-Ƶָʱָ) + * [2. ͳʱָ](#2-ͳʱָ) + * [3. ָ](#3-ָ) + * [4. ָ](#4-ָ) +* [ ·](#-·) + * [](#) + * [1. װ֡](#1-װ֡) + * [2. ͸](#2-͸) + * [3. ](#3-) + * [Եŵ -PPP Э](#Եŵ--ppp-Э) + * [](#) + * [㲥ŵ -CSMA/CD Э](#㲥ŵ--csmacd-Э) + * [](#) + * [MAC ](#mac-) + * [](#) +* [ ](#-) + * [Э IP ](#Э-ip-) + * [IP ݱʽ](#ip-ݱʽ) + * [IP ַַ](#ip-ַַ) + * [1. IP ַ](#1--ip-ַ) + * [2. ](#2-) + * [3. ޷ַ CIDRɳ](#3-޷ַ-cidrɳ) + * [IP ַ MAC ַ](#ip-ַ-mac-ַ) + * [ַЭ ARP](#ַЭ-arp) + * [·Ľṹ](#·Ľṹ) + * [·](#·) + * [·ת](#·ת) + * [·ѡЭ](#·ѡЭ) + * [1. ڲЭ RIP](#1-ڲЭ-rip) + * [2. ڲЭ OSPF](#2-ڲЭ-ospf) + * [3. ⲿЭ BGP](#3-ⲿЭ-bgp) + * [ʿƱЭ ICMP](#ʿƱЭ-icmp) + * [̽ PING](#̽-ping) + * [IP ಥ](#ip-ಥ) + * [ר VPN](#ר-vpn) + * [ַת NAT](#ַת-nat) +* [ ](#-) + * [UDP TCP ص](#udp--tcp-ص) + * [UDP ײʽ](#udp-ײʽ) + * [TCP ײʽ](#tcp-ײʽ) + * [TCP ](#tcp-) + * [TCP Ĵλ](#tcp-Ĵλ) + * [TCP ](#tcp-) + * [TCP ɿ](#tcp-ɿ) + * [TCP ](#tcp-) + * [TCP ӵ](#tcp-ӵ) + * [ʼӵ](#ʼӵ) + * [شָ](#شָ) +* [ Ӧò](#-Ӧò) + * [ϵͳ DNS](#ϵͳ-dns) + * [1. νṹ](#1-νṹ) + * [2. ](#2-) + * [ļЭ FTP](#ļЭ-ftp) + * [ԶնЭ TELNET](#ԶնЭ-telnet) + * [ά WWW](#ά-www) + * [ʼЭ](#ʼЭ) + * [POP3](#pop3) + * [IMAP](#imap) + * [SMTP](#smtp) + * [̬Э DHCP](#̬Э-dhcp) + * [Ե㴫 P2P](#Ե㴫-p2p) + * [ www.baidu.com ִеȫ](#-wwwbaiducom-ִеȫ) + * [ö˿](#ö˿) +* [ο](#ο) + + +# һ + +## + +ǰѶֲͬ˻硣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/04ff7ae6-7bee-4cf8-82f8-dfe2ba1f3616.jpg) + +## ISP + +ṩ ISP Դӻ IP ַͬʱӵͨ·Լ·豸˻ ISP һķþͿԽ뻥 + +ĿǰĻһֶ ISP ṹISP ݸĴСΪ ISP ISP ͱ ISP + + IXP ֱþת顣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/17d807ef-03bf-4824-a97c-ea5fb58ec61d.jpg) + +## + +1. Ե֣ڻϵûֱʹã +2. IJ֣ɴЩ·ɡΪԵֵṩ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/005d83c2-e64a-41f0-bbdd-51c71d494a18.jpg) + +## ֮ͨŷʽ + +**1. ͻ - C/S** + +ͻǷ󷽣Ƿṩ + +**2. ԵȣP2P** + +ֿͻͷ + +## ·齻 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b97958dd-3e43-45f7-97f5-3ec20f3f8b88.jpg) + +### 1. · + +·ڵ绰ͨϵͳûҪ֮ͨǰҪһרõ·ͨŹʼռø·ͨŵĹвһֱʹô·˵··ʺܵͣ 10% + +### 2. Ľ + +Ľʾͨϵͳʾֽյһݱ֮ȴ洢ȻĿĵѡԵذѱתһĿĵأ̾Ǵ洢ת̡ + +### 3. 齻 + +齻Ҳʹ˴洢תתǷDZġݳΪһģһĿܺܳҪȽз֣ܴĴСÿзֵǰײ֮ͳΪ˷飬ײĿĵַԴַȿϢ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6f4af159-8b03-4246-8d0e-222db65bb83c.jpg) + +洢תһ·ϴͶķ飬ҲǷ齻Ҫռö˵˵·Դ + +ڱĽڷȱĸС洢תٶҲ͸졣 + +## ʱ + +ʱ = ʱ + ʱ + ʱ + Ŷʱ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ceee91c2-da26-4169-94c3-e4608b46b9ac.png) + + +### 1. ʱ + +·֡Ҫʱ䡣 + +![](http://latex.codecogs.com/gif.latex?\\\\delay=\frac{l(bit)}{v(bit/s)}) + + l ʾ֡ijȣv ʾʡ + +### 2. ʱ + +ŲŵдһľҪѵʱ䣬ŲٶȽӽ١ + +![](http://latex.codecogs.com/gif.latex?\\\\delay=\frac{l(m)}{v(m/s)}) + + l ʾŵȣv ʾŲŵϵĴʡ + +### 3. ʱ + +·յʱдҪʱ䣬ײӷȡݲֵȡ + +### 4. Ŷʱ + +·кŶӵȴʱ䣬ȡ統ǰͨ + +## ϵṹ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1005dc9d-9049-4b06-9524-6171e56ebd8c.png) + +### 1. ߲Э + +ͼ a ʾбʾͻỰ;£ + +1. ʾ㣺Ϣ﷨ԼǵĹܽܡת롢ѹѹ +2. Ự㣺ͬϵû֮佨Ự + +### 2. Э + +1. Ӧò㣺ΪضӦóṩݴ HTTPDNS ȡݵλΪġ + +2. 㣺ṩǽ̼ͨݴӦòЭܶ࣬ͨõЭͿֲ֧ӦòЭ顣Э飺Э TCPṩӡɿݴݵλΪĶΣûݱЭ UDPṩӡŬݴݵλΪûݱ + +3. 㣺Ϊ֮ṩ񣬶ЭΪеĽṩıĶλûݱװɷд䡣 + +4. ·㣺ԵĻ֮䣬֮кܶ··ЭΪڽ֮ṩ·㴫ķװ֡ + +5. 㣺ǵڴýϴݱָĴý塣ǾδýֶͨεIJ죬ʹϵ·оЩ졣 + +### 3. ڸ֮Ĵݹ + +µĹУҪ²ЭҪײβϵĹвϲײβ + +·ֻЭ飬Ϊ·λУҪΪ̻Ӧóṩ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f7d5da89-2d75-4d8f-85e7-6b608865dc00.jpg) + +### 4. TCP/IP ϵṹ + +ֻIJ㣬൱Э·ϲΪӿڲ㡣 + +ڵ TCP/IP ϵṹϸѭ OSI ֲӦòֱܻʹ IP ӿڲ㡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/3e2200b3-1c18-4853-ae42-7788e8e1f939.png) + +TCP/IP Эһɳ©״мСߴIP Эռþصĵλ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9ecaebee-670e-4cb2-9cdb-3029c00f33bd.png) + +# ڶ + +## ͨŷʽ + +1. ͨţֳΪͨţ +2. ˫ͨţֳΪ˫ͨţ +3. ˫ͬʱͨţֳΪȫ˫ͨš + +## ͨ + +ģźźţźɢźšͨưźתΪģźš + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d2c55c84-aa1f-43c1-bd97-457bcb7816b3.png) + +## ŵü + +### 1. Ƶָáʱָ + +ƵָõûͬʱռòͬƵʴԴʱָõûڲͬʱռͬƵʴԴ + +ʹַʽͨţͨŵĹûһֱռһŵԴڼݵͻʣûҪһֱռŵԴóûʹãַʽŵʶߡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/543d47a1-f0dd-414f-b23c-0c142c814854.png) + +### 2. ͳʱָ + +ǶʱָõһָĽ̶ÿûʱָ֡еλãֻҪݾͼʱָ֡Ȼ͡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/29058e09-bb72-4040-a73d-4c497895e9ce.jpg) + +### 3. ָ + +ƵָáڹƵʺܸߣϰòƵʾʹõĹز + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/78534153-88d1-4f83-a6e0-59064dbdc43a.png) + +### 4. ָ + +Ϊÿû m bit ƬеƬƬ $\vec{S}$ $\vec{T}$ + +![](http://latex.codecogs.com/gif.latex?\\\\\vec{S}\cdot\vec{T}=0) + +Ϊ˷㣬ȡ m=8Ƭ $\vec{S}$ Ϊ 00011011ӵиƬûͱ 1 ʱͷ͸Ƭͱ 0 ʱͷ͸Ƭķ 11100100 + +ڼʱ 00011011 (-1 -1 -1 +1 +1 -1 +1 +1)Եõ + +![](http://latex.codecogs.com/gif.latex?\\\\\frac{1}{m}\vec{S}\cdot\vec{S}=1) + +![](http://latex.codecogs.com/gif.latex?\\\\\frac{1}{m}\vec{S}\cdot\vec{S'}=-1) + + $\vec{S'}$ Ϊ $\vec{S}$ ķ롣 + +ʽ֪նʹƬ $\vec{S}$ ԽյݽڻʱΪ 0 û͵ݣΪ 1 û͵ı 1Ϊ -1 û͵ı 0 + +ָ÷͵Ϊԭȵ m + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/0042edad-8e3b-4279-bd93-6906fcd1b640.jpg) + +# · + +## + +### 1. װ֡ + +㴫ķײβڱ֡Ŀʼͽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ea5ed9b2-6d9f-48fb-b890-0288caf9088a.jpg) + +### 2. ͸ + +͸ʾһʵʴڵ￴񲻴һ + +֡ײβ֡ݲֺкײβͬݣô֡ĿʼͽλþͻᱻжҪгײβͬǰתַҪþתַôתַǰټӸתַڽն˽д֮Իԭԭʼݡ͸תַûѲתַĴڡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/44e1d90e-3fe6-4dd6-8dce-6daab12e7663.jpg) + +### 3. + +Ŀǰ·㷺ʹѭ飨CRCز + +## Եŵ -PPP Э + +ûͨҪӵij ISP ֮ܽ뵽PPP Эû ISP ͨʱʹõ·Э顣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8b5bd2c8-8425-4a8b-89db-235c95800de9.jpg) + + PPP ֡УF ֶΪ֡ĶA C ʱû塣FCS ʹ CRC ļСϢֶεijȲ 1500 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a5fa89e7-54b9-4e2f-8c48-a35712d7b2f5.jpg) + +## + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8b15e36f-69b4-46b6-a07c-7234ac7c7927.jpg) + +## 㲥ŵ -CSMA/CD Э + +ڹ㲥ŵϣͬһʱֻһ̨ݡ + +CSMA/CD ʾز / ײ⡣ + +****˵磬Զķʽӵϡ +**ز**ÿվ벻ͣؼŵڷǰŵʹãͱȴ +**ײ**ڷУŵվڷݣͱʾײȻÿһվڷ֮ǰѾŵΪУڵŲĴʱӵĴڣпܻᷢײ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f9ed4da5-0032-41e6-991a-36d995ec28fd.png) + +Ƕ˵˵ĴʱΪ ӣȷ͵վྭ 2 Ϳ֪Ƿײ 2 Ϊ ****ֻо֮ûм⵽ײܿ϶ηͲᷢײ + +ײʱվҪֹͣͣȴһʱٷ͡ʱ **ض϶ָ˱㷨** ȷɢ {0, 1, .., (2k-1)} ȡһ rȻȡ r Ϊشȴʱ䡣 + +## + +ӱϿʹüľһǼʹõģʵߵĹ߼һϵͳһͳ̫С + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/897a4f4e-2683-44e1-a26a-c0d0234dc576.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/40c3f8e5-3a20-45b6-a60c-77b9b952e104.jpg) + +## MAC + +MAC ַ 6 ֽڣ48 λĵַΨһʾһ̨ӵжж MAC ַʼDZձ + +MAC ֶ֡ϲʹʲôЭ飻ֶγ 46-1500 ֮䣬̫СҪ䣻FCS Ϊ֡Уʹõ CRC 鷽ǰǰֻͬΪ˼ FCS ʱģ֮ᶪ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/50d38e84-238f-4081-8876-14ef6d7938b5.jpg) + +## + +Խλ޹ص߼飬ֻͬһеijԱŻյ㲥Ϣͼ (A1, A2, A3, A4) һA1 ͵Ĺ㲥ᱻ A2A3A4 յվղ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a74b70ac-323a-4b31-b4d5-90569b8a944b.png) + +# + +## Э IP + +ΪĺģӦ㾡ܼ򵥡ֻṩġӵġŬݱ + +ʹ IP Э飬԰칹ʹ㿴һͳһ硣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/fe3d224c-8ffd-40f9-85b1-86ffe1393f6c.jpg) + + IP ЭʹõĻЭ飺 + +1. ַЭ ARPAddress Resolution Protocol +2. ʿƱЭ ICMPInternet Control Message Protocol +3. Э IGMPInternet Group Management Protocol + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/163cf8b4-5f30-46c9-af00-316a71b3c890.jpg) + +## IP ݱʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8681db55-0873-434b-aa98-83d07e8392ae.jpg) + +**汾** : 4IPv4 6IPv6ֵ + +**ײ** : ռ 4 λֵΪ 15ֵΪ 1 ʾ 1 32 λֵijȣҲ 4 ֽڡΪײ̶Ϊ 20 ֽڣ˸ֵСΪ 5ѡֵijȲ 4 ֽڵβ䲿䡣 + +**ַ** : øõķһ²á + +**ܳ** : ײȺݲֳȡ + +**ʶ** : ݱȹӶƬ£ͬݱIJͬƬͬıʶ + +**Ƭƫ** : ͱʶһڷƬƬƫƵĵλΪ 8 ֽڡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/45c86855-9b18-4cf4-a9a7-f8b6eb78d133.png) + +**ʱ** TTLĴΪ˷ֹ޷ݱڻв϶Ȧӡ·Ϊλ TTL Ϊ 0 ʱͶݱ + +**Э**ָЯӦϽĸЭд ICMPTCPUDP ȡ + +**ײ**Ϊݱÿһ·Ҫ¼ͣ˼ͲݲֿԼټĹ + +## IP ַַ + +IP ַıַʽʷ׶Σ + +1. IP ַ +2. Ļ֣ +3. ɳ + +### 1. IP ַ + +ɣźţвͬвͬųȣǹ̶ġ + +IP ַ ::= {< >, < >} + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2ddd6132-60be-4a72-9daa-3d9756191f4a.png) + +### 2. + +ֶͨһΪţ IP ַΪ IP ַע⣬ⲿ翴Ĵڡ + +IP ַ ::= {< >, < >, < >} + +Ҫʹ롣һ B ַĬΪ 255.255.0.0 B ַռأôΪ 11111111 11111111 11000000 000000Ҳ 255.255.192.0 + +### 3. ޷ַ CIDRɳ + +CIDR ˴ͳ A ࡢB C ַԼĸʹǰ׺ IP ַб룬ǰ׺ijȿԸҪ仯 + +IP ַ ::= {< ǰ׺ >, < >} + +CIDR ļǷϲ IP ַǰ׺ȵķ 128.14.35.7/20 ʾǰ 20 λΪǰ׺ + +CIDR ĵַԼΪ룬 1 Ϊǰ׺ijȡ + +һ CIDR ַкַܶһ CIDR ʾͿԱʾԭĺܶ磬·ɱֻҪһ·ɾͿԴԭĶ·ɣ·ɱͨʹǰ׺·ɱķʽΪ·ɾۺϣҲΪɳ + +·ɱÿĿɡǰ׺͡һַɣڲʱܻõֹһƥӦǰ׺ƥ䡣 + +## IP ַ MAC ַ + +ʵ֮ͨţ·ʵ־ÿ·֮ͨšͨŹУIP ݱԴַĿĵַʼղ䣬 MAC ַ·ĸıı䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/86b71296-0d1e-4a63-bcd9-54955b6b781b.jpg) + + +## ַЭ ARP + +ʵ IP ַõ MAC ַ + +ÿһ ARP ٻ棬ӳһ IP ַ MAC ַӳ䲻ڸñУͨ㲥ķʽ ARP 飬ƥ IP ַᷢ ARP Ӧ֪ MAC ַ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8bc6fc2c-d198-4759-b06c-18d94d851e97.png) + +## ·Ľṹ + +·ԻΪ󲿷֣·ѡͷת + +תɣṹһ˿ںһ˿ڡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/3a676c54-b559-4466-9b21-eb10f1e25879.jpg) + +ṹĽʵַʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7f82fd18-7f16-4125-ada6-bb6b795b4fda.png) + +## · + +- ·㣬ʶ MAC ַ MAC ַת·֡ѧά IP ַ MAC ַӳ䡣 + +- ·λ㣬ʶ IP ַ IP ַת顣ά·ɱ·ɱѡ·ߡ + +## ·ת + +1. ݱײȡĿ IP ַ DõĿַ N·ɱŶ IP ַ·ɱĿ +2. N ·ֱijֱַӽ +3. ·ɱĿĵַΪ D ض·ɣݱ͸ָһ· +4. ·ɱе N ·ɣݱ͸·ɱָһ· +5. ·ɱһĬ·ɣݱ͸·ɱָĬ· +6. ת + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8d211911-0e62-4190-ab00-d8610adec4a0.jpg) + +## ·ѡЭ + +ʹõ·ѡЭ鶼Ӧģͨ˱仯Ӧؽе + +ԻΪСϵͳ ASһ AS ʹһֺͱ AS ͬ·ѡЭ顣 + +԰·ѡЭ黮Ϊࣺ + +1. ڲЭ IGPInterior Gateway Protocol ϵͳڲʹã RIP OSPF +2. ⲿЭ EGPExternal Gateway Protocol ϵͳ֮ʹã BGP + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e0be6970-5b0e-44a2-bc71-df4d61c42b8f.jpg) + +### 1. ڲЭ RIP + +RIP һֲַʽĻھ·ѡЭ顣ֱָ·Ϊ 1Ϊ 15 15 ʾɴ + +RIP ̶ʱ·Լ·ɱɴν֮·ջ֪ﱾϵͳκһ̾һ·ַ + +㷨 + +1. ԵַΪ X · RIP ģ޸ıеĿһֶеĵַΪ Xеľֶμ 1 +2. ޸ĺ RIP еÿһĿ²裺 + - ԭ·ɱûĿ NѸĿӵ·ɱУ + - һ·ַ XյĿ滻ԭ·ɱеĿյĿеľ d С·ɱеľ룬и£ԭʼ·ɱΪ Net2, 5, P±Ϊ Net2, 4, X£ʲôҲ +3. 3 ӻûյ·ĸ·ɱѸ·ΪɴѾΪ 16 + +RIP Эʵּ򵥣С RIP ʹõΪ 15ĹģҵֹʱҪȽϳʱܽϢ͵· + +### 2. ڲЭ OSPF + +· OSPFΪ˿˷ RIP ȱġ + +űʾ OSPF ijһҳ̿ƣǹģ·Ϊʹ Dijkstra ·㷨 SPF + +OSPF ص㣺 + +1. ϵͳе·ϢַǺ鷺 +2. ͵Ϣ··״̬·״̬Щ·Լ·Ķ÷á롢ʱӡʾ +3. ֻе·״̬仯ʱ·ŻᷢϢ + +·ȫ˽ṹͼһµġ RIPOSPF ĸ¹ĺܿ졣 + +### 3. ⲿЭ BGP + +AS ֮·ѡѣҪǻģܴ󡣲Ҹ AS ڲʹòͬ·ѡЭ飬޷׼ȷ·Ķ AS ֮·ѡ뿼йصIJԣЩ AS Ը AS + +BGP ֻѰһȽϺõ·ɣ·ɡ··ѡЭ顣 + +ÿ AS BGP ˣͨ BGP ֮佨 TCP ·Ϣ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/eb6271de-22c9-4f4b-8b31-eab1f560efac.png) + +## ʿƱЭ ICMP + +ICMP Ϊ˸Чת IP ݱ߽ɹĻᡣװ IP ݱУDzڸ߲Э顣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9b5e0fa0-9274-4219-a3a9-84fbb509c735.jpg) + +ICMP ķΪ汨ĺѯʱġ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6e11b122-95ce-4869-bf7d-3b0d7591707e.jpg) + +## ̽ PING + +PING ICMP һҪӦãҪ̨֮ͨԡ + +PING Ḷ́ + +1. PING ͬһεĿ MAC ַȻֱӽ޷ҵ MAC ַҪһ ARP +2. PING ͬεͷ͸תͬҪ͸ҲҪͨص MAC ַ MAC ַת + +## IP ಥ + +һԶͨУಥҪ鸴ƶݣӶԼԴ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c77b6a18-dfac-42a2-ac89-7e99481275dc.jpg) + +## ר VPN + + IP ַĽȱһ뵽 IP ַԶСڱӵеһҪе뵽ⲿĻУڵļʹýڱЧ IP ַרõַ + +רõַ飺 + +1. 10.0.0.0 \~ 10.255.255.255 +2. 172.16.0.0 \~ 172.31.255.255 +3. 192.168.0.0 \~ 192.168.255.255 + +VPN ʹùõĻΪר֮ͨ塣רָڵֻ뱾ڵͨţָǡʵϲǣоõĻ + +ͼУ A B ͨŲ A X Ҫһ B Y ͨţIP ݱԴַ 10.1.0.1Ŀĵַ 10.2.0.3ݱȷ͵뻥· R1R1 ڲݽмܣȻ¼ݱײԴַ· R1 ȫַ 125.1.2.3Ŀĵַ· R2 ȫַ 194.4.5.6· R2 յݱݲֽнܣָԭݱʱĿĵַΪ 10.2.0.3ͽ Y + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/bf4ed077-d481-4db7-9e7a-85d841a5a8c3.jpg) + +## ַת NAT + +רڲʹñ IP ַͻϵͨʱʹ NAT IP תΪȫ IP + +ǰNAT IP ȫ IP һһӦַʽӵ n ȫ IP ַרֻͬʱ n ̨뻥Ϊ˸Чȫ IP ַڳõ NAT תĶ˿ںҲˣʹöרڲһȫ IP ַʹö˿ںŵ NAT Ҳַ˿ת NAPT + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/0f31bc7a-d60b-48a6-8e3f-597708369e52.png) + +# + +ֻѷ鷢͵ĿͨŵIJеĽ̡ + +ṩӦý̼߼ͨš߲ûĺϸڣʹӦó򿴼ĺʵ֮һ˵˵߼ͨŵ + +## UDP TCP ص + +ûݰЭ UDPUser Datagram Protocol +Э TCPTransmission Control Protocol + +UDP ӵģܽûӵƣģӦóıIJϲҲֻ֣ UDP ײ + +TCP ӵģṩɿƣӵƣṩȫ˫ͨţֽӦò㴫ıĿֽֽ֯ɴСȵݿ飩 + +## UDP ײʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/bd6c05f3-02ee-4c8a-b374-40c87154a898.jpg) + +ײֶֻ 8 ֽڣԴ˿ڡĿĶ˿ڡȡ͡12 ֽڵαײΪ˼Ͷʱӵġ + +## TCP ײʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/21a00b02-c0a6-4bcd-9af0-5ec6bb66e34c.jpg) + +**** ڶֽбţΪ 301ʾһֽڵıΪ 301ЯݳΪ 100 ֽڣôһĶεӦΪ 401 + +**ȷϺ** յһĶεš B ȷյ A һĶΣΪ 501ЯݳΪ 200 ֽڣ B һĶεΪ 701B ͸ A ȷϱĶȷϺžΪ 701 + +**ƫ** ָݲ־뱨Ķʼƫʵָײijȡ + +**ȷ ACK** ACK=1 ʱȷϺֶЧЧTCP 涨ӽд͵ıĶζ ACK 1 + +**ͬ SYN** ӽʱͬš SYN=1ACK=0 ʱʾһĶΡԷͬ⽨ӣӦ SYN=1ACK=1 + +**ֹ FIN** ͷһӣ FIN=1 ʱʾ˱ĶεķͷѷϣҪͷӡ + +**** ֵΪշ÷ͷ䷢ʹڵݡ֮ҪƣΪշݻռ޵ġ + +## TCP + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/086871db-5871-460f-97b7-126cd738bb0e.jpg) + + A ΪͻˣB Ϊˡ + +1. B LISTEN״̬ȴͻ +2. A B ĶΣSYN=1ACK=0ѡһʼ x +3. B յĶΣͬ⽨ӣ A ȷϱĶΣSYN=1ACK=1ȷϺΪ x+1ͬʱҲѡһʼ y +4. A յ B ȷϱĶκ󣬻Ҫ B ȷϣȷϺΪ y+1Ϊ x+1 +5. B յ A ȷϺӽ + + +## TCP Ĵλ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/78f65456-666b-4044-b4ee-f7692dbbc0d3.jpg) + +źȷϺţΪźȷϺŵĹȽϼ򵥡Ҳ ACKΪ ACK ӽ֮Ϊ 1 + +1. A ͷűĶΣFIN=1 +2. B յ֮󷢳ȷϣʱ TCP ڰر״̬B A ݵ A B ݣ +3. B ҪҪʱͷĶΣFIN=1 +4. A յ󷢳ȷϣʱͷš + +**TIME_WAIT** + +ͻ˽յ˵ FIN ĺ״̬ʱֱӽ CLOSED ״̬Ҫȴһʱʱõʱ䡣ôɣ + +1. ȷһȷϱĶܹ B ûյ A ȷϱĶΣôͻ·ͷĶΣA ȴһʱΪ˴ķ +2. ӹ̿ܡʧЧĶΡΪ˷ֱֹĶγڱ֮⣬Ҫȴһʱ䡣 + +## TCP + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/223fc26e-2fd6-484c-bcb7-443cac134f15.jpg) + +ǻһ֣ʱֽͷͽշһڣշͨ TCP ĶеĴֶθ߷ͷԼĴڴСͷֵϢԼĴڴС + +ʹڵֽڶͣմڵֽڶաʹ󲿵ֽѾͲյȷϣôͽʹһһ룬ֱ󲿵һֽڲѷͲȷϵ״̬մڵĻƣմֽѾȷϲһմڡ + +մֻԴһ򵽴ֽڽȷϣմѾյֽΪ {31, 32, 34, 35} {31, 32} 򵽴 {34, 35} Ͳǣֻֽ 32 ȷϡͷõһֽڵȷ֮󣬾ֽ֪֮ǰֽڶѾա + +## TCP ɿ + +TCP ʹóʱشʵֿɿ䣺һѾ͵ıĶڳʱʱûյȷϣôشĶΡ + +һĶδӷ͵յȷʱΪʱ RTTȨƽʱ RTTs £ + +![](http://latex.codecogs.com/gif.latex?\\\\RTTs=(1-a)*(RTTs)+a*RTT) + +֪ʱʱ RTO ӦԴ RRTsTCP ʹõijʱʱ£ + +![](http://latex.codecogs.com/gif.latex?\\\\RTO=RTTs+4*RTT_d) + + RTTd Ϊƫµ RRT RRTs йء + +## TCP + +Ϊ˿Ʒͷʣ֤շüա + +շ͵ȷϱеĴֶοƷͷڴСӶӰ췢ͷķʡ罫ֶΪ 0ͷܷݡ + +## TCP ӵ + +ӵ齫ᶪʧʱͷشӶӵ̶ȸߡ˵ӵʱӦƷͷʡһƺ񣬵dz㲻ͬΪýշüܣӵΪ˽ӵ̶ȡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a69af9bb-b5ad-4896-862d-697e5ee4feb1.png) + +TCP Ҫͨ㷨ӵƣʼӵ⡢شָͷҪάһӵڣcwnd״̬עӵ뷢ͷڵӵֻһ״̬ʵʾͷܷͶݵǷͷڡ + +Ϊ˱ۣ¼裺 + +1. շ㹻Ľջ棬˲ᷢƣ +2. Ȼ TCP Ĵڻֽڣ贰ڵĴСλΪĶΡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/346244ff-98c1-4f12-9a87-d0832e8c04cf.jpg) + +### ʼӵ + +͵ִʼ cwnd=1ͷֻܷ 1 ĶΣյȷϺ󣬽 cwnd ӱ֮ͷܹ͵ıĶΪ248 ... + +ע⵽ʼÿִζ cwnd ӱ cwnd ٶȷdz죬Ӷʹ÷ͷ͵ٶٶȹ죬ӵĿҲ͸ߡһʼ ssthresh cwnd >= ssthresh ʱӵ⣬ÿִֻ cwnd 1 + +˳ʱ ssthresh = cwnd / 2Ȼִʼ + +### شָ + +ڽշҪÿνյĶζӦ÷ͶյĶεȷϣѾյ M1 M2ʱյ M4ӦͶ M2 ȷϡ + +ڷͷյظȷϣôȷһĶζʧյ M2 M3 ʧʱִпششһĶΡ + +£ֻǶʧĶΣӵִпָ ssthresh = cwnd / 2 cwnd = ssthreshע⵽ʱֱӽӵ⡣ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b18d679b-c8e2-4564-88ee-7600090e46da.jpg) + +# Ӧò + +## ϵͳ DNS + +Ϊ IP ַ + +Ƴɷֲʽϵͳ + +### 1. νṹ + +һɶιɣϲ㵽²ֱΪԼļԻһ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c2117f61-1177-4768-bf33-cf4f950d911c.png) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a4b162e5-db2a-4a27-b213-1fe481c5a06a.png) + +ԷΪࣺ + +**(1) ** + +**(2) ** + +**(3) Ȩ**ڵ + +ĸͬһлֶͼ b abc.com лabc.com y.abc.com + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/fc0c6b2d-68c7-4de8-aaaa-97355a4f0472.jpg) + +˾ҪȨ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8b335d94-c1ca-42e1-ad48-bb179d28a4f1.jpg) + +**(4) **ҲΪĬøٻ档 + +### 2. + +򱾵Ĺ̲õݹ飬ʹõݹ͵ַʽ + +ķʽ£һ֮󣬽صȻ󱾵ݹطʽ£ֱӷصģǼǰĽŻ᷵ء + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6bc61bb8-3b1c-4dc8-ac25-cef925ace0eb.jpg) + +## ļЭ FTP + +FTP ʹ TCPҪе TCP ӣӺӡỰڼһֱִ򿪣ݴ֮͹رաʹö˿ں 21ʹö˿ں 20 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/58633775-8584-4a01-ad3f-eee4d9a466e1.jpg) + +## ԶնЭ TELNET + +TELNET ڵ¼ԶϣԶϵҲ᷵ء + +TELNET ӦͲϵͳIJ죬粻ͬϵͳϵͳĻз塣 + +## ά WWW + + HTTP ʼǡ + +## ʼЭ + +һʼϵͳɣûʼԼʼЭͶȡЭ顣зЭ鳣 SMTPȡЭ鳣 POP3 IMAP + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/de1e46d2-748f-4da3-a29e-7de7bc840366.jpg) + +### POP3 + +POP3 صֻҪûӷ϶ȡʼͰѸʼɾ + +### IMAP + +IMAP Эпͻ˺ͷϵʼͬȥֶɾʼôϵʼҲᱻɾIMAP ûʱȥʷϵʼIMAP ЭҲִ֧ԶļС + +### SMTP + +SMTP ֻܷ ASCII 룬ʼ MIME ԷͶļMIME ûиĶȡ SMTPʼĽṹ˷ ASCII ı + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ed5522bb-3a60-481c-8654-43e7195a48fe.png) + +## ̬Э DHCP + +DHCP ṩ˼弴õʽûҪȥֶ IP ַϢ + +DHCP õݲ IP ַ롢Ĭ· IP ַ IP ַ + +ʽ£Ҫ IP ַ㲥 DHCP ֱģĿĵַΪȫ 1 255.255.255.255:67ԴַΪȫ 0 0.0.0.0:68DHCP յֱ֮ IP ַȡһַ DHCP ṩĸ + +## Ե㴫 P2P + +ijļַжԵȼϳΪһļݵԪΪļ飬ĴСǹ̶ġһµĶԵȷijһʼûļ飬ܹԵȷ𽥵صһЩļ飬ͬʱҲΪĶԵȷϴһЩļ顣 + +ÿһʩΪ׷һԵȷʱ׷ǼǣԵ֪ͨ׷ںСκʱ˳ij + +һµĶԵȷʱ׷ӺѡɸԵȷ¶ԵȷЩԵȷӣЩԵȷΪڶԵȷպͷļ鶼ڶԵȷнС + +һԵȷҪܶļʱͨʹϡȵIJȡļ飬ҲһļڶԵȷи٣ôļ顣 + +ܶԵȷͬһԵȷļʱöԵȷѡ䷢ļĶԵȷ + +P2P һֲʽϵͳκʱжԵȷ˳ʹ÷ֲʽɢб DHTԲҺеԴ IP ַӳ䡣 + +## www.baidu.com ִеȫ + +1ͻͨ DNS www.baidu.com IP ַ 220.181.27.48ͨ IP ַҵͻ˵·ͻһ HTTP Ự 220.161.27.48Ȼͨ TCP зװݰ뵽㡣 + +2ڿͻ˵Ĵ㣬 HTTP ỰֳɱĶΣԴĿĶ˿ڣʹ 80 ˿ڼͻ˵󣬿ͻϵͳѡһ˿ 5000нӦ󷵻ظͻ˵ 5000 ˿ڡȻʹ IP IP ַĿĶˡ + +3ͻ˵㲻ùϵӦòߴĶҪͨ·ɱȷεڼܾ·Щ·ɵĹҲ޷Ǿͨ·ɱͨǸ· + +4ͻ˵·㣬ͨ·㷢͵·ͨھЭҸ IP ַ MAC ַȻ ARP ĿĵַõӦͿʹ ARP Ӧ𽻻 IP ݰھͿԴˣȻ IP ݰĵַ + + +## ö˿ + +| ӦòЭ | ˿ں | Э | +| -- | -- | -- | +| DNS | 53 | UDP | +| FTP | 21 20 | TCP | +| TELNET | 23 | TCP | +| DHCP | 67 68 | UDP | +| HTTP | 80 | TCP | +| SMTP | 25 | TCP | +| POP3 | 110 | TCP | +| IMAP | 143 | TCP | + +# ο + +- ߰ +- Զ¼ +- [ ֮Գ ](https://www.nowcoder.com/discuss/1937) diff --git a/notes/设计模式.md b/notes/设计模式.md new file mode 100644 index 00000000..cc795836 --- /dev/null +++ b/notes/设计模式.md @@ -0,0 +1,1744 @@ + +* [](#) +* [ 1 ģʽ](#-1--ģʽ) +* [ 2 ۲ģʽ](#-2--۲ģʽ) +* [ 3 װģʽ](#-3--װģʽ) +* [ 4 ģʽ](#-4--ģʽ) + * [4.1 򵥹](#41-򵥹) + * [4.2 ģʽ](#42-ģʽ) + * [4.3 󹤳ģʽ](#43-󹤳ģʽ) +* [ 5 ģʽ](#-5--ģʽ) +* [ 6 ģʽ](#-6--ģʽ) +* [ 7 ģʽģʽ](#-7--ģʽģʽ) + * [7.1 ģʽ](#71-ģʽ) + * [7.2 ģʽ](#72-ģʽ) +* [ 8 ģ巽ģʽ](#-8--ģ巽ģʽ) +* [ 9 ģʽ](#-9--ģʽ) + * [9.1 ģʽ](#91-ģʽ) + * [9.2 Java õĵ](#92-java-õĵ) + * [9.3 ģʽ](#93-ģʽ) +* [ 10 ״̬ģʽ](#-10--״̬ģʽ) +* [ 11 ģʽ // TODO](#-11--ģʽ--todo) +* [ 12 ģʽ](#-12--ģʽ) + * [12.1 MVC](#121-mvc) + * [12.1.1 ͳ MVC](#1211-ͳ-mvc) + * [12.1.2 Web е MVC](#1212-web-е-mvc) +* [ 13 ģʽദ](#-13--ģʽദ) +* [ 14 ʣµģʽ // TODO](#-14--ʣµģʽ--todo) + + +# + +- ѧϰͼƬʽͽ̸ʽЧʻߡ + +- ֻԼΪһҪʱŻȥԴϻôԻѧӦһӦΪԾرҪ + +- ظַöʽһڴԵĶ֮ء + +- ͨӰôͶע + +- ˵ַΪ˻DZȽϲ˴򽻵 + +- Чʵ£Ӱڷ飬ҪͣϢһ¡ + +# 1 ģʽ + +**1. ģʽ** + +ģʽǴ룬ǽķѧϰеģʽ鸴á + +ӵģʽʻ㣬ڹͨʱøٵĴʻۣҲҪ˽ײϸڡ + +**2. ** + +ƲͬѼӵвͬĽͷзʽ + +**3. ʵַ** + +ʹü̳еĽ£ַ޷ãѼӵͬķзʽظĴ롣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/144d28a0-1dc5-4aba-8961-ced5bc88428a.jpg) + +**4. ԭ** + +**װ仯**仯ѼӽкͷеΪʽ + +**Խӿڱ̣ʵֱ** Ϊ࣬Ǿijࡣеķʵֲڸ࣬ڸࡣʱԶ̬ıָ͡ + +һԭ򣬽кͷеΪʵֲֶͬĽкͷе࣬ȥʵ־Ľкͷзʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1c8ccf5c-7ecd-4b8a-b160-3f72a510ce26.png) + +**ϣü̳** Ҳ has-a ϵͨϣʱ̬ıʵֻ֣Ҫͨı丸ָĸ༴ɡ̳оͲЩ̳ϵڴʱѾȷ + +һԭ Duck FlyBehavior QuackBehavior ࣬performQuack() performFly() ίиȥַͨʽһ Duck ԸҪȥʵ FlyBehavior QuackBehavior 󣬲ҲԶ̬ؽиı䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/29574e6f-295c-444e-83c7-b162e8a73a83.jpg) + +**5. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e13833c8-e215-462e-855c-1d362bb8d4a0.jpg) + +**6. ģʽ** + +**ģʽ** 㷨壬ֱװ֮Ի滻ģʽ㷨ı仯ʹ㷨Ŀͻ + +**7. ʵִ** + +```java +public abstract class Duck { + FlyBehavior flyBehavior; + QuackBehavior quackBehavior; + + public Duck(){ + } + + public void performFly(){ + flyBehavior.fly(); + } + + public void setFlyBehavior(FlyBehavior fb){ + flyBehavior = fb; + } + + public void performQuack(){ + quackBehavior.quack(); + } + + public void setQuackBehavior(QuackBehavior qb){ + quackBehavior = qb; + } +} +``` +```java +public class MallarDuck extends Duck{ + public MallarDuck(){ + flyBehavior = new FlyWithWings(); + quackBehavior = new Quack(); + } +} +``` +```java +public interface FlyBehavior { + void fly(); +} +``` +```java +public class FlyNoWay implements FlyBehavior{ + @Override + public void fly() { + System.out.println("FlyBehavior.FlyNoWay"); + } +} +``` +```java +public class FlyWithWings implements FlyBehavior{ + @Override + public void fly() { + System.out.println("FlyBehavior.FlyWithWings"); + } +} +``` +```java +public interface QuackBehavior { + void quack(); +} +``` +```java +public class Quack implements QuackBehavior{ + @Override + public void quack() { + System.out.println("QuackBehavior.Quack"); + } +} +``` +```java +public class MuteQuack implements QuackBehavior{ + @Override + public void quack() { + System.out.println("QuackBehavior.MuteQuack"); + } +} +``` +```java +public class Squeak implements QuackBehavior{ + @Override + public void quack() { + System.out.println("QuackBehavior.Squeak"); + } +} +``` +```java +public class MiniDuckSimulator { + public static void main(String[] args) { + Duck mallarDuck = new MallarDuck(); + mallarDuck.performQuack(); + mallarDuck.performFly(); + mallarDuck.setFlyBehavior(new FlyNoWay()); + mallarDuck.performFly(); + } +} +``` +ִн +```html +QuackBehavior.Quack +FlyBehavior.FlyWithWings +FlyBehavior.FlyNoWay +``` + +# 2 ۲ģʽ + +**1. ģʽ** + +˶֮һԶһı״̬ʱ߶֪ܵͨԶ¡⣨SubjectDZ۲Ķ󣬶ߣObserverΪ۲ߡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/26cb5e7e-6fa3-44ad-854e-fe24d1a5278c.jpg) + +**2. ģʽͼ** + +оעƳ۲ߣ֪ͨעߵĹܣͨάһŹ۲бʵЩġ + +۲ӵһãΪעᡢƳݶ⵱УͨӦܡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5c558190-fccd-4b5e-98ed-1896653fc97f.jpg) + +**3. ** + +ݲϢıʱݣжڽӡ + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/760a5d63-d96d-4dd9-bf9a-c3d126b2f401.jpg) + +**5. ԭ** + +**Ϊ֮ƶŬ** ֮ϣȻԽDz̫˴˵ϸڡϵ֮以̶ȺܵͣϵͳеԣܹӦԱ仯 + +**6. ʵִ** + +```java +public interface Subject { + public void resisterObserver(Observer o); + public void removeObserver(Observer o); + public void notifyObserver(); +} +``` +```java +import java.util.ArrayList; +import java.util.List; + +public class WeatherData implements Subject { + private List observers; + private float temperature; + private float humidity; + private float pressure; + + public WeatherData() { + observers = new ArrayList<>(); + } + + @Override + public void resisterObserver(Observer o) { + observers.add(o); + } + + @Override + public void removeObserver(Observer o) { + int i = observers.indexOf(o); + if (i >= 0) { + observers.remove(i); + } + } + + @Override + public void notifyObserver() { + for (Observer o : observers) { + o.update(temperature, humidity, pressure); + } + } + + public void setMeasurements(float temperature, float humidity, float pressure) { + this.temperature = temperature; + this.humidity = humidity; + this.pressure = pressure; + notifyObserver(); + } +} +``` +```java +public interface Observer { + public void update(float temp, float humidity, float pressure); +} +``` +```java +public class CurrentConditionsDisplay implements Observer { + private Subject weatherData; + + public CurrentConditionsDisplay(Subject weatherData) { + this.weatherData = weatherData; + weatherData.resisterObserver(this); + } + + @Override + public void update(float temp, float humidity, float pressure) { + System.out.println("CurrentConditionsDisplay.update:" + temp + " " + humidity + " " + pressure); + } +} +``` +```java +public class StatisticsDisplay implements Observer { + private Subject weatherData; + + public StatisticsDisplay(Subject weatherData) { + this.weatherData = weatherData; + weatherData.resisterObserver(this); + } + + @Override + public void update(float temp, float humidity, float pressure) { + System.out.println("StatisticsDisplay.update:" + temp + " " + humidity + " " + pressure); + } +} +``` +```java +public class WeatherStation { + public static void main(String[] args) { + WeatherData weatherData = new WeatherData(); + CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); + StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); + + weatherData.setMeasurements(0, 0, 0); + weatherData.setMeasurements(1, 1, 1); + } +} +``` +ִн +```html +CurrentConditionsDisplay.update:0.0 0.0 0.0 +StatisticsDisplay.update:0.0 0.0 0.0 +CurrentConditionsDisplay.update:1.0 1.0 1.0 +StatisticsDisplay.update:1.0 1.0 1.0 +``` + +# 3 װģʽ + +**1. ** + +ƲͬϣÿϿԶ̬µIJϣţ̡һϵļ۸ + +**2. ģʽ** + +̬ؽθӵϡչϣװṩ˱ȼ̳иеԵ + +ͼ DarkRoast Mocha Mocha ֱ Whip Ƕ̳ͬ࣬ cost() cost() ʵֵڲ cost() ˣҪ DarkRoast MochaôֻҪ Mocha DarkRoastҪ Whip Whip Mocha cost() ֶܰļ۸񶼰ȥ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/41a4cb30-f393-4b3b-abe4-9941ccf8fa1f.jpg) + +**3. ģʽͼ** + +װߺ;̳ͣоķʵֲҪ󣬶װӵһͶװװ߻߾νװΣǰװڱװεĶ֮⣬Ӷ̬չװߵĹܡװߵķһԼģĹܣȻñװߵķʵ֣ӶҲ˱װߵĹܡԿӦװβεͲ㣬ΪֻоֱʵֶҪίиȥ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/3dc454fb-efd4-4eb8-afde-785b2182caeb.jpg) + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/9c997ac5-c8a7-44fe-bf45-2c10eb773e53.jpg) + +**5. ԭ** + +**Ӧöչţ޸Ĺرա**Ҳ¹ʱҪ޸Ĵ롣ڱиԭڣµIJϣҪȥ޸ϵĴ롣۲ģʽҲԭ򡣲඼ʵԭӦѸԭӦпܸıĵط + +**6. Java I/O еװģʽ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2a40042a-03c8-4556-ad1f-72d89f8c555c.jpg) + +**7. ʵ** + +```java +public interface Beverage { + public double cost(); +} +``` +```java +public class HouseBlend implements Beverage{ + @Override + public double cost() { + return 1; + } +} +``` +```java +public class DarkRoast implements Beverage{ + @Override + public double cost() { + return 1; + } +} +``` +```java +public abstract class CondimentDecorator implements Beverage{ + protected Beverage beverage; +} +``` +```java +public class Mocha extends CondimentDecorator { + + public Mocha(Beverage beverage) { + this.beverage = beverage; + } + + @Override + public double cost() { + return 1 + beverage.cost(); + } +} +``` +```java +public class Milk extends CondimentDecorator { + + public Milk(Beverage beverage) { + this.beverage = beverage; + } + + @Override + public double cost() { + return 1 + beverage.cost(); + } +} +``` +```java +public class StartbuzzCoffee { + public static void main(String[] args) { + Beverage beverage = new HouseBlend(); + beverage = new Mocha(beverage); + beverage = new Milk(beverage); + System.out.println(beverage.cost()); + } +} +``` + + + +```html +3.0 +``` + +# 4 ģʽ + +## 4.1 򵥹 + +**1. ** + +вͬ Pizzaݲͬòͬʵһ Pizza + +**2. ** + +򵥹ģʽһֱϰߡʵһĶʱʵҪݾʹĸࡣ£ʵIJŵУùӦĸʵѿͻ;ʵֽͻҪ֪ЩԼʵĸࡣΪͻжʹü򵥹ôеĿͻ඼Ҫ֪ϸڣһ෢ı䣬࣬ôеĿͻ඼Ҫı䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c470eb9b-fb05-45c5-8bb7-1057dc3c16de.jpg) + +**3. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dc3e704c-7c57-42b8-93ea-ddd068665964.jpg) + + +**4. ʵ** + +```java +public interface Pizza { + public void make(); +} +``` +```java +public class CheesePizza implements Pizza{ + @Override + public void make() { + System.out.println("CheesePizza"); + } +} +``` +```java +public class GreekPizza implements Pizza{ + @Override + public void make() { + System.out.println("GreekPizza"); + } +} +``` +```java +public class SimplePizzaFactory { + public Pizza createPizza(String type) { + if (type.equals("cheese")) { + return new CheesePizza(); + } else if (type.equals("greek")) { + return new GreekPizza(); + } else { + throw new UnsupportedOperationException(); + } + } +} +``` +```java +public class PizzaStore { + public static void main(String[] args) { + SimplePizzaFactory simplePizzaFactory = new SimplePizzaFactory(); + Pizza pizza = simplePizzaFactory.createPizza("cheese"); + pizza.make(); + } +} +``` + +н + +```java +CheesePizza +``` + +## 4.2 ģʽ + +**1. ** + +ÿ Pizza ȻͬǶԼķζҪ֡磬һͻŦԼ cheese Pizza ֥Ӹͬ Pizza Dzͬġ + +**2. ģʽ** + +һĽӿڣҪʵһʵƳٵࡣ + +**3. ģʽͼ** + +ڼ򵥹Уһ࣬ڹУ󡣹ÿ඼ԼһƷࡣΪÿഴļ򵥹ǰѼ򵥹дĴŵԼĿΪ಻DzƷ࣬ȫô + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/903093ec-acc8-4f9b-bf2c-b990b9a5390c.jpg) + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/664f8901-5dc7-4644-a072-dad88cc5133a.jpg) + +**5. ʵ** + +```java +public interface Pizza { + public void make(); +} +``` +```java +public interface PizzaStore { + public Pizza orderPizza(String item); +} +``` +```java +public class NYStyleCheesePizza implements Pizza{ + @Override + public void make() { + System.out.println("NYStyleCheesePizza is making.."); + } +} +``` +```java +public class NYStyleVeggiePizza implements Pizza { + @Override + public void make() { + System.out.println("NYStyleVeggiePizza is making.."); + } +} +``` +```java +public class ChicagoStyleCheesePizza implements Pizza{ + @Override + public void make() { + System.out.println("ChicagoStyleCheesePizza is making.."); + } +} +``` +```java +public class ChicagoStyleVeggiePizza implements Pizza{ + @Override + public void make() { + System.out.println("ChicagoStyleVeggiePizza is making.."); + } +} +``` +```java +public class NYPizzaStore implements PizzaStore { + @Override + public Pizza orderPizza(String item) { + Pizza pizza = null; + if (item.equals("cheese")) { + pizza = new NYStyleCheesePizza(); + } else if (item.equals("veggie")) { + pizza = new NYStyleVeggiePizza(); + } else { + throw new UnsupportedOperationException(); + } + pizza.make(); + return pizza; + } +} +``` +```java +public class ChicagoPizzaStore implements PizzaStore { + @Override + public Pizza orderPizza(String item) { + Pizza pizza = null; + if (item.equals("cheese")) { + pizza = new ChicagoStyleCheesePizza(); + } else if (item.equals("veggie")) { + pizza = new ChicagoStyleVeggiePizza(); + } else { + throw new UnsupportedOperationException(); + } + pizza.make(); + return pizza; + } +} +``` +```java +public class PizzaTestDrive { + public static void main(String[] args) { + PizzaStore nyStore = new NYPizzaStore(); + nyStore.orderPizza("cheese"); + PizzaStore chicagoStore = new ChicagoPizzaStore(); + chicagoStore.orderPizza("cheese"); + } +} +``` + +н + +```html +NYStyleCheesePizza is making.. +ChicagoStyleCheesePizza is making.. +``` + +## 4.3 󹤳ģʽ + +**1. ԭ** + +**ԭ**Ҫ󣬲ҪࡣԽӿڱ̣ʵֱ̣ԭ˵ˣø߲ײңܸ߲ײ߶Ӧڳ磬ͼ PizzaStore ڸ߲ڵײ Pizza ľࡣ Pizza ij࣬ôͿԲù Pizza ľʵϸڡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ddf72ca9-c0be-49d7-ab81-57a99a974c8e.jpg) + +**2. ģʽ** + +ṩһӿڣڴػļ壬Ҫȷָࡣ + +**3. ģʽͼ** + +󹤳ģʽǶ壬ҲǺܶһ󣬲ЩصģҲ˵һ𴴽ģʽֻڴһͳ󹤳ģʽкܴͬң󹤳ģʽҲõ˹ģʽһͼ󲿣AbstractFactory е CreateProductA CreateProductB ʵ֣ڴһϹģʽĶ塣ڴļһ Client ֣Client Ҫͨ AbstractFactory ͬʱкܴԣClient ҪЭ񡣴Ӹ߲󹤳ʹϣ Cilent AbstractFactory ģʽʹ˼̳С + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d301774f-e0d2-41f3-95f4-bfe39859b52e.jpg) + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8785dabd-1285-4bd0-b3aa-b05cc060a24a.jpg) + +**5. ʵ** + +```java +public interface Dough { + public String doughType(); +} +``` +```java +public class ThickCrustDough implements Dough{ + + @Override + public String doughType() { + return "ThickCrustDough"; + } +} +``` +```java +public class ThinCrustDough implements Dough { + @Override + public String doughType() { + return "ThinCrustDough"; + } +} +``` +```java +public interface Sauce { + public String sauceType(); +} +``` +```java +public class MarinaraSauce implements Sauce { + @Override + public String sauceType() { + return "MarinaraSauce"; + } +} +``` +```java +public class PlumTomatoSauce implements Sauce { + @Override + public String sauceType() { + return "PlumTomatoSauce"; + } +} +``` +```java +public interface PizzaIngredientFactory { + public Dough createDough(); + public Sauce createSauce(); +} +``` +```java +public class NYPizzaIngredientFactory implements PizzaIngredientFactory{ + @Override + public Dough createDough() { + return new ThickCrustDough(); + } + + @Override + public Sauce createSauce() { + return new MarinaraSauce(); + } +} +``` +```java +public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory{ + @Override + public Dough createDough() { + return new ThinCrustDough(); + } + + @Override + public Sauce createSauce() { + return new PlumTomatoSauce(); + } +} +``` +```java +public class NYPizzaStore { + private PizzaIngredientFactory ingredientFactory; + + public NYPizzaStore() { + ingredientFactory = new NYPizzaIngredientFactory(); + } + + public void makePizza() { + Dough dough = ingredientFactory.createDough(); + Sauce sauce = ingredientFactory.createSauce(); + System.out.println(dough.doughType()); + System.out.println(sauce.sauceType()); + } +} +``` +```java +public class NYPizzaStoreTestDrive { + public static void main(String[] args) { + NYPizzaStore nyPizzaStore = new NYPizzaStore(); + nyPizzaStore.makePizza(); + } +} +``` + +н + +```html +ThickCrustDough +MarinaraSauce +``` + +# 5 ģʽ + +**1. ģʽ** + +ȷһֻһʵṩһȫַʵ㡣 + +**2. ģʽͼ** + +ģʽ Java ʵһ˽йһ˽о̬Լһо̬ú˽бʹͨúȡĶָΨһ˽о̬ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/59aff6c1-8bc5-48e4-9e9c-082baeb2f274.jpg) + +**3. ʵ** + +ʵУ˽о̬ӳٻʵĺôǣûõ࣬ôͲᴴ˽о̬ӶԼԴʵڶ̻߳DzȫģΪܹ߳ͬʱ if(uniqueInstance == null) ڵ飬ôͻʵ uniqueInstance ˽о̬ + +```java +public class Singleton { + + private static Singleton uniqueInstance; + + private Singleton() { + } + + public static Singleton getUniqueInstance() { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + return uniqueInstance; + } +} +``` + +**4. ̲߳ȫĽһ** + +ֻҪ getUniqueInstance() ø÷һֻһ̷߳ʣӶ˶ uniqueInstance жʵ⡣һһֻһ߳̽룬ϻһ˷ѡ + +```java + public static synchronized Singleton getUniqueInstance() { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + return uniqueInstance; + } +``` + +**5. ̲߳ȫĽ** + +ӳʵֱʵ + +```java +private static Singleton uniqueInstance = new Singleton(); +``` + +**6. ̲߳ȫĽ** + +ǵһֱӶ getUniqueInstance() мʵֻҪ uniqueInstance = new Singleton(); ɡʹж uniqueInstance ǷѾʵûʵҪ + +```java +public class Singleton { + + private volatile static Singleton uniqueInstance; + + private Singleton() { + } + + public static synchronized Singleton getUniqueInstance() { + if (uniqueInstance == null) { + synchronized (Singleton.class) { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + } + } + return uniqueInstance; + } +} +``` + +# 6 ģʽ + +**1. ** + +һңкܶఴťÿťԷһһҵӦзdzļҵ磬ҲӼҵ硣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7b8f0d8e-a4fa-4c9d-b9a0-3e6a11cb3e33.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c3ca36b2-8459-4cf1-98b0-cc95a0e94f20.jpg) + +**2. ģʽ** + +װɶԱʹòͬ + +**3. ģʽͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1e09d75f-6268-4425-acf8-8ecd1b4a0ef3.jpg) + +**4. ͼ** + +Invoker ңҵ execute() Receiver ǵƣִߡConcreteCommand һ Receiver ִίи Receiver Ҳ LightOnCommand excute ίи Light Light ͨ on() ɲInvoker Client ΪĴ Invoker ɵģҪ Client Щ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/5ef94f62-98ce-464d-a646-842d9c72c8b8.jpg) + +**5. ʵ** + +```java +public interface Command { + public void execute(); +} +``` +```java +public class Light { + + public void on() { + System.out.println("Light is on!"); + } + + public void off() { + System.out.println("Light is off!"); + } +} +``` +```java +public class LightOnCommand implements Command{ + Light light; + + public LightOnCommand(Light light) { + this.light = light; + } + + @Override + public void execute() { + light.on(); + } +} +``` +```java +/** + * ң + */ +public class SimpleRemoteControl { + Command slot; + + public SimpleRemoteControl() { + + } + + public void setCommand(Command command) { + this.slot = command; + } + + public void buttonWasPressed() { + slot.execute(); + } + +} +``` +```java +public class RemoteLoader { + public static void main(String[] args) { + SimpleRemoteControl remote = new SimpleRemoteControl(); + Light light = new Light(); + LightOnCommand lightOnCommand = new LightOnCommand(light); + remote.setCommand(lightOnCommand); + remote.buttonWasPressed(); + } +} +``` + + + +```html +Light is on! +``` + +# 7 ģʽģʽ + +## 7.1 ģʽ + +**1. ģʽ** + +һĽӿڣתΪͻһӿڡԭݵԺ޼䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8e8ba824-7a9e-4934-a212-e6a41dcc1602.jpg) + +**2. ģʽͼ** + +ģʽʵ֣һǶʽһ෽ʽʽͨϵķࣨAdapterӵһĶAdapteeӶӦĴίиĶ෽ʽõؼ̳УAdapter Կ Target Adaptee ͣȰ Adaptee Ȼʵһ Adapter ٰ Target ͵ģ Client Ϳ԰󵱳 Target Ķ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/253bd869-ea48-4092-9aed-6906ccb2f3b0.jpg) + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a797959a-0ed5-475b-8d97-df157c672019.jpg) + +**3. ** + +ѼӣDuck𼦣TurkeyDuck quack() Turkey ֻ gobble() ҲҪ Turkey Ҳ Duck quack() + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1a511c76-bb6b-40ab-b8aa-39eeb619d673.jpg) + +**5. ʵ** + +```java +public interface Duck { + public void quack(); + public void fly(); +} +``` +```java +public interface Turkey { + public void gobble(); + public void fly(); +} +``` +```java +public class WildTurkey implements Turkey{ + @Override + public void gobble() { + System.out.println("gobble!"); + } + + @Override + public void fly() { + System.out.println("fly!"); + } +} +``` +```java +public class TurkeyAdapter implements Duck{ + Turkey turkey; + + public TurkeyAdapter(Turkey turkey) { + this.turkey = turkey; + } + + @Override + public void quack() { + turkey.gobble(); + } + + @Override + public void fly() { + turkey.fly(); + } +} +``` +```java +public class DuckTestDrive { + public static void main(String[] args) { + Turkey turkey = new WildTurkey(); + Duck duck = new TurkeyAdapter(turkey); + duck.quack(); + duck.fly(); + } +} +``` + +н +```html +gobble! +fly! +``` + +## 7.2 ģʽ + +**1. ģʽ** + +ṩһͳһĽӿڣϵͳеһȺӿڡ۶һ߲ӿڣϵͳʹá + +**2. ģʽͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/78f2314e-2643-41df-8f3d-b7e28294094b.jpg) + +**3. ** + +ͥӰԺڶҪйۿӰʱҪԺܶвҪЩʹüͥӰԺֻṩһ򻯵ĽӿڣṩһӰĽӿڶþڶ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/106f5585-b2e7-4718-be5d-3b322d1ef42a.jpg) + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/25387681-89f8-4365-a2fa-83b86449ee84.jpg) + +**5. ԭ** + +**֪ʶԭ**̸ֻҲӦʹÿͻҪĶӦ١ + +# 8 ģ巽ģʽ + +**1. ģʽ** + +һжһ㷨ĹǼܣһЩӳٵС + +ģ巽ʹڲı㷨ṹ£¶㷨еijЩ衣 + +**2. ģʽͼ** + +ģ巽 templateMethod() 㷨ĹǼܣȷ primitiveOperation1() primitiveOperation2() ִе˳򣬶 primitiveOperation1() primitiveOperation2() ȥʵ֡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ed62f400-192c-4185-899b-187958201f0c.jpg) + +**3. ** + +忧Ⱥͳ趼Ƶ̣ijЩе㲻һ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/d8f873fc-00bc-41ee-a87c-c1b4c0172844.png) + +**4. ͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/aa20c123-b6b5-432a-83d3-45dc39172192.jpg) + +**5. ԭ** + +**ԭ**ã绰ǣǻã绰㡣һԭԷֹܣֹ߲ײײ߲ԭģ巽Ϊֻи࣬಻øࡣ + +**6. ** + +ӣhockijЩڲͬʵппޣȶһʲôķӵģ巽 templteMethod() УҪ͸ĬʵֲԼʵ֡ + +**7. ʵ** + +```java +public abstract class CaffeineBeverage { + + final void prepareRecipe(){ + boilWater(); + brew(); + pourInCup(); + addCondiments(); + } + + abstract void brew(); + + abstract void addCondiments(); + + void boilWater(){ + System.out.println("boilWater"); + } + + void pourInCup(){ + System.out.println("pourInCup"); + } +} +``` +```java +public class Coffee extends CaffeineBeverage{ + @Override + void brew() { + System.out.println("Coffee.brew"); + } + + @Override + void addCondiments() { + System.out.println("Coffee.addCondiments"); + } +} +``` +```java +public class Tea extends CaffeineBeverage{ + @Override + void brew() { + System.out.println("Tea.brew"); + } + + @Override + void addCondiments() { + System.out.println("Tea.addCondiments"); + } +} +``` +```java +public class CaffeineBeverageTestDrive { + public static void main(String[] args) { + CaffeineBeverage caffeineBeverage = new Coffee(); + caffeineBeverage.prepareRecipe(); + System.out.println("-----------"); + caffeineBeverage = new Tea(); + caffeineBeverage.prepareRecipe(); + } +} +``` + +н + +```html +boilWater +Coffee.brew +pourInCup +Coffee.addCondiments +----------- +boilWater +Tea.brew +pourInCup +Tea.addCondiments +``` + +# 9 ģʽ + +## 9.1 ģʽ + +**1. ģʽ** + +ṩһ˳һۺ϶еĸԪصķֲ¶ڲıʾ + +**2. ģʽͼ** + +ͻӵһۺ϶͵󣬵Ǿۺ϶ɵġֻҪƶIJͿþۺ϶ܹ˳ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/439deca7-fed0-4c89-87e5-7088d10f1fdb.jpg) + +**3. ʵ** + +```java +public class Aggregate { + + private int[] items; + + public Aggregate() { + items = new int[10]; + for (int i = 0; i < items.length; i++) { + items[i] = i; + } + } + + public Iterator createIterator() { + return new ConcreteIterator(items); + } + +} +``` +```java +public interface Iterator { + boolean hasNext(); + int next(); +} +``` +```java +public class ConcreteIterator implements Iterator { + + private int[] items; + private int position = 0; + + public ConcreteIterator(int[] items) { + this.items = items; + } + + @Override + public boolean hasNext() { + return position < items.length; + } + + @Override + public int next() { + return items[position++]; + } +} +``` +```java +public class Client { + public static void main(String[] args) { + Aggregate aggregate = new Aggregate(); + Iterator iterator = aggregate.createIterator(); + while(iterator.hasNext()){ + System.out.println(iterator.next()); + } + } +} +``` +н +```html +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +``` + +## 9.2 Java õĵ + +**1. ʵֽӿ** + +Java Ѿ Iterator ӿڣʹ Java ʵʱҪþۺ϶ʵ Iterable ӿڣýӿһ iterator() ᷵һ Iterator ʹ Java õĵʵ֣ͻʹ foreach ѭۺ϶еÿԪء + +**2. ʵ** + +```java +import java.util.Iterator; + +public class Aggregate implements Iterable{ + + private int[] items; + + public Aggregate() { + items = new int[10]; + for (int i = 0; i < items.length; i++) { + items[i] = i; + } + } + + @Override + public Iterator iterator() { + return new ConcreteIterator(items); + } +} +``` +```java +import java.util.Iterator; + +public class ConcreteIterator implements Iterator { + + private int[] items; + private int position = 0; + + public ConcreteIterator(int[] items) { + this.items = items; + } + + @Override + public boolean hasNext() { + return position < items.length; + } + + @Override + public Integer next() { + return items[position++]; + } +} +``` +```java +public class Client { + public static void main(String[] args) { + Aggregate aggregate = new Aggregate(); + for (int item : aggregate) { + System.out.println(item); + } + } +} +``` + +## 9.3 ģʽ + +**1. ԭ** + +һӦֻһıԭ + +**2. ģʽ** + +ϳνṹ֡ / ֡νṹ + +ÿͻһµķʽԼϡ + +**3. ģʽͼ** + +ϣCompositeӵһComponent϶λνṹм䣬Լ󣬲ľ͡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f99c019e-7e91-4c2e-b94d-b031c402dcb5.jpg) + +**4. ʵ** + +```java +public abstract class Component { + protected String name; + + public Component(String name) { + this.name = name; + } + + abstract public void addChild(Component component); + + public void print() { + print(0); + } + + abstract protected void print(int level); +} +``` +```java +public class Leaf extends Component { + public Leaf(String name) { + super(name); + } + + @Override + public void addChild(Component component) { + throw new UnsupportedOperationException(); // ͸Իȡһְԭ , ͲÿҶӽڵ㻹Ͻڵ + } + + @Override + protected void print(int level) { + for (int i = 0; i < level; i++) { + System.out.print("--"); + } + System.out.println("left:" + name); + } +} +``` +```java +import java.util.ArrayList; +import java.util.List; + +public class Composite extends Component { + + private List childs; + + public Composite(String name) { + super(name); + childs = new ArrayList<>(); + } + + @Override + public void addChild(Component component) { + childs.add(component); + } + + @Override + protected void print(int level) { + for (int i = 0; i < level; i++) { + System.out.print("--"); + } + System.out.println("Composite:" + name); + for (Component component : childs) { + component.print(level + 1); + } + } +} +``` +```java +public class Client { + public static void main(String[] args) { + Composite root = new Composite("root"); + Component node1 = new Leaf("1"); + Component node2 = new Composite("2"); + Component node3 = new Leaf("3"); + root.addChild(node1); + root.addChild(node2); + root.addChild(node3); + Component node21 = new Leaf("21"); + Component node22 = new Composite("22"); + node2.addChild(node21); + node2.addChild(node22); + Component node221 = new Leaf("221"); + node22.addChild(node221); + root.print(); + } +} +``` +н + +```html +Composite:root +--left:1 +--Composite:2 +----left:21 +----Composite:22 +------left:221 +--left:3 +``` + +# 10 ״̬ģʽ + +**1. ģʽ** + +ڲ״̬ıʱıΪ޸ࡣ + +״̬ģʽͼͲģʽһҶܹ̬ıΪ״̬ģʽͨ״̬״̬תıͻϵ״̬󣬶ģʽͨͻľıϵIJԶ磬״̬ģʽ£ͻί״̬һô״̬пܷ״̬תƣʹÿͻӵе״̬ı䡣״̬˿ͻ״̬ת״̬ͨıͻϵ״̬ʵֵġ + +**2. ģʽͼ** + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/c28fd93a-0d55-4a19-810f-72652feee00d.jpg) + +**3. ** + +ǹۻж״̬ÿ״̬ۻвͬΪ״̬ԷתƣʹۻΪҲı䡣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/f7d880c9-740a-4a16-ac6d-be502281b4b2.jpg) + +**4. ֱӽ** + +ǹÿ棬жϵǰ״̬ݲͬ״̬вͬĴҷͬ״̬תơֽеʵϸڶŵͻ࣬״̬ʱҪȥ޸ĿͻĴ롣 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/62ebbb63-8fd7-4488-a866-76a9dc911662.png) + +**5. ʹ״̬ģʽĽ** + +״̬תƱƵ״̬棬ͻÿֻҪίи״̬༴ɣҪ֪ǰʲô״̬Լ״̬ʱνתƵġ + + +**6. ʵ** + +```java +public interface State { + /** + * Ͷ25 Ǯ + */ + void insertQuarter(); + + /** + * ˻25 Ǯ + */ + void ejectQuarter(); + + /** + * ת + */ + void turnCrank(); + + /** + * ǹ + */ + void dispense(); +} +``` +```java +public class HasQuarterState implements State{ + private GumballMachine gumballMachine; + + public HasQuarterState(GumballMachine gumballMachine){ + this.gumballMachine = gumballMachine; + } + + @Override + public void insertQuarter() { + System.out.println("You can't insert another quarter"); + } + + @Override + public void ejectQuarter() { + System.out.println("Quarter returned"); + gumballMachine.setState(gumballMachine.getNoQuarterState()); + } + + @Override + public void turnCrank() { + System.out.println("You turned..."); + gumballMachine.setState(gumballMachine.getSoldState()); + } + + @Override + public void dispense() { + System.out.println("No gumball dispensed"); + } +} +``` +```java +public class NoQuarterState implements State { + GumballMachine gumballMachine; + + public NoQuarterState(GumballMachine gumballMachine) { + this.gumballMachine = gumballMachine; + } + + @Override + public void insertQuarter() { + System.out.println("You insert a quarter"); + gumballMachine.setState(gumballMachine.getHasQuarterState()); + } + + @Override + public void ejectQuarter() { + System.out.println("You haven't insert a quarter"); + } + + @Override + public void turnCrank() { + System.out.println("You turned, but there's no quarter"); + } + + @Override + public void dispense() { + System.out.println("You need to pay first"); + } +} +``` +```java +public class SoldOutState implements State { + + GumballMachine gumballMachine; + + public SoldOutState(GumballMachine gumballMachine) { + this.gumballMachine = gumballMachine; + } + + @Override + public void insertQuarter() { + System.out.println("You can't insert a quarter, the machine is sold out"); + } + + @Override + public void ejectQuarter() { + System.out.println("You can't eject, you haven't inserted a quarter yet"); + } + + @Override + public void turnCrank() { + System.out.println("You turned, but there are no gumballs"); + } + + @Override + public void dispense() { + System.out.println("No gumball dispensed"); + } +} +``` +```java +public class SoldState implements State { + GumballMachine gumballMachine; + + public SoldState(GumballMachine gumballMachine) { + this.gumballMachine = gumballMachine; + } + + @Override + public void insertQuarter() { + System.out.println("Please wait, we're already giving you a gumball"); + } + + @Override + public void ejectQuarter() { + System.out.println("Sorry, you already turned the crank"); + } + + @Override + public void turnCrank() { + System.out.println("Turning twice doesn't get you another gumball!"); + } + + @Override + public void dispense() { + gumballMachine.releaseBall(); + if(gumballMachine.getCount()>0){ + gumballMachine.setState(gumballMachine.getNoQuarterState()); + } else{ + System.out.println("Oops, out of gumballs"); + gumballMachine.setState(gumballMachine.getSoldOutState()); + } + } +} +``` +```java +public class GumballMachine { + private State soldOutState; + private State noQuarterState; + private State hasQuarterState; + private State soldState; + + private State state; + private int count = 0; + + public GumballMachine(int numberGumballs) { + count = numberGumballs; + soldOutState = new SoldOutState(this); + noQuarterState = new NoQuarterState(this); + hasQuarterState = new HasQuarterState(this); + soldState = new SoldState(this); + + if (numberGumballs > 0) { + state = noQuarterState; + } else { + state = soldOutState; + } + } + + public void insertQuarter() { + state.insertQuarter(); + } + + public void ejectQuarter() { + state.ejectQuarter(); + } + + public void turnCrank() { + state.turnCrank(); + state.dispense(); + } + + public void setState(State state) { + this.state = state; + } + + public void releaseBall() { + System.out.println("A gumball comes rolling out the slot..."); + if (count != 0) { + count -= 1; + } + } + + public State getSoldOutState() { + return soldOutState; + } + + public State getNoQuarterState() { + return noQuarterState; + } + + public State getHasQuarterState() { + return hasQuarterState; + } + + public State getSoldState() { + return soldState; + } + + public int getCount() { + return count; + } +} +``` +```java +public class GumballMachineTestDrive { + public static void main(String[] args) { + GumballMachine gumballMachine = new GumballMachine(5); + + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + + gumballMachine.insertQuarter(); + gumballMachine.ejectQuarter(); + gumballMachine.turnCrank(); + + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + gumballMachine.ejectQuarter(); + + gumballMachine.insertQuarter(); + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + gumballMachine.insertQuarter(); + gumballMachine.turnCrank(); + } +} +``` +н +```html +You insert a quarter +You turned... +A gumball comes rolling out the slot... +You insert a quarter +Quarter returned +You turned, but there's no quarter +You need to pay first +You insert a quarter +You turned... +A gumball comes rolling out the slot... +You insert a quarter +You turned... +A gumball comes rolling out the slot... +You haven't insert a quarter +You insert a quarter +You can't insert another quarter +You turned... +A gumball comes rolling out the slot... +You insert a quarter +You turned... +A gumball comes rolling out the slot... +Oops, out of gumballs +You can't insert a quarter, the machine is sold out +You turned, but there are no gumballs +No gumball dispensed +``` + +# 11 ģʽ // TODO + +# 12 ģʽ + +## 12.1 MVC + +### 12.1.1 ͳ MVC + +ͼʹģʽģʹ˹۲ģʽʹ˲ģʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4f67611d-492f-4958-9fa0-4948010e345f.jpg) + +### 12.1.2 Web е MVC + +ģʽʹù۲ģʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1dd56e61-2970-4d27-97c2-6e81cee86978.jpg) + +# 13 ģʽദ + +壺ij **龳** £ij **** ij **** + +ʹģʽܵ´뱻ȹ̻Ӧ򵥵ĽɹҪģʽĵطʹ + +ģʽõĽһ⡣ҪΪ˾治ҪʹЩ + +ģʽࣺ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/524a237c-ffd7-426f-99c2-929a6bf4c847.jpg) + +# 14 ʣµģʽ // TODO diff --git a/notes/面向对象思想.md b/notes/面向对象思想.md new file mode 100644 index 00000000..0403888d --- /dev/null +++ b/notes/面向对象思想.md @@ -0,0 +1,307 @@ + +* [S.O.L.I.D](#solid) + * [1. һԭ](#1-һԭ) + * [2. ŷԭ](#2-ŷԭ) + * [3. 滻ԭ](#3-滻ԭ) + * [4. ӿڷԭ](#4-ӿڷԭ) + * [5. ԭ](#5-ԭ) +* [װ̳С̬](#װ̳ж̬) + * [1. װ](#1-װ) + * [2. ̳](#2-̳) + * [3. ̬](#3-̬) +* [UML](#uml) + * [1. ͼ](#1-ͼ) + * [2. ʱͼ](#2-ʱͼ) +* [ο](#ο) + + +# S.O.L.I.D + +S.O.L.I.Dƺͱ(OOD&OOP)мҪԭ(Programming Priciple)ĸд + +|д |ȫƴ |ķ| +| -- | -- | -- | +|SRP| The Single Responsibility Principle |һԭ| +|OCP| The Open Closed Principle | ŷԭ| +|LSP| The Liskov Substitution Principle |滻ԭ| +|ISP| The Interface Segregation Principle |ӿڷԭ| +|DIP| The Dependency Inversion Principle |ԭ| + + +## 1. һԭ + +Ҫ޸ijʱԭֻһ仰˵һֻһΣҪе͵εʱ򣬾Ҫֽࡣ + +## 2. ŷԭ + +ʵӦǿչ޸ĵġҲ˵չǿŵģ޸Ƿյġ + +## 3. 滻ԭ + +һʵӦܹ滻κ䳬ʵʱ֮ž is-a ϵ + +## 4. ӿڷԭ + +ǿûȥЩDzʹõĽӿڡ仰˵ʹöרŵĽӿڱʹõһܽӿҪá + +## 5. ԭ + +1. ߲ģ鲻ӦڵͲģ飬߶Ӧڳ +2. ӦϸڣϸӦڳ + +# װ̳С̬ + +װ̳С̬ԡ + +## 1. װ + +óͽݺͻݵIJװһʹ乹һɷָĶʵ壬ݱڳ͵ڲܵڲϸڣֻһЩӿʹ֮ⲿϵû֪ڲϸڣͨöṩĽӿʸö + +װô + +1. õķװܹϡ + +2. ڲĽṹ޸ġ + +3. ԶԳԱиȷĿơ + +4. Ϣʵϸڡ + + Person װ namegenderage ԣֻͨ get() ȡһ Person name Ժ gender ԣ޷ȡ age ԣ age ԿԹ work() ʹá + +ע⵽ gender ʹ int ͽд洢װʹûעⲻʵϸڡҪ޸ʹõʱҲڲӰͻ˴½С + +```java +public class Person { + private String name; + private int gender; + private int age; + + public String getName() { + return name; + } + + public String getGender() { + return gender == 0 ? "man" : "woman"; + } + + public void work() { + if(18 <= age && age <= 50) { + System.out.println(name + " is working very hard!"); + } else { + System.out.println(name + " can't work!"); + } + } +} +``` + +## 2. ̳ + +̳ʵ **is-a** ϵ Cat Animal һ is-a ϵ˿Խ Cat ̳ AnimalӶ Animal private Ժͷ + +Cat Ե Animal ʹãҲǿʹ Animal Cat תΪΪ **ת** + +̳Ӧѭ滻ԭ򣺵һʵӦܹ滻κ䳬ʵʱ֮ž is-a ϵ + +```java +Animal animal = new Cat(); +``` + +## 3. ̬ + +̬Ϊʱ̬ʱ̬ʱ̬Ҫָװʱָ̬жĶָľڼȷ + +̬1. ̳У2. Ǹ෽3. ת͡ + +ĴУࣨInstrumentࣺWind PercussionǶ play() main() ʹø Instrument Wind Percussion Instrument õ play() ʱִʵö play() Instrument ķ + +```java +public class Instrument { + public void play() { + System.out.println("Instument is playing..."); + } +} + +public class Wind extends Instrument { + public void play() { + System.out.println("Wind is playing..."); + } +} + +public class Percussion extends Instrument { + public void play() { + System.out.println("Percussion is playing..."); + } +} + +public class Music { + public static void main(String[] args){ + List instruments = new ArrayList<>(); + instruments.add(new Wind()); + instruments.add(new Percussion()); + for(Instrument instrument : instruments){ + instrument.play(); + } + } +} + +``` + + + +# UML + +## 1. ͼ + +**1.1 ̳** + +̳ʽ: generalizeʵ֣realizeΪ is-a ϵ + + ϵ(generalization) + +Ӿм̳ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/29badd92-109f-4f29-abb9-9857f5973928.png) + + ʵֹϵ(realize) + +ӳ߽ӿм̳ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4b16e1d3-3a60-472c-9756-2f31b1c48abe.png) + +**1.2 Ͳ** + + ۺϹϵ(aggregation) + +ʾɲɣͲֲǿģ岻˲ֻǻڡ±ʾ B A ɣ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/34259bb8-ca3a-4872-8771-9e946782d9c3.png) + + + Ϲϵ(composition) + +;ۺϲͬͲǿģ岻˲Ҳˡ繫˾Ͳţ˾û˲žͲˡǹ˾ԱھۺϹϵˣΪ˾ûԱڡ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/7dda050d-ac35-4f47-9f51-18f18ed6fa9a.png) + +**1.3 ໥ϵ** + + ϵ(association) + +ʾ֮ͬйһ־̬ϵй̵״̬޹أʼͿȷҲ 1 1 1ԶֹϵʾѧѧУһֹϵһѧУкܶѧһѧֻһѧУһֶһĹϵпʼ֮ǰͿȷ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/4ccd294c-d6b2-421b-839e-d88336ff5fb7.png) + + ϵ(dependency) + +͹ϵͬ, ϵйõġһΪĹ߷IJ롣˫ʱһֲõơ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/47ca2614-509f-476e-98fc-50ec9f9d43c0.png) + + +## 2. ʱͼ + +**2.1 ** + +ʱͼ˶֮䴫Ϣʱ˳ʾΪ˳ҪͨĽעǶ󣩣ӶѰIJ + +**2.2 ֮սʱͼ** + +ߴ±ʾʱƽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/80c5aff8-fc46-4810-aeaa-215b5c60a003.png) + +ɼͨʱͼ֪ÿ² + +```java +publc class { + public void Ӧս(); +} + +publc class { + public void ⶨ(); + public void Ȩ(); + private void 趫(); +} + +public class { + public void G(); +} + +public class ŷ { + public void ؾǰ(); +} + +public class Ȩ { + public void (); +} +``` + +**2.3 ͼʱͼ֮Ĺϵ** + +ͼʾûĽǶ + +ʱͼǴӼĽǶȣĽ + +**2.4 ͼʱͼĹϵ** + +ͼϵͳľ̬ṹʱͼϵͳĶ̬Ϊ + +**2.5 ʱͼ** + + + +ֱʽ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/25b8adad-2ef6-4f30-9012-c306b4e49897.png) + +ڻͼʱӦѭԭ + +1. ѽƵĶ󾡿ܵؿ£ + +2. ѳʼĶʱһߣߡ + + + +ߴӶĴʼʱֹ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/b7b0eac6-e7ea-4fb6-8bfb-95fec6f235e2.png) + + Ϣ + +֮ĽʽͨϢʵֵġ + +Ϣ4ͣ + +1\. Ϣͬ첽 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/a13b62da-0fa8-4224-a615-4cadacc08871.png) + +2\. ͬϢϢ֮ҪͣȴӦ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/33821037-dc40-4266-901c-e5b38e618426.png) + +3\. 첽ϢϢ֮Ҫȴ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/dec6c6cc-1b5f-44ed-b8fd-464fcf849dac.png) + +4\. Ϣѡ + + + +ϵķʾ״̬ʱ䴦״̬ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/6ab5de9b-1c1e-4118-b2c3-fb6c7ed7de6f.png) + + +# ο + +- Java ˼ + +- [ƵSOLIDԭ](http://www.cnblogs.com/shanyou/archive/2009/09/21/1570716.html) + +- [UMLͼʱͼ](http://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html#generalization) + +- [UMLϵСʱͼ˳ͼsequence diagram](http://www.cnblogs.com/wolf-sun/p/UML-Sequence-diagram.html) + +- [------װ̳С̬](http://blog.csdn.net/jianyuerensheng/article/details/51602015)