深度学习在MRI运动校正中的应用综述
运动是MRI中的主要挑战之一。由于MR信号是在频率空间中获取的,因此除了其他MR成像伪影之外,成像对象的任何运动都会导致重建图像中产生伪影。深度学习被提出用于重建过程的几个阶段的运动校正。广泛的MR采集序列、感兴趣的解剖结构和病理学以及运动模式(刚性与可变形、随机与规则)使综合解决方案变得难以可用。为了促进不同应用之间的交流,该综述详细概述了MRI中基于深度学习的运动校正方法,以及它们的常见挑战。该综述确定了基础数据使用、架构和评估策略方面的差异和协同。
来自:Deep Learning for Retrospective Motion Correction in MRI: A Comprehensive Review
目录
- 背景
- 数据和运动仿真
- 大脑
- 心脏和腹部
- 架构
- 基于图像的MoCo
- 基于k空间的MoCo
- 评价标准
运动是MRI诊断的主要挑战。尽管MRI是一种具有良好软组织对比度的非侵入性医学成像模式,但其固有的长采集时间使其比大多数其他模式更容易受到运动的影响。随着深度学习发展,已经提出了很多基于数据驱动的运动校正方法(MoCo,Motion Correction)。尽管存在关于运动伪影(motion artefacts)和经典MoCo的综述,但到目前为止,还没有对基于学习的MR运动校正方法进行综述。特别是缺少对越来越流行的MoCo + 图像重建领域的综述。
感兴趣区域、采集方案和运动类型的差异本质上影响数据驱动方法,所以需要确定基础模型和整体方法协同作用。该综述包含以下部分:
- 背景:MR运动伪影和经典MoCo
- 数据和运动仿真:常见的大脑和心脏模拟策略
- 架构:基于图像和基于k空间的MoCo
- 评价标准:图像质量、运动检测以及下游任务
背景
MR图像采集期间的相关运动包括运动器官(例如由于心脏运动或呼吸)和身体部位的有意识或无意识运动(例如由于患者不适)。当对不同的身体区域进行成像时,可以观察到不同的运动模式:
- 对于大脑的图像,头部的运动通常被认为是随机的,由六个刚体运动参数(三个旋转分量和三个平移分量)表征,通常忽略了微小的可形变运动(比如大脑的脉动)
- 相反,对于腹部和心脏成像,器官由于呼吸和心跳而产生的内在运动会导致准周期性模式和可变形的非刚性运动,其自由度明显更大。
无论确切的运动模式如何,成像对象的运动都会影响在频率空间(k空间)中获取的MR信号。一方面,位置的变化破坏了对所获取信号中的空间信息进行编码的能力。另一方面,物理MR信号特性受到二阶运动效应的负面影响,例如由于运动引起的磁场不均匀性或自旋效应。因此,在从频率到图像空间重构运动破坏的数据之后,可能会出现复杂的伪影,这无法在简单的过程中进行校正。图1A中大脑和腹部成像的示例性运动损坏图像说明了运动可能阻碍诊断。

