lru页面置换算法_页面更换算法

2023-10-31

当一个理论过时或者出现悖论时,我们就用一个新的理论来替换它。

当一个页面不再有用时,我们也用一个新的页面进行替换。准确地说,我们不是因为一个页面过时而用一个新的页面来替换,而是因为需要使用新的页面而用一个过时的页面作为替换牺牲品。

页面需要更换

分页系统克服了交换系统的各种缺点:外部碎片、难以增长、程序不能大于物理内存等

在交换系统下,一个程序作为一个整体加载到内存。因此,在运行时,无须再从磁盘上加载任何东西。而在分页系统下,一个程序的所有页面并不一定都在内存中,因此,在执行的过程中就有可能发生页面不在内存的情况。

如果访问的页面不在内存中,则系统将产生缺页中断。缺页中断服务程序将负责把位于磁盘上的数据加载到物理内存来。如果物理内存还有空闲页面,那就直接使用空闲的页面。但如果物理内存已满,则需要挑选某个已经使用过的页面进行替换。

页面更换的目标

因为磁盘访问速度远远慢于内存访问速度,缺页中断的代价是非常大的。因此,挑选哪个页面进行更换换是有要求的。

也就是说,我们需要精心设计一种算法来进行页面的更换。

那么要设计这种算法,首先得知道我们的目的是什么。

是降低随后发生缺页中断的次数或者概率

从哲学的层次上来看,所有的算法都归结为两个大类的一类:

  • 公平算法

  • 非公平算法

公平算法主要包括下面4种:

随机算法

先来先出(FIFO)算法

第二次机会算法

时钟算法

非公平算法则包括如下5种:

最优算法

NRU算法

LRU算法

工作集算法

还有一种混合算法,它既想保持公平,又含有区别对待的考虑:工作集时钟算法。

随机更换算法

在需要替换页面的时候,产生一个随机页面号,而替换与该页面号对应的物理页面。

事实上,随机选页所选出的被替换的页面不太可能是随后相当长时间内不会被访问的页面。也就是说,这种算法难以保证最小化随后的缺页中断次数。事实上,这种算法的效果相当差。

先进先出算法

既然随机算法效果不怎么样,那我们就需要进行改进。先进先出就是我们的第一个改进算法。先进先出的英文缩写是FIFO(First In First Out)。顾名思义,该算法的核心是更换最早进入内存的页面。先进先出是任何人都能想到的办法,因为它是人类的天性。

FIFO的实现机制是使用链表将所有在内存的页面按照进入时间的早晚链接起来,然后每次置换链表头上的页面就行了。新加进来的页面则挂在链表的末端。如图

8cffd694351a432883e236a1ef7edfbc.png

如果下次需要寻找页面来替换,A将成为替换页面。

但这个绝对的公平方式容易降低效率。例如,如果最先加载进来的页面是经常被访问的页面,那么这样做很可能造成常被访问的页面替换到磁盘上,导致很快就需要再次发生缺页中断,从而降低效率。

 第二次机会算法

由于FIFO只考虑进入内存的时间,不关心一个页面被访问的频率,从而有可能造成替换掉一个被经常访问的页面而造成效率低下。

那么我们对FIFO改进的方向就是考虑一个页面是否是经常被访问的因素。

如果每个页面都是最近被访问过,那怎么办呢?

因为我们给一个页面第二次机会时已经将其访问位清零。因此,最多轮转一圈后,碰到最先给予机会的页面,此时其访问位已经是0,因此可将其替换。

时钟算法

第二次机会算法既简单、公平,又容易实现。只不过,每次给予一个页面第二次机会时,将其移到链表末端需要耗费时间。

另外,页面的访问位只在页面替换进行扫描时才可能清零,所以其时间局域性体现得不好,访问位为1的页面可能是很久以前访问的,时间上的分辨粒度太粗,从而影响页面替换的效果。

为了改善这些缺点,人们想出了时钟算法。

在时钟算法里,我们把页面排成一个时钟的形状。该时钟有一个针臂。每次需要更换页面时,我们从针臂所指的页面开始检查。如果当前页面的访问位为0,即从上次检查到这次,该页面没有被访问过,将该页面替换。如果当前页面被访问过,那就将其访问位清零,并顺时针移动指针到下一个页面。我们重复这些步骤直到找到一个访问位为0的页面

