自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(78)
  • 问答 (1)
  • 收藏
  • 关注

原创 【ProtoBuf】使用指南

字段类型+字段名=字段唯⼀编号。这里的字段类型和c++一致(在类型后面带上位数)。字段唯⼀编号是⽤来标识字段,⼀旦开始使⽤就不能够再改变。但注意,这里有可能存在变长编码,变⻓编码是指:经过protobuf编码后,原本4字节或8字节的数可能会被变为其他字节数。通过以上知识就能得到如下用例。

2024-01-25 20:51:33 872

原创 【负载均衡oj】(一)架构和公共模块

实现类似牛客网的在线做题,带有判题功能,总体分为三个模块,一个通用头文件模块,一个后端服务模块,用于编译客户的代码并测验数据。还有一个oj客户端,采用mvc架构,负责前后端交互,可以调用后端的编译功能并提供负载均衡选择,这样后端编译模块可以采用集群化部署,通过负载均衡选择负载最低的后端进行业务逻辑。编译服务在细化分为,编译服务,运行服务,后端对上层提供的接口,后端编译的网络服务。

2024-01-08 16:51:21 456

原创 【负载均衡oj】(七)ojserver

负责负载均衡,获取网站首页,通过网络罗调用编译并运行并提供结果给用户。根据用户的操作提供不同的功能。采用mvc结构。使用 ctemplate文字模板做数据渲染m在这里指的是和数据的交互,可以用文件或者sql交互。在使用文件的情况下,就必须要有对应的文件目录存放每一道题。提供题目描述和题头还有测试用例。

2024-01-05 13:59:51 949 1

原创 【负载均衡oj】(六)服务器调用模块

使用第三方库cpphttplib实现网络功能。使用说明,直接拷贝到当前目录下或者放在 /usr/include/目录下都可。要使用高版本的gcc编译器。7版本以上才可以。在建立初步代码后可以用postman进行初步测试。

2023-12-28 18:04:43 399

原创 【负载均衡oj】(五)编译运行链接模块

主要负责链接起编译和运行模块,并和用户的代码结合起来,提供出上层的接口给网络使用,因为用户代码是来自网络的同时我们需要把结果通过网络送还给客户端。通过json来做应用层数据的的序列化,将结构化数据转化为字符串.

2023-12-28 18:04:23 364

原创 【负载均衡oj】(二)编译模块

编译模块只提供编译功能,所以我们不考虑把用户的代码转换成临时文件的整个过程,假设我们已经拿到了一份代码文件,里面是用户的代码。编译只有两种结果,编译成功和编译失败,出错的时候会将错误信息打印到stder上,我们需要将这段信息还给用户,所以需要输出重定向,生成个一个临时文件用来保存错误信息。同时编译本身这一过程必须是另一个进程或者线程,因为服务器不能卡死。

2023-12-28 18:03:55 403

原创 【负载均衡oj】(四) 运行模块

主要负责运行可执行程序。通过文件名就能运行程序。

2023-12-28 18:03:21 354

原创 【负载均衡oj】(三)日志模块

这个项目的输出都被重定向了,为了方便调试和观察,我们需要一个日志文件用来打印日志信息。可以实现成开放式日志,直接拼接在流插入后面,这样使用更灵活 ,例如 LOG()

2023-12-25 14:13:37 353

原创 【tcmalloc】(四)上层调用接口设计

提供给上一层用户申请内存调用,调用时会创建出当前线程的内存线程缓冲区,同时进入内存池逻辑。

2023-12-23 21:17:13 374

原创 【tcmalloc】(三)通用头文件的设计

哈希桶节点上挂的自由链表,不同模块都会使用。

2023-12-23 21:15:37 390

原创 【tcmalloc】优化方法

此项目本意是脱离malloc的使用,但若使用new的话仍然会使用到malloc。因为centralcache和pagecache本身是单例,不考虑创建对象的问题,但是每个线程自身拥有个线程缓冲区和span结构是要考虑new的问题的,引入定长内存池替换new可一提高效率。

2023-12-23 21:11:40 432

原创 【tcmalloc】(六)释放流程

tcmalloc的源码考虑了内存的大小和链表的长度。这里实现的是简单的版本之考虑了链表的长度。当释放内存块后会挂到线程缓冲区对应的自由链表上,当检测到当前自由链表的长度大于我们一次批量申请的大小之后就会将当前自由链表的一部分(一个批量)还给centralcacahe。不是全拿走,有可能有剩余个其他先线程使用。centralcache拿到以后要继续向pagecache归还。

2023-12-17 15:47:06 156

原创 【tcmalloc】(五)pagecache设计(申请)

