Redis深度历险:核心原理与应用实践

基础和应用篇

  • 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的题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值