学习梳理一下用于AEC的各种LMS频域实现方法以及基础知识

news2024/11/24 3:25:12

学习梳理一下用于AEC的各种LMS频域实现方法以及基础知识-未完待续

  • 起源
  • 换个维度,到频域
    • 线性卷积&循环卷积
    • 频域FIR的循环卷积等价于时域补0后的线性卷积
    • 重叠保留&重叠相加---长数据序列滤波的考量
      • 重叠保留
      • 重叠相加
  • block分块自适应探讨
  • 参考

起源

least-mean-square方法是时域的,参考ANC 与 adaptive filter推导,能够得出一个迭代更新公式: W k + 1 = W k + 2 μ e ( k ) X ( k ) \bold W_{k+1}=\bold W_k +2 \mu e(k)X(k) Wk+1=Wk+2μe(k)X(k)
回声消除最终关注的是
e ( n ) = d ( n ) − y ( n ) = d ( n ) − W T X ( n ) = d ( n ) − X T ( n ) W e(n)=d(n)-y(n)=d(n)-\bold W^T\bold X(n)=d(n)-\bold X^T(n)\bold W e(n)=d(n)y(n)=d(n)WTX(n)=d(n)XT(n)W

y ( n ) = W T X ( n ) = X T ( n ) W y(n)=\bold W^T\bold X(n)=\bold X^T(n)\bold W y(n)=WTX(n)=XT(n)W是这个滤波器的输出,抛开数学推导,这个实现范式其实简洁明了。但由于时域跟踪,每个采样点更新一次的计算量是非常巨大的,所以在上个世纪七八十年代涌现了频域lms实现的方法,目的是为了降低计算复杂度,从此,旧时王谢堂前燕,飞入寻常百姓家。人们开始慢慢的享受了无回声通话的便宜,这种情况直到AI的出现和普及。

换个维度,到频域

似乎时频变换是现代信号处理绕不过去的一个梗,我能追溯的文章是这篇Adaptive filtering in the frequency domain,这篇文章本身比较精简,唯一引申了The complex LMS algorithm,很显然后者是从数学推导的方式给了一个复数域更新lms参数以及得出误差信号的结果,并没有谈到时频变换的问题,而前者想到了如果把时域信号分块的变换到频域,采用每块更新参数的方法,将会大大减少计算量,按照文中的计算方法,1024点FFT的块更新方法,能节省的计算量非常的可观。但此文仍专注于频域自适应的拓展,即没有考虑线性、圆周卷积这个DFT之后绕不过去的问题,也没有给出滤波器长度和分块的关系,如【论文笔记之 AFiFD】Adaptive Filtering in the Frequency Domain一文的总结,“论文为实现 LMS 自适应滤波器提供了一个新的思路”,应该属于开创性的著作。90年提出的并被speex实现的Multidelay Block Frequency Domain Adaptive Filter引用了这一时期的Block implementation of adaptive digital filters和Fast implementations of LMS adaptive filters两篇论文,这两篇又大概是20世纪80年代初期的论述。两年后,92年一篇On the implementation of a partitioned block frequency domain adaptive filter (PBFDAF) for long acoustic echo cancellation引用了它,而这篇文章为webrtc第一代AEC的PBFDAF实现提供的算法基础。在继续学习之前,有必要恶补一下相关的基础知识。

线性卷积&循环卷积

这可能是要先理清的一个细节,虽然大学学过dft,工作中不断用fft来做事情,但很多特性和数学关系在这里需要重点的关注起来,线性和循环卷积来自matlab网站的介绍,让线性卷积和循环卷积变得等效,而更加简明扼要的论述可以参考Lecture 23: Circular Convolution,当然经典的数字信号处理教科书都会讲述这部分内容,但有时不用到可能就忽略了。

频域FIR的循环卷积等价于时域补0后的线性卷积

