From 913480bfe3919227ecedc24200ea004d79ea9674 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sun, 27 Aug 2017 15:57:10 +0800 Subject: [PATCH 01/40] 2017 8.27 --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index 85b889c..da47683 100644 --- a/Readme.md +++ b/Readme.md @@ -708,6 +708,8 @@ epoll改了三个缺点. 4. 时间片轮转(RR, Round Robin) 5. 多级反馈队列调度(multilevel feedback queue scheduling) +常见的调度算法总结:http://www.jianshu.com/p/6edf8174c1eb + 实时调度算法: 1. 最早截至时间优先 EDF From e9517f44509ccb33fc9b068c8b6589027411c6db Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sun, 27 Aug 2017 16:17:44 +0800 Subject: [PATCH 02/40] 2017 8.27 --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index da47683..f543116 100644 --- a/Readme.md +++ b/Readme.md @@ -736,7 +736,7 @@ epoll改了三个缺点. 4. 解除死锁 1. 剥夺资源 2. 撤销进程 - +死锁概念处理策略详细介绍:https://wizardforcel.gitbooks.io/wangdaokaoyan-os/content/10.html ## 4 程序编译与链接 From 744b857f43030f3b628e0739ba2088d90c80646f Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sun, 27 Aug 2017 16:18:54 +0800 Subject: [PATCH 03/40] 2017 8.27 --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index f543116..9feabf1 100644 --- a/Readme.md +++ b/Readme.md @@ -736,6 +736,7 @@ epoll改了三个缺点. 4. 解除死锁 1. 剥夺资源 2. 撤销进程 + 死锁概念处理策略详细介绍:https://wizardforcel.gitbooks.io/wangdaokaoyan-os/content/10.html ## 4 程序编译与链接 From d61ef9045e4cd8bfe5f365d301599ca6d75d840d Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sun, 27 Aug 2017 18:29:40 +0800 Subject: [PATCH 04/40] 2017 8.27 --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 9feabf1..22bead7 100644 --- a/Readme.md +++ b/Readme.md @@ -810,6 +810,7 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) ## 1 事务 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 +彻底理解数据库事务: http://www.hollischuang.com/archives/898 ## 2 数据库索引 From 15bff06ac40f0ef1f8a3e055d060effdea247605 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sun, 27 Aug 2017 22:47:55 +0800 Subject: [PATCH 05/40] 2017 8.27 --- Readme.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 22bead7..2df0a92 100644 --- a/Readme.md +++ b/Readme.md @@ -830,8 +830,11 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 +乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html + ## 5 MVCC +轻松理解MYSQL MVCC的实现机制: http://blog.csdn.net/whoamiyang/article/details/51901888 ## 6 MyISAM和InnoDB @@ -839,11 +842,14 @@ MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操 InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。 +mysql 数据库引擎: http://www.cnblogs.com/0201zcr/p/5296843.html +MySQL存储引擎--MyISAM与InnoDB区别: https://segmentfault.com/a/1190000008227211 + # 网络 ## 1 三次握手 -1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。 +1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为随机数 A。 2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。 3. 最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。 @@ -856,6 +862,8 @@ _注意: 中断连接端可以是客户端,也可以是服务器端. 下面仅 3. 服务器等到所有数据传输结束, 向客户端发送一个带有 FIN = 1 的数据分段, 并进入 CLOSE-WAIT 状态, 等待客户端发来带有 ACK = 1 的确认报文. 4. 客户端收到服务器发来带有 FIN = 1 的报文, 返回 ACK = 1 的报文确认, 为了防止服务器端未收到需要重发, 进入 TIME-WAIT 状态. 服务器接收到报文后关闭连接. 客户端等待 2MSL 后未收到回复, 则认为服务器成功关闭, 客户端关闭连接. +图解: http://blog.csdn.net/whuslei/article/details/6667471 + ## 3 ARP协议 地址解析协议(Address Resolution Protocol),其基本功能为透过目标设备的IP地址,查询目标的MAC地址,以保证通信的顺利进行。它是IPv4网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代。 From dabdf8effa2fa11836b126a99ffba43ae9af793a Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 28 Aug 2017 12:09:26 +0800 Subject: [PATCH 06/40] 2017 8.28 --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 2df0a92..3ff27ca 100644 --- a/Readme.md +++ b/Readme.md @@ -988,7 +988,7 @@ WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务 ## 17 c10k问题 所谓c10k问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent 10 000 connection(这也是c10k这个名字的由来)。 -推荐: http://www.kegel.com/c10k.html +推荐: https://my.oschina.net/xianggao/blog/664275 ## 18 socket From d6b759a2a9f12973bdfba4b5d8b09daaa8df4295 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 28 Aug 2017 12:40:11 +0800 Subject: [PATCH 07/40] 2017 8.28 --- Readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Readme.md b/Readme.md index 3ff27ca..c4edd98 100644 --- a/Readme.md +++ b/Readme.md @@ -1040,6 +1040,9 @@ AVL是严格平衡树,因此在增加或者删除节点的时候,根据不 所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。 +红黑树详解: https://xieguanglei.github.io/blog/post/red-black-tree.html +教你透彻了解红黑树: https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/03.01.md + # 编程题 ## 1 台阶问题/斐波纳挈 From c2947cdbb7e269b304030ee6dfe9d4913293574c Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 28 Aug 2017 12:41:36 +0800 Subject: [PATCH 08/40] 2017 8.28 --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index c4edd98..28db32b 100644 --- a/Readme.md +++ b/Readme.md @@ -1041,6 +1041,7 @@ AVL是严格平衡树,因此在增加或者删除节点的时候,根据不 所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。 红黑树详解: https://xieguanglei.github.io/blog/post/red-black-tree.html + 教你透彻了解红黑树: https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/03.01.md # 编程题 From 2235846b5820989d53be7ce78ba3fef4d7a5bdf6 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Tue, 29 Aug 2017 23:23:17 +0800 Subject: [PATCH 09/40] 2017 8.29 --- Readme.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 28db32b..28c6cf9 100644 --- a/Readme.md +++ b/Readme.md @@ -1160,7 +1160,11 @@ l2 = [] [l2.append(i) for i in l1 if not i in l2] ``` -面试官提到的,先排序然后删除. +sorted排序并且用列表推导式. + +l = ['b','c','d','b','c','a','a'] +[single.append(i) for i in sorted(l) if i not in single] +print single ## 6 链表成对调换 @@ -1184,6 +1188,35 @@ class Solution: return head ``` +```python +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class nonrecurse(head): + if head is None or head.next is None: + return head + pre = None + cur = head + h = head + while cur: + h = cur + + temp = cur.next + cur.next = pre + + pre = cur + cur = temp + return h + + +``` + +思路: http://blog.csdn.net/feliciafay/article/details/6841115 +方法: http://www.xuebuyuan.com/2066385.html?mobile=1 + + ## 7 创建字典的方法 ### 1 直接创建 @@ -1236,6 +1269,20 @@ def recursion_merge_sort2(l1, l2): 循环算法 +思路: + +定义一个新的空列表 + +比较两个列表的首个元素 + +小的就插入到新列表里 + +把已经插入新列表的元素从旧列表删除 + +直到两个旧列表有一个为空 + +再把旧列表加到新列表后面 + ```pyhton def loop_merge_sort(l1, l2): tmp = [] @@ -1284,6 +1331,42 @@ def node(l1, l2): l2 = l2.next ``` +修改了一下: +``` +#coding:utf-8 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +def node(l1, l2): + length1, length2 = 0, 0 + # 求两个链表长度 + while l1.next: + l1 = l1.next#尾节点 + length1 += 1 + while l2.next: + l2 = l2.next#尾节点 + length2 += 1 + + #如果相交 + if l1.next == l2.next: + # 长的链表先走 + if length1 > length2: + for _ in range(length1 - length2): + l1 = l1.next + return l1#返回交点 + else: + for _ in range(length2 - length1): + l2 = l2.next + return l2#返回交点 + # 如果不相交 + else: + return +``` + +思路: http://humaoli.blog.163.com/blog/static/13346651820141125102125995/ + ## 10 二分查找 ```python From 9a26878e75977f23718b94c4585a2613c3ef9879 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Tue, 29 Aug 2017 23:26:50 +0800 Subject: [PATCH 10/40] 2017 8.29 --- Readme.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 28c6cf9..f1c9e78 100644 --- a/Readme.md +++ b/Readme.md @@ -1283,6 +1283,7 @@ def recursion_merge_sort2(l1, l2): 再把旧列表加到新列表后面 + ```pyhton def loop_merge_sort(l1, l2): tmp = [] @@ -1298,6 +1299,7 @@ def loop_merge_sort(l1, l2): return tmp ``` + ## 9 交叉链表求交点 去哪儿的面试,没做出来. @@ -1332,7 +1334,9 @@ def node(l1, l2): ``` 修改了一下: -``` + + +```python #coding:utf-8 class ListNode: def __init__(self, x): @@ -1365,8 +1369,10 @@ def node(l1, l2): return ``` + 思路: http://humaoli.blog.163.com/blog/static/13346651820141125102125995/ + ## 10 二分查找 ```python From c1571c8e07297065bc0a85fb13195a01977b63a9 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Tue, 29 Aug 2017 23:56:20 +0800 Subject: [PATCH 11/40] 2017 8.29 --- Readme.md | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Readme.md b/Readme.md index f1c9e78..6a852e2 100644 --- a/Readme.md +++ b/Readme.md @@ -1375,28 +1375,30 @@ def node(l1, l2): ## 10 二分查找 + ```python -def binarySearch(l, t): - low, high = 0, len(l) - 1 - while low < high: - print low, high - mid = (low + high) / 2 - if l[mid] > t: - high = mid - elif l[mid] < t: - low = mid + 1 + +#coding:utf-8 +def binary_search(list,item): + low = 0 + high = len(list)-1 + while low<=high: + mid = (low+high)/2 + guess = list[mid] + if guess>item: + high = mid-1 + elif guess Date: Wed, 30 Aug 2017 11:48:46 +0800 Subject: [PATCH 12/40] 2017 8.30 --- Readme.md | 62 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/Readme.md b/Readme.md index 6a852e2..2e499dc 100644 --- a/Readme.md +++ b/Readme.md @@ -1402,45 +1402,51 @@ print binary_search(mylist,3) ## 11 快排 ```python -def qsort(seq): - if seq==[]: - return [] +#coding:utf-8 +def quicksort(list): + if len(list)<2: + return list else: - pivot=seq[0] - lesser=qsort([x for x in seq[1:] if x=pivot]) - return lesser+[pivot]+greater - -if __name__=='__main__': - seq=[5,6,78,9,0,-1,2,3,-65,12] - print(qsort(seq)) + midpivot = list[0] + lessbeforemidpivot = [i for i in list[1:] if i<=midpivot] + biggerafterpivot = [i for i in list[1:] if i > midpivot] + finallylist = quicksort(lessbeforemidpivot)+[midpivot]+quicksort(biggerafterpivot) + return finallylist + +print quicksort([2,4,6,7,1,2,5]) ``` +递归基本思想: http://blog.csdn.net/morewindows/article/details/6684558 + ## 12 找零问题 + ```python -def coinChange(values, money, coinsUsed): - #values T[1:n]数组 - #valuesCounts 钱币对应的种类数 - #money 找出来的总钱数 - #coinsUsed 对应于目前钱币总数i所使用的硬币数目 - for cents in range(1, money+1): - minCoins = cents #从第一个开始到money的所有情况初始 - for value in values: - if value <= cents: - temp = coinsUsed[cents - value] + 1 - if temp < minCoins: + +#coding:utf-8 +#values是硬币的面值values = [ 25, 21, 10, 5, 1] +#valuesCounts 钱币对应的种类数 +#money 找出来的总钱数 +#coinsUsed 对应于目前钱币总数i所使用的硬币数目 + +def coinChange(values,valuesCounts,money,coinsUsed): + #遍历出从1到money所有的钱数可能 + for cents in range(1,money+1): + minCoins = cents + #把所有的硬币面值遍历出来和钱数做对比 + for kind in range(0,valuesCounts): + if (values[kind] <= cents): + temp = coinsUsed[cents - values[kind]] +1 + if (temp < minCoins): minCoins = temp coinsUsed[cents] = minCoins - print('面值为:{0} 的最小硬币数目为:{1} '.format(cents, coinsUsed[cents]) ) + print ('面值:{0}的最少硬币使用数为:{1}'.format(cents, coinsUsed[cents])) -if __name__ == '__main__': - values = [ 25, 21, 10, 5, 1] - money = 63 - coinsUsed = {i:0 for i in range(money+1)} - coinChange(values, money, coinsUsed) ``` +思路: http://blog.csdn.net/wdxin1322/article/details/9501163 +方法: http://www.cnblogs.com/ChenxofHit/archive/2011/03/18/1988431.html + ## 13 广度遍历和深度遍历二叉树 给定一个数组,构建二叉树,并且按层次打印这个二叉树 From 139b225e58a6bcd09b45b3f675afe1eb4b628193 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Wed, 30 Aug 2017 11:55:18 +0800 Subject: [PATCH 13/40] 2017 8.30 --- Readme.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 2e499dc..0f14b15 100644 --- a/Readme.md +++ b/Readme.md @@ -1445,14 +1445,18 @@ def coinChange(values,valuesCounts,money,coinsUsed): ``` 思路: http://blog.csdn.net/wdxin1322/article/details/9501163 + 方法: http://www.cnblogs.com/ChenxofHit/archive/2011/03/18/1988431.html ## 13 广度遍历和深度遍历二叉树 给定一个数组,构建二叉树,并且按层次打印这个二叉树 -```python + ## 14 二叉树节点 + +```python + class Node(object): def __init__(self, data, left=None, right=None): self.data = data @@ -1461,7 +1465,12 @@ class Node(object): tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4))) +``` + ## 15 层次遍历 + +```python + def lookup(root): stack = [root] while stack: @@ -1471,7 +1480,13 @@ def lookup(root): stack.append(current.left) if current.right: stack.append(current.right) + +``` + ## 16 深度遍历 + +```python + def deep(root): if not root: return From f81d0263f8101e1e7e2f52eb16d300c24d069efa Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Wed, 30 Aug 2017 23:43:14 +0800 Subject: [PATCH 14/40] 2017 8.30 --- Readme.md | 75 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/Readme.md b/Readme.md index 0f14b15..83db54b 100644 --- a/Readme.md +++ b/Readme.md @@ -1188,35 +1188,6 @@ class Solution: return head ``` -```python -class ListNode: - def __init__(self, x): - self.val = x - self.next = None - -class nonrecurse(head): - if head is None or head.next is None: - return head - pre = None - cur = head - h = head - while cur: - h = cur - - temp = cur.next - cur.next = pre - - pre = cur - cur = temp - return h - - -``` - -思路: http://blog.csdn.net/feliciafay/article/details/6841115 -方法: http://www.xuebuyuan.com/2066385.html?mobile=1 - - ## 7 创建字典的方法 ### 1 直接创建 @@ -1503,6 +1474,47 @@ if __name__ == '__main__': 深度遍历改变顺序就OK了 +```python + +#coding:utf-8 +#二叉树的遍历 +#简单的二叉树节点类 +class Node(object): + def __init__(self,value,left,right): + self.value = value + self.left = left + self.right = right + +#中序遍历:遍历左子树,访问当前节点,遍历右子树 + +def mid_travelsal(root): + if root.left is None: + mid_travelsal(root.left) + #访问当前节点 + print(root.value) + if root.right is not None: + mid_travelsal(root.right) + +#前序遍历:访问当前节点,遍历左子树,遍历右子树 + +def pre_travelsal(root): + print (root.value) + if root.left is not None: + pre_travelsal(root.left) + if root.right is not None: + pre_travelsal(root.right) + +#后续遍历:遍历左子树,遍历右子树,访问当前节点 + +def post_trvelsal(root): + if root.left is not None: + post_trvelsal(root.left) + if root.right is not None: + post_trvelsal(root.right) + print (root.value) + +``` + ## 18 求最大树深 ```python @@ -1573,6 +1585,11 @@ while root: root = root.next ``` +思路: http://blog.csdn.net/feliciafay/article/details/6841115 + +方法: http://www.xuebuyuan.com/2066385.html?mobile=1 + + ## 22 两个字符串是否是变位词 ```python From 2dd0d0e7037dbfd246f3defb548179b98826c98d Mon Sep 17 00:00:00 2001 From: MrLevo520 Date: Tue, 5 Sep 2017 09:45:39 +0800 Subject: [PATCH 15/40] update README.md --- Readme.md | 338 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 193 insertions(+), 145 deletions(-) diff --git a/Readme.md b/Readme.md index 85b889c..77a220e 100644 --- a/Readme.md +++ b/Readme.md @@ -1,120 +1,14 @@ **Table of Contents** -- [Python语言特性](#python语言特性) - - [1 Python的函数参数传递](#1-python的函数参数传递) - - [2 Python中的元类(metaclass)](#2-python中的元类metaclass) - - [3 @staticmethod和@classmethod](#3-staticmethod和classmethod) - - [4 类变量和实例变量](#4-类变量和实例变量) - - [5 Python自省](#5-python自省) - - [6 字典推导式](#6-字典推导式) - - [7 Python中单下划线和双下划线](#7-python中单下划线和双下划线) - - [8 字符串格式化:%和.format](#8-字符串格式化和format) - - [9 迭代器和生成器](#9-迭代器和生成器) - - [10 `*args` and `**kwargs`](#10-args-and-kwargs) - - [11 面向切面编程AOP和装饰器](#11-面向切面编程aop和装饰器) - - [12 鸭子类型](#12-鸭子类型) - - [13 Python中重载](#13-python中重载) - - [14 新式类和旧式类](#14-新式类和旧式类) - - [15 `__new__`和`__init__`的区别](#15-__new__和__init__的区别) - - [16 单例模式](#16-单例模式) - - [1 使用`__new__`方法](#1-使用__new__方法) - - [2 共享属性](#2-共享属性) - - [3 装饰器版本](#3-装饰器版本) - - [4 import方法](#4-import方法) - - [17 Python中的作用域](#17-python中的作用域) - - [18 GIL线程全局锁](#18-gil线程全局锁) - - [19 协程](#19-协程) - - [20 闭包](#20-闭包) - - [21 lambda函数](#21-lambda函数) - - [22 Python函数式编程](#22-python函数式编程) - - [23 Python里的拷贝](#23-python里的拷贝) - - [24 Python垃圾回收机制](#24-python垃圾回收机制) - - [1 引用计数](#1-引用计数) - - [2 标记-清除机制](#2-标记-清除机制) - - [3 分代技术](#3-分代技术) - - [25 Python的List](#25-python的list) - - [26 Python的is](#26-python的is) - - [27 read,readline和readlines](#27-readreadline和readlines) - - [28 Python2和3的区别](#28-python2和3的区别) - - [29 super.`__init__`()](#29-super-init) - - [30 range-and-xrange](#30-range-and-xrange) -- [操作系统](#操作系统) - - [1 select,poll和epoll](#1-selectpoll和epoll) - - [2 调度算法](#2-调度算法) - - [3 死锁](#3-死锁) - - [4 程序编译与链接](#4-程序编译与链接) - - [1 预处理](#1-预处理) - - [2 编译](#2-编译) - - [3 汇编](#3-汇编) - - [4 链接](#4-链接) - - [5 静态链接和动态链接](#5-静态链接和动态链接) - - [6 虚拟内存技术](#6-虚拟内存技术) - - [7 分页和分段](#7-分页和分段) - - [分页与分段的主要区别](#分页与分段的主要区别) - - [8 页面置换算法](#8-页面置换算法) - - [9 边沿触发和水平触发](#9-边沿触发和水平触发) -- [数据库](#数据库) - - [1 事务](#1-事务) - - [2 数据库索引](#2-数据库索引) - - [3 Redis原理](#3-redis原理) - - [4 乐观锁和悲观锁](#4-乐观锁和悲观锁) - - [5 MVCC](#5-mvcc) - - [6 MyISAM和InnoDB](#6-myisam和innodb) -- [网络](#网络) - - [1 三次握手](#1-三次握手) - - [2 四次挥手](#2-四次挥手) - - [3 ARP协议](#3-arp协议) - - [4 urllib和urllib2的区别](#4-urllib和urllib2的区别) - - [5 Post和Get](#5-post和get) - - [6 Cookie和Session](#6-cookie和session) - - [7 apache和nginx的区别](#7-apache和nginx的区别) - - [8 网站用户密码保存](#8-网站用户密码保存) - - [9 HTTP和HTTPS](#9-http和https) - - [10 XSRF和XSS](#10-xsrf和xss) - - [11 幂等 Idempotence](#11-幂等-idempotence) - - [12 RESTful架构(SOAP,RPC)](#12-restful架构soaprpc) - - [13 SOAP](#13-soap) - - [14 RPC](#14-rpc) - - [15 CGI和WSGI](#15-cgi和wsgi) - - [16 中间人攻击](#16-中间人攻击) - - [17 c10k问题](#17-c10k问题) - - [18 socket](#18-socket) - - [19 浏览器缓存](#19-浏览器缓存) - - [20 HTTP1.0和HTTP1.1](#20-http10和http11) - - [21 Ajax](#21-ajax) -- [*NIX](#nix) - - [unix进程间通信方式(IPC)](#unixipc) -- [数据结构](#数据结构) - - [1 红黑树](#1-红黑树) -- [编程题](#编程题) - - [1 台阶问题/斐波纳挈](#1-台阶问题斐波纳挈) - - [2 变态台阶问题](#2-变态台阶问题) - - [3 矩形覆盖](#3-矩形覆盖) - - [4 杨氏矩阵查找](#4-杨氏矩阵查找) - - [5 去除列表中的重复元素](#5-去除列表中的重复元素) - - [6 链表成对调换](#6-链表成对调换) - - [7 创建字典的方法](#7-创建字典的方法) - - [1 直接创建](#1-直接创建) - - [2 工厂方法](#2-工厂方法) - - [3 fromkeys()方法](#3-fromkeys方法) - - [8 合并两个有序列表](#8-合并两个有序列表) - - [9 交叉链表求交点](#9-交叉链表求交点) - - [10 二分查找](#10-二分查找) - - [11 快排](#11-快排) - - [12 找零问题](#12-找零问题) - - [13 广度遍历和深度遍历二叉树](#13-广度遍历和深度遍历二叉树) - - [14 二叉树节点](#14-) - - [15 层次遍历](#15-) - - [16 深度遍历](#16-) - - [17 前中后序遍历](#17-前中后序遍历) - - [18 求最大树深](#18-求最大树深) - - [19 求两棵树是否相同](#19-求两棵树是否相同) - - [20 前序中序求后序](#20-前序中序求后序) - - [21 单链表逆置](#21-单链表逆置) - - [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) +[TOC] + + + + + # Python语言特性 ## 1 Python的函数参数传递 @@ -206,15 +100,41 @@ a=A() 对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用`a.static_foo(x)`或者`A.static_foo(x)`来调用. -|\\|实例方法|类方法|静态方法| -|:--|:--|:--|:--| -|a = A()|a.foo(x)|a.class_foo(x)|a.static_foo(x)| -|A|不可用|A.class_foo(x)|A.static_foo(x)| +| \\ | 实例方法 | 类方法 | 静态方法 | +| :------ | :------- | :------------- | :-------------- | +| a = A() | a.foo(x) | a.class_foo(x) | a.static_foo(x) | +| A | 不可用 | A.class_foo(x) | A.static_foo(x) | 更多关于这个问题:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python ## 4 类变量和实例变量 +**类变量:** + +> ​ 是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。例如下例中,num_of_instance 就是类变量,用于跟踪存在着多少个Test 的实例。 + +**实例变量:** + +> 实例化之后,每个实例单独拥有的变量。 + +```python +class Test(object): + num_of_instance = 0 + def __init__(self, name): + self.name = name + Test.num_of_instance += 1 + +if __name__ == '__main__': + print Test.num_of_instance # 0 + t1 = Test('jack') + print Test.num_of_instance # 1 + t2 = Test('lucy') + print t1.name , t1.num_of_instance # jack 2 + print t2.name , t2.num_of_instance # lucy 2 +``` + +> 补充的例子 + ```python class Person: name="aaa" @@ -227,8 +147,6 @@ print p2.name # aaa print Person.name # aaa ``` -类变量就是供类使用的变量,实例变量就是供实例使用的. - 这里`p1.name="bbb"`是实例调用了类变量,这其实和上面第一个问题一样,就是函数传参的问题,`p1.name`一开始是指向的类变量`name="aaa"`,但是在实例的作用域里把类变量的引用改变了,就变成了一个实例变量,self.name不再引用Person的类变量name了. 可以看看下面的例子: @@ -253,6 +171,16 @@ print Person.name # [1] 自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance(). +```python +a = [1,2,3] +b = {'a':1,'b':2,'c':3} +c = True +print type(a),type(b),type(c) # +print isinstance(a,list) # True +``` + + + ## 6 字典推导式 可能你见过列表推导时,却没有见过字典推导式,在2.7中才加入的: @@ -280,11 +208,11 @@ AttributeError: myClass instance has no attribute '__superprivate' {'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'} ``` -`__foo__`:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突. +`__foo__`:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如`__init__()`,`__del__()`,`__call__()`这些特殊方法 -`_foo`:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式. +`_foo`:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.不能用from module import * 导入,其他方面和公有一样访问; -`__foo`:这个有真正的意义:解析器用`_classname__foo`来代替这个名字,以区别和其他类相同的命名. +`__foo`:这个有真正的意义:解析器用`_classname__foo`来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._类名__xxx这样的方式可以访问. 详情见:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python @@ -421,6 +349,31 @@ http://stackoverflow.com/questions/3394835/args-and-kwargs 新式类很早在2.2就出现了,所以旧式类完全是兼容的问题,Python3里的类全部都是新式类.这里有一个MRO问题可以了解下(新式类是广度优先,旧式类是深度优先),里讲的也很多. +> 一个旧式类的深度优先的例子 + +```python +class A(): + def foo1(self): + print "A" +class B(A): + def foo2(self): + pass +class C(A): + def foo1(self): + print "C" +class D(B, C): + pass + +d = D() +d.foo1() + +# A +``` + +**按照经典类的查找顺序`从左到右深度优先`的规则,在访问`d.foo1()`的时候,D这个类是没有的..那么往上查找,先找到B,里面没有,深度优先,访问A,找到了foo1(),所以这时候调用的是A的foo1(),从而导致C重写的foo1()被绕过** + + + ## 15 `__new__`和`__init__`的区别 这个`__new__`确实很少见到,先做了解吧. @@ -428,7 +381,7 @@ http://stackoverflow.com/questions/3394835/args-and-kwargs 1. `__new__`是一个静态方法,而`__init__`是一个实例方法. 2. `__new__`方法会返回一个创建的实例,而`__init__`什么都不返回. 3. 只有在`__new__`返回一个cls的实例时后面的`__init__`才能被调用. -3. 当创建一个新实例时调用`__new__`,初始化一个实例时用`__init__`. +4. 当创建一个新实例时调用`__new__`,初始化一个实例时用`__init__`. [stackoverflow](http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init) @@ -436,7 +389,11 @@ ps: `__metaclass__`是创建类时起作用.所以我们可以分别使用`__met ## 16 单例模式 -这个绝对常考啊.绝对要记住1~2个方法,当时面试官是让手写的. +> ​ 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 +> +> `__new__()`在`__init__()`之前被调用,用于生成实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。单例模式是指创建唯一对象,单例模式设计的类只能实例 + +**这个绝对常考啊.绝对要记住1~2个方法,当时面试官是让手写的.** ### 1 使用`__new__`方法 @@ -471,8 +428,6 @@ class MyClass2(Borg): ### 3 装饰器版本 - - ```python def singleton(cls, *args, **kw): instances = {} @@ -516,7 +471,7 @@ Python 中,一个变量的作用域总是由在代码中被赋值的地方所 ## 18 GIL线程全局锁 -线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程. +线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.**对于io密集型任务,python的多线程起到作用,但对于cpu密集型任务,python的多线程几乎占不到任何优势,还有可能因为争夺资源而变慢。** 见[Python 最难的问题](http://www.oschina.net/translate/pythons-hardest-problem) @@ -668,6 +623,8 @@ Note that the syntax changed in Python 3.0: you can just say super().`__init__`( http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods +[Python2.7中的super方法浅见](http://blog.csdn.net/mrlevo520/article/details/51712440) + ## 30 range and xrange 都在循环时使用,xrange内存性能更好。 for i in range(0, 20): @@ -816,9 +773,28 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) 聚集索引,非聚集索引,B-Tree,B+Tree,最左前缀原理 - ## 3 Redis原理 +### Redis是什么? + +1. 是一个完全开源免费的key-value内存数据库 +2. 通常被认为是一个数据结构服务器,主要是因为其有着丰富的数据结构 strings、map、 list、sets、 sorted sets + +### Redis数据库 + +> ​ 通常局限点来说,Redis也以消息队列的形式存在,作为内嵌的List存在,满足实时的高并发需求。在使用缓存的时候,redis比memcached具有更多的优势,并且支持更多的数据类型,把redis当作一个中间存储系统,用来处理高并发的数据库操作 + +- 速度快:使用标准C写,所有数据都在内存中完成,读写速度分别达到10万/20万 +- 持久化:对数据的更新采用Copy-on-write技术,可以异步地保存到磁盘上,主要有两种策略,一是根据时间,更新次数的快照(save 300 10 )二是基于语句追加方式(Append-only file,aof) +- 自动操作:对不同数据类型的操作都是自动的,很安全 +- 快速的主--从复制,官方提供了一个数据,Slave在21秒即完成了对Amazon网站10G key set的复制。 +- Sharding技术: 很容易将数据分布到多个Redis实例中,数据库的扩展是个永恒的话题,在关系型数据库中,主要是以添加硬件、以分区为主要技术形式的纵向扩展解决了很多的应用场景,但随着web2.0、移动互联网、云计算等应用的兴起,这种扩展模式已经不太适合了,所以近年来,像采用主从配置、数据库复制形式的,Sharding这种技术把负载分布到多个特理节点上去的横向扩展方式用处越来越多。 + +### Redis缺点 + +- 是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。 +- Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。 + ## 4 乐观锁和悲观锁 @@ -828,6 +804,27 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) ## 5 MVCC +> ​ 全称是Multi-Version Concurrent Control,即多版本并发控制,在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。 + +### [MySQL](http://lib.csdn.net/base/mysql)的innodb引擎是如何实现MVCC的 + +innodb会为每一行添加两个字段,分别表示该行**创建的版本**和**删除的版本**,填入的是事务的版本号,这个版本号随着事务的创建不断递增。在repeated read的隔离级别([事务的隔离级别请看这篇文章](http://blog.csdn.net/chosen0ne/article/details/10036775))下,具体各种数据库操作的实现: + +- select:满足以下两个条件innodb会返回该行数据: + - 该行的创建版本号小于等于当前版本号,用于保证在select操作之前所有的操作已经执行落地。 + - 该行的删除版本号大于当前版本或者为空。删除版本号大于当前版本意味着有一个并发事务将该行删除了。 +- insert:将新插入的行的创建版本号设置为当前系统的版本号。 +- delete:将要删除的行的删除版本号设置为当前系统的版本号。 +- update:不执行原地update,而是转换成insert + delete。将旧行的删除版本号设置为当前版本号,并将新行insert同时设置创建版本号为当前版本号。 + +其中,写操作(insert、delete和update)执行时,需要将系统版本号递增。 + +​ 由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。 + +通过MVCC很好的实现了事务的隔离性,可以达到repeated read级别,要实现serializable还必须加锁。 + +> 参考:[MVCC浅析](http://blog.csdn.net/chosen0ne/article/details/18093187) + ## 6 MyISAM和InnoDB @@ -875,11 +872,11 @@ post: [RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1](http://tools.ietf.org ## 6 Cookie和Session -||Cookie|Session| -|:--|:--|:--| -|储存位置|客户端|服务器端| -|目的|跟踪会话,也可以保存用户偏好设置或者保存用户名密码等|跟踪会话| -|安全性|不安全|安全| +| | Cookie | Session | +| :--- | :------------------------- | :------ | +| 储存位置 | 客户端 | 服务器端 | +| 目的 | 跟踪会话,也可以保存用户偏好设置或者保存用户名密码等 | 跟踪会话 | +| 安全性 | 不安全 | 安全 | session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。 @@ -908,13 +905,13 @@ apache 相对nginx 的优点: ## 9 HTTP和HTTPS -|状态码|定义| -|:--|:--| -|1xx 报告|接收到请求,继续进程| -|2xx 成功|步骤成功接收,被理解,并被接受| -|3xx 重定向|为了完成请求,必须采取进一步措施| -|4xx 客户端出错|请求包括错的顺序或不能完成| -|5xx 服务器出错|服务器无法完成显然有效的请求| +| 状态码 | 定义 | +| :-------- | :--------------- | +| 1xx 报告 | 接收到请求,继续进程 | +| 2xx 成功 | 步骤成功接收,被理解,并被接受 | +| 3xx 重定向 | 为了完成请求,必须采取进一步措施 | +| 4xx 客户端出错 | 请求包括错的顺序或不能完成 | +| 5xx 服务器出错 | 服务器无法完成显然有效的请求 | 403: Forbidden 404: Not Found @@ -997,7 +994,7 @@ Socket=Ip address+ TCP/UDP + port 1. 请求头Host字段,一个服务器多个网站 2. 长链接 3. 文件断点续传 -3. 身份认证,状态管理,Cache缓存 +4. 身份认证,状态管理,Cache缓存 ## 21 Ajax AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。 @@ -1030,7 +1027,7 @@ AVL是严格平衡树,因此在增加或者删除节点的时候,根据不 # 编程题 -## 1 台阶问题/斐波纳挈 +## 1 台阶问题/斐波那契 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 @@ -1197,7 +1194,7 @@ dict2={'x':None, 'y':None} 知乎远程面试要求编程 -尾递归 +> 尾递归 ```python def _recursion_merge_sort2(l1, l2, tmp): @@ -1218,7 +1215,7 @@ def recursion_merge_sort2(l1, l2): return _recursion_merge_sort2(l1, l2, []) ``` -循环算法 +> 循环算法 ```pyhton def loop_merge_sort(l1, l2): @@ -1235,9 +1232,54 @@ def loop_merge_sort(l1, l2): return tmp ``` +> pop弹出 + +```Python +a = [1,2,3,7] +b = [3,4,5] + +def merge_sortedlist(a,b): + c = [] + while a and b: + if a[0] >= b[0]: + c.append(b.pop(0)) + else: + c.append(a.pop(0)) + while a: + c.append(a.pop(0)) + while b: + c.append(b.pop(0)) + return c +print merge_sortedlist(a,b) + +``` + + + ## 9 交叉链表求交点 -去哪儿的面试,没做出来. +> 其实思想可以按照从尾开始比较两个链表,如果相交,则从尾开始必然一致,只要从尾开始比较,直至不一致的地方即为交叉点,如图所示 + +![](http://hi.csdn.net/attachment/201106/28/0_1309244136MWLP.gif) + +```python +# 使用a,b两个list来模拟链表,可以看出交叉点是 7这个节点 +a = [1,2,3,7,9,1,5] +b = [4,5,7,9,1,5] + +for i in range(1,min(len(a),len(b))): + if i==1 and (a[-1] != b[-1]): + print "No" + break + else: + if a[-i] != b[-i]: + print "交叉节点:",a[-i+1] + break + else: + pass +``` + +> 另外一种比较正规的方法,构造链表类 ```python class ListNode: @@ -1309,6 +1351,8 @@ if __name__=='__main__': print(qsort(seq)) ``` +> 更多排序问题可见:[数据结构与算法-排序篇-Python描述](http://blog.csdn.net/mrlevo520/article/details/77829204) + ## 12 找零问题 ```python @@ -1524,7 +1568,11 @@ class Anagram: return stillOK print(Solution3('apple','pleap')) - ``` + +## 23 动态规划问题 + +> 可参考:[动态规划(DP)的整理-Python描述](http://blog.csdn.net/mrlevo520/article/details/75676160) + From 7dbcdefdcace895006567d20529619acb657312c Mon Sep 17 00:00:00 2001 From: MrLevo520 Date: Tue, 5 Sep 2017 10:09:34 +0800 Subject: [PATCH 16/40] update README.md --- Readme.md | 2 +- gh-md-toc | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100755 gh-md-toc diff --git a/Readme.md b/Readme.md index 77a220e..dfaf6f8 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ **Table of Contents** -[TOC] + diff --git a/gh-md-toc b/gh-md-toc new file mode 100755 index 0000000..e0c3cb1 --- /dev/null +++ b/gh-md-toc @@ -0,0 +1,189 @@ +#!/usr/bin/env bash + +# +# Steps: +# +# 1. Download corresponding html file for some README.md: +# curl -s $1 +# +# 2. Discard rows where no substring 'user-content-' (github's markup): +# awk '/user-content-/ { ... +# +# 3.1 Get last number in each row like ' ... sitemap.js.*<\/h/)+2, RLENGTH-5) +# +# 5. Find anchor and insert it inside "(...)": +# substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8) +# + +gh_toc_version="0.4.8" + +gh_user_agent="gh-md-toc v$gh_toc_version" + +# +# Download rendered into html README.md by its url. +# +# +gh_toc_load() { + local gh_url=$1 + + if type curl &>/dev/null; then + curl --user-agent "$gh_user_agent" -s "$gh_url" + elif type wget &>/dev/null; then + wget --user-agent="$gh_user_agent" -qO- "$gh_url" + else + echo "Please, install 'curl' or 'wget' and try again." + exit 1 + fi +} + +# +# Converts local md file into html by GitHub +# +# ➥ curl -X POST --data '{"text": "Hello world github/linguist#1 **cool**, and #1!"}' https://api.github.com/markdown +#

