阿龙的学习笔记---202107学习

学这个https://interview.huihut.com/#/


  • this 指针被隐含地声明为: ClassName *const this,这意味着不能给 this 指针赋值;

  • 内联函数
    • 缺点: inline 函数无法随着函数库升级而升级。因为在编译器就编进去了,inline函数的改变需要重新编译,不像 non-inline 可以直接链接。
    • 虚函数(virtual)可以是内联函数(inline)吗?一般都说不可以,但是在不表现出多态时,是有可能被内联的,比如说直接通过对象调用,编译器就可能内联。

  • 内存屏障
    • 大多数现代计算机为了提高性能而采取乱序执行,这使得内存屏障成为必须。
      语义上,内存屏障之前的所有写操作都要写入内存;内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。因此,对于敏感的程序块,写操作之后、读操作之前可以插入内存屏障。

  • 不可以同时用const和static修饰成员函数

    • C++编译器在实现const的成员函数的时候为了确保该函数不能修改类的实例的状态,会在函数中添加一个隐式的参数const this*。但当一个成员为static的时候,该函数是没有this指针的。也就是说此时const的用法和static是冲突的。
    • 我们也可以这样理解:两者的语意是矛盾的。static的作用是表示该函数只作用在类型的静态变量上,与类的实例没有关系;而const的作用是确保函数不能修改类的实例的状态,与类型的静态变量没有关系。因此不能同时用它们。

  • STL中的sort
    • STL中的sort(),在数据量大时,采用quicksort,分段递归排序;一旦分段后的数量小于某个门限值,改用Insertion sort,避免quicksort深度递归带来的过大的额外负担,如果递归层次过深,还会改用heapsort。

  • mutable:
    • 使用场景:对可能要发生变化的成员前,加上存储描述符mutable。
    • 为什么要有这种去除常量标志的需求?
      • 逻辑常量性:对用户而言是常量,但在用户不能访问的细节上不是常量。

  • shared_ptr 初始化
    • 尽量避免使用raw pointer构建shared_ptr吗,使用std::make_shared();
    • std::shared_ptr ptr2(new int());
      • 此方法在堆上创建了两块内存:1:存储int。2:控制块上用于引用计数的内存,管理附加此内存的 shared_ptr 对象的计数,最初计数将为1。
    • std::shared_ptr ptr = std::make_shared();
      • std::make_shared 一次性为int对象和用于引用计数的数据都分配了内存,而new操作符只是为int分配了内存。
    • 优势一是减少了内存碎片,二是效率高,三是还能用move语义,性能更好。

  • 范式化设计优缺点:
    • 优点: 可以尽量得减少数据冗余,使得更新快,体积小
    • 缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化
  • 反范式化:
    • 优点:可以减少表的关联,可以更好得进行索引优化
    • 缺点:数据冗余以及数据异常,数据得修改需要更多的成本

  • mysql 主从复制+读写分离
    • 为了提高数据库的并发性能
    • 读写分离一般master负责写入数据,两台slave负责读取数据。
      • 读写分离好像不是依赖mysql的设置,一般是用框架或者自定义逻辑。
    • 读写分离后,从机需要同步脏数据,一般是 binlog 和 delaylog 的配合完成:
      1. 当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
      2. salve从库连接master主库,Master有多少个slave就会创建多少个binlog dump线程。
      3. 当Master节点的binlog发生变化时,binlog dump 线程会通知所有的salve节点,并将相应的binlog内容推送给slave节点。
      4. I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log
      5. SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。

  • Redis 集群简介
    • Redis 客户端可以直接连接任何一节点获取集群中的键值对。Redis 集群是一个网状结构没有中心节点的说法,每个节点都通过 TCP 连接跟其他每个节点连接。这些 TCP 连接会永久保持。
    • 在这里插入图片描述
    • 自动通过hash分割数据到不同的节点上。
    • 集群使用了主从复制模型,每个主节点master应至少有一个从节点slave。假设某个主节点故障,其所有子节点会广播一个数据包给其他主节点来请求选票,一旦某个从节点收到了大多数主节点的回应,那么它就赢得了选举,被推选为主节点,负责处理之前旧的主节点负责的哈希槽。

  • 算法题拓展:1~n的数字,缺两个数字:
    • 缺一个数字的很常见,用亦或比较优。
    • 缺两个的直接用这个则不好,求和相减也只能知道两个数的和,那么则需要思考如何转换为一个。
    • 将数组中的元素与 1 ~ n 全部进行异或运算,,记为c。由于a!=b。所以c!=0;那么一定有一位是1。用d=(c-(c&(c-1)))就可以得到c的最右边的为1的位,以这一位为分界线,为1的分为一组,不为1的分成另一组,这样就将问题转化成问题1的情况了。那a、b自然也就出来了。

  • Redis:hash、set、zset
    • hash 是哈希表。
      • 实现原理,其在存储内容较少的时候使用ziplist 压缩列表,内容多的时候使用hashtable 哈希表,存储的是string的键值对。
      • 用途:比如购物车缓存,uid对应一个hash,里面存(商品名 : 数量)。再比如做计数器,HINCRBY 操作可以直接加一。(日期 : 访问量)、(文章id:点赞数)等。
    • set 是无序集合。
      • 实现原理:编码可以是 intset 或者 hashtable。往里存入一个string。
      • 无序集合的用途:不允许重复。做并集,搽剂,交集等操作。比如共同好友。
    • zset 有序集合:
      • 实现原理:skip_list跳表和hashtable哈希表。skip_list跳表详解见下方。
      • 存入时,每个value需要对应一个分数,按照分数排序。
      • 用途:用于需要排序的表,比如排行榜,分数榜之类的。还可以交集并集。
        • 博客中还提到了限流也可以用排序set做,很神奇,记录一下:滑动窗口限流,我们把一个用户的访问时间戳作为score和value。我们只需统计某个用户在指定时间戳区间内的次数,限制这个次数来决定是否访问。

  • Redis中的跳表:
    • 跳表:90年提出的。平均 O(logN),最差 O(N)。能与平衡树媲美,但操作还简单,空间换时间。
      • 最简单的结构如下图,上层元素跳着排,下层比上层跳的少,最后一层所有元素。查找时,从上层查找。
        在这里插入图片描述

      • redis中用跳表,利于查找区间,插入、删除时也比较方便,不会设计红黑树的染色旋转等。

      • redis中加强了一下:首先,最底层元素有后驱指针,是前后都可以遍历的。再者,对于是否作为上层节点,是依靠概率的。


  • Redis 6.0 加入了 多线程
    • 6.0之前,核心处理是单线程的,其他操作可能是多线程的,真正处理语句和数据是单线程的,好处是无锁开销,切换线程的开销。但也无法用到多CPU带来的效率提升。

  • 如何避免死锁
    • 代码中可以按顺序获取锁;
    • 可以设置超时时间(redis分布式锁);
    • 银行家算法:还有已知进程资源需求的情况下,在启动时就判断是否有死锁的可能。

  • Redis 过期策略
    • 定时: 定时器,每个过期时间都一个定时器,太消耗资源了,没人用。
    • 惰性:访问到这个键值了之后,才查看,过期了则淘汰。
    • 定期:一段时间清理一次,设置10则是100ms清理一次;并且当maxmemory满了也会清理。

  • Redis 的清理策略:当前已用内存超过maxmemory限定时,触发主动清理策略
    • 设置过期时间的 + LRU 最近最少使用的;
    • 设置过期时间的 + ramdom 随机的;
    • 设置过期时间的 + ttl 即将要过期的;
    • 全部数据中 + LRU;
    • 全部数据 + ramdom;
    • 不淘汰,写入失败。
    • Redis 的 LRU 的实现:通过给每个对象一个时间戳。但维护 LRU队列 需要额外开销。Redis为了效率,策略是随机取出若干个key,然后按照访问时间排序后,淘汰掉最不经常使用的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值