protobuf实用教程
引言
protobuf安装
protobuf数据类型
基本数据类型
复合类型
Map类型
protobuf使用教程
编写.proto文件
编译
使用
序列化与反序列化
结语
引言
protobuf 是 google 的一种数据交换的格式,它独立于平台语言。 google 提供了 protobuf 多种语言的实现:java、c#、c++、go 和 python。
每一种实现都包含了相应语 言的编译器以及库文件。 由于它是一种二进制的格式,比使用 xml(20倍) 、json(10倍)进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数 据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
protobuf安装
先从github下载源代码https://github.com/google/protobuf,或者在分享的链接下载源码包。
通过网盘分享的文件:protobuf-master.zip
链接: https://pan.baidu.com/s/14GVIt2SwpgkobfpUOJQO5Q?pwd=1234 提取码: 1234
--来自百度网盘超级会员v3的分享
源码包中的src/README.md,有详细的安装说明,安装过程如下:
1、解压压缩包:unzip protobuf-master.zip
2、进入解压后的文件夹:cd protobuf-master
3、安装所需工具:sudo apt-get install autoconf automake libtool curl make g++ unzip
4、自动生成configure配置文件:./autogen.sh
5、配置环境:./configure
6、编译源代码(时间比较长):make
7、安装:sudo make install
8、刷新动态库:sudo ldconfig
按步骤进行即可完成安装。安装完成后可以使用 protoc --version 验证,安装成功会输出版本信息。
protobuf数据类型
protobuf的数据类型主要有三种:基本数据类型,复合类,Map类型(proto3版本后支持)。
基本数据类型
- double:双精度浮点数。
- float:单精度浮点数。
- int32:32位有符号整数。
- int64:64位有符号整数。
- uint32:32位无符号整数。
- uint64:64位无符号整数。
- sint32:32位有符号整数,使用zigzag编码以优化负数存储。
- sint64:64位有符号整数,使用zigzag编码以优化负数存储。
- fixed32:32位无符号整数(固定长度,不使用varint编码)。
- fixed64:64位无符号整数(固定长度,不使用varint编码)。
- sfixed32:32位有符号整数(固定长度)。
- sfixed64:64位有符号整数(固定长度)。
- bool:布尔值,true 或 false。
- string:UTF-8 编码的字符串。
- bytes:字节序列。
复合类型
复合类型有三种:消息,枚举,map。
消息
消息是 protobuf 中最核心的复合类型,用于定义结构化数据。我们可以在消息中定义字段,这些字段可以是基本数据类型,也可以是其他消息类型。使用起来和 cpp 的结构体类似。
示例:定义一个Person消息,包含三个字段:名称,id,电子邮件。
message Person
{string name = 1;int32 id = 2;string email = 3;
}
定义中的 = 并不是赋值,而是字段编号,消息体中的每个字段都必须有一个字段编号,这个编号是用于在消息的二进制格式中唯一标识字段的。
每个字段编号在同一个消息定义中必须是唯一的。在二进制格式中,字段编号与字段类型和字段值一起被编码。字段编号用于标识消息中的特定字段。
字段可以使用 repeated 修饰,重复字段类似于数组或列表,允许一个字段有多个值。 重复字段使用 repeated 关键字声明,可以包含基本数据类型或其他消息类型的元素。 重复字段在序列化时会包含元素的数量,因此可以动态地表示不同数量的元素。
使用示例:
message Contact
{repeated string phone_numbers = 1;
}
任意消息Any类型,Any类型可以存储任何消息类型的值,可以在消息中包含未知类型的消息。
使用示例:
message AnyMessage
{google.protobuf.Any details = 1;
}
oneof允许在一个组内为字段提供一个单一的选择,组内字段互斥,只能设置一个字段的值。
message SampleMessage
{oneof test_oneof {string name = 1;int32 id = 2;}
}
枚举
枚举类型用于定义一组命名的整数常量。 用于定义一组命名的整数常量。枚举提供了一种类型安全的方式来表示一组有限的、固定的值。用法和 cpp 中的枚举基本类似。
使用示例:枚举 Color 定义三种颜色。
enum Color
{RED = 0;GREEN = 1;BLUE = 2;
}
枚举类型可以作为消息中的字段类型,提供了对特定值集合的限制。
Map类型
map 用于存储键值对集合。从 protobuf 3.0 开始,map 类型被引入作为语言中原生支持的类型,允许定义一个字段为一个映射,其中键和值可以是任何有效的 protobuf 数据类型。用法和cpp中基本相同。
定义map类型时,需要指定键(key)和值(value)的数据类型。
- 键只能是以下类型之一:int32、sint32、uint32、int64、sint64、uint64、bool 或 string。
- 值可以是任何消息中有效的类型,包括基本数据类型、枚举、消息类型,甚至是另一个 map 类型。
使用示例:
message MapMessage
{map<int32, string> int_to_string = 1;map<string, MapMessage> string_to_message = 2;
}
protobuf使用教程
编写.proto文件
使用protobuf,我们需要创建一个.proto文件来定义数据结构。
syntax = "proto3";package test;message Person
{string name = 1;int32 id = 2;string email = 3;
}
这里定义了一个Person消息,包含三个字段:name、id和email。
syntax
syntax 关键词用于指定 .proto 文件使用的语法版本。syntax 声明必须位于文件的最开始部分,它告诉 protoc 编译器使用哪个版本的 protobuf 语法规则来解析 .proto 文件。
syntax 声明的基本用法:
使用Proto2 语法
proto syntax = "proto2";
使用Proto3 语法
proto syntax = "proto3";
proto2 是 Protocol Buffers 的原始语法版本。 在 proto2 语法中,字段可以被标记为 required、optional 或 repeated。 proto2 支持 default 值和 extensions 等特性。
proto3 是 Protocol Buffers 的更新版本,引入了一些新特性和简化。 在 proto3 语法中,所有字段都是可选的。没有 required 或 optional 关键字,只有 repeated。 proto3 不支持 default 值和 extensions,但引入了 map 类型和字段编号的更多限制。 proto3 语法更简洁,推荐使用。
package
package 声明用于定义一个 .proto 文件中所有消息、枚举和 RPC 服务的命名空间。与 cpp 中的命名空间相同。
语法:
package package_name;
import
要引用其他包中的类型,需要在 .proto文件的顶部使用 import 关键字。
import "path/other.proto";
导入的类型必须使用其完全限定名(包括包名)来引用。使用示例:
syntax = "proto3";package com.example;import "addressbook.proto";message Greeting
{string greeting = 1;com.example.person.Person person = 2; // 引用其他包中的 Person 消息
}
编译
我们需要使用 protoc 命令行工具编译 .proto 文件。语法:
protoc -I=<source_files_directory> --<language>_out=<output_directory> <proto_file.proto>
- -I=<source_files_directory>: 指定 .proto 文件所在的目录。
- -- <language>_out=<output_directory>: 指定生成代码的语言和输出目录。
- <proto_file.proto>: 指定要编译的 .proto 文件。
这里我们准备了一个测试文件person.proto:
syntax = "proto3";package test;message Person
{string name = 1;int32 id = 2;string email = 3;
}
我们执行 protoc 命令编译
protoc --cpp_out=. person.proto
可以看到当前目录下生成了两个文件:person.pb.h 与 person.cc。
person.pb.h 头文件包含了 Person 消息的 C++ 类声明。它定义了消息的结构和所有字段的访问器(getter/setter)函数。
person.pb.cc 文件 这个源文件包含了 Person 消息类的实现,包括字段的访问器函数和序列化/反序列化方法的实现。
我们只关注生成的person类:
class Person : public google::protobuf::Message
{public:// 构造函数和析构函数Person();virtual ~Person();// 字段访问器const std::string& name() const;void set_name(const std::string& value);// ...// 序列化和反序列化bool SerializeToString(std::string* output) const;bool ParseFromString(const std::string& data);// ...
};
对于每个字段都生成了访问器,提供了对定义的数据结构的操作接口:
set_字段名(值):用于设置消息中的字段值。
例如:user->set_name("John Doe");
字段名():用于获取消息中的字段值(只读)。
例如:const string& name = user->name();
mutable_字段名():返回指向字段的指针,允许修改字段值。
例如:string* mutable_name = user->mutable_name();
add_字段名():对于repeated字段,用于添加新的元素。
例如:User* user = userList.add_users();
字段名_size():返回repeated字段中的元素个数。
例如:int size = contacts.contacts_size();
字段名(int index):获取repeated字段中指定索引的元素。
例如:const PeopleInfo& first_contact = contacts.contacts(0);
mutable_字段名(int index):返回指向repeated字段中指定索引元素的指针,允许修改。
例如:PeopleInfo* contact = contacts.mutable_contacts(0);
clear_字段名():清空repeated字段中的所有元素。
例如:contacts.clear_contacts();
对于我们的类生成了以下几个访问接口:
//name
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
void set_name(const char* value);
void set_name(const char* value, size_t size);
std::string* mutable_name();//email
const std::string& email() const;
void set_email(const std::string& value);
void set_email(std::string&& value);
void set_email(const char* value);
void set_email(const char* value, size_t size);
std::string* mutable_email();//id
::PROTOBUF_NAMESPACE_ID::int32 id() const;
void set_id(::PROTOBUF_NAMESPACE_ID::int32 value);
使用
我们简单测试一下:
#include<iostream>
#include<string>
#include"person.pb.h"using namespace std;
using namespace test;int main()
{Person p;p.set_name("张三");p.set_email("123456789@qq.com");p.set_id(234560);string name=p.name();string email=p.email();int id=p.id();cout << "name: " << name << endl;cout << "email: " << email << endl;cout << "id: " << id << endl;return 0;
}
我们编译一下:
g++ -o test person.pb.cc test.cpp -lprotobuf -lpthread -std=c++11
注意:protobuf中使用了线程库,所以我们需要链接线程库。
程序运行结果如下:
序列化与反序列化
序列化和反序列化在类中也生成了接口:
- SerializeToString:将Protobuf消息序列化为字符串。
- SerializeToArray:将Protobuf消息序列化为字节数组。
- SerializeToOstream:将Protobuf消息序列化为输出流。
- ParseFromString:从字符串中解析Protobuf消息。
- ParseFromArray:从字节数组中解析Protobuf消息。
- ParseFromIstream:从输入流中解析Protobuf消息。
我们这里只介绍最常用的接口,即序列化与反序列化为字符串,其他方法也大同小异:
序列化为字符串
bool SerializeToString(std::string* output) const;
反序列为对象
bool ParseFromString(const std::string& data)
我们简单使用一下:
#include "person.pb.h"
#include <iostream>
#include <string>using namespace test;
using namespace std;int main()
{Person p;p.set_name("张三");p.set_email("123456789@qq.com");p.set_id(234560);string out;//序列化p.SerializeToString(&out);cout << "序列化:" << out << endl;Person s;s.ParseFromString(out);string name=s.name();string email=s.email();int id=s.id();cout << "反序列化:" << endl;cout << "name: " << name << endl;cout << "email: " << email << endl;cout << "id: " << id << endl;return 0;
}
运行结果如下:
结语
到这里我们已经完成了prptobuf的基础学习。笔者能力有限,如有错漏之处,欢迎指正。同时很多命令语法只是讲了基础用法,并不全面,如果有读者有兴趣可以深入研究。感谢观看!
相关文章:
protobuf实用教程
引言 protobuf安装 protobuf数据类型 基本数据类型 复合类型 Map类型 protobuf使用教程 编写.proto文件 编译 使用 序列化与反序列化 结语 引言 protobuf 是 google 的一种数据交换的格式,它独立于平台语言。 google 提供了 protobuf 多种语言的实现&am…...
人工智能ACA(五)--深度学习基础
一、深度学习概述 1. 深度学习概念 1-1. 深度学习基本概念 深度学习是机器学习的一个分支基于人工神经网络(模仿人脑结构)通过多层网络自动学习特征能够处理复杂的模式识别问题 1-2. 深度学习的优点与缺点 优点 强大的特征学习能力可以处理复杂问题…...
用python ollama qwen2.5 开发一个AI修仙游戏
用 Python Ollama (Qwen2.5) 开发一个 AI 修仙游戏 简介 本文将介绍如何使用 Python 和 Ollama (Qwen2.5 模型) 开发一个文字版修仙游戏。这个游戏具有以下特点: 完整的修仙世界观和成长体系基于 AI 生成的动态剧情和事件丰富的物品系统(功法、丹药、灵宝等)社交…...
tts语音合成相关开源项目试用对比
chatTTS 如下图所示,在不添加Sample Audio和Text的时候可以正常完成文本转语音,可以自定义添加语气词,笑声和停顿等。 无法实现声音克隆,即模仿某人的音色生成语音。 试用了chatTTS官网推荐的https://voicv.com/voice-cloning进行…...
基于JAVA_JSP电子书下载系统的设计与实现【源码+文档+部署讲解】
目 录 第1章 绪论 课题的研究背景、内容和意义 第2章 主要技术概述 2.1 B/S结构 2.2 JSP技术 2.2.1 JSP技术的强势 2.2.2 JSP技术的弱势 2.3 SQL Server 2000数据库 2.4 JDBC数据库连接 2.4.1 JDBC接口 2.4.2 JDBC的驱动程序 2.5 TOMCAT应用服务器 第3章 需求分…...
外连接转AntiJoin的应用场景与限制条件 | OceanBase SQL 查询改写系列
在《SQL 改写系列:外连接转内连接的常见场景与错误》一文中,我们了解到谓词条件可以过滤掉连接结果中的 null 情形的,将外连接转化为内连接的做法是可行的,正如图1中路径(a)所示。此时,敏锐的你或许会进一步思考&#…...
35道面向初中级前端的基础面试题
新鲜出炉的8月前端面试题 跨域资源共享 CORS 阮一峰 3. JSONP 是什么? 这是我认为写得比较通俗易懂的一篇文章jsonp原理详解——终于搞清楚jsonp是啥了。 4. 事件绑定的方式 嵌入dom 按钮 直接绑定 btn.onclick function(){} 事件监听 btn.addEventList…...
自动驾驶控制算法-横向误差微分方程LQR前馈控制
本文是学习自动驾驶控制算法第六讲 前馈控制与航向误差以及前两节的学习笔记。 1 横向误差微分方程 以规划的轨迹作为自然坐标系,计算自车在轨迹上的投影点,进而计算误差: 如图所示,横向误差为 d d d,航向误差为 θ…...
灭屏情况下,飞行模式+静音模式+插耳,播放音乐,电流异常
1. 功耗现象 灭屏情况下,飞行模式静音模式插耳,播放音乐,电流异常 1.1测试数据 飞行模式静音模式插耳机 原生音乐播放器 DriverOnly 32.5mA User版本 45mA 1.2 电流波形现象 上述看怀疑 CPU 未进入 Deep idle 导致? 2. …...
jsp | servlet | spring forEach读取不了对象List
导致这个问题的原因有很多的,这里讲到的只是原因之一 原因 taglib不认识forEach 解决办法 添加<% taglib uri"http://java.sun.com/jsp/jstl/core" prefix"c" %> (我忘写这个东西了哈哈哈)...
Taro小程序开发性能优化实践
我们团队在利用Taro进行秒送频道小程序的同时,一直在探索性能优化的最佳实践。随着需求的不断迭代,项目中的性能问题难免日积月累,逐渐暴露出来影响用户体验。适逢双十一大促,我们趁着这个机会统一进行了Taro性能优化实践…...
数据结构:栈(顺序栈)
目录 1.栈的定义 2.栈的结构 3.栈的接口 3.1初始化 3.2栈的销毁 3.3压栈 3.4判断栈是否为空 3.5出栈 3.6得到栈顶元素 3.7栈的大小 1.栈的定义 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端…...
【Maven】Maven的快照库和发行库
1、分类 Maven 支持两种类型的仓库:快照库(Snapshot Repository)和发行库(Release Repository),用于存储不同性质的构件(Artifacts)。 (1) 快照库 (Snapshot Repository)ÿ…...
如何给负载均衡平台做好安全防御
在现代网络架构中,负载均衡(Load Balancing)扮演着至关重要的角色。它不仅负责将流量分配到多个服务器以确保高效的服务交付,还作为第一道防线来抵御外部攻击。为了保护您的应用程序和服务免受潜在威胁,必须对负载均衡…...
AI应用-本地模型实现AI生成PPT(简易版)
文章目录 前言技术栈效果展示 一、实现思路二、实现步骤1.本地安装marp-cli2.后端实现3.前端实现 三、代码地址及说明 前言 在许多项目中,生成 PPT 是常见的需求,尤其在教育和报告展示中。传统的生成 PPT 的方法需要手动创建,而使用生成模型…...
JavaScript 数组方法完整指南
JavaScript 数组方法完整指南 1. 数组操作方法 1.1 添加/删除元素 push() 用途: 在数组末尾添加一个或多个元素返回值: 新数组的长度 const fruits [apple, banana]; const newLength fruits.push(orange, grape); console.log(fruits); // [apple, banana, orange, gra…...
基于自定义注解与 AOP 切面实现接口日志全面数据库存储
基于自定义注解与 AOP 切面实现接口日志全面数据库存储 一、引言 在当今复杂的软件系统开发与运维过程中,详细且精准地记录接口的各项信息对于系统性能监测、问题排查、安全审计以及业务分析都有着极为关键的意义。本文将深入讲解如何运用自定义注解与 AOP&#x…...
xcode15 报错 does not contain ‘libarclite‘
新建pod私有库 在xcode15 无法运行 报错 SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a; try increasing the minimum deployment target 下载 资源文件…...
c# 实现一个简单的异常日志记录(异常迭代+分片+定时清理)+AOP Rougamo全局注入
1. 日志目录和文件管理 日志目录:日志文件存储在 ./Exceptions 目录下。日志文件命名:日志文件的命名格式为 yyyy_MM_dd.log,表示当天的日期。如果当天的日志文件大小超过 maxFileSizeBytes(3KB),则会创建…...
python 定时任务管理封装
主逻辑代码 # -*- coding: utf-8 -*- # import apscheduler import pandas as pd from datetime import datetime # 导入调度器,此处使用BackgroundScheduler阻塞调度器 from apscheduler.schedulers.background import BackgroundScheduler # 导入触发器…...
GIS数据处理/程序/指导,街景百度热力图POI路网建筑物AOI等
简介其他数据处理/程序/指导!!!(1)街景数据获取(2)街景语义分割后像素提取,指标计算代码(绿视率,天空开阔度、视觉熵/景观多样性等)(3…...
【落羽的落羽 C语言篇】自定义类型——结构体
文章目录 一、结构体1. 结构体类型的概念和声明2. 结构体变量的创建和初始化3. 结构体成员的访问3.1 直接访问3.2 间接访问 4. 结构体的内存对齐4.1 内存对齐的规则4.2 内存对齐的原因4.3 修改默认对齐数 5. 结构体传参6. 结构体实现位段 在C语言中,已经提供了一些基…...
【WPS安装】WPS编译错误总结:WPS编译失败+仅编译成功ungrib等
WPS编译错误总结:WPS编译失败仅编译成功ungrib等 WPS编译过程问题1:WPS编译失败错误1:gfortran: error: unrecognized command-line option ‘-convert’; did you mean ‘-fconvert’?解决方案 问题2:WPS编译三个exe文件只出现u…...
【Python入门】文件读写
文章一览 一、什么是文件二、文件形态三、文件组成要素四、文件操作五、文件路径六、文件读写操作6.1 文件打开模式6.2 文件的打开6.3 正确关闭文件6.3.1 读文件方法6.3.2 写文件 七、CSV 文件读取7.1 CSV 数据存储格式7.2 CSV 文件特点7.3 使用记事本创建 CSV 文件7.4 用 csv …...
基于变异策略的模糊测试:seed与mutation的含义
1. 引入 最早期的模糊测试(fuzz),是生成一些随机的文本序列,对unix系统的命令行输入进行测试。这种古老的方式,也发现了不少漏洞。 但完全随机的fuzz,存在如下问题: (1)…...
制造研发企业与IPD管理体系
芯片/半导体/制造研发型企业,大都知道华为使用过的IPD管理体系,但大家用到什么程度,那就是参差不齐了。 因为IPD管理体系它只是一个管理理念,是一个方法论。它需要有相应的组织架构来承载,它有很复杂的流程需要有IT系统…...
电子应用设计方案68:智能晾衣架系统设计
智能晾衣架系统设计 一、引言 智能晾衣架作为智能家居的一部分,为用户提供了更便捷、高效和舒适的衣物晾晒体验。本设计方案旨在打造一款功能丰富、性能稳定且易于操作的智能晾衣架系统。 二、系统概述 1. 系统目标 - 实现晾衣架的自动升降,方便衣物的…...
如何实现圆形头像功能
文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了Stack Widget,本章回中将介绍CircleAvatar这种Widget,闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 在上一回中我们使用了CircleAvatar Widget,之前也没有介绍过此Widget,因此有些看官希望对它做一些介绍…...
【python自动化六】UI自动化基础-selenium的使用
selenium是目前用得比较多的UI自动化测试框架,支持java,python等多种语言,目前我们就选用selenium来做UI自动化。 1.selenium安装 安装命令 pip install selenium2.selenium的简单使用 本文以chrome浏览器为例,配套selenium中c…...
时间复杂度和空间复杂度理解
空间复杂度和时间复杂度是算法分析中两个重要的概念,用于评估算法的性能。在前端 JavaScript 中,时间复杂度用于评估算法在最坏情况下的运行时间;空间复杂度描述了算法在执行过程中所需的内存空间的增长率,它包括算法所需的临时空…...
详细解读sedex验厂
SEDEX验厂,即供货商商业道德信息交流认证(Supplier Ethical Data Exchange),是一种表明企业遵守商业道德的认证。以下是对SEDEX验厂的详细解读: 一、SEDEX验厂概述 SEDEX是一家总部位于英国伦敦的非营利组织…...
IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档
IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档 一、引言 在现代制造业和工业管理领域,IOT(物联网)、MES(制造执行系统)、WMS(仓库管理系统)、MOM(制造运营管理系统ÿ…...
ESP32S3 使用LVGL驱动LCD屏(ST7789主控)
ESP32S3 使用LVGL驱动LCD屏(ST7789主控) 目录 1 分析原理图 2 驱动、点亮LCD(ST7789) 2.1 在工程中添加目录、文件 2.2 添加esp_lvgl_port组件 2.3 对工程进行必要的配置 2.4 编写必要代码 3 烧录、验证 1 分析原理图 要使用SOC驱动LCD屏&#…...
Zed调试宏 C语言错误日志 异常错误调试信息
1、C中的错误码 在C语言中通过返回错误码或设置全局的errno值来反馈错误问题。errno.h是一个头文件,它定义了一个全局变量errno,用于在程序中记录和报告错误的原因。这个机制主要用于处理系统调用或标准库函数出错时的错误反馈。当系统调用或库函数…...
GitCode 光引计划征文|JavaVision:引领全能视觉智能识别新纪元
在人工智能技术飞速发展的今天,计算机视觉作为AI领域的重要分支,正逐渐渗透到各行各业中。JavaVision,作为[光引计划]的一部分,致力于提供一个基于Java的全能视觉智能识别解决方案。同时它集成了MilvusPlus,旨在提供一…...
数据分析思维(五):分析方法——假设检验分析方法
数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python,更重要的是数据分析思维。没有数据分析思维和业务知识,就算拿到一堆数据,也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》,本文内容就是提取…...
《OpenCV计算机视觉》--介绍及基础操作
文章目录 《OpenCV计算机视觉》--介绍及基础操作一.OpenCV介绍二.下载OpenCV三.基础操作1.调用OpenCV2.读取图片信息3.读取图片的灰度图4.视频文件读取5.对图片进行切片6.提取RGB颜色通道7.合并颜色通道8.图片修改图片打码图片组合 9.cv2.resize10.图形运算图像加法运算cv2.add…...
利用Java爬虫获取苏宁易购商品详情
在数字化时代,电商平台的商品信息对于市场分析、价格监控和消费者决策至关重要。苏宁易购作为中国领先的电商平台之一,提供了丰富的商品信息。本文将介绍如何使用Java语言开发爬虫,获取苏宁易购商品的详细信息。 Java爬虫技术简介 Java作为一…...
【CVE-2024-53375】TP-Link Archer系列路由器认证操作系统命令注入(内附远离和代码利用)
CVE-2024-53375 TP-Link Archer系列路由器认证操作系统命令注入 受影响的设备 使用 HomeShield 功能的 TP-Link 设备容易受到此漏洞的影响。这包括 TP-Link Archer 系列的多款路由器。 经过测试 Archer AXE75(EU)_V1_1.2.2 Build 20240827(发布日期 2024 年 11 月 4 日)…...
DP动态规划(装箱问题)
# [NOIP2001 普及组] 装箱问题 ## 题目描述 有一个箱子容量为 $V$,同时有 $n$ 个物品,每个物品有一个体积。 现在从 $n$ 个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。…...
selenium学习笔记(一)
文章目录 前言一、selenium的简介java使用seleniumPython使用selenium常用的浏览器selenium的功能 二、chromeDriver的安装查看本机的chrome版本?匹配对应的chromedriver并下载在服务器上例如Centos如何安装Chrome 三、selenium内容详解chrome启动chrome启动参数元素…...
jest expect().resolves和expect().rejects原理
假设存在如下代码 export default function fetchData(fn) {return Axios.get(http://www.dell-lee.com/react/api/demo.json) } 接口返回的数据为 {"success": true } 那么对于测试代码 test(fetchData, async () > {await expect(fetchData()).resolves.to…...
大语言模型驱动的Agent:定义、工作原理与应用
文章目录 引言什么是大语言模型? Agent的概念LLM Agent的工作原理 Dify平台上的AgentLLM Agent的应用场景挑战与展望结论 引言 随着人工智能(AI)技术的发展,特别是自然语言处理(NLP)领域的进步,…...
写作词汇积累:纰漏、坎肩、颠三倒四、隔阂
纰漏 【纰漏】是指因粗心而产生的差错、小事故或漏洞 1. 在准备这次会议的过程中,我们反复核对资料,力求不出现任何【纰漏】。2. 在这次重要的项目汇报中,他小心翼翼地检查每一页 PPT,生怕出现任何【纰漏】。3. 尽管她工作一向细…...
一种简易的免杀绕过方法
一种简易的免杀绕过方法 这里我们直接参考师兄的项目https://github.com/snnxyss/In-Swor exe-shellcode-加密-运行 话不多说直接上图 这里我们用geacon作为本次实验 从这里我们可以看到 geacon已经不行了 这里我们将exe转shellcode 生成之后将123.txt放到config目录下 利…...
CTF web解题 [NISACTF 2022]popchains PHP反序列化 pop链
不积跬步无以至千里 不积小流无以成江海 对web方向有了更近一步的了解,根据一道题目来学习PHP反序列化及pop链 [NISACTF 2022]popchains flag:NSSCTF{3096663a-4b18-4567-bdfb-8403f9414704} Happy New Year~ MAKE A WISH <?php echo?Happy?Ne…...
重温设计模式--单例模式
文章目录 单例模式(Singleton Pattern)概述单例模式的实现方式及代码示例1. 饿汉式单例(在程序启动时就创建实例)2. 懒汉式单例(在第一次使用时才创建实例) 单例模式的注意事项应用场景 C代码懒汉模式-经典…...
AI的进阶之路:从机器学习到深度学习的演变(一)
AI的进阶之路:从机器学习到深度学习的演变 在当今科技迅猛发展的时代,人工智能(AI)、机器学习(ML)和深度学习(DL)已成为推动创新的核心力量。这三个领域虽然紧密相连,却…...
WPF+MVVM案例实战与特效(四十七)-实现一个路径绘图的自定义按钮控件
文章目录 1、案例效果2、创建自定义 PathButton 控件1、定义 PathButton 类2、设计样式与控件模板3、代码解释3、控件使用4、直接在 XAML 中绑定命令3、源代码获取4、总结1、案例效果 2、创建自定义 PathButton 控件 1、定义 PathButton 类 首先,我们需要创建一个新的类 Pat…...
Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印
图样: 就可以导入了 上代码 import tkinter as tk from tkinter import ttk import sqlite3 from datetime import datetime from tkinter import messagebox, filedialog import pandas as pd import reclass OrderSystem:def __init__(self, root):self.root r…...