指针指向的是页面F。这样第一个被考虑替换的是页面F。如果页面F的访问位为0,F将被替换。如果页面F的访问位为1,则F的访问位清零,指针移到页面G。

6ca521de2551b51eeb66cbebbfdd70e9.png

这个算法和第二次机会算法不是一样的吗?

首先,它们的数据结构不一样。

第二次机会使用的是链表,而这里使用的是索引(整数指针)。

然后,这样其使用的内存空间不一样:第二次机会需要使用额外的内存,而时钟算法可以直接使用页表。使用页表的好处是无需额外的空间。更大的好处是页面的访问位会定期自动清零。这样将使得时钟算法的时间分辨粒度较第二次机会算法高,从而取得更好的页面替换效果。

时钟算法的精髓就是第二次机会算法,其缺点就和第二次机会算法一样

最优更换算法

前面介绍的4种算法均属于“公平算法”。

但是这种公平实现方式,会使效率受到一定影响。

这是因为个体对整个系统的贡献没有被区别对待,造成贡献大的和贡献小的待遇一样,自然就会影响整个系统的效率。

在非公平的算法里面,最理想的页面替换算法是选择一个再也不会被访问的页面进行替换。如果不存在这样的页面,那至少选择一个在随后最长时间内不会被访问的页面进行替换。这样,我们就可以保证在随后发生缺页中断的次数最小或者概率最低,这种替换算法就是最优的替换算法。

那我们怎么知道一个页面随后多长时间不会被访问呢?当然不知道。

既然如此,最优更换算法就是一种无法实际实现的算法。那么我们为什么要介绍最优算法呢?那是为了定义一个标杆,以此来评判其他算法的优劣。例如,张三和李四各设计了一个页面替换算法,如何判断它们谁优谁劣呢?与标杆比较即可。谁的算法与最优算法更接近,谁的算法就好;反之就差。

 NRU算法

选择一个最近没有被访问的页面来替换,但在所有的最近没有使用的页面里,不是按照最先进入来划分,而是按照各个页面的修改位和访问位的组合来进行划分。这种算法称为最近未使用算法(Not Recently Used,NRU)。

做出这种选择是基于程序访问的时空局域性。因为根据时空局域性原理,一个最近没有被访问的页面,在随后的时间里也不太可能被访问,而NRU的实现方式就是利用页面的访问和修改位。

凡是对页面进行读写操作时,访问位设置为1。当进程对页面进行写操作时,修改位设置为1。根据这两个位的状态来对页面进行分类的话,可以分成4种页面类型:1、2、3、4

bfe25cb4b4c96d1ab4831eebcc490390.png

第2种状态就是系统对访问位会定期清零,对修改位却不能清零。访问位定期清零是保证这个访问位不失去意义的手段。如果不定期清零,则一段时间后所有的页面都是被访问的。

因为所谓访问和未访问都需要局限在一段时间内讨论才有意义,如果考虑无限长的时间段,页面都是被访问状态。那我们就无法判断了。

这种分类比较笼统,在同一类页面里,我们没有办法分辨出哪一类被访问时间更最近一些。即在某些情况下,我们替换的可能并不是最近没有使用的页面。换言之,在最差情况下,时间的分辨粒度粗到一个访问位清零的周期。

LRU算法

LRU算法是最近使用最少算法(LeastRecently Used)。我们不仅考虑最近是否用过,还要考虑最近使用的频率。

此处我们使用的哲学理念仍是拿过去的数据来预测将来:如果一个页面被访问的频率低,那么以后很可能也用不到。

使用矩阵实现LRU算法

矩阵法,就是使用一个矩阵来记录页面的使用频率和时间。该矩阵为n×n维,n是相关程序当前驻内存的页面数。在一开始矩阵的初值为0。每次一个页面被访问时,例如第k个虚拟页面被访问时,我们进行如下操作:

1)将第k行的值全部设置为1。

2)将第k列的值全部设置为0。

在每次需要更换一个页面时,选择矩阵里对应行值最小的页面更换即可。此处的行值是指把该行所有的0和1连起来看做一个二进制数时的取值。

使用移位寄存器实现LRU算法

虽然使用矩阵法实现LRU算法已经较链表法和页表法有了很大的改善,但成本仍然较高。虽然实际驻内存的页面数比虚拟页面数要少,但毕竟一个n×n维的矩阵还是相当地占空间。

