- 博客(34)
- 收藏
- 关注
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 解读经典并发模型—多进程、多线程、IO多路复用
就比如一位只允许外带的餐馆的服务员,当客流量少的时候,几个顾客隔段时间就来问我们的菜什么时候上,勉强还能应付,但是当客流量多起来的时候,全部隔段时间就来问我们的菜什么时候上,这样服务员肯定会吃不消了。僵尸进程,顾名思义,指一个进程生命周期结束了,但是它的“尸体”PCB等进程信息却还在内存中被保存,就成为了僵尸进程。有较高的要求,需要在有限的时间内进行响应。init 进程是系统中的特殊进程,是内核启动的第一个用户级进程,负责接管孤儿进程(即父进程退出的子进程)、僵尸进程,并负责回收它们的资源。
2024-01-15 22:21:50
1388
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 Redis 内部编码与优化方式
redis 为每种数据类型都提供了多种内部编码方式,以散列类型为例,通过散列表实现散列类型,此时查找和赋值操作时间复杂度为 O(1),但是当键中元素很少时,O(1)的性能并不会比 O(n)有明显的性能提高。所以此时 redis 会使用一种比较紧凑但是性能稍差的内部编码方式,内部编码方式对于开发者来说是透明的,当键中元素变多时,redis 就会自动调整内部编码方式,转换为散列表。查看一个键的内部编码方式可以使用"ziplist"OK"embstr"
2024-01-14 10:58:07
836
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 Redis主从复制的集群模式
数据的复制是单向的,只能由主节点到从节点。但是当主节点崩溃时,情况就比较复杂了,需要先将一个从节点作为主节点,然后再将崩溃的原主节点作为从节点来恢复数据。这里就不介绍了,之后再总结。当从节点从主节点断开后,重连后从节点会发送 SYNC 命令来重新进行一次完整的复制操作,即使断开后的数据改变很小,也需要将完整的数据快照传输一份,这种方式显然不够理想。当开启复制且关闭主节点的持久化时,一定不要使用一些管理工具令主节点崩溃后自动重启,这样启动后主节点数据不但不会恢复,还会因为复制而导致从节点拥有的数据全部清空。
2024-01-14 10:54:10
932
1
原创 Protobuf简单使用
接口定义了允许您检查、操作、读取或写入整个消息的方法,包括从二进制字符串进行解析和序列化到二进制字符串。声明,则该文件的所有内容都将放置在相应的 C++ 命名空间中。的类,该类公开派生自 google::protobuf::Message。该文件中的所有声明都将驻留在。对于其他数字字段类型(包括。编译器将生成以下访问器方法。编译器将生成以下访问器方法。编译器将生成以下访问器方法。编译器将生成以下访问器方法。编译器将生成以下访问器方法。编译器将生成以下访问器方法。该类还定义了以下静态方法。
2024-07-27 20:39:05
296
原创 浅谈IoC——C++怎么实现IoC?
有系统学习过Spring框架的同学都知道,Spring的一个很重要也是很有设计美感的一个特性——IoC (Inversion of Control),即控制反转。所谓控制反转,就是把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。一切设计模式的思想都是为了,这是软件工程追求的终极目标。
2024-07-27 20:38:06
404
原创 CMU 15445 2023fall Project1 Buffer Pool Manager
实验要求通过本地测试大概花了三天,第一次提交线上测试只有45分😭😭😭。后来又陆陆续续修改,又花了两天时间终于过了。不过这个实现基本毫无性能可言,bpm的每个函数都是简单粗暴地直接上scope lock锁住整个函数作用域,所以QPS rank排在200靠后了,后面再做优化吧。
2024-01-24 18:44:04
1628
原创 GoF 23种经典的设计模式——装饰器模式
装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。每个装饰器包含一个指向下一个装饰器或具体组件的引用。装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。引入装饰器主要是为了解决使用继承方式扩展类时,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀的问题。
2024-01-20 12:00:23
456
原创 CMU 15445 2023fall #Project0 实现一个简单的k-v存储引擎
实验要求网站太吓人了,这甚至只是个课程入门实验,但是前两部分主要的内容差不多花了我一整天🥲🥲🥲。主要是考察一下对C++的熟练程度,比如智能指针、移动语义、并发控制,还有数据结构的基础。
2024-01-19 18:04:35
869
原创 GoF 23种经典的设计模式——适配器模式
简而言之,适配器的目的就是将一个类的接口转换成客户希望的另外一个接口。主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。适配器类继承目标接口,并同时包含对源接口的引用。通过继承,适配器类既具有目标接口的特性,又能访问源接口的方法。在对象适配器模式中,适配器类通过组合关系包含源接口的对象,并实现目标接口。适配器类持有源接口对象的引用,并将其方法转换为目标接口的方法。对象适配器模式更灵活,允许适配器适配多个源接口对象。对象,并实现了目标接口。
2024-01-17 12:00:46
400
原创 GoF 23种经典的设计模式——桥接模式
桥接模式的目的是将抽象与实现分离,使它们可以独立地变化,该模式通过将一个对象的抽象部分与它的实现部分分离,使它们可以独立地改变。它通过组合的方式,而不是继承的方式,将抽象和实现的部分连接起来。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类,这两种类型的类可被结构化改变而互不影响。通过桥接模式,我们可以轻松地组合不同的形状和颜色。
2024-01-16 16:53:52
350
原创 C++的并发控制机制——原子操作、互斥锁和条件变量
原子操作是不可中断的操作,要么完全执行,要么完全不执行,不存在部分执行的情况。条件变量是一种线程同步机制,用于在线程之间传递信息和实现线程的等待和唤醒。它通常与互斥锁一起使用,以确保在检查条件和等待条件期间不会发生竞争条件。这些原子操作提供了对共享变量的原子性访问,可以用于实现线程安全的并发操作。使用原子操作可以避免竞争条件和数据竞争等多线程并发问题,确保数据的一致性和可预测性。它提供了一种确保在任何时刻只有一个线程可以访问共享资源的方式,以防止数据竞争和不一致性。条件变为真后,等待的线程被唤醒。
2024-01-15 22:27:33
941
原创 C++的RVO与NRVO
因此,当使用 std::move 返回局部变量时,编译器将无法应用 RVO 或 NRVO,因为它无法保证返回的右值引用不会被修改或继续使用,编译器必须假设这个对象的资源可能已经被外部引用,因此不能在原地构造返回值。但是,通过返回值优化,编译器可以在函数内部直接构造目标位置的对象,避免了不必要的拷贝或移动操作,从而提高了性能。在某些情况下可以提高性能,如在函数接受右值引用参数时,但在返回局部变量时使用它将阻止 RVO 或 NRVO,导致不必要的移动或拷贝操作,从而降低程序性能。,然后在函数返回之前,将。
2024-01-15 22:24:23
1082
2
原创 GoF 23种经典的设计模式——原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,其主要思想是通过复制(克隆)现有对象来创建新的对象,而不是通过构造函数创建。在原型模式中,对象的克隆是通过复制已有对象的数据而不是重新构造对象,因此避免了重复的初始化和资源获取操作,提高了性能。需要注意的是,虽然原型模式可以提高性能,但在一些情况下可能引入对象状态的共享,因此在设计时需要确保克隆的对象是独立的,不会相互影响。通过克隆原型对象,可以创建新的对象,并且可以通过改变克隆的属性来实现个性化定制。是具体的原型类,它继承了。
2024-01-15 21:14:18
342
原创 GoF 23种经典的设计模式——创建者模式
Builder 模式是一种创建对象的设计模式,它将对象的构建过程与其表示分离,允许按照步骤构建复杂对象。,它继承了抽象创建者类,并实现了构建产品的方法。在具体创建者中,我们创建了一个产品对象,并在构建方法中设置了产品的属性。这个示例将对象的构建过程与表示分离,提供了一种灵活且可读性强的方式来构建复杂对象。指导者根据特定的顺序调用创建者的方法来构建产品,并通过创建者的。,它接收一个具体创建者对象,并调用创建者的方法来构建产品。,其中定义了构建产品的纯虚函数,并提供了获取产品的方法。首先定义了一个产品类。
2024-01-15 20:34:10
844
原创 GoF 23种经典的设计模式——抽象工厂模式
作为开发者,我们就不得不创建怪物的类,然后初级怪物、中级怪物等都继承自怪物类(当然不同种类的则需要另创建类,但是模式相同)。可以想象在这个系统中,将会有成千上万的怪物实例要创建,问题是还要保证创建的时候不会出错:初级不能创建高级的怪物,反之也不可以。每个具体工厂类都实现了抽象工厂接口,并负责创建特定的产品对象。Abstract Factory 模式更关注创建一族对象(不同的怪物),通常具有共同的主题(相同的难度系数),而 Factory 模式更关注创建一类对象,通过将对象的创建延迟到子类中实现。
2024-01-15 20:33:28
821
原创 GoF 23种经典的设计模式——工厂模式
在工厂模式中,我们将对象的实例化过程移到一个独立的工厂类中,客户端通过调用工厂类的方法来创建对象,而不是直接使用 new 关键字实例化对象。工厂模式的优点在于它可以提供一种灵活的对象创建方式,可以根据需求动态地创建不同类型的对象。此外,工厂模式也符合单一职责原则,将对象创建的逻辑封装在工厂类中,使得代码更加可维护和可扩展。这样,客户端与具体的图形类解耦,可以通过工厂类来创建不同的图形对象,而无需关心对象创建的具体细节。工厂模式有多种变体,其中最常见的是简单工厂模式、工厂方法模式和抽象工厂模式。
2024-01-15 20:32:33
916
原创 JavaScript生成器
是 JavaScript 中的一种语法,用于在 Generator 函数内部委托(delegate)执行另一个可迭代对象或 Generator 函数的迭代过程。当调用 Generator 函数时,它不会立即执行,而是返回一个称为 Generator 对象的迭代器。异步生成器(Async Generator)是指使用异步函数定义的生成器函数。关键字,异步生成器函数会等待 Promise 的解析结果,并在解析完成后继续执行。异步生成器函数与普通生成器函数的区别在于,异步生成器函数可以在。
2024-01-15 20:23:37
947
原创 GoF 23种经典的设计模式——单例模式
注意:自 C++11 起,静态局部变量在多线程环境下是线程安全的(C++11 标准要求编译器在初始化静态局部变量时提供线程安全的初始化保证。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。由于单例模式的特性,这两个指针应该是相等的,因为它们都指向相同的唯一实例。,用于保存唯一的实例。负责创建实例(如果尚未创建)并返回该实例的指针。
2024-01-15 20:20:08
901
原创 解读经典并发模型—多进程、多线程、IO多路复用
如果给CPU一系列任务,CPU按照事件顺序逐一完成这些任务,在这种情况下后续任务必须等待前面的任务完全完成之后才能占用CPU资源,对于简单的任务,计算机使用这种模型就足够了。但是为了提高系统的性能与用户体验以及资源分配的公平性,操作系统引入了并发机制。某些应用场景对实时性有较高的要求,需要在有限的时间内进行响应。通过并发处理,可以在规定的时间内同时处理多个任务,满足实时性需求。
2024-01-15 20:16:36
1046
原创 SeedLab——Shellcode Development Lab
通常情况下,为了将这个字符串推入堆栈,我们需要使字符串的长度为 4 的倍数,所以我们会将字符串转换为 /bin////bash。然而,对于此任务,我们不能向字符串中添加任何多余的 /,也就是说,命令的长度必须是 9 个字节(/bin/bash)。将args的地址加载到ecx寄存器,envs的地址加载到edx寄存器,path的地址已经存在ebx寄存器中了。ebx寄存器为传递的参数一即path的地址,ecx寄存器为传递的参数二即args的地址,edx寄存器为传递的参数三即envs的地址。然后传递envs参数。
2024-01-15 20:14:24
1081
原创 SeedLab——Cross-Site Scripting (XSS) Attack Lab
CSP通过指定允许加载和执行的内容源和资源,限制了浏览器中可以执行的代码。JavaScript可以操作cookie,因此当一个页面存在xss漏洞时,攻击者嵌入的恶意代码就能够完成截获所有访问该页面的cookie,然后将cookie发送给攻击者的服务器的行为,这样攻击者就能使用cookie冒充这些用户的身份了。cookie是存储在客户端的一些键值数据,它用于跟踪和存储有关用户状态、会话和身份验证,因此cookie是浏览器客户端的十分敏感的数据,如果cookie被泄露,就会造成敏感信息的泄露、用户身份的冒用。
2024-01-14 11:18:41
1233
1
原创 SeedLab——SQL Injection Attack Lab
这里的密码是经过SHA1散列计算后存入数据库的,因此要修改别人的密码,不能直接修改为明文,那样我们自己也无法使用。上面的SELECT语句存在SQL注入漏洞,可能会造成数据库的泄露,如果UPDATE语句存在SQL注入漏洞,危害可能会更严重,因为攻击者可以利用漏洞来修改数据库,造成系统的不可用。获取用户提交的GET参数中获取用户名和密码,然后对密码计算sha1散列值,拼接到sql语句执行查询,以完成身份的校验。我们可以构造输入的用户名,将整个语句提前闭合,并将后面的内容注释掉,如下所示。的话命令格式比较简单。
2024-01-14 11:18:02
990
1
原创 SeedLab——Environment Variable and Set-UID Program Lab
再次执行,发现可以打开/etc/zzz文件,然后进入sh程序,在sh程序中尝试写入,发现权限又不够了,这是因为在打开sh之前调用了。当一个可执行文件设置了 Set-UID 位并且文件所有者是一个特权用户(如 root 用户)时,执行该文件的用户将会获得该文件所有者的权限。当一个可执行文件具有 Set-UID 权限时,它会在执行时继承文件所有者的权限,而不是执行者自身的权限。函数用于降低进程的权限级别,以增加系统的安全性。这样做的效果是,当前进程的有效用户ID将与实际用户ID相同,从而降低了进程的权限。
2024-01-14 11:17:08
1032
1
原创 SeedLab——Packet Sniffing and Spoofing Lab
在这个实验中,攻击者需要能够嗅探数据包,但在容器内运行嗅探程序会有问题,因为容器实际上连接到一个虚拟交换机,所以它只能看到自己的流量,无法看到其他容器之间的数据包。通常情况下,应用程序使用高级套接字(如TCP套接字或UDP套接字)进行网络通信,这些套接字封装了底层的网络协议细节,提供了简化的接口供应用程序使用。它会根据IP头部中的各个字段的值,按照IP协议规范中定义的计算方法,自动生成正确的校验和,并将其填充到IP头部的校验和字段中。通常,在进行数据包嗅探时,我们只对特定类型的数据包感兴趣。
2024-01-14 11:15:44
938
1
原创 使用Libpcap捕获局域网中的数据包
如果过滤表达式中不包含网络地址相关的条件,例如只捕获所有数据包或仅捕获特定端口的数据包,那么可以不设置。结构体的指针,其中包含了数据包的元数据信息,比如时间戳、数据包长度等。第三个参数为指向数据包的原始字节流的指针,可以通过这个指针来访问数据包的内容。:表示捕获的数据包数量,设置为 -1 表示无限循环捕获,直到遇到错误或显式停止。用于输出数据包的内容。第一个参数为指向数据payload的指针,第二个参数为数据包的字节数。的地址并转化为int类型的指针,然后对指针进行解引用并加1表示又收到了一个数据包。
2024-01-14 11:13:46
1139
1
原创 Libnet实现ICMP SMURF攻击
ICMP SMURF攻击是一种DDoS攻击,利用了Internet Control Message Protocol (ICMP) 的功能和网络的特性,目的是通过大量伪造的ICMP回应数据包(通常是使用广播地址)来消耗目标网络的带宽和资源。攻击者发送一个特殊构造的ICMP Echo Request(ping)数据包,将源IP地址设置为目标网络中的广播地址。然后,攻击者期望目标网络中的所有设备都会接收到该请求并发送回应,因为广播地址会被发送到所有设备。
2024-01-14 11:12:27
957
1
原创 SeedLab——TCP/IP Attack Lab
我们刚刚介绍TCP的时候,介绍了三次握手。在TCP三次握手过程中,客户端向服务器发送一个SYN(同步)包,服务器接收到后会返回一个SYN-ACK(同步-确认)包给客户端,然后等待客户端的确认(ACK)。当收到客户端的确认(ACK)后,TCP连接就建立起来了,接下来就可以使用这个连接进行通信了。
2024-01-14 11:10:10
1089
1
原创 Linux下iptables防火墙配置
在每个表中,数据包将按照规则链的顺序进行处理,直到匹配到适用的规则或到达链的末端。对于主机型防火墙通常只处理入站和出站数据,入站数据的匹配流程:PREROUTING --> INPUT -->本机的应用程序,出站数据:本机的应用程序---->OUTPUT ----->POSTROUTING。在规则链内部匹配规则,自上向下按顺序依次进行检查,找到相匹配的规则即停止(LOG策略例外,表示记录相关日志)若在该链内找不到相匹配的规则,则按该链的默认策略处理(未修改的状况下,默认策略为允许)。
2024-01-14 11:08:25
947
1
原创 SeedLab——DNS Attack Lab
然后,本地DNS解析器继续向顶级域名服务器发送查询请求,获取次级域名服务器的地址,以此类推,直到找到负责该域名的DNS服务器。因为查询中的事务ID通常是随机生成的,没有看到查询数据包,攻击者很难知道正确的ID。在 DNS 中,超出域的附加记录是指在 DNS 查询中包含的与请求的域不相关的额外记录。这是通过更改用户机器的解析器配置文件(/etc/resolv.conf)来实现的,将服务器10.9.0.53添加为文件中的第一个nameserver条目,也就是说,这个服务器将被用作主要的DNS服务器。
2024-01-14 11:06:45
1563
2
原创 SeedLab——Spectre Attack Lab
这样可以最大程度地利用处理器的执行资源,提高指令的并行度,加快程序的执行速度。这样虽然有时能正确预测,但是有些情况下会返回255的错误答案,这是因为restrictedAccess的返回类型为uint8_t,整数溢出了,所以修改restrictedAccess的返回值和spectreAttack中的参数s的类型为int即可。传统的安全防护方法通常关注于保护数据存储和传输的过程,而侧信道攻击则利用了系统在处理数据时产生的其他非直接通信渠道,如时间、功耗、电磁辐射等,来获取有关敏感数据的信息。
2024-01-14 11:03:56
986
2
原创 Redis常用数据类型与基本命令指北
要使用字符串类型存储一个对象,那么需要将对象序列化成一个字符串来表达,但是这样无法提供对单个字段的操作,每次都需要将对象完整取出,这样十分消耗资源,同时字符串无法提供对单个字段的原子操作,容易产生条件竞争,因此可以使用散列类型存储。然而,跳跃表并不适合高效地执行诸如按照成员进行查找的操作,因此在 Redis 中,为了提供更高效的成员查找功能,有序集合还使用了一个辅助的数据结构——哈希表。ZDIFFSTORE:计算一个有序集合与一个或多个有序集合的差集,并将结果存储到一个新的有序集合中。
2024-01-14 11:00:15
848
1
原创 Redis事务与乐观锁
Redis 事务是一种将多个命令打包在一起执行的机制。通过使用事务,可以确保一系列命令在一次执行中依次执行,而不会被其他客户端的命令请求打断。开启事务:使用 MULTI 命令开启一个事务。之后的命令都会被添加到事务队列中,而不会立即执行。添加命令:在 MULTI 和 EXEC 命令之间,可以添加任意数量的 Redis 命令,这些命令会按照添加的顺序被放入事务队列中。执行事务:使用 EXEC 命令执行事务。Redis 会按照事务队列中命令的顺序依次执行这些命令。
2024-01-14 10:58:56
721
1
原创 Redis 持久化
Redis 提供了两种持久化方式,即 RDB(Redis Database)和 AOF(Append-Only File)。
2024-01-14 10:55:10
863
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人