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

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

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》
创作者: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);// 手动格式化时间字符串,避免使用strftimechar 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; // 保存下一个IDfor (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😊)

相关文章:

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

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏介绍&#xff1a;《编程项目实战》 目录 一、项目功能概览与亮点分析1. 核心功能…...

【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器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;于是决定手撸一个…...

分布式计算框架学习笔记

一、&#x1f310; 为什么需要分布式计算框架&#xff1f; 资源受限&#xff1a;单台机器 CPU/GPU 内存有限。 任务复杂&#xff1a;模型训练、数据处理、仿真并发等任务耗时严重。 并行优化&#xff1a;通过任务拆分和并行执行提升效率。 可扩展部署&#xff1a;适配从本地…...

数据库管理与高可用-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&…...

rk3506上移植lvgl应用

本文档介绍如何在开发板上运行以及移植LVGL。 1. 移植准备 硬件环境:开发板及其配套屏幕 开发板镜像 主机环境:Ubuntu 22.04.5 2. LVGL启动 ​ 出厂系统默认配置了 LVGL,并且上电之后默认会启动 一个LVGL应用 。 LVGL 的启动脚本为/etc/init.d/pre_init/S00-lv_demo,…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术点解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术点解析 第一轮&#xff1a;基础概念问题 请解释Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; 程序员JY回答&#xff1a;Spring框架的核心容器是IoC容器&#xff08;控制反转…...

Flask和Django,你怎么选?

Flask 和 Django 是 Python 两大最流行的 Web 框架&#xff0c;但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比&#xff1a; 核心区别&#xff1a;哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...

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

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

湖北理元理律师事务所:债务清偿方案中的法律技术革新

文/金融法律研究组 当前债务服务市场存在结构性矛盾&#xff1a;债权人追求快速回款&#xff0c;债务人需要喘息空间。湖北理元理律师事务所通过创新法律技术&#xff0c;在《企业破产法》《民法典》框架下构建梯度清偿模型&#xff0c;实现多方利益平衡。 一、个人债务优化的…...

大模型的LoRa通讯详解与实现教程

一、LoRa通讯技术概述 LoRa(Long Range)是一种低功耗广域网(LPWAN)通信技术,由Semtech公司开发,特别适合于物联网设备的长距离、低功耗通信需求。LoRa技术基于扩频调制技术,能够在保持低功耗的同时实现数公里甚至数十公里的通信距离。 LoRa的主要特点 长距离通信:在城…...

【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 性能调…...

PCA笔记

✅ 问题本质&#xff1a;为什么让矩阵 TT 的行列式为 1&#xff1f; 这个问题通常出现在我们对数据做**线性变换&#xff08;旋转/缩放&#xff09;**的时候&#xff0c;比如在 PCA 中把数据从原始坐标系变换到主成分方向时。 &#x1f4cc; 回顾一下背景 在 PCA 中&#xff…...

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

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

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

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

迁移科技3D视觉系统:重塑纸箱拆垛场景的智能革命

一、传统拆垛场景的困局与破局之道 在汽车零部件仓库中&#xff0c;每天有超过2万只异形纸箱需要拆垛分拣。传统人工拆垛面临三大挑战&#xff1a; 效率瓶颈&#xff1a;工人每小时仅能处理200-300件&#xff0c;且存在间歇性疲劳安全隐患&#xff1a;20kg以上重箱搬运导致年…...

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 ); --------…...

JS的传统写法 vs 简写形式

一、条件判断与逻辑操作 三元运算符简化条件判断 // 传统写法 let result; if (someCondition) {result yes; } else {result no; }// 简写方式 const result someCondition ? yes : no;短路求值 // 传统写法 if (condition) {doSomething(); }// 简写方式 condition &…...

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

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

OCC笔记:TDF_Label中有多个相同类型属性

注&#xff1a;OCCT版本&#xff1a;7.9.1 TDF_Label中有多个相同类型的属性的方案 OCAF imposes the restriction that only one attribute type may be allocated to one label. It is necessary to take into account the design of the application data tree. For exampl…...

如何优雅地绕过限制调用海外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…...

Go 并发编程基础:select 多路复用

select 是 Go 并发编程中非常强大的语法结构&#xff0c;它允许程序同时等待多个通道操作的完成&#xff0c;从而实现多路复用机制&#xff0c;是协程调度、超时控制、通道竞争等场景的核心工具。 一、什么是 select select 类似于 switch 语句&#xff0c;但它用于监听多个通…...

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

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…...

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南 在金融行业安全审计中&#xff0c;未启用HTTPS的Web应用被列为高危漏洞。通过正确配置HTTPS&#xff0c;可将中间人攻击风险降低98%——本文将全面解析Spring Boot中HTTPS的实现方案与实战避坑指南。 一、HTTPS 核心原理与…...

项目研究:使用 LangGraph 构建智能客服代理

概述 本教程展示了如何使用 LangGraph 构建一个智能客服代理。LangGraph 是一个强大的工具&#xff0c;可用于构建复杂的语言模型工作流。该代理可以自动分类用户问题、分析情绪&#xff0c;并根据需要生成回应或升级处理。 背景动机 在当今节奏飞快的商业环境中&#xff0c…...

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

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