inline 是 C++ 中的一个关键字,有两个主要作用:
在 C++17 之后,inline
关键字的“性能”含义(提示内联)越来越弱;而它的“链接”含义(“允许在头文件定义”)越来越强。
作用一:向编译器提议“内联展开”以提升性能
这是 inline 最原始、最广为人知的作用。
普通的函数调用涉及: - 参数压栈,
将函数参数按调用约定放入栈中。 -
保存返回地址:...
我们通过下面这张图来整体理解函数调用和栈的关系:
这张图非常经典,它清晰地展示了计算机程序在执行函数调用时,内存中栈(Stack)的结构和工作原理。图中描述了一个场景:一个名为
DrawSquare 的函数在执行过程中,调用了另一个名为 DrawLine 的函数。
我们先理解下面两个概念: 函数调用栈 (Call Stack) 和 栈帧 (Stack
Frame)。
函数调用...
信号量(Semaphore)是一种用于多线程或多进程编程中的同步机制,主要用于控制对共享资源的访问。它可以用来防止资源竞争和确保线程安全,
一般可以实现为一个特殊的整数计数器,用于管理对有限资源的访问。它代表了可用资源的数量。
当计数值大于0时,表示有可用的资源。
当计数值等于0时,表示没有可用的资源。
信号量的基本操作
信号量主要有两个基本操作:P(Proberen,测试...
成员变量存储和访问
存储顺序:
成员变量在内存中的存储顺序与它们在类定义中出现的顺序一致。
静态成员:静态成员变量不属于任何一个对象,而是存储在程序的数据段中,因此不占用类对象的内存空间
。
地址连续性:一个类对象的内存空间是连续的,其成员变量的地址也是依次排列的。后声明的成员变量拥有更高的内存地址。
非静态成员变量与成员变量偏移值
(Offset)
非静态成员变量是构成 对...
Reactor 模式,也称为“反应器模式”或“分发者模式”(Dispatcher
Pattern),是一种用于处理并发服务请求的事件驱动设计模式。它的核心思想是将所有事件(如
I/O
事件、定时器事件等)的监听和分发任务交给一个中心化的组件(Reactor),当事件发生时,Reactor
负责将事件分发给预先注册的、特定的处理程序(Event
Handler)来进行处理。
这种模...
网格图 (Grid Graph)
是一种特殊的图结构,节点排列成二维矩阵的形式,每个节点与其上下左右(有时包括对角线方向)的邻居节点相连。
它本质上是图论问题,但比图论更“友好”,因为它是一个“隐式图”。你不需要自己构建邻接表,一个
(r, c) 单元格的邻居就是 (r+1, c), (r-1, c) 等。
这一章的核心是考察你对两种最基本图遍历算法的理解和应用: - DFS
(深...
二叉树
二叉树是一种非常适合递归处理的数据结构,
因为每个节点都可以看作是一个子树的根节点.
必须回答的三个核心问题(递归的灵魂)
下面是二叉树递归的三个核心问题。每当你面对一个新的二叉树问题时,都要问自己这三个问题,从而设计出合适的递归函数。
递归边界:nullptr
vs. 叶子节点? - if (root == nullptr)(空节点边界) -
这是最常用、最健壮的边界...
二分查找
二分查找 (Binary Search)
是一种高效的查找算法,适用于在有序数组或列表中查找特定元素。它通过不断将搜索范围减半来快速定位目标元素,从而大大减少了查找的时间复杂度。
代码实现如下: 12345678910111213141516171819int binarySearch(const vector<int>& nums, int target...
什么是调用约定
首先,我们需要理解什么是调用约定(Calling
Convention)。它是一套规则,用于规定函数在调用时如何进行交互。这套规则确保了由不同程序员编写、甚至由不同编译器编译的函数能够正确地相互调用。
调用约定通常定义了以下内容:
参数传递:如何将参数传递给函数(使用寄存器还是栈)。
返回值:函数如何将返回值传回给调用者。
寄存器使用:调用者(Caller)和...
在我们之前创建的最基础的 Client-Server
模型中,服务器是迭代式的:它一次只能处理一个客户端。当
HandleRequest 函数正在为一个客户端服务时,其他所有新的客户端都必须在
accept 的队列中等待。这在实际应用中是完全不可接受的。
而进一步为了解决并发问题,我们实现了两种朴素的思路:
多进程模型:主进程负责 accept 连接,每当有新连接到来时,就
...