蓝牙Mesh学习笔记(一)
Mesh系统结构
- 1 Mesh网络分层
- 1.1 模型层(Model layer)
- 1.2 基础模型层(Foundation Model layer)
- 1.3 接入层(Access layer)
- 1.4 上层传输层(Upper transport layer)
- 1.5 下层传输层(Lower transport layer)
- 1.6 网络层(Network layer)
- 1.7 承载层(Bearer layer)
- 1.8 BLE内核规范(BLE Core Specification)
- 2 Mesh概述
- 2.1 网络和子网
- 2.1.1 网络地址用于识别消息来源和目的地。
- 2.1.1.1 未分配地址
- 2.1.1.2 单播地址
- 2.1.1.3 虚拟地址
- 2.1.1.4 组地址
- 2.1.2 网络密钥用于在网络层对消息进行安全认证。
- 2.1.3 应用密钥用于在访问层对消息进行安全认证。
- 2.1.4 一个用于提供网络寿命的IV Index。
- 2.2 设备和节点
- 2.3 添加设备到Mesh网络
- 2.4 通讯保障
- 2.5 支持低功耗
- 3 Mesh架构概念
- 3.1 状态(States)
- 3.2 绑定状态(Bound states)
- 3.3 消息(Messages)
- 3.4 元素(Elements)
- 3.5 地址(Addresses)
- 3.6 模型(Models)
- 3.7 发布-订阅和信息交换(Publish-subscribe and message exchange)
- 3.8 安全(Security)
- 3.8.1 应用与网络安全(Application and network security)
- 3.8.2 模糊化(Obfuscation)
- 3.8.3 网络和应用密钥(Network and application key identifiers)
- 3.8.4 初始向量索引(Initialization vector index)
- 3.9 朋友(Friendship)
- 3.10 功能(Features)
- 3.11 拓扑(Topology)
- 4 Mesh网关
- 5 并发限制和约束
1 Mesh网络分层

1.1 模型层(Model layer)
模型层定义了用于规范典型用户场景操作的模型,并在蓝牙Mesh模型规范或其他更高层的规范中定义。高层模型规范的例子包括照明和传感器的模型。
1.2 基础模型层(Foundation Model layer)
基础模型层定义了配置和管理mash网络所需的状态、消息和模型。
1.3 接入层(Access layer)
接入层定义了上层应用如何使用上层传输层。它定义了应用程序数据的格式;它定义并控制在上层传输层执行的应用程序数据加密和解密;并且在将传入的应用数据转发到更高层之前,在正确的网络和应用密钥的上下文中检查是否已经接收到传入的应用数据。
1.4 上层传输层(Upper transport layer)
上层传输层对应用数据进行加密、解密和认证,旨在提供访问消息的机密性。它还定义了如何使用传输控制消息来管理节点之间的上层传输层,包括当Friend特性使用时。
1.5 下层传输层(Lower transport layer)
下层传输层定义了如何将上层传输层消息分段并重新组合成多个下层传输PDU,从而将大的上层传输层消息传递给其他节点。它还定义了单个控制消息来管理分段和重组。
1.6 网络层(Network layer)
网络层定义了如何向一个或多个元素寻址传输消息。它定义了允许由承载层传输的PDU网络消息格式。网络层决定是否中继/转发消息,接受消息进行进一步处理或者拒绝消息。它还定义了网络消息如何被加密和认证。
1.7 承载层(Bearer layer)
承载层定义了网络消息如何在节点间传输。定义了两个承载者,广播承载者和GATT承载者。未来可能会定义额外的承载者。
1.8 BLE内核规范(BLE Core Specification)
蓝牙技术联盟中定义的mesh协议栈:

2 Mesh概述
Mesh网络特性:
1.使消息能够从一个元素发送到一个或多个元素。
2.允许消息通过其他节点进行中继以扩展通信范围。
3.信息安全,抵御包括窃听攻击、中间人攻击、重放攻击、垃圾桶攻击、暴力破解密钥攻击,以及其他可能的安全攻击。
4.在当今市场上的现有设备上工作。
5.及时传递消息。
6.当一个或多个设备移动或停止运行时继续工作。
7.具有向前兼容性,以支持未来版本的Mesh Profile规范。
mesh网络通过多种方式来防止消息的无限中继。两种主要的方式是消息缓存和存活时间(Time to Live),消息缓存是通过限制缓存的个数,存活时间是通过限制中继的次数,每次接收到一条消息,然后由设备中继(最高可达126倍),TTL值递减1。
2.1 网络和子网
一个网络可以有一个或多个子网,便于"区域"隔离(例如,酒店网络中的独立客房子网)。子网是可以在网络层中互相通讯的一组节点,因为他们共享网络密钥。一个节点通过知道一个或多个网络密钥可能属于一个或者多个子网。一个设备可以使用配置模型被添加到一个或者多个子网。
在主NetKey的基础上,有一个特殊的子网叫做主子网。主子网上的节点参与IV更新过程,并将IV更新传播给其他子网,而其他子网上的节点只将IV Index更新传播给这些子网。
网络资源由实现Configuration Client模型的节点管理,称为Configuration Client(通常是智能手机或其他移动计算设备),并在配置时使用Configuration Server模型分配给节点。具体来说,配置角色(Provisioner)管理地址的分配,以确保没有重复的单播地址被分配,而Configuration Client生成和分发网络和应用程序密钥,并确保需要相互通信的设备为网络和访问层共享适当的密钥。Configuration Client还知道设备密钥,用于与每个节点进行安全通信,包括分发更新的网络密钥和应用密钥。
一个Mesh网络由共享四个公共资源的节点组成:
2.1.1 网络地址用于识别消息来源和目的地。
网络层定义了地址的四种基本类型:未分配、单播、虚拟和组。地址占用16位,定义如下:

2.1.1.1 未分配地址
未分配地址是节点的元素尚未配置或未分配地址时的一种地址,未分配地址的值应该是0x0000。例如,可以通过将模型的发布地址设置为未分配的地址来禁用模型的消息发布。未分配的地址不得用于消息的源或目的地址字段。
2.1.1.2 单播地址
单播地址是分配给每个元素的唯一地址。单播地址范围0x0001至0x7FFF。单播地址必须用于消息的源地址字段,也可以用于消息的目的地址字段。发送到单播地址的消息最多只能由一个元素处理。

2.1.1.3 虚拟地址
虚拟地址表示一组目的地址。单播地址范围0x8000至0xBFFF。每个虚拟地址在逻辑上表示一个Label UUID,它是一个128位的值,不需要集中管理。一个或多个元素可以被编程来发布或订阅一个Label UUID。虚拟地址的0-13位是hash值,该hash值是Label UUID的派生,使得每个哈希表示多个Label UUIDs。当Access消息被接收到具有匹配哈希的虚拟地址时,上层传输层将每个对应的Label UUID作为作为消息认证的额外一部分数据,直到找到匹配。虚拟地址的一个缺点是在配置过程中需要多段消息将Label UUID传输到发布或订阅节点。控制消息不可以使用虚拟地址。

2.1.1.4 组地址
组地址是被编程为零个或多个元素的地址。0xFF00到0xFFFF范围内的组地址保留给固定组地址,0xC000到0xFEFF范围内的地址一般可用于其他用途。组地址只能在消息的目的地址字段中使用。发送到组地址的消息应传递给所有订阅该组地址的模型实例。

组地址有两种:动态分配的和那些固定的

发送到全代理地址的消息应由启用代理功能的所有节点的主元素处理。
发送到全好友地址的消息应由启用好友功能的所有节点的主元素处理。
发送到全中继地址的消息应由启用中继功能的所有节点的主元素处理。
发送到全节点地址的消息应由所有节点的主元素处理。
2.1.2 网络密钥用于在网络层对消息进行安全认证。
网络密钥( NetKey )使用随机数发生器生成。