- 图1A:大脑,腹部,心脏成像的典型运动模式,以及运动受损(motion-corrupted)和无运动(motion-free)图像的例子。对于大脑成像,通常假设随机刚体运动,这会导致伪影,这取决于确切的采集方案和运动模式。对于心脏和腹部成像,运动通常是可形变的和准周期性的。
目前已经提出了几种策略来减轻运动伪影。第一种,患者的运动可以受到物理限制,例如,仅在患者屏息期间进行腹部扫描,或在成像时使用镇静剂或全身麻醉。第二种,通过选择性地采集特定运动状态下的数据或使用高级采样模式(目前的图像采集方案已被设计为对运动更具鲁棒性)。第三种,目前已经引入了加速和并行成像方法,其优点是采集时间更短,运动事件的机会更少(MRI acceleration)。
除了这些仍然容易受到运动伪影影响的缓解策略之外,目前已经提出了另一组方法,通过明确地去除运动伪影来直接执行运动校正,并通过利用运动模式的规律性来进行补偿,以实现更好的重建。这些方法包括在图像采集过程中应用的前瞻性方法(prospective methods),以及在图像采集后在重建管道中的各个阶段应用的回顾性方法(retrospective methods)。回顾性方法必须处理运动引起的图像信息丢失,例如k空间中的数据不一致。为此,深度学习方法展示出前景,因为它们能够在缺乏完整分析模型的情况下识别复杂模式。
数据和运动仿真
大多数基于学习的MoCo方法依赖于监督训练,即依赖于具有和不具有运动伪影的配对数据。当然,即使是自监督方法也使用配对数据进行定量评估。一些研究已经获得了成对的运动破坏和无运动(GT)图像用于训练和评估。然而,获取大型配对数据集成本高昂,因此,这是运动仿真被广泛使用的原因。
在模拟运动伪影时,重要的是要考虑感兴趣解剖结构的典型运动模式。下面,总结了大脑,心脏和腹部成像的常见模拟程序。
大脑
在存在运动的情况下,刚体运动的模拟遵循MRI正向模型: y = ∑ t = 1 T M t F U t x (1) y=\sum_{t=1}^{T}\textbf{M}_{t}\mathscr{F}\textbf{U}_{t}x\tag{1} y=t=1∑TMtFUtx(1)其中,傅里叶变换 F \mathscr{F} F,采样mask M t \textbf{M}_{t} Mt,运动变换 U t \textbf{U}_{t} Ut被应用于每个时间点 t t t的GT图像 x x x,以生成运动破坏的k空间 y y y。在刚体运动的情况下,运动变换 U t = T t R t \textbf{U}_{t}=\textbf{T}_{t}\textbf{R}_{t} Ut=TtRt,由旋转变换 R t \textbf{R}_{t} Rt和平移变换 T t \textbf{T}_{t} Tt组成。此外,线圈灵敏度或二阶运动效应可以包括在正向模型中,以将模拟扩展到特定应用。
它在数学上等效于模拟图像空间或k空间中的运动。如图2所示,图像空间中的模拟是通过旋转和平移图像并在每个时间步长用变换后的图像的傅立叶变换替换相应的k空间线来执行的。k空间中的模拟基于傅立叶变换的特性:成像对象的旋转对应于k空间中等效的旋转,平移 T \textbf{T} T对应于线性相位斜坡的乘法,这取决于平移参数 a a a和读出方向 k R O k_{RO} kRO上的k空间坐标: T ( y ) = y ⋅ e x p ( − i 2 π a k R O ) (2) \textbf{T}(y)=y\cdot exp(-i2\pi ak_{RO})\tag{2} T(y)=y⋅exp(−i2πakRO)(2)无论在哪个域进行模拟,重要的是将运动的时序与MR采集方案相匹配,以模拟真实的伪影。

- 图2:基于每个时间步长的 x x x、 y y y和 z z z平移和旋转参数,在图像或频域中模拟刚体运动。当在图像域(1)中进行模拟时,平移和旋转参数应用于图像。当在频域(2)中模拟时,相应的k空间线被旋转并与线性相位斜坡相乘(通过箭头可视化)。对于两者,不同时间步长的k空间线被合并到一个损坏的k空间中。
心脏和腹部
从 ( 1 ) (1) (1)可知,通过应用可变形矢量场(DVF,deformable vector field)作为运动变换 U t \textbf{U}_t Ut来实现基于图像的非刚性运动模拟。真实DVF可以通过配准参考图像来获得,例如来自不同运动状态的参考图像。如果可用,可以使用多个时间分辨重建 x t x_t xt来替换 U t x \textbf{U}_{t}x Utx,从而在没有DVF的情况下进行模拟。
与刚性运动相比,直接模拟k空间中的非刚性变形并非易事。因此,心脏和呼吸运动模拟可以在k空间中通过变化的平移来近似。为了模拟周期性运动,在 ( 2 ) (2) (2)中应用具有周期性变化的平移参数的线性相位斜坡,比如 a ( t ) ∝ s i n ( t ) a(t)∝sin(t) a(t)∝sin(t)。需要注意的是,这是一个非常简化的运动表示。
架构
基于图像的MoCo
基于图像的MoCo方法将受运动影响的图像作为输入,并产生经运动校正的图像作为输出,类似于图像去噪或去模糊任务,如图1B所示。这些方法的不同之处在于a.底层网络架构,b.先验信息的潜在使用,以及c.训练目标。

