自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

边城梦溪

微信公众号:边城梦溪,分享最新技术干货、AI资讯

  • 博客(58)
  • 收藏
  • 关注

原创 《保姆级指导,教你用C++从0到1搭建一个异步日志服务AsyncLogServer》

最近几天,有多位在校生向我请教校招的经验,和我分享他们学习的一些技能和项目。学习本项目,你将掌握多线程编程的技能,比如:线程池的创建和回收、多线程同步原语、进程间的通信机制、网络编程,高并发网络库的设计思路、通信协议的设计、protobuf的应用等。前后分别开启4、8、16个线程,测试多线程环境下写日志的性能,磁盘IO还不错,笔者后续将继续做优化和改进,进一步提升磁盘IO性能。在校学生、参加工作时间1~3年的职场新人,苦于简历上没有亮眼的项目经历,或者没有从0到1搭建一个单体服务的经验和能力。

2025-05-28 12:04:59 354

原创 《全网最易懂 | 图文一步步带你搞懂哈希表(下)》

比如:我们先遍历数组A和数组B,统计数组A中的元素a和数组B中元素b的和,并记录a+b和对应的次数,用代码可以这样来实现。看题干,需要求数组中两个元素的和等于指定值的下标,那这也是个范围的问题,也许有同学想到双指针的思想,但这里还略微有些不同,因为题目并没有要求两个元素必须是连续的;那处理完数组A和数组B的元素,接下来就是数组C和数组D了,因为要求四个数组中元素的和为0的元素对应的下标,如果sumMap中存在这样的两数和,该两数和等于数组C和数组D中两两元素之和(也即是:c+d)的相反数。

2025-05-06 18:39:01 657

原创 《全网最易懂 | 图文一步步带你搞懂哈希表(上)》

求两个数组的交集,而且要求输出的结果中的元素是唯一的,那么肯定需要对原始的数组做去重处理,那么求两个数组的交集中所有的元素肯定是唯一的。如何对数组中的元素去重,我们可以想到一个容器unordered_set,相同的元素放到unordered_set中,映射的key都是同一个,相当于对数组的元素做了去重处理。我们遍历s中所有的字母,并统计每个字母出现的次数,遇到重复的字母就累加次数;只要t中出现的字母的个数和t中出现的字母的个数保持一致,那么重新对t中所有的字母进行排列组合,便能得到和s一样的单词。

2025-05-06 18:27:39 670

原创 《全网最易懂 | 图文一步步带你搞懂链表》

dummyNode相当于是一个额外的节点助手,偷偷地改变各节点间的指向,正如图中1、2、3步骤,就完成了Node1、Node2之间的交换,同时把之前原有的红色连接给打断了,即图中红色虚线的箭头。因为要要交换两个相邻的节点,那么一次性操作的肯定是两个节点,链表的操作。比如:以上图为例,第一个节点next指针指向的地址是0x59080,这个地址便是第二个节点的地址,第二个节点的next指针指向地址0x98011,这个地址就是第三个节点的地址,依次类推,这样的数据结构就可以把不连续的内存区域给串起来了。

2025-05-02 17:39:10 981

原创 全网最易懂 | 图文一步步带你搞懂滑动窗口思想

窗口由蓝色的范围,滑动到红色的范围,整个窗口呈现往右侧滑动的趋势,窗口的大小范围也在变动,那如何实现这样一个滑动窗口,第一直觉肯定是用双重for循环去遍历数组,一个下标指向start,另一个下标指向end,但这样做时间复杂度过高。那如何判断当前的窗口包含t中所有的字符呢?该问题也是求解最小子串,但有一点差别,它是要求子串包含了目标字符串中的所有字符即可,至于是不是连续的包含目标字符串中所有的字符,这个没有强制规定,无形中,题目的难度就提高了,按照上文中求长度最小的子数组不同。但是整体的思路还是滑动窗口。

2025-05-02 17:23:38 571

原创 《全网最易懂 | 图文一步步带你搞懂双指针思想》

比如:像这题,数组中的元素本来就是有正有负的,虽然现在的数组是单调递增的,但是平方求值之后,数组会变成这种状态,从左至中间是单调递减的,从中间到右是单调递增的。也就是【16, 1, 0, 9, 100】,如果要继续维护单调递增的趋势,那么我们可以定义首尾指针和同样大小的、空的vector数组res,同时往中间靠拢,遇到平方值较大的就往res的末尾塞。:从数组下标为0的位置开始更新不等于val的元素,等到快指针走到了数组的末尾,那么慢指针也停止更新。既然介绍了快慢指针的方法和思路,那首尾双指针又是怎样的?

