<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[start_fall的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/start_fall</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; start_fall]]></copyright><item><title><![CDATA[文件系统文件管理]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/146130158</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/146130158</guid><author>start_fall</author><pubDate>Sun, 09 Mar 2025 21:15:52 +0800</pubDate><description><![CDATA[OS可以按照扇区为基本单位进行存取，但为了减少IO次数，操作系统也可以基于文件系统按照文件块为基本单位进行存取，8个扇区为一个文件块（4KB，称为LBA逻辑块地址），这样转化后LBA地址即为下标，会进行LBA->CHS地址的转换。从此文件系统不再关心磁头、盘面、磁道，只关心4KB的block[n]数组，对存储设备的管理，在OS层面就变成了对文件块数组的增删查改。文件缓冲区（内核级，OS内部的）存在的意义：系统调用将数据写入缓冲区后函数即可返回，是从内存到内存的，提高了程序的效率。]]></description><category></category></item><item><title><![CDATA[基于RabbitMQ原理的分布式消息队列系统]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/141716796</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/141716796</guid><author>start_fall</author><pubDate>Mon, 02 Sep 2024 15:11:00 +0800</pubDate><description><![CDATA[​RabbitMQ是实现了高级消息队列协议（AMQP）的开源消息代理软件（亦称面向消息的中间件）。异步处理无需即时返回且耗时的操作，提高系统吞吐量。解耦生产者和消费者，提高系统灵活性。实现分布式系统的集成。RabbitMQ实际上是实现了一个基于AMQP的生产者消费者模型。解耦合。并发处理。支持忙闲不均。削谷填峰等。在实际的后端开发中，尤其是分布式系统里，跨主机之间使用生产者消费者模型，也是很普遍的需求。因此我们以AMQP为核心封装一个独立的服务器程序。]]></description><category></category></item><item><title><![CDATA[Linux锁的使用]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/137469699</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/137469699</guid><author>start_fall</author><pubDate>Mon, 08 Apr 2024 19:44:44 +0800</pubDate><description><![CDATA[一个函数在重入的情况下，运行结果不会出现任何不同或者任何问题，则该函数被称为可重入函数，否则，是不可重入函数。多线程会共享例如全局变量等资源，我们把会被多个执行流访问的资源称为临界资源，我们是通过代码访问临界资源的，而我们访问临界资源的那部分代码称为临界区。3.如果将对临界资源的访问加上锁，则这个函数是线程安全的，但如果这个重入函数若锁还未释放则会产生 死锁，因此是不可重入的。答案是会的，当一个线程申请完一个锁，访问完临界资源后，接下来该释放锁了，但是代码却写成了加锁，这就会导致死锁问题。]]></description><category></category></item><item><title><![CDATA[Linux内存管理以及页表如何寻址]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/137396060</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/137396060</guid><author>start_fall</author><pubDate>Sun, 07 Apr 2024 14:29:06 +0800</pubDate><description><![CDATA[如果要扩大文件缓冲区，无非就是在内存中再申请一个数据块，把文件某部分内容加载到这个数据块中，再把数据块添加到文件缓冲区里。由于文件系统IO的基本单位大小是4KB，所以我们的可执行程序被划分为一块一块的4KB大小，分块被加载到内存，所以内存也要划分为一块一块的4KB空间。4GB的内存中有1048576个页框（4GB），OS怎么知道哪个页框已经使用、哪个还没使用、哪个正在刷新、是否需要释放？我们把IO的4KB大小称为page size，把可执行程序的一块4KB称为页帧，把内存中的一块4KB称为页框。]]></description><category></category></item><item><title><![CDATA[Linux线程实现方案]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/137341604</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/137341604</guid><author>start_fall</author><pubDate>Sun, 07 Apr 2024 14:25:30 +0800</pubDate><description><![CDATA[线程并不是越多效率越高，对于计算密集型，假设计算机有两个八核CPU，最好创建16个线程并发执行，如果只有一个单核CPU，一个线程的效率是最高的，因为多个线程还要切换上下文资源，降低效率。所以每个新线程的栈在库中维护，动态库一般被加载到共享区中，当我们创建一个线程时，pthread库在堆中new一段空间，把堆空间的地址写到库里面，在库里面用指针维护它，在线程运行用到的一些栈空间通过这个指针就可以找到了。线程间切换的时候，地址空间和页表这些是不用切换的，只需要切换一些运行中产生的临时数据相关的寄存器。]]></description><category></category></item><item><title><![CDATA[进程地址空间]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136983589</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136983589</guid><author>start_fall</author><pubDate>Mon, 25 Mar 2024 15:50:19 +0800</pubDate><description><![CDATA[当执行代码的时候，读取访问到一个虚拟地址，查页表发现对应的内存和代码都没有，此时OS会暂停访问请求，接着在内存中开辟空间，把可执行程序需要执行的对应虚拟地址的代码加载到内存里，把对应的物理地址填充到页表中，把标志位该为11，最后让暂停的代码继续访问。若子进程先进行修改就把子进程的页表映射关系修改为新的物理地址，此时子进程指向新的空间并修改新空间的数据。哪个进程先改，哪个进程修改页表。，当子进程想要修改共同指向的数据时，OS会现在物理内存中开辟一块空间，并把原来空间的值拷贝一份，这块空间有新的物理地址。]]></description><category></category></item><item><title><![CDATA[命令行参数与环境变量]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136969688</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136969688</guid><author>start_fall</author><pubDate>Sun, 24 Mar 2024 10:39:55 +0800</pubDate><description><![CDATA[实际上，在Linux中大部分的命令是在磁盘当中真正存在的，需要fork创建子进程来执行命令，但还有一种命令，不需要子进程，有bash自己进行执行，这种命令等同于bash内部的一个函数，这种命令我们称之为内建命令。执行shell自带的指令时，会有一个默认搜索路径，称为环境变量PATH，在这里可以找到指令。export命令也是内建命令，因为export不能创建子进程，如果创建子进程会导致把环境变量导入到子进程的环境变量中。系统中会存在大量的环境变量，每一个环境变量都有它自己的特殊用途，用来完成特定的系统功能。]]></description><category></category></item><item><title><![CDATA[进程O(1)调度算法]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136964249</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136964249</guid><author>start_fall</author><pubDate>Sat, 23 Mar 2024 14:31:20 +0800</pubDate><description><![CDATA[一共140个优先级，一共140个进程队列，为了提高查找非空队列的效率，就可以用5*32个 比特位表示队列是否为空，这样，便可以大大提高查找效率。图中框起来的queue[140]代表着140个进程队列，其中下标为[0,99]为实时进程队列，[100,139]为普通进程队列。实时优先级，在运行队列中加入一个进程，这个进程必须一直运行到结束，一次调度运行完毕，适合需要快速响应的场景。3.当活动队列的进程时间片跑完后，与过期队列交换内容，获得一批新的活动进程。2.过期队列上放置的进程，都是时间片耗尽的进程。]]></description><category></category></item><item><title><![CDATA[Linux进程优先级]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136958212</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136958212</guid><author>start_fall</author><pubDate>Sat, 23 Mar 2024 09:38:57 +0800</pubDate><description><![CDATA[进程排队的本质就是确定优先级优先级是什么？得到某种资源的先后顺序。为什么要有优先级这个概念？本质上是因为资源不足。ps -l查看进程更详细的属性。Linux支持动态优先级调整，但不能直接修改PRI，要修改NI（nice值）间接修改PRI。]]></description><category></category></item><item><title><![CDATA[Linux进程的状态]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136949736</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136949736</guid><author>start_fall</author><pubDate>Fri, 22 Mar 2024 22:17:19 +0800</pubDate><description><![CDATA[进程状态在PCB里面也就是一个整型变量，int status。状态变化本质上是：（1）修改pcb中status的值（2）将pcb链入不同的队列中。]]></description><category></category></item><item><title><![CDATA[Linux进程简单介绍]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/136783050</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/136783050</guid><author>start_fall</author><pubDate>Fri, 22 Mar 2024 09:07:48 +0800</pubDate><description><![CDATA[我们可以同时启动多个进程，所以内存中一定会加载多个程序，有多个程序，操作系统就要把它们管理起来。首先要有一个struct结构体，里面要存储进程的属性等（这就是描述），再通过链表将多个PCB组织管理起来（这是组织）。如果某个进程想退出，操作系统可以通过PCB找到可执行程序的代码和数据并释放掉，再把进程的PCB从链表中删掉，操作系统就不再管理这个进程了。CPU在执行进程时，并不直接访问可执行程序，而是找到对应进程的PCB，根据PCB找到可执行程序的代码和数据，交给CPU。进程是运行起来的程序？]]></description><category></category></item><item><title><![CDATA[排序总结样例]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135431987</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135431987</guid><author>start_fall</author><pubDate>Sat, 06 Jan 2024 21:07:42 +0800</pubDate><description><![CDATA[一般的快排遇到大量重复元素会有所下降，若全部为同一个数，时间复杂度为O(N^2)，使用三路归并进行优化，则可以很好解决这种问题，若所有元素相同，时间复杂度为O(N^2)。再取nums中随机一个数作为key，可以使排序时间复杂度更接近O(NlogN)]]></description><category></category></item><item><title><![CDATA[通过指针修改const常量问题]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135421826</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135421826</guid><author>start_fall</author><pubDate>Sat, 06 Jan 2024 09:34:26 +0800</pubDate><description><![CDATA[由于a被const修饰，则a已经是一个常量了，编译器在编译代码时，当遇到获取常量中的内容时，会直接使用常量中的内容替换该常量。a是常量，自己不能修改自己，但可以通过指针对a所在的空间进行修改，a的空间中存储的值也确实被改为了20。所以输出时，a已经被早先的10替换了，最终输出a = 10,*p = 20。程序运行结果为a = 10,*p = 20。]]></description><category></category></item><item><title><![CDATA[在Windows 32位操作系统中，假设字节对齐为4，对于一个空的类A，sizeof(A)的值为（）？]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135421614</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135421614</guid><author>start_fall</author><pubDate>Sat, 06 Jan 2024 08:58:09 +0800</pubDate><description><![CDATA[在Windows 32位操作系统中，假设字节对齐为4，对于一个空的类A，sizeof(A)的值为（）？三者会落在同一地址处，导致无法区分a123。假设空类大小为0，有a1，a2，a3。在主流编译器中空类大小设置为1。]]></description><category></category></item><item><title><![CDATA[在C++中，为了让某个类只能通过new来创建（即如果直接创建对象，编译器将报错），应该（）]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135406447</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135406447</guid><author>start_fall</author><pubDate>Fri, 05 Jan 2024 12:19:50 +0800</pubDate><description><![CDATA[B、将析构函数设为私有，直接创建对象会报错，因为最终程序结束前要调用析构函数释放对象。而通过new来创建对象不会报错，虽然析构函数是私有的，但实际对象是存储在类指针类型中的，程序结束时销毁指针的空间不会调用类的析构函数，自然不会报错。在C++中，为了让某个类只能通过new来创建（即如果直接创建对象，编译器将报错），应该（） A. 将构造函数设为私有。A、若将构造函数设为私有，则直接创建对象与通过new来创建都不可行，两者都要调用构造函数。C. 将构造函数和析构函数均设为私有。B. 将析构函数设为私有。]]></description><category></category></item><item><title><![CDATA[类中static成员相关问题]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135405889</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135405889</guid><author>start_fall</author><pubDate>Fri, 05 Jan 2024 11:54:35 +0800</pubDate><description><![CDATA[2.不能在类内初始化（类内只是声明），只能在类外初始化（类外进行定义，初始化时省略static关键字， 通过类型 类名。4.静态成员同样受private，public，protected访问限定符的限制。1.静态成员为所有对象所共享，不独属于某个具体对象，存放在静态区。如果在静态成员前加const进行修饰，则可以在类内进行初始化。5.静态成员函数没有this指针不能访问任何非静态成员。]]></description><category></category></item><item><title><![CDATA[指针类型数据在构造函数中的初始化问题]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/135402005</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/135402005</guid><author>start_fall</author><pubDate>Fri, 05 Jan 2024 09:49:30 +0800</pubDate><description><![CDATA[构造函数中，在没有指定值的情况下，指针要手动初始化为nullptr，否则指针的值不为空


]]></description><category></category></item><item><title><![CDATA[C++中的static静态成员]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/132039523</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/132039523</guid><author>start_fall</author><pubDate>Tue, 01 Aug 2023 12:34:10 +0800</pubDate><description><![CDATA[2.静态成员函数不能访问或调用任何非静态成员和非静态成员函数，因为静态成员函数没有隐含的this指针。4.静态成员也是类的成员，同样受private，public，protected访问限定符的限制。1.静态成员不属于某个具体的对象，一个类的所有对象共同使用一个静态成员，静态成员存放在静态区。2.静态成员变量必须在类外定义，定义时不再加static，类中的只是声明。类中用static声明的成员为类的静态成员，静态成员在类外进行初始化。5.非静态成员函数可以调用类的静态成员函数。]]></description><category></category></item><item><title><![CDATA[赋值运算符重载详解及注意事项]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/132010172</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/132010172</guid><author>start_fall</author><pubDate>Sun, 30 Jul 2023 19:08:46 +0800</pubDate><description><![CDATA[编译器默认生成的赋值运算符重载已经可以解决问题了，为什么还要自定义呢？因为没有显示赋值运算符重载的话，编译器会生成默认赋值运算符重载，此时再定义一个全局赋值运算符重载会冲突。1.2 返回值类型：T&，返回引用可以提高返回的效率，有返回值目的是为了支持连续赋值。自定义实现赋值运算符重载进行深拷贝以解决两个_array指向同一块空间的问题。如果类中未涉及到资源管理，赋值运算符是否实现都可以；内置类型是直接赋值的，自定义类型需要调用对应的赋值运算符重载完成赋值。1.4 返回*this ：要复合连续赋值的含义。]]></description><category></category></item><item><title><![CDATA[拷贝构造函数详解及存在的一些问题]]></title><link>https://blog.youkuaiyun.com/start_fall/article/details/132006713</link><guid>https://blog.youkuaiyun.com/start_fall/article/details/132006713</guid><author>start_fall</author><pubDate>Sun, 30 Jul 2023 15:41:17 +0800</pubDate><description><![CDATA[d1传值给date′时，date′又要调动拷贝构造获得d1的值，此时date′调用拷贝构造，d1传值给date′′。d1传值给形参date时，date要调动拷贝构造获得d1的值，此时date调用拷贝构造，d1传值给date′。1. 拷贝构造函数的参数只有一个且必须是类类型对象的引用，使用传值方式编译器直接报错，在编译器生成的默认拷贝构造函数中，内置类型是按照字节方式直接拷贝的，而自定。字节序完成拷贝，这种拷贝叫做浅拷贝，或者值拷贝。时，则拷贝构造函数是一定要写的，否则就是浅拷贝。]]></description><category></category></item></channel></rss>