【面试】封装、继承、多态的具象示例 模板编程的理解与应用场景 链表适用的场景

news2025/4/15 13:38:00

文章目录

  • C++面试:封装、继承、多态的具象示例
    • 1. 封装 (Encapsulation)
    • 2. 继承 (Inheritance)
    • 3. 多态 (Polymorphism)
    • 综合示例:封装、继承、多态
  • C++模板编程的理解与应用场景
    • 我对模板编程的理解
    • C++中最常用的模板编程场景
      • 1. STL (标准模板库)
      • 2. 通用容器实现
      • 3. 通用算法实现
      • 4. 类型安全的接口
      • 5. 策略模式实现
      • 6. 元编程和编译期计算
      • 7. CRTP (奇异递归模板模式)
      • 8. 类型萃取(Type Traits)
    • 模板编程的优势
    • 总结
  • 链表适用的场景
    • 1. 频繁的插入和删除操作
    • 2. 不确定数据量的动态存储
    • 3. 不需要随机访问的场景
    • 4. 内存碎片化严重的环境
    • 5. 需要高效合并/拆分的场景
    • 6. 实现高级数据结构
    • 链表 vs 数组的对比
    • 实际案例
    • 何时选择链表
      • 1. **Linux 管理进程队列**
      • 2. **内存页管理(如 Buddy System 的链表)**
      • 3. **堆内存管理(如 malloc 的 free list)**
      • 4. **文件系统管理文件信息(如 inode 链表)**
      • 5. **MySQL 索引的叶子节点链表(B+Tree 特性)**
      • **链表的优势总结**
      • **为什么不选数组或其他结构?**

C++面试:封装、继承、多态的具象示例

1. 封装 (Encapsulation)

封装是将数据和操作数据的方法绑定在一起,并对外隐藏实现细节的过程。

示例:

class BankAccount {
private:  // 数据隐藏
    std::string accountNumber;
    double balance;

public:  // 公开接口
    BankAccount(const std::string& accNum, double initialBalance) 
        : accountNumber(accNum), balance(initialBalance) {}

    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    bool withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
            return true;
        }
        return false;
    }

    double getBalance() const {
        return balance;
    }
};

int main() {
    BankAccount account("123456789", 1000.0);
    account.deposit(500.0);
    account.withdraw(200.0);
    std::cout << "Current balance: " << account.getBalance() << std::endl;
    // account.balance = 1000000.0; // 错误!balance是私有的
}

封装的好处:

  • 保护数据不被外部随意修改
  • 可以修改内部实现而不影响外部代码
  • 提供清晰的接口供外部使用

2. 继承 (Inheritance)

继承允许我们基于已有的类创建新类,新类继承原有类的特性并可以添加新特性。

示例:

// 基类
class Animal {
protected:
    std::string name;
    int age;

public:
    Animal(const std::string& name, int age) : name(name), age(age) {}
    
    void eat() {
        std::cout << name << " is eating." << std::endl;
    }
    
    void sleep() {
        std::cout << name << " is sleeping." << std::endl;
    }
};

// 派生类
class Dog : public Animal {
private:
    std::string breed;

public:
    Dog(const std::string& name, int age, const std::string& breed)
        : Animal(name, age), breed(breed) {}
    
    void bark() {
        std::cout << name << " (a " << breed << ") is barking: Woof! Woof!" << std::endl;
    }
    
    void fetch() {
        std::cout << name << " is fetching the ball." << std::endl;
    }
};

int main() {
    Dog myDog("Buddy", 3, "Golden Retriever");
    myDog.eat();    // 继承自Animal
    myDog.sleep();  // 继承自Animal
    myDog.bark();   // Dog特有的方法
    myDog.fetch();  // Dog特有的方法
}

继承的好处:

  • 代码复用:派生类可以重用基类的代码
  • 层次化组织:可以创建类的层次结构
  • 可扩展性:可以在不修改基类的情况下添加新功能

3. 多态 (Polymorphism)

多态允许我们使用统一的接口处理不同类型的对象。

示例:

class Shape {
public:
    virtual void draw() const = 0;  // 纯虚函数
    virtual ~Shape() {}             // 虚析构函数
};

class Circle : public Shape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}
    
    void draw() const override {
        std::cout << "Drawing a circle with radius " << radius << std::endl;
    }
};

class Square : public Shape {
private:
    double side;

public:
    Square(double s) : side(s) {}
    
    void draw() const override {
        std::cout << "Drawing a square with side " << side << std::endl;
    }
};

