基础和应用篇
-
redis:远程字典服务
-
json.dumps之后的数据类型是str
-
可以将数据序列化之后存入redis用户获取信息只需要进行反序列化
-
redis的字符串是动态字符串,可以修改,就是go中的切片,通过分配冗余空间来减少内存分配
-
过期时间设置命令:expire name x
-
redis的列表是链表不是数组,所以插入和删除非常快,但是索引定位很慢
-
redis的列表结构可以做异步的队列,列表是经过优化的数组加双向链表(快速链表)通过压缩列表+双向链表组成
-
可以用lpop 和 rpop作为队列或栈
-
查找操作lindex、获取所有元素操作lrange 保留切片操作ltrim时间复杂度都是O(n)慎用
-
hash字典:数组+链表,redis的字典的值只能是字符串
-
通过字典引出的一些问题:
class Student():
def __setattr__(self, key, value):
print('调用了setattr')
self.__dict__[key] = value
def __setitem__(self, key, value):
print('调用了setitem')
self.__dict__[key] = value
s = Student()
s.age = 1 # 调用__setattr__ 方法
s['name'] = 'tom' # 调用 __setitem__ 方法
- Python的__dict__是做什么的?
- Python的__repr__是做什么的?
- Python的__setattr__和__setitem__的区别?
- Python的有序字典通过双向链表+dict来实现
class Foo:
def __init__(self):
pass
def __repr__(self):
pass
def __setitem__(self, key, value):
print("调用了setitem")
self.__dict__[key] = value
def __getitem__(self, item):
print("调用了getitem")
print(self.foo)
if __name__ == "__main__":
f = Foo()
f["foo"] = 3
f["foo"]
- Python实现有序字典
class Link:
__slots__ = 'prev', 'next', 'key'
class OrderDict:
def __init__(self):
self.root = Link()
self.map = {}
self._node_map = {}
self.root.next = self.root
self.root.prev = self.root
def __setitem__(self, key, value):
if key in self._node_map:
self.map[key] = value
else:
root = self.root
last = root.prev
link = Link()
link.prev, link.next, link.key = last, root, key
last.next = link
root.prev = link
self._node_map[key] = link
self.map[key] = value
def __getitem__(self, item):
return self.map[item]
def __delitem__(self, key):
del self.map[key]
link = self._node_map.pop(key)
link_prev, link_next = link.prev, link.next
link_prev.next, link_next.prev = link_next, link_prev
link.prev, link.next = None, None
def pop(self):
"""
LIFO
:return:
"""
if not self._node_map:
raise KeyError('dict is empty')
root = self.root
link = root.prev
link_prev = link.prev
link_prev.next = root
root.prev = link_prev
link.prev, link.next = None, None
self._node_map.pop(link.key)
return self.map.pop(link.key)
def __iter__(self):
root = self.root
curr = root.next
while curr != root:
yield curr.key
curr = curr.next
def values(self):
root = self.root
curr = root.next
while curr != root:
yield self.map[curr.key]
curr = curr.next
def __str__(self):
root = self.root
curr = root.next
out = []
while curr != root:
out.append((curr.key, self.map[curr.key]))
curr = curr.next
return str(out)
if __name__ == '__main__':
d = OrderDict()
d['a'] = '1'
d['b'] = '2'
d['c'] = 'c'
print(d)
- Python的List是可变长度的数组
- 链表的插入和删除是O(1)的,但是更新和查找是O(n)
- 数组的插入和删除是O(N),但是更新和获取是O(1)
- 获取列表长度是O(1)
- 本质是对其他对象引用组成的连续数组,指针和长度被保存在列表头中
- dict的数据结构:
-
hashtable的装载因子
-
先对key进行hash如果值相同就hash冲突,会继续找空闲的位置
-
判断hash值和键两者是否相等,如果都相等如果值不同就更新值,如果有一个不同称为hash冲突
-
set先__hash__再__eq__为什么?
-
对于元组,使用tuple()或者切片操作符’:'不会创建一份浅拷贝,相反,它会返回一个指向相同元组的引用
-
浅拷贝,是指重新分配一块内存,创建一个新的对象,里面的元素是原对象中子对象的引用。
-
所谓深度拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
-
del只是删除了变量,但是对象依然存在
-
其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做c.next() 和 c.send(None) 作用是一样的。需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有Python yield语句来接收这个值。
-
Python基于redis实现分布式锁:
https://www.cnblogs.com/angelyan/p/11523846.html
-
NIO:
https://blog.csdn.net/weixin_41207499/article/details/80657201?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158702416219724843337183%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=158702416219724843337183&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v25-3
-
MySQL 的having对分组之后的数据进行操作
-
共享引用,小整数池机制
-
工厂方法:return一个类()
-
aiortc,flink,spark
-
SQL的题