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

树状数组简单介绍

树状数组简单介绍

  • 前言
  • 树状数组(Binary Indexed Tree)JavaScript 详细指南
    • 一、什么是树状数组?
    • 二、核心概念(前置知识):lowbit 函数
    • 三、树状数组的实现
      • 1. 初始化树状数组
      • 2. 使用示例
    • 四、详细原理解释
      • 1. 树状数组结构
      • 2. 更新操作流程
      • 3. 查询操作流程
    • 五、实际应用场景
      • 1. 计算逆序对
      • 2. 区间更新与单点查询(差分数组)
    • 六、与线段树的比较
    • 七、常见问题解答
    • 八、完整示例:动态排名系统


前言

树状数组简单介绍


树状数组(Binary Indexed Tree)JavaScript 详细指南

树状数组(也称为 Binary Indexed Tree 或 Fenwick Tree)是一种高效处理动态前缀和查询与更新的数据结构。
对于新手来说,理解它可能有些挑战,但我会用 JavaScript 示例和详细解释带你逐步掌握它。

补充:博主是看了b站这个视频理解树状数组的
链接: 【树状数组,就是这么简单!】

一、什么是树状数组?

树状数组是一种可以高效进行以下两种操作的数据结构:

  1. 单点更新:给数组中的某个元素加上一个值(时间复杂度 O(log n))
  2. 前缀查询:查询数组前 n 个元素的和(时间复杂度 O(log n))

相比普通数组:

  • 普通数组:单点更新 O(1),前缀查询 O(n)
  • 前缀和数组:单点更新 O(n),前缀查询 O(1)
  • 树状数组:两者都是 O(log n),在频繁更新和查询的场景下非常高效

二、核心概念(前置知识):lowbit 函数

树状数组的核心是一个神奇的 lowbit 函数,它获取数字二进制表示中最低位的 1 所代表的值。

function lowbit(x) {return x & -x;
}

例如:

  • lowbit(6) = 2,因为 6 的二进制是 110,最低位的 1 代表 2
  • lowbit(8) = 8,因为 8 的二进制是 1000
  • lowbit(7) = 1,因为 7 的二进制是 111

三、树状数组的实现

1. 初始化树状数组

无注释版

class FenwickTree {constructor(size) {this.size = size;this.tree = new Array(size + 1).fill(0); // 树状数组下标从1开始}// 更新操作:给位置i的元素加上deltaupdate(i, delta) {while (i <= this.size) {this.tree[i] += delta;i += lowbit(i); // 向上更新父节点}}// 查询操作:求前i个元素的和query(i) {let sum = 0;while (i > 0) {sum += this.tree[i];i -= lowbit(i); // 向左查询前驱节点}return sum;}// 区间查询:[i, j]的和rangeQuery(i, j) {return this.query(j) - this.query(i - 1);}
}

带注释版:

// 树状数组的核心是一个神奇的 `lowbit` 函数,它获取数字二进制表示中最低位的 1 所代表的值。
function lowBit(i) {return (-i) & i
}// 树状数组类class fenwickTree {// 构造函数constructor(size) {// 方便记忆,原数组记为  a[1, 2, 3……]this.size = size // 原数组的长度 this.tree = new Array(size + 1).fill(0) // 树状数组的下标从1开始!!!,并且全初始化为0}// lowBit函数 获取数字二进制表示中最低位的 1 所代表的值lowBit(i) {return (-i) & i}// 点更新  在树状数组的当前元素以及后继(也称 祖宗)上 添加新值// locate: 在树的哪个索引  num:要添加的数值update(locate, num) {// 写法一:for(locate; locate <= this.size; locate += lowBit(locate)) this.tree[locate] += num// 写法二:// while(locate <= this.size) {//   this.tree[locate] += num//   locate += lowBit(locate)// }}// 区间求和(前缀和)// n:原数组前n项的和,复杂度为  O(log n)    一般方法求和为O(n)getSum(n) {// 求前缀和:定义一个 sum 存放求和后的总值,每次都加上 tree[n]以及所有前驱的值let sum = 0// 写法一:for(n; n > 0; n -= lowBit(n)) sum += this.tree[n]// 写法二:// while(n > 0) {//   sum += this.tree[n]//   n -= lowBit(n)// }return sum}// JS居然不支持重载函数!!!getBlockSum(start, end) {return this.getSum(end) - this.getSum(start - 1)}
}const arr = [1, 2, 3, 4, 5]
const fenwick = new fenwickTree(arr.length) // 创建一个树状数组实例for(let i = 0; i < arr.length; i++) fenwick.update(i + 1, arr[i]) // 更新树状数组console.log(fenwick.getSum(5)) // 15
console.log(fenwick.getBlockSum(3, 5)) // 3 + 4 + 5 = 12

