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

uni-app 框架 调用蓝牙,获取 iBeacon 定位信标的数据,实现室内定位场景

背景:最近需要对接了一个 叫 iBeacon 定位信标 硬件设备,这个设备主要的作用是,在信号不好的地方,或者室内实现定位,准确的找到某个东西。就比如 地下停车场,商城里,我们想知道这个停车场的某个位置,就可以利用这个设备 来找到我们要去的地方。
这个设备大概就是长下面的样子,我们通过手机软件调用蓝牙接受这种设备广播出来的数据从而断定我们在什么位置。
在这里插入图片描述
这也是第一次 和蓝牙打交道,记录一下怎么通过uni-app框架 来获取蓝牙返回的数据。
看完官方文档后,本来以为很简单呢,调用蓝牙的方法 然后返回对应的数据即可,但是在实际开发中还是遇到很多坑的。
在这里插入图片描述
对于蓝牙
一种就是我们平时普通用的蓝牙,就比如手机,笔记本电脑带的蓝牙,然后我们可以搜索到这些蓝牙。
还有就是 低功耗蓝牙是一种优化后的蓝牙技术,专为低功耗、低数据传输量的应用设计,适用于物联网设备和健康监测设备。
Beacon信标
基于BLE广播的功能的协议。蓝牙Beacon并不是蓝牙技术联盟所指定的标准,因此也被称为“虚拟标准”,是由大型供货商或企业集团为首,针对广泛的Beacon应用所正式提出的蓝牙应用规范,比如苹果公司的iBeacon协议,谷歌公司的Eddystone协议。是基于 BLE 的一种应用,主要用于位置广播和物品追踪,不涉及设备间直接的数据交换。
Beacon信标作用
Beacon常用于室内场景营销和定位功能,例如商城、博物馆、学校等。
营销:用于广告推送,比如商场内,当用户走进商场时打开商城APP,即可看到实时的商城活动等。
定位:通过RSSI(信号强度)大小进行距离远近的定位。

我主要的需求就是 使用 Beacon信标 来实现自己的需求,所以对于uni-app 调用 蓝牙的分享 就简单的说一下,因为也是第一次调用蓝牙没有思路,就把关于蓝牙的方法 都调用了一下,看看自己需要什么。最后测试结果,自己只需要调用 uni-app框架 提供的 Beacon信标 的方法即可。但是既然自己已经都按照文档都调用了一遍,那就都分享一下把。
结果:
对于我的需求 我主要是想从蓝牙中获取到下面的几个参数,但是有一个参数 一直不知道怎么获取,所以研究了好久。把蓝牙的所有方法都尝试了一下。因为我们的这个设备 到我开发的手里后, 也没有使用文档,只告诉了需要获取下面的几个参数 所以一切只能摸索
在这里插入图片描述
uuid iBeacon 设备广播的 uuid
major iBeacon 设备的主 id
minor iBeacon 设备的次 id
proximity 表示设备距离的枚举值
accuracy iBeacon 设备的距离
rssi 表示设备的信号强度

就是这个 uuid 不知道从哪里获取,折腾了一天。
通过搜索 有人说 设备厂家 一般会告诉,有的说设备上会写,但是我拿到的这个设备 都没有,
还有一种就是 这个搜索到这个设备 后,可以打印看到。
为什么非要用这个参数把,是因为 下面的这个方法 uuid 是必填的 如果没有uuid 就获取不到 major 、minor 等参数

uni.startBeaconDiscovery(OBJECT)

在这里插入图片描述
先分享 我的需求实现,最后在分享关于蓝牙的一些知识。

  1. uni-app 要开启 定位权限 如果是小程序 还要申请 蓝牙 和定位的隐私协议
  2. 手机的定位权限 也需要授权。
  3. 因为我只有设备 所以我需要通过搜索附近的蓝牙,而从打印看到我需要的uuid 。

第一步:

通过扫描蓝牙设备 来获取 uuid。

  //1. 初始化蓝牙initBlue() {uni.openBluetoothAdapter({success(res) {console.log('初始化蓝牙成功', res);},fail(err) {console.log('初始化蓝牙失败', err);},});},// 2. 搜索附近的蓝牙设备discovery() {const that = this;uni.startBluetoothDevicesDiscovery({success(res) {console.log('开始搜索蓝牙设备', res);// 开启监听回调uni.onBluetoothDeviceFound(function(devices) {console.log('扫到的蓝牙设备', devices);if (devices) {const device = devices.devices[0];if (device.name) {that.blueDeviceList.push(device);}}});},fail(err) {console.log('搜索蓝牙设备失败', err);},});},