2025-05-02 17:15:34 307

原创 《全网最易懂 | 图文一步步带你搞懂二分查找》

但在查找的过程中left、right、middle会一直变化的,也即可能在数组middle分割点的左侧区间去寻找,也可能在数组middle分割点右侧寻找。求一个数num的平方根,我们可以想象下,如果num是0或者1,那么它的平方根还是它自己,否则一个非负整数的平方根,肯定是在(0, num)之间的。二分查找的前提是数组必须有序,无论是升序还是降序(同时数组中无重复的元素),因为它核心的思想就是经过一次判断,就需要把搜索的区间缩小一半,直到搜索的范围左右边界的差值为0,也即找到指定的元素为止。

2025-05-02 17:06:06 255

原创 《腾讯天美实验室C++后台面试题讲解》

函数内局部静态变量的初始化,只有被调用的时候才被初始化,而且只初始化一次,局部静态变量存储的位置和全局静态变量存储的位置保持一致。不可以了,如果hello被定义成虚函数,那么hello将存储在类对象的内存中,此时没有给p申请内存,那么直接去访问Test类对象内存中的虚函数表的地址,肯定会抛Access Validate的异常。两者之间没有严格初始化顺序,在同一个编译单元内,谁先定义,谁先初始化,如果在不同的编译单元,就很难保证了,一般是哪个编译单元先参与编译,那该编译单元中的全局变量先初始化。

2025-04-19 09:18:23 1078

原创 《C++面试必读 预编译、编译、汇编、链接》

比如:你跟面试巴拉巴拉说了一堆,介绍完预编译、编译、汇编、链接这几个阶段。面试官可能会问,既然有全局符号表,如果多个目标文件中分别定义了相同名字的全局变量,但变量的类型彼此不同,有些变量做了初始化,但有些却未做初始化。那链接器是如何处理,才不会出现符号重定义的错误?针对这类问题,首先要阐述下,强符号和弱符号的概念,何为强符号?编译器默认函数和初始化了的全局变量。那弱符号呢?未初始化的全局变量。针对多个目标文件,拥有多个同名的强弱符号的场景,链接器有自己的一套处理规则。

2025-04-17 09:36:30 791

原创 《全网最易懂 | 图文一步步带你搞懂深度优先搜索》

针对这种无向图也是同样的道理,找到一条分支一直走,走到底部都没发现我们想要的节点,那回退到上一个节点,继续选择另外一条路径走下去。各节点间的连接关系可以用新的邻接矩阵进行表示,比如:矩阵第一行第二列(matrixAdj[0][1] == 1)的值为1,表示节点0和节点1有单向的连接关系,也正如上图中节点0指向节点1,其它节点间的连接关系可以依次类推。还是以上文的《程序员必学:广度优先搜索的高效实现与应用场景》为例,构建一个包含8个节点的无向图(各个节点之间相互连接),后面再分析单向图的场景。

2025-04-14 09:13:26 574

原创 《全网最易懂 | 图文一步步带你搞懂广度优先搜索算法》

广度优先搜索(Breadth-First-Search),简称 BFS。直观地讲,它其实就是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后是次近的,依次往外搜索。理解起来并不难,所以我画了一张示意图,你可以看下。 虽然上述流程用生动的图片给描述了出来,但还是需要用代码把广度优先搜索的思想给表述出来。 因为BFS是一种遍历图或者搜索的算法,我们可以使用队列(queue)来辅助实现,使用邻接列表表示图。具体的实现如下所示: 我们通过代码构建了一个

2025-04-13 10:04:20 723

原创 《C++基础之模板元编程之高级用法》

