C++课设:实现本地留言板系统(支持留言、搜索、标签、加密等)

news2025/6/10 5:32:49

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
专栏介绍:《编程项目实战》

目录

    • 一、项目功能概览与亮点分析
      • 1. 核心功能模块
      • 2. 技术特色
    • 二、系统架构设计分析
      • 1. 整体架构图
      • 2. 数据结构设计
    • 三、核心功能实现详解
      • 1. 加密机制:简单而实用的凯撒密码
      • 2. 数据持久化:序列化的艺术
      • 3. 智能搜索:多维度查找
    • 四、完整源代码展示
    • 五、编译运行与使用指南
      • 1. 编译环境要求
      • 2. 编译命令
      • 3. 运行效果
      • 4. 使用技巧
    • 六、项目总结与扩展思路
      • 1. 学到的知识点
      • 2. 可扩展的方向

在学习C++的过程中,很多同学都希望能够做一个真正有用的项目来巩固所学知识。今天我们就来分析一个功能完整的本地留言板系统,它集成了面向对象编程、文件操作、数据加密等多个知识点,是练手的绝佳项目!

一、项目功能概览与亮点分析

这个留言板系统虽然是本地版本,但功能相当丰富。让我们先看看它都能做什么:

1. 核心功能模块

  • 📝 留言管理:添加、删除、查看留言
  • 🔍 智能搜索:支持按作者、内容、标签搜索
  • 🏷️ 标签系统:留言分类管理,支持多标签
  • 🔐 加密功能:重要留言可加密存储
  • 📊 数据统计:留言数量、热门标签统计
  • 💾 持久化存储:本地文件自动保存

2. 技术特色

这个项目的设计有几个值得学习的亮点:

  • 面向对象设计:使用MessageMessageBoard两个核心类
  • 数据持久化:实现了完整的文件读写机制
  • 简单加密:采用凯撒密码保护隐私内容
  • 用户友好:清晰的菜单界面和操作提示

二、系统架构设计分析

1. 整体架构图

在这里插入图片描述

2. 数据结构设计

Message结构体是整个系统的基础数据单元,它不仅存储了留言的基本信息,还提供了完整的序列化机制:

struct Message {
    int id;              // 唯一标识
    string author;       // 作者
    string content;      // 内容(可能已加密)
    string tags;         // 标签
    long timestamp;      // 时间戳
    bool encrypted;      // 是否加密
}

这种设计的巧妙之处在于将数据和操作封装在一起,每个Message对象都能自己完成序列化和反序列化操作。

三、核心功能实现详解

1. 加密机制:简单而实用的凯撒密码

系统采用凯撒密码来实现加密功能。虽然这不是最安全的加密方法,但对于学习项目来说既简单又实用:

string encrypt(const string& text, int shift = 3) {
    string result = text;
    for (size_t i = 0; i < result.length(); i++) {
        if (result[i] >= 'a' && result[i] <= 'z') {
            result[i] = 'a' + (result[i] - 'a' + shift) % 26;
        } else if (result[i] >= 'A' && result[i] <= 'Z') {
            result[i] = 'A' + (result[i] - 'A' + shift) % 26;
        }
    }
    return result;
}

实现原理:将每个字母按照字母表顺序向后移动3位,Z之后回到A,形成一个循环。这样"Hello"就会变成"Khoor"。

2. 数据持久化:序列化的艺术

为了将复杂的Message对象保存到文件中,系统实现了一套完整的序列化机制

// 序列化:对象 → 字符串
string serialize() const {
    stringstream ss;
    ss << id << "|" << author << "|" << content << "|" 
       << tags << "|" << timestamp << "|" << (encrypted ? 1 : 0);
    return ss.str();
}

// 反序列化:字符串 → 对象
static Message deserialize(const string& line) {
    Message msg;
    stringstream ss(line);
    string item;
    
    if (getline(ss, item, '|')) msg.id = atoi(item.c_str());
    if (getline(ss, item, '|')) msg.author = item;
    // ... 其他字段类似处理
    
    return msg;
}

这种设计让每个Message对象都能"自己说话",告诉系统怎样把自己保存到文件里,又怎样从文件里重新"复活"。

3. 智能搜索:多维度查找

系统的搜索功能支持在作者、内容、标签三个维度进行查找:

