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

【2D与3D SLAM中的扫描匹配算法全面解析】

引言

扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件,它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法,包括数学原理、实现细节以及实际应用中的性能对比,特别关注激光雷达SLAM中的典型方法。

一、扫描匹配数学基础与核心原理

1.1 刚体变换的数学表示

扫描匹配的核心是求解刚体变换,在2D和3D空间中有不同的数学表示:

2D刚体变换
由旋转矩阵R和平移向量t组成,可表示为:
T = [ cos ⁡ θ − sin ⁡ θ t x sin ⁡ θ cos ⁡ θ t y 0 0 1 ] T = \begin{bmatrix} \cos\theta & -\sin\theta & t_x \\ \sin\theta & \cos\theta & t_y \\ 0 & 0 & 1 \end{bmatrix} T= cosθsinθ0sinθcosθ0txty1
其中 θ θ θ 为旋转角度, ( t x , t y ) (t_x, t_y) (tx,ty) 为平移量。

3D刚体变换
使用齐次坐标表示:
T = [ R 3 × 3 t 3 × 1 0 1 × 3 1 ] T = \begin{bmatrix} R_{3×3} & t_{3×1} \\ 0_{1×3} & 1 \end{bmatrix} T=[R3×301×3t3×11]
其中 R ∈ S O ( 3 ) R∈SO(3) RSO(3) 为旋转矩阵, t ∈ R 3 t∈ℝ³ tR3 为平移向量。

1.2 优化问题的构建

扫描匹配本质上是非线性最小二乘问题
min ⁡ T ∑ i ρ ( ∥ T ∘ p i − q i ∥ 2 ) \min_T \sum_i \rho( \| T \circ p_i - q_i \|^2 ) Tminiρ(Tpiqi2)
其中 ρ ρ ρ 为鲁棒核函数(如Huber、Tukey),用于抑制异常值影响。

目标函数线性化
通过一阶泰勒展开近似:
e ( x + Δ x ) ≈ e ( x ) + J ( x ) Δ x e(x+\Delta x) ≈ e(x) + J(x)\Delta x e(x+Δx)e(x)+J(x)Δx
其中 J J J 为雅可比矩阵, Δ x Δx Δx 为参数增量。

二、2D扫描匹配算法原理详解

2.1 点到点ICP的数学推导

误差函数
对于单个点对 ( p i , q i ) (p_i, q_i) (pi,qi),误差为:
e i = R p i + t − q i e_i = R p_i + t - q_i ei=Rpi+tqi

雅可比矩阵计算
对2D变换参数 x = [ t x , t y , θ ] T x=[t_x, t_y, θ]^T x=[tx,ty,θ]T 求导:
J i = ∂ e i ∂ x = [ 1 0 − p i x sin ⁡ θ − p i y cos ⁡ θ 0 1 p i x cos ⁡ θ − p i y sin ⁡ θ ] J_i = \frac{\partial e_i}{\partial x} = \begin{bmatrix} 1 & 0 & -p_i^x \sin\theta - p_i^y \cos\theta \\ 0 & 1 & p_i^x \cos\theta - p_i^y \sin\theta \end{bmatrix} Ji=xei=[1001pixsinθpiycosθpixcosθpiysinθ]

高斯牛顿法更新
通过求解正规方程获得参数更新:
( J T J ) Δ x = − J T e (J^T J) \Delta x = -J^T e (JTJ)Δx=JTe

2.2 点到线ICP的几何原理

线段表示
目标扫描中的线段由两点 q 1 q₁ q1, q 2 q₂ q2 确定,其直线方程为:
( q 2 − q 1 ) × ( p − q 1 ) = 0 (q₂-q₁) \times (p - q₁) = 0 (q2q1)×(pq1)=0

