- 博客(57)
- 收藏
- 关注
原创 设计模式——工厂方法模式
假如有一个抽象的产品类,然后有很多具体的产品类,一个具体的工厂类根据传入的参数决定生产哪种产品。工程方法模式很好理解,就是在简单工厂模式上面加了一层抽象,然后把针对具体产品的生成交给不同的工厂去做,客户端通过调用不同的工厂类方法生产不同的产品。工厂模式将创建对象的工作交给了工厂的子类(延迟创建对象),自己只提供需要子类实现的方法。上述模式缺点是如果工厂需要管理的产品非常多,那么实现逻辑很复杂且每次增加新的产品要修改原有的工厂类。于是就有了工厂模式,核心是添加一层抽象工厂类,实现间接引用,符合开闭原则。
2024-12-22 20:17:02
374
1
原创 设计模式——单例模式
如果你的代码能够访问单例类, 那它就能调用单例类的静态方法。无论何时调用该方法, 它总是会返回相同的对象。变量,使用互斥锁同步阻塞,且无需手动解锁。,即不管后面创建的实例有没有使用,先创建再说,即饿得不行直接干。单例模式是一种创建型模式,一般的设计模式考察的比较常见。上述实例中,使用了多线程去模拟创建单例,其中我们使用了。,如果已经创建,返回已有的实例,即按需分配。有两种创建方式,一种饿汉式,一种懒汉式。而懒汉式则采用了懒加载的思路,只有在。优点:全局控制,节省资源,懒加载。的库函数,该函数接受一个。
2024-11-25 13:11:12
635
原创 设计模式——装饰器模式
举个简单的例子来说,假设你有一个芭比娃娃类,你想要为它穿上不同颜色、款式的衣服,如果每一个颜色/款式都要实现一个子类,就会产生大量的类。事实上,我们可以考虑用装饰模式动态地添加和删除,而而不需要修改芭比娃娃类本身,这样使得代码更加简洁和灵活。
2024-11-23 22:16:33
613
原创 设计模式——观察者模式
观察者模式(发布-订阅)是行为型模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象的状态发生变化的时候,所有依赖于它的观察者都得到通知并被自动更新。我记得软件工程课里面讲了一个软件设计架构——事件总线模式,又叫出版商-订阅制,英文是Publish-Subscribe。本质是引入中间媒介,避免直接调用,增强独立性(公共数据总线)举个🌰,引入一个邮局作为中间商,新的订阅者只需要在邮局注册,由邮局统一转发就可以,不需要出版商直接发货。
2024-11-07 22:45:21
638
原创 设计模式——迭代器模式
迭代器模式是一种行为型设计模式,是一种比较常见的设计模式。我们知道C++的STL中就包含有迭代器(iterator),begin()就是常见的一种。我们都知道不止vectorstring等序列式容器有,mapset类的关联式容器也有,其主要目的是。
2024-11-06 22:14:03
691
原创 设计模式——模板方法模式
在原来的若干类的基础上,抽象出一个模板方法,定义一个模板抽象类,然后具体类继承自模板类,实现了模板类中定义的抽象方法,去完成算法中的特定步骤。是一种行为设计模式, 它在超类(基类)中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。综上所述,模板方法模式适用于程式固化的模块,抽象出一个算法“骨架”这样可以方便统一管理,也支持一定的拓展。,不同的子类的实现方式略有区别,子类1只实现了必要的操作,而子类2还实现了。子类在不改变算法结构的情况下,重新定义算法的某些步骤。
2024-11-05 12:47:44
508
原创 设计模式——备忘录模式
备忘录模式将创建状态快照 (Snapshot) 的工作委派给实际状态的拥有者原发器(Originator) 对象。这样其他对象就不再需要从 “外部” 复制编辑器状态了, 编辑器类拥有其状态的完全访问权, 因此可以自行生成快照。即原发器拥有对备忘录的完全访问权限, 负责人则只能访问元数据。这种限制策略允许你将备忘录保存在通常被称为_负责人_ (Caretakers) 的对象中。由于负责人仅通过受限接口与备忘录互动, 故其无法修改存储在备忘录内部的状态。
2024-11-04 00:06:54
636
1
原创 设计模式——适配器模式
如图所示,适配器类的主要目的就是将被适配类的对象就行转换,这里是做了最简单的反转操作,然后返回给客户端。否则适配器就只能继承目标类,然后在其中定义一个被适配者实例,再调用其方法。现在的大部分手机都是typec接口,但是依然有很多用户的安卓手机是旧的USB接口,想要匹配用户的需求就需要一个转接头(适配器),然后才能更好的匹配用户的需求。使用适配器模式可以将客户端代码与具体的类解耦,客户端不需要知道被适配者的细节,客户端代码也不需要修改,这使得他具有良好的拓展性,但是这也势必导致系统的复杂性。
2024-11-02 12:02:01
785
原创 C++11新特性的博客汇总
C++ delete与override。引用折叠、万能引用和完美转发那些事。C++中的move和forward。C++chrono时间库。
2024-10-28 11:16:32
104
原创 如何解决路由器的信号覆盖不全的问题
总的来说,选择哪种方法取决于家庭的具体需求和预算。路由中继功能适合那些预算有限且面积不是太大的家庭,而Mesh网络则更适合需要覆盖更大空间或追求无缝网络体验的用户。对于前期家庭装修的情况,可以优先考虑Mesh组网,而后期居住可以优先考虑路由中继。通过适当的技术选择和专业配置,其实任何家庭都可以实现全面且稳定的WiFi覆盖。
2024-09-15 09:45:39
1216
1
原创 YOLT论文精读
文章摘要写的很简洁:先说明了当时研究大尺度卫星遥感图像的一些问题和挑战。每一张图像拥有巨大的像素信息,且涵盖了广袤的地理尺度实际上我们感兴趣的目标非常小,以致于英语中使用tiny形容文章说在超过64km2的地理范围,超过2.5亿像素中识别大约10像素的物体。举个现实🌰,在整个天安门广场(44km2)要找到一个足球,听起来确实有点抽象。上述的挑战注定了使用传统的计算机视觉方案不能很好地应用其中。然后,作者给出了自己的pipeline——YOLT(You Only Look Twice)。
2024-08-13 22:27:44
893
4
原创 OS复习笔记ch12-2
一般来说,像hello.c这种小文件是direct访问(无需建立索引),而single indirect是一级索引,往往存放的是音频文件,double indirect是二级索引,往往是视频文件。索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块(类似于内存管理中的页表→建立逻辑页面到物理页之间的映射关系)。图中的左部是文件描述符表,对应上述进程文件表,中部文件表对应全局文件表。inode表也是一个全局的数据结构,它存储了文件的元数据。
2024-06-23 17:02:24
971
1
原创 OS复习笔记ch12-1
文件是大多数应用程序的核心要素,文件系统是操作系统对用户来说最重要的部分之一。本章的主要内容见下图:文件,大家耳熟能详的就是的docx、pdf、jpg、MP4等各种后缀文件,根据任务需要文件又分成了文本、图片、表格、视频等类型。那么文件该如何定义呢?说白了,文件就是一组有意义的信息集合。我们新建一个文件,核心目的就是为了存储一些有用的信息,比如各种申请表、证件照、产品说明等等,一般不会无故创建文件。文件自身有很多的属性,比如文件名、标识符、类型、位置(路径)、大小、保护信息等。
2024-06-23 15:17:41
1111
原创 OS复习笔记ch11-4
另一个是在扫描期间,新出现的所有请求I/O磁盘的进程进入等待处理的请求队列中,将所有新的请求会推迟到下一次扫描时处理。RAID( Redundant Array of Independent Disks )即独立磁盘冗余阵列,简称为「磁盘阵列」,其实就是用多个独立的磁盘组成在一起形成一个大的磁盘系统,从而实现比单块磁盘更好的存储性能和更高的可靠性。对于即将掉头的扫描点附近的磁道会有偏向或者是不公平:对扫描前进方向上刚刚出现的进程有偏向,而对于刚刚扫描过的磁道的进程请求,进程需要等待很久才会被响应。
2024-06-21 22:45:46
726
原创 OS复习笔记ch11-2
上一节我们学习的内容是I/O系统的特点和设备分类和差异,这一节我们将主要关注I/O控制方式、OS设计问题、I/O逻辑结构等。
2024-06-19 13:29:41
403
原创 OS复习笔记ch11-1
从CPU的角度来看,外设有几个比较重要的I/O接口(interfaces)在设备的视角上(internals)来看,自身有微处理器、内存、特定的硬件芯片。e.g.,磁盘阵列有磁盘自身的处理器来管理。代码部分是轮询的过程,属于程序查询的外设交互。
2024-06-17 11:01:36
461
原创 OS复习笔记ch9-1
主要类型长程调度:决定将哪个进程放入进程池中中程调度:决定将哪些进程部分或者全部放入内存中短程调度:决定哪个空闲进程上处理机I/O调度:决定哪个进程的I/O请求被可用的I/O设备处理处理器调度和进程状态变化调度的主要目的是不断安排进程在处理器上执行层次越往下发生的频率越高(一般时间片在几十到上百ms,短程调度会非常频繁)了解一些短程调度的条件:当发生可能导致当前进程阻塞或可能提供机会抢占当前正在运行的进程以支持另一个进程的事件时调用。
2024-06-15 22:02:56
1038
1
原创 OS复习笔记ch8-3
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。当系统缺少足够的对换区空间的时候就需要从文件区调入,对于可能被修改的部分,换出时需要写回对换区,然后下次使用从对换区调入。在Unix的OS中,通常进程运行之前数据都是在文件区,而使用过的页面需要换出时就需要写回对换区,下次从对换区调入。如图所示,这里磁盘中有一个连续分配的对换区,类似于Cache的设计理念,读写速度很快,可以高速调入调出页面。驻留集,从某种角度可以看成是进程可以常驻内存的内存块的集合。
2024-06-09 11:27:48
568
原创 OS复习笔记ch7-2
此外,由于每个段都是独立的,一个段中的错误,如数组越界,不会影响到其他段。如图所示,主存中给A、C、D进程分配了页框,其中A是连续的0-3,而C是连续的7-10,D比较特殊是4-6,11-12,空闲13-14。一般来说,我们的页面大小都是2的整数次幂,可以直接通过位运算得到想要的结果。类似进程的管理,我们的程序在逻辑上也可以分开,也就是我们常说的分段管理,比如代码段、数据段等,段式管理中一般段长可变,但是有最大段长。如图所示,每一个段都有对应的长度和基址,对应不同的内存空间,可以发现物理存储是不连续的。
2024-06-05 15:31:13
860
原创 OS复习笔记ch7-1
如图所示,我们此时需要16M的内存,first-fit从上往下找到第一个满足的分区(指向22M的分区),best-fit找到最接近的分区(指向中间18M分区),而next-fit找到上次分配指针之后的第一个满足的分区(指向36M分区)。原因很简单,因为编译的时候我们拿不到实际的绝对地址,只有在实际运行的时候才会有,一般编译是得到机器代码,链接是得到逻辑地址,装入的时候才会确定实际的物理地址。每次从上次放置位置往后扫描第一个满足的内存分区,最大的分区容易被分割,需要压缩来获得新的大分区。
2024-05-28 21:22:37
997
原创 OS复习笔记ch6-2
前面我们提到了死锁的四个必要条件接下来我们讨论一下这四个条件如何预防系统需要动态作出决定:如果当前资源分配请求满足,是否会导致死锁。两种方式:拒绝进程启动:如果进程资源请求可能导致死锁则不启动进程拒绝资源访问:如果本次分配可能导致死锁,则拒绝进程的增量资源请求系统中有n个进程,m种资源保守策略e.g.假设银行有账面200万,有三个客户来贷款,总量分别是100、80、60万。按照保守策略,银行对第一个用户和第二个用户贷款申请可以批准一次付清,但是第三个用户就不能批准了,相当于拒绝了第三个用户的贷款申请(
2024-05-26 15:47:46
908
原创 OS复习笔记ch6-1
一组进程中,其中每个进程因等待事件而阻塞,且所等待的事件只能被这组进程中的另一阻塞进程激发称之为死锁。举例如下四个车辆希望紧迫的希望能很快通过,每辆车需要两个象限的资源,然而四个车都只得到一个象限的资源,每辆车都过不去,此时就会发生阻塞。
2024-05-26 13:28:45
415
原创 OS复习笔记ch8-2
比如,当次数足够多的时候,CLOCK算法和LRU算法的性能相差无几,然而维护LRU算法的开销很大,此时使用CLOCK算法不失为一种好的选择。常见的算法有FIFO、LRU、OPT、Clock四种,王道课上还讲解了一种改进的Clock算法,比较复杂,实际考察不多,这里主要讲解提到的四种,并给出对应的代码实现。实现上,最重要的是对后续队列的审查,这里对于内存中已有页面逐个去找它后续使用的频率,对最远的或者不使用的页面下标进行标记,最后淘汰。与LRU的思路相反,在发生页面置换的时刻,看的是后续访问队列。
2024-05-18 18:29:58
1130
原创 OS复习笔记ch5-5
假设每个执行中的线程在放弃互斥锁之前都能保证不变量成立,即在释放互斥锁之前都能确保账户余额的不变量(balance >= 0)成立。综上所述,若每个执行中的线程在放弃互斥锁之前都能保证不变量成立,即确保操作前的条件正确,那么所有线程皆不会导致竞态条件成立。每个线程在执行提款或存款操作时,都需要先获取互斥锁,然后执行相应的操作,最后释放互斥锁。当一个线程执行管程中的一个子程序时,称为占用(occupy)该管程. 管程的实现确保了在一个时间点,最多只有一个线程占用了该管程。这是管程的互斥锁访问性质,即。
2024-05-18 00:14:37
485
原创 OS复习笔记ch5-4-2
上文根据王道课上给的案例进行的分析,博主自身在理解这里的时候感觉不是很好记忆,自己结合老师上课的讨论摸索了一套方法解决这个问题。(信号量命名和王道不一致)首先是解决读者优先问题,设置一个balance信号量(也有写写、写读互斥的作用),解决读写互斥放一个mutex信号量(读的时候不能写),读读允许同样设置一个count计数,配套设置cmutex解决count计数的原子操作。具体实现思路如下先设置好信号量初值然后对写者进程进行分析writer() {while(1) {P(balance)
2024-05-13 23:01:16
759
1
原创 OS复习笔记ch5-4-1
虽然我们能保证生产的产品放入缓冲区前缓冲区不满,但是不能保证消费者取产品时缓冲区不空,所以只用一个同步信号量是不行的。虽然单缓冲区比较少见,对于绝大多数的题目中缓冲区都能容纳比较多的产品,但是它往往更能暴露问题——缓冲区是有界的,放置产品数有上限。所以,我们必须引入其他信号量,表示缓冲区的大小。既然是要表示缓冲区的大小,那么容易联想到使用同步信号量,初始值赋值为缓冲区的大小。第三个信号量也是同步信号量,表示非空闲缓冲区的数量,也即产品数量,用。第二个信号量是同步信号量,表示空闲缓冲区的数量,用。
2024-05-13 16:13:32
919
原创 OS复习笔记ch5-3
最后,我们根据王道的ppt小结一下:信号量机制解决了两个基本问题:进程互斥和同步。实现进程互斥的关键是找到临界区设置互斥信号量,赋值为1前P后V实现进程同步的关键是找到前后关系设置同步信号量,赋值为0前V后P而基于进程同步,又可以衍生出更加复杂的进程前驱关系。前驱关系本质是多个进程之间的同步,采用函数复用的思想就可解决。
2024-05-09 22:22:58
565
原创 OS复习笔记ch5-2
信号量机制是OS考察的重难点,无论是大题小题都会有所涉及,题目中的信号量一般默认情况指的都是记录型信号量,大家在学习的过程中要多动笔,多思考才能灵活运用。
2024-05-07 19:22:31
945
原创 OS复习笔记ch5-1
第一个进程传入了testval=0,newval=1,他访问的时候bolt指向testval的值,满足if条件,此时更新bolt指向newval,最后返回oldval=0,跳出循环执行临界区代码。不过,这个思路只适用于单处理器,原因是单处理器只允许交替进行,关中即不响应中断,CPU拿不到控制权,进程得不到调度,其他进程无法上处理机,也就不可能访问临界区。试想,如果是一个公司的员工,大家坐在一个办公室,使用同一台打印机和饮水机,资源共享很正常,但是如果大家都想晋升,名额又有限,自然就会出现竞争。
2024-04-29 22:13:36
841
原创 《No Silver Bullet》随笔
当我跟着教程学习,一点点,一步步地根据我的需求进行创造和改进的时候,时间悄然流逝,但乐此不疲。因为在我的印象中,论文往往都是刻板的、严谨的,能做到的形象化阐述主要是一些图表,其次是一些example,但是像本文这种story的感觉还是少的。诚然,我们学习软件工程这门课就是在学习软开的方法论,但是实际开发过程中的义无反顾、不屈不挠的热情是学习不来的。作者结合自己在过去几十年间总结的工程经验,以一种尽可能口语化的方式说明了软件工程的本质,同时也对潜在的“银弹”进行了估计,并提出了一些友好的建议。
2024-04-28 21:46:41
609
原创 OS复习笔记ch4
这个公式表明,当增加更多的处理器时,总体的速度提升受到程序可并行化部分的比例的限制。原因其实很简单,在QQ进程底下,会细分成处理聊天的线程、处理文件的线程、处理视频的线程,它们并发执行,类似于OS的多进程,而这就是我们线程的由来。取ULT和KLT的两者所长,有点像CO里面的组相联映射,既获得了仅有用户级线程的开销,又获得了仅有内核级线程的并发度,中庸之道妙哉妙哉。此外,由于引入了多核,程序可以设计有了更多的可能,比如多线程,多进程,或者像Java这种一个进程多个线程,以及多个并行实例。
2024-04-25 22:53:22
798
原创 OS复习笔记ch3-2
还是以运行QQ为例,当我们在Windows上点击QQ.exe时,OS就会把位于磁盘中的QQ程序加载到内存,然后创建相应的进程实体(PCB+程序段+数据段),然后CPU将exe中的机器指令取出执行,再把执行的中间数据存到数据段(比如用户登录的信息)。现在OS都是多进程的,每一个进程都是有时间片的限制,不可能一直占着CPU运行,每隔一段时间OS就会挑选新进程上处理机(进程切换),此在这个过程中处理机控制权就要由程序转为OS,即发生模式切换(用户→系统)。这里说过了PCB,我们就可以对进程的组成有更完整的认识。
2024-04-22 21:51:25
934
原创 OS复习笔记ch3-1
可并发执行的程序在某个数据集合的一次计算活动,是操作系统进行资源分配和保护的基本单位。从上面的定义可知,进程是OS资源分配和保护的基本单位。它为上层应用服务的时候,是以进程为基本单位的。一个程序往往对应着一个进程。这样自然引入多进程,提高了对硬件资源的利用率,但又带来额外的空间和时间开销,增加了OS 的复杂性。
2024-04-22 11:02:47
628
原创 OS复习笔记ch2
最后,我们来简单的总结一下本章的内容,看到这里的小伙伴可以回顾一下之前说的。操作系统的目标和功能服务、功能、内核操作系统的演变简单批处理系统:监督程序、用户态 、核心态多道批处理系统:多道程序设计技术、吞吐量、周转时间、CPU利用率、作业调度、进程调度分时系统:交互性、分时、时间片、响应时间现代操作系统的特征并发、共享、异步性、虚拟、持久性操作系统提供的用户接口系统调用。
2024-04-20 18:58:43
1105
1
原创 OS复习笔记ch1-3
这里说一下后期的更新情况,预计是两到三天更新一篇,每一篇不会太长,尽量把OS繁杂的知识点梳理出来,但是难免会有一些点不太能展开。出于应试的角度,部分章节的内容会比较简洁,当然感兴趣的小伙伴可以深入,或者给我评论和留言,如果有需要我一定补上。回到我们本章一开始的问题:计算机有哪些基本的组成单元呢?(有种20年后的子弹正中眉心的感觉~~)这三节内容很清楚地讲解了处理器、存储器和I/O模块的功能和作用。其中,ch1-1我们详细介绍了处理器寄存器,指令的执行流程,为后续进程和线程相关知识点铺垫。
2024-04-13 20:19:10
681
原创 OS复习笔记ch1-2
我们都知道CPU是计算机的中央处理单元,几乎所有的运算都会经过CPU,而一般外设作为输入和输出设备,其速度和CPU完全不在一个量级上,那么它们如何和CPU进行交互呢?当前正在运行的低优先级的中断。对比一下我们之前学的轮询的方式,中断是会中止CPU现行程序的运行,也就意味着CPU不会一直等待I/O设备Ready,而会去做其他的事情,如下图所示。以上,可以简单的理解为CPU每次中断都参与太累了,找了一个外包叫做DMA,专门用来处理批量的I/O操作,既提高了I/O效率,又提高了CPU的利用率。
2024-04-10 19:23:07
975
1
原创 OS复习笔记ch1-1
此外,对于OS而言,我们的指令根据权限会分成特权指令和非特权指令,特权指令如启动I/O设备、设置时钟、控制中断屏蔽位、清内存、加载PSW等只能被OS内核执行,非特权指令。至于为啥OS和CO两个划分结果不同,原因在于研究的粒度不同,CO更贴近于底层硬件,所以划分会更细,而OS由于是承上启下的作用,所以更多从软件的角度出发,划分相对粗糙。我们这里的处理器寄存器其实就是上图的金字塔塔尖的regs,也是距离CPU最近的,速度最快的存储器。用户可见的regs,又分为数据寄存器,地址寄存器和条件码寄存器(只读)。
2024-04-07 21:22:56
547
C++课程设计-基于电话和转账的数据分析-QT开发-跨平台
2024-10-30
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人