像MyVector vec1(vec)这条语句,我期待它调用的是MyVector的拷贝构造函数,但编译器优先为它匹配到了函数模板,执行了移动构造。1、编译器在编译阶段会判断模板参数U的类型和MyVector是否属于同一种类型,如果类型相同则禁用模板移动构造函数(std::decay_t。

2025-04-07 23:54:53 1094

原创 《C++基础之右值引用》

getTemp()接口返回是一个命名的临时对象,直接把getTemp()返回值去构造一个MoveObj对象,此时必然会调用到MoveObj的移动构造函数,MoveObj移动构造函数的参数类型是个右值引用,它延长了getTemp()返回的临时对象的生命周期。可能有读者会想到函数模板的重载,我们实现多份完美转发的函数模板,每个函数模板的参数类型代表一种具体的类型,比如:左值引用类型、常量左值引用类型、右值引用类型、常量右值引用类型,如果这样的化,就和函数模板的设计出初衷违背了。

2025-04-04 12:48:33 854

原创 《C++基础之函数模板》

函数模板的重载和普通函数重载一样,普通函数重载,是通过参数类型、顺序、个数不同,给多个同名的函数生成不同的特征标,以达到重载的目的。那模板函数也是如此,可以给同名的模板函数定义不同类型的参数,使得重载的模板函数的特征标有所不同,我们的程序调用同名的模板函数,编译器会根据参数的不同,创建出多个不同的函数模板实例出来。下面笔者为您展示一个简单的例子,阐明函数模板重载的方法。既然有函数模板、函数模板特化,当然也有非模板的普通同名函数,编译器是按照什么要的规则去匹配,具体要调用哪种类型的函数,有相应的优先级不?

2025-04-04 12:26:09 410

原创 《WinDbg调试之堆破坏》

【堆破坏导读】堆破坏,顾名思义就是应用层申请的堆块空间,因为某种原因把当前堆块用户数据区的空间写满了,同时把用户数据区后面栅栏字节给写坏了,栅栏字节就是为了内存溢出而准备的,堆管理器在释放堆块时会检查栅栏字节的完整性,如果栅栏字节被破坏了,说明当前堆块被破坏了,立刻会触发中断异常。因为堆破坏的随机性,其实排查起来会很困难,针对这类问题,如果我们能通过某种手段确定当前被破坏的内存空间来自哪个堆块、当前堆块是由哪个业务流程申请的、当前堆块是被哪个堆块给破坏掉的、执行破坏的堆块来自哪个业务模块。

2025-03-24 16:23:31 862

原创 《深入理解Linux:高效崩溃分析与实时栈回溯技巧》

backtrace非常依赖信号处理机制,我们需要在程序中注册好指定的信号,比如:常见的SIGSEGV、SIGILL、SIGFPE等,在响应信号的回调函数中获取到用户空间的上下文信息。将backtrace获取到的buffer的内容转换成字符串通过返回值返回回来,返回值是个char**二级指针,也是指向了一个指针数组,数组中每个元素是一个地址,指向一块内存区域,存储转换后的符号信息。需要在整个源码的开头加入以下宏定义。导致崩溃的信号、信号发生的原因、崩溃的地址、 寄存器信息(上下文信息)、栈回溯的栈帧。

2025-03-10 18:06:55 1077

原创 《Linux栈破坏了,如何还原》

在function中,我们定义了个unsigned long long int类型的指针指向int类型变量a的地址,因为int类型a占用的栈内存大小为4字节,unsigned long long int类型的指针步长就是8字节,连续给4字节的栈内存赋值3个大小为8字节的整形变量,肯定破坏了cpu为function分配的栈空间,甚至可能把上一层的栈帧给写坏了。那进程的虚拟地址空间布局是怎样的?重点关注的共享内存和当前进程加载的动态库在虚拟地址空间的位置,比栈顶指针rsp的地址要小,比堆的最大值要大。

2025-03-09 21:11:49 1042

原创 《如何排查Linux系统平均负载过高》

那这些进程加起来的总数刚好等于系统CPU的核数,那就是最理想化的状态,每个CPU都得到了利用,如果这些进程的数量超过了CPU的核数,就是过载了,至少在同一时刻,有些进程是没法得到CPU资源的。过去 1 分钟、5 分钟、15 分钟的平均负载值,也就是说我的主机,从过去15分钟到最近的一分钟内,平均负载是在降低的,而且平均负载远小于CPU的核数。1.73,0.60,7.98,那说明在最近一分钟内,系统有73%的过载,在过去5分钟的时间点,系统有40%空闲,在过去15分钟,系统有698%的过载。

2025-03-09 20:52:14 815

原创 《malloc底层原理和执行流》

unsortedbins维护的内存块不再和smallbins 、largebins那样,管理的是大小相近的chunk块,而是不固定。好,下面笔者将结合示意图为您剖析各个bin的结构和样式,先从fastbins开始,fastbins包含多个链表(一个bin就是一个链表,所以它的名字就是fastbins),每个 bin链表维护着固定大小的chunk内存块。因此我们每次申请指定大小的堆内存,glibc库给我们返回的实际上一个malloc_chunk,一个chunk头中包含了当前块的大小,上一个块的大小;

2025-02-17 11:56:11 1031

原创 《redis缓存淘汰机制》

好,简单介绍完redis的缓存及类型,那继续讨论一个缓存淘汰的问题,假设redis主库接收到了大量的业务客户端请求,或者业务客户端消费速度过慢,导致redis输出缓冲区中积攒了大量的数据,甚至把缓存写满了,那这个时候该怎么办?读写缓存,那便是业务方的读、写请求都直接在缓存中进行,并将缓存中的结果实时返回给业务方,但缓存中数据的更新并不及时写回数据库,这样就存在最新业务数据丢失的风险。只读缓存的优势在于,数据库中能实时保存最新的业务数据,就算redis服务宕机了,最新的数据不会随着redis的宕机而丢失。

2025-02-08 18:56:25 1166

原创 《Linux多线程同步之底层原理futex》

假设没有多线程对全局资源进行竞争,那此时futex在应用层就是个全局的原子变量,用于记录当前锁的状态,需要持有该锁时,修改这个原子变量的状态,进而获取该锁,释放锁时,如果没有其它线程在等待这把锁,直接将该原子变量的状态还原,随后释放锁资源。c、当线程退出临界区,unlock释放锁资源,如果state==2,表明有线程竞争该锁,通过CAS操作将state置为0,通过futex_wake(&state) 陷入内核态,唤醒等待&state的线程,当前线程切回用户态,完整地退出临界区。此刻没有进入内核态。

2025-02-07 08:20:11 1270

原创 《redis分布式锁》

的逻辑,和单机上加锁、解锁的逻辑一样;在分布式系统中,当多个客户端需要获取锁时,此时的锁就是分布式锁,并不是保存在本地的锁。先给大家介绍个线程非安全的场景,双11活动,大家在淘宝上面购买某一款商品,这款商品的库存量是固定的,随着大家的下单购买,如何保证该商品的库存量一直准确的,保证所有网友看到这个库存值始终是一样的?那加锁就可以用SETNX完成,解锁也有类似的指令DEL,DEL可以直接删除锁变量,那原有的锁变量不存在了,其它客户端就查不到这个锁变量,相当于当前没有客户端持有这把锁,随后可以立即加锁。

2025-02-07 08:09:22 975

原创 《redis的pub/sub机制》

哨兵只要和主库建立起了连接,就可以在主库上发布消息了,比如:发布自己的IP和监听端口,同时它也可以从主库上订阅其它哨兵的IP和端口信息,哨兵集群中多个哨兵都往主库上发布、订阅消息,那么整个哨兵集群就能获取到彼此的IP和端口了,进而整个哨兵集群之间的交流和通信就不存在障碍了。比如:哨兵2通过PING指令判断主库为"主观下线"了,此时它会给其它的哨兵发送is-master-down-by-addr的命令,其它哨兵根据自己和主库的连接情况给出回应,赞同哨兵A的结论,给哨兵A回复Y,不赞成则给哨兵A回复N。

2025-02-05 16:44:58 916

原创 《redis哨兵机制》

答案是肯定的,因为主库要扛住那么高的并发请求,网络带宽的压力肯定很大,那是否存在一种可能,哨兵主动PING主库,主库没来得及回应,此时如果哨兵就单纯地认为主库下线了,就显得不客观,主库便被认定为"主观下线"。基于这一现状,redis推出除了哨兵集群,也就是在多个主机上分别运行多个哨兵,构建成一个哨兵集群,这些哨兵同时监控所有的主库和从库,假设有超过半数以上的哨兵没法和主库PING通,那么此时主库大概率是下线,主库此时便被认定为"客观下线"。如果主库没有回应PING请求,那么哨兵会认为主库挂了,随后便开始。

2025-02-05 16:32:04 346

原创 《redis主从同步机制》

为什么从库不能提供"写"的能力,我们假设一个场景,用户对一个键为"hello",值为"world"的键值对,修改了三次,分别修改为"world1"、"world2"、"world3",假设这三个请求分别发给了上面的主库、从库1、从库2,那么就会出现一个问题,主库、从库的数据出现了不一致的情况。先介绍下从库的概念,何为从库,其实和主库一样,是主库的一个副本,内存中的数据和主库保持一致,从库和主库分别部署在不同的主机上,主库宕机了,从库依然可以对外提供增、删、改、查的能力。主从库网络断开连接,主从库会采用。

2025-02-05 16:21:40 1078

原创 《Redis4.0数据持久化》

但是老的AOF文件,可能存在这种情况,键值"hello"对应的value被多次修改,最终才变成"world",那么老AOF文件会记录下和"hello"相关的所有改动,因为老的AOF文件就存在很多多余的指令,新的AOF文件只会保留一条指令,能让内存中的数据恢复到最新的状态。AOF日志文件的内容可能是这样的。针对问题b,假设AOF文件很大,比如:随着redis运行的时间的递增,AOF文件大小到了10G,那么此时往10G大小的AOF文件末位追加指令,势必给磁盘带来很大的压力,redis采用了。

2025-02-05 16:17:06 938

原创 《redis4.0 通信模块源码分析(一)》

笔者从大学毕业一直有分析redis源码的想法,但由于各种原因,一直没有付诸行动,今天抽空把redis4.0的源码做了一次深层次的剖析,redis作为一款高效的、支持高并发的内存型数据库,相信很多同学认为redis采用了非常复杂的网络通信架构,但实则不然!redis之所以性能高,redis4.0采用了单线程的模式(redis-server也是作为一个独立的进程,既然是独立的进程,那么程序肯定有入口点,也即是main函数入口,全局搜索了下redis的源码,可以看到server.c中有main函数有入口。

2025-02-05 16:11:10 1128

原创 《网络编程基础之完成端口模型》

正如前文所说,完成端口模型帮我把连接建立,我们只需要准备好客户端套接字即可,可以这么理解吧!应用层只需要投递个接收连接的请求,等到操作系统通知我们的时候,连接已经建立好,客户端套接字已经生效,它表示一个合法的"客户端对象",此时可以通过这个客户端套接字和对端建立连接,进行数据通信。那投递接收连接请求的接口是哪个?就是AcceptEx。m_lpfnAcceptEx就是我们拿到的AcceptEx函数指针,我们可以使用它来投递一个接收连接的请求。好!

2025-02-01 12:47:39 766

原创 《多线程基础之互斥锁》

初步看了下源码,__lll_lock_wait会陷入无限循环的等待中去,因为最终传递给lll_futex_timed_wait接口的超时时间为NULL,直到和锁相关的futex状态变成预定值,也即其它线程释放了这把锁,更改了futex的状态。所以锁底层的知识面还是很细的,需要深入剖析底层的源码,分析加解锁的流程,那么遇到锁一类的问题就能迎难而解了。好,我们稍微修改下上述的示例代码,让程序运行的流程出现死锁,我们可以关注下进程如果出现了死锁,会有怎样的表现。)卡住了,两个子线程分别争夺对方占用的锁。

2025-01-29 12:38:22 393

原创 《多线程基础之条件变量》

本文将分别为您介绍条件变量在windows和linux平台下的用法和注意事项,好!直接进入主题。条件变量的使用场景可以用如下流程图进行阐述。我们需反复判断一个多线程共享条件是否满足,一直到该条件满足为止(因此每次判断前进行加锁操作,判断完毕后解锁。但上述逻辑存在严重的效率问题,假设我们解锁离开临界区后,其他线程修改了条件,导致条件满足了;此时程序仍然需要睡眠 n 秒后才能得到反馈。

2025-01-27 20:33:00 502

原创 《STL基础之vector、list、deque》

您真的了解STL的vector、list、deque这三个容器吗?vector还是以原始大小的2倍去动态扩容吗?

2025-01-27 09:35:12 1424

原创 《STL基础之hashtable》

但只有vector还是不够的,因为操作系统的内存空间有限,要支持存储海量数据,而且这些海量数据都存放在连续的内存中,肯定不现实,比如:笔者有1000万个,大小为3字节的随机字符串,我们如果把这些数据存放在一段连续的内存空间中,我们就需要申请长度为10000000的指针数组,依次存放这些字符串,总共占用内存大小将近4。可以这么理解,vector中每个单元便是链表的头节点,如果有其它的字符串的哈希值也是2,那么就在索引值为2的单元下扩展这个单链表。介绍完插入节点,那查找节点的流程又是怎样的?

2025-01-26 12:28:13 408

原创 《STL基础之map》

map相信大家都了解,但是map背后的红黑树大家有了解过吗?本文将以图文并茂的形式向您阐述往map中插入元素的全过程。

2025-01-26 07:52:22 825

原创 《weak_ptr源码剖析》

1、weak_ptr更多是对shared_ptr托管内存的一个弱引用,不参与托管内存的生命周期的管理,从__weak_ptr的析构函数可以看出,它并没有对它维护的_M_ptr执行释放操作。weak_ptr是一种比较特殊的智能指针,不像unique_ptr、shared_ptr一样可以托管原始的指针,它更多扮演着辅助的角色,配合shared_ptr去使用,那它背后的原理是怎样的?把一个shared_ptr拷贝赋值给weak_ptr,内部也是调用__weak_ptr模板类的拷贝构造函数。

2025-01-19 18:23:56 451

原创 《shared_ptr源码剖析》

本文将以Centos标准库为基础,剖析shared_ptr的源码,shared_ptr主要包含两个部分:shared_ptr_base.h和shared_ptr.h,虽然涉及的文件不多,但为了实现一套完备的内存托管方案出来,gcc还是设计很多类出来。且看如下图片,笔者将结合图片逐步为您剖析shared_ptr托管内存的原理和细节。1. shared_ptr结构和源码。

2025-01-05 09:47:12 1292

原创 《Windows堆内存剖析 (三)》

前两节介绍了进程前、后端分配器,进程的私有堆,那么比如:char* pBuf = new char[1024],像这类我们应用层主动申请的crt堆,应该如何去分析?那么本文将为您细致地剖析!本文将重点剖析进程crt堆,结合windbg调试工具,为您分析crt堆从申请到释放的全过程,其中会掺杂一些面试题哦!比如:面试官问你以下代码执行完,操作系统给pBuf分配的内存大小一定是1024个字节吗?我觉得大部分人肯定会回答「1024个字节」让人吃惊的是,这个答案是错的!意不意外!

2024-12-01 18:48:37 1152

原创 《Windows堆内存剖析(二》

逐个分析各字段对应的值,size为00018,也即是24字节,减去8字节的元数据,那就是我们调用HeapAlloc申请的16字节,state为busy,说明这段内存被占用,requested size为10,也即是16字节,刚好是我们申请的大小。对进程的堆数量以及相关的类型有了初步了解,那么以本文为例,我们创建的进程私有堆,到底长什么样,有相关的数据结构去表示进程的私有堆吗?:表示进程的默认堆,进程被操作系统拉起时,需要创建的堆内存,不要和我们应用层主动创建的堆搞混了。进程堆的预定大小,默认值为1M。

2024-12-01 18:18:20 736

原创 《windows堆内存剖析(一)》

虚拟内存管理器申请到的内存为堆段Heap Segment,假设一个堆段的内存空间被耗光了,此时堆管理器将请求虚拟内存管理器创建一个新的堆段出来,而且大小是之前的两倍。也算是一种较为高效的内存分配方式吧,假设应用层需要16字节的内存,而此时24字节(16字节 + 8字节的元数据)的堆块已经耗光了,那么后端分配器将继续往下遍历空闲列表,如果存在48字节的堆块,此时后端分配器将48字节的堆块一分为2,一份24字节的堆块返回给应用层,另外一份24字节的堆块会插到24字节堆块对应的链表中去。内存碎片是如何产生的?

2024-12-01 18:03:43 896

原创 《unique_ptr》源码剖析

unique_ptr很多同学都知道它的用法和规则,标准库是如何保证unique_ptr对它托管数据的唯一性的?unique_ptr的核心部分包含__uniq_ptr_impl、_uniq_ptr_data、unique_ptr三大类,我们剖析源码也将从这三大类开始剖析。1、unique_ptr任何操作都不是线程安全的,它的适用性和可拓展性依赖于内部模板元编程的一些技巧,如类型推断、条件判断和模板特化等。2、unique_ptr不支持拷贝构造和拷贝赋值,托管的堆内存只能在两个unique_ptr之间移动。

2024-12-01 17:36:24 296

原创 Claude 3.5深夜觉醒,学会模仿人类用电脑!编程干翻o1,Agent一夜变天

Claude 3.5 Sonnet能够理解细微的指令和上下文,识别并纠正自身错误,还能从复杂数据中生成深入的分析和洞察。现在,Asana、Canva、Cognition、DoorDash、Replit和The Browser Company等多家知名公司,已经在探索Claude的新潜能,让它们执行数十步甚至数百步的复杂任务了。凭借快速的处理速度、改进的指令执行能力和更准确的工具使用,Claude 3.5 Haiku非常适合面向用户的产品、专门的辅助任务,以及从海量数据中生成个性化体验。

2024-10-29 09:57:06 1223

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除