距离计算
p p p 到线段的距离:
d = ∣ ( q 2 − q 1 ) × ( p − q 1 ) ∣ ∣ q 2 − q 1 ∣ d = \frac{| (q₂-q₁) \times (p-q₁) |}{| q₂-q₁ |} d=q2q1(q2q1)×(pq1)

误差函数
e i = ( q 2 − q 1 ) × ( R p i + t − q 1 ) ∣ q 2 − q 1 ∣ e_i = \frac{(q₂-q₁) \times (R p_i + t - q₁)}{| q₂-q₁ |} ei=q2q1(q2q1)×(Rpi+tq1)

雅可比矩阵
对旋转角度 θ θ θ 的导数为:
∂ e i ∂ θ = ( q 2 − q 1 ) × ( ∂ R ∂ θ p i ) ∣ q 2 − q 1 ∣ \frac{\partial e_i}{\partial \theta} = \frac{(q₂-q₁) \times ( \frac{\partial R}{\partial \theta} p_i )}{| q₂-q₁ |} θei=q2q1(q2q1)×(θRpi)

2.3 似然场法的概率解释

似然场构建

  1. 将目标扫描转换为二值栅格地图
  2. 对每个栅格计算到最近障碍物的距离 d d d
  3. 定义概率场:
    P ( p ) = exp ⁡ ( − d 2 2 σ 2 ) P(p) = \exp(-\frac{d^2}{2\sigma^2}) P(p)=exp(2σ2d2)

优化目标
最大化源扫描点在似然场中的总概率:
max ⁡ T ∏ i P ( T ∘ p i ) \max_T \prod_i P(T \circ p_i) TmaxiP(Tpi)
取负对数后转化为最小化问题:
min ⁡ T ∑ i d ( T ∘ p i ) 2 2 σ 2 \min_T \sum_i \frac{d(T \circ p_i)^2}{2\sigma^2} Tmini2σ2d(Tpi)2

三、3D扫描匹配算法

3.1 3D点到点ICP

原理延续性
3D点到点ICP是2D版本的直接扩展,核心思想完全一致:

  1. 建立点对点对应关系(最近邻搜索)
  2. 最小化对应点间的欧氏距离
  3. 通过SVD或非线性优化求解刚体变换

数学形式扩展

  • 旋转矩阵 R ∈ S O ( 3 ) R ∈ SO(3) RSO(3)(从2D的 θ θ θ 扩展为3D旋转)
  • 平移向量 t ∈ R 3 t ∈ ℝ³ tR3 z z z 方向扩展)
  • 误差函数: e i = R p i + t − q i e_i = R p_i + t - q_i ei=Rpi+tqi

关键差异

  1. 最近邻搜索复杂度

    • 2D:可用KD-tree或栅格搜索(O(n log n))
    • 3D:必须使用KD-tree/Octree(O(n log n)但常数项更大)
  2. 变换求解方法

    • 2D:可直接解析求解或高斯牛顿法

    • 3D:通常采用SVD分解(更稳定):

      W = ∑ ( p i − p ˉ ) ( q i − q ˉ ) T W = \sum (p_i - \bar{p})(q_i - \bar{q})^T W=(pipˉ)(qiqˉ)T

      U Σ V T = SVD ( W ) UΣV^T = \text{SVD}(W) UΣVT=SVD(W)

      R = V U T , t = q ˉ − R p ˉ R = V U^T, \quad t = \bar{q} - R \bar{p} R=VUT,t=qˉRpˉ

PCL实现示例

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(source_cloud);
icp.setMaxCorrespondenceDistance(0.05);  // 比2D更小的距离阈值
icp.align(output_cloud);

3.2 3D点到线ICP

原理延续性
与2D点到线ICP思想相同,但:

  • 3D中的"线"通常来自边缘特征提取
  • 距离计算使用3D空间中的点线距离公式

数学形式
给定目标扫描中的直线(方向向量 v v v,通过点 q q q ):
d = ∥ ( R p i + t − q ) × v ∥ / ∥ v ∥ d = \| (R p_i + t - q) \times v \| / \| v \| d=(Rpi+tq)×v∥/∥v

