自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(377)
  • 收藏
  • 关注

原创 LRU怎么实现,说一下具体思路

摘要:LRU缓存通过哈希表和双向链表结合实现,哈希表提供O(1)查询,双向链表维护访问顺序。get操作时若存在则移动节点至头部;put操作时更新或新增节点至头部,若缓存满则删除尾部节点。这种设计确保所有操作在O(1)时间内完成。

2025-09-23 09:46:00 68

原创 什么是缓存一致性,缓存一致性如何保证?

缓存一致性是保证多处理器系统中各缓存数据一致性的机制。主要方法包括总线监听和目录协议,常用MESI协议实现。在MESI协议中,缓存行有四种状态:修改(M)、独占(E)、共享(S)和无效(I)。当处理器修改数据时,会通知其他处理器使其缓存失效或更新,确保数据一致性。例如,当处理器A修改共享变量时,处理器B的相应缓存会被标记为无效,保证下次读取时获取最新值。这些机制确保了多个处理器对同一内存位置的数据访问结果一致。

2025-09-22 10:09:53 185

原创 TCP滑动窗口是什么?有几种类型?分别是什么?

TCP滑动窗口是TCP协议的关键流量控制机制,允许连续发送多个数据包而不需等待确认。它包含两种类型:接收窗口(由接收方维护,反映其缓冲区容量)和拥塞窗口(由发送方维护,用于网络拥塞评估)。实际发送窗口取两者较小值,既保证接收方处理能力,又兼顾网络承载状况。该机制通过动态调整窗口大小,有效平衡了传输效率和网络稳定性。

2025-09-22 09:47:04 138

原创 十亿个数取最大的10个数怎么取

使用小根堆高效找出十亿数中的最大10个数:建立容量10的小根堆,遍历数据时,若数大于堆顶则替换,最终堆中即为最大数。时间复杂度O(n),空间复杂度O(1)。

2025-09-22 09:41:01 162

原创 什么是并行和并发,有什么区别呢?

并行和并发是两个易混淆的概念。并发是指同一时间段内交替处理多个任务,看似同时实则轮流执行;而并行是真正同时执行多个任务,需要多核等硬件支持。简单说,并发是"处理多个任务"的能力,并行是"同时执行多个任务"的能力。实际系统中常结合使用,如多核处理器既能并行执行多个线程,每个核又能并发处理多个任务。

2025-09-22 09:36:52 71

原创 简述一下 std::move 做了什么才能将一个左值 c++对象中内存的所有权交给其他对象的,什么情况下对一个对象调用 std::move 之后这个对象依旧可以正常使用。

std::move将左值转为右值引用,使能移动语义但不实际移动对象。移动后对象处于有效但未指定状态,能否继续使用取决于类型:标准容器会变为空,智能指针变null,自定义类依实现而定。良好实践是移动后避免使用其值,可重新初始化或销毁。标准库类型通常保证移动后仍可安全使用。

2025-09-22 09:32:26 169

原创 vector和list在内存上怎么存储的

Vector和List在内存存储方式上有本质区别。Vector使用连续内存块,支持O(1)随机访问但插入/删除效率低;List采用链表结构,插入/删除高效但查找需遍历。两者元素数据主要存储在堆内存中:Vector分配一整块连续内存,List则分配多个独立内存块。容器对象本身可能在栈或堆上,但管理的数据通常在堆上。

2025-09-19 10:01:01 192

原创 客户端网断了,服务器会知道吗?

客户端网络断开时,服务器不会立即察觉,但最终会通过以下机制发现:1)TCP重传超时机制(需几十秒到几分钟);2)TCP keepalive探测(通常几分钟);3)应用层心跳机制(最快几秒)。这些机制能区分短暂波动与完全断开,确保连接可靠性。实际开发中常结合多种方式快速检测网络问题。

2025-09-18 09:50:39 166

原创 连接过程中客户端宕机,服务器会知道吗?

服务器不会立即发现客户端宕机,但最终会通过以下方式察觉:1)发送数据时收到RST包;2)TCP保活机制(若启用)多次探测无响应;3)应用层超时。实际应用中建议采用心跳机制、配置TCP保活参数和设置应用层超时,避免无效连接占用资源。

