FIFO和LRU算法实现操作系统中主存管理

news2024/11/22 22:19:41

FIFO,用数组实现

1和2都是使用nextReplace实现新页面位置的更新

1、不精确时间:用ctime输出运行时间都是0.00秒

#include <iostream>
#include <iomanip>
#include<ctime>//用于计算时间
using namespace std;

// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

// FIFO算法
void fifo(int n) {
    int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空
    int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空
    bool status[20];                         // 记录是否缺页

    int pageFaults = 0;                      // 缺页次数
    int nextReplace = 0;                     // 记录下一个要替换的位置

    // 获取开始时间(时钟周期数)
    clock_t start = clock();

    // 遍历每个页面访问
    for (int j = 0; j < 20; j++) {
        int page = pages[j];
        bool found = false;

        // 检查页面是否已在内存中
        for (int i = 0; i < n; i++) {
            if (memory[i] == page) {
                found = true;
                break;
            }
        }

        if (!found) {  // 缺页情况
            memory[nextReplace] = page;       // 替换页面
            nextReplace = (nextReplace + 1) % n; // 更新替换位置
            status[j] = false;                // 标记缺页
            pageFaults++;
        }
        else {
            status[j] = true;                 // 标记命中
        }

        // 记录当前内存状态到表格
        for (int i = 0; i < n; i++) {
            table[i][j] = memory[i];
        }
    }

    // 获取结束时间(时钟周期数)
    clock_t end = clock();

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  ";  // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        if (status[j]) {
            cout << "\u221A ";  // Unicode "√"
        }
        else {
            cout << "\u00D7 ";  // Unicode "×"
        }
    }
    cout << endl;

    cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;
    cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl; // 输出运行时间
}

int main() {
    cout << "内存容量为 3 块:\n";
    fifo(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    fifo(4);

    return 0;
}

2、精确时间:用chrono输出运行时间都是xx微秒,输出时间不定

#include <iostream>
#include <iomanip>
#include <chrono> // 引入chrono库

using namespace std;
using namespace std::chrono; // 使用chrono命名空间

// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

// FIFO算法
void fifo(int n) {
    int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空
    int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空
    bool status[20];                         // 记录是否缺页

    int pageFaults = 0;                      // 缺页次数
    int nextReplace = 0;                     // 记录下一个要替换的位置

    // 获取开始时间
    auto start = high_resolution_clock::now();

    // 遍历每个页面访问
    for (int j = 0; j < 20; j++) {
        int page = pages[j];
        bool found = false;

        // 检查页面是否已在内存中
        for (int i = 0; i < n; i++) {
            if (memory[i] == page) {
                found = true;
                break;
            }
        }

        if (!found) {  // 缺页情况
            memory[nextReplace] = page;       // 替换页面
            nextReplace = (nextReplace + 1) % n; // 更新替换位置
            status[j] = false;                // 标记缺页
            pageFaults++;
        }
        else {
            status[j] = true;                 // 标记命中
        }

        // 记录当前内存状态到表格
        for (int i = 0; i < n; i++) {
            table[i][j] = memory[i];
        }
    }

    // 获取结束时间
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  ";  // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        if (status[j]) {
            cout << "\u221A ";  // Unicode "√"
        }
        else {
            cout << "\u00D7 ";  // Unicode "×"
        }
    }
    cout << endl;

    cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;
    cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}