线性和循环卷积是为了解决DFT的问题而提出来的,的FIR滤波器搬到频域实现属于基本的数字信号处理问题,这个问题首先要解决的是圆周卷积产生的混叠,最好的办法是找到与线性卷积等价的策略,这个策略就是补0。假设一个长为 L L L的有限长序列 x ( n ) x(n) x(n),经过一个长度 M M M冲激响应为 h ( n ) h(n) h(n)的线性系统 ( F I R ) (FIR) (FIR),输出 y ( n ) y(n) y(n)的序列,表示如下:
y ( n ) = ∑ k = 0 M − 1 h ( k ) x ( n − k ) , x ( n ) = 0 , n < 0   o r   n ≥ L ; h ( n ) = 0 , n < 0   o r   n ≥ M y(n) = \sum_{k=0}^{M-1} h(k)x(n-k), \quad x(n)=0,n<0 \ or\ n\geq L;\quad h(n)=0,n<0 \ or\ n\geq M y(n)=k=0M1h(k)x(nk),x(n)=0,n<0 or nL;h(n)=0,n<0 or nM那么 y ( n ) y(n) y(n)的长度是 L + M − 1 L+M-1 L+M1。时域卷积等价于频域相乘(这句话背了很多遍,推导嘛。。。)我们可得:
Y ( ω ) = X ( ω ) H ( ω ) Y(\omega)= X(\omega)H(\omega) Y(ω)=X(ω)H(ω)但凡事都要细想一下,三个序列的长度不同,用 D F T DFT DFT变换得用最大值那个,即 N ≥ L + M − 1 N\ge L+M-1 NL+M1,此时针对于 L L L的有限长序列 x ( n ) x(n) x(n)和长度 M M M冲激响应为 h ( n ) h(n) h(n),后面显然需要补0,否则数据就不对了。数字信号处理――原理、算法与应用(第四版),JohnG.Proakis,DimitrisG.Manolakis著7章都实例。其中第二个例子讲述了混叠是怎么发生对的,并给出了一个结论,前 M − 1 M-1 M1个结果发生混叠污染,而正是利用这一特性,引申出了 长数据分块处理 \bold{长数据分块处理} 长数据分块处理的两个重要方法。

重叠保留&重叠相加—长数据序列滤波的考量

这里需要强调的时候,对应于时频分析类的算法,此类范式是不能够加窗的。Lecture 16 Linear Filtering with the DFT里有简单的介绍John G. Proakis 数字信号处理的离散傅里叶变换和应用章节有更加详细的论述。这里按照John G. Proakis 数字信号处理讲述的来记录分解一下两种方法的差别。

重叠保留

