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

【AI插件开发】Notepad++ AI插件开发实践:支持多平台多模型

引言

上篇文章我们的Notepad++插件介绍到Dock窗口集成,本篇将继续完善插件功能,主要包括两个部分:

  • 支持多平台、多模型
  • 支持多种授权验证、接口类型

一、多平台

原先的配置项很简单:

// PluginConf.h
class PlatformConf {
public:std::string _baseUrl;      // API基础地址std::string _apiSkey;      // 认证密钥std::string _modelName;    // 模型标识std::string _generateEndpoint; // 生成接口std::string _chatEndpoint; // 对话接口
};

但是插件本身可能需要接入多个平台,因此有必要支持多平台,因此需要重新设计配置文件,如下:

{// 当前选用的运行平台标识// 必须与下方platforms对象中的某个平台键名完全一致// 系统将根据此字段加载对应的平台配置"platform": "OurCopDev",// 多平台环境配置集合// 支持预定义多个平台的配置参数,便于快速切换环境// 每个键名代表平台标识,建议采用有明确含义的命名(如环境类型/业务线)"platforms": {// Infini平台配置(示例第三方系统集成)// 可包含API地址、认证信息、超时设置等参数"infini": {// 平台配置项示例:// "api_endpoint": "https://api.infini.ai",// "auth_token": "xxx-xxx-xxx"},// 生产环境配置// 通常包含正式环境地址、生产用密钥等敏感信息"OurCopProd": {// 平台配置项示例:},// 开发环境配置// 一般包含测试服务器地址、调试参数等非生产配置"OurCopDev": {// 典型配置项}}
}

这样,插件根据当前的配置平台名称platform支持使用不同的AI平台

二、多模型

因为一般平台会提供多个内置的模型,因此需要在此基础上,支持用户选择不同的模型。

此外,不同的平台接口也不一样,有的是https,有的是http,有的是post接口,有的是get接口,因此针对各种情况需要抽象细化需求,最终整理设计的平台配置内容如下:

{// SSL配置开关// true: 启用HTTPS协议,所有请求将通过加密通道传输// false: 使用HTTP协议(不建议生产环境使用)// 注意:启用时需确保服务端配置了有效的SSL证书"enable_ssl": true,// 基础服务地址// API请求的根域名/地址,所有接口路径将基于此地址拼接// 示例:https://cloud.infini-ai.com/maas/v1/..."base_url": "cloud.infini-ai.com",// 当前激活的模型名称// 必须与models列表中某个值完全匹配// 用于默认的API请求参数"model_name": "deepseek-r1-distill-qwen-32b",// 可用模型清单// 平台支持的全部模型列表(可动态更新)// 可通过models_endpoint接口自动获取或手动维护"models": [ "deepseek-r1-distill-qwen-32b","deepseek-r1","deepseek-v3"],// 文本生成接口配置// 用于单轮文本生成的API端点设置// prompt字段当前未使用(可能为兼容旧版本保留)"generate_endpoint": {"method": "post",    // HTTP请求方法"api": "/maas/v1/completions",  // 接口路径"prompt": ""        // 保留字段(未来可能用于预设提示词)},// 对话接口配置// 支持多轮对话的API端点设置// prompt字段当前未使用(可能用于会话初始化模板)"chat_endpoint": {"method": "post","api": "/maas/v1/chat/completions","prompt": ""},// 模型列表接口配置// 用于动态获取可用模型列表的API配置// 需要至少包含method和api字段才能启用自动更新// 示例可添加://   "method": "get",//   "api": "/maas/v1/models",//   "auth_required": true  // 是否需要鉴权"models_endpoint": {}  
}

补充说明:

  1. 接口路径均基于base_url拼接,如最终生成接口地址为:
    https://cloud.infini-ai.com/maas/v1/completions
  2. models_endpoint若配置正确,系统可自动更新models列表(目前尚未实现),否则需手动维护
  3. prompt字段的保留设计可能用于未来支持预设提示词模板功能
成功
失败
已配置
未配置
启用认证
Basic
Bearer
ApiKey
成功
失败
插件启动
读取配置文件
解析platform字段
匹配platforms配置
加载对应平台参数
使用默认配置
初始化HTTP客户端
检查models_endpoint
自动拉取模型列表
使用预设models列表
更新models配置
用户选择模型
构建API请求
检查认证配置
调用GetAuthorizationHeader
认证类型判断
生成Basic头
生成Bearer头
生成API Key头
合并请求头
发送HTTP请求
响应处理
返回结果
重试/报错