2025-09-18 09:46:35 130

原创 很多线程都处于close wait的原因是什么,该如何解决

摘要:CLOSE_WAIT状态堆积是由于应用程序未正确关闭TCP连接导致的,常见原因包括代码中遗漏close()调用、异常处理不当或程序繁忙未及时释放连接。解决方案包括:检查并完善连接关闭逻辑,使用连接池管理,设置超时机制,正确使用框架提供的关闭方法,建立监控告警系统。临时措施可调整TCP参数,但根本解决需从代码层面修复连接管理问题。

2025-09-18 09:42:56 117

原创 UDP传输1GB数据可以吗,如何实现

摘要:理论上UDP可以传输1GB数据,但需在应用层进行分包处理,并实现可靠传输机制(如编号、确认应答、超时重传和流量控制),相当于在UDP上重建TCP功能。虽然可能实现,但需要大量工作,实际项目中若无特殊需求,使用TCP或HTTP传输可能更简单可靠。

2025-09-18 09:28:51 242

原创 UDP可以传输1兆数据吗?

摘要:理论上UDP可以传输1兆数据,但存在实际限制。UDP单个报文最大仅65507字节,需应用层分包;且UDP无可靠性保证,大文件传输时丢包风险高。网络设备可能对UDP包分片,单个分片丢失即导致整个包丢失。此外,ISP和防火墙常对UDP流量设限。因此实践中建议使用TCP,或在UDP上实现可靠传输机制(如QUIC协议)来传输大文件。

2025-09-18 09:25:45 219

原创 孤儿进程和僵尸进程

孤儿进程和僵尸进程是多进程编程中的常见现象。孤儿进程是父进程退出后被子进程继续运行,由init进程接管回收,常用于守护进程实现。僵尸进程则是已完成但未被父进程回收的进程,会占用PID资源。解决方法包括:1)父进程主动调用wait/waitpid回收;2)设置SIGCHLD信号处理函数自动回收。实际开发中,特别是多进程服务器场景,通常采用信号处理机制来避免僵尸进程积累,确保系统资源有效释放。

2025-09-17 10:02:31 104

原创 堆和栈会不会冲突

堆和栈在内存中通常朝相反方向增长,理论上可能冲突,但现代操作系统会通过内存保护机制避免直接碰撞。栈自动管理且适合存储小对象,堆需要手动管理适合大对象。实际开发中应合理使用二者:栈用于短生命周期数据,堆用于长生命周期数据。系统会在内存不足时抛出异常而非直接覆盖,因此冲突风险很低。关键在于理解二者特性并正确运用。

2025-09-17 09:42:16 188

原创 如果我有一堆正整数需要频繁的插入和删除并且要知道第几大的数应该用什么数据结构?为什么?

建议使用平衡二叉搜索树(如红黑树或AVL树)来解决该问题。通过在节点中维护子树大小信息,可在O(logn)时间内完成插入、删除和查询第K大元素操作。具体实现时,可利用子树节点数量定位第K大元素:比较K值与右子树节点数决定搜索方向。C++中的std::multiset/map虽基于红黑树,但需自行实现子树计数功能。该数据结构完美满足动态顺序统计问题的各项需求。

2025-09-17 09:29:47 138

原创 TCP和HTTP的关系

TCP和HTTP是网络协议栈中不同层次的协议。TCP是传输层协议,负责可靠的数据传输;HTTP是应用层协议,建立在TCP之上,规范客户端与服务器的通信格式。HTTP依赖TCP建立连接、传输数据并断开连接。虽然HTTP理论上可使用其他传输协议,但实际主要基于TCP实现(HTTP默认80端口,HTTPS默认443端口)。两者的关系类似于邮政系统(TCP)与信件格式标准(HTTP)的关系。

2025-09-17 09:20:16 141

原创 fork的原理,使用fork的时候内核态和用户态之间怎么转化的

