- 博客(36)
- 收藏
- 关注
原创 深入探索C++对象模型-构造、解构、拷贝、语意学
如果把将一个共同变量加到了接口类中,那么这个类也就是纯虚类了,纯虚类需要定义构造函数来完成这个共同变量的初始化。到底要不要把这个公共变量提取出来下放到接口类中,这一点并无一个标准到底怎么做好。纯虚类中,正常来说那些函数我们都无需定义,除了一个函数之外,纯虚析构函数。由于后续继承的子类在析构的过程中会层层调用上级的析构函数,因此缺乏任何一个base class的destructor的定义,就会导致链接失败。因此,定义析构函数时,不要将其定义为纯虚函数,将其定义为虚函数。
2024-03-11 16:21:52
1040
1
原创 [15-445 fall 2023] P2代码解析
举例:那么该bucket对应的split bucket为*0101经过merge后,local depth = 4 - 1 = 3,对应会有 1
2024-01-17 11:48:03
2217
1
原创 深入探索C++对象模型-Function语义学
虚表的析构函数指向的实际上的Derived的析构函数,但是析构函数作为非静态成员函数会接受一个this指针作为参数,这个this指针指向的应当是Derived对象的起始内存地址,如果将pbase2将作为this指针传入,显然这个this指针是错误的,因此这个操作需要连带着this指针调整操作,而这个调整操作必须在执行期完成。同理的还有函数的重载机制,我们称两个函数拥有相同的函数名,但是拥有不同的参数数量和参数类型而能够同时存在的机制为重载,而实际上,这两个函数经过编译器处理都分别会有一个独一无二的函数名。
2023-12-26 23:12:45
1006
原创 [15-445 fall 2023] P0 + P1解析
我们需要实现一个支持copy-on-write的key-value形式存储的前缀树。这个cow trie对于每次修改操作都会生成一个全新的trie。而修改前的trie还是依旧存在的。这就确保了,trie的历史状态全都可以保留下来,如果我们想要回到任意个操作前的trie的状态都可以轻松实现,十分便于回滚操作。此外,cow trie还能够让读写操作并行执行,由于写操作会生成一个新的trie,因此写操作期间不会对旧的trie进行任何修改操作,读操作可以正常进行读取操作。这大大提高了性能。
2023-12-25 23:04:32
1592
原创 深入探索C++对象模型-Data语义学
但是上面我们可以看到X空类给类Y、Z带来的额外内存开销远不止1个字节,部分编译器会针对这个问题做出优化处理。所以编译器不同,上面得到的结果也不同。如果编译器对此进行了优化,那么X空类的1byte去掉后,那么X、Y的代傲为4byte,A的大小也就只有8byte。
2023-11-18 16:27:48
169
原创 CS143:Finite Automata(regular expression->NFA->DFA)
在上个博客中,我们已经知道了,词法分析中的词法规范就是用正则表达式来实现的,我们用正则表达式来表述了编程语言中各种不同的token class。而有限自动机也是一种正则表达式的应用实现,它和正则表达式密切相关,它能够表述和正则表达式一样的规范。
2023-10-13 16:30:26
167
原创 CS143:Lexical Specifications
我们可以使用正则表达式来描述指定信息digit = '0' + '1' + '2' + ... + '9'Integer: a non-empty string of digits = digit^+letter = [a - z A - Z]identifier = letter(letter + digit)^+whitespace: ('\ ' + '\backslash n' + '\backslash t') ^ +email = letter^+ + '@' + letter^+ + '.' +
2023-10-13 16:24:04
117
原创 CS143:Lexical Analysis
词法分析的目的将分割代码,并转化成词法单元:关键字、变量名称、关系运算符等等一段代码,我们写起来是上面那个规范的形式,但是对于编译器而言,代码就是下面的那一段话,空格、换行等都是字符,通过字符可以知道发生了什么。
2023-09-29 22:34:04
106
原创 CS143:The Economy of Programming Languages
一个已经有大量开发者使用的语言,就算仅仅只是语法上的小改变,新功能的添加,编译器接口上的简单改变。但是,从头开始一门语言却十分容易,新语言的使用者很少,因此新语言的更新迭代的速度往往也是十分快速的,因为并没有那么多人在使用这门语言,我们仅需让少数人来学习这新的特性,一言概之就是新语言的实验成本很低。系统编程领域,像嵌入式系统、控制设备、操作系统,对于这些系统,我们要求对资源进行细粒度的控制,以及高精度的实时控制,需要对时间和内存的精确控制,目前为止系统编程领域,基本都还是使用C和C++这两种语言。
2023-09-27 21:38:12
77
原创 CS143:第一个编译器Fortran
对于程序代码的理解的第一步,首先肯定就是对其中的单词理解,我们看到这个句子,可以十分自然地意识到这个句子由4个单词组成,此外我们还能识别到其中的分隔符:空格、句号等标点符号,以及大写字母等信息。但是现代编译器中,词法、语法分析和代码生成这三个阶段不再是编译器的重点,现代编译器的重点工作和实现的复杂度基本都集中在语义分析和优化这两个阶段。如果Jack和her的性别并不相同,Jack是男的,而her是女的,那么就可以确定这是两个人,这好比是类型检查。一旦我们理解了句子的结构,后续我们可以尝试去理解句子的意思。
2023-09-27 21:03:01
226
原创 MIT 6.824分布式 LAB4A:ShardCtrler
lab 4要求实现一个使用raft共识算法的分片存储系统。而在lab 4a中,我们仅需实现分片控制器的功能。lab4中的分片存储系统有多个分片,这些数据分布在众多分片上,而每个分片都对应着一个集群组,可能一个集群组负责多个分片,一个集群组内的所有服务器都会使用raft共识算法进行状态的复制。而本实验的重点为分片控制器,主要负责的工作是对集群组和分片之间关系的管理,我们仅需在/src/shardctrler文件夹中对client.go,server.go,common.go这三个文件进行修改即可。注意事项(实
2023-01-29 16:41:29
661
原创 6.824:分布式事务---two phase commit
那么采取的措施同上,就是协调器在发送commit之前必须要先将该事务的信息保存到本地磁盘,即使崩溃重启后协调器也可以读取磁盘上的日志来获悉被提交的事务的信息,并重新给参与者发送commit消息,获取参与者当前的情况,如果收到了所有参与者的ack回复,那么就表明所有参与者都已经完成该事务就持久化,随后即可在在日志中删除该事务相关的数据。一个分布式事务的完成涉及到多台服务器上的任务,必须要所有服务器上的任务都完成后,事务才能够提交,其中有部分执行该事务的服务器发生了崩溃,那么就需要进行回滚恢复。
2023-01-08 12:20:52
176
原创 Frangipani:6.824课堂笔记
当然,在本地进行文件的任何操作并保存在本地的缓存中,这意味着本地的frangipani模块中必然支持完整的文件操作功能,这些复杂文件操作逻辑功能都封装到了客户端本地的frangipani模块中,这是一种去中心化的体现。每个工作站都有一个对应的日志,这个日志和这个工作站的执行事务紧密相关,这个日志并非是存储在工作站本地,而是存储在远程的petal上,这确保了这个事务在工作站崩溃后,也可以借助petal上的日志来继续完成这个事务的执行。此外,在分布式系统中必须考虑的一个问题就是服务器的崩溃恢复能力。
2023-01-06 21:42:38
175
原创 MIT 6.824分布式 LAB3:kvraft
Lab 3要求实现数据库和raft算法的结合。分别需要设计客户端和服务端,Lab3的代码的复杂性远不如Lab2,因此代码量不是很多,尽量也避免修改raft的源码,不然出了bug改起来也头疼。客户端和服务端进行连接,服务端处运行着数据库服务,服务端同样还需要运行raft算法进行共识。客户端能够向服务端发起的请求有put,append,get。当客户端需要进行指定的功能时,给服务端的发送消息,然后会将操作进行raft共识,共识结束服务端的数据库程序执行该操作。go test -race -run 3注意事
2022-12-19 22:11:28
1551
原创 MIT 6.824分布式 LAB2D:Raft
Lab 2D是lab2的最后阶段了,这一阶段就是加了一个快照机制,但是这种实验中这个快照是何时以及如何进行的,建议大家事前先去看一看,不然就会碰到各种问题。例如,我在测试过程中莫名其妙发现leader死锁了,以及测试显示lastapplied的index值和commandIndex值不匹配等问题。
2022-11-24 01:53:04
1973
原创 MIT 6.824分布式 LAB2C:Raft
Lab 2C目前感觉过来是最考验debug能力的,因为这个实验中的网络测试环境极其不稳定,十分考验程序的网络容错性。需要处理大量的高延迟的网络包,频繁的出现网络分区,节点崩溃的问题。
2022-11-24 01:48:27
760
原创 MIT 6.824分布式 LAB2B:Raft
Lab 2B就是让我们实现log replication,这块功能是和投票、心跳机制紧密关联的,因此我们在实现这部分功能的时候肯定也会适当调整这些代码。#这个就是用来进行Lab 2B的测试指令。
2022-10-31 01:23:57
1339
4
原创 MIT 6.824分布式 LAB2A:Raft
Lab 2A被官方指定为中等难度,对于我这种之前很少写多线程的菜鸡而言,真的花费了大量时间,同时对于论文的理解不够深刻,导致我在写这个lab的过程中多次推倒重写其中的逻辑,以及锁使用的不熟练,让程序在执行过程中经常发生有raft节点死锁。后续记录一下,我写这个lab 2A过程中的踩的坑。
2022-10-20 16:26:40
1350
2
原创 MIT 6.824分布式 LAB1: MapReduce
mit 6.824 lab1 代码也完全都是自己凭感觉去写,代码可能比较丑陋,大伙儿看看就好。lab1其实就是让你利用MapReduce的原理去实现数单词的程序。
2022-10-02 02:01:09
719
原创 计算机网络知识点总结2
HTTP报文格式请求报文GET /index.html HTTP/1.1\r\nHost: www-net.cs.umass.edu\r\nUser-Agent: Firefox/3.6.10\r\nAccept: text/html,application/xhtml+xml\r\n Accept-Language: en-us,en;q=0.5\r\n Accept-Encoding: gzip,deflate\r\n Accept-Charset: ISO-8859-1,utf-8;q
2022-02-18 02:00:27
230
原创 计算机网络知识点总结1
Network core: packet/circuit switching, internet structurepacket-switching: hosts break application-layer messages into packetsforward packets from one router to the next, across links on path from source to destination each packet transmitted at f.
2022-02-15 22:48:00
395
原创 JZ45,46,47,48
JZ45输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。#include <sstream>class Solution {public: string minNumber(vector<int>& nums) { quicksort(nums,0,nums.size()-1); stringstream ss; for(int i=0;i<nums.si
2022-02-11 17:02:15
519
原创 unix网络编程:大端小端、常用的函数细节、inetd介绍、select函数到epoll函数的变化
大端和小端这个概念一般会在体系结构中碰到,我们所常用的x86架构的系统都是采取小端存储方式,而68K架构的系统都是采取大端存储方式。小端的存储方式看起来不是很好看,先存低位数据到低地址,因此看过去是反的。大端存储方式看起来容易理解,就是正常顺序,先存高位数据到低地址。不同机器采取的存储方式不同,在网络通信中数据也难以判断是哪种存储方式的。因此也出了一个统一的规定,在网络上数据必须按照大端的字节序传输。我们在进行网络编程时都会用到字节序有关的库函数 <netinet/in.h>
2022-02-09 17:18:16
642
原创 unix网络编程:非阻塞的IO通信方式、TCP回射客户程序str_cli的需要考虑的问题
阻塞的IO通信调用read、recv、recvfrom函数,这些函数会在数据到来之前保持阻塞状态。调用write、send、sendto函数,这些函数会在writebuffer有空间之前保持阻塞状态。调用accept函数,保持阻塞直到监听到一个连接。调用connect函数,保持阻塞直到成功建立连接。对于UDP而言是没有所谓的连接,对于TCP而言就是发送SYN后阻塞直到收到SYN-ACK。改变通信方式的方法fcntl函数int fcntl(int fd, int cmd);
2022-02-07 16:58:15
1502
原创 wait和waitpid,进程线程同步,exit和_exit
wait和waitpid的区别wait是waitpid的特殊形式。pid_t waitpid(pid_t pid,int *status,int options)这是waitpid的函数原型首先第一个参数pid表示输入一个进程的pid,同时这里有多种情况:1、pid>0,表示等待指定的pid的子进程退出,回收其资源;2、pid=-1,表示等待任意一个子进程退出,回收其资源,此时就和wait一样了3、pid=0,表示等待同一个进程组的任何子进程,如果其中一个子进程中途变成其他进程
2022-02-06 12:09:17
1503
原创 ucore lab5学习笔记整理
在本实验中增加了用户态虚拟内存管理,每个用户态的进程都拥有各自的页表。用户进程一般处于特权级为3的用户态使用的是用户空间,在发生特权级变化后转变为内核态使用的是内核空间。注意:处于内核态时,进程可以访问用户空间的数据,但是不可执行用户空间的代码。为什么不能执行用户空间的代码呢,可以从以下情况来理解,系统并不知道这段代码执行的时候有没有bug,如果在内核态随意执行有问题的代码将会导致崩溃。处于用户态时,进程是无法访问获取内核空间的信息的,道理也显然易见,特权级3不能访问特权级0的信息ucore中专
2022-01-26 16:02:44
724
原创 ucore lab4学习笔记整理
在lab4中接触的还是内核线程,内核线程只运行在内核态。在线性空间中,0-3G是用户空间,而3-4G是内核空间,所有的内核线程都是只用同一块内存,因此不需要为每个内核线程维护单独的内存空间,不像用户进程每个进程都拥有各自的页表,内核进程共享一个页表。为了实现内核线程,需要设计管理线程的数据结构,进程控制块。每个内核线程对应一个进程控制块,而这些控制块都会通过链表连在一起,方便插入,删除和查找操作进行管理。在本实验中,首先从kern_init函数开始,完成虚拟内存初始化后,调用proc_init函数,
2022-01-24 10:51:19
1021
原创 ucore lab3学习笔记整理
此实验借助页表机制和中断异常处理机制,完成page fault异常处理和fifo页替换算法的实现。ucore建立了mm_struct和vma_struct数据结构,描述了ucore模拟应用程序运行所需的合法内存空间。vma_struct描述的地址范围就是程序的合法虚拟地址范围。struct vma_struct { struct mm_struct *vm_mm;//表示该vma隶属于的mm,每个mm中的所有vma均属于同一页目录表的虚拟内存空间 uintptr_t vm_start;
2022-01-21 16:34:04
2855
原创 ucore lab2学习笔记整理
本次实验主要完成ucore内核对物理内存的管理。ucore被启动后,需要探测系统的物理内存布局来了解哪些物理内存空间是可用的。ucore是使用e820h中断来获取内存信息,而这个中断必须在实模式下使用,因此必须在bootloader引导进入保护模式前进行,这些收集到的数据将保存在物理地址0x8000处,通过代码中定义的e820map结构体进行映射。启动分页机制ucore在80386中的分页机制实现了基本平坦模型的段页式内存管理,这是为后续的虚拟内存做好准备。CR开头的寄存器为控制寄存器。
2022-01-20 11:35:24
2358
原创 ucore lab1学习笔记整理
前置知识ucore是运行在80386这一32位x86架构的CPU,汇编采用的格式是AT&T,lab1ucore开始执行makefile会生成磁盘映像,这个磁盘映像就是对应着现实计算机中的硬盘。这个磁盘映像中的第一个扇区为bootloader,其余部分即为ucore的kernel部分。80386在上电后,一般不会直接执行操作系统,而是会执行系统初始化软件并完成基本的IO初始化和引导加载功能,而我们所常说的BIOS和磁盘的引导扇区上的BootLoader就是系统初始化软件,BIOS是
2022-01-12 18:02:00
1239
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人