- 图1B:基于图像的MoCo的经典和对抗性训练目标的可视化。对于经典训练,例如使用voxel intensity-based损失函数 L L L将预测结果与GT图像进行比较。对于对抗性训练,训练额外的鉴别器网络以与生成器网络( L g e n L_{gen} Lgen)竞争并将预测图像与GT( L a d v L_{adv} Ladv)区分开。
对于底层网络架构:
图像到图像的翻译任务可以使用卷积编码器-解码器结构,其包括用于特征编码的下采样路径,然后是用于解码提取特征的上采样路径。与U-Net一样,大多数方法使用skip连接将细节从编码器传输到解码器。此外,一些方法连续级联多个编码器-解码器结构。受transformer架构最近在其他领域取得成功的启发,后来的工作采用自注意机制来编码运动伪像的空间上下文。
先验辅助方法:
可以修改所提出的架构以利用附加信息。这些现有的辅助方法通过具有共享特征提取的共享编码器和解码器处理多个输入。例如,Ghodrati等人试图通过计算由在动态图像上预训练的辅助网络提取的特征来利用时间信息。此外,动态信息可用于基于配准的方法,其中CNN用于将装仓的数据配准到公共空间中,其组合产生运动校正的输出图像。
训练目标:
如图1B所示,在监督设置中的经典网络训练是通过使用基于体素强度的代价函数(即L1或L2)将网络的预测与无运动的GT图像进行比较来执行。然而,条件生成对抗网络(GANs)采用了不同的训练目标。利用鉴别器网络扩展了生成器网络,该生成器网络将运动破坏图像映射为无运动图像,鉴别器网络旨在将预测图像与GT图像区分开。除了对抗损失,其中一些方法依赖于基于体素强度的代价函数作为生成器损失来比较预测图像和GT图像。其他包括感知损失(perceptual loss)、风格迁移损失(style transfer loss)或结构相似性损失(SSIM,structural similarity loss)。除了对抗性方法,Küstner等人提出了另一种使用变分自编码器(VAE)的监督生成训练策略,该策略试图直接从图像对中学习无运动的潜在分布。
为了应对缺乏配对的无运动和损坏的数据,无监督生成模型旨在校正来自无配对数据的运动伪影。由两个GAN组成的CycleGAN架构在(Learning MRI artefact removal with unpaired data)和(Unsupervised Adversarial Correction of Rigid MR Motion Artifacts)中进行了调整。两个生成器,一个破坏无运动图像,另一个校正未配对的损坏图像。对抗性损失可以用来自另一个域的未配对图像来计算,而生成性损失是以无监督的方式在来自同一域的循环变换输入上计算的。刘等人将生成器的潜在表示分解为人工信息和内容信息,并使用从内容翻译中生成的图像来训练网络。这些方法都包括多尺度代价函数。在另一种情况下,Oh等人将运动视为概率欠采样问题,并训练生成器以消除欠采样伪影,他们试图通过组合重复的随机欠采样重建来校正运动破坏的测量(Unpaired MR Motion Artifact Deep Learning Using Outlier-Rejecting Bootstrap Aggregation)。
基于k空间的MoCo
与基于图像的方法不同,MoCo还可以利用原始k空间数据的附加信息内容,与MR重建过程相互作用(见图1C)。运动感知重建管道的不同组件可以是基于学习的。在下面的部分中,概述了将经典模块和基于学习的模块结合在一起的方法,以及纯学习的方法。