fork是Unix/Linux创建新进程的基本方法,通过系统调用从用户态切换到内核态,内核为新进程创建描述符并复制父进程页表(采用写时复制技术)。父子进程最初共享内存页,仅在修改时复制,提高效率。内核为子进程分配PID并设置返回值,最后切换回用户态。写时复制机制通过页错误触发实际复制,优化内存使用。fork常与exec配合使用,避免不必要的内存复制。

2025-09-16 10:01:01 209

原创 MySQL的索引为什么采用B+树而不是B树

MySQL采用B+树而非B树主要基于查询效率考量:B+树将所有数据存储在叶子节点,并形成链表结构,使范围查询和全表扫描更高效;非叶子节点仅存键值,能容纳更多索引项,减少I/O次数;结构更稳定,适合频繁更新的数据库系统。这些特性使B+树特别适合需要大量范围查询的关系型数据库场景。

2025-09-15 14:05:46 394

原创 这段代码输出的是什么

这段代码展示了C++继承和多态的问题。当基类human的析构函数和disp()方法未被声明为virtual时,程序输出为: human disp..(静态绑定导致调用基类方法) humanover...(非虚析构导致只调用基类析构) 主要问题在于: 方法调用由指针静态类型决定 非虚析构导致子类析构未调用 可能引发资源泄漏 解决方案: 将析构函数声明为virtual 需要多态的方法声明为virtual 修改后才会正确输出子类方法和完整析构链。

2025-09-15 09:47:44 149

原创 如果一个shared_ptr的地址引用和对象引用作为一个函数的参数,这个函数被多次调用后shared_ptr内部的引用计数如何变化

当函数参数为shared_ptr的引用时(std::shared_ptr<int>&),多次调用不会改变引用计数,因为传递的是引用而非拷贝。若参数为shared_ptr值传递(std::shared_ptr<int>),每次调用会临时增加引用计数(函数内+1,结束时-1),最终计数保持不变。对象引用参数(int&)不影响引用计数。实际应用中,若无所有权转移需求,建议使用引用或裸指针以提升性能,仅在需要共享所有权时才按值传递shared_ptr。(149字)

2025-09-12 16:05:29 321

原创 delete和delete[]的区别

摘要:delete用于释放new分配的单个对象,只调用一次析构函数;delete[]用于释放new[]分配的数组,会调用每个元素的析构函数。二者混用可能导致资源泄漏或内存损坏:对数组用delete会漏调析构函数,对单对象用delete[]会引发未定义行为。基本原则是:new/delete和new[]/delete[]必须配对使用。这也反映了C++内存管理的严谨性,体现了现代C++推荐智能指针的原因。(150字)

2025-09-12 15:34:24 189

原创 C++编译链接流程

C++程序编译链接流程分为四个阶段:预处理阶段处理#include、#define等指令,生成.i文件;编译阶段进行语法检查并生成汇编代码(.s文件);汇编阶段将代码转为机器指令(.o/.obj文件);最后链接阶段合并目标文件,解决符号引用并生成可执行文件。每个阶段各司其职,共同完成从源代码到可执行程序的转换。

2025-09-10 09:30:08 233 1

原创 LeetCode - LCR 179. 查找总价格为目标值的两个商品

摘要:该题目要求在有序数组中找到两个数使其和等于目标值。解法1暴力枚举未利用有序特性,效率低。解法2利用单调性采用双指针算法:初始设左右指针分别指向首尾元素,根据当前和与目标值的比较调整指针位置(和小于目标则左移右指针,大于则右移左指针),直至找到匹配对。常见错误是直接操作指针而非数组元素值。正确实现应比较数组元素和,最终返回满足条件的数值对或{-1,-1}表示无解。

2025-09-08 22:55:02 423

原创 LeetCode - 611. 有效三角形的个数

本文介绍了两种解决三角形计数问题的算法思路:暴力枚举和双指针优化。重点分析了双指针算法的实现细节,指出常见错误是将下标比较误写为值比较。正确写法应比较nums[left]+nums[right]与nums[c]的大小关系,当满足三角形成立条件时,直接累加right-left种情况,提升效率。通过示例代码展示了错误写法和正确实现的区别。

