自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 CMU-15445(5)——PROJECT#1-BufferPoolManager-Task#3

本节实现PROJECT#1最后一个TASK,主要内容是使用TASK1和TASK2实现的和(前者会跟踪页面的访问情况,以便在需要为新页面腾出空间时决定淘汰哪个帧;后者会通过调度磁盘的读写操作),从磁盘获取数据页并将其存储到内存中,当缓冲池管理器被显式要求写出脏页,或者需要淘汰某个页以为新页腾出空间时,也会调度将脏页写回磁盘。BusTub通过名为的辅助类实现对内存中帧的管理,所有页面数据的访问均需通过该类进行 —— 其提供的GetData方法可返回指向帧内存的原始指针,供与借此将磁盘物理页内容复制到内存。

2025-05-26 17:13:53 619

原创 CMU-15445(4)——PROJECT#1-BufferPoolManager-Task#2

在前一节我实现了 TASK1 并通过了测试,在本节中,我将逐步实现 TASK2。如上图,Page Table(页表)通过哈希表实现,用于跟踪当前存在于内存中的页,将页 ID 映射到缓冲池中的帧位置(其实和虚拟内存中的页表一个思路,缓冲池的页表不应与页目录混淆,后者是页 ID 到数据库文件中页位置的映射)。其实就是实现如何通过页表跟踪缓冲池并且记录页面的使用情况进行相应的淘汰过程。而本节的负责,因为页表还维护了每页的额外元数据、dirty-flag和,每当线程修改页面时,dirty-flag。

2025-05-16 23:22:50 949

原创 CMU-15445(3)——PROJECT#1-BufferPoolManager-Task#1

在完成了前面基础的PROJECT#0后,从本节开始才正式进入了CMU-15445的学习,最终目的是构建一个面向磁盘的数据库管理系统。PROJECT#1的主要任务是实现数据库管理系统的,缓冲池负责在主存缓冲区与持久化存储(硬盘)之间来回移动数据的物理页(虚拟内存通过内存交换实现运行内存超过物理内存的大小),同时充当缓存 —— 将频繁使用的页面保留在内存中以加快访问速度,并将未使用或不活跃的页面回存储设备。

2025-05-08 18:13:41 1183

原创 CMU-15445(2)——PROJECT#0-C++PRIMER

我将从我的角度记录这个项目本身的背景知识,并解释我对这两个task的理解。

2025-04-30 20:26:06 1054

原创 CMU-15445(1)——环境搭建

最近在找完暑期实习之后,终于有了一些干项目外的空余时间学习新的知识,在这么多轮面试中,数据库的考察非常多,但孱弱的数据库基础导致我有很多次面试被问住,因此我希望在学习CMU-15445(Fall 2024)的过程中能夯实我的基础,更好的理解数据库在计算机中的应用。我将从本节开始记录我从查找资源、注册以及后续project提交的过程。

2025-04-28 22:53:56 1127 1

原创 windows安装boost执行bootstrap.bat无法生成b2.exe

2. 在系统变量栏中,选择 INCLUDE,若没有,则手动添加。将下列四条逐个配置到 INCLUDE 中,并保存。在官网下载的boost库中执行 bootstrap.bat 文件无法生成 b2.exe 文件,导致无法编译。至此,问题解决,打开cmd,cd至boost目录中运行bootstrap.bat,b2.exe即可生成。3. 选择 LIB,若没有,则手动添加。环境变量没有正确配置,需要将系统和 VS2019 手动配置为环境变量。

2025-02-17 15:07:54 404

原创 网络编程(24)——实现带参数的http-get请求

在前文中,我们的 get 请求不带任何参数,那如果我们想要实现带参数的 get 请求,我们应该如何做?首先应考虑实现 url 的解析函数,解析 get 请求携带的参数。(也称为百分比编码),确保字符串可以在 URL 中安全传输。我们在前文通过beast实现了http服务器的简单搭建,但是有很多问题我们并没有解决。(0到9 和 A到F),超过这个范围的值不属于十六进制的规范。表示的,查询字符串附加在 URL 的末尾,用于向服务器传递。的字符串进行解码,将其还原为原始字符串。该函数对输入的字符串进行。

2025-02-16 17:21:52 1493

原创 设计模式(5)——观察者模式