int main() {
    cout << "内存容量为 3 块:\n";
    fifo(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    fifo(4);

    return 0;
}

3、数组模拟队列、类似滑动窗口

#include <iostream>
#include <iomanip>
#include <chrono>
#include <cstring>

using namespace std;
using namespace std::chrono;

const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

// FIFO算法
void fifo(int n) {
    memset(memory, 0x3f, sizeof memory);
    bool status[20];  // 记录是否缺页

    int pageFaults = 0;       // 缺页次数
    int hh = 0, tt = -1;      // 队首和队尾指针
    auto start = high_resolution_clock::now(); // 获取开始时间

    for (int j = 0; j < 20; j++) {
        int page = pages[j];
        bool found = false;

        // 检查页面是否已在内存中
        for (int i = hh; i <= tt; i++) {
            if (memory[i] == page) {
                found = true;
                break;
            }
        }

        if (!found) {  // 缺页情况
            memory[++tt] = page; // 新页面加入队尾

            // 控制滑动窗口大小为 n
            if (tt - hh + 1 > n) {
                hh++; // 超过容量,队首出队
            }

            status[j] = false;  // 标记缺页
            pageFaults++;
        }
        else {
            status[j] = true;   // 标记命中
        }

        // 记录当前内存状态到表格
        for (int i = 0; i < n; i++) {
            //如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,
            //因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值
            if (i + hh <= tt && memory[i + hh] != 0x3f) {
                table[i][j] = memory[i + hh];
            }
            else {
                table[i][j] = -1; // 空位显示为 -1
            }
        }
    }

    auto stop = high_resolution_clock::now(); // 获取结束时间
    auto duration = duration_cast<microseconds>(stop - start);

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  ";  // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示
    }
    cout << endl;

    cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;
    cout << "运行时间: " << duration.count() << " 微秒" << endl;
}

int main() {
    cout << "内存容量为 3 块:\n";
    fifo(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    fifo(4);

    return 0;
}

朴素版算缺页率

#include <iostream>
#include <ctime>
#include <cstring>

using namespace std;


const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

// FIFO算法
void fifo(int n) {
    memset(memory, 0x3f, sizeof memory);
    bool status[20];  // 记录是否缺页

    int pageFaults = 0;       // 缺页次数
    int hh = 0, tt = -1;      // 队首和队尾指针
    clock_t start=clock(); // 获取开始时间

    for (int j = 0; j < 20; j++) {
        int page = pages[j];
        bool found = false;

        // 检查页面是否已在内存中
        for (int i = hh; i <= tt; i++) {
            if (memory[i] == page) {
                found = true;
                break;
            }
        }

        if (!found) {  // 缺页情况
            memory[++tt] = page; // 新页面加入队尾

            // 控制滑动窗口大小为 n
            if (tt - hh + 1 > n) {
                hh++; // 超过容量,队首出队
            }

            status[j] = false;  // 标记缺页
            pageFaults++;
        }
        else {
            status[j] = true;   // 标记命中
        }

        // 记录当前内存状态到表格
        for (int i = 0; i < n; i++) {
            //如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,
            //因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值
            if (i + hh <= tt && memory[i + hh] != 0x3f) {
                table[i][j] = memory[i + hh];
            }
            else {
                table[i][j] = -1; // 空位显示为 -1
            }
        }
    }

    clock_t end = clock(); // 获取结束时间

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  ";  // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示
    }
    cout << endl;

    cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;
    cout << "运行时间: " << (double)(end-start)/CLOCKS_PER_SEC << " 秒" << endl;

}

int main() {
    cout << "内存容量为 3 块:\n";
    fifo(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    fifo(4);

    return 0;
}

FIFO,用链表实现

LRU,用计数器实现

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>

using namespace std;

const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

void lru(int n) {
    memset(table, -1, sizeof table);
    m.clear();
    bool status[20]; // 记录是否缺页

    int pageFaults = 0; // 缺页次数

    clock_t start = clock(); // 获取开始时间

    for (int j = 0; j < 20; j++) {
        int page = pages[j];

        if (!m.count(page)) { // 没命中就要加入或者替换页面
            if (m.size() >= n) {
                // 找到count最大的页面进行替换
                int maxpage = -1, maxcounts = -1;
                for (auto p : m) {
                    if (p.second > maxcounts) {
                        maxpage = p.first;
                        maxcounts = p.second;
                    }
                }
                m.erase(maxpage);
            }
            m[page] = 0;//没命中且主存没满则直接加入页面
            pageFaults++;
            status[j] = false; // 标记缺页
        }
        else {
            status[j] = true; // 标记命中
            m[page] = 0;
        }

        // 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的
        for (auto& p : m) {
            if (p.first != page) {
                p.second += 1;
            }
        }

        // 更新当前主存块内存在的页面
        int i = 0;
        for (auto p : m) {
            if (i < n) {//用一个i去便利贮存块,而不用for
                table[i][j] = p.first;
                i++;
            }
        }
        //一开始写错了:
        /*for (int i = 0; i < n; i++) {
            for (auto p : m) {
                table[i][j] = p.first;
            }
        }*/
    }

    clock_t end = clock(); // 获取结束时间

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  "; // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        cout << (status[j] ? "\u221A " : "\u00D7 ");
    }
    cout << endl;

    cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;
    cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;
}

