【鸿蒙HarmonyOS Next实战开发】实现ArkTS/JS和C/C++的交互-Node-API
一、HarmonyOS Node-API简介
在HarmonyOS应用开发中,通常以ArkTS/JS语言为主,但在一些特殊场景下,例如游戏开发、物理模拟等,由于对性能、效率等有较高要求,需要借助现有的C/C++库来实现。为了满足这种需求,HarmonyOS引入了Node-API规范,通过封装I/O、CPU密集型、OS底层等能力,并对外暴露ArkTS/JS接口,从而实现了ArkTS/JS与C/C++之间的高效交互。
HarmonyOS Node-API是基于Node.js 12.x LTS的Node-API规范进行扩展开发的一种机制,它为开发者提供了ArkTS/JS与C/C++模块之间的交互能力。该机制提供了一组稳定且跨平台的API,能够在不同的操作系统上实现无缝使用。
在本文中,若无特别说明,后续提到的“Node-API”均指代HarmonyOS Node-API的相关能力。
关于HarmonyOS Node-API与Node.js 12.x LTS的Node-API规范在接口方面的异同点,可见Node-API参考。
其主要的应用场景包括但不限于以下几种:
-
系统功能开放:系统能够通过ArkTS/JS接口,将框架层丰富的模块功能开放给上层应用,方便开发者调用系统底层能力,实现更强大的功能扩展。
-
性能优化与核心功能封装:应用开发者可以将对性能要求较高或需要底层系统调用的核心功能,使用C/C++进行封装实现,然后通过ArkTS/JS接口在应用中调用,从而显著提高应用的执行效率。
1.Node-API的组成架构
图1 Node-API的组成架构
-
Native Module:开发者使用Node-API开发的模块,用于在ArkTS侧导入使用。
-
Node-API:实现ArkTS与C/C++交互的逻辑。
-
ModuleManager:Native模块管理,包括加载、查找等。
-
ScopeManager:管理napi_value的生命周期。
-
ReferenceManager:管理napi_ref的生命周期。
-
NativeEngine:ArkTS引擎抽象层,统一ArkTS引擎在Node-API层的接口行为。
-
ArkCompiler ArkTS Runtime:ArkTS运行时。
2.Node-API的关键交互流程
图2 Node-API的关键交互流程
ArkTS和C++之间的交互流程,主要分为以下两步:
-
初始化阶段:当ArkTS侧在import一个Native模块时,ArkTS引擎会调用ModuleManager加载模块对应的so及其依赖。首次加载时会触发模块的注册,将模块定义的方法属性挂载到exports对象上并返回该对象。
-
调用阶段:当ArkTS侧通过上述import返回的对象调用方法时,ArkTS引擎会找到并调用对应的C/C++方法。
二、使用Node-API实现跨语言交互开发流程
使用Node-API实现跨语言交互,首先需要按照Node-API的机制实现模块的注册和加载等相关动作。
-
ArkTS/JS侧:实现C++方法的调用。代码比较简单,import一个对应的so库后,即可调用C++方法。
-
Native侧:.cpp文件,实现模块的注册。需要提供注册lib库的名称,并在注册回调方法中定义接口的映射关系,即Native方法及对应的JS/ArkTS接口名称等。
此处以在ArkTS/JS侧实现add()接口、在Native侧实现Add()接口,从而实现跨语言交互为例,呈现使用Node-API进行跨语言交互的流程。
1.创建Native C++工程
-
在DevEco Studio中New > Create Project,选择Native C++模板,点击Next,选择API版本,设置好工程名称,点击Finish,创建得到新工程。
-
创建工程后工程结构可以分两部分,cpp部分和ets部分,工程结构具体介绍可见C++工程目录结构。
2.Native侧方法的实现
-
设置模块注册信息
ArkTS侧import native模块时,会加载其对应的so。加载so时,首先会调用napi_module_register方法,将模块注册到系统中,并调用模块初始化函数。
napi_module有两个关键属性:一个是.nm_register_func,定义模块初始化函数;另一个是.nm_modname,定义模块的名称,也就是ArkTS侧引入的so库的名称,模块系统会根据此名称来区分不同的so。
// entry/src/main/cpp/napi_init.cpp// 准备模块加载相关信息,将上述Init函数与本模块名等信息记录下来。
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = nullptr,
.reserved = {0},
};// 加载so时,该函数会自动被调用,将上述demoModule模块注册到系统中。
extern "C" __attribute__((constructor)) void RegisterDemoModule() {
napi_module_register(&demoModule);
}
注:以上代码无须复制,创建Native C++工程以后在napi_init.cpp代码中已配置好。
-
模块初始化
实现ArkTS接口与C++接口的绑定和映射。
// entry/src/main/cpp/napi_init.cpp
EXTERN_C_START
// 模块初始化
static napi_value Init(napi_env env, napi_value exports) {
// ArkTS接口与C++接口的绑定和映射
napi_property_descriptor desc[] = {
// 注:仅需复制以下两行代码,Init在完成创建Native C++工程以后在napi_init.cpp中已配置好。
{"callNative", nullptr, CallNative, nullptr, nullptr, nullptr, napi_default, nullptr},
{"nativeCallArkTS", nullptr, NativeCallArkTS, nullptr, nullptr, nullptr, napi_default, nullptr}
};
// 在exports对象上挂载CallNative/NativeCallArkTS两个Native方法
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
-
在index.d.ts文件中,提供JS侧的接口方法。
// entry/src/main/cpp/types/libentry/index.d.ts
export const callNative: (a: number, b: number) => number;
export const nativeCallArkTS: (cb: (a: number) => number) => number;
-
在oh-package.json5文件中将index.d.ts与cpp文件关联起来。
// entry/src/main/cpp/types/libentry/oh-package.json5
{
"name": "libentry.so",
"types": "./index.d.ts",
"version": "",
"description": "Please describe the basic information."
}
-
在CMakeLists.txt文件中配置CMake打包参数。
# entry/src/main/cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(MyApplication2)set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)# 添加名为entry的库
add_library(entry SHARED napi_init.cpp)
# 构建此可执行文件需要链接的库
target_link_libraries(entry PUBLIC libace_napi.z.so)
-
实现Native侧的CallNative以及NativeCallArkTS接口。具体代码如下:
// entry/src/main/cpp/napi_init.cpp
static napi_value CallNative(napi_env env, napi_callback_info info)
{
size_t argc = 2;
// 声明参数数组
napi_value args[2] = {nullptr};// 获取传入的参数并依次放入参数数组中
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 依次获取参数
double value0;
napi_get_value_double(env, args[0], &value0);
double value1;
napi_get_value_double(env, args[1], &value1);// 返回两数相加的结果
napi_value sum;
napi_create_double(env, value0 + value1, &sum);
return sum;
}static napi_value NativeCallArkTS(napi_env env, napi_callback_info info)
{
size_t argc = 1;
// 声明参数数组
napi_value args[1] = {nullptr};// 获取传入的参数并依次放入参数数组中
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);// 创建一个int,作为ArkTS的入参
napi_value argv = nullptr;
napi_create_int32(env, 2, &argv );// 调用传入的callback,并将其结果返回
napi_value result = nullptr;
napi_call_function(env, nullptr, args[0], 1, &argv, &result);
return result;
}
3.ArkTS侧调用C/C++方法实现
ArkTS侧通过import引入Native侧包含处理逻辑的so来使用C/C++的方法。
// entry/src/main/ets/pages/Index.ets
// 通过import的方式,引入Native能力。
import nativeModule from 'libentry.so'@Entry
@Component
struct Index {
@State message: string = 'Test Node-API callNative result: ';
@State message2: string = 'Test Node-API nativeCallArkTS result: ';
build() {
Row() {
Column() {
// 第一个按钮,调用add方法,对应到Native侧的CallNative方法,进行两数相加。
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.message += nativeModule.callNative(2, 3);
})
// 第二个按钮,调用nativeCallArkTS方法,对应到Native的NativeCallArkTS,在Native调用ArkTS function。
Text(this.message2)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.message2 += nativeModule.nativeCallArkTS((a: number)=> {
return a * 2;
});
})
}
.width('100%')
}
.height('100%')
}
}
4.Node-API的约束限制
1)SO命名规则
导入使用的模块名和注册时的模块名大小写保持一致,如模块名为entry,则so的名字为libentry.so,napi_module中nm_modname字段应为entry,ArkTS侧使用时写作:import xxx from 'libentry.so'。
2)注册建议
-
nm_register_func对应的函数(如上述Init函数)需要加上static,防止与其他so里的符号冲突。
-
模块注册的入口,即使用__attribute__((constructor))修饰的函数的函数名(如上述RegisterDemoModule函数)需要确保不与其它模块重复。
3)多线程限制
每个引擎实例对应一个JS线程,实例上的对象不能跨线程操作,否则会引起应用crash。使用时需要遵循如下原则:
-
Node-API接口只能在JS线程使用。
-
Native接口入参env与特定JS线程绑定只能在创建时的线程使用。
相关文章:
【鸿蒙HarmonyOS Next实战开发】实现ArkTS/JS和C/C++的交互-Node-API
一、HarmonyOS Node-API简介 在HarmonyOS应用开发中,通常以ArkTS/JS语言为主,但在一些特殊场景下,例如游戏开发、物理模拟等,由于对性能、效率等有较高要求,需要借助现有的C/C库来实现。为了满足这种需求,…...
QT笔记——多语言翻译
文章目录 1、概要2、多语言切换2.1、结果展示2.2、创建项目2.2、绘制UI2.2、生成“.st”文件2.4、生成“.qm”文件2.5、工程demo 1、概要 借助QT自带的翻译功能,实现实际应用用进行 “多语言切换” 2、多语言切换 2.1、结果展示 多语言切换 2.2、创建项目 1、文件…...
JPG、PNG、GIF有什么区别?
JPG、PNG、GIF是三种常见的数字图像格式,它们各自具有不同的特点和适用场景。以下是它们之间的主要区别以及如何进行选择: 一、JPG与PNG、GIF的区别 1. JPG(JPEG): 特点:JPG是一种有损压缩的图像格式&…...
Excel 融合 deepseek
效果展示 代码实现 Function QhBaiDuYunAIReq(question, _Optional Authorization "Bearer ", _Optional Qhurl "https://qianfan.baidubce.com/v2/chat/completions")Dim XMLHTTP As ObjectDim url As Stringurl Qhurl 这里替换为你实际的URLDim postD…...
机器学习在环境科学中的应用
机器学习在环境科学中的应用 第一节 机器学习的基本概念 什么是机器学习 机器学习是一种通过对大量数据的学习和分析,让计算机系统能够逐渐改善其性能和行为的技术。它通过建立数学模型来识别数据中的模式和规律,进而进行预测和决策。 机器学习在环境科学…...
【AIGC魔童】DeepSeek v3推理部署:vLLM/SGLang/LMDeploy
【AIGC魔童】DeepSeek v3推理部署:vLLM/SGLang/LMDeploy (1)使用vLLM推理部署DeepSeek(2)使用SGLang推理部署DeepSeek(3)使用LMDeploy推理部署DeepSeek (1)使用vLLM推理部…...
Monorepo保姆级教程
Monorepo是一种将多个项目或组件存储在一个统一的代码仓库中的策略,旨在提高代码复用性和团队协作效率。以下是一个详细的Monorepo管理多个项目的保姆级教程: 1. 初始化项目 首先,创建一个新的项目目录并初始化为Git仓库: mkdi…...
【蓝桥杯—单片机】第十一届省赛真题代码题解题笔记 | 省赛 | 真题 | 代码题 | 刷题 | 笔记
第十一届省赛真题代码部分 前言赛题代码思路笔记竞赛板配置内部振荡器频率设定键盘工作模式跳线扩展方式跳线 建立模板明确设计要求和初始状态显示功能部分数据界面第一部分第二部分第三部分调试时发现的问题 参数设置界面第一部分第二部分和第四部分第三部分和第五部分 按键功…...
hive的几种复杂数据类型
Hive的几种复杂数据类型 Hive 提供了几种复杂数据类型,能够支持更灵活和多样的数据存储。这些复杂数据类型对于处理嵌套数据或不规则数据特别有用。主要包括以下几种: 文章目录 Hive的几种复杂数据类型1. 数组(ARRAY)2. 结构体&a…...
使用 `WITH` 子句优化复杂 SQL 查询
使用 WITH 子句优化复杂 SQL 查询 在 SQL 中,处理复杂的查询需求时,代码往往会变得冗长且难以维护。为了解决这个问题,SQL 提供了 WITH 子句(也称为公用表表达式,Common Table Expression,CTE)…...
k8s网络插件及基础命令
一、k8s的cni网络插件 1.k8s的内部网络模式 pod内的容器与容器之间的通信。一个节点上的pod之间的通信,docker0网桥直接通信。不同节点上的pod之间的通信:通过物理网卡的ip地址和其他节点上的物理网卡的设备进行通信,然后把流量转发到指定的…...
组合总和II(力扣40)
这道题的难点就在于题目所给的集合中有重复的数字,我们需要进行去重操作。首先明确去重指的是去重哪一部分。注意并不是对递归的集合去重,而是对当前集合的遍历进行去重。这么说可能有点抽象,举个例子:假设集合为1,1,2,3,4&#x…...
【vue3 入门到实战】7. 标签中的 ref
目录 1. ref 的作用 2. 如何使用 1. ref 的作用 用于注册模板引用 用在普通DOM标签上,获取的是DOM节点。 用在组件标签上,获取的是组件的实例对象。 2. 如何使用 代码如下 <template><div class"app"><h2 ref"titl…...
MAC OS安装Homebrew
文章目录 1.下载Homebrew2.完成安装3.验证安装4.更新 Homebrew作为一个包管理器,提供了一种简便的方式来安装、更新和卸载各种命令行工具和应用程序。相比于手动下载和编译源代码,或者从不同的网站下载安装包,使用Homebrew可以显著减少这些操…...
数据结构之栈和队列(超详解)
文章目录 概念与结构栈队列 代码实现栈栈是否为空,取栈顶数据、栈的有效个数 队列入队列出队列队列判空,取队头、队尾数据,队列的有效个数 算法题解有效的括号用队列实现栈用栈实现队列复用 设计循环队列数组结构实现循环队列构造、销毁循环队…...
[Deepseek-自定义Ollama 安装路径+lmStudio 简易安装]
ollama 先下载 https://ollama.org.cn/download 使用 发现报错 检查路径 自己的路径! 再用 .\OllamaSetup.exe /DIRE:\MySoftware\Ollama 删除掉 多余模型 ollama delete <model_name> 例如 ollama delete deepseek-r1:1.5b 下载 ollama run deepseek-r1:1.5b…...
uniapp mqttjs 小程序开发
在UniApp中集成MQTT.js开发微信小程序时,需注意平台差异、协议兼容性及消息处理等问题。以下是关键步骤与注意事项的综合指南: 一、环境配置与依赖安装 安装MQTT.js 推荐使用兼容性较好的版本:mqtt4.1.0(H5和小程序兼容性最佳&…...
LabVIEW位移测量系统
本文介绍了一种基于LabVIEW的位移测量系统,结合先进的硬件设备与LabVIEW平台的强大功能,能够实现对位移的精确测量和高效数据处理。该系统具备高精度、实时性和良好的可扩展性,适用于工程与科学实验中对位移测量的多种需求。 项目背景 位移…...
VMware下Linux和macOS遇到的一些问题总结
1.解决.NET程序通过网盘传到Linux和macOS不能运行的问题 这是文件权限的问题。当你通过U盘将文件传输到虚拟机的macOS和Linux系统时,文件的权限和所有权可能得到了保留或正确设置。但如果你通过网盘上传,文件的权限或所有权可能没有正确设置,…...
Mac: docker安装以后报错Command not found: docker
文章目录 前言解决办法(新的)解决步骤(原来的)不推荐总结 前言 本操作参考 http://blog.csdn.net/enhenglhm/article/details/137955756 原作者,更详细请,查看详细内容请关注原作者。 一般,…...
深度学习里面的而优化函数 Adam,SGD,动量法,AdaGrad 等 | PyTorch 深度学习实战
前一篇文章,使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课:引领人工智能新时代【梗直哥瞿炜】 深度学习里面的而优化函数 …...
C++自研3D教程OPENGL版本---动态批处理的基本实现
又开始找工作了,借机休息出去旅行两个月,顺便利用这段时间整理下以前写的东西。 以下是一个简单的动态批处理实现: #include <GL/glew.h> #include <GLFW/glfw3.h> #include <iostream> #include <vector>// 顶点结…...
如何使用deepseek开发一个翻译API
什么是deepseek Deepseek 是一个基于人工智能技术的自然语言处理平台,提供了多种语言处理能力,包括文本翻译、语义分析、情感分析等。它通过深度学习模型和大规模语料库训练,能够实现高质量的文本翻译和多语言理解。Deepseek 的核心优势在于…...
Java使用aspose实现pdf转word
Java使用aspose实现pdf转word 一、下载aspose-pdf-21.6.jar包【下载地址】,存放目录结构如图;配置pom.xml。 <!--pdf to word--> <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId>…...
fs 文件系统模块
在 Node.js 中,fs(File System)模块提供了与文件系统进行交互的能力。无论是读取、写入还是操作文件和目录,fs 模块都提供了丰富的 API 支持。本文将详细介绍 fs 模块的基本用法、异步与同步方法的区别以及一些高级功能࿰…...
正激变换器拓扑
正激变换器拓扑是一种常见的DC-DC电源拓扑结构,以下是关于它的详细介绍: 基本组成 - 主开关:通常为MOSFET,用于控制输入电压的通断。 - 变压器:实现电压隔离和电压变换,传递能量。 - 续流二极管&#x…...
Rsyslog omhttp(HTTP输出模块)
个人博客地址:Rsyslog omhttp(HTTP输出模块) | 一张假钞的真实世界 使用Rsyslog的omhttp模块可以将收集的日志数据以HTTP请求的方式输出。该模块支持单条/批量发送数据,支持GZIP压缩,支持HTTPS。 Rsyslog默认未包含o…...
防火墙与Squid代理服务器
服务器的安装、搭建与配置准备前期 虚拟机版本:redhat Enterprise Linux Server release 7.2(Maipo)系统架构:x86虚拟机服务器地址:192.168.195.3Window地址:192.168.195.237进行ISO挂载操作进入root模式[yonghu@localhost 桌面]#su 返回上级目录文件进入media文件中,创建…...
为何实现大语言模型的高效推理以及充分释放 AI 芯片的计算能力对于企业级落地应用来说,被认为具备显著的研究价值与重要意义?
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ AI 芯片:为人工智能而生的 “大脑” AI 芯片,又称人工智能加速器或计算卡,是专为加速人工智能应用,特别是深度学习任务设计的专用集成电路(A…...
【教程】docker升级镜像
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 目录 自动升级 手动升级 无论哪种方式,最重要的是一定要通过-v参数做数据的持久化! 自动升级 使用watchtower,可…...
k8s常见面试题2
k8s常见面试题2 安全与权限RBAC配置如何保护 Kubernetes 集群的 API Server?如何管理集群中的敏感信息(如密码、密钥)?如何限制容器的权限(如使用 SecurityContext)?如何防止容器逃逸࿰…...
mysql运维
1、msyqlLinux通用二进制安装 1. MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/https://downloads.mysql.com/archives/community/https://downloads.mysql.com/archives/community/https://downloads.mysql…...
将Deepseek接入pycharm 进行AI编程
目录 专栏导读1、进入Deepseek开放平台创建 API key 2、调用 API代码 3、成功4、补充说明多轮对话 总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️🌈 博客主页:请点击——…...
Redis03 - 高可用
Redis高可用 文章目录 Redis高可用一:主从复制 & 读写分离1:主从复制的作用2:主从复制原理2.1:全量复制2.2:增量复制(环形缓冲区) 3:主从复制实际演示3.1:基本流程准…...
日常知识点之面试后反思遗留问题汇总
梳理一下最近接触到的几个知识点: 1:突然问到端口复用 (SO_REUSEADDR) 端口复用一般用在服务端重启时,套接字处于time_wait状态时,无法绑定该端口,导致无法启动问题。 设置端口复用ÿ…...
软考教材重点内容 信息安全工程师 第15章 网络安全主动防御技术与应用
目录 15.1.1 人侵阻断技术原理 15.1.2 人侵阻断技术应用 15.3 网络流量清洗技术与应用 15.3.1 网络流量清洗技术原理 15.3.2 网络流量清洗技术应用 15.4 可信计算技术与应用 15.4.1 可信计算技术原理 15.5 数字水印技术与应用 15.5.1 数字水印技术原理 15.5.2 数字水…...
大模型的底层逻辑及Transformer架构
一、大模型的底层逻辑 1.数据驱动 大模型依赖海量的数据进行训练,数据的质量和数量直接影响模型的性能。通过大量的数据,模型能够学习到丰富的模式和规律,从而更好地处理各种任务。 2.深度学习架构 大模型基于深度学习技术,通常采用多层神经网络进行特征学习与抽象。其中…...
PostgreSQL-字符串函数
字符串连接 SELECT A||B; 字符串连接,适用于字符串与数字连接 SELECT CONCAT(10,a,hello,20.0); 连接所有参数,个数不限,类型不限 字母转换 SELECT LOWER(ABCD); 将字符转换成小写 SELECT UPPER(ABCD); 将字符转换成大写 SELECT IN…...
Qt修仙之路2-1 炼丹初成
widget.cpp #include "widget.h" #include<QDebug> //实现槽函数 void Widget::login1() {QString userusername_input->text();QString passpassword_input->text();//如果不勾选无法登入if(!check->isChecked()){qDebug()<<"xxx"&…...
华为的IPD模式VS敏捷项目管理模式
本文介绍了华为的IPD模式与敏捷项目管理模式的对比。文章详细阐述了两种模式的特点、适用范围及实施要点,为读者提供了全面的理解。 重点内容: 1. IPD模式强调跨部门协同,注重产品全生命周期管理,适用于复杂产品领域。 2. 敏捷…...
Ollama python交互:chat+embedding实践
Ollama简介 Ollama 是一个开源的大型语言模型(LLM)平台,旨在让用户能够轻松地在本地运行、管理和与大型语言模型进行交互。 Ollama 提供了一个简单的方式来加载和使用各种预训练的语言模型,支持文本生成、翻译、代码编写、问答等…...
Redis进阶
Redis持久化: 前面我们讲到mysql事务有四个比较核心的特性: 原子性:保证多个操作打包成一个。一致性:A给B100,A少一百,B必须多一百。持久性:针对事务操作必须要持久生效,不管是重启…...
【蓝桥杯嵌入式】6_定时器输入捕获
全部代码网盘自取 链接:https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码:3ii2 这是两个信号发生器,可以通过调节板上的两个电位器R39和R40调节输出频率。 将PB4、PA15选择ch1,两个信号发生器只能选择TIM3和TIM…...
C#常用集合优缺点对比
先上结论: 在C#中,链表、一维数组、字典、List<T>和ArrayList是常见的数据集合类型,它们各有优缺点,适用于不同的场景。以下是它们的比较: 1. 一维数组 (T[]) 优点: 性能高:数组在内存中…...
Python调取本地MongoDB招投标数据库,并结合Ollama部署的DeepSeek-R1-8B模型来制作招投标垂直领域模型
根据你的需求,以下是使用Python调取本地MongoDB招投标数据库,并结合Ollama部署的DeepSeek-R1-8B模型来制作招投标垂直领域模型的步骤: 安装PyMongo 首先,确保你已经安装了PyMongo库,用于Python与MongoDB的交互。如果未…...
【MySQL】深入了解索引背后的内部结构
目录 索引的认识: 作用: 索引的使用: 索引底层的数据结构: 哈希表 AVL树 红黑树 B树: B树: B树搜索: 索引的认识: 索引是数据库中的一个数据结构,用于加速查询…...
pytest-xdist 进行多进程并发测试
在自动化测试中,运行时间过长往往是令人头疼的问题。你是否遇到过执行 Pytest 测试用例时,整个测试流程缓慢得让人抓狂?别担心,pytest-xdist 正是解决这一问题的利器!它支持多进程并发执行,能够显著加快测试…...
蓝桥杯准备 【入门3】循环结构
素数小算法(埃氏筛&&欧拉筛) 以下四段代码都是求20以内的所有素数 1.0版求素数 #include<iostream> using namespace std;int main() {int n 20;for(int i2;i<n;i){int j0;for(j2;j<i;j)//遍历i{if(i%j0){break;}}if(ij){cout&l…...
PHP填表统计预约打卡表单系统小程序
📋 填表统计预约打卡表单系统——专属定制,信息互动新纪元 📊 填表统计预约打卡表单系统,一款专为现代快节奏生活量身打造的多元化自定义表单统计小程序,集信息填表、预约报名、签到打卡、活动通知、报名投票、班级统…...
自定义数据集,使用scikit-learn 中K均值包 进行聚类
1. 引言 K均值聚类是一种无监督学习方法,用于将数据集分为多个簇。通过计算数据点之间的距离并将它们分配到最近的簇中心,K均值算法可以帮助我们发现数据中的自然结构。 2. 数据集创建 首先,我们使用numpy创建一个自定义的二维数据集&…...