自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 项目 : 基于正倒排的boost搜索引擎

本文介绍了基于Boost库的站内搜索引擎开发项目。项目使用C++技术栈,实现数据清洗、正排/倒排索引构建等核心功能。Parser模块通过递归读取HTML文件,解析标题、内容和URL并存储为结构化数据;Index模块建立正排索引(文档ID映射内容)和倒排索引(关键词映射文档ID),采用Jieba分词并计算词频权重。系统最终通过HTTP服务器提供搜索服务,返回按权重排序的搜索结果。该项目简化了全网搜索引擎的复杂度,专注于实现站内搜索的核心原理,包括文档处理、索引构建和结果排序等关键技术。

2025-06-15 15:51:52 1210

原创 Linux网络编程:https的协议及其加密解密方式

本文基于http协议的不安全性,深入研究https的解决方案,包含了对称和非对称加密性原理,以及CA证书。http协议在网络中都是以明文的形式传播的,无论是GET还是POST方法都是不安全的,这是因为http协议协议以明文的形式传输数据, 缺乏对信息的保护.如果在网络中传输数据以明文的形式传输, 网络中的任何人都可以轻松的获取数据中携带的敏感信息. 信息太容易泄露了,其次, 由于对信息没有保护措施. 任何人也都有可能篡改发送的信息.由于http的不安全, 所以才出现了https协议。

2025-05-29 11:14:30 1026

原创 Linux网络编程:套接字

上篇文章主要介绍的是网络通信方面的一些知识,也算是为以后的学习先做一下铺垫。从本章开始我们就要正式进入网络编程的学习了。在开始网络编程之前,我们还需要进行一些准备工作,需要先了解一些概念。

2025-05-04 17:37:16 965

原创 Linux 网络编程:网络初认识

在前面的文章中,我们已经学习完了Linux系统编程方面的知识,接下来我们就要开始进入Linux网络编程部分了。在正式认识Linux网络编程前,我们先对网络做一个了解。

2025-05-02 18:58:54 1246 2

原创 c++11: 类型转换

关于这种问题,在linux相关文章中也介绍过了,在main()中, 由于const int ci=10, 编译器会认为 const ci不会改变的,所以cpu会把ci存储在cpu里的寄存器中,不再每次向内存中读取ci的值了,所以后面尽管*pi=20即将ci对应的内存值改成20,但因为cpu并没有去读取,所以输出结果依然ci=10.这个测试例子主要是用于:pa是父类对象A的指针,当我们传过去给f_cast(pa),函数内部会将pa转成B* 类型的,那我们传入了父类指针能调用 pb->_a = 1;

2025-04-28 19:48:04 1120 1

原创 c++11 : 特殊类设计

🎉:饿汉模式与懒汉模式结构上不同在一,饿汉模式的私有成员变量是 Singleton Singleton::_inst,不是指针,饿汉模式在类外对 _inst进行初始化的时候,就相当于已经在main()之前创建好对象了,当我们在main()调用x()函数的时候。一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全 局访问点,该实例被所有程序模块共享。所获取的对象是早就在main函数之前已经创建好的,且由于在主线程之前就已经创建好,所以不存在线程安全问题,不需要加锁。

2025-04-28 14:31:51 1111

原创 c++11 :智能指针

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使⽤的内存,⼀般是忘记释放或者发⽣异常释放程序未能执⾏导致的。内存泄漏并不是指内存在物理上的消失,⽽是应⽤程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因⽽造成了内存的浪费.内存泄漏的危害:普通程序运⾏⼀会就结束了出现内存泄漏问题也不⼤,进程正常结束,⻚表的映射关系解除,物理内存也可以释放。

2025-04-25 19:31:49 1196 1

原创 Linux: 生产者消费者模型

生产者-消费者模型(Producer-Consumer Pattern)是一种经典的多线程同步问题,它描述了一组生产者线程和一组消费者线程共享一个有限缓冲区的情况。生产者负责创建数据并将其放入缓冲区中,而消费者从缓冲区中取出数据并处理它们。这个模型广泛应用于各种并发编程场景中,以确保线程之间高效、安全地交换数据。

2025-04-17 20:54:42 2179 2

原创 Linux: 线程同步

在上篇文章Linux : 多线程互斥-CSDN博客我们讲解了线程互斥的概念,为了防止多个线程同时访问一份临界资源而出问题,我们引入了线程互斥,线程互斥其实就是多个线程同时争抢一份资源,谁抢到了就是谁的,抢不到的只能等待着下一次抢。虽然解决了多个线程同时访问同一资源所产生的问题,但是我们思考一下这样子合理吗?不合理,这会产生另一种问题——线程饥饿。

2025-04-14 16:40:06 1104

原创 Linux : 多线程互斥