2. 使用示例

// 原始数组
const nums = [1, 3, 5, 7, 9, 11]; // 下标从0开始// 初始化树状数组
const fenwick = new FenwickTree(nums.length);// 构建树状数组
for (let i = 0; i < nums.length; i++) {fenwick.update(i + 1, nums[i]); // 注意树状数组下标从1开始
}console.log(fenwick.query(3)); // 前3个元素的和:1 + 3 + 5 = 9
console.log(fenwick.rangeQuery(2, 4)); // 第2到第4个元素的和:3 + 5 + 7 = 15// 更新第3个元素(原始数组的索引2)加2
fenwick.update(3, 2); // 5 → 7console.log(fenwick.query(3)); // 现在前3个元素的和:1 + 3 + 7 = 11

四、详细原理解释

1. 树状数组结构

树状数组的每个节点存储的是一段区间的和:

  • tree[1] = nums[0]
  • tree[2] = nums[0] + nums[1]
  • tree[3] = nums[2]
  • tree[4] = nums[0] + nums[1] + nums[2] + nums[3]
  • 以此类推

2. 更新操作流程

当更新 nums[i] 时,需要更新所有包含它的区间:(即更新 所有后继tree[i]的直接后继为tree[i + lowbit(i)

  1. i+1 开始(因为树状数组下标从1开始)
  2. 每次加上 lowbit(i),直到超过数组长度
  3. 沿途所有节点都加上变化值

例如更新 nums[2](即第3个元素):

  • 更新 tree[3]
  • 3 + lowbit(3)=4 → 更新 tree[4]
  • 4 + lowbit(4)=8 → 如果数组长度≥8则更新 tree[8]

3. 查询操作流程

查询前 i 个元素的和:(即每次要加上 所有前驱tree[i]的直接前驱为tree[i - lowbit(i)]

  1. i 开始
  2. 每次减去 lowbit(i),直到为0
  3. 累加沿途所有节点的值

例如查询前5个元素的和:

  • 加上 tree[5]
  • 5 - lowbit(5)=4 → 加上 tree[4]
  • 4 - lowbit(4)=0 → 结束
  • 总和 = tree[5] + tree[4]

五、实际应用场景

1. 计算逆序对

function countInversions(nums) {// 离散化处理const sorted = [...new Set(nums)].sort((a, b) => a - b);const rank = new Map(sorted.map((num, idx) => [num, idx + 1]));const fenwick = new FenwickTree(sorted.length);let inversions = 0;// 从后向前遍历for (let i = nums.length - 1; i >= 0; i--) {const r = rank.get(nums[i]);inversions += fenwick.query(r - 1); // 查询比当前数小的数的个数fenwick.update(r, 1); // 当前数出现次数+1}return inversions;
}console.log(countInversions([5, 3, 2, 4, 1])); // 输出逆序对数量

2. 区间更新与单点查询(差分数组)

class FenwickTreeRangeUpdate {constructor(size) {this.size = size;this.tree1 = new Array(size + 1).fill(0); // 维护差分数组this.tree2 = new Array(size + 1).fill(0); // 维护i*差分数组}// 区间[l,r]加上valrangeUpdate(l, r, val) {this._update(l, val);this._update(r + 1, -val);}_update(i, val) {const v1 = val;const v2 = i * val;while (i <= this.size) {this.tree1[i] += v1;this.tree2[i] += v2;i += lowbit(i);}}// 查询前i个元素的和query(i) {let sum = 0;let x = i;while (i > 0) {sum += (x + 1) * this.tree1[i] - this.tree2[i];i -= lowbit(i);}return sum;}// 单点查询get(i) {return this.query(i) - this.query(i - 1);}
}

六、与线段树的比较

特性树状数组线段树
代码复杂度简单复杂
时间复杂度两者相同两者相同
功能主要处理前缀和可以处理各种区间操作
空间O(n)O(4n)
适用场景前缀和、逆序对区间最值、复杂区间操作

七、常见问题解答

Q: 为什么树状数组下标从1开始?
A: 因为 lowbit(0) = 0 会导致无限循环,从1开始更方便计算

Q: 树状数组能处理最大值/最小值吗?
A: 可以但不推荐,实现复杂且效率不如线段树,建议用线段树处理最值问题

Q: 如何选择树状数组和线段树?
A: 如果只需要前缀和/单点更新,用树状数组;需要更复杂的区间操作,用线段树

八、完整示例:动态排名系统

class DynamicRanking {constructor(maxValue) {this.maxValue = maxValue;this.ft = new FenwickTree(maxValue);}// 插入一个数insert(num) {this.ft.update(num, 1);}// 删除一个数remove(num) {this.ft.update(num, -1);}// 查询小于num的数的个数rank(num) {return this.ft.query(num - 1);}// 查询第k小的数(k从1开始)select(k) {let left = 1, right = this.maxValue;while (left < right) {const mid = Math.floor((left + right) / 2);if (this.ft.query(mid) < k) {left = mid + 1;} else {right = mid;}}return left;}
}const dr = new DynamicRanking(100);
dr.insert(5);
dr.insert(3);
dr.insert(8);
dr.insert(3);
console.log(dr.rank(5)); // 输出2(有两个数小于5)
console.log(dr.select(2)); // 输出3(第2小的数是3)

通过这个指南,你应该已经掌握了树状数组的基本概念、实现方法和实际应用。记住,理解 lowbit 函数是关键,而多练习实际编码会帮助你更好地掌握这种数据结构。

相关文章:

树状数组简单介绍

树状数组简单介绍 前言树状数组&#xff08;Binary Indexed Tree&#xff09;JavaScript 详细指南一、什么是树状数组&#xff1f;二、核心概念&#xff08;前置知识&#xff09;&#xff1a;lowbit 函数三、树状数组的实现1. 初始化树状数组2. 使用示例 四、详细原理解释1. 树…...

使用Redis实现分布式限流

一、限流场景与算法选择 1.1 为什么需要分布式限流 在高并发系统中&#xff0c;API接口的突发流量可能导致服务雪崩。传统的单机限流方案在分布式环境下存在局限&#xff0c;需要借助Redis等中间件实现集群级流量控制。 1.2 令牌桶算法优势 允许突发流量&#xff1a;稳定速…...

【MySQL学习】存储过程

目录 一、定义 二、基本语法 1.创建存储过程 2.删除存储过程 3.查看存储过程 三、控制语句 1.变量声明与赋值 四、游标&#xff08;Cursor&#xff09; &#xff08;1&#xff09;声明游标 &#xff08;2&#xff09;处理游标结束 &#xff08;3&#xff09;打开游标 …...

Bp靶场 - Jwt

你知道JWT漏洞如何进行攻击利用吗&#xff1f;快来看一看如何利用JWT漏洞进行攻击利用把&#xff01;https://mp.weixin.qq.com/s/2iBIEGnkiliprsuHyY5Udg...

手机上的APN是什么,该怎么设置

网上说改个APN就可以让网速快几倍&#xff0c;那到底APN是个什么东西&#xff0c;真的能让网速快几倍吗&#xff1f; APN的作用 网络连接基础&#xff1a;APN&#xff08;接入点名称&#xff09;是手机连接移动网络的“桥梁”&#xff0c;负责识别运营商网络类型&#xff08;…...

[bug]langchain agent报错Invalid Format: Missing ‘Action Input:‘ after ‘Action:‘

在学习langchain的agent时候&#xff0c;采用ollama调用本地的deepseek-r1:32b来做一个agent&#xff0c;代码如下&#xff1a; def create_custom_agent():llm ChatOllama(model"deepseek-r1:32b", temperature0.5)memory ConversationBufferWindowMemory(memory…...

blender关联复制与Three.js网格和材质共享验证

blender和three.js小白的学习之路。 最近看到Three.js官网上说&#xff0c;模型合并是一个很好的优化性能的方式&#xff0c;因为渲染2000个物体总要比一次性渲染一个模型要来的慢。很有道理&#xff01; 但此时就不禁思考一个问题&#xff0c;现有的模型进行合并通过blender…...

Spark宽窄依赖与Join优化:协同划分与非协同划分的底层逻辑

在大数据领域&#xff0c;Spark的性能优化始终是开发者关注的焦点。理解宽依赖&#xff08;Wide Dependency&#xff09;和窄依赖&#xff08;Narrow Dependency&#xff09;的底层原理&#xff0c;能够帮助我们从根本上优化Join操作的性能。本文将通过这两个核心概念&#xff…...

每日算法-250416

今天我们来探讨两道可以通过贪心算法解决的 LeetCode 题目。 什么是贪心算法&#xff1f; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最…...

python爬虫降低IP封禁,python爬虫除了使用代理IP和降低请求频率,还有哪些方法可以应对IP封禁?

文章目录 前言1. 利用 CDN 节点2. 模拟真实用户行为3. 使用 IP 池轮换策略4. 处理 Cookie 和会话信息5. 分布式爬虫 前言 除了使用代理 IP 和降低请求频率&#xff0c;以下这些方法也能应对 IP 封禁&#xff1a; Python 3.13.2安装教程&#xff08;附安装包&#xff09;Python…...

NLP高频面试题(四十五)——PPO 算法在 RLHF 中的原理与实现详解

近端策略优化(Proximal Policy Optimization, PPO)算法是强化学习领域的一种新颖且高效的策略优化方法,在近年大规模语言模型的人类反馈强化学习(Reinforcement Learning with Human Feedback, RLHF)中发挥了关键作用。本文将以学术严谨的风格,详细阐述 PPO 算法的原理及…...

bert项目解析

读取csv def read_file(file_path):data []label []with open(file_path, "r", encoding"utf-8") as file:reader csv.reader(file)next(reader) # 跳过标题行for row in reader:if len(row) < 2:print(f"跳过不完整行: {row}")continue…...

ubuntu20.04 Android14编译环境配置

ubuntu 更新和必要安装 sudo apt update sudo apt install git sudo apt install python2-minimal sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2 sudo upda…...

lombok requires enabled annotation processing

这个错误信息表明你在使用 Lombok 时&#xff0c;编译器无法正常工作&#xff0c;因为 注解处理器&#xff08;Annotation Processing&#xff09; 没有被启用。Lombok 是一个 Java 库&#xff0c;它通过注解处理器在编译时自动生成代码&#xff08;例如 Getter、Setter、NoArg…...

应用系统中的报表开发成本知多少?

应用系统的开发过程中&#xff0c;报表的业务虽然不算太难&#xff0c;但投入的开发成本可不一定小&#xff0c;因为总会有没完没了的报表要去做&#xff0c;成本的投入不容小觑 下面我们就来分析一下报表开发成本的构成&#xff0c;看看它是多是少 报表的开发成本&#xff0c…...

STM32F103ZET6移植FATFS文件系统教程(W25Q32)

一、FATFS核心特性 跨平台支持‌ 支持FAT12/FAT16/FAT32格式&#xff0c;兼容Windows文件系统‌&#xff1b; 采用标准C语言编写&#xff0c;代码量小且支持RTOS‌。 配置灵活性‌ 通过宏定义实现功能裁剪&#xff0c;例如&#xff1a; FF_FS_READONLY&#xff1a;设为1时禁…...

数据泄露防护系统:全面保护企业信息安全的功能解析

随着信息技术的快速发展&#xff0c;数据泄露事件频发&#xff0c;给企业带来了巨大的经济损失和声誉损害。为了有效应对这一挑战&#xff0c;越来越多的企业开始部署专业的数据泄露防护&#xff08;DLP&#xff09;系统。安固软件作为一款领先的数据防泄漏解决方案&#xff0c…...

【野火模型】利用深度神经网络替代 ELMv1 野火参数化:机制、实现与性能评估

目录 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09;关键机制野火模拟的核心过程 二、采用神经网络模拟野火过程三、总结参考 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09; ELMv1 中的野火模型&#xff08;称为 BASE-Fire&#xff09;源自 Commun…...

【WPF】 在WebView2使用echart显示数据

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、NuGet安装WebView2二、代码部分1.xaml中引入webview22.编写html3.在WebView2中加载html4.调用js方法为Echarts赋值 总结 前言 为了实现数据的三维效果&…...

java实现二叉树的前序、中序、后序遍历(递归和非递归方式)以及层级遍历

java实现二叉树的前序、中序、后序遍历以及层级遍历 一、二叉树节点定义二、递归方式1.前序遍历2.中序遍历3.后序遍历 三、非递归方式1.前序遍历2.中序遍历3.后序遍历4.层级遍历5.分层打印 四、测试用例 一、二叉树节点定义 class TreeNode {int val;TreeNode left;TreeNode r…...

学习笔记十三—— 理解 Rust 闭包:从语法到 impl Fn vs Box<dyn Fn>

&#x1f9e0; 理解 Rust 闭包&#xff1a;从语法到 impl Fn vs Box &#x1f4da; 目录 闭包是什么&#xff1f;和普通函数有什么不同&#xff1f;闭包的语法长什么样&#xff1f;闭包“捕获变量”是什么意思&#xff1f;闭包和所有权的关系Fn、FnMut、FnOnce 三种闭包类型的…...

Linux虚拟机filezilla总是连不上

刚好有两个虚拟机&#xff0c;测试了一下问题所在 从第一个到第二个需要设置什么 image PNG 68.59KB image PNG 134.39KB ChatGLM 从第一个到第二个需要设置开启ssh服务&#xff0c;具体步骤如下&#xff1a; 输入以下命令来启动SSH服务&#xff1a; bash 复制 sud…...

NO.94十六届蓝桥杯备战|图论基础-单源最短路|常规dijkstra|堆优化dijkstra|bellman-ford|spfa(C++)

在图G中&#xff0c;假设 v i v_{i} vi​和 v j v_{j} vj​为图中的两个顶点&#xff0c;那么 v i v_{i} vi​到 v j v_{j} vj​路径上所经过边的权值之和就称为带权路径⻓度。 由于 v i v_{i} vi​到 v j v_{j} vj​的路径可能有多条&#xff0c;将带权路径⻓度最短的那条路径…...

DISCO:利用大型语言模型提取反事实

DISCO: Distilling Counterfactuals with Large Language Models - ACL Anthologyhttps://aclanthology.org/2023.acl-long.302/ 1. 概述 尽管在自然语言处理(NLP)领域针对各种推理任务取得了巨大进展(Wang 等, 2018, 2019a;Xu 等, 2020),但数据集偏差仍然是构建鲁棒模型…...

若依微服务版启动小程序后端

目录标题 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件...

C语言 - 深拷贝与浅拷贝详解

深拷贝与浅拷贝详解 在 C 语言编程中&#xff0c;处理指针和动态内存是常见任务。在涉及数据拷贝操作时&#xff0c;我们经常会听到“深拷贝”和“浅拷贝”这两个术语。理解它们之间的区别对于避免程序中的内存错误和数据覆盖问题至关重要。 本文将全面讲解 C 语言中的深拷贝与…...

Serverless集群搭建:Knative

文章目录 Knative搭建1.准备工作安装Kubernetes安装 Istio 2.部署Knative Knative搭建 搭建流程图&#xff1a; 1.准备工作 准备工作 ● 本安装操作中的步骤 bash 适用于 MacOS 或 Linux 环境。对于 Windows&#xff0c;某些命令可能需要调整。 ● 本安装操作假定您具有现有…...

今日行情明日机会——20250416

指数在区间震荡&#xff0c;还需要等突破下跌趋势企稳 2025年4月16日涨停的主要行业方向分析 1. 外贸&#xff08;9家涨停&#xff09; 细分领域&#xff1a;跨境物流、纺织出口、供应链服务。代表个股&#xff1a; 五板&#xff1a;泰慕士&#xff08;纺织服装出口龙头&…...

STM32基础教程——DMA

目录 前言 ​编辑 技术实现 接线图 代码实现 技术要点 DMA时钟 DMA初始化 DMA数据传输设置 数据改变与显示 实验结果 问题记录 前言 DMA(Direct Memory Access)直接存储器存取&#xff0c;用来提供在外设和存储器 之间或者存储器和存储器之间的高速数据传输。无需…...

Node.js 中文件系统模块(`fs`)的详细总结,包括定义、作用、各种写入方式及使用场景

Node.js 中文件系统模块&#xff08;fs&#xff09;的详细总结&#xff0c;包括定义、作用、各种写入方式及使用场景&#xff1a; &#x1f9e9; 一、fs 模块简介 ✅ 定义 fs&#xff08;File System&#xff09;是 Node.js 官方内置模块&#xff0c;用于实现对文件和目录的操…...

MyBatis与MyBatis-Plus:字段自动填充的两种实现方式

目录 1. 使用 MyBatis 拦截器实现字段自动填充 2. 使用 MyBatis-Plus 实现字段自动填充 1. 使用 MyBatis 拦截器实现字段自动填充 实现步骤 创建拦截器 实现 MyBatis 的 Interceptor 接口&#xff0c;通过拦截 MyBatis 执行的 SQL 操作来自动填充公共字段 Intercepts({Signa…...

比特率、码元速率(波特率)的定义、关系及相关计算公式

一、相关定义 &#xff08;一&#xff09;比特率 比特率&#xff08;Bit Rate&#xff09;&#xff1a;单位时间内传输的二进制比特数&#xff0c;是信息传输速率的度量。单位&#xff1a;比特每秒&#xff08;bit/s&#xff0c;bps&#xff09;。公式&#xff1a;比特率 传…...

炫云平台全面支持Blender4.4云渲染

随着世界渲染大赛众多优秀作品被大家关注&#xff0c;Blender作为建模渲染一体化的软件&#xff0c;也是众多3D艺术家最常用的软件之一。云渲染自然是提升创作效率必不可少的工作。这篇文章说一下炫云云渲染平台近期对Blender云渲染支持的情况。 首先&#xff0c;炫云客户端已经…...

Python自学第1天:变量,打印,类型转化

突然想学Python了。经过Deepseek的推荐&#xff0c;下载了一个Python3.12安装。安装过程请自行搜索。 乖乖从最基础的学起来&#xff0c;废话不说了&#xff0c;上链接&#xff0c;呃&#xff0c;打错了&#xff0c;上知识点。 变量的定义 # 定义一个整数类型的变量 age 10#…...

Flutter 从零到一

iOS 调试与开发工具指南 真机调试 Xcode run 在控制台获取 Dart VM service URIVSCode 点击 Cmd Shift P 选择 Debug: Attach to Flutter on Device粘贴 the URI 后点击 Enter 对于iOS开发者来说&#xff0c;使用appuploader这样的iOS开发助手可以简化真机调试的准备工作。…...

ocr-身份证正反面识别

在阿里云官网&#xff0c;申请一个token [阿里官方]身份证OCR文字识别_API专区_云市场-阿里云 (aliyun.com) 观察一下post请求body部分json字符串&#xff0c;我们根据这个创建一个java对象 先默认是人像面 public class IdentityBody {public String image;class configure…...

深入解析Spring Boot核心组件及其关键功能

【版本&#xff1a;spring-boot-2.1.3.RELEASE】 深入Spring Boot核心组件 Spring Boot是一个流行的框架&#xff0c;简化了基于Spring的应用程序的开发和部署。它通过自动配置和“开箱即用”的特性&#xff0c;使得开发者可以快速启动和运行应用程序。在Spring Boot中&#x…...

JVM 调优不再难:AI 工具自动生成内存优化方案

在 Java 应用程序的开发与运行过程中&#xff0c;Java 虚拟机&#xff08;JVM&#xff09;的性能调优一直是一项极具挑战性的任务&#xff0c;尤其是内存优化方面。不合适的 JVM 内存配置可能会导致应用程序出现性能瓶颈&#xff0c;甚至频繁抛出内存溢出异常&#xff0c;影响业…...

分层式设备控制架构、分布式微服务架构及插件化架构

在现代高端装备制造&#xff08;如半导体设备、精密自动化系统&#xff09;中&#xff0c;分层式设备控制架构、分布式微服务架构和插件化架构是提升系统灵活性、实时性和可扩展性的核心技术。以下从设计原理、实现方式及行业应用三个维度展开说明&#xff1a; &#xfffc; 1.…...

上门服务 APP 30 亿营收商业模式在乌干达的技术赋能与实践

不久前&#xff0c;非洲乌干达出现黑人女技师提供上门足疗服务的消息引发关注。据了解&#xff0c;当地一次40分钟的上门按摩服务仅需约40元人民币&#xff0c;价格仅为国内同类服务的十分之一。这一现象折射出全球健康服务行业正在经历的数字化转型浪潮。 国内领先的上门服务平…...

Chemical Review IF=51.4 综述 | 柔性机器人的当下与未来:材料、技术与应用的深度融合

2025.03.31. 新加坡南洋理工大学研究团队在《Chemical Reviews》期刊上发表 “Soft Materials and Devices Enabling Sensorimotor Functions in Soft Robots” 综述型文章。软机器人的传感器运动功能对其与环境交互至关重要&#xff0c;本文全面综述了相关软材料和设备。传感技…...

Python抽象基类

abstractmethod 详解 abstractmethod 是 Python 中 abc 模块&#xff08;Abstract Base Classes&#xff0c;抽象基类&#xff09;提供的一个装饰器&#xff0c;用于定义抽象方法。抽象方法是一种在基类中声明但不实现具体逻辑的方法&#xff0c;强制子类必须实现该方法。以下…...

计算机网络中各种物理量的单位总结

在计算机网络中&#xff0c;数据速率的单位容易混淆&#xff0c;以下是清晰总结&#xff1a; 一、基本单位区分 比特&#xff08;bit&#xff09;与字节&#xff08;Byte&#xff09; 小写 b 表示 比特&#xff08;bit&#xff09;&#xff0c;是数据传输的基本单位。 大写 B…...

PCIE网卡驱动DMA初始化配置

1. DMA 启用的时机 e1000e 驱动在 设备初始化阶段 启用 DMA&#xff0c;具体步骤如下&#xff1a; (1) PCIe 设备初始化 调用路径&#xff1a; e1000_probe() → e1000_sw_init() → e1000_init_hw() → e1000_configure() 关键操作&#xff1a; 启用 PCIe 设备的 DMA 主控模…...

音视频小白系统入门笔记-1

本系列笔记为博主学习李超老师课程的课堂笔记&#xff0c;仅供参阅 课程传送门&#xff1a;音视频小白系统入门课 音视频基础ffmpeg原理 往期课程笔记传送门&#xff1a;音视频小白系统入门笔记-0 课程实践代码仓库&#xff1a;传送门 音频采集 命令行采集 Android端音频…...

技术速递|使用 BrowserStack App Automate 和 Appium UI 测试 .NET MAUI 应用

作者&#xff1a;Sweeky&Gerald 排版&#xff1a;Alan Wang 本文是 Gerald 的博客《开始使用 Appium 测试 .NET MAUI 应用的 UI 》中创建的 .NET MAUI – 使用 Appium 和 NUnit 进行 UI 测试的续篇。 在本篇博客中&#xff0c;我们将了解如何使用 BrowserStack App Automa…...

在多系统环境中实现授权闭环,Tetra Pak 借助CodeMeter打造食品工业的安全自动化体系

一、 行业背景与安全新挑战 在食品加工自动化不断深化的背景下&#xff0c;食品安全、功能安全与知识产权保护的需求日益迫切。Tetra Pak 作为全球领先的食品加工和包装解决方案提供商&#xff0c;业务遍布 160 多个国家&#xff0c;涵盖从配料混合、碳酸化处理到全线自动包装。…...

Nginx+SpringBoot跨域那些事儿(多域名跨域加强版——Nginx配置详解)

嘿,小伙伴们,咱们接着上回书说到,当你的应用需要支持多个域名跨域访问时,Nginx+SpringBoot这对黄金搭档绝对是你的不二之选!今天,咱们就深入聊聊如何在Nginx中配置多个域名跨域,让你的应用更加灵活、强大! 一、跨域问题再科普(多域名跨域场景) 在前后端分离开发中,…...

基于Python的App流量大数据分析与可视化方案

一、引言 App流量数据通常包括用户的访问时间、停留时间、点击行为、页面跳转路径等信息。这些数据分散在不同的服务器日志、数据库或第三方数据平台中&#xff0c;需要通过有效的技术手段进行整合和分析。Python在数据科学领域的广泛应用&#xff0c;得益于其简洁的语法、强大…...

windows下使用nginx + waitress 部署django

架构介绍 linux一般采用nginx uwsgi部署django&#xff0c;在Windows下&#xff0c;可以取代uwsgi的选项包括Waitressa、Daphnea、Hypercoma和Gunicorna(通过WSLa 运行)。windows服务器一般采用nginx waitress 部署django&#xff0c;,他们的关系如下 django是WEB应用…...