2.1.3 应用密钥用于在访问层对消息进行安全认证。
应用密钥( AppKey)使用随机数发生器生成。

2.1.4 一个用于提供网络寿命的IV Index。
IV Index是共享网络资源(即Mesh网络中的所有节点共享相同的IV Index值,并将其用于它们所属的所有子网)的32位值。IV Index从0x00000000开始。如果一个节点在一段时间内不在网状网络中,它可以扫描安全网络信标(Secure Network beacons)或使用IV Index Recovery过程,从而自主设置IV Index值。
2.2 设备和节点
不属于mesh网络成员的设备称为未配置设备。作为mesh网络成员的设备称为节点。配置角色用于管理未配置的设备和节点之间的转换。未配置的设备不能发送或接收mesh网络消息,但是它可以向配置角色宣传自己的存在。配置角色在认证完毕后会邀请这个未配置设备加入Mesh网络,将其转换为节点。通过配置客户端( Configuration Client )的配置节点可以实现在Mesh网络发送或接收消息,该客户端也可能是和配置角色是同一个设备。配置客户端可以从mesh网络中移除节点,并将其恢复到未配置的设备。
2.3 添加设备到Mesh网络
设备通过一个配置角色添加到一个mesh网络中,此时它们成为节点。将设备配置到mesh网络中不同于蓝牙无线技术中通常使用的点对点绑定和配对,设备的配置可以使用简单的广播承载或基于GATT的点对点承载。两个承载者均使用单一的配置协议。所有的设备都支持基于广播承载的配置。通过提供基于GATT的承载,使得传统电话(也就是说,设备不支持基于广播承载的配置)设备可以成为配置角色。
为了辅助配置多个设备,一个设备有一个可以通过配置角色设置的attention timer。当设置为非零值时,设备可以使用任何方法来标识自己,例如:设备可能闪光、发出声音或振动。当attention timer到期时,设备停止标识自身。配置角色可以向设备发送一条消息使其标识自己,并且设备在给定时间后自动停止标识自己。
2.4 通讯保障
许多现有设备无法在不更新的情况下发布或理解mesh消息。为了使这些设备能够在不需要进行操作系统更新或类似软硬件更新的情况下与Mesh网络中的节点通信,该规范允许对所有现有设备使用GATT连接。
2.5 支持低功耗
规范不要求设备在每个连接上协调传输、建立连接或重启安全认证,从而有利于低功耗运行。需要支持低功耗的设备可以使Friendship的概念,将自己与代表他们存储和中继消息的常开设备关联起来。然而,中继消息的设备将在大部分时间内接收消息和转发消息,导致产生相对较大功耗。
3 Mesh架构概念
Mesh网络架构使用了几种不同的概念:状态、消息、绑定、元素、寻址、模型、发布订阅、Mesh密钥和关联。
3.1 状态(States)
状态是表示元素的一个条件的值。
一个展示状态的元素被称为服务器。例如,最简单的服务器是Generic OnOff Server,表示它要么开要么关。访问状态的元素被称为客户端。例如,最简单的客户端是Generic OnOff Client (一个二进制开关),它可以通过Generic OnOff模型定义的消息控制Generic OnOff Server。
3.2 绑定状态(Bound states)
当一个状态被绑定到另一个状态时,一个状态的变化导致另一个状态的变化。绑定状态可能来自一个或多个元素中的不同模型。例如,一种常见的绑定类型是介于Level状态和OnOff状态之间:将Level改为0将OnOff状态改为Off,将Level改为非零值将OnOff状态改为On。
3.3 消息(Messages)
消息由操作码、相关参数和行为组成。操作码可以是单字节(对于需要参数的最大可能负载的特殊消息)、2个字节(对于标准消息)或3个字节(针对供应商特定的消息)。
包括操作码在内的总消息大小由底层传输层决定,传输层可以使用分段和重组( Segmentation and Resemble,SAR )机制。为了最大限度地提高性能并避免SAR的开销,一个设计目标是在单个段中拟合消息。传输层为非分段消息提供最多11个字节,使用1个字节操作码时可供参数使用的字节最多为10个,使用2个字节操作码时可供参数使用的字节最多为9个,使用特定厂商的3个字节操作码时可供参数使用的字节最多为8个。传输层提供了一种能够传输多达32段SAR的机制。使用SAR时的最大消息大小为384个字节。这意味着,当使用1字节操作码时,参数最多可为379个字节,使用2字节操作码时,参数最多可为378个字节,使用特定于厂商的3字节操作码时,参数最多可为377个字节。
3.4 元素(Elements)
元素是节点内的可寻址实体。每个节点至少有一个元素,即主元素,也可能有一个或多个附加的次元素。元素的数量和结构是静态的,在节点(即只要节点是网络的一部分)的整个生命周期内不会发生变化。
主元素使用配置期间分配给节点的第一个单播地址进行寻址,每个额外的次要元素使用后续地址进行寻址。这些单播元素地址允许节点识别节点内哪个元素正在发送或接收消息。如果元素的数量和结构发生变化,例如由于固件更新,节点必须重新设置。当执行固件更新以更改元素的数量或结构时,需要移除节点。消息在模型中基于操作码和元素地址进行分发。
3.5 地址(Addresses)
一个地址可以是单播地址、虚拟地址或者群组地址。还有一个特殊的值来表示消息中没有使用的未分配地址。
一个单播地址分配给一个元素,并且始终代表一个节点的单个元素。每个mesh网络有32767个单播地址。
虚拟地址是多播地址,可以表示一个或多个节点上的多个元素。每个虚拟地址在逻辑上表示一个Label UUID,它是一个128位的值,不需要集中管理。发送给Label UUID的每条消息都包含用于验证消息的消息完整性校验值中的完整Label UUID。为了减少检查每个已知标签UUID的开销,使用标签UUID的哈希。共有16384个哈希值,每个哈希值编码一组虚拟地址。虽然一个虚拟地址使用的哈希值只有16384个,但是每个哈希值可以代表数百万个可能的Label UUID;因此,虚拟地址的数量被认为非常庞大。
组地址是多播地址,可以表示一个或多个节点上的多个元素。每个mesh网络有16384个组地址。有一组固定的组地址,用于根据节点的功能来解决节点的所有主要元素的子集。所有其他组地址称为动态分配组地址。其中固定组地址256个,动态分配组地址16128个。
3.6 模型(Models)
应用定义在客户端模型、服务器模型和控制模型中。使用客户端-服务器架构与发布-订阅范式通信来指定一个mesh应用。单个设备可能包含客户端模型、服务器模型和控制模型。
服务器模型:一个服务器模型由跨越一个或多个元素的一个或多个状态组成。服务器模型定义了一组它可以发送或接收的强制消息,元素在发送和接收此类消息时所需的行为,以及消息发送或接收后发生的任何附加行为。
客户端模型:客户端模型定义了一组消息(既有强制性又有选择性),客户端用来请求、更改或消费相应的服务器状态,如服务器模型所定义的。客户端模型没有状态。
控制模型:控制模型可能包含客户端模型与其他服务器模型通信的功能和服务器模型与其他客户端模型通信的功能。一个控制模型也可能包含控制逻辑,是协调控制模型所连接的其他模型之间相互作用的一组规则和行为。