用于给centralcache分配内存,也采取哈希桶结构。重点有两个区别,桶的划分规则跟上两层不一致。这一层没有采取区间划分,一页page是第一个桶两页是第二个,以此类推。第二个区别是自由链表同样悬挂的是span,但这里的span不用切分小块内存。在centralcache那一层直接计算出要申请多少页,直接定值法找到pagechace的桶节点进行申请。每一个桶节点的页表页数不相等。

2023-12-17 10:49:47 54

原创 【tcmalloc】(四)centralcache设计(申请)

中心cache,用于threadcache的桶节点没有自由链表时,向下寻找内存的下一层数据结构。起到均衡调度的作用。同样采取和线程缓存一样的哈希桶映射规则。这样方便能直接找到一下层的桶节点,不同点是中央内存区是所有线程共享的所以就有加锁问题。这里用的是桶锁。这样的优点是不同桶之间不会有竞争问题。不同线程申请不同大小的内存空间,会去不同的桶低下找空间。另一个不同点,线程内存区下挂的是大当前桶节点,同样大小的小内存。

2023-12-16 16:45:00 59

原创 【MySQL】基础(一)

正常情况数据是以文件的形式存储在磁盘或者内存上的。这就意味着他就会具有文件保存数据的缺点mysql本身也是一种文件系统是由两部分构成的,客户端(mysql)和服务端(mysqld),mysql数据库本身就是一套网络服务。(登录时需要ip和端口号可以看出)通常不使用数据库的时候,用户直接操作磁盘上文件里的数据,成本很高。当使用mysql,用户将sql指令通过mysql客户端递交给mysqld服务端,由服务端帮助用户操作磁盘上的数据。

2023-12-14 19:00:32 167

原创 【tcmalloc】(二)整体设计和thread cache(申请)

内存池需要考虑以下几方面的问题。1. 性能问题。2. 多线程环境下,锁竞争问题。3. 内存碎片问题(外碎片(内存不连续无法使用),内碎片(因为对齐规则的浪费))malloc 一进入多线程就加锁,tcmalloc有可能不用加锁。1.thread cache:线程缓存是每个线程独有的,用于小于256KB的内存的分配,线程从这里申请内存不需要加锁,,这也就是这个并发线程池高效的地方。

2023-12-14 16:22:25 89

原创 【模拟tcmalloc】(一)定长内存实现

固定大小的内存申请释放需求,特点是性能达到极致,不考虑内存碎片问题。

2023-12-13 21:00:00 56

原创 【QT入门】基础知识

qt是一套应用程序开发库,与MFC不同是跨平台的开发类库,主要用来开发图形界面。完全面向对象容易扩展。1.常见的工程文件有这两种第一个是桌面平台的图形用户界面gui应用程序,第二个是控制台应用程序,一般用于学习c/c++语言可以类比c++的控制台程序,包含主函数,调用了一个函数传入了环境参数。跟c++下没有什么太大区别。QWidget这两者的主要区别是继承的父类不同,QMainWindow中自动为用户创建了一个菜单栏、工具栏、中心窗口和状态栏。而QWidget不会。

2023-12-11 20:51:26 131

原创 (四)详解工厂模式

本质就是工厂接口创建出工厂实例,调用产品接口实现出产品实例。

2023-10-23 23:20:07 315

原创 条例26~31(实现)

尽可能延后变量定义式的出现,这样做能增加效率和可读性尽量避免转型,注重效率时尤其避免dynamic转型若转型是必要的应将其隐藏在函数背后,而不用手动调用尽量使用新式的类型转型避免返回引用,指针,迭代器,指向对象内部。这样能增加封装性,避免虚调的发生异常安全函数即使发生异常也不会泄漏资源或者允许任何数据结构破坏,通常有三种类型的保证:基本型,强烈性,不抛异常性。强烈保证往往能够以拷贝复制实现,但强烈保证并非对所有函数都具备可实现意义。

2023-10-14 21:02:14 320

原创 条例24~25(设计与声明)

如果需要为某个函数的所有参数,包括被this指针所指向的隐含参数,进行类型转换,则需要把它实现成非成员函数。当stl的swap效率不高时,提供一个swap成员函数并保证其不抛出异常用类外成员函数调用类内成员的swap,若实现的是类,则特化标准库的swap在调用的时候针对swap使用using声明不能在stl内添加全新的东西。

2023-10-11 18:51:12 95

原创 (三)详解装饰者模式

主类不需要更改,但是子类需要经常更改,扩展。同时需要能实现动态扩展。可以动态的增加或者删除新的职责。策略模式和装饰者模式很像但是可扩展的功能程度不同。策略模式往往添加了一个和之前几乎完全不一样的功能,而装饰者模式是对之前有的功能的一种修饰。

2023-10-09 21:48:54 86 1

原创 (二)详解观察者模式

