Linux网络——应用层 在这里我们实现一个简易的网络版计算器,首先我们先完成一个 TCP 服务,如下enumBindErr,ListenErr// 监听时套接字排队的未处理连接请求的最大数量class Sockpublic:Sock(){}~Sock(){}public:// 创建套接字// 创建字节流型(TCP)套接字// 绑定// 将一个地址(包括IP地址和端口号)分配给套接字,使得套接字与特定的网络接口和端口关联起来。
Linux网络——套接字编程 在公网上, ip 地址能标识唯一一台主机,端口号 port 能标识该主机上的唯一一个进程,因此我们可以使用 ip:port 来表示全网唯一的一个进程而我们将 client_ip:client_port 与 server_ip:server_port 间的通信称为套接字编程!
Linux基础——线程 线程:我们认为线程是OS调度的基本单位进程:对OS来说,进程是承担分配系统资源的基本实体既然如此,那么线程是资源吗?——算,不过它是当前进程的内部执行流资源!我们重新定义它们后,之前讲的进程又如何理解呢?——OS以进程为单位来分配资源,而当前进程内部只有一个执行流。由于 进程:线程 = 1:n,即 OS 中一定存在大量的线程,而 OS 想要管理它们就需要先描述再组织,而这个过程中不同的操作系统就采取了不同的方案。
Linux应用——线程池 我们创建线程池的目的本质上是用空间换取时间,而我们选择于 C++ 的类内包装原生线程库的形式来创建,其具体实行逻辑如图可以看到,整个线程池其实就是一个大型的 CP 模型,接下来我们来完成它。
Linux基础——信号 对于信号的概念,我们还是举几个生活中的例子,比如照明信号弹,上下课铃声,发令枪,集合哨子,闹钟,外卖电话等等从这里我们就可以提出几点1. 我们是怎么认识这些信号的?——有人教 -> 我们记住了这些常见的信号2. 即便没有信号产生,我们也知道信号产生之后该干什么3. 信号产生了并不代表我们要立刻处理这个信号,可以挑选一个合适的时间去处理,因为我们有可能正在做更重要的事。因此,信号产生后会为他创建一个时间窗口,在处理信号时,我们需要在这个时间窗口内记住有信号来过。
Linux基础——进程间的通信 我们现在所做的工作只是让不同的进程看到同一份资源,我们现在来编写通信代码(IPC code),对于客户端(client)来说,一旦有数据写入到共享内存,立马就能看到,不需要经过系统调用,直接就能看到地址;综上,我们对信号量进行 PV 操作时,必须保证它们是原子的(要么做完,要么不做,没有正在做的概念)!其中,pipefd[2] 是一个输出型参数,它的作用是将文件的文件描述符数字带出来,让用户使用,比如:3,4,其中pipefd[0] 表示读下标(3),pipefd[1] 表示写下标(4)。
Linux应用——简易日志 对于一个日志来说,我们任认为其应该具有以下的内容1. 日志时间2. 日志等级3. 日志内容4. 文件名称与行号在此基础上我们对不同的日志做出分级,即info: 常规信息warning: 报警信号error: 严重信号,可能需要立即处理fatal: 致命信号Debug: 调试信息。
Linux基础——文件 1. 从本质上来说,文件其实就是内容加上属性。而一个文件一般都是先拥有属性,再拥有内容的。2. 文件分为未打开的文件和打开的文件。3. 对于未打开的文件,它们存放在哪呢?——磁盘,对于未打开的文件,我们最关注的是什么呢?我们要知道,在整个磁盘中,没有被打开的文件是相当多的,因此最值得被关注的应该是:文件如何被分门别类的放置好,以便我们快速的进行增删查改。4. 对于打开的文件,它们是由谁来打开呢?——进程,所以研究打开的文件本质上就是研究进程和文件的关系。
数据结构——图 在离散数学中,图(Graph)是用于表示物体与物体之间存在某种关系的结构。数学抽象后的“物体”称作节点或顶点(英語:Vertex,node或point),节点间的相关关系则称作边。在描绘一张图的时候,通常用一组点或小圆圈表示节点,其间的边则使用直线或曲线。
数据结构——并查集 在计算机科学中,并查集(英文:Disjoint-set data structure,直译为不数据结构交集)是一种数据结构,用于处理一些不交集(Disjoint sets,一系列没有重复元素的集合)的合并及查询问题。
算法——BFS算法 BFS(广度优先搜索,Breadth-First Search)算法是一种用于图和树等数据结构中进行搜索的基本算法。它从指定的起始节点开始,逐层地向外扩展搜索,直到找到目标节点或遍历完整个图。BFS算法的基本思想是:先访问起始节点,然后依次访问起始节点的邻居节点,再依次访问邻居节点的邻居节点,以此类推,直到搜索到目标节点或者遍历完整个图。BFS算法使用队列来辅助实现节点的遍历顺序,保证每一层的节点按顺序访问。
算法——动态规划 动态规划(Dynamic Programming)是一种解决多阶段决策问题的优化方法。它通常用于解决具有重叠子问题和最优子结构性质的问题,能够将一个大问题分解为多个重叠的子问题,并通过存储子问题的解来避免重复计算,从而提高算法效率。
Linux基础——进程控制 在这之前我们曾了解过进程创建(详见),我们在这里对fork函数做一些补充其实对于父子进程来说,若是有一方试图修改数据时,会向物理内存中申请一份新空间,并将数据拷贝到其中,拷贝完成后将自己对应页表中的只读属性去掉。
算法——双指针 双指针算法是一种常用于解决数组或链表中的问题的技巧。它涉及使用两个指针(索引或引用),通常分别称为“快指针”和“慢指针”或“左指针”和“右指针”,以协同进行遍历或搜索。该算法的核心思想是通过移动这两个指针来实现特定的目标,例如寻找一对元素的和、判断是否存在某种关系或在特定条件下移动其中一个指针。双指针算法通常能够在O(n)的时间复杂度内解决问题,具有较好的效率。
算法——滑动窗口 滑动窗口算法是一种解决数组或列表中子数组或子序列问题的有效方法。该算法通过定义一个窗口,然后在数据结构上滑动该窗口,逐步处理数据,以解决特定类型的问题。其基本思想是维护一个窗口,初始时窗口覆盖数组中的一部分元素,然后通过滑动窗口来依次处理每个子数组。在每次窗口滑动时,可以通过添加新元素和删除旧元素来更新窗口的内容,以在O(1)时间内完成操作。
算法——模拟 官方一点来说模拟算法(Simulation Algorithm)是一种通过模拟现实或抽象系统的运行过程来研究、分析或解决问题的方法。它通常涉及创建一个模型,模拟系统中的各种事件和过程,以便观察系统的行为,收集数据并得出结论。这类算法适用于复杂的系统,其中涉及许多相互作用的元素和随时间变化的状态。通俗来说我们只需要对照题目,提取出对应的流程,将这个流程转换成代码。需要注意的是, 我们要在草稿纸上过一遍流程,不然很容易出问题。