自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 组成原理备考学习 day2 (2.1)

对应的CRC码:101001 001。

2023-11-11 18:29:01 152

原创 组成原理备考学习 day1 (第一章)

电子管(真空管)时代:第一台电子数字计算机:ENIAC,使用机器语言晶体管时代:第一台使用晶体管线路的计算机:TRADIC;面向过程的程序设计语言:FORTRAN,有了操作系统雏形中小规模集成电路时代:高级语言迅速发展,开始有了分时操作系统大规模、超大规模集成电路时代:产生了微处理器;产生新概念:并行、流水线、高速缓存等机器字长:计算机一次整数运算所处理的二进制位数操作系统位数:其所依赖的指令集的位数。

2023-11-07 11:47:46 165

原创 操作系统备考学习 day12 (第五章)

I/O”就是“输入/输出”I/O设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备。属于计算机中的硬件部件Unix系统将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作理解并记住I/O软件各个层次之间的顺序,要能够推理判断某个处理应该是在哪个层次完成的(最常考的是设备独立性软件、设备驱动程序这两层。直接涉及到硬件具体细节、且与中断无关的操作肯定是在设备驱动程序层完成的;没有涉及硬件的、对各种设备都需要进行的管理工作都是在设备独立性软件层完成的。

2023-11-03 22:20:36 307

原创 操作系统备考学习 day11 (4.1.1~4.1.9)

需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要写入多少数据、指明写入的数据要放在内存中的什么位置。需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要读入多少数据、指明读入的数据要放在内存中的什么位置。当找到文件名对应的目录项时,才需要将索引结点调入内存,索引结点中记录了文件的各种信息,包括文件再外存中的存放位置,根据“存放位置”即可找到文件。索引顺序文件是索引文件和顺序文件思想的结合。

2023-10-30 23:20:26 195

原创 操作系统备考学习 day10 (3.2.1 ~ 3.2.5)

基于局部性原理,在程序装入时,可以将程序中很快会用到的部分装入内存,暂时用不到的部分留在外存,就可以让程序开始执行在程序执行过程中,当所访问的信息不再内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存在操作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存操作系统虚拟性的一个体现,实际的物理内存大小没有变,只是在逻辑上进行了扩充。多次性。

2023-10-20 21:39:35 244

原创 操作系统备考学习 day9 (3.1.1 ~ 3.1.11)

编译、链接后的装入模块的地址都是从0开始,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。缺点:邻近适应算法的规则可能会导致无论低地址、高地址部分的空闲分区都有相同的概率被使用,也就导致了高地址部分的大分区更可能被使用,划分为小分区,最后导致无大分区可用。算法思想:为了解决最佳适应算法的问题–即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用。(因为程序中存在大量的循环)

2023-10-16 20:54:53 207

原创 操作系统备考学习 day8 (2.4.1 ~ 2.4.4)

可以采用静态分配方法,即进程在运行前一次申请完它所需要的全部资源,在它的资源未满足前,不让他投入运行,一旦投入运行后,这些资源就一直归它所有,该进程就不会再请求别的任何资源了。有些资源可能只需要用很短的时间,因此如果进程的整个运行期间都一直保持着所有资源,就会造成严重的资源浪费,资源利用率极低。请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。该策略的缺点:并不是所有的资源都可以改造成可共享使用的资源。

2023-10-11 15:09:12 572

原创 操作系统备考学习 day7 (2.3.4 ~ 2.3.5)

爸爸转向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等着吃盘子中的橘子,女儿专等着吃盘子中的苹果。有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。这些进程之间只存在互斥关系,但是与之前接触到的互斥关系不同的是,每个进程都需要同时持有两个临界资源,因此就有“死锁”问题的隐患。建议:需要注意的是,实现互斥的P操作一定要在实现同步的P操作之后,否则可能引起“死锁”

2023-10-08 21:13:14 175

原创 操作系统备考学习 day6(2.3.2 - 2.3.4)

若刚开始lock是true,则执行TLS后old返回的值为true,while循环条件满足,会一直循环,直到当前访问临界区的进程在退出区进行“解锁”。逻辑上来看Swap和TSL并无太大区别,都是先记录下此时临界区是否已经被上锁(记录在old变量上),再将上锁标记lock设置为true,最后检查old,如果old为false则说明之前没有别的进程对临界区上锁,则可跳出循环,进入临界区。前一个算法的问题是先“检查”后“上锁”,但是这两个操作又无法一气呵成,因此导致了两个进程同时进入临界区的问题。

2023-09-26 12:23:23 129

原创 操作系统备考学习 day5(2.2.5 - 2.3.1)

每当有进程加入就绪队列改变时就需要调度,如果新到达的进程剩余时间比当前运行的进程剩余时间更短,则由新进程抢占处理机,当前运行进程重新回到就绪队列。另外,当一个进程完成时也需要调度。高响应比优先算法:非抢占式的调度算法,只有当前运行的进程主动放弃CPU时(正常/异常完成,或主动阻塞),才需要进行调度,调度时计算所有就绪进程的响应比,选响应比最高的进程上处理机。指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。

2023-09-22 11:35:39 254

原创 操作系统备考学习 day4 (2.1.7 - 2.2.4)

它包括四个部分:作业在外存后备队列上等待作业调度(高级调度)的时间、进程在就绪队列上等待进程调度(低级调度)的时间、进程在CPU上执行的时间、进程等待I/O操作完成的时间。当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的过程,将处理机分配给更重要紧迫的那个进程。即,只允许进程主动放弃处理机。,必然会使整个系统的效率降低,使系统大部分时间都花在了进程切换上,而真正用于执行进程的时间减少。,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间。

2023-09-18 17:22:33 114

原创 操作系统备考学习 day3 (2.1.1 - 2.1.6)

Linux中通过shm_open系统调用,申请一片共享内存区,通过mmap系统调用,将共享内存区映射到进程自己的地址空间,通过“增加页表项/段表项”即可将同一片共享内存区映射到各个进程的地址空间中。引入线程后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务。当进程被创建时,操作系统会为该进程分配一个唯一的、不重复的。缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

2023-09-17 17:46:00 175

原创 操作系统备考学习 day2 (1.3.2 - 1.6)

中断的作用CPU上会运行两种程序,一种是操作系统内核程序,一种是应用程序。在合适的情况下,操作系统内核会把CPU的使用权主动让给应用程序中断是让操作系统内核夺回CPU使用权的唯一途径中断会使CPU由用户态变为内核态,使操作系统重新夺回对CPU的控制权如果没有中断机制,那么一旦应用程序上CPU运行,CPU就会一直运行这个应用程序,就无法实现并发中断的类型若当前执行的指令是非法的,如除法的除数为0,则会引发一个中断信号。

2023-09-03 19:22:21 321

原创 操作系统备考学习 day1 (1.1.1-1.3.1)

操作系统的定义:操作系统(OS)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统软件。操作系统是系统资源的管理者补充知识:执行一个程序前需要将该程序放到内存中,才能被CPU处理封装思想:操作系统吧一些丑陋的硬件功能封装成简单易用的服务,使用户能更方便地使用计算机,用户无需关心底层硬件的原理,只需要对操作系统发出命令即可。向上层提供方便易用的服务联机命令接口= 交互式命令接口 如cmd。

2023-09-01 17:43:02 866

原创 C++linux高并发服务器项目实践 day12

socket是网络环境中进程间通信的API,也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用进程将要传输的一段信息写入它所在主机的socket中,该socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的socket中,使对方能够接收到这段信息。socket是由IP地址和端口结合的,提供向应用层进程传送数据包的机制socket与管道的区别在于,管道只能实现文件间通信,socket可以实现进程间通信。

2023-06-18 14:50:40 735

原创 C++linux高并发服务器项目实践 day11

一旦线程锁定互斥锁,随机称为该互斥锁的所有者,只有所有者才能给互斥锁解锁。不过,这种便捷的共享是有代价的:必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正在由其他线程修改的变量。线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程则处于等待状态。临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,也就是同时访问同一共享资源的其他线程不应中断该片段的执行。信号量的类型 sem_t。

2023-05-13 22:02:38 480 1

原创 C++linux高并发服务器项目实践 day10

在UNIX系统中,用户通过终端登录系统后得到一个shell进程,这个终端称为shell进程的控制终端(Controlling Terminal),进程中,控制终端是保存在PCB中的信息,而fork()会复制PCB中的信息,因此由shell进程启动的其他进程的控制终端也是这个终端。进程组和会话在进程之间形成了一种两级层次关系:进程组是一组相关进程的集合,会话是一组相关进程组的集合。一个进程组拥有一个进程组首进程,该进程是创建该组的进程,其进程ID为该进程组的ID,新进程会继承其父进程所属的进程组ID。

2023-05-12 21:31:55 542

原创 C++linux高并发服务器项目实践 day9

功能:清空信号集中的数据,将信号集中的所有标志位置为0参数:set,传出参数,需要操作的信号集返回值:成功返回0,失败返回-1功能:将信号集中的所有标志位置为1参数:set,传出参数,需要操作的信号集返回值:成功返回0,失败返回-1功能:设置信号集中的某一个信号对应的标志位为1,表示阻塞这个信号参数:set:传出参数,需要操作的信号集signum:需要设置阻塞的那个信号返回值:成功返回0,失败返回-1功能:设置信号集中的某一个信号对应的标志位为0,表示不阻塞这个信号。

2023-05-08 23:13:31 416

原创 C++linux高并发服务器项目实践 day8

信号是Linux进程间通信的最古老的方式之一,是时间发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。虽然我们这里设置的是1秒,但是实际运行起来不止1秒才会终止,这是因为程序虽然设置了1秒结束,但是输出的数据会存储在缓冲区,在缓冲区中会稍慢的输出,所以在我们看来程序运行了不止1秒。在运行的时候,child process会打印2~3次,因为内存中进程是抢时间片运行的,所以在休眠2秒后,肯定会打印2次,概率打印第3次。//每个阶段的时间,间隔时间。

2023-05-07 16:34:39 589

原创 C++linux高并发服务器项目实践 day7

一个为只读而打开一个管道的进程会阻塞,直到另外一个进程为写打开管道一个为只写而打开一个管道的进程会阻塞,直到另外一个进程为读打开管道读管道:管道中有数据,read返回实际读到的字节数管道写端被全部关闭,read返回0(相当于读到文件末尾)管道写端被部分关闭,read阻塞等待写管道:管道读端被全部关闭,进程异常终止(收到一个SIGPIPE信号)管道已经满了,write会阻塞管道没有满,write将数据写入,并返回实际写入的字节数。

2023-04-19 20:41:12 448 1

原创 C++linux高并发服务器项目实践 day6

exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用内部执行一个可执行文件exec函数族的函数执行成功后不会反悔,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样。只有调用失败了,他们才会返回-1,从源程序的调用点接着往下执行前6个都是C库的函数,只有最后一个是Linux的函数前2个是最常用的。

2023-04-17 23:32:12 183

原创 C++linux高并发服务器项目实践 day5

首先,内核会给每个进程分配相等的初始时间片,然后每个进程轮番地执行相应的时间,当所有进程都处于时间片耗尽的状态时,内核会重新为每个进程计算并分配时间片,如此往复。是正在运行的程序的实例。返回值:如果成功,在父进程中返回子进程的PID,在子进程中返回0,如果失败,在父进程中返回-1,子进程不会被创建。默认为on,表示调试当前进程的时候,其他的进程继续运行,如果为off,调试当前进程的时候,其他进程被GDB挂起。系统允许一个进程创建新进程,新进程即为子进程,子进程还可以创建新的子进程,形成进程树结构模型。

2023-04-16 22:21:09 778 1

原创 C++linux高并发服务器项目实践 day4

一个线程或进程没有返回值,正在执行时,能够继续进行的为非阻塞,不能的为阻塞。fd = 3,int fd1 = dup(fd),fd指向的是a.txt,fd1也是指向a.txt。作用:读取目录中的数据,返回一个指针指向dirent类型的结构体,代表下一个目录实体指向dirp。F_DUPFD :复制文件描述符,复制的是第一个参数fd,得到一个新的文件描述符(返回值)作用:打开一个目录流指向目录,并且返回一个指向目录流的指针,流位于目录中的第一个实体。从空闲的文件描述表中找一个最小的,作为新的拷贝的文件描述符。

2023-04-15 22:17:04 821

原创 C++linux高并发服务器项目实践 day3

在vscode中,写入FILE,ctrl加左键可以进入他的定义,发现他的原型是_IO_FILE,再次ctrl加左键,发现该结构体中,有char*类型的各个变量用于读写和缓冲。在fopen打开一个文件时,一个文件描述符被占用,只有将其fclose或以linux内部的close关闭后,这个文件描述符才能再次启用。虽然函数重载是c++的内容,但是上述函数是C语言的,所以两个open其实是采用可变参数的方式实现的。errno:属于Liux系统函数库,库里面的一个全局变量,记录的是最近的错误号。

2023-04-14 22:02:19 382

原创 并非从0开始的c++ day15

public :Maker() {cout

2023-04-13 09:11:35 478

原创 C++linux高并发服务器项目实践 day2

Makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释Makefile文件中指令的命令工具,一般来说,大多数的IDE都有这个命令GDB是由GNU软件系统社区提供的调试工具,同GCC配套组成了一套完整的开发环境,GDB是许多Linux和Unix系统的标准开发环境一般来说,GDB主要帮助你完成下面四个方面的功能启动程序,可以按照自定义的要求随心所欲的运行程序。

2023-04-13 00:01:01 596

原创 并非从0开始的c++ day14

C++的函数在汇编时,会给函数取别名,C语言的不会,这时,如果C++来调用C语言的函数,C++会去找去了别名的函数,但是C语言没有取别名,这时会报错。编译器是通过调用函数时,传入的参数来判断调用重载的哪个函数,我们调用函数时,不需要写返回值,所以返回值不能成为函数重载的条件。上述代码中,值传递是不交换a和b的值,指针传递和引用传递都改变值,但是两者的原理并不一致,参考之前的笔记。函数重载的原理是在汇编时,给各个函数取别名,C语言不能重载的原因就是没有给函数取别名。是:允许函数名相同,这种现象叫函数重载。

2023-04-07 21:46:26 219

原创 并非从0开始的c++ day13

const 有类型,可进行编译器类型安全检查。#define无类型,不可进行类型检查const有作用域,而#define不重视作用域,默认定义处到文件结尾。如果定义在指定作用域下有效的常量,那么#define就不能用。128输入参数为ma时,可以检查数据类型。

2023-04-06 16:23:15 229

原创 并非从0开始的c++ day12

C++语言在c语言的基础上添加了面向对象编程和泛型编程的支持。C++继承了c语言高效,简洁,快速和可移植的传统c语言代表的过程性语言c++在c语言基础上添加的类代表的面向对象语言C++模板支持的泛型编程const用来限制一个变量不允许改变,它将一个对象转换成一个常量Maker() //构造函数 {a = 100;} int a;//数据类型定义变量 //类实例化对象 const Maker ma;

2023-03-30 18:05:49 431

原创 并非从0开始的c++ day11

新建一个.h 和一个.c文件,将同用函数从主文件中,搬到这两个文件中以便后面复用,需要注意的是,回调函数作为用户提供的数据,是不需要将其搬到这两个文件中的。void*数组可以通过[]来访问,void数组不可以。中开辟一块更大的空间复制原本不够装载数据的空间的数据。用两种方法,一种以位置来删除,一种以数组中的值来删除。动态数组的思想是通过在。

2023-03-15 21:24:58 57

原创 C++linux高并发服务器项目实践 day1

实际上,这个宏只是标志着编译器将会吧代码按c还是c++语法来解释如上所述,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则,就是已定义。

2023-03-15 00:03:43 303

原创 并非从0开始的c++ day10

在编译预处理的时候,将程序中在该语句以后出现的所有的num都用100代替。在预编译是将宏名替换成字符串的过程称为“宏展开宏定义,只在宏定义的文件中起作用。宏名一般用大写,以便于变量区别宏定义可以是常数、表达式等宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错宏定义不是c语言,不在行末加分号宏名有效范围为从定义到本源文件结束可以用#undef命令终止宏定义的作用域在宏定义中,可以引用已定义的宏名宏通过使用参数,可以创建外形和作用都与函数类似的类函数宏。

2023-03-14 16:35:46 220

原创 并非从0开始的c++ day9

函数指针 指向函数入口地址的指针函数名 函数的入口地址函数指针写法:返回值类型 +(指针变量名)(形参列表)func();//函数指针 指向函数地址 int * p =(int *) - 775679270;pFunc();//先定义出函数的类型,在通过类型定义函数指针变量 typedef void(FUNC_TYPE)(int , char);//定义出一个函数类型,返回值是void,形参列表(int,char);

2023-02-28 17:05:20 260

原创 并非从0开始的c++ day8

对打开文件进行写入时,若文件缓冲区的空间未被写入的内容填满,这些内容弄不会写到打开的文件中。只有对打开的文件进行关闭操作时,停留在文件缓冲区的内容才能写到改文件中,从而使文件完整。再者一旦关闭了文件,该文件对应的FILE结构将被释放,从而使关闭的文件受到保护,因为这时对该文件的存取操作将不会进行。文件的关闭也意味着释放了该文件的缓冲区。写文件时需要写fclose,因为可能有些数据留在写文件缓冲区,要是直接结束,可能会留这部分数据在里面没写进去,需要我们手动将其输出到文件。

2023-02-27 09:00:53 255

原创 并非从0开始的c++ day7

1int age;} myPerson;//这里的是别名 void test01() {2//第二种定义方式 struct Person2 {int age;//myPerson2是结构体变量 void test02() {3//第三种定义 struct {int age;//匿名的 结构体变量 void test03() {

2023-02-23 13:14:11 64

原创 并非从0开始的c++ day6

/ARRAY_TYPE是一个有5个int元素的数组的类型 ARRAY_TYPE * arrP = & arr;i < 5;i ++) {} }//可以使用,但是比较麻烦 printf("%d\n" , * arrp [ 0 ]);//语法:数组元素类型(*数组指针变量名称)[元素个数] int(* p) [ 5 ] = & arr;i < 5;i ++) {} }三种定义方法,第一种可读性最强。