实现关键点

  1. 线特征提取

    pcl::PointCloud<pcl::PointXYZ>::Ptr edge_points(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::extractEdgePoints(source_cloud, edge_points);  // 基于曲率或PCA方法
    
  2. 误差雅可比

    J = ∂ d ∂ [ t , ω ] = v × ∥ v ∥ ⋅ [ I 3 × 3 , − [ R p i ] × ] J = \frac{\partial d}{\partial [t, \omega]} = \frac{v \times}{\|v\|} \cdot [I_{3×3}, -[R p_i]_\times] J=[t,ω]d=vv×[I3×3,[Rpi]×]

    (其中 ω ω ω 为角速度的李代数表示)

适用场景

  • 室内结构化环境(门框、桌腿等)
  • 激光SLAM中的边缘跟踪(如LOAM)

3.3 3D点到面ICP

平面表示
目标点云中的平面由点 q q q 和法向量 n n n 确定,平面方程为:
n T ( p − q ) = 0 n^T (p - q) = 0 nT(pq)=0

误差函数
e i = n j T ( R p i + t − q j ) e_i = n_j^T (R p_i + t - q_j) ei=njT(Rpi+tqj)

雅可比矩阵
对旋转部分采用李代数 s o ( 3 ) so(3) so(3) 参数化:
∂ e i ∂ ξ = − n j T [ R p i ] × \frac{\partial e_i}{\partial \xi} = -n_j^T [ R p_i ]_\times ξei=njT[Rpi]×
其中 [ ⋅ ] × [·]× []× 表示向量的叉积矩阵, ξ ∈ s o ( 3 ) ξ∈so(3) ξso(3) 为旋转的李代数表示。

3.4 NDT算法的统计原理

体素划分
将目标点云划分为体素网格,对每个体素内的点 q k {q_k} qk 计算:

  • 均值: μ = ( 1 / n ) ∑ q k μ = (1/n)∑q_k μ=(1/n)qk
  • 协方差: Σ = ( 1 / n ) ∑ ( q k − μ ) ( q k − μ ) T Σ = (1/n)∑(q_k-μ)(q_k-μ)^T Σ=(1/n)(qkμ)(qkμ)T

概率密度函数
p ( p ) = exp ⁡ ( − ( p − μ ) T Σ − 1 ( p − μ ) 2 ) p(p) = \exp \left( -\frac{(p-μ)^T Σ^{-1} (p-μ)}{2} \right) p(p)=exp(2(pμ)TΣ1(pμ))

优化目标
最大化源点云在NDT场中的总概率:
min ⁡ T ∑ i ( T p i − μ i ) T Σ i − 1 ( T p i − μ i ) \min_T \sum_i (T p_i - μ_i)^T Σ_i^{-1} (T p_i - μ_i) Tmini(Tpiμi)TΣi1(Tpiμi)

Hessian矩阵计算
NDT的高效实现依赖于精确计算Hessian矩阵:
H = J T Σ − 1 J H = J^T Σ^{-1} J H=JTΣ1J

四、PCL算法实现原理对比

4.1 点到面ICP的实现优化

PCL中的pcl::IterativeClosestPointWithNormals通过以下优化提升性能:

  1. 法线估计加速

    • 使用KD-tree近邻搜索
    • 基于PCA计算法向量
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
    ne.setInputCloud(cloud);
    ne.setSearchMethod(tree);
    ne.setKSearch(30);  // 使用30个最近邻计算法线
    
  2. 对应点筛选策略

    • 法线夹角阈值过滤
    • 距离阈值过滤

4.2 GICP的协方差传播

广义ICP(GICP)通过考虑局部几何结构提升精度:

源点协方差
Σ i s r c = R Σ i s r c , l o c a l R T Σ_i^{src} = R Σ_i^{src,local} R^T Σisrc=RΣisrc,localRT

目标点协方差
Σ i t g t = Σ i t g t , l o c a l Σ_i^{tgt} = Σ_i^{tgt,local} Σitgt=Σitgt,local

马氏距离
d i = ( T p i − q i ) T ( Σ i t g t + Σ i s r c ) − 1 ( T p i − q i ) d_i = (T p_i - q_i)^T (Σ_i^{tgt} + Σ_i^{src})^{-1} (T p_i - q_i) di=(Tpiqi)T(Σitgt+Σisrc)1(Tpiqi)

4.3 NDT的多分辨率策略

PCL中的NDT实现采用多分辨率加速:

  1. 初始使用大体素进行粗配准
  2. 逐步缩小体素尺寸提高精度
ndt.setResolution(2.0);  // 初始分辨率
ndt.setStepSize(0.1);    // 步长控制
ndt.setOulierRatio(0.55);// 异常值比例

4.4 对比总结

方法类型PCL类名优点缺点适用场景
点到点ICPpcl::IterativeClosestPoint实现简单,通用性强收敛慢,对初始位置敏感通用3D配准
点到面ICPpcl::IterativeClosestPointWithNormals收敛快,精度高需要法线计算结构化环境
GICPpcl::GeneralizedIterativeClosestPoint结合点和面信息,更鲁棒计算复杂度高复杂环境
NDTpcl::NormalDistributionsTransform对初始位置不敏感,效率高依赖网格分辨率设置大场景,自动驾驶
Feature-basedpcl::SampleConsensusInitialAlignment利用特征,全局配准依赖特征提取质量无初始猜测的情况

五、算法选择的数学依据

5.1 收敛性分析

方法收敛半径收敛速度数学特性
点到点ICP小(~1m)线性非凸,局部极值多
点到面ICP中等(~3m)超线性利用几何约束,更凸
NDT大(~10m)二次平滑概率场,全局性更好

5.2 计算复杂度比较

算法时间复杂度分析:

  • ICP类算法 O ( n m k ) O(nmk) O(nmk),其中 n n n 为源点数, m m m 为目标点数, k k k 为迭代次数
  • NDT O ( n + v ) O(n + v) O(n+v) v v v 为体素数量,预处理阶段 O ( m ) O(m) O(m)
  • 特征匹配 O ( n + m + f ) O(n + m + f) O(n+m+f) f f f 为特征匹配耗时

这部分的内容还是很重要的,我之前学得很浅,然后到后面实际应用的时候总是搞不明白扫描匹配这一步,所以还是回过头来重新学了。

相关文章:

【2D与3D SLAM中的扫描匹配算法全面解析】

引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件&#xff0c;它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法&#xff0c;包括数学原理、实现细节以及实际应用中的性能对比&#xff0c;特别关注…...

【Vue】scoped+组件通信+props校验

【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性&#xff0c; 令样式只作用于当前组件的标签 作用&#xff1a;防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...

Docker环境下安装 Elasticsearch + IK 分词器 + Pinyin插件 + Kibana(适配7.10.1)

做RAG自己打算使用esmilvus自己开发一个&#xff0c;安装时好像网上没有比较新的安装方法&#xff0c;然后找了个旧的方法对应试试&#xff1a; &#x1f680; 本文将手把手教你在 Docker 环境中部署 Elasticsearch 7.10.1 IK分词器 拼音插件 Kibana&#xff0c;适配中文搜索…...

第14节 Node.js 全局对象

JavaScript 中有一个特殊的对象&#xff0c;称为全局对象&#xff08;Global Object&#xff09;&#xff0c;它及其所有属性都可以在程序的任何地方访问&#xff0c;即全局变量。 在浏览器 JavaScript 中&#xff0c;通常 window 是全局对象&#xff0c; 而 Node.js 中的全局…...

构建Docker镜像的Dockerfile文件详解

文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...

Shell 解释器​​ bash 和 dash 区别

bash 和 dash 都是 Unix/Linux 系统中的 ​​Shell 解释器​​&#xff0c;但它们在功能、语法和性能上有显著区别。以下是它们的详细对比&#xff1a; ​​1. 基本区别​​ ​​特性​​​​bash (Bourne-Again SHell)​​​​dash (Debian Almquist SHell)​​​​来源​​G…...

从0开始学习R语言--Day17--Cox回归

Cox回归 在用医疗数据作分析时&#xff0c;最常见的是去预测某类病的患者的死亡率或预测他们的结局。但是我们得到的病人数据&#xff0c;往往会有很多的协变量&#xff0c;即使我们通过计算来减少指标对结果的影响&#xff0c;我们的数据中依然会有很多的协变量&#xff0c;且…...

ABAP设计模式之---“Tell, Don’t Ask原则”

“Tell, Don’t Ask”是一种重要的面向对象编程设计原则&#xff0c;它强调的是对象之间如何有效地交流和协作。 1. 什么是 Tell, Don’t Ask 原则&#xff1f; 这个原则的核心思想是&#xff1a; “告诉一个对象该做什么&#xff0c;而不是询问一个对象的状态再对它作出决策。…...

Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)