我们在上一章节Linux: 线程控制-CSDN博客学习了什么是多线程,以及多线程的控制和其优点,多线程可以提高程序的并发性和运行效率。但是多线程控制也有一定缺点,例如有些多线程的程序运行结果是有一些问题的,如出现了输出混乱、访问共享资源混乱等特点。所以我们下面提出的这个概念是关于保护共享资源这方面的——线程互斥。

2025-04-13 12:51:43 2372 1

原创 Linux: 线程控制

在上一篇文章中我们已经学习了线程的概念,线程的创建,并且已经从根本上了解了线程和进程的相同点及不同点。在学习进程时,我们学习了进程的相关概念,进程控制接口,而线程作为更轻量级的进程,其自然也有着控制接口。

2025-04-09 20:35:25 1347

原创 Linux: 线程概念初识

之前的文章中我们已经对进程相关的概念做了认识,从创建进程、子进程,进程回收、进程替换等,由于我们之前对于知识框架的不熟悉,为了方便我们的理解学习,我们在之前的学习中没有做到深挖细节和深入理解,对之前的进程内容的有些部分做了简单的抽象,接下来我们学习的是比进程粒度更细的一个概念——线程。在这部分内容中,我们除了学习主线的内容外,还会对之前的內容稍作补充和修改。线程是在进程内部的执行流线程相比进程,粒度更细线程是CPU调度的基本单位我们先通过具体的例子简单认识一下线程。

2025-04-08 12:02:06 968

原创 Linux : 页表

页表设计的优点如果使用一级页表,整个4GB的内存地址空间都需要为每个页面创建一个对应的页表项,这会占用大量内存。而使用多级页表,页目录的大小一般为KB级别,且由于第二级页表是按需创建的,因此只在需要时才分配内存。这样可以显著节省内存。最坏情况下,内存占用也只是MB级别。多级页表的结构类似于一颗多叉树。第一层页表(页目录)指向第二层页表,第二级页表就像树的节点一样,可以按需创建、删除和管理。这种结构使得管理更加灵活和高效,尤其是当内存需求不均匀时,可以动态分配和释放内存。

2025-04-06 22:24:23 1083

原创 Linux : 内核中的信号捕捉

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。在Linux: 进程信号初识-CSDN博客这一篇中已经学习到了一种信号捕捉signal()

2025-04-06 21:03:09 890

原创 Linux: 系统内核中的信号

在Linux: 进程信号初识-CSDN博客信号的初识这一篇我们已经了解了什么是信号,和信号的产生及信号的捕捉,但是那些都是信号在用户层的理解,同时也产生了几个问题:之前讲到的所有进程信号的产生都需要OS来执行,为什么?我们提到进程在接收到信号之后通常有着三种处理方式(1. 忽略此信号。2. 执行该信号的默认处理动作。3. 自定义处理动作),那么针对这三种处理方式,进程是立即处理的吗?如果不是立即处理,那么信号是否需要暂时被进程记录下来?记录下来放在哪里呢?

2025-04-04 14:08:57 1129

原创 Linux: 进程信号初识