void drawAllShapes(const std::vector<Shape*>& shapes) {
    for (const auto& shape : shapes) {
        shape->draw();  // 多态调用
    }
}

int main() {
    std::vector<Shape*> shapes;
    shapes.push_back(new Circle(5.0));
    shapes.push_back(new Square(4.0));
    shapes.push_back(new Circle(3.0));
    
    drawAllShapes(shapes);
    
    // 清理内存
    for (auto shape : shapes) {
        delete shape;
    }
}

多态的好处:

  • 接口统一:可以用相同的方式处理不同的对象
  • 可扩展性:可以添加新类而不需要修改现有代码
  • 灵活性:运行时决定调用哪个方法

综合示例:封装、继承、多态

#include <iostream>
#include <vector>
#include <memory>

// 封装
class Employee {
private:
    std::string name;
    int id;
    double salary;

public:
    Employee(const std::string& n, int i, double s) 
        : name(n), id(i), salary(s) {}
    
    virtual ~Employee() {}
    
    virtual void work() const {
        std::cout << name << " (ID: " << id << ") is working." << std::endl;
    }
    
    virtual double calculateBonus() const {
        return salary * 0.1;  // 默认10%的奖金
    }
    
    std::string getName() const { return name; }
    int getId() const { return id; }
    double getSalary() const { return salary; }
};

// 继承
class Manager : public Employee {
private:
    std::string department;

public:
    Manager(const std::string& n, int i, double s, const std::string& d)
        : Employee(n, i, s), department(d) {}
    
    void work() const override {
        std::cout << getName() << " (Manager of " << department 
                  << ") is managing the team." << std::endl;
    }
    
    double calculateBonus() const override {
        return getSalary() * 0.2;  // 经理有20%的奖金
    }
};

class Developer : public Employee {
private:
    std::string programmingLanguage;

public:
    Developer(const std::string& n, int i, double s, const std::string& lang)
        : Employee(n, i, s), programmingLanguage(lang) {}
    
    void work() const override {
        std::cout << getName() << " is coding in " 
                  << programmingLanguage << "." << std::endl;
    }
    
    void debug() const {
        std::cout << getName() << " is debugging " 
                  << programmingLanguage << " code." << std::endl;
    }
};

// 多态
void processEmployees(const std::vector<std::unique_ptr<Employee>>& employees) {
    for (const auto& emp : employees) {
        emp->work();  // 多态调用
        std::cout << emp->getName() << "'s bonus: $" 
                  << emp->calculateBonus() << std::endl;
        
        // 尝试向下转型
        if (auto dev = dynamic_cast<Developer*>(emp.get())) {
            dev->debug();
        }
    }
}

int main() {
    std::vector<std::unique_ptr<Employee>> employees;
    
    employees.emplace_back(std::make_unique<Manager>("Alice", 101, 80000, "Engineering"));
    employees.emplace_back(std::make_unique<Developer>("Bob", 102, 70000, "C++"));
    employees.emplace_back(std::make_unique<Developer>("Charlie", 103, 75000, "Python"));
    
    processEmployees(employees);
    
    return 0;
}

这个综合示例展示了:

  1. 封装:Employee类隐藏了内部数据,提供公共接口
  2. 继承:Manager和Developer继承自Employee,扩展了功能
  3. 多态:processEmployees函数可以处理不同类型的Employee对象

C++模板编程的理解与应用场景

我对模板编程的理解

模板编程(Template Programming)是C++中一种强大的泛型编程技术,它允许我们编写与数据类型无关的代码。通过模板,我们可以创建能够处理多种数据类型的函数或类,而无需为每种类型重复编写代码。

模板编程的核心思想是**“参数化类型”**,即在编写代码时不指定具体的数据类型,而是使用类型参数,在实际使用时再指定具体类型。

C++中最常用的模板编程场景

1. STL (标准模板库)

STL是C++模板编程最经典、最广泛的应用场景:

#include <vector>
#include <list>
#include <map>
#include <algorithm>

// 这些容器和算法都是模板
std::vector<int> intVec;          // 整数向量
std::list<std::string> strList;   // 字符串链表
std::map<int, double> idMap;      // 整数到浮点数的映射

// 模板算法
std::sort(intVec.begin(), intVec.end());
auto it = std::find(strList.begin(), strList.end(), "template");

2. 通用容器实现

当需要实现可以存储任意类型数据的容器时:

template <typename T>
class MyArray {
private:
    T* data;
    size_t size;
public:
    MyArray(size_t s) : size(s), data(new T[s]) {}
    ~MyArray() { delete[] data; }
    
    T& operator[](size_t index) {
        return data[index];
    }
    // ... 其他成员函数
};

// 使用
MyArray<int> intArray(10);
MyArray<std::string> strArray(5);

3. 通用算法实现

编写适用于多种数据类型的算法:

template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// 使用
int m1 = max(3, 5);                  // int
double m2 = max(3.14, 2.71);          // double
std::string m3 = max("apple", "zoo"); // std::string

4. 类型安全的接口

创建类型安全且灵活的接口:

template <typename T>
class Singleton {
private:
    static T* instance;
    Singleton() = default;
public:
    static T& getInstance() {
        if (!instance) {
            instance = new T();
        }
        return *instance;
    }
};

template <typename T>
T* Singleton<T>::instance = nullptr;

// 使用
class Logger : public Singleton<Logger> {
    friend class Singleton<Logger>;
private:
    Logger() = default;
public:
    void log(const std::string& message) {
        // 实现日志功能
    }
};

Logger::getInstance().log("Template example");

5. 策略模式实现

通过模板实现编译期策略选择:

// 排序策略
struct BubbleSort {
    template <typename Iter>
    static void sort(Iter begin, Iter end) {
        // 冒泡排序实现
    }
};

struct QuickSort {
    template <typename Iter>
    static void sort(Iter begin, Iter end) {
        // 快速排序实现
    }
};

// 排序器模板
template <typename SortStrategy>
class Sorter {
public:
    template <typename Iter>
    void operator()(Iter begin, Iter end) {
        SortStrategy::sort(begin, end);
    }
};

// 使用
std::vector<int> data = {5, 2, 9, 1, 5};
Sorter<QuickSort>()(data.begin(), data.end());

6. 元编程和编译期计算

利用模板进行编译期计算和类型操作:

// 编译期阶乘计算
template <unsigned n>
struct Factorial {
    static const unsigned value = n * Factorial<n-1>::value;
};

template <>
struct Factorial<0> {
    static const unsigned value = 1;
};

// 使用
constexpr unsigned fact5 = Factorial<5>::value;  // 120

7. CRTP (奇异递归模板模式)

用于静态多态和代码复用:

template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
};

class Derived : public Base<Derived> {
public:
    void implementation() {
        std::cout << "Derived implementation" << std::endl;
    }
};

// 使用
Derived d;
d.interface();  // 输出 "Derived implementation"

8. 类型萃取(Type Traits)

在模板中检查和操作类型信息:

#include <type_traits>

template <typename T>
void process(T value) {
    if constexpr (std::is_integral_v<T>) {
        std::cout << "Processing integer: " << value << std::endl;
    } else if constexpr (std::is_floating_point_v<T>) {
        std::cout << "Processing float: " << value << std::endl;
    } else {
        std::cout << "Processing unknown type" << std::endl;
    }
}

// 使用
process(42);        // 处理整数
process(3.14);      // 处理浮点数
process("hello");   // 处理未知类型

模板编程的优势

  1. 代码复用:编写一次,适用于多种类型
  2. 类型安全:编译时类型检查,避免运行时错误
  3. 性能:没有运行时开销,所有工作在编译期完成
  4. 灵活性:可以创建高度通用的库和组件
  5. 可扩展性:易于添加对新类型的支持

总结

C++中模板编程最常见的应用场景包括STL容器和算法、通用数据结构和算法实现、类型安全接口设计、策略模式实现、编译期计算、静态多态以及类型萃取等。模板编程是C++强大表达能力的核心之一,也是现代C++编程不可或缺的部分。

链表适用的场景

链表是一种基础的数据结构,在以下场景中特别适用:

  1. 频繁的中间插入和删除操作
  2. linux管理进程各种队列,内存页,堆内存链表,文件信息链表,mysql的索引叶子结点链表
  3. 实现特定的数据结构:lru,哈希表链地址法,图邻接表,跳表,

1. 频繁的插入和删除操作

当需要频繁在数据集合中间进行插入或删除操作时,链表比数组更有优势。

典型场景

  • 实现撤销(Undo)功能(每次操作都插入链表头部)
  • 浏览器历史记录(前进/后退)
  • 进程调度队列(经常需要添加和移除进程)
// 例如实现撤销功能
struct Command {
    virtual void execute() = 0;
    virtual void undo() = 0;
};

