- 博客(114)
- 收藏
- 关注
原创 【项目】基于Boost自主实现搜索引擎
因为我们使用的jieba库分词可能和我们预想的不太一样,所以weight值可能有些偏差,但是影响不大,此外我们在查找正文中词的数量时包括了标题的词,所以有可能weight会比实际的大一点,可以设置weight-1,更准确一点,但我们也不准备输出weight在网页上,所以就不做处理了。当我们在搜索时,不同的词可能对应一个文档,这样就有多篇相同的文档被索引,是不必要的,所以我们需要在搜索时去重;构建倒排索引需要将词与文档对应,所以我们需要将文档的内容进行分词,可以借助第三方库jieba库来分词。
2025-02-25 16:26:54
1096
7
原创 【Linux】应用层自定义协议与序列化
当使用 Jsoncpp 库进行 JSON 的序列化和反序列化时,确实存在不同的做法和工具类可供选择。反序列化指的是将序列化后的数据重新转换为原来的数据结构或对象。只要保证, 一端发送时构造的数据, 在另一端能够正确的进行解析, 就是 ok 的.。连接既有发送缓冲区,又有接受缓冲区,所以,在内核中,可以在发消息的同时,也可以收消息,即全双工;应答序列和请求序列尽管使用的方法类似,但是因为序列中包含的内容不一样,所以还是需要使用两个类。服务器向客户端发送的信息也该和上述一致,只不过json序列中包含的应该是。
2025-02-15 19:49:19
954
2
原创 【Linux】Socket编程—TCP
其次父进程需要等待回收子进程,此时父进程会阻塞直到子进程完成通信,这样和之前单进程通信效果一样,所以为了不让父进程阻塞,子进程需要再创建子进程,用它来完成通信,此时父进程就可以直接回收子进程,孙子进程就成为孤儿进程进行通信,结束后由操作系统回收。介绍:服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接;对于多进程,首先每个进程都有自己的文件描述符表,所以父子进程都需要关闭自己不需要的文件描述符;引入之前实现的线程池,并使用单例模式。
2025-02-14 19:45:42
948
2
原创 【Linux】Socket编程—UDP
例如,如果服务器有多个网卡(每个网卡上有不同的 IP 地址),使用 INADDR_ANY 可以省去确定数据是从服务器上具体哪个网卡/IP 地址上面获取的。在运行客户端代码之前,我们可以创建一个管道将其重定向到cerro,然后运行客户端,这样服务器群发收到的消息就会写入到管道中。同样,客户端要进行网络通信也需要创建套接字,但是不需要bind信息进入内核,因为在接收到网络信息时会自动进行bind。因为在进行网络通信时不可避免的需要频繁使用到相关信息,所以我们可以考虑将它们封装成为一个类,设置一些常用的方法。
2025-02-09 22:16:09
1353
2
原创 【Linux】线程池封装与介绍
之前我们实现了线程、互斥量、条件变量以及日志的封装,现在我们可以基于以上内容来封装一个线程池。线程池是一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。线程池的应用场景:需要大量的线程来完成任务,且完成任务的时间比较短。比如WEB。
2025-02-04 14:45:06
1432
2
原创 【Linux】日志设计模式与实现
计算机中的日志是记录系统和软件运行中发生事件的文件,主要作用是监控运行状态、记录异常信息,帮助快速定位问题并⽀持程序员进⾏问题修复。它是系统维护、故障排查和安全管理的重要工具。
2025-01-31 17:06:10
1258
1
原创 【Linux】线程互斥与同步
以上就是有关线程互斥与同步有关的内容啦,线程互斥指的是多个线程访问公共资源,保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用;线程同步指的是在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题,叫做同步。以上就是今天所有的内容啦~ 完结撒花~ 🥳🎉🎉。
2025-01-30 22:37:42
1256
1
原创 【Linux】线程概念与控制
线程就是一个执行流,一个进程内可以有多个线程。进程是划分资源的最小单位,而线程(Thread)是操作系统能够进行运算调度的最小单位。通过对线程的各种函数的理解与认识,我们就可以封装便于理解和学习的线程库。
2025-01-23 18:51:29
885
2
原创 【Linux】进程信号
信号就像是一个突然的电话铃声,它会打断正在进行的程序并引起其注意。在Linux系统中,信号是一种软件中断,它通常是异步发生的,用来通知进程某个事件已经发生。每个信号都有一个唯一的编号和一个宏定义名称,这些宏定义可以在signal.h中找到
2024-12-23 21:17:33
2315
71
原创 【Linux】进程间通信——System V共享内存
System V是一种在Linux系统中用于进程间通信(IPC)的机制。它提供了几种不同的通信方式,包括共享内存、消息队列和信号量。System V共享内存是一种高效的进程间通信(IPC)机制,它允许多个进程共享一块物理内存区域,从而避免了数据的复制,显著提高了数据传输速率。
2024-12-08 20:54:33
1590
85
原创 【Linux】进程间通信——命名管道
匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用命名管道来做这项工作。在Linux系统中,命名管道(也称为FIFO)是一种特殊的文件类型,它允许进程间进行通信。与匿名管道不同,命名管道存在于文件系统中,并且可以被任何有适当权限的进程访问。命名管道提供了一种方法,使得不相关的进程能够通过预先定义好的路径来交换数据。匿名管道由pipe函数创建并打开。而命名管道由mkfifo函数创建,打开⽤open。FIFO(命名管道)与pipe。
2024-12-03 19:19:13
2329
77
原创 【Linux】匿名管道通信场景——进程池
基于匿名管道通信实现的进程池,子进程会根据接受到的信息执行不同的任务,父进程可以看作Master来进行管理创建的多个进程。关键点在于对进程管理的封装以及回收子进程时会有多个进程指向匿名管道的读端,所以回收时要注意可能会出现的bug。
2024-12-01 16:09:38
1965
77
原创 【Linux】进程间通信——匿名管道
它的原理与上图类似,是通过pipe系统调用来创建一个管道文件,该文件与上图文件不同,没有inode,也不需要写入磁盘,仅仅用来给父子进程间进行通信,可以说是一次性使用的,没有名字,所以称为匿名管道。读进程从管道中读取数据,写进程向管道中写入数据。(某种形式的内存空间),并且因为进程具有独立性的特性,一个进程不能在另一个进程中操作某种资源,所以该资源的提供者不能是进程,只能是操作系统,这也是进程间通信的核心。管道的通信是单向的,即父进程或子进程不能对一个管道同时读和写,只能选择一个,父进程读,子进程就写;
2024-11-20 20:59:59
971
8
原创 【Linux】ELF可执行程序和动态库加载
在Linux操作系统中,通过elf格式的可执行文件,操作系统可以读取文件中的节和段信息,并加载到内存中执行。程序在调用动态库中的方法时会先将动态库的起始虚拟地址保存起来,然后将调用的方法转化为该方法在动态库中的虚拟地址偏移量,这样就可以根据。中,因为动态库加载可能多个也可能不加载,所有Linux使用了一种灵活的数据结构来保存动态库的虚拟地址,该结构体实际上是一个链表,链接在。程序加载到内存中,是会有物理内存地址的,页表的作用就是将程序物理内存地址与虚拟地址之间进行映射,而。
2024-11-13 21:13:00
1085
5
原创 【Linux】软硬链接和动静态库
在Linux系统中,文件链接分为两种类型:硬链接(Hard Link)和软链接(也称为符号链接或Symbolic Link)。它们都是用于创建文件的额外入口点,但是工作原理和使用场景有所不同。关于引用计数: 新建一个目录文件,它一开始的硬链接引用计数就是2,除了它自己以外,它里面还包含一个隐藏文件,这个其实也是该目录的硬链接,如下图所示:特性:创建方法:使用命令。例如,要为文件创建一个名为的软链接,可以执行命令 。使用场景:总结起来,软连接有独立的inode,软连接内容上保存的是目标文件的路径,当
2024-11-09 16:29:37
1331
7
原创 【Linux】理解文件系统
block 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。就必须先找到保存该文件inode的目录,然后根据inode编号去磁盘中寻找,但是目录也是一个文件,要想打开该目录必须得找到保存该目录inode编号的目录,以此类推一直找到根目录,而根目录的inode编号是固定的,所以我们就可以根据根目录的内容再往下一层一层找到。间接块中存储了多个数据块的编号。
2024-11-06 21:38:03
1001
4
原创 【Linux】第一个小程序——进度条实现
我们之前学习过vim编辑器、gcc/g++的使用和make/makefile工具,所以今天我们就可以使用它们创建Linux上第一个小程序——进度条。在实现进度条之前我们首先需要补充两个小知识。
2024-10-02 19:37:19
10630
114
原创 【Linux】项目自动化构建工具-make/Makefile 详解
在Linux及类Unix系统中,自动化构建项目是提高开发效率、减少重复劳动的关键环节。make工具及其配置文件Makefile是实现这一目标的重要工具组合。它们通过定义一系列规则和依赖关系,自动执行编译、链接等构建过程,确保软件项目能够高效、准确地构建。make是一种控制程序生成的工具,它读取一个名为Makefile(或makefile,不区分大小写)的文件,并根据文件中的指令执行相应的命令。这些命令通常包括编译、链接等,用于生成最终的可执行文件或库文件。
2024-09-26 22:41:23
4393
120
原创 【Linux】深度解析与实战应用:GCC/G++编译器入门指南
在Linux系统中,GCC(GNU Compiler Collection)是极其重要且广泛使用的编译器,它支持多种编程语言,包括C、C++、Objective-C、Java、Fortran等。GCC以其高效、灵活和跨平台的特点赢得了开发者的青睐。本文将详细介绍GCC中的C编译器gcc和C++编译器g++的基本使用方法和编译过程。GCC(GNU Compiler Collection)是一个由GNU项目开发的编译器套件,原名GNU C Compiler,但随着发展,它已支持多种编程语言的编译。
2024-09-24 19:55:20
1956
112
原创 【Linux 】开发利器:深度探索 Vim 编辑器的无限可能
Vim有非常丰富的功能,可以根据具体需求进行扩展和定制。初学者可能需要一些时间来适应Vim的操作方式,但一旦掌握了Vim的一些基本操作,它将成为你在终端环境下高效编辑文本的利器。
2024-09-20 12:25:35
2242
117
原创 【Linux】软件包管理器 yum
在Linux中,软件包是一种以预定义的格式打包的软件安装文件,相当于我们在Windows下需要安装的app。它包含了软件程序的所有文件、依赖关系和安装脚本等信息。软件包通常以特定的格式(如RPM、DEB等)提供,可以通过包管理器(例如yum)来安装、升级和卸载软件包。
2024-09-18 16:54:28
1366
91
原创 【C++11】深入理解与应用右值引用
区分右值还是左值的关键在于是否可以取地址,对于左值的引用是左值引用,右值的引用是右值引用,它们都是给对象取别名。const左值引用可以引用右值,右值引用可以引用move后的左值;右值一般是临时对象,是将亡值,所以我们就可以在类中专门写一个供右值对象使用的拷贝构造和赋值重载函数,来置换它们的资源,从而减少不必要的深拷贝,我们将这两个函数称为移动构造和移动赋值。
2024-09-04 21:44:32
1368
114
原创 【C++11】入门基础
C++11是C++编程语言的一个重要版本,它于2011年发布。相比于C++98/03C++11给C++带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。C++11能更好地用于系统开发和库开发、语法更加泛化和简单化,更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习。
2024-08-18 18:49:11
1659
156
原创 【C++深度探索】unordered_set、unordered_map封装
unordered_map和unordered_set的底层都是使用哈希表来实现的,然后在外面套了一层壳,为了能够更好的实现代码复用,我们对哈希表进行了很多修改还使用了仿函数,封装了普通迭代器和const迭代器等,最终成功对unordered_map和unordered_set实现了封装
2024-08-16 19:00:00
2453
107
原创 【C++深度探索】哈希表介绍与实现
在C++中,哈希(Hash)是一种常用的数据结构技术,用于将数据转换为固定长度的哈希值。哈希值是唯一的,可以用于快速查找、比较和索引。
2024-08-14 22:20:01
1252
94
原创 【C++深度探索】红黑树实现Set与Map的封装
红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O(log2Nlog_2 Nlog2N),但是红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对AVL树而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多。今天我们就可以利用之前实现过的红黑树来对C++STL库中的set和map进行模拟实现。
2024-08-08 00:37:28
1836
112
原创 【C++深度探索】红黑树的底层实现机制
红黑树与AVL树一样,也是一种自平衡的二叉搜索树,它在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black,通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。因为红黑树也是二叉搜索树,其他的类似查找节点,析构函数和构造函数都与二叉搜索树类似,对于删除节点,可按照二叉搜索树的方式将节点删除,然后再进行调整,大家有兴趣可以自己查找了解一下
2024-08-05 01:54:01
1979
107
原创 我的创作纪念日
这算是我从接触编程之后自主实现的第一个较为完整的小游戏,里面蛇的颜色也被我设置成了红色和绿色,像是圣诞树的颜色,非常喜庆🥳🥳,其实里面有很多可以自己决定的设计,比如你可以自己决定蛇的颜色是统一的还是蛇头和蛇身分离的颜色、蛇头也可以设成与蛇身不一样的形状、整个墙围的范围也可以自行决定大小、事物的颜色与样式也可以根据自己喜欢的来……
2024-08-01 23:50:36
1013
32
原创 【C++深度探索】AVL树的底层实现机制
AVL树就是在二叉搜索树的基础上引入了平衡因子,因此AVL树也可以看成是二叉搜索树.一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:它的左右子树都是AVL树,左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1).接下来我们继续学习AVL树底层实现的部分机制.
2024-07-29 23:53:15
1860
105
原创 【C++深度探索】AVL树与红黑树的原理与特性
二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N),因此map、set等关联式容器的底层结构是对二叉树进行了平衡处理,即采用平衡树来实现。而AVL树和红黑树是常用的自平衡二叉搜索树。它们在插入、删除和查找操作上具有较好的性能,并且在各种应用场景中被广泛使用。
2024-07-27 14:55:32
3291
103
原创 【C++深度探索】map与set的基础介绍与实用指南
关联式容器,关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高。根据应用场景的不同,STL总共实现了两种不同结构的关联式容器:树型结构与哈希结构。
2024-07-22 19:52:09
2131
109
原创 【C++深度探索】二叉搜索树的全面解析与高效实现
二叉搜索树(BST,Binary Search Tree)又称二叉排序树,是一种特殊的二叉树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树
2024-07-18 14:02:12
2695
100
原创 【易编橙 · 终身成长社群】携手并进,成长之路不孤单!
易编橙 · 终身成长社群分享优质内容,帮助编程小伙伴少走弯路! 欢迎新老小伙伴们加入星球,一起分享知识,一起进步!
2024-07-14 15:47:24
2236
105
原创 【C++深度探索】全面解析多态性机制(二)
C++多态实现有两个条件——一是基类的指针或引用调用虚函数,另一个是基类中有虚函数并且在派生类中实现虚函数重写;这两个条件缺一不可,这与多态实现的底层原理有关。
2024-07-13 21:47:28
2993
83
原创 【C++深度探索】全面解析多态性机制(一)
在C++中,多态(Polymorphism)是指通过基类指针或引用来访问派生类对象的一种机制。简单来说,它允许我们在基类类型的指针或引用上调用派生类对象的成员函数。通俗来说,就是多种形态,或者说完成某个行为时,当不同的对象去完成会产生出不同的状态。例如:买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。不同的对象去完成同一个行为——买票,会产生不同的状态。在代码中的具体体现则依赖于虚函数在基类中,可以将某个成员函数声明为虚函数,而在派生类中重写该函数。
2024-07-11 11:17:45
3047
95
原创 【C++深度探索】继承机制详解(二)
菱形继承是指在C++中使用多重继承时,出现了多个派生类继承同一个基类,而最终有一个类同时继承了这些派生类,形成了一个菱形的继承结构。
2024-07-08 22:26:59
3288
101
原创 深入探索C语言中的结构体:定义、特性与应用
在C语言中,结构体是一种用户自定义的数据类型,它允许开发者将不同类型的变量组合在一起,形成一个新的数据类型。结构体可以包含多个成员变量,每个成员可以是不同的数据类型,例如整型、字符型、浮点型等。结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。结构体的定义使用关键字struct,后面跟随结构体的名称。int age;上述代码定义了一个名为Person的结构体,它包含三个成员变量:name、age和height。name是一个字符型数组,有20个元素;
2024-07-06 21:12:45
2386
80
原创 掌握高效实用的VS调试技巧
调试(Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。调试的基本步骤✨发现程序错误的存在✨以隔离、消除等方式对错误进行定位✨确定错误产生的原因✨提出纠正错误的解决办法✨对程序错误予以改正,重新测试Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
2024-07-04 13:30:42
2212
80
原创 【C++深度探索】继承机制详解(一)
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类或子类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
2024-06-30 22:38:22
3741
103
原创 【C++】模板进阶
模板的特化是指为具体类型或具体参数提供专门的实现。通常情况下,模板的特化是为了解决某些特殊类型或参数的处理需求,使得模板能更好地适应不同的情况。函数模板的特化步骤:必须要先有一个基础的函数模板关键字template后面接一对空的尖括号函数名后跟一对尖括号,尖括号中指定需要特化的类型函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。注意:一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出。
2024-06-07 05:30:00
3331
180
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人