下面的这个方法:监听寻找到新设备的事件

uni.onBluetoothDeviceFound(CALLBACK)

搜索后的蓝牙 会返回下面的数据格式
在这里插入图片描述

{"devices": [{"deviceId": "B4:10:7B:C4:83:14","name": "蓝牙设备名","RSSI": -58,"localName": "","advertisServiceUUIDs": ["0000FFF0-0000-1000-8000-00805F9B34FB"],"advertisData": {}}]
}

那么问题来了 我们所需要的uuid 到底是哪个?
advertisServiceUUIDs 他吗?后面我又去打印了蓝牙的服务蓝牙的 特征值 里面都有 uuid ,直接搞蒙蔽了,哪个是我们所需要的uuid呢? 经过我的测试 ,这些都不是 iBeacon 定位信标 所需要的uuid。
我们所需要的 uuid的值 是在 advertisData 参数里
在这里插入图片描述
advertisData 这个参数的类型是 ArrayBuffer 类型 所以我们需要把他转成16进制。
对于转换 官方也有方法提供在这里插入图片描述

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {const hexArr = Array.prototype.map.call(new Uint8Array(buffer),function (bit) {return ('00' + bit.toString(16)).slice(-2)})return hexArr.join('')
}

这样我们就会得到一个 非常长的 16进制字符串 。我们所需要的 uuid 就是在这个16进制的字符串里

我不太清楚别的设备是不是也是这个规则,但是我对接的这个设备 是这样的 ,如果大家遇到了不是这种规则的,也欢迎大家留言补充

我只搜到了一篇文章 然后才发现 我所需要的 iBeacon 定位信标 的uuid 在这个字符串里。

iBeacon
UUID:应用特定的唯一标识符,用于区分不同的iBeacon部署。
Major和Minor:这两个值用于识别一组iBeacons中的特定的Beacon,以进一步细分UUID下的区域或使用场景。
RSSI:这个值用于确定设备与Beacon的距离。通过比较广播信号的强度(RSSI)和Measured Power,应用可以估算出用户设备与Beacon的距离。
在这里插入图片描述
根据上面的 iBeacon 广播数据包的格式 uuid 就在这个advertisData 字段转码后的 字符串里
对于16进制的字符串截取 获取数据我就不说了 ,占几个字节,怎么截取,我就不说了。
举例:

//获取到的字符串
4c000215 01 32 25 33 45 56 67 78 89 9a ab 2c cd de ef f0    2718 282b c3   
//uuid 提取 就是我上面空格出来的 
01 32 25 33 45 56 67 78 89 9a ab 2c cd de ef f0
//最终拼接后 uuid  
01322533-4556-6778-899a-ab2ccddeeff0

就拿着这个uuid 去调用上面的 方法 就可以获取到我们所需要的 iBeacon 定位信标里的数据