std::list<std::shared_ptr<Command>> undoStack;

// 执行新命令时
auto cmd = std::make_shared<SomeCommand>();
cmd->execute();
undoStack.push_front(cmd);  // O(1)时间复杂度

// 撤销时
if (!undoStack.empty()) {
    undoStack.front()->undo();
    undoStack.pop_front();  // O(1)时间复杂度
}

2. 不确定数据量的动态存储

当数据量未知或变化很大时,链表可以动态增长而不需要预先分配空间。

典型场景

  • 读取未知长度的数据流
  • 内存受限环境中的动态分配
  • 实现其他数据结构(如栈、队列、图等)
// 读取未知长度的输入
std::list<std::string> inputLines;
std::string line;

while (std::getline(std::cin, line)) {
    inputLines.push_back(line);
}

3. 不需要随机访问的场景

当主要操作是顺序访问而非随机访问时,链表很合适。

典型场景

  • 音乐播放器的播放列表
  • 文件系统的目录结构
  • 多道程序环境下的I/O缓冲区
// 音乐播放列表
class Song {
    std::string title;
    std::string artist;
    // ...
};

std::list<Song> playlist;

// 顺序播放
for (const auto& song : playlist) {
    playSong(song);
}

4. 内存碎片化严重的环境

在内存受限或碎片化严重的环境中,链表比数组更有优势,因为它不需要连续内存空间。

典型场景

  • 嵌入式系统
  • 操作系统内核数据结构
  • 内存分配器实现

5. 需要高效合并/拆分的场景

当需要频繁合并两个集合或拆分集合时,链表可以在O(1)时间内完成。

典型场景

  • 归并排序的实现
  • 数据库中的多表连接操作
  • 消息队列的合并
// 合并两个链表
std::list<int> list1 = {1, 2, 3};
std::list<int> list2 = {4, 5, 6};

list1.splice(list1.end(), list2);  // O(1)操作
// list1现在包含1,2,3,4,5,6

6. 实现高级数据结构

许多高级数据结构基于链表实现:

典型场景

  • 哈希表的链地址法解决冲突
  • 图的邻接表表示
  • 跳表的基础结构
  • 二叉树的某些表示方法
// 哈希表的链地址法实现
template <typename K, typename V>
class HashMap {
private:
    std::vector<std::list<std::pair<K, V>>> buckets;
    // ...
public:
    void insert(const K& key, const V& value) {
        size_t index = hash(key) % buckets.size();
        for (auto& pair : buckets[index]) {
            if (pair.first == key) {
                pair.second = value;
                return;
            }
        }
        buckets[index].emplace_back(key, value);
    }
    // ...
};

链表 vs 数组的对比

场景/操作链表优势数组优势
频繁插入删除✅ O(1)❌ O(n)
随机访问❌ O(n)✅ O(1)
内存使用动态分配局部性好
缓存友好度❌ 差✅ 好
内存碎片化环境✅ 适应❌ 不适应
预知大小、少变动的数据

实际案例

  1. Linux内核:使用链表管理进程、内存页等
  2. Redis:使用双向链表实现List数据类型
  3. Nginx:使用链表管理连接、请求等
  4. 游戏开发:场景中的动态对象管理
  5. 区块链:区块链本身就是一种链表结构

何时选择链表

选择链表而非数组的主要考虑因素是:

  • 插入/删除频率高于随机访问频率
  • 数据量变化大或不可预测
  • 内存连续性无法保证
  • 需要频繁合并/拆分数据结构
  • 实现特定的算法需求(如LRU缓存)

在C++中,std::list(双向链表)和std::forward_list(单向链表)是标准库提供的链表实现,应根据具体需求选择合适的类型。
这些场景选择链表(尤其是双向链表)作为数据结构,主要基于链表的以下特性与场景需求的匹配:


1. Linux 管理进程队列

  • 动态增删频繁:进程的创建、终止、调度等操作需要频繁插入/删除节点。链表在 O ( 1 ) O(1) O(1) 时间内即可完成这些操作,而数组需要移动元素。
  • 不确定性数量:进程数量动态变化,链表无需预分配固定空间,避免内存浪费或扩容开销。
  • 双向遍历需求:Linux 使用双向链表(如 struct list_head),便于从任意节点向前或向后遍历(例如查找相邻进程或优先级调整)。