int main() {
    cout << "内存容量为 3 块:\n";
    lru(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    lru(4);

    return 0;
}

LRU,用堆栈实现

两个算法综合在一起看运行速率

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>
#include <chrono> // 引入chrono库

using namespace std;
using namespace std::chrono; // 使用chrono命名空间

const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };
int memory[N];//每次查找页面进行记录的滑动窗口

// FIFO算法
void fifo(int n) {
    memset(memory, 0x3f, sizeof memory);
    memset(table, -1, sizeof table);
    bool status[20];  // 记录是否缺页

    int pageFaults = 0;       // 缺页次数
    int hh = 0, tt = -1;      // 队首和队尾指针
    //clock_t start = clock(); // 获取开始时间
     // 获取开始时间
    auto start = high_resolution_clock::now();

    for (int j = 0; j < 20; j++) {
        int page = pages[j];
        bool found = false;

        // 检查页面是否已在内存中
        for (int i = hh; i <= tt; i++) {
            if (memory[i] == page) {
                found = true;
                break;
            }
        }

        if (!found) {  // 缺页情况
            memory[++tt] = page; // 新页面加入队尾

            // 控制滑动窗口大小为 n
            if (tt - hh + 1 > n) {
                hh++; // 超过容量,队首出队
            }

            status[j] = false;  // 标记缺页
            pageFaults++;
        }
        else {
            status[j] = true;   // 标记命中
        }

        // 记录当前内存状态到表格
        for (int i = 0; i < n; i++) {
            //如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,
            //因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值
            if (i + hh <= tt && memory[i + hh] != 0x3f) {
                table[i][j] = memory[i + hh];
            }
            else {
                table[i][j] = -1; // 空位显示为 -1
            }
        }
    }

    //clock_t end = clock(); // 获取结束时间
    // 获取结束时间
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  ";  // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示
    }
    cout << endl;

    cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;
    //cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;
    cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间

}
void lru(int n) {
    memset(table, -1, sizeof table);
    m.clear();
    bool status[20]; // 记录是否缺页

    int pageFaults = 0; // 缺页次数

    //clock_t start = clock(); // 获取开始时间
     // 获取开始时间
    auto start = high_resolution_clock::now();

    for (int j = 0; j < 20; j++) {
        int page = pages[j];

        if (!m.count(page)) { // 没命中就要加入或者替换页面
            if (m.size() >= n) {
                // 找到count最大的页面进行替换
                int maxpage = -1, maxcounts = -1;
                for (auto p : m) {
                    if (p.second > maxcounts) {
                        maxpage = p.first;
                        maxcounts = p.second;
                    }
                }
                m.erase(maxpage);
            }
            m[page] = 0;//没命中且主存没满则直接加入页面
            pageFaults++;
            status[j] = false; // 标记缺页
        }
        else {
            status[j] = true; // 标记命中
            m[page] = 0;
        }

        // 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的
        for (auto& p : m) {
            if (p.first != page) {
                p.second += 1;
            }
        }

        // 更新当前主存块内存在的页面
        int i = 0;
        for (auto p : m) {
            if (i < n) {//用一个i去便利贮存块,而不用for
                table[i][j] = p.first;
                i++;
            }
        }
        //一开始写错了:
        /*for (int i = 0; i < n; i++) {
            for (auto p : m) {
                table[i][j] = p.first;
            }
        }*/
    }

    //clock_t end = clock(); // 获取结束时间
    // 获取结束时间
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);

    // 输出结果表格
    cout << "主存块号 ";
    for (int j = 0; j < 20; j++) {
        cout << pages[j] << " ";
    }
    cout << endl;

    for (int i = 0; i < n; i++) {
        cout << "   " << i << "     ";
        for (int j = 0; j < 20; j++) {
            if (table[i][j] == -1) {
                cout << "  "; // 空块显示为空格
            }
            else {
                cout << table[i][j] << " ";
            }
        }
        cout << endl;
    }

    // 输出缺页标记
    cout << "是否缺页 ";
    for (int j = 0; j < 20; j++) {
        cout << (status[j] ? "\u221A " : "\u00D7 ");
    }
    cout << endl;

    cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;
    //cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;
    cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}