给每个存放在内存的页面配备一个移位寄存器。该寄存器用来记录该页面被访问频率和最近的属性。所有移位寄存器的初值皆为0。然后在每个规定长度的周期内,将移位寄存器的值往右移动一位,并将对应页面的访问位的值加到该移位寄存器的最左位。

例如,假定某程序有6个页面在内存中,页号分别为0、1、2、3、4、5。其对应的6个移位寄存器初值皆设置为0,如图13-6a所示。

dd3b0c11ce90087eab2ecc47974eb599.png

在第一个规定周期内,页面0、2、4、5的访问位为1,页面1和3的访问位为0。我们将移位寄存器往右移动一位,并将各个页面的访问位加到相应移位寄存器的左面,就得到图13-6b的状态。在第2个规定周期内,页面0、1、4的访问位为1,而2、3、5的访问位为0,我们重复同样的操作获得图13-6c的状态。假如第3个规定周期内页面0、1、3、5的访问位为1,2、4的访问位为0,则获得图13-6d的状态。第4个周期内页面0、4被访问过,其他页面的访问位为0,得到图13-6e的状态,第5个周期内页面1、2被访问过,其他页面的访问位为0,得到图13-6f的状态。

用移位寄存器实现的,造价高。即使是单价降低了,成本仍然很大,因为需要的寄存器数量较大。

工作集算法

LRU算法为什么会成本高呢?

是因为我们想要分辨出不同页面中哪个页面是最近最少使用的。即需要对每个页面保持某种记录,并在每次页面访问发生时或者周期性地对这些记录进行更新,从而造成空间和时间成本居高不下。

在面对这种时间和空间上的双重困难时,也许我们应该反思一下:我们真的需要为每个页面保留每次访问的记录才能找到一个合适的替换页面吗?

答案是否定的。由于不可能精确地确定哪个页面是最近最少使用的,那就干脆不用花费这个力气,只维持少量的信息使得我们选出的替换页面不太可能是马上又会使用的页面即可。这种少量的信息就是工作集信息。

工作集概念来源于程序访问的时空局域性。即在一段时间内,程序访问的页面将局限在一组页面集合上。例如,最近k次访问均发生在某m个页面上,那么m就是参数为k时的工作集。我们用w(k,t)来表示在时间t时k次访问所涉及的页面数量。

显然,随着k的增长,w(k,t)的值也随着增长;但在k增长到某个数值后,w(k,t)的值将增长极其缓慢甚至接近停滞,并维持一段时间的稳定,如图13-7所示。

ca923a9eef911d89a3e9214a2c309d9f.png

如果其在内存的页面数小于工作集,则发生缺页中断的频率将增加,甚至发生内存抖动。

工作集算法的实现如下:

为页表的每个记录增加一项信息用来记录该页面最后一次被访问的时间。这个时间不必是真实时间,只要是按规律递增的一个虚拟时间即可。同时我们设置一个时间值t,如果一个页面的最后一次访问在当前时间减去t之前,则视为在工作集外,否则视为在工作集内。

这样,在每次需要替换页面时,扫描所有的页面记录,并进行如下操作:

1)如果一个页面的访问位是1,则将该页面的最后一次访问时间设为当前时间,并将访问位清零。

2)如果页面的访问位为0,则查看其访问时间是否在当前时间减去t之前。

a)如果在,则该页面将是被替换页面,算法结束。

b)如果不在,记录当前所有被扫描过页面的最后访问时间里面的最小值。扫描下一个页面并重复1、2两个步骤。

该算法如图13-8所示。

b9d1419d9d14b0ff7238d48022fd37fc.png

如果在所有页面扫描后没有找到一个被替换的页面,则所有页面中最后一次访问时间最早的页面将被替换。这也是第b步记录当前最小值的原因。

这里需要注意的是,该算法只扫描页表一次。如果所有页面的访问位都为1的话

那么该算法的t设置为多少呢?或者说我们怎么知道每个进程的工作集有多大呢?工作集有时空局域性,如果时刻都发生变化,那么就没有工作集了。

通过测试,我们可以求出这个临界的次数。在得到这个次数后,就可以将时间t算出来。只有算一下访问这么多次,需要多长时间即可。

工作集时钟算法

由于其数据结构是线性的,造成每次都按同样的顺序进行扫描,这样就对某些页面不太公平。就好像评选优秀学生,如果大家的表现都同样优秀,就按照学号顺序来确定人选的话,那学号靠后的同学总是吃亏。

