以下提到的每个点会进行简要介绍,并附相关资料链接。
知识点
海量延时任务处理方式
背景:在游戏中,会遇到很多倒计时场景,例如玩家10秒未准备则强制准备等,当游戏房间数量巨大时,就需要一个高效的方法来处理定时任务。
解决方案:采用时间轮算法,可以实现O(1)的复杂度添加定时任务,并以O(1)的复杂度来获得到期任务。不同开源框架定时器实现方式不一,如,libuv采用最小堆来实现,nginx采用红黑树实现,linux内核和skynet采用时间轮算法实现等等。
有序链表:插入O(n),删除O(1),过期expire执行O(1)
最小堆:插入O(logn),删除O(logn),过期expire执行O(1)
红黑树:插入O(logn),删除O(logn),过期expire执行O(logn)
哈希表+链表(时间轮):插入O(1),删除O(1),过期expire平均执行O(1)(最坏为O(n))拓展:层级时间轮
资料:时间轮(TimingWheel)高性能定时任务原理解密
如何实现一个定时器?看这一篇就够了Actor模式
背景:多用于游戏中各种信息的交互,每个玩家抽象化为一个Actor,通过消息的传递,来传递各种事件。
实现思路:reactor模式
资料:Actor模型是解决高并发的终极解决方案缓存相关
缓存雪崩
背景:大量数据同时过期缓存击穿
背景:热点数据过期缓存穿透
背景:请求不存在于缓存和数据库中的数据
资料: 小林coding - 缓存篇大端/小端 字节序
背景:网络传输中,需要把数据转换成网络字节序进行传输。在主机接收时,需要转换成主机字节序进行读取。
大端序(Big-Endian)将数据的低位字节存放在内存的高位地址,高位字节存放在低位地址。这种排列方式与数据用字节表示时的书写顺序一致,符合人类的阅读习惯。
小端序(Little-Endian),将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序。
小端序与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的。
资料: 什么是大端序和小端序,为什么要有字节序?Protobuf通信协议
背景:序列化/反序列化 数据结构,实现将内存中的数据结构存储在硬盘上
资料:深入浅出:如何正确使用 protobufKafka消息队列
资料:Kafka【入门】就这一篇!内存池
背景:在调用malloc(或new)和free(或delete)的时候,会通过系统调用brk或者是mmap来分配内存,并且在第一次使用mmap分配的空间时会发生缺页中断。因此,会频繁的发生内核态和用户态的切换,耗费大量时间。使用池化技术,预先配置好一定数量的内存,并在不足时进行扩充,可以加快内存分配的速率。我自己写了一个内存池,并进行了简单了测试,使用malloc/free(new/delete)耗时590ms,使用内存池耗时199ms。
开源项目:固定大小的内存分配器(内存池)实现:https://github.com/cacay/MemoryPool
资料:性能优化-高效内存池的设计与实现
2万字|带你领略glibc内存管理精髓负载均衡请求转发实现方法
Nginx可以通过反向代理的方法来实现负载均衡,通过轮询、IP哈希等算法决定选用哪一个后端服务器,但是在这个过程结束之后,用户请求是怎么被重定向到其他服务器的,也值得了解。
资料:负载均衡请求转发实现数据库架构优化(从单机到分布式)
当单机部署数据库成为项目性能瓶颈的时候,就需要进行架构优化了。
资料:天天用MySQL开发,你知道数据库能抗多大并发压力吗?乐观锁和悲观锁
乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。
因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。
因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。
资料:面试官灵魂4连问:乐观锁与悲观锁的概念、实现方式、场景、优缺点?
评论区