int main() {
    cout << "内存容量为 3 块:\n";
    fifo(3);
    cout << endl;
    lru(3);
    cout << endl;

    cout << "内存容量为 4 块:\n";
    fifo(4);
    cout << endl;
    lru(4);

    return 0;
}

1)主存块数越多的,不论哪个算法,运行时间都更长一些,用的时chrono精确时间微妙

但是同样的,运行每次的时间不定

2)主存块数越多的,不论哪个算法,缺页率都更低一些

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Ubuntu24.04】VirtualBox安装ubuntu-live-server24.04

目录 0 背景1 下载镜像2 安装虚拟机3 安装UbuntuServer24.044 配置基本环境5 总结0 背景 有了远程连接工具之后,似乎作为服务器的Ubuntu24.04桌面版有点备受冷落了,桌面版的Ubuntu24.04的优势是图形化桌面,是作为一个日常工作的系统来用的,就像Windows,如果要作为服务器来…

《SpringBoot、Vue 组装exe与套壳保姆级教学》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

Flowable第一篇、快速上手(Flowable安装、配置、集成)

目录 Flowable 概述Flowable的安装与配置 2.1. FlowableUI安装 2.2. Flowable BPMN插件下载 2.3 集成Spring Boot流程审核操作 3.3 简单流程部署 3.4 启动流程实例 3.5 流程审批 一、Flowable 概述 Flowable是一个轻量级、高效可扩展的工作流和业务流程管理&#xff08;BPM&…

Docker搭建有UI的私有镜像仓库

Docker搭建有UI的私有镜像仓库 一、使用这个docker-compose.yml文件&#xff1a; version: 3services:registry-ui:image: joxit/docker-registry-ui:2.5.7-debianrestart: alwaysports:- 81:80environment:- SINGLE_REGISTRYtrue- REGISTRY_TITLEAtt Docker Registry UI- DE…

容器安全检测和渗透测试工具

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect Docker-bench-…

Day10_CSS过度动画

Day10_CSS过度动画 背景 : PC和APP项目我们已经开发完毕, 但是再真正开发的时候有些有些简易的动态效果我们可以使用CSS完成 ; 本节课我们来使用CSS完成基础的动画效果 今日学习目标 CSS3过度CSS3平面动态效果CSS3动画效果案例 1. CSS3过渡 ​ 含义 :过渡指的是元素从一种…

iOS应用网络安全之HTTPS

移动互联网开发中iOS应用的网络安全问题往往被大部分开发者忽略, iOS9和OS X 10.11开始Apple也默认提高了安全配置和要求. 本文以iOS平台App开发中对后台数据接口的安全通信进行解析和加固方法的分析. 1. HTTPS/SSL的基本原理 安全套接字层 (Secure Socket Layer, SSL) 是用来…

excel版数独游戏(已完成)

前段时间一个朋友帮那小孩解数独游戏&#xff0c;让我帮解&#xff0c;我看他用电子表格做&#xff0c;只能显示&#xff0c;不能显示重复&#xff0c;也没有协助解题功能&#xff0c;于是我说帮你做个电子表格版的“解题助手”吧&#xff0c;不能直接解题&#xff0c;但该有的…

金融数据中心容灾“大咖说” | 美创科技赋能“灾备一体化”建设

中国人民银行发布的《金融数据中心容灾建设指引》&#xff08;JR/T 0264—2024&#xff09;已于2024年7月29日正式实施。这一金融行业标准对金融数据中心容灾建设中的“组织保障、需求分析、体系规划、建设要求、运维管理”进行了规范和指导。面对不断增加的各类网络、业务、应…

Qt:信号槽