2023-02-22 17:31:33 298

原创 并非从0开始的c++之旅 day5

如果空闲空间不够用,在内存中直接找一块足够大的空间,将原有空间下的数据拷贝到新空间下,并且释放原有的内存空间,将新空间的首地址返回。realloc机制:首先在原有空间后查看空闲空间,如果空闲空间足够大,直接在原空间后续开辟新空间大小并且使用。问题:指针在指向的内容创建在栈区,函数体运行结束后,栈区的内容会自动释放掉,这时指向的内容将会是乱码。,上述代码中,若加入了const,则p->age将不能修改值,会报错,故注释了。但是,p的值还是原来的值(野指针),p还是指向原来的内存。

2023-02-22 08:41:40 73

原创 并非从0开始的c++之旅 day4

memcpy可以复制a到buf的相应位置,若要访问该位置,需要在解引用p指针的时候,强制类型转换为int*通过指针找到对应的地址,可以直接修改这个地址的内容,而不需要改变指针。3、如果以字符串初始化,那么编译器默认会在字符串尾部添加"\0"即用n级指针形参,去间接修改了n-1级指针(实参)的值。2、字符数组部分初始化,剩余填0,不会出现乱码。在主调函数分配内存,被调函数使用。方法二,利用字符串指针 进行翻转。在被调函数中,分配在堆区内存。方法一,利用下标方式进行翻转。方法二,利用字符串指针。