13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...

CentOS 7.9安装Nginx1.24.0时报 checking for LuaJIT 2.x ... not found

Nginx1.24编译时&#xff0c;报LuaJIT2.x错误&#xff0c; configuring additional modules adding module in /www/server/nginx/src/ngx_devel_kit ngx_devel_kit was configured adding module in /www/server/nginx/src/lua_nginx_module checking for LuaJIT 2.x ... not…...

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...

虚拟机网络不通的问题(这里以win10的问题为主,模式NAT)

当我们网关配置好了&#xff0c;DNS也配置好了&#xff0c;最后在虚拟机里还是无法访问百度的网址。 第一种情况&#xff1a; 我们先考虑一下&#xff0c;网关的IP是否和虚拟机编辑器里的IP一样不&#xff0c;如果不一样需要更改一下&#xff0c;因为我们访问百度需要从物理机…...

SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动

飞书文档https://x509p6c8to.feishu.cn/wiki/SKZzwIRH3i7lsckUOlzcuJsdnVf I2S简介 I2S&#xff08;Inter-Integrated Circuit Sound&#xff09;是一种用于传输数字音频数据的通信协议&#xff0c;广泛应用于音频设备中。 ESP32-S3 包含 2 个 I2S 外设&#xff0c;通过配置…...

比较数据迁移后MySQL数据库和ClickHouse数据仓库中的表