3.7 发布-订阅和信息交换(Publish-subscribe and message exchange)
mesh网络中数据的发布和订阅被描述为使用发布-订阅范式。生成消息的节点将消息发布到单播地址、组地址或虚拟地址。有兴趣接收消息的节点将订阅这些地址。生成的消息被发送到目标mesh地址,这些地址可以是单播、预先配置的组地址或虚拟地址。消息可以作为对其他消息的回复发送,也可以是未经请求的消息。当模型的实例发送应答消息时,它使用传入消息发起者的源地址作为目的地址。当模型的实例发送未请求的消息时,它使用模型发布地址作为目标地址。节点内模型的每个实例具有单一的发布地址。
在接收方,节点内模型的每个实例可以订阅一个或多个组地址或虚拟地址。当发送到模型的一个订阅列表上的组地址或虚拟地址的消息到达时,由节点进行处理。当消息的目的地址是接收单元的单播地址时,或者消息的目的地址是该设备所属的固定组地址时,也会对消息进行处理。如果一个节点有多个元素,则在每个被寻址的元素上处理一次消息。
尽管节点可能会限制所支持的订阅数量,但节点可以在每个模型元素的实例中拥有多个订阅。使用多个订阅地址允许节点响应发布到不同组的消息。例如,一盏灯可能会订阅发送给床头灯组、卧室组、楼上组和房子组的消息。每个消息从单个单播地址(一个元素地址)发送,并使用唯一的序列号进行排序,以方便检测和防御重放攻击。
3.8 安全(Security)
3.8.1 应用与网络安全(Application and network security)
3.8.2 模糊化(Obfuscation)
该网络安全模型使用一种名为模糊化的隐私机制,该机制使用AES加密源地址、序列号和其他使用隐私密钥的头信息。模糊化的目的是使跟踪节点更加困难。
3.8.3 网络和应用密钥(Network and application key identifiers)
3.8.4 初始向量索引(Initialization vector index)
3.9 朋友(Friendship)
低功耗节点使用Friendship来限制它们需要侦听的时间量。如果节点不能连续接收,则有可能不会接收到需要处理的mesh消息。这包括维护网络安全所需的安全更新以及正常的mesh消息。如果低功耗节点没有收到这样的消息,那么它可能无法正常工作,也可能无法及时了解网络的最新安全状态,如果这种安全状态在不知情的情况下发生了变化,它最终会退出网络。
Friendship是低功耗节点与一个邻近的Friend节点之间的一种特殊关系。这些节点必须在彼此的单跳内,并且在同一个子网中。Friendship首先由低功耗节点建立并发起;一旦建立,Friend节点执行一系列有助于降低低功耗节点功耗的操作。
Friend节点为低功耗节点维护一个Friend队列,该队列存储所有发送给低功耗节点的消息。当低功耗节点请求时,Friend节点将消息发送给低功耗节点。同时,Friend节点向低功耗节点提供安全更新。
当一个低功耗节点和一个Friend节点建立友谊时,这两个节点被认为是"朋友"。一个Friend节点可能是多个低功耗节点的朋友。低功耗节点只能与单个Friend节点为好友。
3.10 功能(Features)
节点的功能性由其支持的特征决定。所有节点都具有发送和接收Mesh消息的能力。节点还可以选择支持一个或多个额外的特征:
中继功能:在广播承载者上接收和转发网状消息的能力,以实现更大的网络。
代理功能:在GATT和广播承载者之间接收和转发网状消息的能力。
低功耗功能:仅与支持Friend功能的节点一起在接收方占空比显著降低的mesh网络中操作。
Friend功能:通过存储针对这些节点的消息来帮助支持具有低功耗功能的节点操作。
支持某个功能的节点可能启用或禁用该功能,而该功能在启用时可能正在使用,也可能不在使用。
支持Relay特性的节点可能会禁用该特性,但它仍然会支持Relay特性,只是它没有执行该特性所要求的功能。支持Relay特性并启用Relay特性的节点称为Relay节点。
支持Proxy功能的节点可能会禁用该功能,但它仍然会支持Proxy功能,只是它没有执行该功能所要求的功能。支持Proxy特征并启用Proxy特征的节点称为Proxy节点。
一个支持低功耗特性的节点不能禁用该特性,必须与另一个支持Friend特性的节点建立友谊,才能使用低功耗特性来减少接收占空比。一个支持低功耗特性且与支持Friend特性的节点有好友关系的节点称为低功耗节点。
支持Friend特性的节点可能会禁用该特性,但它仍然会支持Friend特性,只是它没有执行该特性所要求的功能。一个支持Friend特性、启用了Friend特性以及与一个支持Low Power特性的节点有好友关系的节点称为Friend节点。
3.11 拓扑(Topology)
支持上述各种特征的节点可以形成mesh网络。