一. 信号槽概念 信号槽 是 Qt 框架中一种用于对象间通信的机制 。它通过让一个对象发出信号&#xff0c;另一个对象连接到这个信号的槽上来实现通信。信号槽机制是 Qt 的核心特性之一&#xff0c;提供了一种灵活且类型安全的方式来处理事件和数据传递。 1. 信号的本质 QT中&a…

SpringBoot与MongoDB深度整合及应用案例

SpringBoot与MongoDB深度整合及应用案例 在当今快速发展的软件开发领域&#xff0c;NoSQL数据库因其灵活性和可扩展性而变得越来越流行。MongoDB&#xff0c;作为一款领先的NoSQL数据库&#xff0c;以其文档导向的存储模型和强大的查询能力脱颖而出。本文将为您提供一个全方位…

大数据调度组件之Apache DolphinScheduler

Apache DolphinScheduler 是一个分布式易扩展的可视化 DAG 工作流任务调度系统。致力于解决数据处理流程中错综复杂的依赖关系&#xff0c;使调度系统在数据处理流程中开箱即用。 主要特性 易于部署&#xff0c;提供四种部署方式&#xff0c;包括Standalone、Cluster、Docker和…

ThinkPHP6门面(Facade)

门面 门面&#xff08;Facade&#xff09; 门面为容器中的&#xff08;动态&#xff09;类提供了一个静态调用接口&#xff0c;相比于传统的静态方法调用&#xff0c; 带来了更好的可测试性和扩展性&#xff0c;你可以为任何的非静态类库定义一个facade类。 系统已经为大部分…

MySQL win安装 和 pymysql使用示例

目录 一、MySQL安装 下载压缩包&#xff1a; 编写配置文件&#xff1a; 配置环境变量&#xff1a; 初始化服务和账户 关闭mysql开机自启&#xff08;可选&#xff09; 建议找一个数据库可视化软件 二、使用pymysql操作数据库 安装pymysql 示例代码 报错处理 一、My…

Parker派克防爆电机在实际应用中的安全性能如何保证?

Parker防爆电机确保在实际应用中的安全性能主要通过以下几个方面来保证&#xff1a; 1.防爆外壳设计&#xff1a;EX系列电机采用强大的防爆外壳&#xff0c;设计遵循严格的防爆标准&#xff0c;能够承受内部可能发生的爆炸而不破损&#xff0c;利用间隙切断原理&#xff0c;防…

空间与单细胞转录组学的整合定位肾损伤中上皮细胞与免疫细胞的相互作用

result 在空间转录组图谱中对人类肾脏进行无监督映射和细胞类型鉴定 我们试图在H&E染色的人类参考肾切除标本组织切片上直接映射转录组特征。该组织来自一名59岁的女性&#xff0c;其肾小球闭塞和间质纤维化程度最低&#xff08;分别影响不到10%的肾小球或肾实质&#xff…

greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用

简略图 greater<>()(a, b) a > b 返回true&#xff0c;反之返回false less<>()(a, b) a < b 返回true&#xff0c;反之返回false 在cmp中使用&#xff08;正着理解&#xff09; 规则返回true时a在前&#xff0c;反之b在前 在priority_queue中使用 &#xff…

详细描述一下Elasticsearch索引文档的过程?

大家好&#xff0c;我是锋哥。今天分享关于【详细描述一下Elasticsearch索引文档的过程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 详细描述一下Elasticsearch索引文档的过程&#xff1f; Elasticsearch的索引文档过程是其核心功能之一&#xff0c;涉及将数据存储到…

入门车载以太网(6) -- XCP on Ethernet

目录 1.寻址方式 2.数据帧格式 3.特殊指令 4.使用实例 了解了SOME/IP之后&#xff0c;继续来看看车载以太网在汽车标定领域的应用。 在汽车标定领域XCP是非常重要的协议&#xff0c;咱们先来回顾下基础概念。 XCP全称Universal Measurement and Calibration Protocol&a…

Python中常用的函数介绍

Python中常用的几种函数 1、input函数 input()函数&#xff1a;主要作用是让用户输入某个内容并接收它。 #输入你的年龄 >>> age input("my age is :") my age is :20 执行代码后输入年龄&#xff0c;年龄被存放到age变量中&#xff0c;执行print后终端会…