当前位置: 首页 > article >正文

操作系统 3.6-内存换出

换出算法总览

页面置换算法

  1. FIFO(先进先出)

    • 最简单的页面置换算法,淘汰最早进入内存的页面。

    • 优点:实现简单。

    • 缺点:可能会导致Belady异常,即增加内存反而降低性能。如果刚换入的页面马上又要换出,FIFO的性能会很差。

  2. MIN(最小使用时间)

    • 理论上的最优算法,淘汰预计在未来最长时间不会被使用的页面。

    • 优点:理论上最优,可以保证最低的缺页率。

    • 缺点:实现复杂,因为需要预测页面未来的使用情况。

  3. LRU(最近最少使用)

    • 淘汰最长时间未被访问的页面。

    • 优点:性能接近最优,实现相对简单。

    • 缺点:需要跟踪每个页面的使用历史,增加了系统开销。

FIFO

在操作系统中,FIFO(先进先出)页面置换算法是一种常见的页面置换策略

FIFO工作流程

FIFO(先进先出)页面置换算法是一种简单的页面置换策略,它基于这样一个原则:最早进入内存的页面将是最早被替换出去的页面。这种算法易于实现,但可能不是最高效的页面置换策略。下面是FIFO页面置换算法的工作流程:

  1. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit),不需要进行页面置换。

  2. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查是否还有空的页框可用。如果有,将新页面加载到空的页框中。

    • 如果没有空的页框,根据FIFO算法,选择队列中最早进入内存的页面进行替换。

  3. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新队列,将新页面添加到队列的末尾,并移除被替换的页面。

  4. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  5. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

案例分析

根据您提供的幻灯片内容,我们可以看到一个具体的例子,其中分配了3个页框,页面引用序列为 ABCABDADBCBCB

在这个例子中,FIFO算法导致了7次缺页。在这个例子中,如果我们按照FIFO算法来操作,我们会看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 当引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  7. 引用 D 时,需要替换掉最早进入的 A,发生缺页。

  8. 引用 A 时,需要替换掉最早进入的 B,发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,没有发生缺页。

  10. 引用 B 时,需要替换掉最早进入的 C,发生缺页。

  11. 引用 C 时,需要替换掉最早进入的 A,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

在这个过程中,总共发生了7次缺页。

MIN

MIN页面置换算法,也被称为OPT(Optimal,最优)算法,是一种理论上最优的页面置换算法。它选择将来最长时间内不会被使用的页面进行置换。由于MIN算法需要知道未来的页面引用信息,这在实际中是不可能的,因此它通常用于理论分析和比较其他算法的性能。

MIN算法工作流程

  1. 初始化

    • 假设系统有固定数量的页框(page frames),用于存储内存中的页面。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中(即是否在页框中)。

  3. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit),不需要进行页面置换。

  4. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查所有在内存中的页面,确定哪个页面在未来最长时间内不会被引用。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

  6. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  7. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。根据MIN算法,我们可以看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  7. 引用 D 时,需要替换掉将来最长时间内不会被使用的页面。在这个例子中,C 在未来的引用序列中出现的最晚,因此被替换,发生缺页。

  8. 引用 A 时,因为 A 已经在内存中,没有发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,没有发生缺页。

  10. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  11. 引用 C 时,需要替换掉将来最长时间内不会被使用的页面。在这个例子中,A 在未来的引用序列中出现的最晚,因此被替换,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

在这个过程中,总共发生了5次缺页。

LRU

LRU(最近最少使用)页面置换算法是一种非常流行且有效的页面置换策略。它基于这样一个假设:如果一个页面最近被访问过,那么它在未来很可能也会被访问;相反,如果一个页面很长时间没有被访问,那么它在未来被访问的可能性就较小。因此,LRU算法会选择最长时间未被访问的页面进行置换。就是用历史推测未来

LRU算法工作流程

  1. 初始化

    • 假设系统有固定数量的页框(page frames),用于存储内存中的页面。

    • 初始化一个数据结构(如链表或栈),用于跟踪每个页面最后一次被访问的时间。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中(即是否在页框中)。

  3. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit)。更新该页面的最后访问时间。

  4. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查所有在内存中的页面,确定哪个页面最长时间未被访问。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新新页面的最后访问时间。

  6. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  7. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。根据LRU算法,我们可以看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,更新其最后访问时间,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

  7. 引用 D 时,需要替换掉最长时间未被访问的页面。在这个例子中,C 是最长时间未被访问的页面,因此被替换,发生缺页。

  8. 引用 A 时,因为 A 已经在内存中,更新其最后访问时间,没有发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,更新其最后访问时间,没有发生缺页。

  10. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

  11. 引用 C 时,需要替换掉最长时间未被访问的页面。在这个例子中,A 是最长时间未被访问的页面,因此被替换,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

