QT聊天项目DAY07
1.Win配置和使用GRPC
1.1 克隆GRPC库
克隆GRPC
git clone -b v1.34.0 https://gitee.com/mirrors/grpc-framework.git
查看Git有没有安装
没有安装
1.1.1 安装Git
https://git-scm.com/
一路next
添加Git的路径到系统环境变量下
我这次没用管理员权限,并且也没有创建grpc文件夹,直接调用下面这个git指令
git clone -b v1.34.0 https://gitee.com/mirrors/grpc-framework.git grpc
1.1.2 修改.gitmodules文件
全部修改成.Gitee上面的
[submodule "third_party/zlib"]path = third_party/zlib#url = https://github.com/madler/zliburl = https://gitee.com/mirrors/zlib.git# When using CMake to build, the zlib submodule ends up with a# generated file that makes Git consider the submodule dirty. This# state can be ignored for day-to-day development on gRPC.ignore = dirty
[submodule "third_party/protobuf"]path = third_party/protobuf#url = https://github.com/google/protobuf.giturl = https://gitee.com/local-grpc/protobuf.git
[submodule "third_party/googletest"]path = third_party/googletest#url = https://github.com/google/googletest.giturl = https://gitee.com/local-grpc/googletest.git
[submodule "third_party/benchmark"]path = third_party/benchmark#url = https://github.com/google/benchmarkurl = https://gitee.com/mirrors/google-benchmark.git
[submodule "third_party/boringssl-with-bazel"]path = third_party/boringssl-with-bazel#url = https://github.com/google/boringssl.giturl = https://gitee.com/mirrors/boringssl.git
[submodule "third_party/re2"]path = third_party/re2#url = https://github.com/google/re2.giturl = https://gitee.com/local-grpc/re2.git
[submodule "third_party/cares/cares"]path = third_party/cares/cares#url = https://github.com/c-ares/c-ares.giturl = https://gitee.com/mirrors/c-ares.gitbranch = cares-1_12_0
[submodule "third_party/bloaty"]path = third_party/bloaty#url = https://github.com/google/bloaty.giturl = https://gitee.com/local-grpc/bloaty.git
[submodule "third_party/abseil-cpp"]path = third_party/abseil-cpp#url = https://github.com/abseil/abseil-cpp.giturl = https://gitee.com/mirrors/abseil-cpp.gitbranch = lts_2020_02_25
[submodule "third_party/envoy-api"]path = third_party/envoy-api#url = https://github.com/envoyproxy/data-plane-api.giturl = https://gitee.com/local-grpc/data-plane-api.git
[submodule "third_party/googleapis"]path = third_party/googleapis#url = https://github.com/googleapis/googleapis.giturl = https://gitee.com/mirrors/googleapis.git
[submodule "third_party/protoc-gen-validate"]path = third_party/protoc-gen-validate#url = https://github.com/envoyproxy/protoc-gen-validate.giturl = https://gitee.com/local-grpc/protoc-gen-validate.git
[submodule "third_party/udpa"]path = third_party/udpa#url = https://github.com/cncf/udpa.giturl = https://gitee.com/local-grpc/udpa.git
[submodule "third_party/libuv"]path = third_party/libuv#url = https://github.com/libuv/libuv.giturl = https://gitee.com/mirrors/libuv.git
拉取grpc的所有依赖
git submodule update --init
1.1.3 下载CMake
去恋恋风辰老师的网盘下载cmake
https://pan.baidu.com/s/1Yg9Usdc3T-CYhyr9GiePCw?pwd=ng6x
1.1.4 下载nasm 2.16.01
由于nasm网站打不开,自己也编译不了,索性直接用恋恋风辰老师编译好的
2. 从网盘获取编译好的GRPC
https://pan.baidu.com/s/1BBaAZ8-R-GSxxcy2s7TRWA?pwd=ybno
3. 配置编译好的GRPC环境
我不使用属性管理器,直接配,我怕自己忘记怎么配置环境的
配置头文件
配置库文件
D:\BoostNetLib\grpc\visualpro\third_party\re2\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\types\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\synchronization\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\status\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\random\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\flags\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\debugging\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\container\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\hash\Debug
D:\BoostNetLib\grpc\visualpro\third_party\boringssl-with-bazel\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\numeric\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\time\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\base\Debug
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\strings\Debug
D:\BoostNetLib\grpc\visualpro\third_party\protobuf\Debug
D:\BoostNetLib\grpc\visualpro\third_party\zlib\Debug
D:\BoostNetLib\grpc\visualpro\Debug
D:\BoostNetLib\grpc\visualpro\third_party\cares\cares\lib\Debug
添加库
libprotobufd.lib
gpr.lib
grpc.lib
grpc++.lib
grpc++_reflection.lib
address_sorting.lib
ws2_32.lib
cares.lib
zlibstaticd.lib
upb.lib
ssl.lib
crypto.lib
absl_bad_any_cast_impl.lib
absl_bad_optional_access.lib
absl_bad_variant_access.lib
absl_base.lib
absl_city.lib
absl_civil_time.lib
absl_cord.lib
absl_debugging_internal.lib
absl_demangle_internal.lib
absl_examine_stack.lib
absl_exponential_biased.lib
absl_failure_signal_handler.lib
absl_flags.lib
absl_flags_config.lib
absl_flags_internal.lib
absl_flags_marshalling.lib
absl_flags_parse.lib
absl_flags_program_name.lib
absl_flags_usage.lib
absl_flags_usage_internal.lib
absl_graphcycles_internal.lib
absl_hash.lib
absl_hashtablez_sampler.lib
absl_int128.lib
absl_leak_check.lib
absl_leak_check_disable.lib
absl_log_severity.lib
absl_malloc_internal.lib
absl_periodic_sampler.lib
absl_random_distributions.lib
absl_random_internal_distribution_test_util.lib
absl_random_internal_pool_urbg.lib
absl_random_internal_randen.lib
absl_random_internal_randen_hwaes.lib
absl_random_internal_randen_hwaes_impl.lib
absl_random_internal_randen_slow.lib
absl_random_internal_seed_material.lib
absl_random_seed_gen_exception.lib
absl_random_seed_sequences.lib
absl_raw_hash_set.lib
absl_raw_logging_internal.lib
absl_scoped_set_env.lib
absl_spinlock_wait.lib
absl_stacktrace.lib
absl_status.lib
absl_strings.lib
absl_strings_internal.lib
absl_str_format_internal.lib
absl_symbolize.lib
absl_synchronization.lib
absl_throw_delegate.lib
absl_time.lib
absl_time_zone.lib
absl_statusor.lib
re2.lib
编译
D:\BoostNetLib\grpc\visualpro\third_party\abseil-cpp\absl\status\Debug
添加上,在编译,编译成功
4.定义通信协议Protobuf
protobuf的语法版本 为 proto3
定义当前的包名为message
定义一个服务 VerifyService
输入参数类型为 GetVerifyRequest
返回值类型为 GetVarifyRsponse
请求的参数结构为
string email = 1;
返回的参数结构为
错误码 邮箱 和 验证码
也就是这个.proto文件定义了一个基于gRpc的邮箱验证码服务接口,前端调用GetVerifyCode发起验证码请求,后端通过邮箱发出并返回结果,通信数据用Protobuf编码
syntax = "proto3";package message;service VerifyService {rpc GetVerifyCode (GetVerifyRequest) returns (GetVerifyRsponse) {}
}message GetVerifyRequest {string email = 1;
}message GetVerifyRsponse {int32 error = 1;string email = 2;string code = 3;
}
5. 编译通信协议
D:\BoostNetLib\grpc\visualpro\third_party\protobuf\Debug\protoc.exe -I="." --grpc_out="." --plugin=protoc-gen-grpc="D:\BoostNetLib\grpc\visualpro\Debug\grpc_cpp_plugin.exe" "message.proto"
你们需要更换BoostNetLib
5.2 生成用于序列化和反序列化的文件
D:\BoostNetLib\grpc\visualpro\third_party\protobuf\Debug\protoc.exe --cpp_out=. "message.proto"
5.3 添加到服务器的解决方案中
编译一下,编译成功
6. 创建GRPC通信客户端
当客户端向我们自己写的服务器里发送Post请求时,根据客户端发来的邮箱然后向GRPC服务器去请求
#ifndef VERIFYGRPCCLIENT_H
#define VERIFYGRPCCLIENT_H#include <grpcpp/grpcpp.h>
#include "message.grpc.pb.h"
#include "GlobalHead.h"using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;using message::VerifyService;
using message::GetVerifyRequest;
using message::GetVerifyRsponse;class VerifyGrpcClient : public Singletion<VerifyGrpcClient>
{friend class Singletion<VerifyGrpcClient>;
public:~VerifyGrpcClient();/* 向GRPC服务器请求验证码 */GetVerifyRsponse GetVerifyCode(string email);private:VerifyGrpcClient();unique_ptr<VerifyService::Stub> stub_;
};
#endif // VERIFYGRPCCLIENT_H
#include "VerifyGrpcClient.h"VerifyGrpcClient::VerifyGrpcClient()
{shared_ptr<Channel> channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); // 创建GRPC通道stub_ = VerifyService::NewStub(channel); // 创建Stub
}VerifyGrpcClient::~VerifyGrpcClient()
{}GetVerifyRsponse VerifyGrpcClient::GetVerifyCode(string email)
{ClientContext context; // GRPC上下文GetVerifyRsponse response; // 响应对象GetVerifyRequest request; // 请求对象request.set_email(email); Status status = stub_->GetVerifyCode(&context, request, &response); // 发起GRPC请求if (status.ok()){return response;}else{response.set_error(ErrorCodes::RPC_FAILED);return response;}
}
所以在服务器处理客户端post请求中,获取到邮箱后立即向grpc服务器获取验证码
/* 向grpc 服务器获取验证码 */
GetVerifyRsponse verifyRsponse = VerifyGrpcClient::GetInstance()->GetVerifyCode(email);/* 返回响应报文给客户端 */
jsonResonse["error"] = verifyRsponse.error();
编译一下,编译成功
7. 为服务器创建配置文件
{"GateServer": {"Port": 8080},"VerifyServer": {"Port": 50051}
}
创建静态函数库,来解析json
函数实现
#ifndef SERVERSTATIC_H
#define SERVERSTATIC_H#include "GlobalHead.h"class ServerStatic
{
public:/* 解析配置文件 */static int ParseConfig(string configPath, string blockName, string key);
};
#endif // SERVERSTATIC_H
#include "ServerStatic.h"#include <fstream>/* 解析配置文件 */
int ServerStatic::ParseConfig(string configPath, string blockName, string key)
{ifstream file(configPath, ifstream::binary);if (!file.is_open()){cerr << "Failed to open config file: " << configPath << endl;return -1;}Json::Value jsonResult;Json::Reader reader;if (!reader.parse(file, jsonResult)){cout << "Failed to parse config file: " << configPath << endl;return -1;}if (!jsonResult.isMember(blockName)){cout << "Failed to find block: " << blockName << endl;return -1;}return jsonResult[blockName][key].asInt();
}
8. 邮箱验证服务
https://nodejs.org/en
一路安装下去
8.1 初始化Nodejs库的配置
报错
找到生成的包,修改命名
{"name": "VerifyServer","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC","description": ""
}
8.2 安装GRPC-JS库
npm install @grpc/grpc-js
8.3 安装proto库
npm install @grpc/proto-loader
8.4 安装Email处理的库
npm install nodemailer
8.5 将protobuf协议复制到VerifyServer文件夹下
8.6 新建proto.js解析proto文件
加载 message.proto
定义的 gRPC 服务或消息结构,并将其暴露出去供其他文件使用
首先导入库,然后获取当前目录下的message.proto文件,加载.proto文件,保持原始字段名,将int类型当作字符串进行处理,枚举类型也当作字符串处理;
然后将加载好的json对象转换成真正可用的gRpc服务对象
提取message包的内容,把提取到的内容暴露给其他文件使用
const path = require('path')
const grpc = require('@grpc/grpc-js')
const protoLoader = require('@grpc/proto-loader')
const PROTO_PATH = path.join(__dirname, 'message.proto')
const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true })
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition)
const message_proto = protoDescriptor.message
module.exports = message_proto
最终会被解析成下面这样
const message_proto = {VerifyService: class {constructor(address, credentials, options) { ... }GetVerifyCode(request, callback) {// 发起 gRPC 调用,request 是 { email: 'xxx@example.com' }// callback 是 (err, response) => { ... }}},GetVerifyRequest: class {constructor({ email }) {this.email = email}},GetVerifyRsponse: class {constructor({ error, email, code }) {this.error = errorthis.email = emailthis.code = code}}
}
8.7 开启smtp服务
8.8 读取配置
8.8.1 新建config.json
8.8.2 新建Global.js
let code_prefix = "code_";const Errors = {Success : 0,RedisErr : 1,Exception : 2,
};module.exports = {code_prefix,Errors}
8.8.3 新建config.js 读取config.json
读取配置文件config.json中的配置信息,并将这些信息导出以供其他模块使用
const fs = require('fs');
let config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
let email_userName = config.email.userName;
let email_passward = config.email.passward;
let mysql_host = config.mysql.host;
let mysql_port = config.mysql.port;
let redis_host = config.redis.host;
let redis_port = config.redis.port;
let redis_passwd = config.redis.passwd;
let code_prefix = "code_";
module.exports = { email_passward, email_userName, mysql_host, mysql_port, redis_host, redis_port, redis_passwd, code_prefix }
8.8.4 新建emial.js
const nodemailer = require('nodemailer');
const config_module = require("./config")
/*** 创建发送邮件的代理*/
let transport = nodemailer.createTransport({host: 'smtp.163.com',port: 465,secure: true,auth: {user: config_module.email_userName, // 发送方邮箱地址pass: config_module.email_passward // 邮箱授权码或者密码}
});
实现发送邮件的函数
/*** 发送邮件的函数* @param {*} mailOptions_ 发送邮件的参数* @returns */
function SendMail(mailOptions_) {return new Promise(function (resolve, reject) {transport.sendMail(mailOptions_, function (error, info) {if (error) {console.log(error);reject(error);} else {console.log('邮件已成功发送:' + info.response);resolve(info.response)}});})
}
module.exports.SendMail = SendMail
上面全部修改成password,我写错了
8.8.5 新建server.js
gRPC 服务端,提供一个叫 GetVerifyCode
的接口,接收一个邮箱地址,生成验证码并发邮件给这个地址
填写自己的邮箱账号
const grpc = require('@grpc/grpc-js')
const message_proto = require('./proto')
const const_module = require('./global')
const { v4: uuidv4 } = require('uuid');
const emailModule = require('./email');async function GetVerifyCode(call, callback) {console.log("email is ", call.request.email)try {uniqueId = uuidv4();console.log("uniqueId is ", uniqueId)let text_str = '您的验证码为' + uniqueId + '请三分钟内完成注册'//发送邮件let mailOptions = {from: '******@163.com',to: call.request.email,subject: '验证码',text: text_str,};let send_res = await emailModule.SendMail(mailOptions);console.log("send res is ", send_res)callback(null, {email: call.request.email,error: const_module.Errors.Success});} catch (error) {console.log("catch error is ", error)callback(null, {email: call.request.email,error: const_module.Errors.Exception});}
}
function main() {var server = new grpc.Server()server.addService(message_proto.VerifyService.service, { GetVerifyCode: GetVerifyCode })server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {server.start()console.log('grpc server started')})
}
main()
Java看不懂,只会c++,这些代码已经脱离我的掌控了,难崩
8.8.6 修改package.json
{"name": "VerifyServer","version": "1.0.0","main": "server.js","scripts": {"serve": "node server.js"},"author": "","license": "ISC","description": "","dependencies": {"@grpc/grpc-js": "^1.13.3","@grpc/proto-loader": "^0.7.15","nodemailer": "^6.10.1"},"devDependencies": {"eslint": "^9.25.1"}
}
8.8.7 卸载MySql并重装
1. 首先查看自己的Mysql的服务名,并停止服务
2. 以管理员权限运行cmd
彻底卸载Mysql的博客
https://blog.csdn.net/m0_52861000/article/details/131354710?ops_request_misc=%257B%2522request%255Fid%2522%253A%25227ed0e707bd1102a74fef6f16d6b0d3e5%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=7ed0e707bd1102a74fef6f16d6b0d3e5&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131354710-null-null.142^v102^pc_search_result_base4&utm_term=mysql%E6%80%8E%E4%B9%88%E5%8D%B8%E8%BD%BD%E5%B9%B2%E5%87%80&spm=1018.2226.3001.4187
重新安装MySql的博客
https://blog.csdn.net/m0_52559040/article/details/121843945
我的MySql密码 123456
我是因为忘了密码才选择重新安装的
8.8.8 修改config.json
"mysql": {"host": "localhost","port": 3306,"password": "123456"},"redis": {"host": "81.68.86.146","port": 6380,"passwd": "123456"}
}
9. 测试
9.1 启动GRPC服务器,通过GRPC服务去发送邮件到注册的邮箱里面
9.2 服务器启动
9.3 QT客户端启动
9.4 获取验证码
已证实发送,从结果反推过程
10. 从结果反推过程
10.1 解决乱码问题
首先验证到底是哪里出了问题
查看自己的VS编码形式,不知道在哪里查的看这篇文章
https://blog.csdn.net/qq_41868108/article/details/105750175
改成UTF-8编码试试看
没有问题,所以是编码形式出错了,需要将中文按照utf-8编码
由于对JavaScript的语法不熟悉,放弃尝试,最后获取到的邮件
已解决
10.2 注册验证一条龙
当注册按钮点击时,将Email中的信息和URL都填充进去,然后发送Post请求给服务器,因为URL的格式如下
http://localhost:8080//getVarifycode,所以本地开启服务器后就能够收到客户端发来的请求了
服务端:
在这里是向GRPC服务器发送请求
在JavaScript中启动grpc服务器,监听本机是否有连接
在我们的message_proto中定义了一个名为VerifyService的服务
服务器会监听VerifyService.GetVerifyCode方法,一旦客户端调用这个方法,服务端就会进入实现的GetVerifyCode函数中去处理请求,然后把响应结果通过callback返回
客户端调用这个方法时(GetVerifyCode)会发送一个GetVerifyRequest服务器返回一个GetVerifyResponse,后续就是通过uuid生成为唯一的验证码去返回给c++调用GRPC中的GetVerifyCode的客户端,然后再qt的前端中输入自己qq邮箱中接收到的验证码,跟c++服务器中的验证码对比,就注册成功了
相关文章:
QT聊天项目DAY07
1.Win配置和使用GRPC 1.1 克隆GRPC库 克隆GRPC git clone -b v1.34.0 https://gitee.com/mirrors/grpc-framework.git 查看Git有没有安装 没有安装 1.1.1 安装Git https://git-scm.com/ 一路next 添加Git的路径到系统环境变量下 我这次没用管理员权限,并且也没…...
2025年PMP 学习三
4.2制定项目管理计划 4. 项目管理计划 - 内容(输出) 项目目标的制定原因: 3个基准(范围基准、进度基准、成本基准) 子管理计划:范围、需求、进度、成本、质量、资源、沟通、风险、采购等管理计划…...
软考-软件设计师中级备考 10、文件管理、设备管理
一、 文件管理 1、文件目录 文件控制块(FCB):是操作系统为管理文件而设置的数据结构,包含了文件的基本信息(如文件名、文件大小、文件类型等)、存取控制信息(如文件所有者的权限、其他用户的权…...
Linux环境下的进程创建-fork函数的使用, 进程退出exit和_exit的区别,以及进程等待waitpid和status数据的提取方法
目录 一、进程创建 1.fork函数 1)进程调用fork函数是如何创建子进程的 2)代码示范 2.写时拷贝 二、进程退出 1.退出码 1)什么是退出码? 2)为什么要有退出码? 3)退出码是怎么做到的? …...
【数据结构与算法】常见排序算法详解(C++实现)
目录 一、排序的基本概念 二、插入排序 2.1 直接插入排序 2.2 折半插入排序 2.3 希尔排序 三、交换排序 3.1 冒泡排序 3.2 快速排序 四、选择排序 4.1 简单选择排序 4.2 堆排序 五、归并排序 六、基数排序 七、计数排序 结语 一、排序的基本概念 排序 就是重新…...
STM32GPIO输入实战-按键key模板及移植
STM32GPIO输入实战-按键key模板及移植 一,按键模板展示二,按键模板逻辑1,准备工作:头文件与全局变量2,读取硬件状态:key_read_raw()3,核心处理:key_process_simple() 的四行代码 三,…...
LeetCode 1128.等价多米诺骨牌对的数量:计数
【LetMeFly】1128.等价多米诺骨牌对的数量:计数 力扣题目链接:https://leetcode.cn/problems/number-of-equivalent-domino-pairs/ 给你一组多米诺骨牌 dominoes 。 形式上,dominoes[i] [a, b] 与 dominoes[j] [c, d] 等价 当且仅当 (a …...
Spring MVC设计与实现
DispatcherServlet的初始化与请求处理流程 初始化阶段 Servlet 生命周期触发:当 Web 容器(如 Tomcat)启动时,根据注解/配置,DispatcherServlet 的 init() 方法被调用。 初始化 WebApplicationContext 根 WebApplicat…...
日语学习-日语知识点小记-进阶-JLPT-N1阶段(1):语法单词
日语学习-日语知识点小记-进阶-JLPT-N1阶段(1):语法单词 1、前言(1)情况说明(2)工程师的信仰(3)高级语法N1语法和难点一、N1语法学习内容(高级语法ÿ…...
stm32week14
stm32学习 十.GPIO 2.基本结构 基本结构: F1与其它的的最大区别是上下拉电阻的位置 施密特触发器是一种整形电路,可以将非标准方波,整形成方波 图中MOS管的输出规则: 3.8中工作模式 ①输入浮空: 上下拉电阻均不工…...
WPF中Binding
绑定ViewModel中的数据 添加数据上下文 方法一:在XAML中添加 <Window.DataContext><local:MainWindowViewModel /> </Window.DataContext>方法二:在界面层的cs文件中添加 this.DataContext new MainWindowViewModel();绑定 publ…...
Google Agent space时代,浅谈Agent2Agent (A2A) 协议和挑战!
如果说去年Google Cloud大会大家还在数“AI”这个词被提了多少次,那么今年,绝对是“Agent”的主场!开发者主题演讲几乎被它“刷屏”,展区的许多 Demo 也都号称是 Agent 应用。 但我得诚实地说,大会现场关于 Agents 的 …...
爬虫的应用
在自然语言处理(NLP)领域,文本数据的预处理是至关重要的基础环节。它如同工匠雕琢璞玉前的打磨工作,直接影响后续模型分析与挖掘的效果。本文将基于 Python,以电商平台的差评和优质评价文本数据为例,详细展…...
力扣面试150题--相同的树
Day 41 题目描述 做法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right…...
Java后端开发day40--异常File
(以下内容全部来自上述课程) 异常 异常:异常就是代表程序出现的问题 1. 异常的分类 1.1 Error 代表的是系统级别的错误(属于严重问题) 系统一旦出现问题,sun公司会把这些错误封装成Error对象。 Error…...
集成算法学习
集成算法通过组合多个弱学习器提升模型性能,以下是核心内容详解: 一、核心思想 - 组合优势:结合多个简单模型(如决策树),通过“少数服从多数”或“加权平均”等策略,降低方差、偏差或过拟合风险…...
工业认知智能:从数据分析到知识创造
工业认知智能:从数据分析到知识创造 引言 当前制造业面临的知识管理困境令人震惊:68%的工艺知识存储于老员工头脑中,30%的企业因知识传承断层导致质量事故。麦肯锡研究显示,应用认知智能技术的企业,其工艺创新速度提升3-5倍。本文将系统阐述工业认知智能的"感知-理…...
8.1 Python+Docker+企业微信集成实战:自动化报告生成与CI/CD部署全攻略
Python+Docker+企业微信集成实战:自动化报告生成与CI/CD部署全攻略 关键词:PDF报告生成, Word文档自动化, 企业微信集成, Docker容器化, CI/CD流水线 1. 多格式报告生成实战 通过扩展报告输出格式,满足不同用户的文档需求。我们使用Python生态的成熟库实现PDF/Word生成,并…...
25.5.4数据结构|哈夫曼树 学习笔记
知识点前言 一、搞清楚概念 ●权:___________ ●带权路径长度:__________ WPL所有的叶子结点的权值*路径长度之和 ●前缀编码:____________ 二、构造哈夫曼树 n个带权值的结点,构造哈夫曼树算法: 1、转化成n棵树组成的…...
统计学中的p值是什么?怎么使用?
李升伟 整理 在统计学中,p值(p-value)是帮助研究者判断假设检验结果是否具有统计显著性的重要指标。以下是关于p值的详细解释和使用方法: 1. p值的定义 p值表示在原假设(H0)为真的情况下,观察…...
22:一维码与二维码区别
一维码(条形码) 一维条码即指条码条和空的排列规则,常用的一维码的码制包括:EAN码、39码、交叉25码、UPC码、128码、93码,ISBN码,及Codabar(库德巴码)等。 条码是由一组规则排列的条…...
Java学习手册:SQL 优化技巧
一、SQL 查询优化 选择合适的索引列 :索引可以显著提高查询速度,但需要选择合适的列来创建索引。通常,对于频繁作为查询条件的列、连接操作的列以及排序或分组操作的列,应该考虑创建索引。例如,在一个订单表中…...
《Vue3学习手记8》
vue3中的一些API shallowRef ( ) 和shallowReactive ( ) shallowRef (浅层响应式) 1.作用:创建一个响应式数据,但只对顶层属性进行响应式处理。 2.用法: const originalref(...) const original2shallowRef(original) 3.特点:只跟踪引用值的变化,不关心…...
平衡二叉搜索树模拟实现1-------AVL树(插入,删除,查找)
本章目标 1.AVL树的概念 2.AVL树的模拟实现 1.AVL树的概念 1.AVL树是最先被发明的平衡二叉搜索树,AVL树是一颗空树或者具有以下的性质 它的左右子树都是AVL树,并且左右高度差不超过1,AVL树是一颗高度平衡二叉搜索树,通过高度差去控制平衡 2.为什么高度差是1? 当结点个数为8…...
运算放大器的主要技术指标
运放(运算放大器)是一种基础电子器件,具有输入阻抗高、开环放大倍数大、输入端电流小、同相端与反相端电压几乎相等等特点。在选型时,需要考虑技术指标如输入失调电压、输入失调电压漂移、输入失调电流、共模抑制比、压摆率、建立…...
51单片机入门教程——每个音符对应的重装载值
前言 本教程基于B站江协科技课程进行个人学习整理,专为拥有C语言基础的零基础入门51单片机新手设计。既帮助解决因时间差导致的设备迭代调试难题,也助力新手快速掌握51单片机核心知识,实现从C语言理论到单片机实践应用的高效过渡 。...
新一代智能座舱娱乐系统软件架构设计文档
一 文档概述 本文档描述了基于Android系统与多模态大模型融合的新一代智能座舱娱乐系统的软件架构设计。该系统将通过深度学习的个性化适配、多模态感知融合和持续自进化能力,重新定义人车交互体验。 二 整体架构设计 2.1 分层架构视图 系统采用五层垂直架构与三…...
深度优先搜索(DFS)与广度优先搜索(BFS):图与树遍历的两大利器
深度优先搜索(DFS)与广度优先搜索(BFS):图与树遍历的两大利器 在数据结构与算法的世界中,深度优先搜索(DFS)和广度优先搜索(BFS)是两种非常经典的遍历算法。…...
比较 TensorFlow 和 PyTorch
TensorFlow和PyTorch是深度学习领域中两个非常流行的开源机器学习框架,下面为你详细介绍。 1. 历史与背景 TensorFlow:由Google开发和维护,于2015年开源。因其强大的生产能力和广泛的工具支持,在工业界得到了广泛应用。PyTorch&…...
jeecg查询指定时间
jeecg查询指定时间 ApiOperation(value"请假表-分页列表查询", notes"请假表-分页列表查询")GetMapping(value "/list")public Result<IPage<MlLeaveRequest>> queryPageList(MlLeaveRequest mlLeaveRequest,RequestParam(name&qu…...
无人机视觉:连接像素与现实世界 —— 像素与GPS坐标双向转换指南
在无人机航拍应用中,一个核心的需求是将图像上的某个点与现实世界中的地理位置精确对应起来。无论是目标跟踪、地图测绘还是农情监测,理解图像像素与其对应的经纬度(GPS坐标)之间的关系至关重要。本文将详细介绍如何实现单个像素坐…...
php study 网站出现404 - Page Not Found 未找到
最近在用php study搭建本地网站时,出现了404 - Page Not Found 未找到的情况,解决方式如下: 第一种:在wp 后台固定链接设置中修改链接形式 第二种:没有安装伪静态! 小皮面板中 设置--配置文件--编辑你所搭建的网站 在红色框框处…...
互联网大厂Java求职面试:核心技术点深度解析
互联网大厂Java求职面试:核心技术点深度解析 在互联网大厂的Java岗位面试中,技术总监级别的面试官通常会从实际业务场景出发,层层深入地考察候选人的技术能力。本文通过一个严肃专业的技术总监与搞笑但有技术潜力的程序员郑薪苦之间的互动对…...
【Java idea配置】
IntelliJ IDEA创建类时自动生成注释 /** * program: ${PROJECT_NAME} * * since: jdk1.8 * * description: ${description} * * author: ${USER} * * create: ${YEAR}-${MONTH}-${DAY} ${HOUR}:${MINUTE} **/自动导入和自动移除无用导入 idea彩色日志不生效 调试日志输出 在…...
[GESP202503 四级] 二阶矩阵c++
题目描述 小 A 有一个 n 行 m 列的矩阵 A。 小 A 认为一个 22 的矩阵 D 是好的,当且仅当 。其中 表示矩阵 D 的第 i 行第 j 列的元素。 小 A 想知道 A 中有多少个好的子矩阵。 输入 第一行,两个正整数 n,m。 接下来 n 行,每行 m 个整数…...
PyQt5基本介绍
PyQt5是基于Digia公司强大图形框架Qt5的python接口,由一组python模块构成。是一个用于创建桌面应用程序的Python库,它是Qt图形用户界面工具包的Python绑定。 Qt是一个跨平台的C库,提供了一套丰富的工具和功能,用于开发图形用户界…...
Spring AI 实战:第十章、Spring AI RAG之博学多才
引言:从“博闻强记”到“博学多才” 在人工智能的发展历程中,大语言模型(LLM)已经展现了惊人的“博闻强记”能力——它们能写诗、编码、解答常识问题,甚至模拟人类对话。然而,当面对专业领域知识或实时更新的信息时,这些模型往往会暴露其局限性:要么“一本正经地胡说八…...
Runnable 组件生命周期监听器与使用场景
Runnable 生命周期监听器 1.1 监听机制演进 在 LangChain 框架中,Runnable 组件提供两种监控方案: 传统模式:通过 config callbacks 参数传递回调配置增强模式:使用 with_listeners() 方法实现生命周期订阅 …...
五、shell脚本--函数与脚本结构:搭积木,让脚本更有条理
随着我们的脚本越来越长、越来越复杂,直接把所有命令堆在一起会变得难以阅读和维护。这时候,函数 (Function) 就派上大用场了! 函数就像一个可以重复使用的代码块,你可以给它起个名字,然后在脚本的任何地方通过名字来…...
单调栈与单调队列(c艹)、可视化Qt?
单调栈和单调队列的区别在于 ChatGLM 单调栈和单调队列都是数据结构中用于处理序列问题的工具,它们在处理问题时具有不同的特性和应用场景。以下是单调栈和单调队列的主要区别: 定义: 单调栈:是一种特殊的栈,其中的元…...
哈夫曼树和哈夫曼编码
哈夫曼编码一般用来对字符串进行编码格式的表示。其中要克服的最大问题,莫过于就是一串由0或者1组成的编码,你无法区分哪些01组成的编码部分是属于哪些字符的,因此哈夫曼编码的出现解决了这个问题。 在介绍哈夫曼编码之前,先介绍…...
基于 AI 的人像修复与编辑技术:CompleteMe 系统的研究与应用
概述 加利福尼亚大学默塞德分校与 Adobe 的新合作在人像补全领域取得了突破性进展——人像补全是一项备受关注的任务,旨在“揭示”人像中被遮挡或隐藏的部分,可用于虚拟试穿、动画制作和照片编辑等场景。 除了修复损坏的图像或根据用户意愿更改图像外&a…...
spring 使用FactoryBean注入bean
spring 使用FactoryBean注入bean 1、介绍 通常是ApplicationContext,就是IOC容器,ApplicationContext是BeanFactory的实现类,是spring最核心的接口。用getBean来加载bean。BeanFactory相当于是IOC的基础类。而FactoryBean是另一个东西&a…...
AI 编程日报 · 2025 年 5 月 04 日|GitHub Copilot Agent 模式发布,Ultralytics 优化训练效率
1、OpenAI 确认 GPT-4o“谄媚”个性更新已完全回滚 OpenAI 官方已确认,先前推送的一项旨在改进 GPT-4o 模型个性的更新已被完全撤销。该更新最初目标是提升模型的智能与个性,使其交互更直观有效,但实际效果却导致模型表现出过度“谄媚”和“…...
C++ STL简介:构建高效程序的基石
0. 引言 在现代软件开发领域,C语言凭借其强大的性能和灵活性占据着重要地位。而C标准模板库(Standard Template Library,简称STL)作为C标准库的核心组件,更是开发者手中不可或缺的利器。它犹如一座知识宝库࿰…...
大模型(LLMs)RAG 版面分析——文本分块面
大模型(LLMs)RAG 版面分析——文本分块面 一、为什么需要对文本分块? 二、能不能介绍一下常见的文本分块方法? 2.1 一般的文本分块方法 2.2 正则拆分的文本分块方法 2.3 Spacy Text Splitter 方法 2.4 基于 langchain 的 Cha…...
系统思考:核心价值与竞争力
最近,设计师的小伙伴跟我提到,行业内竞争越来越激烈,大家都开始拼命降价。但从系统思考的角度来看,我想说一句话:“人多的地方,不要去。” 为什么这么说?在竞争愈发激烈的环境中,我…...
【RocketMQ Broker 相关源码】- broker 启动源码(2)
文章目录 1. 前言2. 创建 DefaultMessageStore3. DefaultMessageStore#load3.1 CommitLog#load3.2 loadConsumeQueue 加载 ConsumeQueue 文件3.3 创建 StoreCheckpoint3.4 indexService.load 加载 IndexFile 文件3.5 recover 文件恢复3.6 延时消息服务加载 4. registerProcesso…...
mysql中int(1) 和 int(10) 有什么区别?
困惑 最近遇到个问题,有个表的要加个user_id字段,user_id字段可能很大,于是我提mysql工单alter table xxx ADD user_id int(1)。领导看到我的sql工单,于是说:这int(1)怕是不够用吧,接下来是一通解…...
jetson orin nano super AI模型部署之路(八)tensorrt C++ api介绍
我们基于tensorrt-cpp-api这个仓库介绍。这个仓库的代码是一个非常不错的tensorrt的cpp api实现,可基于此开发自己的项目。 我们从src/main.cpp开始按顺序说明。 一、首先是声明我们创建tensorrt model的参数。 // Specify our GPU inference configuration optio…...