2025-09-06 21:53:36 264

原创 LeetCode - 202. 快乐数

快乐数问题可通过判断数字变换过程中是否成环来解决。关键点在于初始化快慢指针时,快指针应初始化为bitSum(n)而非n,否则无法进入循环。正确解法使用快慢指针检测环,若最终环内数字为1则是快乐数。常见错误是快指针初始值设置不当导致逻辑错误。时间复杂度和空间复杂度均为O(logn)。

2025-09-06 20:05:23 328

原创 LeetCode - 1089. 复写零

本文介绍了LeetCode题目1089"复写零"的解决思路。采用双指针方法,先通过"异地操作"确定最后一个有效元素的位置,再处理边界情况。初始方案存在三个问题:循环条件错误、缺少边界处理、指针越界风险。改进后的方案正确处理了当最后一个0导致指针越界的情况,在循环中先判断0元素并调整指针位置,最后从后向前复写数组元素。关键点在于正确处理边界条件和指针移动逻辑,确保数组元素正确复写且不越界。

2025-09-06 18:04:34 548

原创 讲一下模版特化和偏特化的区别

模板特化与偏特化的区别 模板特化是针对特定类型提供特殊实现,分为全特化和偏特化两种。全特化确定所有模板参数(如template<> class C<int>),偏特化只确定部分参数(如template<typename T> class C<T*>)。关键区别在于参数确定程度。函数模板只能全特化,不能偏特化(可用重载代替),而类模板支持两种特化方式。编译器会优先匹配最具体的特化版本。

2025-09-06 11:20:57 178

原创 讲解一下冒泡排序

冒泡排序是一种基础排序算法,通过相邻元素比较交换实现排序。算法过程像气泡上浮,每轮将最大元素移至末尾。以数组[5,2,8,1,9]为例,经过多轮比较交换后最终有序。时间复杂度为O(n²),空间复杂度O(1)。示例代码展示了C++实现,包含双重循环和交换操作。该算法直观易懂,适合初学者理解排序原理。

2025-09-06 11:00:14 325

原创 LeetCode - 21. 合并两个有序链表

本文介绍了合并两个有序链表的双指针解法。通过创建哑节点作为头节点,使用两个指针遍历链表,比较节点值并连接较小节点。关键点包括:每次连接后需移动当前指针(cur=cur->next),剩余链表要用while循环处理,最终返回dummy->next。常见错误有:忘记移动cur指针、错误使用if代替while处理剩余节点、返回错误指针等。正确实现需注意上述细节,确保链表正确合并。

2025-08-30 12:00:37 327

原创 LeetCode - 141.环形链表

该文章介绍了使用快慢指针法判断链表是否有环的算法。通过设置慢指针(每次1步)和快指针(每次2步),若有环则两指针必会相遇,否则快指针将先到达链表尾部。文中给出了具体的C++实现代码,并解释了算法原理:在环中快指针每次循环会缩短与慢指针1步的距离,最终必定相遇。该方法时间复杂度为O(n),空间复杂度为O(1)。

2025-08-30 10:45:06 202

原创 B树和B+树有什么区别

B树和B+树的关键区别:1)数据存储位置不同 - B树数据可存于任意节点,B+树仅存于叶子节点;2)叶子节点组织方式不同 - B+树叶节点构成有序链表,利于范围查询;3)查询效率侧重不同 - B树适合随机查询,B+树擅长批量顺序操作。典型应用:MySQL使用B+树优化范围查询,MongoDB采用B树提升单点查询性能。

2025-08-30 10:33:16 152

原创 LeetCode - 234. 回文链表

本文介绍了判断链表是否为回文的算法。使用快慢指针找到中点,处理奇偶长度情况:奇数长度时跳过中间节点,偶数长度时直接反转后半部分。通过递归反转链表后半段,然后比较前后两半是否相同。常见错误是未正确处理奇数长度链表,导致中间节点参与比较。正确解法应区分奇偶情况,奇数时从中点下一个节点开始反转。算法时间复杂度O(n),空间复杂度O(n)来自递归栈。

2025-08-30 10:32:49 447