void searchMessages() {
    string keyword;
    cout << "\n请输入搜索关键词: ";
    getline(cin, keyword);
    
    for (size_t i = 0; i < messages.size(); i++) {
        const Message& msg = messages[i];
        string searchContent = msg.getDisplayContent(); // 自动解密
        
        // 多维度搜索
        if (msg.author.find(keyword) != string::npos ||
            searchContent.find(keyword) != string::npos ||
            msg.tags.find(keyword) != string::npos) {
            results.push_back(msg);
        }
    }
}

注意这里调用了getDisplayContent()方法,它会自动处理加密内容的解密,让用户搜索时无需关心数据是否被加密。

四、完整源代码展示

为了让大家能够完整理解和运行这个项目,这里提供完整的源代码:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <time.h>  // 使用C风格的time.h而不是ctime
#include <algorithm>
#include <sstream>
#include <cstdlib>

using namespace std;

// 简单的加密解密函数(凯撒密码)
string encrypt(const string& text, int shift = 3) {
    string result = text;
    for (size_t i = 0; i < result.length(); i++) {
        if (result[i] >= 'a' && result[i] <= 'z') {
            result[i] = 'a' + (result[i] - 'a' + shift) % 26;
        } else if (result[i] >= 'A' && result[i] <= 'Z') {
            result[i] = 'A' + (result[i] - 'A' + shift) % 26;
        }
    }
    return result;
}

string decrypt(const string& text, int shift = 3) {
    return encrypt(text, 26 - shift);
}

// 简单的标签计数结构
struct TagCount {
    string tag;
    int count;
    TagCount() : count(0) {}
    TagCount(const string& t, int c) : tag(t), count(c) {}
};

// 留言结构体
struct Message {
    int id;
    string author;
    string content;
    string tags;
    long timestamp;  // 使用long而不是time_t来避免兼容性问题
    bool encrypted;
    
    Message() : id(0), timestamp(0), encrypted(false) {}
    
    Message(int _id, const string& _author, const string& _content, 
            const string& _tags, bool _encrypted = false) 
        : id(_id), author(_author), content(_content), tags(_tags), encrypted(_encrypted) {
        timestamp = (long)time(NULL);  // 显式转换为long
    }
    
    // 获取格式化的时间字符串
    string getTimeString() const {
        time_t t = (time_t)timestamp;
        struct tm* timeinfo = localtime(&t);
        
        // 手动格式化时间字符串,避免使用strftime
        char buffer[100];
        sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
                timeinfo->tm_year + 1900,
                timeinfo->tm_mon + 1,
                timeinfo->tm_mday,
                timeinfo->tm_hour,
                timeinfo->tm_min,
                timeinfo->tm_sec);
        return string(buffer);
    }
    
    // 获取显示用的内容(解密后)
    string getDisplayContent() const {
        if (encrypted) {
            return decrypt(content);
        }
        return content;
    }
    
    // 序列化为字符串(用于文件存储)
    string serialize() const {
        stringstream ss;
        ss << id << "|" << author << "|" << content << "|" 
           << tags << "|" << timestamp << "|" << (encrypted ? 1 : 0);
        return ss.str();
    }
    
    // 从字符串反序列化
    static Message deserialize(const string& line) {
        Message msg;
        stringstream ss(line);
        string item;
        
        // 解析各个字段
        if (getline(ss, item, '|')) msg.id = atoi(item.c_str());
        if (getline(ss, item, '|')) msg.author = item;
        if (getline(ss, item, '|')) msg.content = item;
        if (getline(ss, item, '|')) msg.tags = item;
        if (getline(ss, item, '|')) msg.timestamp = atol(item.c_str());
        if (getline(ss, item, '|')) msg.encrypted = (atoi(item.c_str()) != 0);
        
        return msg;
    }
};

// 留言板类
class MessageBoard {
private:
    vector<Message> messages;
    string filename;
    int nextId;
    
public:
    MessageBoard(const string& file = "messages.txt") : filename(file), nextId(1) {
        loadFromFile();
    }
    
    ~MessageBoard() {
        saveToFile();
    }
    