假设一个长长序列 x ( n ) x(n) x(n),经过一个长度 M M M冲激响应为 h ( n ) h(n) h(n)的线性系统 ( F I R ) (FIR) (FIR),输出 y ( n ) y(n) y(n)的序列,为了进行分块分析,把序列分为长度为 L L L的数据块,一般的 L > > M L>>M L>>M,那么 N = L + M − 1 N = L+M-1 N=L+M1作为FFT长度,对应第m个数据块,冲激响应补 L − 1 L-1 L1个0来凑齐,但数据块,则在前面补充上一个数据块的最后 M − 1 M-1 M1个点,完成拼接。将两个N点的DFT变换 H ( k ) {H(k)} H(k) X m ( k ) {X_m(k)} Xm(k)相乘,得出: Y ^ m ( k ) = H ( k ) X m ( k ) ; k = 0 , 1 , . . . . . , N − 1 \hat{Y}_m(k) = H(k)X_m(k);\quad k = 0,1,.....,N-1 Y^m(k)=H(k)Xm(k);k=0,1,.....,N1于是,我们通过逆变换,得出输出序列:
y ^ m ( n ) = { y ^ m ( 0 )   y ^ m ( 1 )   y ^ m ( 2 )   y ^ m ( 3 )   . . . y ^ m ( M − 1 )   y ^ m ( M )   . . . y ^ m ( N − 1 )   } \hat{y}_m(n) = \{\hat{y}_m(0)\ \hat{y}_m(1)\ \hat{y}_m(2)\ \hat{y}_m(3)\ ... \hat{y}_m(M-1)\ \hat{y}_m(M)\ ... \hat{y}_m(N-1)\ \} y^m(n)={y^m(0) y^m(1) y^m(2) y^m(3) ...y^m(M1) y^m(M) ...y^m(N1) }按照拼接原则,实际有效数据的前 M − 1 M-1 M1个数据被混叠污染了,那么剩下的 L L L个数据则被完美还原。即 y m ( n − M ) = y ^ m ( n ) , n = M , M + 1 , . . . , N − 1 {y}_m(n-M) = \hat{y}_m(n) \quad , n = M, M+1, ..., N-1 ym(nM)=y^m(n),n=M,M+1,...,N1而为了满足这种拼接方法,每一块处理前的后M-1个点被保留下来,留给下一次用,第一块前面直接补0,得到这样一个送给DFT的数据:
x 1 ( n ) = { 0 , 0 , ⋯   , 0 , ⏟ M − 1 个点 x ( 0 ) , x ( 1 ) , . . . x ( L − 1 ) } ⏟ 第一帧 L 个点 x 2 ( n ) = { x ( L − M + 1 ) , , ⋯   , x ( L − 1 ) , ⏟ 保留 x 1 最后 M − 1 个点 x ( L ) , x ( L + 1 ) , . . . x ( 2 L − 1 ) } ⏟ 第二帧 L 个点 x 3 ( n ) = { x ( 2 L − M + 1 ) , , ⋯   , x ( 2 L − 1 ) , ⏟ 保留 x 2 最后 M − 1 个点 x ( 2 L ) , x ( 2 L + 1 ) , . . . x ( 3 L − 1 ) } ⏟ 第三帧 L 个点 \begin{align} x_1(n) = \begin{matrix} \underbrace{ \{0,0,\cdots,0,} \\ {M-1个点} \end{matrix}\begin{matrix} \underbrace{ x(0),x(1),...x(L-1)\}} \\ {第一帧L个点} \end{matrix} \newline x_2(n) = \begin{matrix} \underbrace{ \{x(L-M+1),,\cdots,x(L-1),} \\ {保留x_1最后M-1个点} \end{matrix}\begin{matrix} \underbrace{ x(L),x(L+1),...x(2L-1)\}} \\ {第二帧L个点} \end{matrix}\newline x_3(n) = \begin{matrix} \underbrace{ \{x(2L-M+1),,\cdots,x(2L-1),} \\ {保留x_2最后M-1个点} \end{matrix}\begin{matrix} \underbrace{ x(2L),x(2L+1),...x(3L-1)\}} \\ {第三帧L个点} \end{matrix} \end{align} x1(n)= {0,0,,0,M1个点 x(0),x(1),...x(L1)}第一帧L个点x2(n)= {x(LM+1),,,x(L1),保留x1最后M1个点 x(L),x(L+1),...x(2L1)}第二帧L个点x3(n)= {x(2LM+1),,,x(2L1),保留x2最后M1个点 x(2L),x(2L+1),...x(3L1)}第三帧L个点
实用的情况是一般取每帧N点数据通过N阶滤波器,而FFT长度是2N,上式则变为:
x 1 ( n ) = { 0 , 0 , ⋯   , 0 , ⏟ N 个点 x ( 0 ) , x ( 1 ) , . . . x ( N − 1 ) } ⏟ 第一帧 N 个点 x 2 ( n ) = { x ( 0 ) , , ⋯   , x ( N − 1 ) , ⏟ 保留 x 1 最后 N 个点 x ( N ) , x ( N + 1 ) , . . . x ( 2 N − 1 ) } ⏟ 第二帧 N 个点 x 3 ( n ) = { x ( N ) , , ⋯   , x ( 2 N − 1 ) , ⏟ 保留 x 2 最后 N 个点 x ( 2 N ) , x ( 2 N + 1 ) , . . . x ( 3 N − 1 ) } ⏟ 第三帧 N 个点 \begin{aligned} x_1(n) = \begin{matrix} \underbrace{ \{0,0,\cdots,0,} \\ {N个点} \end{matrix}\begin{matrix} \underbrace{ x(0),x(1),...x(N-1)\}} \\ {第一帧N个点} \end{matrix} \newline x_2(n) = \begin{matrix} \underbrace{ \{x(0),,\cdots,x(N-1),} \\ {保留x_1最后N个点} \end{matrix}\begin{matrix} \underbrace{ x(N),x(N+1),...x(2N-1)\}} \\ {第二帧N个点} \end{matrix}\newline x_3(n) = \begin{matrix} \underbrace{ \{x(N),,\cdots,x(2N-1),} \\ {保留x_2最后N个点} \end{matrix}\begin{matrix} \underbrace{ x(2N),x(2N+1),...x(3N-1)\}} \\ {第三帧N个点} \end{matrix} \end{aligned} x1(n)= {0,0,,0,N个点 x(0),x(1),...x(N1)}第一帧N个点x2(n)= {x(0),,,x(N1),保留x1最后N个点 x(N),x(N+1),...x(2N1)}第二帧N个点x3(n)= {x(N),,,x(2N1),保留x2最后N个点 x(2N),x(2N+1),...x(3N1)}第三帧N个点输出则只保留最后的N个点。

