- 博客(188)
- 收藏
- 关注
原创 一文看清:“臭名昭著“ 的双检查锁
但是在实际的中,经过了指令重排可能会出现 ①③② 这种排列。一旦出现了这种情况,可能会对程序造成不可估计的后果。很抱歉,这已经不是普通程序员能涉及的层面了,需要各个语言标准和编译器方来处理。具体原因需要往更深层次去探讨。我们脱离代码层面,考虑 CPU 的指令层次会出现一个问题。双检查锁,即锁前检查一次,锁后检查一次。进而避免了无脑上锁对运行时候的性能损耗。到了这里,我们的问题都解决了吗?答案是并非解决,甚至。因此这两次检查都是必不可少的。③. 给调用方返回地址。
2026-05-25 16:30:46
14
原创 一文读懂:C++中单例模式的实现
单例模式是一个比较模板化的设计模式,通常在实际应用中可以直接复用写好的框架。对于这个全局的访问点,我们需要设置一个 pubilc 的 static 函数,下文也是着重对该函数进行讲解。
2026-05-25 08:42:47
110
原创 线段树入门:更新数组后处理求和查询
对于操作2,由于题中表明 数组中的值只有 ,因此每次 数组中增加的大小实际上是 数组中当前 的个数;由上述可知,对于某一段区间不需要知道其具体位置上是 ,只需要维护该区间内 的个数(通过 线段树 ),因此对于操作 ,只需要改变区间内 的个数;每当遇到操作 ,将当前的 值加入答案数组即可。:第一个操作后 nums1 变为 [1,1,1]。第二个操作后,nums2 变成 [1,1,1] ,所以第三个操作的答案为 3。:第一个操作后,nums2 保持不变为 [5] ,所以第二个操作的答案是 5。
2026-05-24 17:22:53
33
原创 线段树入门:区间更新
在查询过程中,若当前节点带有懒标记,则将懒标记下传给子节点 (将当前节点的懒标记清除,将子节点更新并做懒标记),继续查询。(1)若当前节点的区间被查询区间 覆盖,则仅对该节点进行更新并做懒标记,表示该节点已被更新,对该节点的子节点暂不更新。另外,带有懒标记的区间查询和普通的区间查询不同,在查询过程中若遇到有节点带有懒标记,则下传懒标记,继续查询。若对区间的每个点都进行更新,则时间复杂度较高,可以引入懒操作。对 区间进行更新,例如将 区间的所有元素都更新为 ,步骤如下。(3)在返回时更新最值。
2026-05-24 09:26:37
104
原创 五分钟读懂:桥接模式是如何构成的?
具体抽象化 (Refined Abstraction):具体抽象化是对抽象化的实现,它继承了抽象化并实现了其中的抽象方法。具体实现化 (Concrete Implementor):具体实现化是对实现化的具体实现,它实现了实现化接口中定义的方法。理论性的概念比较难以理解接下来我们就通过前文的汽车和颜色的例子来使用桥接模式来关联汽车类型与颜色的关系,同时为不同类型汽车灵活扩展颜色。的历史发展经过了多年的实践和应用,它已经成为了软件开发中常用的一种设计模式,被广泛地应用于各种不同的领域和项目中。
2026-05-23 20:46:12
35
原创 双栈实现方法实例分析
在考研中一般要求学生能够写出单次计算和后缀表达式生成的全过程。而求职中则需要能够 ac 掉笔试的代码题。最后基于双栈的方法除了处理本文中提到的常见四则运算外,还可以针对四则运算以外的运算符或者自定义的运算符进行处理。根据运算符的种类,对数值栈的栈顶元素和栈顶倒数第二个元素进行运算,并将计算结果再次保存到数值栈中。表达式求值是数据结构的学习中非常经典的一个应用。基于上文对后缀表达式的操作与解释。现在正式展示具体的代码实现。在遍历时,需要同时对后缀表达式的。首先最重要的,我们需要两个和栈。
2026-05-23 09:46:16
223
原创 钣金仿真软件|Dynaform 5.9.4全流程下载安装教程
如大家所了解的,Dynaform是一款功能强大的专用板料成形(钣金冲压)CAE仿真软件,基于有限元方法,集成LS-DYNA求解器与ETA/FEMB前后处理器,用于模拟从坯料展开到回弹补偿的全流程冲压工艺。目前比较常用且稳定的版本为Dynaform 5.9.4中文版,深受使用者的青睐与好评。接下来,小编将从应用场景、核心功能与特点学习、安装包下载、Dynaform保姆级安装教程等几个方面带大家来了解和熟悉这款可视化分析工具,希望对大家的学习、工作有所帮助!
2026-05-22 12:58:08
759
原创 机器学习评价指标之基础指标与综合指标
对于转换为二分类的多分类模型,我们可以沿用常用的二分类模型的评价指标,包括准确率(Accuracy)、混淆矩阵(Confusion Matrix)、精确率(Precision)、召回率(Recall)、F1 分数(F1-Score)等,此处不展开介绍。评价指标的计算方法在两种方法中有一些差异,但它们都提供了对模型性能的有效度量,用于评估模型在多分类任务中的表现。混淆矩阵(Confusion Matrix):展示模型在每个类别上的表现,计算各个类别的精确率、召回率、F1 分数等评价指标。
2026-05-22 09:04:21
149
原创 什么是换根DP及第一步操作说明
以上的描述,就是最基础的树形 DP 操作。也是换根 DP 中的第一轮扫描。获取以确定 root 为根的状态下,所有子树的深度 deep[]。我们规定任意一个点作为根 root,进行树形 DP 的操作。
2026-05-21 21:56:15
47
原创 三分查找经典实例分析与学习
想必大家不会陌生,二分查找,又名折半查找。是一种非常经典,简单又实用的查找算法。而在二分的基础行又衍生出了三分查找的技术和应用。
2026-05-21 09:17:48
25
原创 一文读懂什么是 A* 算法
如果您最多可以消除 个障碍物,请找出从左上角 到右下角 的最短路径,并返回通过该路径所需的步数。如果找不到这样的路径,则返回。A* 算法(A-star search algorithm)是一种在图形平面上,有多个节点的路径,求出最低通过成本的演算法。解释: 不消除任何障碍的最短路径是。消除位置 处的障碍后,最短路径是。其实,电子地图之所以能够快速的从无数条线路中找到最短路径,就是因为 A* 算法的帮助。本文将带大家了解 A* 算法的基本思想,并通过一道例题去学习该算法的使用技巧。
2026-05-20 14:00:08
126
原创 浅谈:GROUP BY 1,2 和 GROUP BY 列名
但在大规模数据集(例如百万甚至千万数据集以上),特别是当有索引可用时,MySQL 优化器可能会根据 索引的情况 选择更有效的方式进行分组。GROUP BY 1,2 是使用列的位置(第一列和第二列)进行分组,而 GROUP BY 列名 是使用列的名称进行分组。在实际操作中,MySQL 优化器会将列的位置或名称映射到实际的列,并在执行计划中选择最有效的方式进行分组。因为它们都是对相同的列进行分组操作。如果你觉得有,说出你的看法,欢迎大家评论区留言探讨,如果大家想要看那个存储过程是如何写的,也可以评论区留言。
2026-05-20 08:35:04
148
原创 C++中函数对象之重载 operator()
如大家所熟悉的,重载 operator()是 C++ 中一种特殊机制,允许类的对象像函数一样被调用。这种对象被称为 函数对象(functor) 或 仿函数。
2026-05-19 21:13:19
50
原创 一文读懂递归求值的简单应用
这里的终止条件简单说就是没有数需要相加了。因为可以写一个空参的函数表示终止的调用。这里我们借助:C++ Insights (C++ Insights) 来进行查看编译器中间代码的生成。观察到代码中的几个模板特化,可以看的出,编译器为每次递归的都进行的模板的展开。直到展开到我们的终止条件为止,这也非常符合我们使用递归算法的直觉。我们现在预想一个需求场景:使用递归的方式计算一系列数值的和。而每次的运算,需要取出一个数,并将剩下的数进行递归调用。但是编译器到底是如何处理该代码的呢?
2026-05-19 08:47:59
24
原创 数控编程软件|PowerMill 2026全流程下载安装教程
模具制造:高效处理深腔、倒扣、薄壁等难加工结构;航空航天:用于叶片、轮毂、歧管等复杂曲面零件的高精度五轴加工;汽车工业:支持端口、缸体等关键部件的高速铣削与混合制造;增材与混合制造:支持DED(定向能量沉积)、FFF等工艺的路径规划与仿真。。
2026-05-18 17:41:03
1669
原创 路径规划之穷举法实例讲解与学习
该代码用邻接矩阵存储图,通过库函数 next_permutation 获得所有的遍历情况,并计算每种情况的路径和,来获得最短路径。是最直观的解决方案,但随着城市数量的增加,计算时间呈指数级增长,效率极低。2.将选定的城市标记为已访问,重复上述步骤,直到所有城市都被访问过。1.从一个起始城市开始,选择距离当前城市最近的未访问城市。3.最后,回到起点城市,形成一条路径。
2026-05-18 08:58:38
136
原创 广度优先搜索之层序遍历
二叉树的层序遍历方式是从上到下,从左到右依次访问二叉树的所有节点。算法使用一个队列来存储二叉树的节点。初始时,将根节点加入队列。然后从队列首部取出一个节点,访问该节点,并将其左右子节点(如果存在)加入队列尾部。重复上述操作,直到队列为空。给你二叉树的根节点 root,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。树中节点数目在范围 [0, 2000] 内。
2026-05-17 17:53:55
29
原创 二叉树的遍历算法之中序遍历
应用场景:广泛应用于计算机科学中的表达式树求值、数据检索及非线性存储结构处理。遍历规则:先递归遍历左子树,再访问根结点,最后递归遍历右子树,若树为空则直接返回。主要特点:对于二叉搜索树,中序遍历能得到从小到大的有序序列,常用于数据排序。是二叉树的一种遍历方式,核心顺序是“左子树→根节点→右子树”。中序遍历就是先遍历左子树,然后访问根节点,最后遍历右子树。相信正在学习二叉树的小伙伴,不会感到陌生。
2026-05-17 09:25:34
38
原创 一文读懂:原始套接字的前世今生
也就是,从 ICMP 的报文格式来说,ICMP 是 IP 的上层协议。一个 ICMP 报文包括 IP 报头(至少 20 字节)、ICMP 报头(至少 8 字节)和 ICMP 报文(属于 ICMP 报文的数据部分)。对于类型为 1 的报文且其 ID 为需要接收的报文,从 28 字节后面开始解析发送的数据为发送时间,数据类型及长度根据发送的数据来确定。就好比是公司里的某位员工哪天有事不去上班,他就要向领导请假,写好“请假条”告知自己的请假原因,如果无故旷工,领导肯定是会找麻烦的。d:浮点型数据(f)。
2026-05-16 20:39:52
160
原创 认识Python网络套接字编程客户端代码实现
socket 的 send 函数用来发送 TCP 数据,但是请注意它只允许传 byte 类型的数据,如果我们想要传递 str 类型的数据,就要用 bytes 函数强制转换为 byte 类型,然后接收方接受到字节流数据,再用 str 函数转换为 str 类型,就可以实现正常的收发消息了。其实这个一点儿也不难理解,这就像我们平常喝水,杯子是必不可少的,它只是一个装水的容器,但是缺了它万万不可,没有杯子水就流的遍地都是,这还怎么喝呢?这样模拟点餐的效果就做好了。
2026-05-16 13:34:02
120
原创 在C++中尝试封装为函数
原因主要在于 warning: '__func__' is not defined outside of function scope。也就是说 __func__ 仅在函数体内可用。并且 __LINE__ 所替换成的常量也是在函数的参数位置的行号。因此这种方式无法满足我们的需求。
2026-05-15 19:38:00
131
原创 认识Python网络套接字编程之流式套接字(一)
光谈这些概念显得很抽象,还是举送外卖的这个例子,假设你点了一份烤鸭,外卖骑手需要先去店铺取餐,然后送到你的家门口,那么商家就是服务端,你的家门口是客户端,那份烤鸭是你需要接受的数据。一开始商家不知道你的住所在哪,但你知道商家的地址,你点餐这个操作就相当于和商家建立连接,当你成功下单之后,商家才知道了你的住所,就会派骑手去为你送餐了,此时你需要做的只有等待外卖骑手送餐了。这是套接字编程中最常用的一种。下篇文章,与大家分享:实现客户端代码,当客户端接受到服务端的消息时,输出到控制台。
2026-05-15 12:32:11
51
原创 可视化与分析|Tecplot 360 EX超详细下载安装教程
航空航天:翼型压力分布、全机流线、热防护分析;汽车工业:气动性能优化、风洞试验可视化;能源领域:电站热力计算、油藏模拟(通过Tecplot RS);科研教学:PIV数据分析、传感器频谱、CFD结果验证。
2026-05-14 15:46:49
1488
1
原创 RAII妙用:定时器比较算法运行时间
并在析构中计算两个时间点的差值,这就是 Timer 对象所占用的生存周期,也就是我们所测试算法的时间了。在很多情况下,我们希望能够获得算法的运行时间。无论是在项目中,还是算法学习中都会有这个需求。常规操作就是在算法的前后记录各种时间信息,但这样写一定程度上会让代码变得很凌乱,不够优雅。我们分别在构造函数和析构函数中都记录一个时间点。比如我们需要比较冒泡排序和快速排序的速度差距。此时又可以使用 RAII 的技术,来编写一个。
2026-05-14 11:38:26
118
原创 RAII妙用:使用标准库的包装器
当我们指定删除器后,在智能指针析构时会调用我们指定的 lambda 表达式,此时就可以保证句柄的 close 操作。此时有可能出现了我们上面提出的问题,如果出现了异常怎么办?如果编码时遗忘了怎么办?首先我们完全可以参上前面几个例子来编写一个包装类。此时我们就可以使用 RAII 的性质来处理。但这里介绍另一个技巧。在打开并使用后需要将其关闭。指定的删除器来操作。
2026-05-13 22:12:29
128
原创 使用面向对象的多态形式解决方案
并在对于需求增加的情况下可以用通过添加子类,使得对其他模块达到最小程度的影响程度,这一定程度上也体现了软件开发中的开闭原则。由于我们目的是使用多态的指针,需要指向具体的每个状态类的实例。防止内存膨胀的考虑,可以使用类似单例模式的方式,来获取具体的实例。在状态较少的情况下,可以通过简单的制表进行处理,但随着场景的变化与需求的变更,会使得代码越来越臃肿。在具体的迭代过程中,不断根据当前字符转换状态,并根据具体状态做具体的逻辑处理。在 C++ 中最常用的使用多态的方式就是虚函数和基类的多态指针。
2026-05-13 11:09:20
37
原创 状态机实例:字符串转换整数 (atoi)
如大家所了解的,状态机,又名有限状态机,自动机。指的是在限定环境中,根据规律抽象成的数学模型。具体的模型可以作为一种状态产生不同的作用,并且状态间可以进行转换。在许多算法中,尤其是很多字符串相关算法,如 KMP,AC 自动机等,都会使用该思路。并且在各种实际项目的底层逻辑中也是使用的状态机这一模型进行管理。此处,引入一道比较简单与典型的字符串处理的题目。
2026-05-12 14:32:28
131
原创 C++中emplace函数的由来
其中在我们开发和刷题中最常用的一些容器也具备相应的函数。在 vector, deque, list 中拥有 emplace_back() 函数,更具体的其可以在容器尾部添加元素。主要有emplace(),emplace_after(),emplace_back(),emplace_front(),emplace_hint() 这一系列的函数。由于设计的函数和数据类型比较多,但 emplace() 的核心就是原位构造,因此下面着重对 vector 中的 emplace_back() 进行讲解和分析。
2026-05-12 11:29:14
31
原创 二分查找算法:中间值左偏还是右偏?
当区间的长度是奇数时,中间索引只有一个位置 mid = (st + ed) / 2,而当区间长度是偶数时,中间索引就有了两个中间位置,一个左偏一个右偏。观察动画可以发现,只有在当前搜索区间的长度为偶数时,mid 指针的位置才会有所差别。我们在前面探讨了区间的选择和主循环的停止判断条件,但是没有提到。
2026-05-11 16:34:56
117
原创 如何优雅地抽离出数据库的共同特点
比如所有数据库有连接,断开关闭,执行 sql 语句的需求和功能。将这些抽离成接口,然后让举例的类去实现。最后通过注入的方式添加到 Application 中。这样如是,下次需要更换成 Oracle 数据库时,只要重新注入即可。
2026-05-11 11:53:16
156
原创 超实用录屏工具Bandicam全流程下载及安装教程分享
支持最高4K UHD(3840×2160) 分辨率(Windows版)和5K(macOS版),帧率最高达480fps,适合高清游戏与专业教程录制。通过NVIDIA NVENC、Intel Quick Sync Video、AMD VCE/VCN等硬件加速技术,显著降低CPU/GPU负载。多模式录制:屏幕录制:全屏、自定义区域、特定窗口或追随鼠标录制;游戏录制:专为DirectX/OpenGL/Vulkan游戏优化,支持实时FPS显示;
2026-05-10 18:04:24
448
原创 软件设计原则之SRP单一职责原则
如大家所熟知的,在程序开发过程中, 每位程序员都应该了解许多重要的原则。就如经典的面向对象三原则:封装,继承,多态。
2026-05-10 14:42:23
38
原创 实例分析:C++20的std::jthread
我们首先开门见山来介绍一下,在C++20 的 std::jthread具有两大特性:自动合并 joining thread线程取消 stop token其中 jthread 的 “j” 指的就是 joining。
2026-05-09 13:53:43
41
原创 实例分析:重载自定义参数的new
我们观察一下 placement new 的使用方式和重载方式。使用时就像函数一样有个小括号来表示传参,而接口不考虑第一个固定的 std::size_t,第二个参数开始正好与时候调用时一致。这和我们编写和使用函数非常类似。是的,为了更加的方便和可拓展,标准也允许自定义接口的参数。
2026-05-09 09:06:01
23
原创 C++20中带有约束条件的new
在 C 语言中使用 malloc 函数,若申请内存失败,则会返回空指针。但在 C++ 中的 new 则是直接抛出异常,若不想有异常,则可以在 new 时指定 std::nothrow。这样在申请失败时候就可以用是否为空来进行判断。我们在 new 时可以对数据类型进行约束,这样我们可以在代码层面更加显示的表示出我们需要操作的类型。在C++20中,提出了约束与概念的新特性。
2026-05-08 17:29:28
29
原创 C++中普通对象数组与函数指针数组
对于一个入参为空,返回值为 int 的函数指针一般书写形式为 int(*)(void),而数组的中括号标志跟在 * 后面。基于上一个例子可知对于数组类型,返回的是单个元素的指针,放到这里就是函数指针的指针。请注意,在 C/C++ 中,数组属于一种单独类型,但是对于 new Type[] 的操作,返回的不是 Type[] * 而是 Type *。下面 code 的 p 在 msvc-x64 环境下表示的数据类型为 int (__cdecl** __ptr64)(void)。下面先看一个最基础的使用方式。
2026-05-08 08:44:36
38
原创 Dijkstra算法推导练习之题目实操
只要答案与标准答案的误差不超过 1e-5 ,就会被视作正确答案。指定两个节点分别作为起点 start 和终点 end ,请你找出从起点到终点成功概率最大的路径,并返回其成功概率。表示连接节点 a 和 b 的一条无向边,且该边遍历成功的概率为 succProb[i]。Dijkstra 算法中的权重累计方式是相加,秉承非递减原则,最短路径上的权重和最小。本题的权重累计方式是相乘,但概率 ,秉承非递增原则,求解概率最大的路径。加权图,该图由一个描述边的列表组成,其中。所以可以镜像转换松弛过程,代码如下所示。
2026-05-07 17:14:15
19
原创 堆(Heap)的定义及表示方法
因为堆是完全二叉树,所以没有浪费空间的节点,这允许我们使用数组来紧凑地表示堆。在这种表示中,数组中的每个元素对应于树中的一个节点。如果节点 的索引为 ,则其左子节点的索引为 ,右子节点的索引为 ,父节点的索引为。在实际应用中,通常使用数组表示法来实现堆。二叉树表示更符合堆的直观概念,它通过节点和指针显式地表示每个元素及其子节点的关系。下图展示了一个最小堆的二叉树表示,从图中可以看出,二叉树中每节点的值都要比其父节点的值更大。堆的定义非常简单,但要选择什么样的数据结构来实现堆呢?
2026-05-07 11:48:37
21
原创 如何做到多线程的资源争夺安全?
而为什么这么一个普通的对象,在多线程的操作中会与我们在单线程操作时的期望有所不同呢?这就需要我们回顾一下计算机组成原理中内存模型的相关知识了。倘若取消 mtx 对 x 操作时的保护,相信大多数情况下会出现五花八门的运行结果。可见,锁是在处理多线程资源争夺问题上的一种强力手段。该程序创建了两个线程,并在线程中都对同一个共享资源(对象 x)进行了操作。为了保证线程安全用了互斥锁(对象 mtx)对其进行保护。对于大多数开发者能够第一想到的一种方案就是给程序上锁。是一个非常经典的多线程应用问题。
2026-05-06 12:16:43
17
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