观察者模式用于解决一个对象的状态变化需要通知多个对象的问题。有一个主题对象(被观察者),负责维护数据和状态。有多个观察者对象,想了解主题对象的变化。当主题对象状态发生变化时,会通知所有观察者。这样设计的优点是低耦合,主题和观察者之间的依赖关系很松散,方便扩展和维护。主题负责变化,观察者负责监听,变化后自动通知监听者。图片来源:https://refactoringguru.cn/design-patterns/observer。

2025-01-09 20:33:03 1502

原创 设计模式(4)——七大原则

每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现在成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类(方法体内部的类)则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

2025-01-09 16:43:14 1386

原创 设计模式(3)——工厂模式

如果想要生产这些产品,我们可以创建一个工厂类,然后给这个工厂添加一个工厂函数(通过这个函数来创建我们需要的对象,关于这个函数一般将其称之为工厂函数),我们通过枚举变量控制工厂类要生成哪一类产品,比如 Sheep,Lion或Bat。总结来说,工厂方法模式通过定义一个创建对象的接口,将对象的实例化延迟到子类中去完成,实现了对象的创建与使用的解耦,提高了系统的可扩展性和灵活性。尽管简单工厂模式能生成我们需要的产品,但是如果我们想要生成更多类型不同的产品,超出了枚举变量的范围,那么就需要在工厂函数中添加更多的。

2025-01-08 18:09:10 1185

原创 设计模式(1)——面向对象和面向过程,封装、继承和多态

要学习设计模式,首先需要了解什么是面向对象,并掌握其三大要素:封装、继承和多态。我们可以通过一个简单的例子来说明:假设我们想要把一头大象放进冰箱,这个过程可以分为三个步骤:1)打开冰箱门;2)把大象放进去;3)关上冰箱门。在面向过程的编程中,这三个步骤通常被抽象为三个函数,并在调用时按需提供参数。而在面向对象的编程中,需要围绕具体的对象进行设计。这里有两个关键对象:冰箱和大象。冰箱需要具备开门和关门的功能;大象则需要具备进入冰箱和离开冰箱的功能。对象是类的实例。

2025-01-07 22:43:45 1402

原创 设计模式(2)——单例模式

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点,单例模式是在内存中仅会创建一次对象的设计模式。//通过静态成员变量实现单例//懒汉式private:public:在上面的代码块中,定义了一个Single2类,Single2类的默认构造函数被声明为私有,且删除拷贝构造函数和赋值运算符,确保Single2类不能通过拷贝创建或赋值创建新的实例。Single2类只有一个公共静态方法GetInst(),用于获取Single2类的唯一实例。局部静态成员。

2025-01-07 14:46:08 751

原创 并发线程(21)——线程池

commit 函数执行完后需要返回 std::packaged_task 对象的 future,以便获取任务执行结果,但是 future 的类型和可调用对象绑定,我们不知道任务执行的结果是什么,我们应该如何确定函数的返回类型?,我们可以根据这个结果在线程池中创建出数量相等的线程,每个线程独自占有一个CPU核心,这些线程就不用分时复用CPU时间片,此时程序的并发效率是最高的。的可调用对象,但是现实情况是存在不同类型的任务,返回类型已经参数类型军可能不同,我们应该如何将其封装为一个。

2025-01-06 19:43:21 919

原创 cpp——chrono库

(时间间隔)是C++中表示时间段的类型。它是一个模板类,可以表示秒、毫秒、微秒等不同的时间单位。它不仅可以表示时间长度,也可以表示特定时间点到另一个时间点的间隔。与人的感知类似,duration可以表示"过去多久"(例如5秒前)、“现在”(例如现在到程序开始的时间)、或"未来多久"(例如5秒后)。duration位于头文件<chrono >Rep:表示时钟数(周期)的类型(默认为整形,可以自定义为doublefloat等其他类型)。若Rep是浮点数,则duration能使用小数描述时钟周期。

2025-01-05 01:39:59 902

原创 并发编程(20)——基于内存模型和原子操作的无锁队列