方法就是将工作集算法与时钟算法结合起来,设计出工作集时钟算法,即使用工作集算法的原理,但是将页面的扫描顺序按照时钟的形式组织起来。这样每次需要替换页面时,从指针指向的页面开始扫描,从而达到更加公平的状态。而且,按时钟组织的页面只是在内存里的页面,在内存外的页面不放在时钟圈里,从而提高实现效率。

页面替换策略

前面的内容讨论了页面替换的各种算法,但是任何算法都可以应用到不同的数据集上。在页面替换算法的考虑中,算法应用的对象可以分为全局和本局两类,从而形成两类替换策略:全局策略和局部策略。

在全局策略下,算法应用的对象是物理内存里面的所有页面,即我们是从所有的页里面按照选定的算法选出替换页面。这个被选出的页面既可以是当前发生缺页中断的进程的页面,也可以是另外一个进程的页面。这种策略可能影响其他进程的内存使用。

在局部策略下,算法应用的对象是当前进程的所有页面,即我们是从当前进程中物理页面按照我们选定的算法选出替换页面。这种策略不会影响其他进程的内存使用。

全局策略的优点是系统的总页面缺失率低,但程序运行不稳定。因为程序无法控制自己的缺页率。

局部替换策略的优点是更加公平,程序运行更加稳定。

  • 固定与可变驻留集

使用何种页面替换策略决定了一个进程在内存所占页面的数量是否固定。

局部策略由于只选择本进程的页面进行替换,所以一个进程所占的物理页面数将保持不变,即进程驻留内存的页面数是固定的。

全局页面替换策略由于动态地改变一个进程所占物理页面数,进程驻留内存的页面数是可变的。从另一方面说,凡是支持固定驻留集的页面替换算法只能使用局部替换策略,凡是支持可变驻留集的页面替换算法只能使用全局页面替换策略。

  • 初始页面数确定

为每个进程分配内存块的算法主要有3种:均分法、比例法、优先权法。

   《操作系统之哲学原理第2版》邹恒明

                             精彩摘抄

                                    ?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