三、兼容不同的授权方式

1. API Key(最常见)

  • 原理:客户端在请求头或参数中携带唯一密钥,服务端验证密钥有效性。
  • 典型场景
    • OpenAI、讯飞星火等大模型 API 调用(如 X-API-Key: your_key)。
    • 云服务商提供的 AI 服务(如图像识别、自然语言处理)。
  • 优势:轻量、易集成,适合开放平台和第三方调用。
  • 安全建议
    • 限制密钥权限范围(如绑定 IP、设置调用频率)。
    • 定期轮换密钥,防范泄露风险。

2. OAuth 2.0(第三方授权)

  • 原理:通过授权服务器颁发 access_token,客户端携带令牌访问 AI 服务。
  • 典型场景
    • 需要用户授权的 AI 服务(如企业级模型调用、个性化推荐)。
    • 微信/QQ 登录后调用 AI 能力。
  • 流程
    1. 用户授权 → 2. 获取 code → 3. 兑换 access_token → 4. 调用 API。
  • 优势:支持细粒度权限控制,适合生态化平台。

3. JWT(无状态令牌)

  • 原理:服务端生成含用户信息和过期时间的加密 Token,客户端后续请求携带。
  • 典型场景
    • 分布式 AI 服务调用(如多模型协同推理)。
    • 移动端或单页应用调用 AI 接口(如语音合成、对话机器人)。
  • 结构Header.Payload.Signature(如 xxxxx.yyyyy.zzzzz)。
  • 优势:无状态,减轻服务端压力;支持短时效+刷新机制。

4. HMAC(防篡改签名)

  • 原理:客户端与服务端共享密钥,对请求内容(时间戳、请求体)生成签名。
  • 典型场景
    • 金融风控模型调用、支付验证等高安全场景。
    • 防止请求被篡改或重放攻击。
  • 示例头
    Authorization: HMAC-SHA256 key_id="123", signature="abc123..."
    
  • 优势:确保请求完整性和身份真实性。

5. Basic Auth(基础认证)

  • 原理:HTTP 头携带 username:password 的 Base64 编码。
  • 典型场景
    • 内部测试环境或低风险 AI 服务调用。
    • 配合 HTTPS 使用以加密传输。
  • 示例头
    Authorization: Basic base64encode("user:pass")
    
  • 局限:明文传输风险,需严格依赖 HTTPS。

6. 授权实现

基于常见的类型,本插件自持不同的header方式的认证授权方式。

授权流程
Header
Para
DeliveryType
认证配置解析
构造HTTP头
构造请求参数
Basic认证编码
Bearer Token拼接
API Key处理
Base64加密
注入认证信息
完成请求准备
抽象定义结构对象
class AuthorizationConf : public IConfig
{
public:// 授权类型枚举,定义支持的认证授权方式 enum class AuthType{None,    // 无认证授权 Basic,   // 基础认证(用户名+密码的Base64编码)Bearer,  // Bearer Token认证(如JWT/OAuth 2.0令牌)ApiKey   // API Key认证(支持云服务/AI模型调用场景)};// 参数传递方式枚举,定义认证信息传输位置 enum class DeliveryType{Header,  // 通过HTTP请求头传递(如Authorization头)Para     // 通过请求参数传递(如URL参数或POST参数)};AuthType eAuthType = AuthType::None;          // 当前配置的授权类型,默认关闭认证 DeliveryType eDeliveryType = DeliveryType::Header; // 认证信息传递方式,默认使用请求头 // 认证授权数据,内容格式与授权类型强相关:// - Basic: "username:password"的Base64编码 // - Bearer: "access_token"字符串 // - ApiKey: 明文密钥(如"X-API-Key: your_key")std::string auth_data; 
};