2023-02-16 18:00:44 328

原创 并非从0开始的c++之旅 day3

但从定义上看,NULL指针并未指向任何东西,因为对一个空指针引用是一个非法的操作,在解引用之前,必须确保他不是一个空指针。函数的调用方法和被调用方对于函数是如何调用的必须有一个明确的约定,只有双方都遵循同样的约定,函数才能够被正确的调用,这样的约定被称为“调用惯例”fastcall 函数本身 前两个参数由寄存器传递,其余参数通过堆栈传递 @+函数名+@+参数的字节数。不能简单的x+y,先计算x和y自己的值,再将他们相加,这样才能严谨地算出想要的结果。宏函数使用场景:将频繁短小的函数,封装为宏函数。

2023-02-14 17:17:13 165

原创 并非从0开始的c++之旅 day2

将p指针类型改为char *型,这时增加p指针的值会使其会一个一个往前走,在输出时,因为我们需要的是4个字节的int类型的内容,故需要做强制类型转换,将其转换为int *类型。p一开始为NULL,参数p的值为传入p的地址,temp为堆区开辟的地址,解参数p后赋值temp,也就是将temp所含的地址赋予p,这样p就能直接指向temp所指向的堆。打印出来的结果为NULL,因为test中的p和函数的参数p属于同级指针,test的p为NULL时,同级指针无法改变他的值,若要改需要更高级的二级指针。

2023-02-14 10:29:53 293

空空如也

空空如也

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

TA关注的人

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