2. 内存页管理(如 Buddy System 的链表)

  • 碎片化处理:内存页需按不同大小(如 4KB、8KB)组织成多个链表。链表可灵活管理非连续的空闲页块。
  • 快速分配/释放:分配内存时从对应大小的链表中移除节点;释放时快速插入,均无需移动其他元素。
  • 合并操作:双向链表便于合并相邻空闲页块(通过前后指针检查相邻页状态)。

3. 堆内存管理(如 malloc 的 free list)

  • 变长内存块:堆内存块大小不一,链表可串联不同大小的空闲块,通过指针连接,无需连续内存。
  • 高效合并:释放内存时,双向链表能快速检查前后块是否空闲,合并减少碎片。

4. 文件系统管理文件信息(如 inode 链表)

  • 动态文件数量:文件创建/删除导致 inode 数量变化,链表支持动态扩展。
  • 快速查找与遍历:结合哈希表或树,链表用于维护同一哈希桶或目录下的文件序列,便于线性访问。

5. MySQL 索引的叶子节点链表(B+Tree 特性)

  • 范围查询优化:B+Tree 的叶子节点通过链表串联,使范围查询(如 WHERE id BETWEEN 10 AND 100)只需定位起始节点后顺链遍历,无需回溯父节点。
  • 磁盘 I/O 优化:链表结构适合磁盘预读(顺序访问性能接近数组),而插入/删除节点仅需修改相邻节点的指针,避免大量数据移动。

链表的优势总结

  • 插入/删除高效:尤其适合频繁动态修改的场景。
  • 无预分配限制:适应数据规模不确定的情况。
  • 双向链表支持逆向操作:如 Linux 进程回滚、内存块合并等。
  • 天然支持非连续存储:适合内存碎片化或磁盘分散存储的场景。

为什么不选数组或其他结构?

  • 数组:插入/删除需移动元素,扩容成本高;静态大小不灵活。
  • 哈希表:无法高效支持范围查询(如 MySQL 需要链表辅助)。
  • 普通树结构:维护复杂,且范围查询不如链表直接。

在这些场景中,链表(尤其是双向链表)在动态性、操作效率和空间利用率上达到了最佳平衡。

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

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

相关文章

0.机器学习基础

0.人工智能概述&#xff1a; &#xff08;1&#xff09;必备三要素&#xff1a; 数据算法计算力 CPU、GPU、TPUGPU和CPU对比&#xff1a; GPU主要适合计算密集型任务&#xff1b;CPU主要适合I/O密集型任务&#xff1b; 【笔试问题】什么类型程序适合在GPU上运行&#xff1…

系统与网络安全------网络通信原理(4)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 网络层解析 IP 网络层概述 位于OSI模型第三层作用 定义网络设备的逻辑地址&#xff0c;俗称网络层地址&#xff08;如IP地址&#xff09; 在不同的网段之间选择最佳数据转发路径 协议 IP协议 IP数据包…

Java基础 4.12

1.方法的重载&#xff08;OverLoad&#xff09; 基本介绍 Java中允许同一个类&#xff0c;多个同名方法的存在&#xff0c;但要求形参列表不一致&#xff01; 如 System.out.println(); out是PrintStream类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 2.重载的快速入…

XILINX DDR3专题---(1)IP核时钟框架介绍

1.什么是Reference Clock&#xff0c;这个时钟一定是200MHz吗&#xff1f; 2.为什么APP_DATA是128bit&#xff0c;怎么算出来的&#xff1f; 3.APP &#xff1a;MEM的比值一定是1:4吗&#xff1f; 4.NO BUFFER是什么意思&#xff1f; 5.什么情况下Reference Clock的时钟源可…

clickhouse注入手法总结

clickhouse 遇到一题clickhouse注入相关的&#xff0c;没有见过&#xff0c;于是来学习clickhouse的使用&#xff0c;并总结相关注入手法。 环境搭建 直接在docker运行 docker pull clickhouse/clickhouse-server docker run -d --name some-clickhouse-server --ulimit n…

React 组件样式

在这里插入图片描述 分为行内和css文件控制 行内 通过CSS中类名文件控制

利用 pyecharts 实现地图的数据可视化——第七次人口普查数据的2d、3d展示(关键词:2d 、3d 、map、 geo、涟漪点)

参考文档&#xff1a;链接: link_pyecharts 官方文档 1、map() 传入省份全称&#xff0c;date_pair 是列表套列表 [ [ ],[ ] … ] 2、geo() 传入省份简称&#xff0c;date_pair 是列表套元组 [ ( ),( ) … ] 1、准备数据 population_data&#xff1a;简称经纬度 population_da…

解决 Elasticsearch 分页查询性能瓶颈——从10分钟到秒级的优化实践

大家好&#xff0c;我是铭毅天下&#xff0c;一名专注于 Elasticsearch &#xff08;以下简称ES&#xff09;技术栈的技术爱好者。 今天我们来聊聊球友提出的一个实际问题&#xff1a; ES分页查询性能很差&#xff0c;使用from/size方式检索居然需要10分钟&#xff01; 这是一个…

记录IBM服务器检测到备份GPT损坏警告排查解决过程

服务器设备&#xff1a;IBM x3550 M4 Server IMM默认IP地址&#xff1a;192.168.70.125 用户名&#xff1a;USERID 密码&#xff1a;PASSW0RD&#xff08;注意是零0&#xff09; 操作系统&#xff1a;Windows Hyper-V Server 2016 IMM Web System Status Warning&#xff1…

毫米波测试套装速递!高效赋能5G/6G、新材料及智能超表面(RIS)研发

德思特&#xff08;Tesight&#xff09;作为全球领先的测试测量解决方案提供商&#xff0c;始终致力于为前沿技术研发提供高精度、高效率的测试工具。 针对毫米波技术在高频通信、智能超表面&#xff08;RIS&#xff09;、新材料等领域的快速应用需求&#xff0c;我们推出毫米…

Linux中卸载宝塔面板

输入命令 wget http://download.bt.cn/install/bt-uninstall.sh 执行脚本命令 sh bt-uninstall.sh 根据自己的情况选择1还是2 卸载完成校验 bt 这样我们的宝塔面板就卸载完了

无人机的振动与噪声控制技术!

一、振动控制技术要点 1. 振动源分析 气动振动&#xff1a;旋翼桨叶涡脱落&#xff08;如叶尖涡干涉&#xff09;、动态失速&#xff08;Dynamic Stall&#xff09;引发的周期性气动激振力&#xff08;频率与转速相关&#xff09;。 机械振动&#xff1a;电机偏心、传动轴不…

【蓝桥杯】第十六届蓝桥杯 JAVA B组记录

试题 A: 逃离高塔 很简单&#xff0c;签到题&#xff0c;但是需要注意精度&#xff0c;用int会有溢出风险 答案&#xff1a;202 package lanqiao.t1;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWrit…

OSPF的接口网络类型【复习篇】

OSPF在不同网络环境下默认的不同工作方式 [a3]display ospf interface g 0/0/0 # 查看ospf接口的网络类型网络类型OSPF接口的网络类型&#xff08;工作方式&#xff09;计时器BMA&#xff08;以太网&#xff09;broadcast &#xff0c;需要DR/BDR的选举hello&#xff1a;10s…

python+requests接口自动化测试框架实例教程

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 前段时间由于公司测试方向的转型&#xff0c;由原来的web页面功能测试转变成接口测试&#xff0c;之前大多都是手工进行&#xff0c;利用postman和jmeter进行…

2021第十二届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、空间-&#xff08;题解&#xff09;-字节单位转换 2、卡片-&#xff08;题解&#xff09;-可以不用当组合来写&#xff0c;思维题 3、直…

智能资源管理机制-重传机制

一、发送端资源管理的核心机制 1. 滑动窗口&#xff08;Sliding Window&#xff09; 这是TCP协议的核心优化设计&#xff1a; 窗口动态滑动&#xff1a;发送端不需要保留所有已发送的分组&#xff0c;只需维护一个"发送窗口"窗口大小&#xff1a;由接收方通告的接…

设计模式 --- 原型模式

原型模式是创建型模式的一种&#xff0c;是在一个原型的基础上&#xff0c;建立一致的复制对象的方式。这个原型通常是我们在应用程序生命周期中需要创建多次的一个典型对象。为了避免初始化新对象潜在的性能开销&#xff0c;我们可以使用原型模式来建立一个非常类似于复印机的…

汽车软件开发常用的建模工具汇总

目录 往期推荐 1.Enterprise Architect&#xff08;EA&#xff09; 2.MATLAB/Simulink 3.TargetLink 4.Rational Rhapsody 5.AUTOSAR Builder 6.PREEvision 总结 往期推荐 2025汽车行业新宠&#xff1a;欧企都在用的工具软件ETAS工具链自动化实战指南&#xff1c;一&am…

SSM废品买卖回收管理系统的设计与实现

&#x1f345;点赞收藏关注 → 添加文档最下方联系方式咨询本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 项目视频 07…