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 = 3£¬K = 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' 字符进行填充的。 +ÓÉÓÚÁ½¸ö×Ö·û´®µÄ³¤¶È¿ÉÄܲ»ÏëµÈ£¬ÔÚ 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. °Ù¶È-×ï·¸×ªÒÆ -部分和问题,将æ¯�次求的部分和缓存起æ�¥ã€‚ +²¿·ÖºÍÎÊÌ⣬½«Ã¿´ÎÇóµÄ²¿·ÖºÍ»º´æÆðÀ´¡£ ```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»ù´¡ + +HTTP£¨HyperText Transfer Protocol£¬³¬Îª±¾´«ÊäЭÒ飩¡£ + +WWW£¨Word Wide Web£©µÄÈýÖÖ¼¼Êõ£ºHTML¡¢HTTP¡¢URL¡£ + +RFC£¨Request for Comments£¬Õ÷ÇóÐÞÕýÒâ¼ûÊ飩£¬»¥ÁªÍøµÄÉè¼ÆÎĵµ¡£ + +## URL + +URI£¨Uniform Resource Indentifier£¬Í³Ò»×ÊÔ´±êʶ·û£©£¬URL£¨Uniform Resource Locator£¬Í³Ò»×ÊÔ´¶¨Î»·û£©£¬URN£¨Uniform 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 Ö÷ҪĿµÄ²»ÊÇ»ñÈ¡×ÊÔ´£¬¶øÊÇ´«ÊäʵÌåÖ÷ÌåÊý¾Ý¡£ + +GET ºÍ POST µÄÇëÇó¶¼ÄÜʹÓöîÍâµÄ²ÎÊý£¬µ«ÊÇ GET µÄ²ÎÊýÊÇÒÔ²éѯ×Ö·û´®³öÏÖÔÚ URLÖУ¬¶ø POST µÄ²ÎÊý´æ´¢ÔÚʵÌåÖ÷Ì岿·Ö¡£ + +``` +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 ´«µÄ²ÎÊýÔÚ 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 ͨÐÅ¡£ + +Ö÷ҪʹÓà SSL£¨Secure Sokets Layer£¬°²È«Ì×½Ó×Ö£©ºÍ TLS£¨Transport 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 ЭÒ鹿¶¨ 301¡¢302 ״̬ÏÂÖØ¶¨Ïòʱ²»ÔÊÐí°Ñ POST ·½·¨¸Ä³É GET ·½·¨£¬µ«ÊÇ´ó¶àÊýä¯ÀÀÆ÷¶¼»á°Ñ 301¡¢302 ºÍ 303 ״̬ϵÄÖØ¶¨Ïò°Ñ POST ·½·¨¸Ä³É GET ·½·¨¡£ + +**304 Not Modified**£ºÈç¹ûÇëÇó±¨ÎÄÊײ¿°üº¬Ò»Ð©Ìõ¼þ£¬ÀýÈ磺If-Match£¬If-ModifiedSince£¬If-None-Match£¬If-Range£¬If-Unmodified-Since£¬µ«ÊDz»Âú×ãÌõ¼þ£¬Ôò·þÎñÆ÷»á·µ»Ø 304 ״̬Âë¡£ + +**307 Temporary Redirect**£ºÁÙÊ±ÖØ¶¨Ïò£¬Óë 302 µÄº¬ÒåÀàËÆ£¬µ«ÊÇ 307 ÒªÇóä¯ÀÀÆ÷²»»á°ÑÖØ¶¨ÏòÇëÇóµÄ POST ·½·¨¸Ä³É 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 ID¡£HTTP ¾ÍÊÇ 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£©Ö÷ÒªÊÇΪÁ˶ÔʵÌå½øÐÐѹËõ¡£³£ÓõıàÂëÓУºgzip¡¢compress¡¢deflate¡¢identity£¬ÆäÖÐ 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 ״̬¡£ + +## ÄÚÈÝЭÉÌ + +ͨ¹ýÄÚÈÝЭÉÌ·µ»Ø×îºÏÊʵÄÄÚÈÝ£¬ÀýÈç¸ù¾Ýä¯ÀÀÆ÷µÄĬÈÏÓïÑÔÑ¡Ôñ·µ»ØÖÐÎĽçÃæ»¹ÊÇÓ¢ÎĽçÃæ¡£ + +Éæ¼°ÒÔÏÂÊײ¿×ֶΣºAccept¡¢Accept-Charset¡¢Accept-Encoding¡¢Accept-Language¡¢Content-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 ÏÈºÍ SSL£¨Secure Socket Layer£©Í¨ÐÅ£¬ÔÙÓÉ SSL ºÍ TCP ͨÐÅ¡£Í¨¹ýʹÓà SSL£¬HTTPs ÌṩÁ˼ÓÃÜ¡¢ÈÏÖ¤ºÍÍêÕûÐÔ±£»¤¡£ + +## ¼ÓÃÜ + +ÓÐÁ½ÖÖ¼ÓÃÜ·½Ê½£º¶Ô³ÆÃÜÔ¿¼ÓÃܺ͹«¿ªÃÜÔ¿¼ÓÃÜ¡£¶Ô³ÆÃÜÔ¿¼ÓÃܵļÓÃܺͽâÃÜʹÓÃͬһÃÜÔ¿£¬¶ø¹«¿ªÃÜÔ¿¼ÓÃÜʹÓÃÒ»¶ÔÃÜÔ¿ÓÃÓÚ¼ÓÃܺͽâÃÜ£¬·Ö±ðΪ¹«¿ªÃÜÔ¿ºÍ˽ÓÐÃÜÔ¿¡£¹«¿ªÃÜÔ¿ËùÓÐÈ˶¼¿ÉÒÔ»ñµÃ£¬Í¨ÐÅ·¢ËÍ·½»ñµÃ½ÓÊÕ·½µÄ¹«¿ªÃÜÔ¿Ö®ºó£¬¾Í¿ÉÒÔʹÓù«¿ªÃÜÔ¿½øÐмÓÃÜ£¬½ÓÊÕ·½ÊÕµ½Í¨ÐÅÄÚÈݺóʹÓÃ˽ÓÐÃÜÔ¿½âÃÜ¡£ + +¶Ô³ÆÃÜÔ¿¼ÓÃܵÄȱµã£ºÎÞ·¨°²È«´«ÊäÃÜÔ¿£»¹«¿ªÃÜÔ¿¼ÓÃܵÄȱµã£ºÏà¶ÔÀ´Ëµ¸üºÄʱ¡£ + +HTTPs ²ÉÓà **»ìºÏµÄ¼ÓÃÜ»úÖÆ**£¬Ê¹Óù«¿ªÃÜÔ¿¼ÓÃÜÓÃÓÚ´«Êä¶Ô³ÆÃÜÔ¿£¬Ö®ºóʹÓöԳÆÃÜÔ¿¼ÓÃܽøÐÐͨÐÅ¡££¨ÏÂͼÖУ¬¹²ÏíÃÜÔ¿¼´¶Ô³ÆÃÜÔ¿£© + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/110b1a9b-87cd-45c3-a21d-824623715b33.jpg) + +## ÈÏÖ¤ + +ͨ¹ýʹÓà **Ö¤Êé** À´¶ÔͨÐÅ·½½øÐÐÈÏÖ¤¡£Ö¤ÊéÖÐÓй«¿ªÃÜÔ¿Êý¾Ý£¬Èç¹û¿ÉÒÔÑéÖ¤¹«¿ªÃÜÔ¿µÄÈ·ÊôÓÚͨÐÅ·½µÄ£¬ÄÇô¾Í¿ÉÒÔÈ·¶¨Í¨ÐÅ·½Êǿɿ¿µÄ¡£ + +Êý×ÖÖ¤ÊéÈÏÖ¤»ú¹¹£¨CA£¬Certificate +Authority£©°ä·¢µÄ¹«¿ªÃÜÔ¿Ö¤Ê飬¿ÉÒÔͨ¹ý CA ¶ÔÆä½øÐÐÑéÖ¤¡£ + +½øÐÐ HTTPs ͨÐÅʱ£¬·þÎñÆ÷»á°ÑÖ¤Êé·¢Ë͸ø¿Í»§¶Ë£¬¿Í»§¶ËÈ¡µÃÆäÖеĹ«¿ªÃÜÔ¿Ö®ºó£¬¾Í¿ÉÒÔ¿ªÊ¼¼ÓÃܹý³Ì¡£ + +ʹÓà OpenSSL ÕâÌ׿ªÔ´³ÌÐò£¬Ã¿¸öÈ˶¼¿ÉÒÔ¹¹½¨Ò»Ì×ÊôÓÚ×Ô¼ºµÄÈÏÖ¤»ú¹¹£¬´Ó¶ø×Ô¼º¸ø×Ô¼º°ä·¢·þÎñÆ÷Ö¤Êé¡£ä¯ÀÀÆ÷ÔÚ·ÃÎʸ÷þÎñÆ÷ʱ£¬»áÏÔʾ¡°ÎÞ·¨È·ÈÏÁ¬½Ó°²È«ÐÔ¡±»ò¡°¸ÃÍøÕ¾µÄ°²È«Ö¤Êé´æÔÚÎÊÌ⡱µÈ¾¯¸æÏûÏ¢¡£ + +¿Í»§¶ËÖ¤ÊéÐèÒªÓû§×ÔÐа²×°£¬Ö»ÓÐÔÚÒµÎñÐèÒª·Ç³£¸ß°²È«ÐÔʱ²ÅʹÓÿͻ§¶ËÖ¤Ê飬ÀýÈçÍøÉÏÒøÐС£ + +## ÍêÕûÐÔ + +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 ÈíÒýÓà + + +·Ç±ØÐëÒýÓã¬ÄÚ´æÒç³ö֮ǰ½øÐлØÊÕ¡£ + +```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 µÄ³¡¾°¶¼ÐèÒªÐéÄâ»ú¾ß±¸ÀàÐ¶ÔØ¹¦ÄÜ£¬ÒÔ±£Ö¤²»»á³öÏÖÄÚ´æÒç³ö¡£ + +### 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 ºÍ Survivor¡£HotSpot ÐéÄâ»úµÄ 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 ÓÃÓÚÔËÐÐÓû§´úÂëµÄʱ¼äÕ¼×Üʱ¼äµÄ±ÈÖµ¡£ + +Í£¶Ùʱ¼äÔ½¶Ì¾ÍÔ½ÊʺÏÐèÒªÓëÓû§½»»¥µÄ³ÌÐò£¬Á¼ºÃµÄÏìÓ¦ËÙ¶ÈÄÜÌáÉýÓû§ÌåÑé¡£¶ø¸ßÍÌÍÂÁ¿Ôò¿ÉÒÔ¸ßЧÂʵØÀûÓà CPU ʱ¼ä£¬¾¡¿ìÍê³É³ÌÐòµÄÔËËãÈÎÎñ£¬Ö÷ÒªÊʺÏÔÚºǫ́ÔËËã¶ø²»ÐèҪ̫¶à½»»¥µÄÈÎÎñ¡£ + +ÌṩÁËÁ½¸ö²ÎÊýÓÃÓÚ¾«È·¿ØÖÆÍÌÍÂÁ¿£¬·Ö±ðÊÇ¿ØÖÆ×î´óÀ¬»øÊÕ¼¯Í£¶Ùʱ¼ä -XX:MaxGCPauseMillis ²ÎÊýÒÔ¼°Ö±½ÓÉèÖÃÍÌÍÂÁ¿´óСµÄ -XX:GCTimeRatio ²ÎÊý£¨ÖµÎª´óÓÚ 0 ÇÒСÓÚ 100 µÄÕûÊý£©¡£Ëõ¶ÌÍ£¶Ùʱ¼äÊÇÒÔÎþÉüÍÌÍÂÁ¿ºÍÐÂÉú´ú¿Õ¼äÀ´»»È¡µÄ£ºÐÂÉú´ú¿Õ¼ä±äС£¬À¬»ø»ØÊÕ±äµÃƵ·±£¬µ¼ÖÂÍÌÍÂÁ¿Ï½µ¡£ + +»¹ÌṩÁËÒ»¸ö²ÎÊý -XX:+UseAdaptiveSizePolicy£¬ÕâÊÇÒ»¸ö¿ª¹Ø²ÎÊý£¬´ò¿ª²ÎÊýºó£¬¾Í²»ÐèÒªÊÖ¹¤Ö¸¶¨ÐÂÉú´úµÄ´óС£¨-Xmn£©¡¢Eden ºÍ 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 ×ÊÔ´Ãô¸ÐµÄ³¡ºÏ£¬¶¼¿ÉÒÔÓÅÏÈ¿¼ÂÇ Parallel Scavenge ¼Ó Parallel Old ÊÕ¼¯Æ÷¡£ + +### 3.6 CMS ÊÕ¼¯Æ÷ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg) + +CMS£¨Concurrent Mark Sweep£©£¬´Ó Mark Sweep ¿ÉÒÔÖªµÀËüÊÇ»ùÓÚ ±ê¼Ç - Çå³ý Ë㷨ʵÏֵġ£ + +ÌØµã£º²¢·¢ÊÕ¼¯¡¢µÍÍ£¶Ù¡£ + +·ÖΪÒÔÏÂËĸöÁ÷³Ì£º + +1. ³õʼ±ê¼Ç£º½ö½öÖ»ÊDZê¼ÇһϠGC Roots ÄÜÖ±½Ó¹ØÁªµ½µÄ¶ÔÏó£¬ËٶȺܿ죬ÐèҪͣ¶Ù¡£ +2. ²¢·¢±ê¼Ç£º½øÐÐ GC Roots Tracing µÄ¹ý³Ì£¬ËüÔÚÕû¸ö»ØÊÕ¹ý³ÌÖкÄʱ×£¬²»ÐèҪͣ¶Ù¡£ +3. ÖØÐ±ê¼Ç£ºÎªÁËÐÞÕý²¢·¢±ê¼ÇÆÚ¼äÒòÓû§³ÌÐò¼ÌÐøÔË×÷¶øµ¼Ö±ê¼Ç²úÉú±ä¶¯µÄÄÇÒ»²¿·Ö¶ÔÏóµÄ±ê¼Ç¼Ç¼£¬ÐèҪͣ¶Ù¡£ +4. ²¢·¢Çå³ý£º²»ÐèҪͣ¶Ù¡£ + +ÔÚÕû¸ö¹ý³ÌÖкÄʱ×µÄ²¢·¢±ê¼ÇºÍ²¢·¢Çå³ý¹ý³ÌÖУ¬ÊÕ¼¯Æ÷Ï̶߳¼¿ÉÒÔÓëÓû§Ïß³ÌÒ»Æð¹¤×÷£¬²»ÐèÒª½øÐÐÍ£¶Ù¡£ + +¾ßÓÐÒÔÏÂȱµã£º + +1. ¶Ô CPU ×ÊÔ´Ãô¸Ð¡£CMS ĬÈÏÆô¶¯µÄ»ØÊÕÏß³ÌÊýÊÇ (CPU ÊýÁ¿ + 3) / 4£¬µ± CPU ²»×ã 4 ¸öʱ£¬CMS ¶ÔÓû§³ÌÐòµÄÓ°Ïì¾Í¿ÉÄܱäµÃºÜ´ó£¬Èç¹û±¾À´ CPU ¸ºÔؾͱȽϴ󣬻¹Òª·Ö³öÒ»°ëµÄÔËËãÄÜÁ¦È¥Ö´ÐÐÊÕ¼¯Æ÷Ị̈߳¬¾Í¿ÉÄܵ¼ÖÂÓû§³ÌÐòµÄÖ´ÐÐËٶȺöÈ»½µµÍÁË 50%£¬ÆäʵҲÈÃÈËÎÞ·¨½ÓÊÜ¡£²¢ÇÒµÍÍ£¶Ùʱ¼äÊÇÒÔÎþÉüÍÌÍÂÁ¿Îª´ú¼ÛµÄ£¬µ¼Ö CPU ÀûÓÃÂʱäµÍ¡£ + +2. ÎÞ·¨´¦Àí¸¡¶¯À¬»ø¡£ÓÉÓÚ²¢·¢ÇåÀí½×¶ÎÓû§Ï̻߳¹ÔÚÔËÐÐ×Å£¬°éËæ³ÌÐòÔËÐÐ×ÔÈ»¾Í»¹»áÓÐеÄÀ¬»ø²»¶Ï²úÉú¡£ÕâÒ»²¿·ÖÀ¬»ø³öÏÖÔÚ±ê¼Ç¹ý³ÌÖ®ºó£¬CMS ÎÞ·¨ÔÚµ±´ÎÊÕ¼¯Öд¦ÀíµôËüÃÇ£¬Ö»ºÃÁôµ½ÏÂÒ»´Î GC ʱÔÙÇåÀíµô£¬ÕâÒ»²¿·ÖÀ¬»ø¾Í±»³ÆÎª¡°¸¡¶¯À¬»ø¡±¡£Ò²ÊÇÓÉÓÚÔÚÀ¬»øÊÕ¼¯½×¶ÎÓû§Ï̻߳¹ÐèÒªÔËÐУ¬ÄÇÒ²¾Í»¹ÐèÒªÔ¤ÁôÓÐ×ã¹»µÄÄÚ´æ¿Õ¼ä¸øÓû§Ïß³ÌʹÓã¬Òò´ËËü²»ÄÜÏñÆäËûÊÕ¼¯Æ÷ÄÇÑùµÈµ½ÀÏÄê´ú¼¸ºõÍêÈ«±»ÌîÂúÁËÔÙ½øÐÐÊÕ¼¯£¬ÐèÒªÔ¤ÁôÒ»²¿·Ö¿Õ¼äÌṩ²¢·¢ÊÕ¼¯Ê±µÄ³ÌÐòÔË×÷ʹÓ᣿ÉÒÔʹÓà -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) + +G1£¨Garbage-First£©ÊÕ¼¯Æ÷Êǵ±½ñÊÕ¼¯Æ÷¼¼Êõ·¢Õ¹×îÇ°ÑØµÄ³É¹ûÖ®Ò»£¬ËüÊÇÒ»¿îÃæÏò·þÎñ¶ËÓ¦ÓõÄÀ¬»øÊÕ¼¯Æ÷£¬HotSpot ¿ª·¢ÍŶӸ³ÓèËüµÄʹÃüÊÇ£¨ÔڱȽϳ¤ÆÚµÄ£©Î´À´¿ÉÒÔÌæ»»µô JDK 1.5 Öз¢²¼µÄ CMS ÊÕ¼¯Æ÷¡£ + +¾ß±¸ÈçÏÂÌØµã£º + +- ²¢ÐÐÓë²¢·¢£ºÄܳä·ÖÀûÓöà CPU »·¾³ÏµÄÓ²¼þÓÅÊÆ£¬Ê¹Óöà¸ö CPU À´Ëõ¶ÌÍ£¶Ùʱ¼ä£» +- ·Ö´úÊÕ¼¯£º·Ö´ú¸ÅÄîÒÀÈ»µÃÒÔ±£Áô£¬ËäÈ»Ëü²»ÐèÒªÆäËüÊÕ¼¯Æ÷ÅäºÏ¾ÍÄܶÀÁ¢¹ÜÀíÕû¸ö GC ¶Ñ£¬µ«ËüÄܹ»²ÉÓò»Í¬·½Ê½È¥´¦Àíд´½¨µÄ¶ÔÏóºÍÒÑ´æ»îÒ»¶Îʱ¼ä¡¢°¾¹ý¶à´Î GC µÄ¾É¶ÔÏóÀ´»ñÈ¡¸üºÃµÄÊÕ¼¯Ð§¹û¡£ +- ¿Õ¼äÕûºÏ£ºÕûÌåÀ´¿´ÊÇ»ùÓÚ¡°±ê¼Ç - ÕûÀí¡±Ë㷨ʵÏÖµÄÊÕ¼¯Æ÷£¬´Ó¾Ö²¿£¨Á½¸ö Region Ö®¼ä£©ÉÏÀ´¿´ÊÇ»ùÓÚ¡°¸´ÖÆ¡±Ë㷨ʵÏֵģ¬ÕâÒâζ×ÅÔËÐÐÆÚ¼ä²»»á²úÉúÄÚ´æ¿Õ¼äË鯬¡£ +- ¿ÉÔ¤²âµÄÍ£¶Ù£ºÕâÊÇËüÏà¶Ô CMS µÄÒ»´óÓÅÊÆ£¬½µµÍÍ£¶Ùʱ¼äÊÇ G1 ºÍ CMS ¹²Í¬µÄ¹Ø×¢µã£¬µ« G1 ³ýÁ˽µµÍÍ£¶ÙÍ⣬»¹Äܽ¨Á¢¿ÉÔ¤²âµÄÍ£¶Ùʱ¼äÄ£ÐÍ£¬ÄÜÈÃʹÓÃÕßÃ÷È·Ö¸¶¨ÔÚÒ»¸ö³¤¶ÈΪ M ºÁÃëµÄʱ¼äƬ¶ÎÄÚ£¬ÏûºÄÔÚ GC ÉϵÄʱ¼ä²»µÃ³¬¹ý N ºÁÃ룬Õ⼸ºõÒѾ­ÊÇʵʱ Java£¨RTSJ£©µÄÀ¬»øÊÕ¼¯Æ÷µÄÌØÕ÷ÁË¡£ + +ÔÚ 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 µÄ²Ù×÷£¬G1 ÊÕ¼¯Æ÷µÄÔË×÷´óÖ¿ɻ®·ÖΪÒÔϼ¸¸ö²½Ö裺 + +1. ³õʼ±ê¼Ç +2. ²¢·¢±ê¼Ç +3. ×îÖÕ±ê¼Ç£ºÎªÁËÐÞÕýÔÚ²¢·¢±ê¼ÇÆÚ¼äÒòÓû§³ÌÐò¼ÌÐøÔË×÷¶øµ¼Ö±ê¼Ç²úÉú±ä¶¯µÄÄÇÒ»²¿·Ö±ê¼Ç¼Ç¼£¬ÐéÄâ»ú½«Õâ¶Îʱ¼ä¶ÔÏó±ä»¯¼Ç¼ÔÚÏß³ÌµÄ 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£¬Æä´¥·¢Ìõ¼þ·Ç³£¼òµ¥£¬µ± 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 ÀÏÄê´ú¿Õ¼ä²»×ã + +ÀÏÄê´ú¿Õ¼ä²»×ãµÄ³£¼û³¡¾°ÎªÇ°ÎÄËù½²µÄ´ó¶ÔÏóÖ±½Ó½øÈëÀÏÄê´ú¡¢³¤ÆÚ´æ»îµÄ¶ÔÏó½øÈëÀÏÄê´úµÈ£¬µ±Ö´ÐÐ 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. Óöµ½ new¡¢getstatic¡¢putstatic¡¢invokestatic ÕâËÄÌõ×Ö½ÚÂëÖ¸Áîʱ£¬Èç¹ûÀàûÓнøÐйý³õʼ»¯£¬Ôò±ØÐëÏÈ´¥·¢Æä³õʼ»¯¡£×î³£¼ûµÄÉú³ÉÕâ 4 ÌõÖ¸ÁîµÄ³¡¾°ÊÇ£ºÊ¹Óà new ¹Ø¼ü×ÖʵÀý»¯¶ÔÏóµÄʱºò£»¶ÁÈ¡»òÉèÖÃÒ»¸öÀàµÄ¾²Ì¬×ֶΣ¨±» final ÐÞÊΡ¢ÒÑÔÚ±àÒëÆ÷°Ñ½á¹û·ÅÈë³£Á¿³ØµÄ¾²Ì¬×ֶγýÍ⣩µÄʱºò£»ÒÔ¼°µ÷ÓÃÒ»¸öÀàµÄ¾²Ì¬·½·¨µÄʱºò¡£ + +2. ʹÓà java.lang.reflect °üµÄ·½·¨¶ÔÀà½øÐз´Éäµ÷ÓõÄʱºò£¬Èç¹ûÀàûÓнøÐгõʼ»¯£¬ÔòÐèÒªÏÈ´¥·¢Æä³õʼ»¯¡£ + +3. µ±³õʼ»¯Ò»¸öÀàµÄʱºò£¬Èç¹û·¢Ï֯䏏À໹ûÓнøÐйý³õʼ»¯£¬ÔòÐèÒªÏÈ´¥·¢Æä¸¸ÀàµÄ³õʼ»¯¡£ + +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\. ͨ¹ýÊý×鶨ÒåÀ´ÒýÓÃÀ࣬²»»á´¥·¢´ËÀàµÄ³õʼ»¯¡£¸Ã¹ý³Ì»á¶ÔÊý×éÀà½øÐгõʼ»¯£¬Êý×éÀàÊÇÒ»¸öÓÉÐéÄâ»ú×Ô¶¯Éú³ÉµÄ¡¢Ö±½Ó¼Ì³Ð×Ô Object µÄ×ÓÀ࣬ÆäÖаüº¬ÁËÊý×éµÄÊôÐԺͷ½·¨¡£ + +```java +SuperClass[] sca = new SuperClass[10]; +``` + +3\. ³£Á¿ÔÚ±àÒë½×¶Î»á´æÈëµ÷ÓÃÀàµÄ³£Á¿³ØÖУ¬±¾ÖÊÉϲ¢Ã»ÓÐÖ±½ÓÒýÓõ½¶¨Òå³£Á¿µÄÀ࣬Òò´Ë²»»á´¥·¢¶¨Òå³£Á¿µÄÀàµÄ³õʼ»¯¡£ + +```java +System.out.println(ConstClass.HELLOWORLD); +``` + +## 3. Àà¼ÓÔØ¹ý³Ì + +°üº¬Á˼ÓÔØ¡¢ÑéÖ¤¡¢×¼±¸¡¢½âÎöºÍ³õʼ»¯Õâ 5 ¸ö½×¶Î¡£ + +### 3.1 ¼ÓÔØ + +¼ÓÔØÊÇÀà¼ÓÔØµÄÒ»¸ö½×¶Î£¬×¢Òâ²»Òª»ìÏý¡£ + +¼ÓÔØ¹ý³ÌÍê³ÉÒÔÏÂÈý¼þÊ£º + +1. ͨ¹ýÒ»¸öÀàµÄÈ«ÏÞ¶¨ÃûÀ´»ñÈ¡¶¨Òå´ËÀàµÄ¶þ½øÖÆ×Ö½ÚÁ÷¡£ +2. ½«Õâ¸ö×Ö½ÚÁ÷Ëù´ú±íµÄ¾²Ì¬´æ´¢½á¹¹×ª»¯Îª·½·¨ÇøµÄÔËÐÐʱ´æ´¢½á¹¹¡£ +3. ÔÚÄÚ´æÖÐÉú³ÉÒ»¸ö´ú±íÕâ¸öÀàµÄ Class ¶ÔÏó£¬×÷Ϊ·½·¨ÇøÕâ¸öÀàµÄ¸÷ÖÖÊý¾ÝµÄ·ÃÎÊÈë¿Ú¡£ + +ÆäÖжþ½øÖÆ×Ö½ÚÁ÷¿ÉÒÔ´ÓÒÔÏ·½Ê½ÖлñÈ¡£º + +- ´Ó ZIP °ü¶ÁÈ¡£¬ÕâºÜ³£¼û£¬×îÖÕ³ÉΪÈÕºó JAR¡¢EAR¡¢WAR ¸ñʽµÄ»ù´¡¡£ +- ´ÓÍøÂçÖлñÈ¡£¬ÕâÖÖ³¡¾°×îµäÐ͵ÄÓ¦ÓÃÊÇ 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>() ·½·¨µÄ¹ý³Ì¡£ + +ÔÚ×¼±¸½×¶Î£¬Àà±äÁ¿ÒѾ­¸³¹ýÒ»´ÎϵͳҪÇóµÄ³õʼֵ£¬¶øÔÚ³õʼ»¯½×¶Î£¬¸ù¾Ý³ÌÐòԱͨ¹ý³ÌÐòÖÆ¶¨µÄÖ÷¹Û¼Æ»®È¥³õʼ»¯Àà±äÁ¿ºÍÆäËü×ÊÔ´¡£ + +<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>() ·½·¨ÖÐÓкÄʱµÄ²Ù×÷£¬¾Í¿ÉÄÜÔì³É¶à¸ö½ø³Ì×èÈû£¬ÔÚʵ¼Ê¹ý³ÌÖдËÖÖ×èÈûºÜÒþ±Î¡£ + +## 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£© Õâ¸öÀà¼ÓÔØÆ÷ÊÇÓÉ ExtClassLoader£¨sun.misc.Launcher$ExtClassLoader£©ÊµÏֵġ£Ëü¸ºÔ𽫠/lib/ext »òÕß±» java.ext.dir ϵͳ±äÁ¿ËùÖ¸¶¨Â·¾¶ÖеÄËùÓÐÀà¿â¼ÓÔØµ½ÄÚ´æÖУ¬¿ª·¢Õß¿ÉÒÔÖ±½ÓʹÓÃÀ©Õ¹Àà¼ÓÔØÆ÷¡£ + +- Ó¦ÓóÌÐòÀà¼ÓÔØÆ÷£¨Application ClassLoader£© Õâ¸öÀà¼ÓÔØÆ÷ÊÇÓÉ AppClassLoader£¨sun.misc.Launcher$AppClassLoader£©ÊµÏֵġ£ÓÉÓÚÕâ¸öÀà¼ÓÔØÆ÷ÊÇ ClassLoader ÖÐµÄ getSystemClassLoader() ·½·¨µÄ·µ»ØÖµ£¬Òò´ËÒ»°ã³ÆÎªÏµÍ³Àà¼ÓÔØÆ÷¡£Ëü¸ºÔð¼ÓÔØÓû§Àà·¾¶£¨ClassPath£©ÉÏËùÖ¸¶¨µÄÀà¿â£¬¿ª·¢Õß¿ÉÒÔÖ±½ÓʹÓÃÕâ¸öÀà¼ÓÔØÆ÷£¬Èç¹ûÓ¦ÓóÌÐòÖÐûÓÐ×Ô¶¨Òå¹ý×Ô¼ºµÄÀà¼ÓÔØÆ÷£¬Ò»°ãÇé¿öÏÂÕâ¸ö¾ÍÊdzÌÐòÖÐĬÈϵÄÀà¼ÓÔØÆ÷¡£ + +### 4.3 Ë«Ç×ίÅÉÄ£ÐÍ + +Ó¦ÓóÌÐò¶¼ÊÇÓÉÈýÖÖÀà¼ÓÔØÆ÷Ï໥ÅäºÏ½øÐмÓÔØµÄ£¬Èç¹ûÓбØÒª£¬»¹¿ÉÒÔ¼ÓÈë×Ô¼º¶¨ÒåµÄÀà¼ÓÔØÆ÷¡£ÏÂͼչʾµÄÀà¼ÓÔØÆ÷Ö®¼äµÄ²ã´Î¹ØÏµ£¬³ÆÎªÀà¼ÓÔØÆ÷µÄË«Ç×ίÅÉÄ£ÐÍ£¨Parents Delegation Model£©¡£¸ÃÄ£ÐÍÒªÇó³ýÁ˶¥²ãµÄÆô¶¯Àà¼ÓÔØÆ÷Í⣬ÆäÓàµÄÀà¼ÓÔØÆ÷¶¼Ó¦ÓÐ×Ô¼ºµÄ¸¸Àà¼ÓÔØÆ÷£¬ÕâÀïÀà¼ÓÔØÆ÷Ö®¼äµÄ¸¸×Ó¹ØÏµÒ»°ãͨ¹ý×éºÏ£¨Composition£©¹ØÏµÀ´ÊµÏÖ£¬¶ø²»ÊÇͨ¹ý¼Ì³Ð£¨Inheritance£©µÄ¹ØÏµÊµÏÖ¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/2cdc3ce2-fa82-4c22-baaa-000c07d10473.jpg) + +**¹¤×÷¹ý³Ì** + +Èç¹ûÒ»¸öÀà¼ÓÔØÆ÷ÊÕµ½ÁËÀà¼ÓÔØµÄÇëÇó£¬ËüÊ×ÏȲ»»á×Ô¼ºÈ¥³¢ÊÔ¼ÓÔØ£¬¶øÊǰÑÕâ¸öÇëÇóίÅɸø¸¸Àà¼ÓÔØÆ÷£¬Ã¿Ò»¸ö²ã´ÎµÄ¼ÓÔØÆ÷¶¼ÊÇÈç´Ë£¬ÒÀ´ÎµÝ¹é£¬Òò´ËËùÓеļÓÔØÇëÇó×îÖÕ¶¼Ó¦¸Ã´«Ë͵½¶¥²ãµÄÆô¶¯Àà¼ÓÔØÆ÷ÖУ¬Ö»Óе±¸¸¼ÓÔØÆ÷·´À¡×Ô¼ºÎÞ·¨Íê³É´Ë¼ÓÔØÇëÇó£¨ËüËÑË÷·¶Î§ÖÐûÓÐÕÒµ½ËùÐèÀࣩʱ£¬×Ó¼ÓÔØÆ÷²Å»á³¢ÊÔ×Ô¼º¼ÓÔØ¡£ + +**ºÃ´¦** + +ʹÓÃË«Ç×ίÅÉÄ£ÐÍÀ´×éÖ¯Àà¼ÓÔØÆ÷Ö®¼äµÄ¹ØÏµ£¬Ê¹µÃ Java ÀàËæ×ÅËüµÄÀà¼ÓÔØÆ÷Ò»Æð¾ß±¸ÁËÒ»ÖÖ´øÓÐÓÅÏȼ¶µÄ²ã´Î¹ØÏµ¡£ÀýÈçÀà 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. ·Ç×èÈûʽ IO£ºNIO + +# ´ÅÅ̲Ù×÷ + +File Àà¿ÉÒÔÓÃÓÚ±íʾÎļþºÍĿ¼£¬µ«ÊÇËüÖ»ÓÃÓÚ±íʾÎļþµÄÐÅÏ¢£¬¶ø²»±íʾÎļþµÄÄÚÈÝ¡£ + +# ×Ö½Ú²Ù×÷ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/8143787f-12eb-46ea-9bc3-c66d22d35285.jpg) + +Java I/O ʹÓÃÁË×°ÊÎÕßģʽÀ´ÊµÏÖ¡£ÒÔ InputStream ΪÀý£¬InputStream ÊdzéÏó×é¼þ£¬FileInputStream ÊÇ InputStream µÄ×ÓÀ࣬ÊôÓÚ¾ßÌå×é¼þ£¬ÌṩÁË×Ö½ÚÁ÷µÄÊäÈë²Ù×÷¡£FilterInputStream ÊôÓÚ³éÏó×°ÊÎÕߣ¬×°ÊÎÕßÓÃÓÚ×°ÊÎ×é¼þ£¬Îª×é¼þÌṩ¶îÍâµÄ¹¦ÄÜ£¬ÀýÈç BufferedInputStream Ϊ FileInputStream Ìṩ»º´æµÄ¹¦ÄÜ¡£ÊµÀý»¯Ò»¸ö¾ßÓлº´æ¹¦ÄܵÄ×Ö½ÚÁ÷¶ÔÏóʱ£¬Ö»ÐèÒªÔÚ FileInputStream ¶ÔÏóÉÏÔÙÌ×Ò»²ã BufferedInputStream ¶ÔÏó¼´¿É¡£ + +```java +BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); +``` + +DataInputStream ×°ÊÎÕßÌṩÁ˶Ըü¶àÊý¾ÝÀàÐͽøÐÐÊäÈëµÄ²Ù×÷£¬±ÈÈç int¡¢double µÈ»ù±¾ÀàÐÍ¡£ + +ÅúÁ¿¶ÁÈëÎļþÖеÄÄÚÈݵ½×Ö½ÚÊý×éÖÐ + +```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 Ò»´ÎÒ»¸ö×Ö½Ú½øÐд¦ÀíÊý¾Ý£¬Ò»¸öÊäÈëÁ÷²úÉúÒ»¸ö×Ö½ÚµÄÊý¾Ý£¬Ò»¸öÊä³öÁ÷Ïû·ÑÒ»¸ö×Ö½ÚµÄÊý¾Ý¡£ÎªÁ÷ʽÊý¾Ý´´½¨¹ýÂËÆ÷·Ç³£ÈÝÒ×£¬Á´½Ó¼¸¸ö¹ýÂËÆ÷£¬ÒÔ±ãÿ¸ö¹ýÂËÆ÷Ö»¸ºÔ𵥸ö¸´ÔÓ´¦Àí»úÖÆµÄÒ»²¿·Ö£¬ÕâÑùÒ²ÊÇÏà¶Ô¼òµ¥µÄ¡£²»ÀûµÄÒ»ÃæÊÇ£¬ÃæÏòÁ÷µÄ I/O ͨ³£Ï൱Âý¡£ + +Ò»¸öÃæÏò¿éµÄ I/O ϵͳÒÔ¿éµÄÐÎʽ´¦ÀíÊý¾Ý£¬Ã¿Ò»¸ö²Ù×÷¶¼ÔÚÒ»²½ÖвúÉú»òÕßÏû·ÑÒ»¸öÊý¾Ý¿é¡£°´¿é´¦ÀíÊý¾Ý±È°´Á÷´¦ÀíÊý¾ÝÒª¿ìµÃ¶à¡£µ«ÊÇÃæÏò¿éµÄ I/O ȱÉÙÒ»Ð©ÃæÏòÁ÷µÄ I/O Ëù¾ßÓеÄÓÅÑÅÐԺͼòµ¥ÐÔ¡£ + +I/O °üºÍ NIO ÒѾ­ºÜºÃµØ¼¯³ÉÁË£¬java.io.\* ÒѾ­ÒÔ NIO Ϊ»ù´¡ÖØÐÂʵÏÖÁË£¬ËùÒÔÏÖÔÚËü¿ÉÒÔÀûÓà NIO µÄÒ»Ð©ÌØÐÔ¡£ÀýÈ磬 java.io.\* °üÖеÄһЩÀà°üº¬ÒÔ¿éµÄÐÎʽ¶ÁдÊý¾ÝµÄ·½·¨£¬ÕâʹµÃ¼´Ê¹ÔÚ¸üÃæÏòÁ÷µÄϵͳÖУ¬´¦ÀíËÙ¶ÈÒ²»á¸ü¿ì¡£ + +## 2. ͨµÀÓ뻺³åÇø + +### 2.1 ͨµÀ + +ͨµÀ Channel ÊǶÔÔ­ I/O °üÖеÄÁ÷µÄÄ£Ä⣬¿ÉÒÔͨ¹ýËü¶ÁÈ¡ºÍдÈëÊý¾Ý¡£ + +ͨµÀÓëÁ÷µÄ²»Í¬Ö®´¦ÔÚÓÚ£¬Á÷Ö»ÄÜÔÚÒ»¸ö·½ÏòÉÏÒÆ¶¯£¬(Ò»¸öÁ÷±ØÐëÊÇ 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 == 9¡£capacity ±äÁ¿²»»á¸Ä±ä£¬ÏÂÃæµÄÌÖÂÛ»áºöÂÔËü¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png) + +2\. ´ÓÊäÈëͨµÀÖжÁÈ¡ 3 ¸ö×Ö½ÚÊý¾ÝдÈ뻺³åÇøÖУ¬´Ëʱ position ÒÆ¶¯ÉèΪ 3£¬limit ±£³Ö²»±ä¡£ + +![](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 ÉϵÄÕâ¸ö×¢²á¡£µ±Ä³¸ö 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àÒëʱ³£Á¿£¬Ò²¿ÉÒÔÊÇÔÚÔËÐÐʱ±»³õʼ»¯ºó²»Äܱ»¸Ä±äµÄ³£Á¿¡£ + +¶ÔÓÚ»ù±¾ÀàÐÍ£¬final ʹÊýÖµ²»±ä£»¶ÔÓÚÒýÓöÔÏó£¬final ʹÒýÓò»±ä£¬Ò²¾Í²»ÄÜÒýÓÃÆäËü¶ÔÏ󣬵«ÊDZ»ÒýÓõĶÔÏó±¾ÉíÊÇ¿ÉÒÔÐ޸ĵġ£ + +**final ·½·¨** + +ÉùÃ÷·½·¨²»Äܱ»×ÓÀา¸Ç¡£ + +private ·½·¨ÒþʽµØ±»Ö¸¶¨Îª final£¬Èç¹ûÔÚ×ÓÀàÖж¨ÒåµÄ·½·¨ºÍ»ùÀàÖеÄÒ»¸ö private ·½·¨Ç©ÃûÏàͬ£¬´Ëʱ×ÓÀàµÄ·½·¨²»ÊǸ²¸Ç»ùÀà·½·¨£¬¶øÊÇÖØÔØÁË¡£ + +**final Àà** + +ÉùÃ÷À಻ÔÊÐí±»¼Ì³Ð¡£ + +## ³õʼ»¯Ë³Ðò + +static ÉùÃ÷µÄ¾²Ì¬Êý¾ÝÔÚÄÚ´æÖÐÖ»´æÔÚÒ»·Ý£¬Ö»ÔÚÀàµÚÒ»´ÎʵÀý»¯Ê±³õʼ»¯Ò»´Î£¬ÓÅÏÈÓÚÆäËüÊý¾ÝµÄ³õʼ»¯¡£ + +```java +public static String staticField = "¾²Ì¬±äÁ¿"; +``` + +static Óï¾ä¿éºÍ static Êý¾ÝÒ»ÑùÔÚÀàµÚÒ»´ÎʵÀý»¯Ê±ÔËÐÐÒ»´Î£¬¾ßÌåÄĸöÏÈÔËÐÐÈ¡¾öÓÚËüÃÇÔÚ´úÂëÖеÄ˳Ðò¡£ + +```java +static { + System.out.println("¾²Ì¬³õʼ»¯¿é"); +} +``` + +ÆÕͨÊý¾ÝºÍÆÕͨÓï¾ä¿éµÄ³õʼ»¯ÔÚ¾²Ì¬Êý¾ÝºÍ¾²Ì¬Óï¾ä¿é³õʼ»¯½áÊøÖ®ºó¡£ + +```java +public String field = "±äÁ¿"; +``` + +```java +{ + System.out.println("³õʼ»¯¿é"); +} +``` + +×îºó²ÅÊǹ¹Ô캯ÊýÖеÄÊý¾Ý½øÐгõʼ»¯ + +```java +public InitialOrderTest() +{ + System.out.println("¹¹ÔìÆ÷"); +} +``` + +´æÔڼ̳еÄÇé¿öÏ£¬³õʼ»¯Ë³ÐòΪ£º + +1. ¸¸Àࣨ¾²Ì¬Êý¾Ý¡¢¾²Ì¬Óï¾ä¿é£© +2. ×ÓÀࣨ¾²Ì¬Êý¾Ý¡¢¾²Ì¬Óï¾ä¿é£© +3. ¸¸ÀࣨÊý¾Ý¡¢Óï¾ä¿é£© +4. ¸¸Àࣨ¹¹ÔìÆ÷£© +5. ×ÓÀࣨÊý¾Ý¡¢Óï¾ä¿é£© +6. ×ÓÀࣨ¹¹ÔìÆ÷£© + +## ·ÃÎÊȨÏÞ + +Java ÖÐÓÐÈý¸ö·ÃÎÊȨÏÞÐÞÊηû£ºprivate¡¢protected ÒÔ¼° public£¬Èç¹û²»¼Ó·ÃÎÊÐÞÊηû£¬±íʾ°ü¼¶¿É¼û¡£ + +¿ÉÒÔ¶ÔÀà»òÀàÖеijÉÔ±£¨×Ö¶ÎÒÔ¼°·½·¨£©¼ÓÉÏ·ÃÎÊÐÞÊηû¡£³ÉÔ±¿É¼û±íʾÆäËüÀà¿ÉÒÔÓóÉÔ±ËùÔÚÀàµÄ¶ÔÏó·ÃÎʵ½¸Ã³ÉÔ±£»Àà¿É¼û±íʾÆäËüÀà¿ÉÒÔÓÃÕâ¸öÀà´´½¨¶ÔÏ󣬿ÉÒÔ°ÑÀ൱×ö°üÖеÄÒ»¸ö³ÉÔ±£¬È»ºó°ü±íʾһ¸öÀ࣬ÕâÑù¾ÍºÃÀí½âÁË¡£ + +protected ÓÃÓÚÐÞÊγÉÔ±£¬±íʾÔڼ̳ÐÌåϵÖгÉÔ±¶ÔÓÚ×ÓÀà¿É¼û¡£µ«ÊÇÕâ¸ö·ÃÎÊÐÞÊηû¶ÔÓÚÀàûÓÐÒâÒ壬ÒòΪ°üûÓм̳ÐÌåϵ¡£ + +# ÈÝÆ÷ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/114c49a6-72e3-4264-ae07-c564127094ac.png) + +ÈÝÆ÷Ö÷Òª°üÀ¨ Collection ºÍ Map Á½ÖÖ£¬Collection ÓÖ°üº¬ÁË List¡¢Set ÒÔ¼° Queue¡£ + +## Set + +- HashSet£ºÊ¹Óà Hash ʵÏÖ£¬Ö§³Ö¿ìËÙ²éÕÒ£¬µ«ÊÇʧȥÓÐÐòÐÔ£» + +- TreeSet£ºÊ¹ÓÃÊ÷ʵÏÖ£¬±£³ÖÓÐÐò£¬µ«ÊDzéÕÒЧÂʲ»Èç HashSet£» + +- LinkedListHashSet£º¾ßÓÐ HashSet µÄ²éÕÒЧÂÊ£¬ÇÒÄÚ²¿Ê¹ÓÃÁ´±íά»¤ÔªËص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 = 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£¬´Ëʱѭ»·Í˳ö£¬Ö±½Ó°Ñ²éÕÒµÄÊýÌø¹ýÁË¡£ -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 ³ö·¢£¬±éÀúµ½ 6¡¢2¡¢1 ºÍ 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 度对角线标记数组。 +Ò»ÐÐÒ»Ðеذڷţ¬ÔÚÈ·¶¨Ò»ÐÐÖеÄÄǸö»ÊºóÓ¦¸Ã°ÚÔÚÄÄÒ»ÁÐʱ£¬ÐèÒªÓÃÈý¸ö±ê¼ÇÊý×éÀ´È·¶¨Ä³Ò»ÁÐÊÇ·ñºÏ·¨£¬ÕâÈý¸ö±ê¼ÇÊý×é·Ö±ðΪ£ºÁбê¼ÇÊý×é¡¢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}£¬ÆäÖÐ i1¡¢i2 ... 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 µÄÐòÁÐ S2£¬dp[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±³°üÎÊÌâÔÚʵÏÖÉÏΨһµÄ²»Í¬ÊÇ£¬µÚ¶þ²ãÑ­»·ÊÇ´Ó 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] Ϊ½áβµÄ×ÓÊý×é²»Äܰüº¬Ç°ÃæµÄÄÚÈÝ£¬ÒòΪ¼ÓÉÏÇ°ÃæµÄ²¿·Ö£¬ÄÇôºÍÒ»¶¨»á±È 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 \* … +ÿһ¸öÊý¶¼¿ÉÒÔ·Ö½â³ÉËØÊýµÄ³Ë»ý£¬ÀýÈç 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 Õû³ý y£¨y mod x == 0£©£¬Ôò¶ÔÓÚËùÓÐ i£¬mi <= 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) { } ``` -最大公å€�数为两数的乘积除以最大公约数。 +×î´ó¹«±¶ÊýΪÁ½ÊýµÄ³Ë»ý³ýÒÔ×î´ó¹«Ô¼Êý¡£ ```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 µÄ±¶Êý¹±Ï×Ò»¸ö 5£¬N/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£¬»òÕßÓÐ majority£¬µ«ÊdzöÏֵĴÎÊýÉÙÓÚ 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/) -题目æ��述:给定一个数组,创建一个新数组,新数组的æ¯�个元素为原始数组中除了该ä½�置上的元素之外所有元素的乘积。 +ÌâÄ¿ÃèÊö£º¸ø¶¨Ò»¸öÊý×飬´´½¨Ò»¸öÐÂÊý×飬ÐÂÊý×éµÄÿ¸öÔªËØÎªÔ­Ê¼Êý×éÖгýÁ˸ÃλÖÃÉϵÄÔªËØÖ®ÍâËùÓÐÔªËØµÄ³Ë»ý¡£ -题目è¦�求:时间å¤�æ�‚度为 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/) -使用栈æ�¥å­˜å‚¨è¿˜æœªè®¡ç®—的元素。å�¯ä»¥ä¿�è¯�从栈顶å�‘下元素递增,å�¦åˆ™ä¸Šé�¢æœ‰ä¸€ä¸ªæ¯”下é�¢æŸ�个元素大的元素进入栈中,下é�¢é‚£ä¸ªå…ƒç´ å·²ç»�找到比它大的元素,因此会出栈。 +ʹÓÃÕ»À´´æ´¢»¹Î´¼ÆËãµÄÔªËØ¡£¿ÉÒÔ±£Ö¤´ÓÕ»¶¥ÏòÏÂÔªËØµÝÔö£¬·ñÔòÉÏÃæÓÐÒ»¸ö±ÈÏÂÃæÄ³¸öÔªËØ´óµÄÔªËØ½øÈëÕ»ÖУ¬ÏÂÃæÄǸöÔªËØÒѾ­ÕÒµ½±ÈËü´óµÄÔªËØ£¬Òò´Ë»á³öÕ»¡£ ```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 µÄ²¼¶ûÊý×éÀ´´æ´¢Ò»¸ö×Ö·û¼¯ºÏ£¬Ê¹µÃ¿Õ¼ä¸´ÔӶȽµµÍΪ 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 µÄ³¤¶ÈΪ a + c£¬B µÄ³¤¶ÈΪ 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; // ºóÃæµÄ²Ù×÷»á¸Ä±ä 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) { // Ä£ÄâµÝ¹éÕ»µÄ²»¶ÏÉîÈë 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 Óë mask£º00111100 ½øÐÐλ»ò²Ù×÷£¬½« 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 µÄ mask£¬1<<(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 = a£¬a ^ 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) { } ``` -**求一个数的补ç �** +**ÇóÒ»¸öÊýµÄ²¹Âë** [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. ÅÅÐòÃüÁsort¡¢uniq](#2-ÅÅÐòÃüÁîsortuniq) + * [3. Ë«ÏòÊä³öÖØ¶¨Ïò£ºtee](#3-Ë«ÏòÊä³öÖØ¶¨Ïòtee) + * [4. ×Ö·ûת»»Ö¸Átr¡¢col¡¢expand¡¢join¡¢paste](#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. ÆäËü¹Ø»úÖ¸Áî** + +reboot¡¢halt¡¢poweroff¡£ + +## ²é¿´½ø³Ì + +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] + +ÆäÖÐÎļþÃûºóÃæµÄÐòºÅµÄÈ·¶¨Óë´ÅÅ̲åÈëµÄ˳ÐòÓйأ¬¶øÓë´ÅÅÌËù²åÈëµÄ²å²ÛλÖÃÎ޹ء£ + +## ·ÖÇø±í + +´ÅÅÌ·ÖÇø±íÖ÷ÒªÓÐÁ½ÖÖ¸ñʽ£¬Ò»ÖÖÊÇÏÞÖÆ½Ï¶àµÄ MBR ·ÖÇø±í£¬Ò»ÖÖÊǽÏÐÂÇÒÏÞÖÆ½ÏÉÙµÄ GPT ·ÖÇø±í¡£ + +### 1. MBR + +MBR ÖУ¬µÚÒ»¸öÉÈÇø×îÖØÒª£¬ÀïÃæÓУºÖ÷Òª¿ª»ú¼Ç¼£¨Master boot record, MBR£©¼°·ÖÇø±í£¨partition table£©£¬ÆäÖÐ MBR Õ¼ 446 bytes£¬partition table Õ¼ 64 bytes¡£ + +·ÖÇø±íÖ»ÓÐ 64 bytes£¬×î¶àÖ»ÄÜ´æ´¢ 4 ¸ö·ÖÇø£¬Õâ 4 ¸ö·ÖÇøÎªÖ÷·ÖÇø£¨Primary£©ºÍÀ©Õ¹·ÖÇø£¨Extended£©¡£ÆäÖÐÀ©Õ¹·ÖÇøÖ»ÓÐÒ»¸ö£¬Ëü½«ÆäËü¿Õ¼äÓÃÀ´¼Ç¼·ÖÇø±í£¬¿ÉÒԼǼ¸ü¶àµÄ·ÖÇø£¬Òò´Ëͨ¹ýÀ©Õ¹·ÖÇø¿ÉÒÔ·Ö³ö¸ü¶àÇø·Ö£¬ÕâЩ·ÖÇø³ÆÎªÂß¼­·ÖÇø¡£ + +Linux Ò²°Ñ·ÖÇøµ±³ÉÎļþ£¬·ÖÇøÎļþµÄÃüÃû·½Ê½Îª£º´ÅÅÌÎļþÃû+±àºÅ£¬ÀýÈç /dev/sda1¡£×¢Ò⣬Âß¼­·ÖÇøµÄ±àºÅ´Ó 5 ¿ªÊ¼¡£ + +### 2. GPT + +²»Í¬µÄ´ÅÅÌÓв»Í¬µÄÉÈÇø´óС£¬ÀýÈç 512bytes ºÍ×îдÅÅÌµÄ 4k¡£GPT ΪÁ˼æÈÝËùÓдÅÅÌ£¬ÔÚ¶¨ÒåÉÈÇøÉÏʹÓÃÂß¼­Çø¿éµØÖ·£¨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 ÖеĿª»ú¹ÜÀí³ÌÐòʱ£¬¾Í¿ÉÒÔÑ¡ÔñÆô¶¯µ±Ç°µÄ²Ù×÷ϵͳ»òÕßת½»¸øÆäËü¿ª»ú¹ÜÀí³ÌÐò´Ó¶øÆô¶¯ÁíÒ»¸ö²Ù×÷ϵͳ¡£ + +![](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 λ·Ö±ðΪ r¡¢w¡¢x ȨÏÞ£¬±íʾ¿É¶Á¡¢¿Éд¡¢¿ÉÖ´ÐС£ + +## ÎļþÊôÐÔÒÔ¼°È¨ÏÞµÄÐÞ¸Ä + +### 1. ÐÞ¸ÄÎļþËùÊôȺ×é + +```html +# chgrp [-R] groupname dirname/filename +-R£ºµÝ¹éÐÞ¸Ä +``` + +### 2. ÐÞ¸ÄÎļþÓµÓÐÕß + +²»½ö¿ÉÒÔÐÞ¸ÄÎļþÓµÓÐÕߣ¬Ò²¿ÉÒÔÐÞ¸ÄÎļþËùÊôȺ×é¡£ + +```html +# chown [-R] Óû§Ãû:Ⱥ×éÃû dirname/filename +``` + +### 3. ÐÞ¸ÄȨÏÞ + +¿ÉÒÔ½«Ò»×éȨÏÞÓÃÊý×ÖÀ´±íʾ£¬´Ëʱһ×éȨÏÞµÄ 3 ¸öλµ±×ö¶þ½øÖÆÊý×ÖµÄ룬´Ó×óµ½ÓÒÿ¸öλµÄȨֵΪ 4¡¢2¡¢1£¬¼´Ã¿¸öȨÏÞ¶ÔÓ¦µÄÊý×ÖȨֵΪ r£º4¡¢w£º2¡¢x£º1¡£ + +```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 ¸üеÄÎļþ +``` + ++4¡¢4 ºÍ -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: ´ú±í byte£¬k: ´ú±í 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 ´óСÓÐ 1k¡¢2k ºÍ 4k ÈýÖÖ£¬²»Í¬µÄ block ´óСÏÞÖÆÁ˵¥Ò»ÎļþµÄ´óС¡£¶øÃ¿¸ö inode ´óСÊǹ̶¨Îª 128 bytes¡£ + +inode ÖмǼÁËÎļþÄÚÈÝËùÔÚµÄ block£¬µ«ÊÇÿ¸ö block ·Ç³£Ð¡£¬Ò»¸ö´óÎļþËæ±ã¶¼ÐèÒª¼¸Ê®ÍòµÄ 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 ÓëÖÁÉÙÒ»¸ö block¡£block ¼Ç¼µÄÄÚÈÝÊÇĿ¼ÏÂËùÓÐÎļþµÄ 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 ʹÓÃ×î¹ãµÄѹËõÖ¸Á¿ÉÒԽ⿪ compress¡¢zip Óë gzip ËùѹËõµÄÎļþ¡£ + +¾­¹ý gzip ѹËõ¹ý£¬Ô´Îļþ¾Í²»´æÔÚÁË¡£ + +ÓÐ 9 ¸ö²»Í¬µÄѹËõµÈ¼¶¿ÉÒÔʹÓᣠ+ +¿ÉÒÔʹÓà zcat¡¢zmore¡¢zless À´¶ÁȡѹËõÎļþµÄÄÚÈÝ¡£ + +```html +$ gzip [-cdtv#] filename +-c £º½«Ñ¹ËõµÄÊý¾ÝÊä³öµ½ÆÁÄ»ÉÏ +-d £º½âѹËõ +-t £º¼ìÑéѹËõÎļþÊÇ·ñ³ö´í +-v £ºÏÔʾѹËõ±ÈµÈÐÅÏ¢ +-# £º # ΪÊý×ÖµÄÒâ˼£¬´ú±íѹËõµÈ¼¶£¬Êý×ÖÔ½´óѹËõ±ÈÔ½¸ß£¬Ä¬ÈÏΪ6 +``` + +### 2. bzip2 + +Ìṩ±È gzip ¸ü¸ßµÄѹËõ±È¡£ + +²é¿´ÃüÁbzcat¡¢bzmore¡¢bzless¡¢bzgrep¡£ + +```html +$ bzip2 [-cdkzv#] filename +-k £º±£ÁôÔ´Îļþ +``` + +### 3. xz + +Ìṩ±È bzip2 ¸ü¼ÑµÄѹËõ±È¡£ + +¿ÉÒÔ¿´µ½£¬gzip¡¢bzip2¡¢xz µÄѹËõ±È²»¶ÏÓÅ»¯£¬²»¹ýҪעÒ⣬ѹËõ±ÈÔ½¸ß£¬Ñ¹ËõµÄʱ¼äÒ²Ô½³¤¡£ + +²é¿´ÃüÁxzcat¡¢xzmore¡¢xzless¡¢xzgrep¡£ + +```html +$ xz [-dtlkc#] filename +``` + +## ´ò°ü + +ѹËõÖ¸ÁîÖ»ÄܶÔÒ»¸öÎļþ½øÐÐѹËõ£¬¶ø´ò°üÄܹ»½«¶à¸öÎļþ´ò°ü³ÉÒ»¸ö´óÎļþ¡£tar ²»½ö¿ÉÒÔÓÃÓÚ´ò°ü£¬Ò²¿ÉÒÔʹÓà gip¡¢bzip2¡¢xz ½«´ò°üÎļþ½øÐÐѹËõ¡£ + +```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 £¬Ï൱ÓÚÈÓ½øÀ¬»øÏä¡£ + +Èç¹ûÐèÒª½«±ê×¼Êä³öÒÔ¼°±ê×¼´íÎóÊä³öÍ¬Ê±ÖØ¶¨Ïòµ½Ò»¸öÎļþ£¬ÐèÒª½«Ä³¸öÊä³öת»»ÎªÁíÒ»¸öÊä³ö£¬ÀýÈç 2>&1 ±íʾ½«±ê×¼´íÎóÊä³öת»»Îª±ê×¼Êä³ö¡£ + +```bash +$ find /home -name .bashrc > list 2>&1 +``` + +## ¹ÜÏßÖ¸Áî + +¹ÜÏßÊǽ«Ò»¸öÃüÁîµÄ±ê×¼Êä³ö×÷ΪÁíÒ»¸öÃüÁîµÄ±ê×¼ÊäÈ룬ÔÚÊý¾ÝÐèÒª¾­¹ý¶à¸ö²½ÖèµÄ´¦ÀíÖ®ºó²ÅÄܵõ½ÎÒÃÇÏëÒªµÄ¸ñʽʱ¾Í¿ÉÒÔʹÓùÜÏß¡£ÔÚÃüÁîÖ®¼äʹÓà | ·Ö¸ô¸÷¸ö¹ÜÏßÃüÁî¡£ + +```bash +$ ls -al /etc | less +``` + +### 1. ÌáȡָÁcut + +ÌáÈ¡¹ý³ÌÒ»ÐÐÒ»ÐеؽøÐС£ + +cut ¶ÔÊý¾Ý½øÐÐÇз֣¬È¡³öÏëÒªµÄ²¿·Ö¡£ + +```html +$ cut +-d £º·Ö¸ô·û +-f £º¾­¹ý -d ·Ö¸ôºó£¬Ê¹Óà -f n È¡³öµÚ n ¸öÇø¼ä +-c £ºÒÔ×Ö·ûΪµ¥Î»È¡³öÇø¼ä +``` + +·¶Àý1£ºlast ½«ÏÔʾµÄµÇÈëÕßµÄÐÅÏ¢£¬ÒªÇó½öÏÔʾÓû§Ãû¡£ + +```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. ÅÅÐòÃüÁsort¡¢uniq + +**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. ×Ö·ûת»»Ö¸Átr¡¢col¡¢expand¡¢join¡¢paste + + **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 £ººöÂÔ´óСдµÄ²îÒì +-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 ÿ´Î´¦ÀíÒ»ÐУ¬´¦ÀíµÄ×îСµ¥Î»ÊÇ×ֶΣ¬Ã¿¸ö×ֶεÄÃüÃû·½Ê½Îª£º\$n£¬n Ϊ×ֶκţ¬´Ó 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 À´Ö§³Ö¸ß²¢·¢£¬²¢ÇÒʵÏÖÁËËĸö±ê×¼µÄ¸ôÀë¼¶±ð£¬Ä¬Èϼ¶±ðÊÇ¿ÉÖØ¸´¶Á¡£ + +±íÊÇ»ùÓÚ¾Û´ØË÷Òý½¨Á¢µÄ£¬Ëü¶ÔÖ÷¼üµÄ²éѯÐÔÄÜÓкܸߵÄÌáÉý¡£ + +ÄÚ²¿×öÁ˺ܶàÓÅ»¯£¬°üÀ¨´Ó´ÅÅ̶ÁÈ¡Êý¾Ýʱ²ÉÓõĿÉÔ¤²âÐÔ¶Á£¬Äܹ»×Ô¶¯ÔÚÄÚ´æÖд´½¨ hash Ë÷ÒýÒÔ¼ÓËÙ¶Á²Ù×÷µÄ×ÔÊÊÓ¦¹þÏ£Ë÷Òý£¬ÒÔ¼°Äܹ»¼ÓËÙ²åÈë²Ù×÷µÄ²åÈ뻺³åÇøµÈ¡£ + +ͨ¹ýһЩ»úÖÆºÍ¹¤¾ßÖ§³ÖÕæÕýµÄÈȱ¸·Ý¡£ + +## 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 µÄ¼ÆËã±È¸¡µãÀàÐÍÐèÒª¸ü¸ßµÄ´ú¼Û¡£ + +FLOAT¡¢DOUBLE ºÍ DECIMAL ¶¼¿ÉÒÔÖ¸¶¨ÁÐ¿í£¬ÀýÈç DECIMAL(18, 9) ±íʾ×ܹ² 18 λ£¬È¡ 9 λ´æ´¢Ð¡Êý²¿·Ö£¬Ê£Ï 9 λ´æ´¢ÕûÊý²¿·Ö¡£ + +## 3. ×Ö·û´® + +Ö÷ÒªÓÐ CHAR ºÍ VARCHAR Á½ÖÖÀàÐÍ£¬Ò»ÖÖÊǶ¨³¤µÄ£¬Ò»ÖÖÊDZ䳤µÄ¡£ + +VARCHAR ÕâÖֱ䳤ÀàÐÍÄܹ»½ÚÊ¡¿Õ¼ä£¬ÒòΪֻÐèÒª´æ´¢±ØÒªµÄÄÚÈÝ¡£µ«ÊÇÔÚÖ´ÐÐ UPDATE ʱ¿ÉÄÜ»áʹÐбäµÃ±ÈÔ­À´³¤£¬µ±³¬³öÒ»¸öÒ³ËùÄÜÈÝÄɵĴóСʱ£¬¾ÍÒªÖ´ÐжîÍâµÄ²Ù×÷£¬MyISAM »á½«Ðвð³É²»Í¬µÄƬ¶Î´æ´¢£¬¶ø 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£Ð¡µÄ±í¡¢´ó²¿·ÖÇé¿öϼòµ¥µÄÈ«±íɨÃè±È½¨Á¢Ë÷Òý¸ü¸ßЧ¡£¶ÔÓÚÖе½´óÐÍµÄ±í£¬Ë÷Òý¾Í·Ç³£ÓÐЧ¡£µ«ÊǶÔÓÚÌØ´óÐÍµÄ±í£¬½¨Á¢ºÍʹÓÃË÷ÒýµÄ´ú¼Û½«»áËæÖ®Ôö³¤¡£ÕâÖÖÇé¿öÏ£¬ÐèÒªÓõ½Ò»ÖÖ¼¼Êõ¿ÉÒÔÖ±½ÓÇø·Ö³öÐèÒª²éѯµÄÒ»×éÊý¾Ý£¬¶ø²»ÊÇÒ»Ìõ¼Ç¼һÌõ¼Ç¼µØÆ¥Å䣬ÀýÈç¿ÉÒÔʹÓ÷ÖÇø¼¼Êõ¡£ + +## 1. Ë÷Òý·ÖÀà + +### 1.1 B-Tree Ë÷Òý + +B-Tree Ë÷ÒýÊÇ´ó¶àÊý MySQL ´æ´¢ÒýÇæµÄĬÈÏË÷ÒýÀàÐÍ¡£ + +ÒòΪ²»ÔÙÐèÒª½øÐÐÈ«±íɨÃ裬ֻÐèÒª¶ÔÊ÷½øÐÐËÑË÷¼´¿É£¬Òò´Ë²éÕÒËÙ¶È¿ìºÜ¶à¡£ + +¿ÉÒÔÖ¸¶¨¶à¸öÁÐ×÷ΪË÷ÒýÁУ¬¶à¸öË÷ÒýÁй²Í¬×é³É¼ü¡£B-Tree Ë÷ÒýÊÊÓÃÓÚÈ«¼üÖµ¡¢¼üÖµ·¶Î§ºÍ¼üǰ׺²éÕÒ£¬ÆäÖмüǰ׺²éÕÒÖ»ÊÊÓÃÓÚ×î×óǰ׺²éÕÒ¡£ + +³ýÁËÓÃÓÚ²éÕÒ£¬»¹¿ÉÒÔÓÃÓÚÅÅÐòºÍ·Ö×é¡£ + +Èç¹û²»Êǰ´ÕÕË÷ÒýÁеÄ˳Ðò½øÐвéÕÒ£¬ÔòÎÞ·¨Ê¹ÓÃË÷Òý¡£ + +### 1.2 ¹þÏ£Ë÷Òý + +»ùÓÚ¹þÏ£±íʵÏÖ£¬ÓŵãÊDzéÕҷdz£¿ì¡£ + +ÔÚ MySQL ÖÐÖ»ÓÐ Memory ÒýÇæÏÔʽ֧³Ö¹þÏ£Ë÷Òý¡£ + +InnoDB ÒýÇæÓÐÒ»¸öÌØÊâµÄ¹¦ÄܽС°×ÔÊÊÓ¦¹þÏ£Ë÷Òý¡±£¬µ±Ä³¸öË÷ÒýÖµ±»Ê¹Óõķ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í´ïʽµÄÒ»²¿·Ö£¬Ò²²»ÄÜÊǺ¯ÊýµÄ²ÎÊý£¬·ñÔòÎÞ·¨Ê¹ÓÃË÷Òý¡£ + +ÀýÈçÏÂÃæµÄ²éѯ²»ÄÜʹÓà actor_id ÁеÄË÷Òý£º + +```sql +SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; +``` + +### 3.2 ǰ׺Ë÷Òý + +¶ÔÓÚ BLOB¡¢TEXT ºÍ VARCHAR ÀàÐ͵ÄÁУ¬±ØÐëʹÓÃǰ׺Ë÷Òý£¬Ö»Ë÷Òý¿ªÊ¼µÄ²¿·Ö×Ö·û¡£ + +¶ÔÓÚǰ׺³¤¶ÈµÄѡȡÐèÒª¸ù¾Ý **Ë÷ÒýÑ¡ÔñÐÔ** À´È·¶¨£º²»Öظ´µÄË÷ÒýÖµºÍ¼Ç¼×ÜÊýµÄ±ÈÖµ¡£Ñ¡ÔñÐÔÔ½¸ß£¬²éѯЧÂÊÒ²Ô½¸ß¡£×î´óֵΪ 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 ¼ìË÷Êý¾ÝµÄËã·¨·Ç³£Ö±¹Û£ºÊ×ÏÈ´Ó¸ù½Úµã½øÐжþ·Ö²éÕÒ£¬Èç¹ûÕÒµ½Ôò·µ»Ø¶ÔÓ¦½ÚµãµÄ 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 ·Ç³£Ð¡£¨Í¨³£²»³¬¹ý 3£©¡£¶øºìºÚÊ÷ÕâÖֽṹ£¬h Ã÷ÏÔÒªÉîµÄ¶à¡£²¢ÇÒÓÚÂß¼­ÉϺܽüµÄ½Úµã£¨¸¸×Ó£©ÎïÀíÉÏ¿ÉÄܺÜÔ¶£¬ÎÞ·¨ÀûÓþֲ¿ÐÔ£¬Ð§ÂÊÃ÷ÏÔ±È B-Tree ²îºÜ¶à¡£ + +B+Tree ¸üÊʺÏÍâ´æË÷Òý£¬Ô­ÒòºÍÄÚ½Úµã³ö¶È d Óйء£ÓÉÓÚ B+Tree ÄÚ½ÚµãÈ¥µôÁË data Óò£¬Òò´Ë¿ÉÒÔÓµÓиü´óµÄ³ö¶È£¬ÓµÓиüºÃµÄÐÔÄÜ¡£ + +# ²éѯÐÔÄÜÓÅ»¯ + +## 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 Óï¾ä + +Èç¹ûÒ»´ÎÐÔÖ´Ðеϰ£¬¿ÉÄÜÒ»´ÎËø×¡ºÜ¶àÊý¾Ý¡¢Õ¼ÂúÕû¸öÊÂÎñÈÕÖ¾¡¢ºÄ¾¡ÏµÍ³×ÊÔ´¡¢×èÈûºÜ¶àСµÄµ«ÖØÒªµÄ²éѯ¡£ + +```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. ·Ö±íÓë·ÖÇøµÄ²»Í¬** + +·Ö±í£¬¾ÍÊǽ²Ò»Õűí·Ö³É¶à¸öС±í£¬ÕâЩС±íÓµÓв»Í¬µÄ±íÃû£»¶ø·ÖÇøÊǽ«Ò»ÕűíµÄÊý¾Ý·ÖΪ¶à¸öÇø¿é£¬ÕâÐ©Çø¿é¿ÉÒÔ´æ´¢ÔÚͬһ¸ö´ÅÅÌÉÏ£¬Ò²¿ÉÒÔ´æ´¢ÔÚ²»Í¬µÄ´ÅÅÌÉÏ£¬ÕâÖÖ·½Ê½Ï±íÈÔȻֻÓÐÒ»¸ö¡£ + +**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 @@ + +* [»ù´¡](#»ù´¡) +* [²éѯ](#²éѯ) +* [ÅÅÐò](#ÅÅÐò) +* [¹ýÂË](#¹ýÂË) +* [ͨÅä·û](#ͨÅä·û) +* [¼ÆËã×Ö¶Î](#¼ÆËã×Ö¶Î) +* [º¯Êý](#º¯Êý) + * [Îı¾´¦Àí](#Îı¾´¦Àí) + * [ÈÕÆÚºÍʱ¼ä´¦Àí](#ÈÕÆÚºÍʱ¼ä´¦Àí) + * [ÊýÖµ´¦Àí](#ÊýÖµ´¦Àí) + * [»ã×Ü](#»ã×Ü) +* [·Ö×é](#·Ö×é) +* [×Ó²éѯ](#×Ó²éѯ) +* [Á¬½Ó](#Á¬½Ó) + * [ÄÚÁ¬½Ó](#ÄÚÁ¬½Ó) + * [×ÔÁ¬½Ó](#×ÔÁ¬½Ó) + * [×ÔÈ»Á¬½Ó](#×ÔÈ»Á¬½Ó) + * [ÍâÁ¬½Ó](#ÍâÁ¬½Ó) +* [×éºÏ²éѯ](#×éºÏ²éѯ) +* [²åÈë](#²åÈë) +* [¸üÐÂ](#¸üÐÂ) +* [ɾ³ý](#ɾ³ý) +* [´´½¨±í](#´´½¨±í) +* [Ð޸ıí](#Ð޸ıí) +* [ÊÓͼ](#ÊÓͼ) +* [´æ´¢¹ý³Ì](#´æ´¢¹ý³Ì) +* [Óαê](#Óαê) +* [´¥·¢Æ÷](#´¥·¢Æ÷) +* [ÊÂÎñ´¦Àí](#ÊÂÎñ´¦Àí) +* [×Ö·û¼¯](#×Ö·û¼¯) +* [ȨÏÞ¹ÜÀí](#ȨÏÞ¹ÜÀí) + + +# »ù´¡ + +ģʽ£º¶¨ÒåÁËÊý¾ÝÈçºÎ´æ´¢¡¢´æ´¢Ê²Ã´ÑùµÄÊý¾ÝÒÔ¼°Êý¾ÝÈçºÎ·Ö½âµÈÐÅÏ¢£¬Êý¾Ý¿âºÍ±í¶¼ÓÐģʽ¡£ + +Ö÷¼üµÄÖµ²»ÔÊÐíÐ޸ģ¬Ò²²»ÔÊÐí¸´Ó㨲»ÄÜʹÓÃÒѾ­É¾³ýµÄÖ÷¼üÖµ¸³¸øÐÂÊý¾ÝÐеÄÖ÷¼ü£©¡£ + +SQL£¨Structured Query Language)£¬±ê×¼ SQL ÓÉ ANSI ±ê׼ίԱ»á¹ÜÀí£¬´Ó¶ø³ÆÎª ANSI SQL£¬¸÷¸ö DBMS ¶¼ÓÐ×Ô¼ºµÄʵÏÖ£¬Èç PL/SQL¡¢Transact-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»ÔÚ·þÎñÆ÷¶Ë½øÐйýÂ˵ÄÊý¾Ý·Ç³£´ó£¬µ¼ÖÂͨ¹ýÍøÂç´«ÊäÁ˺ܶà¶àÓàµÄÊý¾Ý£¬´Ó¶øÀË·ÑÁËÍøÂç´ø¿í¡£ + +```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¿ªÍ·µÄÈÎÒâÎı¾ +``` + +²»ÒªÀÄÓÃͨÅä·û£¬Í¨Åä·ûλÓÚ¿ªÍ·´¦Æ¥Åä»á·Ç³£Âý¡£ + +# ¼ÆËã×Ö¶Î + +ÔÚÊý¾Ý¿â·þÎñÆ÷ÉÏÍê³ÉÊý¾ÝµÄת»»ºÍ¸ñʽ»¯µÄ¹¤×÷ÍùÍù±È¿Í»§¶ËÉÏ¿ìµÃ¶à£¬²¢ÇÒת»»ºÍ¸ñʽ»¯ºóµÄÊý¾ÝÁ¿¸üÉٵϰ¿ÉÒÔ¼õÉÙÍøÂçͨÐÅÁ¿¡£ + +¼ÆËã×Ö¶Îͨ³£ÐèҪʹÓà **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() |·µ»ØÄ³ÁÐµÄÆ½¾ùÖµ| +|COUNT()| ·µ»ØÄ³ÁеÄÐÐÊý| +|MAX()| ·µ»ØÄ³ÁеÄ×î´óÖµ| +|MIN()| ·µ»ØÄ³ÁеÄ×îСֵ| +|SUM() |·µ»ØÄ³ÁÐÖµÖ®ºÍ| + +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; +``` + +# ÊÓͼ + +ÊÓͼÊÇÐéÄâµÄ±í£¬±¾Éí²»°üº¬Êý¾Ý£¬Ò²¾Í²»ÄÜ¶ÔÆä½øÐÐË÷Òý²Ù×÷¡£¶ÔÊÓͼµÄ²Ù×÷ºÍ¶ÔÆÕͨ±íµÄ²Ù×÷Ò»Ñù¡£ + +ÊÓͼ¾ßÓÐÈçϺô¦£º + +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. ÓÉÓÚÊÇÔ¤ÏȱàÒ룬Òò´Ë¾ßÓкܸߵÄÐÔÄÜ¡£ + +**´´½¨´æ´¢¹ý³Ì** + +ÃüÁîÐÐÖд´½¨´æ´¢¹ý³ÌÐèÒª×Ô¶¨Òå·Ö¸ô·û£¬ÒòΪÃüÁîÐÐÊÇÒÔ ; Ϊ½áÊø·û£¬¶ø´æ´¢¹ý³ÌÖÐÒ²°üº¬Á˷ֺţ¬Òò´Ë»á´íÎó°ÑÕⲿ·Ö·ÖºÅµ±³ÉÊǽáÊø·û£¬Ôì³ÉÓï·¨´íÎó¡£ + +°üº¬ in¡¢out ºÍ inout ÈýÖÖ²ÎÊý¡£ + +¸ø±äÁ¿¸³Öµ¶¼ÐèÒªÓà select into Óï¾ä¡£ + +ÿ´ÎÖ»ÄܸøÒ»¸ö±äÁ¿¸³Öµ£¬²»Ö§³Ö¼¯ºÏµÄ²Ù×÷¡£ + +```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¸ö±íÖ´ÐÐÒÔÏÂÓï¾äʱ¶ø×Ô¶¯Ö´ÐУºDELETE¡¢INSERT¡¢UPDATE + +´¥·¢Æ÷±ØÐëÖ¸¶¨ÔÚÓï¾äÖ´ÐÐ֮ǰ»¹ÊÇÖ®ºó×Ô¶¯Ö´ÐУ¬Ö®Ç°Ö´ÐÐʹÓà 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һ¸ö¸ñ×Ó£¬Ôò¸Ã·¾¶²»ÄÜÔÙ½øÈë¸Ã¸ñ×Ó¡£ ÀýÈç 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. ¼ôÉþ×Ó + +**ÌâÄ¿ÃèÊö** + +°ÑÒ»¸ùÉþ×Ó¼ô³É¶à¶Î£¬²¢ÇÒʹµÃÿ¶ÎµÄ³¤¶È³Ë»ý×î´ó¡£ + +**½âÌâ˼·** + +¾¡¿ÉÄܶàµÃ¼ô³¤¶ÈΪ 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. °ÑÊý×éÅųÉ×îСµÄÊý + +**ÌâÄ¿ÃèÊö** + +ÊäÈëÒ»¸öÕýÕûÊýÊý×飬°ÑÊý×éÀïËùÓÐÊý×ÖÆ´½ÓÆðÀ´ÅųÉÒ»¸öÊý£¬´òÓ¡ÄÜÆ´½Ó³öµÄËùÓÐÊý×ÖÖÐ×îСµÄÒ»¸ö¡£ÀýÈçÊäÈëÊý×é {3£¬32£¬321}£¬Ôò´òÓ¡³öÕâÈý¸öÊý×ÖÄÜÅųɵÄ×îСÊý×ÖΪ 321323¡£ ```java public String PrintMinNumber(int[] numbers) { @@ -1092,7 +1360,11 @@ public String PrintMinNumber(int[] numbers) { } ``` -## 49. 丑数 +## 49. ³óÊý + +**ÌâÄ¿ÃèÊö** + +°ÑÖ»°üº¬Òò×Ó 2¡¢3 ºÍ 5 µÄÊý³Æ×÷³óÊý£¨Ugly Number£©¡£ÀýÈç 6¡¢8 ¶¼Ê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£¬Èç¹ûÓжà¶ÔÊý×ֵĺ͵ÈÓÚ S£¬Êä³öÁ½¸öÊýµÄ³Ë»ý×îСµÄ¡£ ```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£¬ÒªÇó²»ÄÜʹÓó˳ý·¨¡¢for¡¢while¡¢if¡¢else¡¢switch¡¢case µÈ¹Ø¼ü×Ö¼°Ìõ¼þÅжÏÓï¾ä£¨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. ×¢ÒâÊÂÏî + +**´ó³£Êý** + +ÔÚÇó½üËÆÊ±£¬Èç¹ûµÍ¼¶ÏîµÄ³£ÊýϵÊýºÜ´ó£¬ÄÇô½üËÆµÄ½á¹û¾ÍÊÇ´íÎóµÄ¡£ + +**»º´æ** + +¼ÆËã»úϵͳ»áʹÓûº´æ¼¼ÊõÀ´×éÖ¯Äڴ棬·ÃÎÊÊý×éÏàÁÚµÄÔªËØ»á±È·ÃÎʲ»ÏàÁÚµÄÔªËØ¿ìºÜ¶à¡£ + +**¶Ô×Çé¿öϵÄÐÔÄܵı£Ö¤** + +Ôں˷´Ó¦¶Ñ¡¢ÐÄÔàÆð²«Æ÷»òÕßɲ³µ¿ØÖÆÆ÷ÖеÄÈí¼þ£¬×Çé¿öϵÄÐÔÄÜÊÇÊ®·ÖÖØÒªµÄ¡£ + +**Ëæ»ú»¯Ëã·¨** + +ͨ¹ý´òÂÒÊäÈ룬ȥ³ýËã·¨¶ÔÊäÈëµÄÒÀÀµ¡£ + +**¾ù̯·ÖÎö** + +½«ËùÓвÙ×÷µÄ×ܳɱ¾ËùÒÔ²Ù×÷×ÜÊýÀ´½«³É±¾¾ù̯¡£ÀýÈç¶ÔÒ»¸ö¿ÕÕ»½øÐÐ N ´ÎÁ¬ÐøµÄ push() µ÷ÓÃÐèÒª·ÃÎÊÊý×éµÄÔªËØÎª N+4+8+16+...+2N=5N-4£¨N ÊÇÏòÊý×éдÈëÔªËØ£¬ÆäÓàµÄ¶¼Êǵ÷ÕûÊý×é´óСʱ½øÐи´ÖÆÐèÒªµÄ·ÃÎÊÊý×é²Ù×÷£©£¬¾ù̯ºóÿ´Î²Ù×÷·ÃÎÊÊý×éµÄƽ¾ù´ÎÊýΪ³£Êý¡£ + +## 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 µÄ²Ù×÷´ú¼ÛÈ´ºÜ¸ß£¬ÐèÒª½«ÆäÖÐÒ»¸öÁ¬Í¨·ÖÁ¿ÖеÄËùÓнڵã 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() ·½·¨¡£ + +Ñо¿ÅÅÐòËã·¨µÄ³É±¾Ä£ÐÍʱ£¬¼ÆËãµÄÊDZȽϺͽ»»»µÄ´ÎÊý¡£ + +ʹÓø¨Öúº¯Êý less() ºÍ exch() À´½øÐбȽϺͽ»»»µÄ²Ù×÷£¬Ê¹µÃ´úÂëµÄ¿É¶ÁÐԺͿÉÒÆÖ²ÐÔ¸üºÃ¡£ + +```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; +} +``` + +### Ñ¡ÔñÅÅÐò + +ÕÒµ½Êý×éÖеÄ×îÐ¡ÔªËØ£¬È»ºó½«ËüÓëÊý×éµÄµÚÒ»¸öÔªËØ½»»»Î»Öá£È»ºóÔÙ´ÓʣϵÄÔªËØÖÐÕÒµ½×îСµÄÔªËØ£¬½«ËüÓëÊý×éµÄµÚ¶þ¸öÔªËØ½»»»Î»Öᣲ»¶Ï½øÐÐÕâÑùµÄ²Ù×÷£¬Ö±µ½½«Õû¸öÊý×éÅÅÐò¡£ + +![](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); + } + } + } +} +``` + +²åÈëÅÅÐòµÄ¸´ÔÓ¶ÈÈ¡¾öÓÚÊý×éµÄ³õʼ˳Ðò£¬Èç¹ûÊý×éÒѾ­²¿·ÖÓÐÐòÁË£¬ÄÇô²åÈëÅÅÐò»áºÜ¿ì¡£Æ½¾ùÇé¿öϲåÈëÅÅÐòÐèÒª \~N2/4 ±È½ÏÒÔ¼° \~N2/4 ´Î½»»»£¬×µÄÇé¿öÏÂÐèÒª \~N2/2 ±È½ÏÒÔ¼° \~N2/2 ´Î½»»»£¬×µÄÇé¿öÊÇÊý×éÊÇÄæÐòµÄ£»¶ø×îºÃµÄÇé¿öÏÂÐèÒª N-1 ´Î±È½ÏºÍ 0 ´Î½»»»£¬×îºÃµÄÇé¿ö¾ÍÊÇÊý×éÒѾ­ÓÐÐòÁË¡£ + +²åÈëÅÅÐò¶ÔÓÚ²¿·ÖÓÐÐòÊý×éºÍС¹æÄ£Êý×éÌØ±ð¸ßЧ¡£ + +### Ñ¡ÔñÅÅÐòºÍ²åÈëÅÅÐòµÄ±È½Ï + +¶ÔÓÚËæ»úÅÅÐòµÄÎÞÖØ¸´Ö÷¼üµÄÊý×飬²åÈëÅÅÐòºÍÑ¡ÔñÅÅÐòµÄÔËÐÐʱ¼äÊÇÆ½·½¼¶±ðµÄ£¬Á½ÕßÖ®±ÈÊÇÒ»¸ö½ÏСµÄ³£Êý¡£ + +### Ï£¶ûÅÅÐò + +¶ÔÓÚ´ó¹æÄ£µÄÊý×飬²åÈëÅÅÐòºÜÂý£¬ÒòΪËüÖ»Äܽ»»»ÏàÁÚµÄÔªËØ£¬Èç¹ûÒª°ÑÔªËØ´ÓÒ»¶ËÒÆµ½ÁíÒ»¶Ë£¬¾ÍÐèÒªºÜ¶à´Î²Ù×÷¡£ + +Ï£¶ûÅÅÐòµÄ³öÏÖ¾ÍÊÇΪÁ˸Ľø²åÈëÅÅÐòµÄÕâÖÖ¾ÖÏÞÐÔ£¬Ëüͨ¹ý½»»»²»ÏàÁÚµÄÔªËØ£¬Ê¹µÃÔªËØ¸ü¿ìµÄÒÆµ½ÕýÈ·µÄλÖÃÉÏ¡£ + +Ï£¶ûÅÅÐòʹÓòåÈëÅÅÐò¶Ô¼ä¸ô 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+1¡£ÕâÀïÎÒÃDz»Ê¹ÓÃÊý×éË÷ÒýΪ 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=k£¬a[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 ´Î±È½Ï£¬Ê¹Óöþ·Ö²éÕÒʵÏֵķûºÅ±íµÄ²éÕÒ²Ù×÷ËùÐèÒªµÄʱ¼ä×î¶àÊǶÔÊý¼¶±ðµÄ¡£µ«ÊDzåÈë²Ù×÷ÐèÒªÒÆ¶¯Êý×éÔªËØ£¬ÊÇÏßÐÔ¼¶±ðµÄ¡£ + +## ¶þ²æ²éÕÒÊ÷ + +¶¨Ò壺¶þ²æÊ÷¶¨ÒåΪһ¸ö¿ÕÁ´½Ó£¬»òÕßÊÇÒ»¸öÓÐ×óÓÒÁ½¸öÁ´½ÓµÄ½Úµã£¬Ã¿¸öÁ´½Ó¶¼Ö¸ÏòÒ»¿Å×Ó¶þ²æÊ÷¡£¶þ²æ²éÕÒÊ÷£¨BST£©ÊÇÒ»¿Å¶þ²æÊ÷£¬²¢ÇÒÿ¸ö½ÚµãµÄ¼ü¶¼´óÓÚÆä×ó×ÓÊ÷ÖеÄÈÎÒâ½ÚµãµÄ¼ü¶øÐ¡ÓÚÓÒ×ÓÊ÷µÄÈÎÒâ½ÚµãµÄ¼ü¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/25226bb2-92cc-40cb-9e7f-c44e79fbb64a.jpg) + +¶þ²æ²éÕÒÊ÷µÄ²éÕÒ²Ù×÷ÿ´Îµü´ú¶¼»áÈÃÇø¼ä¼õÉÙÒ»°ë£¬ºÍ¶þ·Ö²éÕÒÀàËÆ¡£ + +```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 ²éÕÒÊ÷µÄ²éÕҺͲåÈë²Ù×÷¸´ÔӶȺͲåÈë˳ÐòÎ޹أ¬ÔÚ×µÄÇé¿öϲéÕҺͲåÈë²Ù×÷·ÃÎÊµÄ½Úµã±ØÈ»²»³¬¹ý logN ¸ö¡£º¬ÓÐ 10 ÒÚ¸ö½ÚµãµÄ 2-3 ²éÕÒÊ÷×î¶àÖ»ÐèÒª·ÃÎÊ 30 ¸ö½Úµã¾ÍÄܽøÐÐÈÎÒâµÄ²éÕҺͲåÈë²Ù×÷¡£ + +### ºìºÚ¶þ²æ²éÕÒÊ÷ + +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; +} +``` + +#### ÓÒÐýת + +½øÐÐÓÒÐýתÊÇΪÁËת»»Á½¸öÁ¬ÐøµÄ×óºìÁ´½Ó£¬Õâ»áÔÚÖ®ºóµÄ²åÈë¹ý³ÌÖÐ̽ÌÖ¡£ + +![](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 µÄ²åÈë²Ù×÷ÀàËÆ£¬Ö»ÊÇÔÚ×îºó¼ÓÈëÁËÐýתºÍÑÕÉ«±ä»»²Ù×÷¼´¿É¡£ + +¸ù½ÚµãÒ»¶¨ÎªºÚÉ«£¬ÒòΪ¸ù½ÚµãûÓÐÉϲã½Úµã£¬Ò²¾ÍûÓÐÉϲã½ÚµãµÄ×óÁ´½ÓÖ¸Ïò¸ù½Úµã¡£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- ½Úµã¡£ + +ºìºÚÊ÷´ó¶àÊýµÄ²Ù×÷ËùÐèÒªµÄʱ¼ä¶¼ÊǶÔÊý¼¶±ðµÄ¡£ + +## É¢Áбí + +É¢ÁбíÀàËÆÓÚÊý×飬¿ÉÒÔ°ÑÉ¢ÁбíµÄÉ¢ÁÐÖµ¿´³ÉÊý×éµÄË÷ÒýÖµ¡£·ÃÎÊÉ¢ÁбíºÍ·ÃÎÊÊý×éÔªËØÒ»Ñù¿ìËÙ£¬Ëü¿ÉÒÔÔÚ³£Êýʱ¼äÄÚʵÏÖ²éÕҺͲåÈëµÄ·ûºÅ±í¡£ + +ÓÉÓÚÎÞ·¨Í¨¹ýÉ¢ÁÐÖµÖªµÀ¼üµÄ´óС¹ØÏµ£¬Òò´ËÉ¢ÁбíÎÞ·¨ÊµÏÖÓÐÐòÐÔ²Ù×÷¡£ + +### É¢Áк¯Êý + +¶ÔÓÚÒ»¸ö´óСΪ 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 ÖÐµÄ String¡¢Integer µÈ¶ÔÏóµÄ 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 Ó¦µ±´óÓÚ¼üµÄ¸öÊý N£¨M>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(); +} +``` + +#### µ÷ÕûÊý×é´óС + +ÏßÐÔ̽²â·¨µÄ³É±¾È¡¾öÓÚÁ¬ÐøÌõÄ¿µÄ³¤¶È£¬Á¬ÐøÌõĿҲ½Ð¾Û´Ø¡£µ±¾Û´ØºÜ³¤Ê±£¬ÔÚ²éÕҺͲåÈëʱҲÐèÒª½øÐкܶà´Î̽²â¡£ + +¦Á = 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. ×î½ü×î¾ÃδʹÓã¨LRU£¬Least Recently Used£©](#3-×î½ü×î¾ÃδʹÓã¨lru£¬least-recently-used£©) + * [4. ʱÖÓ£¨Clock£©](#4-ʱÖÓ£¨clock£©) +* [µÚÎåÕ É豸¹ÜÀí](#µÚÎåÕÂ-É豸¹ÜÀí) + * [´ÅÅ̵÷¶ÈËã·¨](#´ÅÅ̵÷¶ÈËã·¨) + * [1. ÏÈÀ´ÏÈ·þÎñ£¨FCFS£¬First Come First Serverd£©](#1-ÏÈÀ´ÏÈ·þÎñ£¨fcfs£¬first-come-first-serverd£©) + * [2. ×î¶ÌѰµÀʱ¼äÓÅÏÈ£¨SSTF£¬Shortest Seek Time First£©](#2-×î¶ÌѰµÀʱ¼äÓÅÏÈ£¨sstf£¬shortest-seek-time-first£©) + * [3. ɨÃèËã·¨£¨SCAN£©](#3-ɨÃèËã·¨£¨scan£©) + * [4. Ñ­»·É¨ÃèËã·¨£¨CSCAN£©](#4-Ñ­»·É¨ÃèËã·¨£¨cscan£©) +* [²Î¿¼×ÊÁÏ](#²Î¿¼×ÊÁÏ) + + +# µÚÒ»Õ ¸ÅÊö + +## ²Ù×÷ϵͳ»ù±¾ÌØÕ÷ + +### 1. ²¢·¢ + +²¢·¢ÐÔÊÇÖ¸ºê¹ÛÉÏÔÚÒ»¶Îʱ¼äÄÚÄÜͬʱÔËÐжà¸ö³ÌÐò£¬¶ø²¢ÐÐÐÔÔòָͬһʱ¿ÌÄÜÔËÐжà¸öÖ¸Áî¡£ + +²¢ÐÐÐèÒªÓ²¼þÖ§³Ö£¬Èç¶àÁ÷Ë®Ïß»òÕß¶à´¦ÀíÆ÷¡£ + +²Ù×÷ϵͳͨ¹ýÒýÈë½ø³ÌºÍỊ̈߳¬Ê¹µÃ³ÌÐòÄܹ»²¢·¢ÔËÐС£ + +### 2. ¹²Ïí + +¹²ÏíÊÇָϵͳÖеÄ×ÊÔ´¿ÉÒÔ¹©¶à¸ö²¢·¢µÄ½ø³Ì¹²Í¬Ê¹Óᣠ+ +ÓÐÁ½ÖÖ¹²Ïí·½Ê½£º»¥³â¹²ÏíºÍͬʱ¹²Ïí¡£ + +»¥³â¹²ÏíµÄ×ÊÔ´³ÆÎªÁÙ½ç×ÊÔ´£¬ÀýÈç´òÓ¡»úµÈ£¬ÔÚͬһʱ¼äÖ»ÔÊÐíÒ»¸ö½ø³Ì·ÃÎÊ£¬·ñÔò»á³öÏÖ´íÎó£¬ÐèÒªÓÃͬ²½»úÖÆÀ´ÊµÏÖ¶ÔÁÙ½ç×ÊÔ´µÄ·ÃÎÊ¡£ + +### 3. ÐéÄâ + +ÐéÄâ¼¼Êõ°ÑÒ»¸öÎïÀíʵÌåת»»Îª¶à¸öÂß¼­ÊµÌå¡£Ö÷ÒªÓÐÁ½ÖÖÐéÄâ¼¼Êõ£ºÊ±·Ö¸´Óü¼ÊõºÍ¿Õ·Ö¸´Óü¼Êõ£¬ÀýÈç¶à¸ö½ø³ÌÄÜÔÚͬһ¸ö´¦ÀíÆ÷Éϲ¢·¢Ö´ÐÐʹÓÃÁËʱ·Ö¸´Óü¼Êõ£¬ÈÃÿ¸ö½ø³ÌÂÖÁ÷Õ¼Óд¦ÀíÆ÷£¬Ã¿´ÎÖ»Ö´ÐÐһС¸öʱ¼äƬ²¢¿ìËÙÇл»£¬ÕâÑù¾ÍºÃÏñÓжà¸ö´¦ÀíÆ÷½øÐд¦Àí¡£ + +### 4. Òì²½ + +Òì²½ÊÇÖ¸½ø³Ì²»ÊÇÒ»´ÎÐÔÖ´ÐÐÍê±Ï£¬¶øÊÇ×ß×ßͣͣ£¬ÒÔ²»¿ÉÖªµÄËÙ¶ÈÏòÇ°ÍÆ½ø¡£ + +## ϵͳµ÷Óà + +Èç¹ûÒ»¸ö½ø³ÌÔÚÓû§Ì¬ÐèÒªÓõ½²Ù×÷ϵͳµÄһЩ¹¦ÄÜ£¬¾ÍÐèҪʹÓÃϵͳµ÷ÓôӶøÏÝÈëÄںˣ¬ÓɲÙ×÷ϵͳ´úΪÍê³É¡£ + +¿ÉÒÔÓÉϵͳµ÷ÓÃÇëÇóµÄ¹¦ÄÜÓÐÉ豸¹ÜÀí¡¢Îļþ¹ÜÀí¡¢½ø³Ì¹ÜÀí¡¢½ø³ÌͨÐÅ¡¢´æ´¢Æ÷¹ÜÀíµÈ¡£ + +## ÖжϷÖÀà + +### 1. ÍâÖÐ¶Ï + +ÓÉ CPU Ö´ÐÐÖ¸ÁîÒÔÍâµÄʼþÒýÆð£¬Èç I/O ½áÊøÖжϣ¬±íʾÉ豸ÊäÈë/Êä³ö´¦ÀíÒѾ­Íê³É£¬´¦ÀíÆ÷Äܹ»·¢ËÍÏÂÒ»¸öÊäÈë/Êä³öÇëÇó¡£´ËÍ⻹ÓÐʱÖÓÖжϡ¢¿ØÖÆÌ¨Öжϵȡ£ + +### 2. Òì³£ + +ÓÉ CPU Ö´ÐÐÖ¸ÁîµÄÄÚ²¿Ê¼þÒýÆð£¬Èç·Ç·¨²Ù×÷Âë¡¢µØÖ·Ô½½ç¡¢ËãÊõÒç³öµÈ¡£ + +### 3. ÏÝÈë + +ÔÚÓû§³ÌÐòÖÐʹÓÃϵͳµ÷Óᣠ+ +## ´óÄں˺Í΢ÄÚºË + +### 1. ´óÄÚºË + +´óÄÚºËÊǽ«²Ù×÷ϵͳ¹¦ÄÜ×÷Ϊһ¸ö½ôÃܽáºÏµÄÕûÌå·Åµ½Äںˣ¬ÓÉÓÚ¸÷Ä£¿é¹²ÏíÐÅÏ¢£¬Òò´ËÓкܸߵÄÐÔÄÜ¡£ + +### 2. ΢ÄÚºË + +ÓÉÓÚ²Ù×÷ϵͳ²»¶Ï¸´ÔÓ£¬Òò´Ë½«Ò»²¿·Ö²Ù×÷ϵͳ¹¦ÄÜÒÆ³öÄںˣ¬´Ó¶ø½µµÍÄں˵ĸ´ÔÓÐÔ¡£ÒƳöµÄ²¿·Ö¸ù¾Ý·Ö²ãµÄÔ­Ôò»®·Ö³ÉÈô¸É·þÎñ£¬Ï໥¶ÀÁ¢¡£µ«ÊÇÐèҪƵ·±µØÔÚÓû§Ì¬ºÍºËÐÄ̬֮¼ä½øÐÐÇл»£¬»áÓÐÒ»¶¨µÄÐÔÄÜËðʧ¡£ + +# µÚ¶þÕ ½ø³Ì¹ÜÀí + +## ½ø³ÌÓëÏß³Ì + +### 1. ½ø³Ì + +½ø³ÌÊDzÙ×÷ϵͳ½øÐÐ×ÊÔ´·ÖÅäµÄ»ù±¾µ¥Î»¡£ + +½ø³Ì¿ØÖÆ¿é (Process Control Block, PCB) ÃèÊö½ø³ÌµÄ»ù±¾ÐÅÏ¢ºÍÔËÐÐ״̬£¬ËùνµÄ´´½¨½ø³ÌºÍ³·Ïú½ø³Ì£¬¶¼ÊÇÖ¸¶Ô PCB µÄ²Ù×÷¡£ + +### 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¡£ + +µ÷¶È×îÏȽøÈë¾ÍÐ÷¶ÓÁеÄ×÷Òµ¡£ + +ÓÐÀûÓÚ³¤×÷Òµ£¬µ«²»ÀûÓÚ¶Ì×÷Òµ£¬ÒòΪ¶Ì×÷Òµ±ØÐëÒ»Ö±µÈ´ýÇ°ÃæµÄ³¤×÷ÒµÖ´ÐÐÍê±Ï²ÅÄÜÖ´ÐУ¬¶ø³¤×÷ÒµÓÖÐèÒªÖ´Ðкܳ¤Ê±¼ä£¬Ôì³ÉÁ˶Ì×÷ÒµµÈ´ýʱ¼ä¹ý³¤¡£ + +#### 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. ʵʱϵͳÖеĵ÷¶È + +ʵʱϵͳҪһ¸ö·þÎñÇëÇóÔÚÒ»¸öÈ·¶¨Ê±¼äÄڵõ½ÏìÓ¦¡£ + +·ÖΪӲʵʱºÍÈíʵʱ£¬Ç°Õß±ØÐëÂú×ã¾ø¶ÔµÄ½ØÖ¹Ê±¼ä£¬ºóÕß¿ÉÒÔÈÝÈÌÒ»¶¨µÄ³¬Ê±¡£ + +## ½ø³Ìͬ²½ + +### 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; +``` + +¹Ü³ÌÓÐÒ»¸öÖØÒªÌØÐÔ£ºÔÚÒ»¸öʱ¿ÌÖ»ÄÜÓÐÒ»¸ö½ø³ÌʹÓù̡ܳ£½ø³ÌÔÚÎÞ·¨¼ÌÐøÖ´ÐеÄʱºò²»ÄÜÒ»Ö±Õ¼Óụ̀ܳ¬±ØÐ뽫½ø³Ì×èÈû£¬·ñÕ߯äËü½ø³ÌÓÀÔ¶²»ÄÜʹÓù̡ܳ£ + +¹Ü³ÌÒýÈëÁË **Ìõ¼þ±äÁ¿** ÒÔ¼°Ïà¹ØµÄ²Ù×÷£º**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) + +ÉÏͼÖÐÓÐÎå¸ö½ø³Ì£¬Ëĸö×ÊÔ´¡£×ó±ßµÄͼ±íʾÒѾ­·ÖÅäµÄ×ÊÔ´£¬ÓұߵÄͼ±íʾ»¹ÐèÒª·ÖÅäµÄ×ÊÔ´¡£×îÓÒ±ßµÄ E¡¢P ÒÔ¼° 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 ËÀËø»Ö¸´ + +¢Ù ÀûÓÃÇÀÕ¼»Ö¸´ +¢Ú ɱËÀ½ø³Ì + +# µÚËÄÕ ´æ´¢Æ÷¹ÜÀí + +## ÐéÄâÄÚ´æ + +ÿ¸ö³ÌÐòÓµÓÐ×Ô¼ºµÄµØÖ·¿Õ¼ä£¬Õâ¸öµØÖ·¿Õ¼ä±»·Ö¸î³É¶à¸ö¿é£¬Ã¿Ò»¿é³ÆÎªÒ» Ò³¡£ÕâЩҳ±»Ó³Éäµ½ÎïÀíÄڴ棬µ«²»ÐèÒªÓ³Éäµ½Á¬ÐøµÄÎïÀíÄڴ棬Ҳ²»ÐèÒªËùÓÐÒ³¶¼±ØÐëÔÚÎïÀíÄÚ´æÖС£ + +µ±³ÌÐòÒýÓõ½Ò»²¿·ÖÔÚÎïÀíÄÚ´æÖеĵØÖ·¿Õ¼äʱ£¬ÓÉÓ²¼þÁ¢¼´Ö´ÐбØÒªµÄÓ³Éä¡£µ±³ÌÐòÒýÓõ½Ò»²¿·Ö²»ÔÚÎïÀíÄÚ´æÖеĵØÖ·¿Õ¼äʱ£¬ÓɲÙ×÷ϵͳ¸ºÔð½«È±Ê§µÄ²¿·Ö×°ÈëÎïÀíÄÚ´æ²¢ÖØÐÂÖ´ÐÐʧ°ÜµÄÖ¸Áî¡£ + +## ·ÖÒ³Óë·Ö¶Î + +### 1. ·ÖÒ³ + +Óû§³ÌÐòµÄµØÖ·¿Õ¼ä±»»®·ÖΪÈô¸É¹Ì¶¨´óСµÄÇøÓò£¬³ÆÎª¡°Ò³¡±¡£ÏàÓ¦µØ£¬ÄÚ´æ¿Õ¼ä·Ö³ÉÈô¸É¸öÎïÀí¿é£¬Ò³ºÍ¿éµÄ´óСÏàµÈ¡£¿É½«Óû§³ÌÐòµÄÈÎÒ»Ò³·ÅÔÚÄÚ´æµÄÈÎÒ»¿éÖУ¬ÊµÏÖÁËÀëÉ¢·ÖÅ䣬ÓÉÒ»¸öÒ³±íÀ´Î¬»¤ËüÃÇÖ®¼äµÄÓ³Éä¹ØÏµ¡£ + +### 2. ·Ö¶Î + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png) + +ÉÏͼΪһ¸ö±àÒëÆ÷ÔÚ±àÒë¹ý³ÌÖн¨Á¢µÄ¶à¸ö±í£¬ÓÐ 4 ¸ö±íÊǶ¯Ì¬Ôö³¤µÄ£¬Èç¹ûʹÓ÷ÖҳϵͳµÄһάµØÖ·¿Õ¼ä£¬¶¯Ì¬µÝÔöµÄÌØµã»áµ¼Ö¸²¸ÇÎÊÌâµÄ³öÏÖ¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png) + +·Ö¶ÎµÄ×ö·¨ÊǰÑÿ¸ö±í·Ö³É¶Î£¬Ò»¸ö¶Î¹¹³ÉÒ»¸ö¶ÀÁ¢µÄµØÖ·¿Õ¼ä¡£Ã¿¸ö¶ÎµÄ³¤¶È¿ÉÒÔ²»Í¬£¬¿ÉÒÔ¶¯Ì¬¸Ä±ä¡£ + +ÿ¸ö¶Î¶¼ÐèÒª³ÌÐòÔ±À´»®·Ö¡£ + +### 3. ¶Îҳʽ + +Ó÷ֶη½·¨À´·ÖÅäºÍ¹ÜÀíÐéÄâ´æ´¢Æ÷¡£³ÌÐòµÄµØÖ·¿Õ¼ä°´Âß¼­µ¥Î»·Ö³É»ù±¾¶ÀÁ¢µÄ¶Î£¬¶øÃ¿Ò»¶ÎÓÐ×Ô¼ºµÄ¶ÎÃû£¬ÔÙ°Ñÿ¶Î·Ö³É¹Ì¶¨´óСµÄÈô¸ÉÒ³¡£ + +Ó÷ÖÒ³·½·¨À´·ÖÅäºÍ¹ÜÀíʵ´æ¡£¼´°ÑÕû¸öÖ÷´æ·Ö³ÉÓëÉÏÊöÒ³´óСÏàµÈµÄ´æ´¢¿é£¬¿É×°Èë×÷ÒµµÄÈκÎÒ»Ò³¡£³ÌÐò¶ÔÄÚ´æµÄµ÷Èë»òµ÷³öÊǰ´Ò³½øÐеġ£µ«ËüÓֿɰ´¶ÎʵÏÖ¹²ÏíºÍ±£»¤¡£ + +### 4. ·ÖÒ³Óë·Ö¶ÎÇø±ð + +¢Ù ¶Ô³ÌÐòÔ±µÄ͸Ã÷ÐÔ£º·Öҳ͸Ã÷£¬µ«ÊÇ·Ö¶ÎÐèÒª³ÌÐòÔ±ÏÔʾ»®·Öÿ¸ö¶Î¡£ + +¢Ú µØÖ·¿Õ¼äµÄά¶È£º·ÖÒ³ÊÇһάµØÖ·¿Õ¼ä£¬·Ö¶ÎÊǶþάµÄ¡£ + +¢Û ´óСÊÇ·ñ¿ÉÒԸı䣺ҳµÄ´óС²»¿É±ä£¬¶ÎµÄ´óС¿ÉÒÔ¶¯Ì¬¸Ä±ä¡£ + +¢Ü ³öÏÖµÄÔ­Òò£º·ÖÒ³Ö÷ÒªÓÃÓÚʵÏÖÐéÄâÄڴ棬´Ó¶ø»ñµÃ¸ü´óµÄµØÖ·¿Õ¼ä£»·Ö¶ÎÖ÷ÒªÊÇΪÁËʹ³ÌÐòºÍÊý¾Ý¿ÉÒÔ±»»®·ÖΪÂß¼­É϶ÀÁ¢µÄµØÖ·¿Õ¼ä²¢ÇÒÓÐÖúÓÚ¹²ÏíºÍ±£»¤¡£ + +## Ò³ÃæÖû»Ëã·¨ + +ÔÚ³ÌÐòÔËÐйý³ÌÖУ¬ÈôÆäËùÒª·ÃÎʵÄÒ³Ãæ²»ÔÚÄÚ´æ¶øÐèÒª°ÑËüÃǵ÷ÈëÄڴ棬µ«ÊÇÄÚ´æÒÑÎÞ¿ÕÏпռäʱ£¬ÏµÍ³±ØÐë´ÓÄÚ´æÖе÷³öÒ»¸öÒ³Ãæµ½´ÅÅ̶Ի»ÇøÖУ¬²¢ÇÒ½«³ÌÐòËùÐèÒªµÄÒ³Ãæµ÷ÈëÄÚ´æÖС£Ò³ÃæÖû»Ëã·¨µÄÖ÷ҪĿ±êÊÇÊ¹Ò³ÃæÖû»ÆµÂÊ×îµÍ£¨Ò²¿ÉÒÔ˵ȱҳÂÊ×îµÍ£©¡£ + +### 1. ×î¼Ñ£¨Optimal£© + +ËùÑ¡ÔñµÄ±»»»³öµÄÒ³Ãæ½«ÊÇ×ʱ¼äÄÚ²»ÔÙ±»·ÃÎÊ£¬Í¨³£¿ÉÒÔ±£Ö¤»ñµÃ×îµÍµÄȱҳÂÊ¡£ + +ÊÇÒ»ÖÖÀíÂÛÉϵÄËã·¨£¬ÒòΪÎÞ·¨ÖªµÀÒ»¸öÒ³Ãæ¶à³¤Ê±¼ä»á±»ÔÙ·ÃÎʵ½¡£ + +¾ÙÀý£ºÒ»¸öϵͳΪij½ø³Ì·ÖÅäÁËÈý¸öÎïÀí¿é£¬²¢ÓÐÈçÏÂÒ³ÃæÒýÓÃÐòÁУº + +7£¬0£¬1£¬2£¬0£¬3£¬0£¬4£¬2£¬3£¬0£¬3£¬2£¬1£¬2£¬0£¬1£¬7£¬0£¬1 + +½ø³ÌÔËÐÐʱ£¬ÏȽ« 7,0,1 Èý¸öÒ³Ãæ×°ÈëÄÚ´æ¡£µ±½ø³ÌÒª·ÃÎÊÒ³Ãæ 2 ʱ£¬²úÉúȱҳÖжϣ¬»á½«Ò³Ãæ 7 »»³ö£¬ÒòÎªÒ³Ãæ 7 Ôٴα»·ÃÎʵÄʱ¼ä×¡£ + +### 2. ÏȽøÏȳö£¨FIFO£© + +ËùÑ¡Ôñ»»³öµÄÒ³ÃæÊÇ×îÏȽøÈëµÄÒ³Ãæ¡£ + +¸ÃËã·¨»á½«ÄÇЩ¾­³£±»·ÃÎʵÄÒ³ÃæÒ²±»»»³ö£¬´Ó¶øÊ¹È±Ò³ÂÊÉý¸ß¡£ + +### 3. ×î½ü×î¾ÃδʹÓã¨LRU£¬Least Recently Used£© + +ËäÈ»ÎÞ·¨ÖªµÀ½«À´ÒªÊ¹ÓõÄÒ³ÃæÇé¿ö£¬µ«ÊÇ¿ÉÒÔÖªµÀ¹ýȥʹÓÃÒ³ÃæµÄÇé¿ö¡£LRU ½«×î½ü×î¾ÃδʹÓõÄÒ³Ãæ»»³ö¡£ + +¿ÉÒÔÓÃÕ»À´ÊµÏÖ¸ÃËã·¨£¬Õ»ÖÐ´æ´¢Ò³ÃæµÄÒ³ÃæºÅ¡£µ±½ø³Ì·ÃÎÊÒ»¸öÒ³ÃæÊ±£¬½«¸ÃÒ³ÃæµÄÒ³ÃæºÅ´ÓÕ»ÒÆ³ý£¬²¢½«ËüѹÈëÕ»¶¥£¬ÕâÑù£¬×î½ü±»·ÃÎʵÄÒ³ÃæµÄÒ³ÃæºÅ×ÜÊÇÔÚÕ»¶¥£¬¶ø×î½ü×î¾ÃδʹÓõÄÒ³ÃæµÄÒ³ÃæºÅ×ÜÊÇÔÚÕ»µ×¡£ + +4£¬7£¬0£¬7£¬1£¬0£¬1£¬2£¬1£¬2£¬6 + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/eb859228-c0f2-4bce-910d-d9f76929352b.png) + +### 4. ʱÖÓ£¨Clock£© + +Clock Ò³ÃæÖû»Ëã·¨ÐèÒªÓõ½Ò»¸ö·ÃÎÊ룬µ±Ò»¸öÒ³Ãæ±»·ÃÎÊʱ£¬½«·ÃÎÊΪÖÃΪ 1¡£ + +Ê×ÏÈ£¬½«ÄÚ´æÖеÄËùÓÐÒ³ÃæÁ´½Ó³ÉÒ»¸öÑ­»·¶ÓÁУ¬µ±È±Ò³ÖжϷ¢Éúʱ£¬¼ì²éµ±Ç°Ö¸ÕëËùÖ¸ÏòÒ³ÃæµÄ·ÃÎÊ룬Èç¹û·ÃÎÊλΪ 0£¬¾Í½«¸ÃÒ³Ãæ»»³ö£»·ñÔò½«¸ÃÒ³µÄ·ÃÎÊλÉèÖÃΪ 0£¬¸ø¸ÃÒ³ÃæµÚ¶þ´ÎµÄ»ú»á£¬Òƶ¯Ö¸Õë¼ÌÐø¼ì²é¡£ + +# µÚÎåÕ É豸¹ÜÀí + +## ´ÅÅ̵÷¶ÈËã·¨ + +µ±¶à¸ö½ø³ÌͬʱÇëÇó·ÃÎÊ´ÅÅÌʱ£¬ÐèÒª½øÐдÅÅ̵÷¶ÈÀ´¿ØÖƶԴÅÅ̵ķÃÎÊ¡£´ÅÅ̵÷¶ÈµÄÖ÷ҪĿ±êÊÇʹ´ÅÅÌµÄÆ½¾ùѰµÀʱ¼ä×îÉÙ¡£ + +### 1. ÏÈÀ´ÏÈ·þÎñ£¨FCFS£¬First Come First Serverd£© + +¸ù¾Ý½ø³ÌÇëÇó·ÃÎÊ´ÅÅ̵ÄÏȺó´ÎÐòÀ´½øÐе÷¶È¡£ÓŵãÊǹ«Æ½ºÍ¼òµ¥£¬È±µãÒ²ºÜÃ÷ÏÔ£¬ÒòΪδ¶ÔѰµÀ×öÈκÎÓÅ»¯£¬Ê¹Æ½¾ùѰµÀʱ¼ä¿ÉÄܽϳ¤¡£ + +### 2. ×î¶ÌѰµÀʱ¼äÓÅÏÈ£¨SSTF£¬Shortest Seek Time First£© + +ÒªÇó·ÃÎʵĴŵÀÓ뵱ǰ´ÅÍ·ËùÔڴŵÀ¾àÀë×î½üµÄÓÅÏȽøÐе÷¶È¡£ÕâÖÖËã·¨²¢²»Äܱ£Ö¤Æ½¾ùѰµÀʱ¼ä×î¶Ì£¬µ«ÊÇ±È 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., & O¡¯Hallaron, 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 ±íʾÊý¾ÝÖ¡µÄ³¤¶È£¬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. Ó¦ÓÃ²ã£ºÎªÌØ¶¨Ó¦ÓóÌÐòÌṩÊý¾Ý´«Êä·þÎñ£¬ÀýÈç HTTP¡¢DNS µÈ¡£Êý¾Ýµ¥Î»Îª±¨ÎÄ¡£ + +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 ЭÒé + +»¥ÁªÍøÓû§Í¨³£ÐèÒªÁ¬½Óµ½Ä³¸ö 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 µØÖ·£¬ÀýÈç±Ê¼Ç±¾µçÄÔÆÕ±é´æÔÚÎÞÏßÍøÂçÊÊÅäÆ÷ºÍÓÐÏßÍøÂçÊÊÅäÆ÷¡£ + +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 ·¢Ë͵Ĺ㲥»á±» A2¡¢A3¡¢A4 ÊÕµ½£¬¶øÆäËüÕ¾µãÊÕ²»µ½¡£ + +![](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. µØÖ·½âÎöЭÒé ARP£¨Address Resolution Protocol£© +2. Íø¼Ê¿ØÖƱ¨ÎÄЭÒé ICMP£¨Internet Control Message Protocol£© +3. Íø¼Ê×é¹ÜÀíЭÒé IGMP£¨Internet 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) + +**°æ±¾** : ÓÐ 4£¨IPv4£©ºÍ 6£¨IPv6£©Á½¸öÖµ£» + +**Êײ¿³¤¶È** : Õ¼ 4 룬Òò´Ë×î´óֵΪ 15¡£ÖµÎª 1 ±íʾµÄÊÇ 1 ¸ö 32 λ×ֵij¤¶È£¬Ò²¾ÍÊÇ 4 ×Ö½Ú¡£ÒòΪÊײ¿¹Ì¶¨³¤¶ÈΪ 20 ×Ö½Ú£¬Òò´Ë¸ÃÖµ×îСΪ 5¡£Èç¹û¿ÉÑ¡²¿·ÖµÄ³¤¶È²»ÊÇ 4 ×Ö½ÚµÄÕûÊý±¶£¬¾ÍÓÃβ²¿µÄÌî³ä²¿·ÖÀ´Ìî³ä¡£ + +**Çø·Ö·þÎñ** : ÓÃÀ´»ñµÃ¸üºÃµÄ·þÎñ£¬Ò»°ãÇé¿öϲ»ÊÊÓᣠ+ +**×ܳ¤¶È** : °üÀ¨Êײ¿³¤¶ÈºÍÊý¾Ý²¿·Ö³¤¶È¡£ + +**±êʶ** : ÔÚÊý¾Ý±¨³¤¶È¹ý³¤´Ó¶ø·¢Éú·ÖƬµÄÇé¿öÏ£¬ÏàͬÊý¾Ý±¨µÄ²»Í¬·ÖƬ¾ßÓÐÏàͬµÄ±êʶ·û¡£ + +**Æ¬Æ«ÒÆ** : ºÍ±êʶ·ûÒ»Æð£¬ÓÃÓÚ·¢Éú·ÖƬµÄÇé¿ö¡£Æ¬Æ«ÒƵĵ¥Î»Îª 8 ×Ö½Ú¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/45c86855-9b18-4cf4-a9a7-f8b6eb78d133.png) + +**Éú´æÊ±¼ä** £ºTTL£¬ËüµÄ´æÔÚΪÁË·ÀÖ¹ÎÞ·¨½»¸¶µÄÊý¾Ý±¨ÔÚ»¥ÁªÍøÖв»¶Ï¶µÈ¦×Ó¡£ÒÔ·ÓÉÆ÷ÌøÊýΪµ¥Î»£¬µ± TTL Ϊ 0 ʱ¾Í¶ªÆúÊý¾Ý±¨¡£ + +**ЭÒé**£ºÖ¸³öЯ´øµÄÊý¾ÝÓ¦¸ÃÉϽ»¸øÄĸöЭÒé½øÐд¦Àí£¬ÀýÈç ICMP¡¢TCP¡¢UDP µÈ¡£ + +**Êײ¿¼ìÑéºÍ**£ºÒòΪÊý¾Ý±¨Ã¿¾­¹ýÒ»¸ö·ÓÉÆ÷£¬¶¼ÒªÖØÐ¼ÆËã¼ìÑéºÍ£¬Òò´Ë¼ìÑéºÍ²»°üº¬Êý¾Ý²¿·Ö¿ÉÒÔ¼õÉÙ¼ÆËãµÄ¹¤×÷Á¿¡£ + +## 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 µØÖ·½øÐбàÂë£¬ÍøÂçǰ׺µÄ³¤¶È¿ÉÒÔ¸ù¾ÝÐèÒª±ä»¯¡£ + +IP µØÖ· ::= {< ÍøÂçǰ׺ºÅ >, < Ö÷»úºÅ >} + +CIDR µÄ¼Ç·¨ÉϲÉÓÃÔÚ IP µØÖ·ºóÃæ¼ÓÉÏÍøÂçǰ׺³¤¶ÈµÄ·½·¨£¬ÀýÈç 128.14.35.7/20 ±íʾǰ 20 Î»ÎªÍøÂçǰ׺¡£ + +CIDR µÄµØÖ·ÑÚÂë¿ÉÒÔ¼ÌÐø³ÆÎª×ÓÍøÑÚÂ룬×ÓÍøÑÚÂëÊ× 1 ³¤¶ÈÎªÍøÂçǰ׺µÄ³¤¶È¡£ + +Ò»¸ö 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. ÄÚ²¿Íø¹ØÐ­Òé IGP£¨Interior Gateway Protocol£© ÔÚ×ÔÖÎϵͳÄÚ²¿Ê¹Óã¬Èç RIP ºÍ OSPF¡£ +2. Íâ²¿Íø¹ØÐ­Òé EGP£¨External 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. Ö»Óе±Á´Â·×´Ì¬·¢Éú±ä»¯Ê±£¬Â·ÓÉÆ÷²Å»á·¢ËÍÐÅÏ¢¡£ + +ËùÓзÓÉÆ÷¶¼¾ßÓÐÈ«ÍøµÄÍØÆË½á¹¹Í¼£¬²¢ÇÒÊÇÒ»Öµġ£Ïà±ÈÓÚ RIP£¬OSPF µÄ¸üйý³ÌÊÕÁ²µÄºÜ¿ì¡£ + +### 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¡£Êý¾Ý±¨ÏÈ·¢Ë͵½Ó뻥ÁªÍøÏàÁ¬µÄ·ÓÉÆ÷ R1£¬R1 ¶ÔÄÚ²¿Êý¾Ý½øÐмÓÃÜ£¬È»ºóÖØÐ¼ÓÉÏÊý¾Ý±¨µÄÊײ¿£¬Ô´µØÖ·ÊÇ·ÓÉÆ÷ 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 µÄÌØµã + +Óû§Êý¾Ý°üЭÒé UDP£¨User Datagram Protocol£© +´«Êä¿ØÖÆÐ­Òé TCP£¨Transmission 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 ÆÚÍûÏÂÒ»¸ö±¨ÎĶεÄÐòºÅΪ 701£¬B ·¢Ë͸ø A µÄÈ·Èϱ¨ÎĶÎÖÐÈ·ÈϺžÍΪ 701¡£ + +**Êý¾ÝÆ«ÒÆ** £ºÖ¸µÄÊÇÊý¾Ý²¿·Ö¾àÀ뱨ÎÄ¶ÎÆðʼ´¦µÄÆ«ÒÆÁ¿£¬Êµ¼ÊÉÏÖ¸µÄÊÇÊײ¿µÄ³¤¶È¡£ + +**È·ÈÏ ACK** £ºµ± ACK=1 ʱȷÈϺÅ×Ö¶ÎÓÐЧ£¬·ñÔòÎÞЧ¡£TCP ¹æ¶¨£¬ÔÚÁ¬½Ó½¨Á¢ºóËùÓд«Ë͵ı¨ÎĶζ¼±ØÐë°Ñ ACK Öà 1¡£ + +**ͬ²½ SYN** £ºÔÚÁ¬½Ó½¨Á¢Ê±ÓÃÀ´Í¬²½ÐòºÅ¡£µ± SYN=1£¬ACK=0 ʱ±íʾÕâÊÇÒ»¸öÁ¬½ÓÇëÇó±¨ÎĶΡ£Èô¶Ô·½Í¬Ò⽨Á¢Á¬½Ó£¬ÔòÏìÓ¦±¨ÎÄÖÐ SYN=1£¬ACK=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=1£¬ACK=0£¬Ñ¡ÔñÒ»¸ö³õʼµÄÐòºÅ x¡£ +3. B ÊÕµ½Á¬½ÓÇëÇó±¨ÎĶΣ¬Èç¹ûͬÒ⽨Á¢Á¬½Ó£¬ÔòÏò A ·¢ËÍÁ¬½ÓÈ·Èϱ¨ÎĶΣ¬SYN=1£¬ACK=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 Ó¦¸ÃÂÔ´óÓÚ RRTs£¬TCP ʹÓõ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 ¼Ó±¶£¬Òò´ËÖ®ºó·¢ËÍ·½Äܹ»·¢Ë͵ı¨ÎĶÎΪ£º2¡¢4¡¢8 ... + +×¢Òâµ½Âý¿ªÊ¼Ã¿¸öÂִζ¼½« 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 ¿ÉÒÔÊÊÓ¦Ðí¶à¼ÆËã»úºÍ²Ù×÷ϵͳµÄ²îÒ죬ÀýÈ粻ͬ²Ù×÷ϵͳϵͳµÄ»»Ðзû¶¨Òå¡£ + +## ÍòÎ¬Íø 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:68£©£¬DHCP ·þÎñÆ÷ÊÕµ½·¢ÏÖ±¨ÎÄÖ®ºó£¬ÔòÔÚ 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. ģʽ¶¨Òå** + +¶¨ÒåÁ˶ÔÏóÖ®¼äµÄÒ»¶Ô¶àÒÀÀµ£¬µ±Ò»¸ö¶ÔÏó¸Ä±ä״̬ʱ£¬ËüµÄËùÓÐÒÀÀµÕß¶¼»áÊܵ½Í¨Öª²¢×Ô¶¯¸üС£Ö÷Ì⣨Subject£©ÊDZ»¹Û²ìµÄ¶ÔÏ󣬶øÆäËùÓÐÒÀÀµÕߣ¨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. ¶¨Òå** + +¼òµ¥¹¤³§²»ÊÇÉè¼ÆÄ£Ê½£¬¸üÏñÊÇÒ»ÖÖ±à³Ìϰ¹ß¡£ÔÚʵÀý»¯Ò»¸ö³¬ÀàµÄ¶ÔÏóʱ£¬¿ÉÒÔÓÃËüµÄËùÓÐ×ÓÀàÀ´½øÐÐʵÀý»¯£¬Òª¸ù¾Ý¾ßÌåÐèÇóÀ´¾ö¶¨Ê¹ÓÃÄĸö×ÓÀà¡£ÔÚÕâÖÖÇé¿öÏ£¬°ÑʵÀý»¯µÄ²Ù×÷·Åµ½¹¤³§À´ÖУ¬Èù¤³§ÀàÀ´¾ö¶¨Ó¦¸ÃÓÃÄĸö×ÓÀàÀ´ÊµÀý»¯¡£ÕâÑù×ö°Ñ¿Í»§¶ÔÏóºÍ¾ßÌå×ÓÀàµÄʵÏÖ½âñ¿Í»§¶ÔÏó²»ÔÙÐèÒªÖªµÀÓÐÄÄЩ×ÓÀàÒÔ¼°ÊµÀý»¯Äĸö×ÓÀà¡£ÒòΪ¿Í»§ÀàÍùÍùÓжà¸ö£¬Èç¹û²»Ê¹Óüòµ¥¹¤³§£¬ÄÇôËùÓеĿͻ§Àà¶¼ÒªÖªµÀËùÓÐ×ÓÀàµÄϸ½Ú£¬Ò»µ©×ÓÀà·¢Éú¸Ä±ä£¬ÀýÈçÔö¼Ó×ÓÀ࣬ÄÇôËùÓеĿͻ§Àà¶¼Òª·¢Éú¸Ä±ä¡£ + +![](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 µÄ³éÏóÀ࣬ÄÇô¾Í¿ÉÒÔ²»ÓùØÐÄ 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£©ÊÊÅä»ð¼¦£¨Turkey£©£¬Duck ÓÐ 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. ¹³×Ó** + +¹³×Ó£¨hock£©£ºÄ³Ð©²½ÖèÔÚ²»Í¬ÊµÏÖÖпÉÓпÉÎÞ£¬¿ÉÒÔÏȶ¨ÒåÒ»¸öʲô¶¼²»×öµÄ·½·¨£¬°ÑËü¼Óµ½Ä£°å·½·¨ 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. ģʽÀàͼ** + +¿Í»§ÀàÓµÓÐÒ»¸ö¾ÛºÏ¶ÔÏóºÍµü´úÆ÷¶ÔÏ󣬵ü´úÆ÷¶ÔÏóÊǾۺ϶ÔÏóÉú³ÉµÄ¡£Ö»ÐèÒªµü´úÆ÷¶¨ÒåºÃÒÆ¶¯µÄ²Ù×÷£¬¾Í¿ÉÒÔÈþۺ϶ÔÏóÄܹ»Ë³Ðò±éÀú¡£ + +![](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. ģʽ¶¨Òå** + +ÔÊÐí¶ÔÏóÔÚÄÚ²¿×´Ì¬¸Ä±äʱ¸Ä±äËüµÄÐÐΪ£¬¶ÔÏó¿´ÆðÀ´ºÃÏñÐÞ¸ÄÁËËüµÄÀà¡£ + +״̬ģʽµÄÀàͼºÍ²ßÂÔģʽһÑù£¬²¢ÇÒ¶¼ÊÇÄܹ»¶¯Ì¬¸Ä±ä¶ÔÏóµÄÐÐΪ¡£µ«ÊÇ״̬ģʽÊÇͨ¹ý״̬¶ÔÏóµÄ×´Ì¬×ªÒÆÀ´¸Ä±ä¿Í»§¶ÔÏó×éºÏµÄ״̬¶ÔÏ󣬶ø²ßÂÔģʽÊÇͨ¹ý¿Í»§¶ÔÏó±¾ÉíµÄ¾ö²ßÀ´¸Ä±ä×éºÏµÄ²ßÂÔ¶ÔÏó¡£ÀýÈ磬״̬ģʽÏ£¬¿Í»§¶ÔÏóίÍÐ״̬¶ÔÏó½øÐÐÒ»¸ö´¦Àí²Ù×÷£¬ÄÇô״̬¶ÔÏóÓпÉÄÜ·¢Éú×´Ì¬×ªÒÆ£¬Ê¹µÃ¿Í»§¶ÔÏóÓµÓеÄ״̬¶ÔÏó·¢Éú¸Ä±ä¡£×´Ì¬¶ÔÏó×éºÏÁ˿ͻ§¶ÔÏó£¬×´Ì¬×ªÒÆÊÇ״̬¶ÔÏóͨ¹ý¸Ä±ä¿Í»§¶ÔÏóËù×éºÏµÄ״̬¶ÔÏóʵÏֵġ£ + +**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. ·â×° + +ÀûÓóéÏóÊý¾ÝÀàÐͽ«Êý¾ÝºÍ»ùÓÚÊý¾ÝµÄ²Ù×÷·â×°ÔÚÒ»Æð£¬Ê¹Æä¹¹³ÉÒ»¸ö²»¿É·Ö¸îµÄ¶ÀÁ¢ÊµÌ壬Êý¾Ý±»±£»¤ÔÚ³éÏóÊý¾ÝÀàÐ͵ÄÄÚ²¿£¬¾¡¿ÉÄܵØÒþ²ØÄÚ²¿µÄϸ½Ú£¬Ö»±£ÁôһЩ¶ÔÍâ½Ó¿Úʹ֮ÓëÍⲿ·¢ÉúÁªÏµ¡£Óû§ÊÇÎÞÐèÖªµÀ¶ÔÏóÄÚ²¿µÄϸ½Ú£¬µ«¿ÉÒÔͨ¹ý¸Ã¶ÔÏó¶ÔÍâµÄÌṩµÄ½Ó¿ÚÀ´·ÃÎʸöÔÏó¡£ + +·â×°ÓÐÈý´óºÃ´¦£º + +1. Á¼ºÃµÄ·â×°Äܹ»¼õÉÙñîºÏ¡£ + +2. ÀàÄÚ²¿µÄ½á¹¹¿ÉÒÔ×ÔÓÉÐ޸ġ£ + +3. ¿ÉÒÔ¶Ô³ÉÔ±½øÐиü¾«È·µÄ¿ØÖÆ¡£ + +4. Òþ²ØÐÅÏ¢£¬ÊµÏÖϸ½Ú¡£ + +ÒÔÏ Person Àà·â×° name¡¢gender¡¢age µÈÊôÐÔ£¬Íâ½çÖ»ÄÜͨ¹ý 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) + +ºÍ¹ØÁª¹ØÏµ²»Í¬µÄÊÇ, ÒÀÀµ¹ØÏµÊÇÔÚÔËÐйý³ÌÖÐÆð×÷Óõġ£Ò»°ãÒÀÀµ×÷ΪÀàµÄ¹¹ÔìÆ÷»òÕß·½·¨µÄ²ÎÊý´«È롣˫ÏòÒÀÀµÊ±Ò»ÖÖ²»ºÃµÄÉè¼Æ¡£ + +![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/47ca2614-509f-476e-98fc-50ec9f9d43c0.png) + + +## 2. ʱÐòͼ + +**2.1 ¶¨Òå** + +ʱÐòͼÃèÊöÁ˶ÔÏóÖ®¼ä´«µÝÏûÏ¢µÄʱ¼ä˳Ðò£¬ËüÓÃÀ´±íʾÓÃÀýµÄÐÐΪ˳Ðò¡£ËüµÄÖ÷Òª×÷ÓÃÊÇͨ¹ý¶ÔÏó¼äµÄ½»»¥À´ÃèÊöÓÃÀý£¨×¢ÒâÊǶÔÏ󣩣¬´Ó¶øÑ°ÕÒÀàµÄ²Ù×÷¡£ + +**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)