重叠相加

所有假设与重叠保留一致,只是拼帧的时候,数据块补充M-1个0,并计算DFT,这样得到的结果是没有任何混叠的L+M-1个点。我们通过逆变换,得出输出序列:
y ^ m ( n ) = { y ^ m ( 0 )   y ^ m ( 1 )   y ^ m ( 2 )   y ^ m ( 3 )   . . . y ^ m ( L − 1 )   y ^ m ( L )   . . . y ^ m ( N − 1 )   } \hat{y}_m(n) = \{\hat{y}_m(0)\ \hat{y}_m(1)\ \hat{y}_m(2)\ \hat{y}_m(3)\ ... \hat{y}_m(L-1)\ \hat{y}_m(L)\ ... \hat{y}_m(N-1)\ \} y^m(n)={y^m(0) y^m(1) y^m(2) y^m(3) ...y^m(L1) y^m(L) ...y^m(N1) }
虽然没有混叠,但数据输出长度多出了M-1个,这M-1个信息需要与后面的数据对应相加,完成卷积的交叠拼接。最终得到: y ( n ) = { y 1 ( 0 ) ,   y 1 ( 1 ) ,   . . .   y 1 ( L − 1 ) ,   y 1 ( L ) + y 2 ( 0 ) ,   y 1 ( L + 1 ) + y 2 ( 1 ) ,   . . . y 1 ( N − 1 ) + y 2 ( M − 1 ) , y 2 ( M )   . . . } {y}(n) = \{{y}_1(0),\ {y}_1(1),\ ...\ {y}_1(L-1),\ {y}_1(L)+y_2(0), \ {y}_1(L+1)+y_2(1), \ ...{y}_1(N-1)+y_2(M-1), y_2(M)\ ...\} y(n)={y1(0), y1(1), ... y1(L1), y1(L)+y2(0), y1(L+1)+y2(1), ...y1(N1)+y2(M1),y2(M) ...}这种情况的拼接关系比较简单: x 1 ( n ) = { x ( 0 ) , x ( 1 ) , . . . x ( L − 1 ) ⏟ 第一帧 L 个点 0 , 0 , ⋯   , 0 , } ⏟ M − 1 个点 x 2 ( n ) = { x ( L ) , x ( L + 1 ) , . . . x ( 2 L − 1 ) ⏟ 第二帧 L 个点 0 , 0 , ⋯   , 0 , } ⏟ M − 1 个点 x 3 ( n ) = { x ( 2 L ) , x ( 2 L + 1 ) , . . . x ( 3 L − 1 ) ⏟ 第三帧 L 个点 0 , 0 , ⋯   , 0 , } ⏟ M − 1 个点 \begin{align} x_1(n) = \begin{matrix} \underbrace{ \{x(0),x(1),...x(L-1)} \\ {第一帧L个点} \end{matrix}\begin{matrix} \underbrace{ 0,0,\cdots,0,\}} \\ {M-1个点} \end{matrix} \newline x_2(n) = \begin{matrix} \underbrace{\{ x(L),x(L+1),...x(2L-1)} \\ {第二帧L个点} \end{matrix}\begin{matrix} \underbrace{ 0,0,\cdots,0,\}} \\ {M-1个点} \end{matrix}\newline x_3(n) = \begin{matrix} \underbrace{\{ x(2L),x(2L+1),...x(3L-1)} \\ {第三帧L个点} \end{matrix}\begin{matrix} \underbrace{ 0,0,\cdots,0,\}} \\ {M-1个点} \end{matrix} \end{align} x1(n)= {x(0),x(1),...x(L1)第一帧L个点 0,0,,0,}M1个点x2(n)= {x(L),x(L+1),...x(2L1)第二帧L个点 0,0,,0,}M1个点x3(n)= {x(2L),x(2L+1),...x(3L1)第三帧L个点 0,0,,0,}M1个点

block分块自适应探讨

