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

【HarmonyOS Next】三天撸一个BLE调试精灵

【HarmonyOS Next】三天撸一个BLE调试精灵

一、功能介绍

BLE调试精灵APP属于工具类APP,在用户使用的过程中,负责调试BLE设备从机端,比如蓝牙耳机、低功耗设备、带有BLE的空调等设备,可以在页面中清晰看到设备的厂商,拥有扫描设备、连接设备、发送测试数据等主要的功能。当通过BLE调试精灵APP调试时,可以方便快捷的查看设备的属性。

本APP包含以下功能:

  • 扫描BLE从机设备
  • 区分从机设备的厂商
  • 广播包解析展示
  • 连接设备
  • 展示服务和特征值
  • 特征值的读、写、通知
  • 根据MTU分包大数据发送

在这里插入图片描述

二、基本知识

在实现BLE调试APP之前,需要对BLE有基本的了解。

  • BLE是低功耗蓝牙,用于可穿戴设备,IoT智能设备等众多物联网设备,功耗低、带宽也低。不同于经典蓝牙,经典蓝牙功耗高、带宽高。
  • BLE分为主机和从机,主动连接其它设备的是主机,比如手机是主机,可穿戴设备等是从机
  • 在有些平台下需要先扫描才能进行连接。
  • 在纯血鸿蒙平台下,从机的MAC地址无法获取,而是被包装成了deviceId,类似于某水果平台。
  • 广播中厂商信息、UUID有一定的规范,厂商可对应具体的厂家,由蓝牙技术联盟分配,UUID有比如获取电量等服务。
  • 连接的过程中通常会自定义超时时间、重连次数。
  • 下发数据时通常会根据MTU进行数据包的分割。
  • 基本的字节操作。

三、技术解析

1. 侧边栏容器

SideBarContainer 组件是鸿蒙的内置组件,配合状态管理,可以很轻松的实现侧边栏展示与隐藏的效果。
用内置属性controlButton展示不同的按钮,用@State tabShow控制侧边栏展示与隐藏的状态,用背景颜色达到蒙版的效果。

 SideBarContainer(SideBarContainerType.Overlay) {Column() {DrawerTab();}.height('100%')Column() {MainPage({ tabShow: this.tabShow })}.onClick(() => {animateTo({duration: 500,curve: Curve.EaseOut,playMode: PlayMode.Normal,}, () => {this.tabShow = false;})}).width('100%').height('100%').backgroundColor(this.tabShow ? '#c1c2c4' : '')}.showSideBar(this.tabShow).controlButton({left: 6,top: 6,height: 40,width: 40,icons: {shown: $r("app.media.tab_change_back"),hidden: $r("app.media.tab_change"),switching: $r("app.media.tab_change")}}).onChange((value: boolean) => {this.tabShow = value;})
2. BLE扫描

