灵犀互娱 一面
1.STL迭代器失效?如何避免迭代器失效?
2.时间轮数据结构?
3.tcp_cookie?
4.brk中的伙伴算法?
5.内存池的设计思路?
1:搜索的答案:避免迭代器失效是使用STL容器时需要注意的重要问题。以下是一些常用的方法来避免迭代器失效:
- 使用索引而不是迭代器:如果可能的话,可以使用索引来访问容器的元素而不是迭代器。索引不会受到插入或删除元素的影响。
- 使用erase()返回的迭代器:在使用STL容器的erase()函数删除元素时,函数会返回指向被删除元素之后的元素的迭代器。可以使用该迭代器来继续遍历容器,而不是使用之前的失效迭代器。
- 使用insert()返回的迭代器:在使用STL容器的insert()函数插入元素时,函数会返回插入的元素的迭代器。可以使用该迭代器来继续遍历容器,而不是使用之前的失效迭代器。
- 使用逆向迭代器:对于支持逆向迭代器的容器(如vector、deque等),使用rbegin()和rend()函数获取逆向迭代器进行遍历操作。逆向迭代器不会受到插入或删除元素的影响。
- 避免在循环中修改容器:如果需要在循环中对容器进行修改操作,可以采用以下方法之一:使用标志变量记录需要删除或修改的元素,在循环结束后再执行修改操作。使用支持安全迭代器的操作,如list容器的erase()函数不会使迭代器失效。
- 在循环中避免缓存迭代器:如果容器的结构可能会改变,尽量避免在循环中缓存迭代器。而是在每次迭代时根据需要重新获取迭代器。
- 了解特定容器的迭代器失效规则:不同的STL容器有不同的迭代器失效规则,最好查阅相关文档以了解确切的失效情况,并在使用容器时遵循相应的规则。
2.时间轮数据结构:时间轮(Time Wheel)是一种常用的数据结构,用于管理定时任务和事件调度。它基于时钟的概念,将时间划分为一系列的时间槽(slot),每个时间槽代表一个时间段。时间轮中包含多个时间槽,每个时间槽上可以关联多个任务或事件。
时间轮的基本原理如下:
- 时间轮由若干个时间槽组成,时间槽的数量通常是固定的。
- 每个时间槽有一个指针,指向下一个时间槽。
- 时间轮不断地按照固定的时间间隔向前滚动,当前时间指针指向当前时间槽。
- 当有任务或事件需要被调度时,根据其触发时间计算出相对于当前时间的偏移量,并将其放入对应的时间槽中。
- 当时间轮滚动到某个时间槽时,执行该时间槽中的任务或事件。
使用时间轮的好处包括:
- 时间轮提供了高效的定时任务管理方式,适用于需要按照时间触发的任务调度。
- 时间轮的时间复杂度是O(1),即使在大量任务的情况下,也能保持高效性能。
- 时间轮是一种循环结构,可以不断重复使用,无需频繁创建和销毁对象。
4.伙伴算法:伙伴算法是一种常见的内存分配算法,用于高效地管理可用内存块。它通过将内存块划分为大小相等的块,并使用二叉树的结构来组织这些块。每个内存块都有一个对应的伙伴块,两个伙伴块的大小相等,并且相邻。
在brk中使用伙伴算法的基本步骤如下:
- 初始化堆空间:当进程启动时,通过brk系统调用将堆空间初始化为一个初始大小的内存块。这个内存块被划分为最大的块,并被标记为可用。
- 分配内存:当进程请求分配一块特定大小的内存时,brk将使用伙伴算法来查找合适的可用块。它从初始的最大块开始,通过二叉树的方式进行搜索,直到找到一个大小合适的块。如果找到的块大小正好与请求的大小匹配,将该块标记为已分配,并返回给进程使用。如果找到的块大小大于请求的大小,将该块划分为两个相等大小的伙伴块,并继续在其中一个伙伴块中进行搜索,直到找到匹配大小的块。
- 释放内存:当进程释放已分配的内存块时,brk将使用伙伴算法来合并相邻的空闲块。它检查被释放的块是否有一个相邻的伙伴块也是空闲的,如果是,则将它们合并为一个更大的块,并继续合并相邻的空闲块,直到不能再合并为止。
5.内存池设计思路(有会的大佬,请留言,膜拜一下):
内存池(Memory Pool)是一种常见的内存管理技术,旨在提高内存分配和释放的效率。它通过预分配一块连续的内存空 间,并将其划分为多个固定大小的内存块,以减少内存碎片化和频繁的系统调用。
下面是一些常见的内存池设计思路:
- 内存分配策略:内存池的设计需要考虑如何高效地分配内存块。一种常见的策略是使用自由链表(Free List),将空闲的内存块组织成链表,当需要分配内存时,从链表中取出一个空闲块并返回给请求者。另外,可以使用位图或其他数据结构来跟踪内存块的使用情况,以提高查找和分配的效率。
- 内存释放策略:内存池还需要考虑如何高效地释放内存块。一种常见的策略是使用标记位或其他方式来标记内存块是否被使用。当内存块被释放时,将其标记为空闲,并将其添加到空闲链表中以便后续分配时使用。
- 内存对齐:为了提高内存访问的效率,内存池通常会要求内存块的大小是固定的,并且需要进行内存对齐。例如,要求内存块的大小为2的幂次方或其他固定的大小,以便更有效地使用内存和提高访问速度。
- 内存池扩展和回收:内存池的设计还需要考虑如何处理内存不足或内存过剩的情况。一种常见的策略是动态扩展内存池,当内存不足时,分配更多的内存空间以满足需求。另外,可以设计回收机制,在内存块不再使用时,将其返还给操作系统或者保留在内存池中以供后续使用。
- 线程安全性:如果内存池需要在多线程环境中使用,需要考虑线程安全性。可以使用锁或其他同步机制来保护内存池的并发访问,以防止数据竞争和不一致的状态。
- 性能和效率考虑:内存池的设计应该尽量追求高性能和效率。这包括减少内存碎片化、减少系统调用次数、快速分配和释放等。可以通过合理的数据结构和算法选择、内存块的预分配和缓存策略等方式来提高性能。