当我们需要一个类,在他的内部元素发生变化的时候可以主动通知其他类的时候,同时要保持良好的可拓展性,可以采用观察者模式。

2023-10-02 21:52:26 322

原创 条例18~23(设计与声明)

好的接口很容易被正常使用,不容易被误用。应该在所有接口努力达成这些性质促进正确使用的办法包括接口的一致性,以及与内置行为兼容阻止误用的办法包括建立新类型,限制操作,消除客户的资源管理责任,束缚对象值使用share_ptr的定制删除器用来防范dll问题,还可以用来自动解除互斥锁。尽量以const的引用替换传值拷贝,前者比较高效,并可避免切割问题。以上规则不适用于内置类型,以及stl的迭代器和函数对象。对这些而言使用传值拷贝更加恰当。

2023-09-26 19:52:12 68

原创 条例13~17(资源管理)

为了防止资源泄漏,需要使用raii对象,他们在构造函数中获得资源,并在析构函数中释放资源常用的智能指针是shared和auto,前者效果更佳。复制raii对象必须一并复制它所管理的资源,所以资源的拷贝行为决定了raii的拷贝行为。常见的raii行为禁止拷贝,实行引用计数。每个RAII对象都应该提供一个取得其管理资源的方法。对原始资源的调用可以通过显示调用或者隐式调用。通常显示调用更加安全。若使用new[]则必须使用delete[],反之同理。

2023-09-24 20:24:11 90

原创 (一)详解策略模式

目录必备背景知识一.使用场景二.核心逻辑三.举例子总结由当前对象所拓展出来的对象有可能有新增功能,或者不具备原来某些功能的时候可以使用。优点在于可拓展性高,维护便捷,能动态的改变对象的属性。若想给所有同一大类但不同属性的不同对象增加一个新的公用功能,直接提供接口即可。不用依次修改。将不同对象反复变化的部分抽象封装出来,后序修改时只针对变化的部分进行修改这样不会影响其他不变化的部分。从代码理解好理解一些。假设我们有个基类鸭子,我想拥有不同种类的鸭子子类。不同鸭子拥有不同的行为。有的会叫有的不会叫。我们统一将这

2023-09-23 19:56:48 325

原创 条例11~12(构造/析构/赋值函数)

应当确保赋值操作有良好的行为。确保自己赋值时行为仍然正确。拷贝函数应该保证赋值对象内所有成员变量,以及所有父类成员的成分(调用父类成员的拷贝函数)不要尝试在拷贝构造和拷贝赋值之间相互复用,应该向共同技能放在第三方函数内,用两个函数共同调用。

2023-09-20 20:40:59 55

原创 条例6~10(构造/析构/赋值函数)

若不想使用编译器自动生成的成员函数,可以通过只声明不实现,或者将拷贝函数作为父类并私有化带有多态性质的父类应该声明虚析构函数,若类内有任意一个虚函数,则析构函数也应该为虚函数若类的设计不是作为父类使用,或不是为了多态,则不需要虚析构函数析构函数不能吐出异常,只能吞下或者结束进程若客户要对某个操作函数进行异常捕捉,应该在不同函数内执行。在构造函数和析构函数内不要调用虚函数,因为这种调用不会下降到子类对象令赋值操作符返回一个this*的引用。

2023-09-20 00:26:46 51

原创 条例1~5(构造/析构/赋值函数)

对于单纯的常量,最好用const 或enums 替换宏对于函数,最好用内联替换宏若条件允许,可以用non const 函数复用const函数编译器强制实施 bitwise constness函数尽量声明为const 可以帮助编译器检查出错误用法内置对象都要手动初始化,编译器不会保证会自动初始化最好使用初始化列表初始化,同时初始化列表的排列顺序最好的声明顺序一致多文件编译最好用静态变量替换局部静态变量,这样能确保初始化顺序编译器可以暗自生成构造,析构,拷贝,赋值等成员函数。

2023-09-15 21:40:09 51

原创 【Linux服务器编程总结】网络编程基础知识 (udp初级)

其实本质就是大小端。通常在网络传输的时候会将要发送的数据转同一转换成大端后再发送。在linux中提供了如下四个函数进行大小端转换。

2023-06-07 00:39:52 364

原创 【算法训练(day7)】区间和并,离散化数组模板

问题:给定 n个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。输出合并完成后的区间个数。例如:[1,3][1,3] 和 [2,6][2,6] 可以合并为一个区间 [1,6][1,6]。

2023-06-02 17:57:13 657

原创 【算法训练(day6)】双指针模板

通常情况下我们可能会遇到在某些可遍历的集合中寻找满足某种性质的字串或元素。这时候我们采取暴力的思路就会面临多重循环。我们可以利用题目中所给的集合并利用其性质将多重循环降成一重循环。光用语言描述可能不太好理解。接下来看几个双指针典型案例。