在Linux操作系统中,进程信号是一个非常重要的概念。我们在前面的文章中已经见识过了进程信号了,比如我们在进程的一章中,尝试过向进程发送9号信号来终止进程(所以对于用户来说,我们可以通过向进程发送特定的信号使得进程完成某些指定的动作。

2025-04-02 18:02:18 918 2

原创 Linux : System V 共享内存

共享内存区是最快的IPC形式(进程间通信:IPC,InterProcess Communication) 一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用write()和read()来传递彼此的数据。

2025-03-31 17:19:16 847

原创 Linux: 进程间通信

在我们学习进程的时候,我们知道正是因为程序地址空间的存在,所以进程之间具有独立性,他们互不影响,但是在我们的实际应用中,进程之间总会有需要通信(交流获取对方数据)。

2025-03-29 14:24:25 2265

原创 Linux: 静态库和动态库

在Linux环境下,我们使用gcc编译链接代码时,可以分为静态链接和动态链接。静态链接即在编译链接时,将代码所使用到的静态库文件代码全部拷贝到可执行文件中(拷贝实质上是将库文件的代码展开拷贝至我们的可执行程序的代码段。,这样做的缺点是可执行文件会生成的比较大,优点是此时再运行可执行文件就不需要再查找库了。静态库文件一般以.a 结尾动态链接不会在编译时将动态库文件的代码加入到可执行文件中,而是在可执行文件运行时,去查找所需的动态库,并将其加载到相应的进程中,并且不同的进程可以共享这些动态库。

2025-03-25 20:35:37 1250 2

原创 Linux: 文件系统

操作系统对打开的文件会加载到内存中进行管理,但是整个计算机中还存在着许许多多的没有被打开的文件,这些文件又是存在在哪里呢?操作系统对这些文件又是怎么管理的呢?

2025-03-24 11:58:43 1001

原创 Linux:进程程序替换

一般情况下,对应的语言写的程序只能调用对应的语言的接口,对于其它类型的语言的接口,如C++就不能 调用java或者python的接口,那如果我们想要调用别人的接口怎么办?所以进程程序替换就能很好的解决这个问题,这样我们就可以使用现成其他语言接口的程序而不用费力地去再实现一个,很大程度上能减少我们的编程成本。

2025-03-15 21:34:49 1017 2

原创 Linux : 进程控制

我么在Linux:进程概念-CSDN博客这一章节中认识使用fork()函数来创建子进程,在Linux : 进程地址空间-CSDN博客这一篇详细介绍了父子进程的代码和数据共享的问题(写时拷贝)但是我们之前的实验都是为了演示子进程创建成功的现象,并没有说明子进程创建失败是什么结果。在Linux :进程状态-CSDN博客中我们提到了许多进程状态,其中提到了僵尸进程,这是一种在子进程退出时没有被父进程读取所产生的一种状态。所以在这篇文章中,我们再深入认识一下进程的终止和进程的等待。

2025-03-12 16:10:51 1008 3

原创 Linux : 进程地址空间

目录一 前言二 进程地址空间是什么1,现象2.虚拟地址空间3. 现象解释 4. 写时拷贝三 为什么要存在进程地址空间四 进程地址空间是如何实现的1 操作系统如何管理进程地址空间进程地址空间图:在学习C语言的内存管理的时候,我们看到过这样一张图:😀栈:放的是非静态局部变量、函数参数、返回值等。 栈是向下增长的,且栈是一段线性空间,遵从先进后出的规则,小内存。我们通常会在函数栈帧中创建很多变量,我们称这个变量具有临时性,这个变量即为局部变量,存于栈上。且函数的递归意味着不停的创建局部变量,函数参数,返回值,

2025-03-06 20:59:09 802

原创 Linux : 环境变量

这就是为什么我们每次启动系统后(中途不关机),无论怎么运行、运行多少次自己的程序,该进程的父进程的PID,也就是该进程的PPID永远不变的原因,因为它的父进程一直都是bash进程。我们在Linux命令行中输入指令的时候,如我们在不同的目录或者文件夹下输入ls、pwd、cd等等命令的时候,我们并没有带路径的名称,但是系统仍然给出了我们正确的反馈,那么系统是怎么知道我们这个时候是在哪个路径下呢?我们在进行C或者C++编程的时候,主函数main()都不带参数,但是这并不意味着它没有参数,相反它有着三个参数。

2025-03-04 21:09:41 684 2

原创 Linux :进程状态

可是我们知道,系统中的内存资源是非常宝贵的,且系统中存在着大量的进程,对于这些进程,系统需要给其分配所需要的资源,对于如今的单核或者多核的计算机,想象一下,如果大量的进程同时需要进行处理,那么会产生什么样子的后果呢?僵尸进程 Z的感性认识:进程被创建出来------->完成任务----------->要知道它完成的如何,可以不关心结果(进程退出的时候,不能立即被释放进程对应的资源,而是保存一段时间,让父进程或os来进行读取)------------------>进程进入死亡状态X被系统回收。

2025-03-02 22:00:04 799 2

原创 Linux:进程概念

当你写完一个程序的时候,在没运行的时候,代码存在于哪里呢?存在于磁盘中,当程序运行的时候,程序就会被加载到内存之中,此时该程序还不是进程。在一个操作系统中,除了运行你的程序之外,还运行着其他的程序,那么系统中这些程序都是杂乱无章的吗?当CPU处理这些任务的时候考不考虑优先级呢?运行中程序的管理:先描述再组织操作系统为每一个运行的程序用一个 struct task_struct 结构体来描述运行的程序的属性和信息。组织过程:可以认为把创建的strcut 用双向链表进行链接。

2025-03-01 17:01:35 937 2

原创 Linux: 常见指令

cd ../day02/ : 相对路径。cd /home/litao/linux/ : 绝对路径。/为根目录 绝对路径:/home/lt/106/lesson2 从根开始。以 .开头的文件,在linux 下我们叫做隐藏文件。文件=文件内容+文件属性(空文件也占磁盘空间)将当前工作目录改变到指定的目录下。cp - r 目录 目录。文件之间(普通文件 和目录)相对路径,不从根开始。linux 常见指令。

2025-02-22 21:10:03 591

原创 unordered_set 和 unordered_map的模拟实现(c++)

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到,即最差情况下 需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次 数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑 树结构的关联式容器使用方式基本类似,只是其底层结构不同,

2025-02-17 22:33:49 1283 2

原创 封装红黑树实现set 和map

✍ set 和 map 的底层是用红黑叔进行实现的,set 是用 key 结构的红黑树,map 是用key-value 结构的红黑树。我们再模拟实现的时候可以把红黑树复制两份,一份用K结构封装set,一份用K-V结构封装map。但是这样会造成代码的冗余与重复。下面是STL30源码拆减分析。

2025-02-14 14:44:35 1095

原创 红黑树的实现

/结点颜色enum ColorBlack,Red//节点的左孩子//节点的右孩子// 节点的双亲//节点的值域,键值对Color _col;//结点的颜色//结点的构造函数:_kv(kv),_col(Red)//默认结点为红色{}☯枚举是一种用户自定义的数据类型,用于定义一组具有离散值的符号常量。枚举使得代码更加可读和易于理解,提高了代码的可读性和可维护性。//枚举的语法enum 枚举名称 {值1,值2,值3,...//最后一个没有,

2025-02-12 20:35:44 810

原创 AVL树的实现

/三叉链结构int _bf;//balance factor平衡因子//键值对。

2025-02-11 16:24:15 724

原创 二叉搜索树

对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的 深度的函数,即结点越深,则比较次数越多。比如:给一个单词word,判断该单词是否拼写正确,具体方式如下: 以单词集合中的每个单词作为key,构建一棵二叉搜索树 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。堆删除一样我们是找堆的最后一个元素与堆顶交换数据,这样就不会破坏堆的结构,搜索二叉树也类型,我们可以找左子树最右结点(或者右子树最左结点),例如上图最有结点时。

2025-02-03 12:51:57 1149

原创 c++多态

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。在继承中要构成多态需要满足必须通过基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写例子:在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类 不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。

2025-01-28 17:28:37 1135

原创 c++继承

下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。单继承::一个子类只有一个直接父类时称这个继承关系为单继承多继承:一个子类有两个或以上直接父类时称这个继承关系为多继菱形继承:菱形继承是多继承的一种特殊情况。菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant 的对象中Person成员会有两份。例子:虚拟继承可以解决菱形继承的二义性和数据冗余的问题。

2025-01-26 13:41:05 1054

原创 c++模板进阶

模板参数分类类型形参即类似class<T>与常量例如我们要用模板来创造一个可以申请任意长度和类型的数组,其中长度它的类型一定是,唯一不同的就是size_t对应的值。那么此时就可以用注:浮点数(double)和。

2025-01-25 22:38:22 916

原创 优先级队列 priority_queue

例如_con 为vector<int>,系统会自动调用vector 的构造函数,

2025-01-23 18:05:59 674 1

原创 stack 和queue 的模拟实现

适配器是一种,我们最终实现的功能可以通过不同的路径来实现,那么这个路径就可以称作适配器。c++中也有适配器,例如、queue它们并不是使用了什么新的内存形式,而是利用适配了其他的容器,然后来实现自己的功能。我们在实现stack的时候,发现和的代码其实是差不多的,就是因为,顺序表的内存特点可以支持栈的功能实现,也可以用实现,因为 vector 和list 的 尾插尾删消耗都不大。我们在实现模拟实现的时候,不能使用vector ,因为vector 头插头删需要挪动数据消耗大,且STL中。

2025-01-22 13:27:57 402

原创 list的底层实现

list是封装的双向链表结构,因为独特的链式结构,所以在插入、删除效率上很高。

2025-01-19 19:17:41 1021

原创 vector类的实现

vector类似于数据结构中的顺序表,那么string也是一个数组,它与vector的区别是什么呢?首先对于string类,因为其是字符数组,里面存有'\0',其次其可以实现字符的比较或者'+='之类的操作符重载。而vector可以表示自定义类型数组,没有’\0‘,’+=‘对于其毫无意义。vector是一个表示可变大小数组的序列容器。就像数组一样,其也采用连续的空间来存储元素,也就是支持随机访问,和数组一样高效,但其大小是可以动态改变的。

2025-01-12 14:19:59 479

原创 string类的实现

在创建对象的时候,创造一个与已存在对象一摸一样的对象——拷贝构造函数拷贝构造函数是构造函数的一个重载形式拷贝构造函数的参数只有一个且必须时类类型对象的引用,使用传值方式编译器会直接报错,因为此时会引发无穷递归调用。若未显示定义,编译器会生成默认的拷贝构造函数。但是默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。注意:类中如果没有涉及到资源申请时,拷贝构造函数写不写都行,一旦涉及到资源申请时,则拷贝构造函数时一定要写的,否则就是浅拷贝。

2025-01-07 19:50:43 1061 2

空空如也

空空如也

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

TA关注的人

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