设计一个MySQL数据库和Clickhouse数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

break 语句和 continue 语句

break语句和continue语句都具有跳转作用&#xff0c;可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...

使用 uv 工具快速部署并管理 vLLM 推理环境

uv&#xff1a;现代 Python 项目管理的高效助手 uv&#xff1a;Rust 驱动的 Python 包管理新时代 在部署大语言模型&#xff08;LLM&#xff09;推理服务时&#xff0c;vLLM 是一个备受关注的方案&#xff0c;具备高吞吐、低延迟和对 OpenAI API 的良好兼容性。为了提高部署效…...

更新 Docker 容器中的某一个文件

&#x1f504; 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法&#xff0c;适用于不同场景。 ✅ 方法一&#xff1a;使用 docker cp 拷贝文件到容器中&#xff08;最简单&#xff09; &#x1f9f0; 命令格式&#xff1a; docker cp <…...

【Linux】使用1Panel 面板让服务器定时自动执行任务

服务器就是一台24小时开机的主机&#xff0c;相比自己家中不定时开关机的主机更适合完成定时任务&#xff0c;例如下载资源、备份上传&#xff0c;或者登录某个网站执行一些操作&#xff0c;只需要编写 脚本&#xff0c;然后让服务器定时来执行这个脚本就可以。 有很多方法实现…...