4 Mesh网关
Mesh网关是能够在Mesh网络和非蓝牙技术之间转换消息的节点。节点可以通过Mesh网关发送和接收Mesh消息。
5 并发限制和约束
规范对节点没有并发限制或约束。
相关文章:
蓝牙Mesh学习笔记(一)
Mesh系统结构1 Mesh网络分层1.1 模型层(Model layer)1.2 基础模型层(Foundation Model layer)1.3 接入层(Access layer)1.4 上层传输层(Upper transport layer)1.5 下层传输层(Lower transport layer)1.6 网络层(Network layer)1.7 承载层(Bearer layer)1.8 BLE内核规范(BLE Co…...
【1234. 替换子串得到平衡字符串】
来源:力扣(LeetCode) 描述: 有一个只含有 Q, W, E, R 四种字符,且长度为 n 的字符串。 假如在该字符串中,这四个字符都恰好出现 n/4 次,那么它就是一个「平衡字符串」。 给你一个这样的字符…...
独自开:提供创业机会、享受平台分红、推出新颖赚钱副业
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 前言 独自开:一款聚焦软件定制开发,独立、自主、开放平台 独创分层标准化平台架构,满足系统不断生长的个性化需求多端一键部署前端业务交互与展…...
C++【二叉树进阶(二叉搜索树)】
文章目录前言1、二叉搜索树1-1、 二叉搜索树概念2、二叉搜索树操作2-1、树和节点的基本框架2-2、二叉搜索树的查找2-3、中序遍历2-4、二叉搜索树的插入2-5、二叉搜索树的删除3、二叉搜索树的模拟实现3-1、循环版本3-2、递归版本4、二叉搜索树的应用4-1、K模型4-2、KV模型4-3、K…...
【C++初阶】vector的使用
大家好我是沐曦希💕 文章目录一.vector介绍二、构造函数三、遍历1.[]2.迭代器3.范围for四、容量操作1.扩容机制五、增删查改六、迭代器失效问题一.vector介绍 vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。…...
OPenPCDet windows流程及其问题
首先的首先极其不推荐将OPenPCDet运行在Windows上,过程非常复杂,适配也不是很好,不推荐在windows下载并训练,本人做这个主要是方便再笔记本电脑上对实验结果进行整理,处理一些简单的推理评估等任务。如有必要请继续阅读: 以下是正文: 常规的安装流程不再赘述,请参考官方…...
【自学Python】Python字符大小写判断
大纲 Python字符串是否是小写 Python字符串是否是小写教程 在开发过程中,有时候我们需要判断一个 字符串 是否是小写形式(即,所有的字符都是小写字母,不是英文字符的忽略不做判断),在 Python 中ÿ…...
设计模式之美总结(开源实战篇)
title: 设计模式之美总结(开源实战篇) date: 2023-01-10 17:13:05 tags: 设计模式 categories:设计模式 cover: https://cover.png feature: false 文章目录1. Java JDK 应用到的设计模式1.1 工厂模式在 Calendar 类中的应用1.2 建造者模式在 Calendar …...
两个月,测试转岗产品经理,我是怎么规划的?
本期同学依旧来自深圳 测试到产品转变,用了两个月 本周,为大家介绍M同学的佛系转岗经历 学员档 学员档案 原岗位:测试 转岗级别:中级产品经理 转岗特点: 1.未接触产品工作 2.对岗位地点要求严格 先看结果 …...
三数之和-力扣15-java排序+双指针
一、题目描述给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。…...
【编程基础之Python】3、创建Python虚拟环境
【编程基础之Python】3、创建Python虚拟环境创建Python虚拟环境为什么需要虚拟环境Windows上的Anaconda创建虚拟环境conda 命令conda env 命令创建虚拟环境切换虚拟环境验证虚拟环境Linux上的Anaconda创建虚拟环境创建虚拟环境切换虚拟环境验证虚拟环境总结创建Python虚拟环境 …...
kettle开发-Day36-循环驱动作业
前言:在日常数据处理时,我们通过变量传参来完成某个日期的数据转换。但可能因程序或者网络原因导致某个时间段的数据抽取失败。常见导致kettle作业失败的原因大概分为三大类,数据源异常、数据库异常、程序异常。因此面对这些异常时࿰…...
2023秋招 新凯来 算法工程师 面经分享
本专栏分享 计算机小伙伴秋招春招找工作的面试经验和面试的详情知识点 专栏首页:秋招算法类面经分享 主要分享计算机算法类在面试互联网公司时候一些真实的经验 一面 技术面 30分钟左右 1.主要是问项目和论文上的东西,问的不深,中间还介绍他们是做缺陷检测的,大概问了16分钟…...
Web3CN|Damus刷频背后,大众在期待什么样的去中心化社交?
刚过去的一周,许多人的朋友圈包括Twitter、Faceboo在内都在被一串公钥字母刷屏,其重要起因就是 Twitter 前首席执行官 Jack Dorsey 发推称,(2月1日)基于去中心化社交协议 Nostr 的社交产品 Damus 和 Amethyst 已分别在…...
Jenkins自动发布到WindowsServer,在WindowsServer执行的命令
echo off set apppoolname"6.usegitee" set websitename"6.usegitee" set webfolder"usegitee" echo 停止站点的应用程序池 C:\Windows\System32\inetsrv\appcmd.exe stop apppool %apppoolname% echo 停止站点 c:\Windows\System32\inetsrv\a…...
【Git学习】Git如何Clone带有Submodule的仓库?
文章目录一、问题描述二、解决问题三、参考链接四、解决问题4.1 下载主模块4.2 查看主模块的配置4.2 子模块的添加4.3 查看子模块的配置4.4 查看子模块的检出状态4.5 检出submodule4.6 再次查看.git/config4.7 重新打开Android Studio运行代码一、问题描述 在GitHub上下载了一…...
C语言进阶——通讯录模拟实现
🌇个人主页:_麦麦_ 📚今日名言:只有走在路上,才能摆脱局限,摆脱执着,让所有的选择,探寻,猜测,想象都生机勃勃。——余秋雨《文化苦旅》 目录 一、前言 二、正…...
【C#基础】C# 变量和常量的使用
序号系列文章1【C#基础】C# 程序通用结构总结2【C#基础】C# 程序基础语法解析3【C#基础】C# 数据类型总结文章目录前言一. 变量(variable)1,变量定义及初始化2,变量的类别3,接收输出变量二. 常量(constant&…...
nvm安装后出现‘node‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件
出现这个问题多半是path地址不对。 打开系统环境变量。看看path里面有没有?没有的话,加上就行! 我的报错原因就是因为path里没有自动加上nvm的相关路径。 注意项: 1,在安装nvm之前,提前要把本机以前安装…...
张驰咨询:关于六西格玛,有一些常见的疑惑!
很多想要学习六西格玛的学员,经常会有这些困惑: 以前没有接触过六西格玛,需要什么基础吗?自学还是培训?哪些行业会用到六西格玛呢?学习六西格玛对以后的工作有哪些帮助?如何选择六西格玛培…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