原创 LeetCode - 160. 相交链表

本文介绍了一种寻找两个单链表相交节点的巧妙方法。通过使用双指针遍历链表,当指针到达链表末尾时切换到另一链表头部继续遍历。这样两个指针走过的路径长度相同(A链表长度+B链表长度),若链表相交则必会在交点相遇,否则同时到达NULL。该方法时间复杂度O(m+n),空间复杂度O(1),能高效解决问题。

2025-08-30 08:48:52 290

原创 LeetCode - 11. 盛最多水的容器

摘要:该问题采用双指针法高效求解,初始时左右指针分别位于数组两端,计算当前容器容量后移动高度较小的指针。这种方法基于容器容量受限于较短边的原理,移动短边可能增加容量,而移动长边必然减少容量。算法时间复杂度优化至O(n),空间复杂度为O(1)。关键代码仅需10行左右,通过比较指针处高度并更新最大值来解决问题。

2025-08-30 08:32:53 338

原创 LeetCode - 283. 移动零

本文介绍力扣283题"移动零"的双指针解法。使用左指针left标记非零元素末尾位置(初始为-1),右指针right遍历数组。当遇到非零元素时,先递增left再交换元素,保证非零元素顺序不变。常见错误是交换和递增顺序错误,正确做法是使用前置递增++left交换,避免初始left=-1时的越界问题。该算法时间复杂度O(n),空间复杂度O(1),能高效完成零元素后移任务。

2025-08-29 22:58:16 299

原创 LeetCode - 128. 最长连续序列

题目要求O(n)时间复杂度,因此不能使用排序。核心思路是利用哈希集合实现常数查找,通过仅从序列起点(即当前数字-1不在集合中时)开始计算,避免重复操作。常见错误是在遍历时直接使用原数组而非集合,导致重复计算和超时。正确解法应遍历哈希集合,确保每个数字只处理一次,从而保证总体时间复杂度为O(n)。

2025-08-29 17:22:13 171

原创 LeetCode - 49. 字母异位词分组

该题解讨论了LeetCode字母异位词分组问题的解法。核心思路是利用哈希表,将排序后的字符串作为键,原词存入对应列表。常见错误包括:直接赋值而非push_back添加元素,以及返回类型不匹配。正确解法需遍历输入数组,排序字符串作为键存入哈希表,最后将哈希表值转为二维vector返回。该方法有效将异位词(如"eat"和"tea")分组存放。

2025-08-29 16:29:00 309

原创 LeetCode - 1. 两数之和

本文介绍了LeetCode"两数之和"问题的哈希表解法。核心思路是通过一次遍历数组,在哈希表中存储元素值及其索引,同时检查目标值与当前元素的差值是否存在。常见错误包括:1)错误地存储元素出现次数而非索引;2)条件判断表达式错误;3)返回结果格式不正确。正确解法应直接查找差值是否存在,并返回对应索引。该方法将时间复杂度优化至O(n),空间复杂度为O(n)。

2025-08-29 15:56:00 178

原创 TCP和HTTP的keep-alive的区别

TCP和HTTP的keep-alive机制有本质区别。TCP的keep-alive是传输层机制,通过探测包检测连接有效性,防止资源浪费;而HTTP的keep-alive是应用层机制,用于实现持久连接,在单个TCP连接上传输多个HTTP请求/响应以提高效率。前者关注连接存活状态,后者侧重连接复用。

2025-08-29 00:00:04 142

原创 HTTPS的底层是怎么做的,使得数据更安全

HTTPS通过TLS/SSL协议实现安全数据传输,主要采用三种机制: 混合加密(非对称加密交换密钥+对称加密传输数据) 数字证书认证服务器身份 消息认证码保证数据完整性 此外还支持完美前向保密,即使私钥泄露也不会影响历史通信安全。这些措施共同确保了网络通信的机密性、真实性和完整性。

2025-08-28 23:59:45 233

耗时一个月,15万字+的Linux思维导图!!!

耗时一个月,15万字+的Linux思维导图!!!

2025-05-31

空空如也

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

TA关注的人

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