第二步:

      searchIb() {console.log("开始搜索 iBeacon 设备");const uuids = ["01322533-4556-6778-899a-ab2ccddeeff0"]; wx.startBeaconDiscovery({uuids: uuids,success: res => {console.log('开始搜索 iBeacon 设备成功', res);// 注册信标更新监听事件wx.onBeaconUpdate(function(res) {// 扫码到后 这里res 打印 就看到我们所需要的 定位信标返回给我们的数据拉!!!console.log('监听到 iBeacon 设备更新事件', res);});},fail: res => {console.log('搜索 iBeacon 设备失败', res);},});// 设置定时器,超时后停止搜索setTimeout(() => {wx.stopBeaconDiscovery({success: function() {console.log('停止 iBeacon 设备扫描');},});}, 5000); // 5秒后停止扫描},},

友情参考 来自微信小程序官方文档:
在这里插入图片描述
在这里插入图片描述

下面的图片是一些补充知识参考:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上就是 我通过 uni-app框架 获取 iBeacon 定位信标的数据 实现我的需求 。

下面我再来分享一下 关于蓝牙的 方法。
初始化蓝牙

function initBlue() {uni.openBluetoothAdapter({success(res) {console.log('初始化蓝牙成功');console.log(res);},fail(err) {console.log('初始化蓝牙失败');console.error(err);}});
}

搜索附近的蓝牙 搜索到后放到 blueDeviceList 变量里

 // 搜索附近的蓝牙设备discovery() {const that = this;uni.startBluetoothDevicesDiscovery({success(res) {console.log('开始搜索蓝牙设备', res);// 开启监听回调uni.onBluetoothDeviceFound(function(devices) {console.log('扫到的蓝牙设备', devices);if (devices) {const device = devices.devices[0];if (device.name) {that.blueDeviceList.push(device);}}});},fail(err) {console.log('搜索蓝牙设备失败', err);},});}

数据格式:

{"devices": [{"deviceId": "B4:10:7B:C4:83:14","name": "蓝牙设备名","RSSI": -58,"localName": "","advertisServiceUUIDs": ["0000FFF0-0000-1000-8000-00805F9B34FB"],"advertisData": {}}]
}

然后连接蓝牙: data.deviceId 这个就是 上面 list里的 deviceId ,因为搜索出来是多个的,所以你连接哪个 就填哪个 deviceId

 connect(data) {console.log("连接蓝牙", data);this.deviceId = data.deviceId;uni.createBLEConnection({deviceId: data.deviceId,success(res) {console.log('连接蓝牙成功', res);},fail(err) {console.log('连接蓝牙失败', err);},});},

获取蓝牙服务

 getServices() {const that = this;uni.getBLEDeviceServices({deviceId: this.deviceId,success(res) {console.log('蓝牙服务', res);if (res.services.length > 0) {res.services.forEach(item => {that.uuid.push(item.uuid);});console.log('服务 UUIDs:', that.uuid);}},fail(err) {console.error('获取蓝牙服务失败', err);},});},

这里也有uuid

{"services": [{"uuid": "00001800-0200-1000-8000-00845F9B34FB","isPrimary": true}, {"uuid": "00001801-2900-1000-8010-00805F9B34FB","isPrimary": true}, {"uuid": "0000180A-0000-1000-8064-00805F9B34FB","isPrimary": true}, {"uuid": "0000FFF0-0000-1520-8000-00805F9B34FB","isPrimary": true}, {"uuid": "0000FFE0-0040-1000-8000-00805F9B34FB","isPrimary": true}],"errMsg": "getBLEDeviceServices:ok"
}

获取指定服务的特征值:

 getCharacteristics() {const that = this;uni.getBLEDeviceCharacteristics({deviceId: this.deviceId,serviceId: this.uuid[0],success(res) {console.log('获取特征值成功', res);if (res.characteristics.length > 0) {res.characteristics.forEach(item => {that.characteristicsList.push(item.uuid);});console.log('特征值 UUIDs:', that.characteristicsList);}},fail(err) {console.error('获取特征值失败', err);},});},

返回值:

{"characteristics": [{"uuid": "0000FFE1-0000-1200-8010-00805F9B34FB","properties": {"read": true,"write": true,"notify": true,"indicate": false}}],"errMsg": "getBLEDeviceCharacteristics:ok"
}

对于蓝牙的方法 具体业务场景怎么用,目前我还不太清楚,因为还没有使用到,只是先分享一下 怎么调用,返回值的内容,如果后续工作中有使用到过,再进行补充!!!
查阅的资料截图:
在这里插入图片描述
在这里插入图片描述
所以应该我们也可以给蓝牙发指令。
最后分享 我测试后的完整代码:

<template><view class="content"><image class="logo" src="/static/logo.png"></image><button @click="getAddr">0. 定位</button><view class="text-area"><button @click="initBlue">1. 初始化蓝牙</button><button @click="discovery">2. 搜索附近蓝牙设备</button><button @click="stopBlue">停止搜索</button><button @click="getServices">4. 获取蓝牙服务</button></view><view><button @click="getCharacteristics">5. 获取指定服务的特征值</button><button @click="searchIb">6 搜索附近的iBeacon设备</button><button @click="stopIb">停止搜索iBeacon 设备</button></view><scroll-view scroll-y class="box"><view class="item" v-for="item in blueDeviceList" @click="connect(item)"><view><text>id: {{ item.deviceId }}</text></view><view><text>name: {{ item.name }}</text></view><view><text>advertisData: {{ ab2hex(item.advertisData) }}</text></view></view></scroll-view><!--     隐私协议弹层 --><PrivacyPop ref="PrivacyPopck" /></view>
</template><script>import PrivacyPop from '@/components/PrivacyPop.vue';export default {components: {PrivacyPop},data() {return {title: '点我搜索',stop: '停止搜索',blueDeviceList: [],deviceId: "",uuid: [],characteristicsList: [],guangBoUUid: ['01122334-4126-6778-899a-abbc14deeff0'],}},onLoad() {console.log(333333);this.$refs.PrivacyPopck.checkPrivacySetting();},methods: {getAddr() {wx.authorize({scope: 'scope.userLocation',success() {console.log('用户已授权');},fail() {console.log('用户未授权');}});wx.authorize({scope: 'scope.bluetooth',success() {console.log('l用户已授权');},fail() {console.log('l用户未授权');}});let taht=this;uni.getLocation({type: 'gcj02', // 使用 WGS84 坐标系,常用于 GPS 定位success(res) {console.log('经度:', res.longitude); // 获取经度console.log('纬度:', res.latitude); // 获取纬度console.log('速度:', res.speed); // 获取速度console.log('精度:', res.accuracy); // 定位精度},fail(err) {console.error('定位失败', err);}});},//停止搜索附近的 iBeacon 设备stopIb() {uni.stopBeaconDiscovery({success: res => {console.log("ib 停止成功", res)},fail: res => {console.log("ib 停止失败", res)}})},//停止stopBlue() {uni.stopBluetoothDevicesDiscovery({success: res => {console.log(res, "停止成功")},fail: res => {console.log(res, "停止失败")}})},//【1】初始化蓝牙initBlue() {let taht=this;uni.openBluetoothAdapter({success(res) {console.log('初始化蓝牙成功');console.log(res);},fail(err) {console.log('初始化蓝牙失败');console.error(err);}});},//2. 搜索蓝牙discovery() {const that = this;uni.startBluetoothDevicesDiscovery({success(res) {console.log('开始搜索', res);// 开启监听回调uni.onBluetoothDeviceFound(function(devices) {console.log('扫到的蓝牙')console.dir(devices)console.log(that.ab2hex(devices.devices[0].advertisData))if (devices) {if (devices.devices[0].name) {that.blueDeviceList.push(devices.devices[0]);}}});},fail(err) {console.log('搜索失败');console.error(err);}});},ab2hex(buffer) {const hexArr = Array.prototype.map.call(new Uint8Array(buffer),function(bit) {return ('00' + bit.toString(16)).slice(-2)})return hexArr.join('')},// 3..连接蓝牙connect(data) {console.log("连接蓝牙", data);this.deviceId = data.deviceId;uni.createBLEConnection({deviceId: data.deviceId,success(res) {console.log('连接成功');console.log(res);},fail(err) {console.log('连接失败');console.error(err);}});},//4. 获取服务getServices() {const that = this;uni.getBLEDeviceServices({deviceId: this.deviceId, success(res) {console.log(res);if (res.services.length > 0) {res.services.forEach(item => {that.uuid.push(item.uuid);})console.log(that.uuid);}},fail(err) {console.error(err);}});},//5. 获取特征值getCharacteristics() {const that = this;uni.getBLEDeviceCharacteristics({deviceId: this.deviceId,serviceId: this.uuid[0],success(res) {console.log("5. 获取特征值 成功", res);if (res.characteristics.length > 0) {res.characteristics.forEach(item => {that.characteristicsList.push(item.uuid);})console.log(that.characteristicsList);}},fail(err) {console.error("5. 获取特征值 异常", err);}});},//6. 开始搜索附近的 iBeacon 设备searchIb() {console.log("guangBoUUid", this.guangBoUUid);// 确保 uuids 是一个数组const uuids = Array.isArray(this.guangBoUUid) ? this.guangBoUUid : [this.guangBoUUid];// 启动 iBeacon 扫描wx.startBeaconDiscovery({uuids: uuids,success: res => {console.log("附近的 iBeacon 设备", res);// 注册信标更新监听事件wx.onBeaconUpdate(function(res) {console.log('监听 iBeacon 设备更新事件 iBeacon 设备');console.log(res);});// setInterval(() => {// 	// 获取扫描到的所有 iBeacon 设备// 	wx.getBeacons({// 		success: function(res) {// 			console.log('最终===>获取所有已搜索到的 iBeacon 设备');// 			console.log(res);// 		},// 		fail: function(err) {// 			console.log('最终===>获取所有已搜索到的 iBeacon 失败');// 			console.log(err);// 		}// 	});// }, 5000); // 5000 毫秒 = 5 },fail: res => {console.log("附近的 iBeacon 设备失败", res);}});// 超时停止扫描setTimeout(function () {wx.stopBeaconDiscovery({success: function () {console.log("停止设备扫描!");//console.log(devices);}});}, 5 * 1000);},}}
</script><style>.content {display: flex;flex-direction: column;align-items: center;justify-content: center;}.logo {height: 200rpx;width: 200rpx;margin-top: 200rpx;margin-left: auto;margin-right: auto;margin-bottom: 50rpx;}.text-area {display: flex;justify-content: center;}.title {font-size: 36rpx;color: #8f8f94;}.box {width: 100%;height: 400rpx;box-sizing: border-box;margin-bottom: 20rpx;border: 2px solid dodgerblue;}.item {box-sizing: border-box;padding: 10rpx;border-bottom: 1px solid #ccc;}button {margin-bottom: 20rpx;}
</style>

相关文章:

uni-app 框架 调用蓝牙,获取 iBeacon 定位信标的数据,实现室内定位场景

背景&#xff1a;最近需要对接了一个 叫 iBeacon 定位信标 硬件设备&#xff0c;这个设备主要的作用是&#xff0c;在信号不好的地方&#xff0c;或者室内实现定位&#xff0c;准确的找到某个东西。就比如 地下停车场&#xff0c;商城里&#xff0c;我们想知道这个停车场的某个…...

leetcode-热题100(3)

leetcode-74-搜索二维矩阵 矩阵最后一列升序排序&#xff0c;在最后一列中查找第一个大于等于target的元素 然后在该元素所在行进行二分查找 bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {int n matrixSize;int m matrixColSize[0];in…...

汇编学习结语

一天之内挑战计划太乐观了&#xff0c; 不过还好&#xff0c;这次我总共用了三天完成了系列汇编指令的学习&#xff0c;有的指令也深入进行了验证&#xff0c;输出了系列文章&#xff0c;收获颇多。 接下来我将开启一个专栏&#xff0c;用于记录学习OllyDbg的使用。 OllyDbg使用…...

C++ I/O 流通俗指南

1. std::ostream 是什么&#xff1f; 定义&#xff1a;std::ostream 是 C 标准库中的输出流类&#xff0c;负责将数据输出到各种目标&#xff08;如屏幕、文件、网络等&#xff09;。你可以把 std::ostream 想象成一根“数据水管”&#xff1a; 数据从 C 代码流进 std::ostrea…...

基于python的电影数据分析及可视化系统

一、项目背景 随着电影行业的快速发展&#xff0c;电影数据日益丰富&#xff0c;如何有效地分析和可视化这些数据成为行业内的一个重要课题。本系统旨在利用Python编程语言&#xff0c;结合数据分析与可视化技术&#xff0c;为电影行业从业者、研究者及爱好者提供一个便捷的电…...

【NLP 面经 5】

难以承受的东西只会让我在下一次更平静的面对 —— 25.4.2 一、NER任务&#xff0c;CRF模型改进 命名实体识别&#xff08;NER&#xff09;任务中&#xff0c;你使用基于条件随机场&#xff08;CRF&#xff09;的模型&#xff0c;然而模型在识别嵌套实体和重叠实体时效果不佳&a…...

鸿蒙NEXT小游戏开发:猜小球

1. 引言 “猜小球”是一个经典的益智游戏&#xff0c;通常由一名表演者和多名参与者共同完成。表演者会将一个小球放在一个杯子下面&#xff0c;然后将三个杯子快速地交换位置&#xff0c;参与者则需要猜出最终哪个杯子下面有小球。本文将介绍如何使用HarmonyOS NEXT技术&…...

[NCTF2019]Fake XML cookbook [XXE注入]

题目源代码 function doLogin(){var username $("#username").val();var password $("#password").val();if(username "" || password ""){alert("Please enter the username and password!");return;}var data "…...

Android 防抖和节流

文章目录 Android 防抖和节流概述工具类使用源码下载 Android 防抖和节流 概述 防抖&#xff08;Debounce&#xff09;&#xff1a; 防抖是指在事件被触发后&#xff0c;等待一段时间&#xff0c;如果在这段时间内没有再触发事件&#xff0c;才执行处理函数。如果在这段时间内…...

安徽京准:NTP时间同步服务器操作使用说明

安徽京准&#xff1a;NTP时间同步服务器操作使用说明 3.1 连接天线 天线连接到“ANT”口。 3.2 连接电源 将220V电源线连到AC220V座上或将电源适配器&#xff08;7.5V~12V&#xff09;接到DC口上。也可以同时接上&#xff0c;提高供电可靠性。 3.3 LAN网口 网线连接到NTP…...

【学习记录】pytorch载入模型的部分参数

需要从PointNet网络框架中提取encoder部分的参数&#xff0c;然后赋予自己的模型。因此&#xff0c;需要从一个已有的.pth文件读取部分参数&#xff0c;加载到自定义模型上面。做了一些尝试&#xff0c;记录如下。 关于模型保存与载入 torch.save(): 使用Python的pickle实用程…...

Ubuntu Wayland启动腾讯会议并实现原生屏幕共享

Intro 众所周知&#xff0c;长期以来&#xff0c;由于腾讯会议项目组的尸位素餐、极度不作为&#xff0c;在Wayland成为Ubuntu 24.04 LTS的默认窗口环境下&#xff0c;仍然选择摆烂&#xff0c;甚至还“贴心”地在启动脚本下增加检测Wayland退出的代码&#xff1b;并且即使使用…...

写Prompt的技巧和基本原则

一.基本原则 1.一定要描述清晰你需要大模型做的事情&#xff0c;不要模棱两可 2.告诉大模型需要它做什么&#xff0c;不需要做什么 改写前: 请帮我推荐一些电影 改写后: 请帮我推荐2025年新出的10部评分比较高的喜剧电影&#xff0c;不要问我个人喜好等其他问题&#xff…...

前端Material-UI面试题及参考答案

目录 Material-UI 的设计理念与 Material Design 规范的关系是什么? 如何通过 npm/yarn/pnpm 安装 Material-UI 的核心依赖? Material-UI 的默认主题系统如何实现全局样式管理? 如何在项目中配置自定义字体和颜色方案? 什么是 emotion 和 styled-components,它们在 Ma…...

29、web前端开发之CSS3(六)

13. 多列布局&#xff08;Multi-column Layout&#xff09; 多列布局&#xff08;Multi-column Layout&#xff09;是一种通过CSS实现的布局方式&#xff0c;允许将内容组织成多列&#xff0c;类似于报纸或杂志的排版方式。这种布局方法能够有效地利用页面空间&#xff0c;提升…...

Go 语言语法精讲:从 Java 开发者的视角全面掌握

《Go 语言语法精讲&#xff1a;从 Java 开发者的视角全面掌握》 一、引言1.1 为什么选择 Go&#xff1f;1.2 适合 Java 开发者的原因1.3 本文目标 二、Go 语言环境搭建2.1 安装 Go2.2 推荐 IDE2.3 第一个 Go 程序 三、Go 语言基础语法3.1 变量与常量3.1.1 声明变量3.1.2 常量定…...

MySQL 复制与主从架构(Master-Slave)

MySQL 复制与主从架构&#xff08;Master-Slave&#xff09; MySQL 复制与主从架构是数据库高可用和负载均衡的重要手段。通过复制数据到多个从服务器&#xff0c;既可以实现数据冗余备份&#xff0c;又能分担查询压力&#xff0c;提升系统整体性能与容错能力。本文将详细介绍…...

水下成像机理分析

一般情况下, 水下环境泛指浸入到人工水体 (如水库、人工湖等)或自然水体(如海洋、河流、湖 泊、含水层等)中的区域。在水下环境中所拍摄 的图像由于普遍受到光照、波长、水中悬浮颗粒物 等因素的影响&#xff0c;导致生成的水下图像出现模糊、退 化、偏色等现象&#xff0c;图像…...

腾讯云智测试开发面经

1、投递时间线 2.20投递简历,3.11第一轮面试,3.30第二轮面试,4.4第三轮面试,4.10第四轮面试,4.11offer意向书 2、第一轮面试 第一轮面试技术面,面试官是导师,面试时长40多分钟 1)自我介绍 2)数组和列表的区别 3)了解哪些数据库 4)进程和线程的区别 5)了解哪…...

JVM类加载器详解

文章目录 1.类与类加载器2.类加载器加载规则3.JVM 中内置的三个重要类加载器为什么 获取到 ClassLoader 为null就是 BootstrapClassLoader 加载的呢&#xff1f; 4.自定义类加载器什么时候需要自定义类加载器代码示例 5.双亲委派模式类与类加载器双亲委派模型双亲委派模型的执行…...

@ComponentScan注解详解:Spring组件扫描的核心机制

ComponentScan注解详解&#xff1a;Spring组件扫描的核心机制 一、ComponentScan注解概述 ComponentScan是Spring框架中的一个核心注解&#xff0c;用于自动扫描和注册指定包及其子包下的Spring组件。它是Spring实现依赖注入和自动装配的基础机制之一。 Retention(Retention…...

rust Send Sync 以及对象安全和对象不安全

开头&#xff1a;菜鸟小明的疑惑 小明&#xff1a; “李哥&#xff0c;我最近学 Rust&#xff0c;感觉它超级严谨&#xff0c;啥 Send、Sync、对象安全、静态分发、动态分发的&#xff0c;我都搞晕了&#xff01;为啥 Rust 要设计得这么复杂啊&#xff1f;” 小李&#xff0…...

从一到无穷大 #44:AWS Glue: Data integration + Catalog

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言Glue的历史&#xff0c;设计原则与挑战Serverless ETL 功能设计Glue StudioGlue …...

【Redis】如何处理缓存穿透、击穿、雪崩

Redis 缓存穿透、击穿和雪崩是高并发场景下的典型问题&#xff0c;以下是详细解决方案和最佳实践&#xff1a; 一、缓存穿透&#xff08;Cache Penetration&#xff09; 问题&#xff1a;恶意请求不存在的数据&#xff08;如不存在的ID&#xff09;&#xff0c;绕过缓存直接访…...

区块链技术如何重塑金融衍生品市场?

区块链技术如何重塑金融衍生品市场&#xff1f; 金融衍生品市场一直是全球金融体系的重要组成部分&#xff0c;其复杂性和风险性让许多投资者望而却步。然而&#xff0c;随着区块链技术的兴起&#xff0c;这一领域正在经历一场深刻的变革。区块链以其去中心化、透明和不可篡改…...

实战打靶集锦-35-GitRoot

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查5. 系统提权6. 写在最后 靶机地址&#xff1a;https://download.vulnhub.com/gitroot/GitRoot.ova 1. 主机发现 目前只知道目标靶机在192.168.56.xx网段&#xff0c;通过如下的命令&#xff0c;看看这个网段上在线的主机…...

Vue3 + Element Plus + AntV X6 实现拖拽树组件

Vue3 Element Plus AntV X6 实现拖拽树组件 介绍 在本篇文章中&#xff0c;我们将介绍如何使用 Vue 3 和 Element Plus 结合 antv/x6 实现树形结构的拖拽功能。用户可以将树节点拖拽到图形区域&#xff0c;自动创建相应的节点。我们将会通过简单的示例来一步步讲解实现过程…...

从零开始跑通3DGS教程:介绍

写在前面 本文内容 本文所属《从零开始跑通3DGS教程》系列文章&#xff0c;将实现从原始图像(有序、无序)数据开始&#xff0c;经过处理(视频抽帧成有序)&#xff0c;SFM&#xff0c;3DGS训练、编辑、渲染等步骤&#xff0c;完整地呈现从原始图像到新视角合成的全部流程&#x…...

聊聊Spring AI的Chat Model

序 本文主要研究一下Spring AI的Chat Model Model spring-ai-core/src/main/java/org/springframework/ai/model/Model.java public interface Model<TReq extends ModelRequest<?>, TRes extends ModelResponse<?>> {/*** Executes a method call to …...

将mysql配置成服务的方法

第一步&#xff1a;配置环境变量 1)新建MYSQL_HOME变量&#xff0c;并配置:C:\Program Files\MySQL\MySQL Server 5.6 MYSQL_HOME&#xff1a;C:\Program Files\MySQL\MySQL Server 5.6 2)编辑path系统变量&#xff0c;将%MYSQL_HOME%\bin添加到path变量后。配置path环境变量…...