- 图1C:基于k空间的MoCo图解。
- 将经典模块和基于学习的模块相结合的方法可以分为以下几类:1.替换基于模型重建的不同组件,该方法通过最小化损失函数 L ( θ , x ) L(θ,x) L(θ,x)在找到图像 x x x和相应的运动参数 θ θ θ之间迭代。基于学习的模块以图像初始化、损失函数或运动参数为目标。2.将经典重建与基于学习的损坏k空间测量的运动检测或基于学习的运动场 U t \textbf{U}_{t} Ut估计相结合。3.将经典的运动检测或估计与学习的展开重建相结合,该重建在去噪网络和数据一致性(DC)块之间迭代。
- 纯粹基于学习的方法包括:4.直接旨在通过在k空间和图像空间中执行卷积或从基于学习的重建中排除运动破坏的k空间测量来校正运动伪影的方法。5.运动补偿方法,其隐式或显式地使用运动信息来实现更高质量的图像重建。一个子类方法将生成重建模型与个人的原始数据相匹配,而运动可以选择性地通过包括变形场来显式建模。
A.经典方法和基于学习的方法相结合:多种方法使用基于学习的MoCo或重建组件扩展了经典框架。可以学习基于模型的重建的一部分、运动分析或重建本身。
替换部分基于模型的重建:
基于模型的MoCo算法依赖于运动参数 θ \theta θ和重建图像 x x x的联合估计。这些方法建议用基于学习的组件替换优化过程的不同部分,以实现更快的收敛和理想情况下更稳定的重建(图1C.1)。Kuzmina等人使用CNN作为自动聚焦的损失函数的一部分,其中优化基于图像质量度量。对于基于数据一致性(DC)的优化过程,CNNs或U-Nets被用于运动参数估计,作为运动校正图像的初始化,或者作为重建网络,其权重由依赖于运动参数的超网络定义。相反,Levac等人提出了一种无监督方法,使用基于分数的模型,在无运动图像上训练。所有这些方法的共同点是,网络经过预训练,并在测试时间优化期间用作即插即用组件。此外,所有这些方法都专注于刚体运动,其自由度比非刚体运动小得多。
基于学习的运动分析与经典重建:
另一组方法利用了刚体运动的随机性。如图1C.2所示,他们学习受运动影响的k空间测量的检测模型,并用提取的运动时序为经典重建过程提供信息。Eichhorn等人将CNN用于k空间中的line检测,并将这些线分类标签用作基于总变化的重建过程的DC项中的权重。崔等人训练基于图像的CNN来校正运动伪影,并比较原始图像和运动校正图像的k空间,以生成受运动影响的k空间线的欠采样掩码,然后使用经典的压缩感测过程来重构欠采样的原始数据(Motion artifact reduction for magnetic resonance imaging with deep learning and k-space analysis)。
在准周期运动的情况下,单个运动破坏的k空间线的假设不适用。运动补偿方法不是针对单个运动事件进行校正,而是利用运动的周期性来对欠采样数据进行更高质量的重建。这些方法学习运动估计,这些估计包含在基于模型的经典重建中。使用基于图像的配准来预测运动场,并将其集成到重建问题的前向算子中。现有的方法在注册网络的输入方面各不相同,即完整图像与图像patch,配对与分组输入。此外,运动估计网络可以进行预训练,也可以与重建问题一起进行优化。
经典运动分析与基于学习的重建:
相反,运动检测和估计也可以用经典方法执行,并与学习的基于展开DC的重建相结合(图1C.3)。Rotman等人通过比较来自两个相对线圈元件的信号来检测离散运动定时,并学习展开重建,其中规则化网络分别接收在主导运动状态和剩余运动状态中获取的数据。Miller等人采用了动态图像到单个运动状态的经典时空约束配准。注册的图像被编码并转发到展开的重建中,该重建通过将可用数据分割成子集以自监督的方式进行训练。
B.纯粹基于学习的方法:与A相比,有几种方法将MoCo和图像重建结合在一个纯粹基于学习的框架中。这些可以通过其校正或补偿运动的目的来区分。
基于运动校正目的:所提出的运动校正方法明确旨在去除底层数据中的运动伪影(图1C.4)。Singh等人提出了一种由图像和k空间中的交错或交替卷积组成的网络,用于同时进行刚体MoCo和重建。这种方法被进一步发展为一种数据一致性方法。Oksuz等人提出使用CNN来学习受运动影响的k空间线的欠采样掩码,并使用递归网络重建欠采样数据(Detection and Correction of Cardiac MR Motion Artefacts during Reconstruction from K-space)。在扩展中,他们用分割网络来训练检测和重建网络,从而专门针对感兴趣的下游任务优化MoCo。
基于运动补偿目的:所提出的运动补偿方法利用发生的运动来改善重建结果,同时加快采集时间,如图1C.5所示。空间和时间卷积以级联或并行的方式应用于具有联合或分离时空内核的动态图像序列。为了利用来自相邻帧的进一步信息,Schlenper等人包括数据共享层。Terpstra等人用从预训练模型中获得的运动场扩展了隐式运动补偿重建。相反,有几种方法以端到端的方式明确地学习具有重建问题的运动模型。Huang等人将运动估计和校正模块附加到重建网络中,并用一个组合损失函数训练框架(Dynamic MRI reconstruction with end-to-end motion-guided network)。
评价标准
由于MoCo是作为实现高质量图像重建的一种手段,因此主要基于其最终结果,使用图像质量指标来评估所提出方法的性能。然而,一些人也评估中间运动估计或利用下游任务来评估。下面概述了最常见的评估策略。
图像质量:
可以通过分别计算图像质量度量或专家图像质量评级来执行定量或定性图像质量评估。定量图像质量度量可以是通过与GT参考图像进行比较来评估图像质量的全参考度量,也可以是不依赖于单独的GT图像的无参考度量。由于运动伪影的可变性,没有一个单一的图像质量测量对所有可能的伪影敏感。
大多数方法使用了两种试图模仿人类视觉感知的完整参考(reference-full)指标:结构相似性指数(SSIM),用于评估结构信息的退化;峰值信噪比(PSNR),用于将像素误差与最大信号强度进行对比。不太常用的全参考指标是均方误差(MSE)、均方误差根(RMSE)、归一化均方误差、平均绝对(百分比)误差(MAE或MAPE)、归一化互信息(NMI)和视觉信息保真度(VIF)。此外,对于无参考指标(reference-free),如信噪比(SNR)、对比度噪声比(CNR)和Tenengrad,用于评估没有参考图像的图像质量。
下游任务:
在某些情况下,MoCo框架不仅旨在提供高质量的重建,还能够完成进一步的下游任务。在这种情况下,下游发现可以独立评估,例如通过计算器官分割上的Dice重叠或计算T2* map上的SSIM和相对误差度量。为了评估MoCo在纵向分析中增加的统计能力,可以采用皮质表面重建和皮质厚度相关性分析等结构元素的手动质量控制。特别是在没有参考的情况下,可以分析冠状血管等小解剖特征的清晰度。在心脏成像中,可以评估心脏功能分析。此外,作为MR MoCo的一个重要最终目标,可以对运动受损和校正扫描的临床结果进行比较。
相关文章:
深度学习在MRI运动校正中的应用综述
运动是MRI中的主要挑战之一。由于MR信号是在频率空间中获取的,因此除了其他MR成像伪影之外,成像对象的任何运动都会导致重建图像中产生伪影。深度学习被提出用于重建过程的几个阶段的运动校正。广泛的MR采集序列、感兴趣的解剖结构和病理学以及运动模式&…...
内存不足V4L2 申请DMC缓存报错问题
当内存不足时,V4L2可能存在申请DMA缓存报错,如下日志: 13:36:54:125 [15070.640862] rkcifhw fdfe0000.rkcif: swiotlb buffer is full (sz: 1843200 bytes) 13:36:54:125 [15070.640891] rkcifhw fdfe0000.rkcif: swiotlb: coherent allocation failed, size=1843200 13:3…...
论文笔记--Llama 2: Open Foundation and Fine-Tuned Chat Models
论文笔记--Llama 2: Open Foundation and Fine-Tuned Chat Models 1. 文章简介2. 文章概括3 文章重点技术3.1 预训练Pretraining3.1.1 预训练细节3.1.2 Llama2模型评估 3.2 微调Fine-tuning3.2.1 Supervised Fine-Tuning(FT)3.2.2 Reinforcement Learning with Human Feedback(…...
客达天下项目案例
本资料转载于传智播客https://www.itheima.com/ https://space.bilibili.com/3493265607232348 黑马程序员主办的全日制统招大学——大同互联网职业技术学院 预计2024年开始招生,敬请持续关注! B站视频入口:002_接口项目介绍_哔哩哔哩_bili…...
系统设计类题目汇总二
12 如何在实际的生产者端减少数据库的IO次数? 我自己想到的: 1 对于局部性很强的数据,启用mysql缓存机制,这样就不用磁盘IO 2 对于行数很多的表,可以分库分表,单表的数据量下来了,则查找索引要…...
MySQL和Redis如何保证数据一致性
MySQL与Redis都是常用的数据存储和缓存系统。为了提高应用程序的性能和可伸缩性,很多应用程序将MySQL和Redis一起使用,其中MySQL作为主要的持久存储,而Redis作为主要的缓存。在这种情况下,应用程序需要确保MySQL和Redis中的数据是…...
Go学习第九天
使用sqlite3 package mainimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx"_ "github.com/mattn/go-sqlite3""log""time" )var schema CREATE TABLE perso…...
kafka集成篇
kafka的Java客户端 生产者 1.引入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.6.3</version></dependency>2.生产者发送消息的基本实现 /*** 消息的发送⽅*/ …...
go-安装部署
一、安装go 详细安装方式可以查看官网 # 下载 wget https://golang.google.cn/dl/go1.21.0.linux-amd64.tar.gz # 解压缩 tar -xzf go1.21.0.linux-amd64.tar.gz # 迁移目录 mv go /usr/local # 配置环境变量 export PATH$PATH:/usr/local/go/bin # 检查go的版本 go version有…...
vue项目的实用性总结
1、mockjs 基本使用 ★ 安装:npm i mockjs。 在src/mock/index.js内容如下: import Mock from mockjs //制订拦截规则 Mock.mock(http://www.0313.com,get,你好啊)记得在main.js中引入一下,让其参与整个项目的运行。 只要发出去的是get类型…...
IOC容器
DI(依赖注入):DI(Dependency Injection)是一种实现松耦合和可测试性的软件设计模式。它的核心思想是将依赖关系的创建与管理交给外部容器,使得对象之间只依赖于接口而不直接依赖于具体实现类。通过依赖注入…...
若依框架浅浅介绍
由若依官网所给介绍可知 1、文件结构介绍 在ruoyi-admin的pom.xml文件中引入了ruoyi-framework、ruoyi-quartz和ruoyi-generatior模块,在ruoyi-framework的pom.xml文件中引入了ruoyi-system模块。 2、技术栈介绍 前端:Vue、Element UI后端:…...
echarts 柱状图-折线图-饼图的基础使用
上图示例图表展示相关配置: var myChart echarts.init(this.$refs.firstMain);myChart.setOption({legend: { // 图例设置top: "15%",type: "scroll",orient: "vertical",//图例列表的布局朝向。left: "right",pageIconCo…...
mac电脑 node 基本操作命令
1. 查看node的版本 node -v2. 查看可安装的node版本 sudo npm view node versions3. 安装指定版本的node sudo n 18.9.04. 安装最新版本node sudo n latest5. 安装最新稳定版 sudo n stable6. 清楚node缓存 sudo npm cache clean -f7. 列举已经安装的node版本 n ls 8. 在…...
Hlang社区项目说明
文章目录 前言Hlang社区技术前端后端 前言 Hello,欢迎来到本专栏,那么这也是第一次做这种类型的专栏,如有不做多多指教。那么在这里我要隆重介绍的就是这个Hlang这个项目。 首先,这里我要说明的是,我们的这个项目其实是分为两个…...
RTC实验
一、RTC简介 RTC(Real Time Clock)即实时时钟,它是一个可以为系统提供精确的时间基准的元器件,RTC一般采用精度较高的晶振作为时钟源,有些RTC为了在主电源掉电时还可以工作,需要外加电池供电BCD码,四位二进制表示一位…...
C#多线程报错:The destination thread no longer exists.
WinForm,C#多线程报错: System.ComponentModel.InvalidAsynchronousStateException: An error occurred invoking the method. The destination thread no longer exists. 研究一番,找到了原因: 有问题的写法: ne…...
使用 Visual Studio GoogleTest编写 C/C++ 单元测试——入门篇
入门教程 Visual Studio 新建 GoogleTest项目,一路选默认参数 pch.h #pragma once#include "gtest/gtest.h"int add(int a, int b);pch.cpp #include "pch.h"int add(int a, int b) {return a b; }test.cpp #include "pch.h"TES…...
Linux下TA_Lib安装失败的问题处理
Linux下TA_Lib安装失败的问题处理 TA_Lib是python的量化指标库,其中包含了很多150多种量化指标 ,量化分析中经常使用。 This is a Python wrapper for TA-LIB based on Cython instead of SWIG. From the homepage: TA-Lib is widely used by trading …...
egg.js企业级web框架
egg与express、koa的区别 三者皆为node.js web框架,但: express适合做个人项目,灵活性太高;egg是基于koa封装的企业级框架,奉行约定优于配置,按照一套统一的约定进行应用开发,减少开发学习成本…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