频域处理和分块一体不可区分的,分块处理大大减轻了自适应的算法负担,块内只算一次参数更新(输出一块的数据也只在块边界更新一次(相对于sample)),Block implementation of adaptive digital filters被引用的是比较多的一篇,A Unified Approach to Time- and Frequency-Domain Realization of FIR Adaptive Digital Filters也阐述了block lms的一些特性,但这篇文章有点长,而且时间久远,晦涩难懂。由于这个领域的诱人前景,美国OSTI在80年左右召开了一个Block adaptive filtering的会议。讲到这里,我们回顾一下,上一章节的重叠保留&重叠相加方法为块处理数字滤波器奠定了基础,但要实现块处理自适应滤波器,不仅仅要完成时-频-时变换,还有一个自适应参数更新的过程,这个如何更新?在时域还是频域做?不同策略会带来什么样的计算效率?在想实战之前,应该先撸一撸基础的理论和方法,但论文眼花缭乱,从何撸起呢?综合几篇大作,并拜读浩哥依然选三篇,或者说是2+1,1是Block implementation of adaptive digital filters,而2是这篇引用的Adaptive filtering in the frequency domain和Fast implementations of LMS adaptive filters,不妨对比着看看后两篇讲述了啥,尝试解决什么问题。从时间线上来说Adaptive filtering in the frequency domain发表于1978年,文章简短的描述了从利用The complex LMS algorithm算法从频域上计算的可行性和计算效率,但没有追究时频算法的等价性和相关性,以及误差收敛等关键问题,文中的权重值应该都是在频域存在的,计算量非常经济实惠,看着也似乎比较容易实现。1980年发表的Fast implementations of LMS adaptive filters引用了前者,这也说明了一种传承关系,后者推导的时候严格遵守了“重叠保留”方法,有了前文的铺垫,这里不难理解,文中的创新点应该是参数更新部分的时频等价变换这里了。Block implementation of adaptive digital filters侧重点在于论述了分块自适应的数学推导,给出了理论上分块方法的基础,并没有特意强调在频域还是时域。

参考

The Comparison of the Constrained and Unconstrained Frequency-Domain Block-LMS Adaptive Algorithms
线性和循环卷积
Lecture 23: Circular Convolution

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)

1、前言 在 Vue 3 项目中结合 vue-i18n 和 Element Plus 实现中英文切换是一个常见的需求。下面是一个详细的步骤指南&#xff0c;帮助你完成这个任务。 安装引入 1. 安装依赖 首先&#xff0c;你需要安装 vue-i18n 和 Element Plus。 npm install vue-i18nnext element-p…

【YOLOv8】安卓端部署-1-项目介绍

【YOLOv8】安卓端部署-1-项目介绍 1 什么是YOLOv81.1 YOLOv8 的主要特性1.2 YOLOv8分割模型1.2.1 YOLACT实例分割算法之计算掩码1.2.1.1 YOLACT 的掩码原型与最终的掩码的关系1.2.1.2 插值时的目标检测中提取的物体特征1.2.1.3 coefficients&#xff08;系数&#xff09;作用1.…

基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法、二维码识别&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…

Spring Boot 3 【八】整合实现高可用 Redis 集群

一、引言 在当今快速发展的软件开发领域&#xff0c;系统的性能和可靠性至关重要。Springboot 3 整合 Redis 7 集群具有多方面的重大意义。 首先&#xff0c;随着业务的不断发展&#xff0c;数据量呈爆炸式增长&#xff0c;单个 Redis 服务器往往难以满足存储和处理需求。Red…

网络安全-企业环境渗透2-wordpress任意文件读FFmpeg任意文件读

一、 实验名称 企业环境渗透2 二、 实验目的 【实验描述】 操作机的操作系统是kali 进入系统后默认是命令行界面 输入startx命令即可打开图形界面。 所有需要用到的信息和工具都放在了/home/Hack 目录下。 本实验的任务是通过外网的两个主机通过代理渗透到内网的两个主机。…

如何创建一个网站?初学者的分步指南

在当今数字化时代&#xff0c;即便你对 Web 开发、设计或编码一窍不通&#xff0c;也能轻松搭建属于自己的网站。无论你是想为个人打造展示平台&#xff0c;还是为企业建立线上形象&#xff0c;只要掌握正确的方法&#xff0c;借助合适的工具与资源&#xff0c;就能在短时间内完…

OceanBase V4.x应用实践:如何排查表被锁问题

DBA在日常工作中常常会面临以下两种常见情况&#xff1a; 业务人员会提出问题&#xff1a;“表被锁了&#xff0c;导致业务受阻&#xff0c;请帮忙解决。” 业务人员还会反馈&#xff1a;“某个程序通常几秒内就能执行完毕&#xff0c;但现在却运行了好几分钟&#xff0c;不清楚…