    // 添加留言
    void addMessage() {
        string author, content, tags;
        char choice;
        bool encrypted = false;
        
        cout << "\n=== 添加新留言 ===" << endl;
        cout << "作者: ";
        cin.ignore();
        getline(cin, author);
        
        cout << "留言内容: ";
        getline(cin, content);
        
        cout << "标签 (用逗号分隔,如: 生活,心情): ";
        getline(cin, tags);
        
        cout << "是否加密此留言? (y/n): ";
        cin >> choice;
        
        if (choice == 'y' || choice == 'Y') {
            encrypted = true;
            content = encrypt(content);
        }
        
        Message msg(nextId++, author, content, tags, encrypted);
        messages.push_back(msg);
        
        cout << "留言添加成功!" << endl;
        saveToFile();
    }
    
    // 显示所有留言
    void displayAllMessages() {
        if (messages.empty()) {
            cout << "\n暂无留言。" << endl;
            return;
        }
        
        // 按时间排序(最新的在前)
        vector<Message> sortedMessages = messages;
        sort(sortedMessages.begin(), sortedMessages.end(), compareByTime);
        
        cout << "\n=== 所有留言 ===" << endl;
        for (size_t i = 0; i < sortedMessages.size(); i++) {
            displayMessage(sortedMessages[i]);
            cout << "----------------------------------------" << endl;
        }
    }
    
    // 搜索功能
    void searchMessages() {
        string keyword;
        cout << "\n请输入搜索关键词: ";
        cin.ignore();
        getline(cin, keyword);
        
        vector<Message> results;
        
        for (size_t i = 0; i < messages.size(); i++) {
            const Message& msg = messages[i];
            string searchContent = msg.getDisplayContent();
            
            // 在作者、内容、标签中搜索
            if (msg.author.find(keyword) != string::npos ||
                searchContent.find(keyword) != string::npos ||
                msg.tags.find(keyword) != string::npos) {
                results.push_back(msg);
            }
        }
        
        if (results.empty()) {
            cout << "未找到包含关键词 \"" << keyword << "\" 的留言。" << endl;
            return;
        }
        
        cout << "\n=== 搜索结果 (" << results.size() << " 条) ===" << endl;
        for (size_t i = 0; i < results.size(); i++) {
            displayMessage(results[i]);
            cout << "----------------------------------------" << endl;
        }
    }
    
    // 按标签过滤
    void filterByTag() {
        string tag;
        cout << "\n请输入标签: ";
        cin.ignore();
        getline(cin, tag);
        
        vector<Message> results;
        
        for (size_t i = 0; i < messages.size(); i++) {
            if (messages[i].tags.find(tag) != string::npos) {
                results.push_back(messages[i]);
            }
        }
        
        if (results.empty()) {
            cout << "未找到标签为 \"" << tag << "\" 的留言。" << endl;
            return;
        }
        
        cout << "\n=== 标签筛选结果 (" << results.size() << " 条) ===" << endl;
        for (size_t i = 0; i < results.size(); i++) {
            displayMessage(results[i]);
            cout << "----------------------------------------" << endl;
        }
    }
    