Python爬虫(四):PyQuery 框架

PyQuery 框架详解与对比 BeautifulSoup 第一部分&#xff1a;PyQuery 框架介绍 1. PyQuery 是什么&#xff1f; PyQuery 是一个 Python 的 HTML/XML 解析库&#xff0c;它采用了 jQuery 的语法风格&#xff0c;让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...

Excel 怎么让透视表以正常Excel表格形式显示

目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...

LINUX编译vlc

下载 VideoLAN / VLC GitLab 选择最新的发布版本 准备 sudo apt install -y xcb bison sudo apt install -y autopoint sudo apt install -y autoconf automake libtool编译ffmpeg LINUX FFMPEG编译汇总&#xff08;最简化&#xff09;_底部的附件列表中】: ffmpeg - lzip…...

初级程序员入门指南

初级程序员入门指南 在数字化浪潮中&#xff0c;编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言&#xff0c;明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 &#xff08;一&#xff09;编程语言抉择 编…...

WinUI3开发_使用mica效果

简介 Mica(云母)是Windows10/11上的一种现代化效果&#xff0c;是Windows10/11上所使用的Fluent Design(设计语言)里的一个效果&#xff0c;Windows10/11上所使用的Fluent Design皆旨在于打造一个人类、通用和真正感觉与 Windows 一样的设计。 WinUI3就是Windows10/11上的一个…...

Python爬虫(52)Scrapy-Redis分布式爬虫架构实战:IP代理池深度集成与跨地域数据采集

目录 一、引言&#xff1a;当爬虫遭遇"地域封锁"二、背景解析&#xff1a;分布式爬虫的两大技术挑战1. 传统Scrapy架构的局限性2. 地域限制的三种典型表现 三、架构设计&#xff1a;Scrapy-Redis 代理池的协同机制1. 分布式架构拓扑图2. 核心组件协同流程 四、技术实…...

MyBatis-Plus 常用条件构造方法

1.常用条件方法 方法 说明eq等于 ne不等于 <>gt大于 >ge大于等于 >lt小于 <le小于等于 <betweenBETWEEN 值1 AND 值2notBetweenNOT BETWEEN 值1 AND 值2likeLIKE %值%notLikeNOT LIKE %值%likeLeftLIKE %值likeRightLIKE 值%isNull字段 IS NULLisNotNull字段…...

华为OD机考- 简单的自动曝光/平均像素

import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...

C/Python/Go示例 | Socket Programing与RPC

Socket Programming介绍 Computer networking这个领域围绕着两台电脑或者同一台电脑内的不同进程之间的数据传输和信息交流&#xff0c;会涉及到许多有意思的话题&#xff0c;诸如怎么确保对方能收到信息&#xff0c;怎么应对数据丢失、被污染或者顺序混乱&#xff0c;怎么提高…...

Spring是如何实现无代理对象的循环依赖

无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见&#xff1a;mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中&#xff0c;两个或多个对象相互依赖&#xff0c;导致创建过程陷入死循环。以下通过一个简…...

C++ Saucer 编写Windows桌面应用

文章目录 一、背景二、Saucer 简介核心特性典型应用场景 三、生成自己的项目四、以Win32项目方式构建Win32项目禁用最大化按钮 五、总结 一、背景 使用Saucer框架&#xff0c;开发Windows桌面应用&#xff0c;把一个html页面作为GUI设计放到Saucer里&#xff0c;隐藏掉运行时弹…...

中国政务数据安全建设细化及市场需求分析

(基于新《政务数据共享条例》及相关法规) 一、引言 近年来,中国政府高度重视数字政府建设和数据要素市场化配置改革。《政务数据共享条例》(以下简称“《共享条例》”)的发布,与《中华人民共和国数据安全法》(以下简称“《数据安全法》”)、《中华人民共和国个人信息…...