MongoDB进阶篇-索引(索引概述、索引的类型、索引相关操作、索引的使用)

文章目录 1. 索引概述2. 索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引2.3.1 地理空间索引&#xff08;Geospatial Index&#xff09;2.3.2 文本索引&#xff08;Text Indexes&#xff09;2.3.3 哈希索引&#xff08;Hashed Indexes&#xff09; 3. 索引相关操作3.1 查看索…

Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0

firefly 公司出的rk3588的设备&#xff0c;其中已经安装了gcc 交叉编译工具&#xff0c;系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…

Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

Java项目-基于SpringBoot+vue的租房网站设计与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

24.UE5枚举,怪物分类,龙卷风技能

2-26 枚举、怪物分类、龙旋风技能、掉落概率_哔哩哔哩_bilibili 目录 1.枚举 1.1枚举类型的创建 1.2 将枚举类型绑定到怪物蓝图上 1.3枚举类型的使用 1.3.1创建新的掉落物 1.3.2更改怪物掉落逻辑 2.龙卷风技能 2.1输入映射 2.2龙卷风发射物的创建 2.3龙卷风伤害逻辑…

推荐几个 VSCode 流程图工具

Visual Studio Code&#xff08;简称VSCode&#xff09;是一个由微软开发的免费、开源的代码编辑器。 VSCode 发布于 2015 年&#xff0c;而且很快就成为开发者社区中广受欢迎的开发工具。 VSCode 可用于 Windows、macOS 和 Linux 等操作系统。 VSCode 拥有一个庞大的扩展市…

解决 VMware 嵌套虚拟化提示 关闭“侧通道缓解“

最近给电脑做了新版的 Windows 11 LTSC操作系统&#xff0c;在启动VMware Workstation时&#xff0c;提示"此虚拟机已启用侧通道缓解&#xff0c;可增强安全性&#xff0c;但也会降低性能"&#xff0c;但是我没有启用 Hyper-V 相关的任何功能以及 WSL&#xff0c; 从…

Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复

目录 安装包 flume的部署 负载均衡测试 故障恢复 安装包 在这里给大家准备好了flume的安装包 通过网盘分享的文件&#xff1a;apache-flume-1.9.0-bin.tar.gz 链接: https://pan.baidu.com/s/1DXMA4PxdDtUQeMB4J62xoQ 提取码: euz7 --来自百度网盘超级会员v4的分享 ----…

P2TR(Taproot 交易)和Musig2

目录 P2TR(Taproot 交易)和Musig2 P2TR(Taproot 交易) Musig2 总结 P2TR(Taproot 交易)和Musig2 都是比特币和区块链技术中的先进功能,它们各自具有独特的特点和应用场景。以下是两者的区别及举例说明: P2TR(Taproot 交易) 定义: P2TR是一种比特币交易类型,旨…

Web 入门

HTTP 一、概念 Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 二、特点 基于TCP协议&#xff1a;面向连接&#xff0c;安全。基于请求-响应模型的&#xff1a;一次请求对应一次响应。HTTP协议是无状态的协…

Docker+Nginx | Docker(Nginx) + Docker(fastapi)反向代理

在DockerHub搜 nginx&#xff0c;第一个就是官方镜像库&#xff0c;这里使用1.27.2版本演示 1.下载镜像 docker pull nginx:1.27.2 2.测试运行 docker run --name nginx -p 9090:80 -d nginx:1.27.2 这里绑定了宿主机的9090端口&#xff0c;只要访问宿主机的9090端口&#…

Postman之变量操作

系列文章目录 1.Postman之安装及汉化基本使用介绍 2.Postman之变量操作 3.Postman之数据提取 4.Postman之pm.test断言操作 5.Postman之newman Postman之变量操作 1.pm.globals全局变量2.pm.environment环境变量3.pm.collectionVariables集合变量4.pm.variables5.提取数据-设置变…

鸿蒙动画开发08——帧动画

1、概 述 帧动画通过应用onFrame逐帧回调的方式&#xff0c;让开发者在应用侧的每一帧都可以设置属性值&#xff0c;从而实现设置了该属性值对应组件的动画效果。 相比于属性动画&#xff0c;开发者可感知动画的过程&#xff0c;实时修改UI侧的值&#xff0c;具有事件可实时响…