diff --git "a/docs/study/BigData/ClickHouse/clickhouse\345\216\237\347\220\206\350\247\243\346\236\220\344\270\216\345\272\224\347\224\250\345\256\236\350\267\265-\345\255\246\344\271\240\347\254\224\350\256\260-02.md" "b/docs/study/BigData/ClickHouse/clickhouse\345\216\237\347\220\206\350\247\243\346\236\220\344\270\216\345\272\224\347\224\250\345\256\236\350\267\265-\345\255\246\344\271\240\347\254\224\350\256\260-02.md" index 6fd46d4..c7e3123 100644 --- "a/docs/study/BigData/ClickHouse/clickhouse\345\216\237\347\220\206\350\247\243\346\236\220\344\270\216\345\272\224\347\224\250\345\256\236\350\267\265-\345\255\246\344\271\240\347\254\224\350\256\260-02.md" +++ "b/docs/study/BigData/ClickHouse/clickhouse\345\216\237\347\220\206\350\247\243\346\236\220\344\270\216\345\272\224\347\224\250\345\256\236\350\267\265-\345\255\246\344\271\240\347\254\224\350\256\260-02.md" @@ -5404,4 +5404,14 @@ INSERT INTO TABLE test_backup_0206 SELECT * FROM remote('ch5.nauu.com:9000', ## 11.6 本章小结 -​ 通过对本章的学习,大家可进一步了解ClickHouse的安全性和健壮性。本章首先站在安全的角度介绍了用户的定义方法和权限的设置方法。在权限设置方面,ClickHouse分别从连接访问、资源访问、查询操作和数据权限等几个维度出发,提供了一个较为立体的权限控制体系。接着站在系统运行的角度介绍了如何通过熔断机制保护ClickHouse系统资源不会被过度使用。最后站在运维的角度介绍了数据的多种备份方法以及如何通过系统表和查询日志,实现对日常运行情况的监控。 \ No newline at end of file +​ 通过对本章的学习,大家可进一步了解ClickHouse的安全性和健壮性。本章首先站在安全的角度介绍了用户的定义方法和权限的设置方法。在权限设置方面,ClickHouse分别从连接访问、资源访问、查询操作和数据权限等几个维度出发,提供了一个较为立体的权限控制体系。接着站在系统运行的角度介绍了如何通过熔断机制保护ClickHouse系统资源不会被过度使用。最后站在运维的角度介绍了数据的多种备份方法以及如何通过系统表和查询日志,实现对日常运行情况的监控。 + +# X. 网文搜集 + +> [Doris 与 ClickHouse 的深度对比及选型建议_doris和clickhouse-CSDN博客](https://blog.csdn.net/u011250186/article/details/135963133) => 很全面,推荐阅读 +> +> [实时OLAP都选Clickhouse?我们用Doris明明也很香_数据 (sohu.com)](https://www.sohu.com/a/451440153_411876) +> +> [Apache Druid 简介 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/82038648) +> +> [干货高能!ClickHouse性能优化,看这一篇就够了 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/667086347) \ No newline at end of file diff --git "a/docs/study/LeetCode_Study/\345\201\232\351\242\230\347\254\224\350\256\260/leetcode\345\201\232\351\242\230\347\254\224\350\256\260.md" "b/docs/study/LeetCode_Study/\345\201\232\351\242\230\347\254\224\350\256\260/leetcode\345\201\232\351\242\230\347\254\224\350\256\260.md" index b2116b9..fdcb7c2 100644 --- "a/docs/study/LeetCode_Study/\345\201\232\351\242\230\347\254\224\350\256\260/leetcode\345\201\232\351\242\230\347\254\224\350\256\260.md" +++ "b/docs/study/LeetCode_Study/\345\201\232\351\242\230\347\254\224\350\256\260/leetcode\345\201\232\351\242\230\347\254\224\350\256\260.md" @@ -10100,6 +10100,35 @@ class Solution { } ``` +代码2:快速选择 + +```java +class Solution { + public int findKthLargest(int[] nums, int k) { + int len = nums.length; + return quickSelect(nums, 0, len-1, len-k); + } + + public int quickSelect(int[] nums, int l, int r, int k) { + if(l == r) { + return nums[k]; + } + int base = nums[l], x = l-1, y = r+1; + while(x < y) { + do --y; while(nums[y] > base); + do ++x; while(nums[x] < base); + if(x < y) { + nums[x] ^= nums[y]; + nums[y] ^= nums[x]; + nums[x] ^= nums[y]; + } + } + if(y < k) return quickSelect(nums, y+1,r, k); + return quickSelect(nums, l, y, k); + } +} +``` + ## 25. K 个一组翻转链表 语言:java @@ -10551,3 +10580,169 @@ class Solution { } ``` +## 面试题 08.09. 括号 + +语言:java + +思路:回溯算法,类似组合问题,需要注意的就是加入右括号的时机 + +代码(1ms,72.52%): + +```java +class Solution { + public List generateParenthesis(int n) { + List result = new ArrayList<>(); + backTracking(result, new StringBuilder(), n, n); + return result; + } + + public void backTracking(List result, StringBuilder sb, int left,int right) { + if(left == 0 && right == 0) { + result.add(sb.toString()); + } + if(left > 0) { + sb.append('('); + backTracking(result, sb, left-1, right); + sb.deleteCharAt(sb.length()-1); + } + if(right > 0 && right > left) { + sb.append(')'); + backTracking(result, sb, left, right-1); + sb.deleteCharAt(sb.length()-1); + } + } +} +``` + +## 74. 搜索二维矩阵 + +语言:java + +思路:就是有序数组变成二维而已,二分查找完事了 + +代码: + +```java +class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + int x = matrix.length, y = matrix[0].length, n = x * y; + if(target < matrix[0][0] || target > matrix[x-1][y-1]) { + return false; + } + int left = 0, right = n, mid = 0, cur = 0; + while(left <= right) { + mid = left + (right - left) / 2; + // 主要难点在于这个 二维坐标 转成 一维坐标 + cur = matrix[mid / y][mid % y]; + if(cur == target) { + return true; + } else if (cur < target) { + left = mid + 1; + } else { + right = mid -1; + } + } + return false; + } +} +``` + +## 240. 搜索二维矩阵 II + +语言:java + +思路:从左下角出发,根据节点大小判断往哪边走就行 + +代码(6ms,99.91%): + +```java +class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + int x = matrix.length, y = matrix[0].length; + if(matrix[0][0] > target || target > matrix[x-1][y-1]) { + return false; + } + int i = x-1, j = 0; + while(i >= 0 && j < y) { + if(matrix[i][j] == target) { + return true; + } else if (matrix[i][j] > target) { + --i; + } else { + ++j; + } + } + return false; + } +} +``` + +## LCR 070. 有序数组中的单一元素 + +语言:java + +思路:二分查找,需要注意mid为偶数和奇数的处理不同,还有就是right初始值 + +代码(0ms,100%):要求O(logN)时间复杂度 + O(1)空间复杂度,不然实际也可以直接用异或位运算 + +```java +class Solution { + public int singleNonDuplicate(int[] nums) { + int len = nums.length, left = 0, right = len-1, mid = 0; + while (left < right) { + mid = left + (right - left) / 2; + // mid 偶数 + if (mid % 2 == 0 && nums[mid] == nums[mid + 1] + || mid % 2 == 1 && nums[mid] == nums[mid - 1]) { + left = mid + 1; + } else { + right = mid; + } + } + return nums[left]; + } +} +``` + +## 92. 反转链表 II + +语言:java + +思路:找到需要翻转的开始位置的前一个节点,然后对后续的链表进行翻转 + +代码(0ms,100%): + +```java +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode reverseBetween(ListNode head, int left, int right) { + ListNode preHead = new ListNode(), preResult = preHead; + preHead.next = head; + int start = 1; + while(start++ < left) { + preHead = preHead.next; + } + ListNode cur = preHead.next, pre = null, next = null; + while(left <= right) { + next = cur.next; + cur.next = pre; + pre = cur; + cur = next; + ++left; + } + preHead.next.next = next; + preHead.next = pre; + return preResult.next; + } +} +``` + diff --git "a/docs/study/\347\274\226\347\250\213\346\200\235\346\203\263/\343\200\212\344\273\243\347\240\201\345\244\247\345\205\2502\343\200\213-\350\257\273\344\271\246\347\254\224\350\256\260.md" "b/docs/study/\347\274\226\347\250\213\346\200\235\346\203\263/\343\200\212\344\273\243\347\240\201\345\244\247\345\205\2502\343\200\213-\350\257\273\344\271\246\347\254\224\350\256\260.md" index e0100be..0221fc3 100644 --- "a/docs/study/\347\274\226\347\250\213\346\200\235\346\203\263/\343\200\212\344\273\243\347\240\201\345\244\247\345\205\2502\343\200\213-\350\257\273\344\271\246\347\254\224\350\256\260.md" +++ "b/docs/study/\347\274\226\347\250\213\346\200\235\346\203\263/\343\200\212\344\273\243\347\240\201\345\244\247\345\205\2502\343\200\213-\350\257\273\344\271\246\347\254\224\350\256\260.md" @@ -1,2 +1,75 @@ # 《代码大全2》-读书笔记 +# 阅读指南 + +1. 初级程序员:优先18章 +2. 高级程序员:优先4章 +3. 项目经理:优先33章 +4. 低年级学生:优先11章 +5. 高年级学生:优先8章 +6. 制定编码标准的人:优先32章 +7. 自学编程的人:优先7章 +8. 喜欢参与网上争议的人:13.3和17.3 + +# 第1部分 打好基础 + +# 第1章 欢迎进入软件构建的世界 + +## 1.1 什么是软件构建 + +软件开发过程中的不同活动: + ++ 定义问题 ++ 需求分析 ++ 规划构建 ++ 软件架构,高层设计 ++ 详细设计 ++ 编码与调试 ++ 单元测试 ++ 集成测试 ++ 集成 ++ 系统测试 ++ 保障维护 + +## 1.2 软件构建为何如此重要 + +## 1.3 如何阅读本书 + +# 第2章 用隐喻来更充分地理解软件开发 + +## 2.1 隐喻的重要性 + +类比,比较, 最后使用隐喻表述,即“建模”(modeling)。 + +## 2.2 如何使用软件隐喻 + +将问题有效地概念化。(个人理解上就是将问题拆解成通俗、广为人知的小问题或者概念,而不是指一昧地造词增加理解难度) + +## 2.3 常见的软件隐喻 + ++ 隐喻是启示而不是算法。因此它们往往有一点随意(sloopy)。 ++ 隐喻把软件开发过程与其他你熟系的活动联系在一起,帮助你更好地理解。 有些隐喻比其他一些隐喻更贴切。 ++ 通过把软件的构建过程比作是房屋的建设过程,我们可以发现,仔细的准备 是必要的,而大型项目和小型项目之间也是有差异的。 ++ 通过把软件开发中的实践比作是智慧工具箱中的工具,我们又发现,每位程 序员都有许多工具,但并不存在任何一个能适用于所有工作的工具,因地制 宜地选择正确工具是成为能有效编程的程序员的关键。 ++ 不同的隐喻彼此并不排斥,应当使用对你最有益处的某种隐喻组合。 + +# 第3章 三思而后行: 前期准备 + +## 3.1 前期准备的重要性 + +造成准备工作不充分的常见原因: + +1. 开发人员本身不具备做前期准备的专业技能能力 +2. 无法抵抗快速开始代码工作的欲望 +3. 管理者轻视准备工作并压缩开发者的工作时间 + +## 3.2 辨明你所从事的软件的类型 + +## 3.3 问题定义的先决条件 + +## 3.4 需求的先决条件 + +## 3.5 架构的先决条件 + +## 3.6 花费在前期准备上的时间长度 + diff --git "a/docs/study/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\244\215\344\271\240.md" "b/docs/study/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\244\215\344\271\240.md" index ae951c1..82a1c69 100644 --- "a/docs/study/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\244\215\344\271\240.md" +++ "b/docs/study/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\244\215\344\271\240.md" @@ -1979,6 +1979,14 @@ PC1 ===> PC2 发送数据报,经过以下几个流程: ​ *连接到因特网的主机都拥有统一的IP地址(指公网IP),它们之间的通信就像连接在同一个网络上那样简单方便。因为调用ARP来寻找某个路由器或者主机的硬件地址都是由计算机软件自动进行的,对用户来说是看不见这种调用过程的。* +### 4.3.10 服务端如何保证获取的用户IP非伪造 + +> [你确信 X-Forwarded-For 拿到的就是用户真实 IP 吗? - 卤蛋实验室 - 博客园 (cnblogs.com)](https://www.cnblogs.com/skychx/p/X-Forwarded-For-get-real-IP.html) +> +> [关于X-Forwarded-For被伪造情况下获取真实ip的处理 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/134618410) <= 推荐阅读 + + + ### 4.4 ARP&RARP #### 4.4.1 ARP和RARP概述