2023-05-28 16:13:18 689

原创 【算法训练(day5)】前缀和与差分

通常我们要求前缀和的时候题目会给出原始数组,我们需要另一个数组来记录每一个位置的前缀和,我们的前缀和数组记录从开头到当前位置的所有数据的和,用于后续的处理。因为我们前缀和数组内部存放的是从头到当前位置(原数组内)的数据和当我们做差的时候会将范围外的部分剪掉,这样留下的就是从范围起始位置到结束位置的前缀和了。最后对修改后的差分数组求前缀和就能得到修改后的前缀和数组。在一维前缀和的基础上增加一维,原先的前缀和是从左向右计算,二维前缀和是从左上角向右上角计算的矩阵,这时候求的区间和是一个矩阵范围的区间和。

2023-05-23 17:50:51 759

原创 【算法训练(day4)】高精度与低精度计算模板

加法其实是比较简单的,我们首先从从低位算起,把较短的那个数按照每一位拆开,从最低位开始依次和较长的数字相加,将每一位的结果加起来就是最终结果,其实就是竖式相加的过程。减法首先我们要让大的数作为被减数,小的数作为减数,通过标记位来判断正负,这样就能用同一段代码处理正数和负数的计算,同样也是从最低位到最高位以此相减,再遇到不够减的情况下,向下一位借10,同时让借位t变成1,证明借走了一位。这点在竖式除法里也有体现,从最高位的每一位开始依次看够不够整除,不够的话就让当前位参与到下一位的计算。

2023-05-17 18:52:53 109 1

原创 【算法训练(day3)】快速排序模版选择及不同版本快排对比

目前市面上常用的有两种划分区间,一种是hoare划分另一种是Lomuto划分。常见快速排序实现模版比如挖坑法和经典快速排序就是用的是hoare划分。那么这两种区间划分方式有什么不同呢。先上结论,hoare划分在面对大量重复数据的时候效率会明显好于lomuto划分。当面对大量不同数据的时候两种划分区间相差不大。下面来解释为什么大量重复数据处理效率会有差异。因为lomuto的工作流程是先选定key值,再在数组的一侧初始化两个指针i和j。

2023-04-19 23:34:13 457 1

原创 【算法训练 (day2)】积木画(dp问题)

小明最近迷上了积木画,有这么两种类型的积木,分别为 I 型(大小为 2 个单位面积)和 L 型(大小为 3 个单位面积):同时,小明有一块面积大小为 2 × N 的画布,画布由 2 × N 个 1 × 1 区域构成。小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式?积木可以任意旋转,且画布的方向固定。

2023-04-10 20:38:22 784 5

原创 【算法训练(day1)】李白打酒加强版(dp问题)

这道题可以用dp求解,因为最后恰好喝完酒,并且没酒的时候遇到花是不合法的,这说明酒的最大数量不能大于花加起来的数量,如果酒的数量大于花的数量在最后就无法将所有的酒喝完,这是一个关键点。这样我们就需要记录下来酒的数量,花的数量,和经历的店的数量。我们可以用一个三维数组来表示,数组内存的是状态数,也就是走到当前位置有多少种方案。

2023-04-05 15:37:44 1211 5

原创 【多线程操作】线程池模拟实现

首先我们需要在构造函数内初始化条件变量和锁,并创建指定数量的线程,并完成所有的线程准备工作,并通过vector管理起来,当我们通过run拉起所有线程的时候,各个线程会执行routine函数,不同的线程执行不同的任务,不过当任务队列为空的时候各个线程是不会执行routine函数的,只有当向任务队列添加完任务后,并唤醒消费线程,线程才会执行各自的任务,并将任务任务队列中移除。可以把线程的创建和回收用函数封装,实现线程的初始化和回收,同时给传进来的任务通过ThreadData绑定上线程的名称。

2023-03-06 21:38:59 380

原创 【c++初阶】特殊类设计

我们可以通过构造函数私有化,或者析构函数私有化来实现,我们可以单独写一个供上层使用的删除函数或者创建函数,注意的问题是我们需要同时禁用掉拷贝构造和赋值,不然拷贝构造创建的对象还是在栈上。在98中我们可把赋值函数和拷贝构造私有化,在c++11当中我们可以直接delete掉这两个函数。

2023-01-29 15:19:55 80

原创 【C++初阶】右值引用

一般来说能取地址的,也就是等号左边的值,比如创建的int变量是左值,而右值就是与他相反, 在等号右边,并且不能被取地址,比如说数字10。一般的普通引用只能引用左值。引用和const组合在一起使用的话既可以引用左值也可以引用右值。右值引用可以引用右值,也可以引用move后的左值。

2023-01-18 20:07:32 90

空空如也

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

TA关注的人

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