startBLEScan 方法进行扫描,使用ScanFilter进行扫描过滤,使用ScanOptions可传入扫描的配置,比如用最快速的响应扫描所有的设备。
BLEDeviceFind 监听该事件接收扫描的结果回调。

      ble.on("BLEDeviceFind", this.onReceiveEvent);let scanFilter: ble.ScanFilter = {//name: scanName,};let scanOptions: ble.ScanOptions = {interval: 0,dutyMode: ble.ScanDuty.SCAN_MODE_LOW_LATENCY,matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE}ble.startBLEScan([scanFilter], scanOptions);

当扫描到一定时间时,停止扫描。

       // 取消上一次定时器if (this.mScanTimerId != 0) {clearTimeout(this.mScanTimerId)}this.mScanTimerId = setTimeout(() => {BleLogger.debug(TAG, "setTimeout")this.stopBLEScan();if (this.mCallback) {this.mCallback.scanFinish();}}, scanTime);

扫描到结果ble.ScanResult对象,包含deviceId、广播包等数据,deviceId相当于本次扫描过程中的设备的唯一标识,可在后续的流程中用于连接;广播包一般是31个字节,在BLE5.0及以上可超出31个字节,使用拓展广播包,广播包由LTV格式构成,可以在LTV格式中解析出厂商代码,厂商代码可对应成具体厂家。

解析LTV格式:

/*** LTV格式数据*/
export class LtvInfo {length: number;tag: number;value: Uint8Array;constructor(length: number, tag: number, value: Uint8Array) {this.length = length;this.tag = tag;this.value = value;}
}export class BleBeaconUtil2 {/*** 解析 BLE 广播数据* @param advData 广播数据字节数组* @returns 解析结果的 Map,键是数据类型,值是对应的数据内容*/public static parseData(advData: Uint8Array): Array<LtvInfo> {let result: Array<LtvInfo> = []; // 存放解析后的结果let index = 0; // 用于遍历数据while (index < advData.length) {let length = advData[index]; // 获取当前数据单元的长度index++;if (length === 0) {break; // 长度为 0 时结束解析}const type = advData[index]; // 获取数据类型index++;const data = advData.slice(index, index + length - 1); // 获取实际数据index += length - 1; // 更新索引// 根据不同类型解析数据let ltvInfo: LtvInfo = BleBeaconUtil2.parseDataType(length, type, data);result.push(ltvInfo);}return result; // 返回解析后的数据}/*** 根据广播数据的类型解析具体的数据* @param type 数据类型* @param data 对应类型的数据* @param result 存放解析结果的对象*/private static parseDataType(length: number, type: number, data: Uint8Array): LtvInfo {return new LtvInfo(length, type, data);}
}

获取厂商代码,厂商代码和厂家对应信息应构成Map<number, string>数据结构,具体厂商代码在该网址下进行获取
https://bitbucket.org/bluetooth-SIG/public/raw/HEAD/assigned_numbers/company_identifiers/company_identifiers.yaml

 /*** 获取厂商代码* @returns*/public getManufacturerData(ltvArray: Array<LtvInfo>): number {let manufacturerData = new Uint8Array(2);if (ltvArray.length == 0) {return 0;}for (const ltvInfo of ltvArray) {if (ltvInfo.tag === 0xff) {if (ltvInfo.value && ltvInfo.value.length > 2) {manufacturerData[0] = ltvInfo.value[1];manufacturerData[1] = ltvInfo.value[0];return ByteUtils.byteToShortBig(manufacturerData);}}}return 0;}
3. BLE连接

GattClientDevice.connect 传入deviceId用于连接,可自定义超时逻辑。

  /*** 开始链接* @param deviceId*/private connect(deviceId: string) {this.notifyConnectStart(deviceId);this.mDevice = ble.createGattClientDevice(deviceId);this.mDevice.on('BLEConnectionStateChange', this.ConnectStateChanged.bind(this));try {this.mDevice.connect();} catch (e) {// todo 比如,蓝牙突然关闭时的错误this.notifyConnectError(BleException.ERROR_CODE_CONNECT_10001, this.mDeviceId);return;}this.cancelTimeoutRunnable();this.startTimeoutRunnable(this.mConnectTimeout);}

在核心回调中处理连接成功或失败的状态,抛给业务层。值得注意的是,并不是连接成功之后就算业务上的连接成功,还需要发现服务,如需进行数据交互,还需要启用通知->设置MTU操作,都完成之后,才是业务层面的连接成功。

4. 获取服务和特征值

BLE丛机包含多个服务,每个服务都有一个UUID,主服务下可包含多个子服务,子服务下可以包含多个特征值。

连接成功之后得到services: Array<ble.GattService>,从中循环取出服务和特征值并展示。

 List() {ForEach(this.deviceInfo.services, (item: ble.GattService) => {ListItem() {/* item view */ServiceItemView({ item: item, deviceId: this.deviceInfo.deviceId })}})}List() {ForEach(this.item.characteristics, (itemChild: ble.BLECharacteristic) => {ListItem() {Column() {Text(this.getName(itemChild.characteristicUuid)).fontSize($r('app.float.font_normal')).fontWeight(FontWeight.Bold)BlockView({ block: 2 })Text('UUID:' + itemChild.characteristicUuid).fontSize(12)BlockView({ block: 2 })Text('可操作属性')ServiceItemButtonView({ itemChild: itemChild, deviceId: this.deviceId })// 子服务-描述符if (itemChild.descriptors) {ForEach(itemChild.descriptors, (itemChildDes: ble.BLEDescriptor) => {ListItem() {Column() {Text('Descriptors').fontSize($r('app.float.font_normal')).fontWeight(FontWeight.Bold)BlockView({ block: 2 })Text('UUID:' + itemChildDes.descriptorUuid).fontSize(12)}.alignItems(HorizontalAlign.Start)}})}}.alignItems(HorizontalAlign.Start).width('100%').padding({left: 30,right: 10,top: 10,bottom: 10})}})}.divider({strokeWidth: 1,color: '#cccccc'}).backgroundColor('#eeeeee')
5. 特征值

特征值一共有五个。

  • Read:可读取数据(如设备名称、电量)
  • Write:可写入数据(如配置参数)
  • Notify:丛机主动通知主机(无需确认)
  • Indicate:丛机通知主机(需确认,比Notify多了一个确认)
  • Write Without Response:写入无需回复(低延迟,如控制指令)

用最常见的数据通信举例,主机给丛机发送一个文件数据,丛机给主机回复收到。

this.mDeviceble.GattClientDevice对象,在连接时根据createGattClientDevice获取。

首先请求设置MTU,拿到MTU之后,再对数据进行分包

private mtuChangeCallback = (mtu: number) => {BleLogger.debug(TAG, 'set mtu change:' + mtu)if (!this.mDeviceId) {this.notifyError(BleException.ERROR_CODE_CONNECT_10009, this.mDeviceId);return;}let bluetoothGatt = BleConnectionList.getInstance().get(this.mDeviceId);if (!bluetoothGatt) {this.notifyError(BleException.ERROR_CODE_CONNECT_10009, this.mDeviceId);return;}bluetoothGatt.off('BLEMtuChange', this.mtuChangeCallback);BLESdkConfig.getInstance().setBleMaxMtu(mtu);this.notifySuccess(mtu, this.mDeviceId);}

将分隔的组成一个队列,队列中每个数据的长度是MTU

let queuePacket: Queue<Uint8Array> =BleDataUtils.splitByte(requestPacket, BLESdkConfig.getInstance().getBleMaxMtu());

将数据依次取出,然后发送数据

let data: Uint8Array = this.mDataQueue.pop();
let bluetoothGatt = BleConnectionList.getInstance().get(this.mDeviceId!);
// 携带数据
this.mBleCharacteristic.characteristicValue = this.typedArrayToBuffer(data);
bluetoothGatt.writeCharacteristicValue(this.mBleCharacteristic, this.mWriteType,
this.writeCharacteristicValueCallBack.bind(this))

至此功能讲解完毕,有问题欢迎沟通。

相关文章:

【HarmonyOS Next】三天撸一个BLE调试精灵

【HarmonyOS Next】三天撸一个BLE调试精灵 一、功能介绍 BLE调试精灵APP属于工具类APP&#xff0c;在用户使用的过程中&#xff0c;负责调试BLE设备从机端&#xff0c;比如蓝牙耳机、低功耗设备、带有BLE的空调等设备&#xff0c;可以在页面中清晰看到设备的厂商&#xff0c;…...

STM32实现智能温控系统(暖手宝):PID 算法 + DS18B20+OLED 显示,[学习 PID 优质项目]

一、项目概述 本文基于 STM32F103C8T6 单片机&#xff0c;设计了一个高精度温度控制系统。通过 DS18B20 采集温度&#xff0c;采用位置型 PID 算法控制 PWM 输出驱动 MOS 管加热Pi膜&#xff0c;配合 OLED 实时显示温度数据。系统可稳定将 PI 膜加热至 40℃&#xff0c;适用于…...

【docker】docker-compose安装RabbitMQ

docker-compose安装RabbitMQ 1、配置docker-compose.yml文件&#xff08;docker容器里面的目录请勿修改&#xff09;2、启动mq3、访问mq4、查看服务器映射目录5、踩坑5.1、权限不足 1、配置docker-compose.yml文件&#xff08;docker容器里面的目录请勿修改&#xff09; versi…...

如何突破MacBook苹果电脑Cursor限制:免费版的解决方法

Macbook苹果电脑无限白嫖Cursor|解决免费版限制问题|达到50次150次续杯|arm|intel 如何突破MacBook苹果电脑Cursor限制&#xff1a;免费版的解决方法 前言 本文介绍了如何在MacBook上突破Cursor免费版的使用限制。请遵循以下步骤进行操作。 操作步骤 进入程序目录&#xff1a;…...

网络原理之传输层

前文我们了解 应用层 传输层 网络层 数据链路层 物理层 这五层结构,此文我先讨论传输层相关的知识 1. 传输层 负责数据能够从发送端传输到接收端. 1.1 端口号 端⼝号(Port)标识了⼀个主机上进行通信的不同的应用程序 端口号范围划分: 0-1023:知名端口号,HTTP,FTP,SSH等这些…...

一个免费 好用的pdf在线处理工具

pdf24 doc2x 相比上面能更好的支持数学公式。但是收费...

新书速览|云原生Kubernetes自动化运维实践

《云原生Kubernetes自动化运维实践》 本书内容&#xff1a; 《云原生Kubernetes自动化运维实践》以一名大型企业集群运维工程师的实战经验为基础&#xff0c;全面系统地阐述Kubernetes&#xff08;K8s&#xff09;在自动化运维领域的技术应用。《云原生Kubernetes自动化运维实践…...

解决安卓so库异常无法打印堆栈的问题

解决方案&#xff1a; 设置 android:extractNativeLibs"true" 直接在 AndroidManifest.xml 里加上&#xff1a; <applicationandroid:extractNativeLibs"true"> </application>这样&#xff0c;so 文件会被解压&#xff0c;崩溃时可以正常打…...

996引擎-接口测试:背包

996引擎-接口测试:背包 背包测试NPC参考资料背包测试NPC CONSTANT = require("Envir/QuestDiary/constant/CONSTANT.lua"); MsgUtil = require("Envir/QuestDiary/utils/996/MsgUtil.lua");...

红数码影视(RED Digital Cinema)存储卡格式化后的恢复方法

红数码影视(RED Digital Cinema)的摄像机可以生成两种RAW级高清视频文件&#xff0c;一种是R3D&#xff0c;一种是MOV。其中MOV属于苹果(apple)公司的QT视频封装结构&#xff0c;使用的视频编码是Apple ProRes;而R3D则是RED公司自创的RAW视频文件&#xff0c;这种文件解码需要使…...

若依前端框架增删改查

1.下拉列表根据数据库加载 这个是用来查询框 绑定了 change 事件来处理站点选择变化后的查询逻辑。 <el-form-item label"站点选择" prop"stationId" v-has-permi"[ch:m:y]"><el-select v-model"queryParams.stationId" pl…...

YARN Cluster模式和Client模式的区别是什么

在 Apache Spark 的 YARN 部署中&#xff0c;Cluster 模式和Client 模式的核心区别在于 Driver 的启动位置和客户端&#xff08;提交任务的机器&#xff09;的角色。以下是两者的详细对比&#xff1a; 1. 核心区别概览 特性YARN Cluster 模式YARN Client 模式Driver 位置在 YA…...

哪吒汽车:一边熬夜蹦迪,一边找药投医

两年前&#xff0c;威马CEO沈晖发了个短视频&#xff0c;内容是“活下去&#xff0c;像牲口一样活下去”。 如今最能体会沈晖当时心情的&#xff0c;估计就是方运舟了。 作为哪吒汽车创始人兼董事长&#xff0c;他连续多次被限高&#xff0c;为了让哪吒汽车活下去&#xff0c…...

Java 集合 List、Set、Map 区别与应用

一、核心特性对比 二、底层实现与典型差异 ‌List‌ ‌ArrayList‌&#xff1a;动态数组结构&#xff0c;随机访问快&#xff08;O(1)&#xff09;&#xff0c;中间插入/删除效率低&#xff08;O(n)&#xff09;‌‌LinkedList‌&#xff1a;双向链表结构&#xff0c;头尾操作…...

天地图InfoWindow插入React自定义组件

截至2025年03月21日天地图的Marker不支持添加Label; 同时Label和Icon是不支持自定义HTMLElement只支持String&#xff1b;目前只有InfoWindow支持自定义HTMLElement; 效果图 React核心api import ReactDOM from react-dom/client const content document.createElement(div);…...

深度学习PyTorch之动态计算图可视化 - 使用 torchviz 生成计算图

序号系列文章1深度学习训练中GPU内存管理2深度学习PyTorch之数据加载DataLoader3深度学习 PyTorch 中 18 种数据增强策略与实现4深度学习pytorch之简单方法自定义9类卷积即插即用5深度学习PyTorch之13种模型精度评估公式及调用方法6深度学习pytorch之4种归一化方法&#xff08;…...

拓展知识三:编码学及密码学

编码和密码的区别 研究密码变化的客观规律&#xff0c;应用于编制密码以保守通信秘密的&#xff0c;称为编码学&#xff1b;应用于破译密码以获取通信情报的&#xff0c;称为破译学&#xff0c;总称密码学。 编码和密码是两个不同的概念&#xff0c;它们的区别如下&#xff1a;…...

【商城实战(54)】解锁商城国际化密码:内容管理全攻略

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…...

JS 应用WebPack 打包器第三方库 JQuery安装使用安全检测

# 打包器 -WebPack- 使用 & 安全 参考&#xff1a; https://mp.weixin.qq.com/s/J3bpy-SsCnQ1lBov1L98WA Webpack 是一个模块打包器。在 Webpack 中会将前端的所有资源文件都作为模块处理。 它将根据模块的依赖关系进行分析&#xff0c;生成对应的资源。 五个核心概…...

【嵌入式硬件】三款DCDC调试笔记

关于开关电源芯片&#xff0c;重点关注输入电源范围、输出电流、最低压降。 1.MP9943: 以MP9943为例&#xff0c;输入电压范围4-36V&#xff0c;输出最大电流3A&#xff0c;最低压降为0.3V 调整FB使正常输出为5.06V 给定6V空载、5V空载、5V带2A负载的情况&#xff1a; 6V带2A…...

深入理解 HTML5 Web Workers:提升网页性能的关键技术解析

深入理解 HTML5 Web Workers&#xff1a;提升网页性能的关键技术解析 引言1. 什么是 Web Workers&#xff1f;Web Workers 的特点&#xff1a; 2. Web Workers 的使用方式2.1 创建一个 Web Worker步骤 1&#xff1a;创建 Worker 文件步骤 2&#xff1a;在主线程中调用 Worker 3…...

计算机网络的分类——按照按拓扑结构分类

计算机的拓扑结构是引用拓扑学中研究和大小、形状无关的点、线关系的方法&#xff0c;将网络中的计算机和通信设备抽象为一个点&#xff0c;把传输介质抽象成一条线&#xff0c;由点和线组成的几何图形就是计算机网络的拓扑结构。计算机网络的拓扑结构主要由通信子网决定&#…...

AI大白话(四):自然语言处理——AI是如何理解和生成人类语言的?

🌟引言: 专栏:《AI大白话》 AI大白话(一):5分钟了解AI到底是什么? AI大白话(二):机器学习——AI是怎么“学习“的? AI大白话(三):深度学习——AI的‘大脑‘是如何构建的? 大家好!欢迎回到"AI大白话"系列。前面我们聊了AI的基本概念、机器学习的原理…...

Android第六次面试总结(Java设计模式篇一)

单例模式属于创建型设计模式&#xff0c;它保证一个类仅有一个实例&#xff0c;并且提供一个全局访问点来获取该实例。下面为你详细阐述单例模式的好处和坏处。 好处 资源优化&#xff1a;单例模式能保证一个类只有一个实例&#xff0c;这对于那些创建和销毁开销大的对象&…...

如何在 React 项目中进行服务器端渲染(SSR),它有什么优势

大白话如何在 React 项目中进行服务器端渲染&#xff08;SSR&#xff09;&#xff0c;它有什么优势 什么是服务器端渲染&#xff08;SSR&#xff09; 在传统的 React 项目里&#xff0c;页面的渲染工作是在浏览器里完成的。也就是当你访问一个网页时&#xff0c;浏览器会先下…...

JVM 01

今天是2025/03/20 16:36 day 09 总路线请移步主页Java大纲相关文章 今天进行JVM前二个模块的归纳 首先是JVM的相关内容概括的思维导图 以下是针对思维导图中 内存管理 和 垃圾回收&#xff08;GC&#xff09; 模块的详细说明&#xff1a; 1. 内存管理&#xff08;运行时数据…...

MATLAB 调用arduino uno

为了授课&#xff0c;必须重新把arduino用上。 采用MATLAB编码&#xff0c;可以简化相关程序授课部分 1 安装包 MATLAB Support Package for Arduino Hardware - File Exchange - MATLAB Central (mathworks.com) 需要这个插件。 当然也可下载simulink的模块&#xff0c;但…...

WPS宏开发手册——JSA语法

目录 系列文章2、JSA语法2.1、打印输出2.2、注释2.3、变量2.4、数据类型2.5、函数2.6、运算符2.7、比较2.8、if else条件语句2.9、for循环2.10、Math对象&#xff08;数字常用方法&#xff09;2.11、字符串常用方法2.12、数组常用方法 系列文章 使用、工程、模块介绍 JSA语…...

linux如何释放内存缓存

[rootredis ~]# sync #将内存缓存数据强制写入磁盘&#xff08;保存数据后再做释放&#xff09; [rootredis ~]# echo 1 > /proc/sys/vm/drop_caches #释放内存缓存...

2025年渗透测试面试题总结-某360-企业蓝军面试复盘 (题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 360-企业蓝军 一、Shiro绕WAF实战方案 二、WebLogic遭遇WAF拦截后的渗透路径 三、JBoss/WebLogic反序…...

Atlas 800I A2 双机直连部署DeepSeek-R1-w8a8

一、环境信息 1.1、硬件信息 Atlas 800I A2 * 2 1.2、环境信息 操作系统&#xff1a;openEuler 22.03 LTS NPU驱动&#xff1a;Ascend-hdk-910b-npu-driver 24.1.0 linux-aarch64.run NPU固件&#xff1a;Ascend-hdk-910b-npu-firware 7.5.0.3.220.run MindIE镜像&#xff…...

OpenHarmony 入门——ArkUI 跨页面数据同步和页面级UI状态存储LocalStorage小结(二)

文章大纲 引言一、在代码逻辑使用LocalStorage二、从UI内部使用LocalStorage三、LocalStorageProp和LocalStorage单向同步四、LocalStorageLink和LocalStorage双向同步五、兄弟组件之间同步状态变量七、将LocalStorage实例从UIAbility共享到一个或多个视图 引言 前面一篇文章主…...

自我革命!优利德全面进入智能示波器时代

AI重构电子测试新范式 春节期间&#xff0c;DeepSeek&#xff08;深度求索&#xff09;火遍全网。作为国内首个全面对标GPT-4技术架构的AI大模型&#xff0c;DeepSeek凭借其自主研发的通用大语言模型体系&#xff0c;涵盖了从7B到超千亿参数的完整模型矩阵&#xff0c;在数学推…...

Vue3 实战:基于 mxGraph 与 WebSocket 的动态流程图构建

本文将详细介绍如何在 Vue3 项目中集成 mxGraph 可视化库&#xff0c;并通过 WebSocket 实现画布元素的实时更新。适合有 Vue 基础的前端开发者学习参考。 一、技术栈准备 Vue3&#xff1a;采用 Composition API 开发mxGraph&#xff1a;JavaScript 流程图库&#xff08;版本 …...

Python-金融相关代码讲解

文章目录 概要整体架构流程1.代码部分2.逐个讲解1&#xff09;# -*- coding: utf-8 -*-2&#xff09;基本库引入3&#xff09;函数模块4&#xff09;主程序 小结1. 问题拆解思维2. 文件处理三件套3. 字典的妙用&#xff1a;4. 上下文管理器&#xff08;with open...&#xff09…...

深度解读DeepSeek:开源周(Open Source Week)技术解读

深度解读DeepSeek&#xff1a;开源周&#xff08;Open Source Week&#xff09;技术解读 深度解读DeepSeek&#xff1a;源码解读 DeepSeek-V3 深度解读DeepSeek&#xff1a;技术原理 深度解读DeepSeek&#xff1a;发展历程 文章目录 一、开源内容概览Day1&#xff1a;FlashMLAD…...

【算法】十大排序算法(含时间复杂度、核心思想)

以下是 **十大经典排序算法** 的时间复杂度、空间复杂度及稳定性总结&#xff0c;适用于面试快速回顾&#xff1a;排序算法对比表 排序算法最佳时间复杂度平均时间复杂度最差时间复杂度空间复杂度稳定性核心思想冒泡排序O(n)O(n)O(n)O(1)稳定相邻元素交换&#xff0c;大数沉底…...

TCP传输---计算机网络

TCP结构 源端口和目标端口&#xff1a;标识通信的应用程序。序列号&#xff1a;标记发送的数据段的顺序序号。确认号 ( ACK)&#xff1a;确认接收到的数据序号。标志位&#xff1a;控制连接状态&#xff0c;包括 SYN&#xff08;同步&#xff09;、ACK&#xff08;确认&#xf…...

创建vue2项目

1、前往 Node.js 官网下载并安装 Node.js&#xff0c;安装完成后&#xff0c;npm 会随之安装。确认 Node.js 和 npm 是否成功安装&#xff0c;可以在命令行中运行以下命令检查版本&#xff1a; node -v npm -v 运行结果&#xff1a;&#xff08;如下&#xff0c;表示node和n…...

从投机到可持续发展:ETHDenver 2025 的关键启示!

ETHDenver 2025 重点讨论了 Web3 向可持续发展转型&#xff0c;特别强调了人才培养、去中心化治理和激励机制的紧密结合。Polkadot 一直以来的长期观点也进一步支持了行业从投机转向长期、社区驱动增长的趋势。随着 ETHDenver 2025 会议的的落幕&#xff0c;Polkadot 生态中的贡…...

WPS宏开发手册——使用、工程、模块介绍

目录 系列文章前言1、开始1.1、宏编辑器使用步骤1.2、工程1.3、工程 系列文章 使用、工程、模块介绍 JSA语法 第三篇练习练习题&#xff0c;持续更新中… 前言 如果你是开发人员&#xff0c;那么wps宏开发对你来说手拿把切。反之还挺吃力&#xff0c;需要嘻嘻&#xf…...

操作系统为ubantu的服务器上部署nginx软件基础步骤总结

今天在这里&#xff0c;我们总结一下ubantu的服务器上部署nginx软件&#xff0c;请按照以下步骤进行安装&#xff1a; 1、更新包列表&#xff1a; 首先更新你系统中的可用软件包列表&#xff0c;以确保你可以安装最新版本。 sudo apt update2、 Ubuntu上更新已安装软件包&…...

批量给 PPT 文档添加或删除保护,批量设置打开密码和只读密码

为了保护保护档的安全&#xff0c;我们经常会给 PPT 文档添加打开密码或者只读密码保护。有些场景下&#xff0c;我们也可能会碰到需要删除 PPT 文档的打开密码或者只读密码的需求。今天就给大家介绍一种方法可以一次性批量给多个 PPT 文档添加打开密码或者只读密码保护&#x…...

Elasticsearch 中的数据分片问题

Elasticsearch 分片机制 Elasticsearch 在存储数据时采用 分片&#xff08;Shard&#xff09;机制&#xff0c;以提高性能和可扩展性。它索引中的数据被划分成多个 主分片&#xff08;Primary Shard&#xff09; 和 副本分片&#xff08;Replica Shard&#xff09;&#xff0c…...

如何在IPhone 16Pro上运行python文件?

在 iPhone 16 Pro 上运行 Python 文件需要借助第三方工具或远程服务&#xff0c;以下是具体实现方法和步骤&#xff1a; 一、本地运行方案&#xff08;无需越狱&#xff09; 使用 Python 编程类 App 以下应用可在 App Store 下载&#xff0c;支持直接在 iPhone 上编写并运行 …...

Xinference安装、使用详细笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Xinference安装、使用详细笔记 支持推理引擎安装Xinference启动Xinference关于模型的推理引擎运行 qwen2.5-instruct管理模型官方详细文档&#xff1a;具体使用&#xff1a;对…...

NAT 模式

使用LVS的 NAT 模式实现 3 台RS的轮询访问。IP地址和主机自己规划。 1.节点规划 主机角色系统网络IPclientclientredhat 9.5仅主机192.168.180.100/24lvslvsredhat 9.5仅主机 NAT192.168.180.200/24 VIP 192.168.72.8/24 DIPnginxrs1redhat 9.5NAT192.168.226.7/24nginxrs2r…...

【中间件】Rabbit离线部署操作

准备安装包&#xff1a; 1.rabbitmq-server-4.0.7-1.el8.noarch.rpm 2.erlang-26.2.5.4-1.el9.x86_64.rpm 3.socat-1.7.4.1-6.el9.x86_64.rpm 操作步骤&#xff1a; 1.上传将RabbitMQ文件夹上传至服务器的home中 2.先安装erlang服务&#xff0c;顺序执行以下命令 设置服务的S…...

thinkphp漏洞再现

Thinkphp5x远程命令执行及getshell 1、开环境 2、使用工具攻击 开启工具 输入地址&#xff0c;点击漏洞检测 存在漏洞之后&#xff0c;选择漏洞&#xff0c;执行命令 3、也可以执行远程命令 执行命令 ?sindex/think\app/invokefunction&functioncall_user_func_array&…...

a-date-picker 格式化日期格式 YYYY-MM-DD HH:mm:ss

<template><a-range-pickerv-model:value"dateRange":show-time"{ format: HH:mm:ss, // 时间部分格式defaultValue: [moment(00:00:00, HH:mm:ss), moment(23:59:59, HH:mm:ss)] // 默认时间范围}"format"YYYY-MM-DD HH:mm:ss" // 整体…...