lru页面置换算法_页面更换算法 的相关文章

  • Ruby on Rails - 复选框未保存到数据库?

    我有一个迁移 它使用布尔值并在其视图中生成一个复选框 但是 无论我单击什么 保存到数据库的值都不会受到影响 我的迁移看起来像这样 def self up create table blogposts do t t string title
  • Cassandra 会话与集群 有什么可分享的?

    考虑 Cassandra 的 Session 和 Cluster 类 Java 驱动程序 我想知道有什么区别 在 Hibernate 中 每次都会创建一个会话并共享会话工厂 从许多来源我了解到 它被认为是创建一个会话并在多个线程之间共享它
  • Git - 在特定提交之前压缩历史记录中的所有提交

    我有一个 Mercurial 存储库 正在将其转换为 Git 提交历史记录非常大 我不需要新存储库中的所有提交历史记录 一旦我将提交历史记录转换为 Git 并且在推送到新存储库之前 我想将某个标记之前的所有提交压缩为一个提交 所以 如果我有
  • 如何设置 Swashbuckle 与 Microsoft.AspNetCore.Mvc.Versioning

    我们有asp net core webapi 我们添加了Microsoft AspNetCore Mvc Versioning and Swashbuckle拥有招摇的用户界面 我们将控制器指定为 ApiVersion 1 0 Route
  • 如何制作饼图聚合数据源?

    Using 适用于 ASP NET MVC 的 Kendo UI 完整版 http www kendoui com 版本 2013 3 1119 2013年11月20日 如果我有这段代码 status chart kendoChart da
  • 在 url 中传递百分号 (%) 并使用 php 获取其准确值

    我正在尝试在 url 中传递百分号 例如 B6011000995504101 SB 但当我回声时 它又回来了 011000995504101 SB 我想要与在 URL 中传递的值完全相同的值 我尝试使用 urlencode 函数 但它给了我
  • 如何在不同的目录中执行python脚本?

    Solved对于可能觉得这有帮助的人 请参阅下面我的答案 我有两个脚本 a py 和 b py 在我当前的目录 C Users MyName Desktop MAIN 中 我运行 gt python a py 第一个脚本 a py 在我当前
  • 如何使用 jQuery 和“this”捕获更改的表单元素值

    我有以下代码 每当我的 Web 表单中发生元素更改时 该代码都会起作用 我一直在纠结的是如何捕捉表单字段元素 id name and 改变值当更改事件被触发时 谁能帮我解决这个问题吗 Thanks JavaScript
  • Android Studio 3.0 中的 DexGuard 集成

    我已升级我的 Android 项目以使用最新的 Android Studio 3 0 功能 从那时起 我在每次 Gradle 同步时都会收到以下警告消息 警告 您正在使用的插件之一支持 Java 8 语言 特征 要尝试 Android 插件
  • ES6解构对象赋值函数参数默认值

    您好 我正在查看在传递函数参数时使用对象解构的示例对象解构演示 https developer mozilla org en US docs Web JavaScript Reference Operators Destructuring
  • 在Python中使用os.makedirs创建目录时出现权限问题

    我只是想处理上传的文件并将其写入工作目录中 该目录的名称是系统时间戳 问题是我想以完全权限创建该目录 777 但我不能 使用以下代码创建的目录755权限 def handle uploaded file upfile cTimeStamp
  • 将蒙版图像作为 PNG 文件写入磁盘

    基本上 我从网络服务器下载图像 然后将它们缓存到磁盘上 但在这样做之前 我想屏蔽它们 我正在使用每个人似乎都指出的屏蔽代码 可以在这里找到 http iosdevelopertips com cocoa how to mask an ima
  • Java编程编译jar

    我有一个文本文件中的java源代码 必须在源代码中输入一些自定义的硬编码变量 然后将其转换为 jar 这是可行的 但是当我运行 jar 时 找不到 Main 类 当我用 WinRAR 解压 jar 文件时 我似乎找不到错误 当我通过 cmd
  • Android 中用于过渡的自定义动画对象?

    我想用一些更奇特的东西来覆盖 Android 中的默认活动转换 我想做的事情不能用通常使用的 XML 集来完成 所以我不能使用overridePendingTransition因为它只接受对基于 XML 的动画资源的整数引用 我想做的是创建
  • git jenkins 中未找到存储库

    我正在使用 jenkins 2 64 并安装了最新的插件 我试图在 jenkins 中设置 git 存储库并给出凭据 但给出错误无法连接存储库 状态代码为 128 Cloning repository https github com so
  • XmlDocument Save 使文件保持打开状态

    我有一个简单的 C 函数 可以创建一个基本的 XML 文件并保存 private void CreateXMlFile string Filename string Name string Company XmlDocument doc n
  • 如何使 Django 自定义管理命令参数不再需要?

    我正在尝试在 django 中编写自定义管理命令 如下所示 class Command BaseCommand def add arguments self parser parser add argument delay type int
  • 是什么让 DVCS 中的合并变得如此简单?

    我读于乔尔谈软件 http www joelonsoftware com items 2010 03 17 html 通过分布式版本控制 分布式部分实际上不是 最有趣的部分 有趣的是 这些 系统根据变化来思考 而不是 就版本而言 and a
  • 如何获取通过网络驱动器访问的文件的 UNC 路径?

    我正在 VC 中开发一个应用程序 其中网络驱动器用于访问文件 驱动器由用户手动分配 然后在应用程序中选择驱动器 这会导致驱动器并不总是映射到相同的服务器 我该如何获取此类文件的 UNC 路径 这主要是为了识别目的 这是我用来将普通路径转换为
  • 通过jquery ajax()和serialize()提交html表单

    我想通过 jquery ajax 提交此表单 这是我所做的 但它不起作用 即表单正在提交并刷新页面 但我没有看到响应 即在同一页面上打印数组 HTML