    // 显示统计信息
    void showStatistics() {
        cout << "\n=== 留言板统计 ===" << endl;
        cout << "总留言数: " << messages.size() << endl;
        
        int encryptedCount = 0;
        for (size_t i = 0; i < messages.size(); i++) {
            if (messages[i].encrypted) {
                encryptedCount++;
            }
        }
        cout << "加密留言数: " << encryptedCount << endl;
        
        // 统计标签
        vector<TagCount> tagCounts;
        
        for (size_t i = 0; i < messages.size(); i++) {
            string tags = messages[i].tags;
            stringstream ss(tags);
            string tag;
            
            while (getline(ss, tag, ',')) {
                // 去除空格
                while (!tag.empty() && tag[0] == ' ') {
                    tag = tag.substr(1);
                }
                while (!tag.empty() && tag[tag.length()-1] == ' ') {
                    tag = tag.substr(0, tag.length()-1);
                }
                
                if (!tag.empty()) {
                    // 查找是否已存在
                    bool found = false;
                    for (size_t j = 0; j < tagCounts.size(); j++) {
                        if (tagCounts[j].tag == tag) {
                            tagCounts[j].count++;
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        tagCounts.push_back(TagCount(tag, 1));
                    }
                }
            }
        }
        
        if (!tagCounts.empty()) {
            cout << "\n热门标签:" << endl;
            for (size_t i = 0; i < tagCounts.size(); i++) {
                cout << "  " << tagCounts[i].tag << ": " << tagCounts[i].count << " 次" << endl;
            }
        }
    }
    
    // 删除留言功能
    void deleteMessage() {
        if (messages.empty()) {
            cout << "\n暂无留言可删除。" << endl;
            return;
        }
        
        cout << "\n请输入要删除的留言ID: ";
        int id;
        cin >> id;
        
        for (vector<Message>::iterator it = messages.begin(); it != messages.end(); ++it) {
            if (it->id == id) {
                cout << "确认删除以下留言?(y/n)" << endl;
                displayMessage(*it);
                
                char choice;
                cin >> choice;
                if (choice == 'y' || choice == 'Y') {
                    messages.erase(it);
                    cout << "留言删除成功!" << endl;
                    saveToFile();
                } else {
                    cout << "取消删除。" << endl;
                }
                return;
            }
        }
        
        cout << "未找到ID为 " << id << " 的留言。" << endl;
    }
    
private:
    // 显示单条留言
    void displayMessage(const Message& msg) {
        cout << "ID: " << msg.id << endl;
        cout << "作者: " << msg.author << endl;
        cout << "时间: " << msg.getTimeString() << endl;
        cout << "内容: " << msg.getDisplayContent() << endl;
        if (!msg.tags.empty()) {
            cout << "标签: " << msg.tags << endl;
        }
        if (msg.encrypted) {
            cout << "[已加密]" << endl;
        }
    }
    
    // 时间比较函数(用于排序)
    static bool compareByTime(const Message& a, const Message& b) {
        return a.timestamp > b.timestamp; // 降序排列,最新的在前
    }
    
    // 保存到文件
    void saveToFile() {
        ofstream file(filename.c_str());
        if (!file.is_open()) {
            cout << "无法打开文件进行保存!" << endl;
            return;
        }
        
        file << nextId << endl; // 保存下一个ID
        
        for (size_t i = 0; i < messages.size(); i++) {
            file << messages[i].serialize() << endl;
        }
        
        file.close();
    }
    
    // 从文件加载
    void loadFromFile() {
        ifstream file(filename.c_str());
        if (!file.is_open()) {
            return; // 文件不存在,使用默认值
        }
        
        string line;
        if (getline(file, line)) {
            nextId = atoi(line.c_str());
        }
        
        while (getline(file, line)) {
            if (!line.empty()) {
                messages.push_back(Message::deserialize(line));
            }
        }
        
        file.close();
    }
};

// 显示菜单
void showMenu() {
    cout << "\n=== 留言板系统 ===" << endl;
    cout << "1. 添加留言" << endl;
    cout << "2. 查看所有留言" << endl;
    cout << "3. 搜索留言" << endl;
    cout << "4. 按标签筛选" << endl;
    cout << "5. 查看统计信息" << endl;
    cout << "6. 删除留言" << endl;
    cout << "0. 退出系统" << endl;
    cout << "请选择操作: ";
}

int main() {
    MessageBoard board;
    int choice;
    
    cout << "欢迎使用留言板系统!" << endl;
    
    while (true) {
        showMenu();
        cin >> choice;
        
        switch (choice) {
            case 1:
                board.addMessage();
                break;
                
            case 2:
                board.displayAllMessages();
                break;
                
            case 3:
                board.searchMessages();
                break;
                
            case 4:
                board.filterByTag();
                break;
                
            case 5:
                board.showStatistics();
                break;
                
            case 6:
                board.deleteMessage();
                break;
                
            case 0:
                cout << "感谢使用,再见!" << endl;
                return 0;
                
            default:
                cout << "无效选择,请重新输入。" << endl;
                break;
        }
        
        cout << "\n按回车键继续...";
        cin.ignore();
        cin.get();
    }
    
    return 0;
}

五、编译运行与使用指南

1. 编译环境要求

