自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux 线程控制

注意这里是独立,并不是私有,其它线程想访问还是可以的,比如主线程想访问Thread-2的x值。以这个为例子,如果一个计算任务很大,比如1-100000,就可以拆分,让不同的线程执行不同的范围,最后主线程再将子线程的结果进行汇总。可以看到,打印出来的tid的值与LWP的值完全不一样,这是因为tid是给用户使用的的,而LWP是给OS使用的。对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,joinable和分离是冲突的,一个线程不能既是joinable又是分离的。

2024-09-19 19:00:05 458

原创 布隆过滤器

在上图中,如果想要精确的结果,可以在判断"该昵称被别人注册的时候",这时去服务器中进行查询(由于布隆过滤器判断 在 是不准确的),来得到准确的结果。近似算法可以使用布隆过滤器,精确算法可以先使用哈希切割,再将Ai和Bi插入到setA和setB中,这样就可以快速且准确的找交集。如果是情况1,文件很大有很多重复,后面重复插入都失败,可以插入到set中。如果是情况2,不断插入set以后,内存不足,会抛异常,需要换一个哈希函数进行二次切分,再找交集。哈希切割,如果需要统计ip的topK问题,可以使用优先级队列。

2024-09-12 20:11:02 688

原创 Linux线程概念

是进程内的一个执行分支。线程的执行粒度要比进程细之前理解的进程:进程 = 内核数据结构(task_struct)+ 代码和数据什么叫做线程?我们认为,线程操作系统调度的基本单位!重新理解进程?进程是承担分配系统资源的基本实体,即操作系统分配资源,是以进程为单位进行分配的。线程是进程内部的执行流资源。

2024-09-10 22:02:22 999

原创 哈希表的封装和位图

数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。也是一样,两个位图,00表示出现0次,01表示出现1次,10表示出现2次,11表示出现3次及以上。使用两个bitset,00表示出现0次,01表示出现1次,10表示出现2次或者2次以上。与上面类似:将这些整数各自映射到一个位图,一个值在两个位图都存在,则是交集。可以计算一下,40亿个数,需要开2^32bit,即512MB。

2024-09-08 19:07:39 993

原创 信号的捕捉处理

举例如下: 用户程序写了SIGQUIT信号的处理函数sighandler。当前正在执行main函数,这时**发生中断或异常(也可能是系统调用)**切换到内核态。在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函 数,

2024-09-06 21:24:29 612

原创 map和set的封装

