Protobuf的速成之旅
注意事项:本文使用Linux下的Ubuntu C/C++
一.Protobuf的安装
在安装Protobuf前需要先安装protobuf的依赖库
sudo apt-get install autoconf automake libtool curl make g++ unzip -y
Protobuf的安装链接:https://github.com/protocolbuffers/protobuf/releases
这里根据自己的环境选择安装
安装后对protobuf文件进行解压缩
如图所示,紧接着进入到文件中
进行protobuf的安装
第⼀步执⾏ autogen.sh ,
./autogen.sh 但如果下载的是具体的某⼀⻔语⾔,不需要执⾏这⼀步。
# 第⼆步执⾏ configure ,有两种执⾏⽅式,任选其⼀即可,
如下:
# 1 、 protobuf 默认安装在 /usr/local ⽬录, lib 、 bin 都是分散的 ./configure
# 2 、修改安装⽬录,统⼀安装在 /usr/local/protobuf 下
./configure --prefix=/usr/local/protobuf
make// 执⾏ 15 分钟左右
make check
sudo make install //执行15分钟左右
若make check因服务器运行内存小而失败,可以调大swap分区至5G,若还是失败,可以跳过此步。
若你在执行./configure选择了第二步,需要进行以下操作,反之不需要
sudo vim /etc/profile
# 添加内容如下:
#( 动态库搜索路径 ) 程序加载运⾏期间查找动态链接库时指定除了系统默认路径之外的其他路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib/
#( 静态库搜索路径 ) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib/
# 执⾏程序搜索路径
export PATH=$PATH:/usr/local/protobuf/bin/
#c 程序头⽂件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c++ 程序头⽂件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
source /etc/profile
再执行以下以上命令就可以使用protobuf了
通过 protoc --version检查是否安装成功,若出现version,则安装成功。
二.Protobuf的运行和编译
1.protobuf文件:文件以.proto为后缀
如:
//语法指定行
syntax="proto3";
//相当于命名域
package contacts;
message PeopleInfo{string name=1;int32 age=2;
}
基本的格式
proto3也可以换成proto2,这里我们使用proto3
package就是c++的namespace
mssage就是c++的类 class
后面的数字代表字段唯一编号,用来唯一标识字段
在这⾥还要特别讲解⼀下字段唯⼀编号的范围: 1~536,870,911(2^29-1) ,其中19000~19999不可⽤。 19000 ~19999不可⽤是因为:在Protobuf协议的实现中,对这些数进⾏了预留。如果⾮要在.proto ⽂件中使⽤这些预留标识号,例如将name字段的编号设置为19000,编译时就会报警
此外值得⼀提的是,范围为1~15的字段编号需要⼀个字节进⾏编码,16~2047内的数字需要两个字节 进⾏编码。编码后的字节不仅只包含了编号,还包含了字段类型。所以1~15要⽤来标记出现⾮常频 繁的字段,要为将来有可能添加的、频繁出现的字段预留⼀些出来。
Protobuf 类型 | C++ 类型 |
---|---|
double | double |
float | float |
int32 | int32_t |
int64 | int64_t |
uint32 | uint32_t |
uint64 | uint64_t |
sint32 | int32_t |
sint64 | int64_t |
fixed32 | uint32_t |
fixed64 | uint64_t |
sfixed32 | int32_t |
sfixed64 | int64_t |
bool | bool |
string | std::string |
bytes | std::string |
以上是Protobuf 与 C++类型对照表
需要注意的是对于,若是负数可以选择sint代替int,因为编码效率更高
2.编译.proto文件
protoc --cpp_out=. contacts.proto
1. --cpp_out是选择语言
2. =后面是编译后文件的放置路径
3. contacts.proto 是被编译文件
protoc -h
若是遇到不知道可以通过以上命令进行查询。
最后会生成以下两个文件
以下是简单的运用
#include<iostream>
#include<string>
#include"contacts.pb.h"int main()
{//protobuf是二进制存储的 contacts::PeopleInfo pinf;std::string people_str;pinf.set_age(18);pinf.set_name("张三");pinf.SerializeToString(&people_str);std::cout<<"序列化结果: "<<people_str<<std::endl;contacts::PeopleInfo dpinf;dpinf.ParseFromString(people_str);std::cout<<"反序列化结果:"<<std::endl;std::cout<<"name :"<<dpinf.name()<<'\n';std::cout<<"age :"<<dpinf.age()<<'\n';return 0;
}
g++ -o testPb contacts.cc contacts.pb.cc -std=c++11 -lprotobuf
需要和contacts.pb.cc一起编译,并且要c++11以上,要链接protobuf库 -lprotobuf
最后是运行结果:
注意:protobuf是以二进制的方式存储在文件中,所以我们序列化的结果可能跟我们想看到的内容不一样
三.protobuf .proto文件的语法与运用
本文会通过实践进行教学。
跟C++里的类一样可以嵌套使用,可以讲Phone的定义写在PeopleInfo的外面,也可以也在里面,
若是写在里面,他的类型就是PeopleInfo_Phone,就跟C++中的 PeopleInfo::Phone xxx差不多。
这里的repeated就相当于数组,可以有多个值。
此外可还可以用singular字段修饰
该字段的规则是消息中可以包含该字段零次或⼀次(不超过⼀次)。proto3语法中,字段默认使⽤该 规则。
//语法指定行
syntax="proto3";
//相当于命名域
package contacts;
message Phone
{string num=1;
}
message PeopleInfo{string name=1;int32 age=2;repeated Phone phone=3;
}
message Contacts
{repeated PeopleInfo contacts=1;
}
紧接着我们用这个.proto生成的头文件编写一段代码试试:
#include <iostream>
#include <string>
#include <fstream>
#include "contacts.pb.h"
void AddPeopleInfo(contacts::PeopleInfo *pinfo)
{std::cout << "-------------新增联系人-------------" << std::endl;std::cout << "请输入姓名:";std::string name;std::getline(std::cin, name);std::cout << "请输入年龄:";int32_t age;std::cin >> age;pinfo->set_age(age);pinfo->set_name(name);std::cin.ignore(256, '\n');for (int i = 1;; i++){std::cout << "请输入第" << i << "个电话号码:";std::string num;std::getline(std::cin, num);contacts::Phone *ph = pinfo->add_phone();if (num.size())ph->set_num(num);elsebreak;}std::cout << "-------------添加联系人成功-------------" << std::endl;
}
int main()
{contacts::Contacts contacts;std::ifstream in("contacts.bin", std::ios::in | std::ios::binary);if (!in.is_open()){std::cerr << "file not found,create new file for you" << std::endl;}else if (!contacts.ParseFromIstream(&in)){std::cerr << "反序列失败" << std::endl;return -1;}AddPeopleInfo(contacts.add_contacts());std::fstream output("contacts.bin", std::ios::out | std::ios::trunc | std::ios::binary);if (!contacts.SerializeToOstream(&output)){std::cerr << "Failed to write contacts." << std::endl;in.close();output.close(); return -1;}in.close();output.close();return 0;
}
可以看到,
1.对于一个类似C++中的基本数据类型,可以直接使用set_xxx()函数直接设置
2.对于类似C++中的类对象和数组,通过add_xxxx()函数,获取对应指针,然后再给指针指向的数据类使用set_xxx()赋值即可。
运行结果:
contacts.bin:
若是想将二进制形式转换为我们能看懂的文本形式可以通过:
protoc --decode=contacts.Contacts contacts.proto < contacts.bin
--docode=跟的是package.message proto文件 ,因为默认是标准输入,所以需要将标准输入重定向到 contacts.bin
紧接着我们再写一个读取的代码:
1.可以看到通过protobuf生成的类,内置了很多函数方法如 xxx_size(), xxx.xxx() 类似的数组的&获取元素。
2.可以通过xxx.praseXXX()的方式将proto格式的数据转换为具体的proto实例对象。
#include <iostream>
#include <fstream>
#include "contacts.pb.h"
using namespace std;
using namespace contacts;
void PrintfContacts(const Contacts &contacts)
{for (int i = 0; i < contacts.contacts_size(); ++i){const PeopleInfo &people = contacts.contacts(i);cout << "-----------联系人" << i+1 << " -- -- -- -- -- --" << endl;cout<< "姓名:" << people.name() << endl;cout<< "年龄:" << people.age() << endl;int j = 1;for (const Phone &phone : people.phone()){cout << "电话 "<< j++ << ":" << phone.num() << endl;}}
}
int main()
{GOOGLE_PROTOBUF_VERIFY_VERSION;Contacts contacts;fstream input("contacts.bin", ios::in | ios::binary);if (!contacts.ParseFromIstream(&input)){cerr << "Failed to parse contacts." << endl;input.close();return -1;}PrintfContacts(contacts);
}
四.Protobuf基本类型
1.enum类型
enum与c中的enum类似,但有几个注意事项
1.0值常量必须存在,且要作为第⼀个元素。这是为了与proto2的语义兼容:第⼀个元素作为默认 值,且值为0。
2. 枚举类型可以在消息外定义,也可以在消息体内定义(嵌套)。
3. 枚举的常量值在32位整数的范围内。但因负值⽆效因⽽不建议使⽤(与编码规则有关)
4.同级(同层)的枚举类型,各个枚举类型中的常量不能重名。
enum PhoneType
{MP=0;TEL=1;
}
enum PhoneT
{MP=0;
}
可以对于第四种情况会报错。
简单的写一个具体例子
message PeopleInfo{string name=1;int32 age=2;message Phone{string num=1;enum PhoneType{MP=0;TEL=1;}PhoneType type=2;}repeated Phone phone=3;
}
std::cout << "选择此电话类型(1、移动电话 2、固定电话) : ";int type;std::cin >> type;std::cin.ignore(256, '\n');switch (type){case 1:ph->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);break;case 2:ph->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);break;default:std::cout << "⾮法选择,使⽤默认值!" << std::endl;break;}
运行结果如下,可以看到,对于之前没有设置过的电话类型,如联系人张三,他会自动的设置默认值为0的类型。
2.Any类型
Any类型可以简单的理解为C++的template类
//语法指定行
syntax="proto3";
//相当于命名域
package contacts;//引入any类
import "google/protobuf/any.proto";message Address
{string home_addr=1;string unit_addr=2;
}message PeopleInfo{string name=1;int32 age=2;message Phone{string num=1;enum PhoneType{MP=0;TEL=1;}PhoneType type=2;}repeated Phone phone=3;google.protobuf.Any data=4;
}message Contacts
{repeated PeopleInfo contacts=1;
}
contacts::Address addr;std::cout << "请输⼊联系⼈家庭地址: ";std::string home_address;std::getline(std::cin, home_address);addr.set_home_addr(home_address);std::cout << "请输⼊联系⼈单位地址: ";std::string unit_address;std::getline(std::cin,unit_address);addr.set_unit_addr(unit_address);//mutable_data为any类型的数据开辟空间google::protobuf::Any* data=pinfo->mutable_data();//将addr转换为了any类型,并设置在开辟的空间中data->PackFrom(addr);std::cout << "-------------添加联系人成功-------------" << std::endl;
//has_data()看any类型的数据是否有设置,Is<>看data的数据是否为Address 类型if (people.has_data() && people.data().Is<Address>()) {Address address;//UnpackTo将Any类型转换为address 的Address类型people.data().UnpackTo(&address);if (!address.home_addr().empty()) {cout << "家庭地址:" << address.home_addr() << endl;}if (!address.unit_addr().empty()) {cout << "单位地址:" << address.unit_addr() << endl;}}
可以看到对于设置过address的类型会走到if里,并打印相关信息。
3.oneof类型
作用场景:
1.若消息中有很多可选字段,并且将来同时只有⼀个字段会被设置
2.节约内存。
注意事项:
1.可选字段中的字段编号,不能与非可选字段的编号冲突。
2.不能在oneof中使用repeated字段。
3. 将来在设置oneof字段中值时,如果将oneof中的字段设置多个,那么只会保留最后⼀次设置的成员,之前设置的oneof成员会自动清除。
对于1
repeated Phone phone=3;google.protobuf.Any data=4;oneof other_contact{string qq=4;//与data的字段重复标识4string weixin=6;}
message PeopleInfo{string name=1;int32 age=2;message Phone{string num=1;enum PhoneType{MP=0;TEL=1;}PhoneType type=2;}repeated Phone phone=3;google.protobuf.Any data=4;oneof other_contact{string qq=5;string weixin=6;}
}
std::cout << "选择添加⼀个其他联系⽅式(1、qq号2、微信号) : ";int other_contact;std::cin >> other_contact;std::cin.ignore(256, '\n');if (1 == other_contact){std::cout << "请输⼊qq号: ";std::string qq;getline(std::cin, qq);pinfo->set_qq(qq);}else if (2 == other_contact){std::cout << "请输⼊微信号: ";std::string weixin;std::cout << "-------------添加联系人成功-------------" << std::endl;std::getline(std::cin, weixin);pinfo->set_weixin(weixin);}else{std::cout << "⾮法选择,该项设置失败!" << std::endl;}
/*可以选择通过has判断if(people.has_qq()){}else if(people.has_weixin()){}else {}*/
//也可以通过other_contact_case()函数取出枚举值判断switch (people.other_contact_case()) {case PeopleInfo::OtherContactCase::kQq:cout << "qq号: " << people.qq() << endl;break;case PeopleInfo::OtherContactCase::kWeixin:cout << "微信号: " << people.weixin() << endl;break;case PeopleInfo::OtherContactCase::OTHER_CONTACT_NOT_SET:break;}
以上是通过自动生成的othercontactcase枚举类
运行结果:
4.map类型
map<key_type,value_type> xxx = N;
注意事项:
1.key_type 是除了float和bytes类型以外的任意标量类型。
2.map字段不可以⽤repeated修饰
3.map中存⼊的元素是⽆序的
message PeopleInfo{string name=1;int32 age=2;message Phone{string num=1;enum PhoneType{MP=0;TEL=1;}PhoneType type=2;}repeated Phone phone=3;google.protobuf.Any data=4;oneof other_contact{string qq=5;string weixin=6;}map<string,string> remark=7; //备注
}
for (int i = 1;; i++){std::cout << "请输入备注" << i << " 标题(只输入回车完成备注新增) : ";std::string remark_key;std::getline(std::cin, remark_key);if (remark_key.empty()){break;}std::cout << "请输入备注" << i << " 内容: ";std::string remark_value;std::getline(std::cin, remark_value);//mutable_xxxx()开辟空间,可以向该空间进行修改和设置值pinfo->mutable_remark()->insert({remark_key, remark_value});}
if (people.remark_size()){cout << "备注信息: " << endl;}//cbegin() <-> const_begin,迭代器for (auto it = people.remark().cbegin(); it != people.remark().cend();++it){cout << " " << it->first << ": " << it->second << endl;}
相关文章:
Protobuf的速成之旅
注意事项:本文使用Linux下的Ubuntu C/C 一.Protobuf的安装 在安装Protobuf前需要先安装protobuf的依赖库 sudo apt-get install autoconf automake libtool curl make g unzip -y Protobuf的安装链接:https://github.com/protocolbuffers/protobuf/releases 这里根据自己的环…...
使用 Python 监控系统资源
使用 Python 监控系统资源 在开发分布式系统或性能敏感的应用时,实时监控系统资源(如 CPU、内存、磁盘、网络和 GPU 使用率)至关重要。本文介绍一个基于 Python 的 SystemMonitor 类,它以单例模式持续采集系统资源信息࿰…...
【Qt4】Qt4中实现PDF预览
方案一: 在Qt4中预览PDF文件,你可以使用多种方法,但最常见和简单的方法之一是使用第三方库。Qt本身并没有内置直接支持PDF预览的功能,但你可以通过集成如Poppler、MuPDF等库来实现这一功能。下面我将展示如何使用Poppler库在Qt4中…...
从试错到智能决策:Python与强化学习优化自动驾驶策略
从试错到智能决策:Python与强化学习优化自动驾驶策略 一、引言:自动驾驶如何更聪明? 自动驾驶技术的发展,已经从简单的感知与规则控制,迈向更加智能化的强化学习(Reinforcement Learning,RL)决策优化时代。过去,自动驾驶更多依赖 传统算法(如A、Dijkstra路径规划)…...
【免费下载】全国范围的城市用地类型数据
该数据以路网及水系切分得到的交通小区为最小地块,并基于卫星影像、夜间灯光数据、POI数据、手机信令数据对地块进行分类。 需要这份数据,请在文末查看下载方法。 一、数据介绍 该数据的用地类型可分为居住用地、商务办公用地、商业服务用地、工业用地…...
小程序问题(记录版)
1、样式不生效 在h5上生效 但是 小程序上没反应 解决办法:解除组件样式隔离 1、isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值) 2、apply-shared 表示页面 wxs…...
STL之stackqueue
stack的介绍(可以想象成栈) 1.stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作 2.stack是作为容器适配器被实现的,容器适配器即是对特点类封装作为其…...
学习海康VisionMaster之间距检测
一:进一步学习了 今天学习下VisionMaster中的间距检测工具:主要类似于卡尺工具,测量物体的长度或者宽度或者间距 二:开始学习 1:什么是间距检测? 间距测量模块用于检测两特征边缘之间的间距,首…...
【SpringBoot教程】SpringBoot自定义注解与AOP实现切面日志
🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 文章目录 1.前言2.SpringAOP实现切面日志快速入门1.1 创建SpringBoot项目1.2 依赖配置pom.xml1.3 自定义日志注解1.4 配置 AOP 切面1.5 怎么使用呢?1.6 实…...
C++学习之路,从0到精通的征途:stack_queue的模拟实现及deque原理介绍
目录 一.容器适配器 1.什么是适配器 2.STL标准库中stack和queue的底层结构 3.deque的原理介绍 deque是如何借助其迭代器维护其假想连续的结构呢? 头插 尾插 遍历 4.deque的优缺点 二.stack的模拟实现 三.queue的模拟实现 一.容器适配器 1.什么是适配…...
文件上传漏洞篇:upload-labs靶场搭建
一、文件上传漏洞简述 文件上传漏洞是一种常见的Web安全漏洞,当网站或应用程序允许用户上传文件(如图片、文档等)时,若未对上传的文件进行充分的安全检查,攻击者可能利用此漏洞上传恶意文件(如Web Shell、…...
TikTok 矩阵账号运营实操细节:打造爆款矩阵
在 TikTok 的流量版图里,打造 TikTok 矩阵账号能显著提升影响力与吸粉能力。而借助 AI 工具,更可为 TikTok 矩阵运营效率的提升赋能,让运营如虎添翼。下面就为大家详细讲讲其中的实操细节,并结合一些伪代码示例辅助理解。 一、矩…...
Nginx安全防护与HTTPS部署实战
一.核心安全配置 1.编译安装Nginx (1)安装支持软件 Nginx的配置及运行需要pcre、zlib等软件包的支持,因此应预先安装这些软件的开发包(devel),以便提供相应的库和头文件,确保Nginx的安装顺利…...
【C语言】初阶数据结构相关习题(一)
🎆个人主页:夜晚中的人海 今日语录:人的生命似洪水在奔流,不遇着岛屿、暗礁,难以激起美丽的浪花。——奥斯特洛夫斯基 文章目录 ⭐一、判定是否互为字符重排🎉二、 回文排列🚀三、字符串压缩&am…...
MySQL从入门到精通(一):MySQL介绍及数据库相关概念
目录 一、MySQL 介绍 二、数据库相关概念 (一)数据库基础知识 (二)主流的关系型数据库管理系统 三、关系型数据库与非关系型数据库 (一)定义 (二)数据模型对比 (…...
宁德时代区块链+数字孪生专利解析:去中心化身份认证重构产业安全底座
引言:当动力电池巨头瞄准数字孪生安全 2025年5月6日,金融界披露宁德时代未来能源(上海)研究院与母公司宁德时代新能源科技股份有限公司联合申请的一项关键专利——“身份验证方法、系统、电子设备及存储介质”。这项技术将区块链…...
Kotlin数据类在Android开发中的应用
在 Android 开发中,Kotlin 的数据类(Data Class)因其简洁性和自动生成的功能特性,成为了提升开发效率的利器。以下是我总结的 7 大核心妙用场景,配合代码示例助您快速掌握: 1️⃣ JSON 解析利器 → 网络请求模型 与 Retrofit/Moshi 完美配合,自动生成 equals()/hashCod…...
程序员学商务英语之Shipment Claim 运输和索赔
Dia-3: Claim 1 索赔 1. He claimed that he would quit smoking. 他宣布他将要禁烟。 2. BYD is inferior to Tesla. 差 be worse than… 比亚迪比特斯拉差。 Tesla is superior to BYD. 特斯拉比比亚迪好。 be better than… 3. The survey report reveals/s…...
Kotlin密封类优化Android状态管理
Kotlin 的密封类(Sealed Class)确实是 Android 开发中管理复杂 UI 状态的利器。它通过类型安全的层次结构,让状态管理代码更加清晰简洁。让我们从实际开发场景出发,深入探讨其应用: 一、密封类核心优势 受限的类继承…...
基于图像处理的道路监控与路面障碍检测系统设计与实现 (源码+定制+开发) 图像处理 计算机视觉 道路监控系统 视频帧分析 道路安全监控 城市道路管理
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
依赖注入详解与案例(前端篇)
依赖注入详解与案例(前端篇) 一、依赖注入核心概念与前端价值 依赖注入(Dependency Injection, DI) 是一种通过外部容器管理组件/类间依赖关系的设计模式,其核心是控制反转(Inversion of Control, IoC&…...
Spark 的 Shuffle 机制:原理与源码详解
Apache Spark 是一个分布式数据处理框架,专为大规模数据分析设计。其核心操作之一是 Shuffle,这是一个关键但复杂的机制,用于在某些操作期间在集群中重新分配数据。理解 Shuffle 需要深入探讨其目的、机制和实现,既包括概念层面&a…...
IdeaVim配置指南
一、什么是 IdeaVim? IdeaVim 是 JetBrains 系列 IDE(如 IntelliJ IDEA, WebStorm, PyCharm 等)中的一个插件,让你在 IDE 里使用 Vim 的按键习惯,大大提升效率。 安装方法: 在 IDE 中打开 设置(Settings) →…...
[监控看板]Grafana+Prometheus+Exporter监控疑难排查
采用GrafanaPrometheusExporter监控MySQL时发现经常数据不即时同步,本示例也是本地搭建采用。 Prometheus面板 1,Detected a time difference of 11h 47m 22.337s between your browser and the server. You may see unexpected time-shifted query res…...
P56-P60 统一委托,关联游戏UI,UI动画,延迟血条
这一部分首先把复杂的每个属性委托全部换成了简洁可复用的委托,之后重新修改了UI蓝图,然后在新增了一个与之前表格关联的动画与血条延迟下降的蓝图 OverlayAuraWidgetController.h // Fill out your copyright notice in the Description page of Project Settings. #pragma …...
智能修复大模型生成的 JSON 字符串:Python 实现与优化
在使用大语言模型(LLM)生成 JSON 格式数据时,常因模型输出不完整、语法错误或格式不规范导致 JSON 解析失败。本文介绍如何通过 json_repair 库实现对 LLM 生成 JSON 字符串的自动修复,并改进原始提取函数以提升容错能力。 一、LLM 生成 JSON 的常见问题 LLM 输出的 JSON …...
【PPT制作利器】DeepSeek + Kimi生成一个初始的PPT文件
如何基于DeepSeek Kimi进行PPT制作 步骤: Step1:基于DeepSeek生成文本,提问 Step2基于生成的文本,用Kimi中PPT助手一键生成PPT 进行PPT渲染-自动渲染 可选择更改模版 生成PPT在桌面 介绍的比较详细,就是这个PPT模版…...
华为设备端口隔离
端口隔离的理论与配置指南 一、端口隔离的理论 基本概念 端口隔离(Port Isolation)是一种在交换机上实现的安全功能,用于限制同一VLAN内指定端口间的二层通信。被隔离的端口之间无法直接通信,但可通过上行端口访问公共资源&#…...
YOLO12改进-C3K2模块改进-引入离散余弦变换DCT 减少噪声提取图像的细节、边缘和纹理等微观特征
离散余弦变换(Discrete Cosine Transform, DCT)由 Nasir Ahmed 于 1974 年提出,最初是为了优化数据压缩。其核心思想是将信号从空间域转换为频率域,从而实现冗余信息的压缩。DCT 在图像和视频处理领域应用广泛,例如 JP…...
基于大模型的自然临产阴道分娩全流程预测与方案研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究意义 1.3 国内外研究现状 二、大模型技术原理与应用概述 2.1 大模型基本原理 2.2 在医疗领域的应用现状 2.3 用于分娩预测的优势 三、术前预测与准备方案 3.1 产妇身体状况评估指标 3.2 大模型预测流程与方法 3.3 基于预…...
用 Tailwind CSS 优化你的 Vue 3 项目! ! !
Vue 3 的响应式魅力 TailwindCSS 的原子级美学 前端开发的舒适巅峰! 在现代前端开发中,组件驱动 原子化 CSS 正在成为新的标准。如果你已经在使用 Vue 3,那不妨试试 Tailwind CSS —— 一个强大的原子化 CSS 框架,它能让你几乎…...
PostgreSQL数据库的array类型
PostgreSQL数据库相比其它数据库,有很多独有的字段类型。 比如array类型,以下表的pay_by_quarter与schedule两个字段便是array类型,即数组类型。 CREATE TABLE sal_emp (name text,pay_by_quarter integer[],schedule t…...
融智学视角集大成范式革命:文理工三类AI与网络大数据的赋能
融智学视角下的“集大成”范式革命:AI与大数据的终极赋能 一、化繁为简的工具革命:AI与大数据的三重解构 信息压缩的数学本质 Kolmogorov复杂度极限突破: K_AI(x)min_p∈P_NN ℓ(p)λ⋅dist(U(p),x) (神经网络程序p的描述长度语…...
【2025】Visio 2024安装教程保姆级一键安装教程(附安装包)
前言 大家好!最近很多朋友在问我关于Visio 2024的安装问题,尤其是对于那些需要制作专业流程图和组织结构图的小伙伴来说,这款软件简直是必不可少的办公神器!今天就给大家带来这篇超详细保姆级的Visio 2024安装教程,不…...
C++【继承】
继承 1.继承1.1 继承的概念1.2继承的定义1.2.1定义格式1.2.2继承基类成员访问方式的变化 1.3继承模板 2.基类和派生类之间的转换 1.继承 1.1 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上…...
理解字、半字与字节 | 从 CPU 架构到编程实践的数据类型解析
注:本文为 “字、半字、字节” 相关文章合辑。 略作重排,未全校。 如有内容异常,请看原文。 理解计算机体系结构中的字、半字与字节 在计算机科学中,理解“字 (Word)”、“半字 (Half-Word)”和“字节 (Byte)”等基本数据单元的…...
VMware搭建ubuntu保姆级教程
目录 VMware Ubuntu 虚拟机配置指南 创建虚拟机 下载 Ubuntu ISO 新建虚拟机 网络配置(双网卡模式) 共享文件夹设置 SSH 远程访问配置 VMware Ubuntu 虚拟机配置指南 创建虚拟机 下载 Ubuntu ISO 【可添加我获取】 官网:Get Ubunt…...
内容社区系统开发文档
1 系统分析 1.1 项目背景 1.2 需求分析 2 系统设计 2.1 系统功能设计 2.2 数据库设计 2.2.1 数据库需求分析 2.2.2 数据库概念结构设计 2.2.3 数据库逻辑结构设计 2.2.4 数据库物理结构设计 2.2.5 数据库视图设计 2.2.6 函数设计 2.2.7 存储过程设计 2.2.8 触发器…...
Ubuntu开放端口
在 Ubuntu 中,我们可以使用 ufw (Uncomplicated Firewall) 来管理防火墙。以下是打开 80 和 8090 端口的步骤: 首先检查防火墙状态 sudo ufw status 如果防火墙没有启用,先启用它: sudo ufw enable 允许 80 端口(…...
PyTorch 与 TensorFlow 中基于自定义层的 DNN 实现对比
深度学习双雄对决:PyTorch vs TensorFlow 自定义层大比拼 目录 深度学习双雄对决:PyTorch vs TensorFlow 自定义层大比拼一、TensorFlow 实现 DNN1. 核心逻辑 二、PyTorch 实现自定义层1. 核心逻辑 三、关键差异对比四、总结 一、TensorFlow 实现 DNN 1…...
质量员考试案例题有哪些常见考点?
质量员考试案例题常见考点如下: 施工质量控制 施工工艺与工序:如混凝土浇筑时的振捣时间、方法,若振捣不充分会导致混凝土出现蜂窝、麻面等质量问题。 施工环境:例如在高温天气下进行砌筑作业,未对砌块进行适当处理或…...
Axure疑难杂症:深度理解与认识“事件”“动作”(玩转交互)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:深度理解与认识“事件”“动作” 主要内容:事件、动作定义、本质、辩证关系、执行顺序 应用场景:原型交互 …...
【AI知识库云研发部署】RAGFlow + DeepSeek
gpu 安装screen:yum install screen 配置ollama: 下载官方安装脚本并执行: curl -fsSL https://ollama.com/install.sh | sh 通过screen后台运行ollama:screen -S ollama 在screen会话中启动服务: export OLLA…...
HTML07:表格标签
表格 基本结构 单元格行列跨行跨列 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表格学习</title><style>td {text-align: center;vertical-align: middle;}</style> </he…...
【专家库】Kuntal Chowdhury
昆塔尔乔杜里 Kuntal Chowdhury 是 NVIDIA 的 6G 开发者关系经理和技术布道师。他致力于推动与 NVIDIA 平台和工具的开发者和早期采用者生态系统的联系,以促进 6G 研究社区的蓬勃发展。在此之前,他是 BlueFusion, Inc. 的创始人,这是一家创新…...
IAA-Net:一种实孔径扫描雷达迭代自适应角超分辨成像方法——论文阅读
IAA-Net:一种实孔径扫描雷达迭代自适应角超分辨成像方法 1. 论文的研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、公式与优势2.1 方法框架与核心步骤2.2 核心公式与推导2.2.1 回波模型与目标函数2.2.2 正则化加权矩阵设计2.2.3 迭代更新公式2.2.4 …...
[论文阅读]MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System
MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System http://arxiv.org/abs/2504.12757 推出了 MCP Guardian,这是一个框架,通过身份验证、速率限制、日志记录、跟踪和 Web 应用程序防火墙 (WAF) 扫描来…...
提示词工程:通向AGI时代的人机交互艺术
引言:从基础到精通的提示词学习之旅 欢迎来到 "AGI时代核心技能" 系列课程的第二模块——提示词工程。在这个模块中,我们将系统性地探索如何通过精心设计的提示词,释放大型语言模型的全部潜力,实现高效、精…...
地级市-机器人、人工智能等未来产业水平(2009-2023年)-社科数据
地级市-机器人、人工智能等未来产业水平(2009-2023年)-社科数据https://download.csdn.net/download/paofuluolijiang/90623814 https://download.csdn.net/download/paofuluolijiang/90623814 此数据集统计了2009-2023年全国地级市在机器人、人工智能等…...
神经网络中之多类别分类:从基础到高级应用
神经网络中之多类别分类:从基础到高级应用 摘要 在机器学习领域,多类别分类是解决复杂问题的关键技术之一。本文深入探讨了神经网络在多类别分类中的应用,从基础的二元分类扩展到一对多和一对一分类方法。我们详细介绍了 softmax 函数的原理…...