在这个过程中,总共发生了5次缺页。

时间戳实现

图中展示了如何使用时间戳来准确实现LRU(最近最少使用)页面置换算法。这种方法通过为每个页面维护一个时间戳来记录页面最后一次被访问的时间。当需要进行页面置换时,选择具有最小时间戳的页面进行淘汰,即该页面是最近最少使用的。

实现步骤

  1. 初始化

    • 为每个页面分配一个时间戳变量,初始值设为0。

    • 设置一个全局时钟,用于生成时间戳。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

  3. 页面命中

    • 如果页面已经在内存中,更新该页面的时间戳为当前的全局时钟值。

  4. 页面缺失

    • 如果页面不在内存中,需要进行页面置换。

    • 遍历所有在内存中的页面,找到具有最小时间戳的页面,即最长时间未被访问的页面。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新新页面的时间戳为当前的全局时钟值。

  6. 更新全局时钟

    • 每次页面访问后,无论是否发生页面置换,都递增全局时钟值。

  7. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。以下是使用时间戳实现LRU算法的具体步骤:

  1. 开始时,内存为空,时间戳表也为空。

  2. 引用 A 时,将 A 放入第一个页框,时间戳设为1。

  3. 引用 B 时,将 B 放入第二个页框,时间戳设为2。

  4. 引用 C 时,将 C 放入第三个页框,时间戳设为3。

  5. 再次引用 A 时,更新 A 的时间戳为4(页面命中)。

  6. 引用 B 时,更新 B 的时间戳为5(页面命中)。

  7. 引用 D 时,需要进行页面置换。此时,C 的时间戳最小(3),因此选择 C 进行淘汰,将 D 放入第三个页框,时间戳设为6。

  8. 引用 A 时,更新 A 的时间戳为7(页面命中)。

  9. 引用 D 时,更新 D 的时间戳为8(页面命中)。

  10. 引用 B 时,更新 B 的时间戳为9(页面命中)。

  11. 引用 C 时,需要进行页面置换。此时,A 的时间戳最小(4),因此选择 A 进行淘汰,将 C 放入第一个页框,时间戳设为10。

  12. 引用 B 时,更新 B 的时间戳为11(页面命中)。

在这个过程中,总共发生了5次缺页。

难实现!!!

页码栈实现

图中展示了如何使用页码栈来实现LRU(最近最少使用)页面置换算法。这种方法通过维护一个栈(或队列)来跟踪页面的使用顺序。当需要进行页面置换时,选择栈底的页面进行淘汰,即该页面是最近最少使用的。

实现步骤

  1. 初始化

    • 创建一个栈,用于存储当前在内存中的页面。

    • 初始化一个映射(如哈希表),用于快速查找页面在栈中的位置。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

  3. 页面命中

    • 如果页面已经在内存中,将该页面移到栈顶(表示最近被访问过)。

  4. 页面缺失

    • 如果页面不在内存中,需要进行页面置换。

    • 选择栈底的页面进行淘汰(最长时间未被访问的页面)。

  5. 页面置换

    • 将选中的页面从栈中移除,并将新页面加载到栈顶。

  6. 更新映射

    • 更新映射,以反映新页面在栈中的位置。

  7. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。以下是使用页码栈实现LRU算法的具体步骤:

  1. 开始时,栈为空。

  2. 引用 A 时,将 A 压入栈顶。

  3. 引用 B 时,将 B 压入栈顶。

  4. 引用 C 时,将 C 压入栈顶。

  5. 再次引用 A 时,将 A 从栈中移出并重新压入栈顶(页面命中)。

  6. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

  7. 引用 D 时,需要进行页面置换。此时,栈底是 C,因此选择 C 进行淘汰,将 D 压入栈顶。

  8. 引用 A 时,将 A 从栈中移出并重新压入栈顶(页面命中)。

  9. 引用 D 时,将 D 从栈中移出并重新压入栈顶(页面命中)。

  10. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

  11. 引用 C 时,需要进行页面置换。此时,栈底是 A,因此选择 A 进行淘汰,将 C 压入栈顶。

  12. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

在这个过程中,总共发生了5次缺页。

难实现!!!

SCR

图中展示的是Clock算法,也称为Second Chance算法,这是一种近似实现LRU(最近最少使用)页面置换策略的方法。它通过给每个页面添加一个引用位(reference bit)来模拟时间戳,从而实现页面的置换决策。这种方法比维护全局时间戳或页码栈的实现方式要简单,且实现代价较小。

Clock算法实现步骤

  1. 初始化

    • 为每个页框分配一个引用位(通常为一个二进制位),初始值设为0。

    • 创建一个指针(或称为“时钟指针”),用于扫描页框。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

    • 如果页面命中,硬件自动将该页面的引用位设置为1。

  3. 页面缺失

    • 如果页面不在内存中(页面缺失),时钟指针开始扫描页框。

    • 扫描过程中,如果遇到引用位为1的页面,将其引用位清0,并继续扫描下一个页面。

    • 如果遇到引用位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中。

  4. 更新引用位

    • 当新页面加载到页框后,将其引用位设置为1。

  5. 循环扫描

    • 如果在一轮扫描中没有找到引用位为0的页面(即所有页面的引用位都被设置为1),则选择第一个引用位为1的页面进行淘汰,并重新设置其引用位为0。

    • 如果遇到引用位为0的页面,淘汰。

  6. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

图中展示了Clock算法的工作流程,其中每个页框都有一个引用位(R=0或R=1)。以下是具体步骤:

  1. 开始时,所有引用位都设置为0。

  2. 当访问页面时,硬件自动将对应的引用位设置为1。

  3. 当需要置换页面时,时钟指针开始扫描页框。

  4. 在扫描过程中,如果遇到引用位为1的页面,将其引用位清0,并继续扫描

  5. 如果遇到引用位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中,同时将新页面的引用位设置为1。

  6. 如果在一轮扫描中没有找到引用位为0的页面(即所有页面的引用位都被设置为1),则选择第一个引用位为1的页面进行淘汰,并重新设置其引用位为0

Clock算法改造优化

问题描述

  1. 缺页很少时的情况

    • 如果系统中的缺页很少,可能会导致所有页面的引用位(R位)都被设置为1。这种情况下,Clock算法可能会退化为FIFO算法,因为它会不断地扫描直到找到一个可以替换的页面。

  2. 记录太长的历史信息

    • 如果系统中的页面长时间没有被替换,它们的引用位可能会一直保持为1,这会导致算法效率降低,因为它需要扫描更多的页面来找到一个R位为0的页面。

改造建议:

  1. 定时清除R位

    • 为了解决R位长时间为1的问题,可以定时清除所有页面的R位。这样可以确保算法不会记住太长的历史信息,从而避免退化为FIFO算法。

  2. 使用两个扫描指针

    • 引入一个快速移动的扫描指针用于清除R位,一个慢速移动的扫描指针用于选择淘汰页面。这样可以提高清除R位的效率,同时保持选择淘汰页面的准确性。

实现步骤:

  1. 初始化

    • 为每个页框分配一个引用位(R位),初始值设为0。

    • 创建两个扫描指针,一个用于清除R位(快速移动),一个用于选择淘汰页面(慢速移动)。

  2. 页面引用

    • 当程序引用一个页面时,将该页面的R位设置为1。

  3. 页面缺失

    • 如果页面不在内存中,慢速扫描指针开始扫描页框以选择淘汰页面。

    • 如果遇到R位为1的页面,将其R位清0,并继续扫描。

    • 如果遇到R位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中,同时将新页面的R位设置为1。

  4. 清除R位

    • 快速扫描指针周期性地扫描所有页框,将所有页面的R位清0。

  5. 更新扫描指针

    • 每次页面置换后,慢速扫描指针前移一位。

    • 快速扫描指针在清除完所有R位后也前移一位。

  6. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

给进程分配多少页框

分配页框的挑战:

  1. 分配过多

    • 如果给每个进程分配过多的页框,虽然可以减少缺页率,提高内存的高效利用,但这样做会减少系统中可用的页框总数,导致无法同时运行更多的进程。

  2. 分配过少

    • 如果分配的页框太少,每个进程的缺页率会增大,导致更多的页面置换操作,从而增加进程等待调页完成的时间,降低CPU利用率。

颠簸(Thrashing)现象:

  • 定义:颠簸是指系统因为进程的缺页率过高,导致大部分时间都在进行页面置换操作,而实际的CPU利用率却很低的现象。

  • 原因:当系统中进程数量过多时,每个进程分配到的页框数量减少,导致缺页率增加。随着缺页率的增加,进程需要花费更多的时间等待页面置换完成,从而减少了CPU的有效工作时间。

  • 影响:颠簸会导致系统性能急剧下降,因为CPU大部分时间都在处理页面置换,而不是执行用户进程。

图中现象分析:

图中展示了CPU利用率与多道程序程度(即系统中同时运行的进程数量)之间的关系。随着进程数量的增加,CPU利用率先增加后减少,形成一个峰值。这个峰值之后,CPU利用率急剧下降,这就是颠簸现象。

解决策略:

  1. 合理分配页框

    • 需要找到一个平衡点,即合理分配页框数量,使得系统中的进程既能有效利用内存,又不至于因为缺页率过高而导致颠簸。

通过这些策略,可以有效地避免颠簸现象,提高系统的稳定性和性能。

相关文章:

操作系统 3.6-内存换出

换出算法总览 页面置换算法 FIFO(先进先出): 最简单的页面置换算法,淘汰最早进入内存的页面。 优点:实现简单。 缺点:可能会导致Belady异常,即增加内存反而降低性能。如果刚换入的页面马上又要…...

【Amazon EC2】为何基于浏览器的EC2 Instance Connect 客户端连接不上EC2实例

文章目录 前言📖一、报错先知❌二、问题复现😯三、解决办法🎲四、验证结果👍五、参考链接🔗 前言📖 这篇文章将讲述我在 Amazon EC2 上使用 RHEL9 AMI 时无法连接到 EC2 实例时所遇到的麻烦😖 …...

Java并发编程:深入解析原子操作类与CAS原理

一、原子操作类概述 Java并发包(java.util.concurrent.atomic)提供了一系列原子操作类,这些类通过无锁算法实现了线程安全的操作,相比传统的锁机制具有更高的性能。原子类基于CAS(Compare-And-Swap)指令实现,是现代并发编程的重要基础。 原…...

新一代AI低代码MES,助力企业数字化升级

随着DeepSeek低成本AI模型的火热,对于传统的MES而言,在这场AI的盛宴中,该如何去调整产品的定位,让MES更符合工业企业的需求呢? 工业互联网、AI、数字孪生等技术加速与MES融合,实现生产全流程的实时监控与智…...

位运算与实战场景分析-Java代码版

一、为什么每个程序员都要掌握位运算? 在电商秒杀系统中,位运算可以快速判断库存状态;在权限管理系统里,位运算能用极小的空间存储复杂权限配置;在算法竞赛中,位运算更是高频出现的性能优化利器。这项看似…...

面试之《前端信息加密》

前端代码是直接暴漏给用户的,请求的接口也可以通过控制台network看到参数,这是不够安全的,如果遇到坏人想要破坏,可以直接修改参数,或者频繁访问导致系统崩溃,或数据毁坏。 所以信息加密在某些场合就变得非…...

CentOS 系统磁盘扩容并挂载到根目录(/)的详细步骤

在使用 CentOS 系统时,经常会遇到需要扩展磁盘空间的情况。例如,当虚拟机的磁盘空间不足时,可以通过增加磁盘容量并将其挂载到根目录(/)来解决。以下是一个完整的操作流程,详细介绍了如何将新增的 10G 磁盘…...

HTML应用指南:利用GET请求获取全国汉堡王门店位置信息

在当今快节奏的都市生活中,餐饮品牌的门店布局不仅反映了其市场策略,更折射出消费者对便捷、品质和品牌认同的追求。汉堡王(Burger King)作为全球知名的西式快餐品牌之一,在中国市场同样占据重要地位。自进入中国市场以…...

浅入浅出 GRPO in DeepSeekMath

GRPO in DeepSeekMath GRPO 通过在生成组内进行比较来直接评估模型生成的响应,以优化策略模型,而不是训练单独的价值模型,这种方法显著降低了计算成本。GRPO 可以应用于任何可以确定响应正确性的可验证任务。例如,在数学推理中&a…...

计算机网络起源

互联网的起源和发展是一个充满创新、突破和变革的历程,从20世纪60年代到1989年,这段时期为互联网的诞生和普及奠定了坚实的基础。让我们详细回顾这一段激动人心的历史。 计算机的发展与ARPANET的建立(20世纪60年代) 互联网的诞生…...

HTML 嵌入标签对比:小众(<embed>、<object>) 与 <iframe> 的优缺点及使用场景和方式

需求背景 在网页开发中&#xff0c;嵌入外部资源预览&#xff08;如视频、PDF、地图或其他网页&#xff09;是常见的需求。HTML 提供了多种标签来实现这一功能&#xff0c;其中 <embed>、<object> 和 <iframe> 是最常用的三种。本文将对比它们的优缺点&…...

[python] 作用域

Python中查找变量的顺序遵循LEGB规则(Local->Enclosing->Global->Built-in)。Python中的if/elif/else、for/while等代码块不会创建新的作用域&#xff0c;只有def、class、lambda才会改变作用域。这和C中不同&#xff0c;C中在{}代码块中创建的变量离开这个代码块后就…...

AICon 2024年全球人工智能与大模型开发与应用大会(脱敏)PPT汇总(36份).zip

AICon 2024年全球人工智能与大模型开发与应用大会&#xff08;脱敏&#xff09;PPT汇总&#xff08;36份&#xff09;.zip 1、面向开放域的大模型智能体.pdf 2、企业一站式 AI 智能体构建平台演进实践.pdf 3、PPIO 模型平台出海实战&#xff0c;跨地域业务扩展中的技术优化之道…...

51电子表

设计要求&#xff1a; 基本任务&#xff1a; 用单片机和数码管设计可调式电子钟&#xff0c;采用24小时制计时方式&#xff0c;要求能够稳定准确计时&#xff0c;并能调整时间。发光二极管每秒亮灭一次。电子钟显示格式为&#xff1a;时、分、秒各两位&#xff0c;中间有分隔…...

9-函数的定义及用法

一.前言 C 语⾔强调模块化编程&#xff0c;这⾥所说的模块就是函数&#xff0c;即把每⼀个独⽴的功能均抽象为⼀个函数来实现。从⼀定意义上讲&#xff0c;C 语⾔就是由⼀系列函数串组成的。 我们之前把所有代码都写在 main 函数中&#xff0c;这样虽然程序的功能正常实现&…...

高清视频会议系统BeeWorks Meet,支持私有化部署

在数字化办公时代&#xff0c;视频会议已成为企业协作的关键工具。然而&#xff0c;随着信息安全意识的不断提高&#xff0c;传统的公有云视频会议软件已难以满足企业对数据安全和隐私保护的严格要求。BeeWorks Meet凭借其独特的私有化部署模式、强大的功能集成以及对国产化的适…...

用HTML和CSS绘制佩奇:我不是佩奇

在这篇博客中&#xff0c;我将解析一个完全使用HTML和CSS绘制的佩奇(Pig)形象。这个项目展示了CSS的强大能力&#xff0c;仅用样式就能创造出复杂的图形&#xff0c;而不需要任何图片或JavaScript。 项目概述 这个名为"我不是佩奇"的项目是一个纯CSS绘制的卡通猪形象…...

彩讯携Rich AICloud与一体机智算解决方案亮相中国移动云智算大会

2025年4月10日&#xff0c;2025中国移动云智算大会在苏州盛大开幕&#xff0c;本次大会以“由云向智 共绘算网新生态”为主题&#xff0c;与会嘉宾围绕算力展开重点探讨。 大会现场特设区域展出各参会单位的最新算力成果&#xff0c;作为中国移动重要合作伙伴&#xff0c;彩讯…...

BERT - 直接调用transformers.BertModel, BertTokenizerAPI不进行任何微调

本节代码将使用 transformers 库加载预训练的BERT模型和分词器&#xff08;Tokenizer&#xff09;&#xff0c;并处理文本输入。 1. 加载预训练模型和分词器 from transformers import BertTokenizer, BertModelmodel_path "/Users/azen/Desktop/llm/models/bert-base-…...

安卓开发提示Android Gradle plugin错误

The project is using an incompatible version (AGP 8.9.1) of the Android Gradle plugin. Latest supported version is AGP 8.8.0-alpha05 See Android Studio & AGP compatibility options. 改模块级 build.gradle&#xff08;如果有独立配置&#xff09;&#xff1a;…...

声学测温度原理解释

已知声速&#xff0c;就可以得到温度。 不同温度下的胜诉不同。 25度的声速大约346m/s 绝对温度-273度 不同温度下的声速。 FPGA 通过测距雷达测温度&#xff0c;固定测量距离&#xff0c;或者可以测出当前距离。已知距离&#xff0c;然后雷达发出声波到接收到回波的时间&a…...

Cuto壁纸 2.6.9 | 解锁所有高清精选壁纸,无广告干扰

Cuto壁纸 App 提供丰富多样的壁纸选择&#xff0c;涵盖动物、风景、创意及游戏动漫等类型。支持分类查找与下载&#xff0c;用户可轻松将心仪壁纸设为手机背景&#xff0c;并享受软件内置的编辑功能调整尺寸。每天更新&#xff0c;确保用户总能找到新鲜、满意的壁纸。 大小&am…...

C语言 AI 通义灵码 VSCode插件安装与功能详解

在 C 语言开发领域&#xff0c;一款高效的编码助手能够显著提升开发效率和代码质量。 通义灵码&#xff0c;作为阿里云技术团队打造的智能编码助手&#xff0c;凭借其强大的功能&#xff0c;正逐渐成为 C 语言开发者的新宠。 本文将深入探讨通义灵码在 C 语言开发中的应用&am…...

二分查找5:852. 山脉数组的峰顶索引

链接&#xff1a;852. 山脉数组的峰顶索引 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a; 事实证明&#xff0c;二分查找不局限于有序数组&#xff0c;非有序的数组也同样适用 二分查找主要思想在于二段性&#xff0c;即将数组分为两段。本体就可以将数组分为ar…...

1.2 测试设计阶段:打造高质量的测试用例

测试设计阶段&#xff1a;打造高质量的测试用例 摘要 本文详细介绍了软件测试流程中的测试设计阶段&#xff0c;包括测试用例设计、测试数据准备、测试环境搭建和测试方案设计等内容。通过本文&#xff0c;读者可以系统性地了解测试设计的方法和技巧&#xff0c;掌握如何高效…...

【模拟电路】稳压二极管/齐纳二极管

齐纳二极管也被称为稳压二极管,是一种特殊的二极管,其工作原理是利用PN结的反向击穿状态。在齐纳二极管中,当反向电压增加到一定程度,即达到齐纳二极管的击穿电压时,反向电流会急剧增加,但此时齐纳二极管的电压却基本保持不变。这种特性使得齐纳二极管可以作为稳压器或电…...

项目周期过长,如何拆分里程碑

应对项目周期过长&#xff0c;合理拆分里程碑需要做到&#xff1a;明确项目整体目标与阶段目标、合理进行任务细分与分组、设定阶段性里程碑节点、实施有效的进度跟踪与反馈机制、灵活进行里程碑调整。其中&#xff0c;明确项目整体目标与阶段目标尤为关键。这能够帮助团队在长…...

Java基础 - 泛型(常见用法)

文章目录 泛型类泛型方法泛型类派生子类示例 1&#xff1a;子类固定父类泛型类型&#xff08;StringBox 继承自 Box<String>&#xff09;示例 2&#xff1a;子类保留父类泛型类型&#xff08;AdvancedBox<T> 继承自 Box<T>)示例 3&#xff1a;添加子类自己的…...

蓝桥杯刷题总结 + 应赛技巧

当各位小伙伴们看到这篇文章的时候想必蓝桥杯也快开赛了&#xff0c;那么本篇文章博主就来总结一下一些蓝桥杯的应赛技巧&#xff0c;那么依旧先来走个流程 那么接下来我们分成几个板块进行总结 首先是一些基本语法 编程语言的基本语法 首先是数组&#xff0c;在存数据的时候…...

希哈表的学习

#include <stdio.h> #include <stdlib.h> #include "uthash.h"typedef struct {int id; // 学号&#xff0c;作为keychar name[20]; // 姓名&#xff0c;作为valueUT_hash_handle hh; // 必须有这个字段 } Student;Student* studen…...