Hello world github/linguist#1 cool, and #1!

'" +gh_toc_md2html() { + local gh_file_md=$1 + URL=https://api.github.com/markdown/raw + TOKEN="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/token.txt" + if [ -f "$TOKEN" ]; then + URL="$URL?access_token=$(cat $TOKEN)" + fi + curl -s --user-agent "$gh_user_agent" \ + --data-binary @"$gh_file_md" -H "Content-Type:text/plain" \ + $URL +} + +# +# Is passed string url +# +gh_is_url() { + case $1 in + https* | http*) + echo "yes";; + *) + echo "no";; + esac +} + +# +# TOC generator +# +gh_toc(){ + local gh_src=$1 + local gh_src_copy=$1 + local gh_ttl_docs=$2 + + if [ "$gh_src" = "" ]; then + echo "Please, enter URL or local path for a README.md" + exit 1 + fi + + + # Show "TOC" string only if working with one document + if [ "$gh_ttl_docs" = "1" ]; then + + echo "Table of Contents" + echo "=================" + echo "" + gh_src_copy="" + + fi + + if [ "$(gh_is_url "$gh_src")" == "yes" ]; then + gh_toc_load "$gh_src" | gh_toc_grab "$gh_src_copy" + else + gh_toc_md2html "$gh_src" | gh_toc_grab "$gh_src_copy" + fi +} + +# +# Grabber of the TOC from rendered html +# +# $1 — a source url of document. +# It's need if TOC is generated for multiple documents. +# +gh_toc_grab() { + # if closed is on the new line, then move it on the prev line + # for example: + # was: The command foo1 + # + # became: The command foo1 + sed -e ':a' -e 'N' -e '$!ba' -e 's/\n<\/h/<\/h/g' | + # find strings that corresponds to template + grep -E -o '//' | sed 's/<\/code>//' | + # now all rows are like: + # ... .*<\/h/)+2, RLENGTH-5)"](" gh_url substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8) ")"}' | sed 'y/+/ /; s/%/\\x/g')" +} + +# +# Returns filename only from full path or url +# +gh_toc_get_filename() { + echo "${1##*/}" +} + +# +# Options hendlers +# +gh_toc_app() { + local app_name="gh-md-toc" + + if [ "$1" = '--help' ] || [ $# -eq 0 ] ; then + echo "GitHub TOC generator ($app_name): $gh_toc_version" + echo "" + echo "Usage:" + echo " $app_name src [src] Create TOC for a README file (url or local path)" + echo " $app_name - Create TOC for markdown from STDIN" + echo " $app_name --help Show help" + echo " $app_name --version Show version" + return + fi + + if [ "$1" = '--version' ]; then + echo "$gh_toc_version" + return + fi + + if [ "$1" = "-" ]; then + if [ -z "$TMPDIR" ]; then + TMPDIR="/tmp" + elif [ -n "$TMPDIR" -a ! -d "$TMPDIR" ]; then + mkdir -p "$TMPDIR" + fi + local gh_tmp_md + gh_tmp_md=$(mktemp $TMPDIR/tmp.XXXXXX) + while read input; do + echo "$input" >> "$gh_tmp_md" + done + gh_toc_md2html "$gh_tmp_md" | gh_toc_grab "" + return + fi + + for md in "$@" + do + echo "" + gh_toc "$md" "$#" + done + + echo "" + echo "Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)" +} + +# +# Entry point +# +gh_toc_app "$@" From aa8a284eca43bce2f29b9f6959d32476a0cf7cfc Mon Sep 17 00:00:00 2001 From: MrLevo520 Date: Tue, 5 Sep 2017 10:43:08 +0800 Subject: [PATCH 17/40] update README.md --- Readme.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index dfaf6f8..6f1e471 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,120 @@ **Table of Contents** - + * [Python语言特性](#python语言特性) + * [1 Python的函数参数传递](#1-python的函数参数传递) + * [2 Python中的元类(metaclass)](#2-python中的元类metaclass) + * [3 @staticmethod和@classmethod](#3-staticmethod和classmethod) + * [4 类变量和实例变量](#4-类变量和实例变量) + * [5 Python自省](#5-python自省) + * [6 字典推导式](#6-字典推导式) + * [7 Python中单下划线和双下划线](#7-python中单下划线和双下划线) + * [8 字符串格式化:\x和.format](#8-字符串格式化和format) + * [9 迭代器和生成器](#9-迭代器和生成器) + * [10 *args and **kwargs](#10-args-and-kwargs) + * [11 面向切面编程AOP和装饰器](#11-面向切面编程aop和装饰器) + * [12 鸭子类型](#12-鸭子类型) + * [13 Python中重载](#13-python中重载) + * [14 新式类和旧式类](#14-新式类和旧式类) + * [15 __new__和__init__的区别](#15-__new__和__init__的区别) + * [16 单例模式](#16-单例模式) + * [1 使用__new__方法](#1-使用__new__方法) + * [2 共享属性](#2-共享属性) + * [3 装饰器版本](#3-装饰器版本) + * [4 import方法](#4-import方法) + * [17 Python中的作用域](#17-python中的作用域) + * [18 GIL线程全局锁](#18-gil线程全局锁) + * [19 协程](#19-协程) + * [20 闭包](#20-闭包) + * [21 lambda函数](#21-lambda函数) + * [22 Python函数式编程](#22-python函数式编程) + * [23 Python里的拷贝](#23-python里的拷贝) + * [24 Python垃圾回收机制](#24-python垃圾回收机制) + * [1 引用计数](#1-引用计数) + * [2 标记-清除机制](#2-标记-清除机制) + * [3 分代技术](#3-分代技术) + * [25 Python的List](#25-python的list) + * [26 Python的is](#26-python的is) + * [27 read,readline和readlines](#27-readreadline和readlines) + * [28 Python2和3的区别](#28-python2和3的区别) + * [29 super init](#29-super-init) + * [30 range and xrange](#30-range-and-xrange) + * [操作系统](#操作系统) + * [1 select,poll和epoll](#1-selectpoll和epoll) + * [2 调度算法](#2-调度算法) + * [3 死锁](#3-死锁) + * [4 程序编译与链接](#4-程序编译与链接) + * [1 预处理](#1-预处理) + * [2 编译](#2-编译) + * [3 汇编](#3-汇编) + * [4 链接](#4-链接) + * [5 静态链接和动态链接](#5-静态链接和动态链接) + * [6 虚拟内存技术](#6-虚拟内存技术) + * [7 分页和分段](#7-分页和分段) + * [分页与分段的主要区别](#分页与分段的主要区别) + * [8 页面置换算法](#8-页面置换算法) + * [9 边沿触发和水平触发](#9-边沿触发和水平触发) + * [数据库](#数据库) + * [1 事务](#1-事务) + * [2 数据库索引](#2-数据库索引) + * [3 Redis原理](#3-redis原理) + * [Redis是什么?](#redis是什么) + * [Redis数据库](#redis数据库) + * [Redis缺点](#redis缺点) + * [4 乐观锁和悲观锁](#4-乐观锁和悲观锁) + * [5 MVCC](#5-mvcc) + * [MySQL的innodb引擎是如何实现MVCC的](#mysql的innodb引擎是如何实现mvcc的) + * [6 MyISAM和InnoDB](#6-myisam和innodb) + * [网络](#网络) + * [1 三次握手](#1-三次握手) + * [2 四次挥手](#2-四次挥手) + * [3 ARP协议](#3-arp协议) + * [4 urllib和urllib2的区别](#4-urllib和urllib2的区别) + * [5 Post和Get](#5-post和get) + * [6 Cookie和Session](#6-cookie和session) + * [7 apache和nginx的区别](#7-apache和nginx的区别) + * [8 网站用户密码保存](#8-网站用户密码保存) + * [9 HTTP和HTTPS](#9-http和https) + * [10 XSRF和XSS](#10-xsrf和xss) + * [11 幂等 Idempotence](#11-幂等-idempotence) + * [12 RESTful架构(SOAP,RPC)](#12-restful架构soaprpc) + * [13 SOAP](#13-soap) + * [14 RPC](#14-rpc) + * [15 CGI和WSGI](#15-cgi和wsgi) + * [16 中间人攻击](#16-中间人攻击) + * [17 c10k问题](#17-c10k问题) + * [18 socket](#18-socket) + * [19 浏览器缓存](#19-浏览器缓存) + * [20 HTTP1.0和HTTP1.1](#20-http10和http11) + * [21 Ajax](#21-ajax) + * [*NIX](#nix) + * [unix进程间通信方式(IPC)](#unix进程间通信方式ipc) + * [数据结构](#数据结构) + * [1 红黑树](#1-红黑树) + * [编程题](#编程题) + * [1 台阶问题/斐波那契](#1-台阶问题斐波那契) + * [2 变态台阶问题](#2-变态台阶问题) + * [3 矩形覆盖](#3-矩形覆盖) + * [4 杨氏矩阵查找](#4-杨氏矩阵查找) + * [5 去除列表中的重复元素](#5-去除列表中的重复元素) + * [6 链表成对调换](#6-链表成对调换) + * [7 创建字典的方法](#7-创建字典的方法) + * [1 直接创建](#1-直接创建) + * [2 工厂方法](#2-工厂方法) + * [3 fromkeys()方法](#3-fromkeys方法) + * [8 合并两个有序列表](#8-合并两个有序列表) + * [9 交叉链表求交点](#9-交叉链表求交点) + * [10 二分查找](#10-二分查找) + * [11 快排](#11-快排) + * [12 找零问题](#12-找零问题) + * [13 广度遍历和深度遍历二叉树](#13-广度遍历和深度遍历二叉树) + * [17 前中后序遍历](#17-前中后序遍历) + * [18 求最大树深](#18-求最大树深) + * [19 求两棵树是否相同](#19-求两棵树是否相同) + * [20 前序中序求后序](#20-前序中序求后序) + * [21 单链表逆置](#21-单链表逆置) + * [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) + * [23 动态规划问题](#23-动态规划问题) From 884a4ba864935f4219c4c89413da62dd886b5116 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 25 Sep 2017 17:04:24 +0800 Subject: [PATCH 18/40] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E9=81=93?= =?UTF-8?q?=E5=89=91=E6=8C=87offer=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Readme.md b/Readme.md index 83db54b..100c659 100644 --- a/Readme.md +++ b/Readme.md @@ -113,6 +113,7 @@ - [20 前序中序求后序](#20-前序中序求后序) - [21 单链表逆置](#21-单链表逆置) - [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) + - [23 O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素](#23-O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素) # Python语言特性 @@ -1673,3 +1674,71 @@ class Anagram: ``` +## 23 O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素 + +```python +#定义栈结构,根据栈的后进先出特性,增加辅助栈,来存储当前状态下数据栈中的最小、最大元素。 +class Stack(object): + + def __init__(self): + self.data = [] + self.minValue = [] + self.maxValue = [] + + def push(self,data): + self.data.append(data) + if len(self.minValue)==0: + self.minValue.append(data) + else: + if data <= self.minValue[-1]: + self.minValue.append(data) + if len(self.maxValue)==0: + self.maxValue.append(data) + else: + if data>=self.maxValue[-1]: + self.maxValue.append(data) + + def pop(self): + if len(self.data)==0: + return None + else: + temp = self.data.pop() + if temp == self.minValue[-1]: + self.minValue.pop() + if temp == self.maxValue[-1]: + self.maxValue.pop() + return temp + + def min(self): + if len(self.data)==0: + return None + else: + return self.minValue[-1] + + def max(self): + if len(self.data)==0: + return None + else: + return self.maxValue[-1] + + def show(self): + print("stack data") + for data in self.data: + print(data) + print("min",self.min()) + print("max",self.max()) + +if __name__ == "__main__": + s = Stack() + s.push(2) + s.push(1) + s.show() + s.push(4) + s.push(3) + s.push(2) + s.show() + s.pop() + s.show() + s.pop() + s.show() +``` From 383926a408ebd3a987a0e7c1616681255cbc0b86 Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 25 Sep 2017 17:08:22 +0800 Subject: [PATCH 19/40] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E9=81=93?= =?UTF-8?q?=E5=89=91=E6=8C=87offer=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 100c659..ed544bd 100644 --- a/Readme.md +++ b/Readme.md @@ -113,7 +113,7 @@ - [20 前序中序求后序](#20-前序中序求后序) - [21 单链表逆置](#21-单链表逆置) - [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) - - [23 O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素](#23-O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素) + - [23 O(1)时间复杂度实现入栈出栈获得栈中最小元素最大元素](#23-O(1)时间复杂度实现入栈出栈获得栈中最小元素最大元素) # Python语言特性 From 393f22b78585ba5b9f239c0ad2c0fc0612c31c9c Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Mon, 25 Sep 2017 17:09:49 +0800 Subject: [PATCH 20/40] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E9=81=93?= =?UTF-8?q?=E5=89=91=E6=8C=87offer=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index ed544bd..e41a662 100644 --- a/Readme.md +++ b/Readme.md @@ -1674,7 +1674,7 @@ class Anagram: ``` -## 23 O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素 +## 23 O(1)时间复杂度实现入栈出栈获得栈中最小元素最大元素 ```python #定义栈结构,根据栈的后进先出特性,增加辅助栈,来存储当前状态下数据栈中的最小、最大元素。 From 80989d6ef6e4b7c43d75f8c503c3ce3c3d473d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B4=BE=E4=BC=9F=E5=B7=9D?= Date: Tue, 26 Sep 2017 11:13:15 -0500 Subject: [PATCH 21/40] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 6f1e471..376d3b4 100644 --- a/Readme.md +++ b/Readme.md @@ -175,7 +175,7 @@ fun(a) print a # [1] ``` -这里记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。(这就是这个问题的重点) +这里记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而 list, dict, set 等则是可以修改的对象。(这就是这个问题的重点) 当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用没半毛感觉.而第二个例子就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改. From ae97908293d4797742f5b9aaf6b693ccdf01a51d Mon Sep 17 00:00:00 2001 From: 584807419 <584807419@qq.com> Date: Sat, 30 Sep 2017 16:13:49 +0800 Subject: [PATCH 22/40] =?UTF-8?q?=E5=85=B3=E4=BA=8E=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=99=A8=E7=9A=84=E5=88=9B=E5=BB=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Readme.md b/Readme.md index e41a662..bd00216 100644 --- a/Readme.md +++ b/Readme.md @@ -320,6 +320,20 @@ http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format 这是中文版: http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/1/README.html +这里有个关于生成器的创建问题面试官有考: +问: 将列表生成式中[]改成() 之后数据结构是否改变? +答案:是,从列表变为生成器 + +```python +>>> L = [x*x for x in range(10)] +>>> L +[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] +>>> g = (x*x for x in range(10)) +>>> g + at 0x0000028F8B774200> +``` +通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator + ## 10 `*args` and `**kwargs` 用`*args`和`**kwargs`只是为了方便并没有强制使用它们. From 35124aae256a8fd3a4e9198590332cc5e5fb9c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=86?= <584807419@qq.com> Date: Tue, 3 Oct 2017 12:54:06 +0800 Subject: [PATCH 23/40] Update Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HTTP请求8种方法介绍 --- Readme.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Readme.md b/Readme.md index bd00216..5ee862c 100644 --- a/Readme.md +++ b/Readme.md @@ -1026,6 +1026,54 @@ Socket=Ip address+ TCP/UDP + port 3. 文件断点续传 3. 身份认证,状态管理,Cache缓存 +HTTP请求8种方法介绍 +HTTP/1.1协议中共定义了8种HTTP请求方法,HTTP请求方法也被叫做“请求动作”,不同的方法规定了不同的操作指定的资源方式。服务端也会根据不同的请求方法做不同的响应。 + +GET + +GET请求会显示请求指定的资源。一般来说GET方法应该只用于数据的读取,而不应当用于会产生副作用的非幂等的操作中。 + +GET会方法请求指定的页面信息,并返回响应主体,GET被认为是不安全的方法,因为GET方法会被网络蜘蛛等任意的访问。 + +HEAD + +HEAD方法与GET方法一样,都是向服务器发出指定资源的请求。但是,服务器在响应HEAD请求时不会回传资源的内容部分,即:响应主体。这样,我们可以不传输全部内容的情况下,就可以获取服务器的响应头信息。HEAD方法常被用于客户端查看服务器的性能。 + +POST + +POST请求会 向指定资源提交数据,请求服务器进行处理,如:表单数据提交、文件上传等,请求数据会被包含在请求体中。POST方法是非幂等的方法,因为这个请求可能会创建新的资源或/和修改现有资源。 + +PUT + +PUT请求会身向指定资源位置上传其最新内容,PUT方法是幂等的方法。通过该方法客户端可以将指定资源的最新数据传送给服务器取代指定的资源的内容。 + +DELETE + +DELETE请求用于请求服务器删除所请求URI(统一资源标识符,Uniform Resource Identifier)所标识的资源。DELETE请求后指定资源会被删除,DELETE方法也是幂等的。 + +CONNECT + +CONNECT方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。 + +OPTIONS + +OPTIONS请求与HEAD类似,一般也是用于客户端查看服务器的性能。 这个方法会请求服务器返回该资源所支持的所有HTTP请求方法,该方法会用’*’来代替资源名称,向服务器发送OPTIONS请求,可以测试服务器功能是否正常。JavaScript的XMLHttpRequest对象进行CORS跨域资源共享时,就是使用OPTIONS方法发送嗅探请求,以判断是否有对指定资源的访问权限。 允许 + +TRACE + +TRACE请求服务器回显其收到的请求信息,该方法主要用于HTTP请求的测试或诊断。 + +HTTP/1.1之后增加的方法 + +在HTTP/1.1标准制定之后,又陆续扩展了一些方法。其中使用中较多的是 PATCH 方法: + +PATCH + +PATCH方法出现的较晚,它在2010年的RFC 5789标准中被定义。PATCH请求与PUT请求类似,同样用于资源的更新。二者有以下两点不同: + +但PATCH一般用于资源的部分更新,而PUT一般用于资源的整体更新。 +当资源不存在时,PATCH会创建一个新的资源,而PUT只会对已在资源进行更新。 + ## 21 Ajax AJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。 From 7399b905e360202078ee4eb10def560e53603019 Mon Sep 17 00:00:00 2001 From: Lchen Date: Tue, 19 Dec 2017 18:08:02 +0800 Subject: [PATCH 24/40] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=B1=BB=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=92=8C=E9=9D=99=E6=80=81=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E5=8F=82=E8=80=83=E8=B5=84=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 87614f3..396d918 100644 --- a/Readme.md +++ b/Readme.md @@ -219,8 +219,9 @@ a=A() | a = A() | a.foo(x) | a.class_foo(x) | a.static_foo(x) | | A | 不可用 | A.class_foo(x) | A.static_foo(x) | -更多关于这个问题:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python - +更多关于这个问题: +1. http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python +2. https://realpython.com/blog/python/instance-class-and-static-methods-demystified/ ## 4 类变量和实例变量 **类变量:** From 6f1b92c10e1c78223b67aaefbd111c8e8b6684db Mon Sep 17 00:00:00 2001 From: Taoyu Su Date: Sat, 10 Mar 2018 13:24:32 +0800 Subject: [PATCH 25/40] =?UTF-8?q?=E5=A2=9E=E6=B7=BB=E5=8D=95=E4=BE=8B?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 396d918..e9a53e0 100644 --- a/Readme.md +++ b/Readme.md @@ -521,7 +521,7 @@ ps: `__metaclass__`是创建类时起作用.所以我们可以分别使用`__met > ​ 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 > > `__new__()`在`__init__()`之前被调用,用于生成实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。单例模式是指创建唯一对象,单例模式设计的类只能实例 - +[伯乐在线详细解释](http://python.jobbole.com/87294/) **这个绝对常考啊.绝对要记住1~2个方法,当时面试官是让手写的.** ### 1 使用`__new__`方法 From 99928d8d48e0436f7b59ea78258a400b692fbbbf Mon Sep 17 00:00:00 2001 From: Taoyu Su Date: Sat, 10 Mar 2018 13:28:51 +0800 Subject: [PATCH 26/40] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8D=95=E4=BE=8B?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=8F=82=E8=80=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index e9a53e0..3857005 100644 --- a/Readme.md +++ b/Readme.md @@ -521,7 +521,6 @@ ps: `__metaclass__`是创建类时起作用.所以我们可以分别使用`__met > ​ 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 > > `__new__()`在`__init__()`之前被调用,用于生成实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。单例模式是指创建唯一对象,单例模式设计的类只能实例 -[伯乐在线详细解释](http://python.jobbole.com/87294/) **这个绝对常考啊.绝对要记住1~2个方法,当时面试官是让手写的.** ### 1 使用`__new__`方法 @@ -589,6 +588,7 @@ from mysingleton import my_singleton my_singleton.foo() ``` +**[单例模式伯乐在线详细解释](http://python.jobbole.com/87294/)** ## 17 Python中的作用域 From 947c33d73bbb2f80b53f41627a7efa482d5eddbc Mon Sep 17 00:00:00 2001 From: yinwoods Date: Wed, 14 Mar 2018 22:56:44 +0800 Subject: [PATCH 27/40] =?UTF-8?q?update=20=E6=A0=91=E7=9A=84=E5=B1=82?= =?UTF-8?q?=E6=AC=A1=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Readme.md b/Readme.md index 3857005..4c45059 100644 --- a/Readme.md +++ b/Readme.md @@ -1664,14 +1664,10 @@ tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4))) ```python def lookup(root): - stack = [root] - while stack: - current = stack.pop(0) - print current.data - if current.left: - stack.append(current.left) - if current.right: - stack.append(current.right) + row = [root] + while row: + row = [kid for item in row for kid in (item.left, item.right) if kid] + print(row) ``` From 76939ef5070a4be001e452beee3fbebbaf423c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=B7=E6=88=90=E6=B6=9B?= Date: Wed, 14 Mar 2018 22:59:43 +0800 Subject: [PATCH 28/40] =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=BA=86=E5=B1=82?= =?UTF-8?q?=E6=AC=A1=E9=81=8D=E5=8E=86=E4=B8=ADprint=E7=9A=84=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 4c45059..3edcb2d 100644 --- a/Readme.md +++ b/Readme.md @@ -1666,8 +1666,8 @@ tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4))) def lookup(root): row = [root] while row: - row = [kid for item in row for kid in (item.left, item.right) if kid] - print(row) +        print(row) +        row = [kid for item in row for kid in (item.left, item.right) if kid] ``` From b73293fc3e0a2e375d233459c181d90d15541e8f Mon Sep 17 00:00:00 2001 From: kang Date: Fri, 30 Mar 2018 22:28:28 +0800 Subject: [PATCH 29/40] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A3=85=E9=A5=B0?= =?UTF-8?q?=E5=99=A8=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 3edcb2d..b3b5a90 100644 --- a/Readme.md +++ b/Readme.md @@ -557,9 +557,9 @@ class MyClass2(Borg): ### 3 装饰器版本 ```python -def singleton(cls, *args, **kw): +def singleton(cls): instances = {} - def getinstance(): + def getinstance(*args, **kw): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] From 3fcd1aede065af360ae473d4b32afaee3f768465 Mon Sep 17 00:00:00 2001 From: zhongyuhang <1076525788@qq.com> Date: Wed, 7 Nov 2018 14:52:00 +0800 Subject: [PATCH 30/40] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index b3b5a90..453aed0 100644 --- a/Readme.md +++ b/Readme.md @@ -476,7 +476,7 @@ http://stackoverflow.com/questions/3394835/args-and-kwargs 这篇文章很好的介绍了新式类的特性: http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html -新式类很早在2.2就出现了,所以旧式类完全是兼容的问题,Python3里的类全部都是新式类.这里有一个MRO问题可以了解下(新式类是广度优先,旧式类是深度优先),里讲的也很多. +新式类很早在2.2就出现了,所以旧式类完全是兼容的问题,Python3里的类全部都是新式类.这里有一个MRO问题可以了解下(新式类继承是根据C3算法,旧式类是深度优先),里讲的也很多. > 一个旧式类的深度优先的例子 From e728f6185ac3b6c434eee5942fb03f68bd7386a3 Mon Sep 17 00:00:00 2001 From: qinggniq Date: Tue, 27 Nov 2018 20:04:46 +0800 Subject: [PATCH 31/40] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E5=BA=8F?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E4=B8=AD=E6=9D=A1=E4=BB=B6=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index b3b5a90..0a6e9fb 100644 --- a/Readme.md +++ b/Readme.md @@ -1705,7 +1705,7 @@ class Node(object): #中序遍历:遍历左子树,访问当前节点,遍历右子树 def mid_travelsal(root): - if root.left is None: + if root.left is not None: mid_travelsal(root.left) #访问当前节点 print(root.value) From 3827dfeeedc3baac5b8ad6df9fe6b1595df9505e Mon Sep 17 00:00:00 2001 From: dengshilong Date: Tue, 14 May 2019 19:20:47 +0800 Subject: [PATCH 32/40] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=8C?= =?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Readme.md | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/Readme.md b/Readme.md index 12721ad..5d71338 100644 --- a/Readme.md +++ b/Readme.md @@ -1569,21 +1569,21 @@ def node(l1, l2): ```python #coding:utf-8 -def binary_search(list,item): +def binary_search(list, item): low = 0 - high = len(list)-1 - while low<=high: - mid = (low+high)/2 + high = len(list) - 1 + while low <= high: + mid = (high - low) / 2 + low # 避免(high + low) / 2溢出 guess = list[mid] - if guess>item: - high = mid-1 - elif guess item: + high = mid - 1 + elif guess < item: + low = mid + 1 else: return mid return None mylist = [1,3,5,7,9] -print binary_search(mylist,3) +print binary_search(mylist, 3) ``` From fa3d55d0fb8e8d6b74a6c4f0d661938929a72756 Mon Sep 17 00:00:00 2001 From: ZoeLiao Date: Mon, 29 Jul 2019 08:36:38 +0800 Subject: [PATCH 33/40] Update operation system part 6-9 --- Readme.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 5d71338..b63777f 100644 --- a/Readme.md +++ b/Readme.md @@ -878,18 +878,20 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) 1. 页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要.段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要. 2. 页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的.而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分. -3. 分页的作业地址空间是一维的.分段的地址空间是二维的. +3. 分页的作业地址空间是一维的、分段的地址空间是二维的。 ## 8 页面置换算法 -1. 最佳置换算法OPT:不可能实现 -2. 先进先出FIFO -3. 最近最久未使用算法LRU:最近一段时间里最久没有使用过的页面予以置换. -4. clock算法 +页面置换:在地址映射过程中,若所要访问的页面不在内存中,则产生了‘缺页中断(page fault)’。此时操作系统必须在内存中选择一个页面将其移出内存,为即将调入的页面让出空间。 +1. 最佳置换算法 OPT (optional replacement):被替换的页面为在未来最长时间内不会被访问的页面,可保证最低的缺页率,但不可能实现,主要用于评估算法。 +2. 先进先出 FIFO:最易实现,但会频繁换页,性能差。 +3. 最近最久未使用算法 LRU (Least Recently Used):最近一段时间里最久没有使用过的页面予以置换。 +4. 时钟替换算法 (Clock):依照使用位替换页面。 ## 9 边沿触发和水平触发 -边缘触发是指每当状态变化时发生一个 io 事件,条件触发是只要满足条件就发生一个 io 事件 +1. 边沿触发 (Edge Trigger):自上次状态改变后有新的 I/O 事件就会触发通知,需要尽可能多的执行 I/O 操作。 +2. 水平触发 (Level Trigger):准备就绪时(可非阻塞地执行 I/O 系统调用)触发通知,可在任意时刻重复检测 I/O 状态。 # 数据库 From 10bf09af48ce7b2463375f643fb24ce0db9f42eb Mon Sep 17 00:00:00 2001 From: hackerxu Date: Sun, 31 May 2020 01:04:32 +0800 Subject: [PATCH 34/40] Create FUNDING.yml --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..4b16f59 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 6dc27a18d4f6106b9d4f81d6aa3ef9bf60defbf7 Mon Sep 17 00:00:00 2001 From: hackerxu Date: Sun, 31 May 2020 01:05:28 +0800 Subject: [PATCH 35/40] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 4b16f59..c38a894 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +github: [taizilongxu]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username From f5a1e159379d83cbb9bf81d033523105b081e8c2 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Fri, 31 Jul 2020 16:28:33 +0800 Subject: [PATCH 36/40] =?UTF-8?q?fix:=20=E7=BA=A0=E6=AD=A3README=E9=94=99?= =?UTF-8?q?=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 5d71338..0a68eee 100644 --- a/Readme.md +++ b/Readme.md @@ -449,7 +449,7 @@ http://stackoverflow.com/questions/3394835/args-and-kwargs 又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等. -鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。 +鸭子类型在动态语言中经常使用,非常灵活,使得python不像java那样专门去弄一大堆的设计模式。 ## 13 Python中重载 From 5af6c5989a9b0cc22d176e3f0b78496c8d0dafc2 Mon Sep 17 00:00:00 2001 From: wangyu95 Date: Wed, 3 Mar 2021 10:47:03 +0800 Subject: [PATCH 37/40] style: code style --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 0a68eee..9afe4e2 100644 --- a/Readme.md +++ b/Readme.md @@ -1747,9 +1747,9 @@ def maxDepth(root): def isSameTree(p, q): if p == None and q == None: return True - elif p and q : + elif p and q: return p.val == q.val and isSameTree(p.left,q.left) and isSameTree(p.right,q.right) - else : + else: return False ``` From b329760313454267d4354a44170d2b71001123bc Mon Sep 17 00:00:00 2001 From: chaoqun <48987742+uonxhou@users.noreply.github.com> Date: Wed, 7 Sep 2022 22:49:34 +0800 Subject: [PATCH 38/40] Update Readme.md Sine the link of blog which introduce the database index is no longer valid, update the link. --- Readme.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 0a68eee..26af5ca 100644 --- a/Readme.md +++ b/Readme.md @@ -900,10 +900,7 @@ Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation) ## 2 数据库索引 -推荐: http://tech.meituan.com/mysql-index.html - -[MySQL索引背后的数据结构及算法原理](http://blog.codinglabs.org/articles/theory-of-mysql-index.html) - +推荐: https://zhuanlan.zhihu.com/p/113917726 聚集索引,非聚集索引,B-Tree,B+Tree,最左前缀原理 ## 3 Redis原理 From 3ad75d186f595300065d541a921e375ec180ebf6 Mon Sep 17 00:00:00 2001 From: zi-fei-yu-2020 <811944902@qq.com> Date: Mon, 15 May 2023 17:36:42 +0800 Subject: [PATCH 39/40] Modify print to a version above python3, and correct some problems --- Readme.md | 280 ++++++++++++++++++++---------------------------------- 1 file changed, 102 insertions(+), 178 deletions(-) diff --git a/Readme.md b/Readme.md index 0a68eee..1c4ee9b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,127 +1,4 @@ - -**Table of Contents** - - - * [Python语言特性](#python语言特性) - * [1 Python的函数参数传递](#1-python的函数参数传递) - * [2 Python中的元类(metaclass)](#2-python中的元类metaclass) - * [3 @staticmethod和@classmethod](#3-staticmethod和classmethod) - * [4 类变量和实例变量](#4-类变量和实例变量) - * [5 Python自省](#5-python自省) - * [6 字典推导式](#6-字典推导式) - * [7 Python中单下划线和双下划线](#7-python中单下划线和双下划线) - * [8 字符串格式化:\x和.format](#8-字符串格式化和format) - * [9 迭代器和生成器](#9-迭代器和生成器) - * [10 *args and **kwargs](#10-args-and-kwargs) - * [11 面向切面编程AOP和装饰器](#11-面向切面编程aop和装饰器) - * [12 鸭子类型](#12-鸭子类型) - * [13 Python中重载](#13-python中重载) - * [14 新式类和旧式类](#14-新式类和旧式类) - * [15 __new__和__init__的区别](#15-__new__和__init__的区别) - * [16 单例模式](#16-单例模式) - * [1 使用__new__方法](#1-使用__new__方法) - * [2 共享属性](#2-共享属性) - * [3 装饰器版本](#3-装饰器版本) - * [4 import方法](#4-import方法) - * [17 Python中的作用域](#17-python中的作用域) - * [18 GIL线程全局锁](#18-gil线程全局锁) - * [19 协程](#19-协程) - * [20 闭包](#20-闭包) - * [21 lambda函数](#21-lambda函数) - * [22 Python函数式编程](#22-python函数式编程) - * [23 Python里的拷贝](#23-python里的拷贝) - * [24 Python垃圾回收机制](#24-python垃圾回收机制) - * [1 引用计数](#1-引用计数) - * [2 标记-清除机制](#2-标记-清除机制) - * [3 分代技术](#3-分代技术) - * [25 Python的List](#25-python的list) - * [26 Python的is](#26-python的is) - * [27 read,readline和readlines](#27-readreadline和readlines) - * [28 Python2和3的区别](#28-python2和3的区别) - * [29 super init](#29-super-init) - * [30 range and xrange](#30-range-and-xrange) - * [操作系统](#操作系统) - * [1 select,poll和epoll](#1-selectpoll和epoll) - * [2 调度算法](#2-调度算法) - * [3 死锁](#3-死锁) - * [4 程序编译与链接](#4-程序编译与链接) - * [1 预处理](#1-预处理) - * [2 编译](#2-编译) - * [3 汇编](#3-汇编) - * [4 链接](#4-链接) - * [5 静态链接和动态链接](#5-静态链接和动态链接) - * [6 虚拟内存技术](#6-虚拟内存技术) - * [7 分页和分段](#7-分页和分段) - * [分页与分段的主要区别](#分页与分段的主要区别) - * [8 页面置换算法](#8-页面置换算法) - * [9 边沿触发和水平触发](#9-边沿触发和水平触发) - * [数据库](#数据库) - * [1 事务](#1-事务) - * [2 数据库索引](#2-数据库索引) - * [3 Redis原理](#3-redis原理) - * [Redis是什么?](#redis是什么) - * [Redis数据库](#redis数据库) - * [Redis缺点](#redis缺点) - * [4 乐观锁和悲观锁](#4-乐观锁和悲观锁) - * [5 MVCC](#5-mvcc) - * [MySQL的innodb引擎是如何实现MVCC的](#mysql的innodb引擎是如何实现mvcc的) - * [6 MyISAM和InnoDB](#6-myisam和innodb) - * [网络](#网络) - * [1 三次握手](#1-三次握手) - * [2 四次挥手](#2-四次挥手) - * [3 ARP协议](#3-arp协议) - * [4 urllib和urllib2的区别](#4-urllib和urllib2的区别) - * [5 Post和Get](#5-post和get) - * [6 Cookie和Session](#6-cookie和session) - * [7 apache和nginx的区别](#7-apache和nginx的区别) - * [8 网站用户密码保存](#8-网站用户密码保存) - * [9 HTTP和HTTPS](#9-http和https) - * [10 XSRF和XSS](#10-xsrf和xss) - * [11 幂等 Idempotence](#11-幂等-idempotence) - * [12 RESTful架构(SOAP,RPC)](#12-restful架构soaprpc) - * [13 SOAP](#13-soap) - * [14 RPC](#14-rpc) - * [15 CGI和WSGI](#15-cgi和wsgi) - * [16 中间人攻击](#16-中间人攻击) - * [17 c10k问题](#17-c10k问题) - * [18 socket](#18-socket) - * [19 浏览器缓存](#19-浏览器缓存) - * [20 HTTP1.0和HTTP1.1](#20-http10和http11) - * [21 Ajax](#21-ajax) - * [*NIX](#nix) - * [unix进程间通信方式(IPC)](#unix进程间通信方式ipc) - * [数据结构](#数据结构) - * [1 红黑树](#1-红黑树) - * [编程题](#编程题) - * [1 台阶问题/斐波那契](#1-台阶问题斐波那契) - * [2 变态台阶问题](#2-变态台阶问题) - * [3 矩形覆盖](#3-矩形覆盖) - * [4 杨氏矩阵查找](#4-杨氏矩阵查找) - * [5 去除列表中的重复元素](#5-去除列表中的重复元素) - * [6 链表成对调换](#6-链表成对调换) - * [7 创建字典的方法](#7-创建字典的方法) - * [1 直接创建](#1-直接创建) - * [2 工厂方法](#2-工厂方法) - * [3 fromkeys()方法](#3-fromkeys方法) - * [8 合并两个有序列表](#8-合并两个有序列表) - * [9 交叉链表求交点](#9-交叉链表求交点) - * [10 二分查找](#10-二分查找) - * [11 快排](#11-快排) - * [12 找零问题](#12-找零问题) - * [13 广度遍历和深度遍历二叉树](#13-广度遍历和深度遍历二叉树) - * [17 前中后序遍历](#17-前中后序遍历) - * [18 求最大树深](#18-求最大树深) - * [19 求两棵树是否相同](#19-求两棵树是否相同) - * [20 前序中序求后序](#20-前序中序求后序) - * [21 单链表逆置](#21-单链表逆置) - * [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) - * [23 动态规划问题](#23-动态规划问题) - - - - - - +[toc] # Python语言特性 @@ -134,7 +11,7 @@ a = 1 def fun(a): a = 2 fun(a) -print a # 1 +print(a) # 1 ``` ```python @@ -142,7 +19,7 @@ a = [] def fun(a): a.append(1) fun(a) -print a # [1] +print(a) # [1] ``` 所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。 @@ -152,12 +29,12 @@ print a # [1] ```python a = 1 def fun(a): - print "func_in",id(a) # func_in 41322472 + print("func_in",id(a)) # func_in 41322472 a = 2 - print "re-point",id(a), id(2) # re-point 41322448 41322448 -print "func_out",id(a), id(1) # func_out 41322472 41322472 + print("re-point",id(a), id(2)) # re-point 41322448 41322448 +print("func_out",id(a), id(1)) # func_out 41322472 41322472 fun(a) -print a # 1 +print(a) # 1 ``` 注:具体的值在不同电脑上运行时可能不同。 @@ -169,11 +46,11 @@ print a # 1 ```python a = [] def fun(a): - print "func_in",id(a) # func_in 53629256 + print ("func_in",id(a)) # func_in 53629256 a.append(1) -print "func_out",id(a) # func_out 53629256 +print("func_out",id(a)) # func_out 53629256 fun(a) -print a # [1] +print(a) # [1] ``` 这里记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而 list, dict, set 等则是可以修改的对象。(这就是这个问题的重点) @@ -192,19 +69,19 @@ Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod) ```python def foo(x): - print "executing foo(%s)"%(x) + print("executing foo(%s)"%(x)) class A(object): def foo(self,x): - print "executing foo(%s,%s)"%(self,x) + print("executing foo(%s,%s)"%(self,x)) @classmethod def class_foo(cls,x): - print "executing class_foo(%s,%s)"%(cls,x) + print("executing class_foo(%s,%s)"%(cls,x)) @staticmethod def static_foo(x): - print "executing static_foo(%s)"%x + print("executing static_foo(%s)"%x) a=A() @@ -240,12 +117,12 @@ class Test(object): Test.num_of_instance += 1 if __name__ == '__main__': - print Test.num_of_instance # 0 + print(Test.num_of_instance) # 0 t1 = Test('jack') - print Test.num_of_instance # 1 + print(Test.num_of_instance) # 1 t2 = Test('lucy') - print t1.name , t1.num_of_instance # jack 2 - print t2.name , t2.num_of_instance # lucy 2 + print(t1.name , t1.num_of_instance) # jack 2 + print(t2.name , t2.num_of_instance) # lucy 2 ``` > 补充的例子 @@ -257,9 +134,9 @@ class Person: p1=Person() p2=Person() p1.name="bbb" -print p1.name # bbb -print p2.name # aaa -print Person.name # aaa +print(p1.name) # bbb +print(p2.name) # aaa +print(Person.name) # aaa ``` 这里`p1.name="bbb"`是实例调用了类变量,这其实和上面第一个问题一样,就是函数传参的问题,`p1.name`一开始是指向的类变量`name="aaa"`,但是在实例的作用域里把类变量的引用改变了,就变成了一个实例变量,self.name不再引用Person的类变量name了. @@ -273,12 +150,14 @@ class Person: p1=Person() p2=Person() p1.name.append(1) -print p1.name # [1] -print p2.name # [1] -print Person.name # [1] +print(p1.name) # [1] +print(p2.name) # [1] +print(Person.name) # [1] ``` -参考:http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block +当类变量值为可变对象(列表、字典等)时,共享类变量可能会造成意外的结果。 + +为了避免变量混淆,推荐使用 self 来定义实例变量,使用类名或 cls 来定义类变量。对于可变对象的类变量,可以在类定义时使用深复制来避免共享。 ## 5 Python自省 @@ -290,18 +169,16 @@ print Person.name # [1] a = [1,2,3] b = {'a':1,'b':2,'c':3} c = True -print type(a),type(b),type(c) # -print isinstance(a,list) # True +print(type(a),type(b),type(c)) # +print(isinstance(a,list)) # True ``` - - ## 6 字典推导式 可能你见过列表推导时,却没有见过字典推导式,在2.7中才加入的: ```python -d = {key: value for (key, value) in iterable} +d = {key: value for (key, value) in iterable.items()} ``` ## 7 Python中单下划线和双下划线 @@ -313,13 +190,13 @@ d = {key: value for (key, value) in iterable} ... self._semiprivate = ", world!" ... >>> mc = MyClass() ->>> print mc.__superprivate +>>> print(mc.__superprivate) Traceback (most recent call last): File "", line 1, in AttributeError: myClass instance has no attribute '__superprivate' ->>> print mc._semiprivate +>>> print(mc._semiprivate) , world! ->>> print mc.__dict__ +>>> print(mc.__dict__) {'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'} ``` @@ -356,6 +233,16 @@ AttributeError: myClass instance has no attribute '__superprivate' http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format + + +Python f-string 是**执行字符串格式化的最新Python 语法**。 自Python 3.6 起可用。 Python f 字符串提供了一种更快,更易读,更简明且不易出错的在Python 中格式化字符串的方式。f 字符串的前缀为f,并使用{}括号评估值。 在冒号后指定用于类型,填充或对齐的格式说明符。 + +```python +name = "小明" +age = 20 +print(f"{name}的年龄是{age}岁!") #小明的年龄是20岁! +``` + ## 9 迭代器和生成器 这个是stackoverflow里python排名第一的问题,值得一看: http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python @@ -374,7 +261,9 @@ http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format >>> g at 0x0000028F8B774200> ``` -通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator +通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。 + +在Python中,我们可以采用生成器:边循环,边计算的机制—>generator ## 10 `*args` and `**kwargs` @@ -385,7 +274,7 @@ http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format ```python >>> def print_everything(*args): for count, thing in enumerate(args): -... print '{0}. {1}'.format(count, thing) +... print(f'{count}. {thing}' ... >>> print_everything('apple', 'banana', 'cabbage') 0. apple @@ -398,7 +287,7 @@ http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format ```python >>> def table_things(**kwargs): ... for name, value in kwargs.items(): -... print '{0} = {1}'.format(name, value) +... print('{name} = {value}') ... >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable @@ -417,7 +306,7 @@ def table_things(titlestring, **kwargs) ```python >>> def print_three_things(a, b, c): -... print 'a = {0}, b = {1}, c = {2}'.format(a,b,c) +... print('a = {a}, b = {b}, c = {c}') ... >>> mylist = ['aardvark', 'baboon', 'cat'] >>> print_three_things(*mylist) @@ -483,13 +372,13 @@ http://stackoverflow.com/questions/3394835/args-and-kwargs ```python class A(): def foo1(self): - print "A" + print("A") class B(A): def foo2(self): pass class C(A): def foo1(self): - print "C" + print("C") class D(B, C): pass @@ -631,10 +520,42 @@ Python里最常见的yield就是协程的思想!可以查看第九个问题. 闭包就像个空心球一样,你知道外面和里面,但你不知道中间是什么样. +```python +def count_time_wrapper(func): + def improved_func(): + start_time = time.time() + func() + end_time = time.time() + print(f"it takes {end_time - start_time}s to find all the olds") + + return improved_func + # 闭包本质上是一个函数 + # 闭包函数的传入参数和返回值都是函数 + # 闭包函数的返回值函数是对传入函数进行增强的函数 +``` + ## 21 lambda函数 其实就是一个匿名函数,为什么叫lambda?因为和后面的函数式编程有关. +```python +f = lambda x: x * x +print(f(4)) #16 + +g = lambda x, y: x + y +print(g(1, 2)) #3 + + +def que(a, b, c): + return lambda x: a * x * x + b * x + c + +# 第一种写法 +f = que(-1, 1, 2) #-18 +print(f(5)) +# 第二种写法 +print(que(-1, 1, 2)(5)) #-18 +``` + 推荐: [知乎](http://www.zhihu.com/question/20125256) @@ -651,7 +572,7 @@ filter 函数的功能相当于过滤器。调用一个布尔函数`bool_func` ```python >>>a = [1,2,3,4,5,6,7] >>>b = filter(lambda x: x > 5, a) ->>>print b +>>>print(b) >>>[6,7] ``` @@ -685,10 +606,10 @@ d = copy.deepcopy(a) #对象拷贝,深拷贝 a.append(5) #修改对象a a[4].append('c') #修改对象a中的['a', 'b']数组对象 -print 'a = ', a -print 'b = ', b -print 'c = ', c -print 'd = ', d +print('a = ', a) +print('b = ', b) +print('c = ', c) +print('d = ', d) 输出结果: a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] @@ -697,6 +618,10 @@ c = [1, 2, 3, 4, ['a', 'b', 'c']] d = [1, 2, 3, 4, ['a', 'b']] ``` +**浅拷贝: 创建新对象,其内容是原对象的引用。** + +**深拷贝:和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。** + ## 24 Python垃圾回收机制 Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。 @@ -1315,7 +1240,7 @@ list(set(l)) ```python l1 = ['b','c','d','b','c','a','a'] l2 = {}.fromkeys(l1).keys() -print l2 +print(l2) ``` 用字典并保持顺序 @@ -1324,7 +1249,7 @@ print l2 l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) l2.sort(key=l1.index) -print l2 +print(l2) ``` 列表推导式 @@ -1430,7 +1355,7 @@ def recursion_merge_sort2(l1, l2): 再把旧列表加到新列表后面 -```pyhton +```python def loop_merge_sort(l1, l2): tmp = [] while len(l1) > 0 and len(l2) > 0: @@ -1583,7 +1508,7 @@ def binary_search(list, item): return mid return None mylist = [1,3,5,7,9] -print binary_search(mylist, 3) +print(binary_search(mylist, 3)) ``` @@ -1603,7 +1528,7 @@ def quicksort(list): finallylist = quicksort(lessbeforemidpivot)+[midpivot]+quicksort(biggerafterpivot) return finallylist -print quicksort([2,4,6,7,1,2,5]) +print(quicksort([2,4,6,7,1,2,5])) ``` @@ -1632,7 +1557,7 @@ def coinChange(values,valuesCounts,money,coinsUsed): if (temp < minCoins): minCoins = temp coinsUsed[cents] = minCoins - print ('面值:{0}的最少硬币使用数为:{1}'.format(cents, coinsUsed[cents])) + print('面值:{0}的最少硬币使用数为:{1}'.format(cents, coinsUsed[cents])) ``` @@ -1678,7 +1603,7 @@ def lookup(root): def deep(root): if not root: return - print root.data + print(root.data) deep(root.left) deep(root.right) @@ -1728,7 +1653,7 @@ def post_trvelsal(root): post_trvelsal(root.left) if root.right is not None: post_trvelsal(root.right) - print (root.value) + print(root.value) ``` @@ -1772,7 +1697,7 @@ def deep(root): return deep(root.left) deep(root.right) - print root.data + print(root.data) ``` ## 21 单链表逆置 @@ -1798,7 +1723,7 @@ def rev(link): root = rev(link) while root: - print root.data + print(root.data) root = root.next ``` @@ -1895,4 +1820,3 @@ class Anagram: > 可参考:[动态规划(DP)的整理-Python描述](http://blog.csdn.net/mrlevo520/article/details/75676160) - From 12153514cb8f5bee8c8a04f414bb21c6c8248898 Mon Sep 17 00:00:00 2001 From: zi-fei-yu-2020 <811944902@qq.com> Date: Mon, 15 May 2023 17:46:49 +0800 Subject: [PATCH 40/40] Correct directory errors --- Readme.md | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 1c4ee9b..13e2b39 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,123 @@ -[toc] + +**Table of Contents** + + + * [Python语言特性](#python语言特性) + * [1 Python的函数参数传递](#1-python的函数参数传递) + * [2 Python中的元类(metaclass)](#2-python中的元类metaclass) + * [3 @staticmethod和@classmethod](#3-staticmethod和classmethod) + * [4 类变量和实例变量](#4-类变量和实例变量) + * [5 Python自省](#5-python自省) + * [6 字典推导式](#6-字典推导式) + * [7 Python中单下划线和双下划线](#7-python中单下划线和双下划线) + * [8 字符串格式化:\x和.format](#8-字符串格式化和format) + * [9 迭代器和生成器](#9-迭代器和生成器) + * [10 *args and **kwargs](#10-args-and-kwargs) + * [11 面向切面编程AOP和装饰器](#11-面向切面编程aop和装饰器) + * [12 鸭子类型](#12-鸭子类型) + * [13 Python中重载](#13-python中重载) + * [14 新式类和旧式类](#14-新式类和旧式类) + * [15 __new__和__init__的区别](#15-__new__和__init__的区别) + * [16 单例模式](#16-单例模式) + * [1 使用__new__方法](#1-使用__new__方法) + * [2 共享属性](#2-共享属性) + * [3 装饰器版本](#3-装饰器版本) + * [4 import方法](#4-import方法) + * [17 Python中的作用域](#17-python中的作用域) + * [18 GIL线程全局锁](#18-gil线程全局锁) + * [19 协程](#19-协程) + * [20 闭包](#20-闭包) + * [21 lambda函数](#21-lambda函数) + * [22 Python函数式编程](#22-python函数式编程) + * [23 Python里的拷贝](#23-python里的拷贝) + * [24 Python垃圾回收机制](#24-python垃圾回收机制) + * [1 引用计数](#1-引用计数) + * [2 标记-清除机制](#2-标记-清除机制) + * [3 分代技术](#3-分代技术) + * [25 Python的List](#25-python的list) + * [26 Python的is](#26-python的is) + * [27 read,readline和readlines](#27-readreadline和readlines) + * [28 Python2和3的区别](#28-python2和3的区别) + * [29 super init](#29-super-init) + * [30 range and xrange](#30-range-and-xrange) + * [操作系统](#操作系统) + * [1 select,poll和epoll](#1-selectpoll和epoll) + * [2 调度算法](#2-调度算法) + * [3 死锁](#3-死锁) + * [4 程序编译与链接](#4-程序编译与链接) + * [1 预处理](#1-预处理) + * [2 编译](#2-编译) + * [3 汇编](#3-汇编) + * [4 链接](#4-链接) + * [5 静态链接和动态链接](#5-静态链接和动态链接) + * [6 虚拟内存技术](#6-虚拟内存技术) + * [7 分页和分段](#7-分页和分段) + * [分页与分段的主要区别](#分页与分段的主要区别) + * [8 页面置换算法](#8-页面置换算法) + * [9 边沿触发和水平触发](#9-边沿触发和水平触发) + * [数据库](#数据库) + * [1 事务](#1-事务) + * [2 数据库索引](#2-数据库索引) + * [3 Redis原理](#3-redis原理) + * [Redis是什么?](#redis是什么) + * [Redis数据库](#redis数据库) + * [Redis缺点](#redis缺点) + * [4 乐观锁和悲观锁](#4-乐观锁和悲观锁) + * [5 MVCC](#5-mvcc) + * [MySQL的innodb引擎是如何实现MVCC的](#mysql的innodb引擎是如何实现mvcc的) + * [6 MyISAM和InnoDB](#6-myisam和innodb) + * [网络](#网络) + * [1 三次握手](#1-三次握手) + * [2 四次挥手](#2-四次挥手) + * [3 ARP协议](#3-arp协议) + * [4 urllib和urllib2的区别](#4-urllib和urllib2的区别) + * [5 Post和Get](#5-post和get) + * [6 Cookie和Session](#6-cookie和session) + * [7 apache和nginx的区别](#7-apache和nginx的区别) + * [8 网站用户密码保存](#8-网站用户密码保存) + * [9 HTTP和HTTPS](#9-http和https) + * [10 XSRF和XSS](#10-xsrf和xss) + * [11 幂等 Idempotence](#11-幂等-idempotence) + * [12 RESTful架构(SOAP,RPC)](#12-restful架构soaprpc) + * [13 SOAP](#13-soap) + * [14 RPC](#14-rpc) + * [15 CGI和WSGI](#15-cgi和wsgi) + * [16 中间人攻击](#16-中间人攻击) + * [17 c10k问题](#17-c10k问题) + * [18 socket](#18-socket) + * [19 浏览器缓存](#19-浏览器缓存) + * [20 HTTP1.0和HTTP1.1](#20-http10和http11) + * [21 Ajax](#21-ajax) + * [*NIX](#nix) + * [unix进程间通信方式(IPC)](#unix进程间通信方式ipc) + * [数据结构](#数据结构) + * [1 红黑树](#1-红黑树) + * [编程题](#编程题) + * [1 台阶问题/斐波那契](#1-台阶问题斐波那契) + * [2 变态台阶问题](#2-变态台阶问题) + * [3 矩形覆盖](#3-矩形覆盖) + * [4 杨氏矩阵查找](#4-杨氏矩阵查找) + * [5 去除列表中的重复元素](#5-去除列表中的重复元素) + * [6 链表成对调换](#6-链表成对调换) + * [7 创建字典的方法](#7-创建字典的方法) + * [1 直接创建](#1-直接创建) + * [2 工厂方法](#2-工厂方法) + * [3 fromkeys()方法](#3-fromkeys方法) + * [8 合并两个有序列表](#8-合并两个有序列表) + * [9 交叉链表求交点](#9-交叉链表求交点) + * [10 二分查找](#10-二分查找) + * [11 快排](#11-快排) + * [12 找零问题](#12-找零问题) + * [13 广度遍历和深度遍历二叉树](#13-广度遍历和深度遍历二叉树) + * [17 前中后序遍历](#17-前中后序遍历) + * [18 求最大树深](#18-求最大树深) + * [19 求两棵树是否相同](#19-求两棵树是否相同) + * [20 前序中序求后序](#20-前序中序求后序) + * [21 单链表逆置](#21-单链表逆置) + * [22 两个字符串是否是变位词](#22-两个字符串是否是变位词) + * [23 动态规划问题](#23-动态规划问题) + + # Python语言特性