至于为什么可以这样做,可以看pair的构造函数的[官方文档](中返回的iterator转化为const_iterator。先修改RBTree.h的insert函数。加上const_iterator。中的insert函数的返回值。

2024-09-03 19:27:40 320

原创 c++哈希表

通过哈希函数获取待插入元素在哈希表中的位置如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探测找到下一个空位置,插入新元素。上面写的扩容效率太低,每次都需要调用析构函数释放之前链表的节点,很麻烦,所以可以让之前链表的节点“挪动”下来、当key为string时,取模就会有问题,此时需要将字符串映射为某一个数字。线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。但是这样传string就要多传一个参数,很烦,所以可以使用类模版的全特化。

2024-09-03 16:51:01 515

原创 信号的保存

sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的,使用者只需要调用以下函数来操作sigset_t变量,而不应该也不需要对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。现在需要屏蔽某一信号,接着给进程发该信号,观察pending表。

2024-09-01 17:48:25 793

原创 信号的产生

进程上下文切换发生在CPU从执行一个进程切换到执行另一个进程时。上下文切换涉及。

2024-08-26 22:20:52 787

原创 进程间通信

管道是Unix中最古老的进程间通信的形式我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”管道实际就是一个内存级别的文件,具体见2.2通信不仅仅是通信数据,互相协同也是要协同,本质也是通信,信号量首先要被所有的通信进程看到信号量本质是一把计数器,PV操作,原子的。执行流申请资源,必须先申请信号量资源,得到信号量之后,才能访问临界资源信号量值1,0两态的,二元信号量,就是互斥功能申请信号量的本质: 是对临界资源的预订机制。

2024-08-20 18:20:22 821

原创 信号入门学习

Ctrl-C产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行, 这样Shell不必等待进程结束就可以接受新的命令, 启动新的进程。Shell可以同时运行一个前台进程和任意多个后台进程, 只有前台进程才能接到像Ctrl-C这种控制键产生的信号。前台进程在运行过程中用户随时可能按下Ctrl-C而产生一个信号, 也就是说该进程的用户空间代码执行到任何地方都有可能收到SIGINT信号而终止, 所以信号的产生相对于我们自己的代码运行来说是异步(Asynchronous)的。

2024-08-16 15:05:18 455

原创 红黑树的插入

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树。解答: 根据性质3和性质4可知, 如果有一颗红黑树, 那么它的最短路径应是全黑节点, 最长路径应是一红一黑节点交替。问题: 为什么满足上面的性质,红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍?规定cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点。情况2:cur为红,p为红,g为黑,情况3:cur为红,p为红,g为黑,

2024-08-12 13:06:30 313

原创 System V共享内存

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

2024-08-09 18:55:27 665

原创 使用命名管道的通信程序, 加入了日志系统

【代码】使用命名管道的通信程序, 加入了日志系统。

2024-07-28 17:08:40 241

原创 使用匿名管道实现一个进程池

因为我们看上面的图可以知道, 当我们只关闭一个fd时, 其实写端并没有全部关闭, 还有好多子进程指向该管道的写端, 子进程不会break, 依然会阻塞等待。这样,一个管道就会有多个写端(随着子进程数量的增多而增加), 这不是我们想要的。解决方案1: 由于最后一个子进程只有一个写端, 所以我们可以倒着close。已将N设置为2, 所以只跑了2个任务就退出了。更改为下面的代码后, 程序退出时就会卡住。中的代码, 确保每一个子进程只有一个写端。上面的代码有点小小的问题, 看下面的图。解决方案2: 非阻塞等待。

2024-07-27 13:16:28 277

原创 avl树的部分实现

如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在。即,先对30进行左单旋,然后再对90进行右单旋,旋转完成后再考虑平衡因子的更新。新增节点在右子树,父亲bf++新增节点在左子树,父亲bf–关于旋转的代码,分几种情况。

2024-07-25 12:54:24 602

原创 map的operator[]

有个面试题:当key不在map中时,通过operator[]获取对应value时会发生什么问题?要想理解上面的实现,我们先看一下insert的[文档]([官方文档]([map::operator。假设现在有一个统计次数的要求。

2024-07-25 12:48:08 308

原创 Linux文件

程序的执行是基于虚拟地址空间的,由。虽然1号fd和2号fd都对应的显示器文件,但是他们两个是不同的,如同认为,同一个显示器文件,被打开了两次,所以log.txt里只有1号fd的内容,而显示器上还是2号fd内容的数据。我们知道,动态库在进程运行的时候,是要被加载的(静态库没有), 且常见的动态库是被所有程序动态链接的,都要使用, 所以动态库也叫共享库.于是我们可以得到一个结论,实际上,0,1,2分别是stdin,stdout,stderro,其中stdin,stdout,stderro是FILE* 类型的,

2024-06-18 11:15:05 417

原创 搜索二叉树

但是InOrder()需要一个参数root,现在有三种解决办法,a.将_root改为public,b.写一个GetRoot(),c.如下。此时有两种解决办法,一是更新_root,更新为节点3,二是找左子树的最大值来作为cur的prev。我们知道,搜索二叉树的中序遍历是一个有序表,现在我们想要像这样调用。看似上面的代码没有问题,但面对下面的测试用例时,就会有问题。这个引用起作用,就需要一层一层的往下递归传递。, 这样是错误的,因为函数的默认参数。其中第②种情况包含第①中情况。,可以看下面的递归展开图。

2024-05-22 15:24:05 397

原创 c++多态

public:cout

2024-05-07 19:25:22 642

原创 c++继承

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用public:protected:// 公有继承protected:int _stuid;// 学号protected:int _jobid;// 工号int main()

2024-04-25 18:40:58 991

原创 linux进程控制

c语言提供了一共有6个execl函数关于函数命名规则的理解l(list) : 表示参数采用列表v(vector) : 参数用数组p(path) : 有p自动搜索环境变量PATHe(env) : 表示自己维护环境变量。

2024-04-22 20:56:00 725

原创 c++模版进阶

/ add.hpp地址,因为add没有实例化,没办法确定T// add.hpp。

2024-04-15 20:34:26 943

原创 反向迭代器

为例,我们完全可以再添加一个__list_reverse_iterator结构体,只需要修改++和–的逻辑。但是这样代码重复度太高了!而且自定义类型的迭代器才可以这样用,所以SGI版本的STL使用了迭代器适配模式。创立一个reverse_iterator.h,弱化了源码的萃取版本。单独写一个迭代器的类不仅减少了代码的冗余,其他容器也可以很好的适用。

2024-03-03 21:31:28 312

原创 stack和queue

是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

2024-03-03 21:29:56 818

原创 进程地址空间

看task_struct的源码,可以看到有一个指针,其中mm_struct就是地址空间,里面有各个区域的划分所以地址空间就是一种内核数据结构......

2024-02-14 20:38:07 1315

原创 stl_list

迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

2024-01-31 20:56:35 350 1

原创 linux进程(1)

抢占与中断:抢占是内核对进程的管理:当高优先级的任务因中断而成为就绪,特定的低优先级进程将让出CPU,而那个高优先级的进程得到CPU。如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。时间片:时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。独立性: 多进程运行,需要独享各种资源,多进程运行期间。

2024-01-29 20:12:03 1884 1

原创 一种比较好理解的高精度结构体

10。

2024-01-28 20:07:19 354

原创 vector

insert,erase pos位置后,不要再次访问pos,可能会出现各种出乎意料的结果,这就是迭代器失效。

2024-01-26 16:50:09 393 3

原创 c++ string(包含string的部分实现)

at越界后会抛异常,[]越界后会直接报错。

2023-11-10 20:26:37 71 1

原创 模版_函数模版与类模版_使用类模板写一个通用栈

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定 类型版本。

2023-10-19 15:46:37 48 1

原创 Linux工具_vim,make和Makefile, yum,git,gdb

三种模式:命令模式(默认打开的模式),编辑/插入模式,底行模式。

2023-10-18 20:23:54 47 1

原创 cc++内存管理

选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)globalVar在哪里?C localVar在哪里?AstaticGlobalVar在哪里?C staticVar在哪里?Cnum1 在哪里?Achar2在哪里?A *char2在哪里?ApChar3在哪里?A *pChar3在哪里?Dptr1在哪里?A *ptr1在哪里?B。

2023-10-14 20:23:23 37 1

原创 c++类和对象第二部分

public:static StackOnly CreatObj() // 提供一个静态成员函数供外界使用return s;StackOnly(int a = 0) : _a(a){} // 将构造函数私有化int main()return 0;public:static StackOnly CreatObj() // 提供一个静态成员函数供外界使用return s;

2023-10-08 16:18:28 63 5

原创 c++类和对象

在Person.h中有如下代码int age;// 定义public:// 声明private:int _age;// 声明Person.cppmain.cppint main()Person p1;return 0;此时运行代码会出现链接错误(fatal error LNK1169: 找到一个或多个多重定义的符号),因为age会在person.cpp和main.cpp展开,都会放到符号表,链接时就会有两个age,所以.h文件中要谨慎地定义全局变量。

2023-09-14 17:49:16 73 7

原创 c++的静态成员

static数据成员在类外定义和初始化是为了保证只被定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的’=’操作是赋值还是初始化了。static const int可以在类里面初始化,是因为它既然是const的,那程序就不会再去试图初始化了。因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。// 必须要进行初始化,且类内声明,类外初始化。// 也可以在类外初始化。// 静态成员属于类,不属于对象,是所有对象共享。

2023-08-03 08:46:45 45 6

原创 基础数据结构链表以及oj题目

本文介绍了链表的结构,以及常见的面试题

2023-08-01 11:14:37 93 5

原创 stl_set

同样的,map容器也要求比较函数对象必须是const的,因为map容器也是一个有序的关联容器,它会根据比较函数对象的结果来排序和存储键值对。set容器要求比较函数对象必须是const的,是因为set容器是一个有序的关联容器,它会根据比较函数对象的结果来排序和存储元素。为了保证set容器的正确性和稳定性,比较函数对象必须是const的,这样它就不能修改自身或者其他元素的值,只能进行比较操作。容器,以在容器中对元素进行排序和比较。容器对象,并使用自定义的比较函数。是一个有序容器,其中的元素类型是。

2023-05-25 10:10:04 47

原创 c++的静态成员

static数据成员在类外定义和初始化是为了保证只被定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的’=’操作是赋值还是初始化了。static const int可以在类里面初始化,是因为它既然是const的,那程序就不会再去试图初始化了。因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。C中一个函数里定义一个static变量是为了保证只初始化一次。

2023-05-13 21:14:26 40

空空如也

空空如也

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

TA关注的人

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