指向节点的数据是否为空(如果为空说明尾指针还未更新或已更新完毕,如果不为空说明尾指针指向的内存块已经存储了新数据,但尾指针尚未更新,我们需要等待尾指针更新完毕),如果为空则将需将需要压入的数据传递给当前尾指针指向的节点(这里为了保证数据的独占性,将数据内容交给。函数用于弹出队首的元素(因为队列是先入先出的,所以必须是弹出 head 指向的节点),原理很简单:*当 head 和 tail 指向同一个内存空间时,表示当前队列无数据,返回空指针,反之,返回队首元素。最后,我们需要释放一开始为了存储数据而创建的。

2025-01-03 19:07:54 1240

原创 并发编程(19)——引用计数型无锁栈

计数器需要和 head 指针处于同一“层级”(即数据结构体node和ref_node相互关联,我们通过ref_node->node_ptr即可访问数据内容,通过node->next即可访问下一个节点的计数器),成为所有线程都能直接操作的数据。访问节点内部的计数器并增加计数,而线程 B 率先操作了节点的计数器,加了 1,然后弹出了节点,并在操作完成后让计数器减 1,发现计数变成了 0,于是删除了节点。通过这样的流程,可以确保节点在无人引用时才被安全回收,同时减少不必要的内存操作,提升了效率和线程安全性。

2024-12-24 20:15:25 883

原创 并发编程(18)——基于内存模型和原子操作的线程安全的栈

锁的本质是阻止其他线程进入锁住的临界区,当一个线程在临界区中休眠,其他线程的操作也会被卡在临界区外(锁的根本意图就是杜绝并发功能,是阻塞型数据结构,但我们也可以实现基于锁的高并发线程安全的栈、队列、链表等其他数据结构,参考前面几节内容)。而无锁数据结构(非阻塞性数据结构)要求总有一个线程能够真正推进事情的进展,而不是空转,也就是说即使一些线程在任意位置休眠,其他线程也能完成操作并返回,这也说明任何时候都不存在锁住的临界区。

2024-12-18 18:05:08 862

原创 并发编程(17)——基于同步方式的线程安全的链表

文章目录十七、day171. 链表的概念2. 支持多线程、高并发的单向链表2.1 支持前插的单向链表2.2 支持前插and后插的单向链表2.3 测试十七、day17上一节实现的查找表中,桶类 bucket_type 使用了C++标准库提供的存储结构链表 list 作为数据存储容器,但通过C++标准库提供的链表 list 存储键值对虽然对并发读不影响(共享锁保证多个线程可以线程安全的读共享数据),但是不能并发写,在同一时间有且仅有一个线程可以修改共享数据(因为C++标准库提供的链表的增删改查是通过同一个互

2024-12-13 17:30:42 864

原创 并发编程(16)——基于同步方式的线程安全的查找表

哈希表相比上面两种方式无疑是更好的选择,哈希表有很多个桶(哈希函数生成的值,我们这里用链表的方式存储桶中值),每个关键字(key)都属于一个桶,因为每个桶都占据一块独立的内存,所以我们可以为每个桶单独的施加独立的锁。,在同一时间有且仅有一个线程可以修改共享数据(因为C++标准库提供的链表的增删改查是通过同一个互斥量实现的,锁粒度不够精细),我们需要像上一节实现队列一样,自定义一个链表结构,通过多个锁来为增删查改进行保护,每个操作有自己独立的锁,实现写操作的并发。这里不多过叙述,可以自行查找相关的资源。

2024-12-09 17:21:07 1059

原创 并发编程(15)——基于同步方式的线程安全的栈和队列

在上面的代码中,push 和 pop 函数施加同步是用的同一个mutex,这会导致 push 和 pop 在多线程环境中串行化,即,一个线程执行 push ,那么其他线程就没办法执行 pop 或 push,虽然我们通过条件变量挂起了这些线程,避免了算力资源的浪费,但是我们没有办法实现 push 和 pop 的同时调用。获取的尾节点并不是最终的尾节点。其实创建一个智能指针共享资源也会造成一定程度的内存开销,只不过很少,因为智能指针在栈上开辟,占8字节,所以每创建一个新的智能指针,便会在栈上开辟8字节的空间。

2024-12-05 22:38:07 1274

原创 分享几个常使用的轨道外推模型

该函数我是从一个类中直接取出来的,如果要使用需要提前将卫星的位置速度转换至轨道六根数输入。具体求法可以参考国防科大张洪波老师出版的《航天器轨道力学理论与方法》书中P85-P93。

2024-12-04 18:11:15 527

原创 并发编程(14)——内存栅栏

栅栏主要用于强制施加内存次序,却无须更改任何数据,通常于服从次序的原子操作组合使用。用大白话来说,栅栏用于阻止编译器或CPU对某些内存操作进行重排,确保在它之前的操作完成后,才会执行它之后的操作,从而维护内存操作的顺序一致性。因为是最宽松的内存序,它只能保证原子性,却不能保证多线程之间的先行性和顺序性,所以服从次序的原子操作通常会通过编译器进行指令重排,而栅栏会限制这种重排。我们之前学习了互斥量mutex:拿到mutex锁的线程将拥有唯一进入临界区的资格(共享互斥除外)。其实mutex。

2024-11-28 23:14:32 1178

原创 并发编程(13)——无锁环形并发队列

锁的本质是阻止其他线程进入锁住的临界区,当一个线程在临界区中休眠,其他线程的操作也会被卡在临界区外(锁的根本意图就是杜绝并发功能,是阻塞型数据结构)。而无锁数据结构要求总有一个线程能够真正推进事情的进展,而不是空转,也就是说即使一些线程在任意位置休眠,其他线程也能完成操作并返回,这也说明任何时候都不存在锁住的临界区。无锁数据结构不一定更快,因为常常需要很多原子操作,每个原子操作都有额外开销并可能涉及 CPU 和缓存的竞争。无锁数据结构的优点最大限度地实现并发:还是那句话,锁的根本意图就是杜绝并发功能。

2024-11-23 17:51:35 1393

原创 并发编程(12)——内存次序与内存模型

直观上,读操作应该返回写操作“最后”一次写入的值。在单处理器系统(单线程)中,“最后”由程序次序定义。在多处理器系统(多线程)中,我们称之为顺序连贯(sequential consistency, SC).通俗地说,SC要求所有内存操作表现为(appear)逐个执行(任一次的执行结果都像是所有处理器的操作都以某种次序执行),每个处理器中的操作顺序都以其程序指定的顺序执行。SC有两点要求每个处理器的执行顺序和代码中的顺序(program order)一样。

2024-11-21 17:14:12 1112

原创 并发编程(11)——同步、先行关系

单线程下单线程情况下前面的语句先执行,后面的语句后执行。操作a先于操作b,那么操作b可以看到操作a的结果。我们称操作a顺序先行于操作b。也就是”a sequenced-before b”,也可以称为”a happens before b”。比如//操作a//操作b操作a在操作b前执行,也就是说操作a顺序先行于操作b,即操作a先行于操作b,所以操作a的结果对操作b可见,操作b可读到m的值。

2024-11-20 21:54:26 766

原创 C++——智能指针剖析

除了STL容器的并发修改操作(这里指的是修改容器的结构,并不是修改容器中某个元素的值,后者是线程安全的,前者不是),protobuf的Message对象也是不能并发操作的,比如一个线程中修改Message对象(set、add、clear),另外一个线程也在修改,或者在将其序列化成字符串都会触发core dump。对象(管理的数据是同一份,引用计数共享,但shared_ptr不是同一个对象),每个线程读写的指针也不是同一个,引用计数又是线程安全的,那么自然不存在数据竞争,可以安全的调用所有成员函数。

2024-11-19 16:12:17 1186

原创 前端(4)——demo分享

这两天需要用HTML、CSS和js简单组合一个html网页用于展示一些数据内容,这是我简单组合别人的一些文件形成的简单demo,大家也可以拿过去使用。

2024-11-18 16:36:21 570

原创 前端(3)——快速入门JaveScript

事件处理是前端开发中的一个重要部分,涉及到如何让网页响应用户的点击、输入、键盘操作、鼠标移动等行为。通常,我们更倾向于使用 JavaScript 来处理事件,而不是在 HTML 中内联定义。例如,假设你有一个列表,里面包含了多个按钮,传统方法会给每个按钮单独绑定事件。但使用事件委托,只需要在父元素上绑定一个事件处理程序即可。事件委托是通过在父元素上绑定事件,而不是在每个子元素上绑定事件,来优化性能的一种技巧。),该对象包含了有关事件的所有信息,如触发事件的元素、事件类型、键盘按键等。

2024-11-15 21:20:58 925

原创 前端(2)——快速入门CSS

它以冒号开头,用于构造用户交互结构,比如,鼠标悬停在一个元素上,元素的格式或者状态可以被改变,这种方式可以通过伪类选择器实现。其实这涉及到优先级的问题,id>类>标签名,因为子元素选择器相当于类选择器(通过.类名构造),所以肯定比p标签选择器优先大,所以第一行不改变。选择器就是选择要应用样式的HTML元素或者标签,它可以选择所有元素或特定元素或特定类或特定id。选择位于父元素内部的子元素,就是一个大标签嵌套一个小标签,子元素选择器用于选择小标签。:元素脱离文档流,根据开发者的意愿漂浮到网的任意方向。

2024-11-14 19:33:53 850

原创 前端(1)——快速入门HTML

参考:W3school1. HTML我使用的是vs code,在使用之前,先安装以下几个插件:Auto Rename Tage HTML CSS Support Live Server1.1 HTML标签HTML全称是Hypertext Markup Language(超文本标记语言)HTML通过一系列的标签(也称为元素)来定义文本、图像、链接等等。HTML,标签是由尖括号包围的关键 字。标签通常成对出现,包括开始标签和结束标签(也称为双标签),内容位于这两个标签之间,例如

2024-11-14 15:33:48 1221

原创 并发编程(10)——内存模型和原子操作

有关内存模型和原子操作的知识。

2024-11-13 23:19:38 827

原创 并发编程(9)——Actor/CSP设计模式

简单来说,Actor在发送消息前必须知道接收方是谁,而接受方收到消息后也需知道发送方是谁,更像是邮件的通信模式。而csp是完全解耦合的,不关心消息从哪来或到哪去,只关心消息是通过哪个channel传递的。这里有一个问题需要注意:消费者线程是在生产者线程结束之后才运行的(消费者线程延迟500ms),那么就没有代码唤醒消费者线程,为什么消费者线程可以正常运行?主要步骤是通过条件变量挂起当前线程,若当前线程被唤醒,并且满足判断条件,则继续执行下面的代码,过程如下。如果不满足,线程继续挂起,等待被再次唤醒;

2024-11-11 22:08:10 1361

原创 并发编程(8)—— std::async、std::future 源码解析

解析async和future源码

2024-11-07 22:36:12 1031

原创 C++——完美转发(引用折叠+forward)

介绍什么是C++完美转发,内容包括引用折叠、forward和模板类型推导规则

2024-11-07 15:31:04 1301

原创 如何安装QT(linux/windows)

选择qt5.15,组件只需要选择第一个即可,在使用过程中如果需要其他组件,可对于的添加下载,全部选择需要耗费一百多个g,没必要,我们只用选择我们需要的即可。我这里需要安装5.15版本,但是QT安装程序中没有,我们这里点击右边的 `Archive` ,再点击筛选,这样可以看到qt以前的一些其他的版本。同理,如果没有想要安装的版本,我这里准备安装5.15,但选择界面没有,我们可以点击右面的archive,然后筛选。填写之后会出现下面这个网页,我选择的是linux x64版本,你们可输入下面的指令查看你的架构”

2024-11-05 19:48:03 3922

原创 并发编程(7)——利用并行和函数式编程提升计算效率

这里使用博主的原话:我对async的理解就是开辟一个一次性的线程执行并行任务,主线程可以通过future在合适的时机执行等待汇总结果。今天学习如何通过async、future、并行和函数式编程实现快速排序提高计算效率。up主up主[mq白的代码仓库](

2024-11-05 12:13:59 908

原创 并发编程(6)——future、promise、async,线程池

今天学习如何使用std::future、std::async、std::promise。

2024-11-04 23:01:12 1621

原创 如何快速搭建一个个人博客

我这里使用了两种方法实现个人博客的快速搭建,如果想自己从零开始实现个人博客的实现,可自学前端知识。

2024-11-03 16:07:56 1270

原创 并发编程(5)——利用条件变量实现线程安全队列

C++条件变量如何使用,如何通过条件变量实现线程安全队列

2024-11-01 17:04:26 681

原创 并发编程(4)——锁(下)

解锁unique_lock、共享锁和递归锁的的使用

2024-10-31 17:54:08 1077

空空如也

空空如也

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

TA关注的人

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