随机推荐

  • PyCharm如何安装torch

    运行Pycharm中的代码时候提示ModuleNotFoundError No module named torch 试了很多种方法都不行 然后进入官网查了下具体的安装方法 附上网址https pytorch org get started
  • Oracle的高可用

    快速浏览了一下Oracle官方的网页以及非官方的ppt 简单了解了一下Oracle提供的高可用方案 主要有三种 1 RAC RAC Real Application Clusters 多个Oracle服务器组成一个共享的Cache 而这些O
  • Python读取cfg文件

    mysql HOST 127 0 0 1 PORT 3306 USER root PWD 123456789 DB employees CHARSET utf8 redis redis配置 暂时写在这里 线下配置 线上一定要从新配置 并且不
  • Android入门教程

    EditText 监听回车 使用EditText时 有时候我们会需要监听输入的回车 以做出一些操作 或者需要把回车变成 搜索 发送 或 完成 等等 EditText 为我们提供了一个属性 imeOptions 用来替换软键盘中 enter
  • 怎样简便的使用vw完成移动端rem适配

    怎样简便的完成移动端rem适配 了解一些必要的单位 px 像素 进行页面开发的基础单位 em 相对单位 rem 相对单位 vw 相对宽度 vh 相对高度 如何进行简单的px rem转换 了解一些必要的单位 px 像素 进行页面开发的基础单位
  • 数据库第十五课-------------非关系型数据库----------Redis

    作者前言 作者介绍 作者id 老秦包你会 简单介绍 喜欢学习C语言和python等编程语言 是一位爱分享的博主 有兴趣的小可爱可以来互讨 个人主页 小小页面 gitee页面 秦大大 一个爱分享的小博主 欢迎小可爱们前来借鉴 Redis的简单
  • 通信工程专业论文毕设选题推荐

    文章目录 1前言 2 如何选题 2 1 移动通信方向 2 2 嵌入式开发方向 2 3 人工智能方向 2 4 物联网方向 2 5 算法研究方向 2 6 移动应用开发方向 2 7 网络通信方向 2 8 学长作品展示 4 最后 1前言 近期不少学
  • html视频自动播放

    音频
  • Java如何让CPU利用率达到100%

    一 背景 记得有一次去面试Java软件开发工程师 面试官问了我一个关于Java如何让CPU利用率到达百分百的问题 我当时下意识的回答到让程序死循环就可以了 这源于我之前的工作中有一次无意间写了死循环 当时电脑卡的简直不能动 我都关机了 可是
  • C/C++编程:模板参数

    现在存在3种模板参数 类型参数 非类型参数 模板的模板参数 C 设计模板参数的用意在于 尽量将编译可知的因素提取处理 从而进一步抽象代码 无论时代码中的类型 变量地址还是函数地址 只要编译时可知 C 语言就为其一视同仁的提供模板参数支持 以
  • el-dialog 内容居中

    原样 dialog 内容部分 默认左对齐 目的 内容居中显示 比如表单 修改 el dialog el dialog body display flex justify content center align items center
  • 微信 获取signature签名

    本文是使用java语言调用微信提供的接口 获取签名的详细过程 大致步骤如下 在官网生成appId 与 appSecret 然后通过appId 与 appSecret调用接口获取到Access token 通过Access token调用微信
  • SAP 谈谈成本中心和内部订单

    内部订单 内部订单用于计划 收集 监视和结算在公司内部进行的特定操作或任务 内部订单可用于不同的目的 这种功能分类反映在不同的订单类型中 其属性定义了在系统中处理订单的方式 SAP系统内内部定单分为两类 实际定单 和 统计性定单 统计性定单
  • 【千律】C++基础:文件的删除、复制、移动和重命名

    include
  • Qt--在.pro文件中添加链接库的写法

    要在Qt中使用OpenCV 按照OpenCV与Qt的环境搭建及Demo中的步骤配置了Qt Creator的编译选项 选择MSVC 再修改 pro文件 INCLUDEPATH D Program Files opencv opencv3 4
  • automake 生成的Makefile之 install过程

    automake生成的Makefile当你执行make install 的时候我们知道会找install规则 那么具体是怎么安装的呢 看下面 install install recursive 很显然 install recursive是依
  • SYNPROXY抵御DDoS攻击的原理和优化

    序 又到了周末 我又要必须写点什么了 周末依然加班 感谢周末上班平日休息的老婆分担了几乎所有家务 一切依然 然而这些对我来讲都不是个事儿 事实上我是希望取消一切节假日和周末的 所谓的周末和节假日是我一直以来觉得出自 圣经 里面最荒唐的东西
  • 一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?

    include
  • Creator实战项目【保卫萝卜】-- 格子地图

    import ScriptBase from ScriptBase const ccclass property cc decorator ccclass export default class TiledMapCtrl extends
  • lru页面置换算法_页面更换算法

    当一个理论过时或者出现悖论时 我们就用一个新的理论来替换它 当一个页面不再有用时 我们也用一个新的页面进行替换 准确地说 我们不是因为一个页面过时而用一个新的页面来替换 而是因为需要使用新的页面而用一个过时的页面作为替换牺牲品 页面需要更换