注解说明:

  1. AuthType 枚举:覆盖主流认证方式,其中:

    • Basic 对应HTTP基础认证,需配合HTTPS使用
    • Bearer 适用于JWT/OAuth 2.0等令牌体系
    • ApiKey 常用于云服务商API调用(如阿里云OSS的C++ SDK)
  2. DeliveryType 枚举:区分认证信息的传输载体:

    • Header 符合RESTful API设计规范(如Authorization: Bearer xxx
    • Para 多用于简易场景或兼容旧系统
  3. auth_data 格式:需根据认证类型动态调整内容:

    • Basic认证需按user:pass格式Base64编码
    • API Key通常直接使用明文密钥(需HTTPS保障安全)
定义配置加载函数
virtual void from_json(const nlohmann::json& j) override
{std::string strVal;if (Util::JsonGet(j, "type", strVal)){eAuthType = AuthType::None;if (!Util::icasecompare(strVal, "Basic")){eAuthType = AuthType::Basic;}if (!Util::icasecompare(strVal, "Bearer")){eAuthType = AuthType::Bearer;}if (!Util::icasecompare(strVal, "ApiKey")){eAuthType = AuthType::ApiKey;}}Util::JsonGet(j, "data", auth_data);
}
实现接口授权信息的设置
bool AiModel::GetAuthorizationHeader(const AuthorizationConf& auth, std::string& hkey, std::string& hval)
{hkey = "";  // 初始化HTTP头键名hval = "";  // 初始化HTTP头值const std::string& auth_data = auth.auth_data;  // 获取认证配置数据switch (auth.eAuthType) {// 无认证授权时直接返回成功(空头信息)case AuthorizationConf::AuthType::None:return true;  // 无认证场景直接通过case AuthorizationConf::AuthType::Basic: {// Basic认证需要"username:password"格式size_t colonPos = auth_data.find(':');if (colonPos == std::string::npos) return false;  // 缺少分隔符格式错误std::string encoded = Util::Base64Encode(auth_data);  // 对凭证进行Base64编码hkey = "Authorization";  // 固定使用标准HTTP头hval = "Basic " + encoded;  // 符合RFC 7617规范return true;}case AuthorizationConf::AuthType::Bearer:{if (auth_data.empty()) return false;  // 空Token无效hkey = "Authorization";  // 标准Bearer Token头hval = "Bearer " + auth_data;  // 符合RFC 6750规范return true;}case AuthorizationConf::AuthType::ApiKey: {if (auth.eDeliveryType == AuthorizationConf::DeliveryType::Header) {// 支持自定义头格式或默认X-API-Key头size_t colonPos = auth_data.find(':');if (colonPos != std::string::npos) {// 用户自定义头格式(如"X-Custom-Key: value")hkey = Util::Trim(auth_data.substr(0, colonPos));  // 提取头名称hval = Util::Trim(auth_data.substr(colonPos + 1));  // 提取头值}else {// 默认使用行业通用的X-API-Key头hkey = "X-API-Key";hval = auth_data;}return true;}// 参数传递需在URL构造阶段处理,此处无法支持return false;}default:return false;  // 未知认证类型处理失败}return true;  // 默认返回(实际不可达)
}

注解说明:

  1. 函数职责:根据认证配置生成HTTP请求头的键值对,支持多种认证方式的动态适配

  2. Basic认证实现

    • 严格校验username:password格式
    • 使用Base64编码但非加密(需配合HTTPS)
  3. Bearer Token处理

    • 直接拼接Bearer 前缀,符合RFC 6750规范
    • 适用于JWT/OAuth 2.0等令牌体系
  4. API Key机制

    • 支持灵活的头定义(如云服务商特定要求)
    • 默认使用X-API-Key头(遵循行业惯例)
    • 参数传递方式需在URL构造时实现(如?api_key=xxx
设置授权认证信息
// 初始化HTTP请求头,设置默认的Content-Type为JSON格式,确保数据以UTF-8编码传输
std::unordered_map<std::string, std::string> headers = {{"Content-Type", "application/json; charset=UTF-8"}
};// 从授权配置中提取认证名称和值,若获取成功且认证名称非空则添加到请求头
std::string authName, authValue;
if (GetAuthorizationHeader(plat.authorization, authName, authValue) && !authName.empty()) {headers[authName] = authValue;  // 动态添加认证信息到请求头
}// 将构建完成的请求头绑定到HTTP客户端实例,后续请求将自动携带这些头信息
cli.SetHeaders(headers);

注解说明:

  1. headers初始化块通过显式设置Content-Type声明了数据交换格式,这符合RESTful接口的通用规范
  2. GetAuthorizationHeader的返回值校验结合了空值检查,确保认证字段有效性(如Bearer Token或API Key)
  3. 使用unordered_mapoperator[]进行键值操作,保证认证头的高效存取(O(1)时间复杂度)
  4. SetHeaders调用将配置固化到客户端实例,符合C++ RAII(Resource Acquisition Is Initialization)设计原则

四、总结说明

1. 架构设计核心价值

本AI插件通过分层解耦设计实现了三大核心能力:

  • 平台无关性:通过platforms配置体系(如OurCopDev/infini)实现多环境快速切换
  • 模型动态适配:支持models_endpoint自动发现机制,结合手动配置保障兼容性
  • 认证统一抽象:封装主流授权方式(Basic/Bearer/ApiKey等),满足从测试到生产的全场景需求

2. 未来演进方向

模块当前状态规划能力
模型管理手动维护models列表实现models_endpoint自动同步
授权体系支持Header传递扩展DeliveryType::Para参数级认证
协议支持HTTP/HTTPS双模增加WebSocket实时接口支持
性能优化单线程请求引入异步协程提升并发能力

3. 配置模板

{"platform": "OurCopDev","timeout": 90,"platforms": {"infini": {"enable_ssl": true,"base_url": "cloud.infini-ai.com","authorization": {"type": "Bearer","data": "sk-**"},"model_name": "deepseek-r1-distill-qwen-32b","models": [ "deepseek-r1-distill-qwen-32b", "deepseek-r1", "deepseek-v3" ],"generate_endpoint": {"method": "post","api": "/maas/v1/completions","prompt": ""},"chat_endpoint": {"method": "post","api": "/maas/v1/chat/completions","prompt": ""},"models_endpoint": {}},"OurCopProd": {"enable_ssl": true,"base_url": "open.arbboter.com.cn","authorization": {"type": "ApiKey","data": "api-key:k****"},"model_name": "qwq_32b","models": [ "qwq_32b", "deepseek_v3_0324", "deepseek_r1_671b" ],"generate_endpoint": {"method": "post","api": "/maas/v1/completions","prompt": ""},"chat_endpoint": {"method": "post","api": "/prod/llm/personal/v1/chat/completions","prompt": ""},"models_endpoint": {}},"OurCopDev": {"enable_ssl": false,"base_url": "openapi.arbboter.com","authorization": {"type": "ApiKey","data": "api-key:k****"},"model_name": "deepseek_r1_671b","models": [ "qwq_32b", "deepseek_v3_0324", "deepseek_r1_671b" ],"generate_endpoint": {"method": "post","api": "/maas/v1/completions","prompt": ""},"chat_endpoint": {"method": "post","api": "/test/llm/personal/v1/chat/completions","prompt": ""},"models_endpoint": {}}}
}

相关文章:

【AI插件开发】Notepad++ AI插件开发实践:支持多平台多模型

引言 上篇文章我们的Notepad插件介绍到Dock窗口集成&#xff0c;本篇将继续完善插件功能&#xff0c;主要包括两个部分&#xff1a; 支持多平台、多模型支持多种授权验证、接口类型 一、多平台 原先的配置项很简单&#xff1a; // PluginConf.h class PlatformConf { publ…...

微信小程序数字滚动效果

效果图 .wxml <view class"container"><view class"container-num" wx:for"{{number}}" wx:key"index"><view class"num-container" style"--h:{{h}}px;--y:{{-item * h }}px;"><view wx:f…...

wx219基于ssm+vue+uniapp的教师管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…...

Python 注释进阶之Google风格

文章目录 1. Google 风格 Docstring 的核心特点2. Google 风格的基本结构3. 编写规则和注意事项4. 最常用的 Google 风格 Docstring 示例示例 1&#xff1a;普通函数 示例 2&#xff1a;带默认参数和可变参数的函数示例 3&#xff1a;类示例 4&#xff1a;生成器函数示例 5&…...

写测试文档时,需要的环境配置怎么查看

操作系统 cat /etc/os-releaseCPU信息 lscpu 内存 sudo dmidecode --type memory | grep -E "Size:|Type:|Speed:"硬盘 列出当前系统中 所有块设备&#xff08;Block Devices&#xff09; 的信息&#xff0c;并显示指定列&#xff08;-o 参数&#xff09; lsblk…...

强化学习的数学原理(十)actor-critic 方法

由于全文太长&#xff0c;只好分开发了。(已完结&#xff01;在专栏查看本系列其他文章&#xff09; 个人博客可以直接看全文~ 本系列为在学习赵世钰老师的“强化学习的数学原理” 课程后所作笔记。 课堂视频链接https://www.bilibili.com/video/BV1sd4y167NS/ 第十章 acto…...

多个定时器同时工作时,会出现哪些常见的bug ,如何解决??(定时任务未实时更新但刷新后正常的问题分析)

1. 定时器冲突与覆盖 问题&#xff1a;后设置的定时器可能覆盖先前的定时器&#xff0c;导致前一个定时器失效 原因&#xff1a;未正确管理定时器ID或未清除前一个定时器 2. 性能问题 内存泄漏&#xff1a;未清除不再需要的定时器会导致内存占用不断增加 CPU过载&#xff1a…...

代码随想录算法训练营day5(哈希表)

华子目录 有效的字母异位词思路 有效的字母异位词 https://leetcode.cn/problems/valid-anagram/description/ 思路 使用哈希表&#xff0c;这里哈希表使用数组先申请一个26空间的大小的数组遍历第一个字符串&#xff0c;记录每个字符出现的次数1遍历第二个字符串&#xff0c…...

Python(17)Python字符编码完全指南:从存储原理到乱码终结实战

目录 背景介绍一、字符编码核心原理1. 计算机存储本质2. Python3的编码革命3. 主流编码格式对比 二、编码转换核心方法1. 编码&#xff08;Encode&#xff09;过程2. 解码&#xff08;Decode&#xff09;过程3. 错误处理策略 三、文件操作编码实战1. 文本文件读写2. 二进制模式…...

Node.js 文件读取与复制相关内容

Node.js 文件读取与复制相关内容的系统总结&#xff0c;包括 同步读取、异步读取、流式读取、复制操作、两者对比及内存测试。 &#x1f9e9; 一、Node.js 文件读取方式总结 Node.js 使用 fs&#xff08;文件系统&#xff09;模块进行文件操作&#xff1a; 1. 同步读取&#…...

大数据面试问答-HBase/ClickHouse

1. HBase 1.1 概念 HBase是构建在Hadoop HDFS之上的分布式NoSQL数据库&#xff0c;采用列式存储模型&#xff0c;支持海量数据的实时读写和随机访问。适用于高吞吐、低延迟的场景&#xff0c;如实时日志处理、在线交易等。 RowKey&#xff08;行键&#xff09; 定义&#xf…...

jupyter 文件浏览器,加强版,超好用,免费exe

第一步&#xff1a;github搜索 lukairui的 jupyter-viewer-plus 仓库 第二步&#xff1a; git clone 到本地。 解压zip包 第三步&#xff1a; 进入压缩包&#xff0c;第一次双击打开jupyter-viewer-plus.exe运行&#xff0c;第一次运行后&#xff0c;界面上有一个“设为…...

【AI工具】用大模型生成脑图初试

刚试用了一下通过大模型生成脑图&#xff0c;非常简单&#xff0c;记录一下 一、用大模型生成脑图文件 关键&#xff1a;存在markdown文件 举例&#xff1a;使用Deepseek&#xff0c;输入问题&#xff1a;“针对大模型的后训练&#xff0c;生成一个开发计划&#xff0c;用ma…...

数据结构-树与二叉树

一、树的定义与基本术语 1.1 树的定义 树&#xff08;Tree&#xff09;是一种非线性的数据结构&#xff0c;它是由 n&#xff08;n ≥ 0&#xff09;个有限节点组成的集合。如果 n 0&#xff0c;称为空树&#xff1b;如果 n > 0&#xff0c;则&#xff1a; 有一个特定的节…...

STL_unordered_map_01_基本用法

&#x1f44b; Hi, I’m liubo&#x1f440; I’m interested in harmony&#x1f331; I’m currently learning harmony&#x1f49e;️ I’m looking to collaborate on …&#x1f4eb; How to reach me …&#x1f4c7; sssssdsdsdsdsdsdasd&#x1f383; dsdsdsdsdsddfsg…...

ARCGIS国土超级工具集1.5更新说明

ARCGIS国土超级工具集V1.5版本更新说明&#xff1a;因作者近段时间工作比较忙及正在编写ARCGISPro国土超级工具集&#xff08;截图附后&#xff09;的原因&#xff0c;故本次更新为小更新&#xff08;没有增加新功能&#xff0c;只更新了已有的工具&#xff09;。本次更新主要修…...

主流物理仿真引擎和机器人/强化学习仿真平台对比

以下是当前主流的物理仿真引擎和机器人/强化学习仿真平台的特点和适用场景&#xff0c;方便根据需求选择&#xff1a; &#x1f9e0; NVIDIA 系列 ✅ Isaac Lab v1.4 / v2 特点&#xff1a; 基于 Omniverse Isaac Sim&#xff0c;属于高端视觉机器人仿真框架v2 更加模块化&a…...

STM32 HAL库内部 Flash 读写实现

一、STM32F407 内部 Flash 概述 1.1 Flash 存储器的基本概念 Flash 存储器是一种非易失性存储器&#xff0c;它可以在掉电的情况下保持数据。STM32F407 系列微控制器内部集成了一定容量的 Flash 存储器&#xff0c;用于存储程序代码和数据。Flash 存储器具有擦除和编程次数的…...

C++学习:六个月从基础到就业——面向对象编程:构造函数与析构函数

C学习&#xff1a;六个月从基础到就业——面向对象编程&#xff1a;构造函数与析构函数 本文是我C学习之旅系列的第十篇技术文章&#xff0c;主要讨论C中构造函数与析构函数的概念、特点和使用技巧。这些是C对象生命周期管理的关键组成部分。查看完整系列目录了解更多内容。 引…...

dfs二叉树中的深搜(回溯、剪枝)--力扣129、814、230、257

目录 1.1题目链接&#xff1a;129.求根节点到叶结点数字之和 1.2题目描述&#xff1a;给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。 1.3解法(dfs-前序遍历)&#xff1a; 2.1题目链接&#xff1a;814.二叉树剪枝 2.2题目描述&…...

Python Selenium 一小时速通教程

Python Selenium 一小时速通教程 实战案例 一、环境配置&#xff08;10分钟&#xff09; 安装Python 确保已安装Python 3.x&#xff08;官网下载&#xff09;。 安装Selenium 在终端运行&#xff1a; pip install selenium下载浏览器驱动 Chrome&#xff1a;访问 ChromeDriv…...

通过GO后端项目实践理解DDD架构

最近在工作过程中重构的项目要求使用DDD架构&#xff0c;在网上查询资料发现教程五花八门&#xff0c;并且大部分内容都是长篇的概念讲解&#xff0c;晦涩难懂&#xff0c;笔者看了一些github上入门的使用DDD的GO项目&#xff0c;并结合自己开发中的经验&#xff0c;谈谈自己对…...

MybatisPlus最新版分页无法使用

在使用分页的时候发现分页拦截器关键API会报错&#xff0c;其实根本原因是在之前只需要导入一个mybatisplus依赖&#xff0c;而现在分页似乎被单独分离出来了&#xff0c;需要额外导入新依赖使其支持 ​ <dependency><groupId>com.baomidou</groupId><art…...

【Android学习记录】工具使用

文章目录 一. 精准找视图资源ID1. 准备工作2. 使用 uiautomator 工具2.1. 获取设备的窗口内容2.2. Pull XML 文件2.3. 查看 XML 文件 3. 直接使用 ADB 命令4. 使用 Android Studio 的 Layout Inspector总结 二. adb shell dumpsys activity1. 如何使用 ADB 命令2. 输出内容解析…...

youtube视频和telegram视频加载原理差异分析

1. 客户侧缓存与流式播放机制​​ 流式视频应用&#xff08;如 Netflix、YouTube&#xff09;通过​​边下载边播放​​实现流畅体验&#xff0c;其核心依赖以下技术&#xff1a; ​​缓存预加载​​&#xff1a;客户端在后台持续下载视频片段&#xff08;如 DASH/HLS 协议的…...

在机器视觉检测中为何选择线阵工业相机?

线阵工业相机&#xff0c;顾名思义是成像传感器呈“线”状的。虽然也是二维图像&#xff0c;但极宽&#xff0c;几千个像素的宽度&#xff0c;而高度却只有几个像素的而已。一般在两种情况下使用这种相机&#xff1a; 1. 被测视野为细长的带状&#xff0c;多用于滚筒上检测的问…...

lwip记录

Index of /releases/lwip/ (gnu.org) 以太网(Ethernet)是互联网技术的一种&#xff0c;由于它是在组网技术中占的比例最高&#xff0c;很多人 直接把以太网理解为互联网。 以太网是指遵守 IEEE 802.3 标准组成的局域网&#xff0c;由 IEEE 802.3 标准规定的主要是位于 参考模…...

Redis清空缓存

尽管redis可以设置ttl过期时间进行指定key的定时删除&#xff0c;但是在某些场景下&#xff0c;比如&#xff1a; 测试时需要批量删除指定库下所有库下所有的数据&#xff0c;则会涉及到缓存清除的话题。 如下为具体的操作及说明&#xff1a; 场景类型操作指令清空当前库下所有…...

WPF 依赖注入启动的问题

原因是在App.xaml 设置了 StartupUri“MainWindow.xaml” 1.依赖注入后启动的主窗体存在无参构造 程序正常启动&#xff0c;但是主窗体界面会弹出2个窗体。 2.依赖注入后启动的主窗体存在有参构造 报错...

Arcgis经纬线标注设置(英文、刻度显示)

在arcgis软件中绘制地图边框&#xff0c;添加经纬度度时常常面临经纬度出现中文&#xff0c;如下图所示&#xff1a; 解决方法&#xff0c;设置一下Arcgis的语言 点击高级--确认 这样Arcgis就转为英文版了&#xff0c;此时在来看经纬线刻度的标注&#xff0c;自动变成英文...

【电子通识】案例:电缆的安装方式也会影响设备的可靠性?

背景 在日常生活中&#xff0c;我们常常会忽略一些看似微不足道的细节&#xff0c;但这些细节有时却能决定设备的寿命和安全性。比如&#xff0c;你知道吗&#xff1f;一根电缆的布置方式&#xff0c;可能会决定你的设备是否会因为冷凝水而损坏。 今天&#xff0c;我们就来聊聊…...

房屋装修费用预算表:45594 =未付14509 + 付清31085【时间:20250416】

文章目录 引言I 房屋装修费用预算表II 市场价参考防水搬运3000III 装修计划整体流程进度细节国补IV 付款凭证(销售单)伟星 PPR +PVC+太阳线+地漏=6500入户门设计通铺大板瓷砖 | 湿贴 3408(地)+3600(加)+5209(墙)=12217元门头铁空调引言 关注我,发送【装修记账】获取预…...

Python文件操作完全指南:从基础到高级应用

目录 一、文件基础概念 1.1 什么是文件&#xff1f; 1.2 文件的存储方式 文本文件 二进制文件 二、Python文件操作基础 2.1 文件操作三步曲 2.2 核心函数与方法 2.3 文件读取详解 基本读取示例 文件指针机制 2.4 文件打开模式 写入文件示例 2.5 高效读取大文件 三…...

03(总)-docker篇 Dockerfile镜像制作(jdk,jar)与jar包制作成docker容器方式

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.2 上文传送门 2. docker镜像制作一: jdk2.1 制作jdk镜像2.1.1 准备工作2.1.2 jdk镜像的Dockerfile2.1.3 基于Dockerfile构建镜像2.1.4 docker使用镜像运行容器2.1.5 进入jdk1.8容器内测试 3. docker镜像制作二: java镜像(jar包)…...

CUDA的安装

打开nvidia控制面板 找到组件 打开 CUDA Toolkit Archive | NVIDIA Developer 下载CUDA...

四六级听力调频广播有线传输无线覆盖系统:弥补单一发射系统安全缺陷,构建稳定可靠听力系统平台

四六级听力调频广播有线传输无线覆盖系统:弥补单一发射系统安全缺陷&#xff0c;构建稳定可靠听力系统平台 北京海特伟业科技有限公司任洪卓发布于2025年4月16日 随着英语四六级考试的规模不断扩大&#xff0c;听力考试部分的设备可靠性问题日益凸显。传统的无线发射系统存在…...

信创服务器-大国崛起,信创当道!

信创产业是数据安全、网络安全的基础&#xff0c;也是新基建的重要组成部分。在政策的推动下&#xff0c;2020-2022 年&#xff0c;中国信创服务器出货量整体呈现出快速增长的趋势&#xff0c;其中党政、电信、金融等领域采购频次高&#xff0c;单次采购量大&#xff0c;是中国…...

【仿Mudou库one thread per loop式并发服务器实现】SERVER服务器模块实现

SERVER服务器模块实现 1. Buffer模块2. Socket模块3. Channel模块4. Poller模块5. EventLoop模块5.1 TimerQueue模块5.2 TimeWheel整合到EventLoop5.1 EventLoop与线程结合5.2 EventLoop线程池 6. Connection模块7. Acceptor模块8. TcpServer模块 1. Buffer模块 Buffer模块&…...

冒泡与 qsort 排序策略集

今天我们要学习两种排序方法&#xff0c;分别是冒泡排序和qsort函数排序,冒泡排序相对qsort函数排序要简单一点&#xff0c;更易于理解。 1.冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复遍历元素列并比较相邻元素来实现排…...

【Linux】第七章 控制对文件的访问

目录 1. 什么是文件系统权限&#xff1f;它是如何工作的&#xff1f;如何查看文件的权限&#xff1f; 2. 解释‘-rw-r--r--’这个字符串。 3. 使用什么命令可以更改文件和目录的权限&#xff1f;写出分别使用符号法和数值法将权限从 754 修改为 775 的命令。 4. 如何修改文…...

网站301搬家后谷歌一直不收录新页面怎么办?

当网站因更换域名或架构调整启用301重定向后&#xff0c;许多站长发现谷歌迟迟不收录新页面&#xff0c;甚至流量大幅下滑。 例如&#xff0c;301跳转设置错误可能导致权重传递失效&#xff0c;而新站内容与原站高度重复则可能被谷歌判定为“低价值页面”。 即使技术层面无误&a…...

socket 客户端和服务器通信

服务器 using BarrageGrab; using System; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace Lyx {class Server{private TcpListener listener;private Concurre…...

C实现md5功能

md5在线验证&#xff1a; 在线MD5计算_ip33.com 代码如下&#xff1a; #include "md5.h" #include <string.h> #include "stdio.h"/** 32-bit integer manipulation macros (little endian)*/ #ifndef GET_ULONG_LE #define GET_ULONG_LE(n,b,i) …...

【项目】CherrySudio配置MCP服务器

CherrySudio配置MCP服务器 &#xff08;一&#xff09;Cherry Studio介绍&#xff08;二&#xff09;MCP服务环境搭建&#xff08;1&#xff09;环境准备&#xff08;2&#xff09;依赖组件安装<1> Bun和UV安装 &#xff08;3&#xff09;MCP服务器使用<1> 搜索MCP…...

第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能

反模式&#xff1a;滥用导致的内存开销React 19编译器自动Memoization原理 React Hooks 性能优化进阶&#xff1a;从手动到自动 Memoization &#xff08;基于 React 18 及以下版本&#xff0c;结合 React 19 新特性分析&#xff09; 一、useMemo/useCallback 的正确使用场景…...

【Qt】QWidget 核⼼属性详解

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;QT 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f3dd; 一.相关概念&#x1f3a8;二. 核⼼属性概览&#x1f344;2.1 enabled&#x1f96d;2.2geometry&#x1f338; 2.3 windowTitle&#…...

如何知道raid 有问题了

在 Rocky Linux 8 上&#xff0c;你的服务器使用了 RAID5&#xff08;根据 lsblk 输出&#xff0c;/dev/sda3、/dev/sdb1 和 /dev/sdc1 组成 md127 RAID5 阵列&#xff09;。为了监控 RAID5 阵列中磁盘的健康状态&#xff0c;并及时发现某块磁盘损坏&#xff0c;可以通过以下方…...

操作系统之shell实现(上)

&#x1f31f; 各位看官好&#xff0c;我是maomi_9526&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习C语言的相关知识。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更…...

精益数据分析(3/126):用数据驱动企业发展的深度解析

精益数据分析&#xff08;3/126&#xff09;&#xff1a;用数据驱动企业发展的深度解析 大家好&#xff01;一直以来&#xff0c;我都坚信在当今竞争激烈的商业环境中&#xff0c;数据是企业获得竞争优势的关键。最近深入研究《精益数据分析》这本书&#xff0c;收获颇丰&…...

React 18/19 使用Ant Design全局弹窗message

react 18 及以上&#xff0c;拥有并发模式&#xff0c;不允许在渲染过程中直接触发副作用&#xff08;如弹窗、网络请求等&#xff09;&#xff0c;应将其放至 useEffect 中&#xff0c;确保其在渲染完成后调用 useEffect(() > {message.success(操作成功&#xff01;);}, …...