  • 编译器:支持C++98标准的任意编译器(g++、clang++、Visual Studio等)
  • 操作系统:Windows、Linux、macOS均可
  • 依赖库:仅使用C++标准库,无需额外安装

2. 编译命令

# Linux/macOS
g++ -o message_board message_board.cpp

# Windows (使用MinGW)
g++ -o message_board.exe message_board.cpp

3. 运行效果

程序启动后会显示友好的菜单界面:

欢迎使用留言板系统!

=== 留言板系统 ===
1. 添加留言
2. 查看所有留言  
3. 搜索留言
4. 按标签筛选
5. 查看统计信息
6. 删除留言
0. 退出系统
请选择操作: 

在这里插入图片描述

4. 使用技巧

  • 标签功能:添加留言时可以使用多个标签,用逗号分隔,如"学习,编程,C++"
  • 加密功能:选择加密的留言在文件中以密文存储,但显示时会自动解密
  • 搜索功能:支持模糊搜索,会在作者、内容、标签三个字段中查找

六、项目总结与扩展思路

这个留言板系统虽然简单,但涵盖了C++开发的多个重要概念:

1. 学到的知识点

  • 面向对象编程:类的设计、封装、构造函数
  • STL容器vector的使用和迭代器操作
  • 文件操作fstream进行数据持久化
  • 字符串处理stringstream进行数据解析
  • 算法应用:排序、搜索算法的实际运用

2. 可扩展的方向

如果你想进一步完善这个项目,可以考虑以下方向:

  • 🔐 安全性提升:使用更强的加密算法,如AES
  • 🗄️ 数据库支持:集成SQLite实现更高效的数据管理
  • 🌐 网络功能:添加网络模块,支持多用户协作
  • 🎨 图形界面:使用Qt或其他GUI库创建可视化界面
  • 📱 移动端适配:适配移动设备,开发跨平台应用

总的来说,这个留言板系统是一个非常适合C++初学者的练手项目。它不仅能让你巩固基础语法,更能让你体验到完整软件开发的全过程。通过这个项目,你会发现编程不仅仅是写代码,更是解决实际问题的艺术!

希望这个项目能激发你对C++编程的兴趣,也期待看到你基于这个项目开发出更加精彩的应用!

创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

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

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

相关文章

【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2

----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导&#xff0c;采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…

Xcode 16.2 版本 pod init 报错

Xcode 版本升级到 16.2 后&#xff0c;项目执行 pod init 报错&#xff1b; ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchron…

timestamp时间戳转换工具

作为一名程序员&#xff0c;一款高效的 在线转换工具 &#xff08;在线时间戳转换 计算器 字节单位转换 json格式化&#xff09;必不可少&#xff01;https://jsons.top 排查问题时非常痛的点: 经常在秒级、毫秒级、字符串格式的时间单位来回转换&#xff0c;于是决定手撸一个…

数据库管理与高可用-MySQL故障排查与生产环境优化

目录 #1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 1.1.2MySQL主从故障排查 #2.1MySQL优化 2.1.1硬件方面的优化 2.1.2进程方面的优化 #3.1MySQL存储引擎 3.1.1 MyISAM存储引擎 3.1.2 InnoDB存储引擎 1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 &#xff08;1&…

LangChain + LangSmith + DeepSeek 入门实战:构建代码生成助手

本文基于 Jupyter Notebook 实践代码&#xff0c;结合 LangChain、LangSmith 和 DeepSeek 大模型&#xff0c;手把手演示如何构建一个代码生成助手&#xff0c;并实现全流程追踪与优化。 一、环境准备与配置 1. 安装依赖 pip install langchain langchain_openai2. 设置环境变…

【Elasticsearch基础】Elasticsearch批量操作(Bulk API)深度解析与实践指南

目录 1 Bulk API概述 1.1 什么是批量操作 1.2 Bulk API的优势 2 Bulk API的工作原理 2.1 请求处理流程 2.2 底层机制 3 Bulk API的使用方法 3.1 基本请求格式 3.2 操作类型示例 3.3 响应格式 4 Bulk API的最佳实践 4.1 批量大小优化 4.2 错误处理策略 4.3 性能调…

MySQL 数据库深度剖析:事务、SQL 优化、索引与 Buffer Pool

在当今数据驱动的时代&#xff0c;数据库作为数据存储与管理的核心&#xff0c;其性能与可靠性至关重要。MySQL 作为一款广泛使用的开源数据库&#xff0c;在众多应用场景中发挥着关键作用。在这篇博客中&#xff0c;我将围绕 MySQL 数据库的核心知识展开&#xff0c;涵盖事务及…

MAZANOKE结合内网穿透技术实现跨地域图像优化服务的远程访问过程

文章目录 前言1. 关于MAZANOKE2. Docker部署3. 简单使用MAZANOKE4. 安装cpolar内网穿透5. 配置公网地址6. 配置固定公网地址总结 前言 在数字世界高速发展的今天&#xff0c;您是否察觉到那些静默增长的视觉数据正在悄然蚕食存储空间&#xff1f;随着影像记录成为日常习惯&…

World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored

https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…

信息收集:从图像元数据(隐藏信息收集)到用户身份的揭秘 --- 7000

目录 &#x1f310; 访问Web服务 &#x1f4bb; 分析源代码 ⬇️ 下载图片并保留元数据 &#x1f50d; 提取元数据&#xff08;重点&#xff09; &#x1f464; 生成用户名列表 &#x1f6e0;️ 技术原理 图片元数据&#xff08;EXIF 数据&#xff09; Username-Anarch…

如何优雅地绕过限制调用海外AI-API?反向代理与API中转技术详解​

阅读时长​​ | 8分钟 ​​适用读者​​ | 需要跨境调用OpenAI等AI服务的开发者/企业 ​​一、问题背景&#xff1a;为什么需要代理&#xff1f;​​ 最近在技术社区看到这样的求助&#xff1a; "公司服务器在国内&#xff0c;但业务需要调用OpenAI接口&#xff0c;直接访…

【自然语言处理】大模型时代的数据标注(主动学习)

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计E 个人总结 A 论文出处 论文题目&#xff1a;FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models发表情况&#xff1a;2023-EMNLP作者单位&#xff1a;浙江大…

React与原生事件:核心差异与性能对比解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…

暴雨新专利解决服务器噪音与性能悖论

6月1日&#xff0c;我国首部数据中心绿色化评价方面国家标准《绿色数据中心评价》正式实施&#xff0c;为我国数据中心的绿色低碳建设提供了明确指引。《评价》首次将噪音控制纳入国家级绿色评价体系&#xff0c;要求从设计隔声结构到运维定期监测实现闭环管控&#xff0c;加速…

Go 语言中的内置运算符

1. 算术运算符 注意&#xff1a; &#xff08;自增&#xff09;和--&#xff08;自减&#xff09;在 Go 语言中是单独的语句&#xff0c;并不是运算符。 package mainimport "fmt"func main() {fmt.Println("103", 103) // 13fmt.Println("10-3…

JS面试常见问题——数据类型篇

这几周在进行系统的复习&#xff0c;这一篇来说一下自己复习的JS数据结构的常见面试题中比较重要的一部分 文章目录 一、JavaScript有哪些数据类型二、数据类型检测的方法1. typeof2. instanceof3. constructor4. Object.prototype.toString.call()5. type null会被判断为Obje…

【靶场】XXE-Lab xxe漏洞

前言 学习xxe漏洞,搭了个XXE-Lab的靶场 一、搭建靶场 现在需要登录,不知道用户名密码,先随便试试抓包 二、判断是否存在xxe漏洞 1.首先登录抓包 看到xml数据解析,由此判断和xxe漏洞有关,但还不确定xxe漏洞是否存在。 2.尝试xxe 漏洞 判断是否存在xxe漏洞 A.send to …

开源项目实战学习之YOLO11:12.6 ultralytics-models-tiny_encoder.py

👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 ultralytics-models-sam 1.sam-modules-tiny_encoder.py2.数据处理流程3.代码架构图(类层次与依赖)blocks.py: 定义模型中的各种模块结构 ,如卷积块、残差块等基础构建…

Python[数据结构及算法 --- 栈]

一.栈的概念 在 Python 中&#xff0c;栈&#xff08;Stack&#xff09;是一种 “ 后进先出&#xff08;LIFO&#xff09;”的数据结构&#xff0c;仅允许在栈顶进行插入&#xff08;push&#xff09;和删除&#xff08;pop&#xff09;操作。 二.栈的抽象数据类型 1.抽象数…

Unity VR/MR开发-开发环境准备

视频讲解链接&#xff1a; 【XR马斯维】UnityVR/MR开发环境准备【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili