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

[操作系统作业]页面置换算法实现(C++)

💓博主csdn个人主页:小小unicorn
⏩专栏分类:linux
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

目录

  • 必做题
    • 代码分析(重点以时间统计)
      • 1. 引入 `<chrono>` 库
      • 2. 开始计时
      • 3. 执行被测代码
      • 4. 结束计时
      • 5. 计算执行时间
      • 6. 对每个算法重复以上步骤
      • 7. 输出结果
      • 总结1
    • 运行结果
    • 结果分析(我们以块数为3为例)
      • 缺页次数比较
      • 2. 执行时间比较
      • 3. 性能评估
      • 4. 总结
  • 选做题
      • 1. 计算页面走向
      • 页面走向
      • 2. 定义内存和算法
      • C++ 实现
      • 代码说明
      • 结果分析

必做题

在一个请求分页系统中,假如一个作业的页面走向为1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6,当分配给该作业的物理块数分别为3和5时,分别采用FIFO/OPT/LRU页面置换算法,计算中访问过程中发生的缺页次数和缺页率。(建议增加必要的算法执行时间统计)

实现算法如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <chrono>using namespace std;class Base
{
public:Base(int m, int n, int* p) :m(m), n(n), p(p), missed(0),field(new int[m] {}),blocks(new int[m]) {for (int j = 0; j < m; ++j)blocks[j] = -1;}int getMissedCount() const { return missed; } // 获取缺页次数protected:int m;int n;int* p; // 页面调用序列int i{}; // 页面调用序列的指针int missed; // 缺页次数int* field; // 访问字段int* blocks; // 物理块void run(); // 运行函数
private:float rateOfMissingPage{}; // 缺页率bool isHit(); // 检查是否命中virtual int blockSelect() = 0; // 换出页面选择函数virtual void printAlgorithmName() const = 0;void pageExchange(int blockInd, int page); // 页面换出函数void updateField(); // 更新访问字段void printBlocks();void printRateOfMissingPage() const;
};void Base::pageExchange(int blockInd, int page)
{blocks[blockInd] = page;
}void Base::printBlocks()
{int t;for (int j = 0; j < m; ++j){t = blocks[j];if (t >= 0) printf("%d ", t);else printf("- ");}
}bool Base::isHit()
{int page = p[i];for (int j = 0; j < m; ++j)if (page == blocks[j]){// 命中则修改访问字段field[j] = 0;return true;}return false;
}void Base::run()
{int blockInd;printAlgorithmName();for (i = 0; i < n; ++i){updateField();// 尚有空闲物理块if (i < m){blocks[i] = p[i];blockInd = i;}else{// 命中if (isHit()){printf("\033[32m%d: ", p[i]);printBlocks();printf("(hit)\033[0m\n");continue;}else{ // 未命中blockInd = blockSelect();pageExchange(blockInd, p[i]);}}printf("\033[31m%d: ", p[i]);printBlocks();printf("(miss)\033[0m\n");++missed;field[blockInd] = 0;}rateOfMissingPage = (float)missed / (float)n;printRateOfMissingPage();
}void Base::printRateOfMissingPage() const
{printf("缺页率为: %.3f\n", rateOfMissingPage);
}void Base::updateField()
{for (int j = 0; j < m; ++j)++field[j];
}class OPT : public Base
{
public:OPT(int m, int n, int* p) : Base(m, n, p) { run(); }private:int blockSelect() override{int j, k;int obj_page;int look_back = 0;for (j = 0; j < m; ++j){for (k = i + 1; k < n; ++k){if (blocks[j] == p[k]){if (k > look_back){obj_page = j;look_back = k;}break;}}if (k == n) {obj_page = j;break;}}return obj_page;}void printAlgorithmName() const override{cout << "OPT: " << endl;}
};class FIFO : public Base
{
public:FIFO(int m, int n, int* p) : Base(m, n, p) { run(); }private:int blockSelect() override{return (missed) % m;}void printAlgorithmName() const override{cout << "FIFO: " << endl;}
};class LRU : public Base
{
public:LRU(int m, int n, int* p) : Base(m, n, p) { run(); }private:int blockSelect() override{int tag = 0;int obj_page;for (int j = 0; j < m; ++j){if (tag < field[j]){tag = field[j];obj_page = j;}}return obj_page;}void printAlgorithmName() const override{cout << "LRU: " << endl;}
};int main()
{int m = 0; // 块数// 分配给该作业的物理块数cout << "请输入分配给该作业的物理块数:" << endl;cin >> m;int n = 0; // 页面访问次数cout << "请输入页面访问次数: ";cin >> n;// 动态分配数组int* P = new int[n];cout << "请输入页面访问序列: ";for (int i = 0; i < n; i++){cin >> P[i];}// 时间统计auto start = chrono::high_resolution_clock::now();OPT opt(m, n, P);auto end = chrono::high_resolution_clock::now();auto durationOpt = chrono::duration_cast<chrono::microseconds>(end - start).count();start = chrono::high_resolution_clock::now();FIFO fifo(m, n, P);end = chrono::high_resolution_clock::now();auto durationFifo = chrono::duration_cast<chrono::microseconds>(end - start).count();start = chrono::high_resolution_clock::now();LRU lru(m, n, P);end = chrono::high_resolution_clock::now();auto durationLru = chrono::duration_cast<chrono::microseconds>(end - start).count();// 打印缺页次数和执行时间cout << "OPT 缺页次数: " << opt.getMissedCount() << ", 执行时间: " << durationOpt << " 微秒" << endl;cout << "FIFO 缺页次数: " << fifo.getMissedCount() << ", 执行时间: " << durationFifo << " 微秒" << endl;cout << "LRU 缺页次数: " << lru.getMissedCount() << ", 执行时间: " << durationLru << " 微秒" << endl;// 释放动态分配的内存delete[] P;return 0;
}

代码分析(重点以时间统计)

我们时间统计的部分主要使用了 C++ 的 <chrono> 库来测量代码块的执行时间。以下是对这部分代码的详细解释:

1. 引入 <chrono>

#include <chrono>

这一行代码引入了 <chrono> 库,它提供了时间处理的功能,包括高精度计时器。

2. 开始计时

auto start = chrono::high_resolution_clock::now();

这行代码使用 chrono::high_resolution_clock::now() 来获取当前时间点,并将其存储在 start 变量中。这个时间点代表了计时的开始。

  • high_resolution_clock 是 C++ 中提供的一个高精度时钟,适合用于测量较短时间的运行。
  • auto 关键字自动推导变量类型,这里 start 将是一个时间点类型。

3. 执行被测代码

OPT opt(m, n, P);

在这行代码中,调用了 OPT 算法的构造函数。这段代码会执行页面置换算法的主要逻辑,并记录缺页次数。

4. 结束计时

auto end = chrono::high_resolution_clock::now();

这行代码获取了当前时间点,存储在 end 变量中,表示计时的结束。

5. 计算执行时间

auto durationOpt = chrono::duration_cast<chrono::microseconds>(end - start).count();

在这一行中,执行了以下操作:

  • end - start 计算了两个时间点之间的时间差,这个结果是一个持续时间对象(duration)。
  • chrono::duration_cast<chrono::microseconds> 将这个持续时间对象转换为微秒(microseconds)单位。你可以选择不同的单位,比如秒(seconds)、毫秒(milliseconds)等,根据需求而定。
  • .count() 方法返回这个时间差的数值,即以微秒为单位的执行时间。

6. 对每个算法重复以上步骤

FIFOLRU 算法同样进行开始计时、执行算法和结束计时的操作,确保每个算法的执行时间都能被准确记录。

7. 输出结果

最后,输出每个算法的缺页次数和执行时间:

cout << "OPT 缺页次数: " << opt.getMissedCount() << ", 执行时间: " << durationOpt << " 微秒" << endl;

这样,我们就能够清晰地看到每个页面置换算法的缺页次数以及它们的执行时间,便于对比和分析不同算法的性能。

总结1

使用 <chrono> 库来进行时间统计能够提供高精度的性能测量,适用于分析程序性能或调试。通过这种方式,你可以识别出性能瓶颈,并作出相应的优化。

运行结果

运行结果如下:

块数为3时:
在这里插入图片描述

块数为5时:
在这里插入图片描述

结果分析(我们以块数为3为例)

缺页次数比较

  • OPT 算法: 缺页次数为 11,是所有算法中最少的。这是因为 OPT 算法使用了未来知识,能够根据未来的页面请求来选择最合适的页面替换,确保在执行过程中尽量减少缺页。
  • FIFO 算法: 缺页次数为 16,表现中等。FIFO 算法简单地按照页面进入的顺序替换页面,虽然实现简单,但在某些情况下可能导致较多的缺页(例如,“Belady’s Anomaly”)。
  • LRU 算法: 缺页次数为 15,略优于 FIFO,但仍明显高于 OPT。LRU 算法通过替换最近最少使用的页面来降低缺页率,通常能有效地减少缺页,但没有利用未来的信息,因此在某些情况下性能不如 OPT。

2. 执行时间比较

  • OPT 算法: 执行时间为 5735 微秒,是最快的。这与缺页次数的结果相符,因为更少的缺页通常意味着更高的执行效率。
  • FIFO 算法: 执行时间为 8051 微秒,相对较慢。虽然 FIFO 算法简单,但由于其简单的替换策略,可能导致更多的缺页,从而增加执行时间。
  • LRU 算法: 执行时间为 19705 微秒,是所有算法中最慢的。LRU 的实现相对复杂,因为需要跟踪每个页面的使用情况,这增加了时间开销,尤其是在页面访问次数较多时。

3. 性能评估

  • OPT 是最优的选择,虽然其实现可能不适合实际应用(因为不能提前知道未来的页面请求)。
  • FIFOLRU 是两种常见的替换算法,FIFO 实现简单,但可能在某些情况下表现不佳,而 LRU 更加复杂,可能在资源利用上更优,但开销更大。

4. 总结

综合缺页次数和执行时间,OPT 算法是最有效的选择,尤其是在缺页次数和执行时间上都表现最佳。FIFO 和 LRU 在执行时间和缺页次数上有差距,具体选择哪种算法还需考虑实际应用场景的需求,比如内存资源的限制、算法的实现复杂度等。

选做题

考虑下面存储访问序列,该程序大小为460字:10,11,104,170,73,309,185,245,246,434,458,364,假设页面大小是100字,请给出该访问序列的页面走向。又假设该程序基本可用内存是200字,采用FIFO置换算法,求出其缺页率。如果采用LRU页面算法,缺页率是多少?如果采用最优淘汰算法,其缺页率又是多少?(建议增加必要的算法执行时间统计)

为了分析这个存储访问序列并计算缺页率,我们可以首先计算出访问序列对应的页面,然后使用 FIFO、LRU 和 OPT 算法来进行页面置换。下面是详细的步骤和 C++ 实现:

1. 计算页面走向

给定的页面大小是 100 字,因此我们可以通过将每个字节地址除以 100 来计算页面编号。

  • 存储访问序列: 10, 11, 104, 170, 73, 309, 185, 245, 246, 434, 458, 364
  • 对应页面编号:
    • 10 / 100 = 0
    • 11 / 100 = 0
    • 104 / 100 = 1
    • 170 / 100 = 1
    • 73 / 100 = 0
    • 309 / 100 = 3
    • 185 / 100 = 1
    • 245 / 100 = 2
    • 246 / 100 = 2
    • 434 / 100 = 4
    • 458 / 100 = 4
    • 364 / 100 = 3

页面走向

根据上述计算,访问的页面序列为:0, 0, 1, 1, 0, 3, 1, 2, 2, 4, 4, 3

2. 定义内存和算法

假设可用内存为 200 字,即可以容纳 2 个页面。我们将实现 FIFO、LRU 和 OPT 三种页面置换算法,计算缺页率,并进行时间统计。

C++ 实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <chrono>
#include <vector>
#include <unordered_map>using namespace std;class PageReplacement 
{
public:PageReplacement(int m, const vector<int>& pages): m(m), pages(pages), missed(0), n(pages.size()) {}virtual void run() = 0;int getMissedCount() const { return missed; }protected:int m; // 可用页面数vector<int> pages; // 页面访问序列int missed; // 缺页次数int n; // 页面序列长度
};class FIFO : public PageReplacement 
{
public:FIFO(int m, const vector<int>& pages) : PageReplacement(m, pages) { run(); }void run() override {vector<int> frame(m, -1);int index = 0;for (int page : pages) {bool hit = false;for (int f : frame) {if (f == page) {hit = true;break;}}if (!hit) {frame[index] = page;index = (index + 1) % m;missed++;}}}
};class LRU : public PageReplacement 
{
public:LRU(int m, const vector<int>& pages) : PageReplacement(m, pages) { run(); }void run() override {vector<int> frame(m, -1);unordered_map<int, int> pageIndex; // 页面到索引的映射int index = 0;for (int page : pages) {bool hit = pageIndex.find(page) != pageIndex.end();if (!hit) {if (index < m) {frame[index] = page;pageIndex[page] = index;index++;}else {// 找到最近最少使用的页面int lruIndex = 0;for (int j = 1; j < m; j++) {if (pageIndex[frame[j]] < pageIndex[frame[lruIndex]]) {lruIndex = j;}}pageIndex.erase(frame[lruIndex]);frame[lruIndex] = page;pageIndex[page] = lruIndex;}missed++;}else {// 更新页面使用时间pageIndex[page] = index++;}}}
};class OPT : public PageReplacement 
{
public:OPT(int m, const vector<int>& pages) : PageReplacement(m, pages) { run(); }void run() override {vector<int> frame(m, -1);int index = 0;for (int page : pages) {bool hit = false;for (int f : frame) {if (f == page) {hit = true;break;}}if (!hit) {if (index < m) {frame[index] = page;index++;}else {// 找到将来最久未使用的页面int farthest = -1;int replaceIndex = -1;for (int j = 0; j < m; j++) {int nextUse = findNextUse(frame[j], index);if (nextUse > farthest) {farthest = nextUse;replaceIndex = j;}}frame[replaceIndex] = page;}missed++;}}}private:int findNextUse(int page, int start) {for (int j = start; j < n; j++) {if (pages[j] == page) return j;}return n; // 表示不再使用}
};int main() 
{// 页面访问序列vector<int> accessSequence = { 10, 11, 104, 170, 73, 309, 185, 245, 246, 434, 458, 364 };vector<int> pages;// 计算页面走向for (int address : accessSequence) {pages.push_back(address / 100); // 根据页面大小计算页面编号}int m = 2; // 可用页面数// FIFO算法auto start = chrono::high_resolution_clock::now();FIFO fifo(m, pages);auto end = chrono::high_resolution_clock::now();auto durationFifo = chrono::duration_cast<chrono::microseconds>(end - start).count();// LRU算法start = chrono::high_resolution_clock::now();LRU lru(m, pages);end = chrono::high_resolution_clock::now();auto durationLru = chrono::duration_cast<chrono::microseconds>(end - start).count();// OPT算法start = chrono::high_resolution_clock::now();OPT opt(m, pages);end = chrono::high_resolution_clock::now();auto durationOpt = chrono::duration_cast<chrono::microseconds>(end - start).count();// 打印结果cout << "FIFO 缺页次数: " << fifo.getMissedCount() << ", 执行时间: " << durationFifo << " 微秒" << endl;cout << "LRU 缺页次数: " << lru.getMissedCount() << ", 执行时间: " << durationLru << " 微秒" << endl;cout << "OPT 缺页次数: " << opt.getMissedCount() << ", 执行时间: " << durationOpt << " 微秒" << endl;return 0;
}

代码说明

  • 页面走向计算: 通过将每个字节地址除以 100 得到页面编号。
  • 页面置换算法: 实现了 FIFO、LRU 和 OPT 三种算法,每个算法在 run 方法中执行页面替换逻辑。
  • 时间统计: 使用 chrono 库来测量每种算法的执行时间。

结果分析

在这里插入图片描述

运行该程序后,会输出每种算法的缺页次数和执行时间。你可以根据缺页次数判断每种算法的性能,通常来说,OPT 算法的缺页次数最少,而 FIFO 和 LRU 可能会有所不同,具体取决于页面访问序列。

相关文章:

[操作系统作业]页面置换算法实现(C++)

&#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;linux &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识 目录 必做题代码分析&#xff08;重点以时间统计…...

前端技术月刊-2024.11

本月技术月刊聚焦于前端技术的最新发展和业务实践。业界资讯部分&#xff0c;React Native 0.76 版本发布&#xff0c;带来全新架构&#xff1b;Deno 2.0 和 Node.js 23 版本更新&#xff0c;推动 JavaScript 生态进步&#xff1b;Flutter 团队规模缩减&#xff0c;引发社区关注…...

搜索引擎语法大全(Google、bing、baidu)

搜索引擎语法大全 搜索引擎语法通常指的是在搜索引擎中使用特定的运算符和语法来优化搜索结果。 提高搜索精度&#xff1a;使用特定的语法可以帮助用户更精确地找到相关信息&#xff0c;避免无关结果。例如&#xff0c;通过使用引号搜索确切短语&#xff0c;可以确保搜索结果包…...

java设计模式之行为型模式(11种)

行为型模式 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象型模式&#xff0c;前者采用继承机制来在类间分派…...

微服务系列一:基础拆分实践

目录 前言 一、认识微服务 1.1 单体架构 VS 微服务架构 1.2 微服务的集大成者&#xff1a;SpringCloud 1.3 微服务拆分原则 1.4 微服务拆分方式 二、微服务拆分入门步骤 &#xff1a;以拆分商品模块为例 三、服务注册订阅与远程调用&#xff1a;以拆分购物车为例 3.1 …...

leetcode 1470.重新排列数组

1.题目要求: 2.题目代码: class Solution { public:vector<int> shuffle(vector<int>& nums, int n) {vector<int> x_array(nums.begin(),nums.begin() n);vector<int> y_array(nums.begin() n,nums.end());int x_index 0;int y_index 0;for…...

windows在两台机器上测试 MySQL 集群实现实时备份

在两台机器上测试 MySQL 集群实现实时备份的基本步骤&#xff1a; 一、环境准备 机器配置 确保两台机器&#xff08;假设为服务器 A 和服务器 B&#xff09;能够互相通信&#xff0c;例如它们在同一个局域网内&#xff0c;并且开放了 MySQL 通信所需的端口&#xff08;默认是 …...

点晴模切ERP系统助力模切企业转型升级之路

随着我国制造业规模不断扩大&#xff0c;中国制造业已经从高速扩张转向深入挖潜的关键阶段。数字化转型不仅有助于提升企业的生产效率和管理水平&#xff0c;还能有效应对市场竞争&#xff0c;实现可持续发展。在数字化转型的过程中&#xff0c;企业资源规划&#xff08;ERP&am…...

redis修改配置文件配置密码开启远程访问后台运行

编辑 Redis 配置文件 编辑 /etc/redis/redis.conf&#xff0c;设置必要的参数。 sudo vim /etc/redis/redis.conf设置后台运行&#xff1a; 找到以下行&#xff0c;将 no 改为 yes&#xff1a; daemonize yes设置密码&#xff1a; 找到以下行&#xff0c;取消注释并设置密码为…...

市场分化!汽车零部件「变天」

全球汽车市场的动荡不安&#xff0c;还在持续。 本周&#xff0c;全球TOP20汽车零部件公司—安波福&#xff08;Aptiv&#xff09;发布2024年第三季度财报显示&#xff0c;三季度公司经调整后确认收入同比下降6%&#xff1b;按照区域市场来看&#xff0c;也几乎是清一色的下滑景…...

SCSS在Vue中的用法

SCSS在Vue中的用法 一、安装相关依赖1、安装sass - loader和node - sass&#xff08;或dart - sass&#xff09; 二、在组件中使用SCSS1、单文件组件&#xff08;.vue&#xff09;中的样式使用2、**全局样式使用SCSS**3、在组件中使用变量和混入&#xff08;Mixins&#xff09;…...

CPU用户时间百分比

在计算机系统中&#xff0c;"CPU用户时间百分比&#xff08;CPU User Time&#xff09;"是一个性能监控指标&#xff0c;它描述了CPU在用户模式下执行的累积时间与总的CPU时间的比例。这个指标可以帮助我们了解系统在执行用户态程序时的负载情况。下面是一些关于CPU用…...

RN中的StyleSheet

一、RN中样式的特点 RN的样式和前端的CSS的样式有一些区别。主要如下&#xff1a; RN中的样式 前端的CSS 继承性 没有继承性 有继承性 命名 fontSize&#xff08;小驼峰命名&#xff09; font-size 尺寸单位 with: 100 With: 100px 特殊的样式名 marginHorizontal…...

Swift 开发教程系列 - 第1章:Swift 简介与开发环境配置

在开始开发 Swift 应用之前&#xff0c;了解 Swift 语言的背景和设置开发环境非常重要。接下来&#xff0c;我们将逐步介绍 Swift 的基本概念&#xff0c;并带你完成开发环境的安装和项目创建。 1.1 Swift 简介 Swift 是由 Apple 开发的一种现代化编程语言&#xff0c;于 201…...

躺平成长-下一个更新的数据(躺平成长数据显示核心)

旭日图&#xff08;Sunburst Chart&#xff09;是一种用于展示具有层次结构数据的可视化图表。 开源竞争&#xff1a; &#xff08;当你无法掌握技术的时候&#xff0c;就开源这个技术&#xff0c;培养出更多的技术依赖&#xff0c;让更多的人帮助你完善你的技术&#xff0c;那…...

你们接口怎么测?有没有完完整整的把一个接口测下来?

面试官在问到这道问题的时候&#xff0c;我们应该这么去回答&#xff0c;根据自己技术掌握的水准进行由浅入深的回答。 基础&#xff1a; 我们接口测试之前&#xff0c;开发都会有一份接口文档给到我们&#xff0c;我们要分析接口中的入参和响应。 针对入参的参数类型和参数…...

Pinia-状态管理

Pinia-状态管理 特点&#xff1a; 1. 轻量和模块化 Pinia 是一个轻量级的状态管理库&#xff0c;支持模块化管理&#xff0c;即可以将应用的状态分成多个 store 以实现更好的组织。使用 Pinia&#xff0c;可以定义多个 store&#xff0c;每个 store 都是一个独立的模块&#x…...

IP系列之bscan讨论

1、做Bcan前首先要确定ip_vender是否已经在phy_level做好了bscan_chian&#xff1f;&#xff1f;&#xff1f; 若已经做好&#xff0c;那么vender会给一个XXX.bsdl文件&#xff0c;结合详细的ip文档指导手册&#xff0c;确定bscan_chain是在内部的tap下挂着&#xff0c;还是单…...

Centos安装配置Jenkins

下载安装 注意&#xff1a;推荐的LTS版本对部分插件不适配&#xff0c;直接用最新的版本&#xff0c;jenkins还需要用到git和maven&#xff0c;服务器上已经安装&#xff0c;可查看参考文档[1]、[2]&#xff0c;本次不再演示 访问开始使用 Jenkins 下载jenkins 上传至服务器…...

创新医疗突破:新型穿刺器显著提高手术安全性与效率

据QYResearch调研团队最新报告“中国穿刺器市场报告2023-2029”显示&#xff0c;预计2029年中国穿刺器市场规模将达到18.5亿美元&#xff0c;未来几年年复合增长率CAGR为18.1%。 如上图表/数据&#xff0c;摘自QYResearch最新报告“中国穿刺器市场研究报告2023-2029. 如上图表/…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...

CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx

“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网&#xff08;IIoT&#xff09;场景中&#xff0c;结合 DDS&#xff08;Data Distribution Service&#xff09; 和 Rx&#xff08;Reactive Extensions&#xff09; 技术&#xff0c;实现 …...