SoundStream: 下一代的神经网络音频编解码器,实时压缩不牺牲音质

news2024/11/23 16:47:42

音频编解码技术的目标是,通过减少音频文件的大小来节省存储空间或减轻网络传输的负担。理想的情况下,即使音频被压缩,我们听到的声音与原版也应该没有任何区别。

过去,已经有不少编解码技术被开发出来,满足了这些需求,比如Opus和EVS这两种编解码器就很出名。

Opus是一个多才多艺的音频编解码器,它适用于各种应用,从视频会议(比如 Google Meet)到在线视频流(比如 YouTube)。Opus支持的压缩比率非常灵活,从每秒6千比特到每秒510千比特都可以。

而EVS,是由3GPP标准化组织针对移动电话>)开发的最新编解码器。它也支持不同的压缩比率,从每秒5.9千比特到每秒128千比特。使用Opus和EVS,我们能在中低比特率(每秒12-20千比特)下得到很高的音频质量,但是如果比特率太低(比如每秒小于3千比特),音质就会显著下降。

这些编解码器都是基于对人类听觉系统的深入了解和精心设计的信号处理流程来优化压缩效率的。但现在,研究人员开始探索使用机器学习技术来优化这一过程。

一个名为SoundStream的神经网络编解码器在这方面取得了突破。它不仅能处理语音和音乐,还能在智能手机的CPU上实时运行。SoundStream可以利用单个模型,在一个很宽的比特率范围内提供极高的音质,这是学习型编解码器一个重要的进步。

预备知识

音频基础

在音频编解码的世界里,有一个非常重要的概念叫做“比特率”,有时候也被叫做“码率”。这个概念告诉我们在每一秒钟内,有多少比特(数据的基本单位)被用来存储或传输音频。比特率的单位是bps,即每秒比特数。

在一段音频被压缩后,它的比特率会告诉我们这段压缩音频每秒钟包含多少比特。当我们提高了比特率,意味着我们用更多的比特来存储或传输同样长度的音频,这样相应的文件大小也就变大了。因此,如果我们说一个音频的压缩比特率很低,那通常也意味着我们把它压得非常紧,但这样可能会影响音质。

我们可以用一个简单的公式来计算比特率:比特率(以千比特每秒kbps计)等于文件大小(以千字节KB为单位)乘以8(因为1字节包含8比特),然后除以时间(秒)。举个例子,有一段24千赫兹(也就是采样率,表示每秒采样的次数),16位深度的PCM编码音频,它的比特率是384千比特每秒(kbps)。如果我们有一段这样的2秒音频文件,文件大小会是96千字节(KB),计算出来的比特率就是384千比特每秒。

在音频质量的评价中,我们通常会用到两个评分系统:MUSHRA分数和MOS(Mean Opinion Score,平均意见得分)分数。这两个得分系统都是用来评估人们听后对音频质量的主观感受。MUSHRA分数的一大优势在于,即使是少量的测试人员也能提供具有统计意义的结果。如果你想了解更多关于MUSHRA的信息,可以参考它的[维基百科页面](https://en.wikipedia.org/wiki/MUSHRA](https://en.wikipedia.org/wiki/MUSHRA)。

传统的音频编(解)码方法可以分为两大类:波形编(解)码和参数编(解)码。

波形编码(非参数编码)

波形编码,也叫非参数编码,其主要目标是让解码后的音频信号尽可能地与原始音频信号在波形形状上保持一致。这意味着波形编码尽力精确复现原音频的所有采样点,就像给音频做一个全面且详细的复印。

在波形编码的过程中,音频先从时间上的波形转换成频率上的表示形式,然后将这些频率内容进行量化(也就是根据一定的规则简化)和熵编码(一种根据数据内容复杂度来压缩数据的方法)。解码的时候,就是做相反的工作,从简化后的频率内容恢复还原成原始的时间波形。在量化的过程中,考虑到人耳对不同频率的敏感程度不一样,会根据这一心理声学原理分配不同的数据量给不同的频段。

波形编码不需要对音频内容是语音、音乐、噪声或是混响有任何特别的假设,它把音频信号看作普通的波形来处理,所以这种方法非常通用。为了获得高质量的音频,它通常需要较高的比特率(每秒16到64千比特),如果比特率太低,音质就会降低。

声码化编码(参数编码)

另一方面,声码化编码,也称为参数编码或模型编码,采用不同的策略。它对音频信号,尤其是语音信号,有一些特定的假设。通过使用一个参数化的模型,它引入了强有力的先验知识。编码器的工作是估计这个模型的参数并量化它们,而解码器则利用这些参数重建出音频波形。

与波形编码不同,声码化编码更关注音频信号重建后的感知相似度而不是每个采样点的准确度。重建出来的音频可能在波形上与原音比较不同,但目的是保留其语义。声码化编码的好处是比特率低,但缺点是音质通常不如波形编码自然,而且这种编码方式也比较敏感:在安静环境下的音质更好,在噪声较大的环境或信号有错误时音质下降。

总结这两种传统的音频编解码方式,都需要精心设计的信号处理流程和工程设计。要提高编码效果,还需要借助心理声学和语音合成领域的知识。现在,业界常用的编码器如Opus和EVS(增强语音服务),都是基于这些传统方法,并且能够确保在低延迟和实时通讯条件下,在多种内容、比特率和采样率下保持高效率的表现。

神经网络音频编解码

近些年,基于机器学习和深度学习的方法已经应用于音频编解码方向,主要分为以下两类思想:

  1. 作为音频解码器的后处理模块:比如,在现有音频解码器恢复出的音频基础上,使用音频超分(super-resolution)的方法扩展频带;或者使用音频降噪的思想去除编码损失带来的失真;或者使用丢包补偿的方法。

  2. 集成到音频编解码器中:语音合成中的神经网络声码器,可以自然地应用于音频编解码(同样是音频波形压缩到某一种低维特征,再从低维特征恢复生成原始的音频信息),不同的工作主要体现在模型结构的差异:WaveNet 使用的是全卷积结构,LPCNet 使用的是 WaveRNN,而 Google 2021 年 2 月提出的 Lyra 使用的是 WaveGRU,以上这些工作主要针对的都是低比特率的音频编解码场景。

SoundStream模型

SoundStream 编解码器是全卷积的网络结构。输入是原始的音频波形,Encoder 将其映射为较低采样率的 embedding 序列,RVQ 残差向量器对 embedding 序列进行量化;Decoder 输入是量化的 embedding,预测目标是恢复原始波形。
在这里插入图片描述

编码器结构

在这里插入图片描述

我们的编码器是用来处理声音波形的,它的工作起点是每秒24,000个声波样本。首先,声音会通过一个特殊的过滤器,这个过滤器看起来有点像漏斗,能把声音的特征捕捉出来。接下来,声音还会穿过一系列的处理单元,我们叫它们EncoderBlock,每个单元都有三个特别的创新点叫做"ResidualUnit"。

这个ResidualUnit非常聪明,里面有两层过滤器,第一层是擅长扩展的,可以抓住声音中更多的细节,有点像放大镜。第二层过滤器则有点像我们大脑中的神经元,帮助将所捕捉到的信息汇总起来。

而一个EncoderBlock会重复用三个不同放大能力的ResidualUnit来分析声音,它们能逐步探索声音的深层细节。每个EncoderBlock 还会使声音样本"稀疏"一些,也就是降低样本的数量,但仍然保留关键信息。

我们一共用了四个不同的EncoderBlock,每个都以不同的速度"稀疏"声音。最终,我们将声音的样本量减少了320倍。也就是说,如果原来每秒钟有24,000个样本的话,通过这些过程处理后,就只剩下每秒75个样本了。而且,每经过一个EncoderBlock,我们收集的细节就会加倍。

最后,声音会通过一个最终的过滤器,这个过滤器的作用是给出最终的声音"指纹",也就是我们所说的声音特征或嵌入(embedding),这些特征包含了所有我们关心的声音信息。

解码器

解码器采用的是和编码器完全对偶的结构,就不再赘述。

残差向量量化器

SoundStream 整体的编解码器结构比较直观,但论文的关键技术点之一是引入了残差向量量化(RVQ)模块,目的是将 Encoder 输出的 embedding 通过量化层压缩到目标的比特率。

VQ(Vector Quantization)回顾

Vector quantization - Wikipedia
向量量化是一种数据压缩技术,其基本想法是把一堆数据点分成几组,每组的数据点都彼此接近。想象一下,你有一堆点在纸上,现在你用几个不同颜色的圆圈来围起这些点,每个圆圈中的点都靠得比较近。然后你在每个圆圈里画一个点,代表这个圆圈中所有点的中央或者平均位置,我们叫这个点为“质心”。这个过程跟K-Means聚类算法很像,用来在数据分析中找到数据的自然分组。

在这篇论文中,我们运用向量量化的技巧来处理音频信号。具体地说,我们想要学习一套N个向量的集合,我们称之为“codebook”或“码本”。码本里的每个向量都代表着音频信号中的一种基本特征,就像一个词典里面的单词一样,每个单词表示一种意义。我们的目标是将音频编码器(Encoder)输出的一串特征(我们称这些为“embedding”)转换成码本中相应的向量。

举个例子,如果编码器输出了一个长度为S的特征序列,每个特征都是一个D维的点,那我们使用向量量化后,每个点会被转换成一个包含了一个1和很多0的特殊向量,这称为one-hot向量。这里的1所在的位置表示了它对应码本中哪一个向量。量化后的序列变成了SxN的大小,而且因为我们用one-hot向量来表示,所以只需要log2N比特来存储这个信息。

总之,码本就是一个包含了所有基本特征向量的集合。在实践中,为了表明哪一个特征被选择了,我们只需要用log2N这么多比特,这大大节省了存储空间。

普通 VQ 的局限性
向量量化(VQ)是音频编码中使用的一种技术,但普通的VQ面临一个问题,那就是它需要一个庞大的码本(codebook)来进行工作。码本就像是一本厚厚的图书馆索引,它列出了所有可能的音频片段特征的编码方式。

想象一下,如果我们有一段音频,比如说24kHz的高质量音频,我们希望用VQ技术将其压缩到6千比特每秒(kbps)的比特率。首先,我们得通过编码器将这段音频处理成一个“简化版”,这个过程就像是把音频“稀疏”化,我们称之为降采样,这里提到的降采样倍数是320倍。经过这个处理,原始音频里每75 ( 24 k / 320 = 75 ) (24k / 320 = 75) (24k/320=75) 个音频片段特征就变成了一个“embedding”,而这个embedding需要80 ( 6 k / 75 = 80 b i t ) (6k/75=80bit) (6k/75=80bit) 个比特来表示。

但问题在于,要描述所有不同的embedding,我们需要的码本大小是2的80次方,这是一个天文数字,用现实中的技术和资源根本无法存储这么大规模的码本。

残差 VQ/多阶段
为了解决普通VQ的这个问题,研究者们提出了残差VQ或多阶段VQ的方案。在这个系统中,我们用多层次的VQ来处理音频。这就像是你不是一次性把整个音频全都打包好,而是先打一个包裹,然后对这个包裹再进行打包,如此多次。

在多阶段VQ中,我们先用第一层VQ来处理原始编码器输出的embedding,然后计算出它和原始信号之间的差异,我们称之为残差。接着,第二层VQ只处理这个残差,而不是整个信号,然后第三层处理第二层的残差,以此类推。

通过这种方法,如果我们有8个这样的VQ层次,每一层都有自己的小型码本,那么每个层级的码本大小就变成了2的10次方 2 80 / 8 = 2 10 = 1024 2^{80/8}=2^{10}=1024 280/8=210=1024 ,也就是1024个可能的选项。这比起一开始天文数字的量级,变成了一个我们可以实际管理和存储的数量。通过这种多层次的方式,我们就可以用合理的资源来压缩并存储高质量的音频了。
在这里插入图片描述

判别器

为了确保压缩再解压(编解码)的音频听起来像原来一样好,论文介绍了两种特殊的“音质判断工具”,我们称之为判别器。这些判别器的工作是分辨一段音频是不是经过编解码处理的,还是原始未经处理的真实音频。

第一种判别器关注的是音频的波形,也就是声音波动的形状。这个工具用了一种叫做多精度(multi-resolution)的技术,类似于已经存在的一些高清音质生成技术,比如MelGAN和HiFI-GAN。这种方法不仅会检查整个原始波形,还会查看它被压缩两倍和四倍后的情况,这样可以从不同层面上检测波形的细节。

第二种判别器则是基于STFT——短时傅里叶变换。这是一种将音频信号转换成时间和频率两个维度上的信息的技术。简单来说,判别器先拿到24kHz的音频,然后把它通过STFT转换成一个有时间和频率信息的二维图像。在这个过程中,我们用到了一个特定大小的窗口(窗长W=1024)去“观察”音频,并且以一个固定的步长(H=256采样点)在音频上移动这个窗口。这样处理之后,我们得到了一个包含时间点(T)数量和频率块(F)数量( F = W / 2 = 512 F=W/2=512 F=W/2=512)的二维表盘。

接下来,这个二维的信息会被送进一个特殊的过滤器,也就是一个7×7大小的二维卷积层。这个层的作用就像是一种复杂的过滤网,可以捕获音频的细节。而且,它后面还有其他几层增强的过滤器,它们在论文里被称作ResidualUnit,只不过这次我们使用的是二维版本来处理我们的音频“图像”。

最终,一个全连接层(也就是一个将信息汇集起来的网络层)会把这些数据汇总并生成一个单一的数值,我们称之为logits。此数值的目的是给出一个信号,说明正在检查的波形是经过编解码的音频还是真实的、未经处理的音频。
在这里插入图片描述

训练目标

SoundStream 整体使用 GAN(生成对抗网络)作为训练目标,采用 hinge loss 形式的对抗 loss。
对应到 GAN 模型中,整个编解码器作为 Generator 生成器,使用前文所述的两种 Discriminator 判别器:一个 STFT 判别器和三个参数不同的 multi-resolution 判别器。判别器用来区分是解码出的音频还是真实的原始音频,本文采用 hinge loss 形式的损失函数进行真假二分类:
![[Pasted image 20240423155935.png]]

  • L_D 是判别器损失函数。
  • Ex 表示对真实样本 x 的期望。
  • G(x) 是生成器根据 x 生成的样本。
  • K 表示判别器的个数。
  • T_k 表示第 k 个判别器logits的时间维度大小
  • D_k,t(x) 和 D_k,t(G(x)) 分别表示第 k 个判别器在时间步 t 对真实样本 x 和生成样本 G(x) 的预测。
    这个损失函数由两部分组成:
    第一部分惩罚判别器将真实样本误判为生成的错误。max(0, 1 - D_k,t(x)) 确保当判别器预测真实样本时,损失为0,否则损失为预测误差的绝对值。
    第二部分惩罚判别器将生成样本误判为真实的错误。max(0, 1 + D_k,t(G(x))) 确保当判别器预测生成样本时,损失为0,否则损失为预测误差的绝对值。
    总的来说,这个损失函数旨在让判别器区分真实和生成的样本,使其预测尽可能接近真实情况。

K 表示 K 个独立的判别器,K=0时表示 STFT-based 的叛变起,K>1 时表示multi-resolution 判别器。
生成器的损失函数是为了让生成器的输出被分类为 1 类别,已达到以假乱真的目的,损失函数为:
![[Pasted image 20240423160525.png]]

训练目标中还增加了 GAN 中常用的 feature matching 损失函数和多尺度频谱重建的损失函数。feature matching 就是让生成器恢复出的音频和真实的音频,在判别器的中间层上达到相近的分布,用 表示在中间层 l l l上进行求和,feature matching 的损失函数为:
![[Pasted image 20240423160634.png]]

多尺度频谱重建损失函数为:
![[Pasted image 20240423160712.png]]

综上所述,GAN 的训练损失函数为:
![[Pasted image 20240423160752.png]]

λ \lambda λ 表示加权值,实验中设置为: λ a d v = 1 , λ f e a t = 100 , λ r e c = 1 \lambda_{adv}=1, \lambda_{feat}=100, \lambda_{rec}=1 λadv=1,λfeat=100,λrec=1

SoundStream评测

评测准备

评测数据集

评测覆盖多种类型的音频,包括干净和带噪的语音和音乐,都是 24kHz 采样率。干净的语音来自 LibriTTS,带噪的语音是将 LibriTTS 和 freesound 里的噪声叠加,叠加时噪声的增益系数在 -30dB 和 0 dB 之间;音乐数据来源是 MagnaTagATune;论文还采集了真实场景的音频数据集,覆盖了近场、远场(带混响)和背景噪声的音频。相当于共四个测试集,每个测试集是 50 个待测样本。

评测指标

模型最终评测的指标采用前文所述的 MUSHRA 分数,评测人母语均为英语,戴耳机进行评测。但是在模型训练和调参时,留出一个验证集,在上面计算客观指标进行模型评价,可以用 PESQ 和 POLQA 的,本文选择的是开源的 ViSQOL 评测指标。

评测baseline

Opus 是传统的音频编解码方法,支持 4kHz ~ 24 kHz 的采样率和 6 kbps ~ 510 kbps 的比特率,在 Youtube 流媒体上都在使用。另外 EVS (增强语音服务) 也是一种新编解码方法,支持 4kHz ~ 20 kHz 的采样率和 5.9 kbps ~ 128 kbps 的比特率。Google 还提出了基于自回归模型的 Lyra 编解码器,可以在 3 kbps 的低比特率下使用。本文将以上三种方法作为基线。

评测结果

不同比特率下的结果

![[Pasted image 20240423163357.png]]

其中 scalable 的 SoundStream 代表一个支持多比特率的模型,不带 scalable 的模型表示给当前比特率专门训练的模型,可以看出模型是否 scalable 差别不大,尤其是高比特率下几乎无差别。相同比特率下,SoundStream 碾压其他三个基线模型。

不同类型音频的结果

![[Pasted image 20240423163419.png]]

SoundStream @ 3kbps 相当于 EVS @ 9.6kbps 和 Opus@12kbps,SoundStream@6kbps 相当于 Opus @ 16kbps 和 EVS @ 13.2kbps,SoundStream @ 12kbps 超过了 Opus @ 20kbps 和 EVS @ 16.4kbps。普遍性地,编解码后恢复的音频,MUSHRA 分数上:干净语音 > 真实场景音频 > 带噪语音 > 音乐。

参考文献

  • 详解SoundStream:一款端到端的神经音频编解码器_AI&大模型_谷歌研究团队_InfoQ精选文章
  • soundstream - mdnice 墨滴
  • ViSQOL 指标: Chinen, Michael, et al. “ViSQOL v3: An open source production ready objective speech and audio metric.” 2020 twelfth international conference on quality of multimedia experience (QoMEX). IEEE, 2020.
  • 官方博客: https://opensource.googleblog.com/2022/09/lyra-v2-a-better-faster-and-more-versatile-speech-codec.html
  • 示例音频: https://google-research.github.io/seanet/soundstream/examples
  • 官方开源: https://github.com/google/lyra
  • 非官方实现(PyTorch)Lucidrains: https://github.com/lucidrains/audiolm-pytorch/blob/main/audiolm_pytorch/soundstream.py
  • 非官方实现(Pytorch)wesbz: https://github.com/wesbz/SoundStream
  • 非官方实现(PyTorch)Lucidrains: https://github.com/lucidrains/audiolm-pytorch/blob/main/audiolm_pytorch/soundstream.py
  • 非官方实现(Pytorch)wesbz: https://github.com/wesbz/SoundStream

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

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

相关文章

Linux基础-socket详解、TCP/UDP

文章目录 一、Socket 介绍二、Socket 通信模型三、Socket 常用函数1 创建套接字2 绑定套接字3、监听连接4、接受连接5、接收和发送数据接收数据发送数据 6、关闭套接字 四、Socket编程试验1、源码server.cclient.c 2、编译:3、执行结果 五、补充TCP和UDP协议的Socke…

无人机+三维建模:倾斜摄影技术详解

无人机倾斜摄影测量技术是一项高新技术,近年来在国际摄影测量领域得到了快速发展。这种技术通过从一个垂直和四个倾斜的五个不同视角同步采集影像,从而获取到丰富的建筑物顶面及侧视的高分辨率纹理。这种技术不仅能够真实地反映地物情况,还能…

3.CQL使用-创建、查询、返回

Neo4j的Cypher语言为处理图形数据而构建的。 CQL代表Cypher查询语言。 https://neo4j.com/docs/cypher-manual/3.5/clauses/load-csv/ CQL语句使用文档地址。 小技巧:在neo4j的CQL语句输入框里,shift enter换行,直接enter键会执行CQL语…

2024智能科学与软件工程国际学术会议(ICISSE 2024)

2024智能科学与软件工程国际学术会议(ICISSE 2024) 会议简介 2024智能科学与软件工程国际学术会议(ICISSE 2024)将在北京隆重举行。本次会议汇集了全球智能科学和软件工程领域的专家学者,共同探讨该领域的最新研究成果和发展趋…

跟TED演讲学英文:AI isn‘t as smart as you think -- but it could be by Jeff Dean

AI isn’t as smart as you think – but it could be Link: https://www.ted.com/talks/jeff_dean_ai_isn_t_as_smart_as_you_think_but_it_could_be Speaker: Jeff Dean Jeffrey Adgate “Jeff” Dean (born July 23, 1968) is an American computer scientist and software…

Spirng 当中 Bean的作用域

Spirng 当中 Bean的作用域 文章目录 Spirng 当中 Bean的作用域每博一文案1. Spring6 当中的 Bean的作用域1.2 singleton 默认1.3 prototype1.4 Spring 中的 bean 标签当中scope 属性其他的值说明1.5 自定义作用域,一个线程一个 Bean 2. 总结:3. 最后: 每…

JAVA基础---Stream流

Stream流出现背景 背景 在Java8之前,通常用 fori、for each 或者 Iterator 迭代来重排序合并数据,或者通过重新定义 Collections.sorts的 Comparator 方法来实现,这两种方式对 大数量系统来说,效率不理想。 Java8 中添加了一个…

一款可视化正则表达式工具

regex-vis是一款在线免费且可视化的正则表达式工具 界面图: 只能输入由26个英文字母组成的字符串 ^[A-Za-z]$ 只能输入数字 ^[0-9]*$测试错误 测试正确 快来感受一下叭 官方网址: Regex VisRegex visualizer & editor, make the regular expr…

西门子:HMI小游戏-灰太狼与喜羊羊

DB块: HMI界面: 实际视频: 抓羊小游戏

docker各目录含义

目录含义builder构建docker镜像的工具或过程buildkit用于构建和打包容器镜像,官方构建引擎,支持多阶段构建、缓存管理、并行化构建和多平台构建等功能containerd负责容器生命周期管理,能起、停、重启,确保容器运行。负责镜管理&am…

电脑技巧:推荐一款非常好用的媒体播放器PotPlayer

目录 一、 软件简介 二、功能介绍 2.1 格式兼容性强 2.2 高清播放与硬件加速 2.3 自定义皮肤与界面布局 2.4 多音轨切换与音效增强 2.5 字幕支持与编辑 2.6 视频截图与录像 2.7 网络流媒体播放 三、软件特色 四、使用技巧 五、总结 一、 软件简介 PotPlayer播放器 …

【面试经典 150 | 回溯】括号生成

文章目录 写在前面Tag题目来源解题思路方法一:暴力法方法二:回溯 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到…

compose调用系统分享功能分享图片文件

compose调用系统分享功能图片文件 简介UI界面提供给外部程序的文件访问权限创建FileProvider设置共享文件夹 通用分享工具虚拟机验证结果参考 本系列用于新人安卓基础入门学习笔记,有任何不同的见解欢迎留言 运行环境 jdk17 andriod 34 compose material3 简介 本案…

JAVA面试专题-Redis

你在最近的项目中哪些场景使用了Redis 缓存 缓存穿透 缓存穿透:查询一个不存在的数据,mysql查询不到数据也不好直接写入缓存,导致每次请求都查数据库。 解决方案一:缓存空数据,即使查询返回的数据为空,也把…

xss漏洞学习

1.xss漏洞简介 跨站脚本(Cross-Site Scripting),本应该缩写为CSS,但是该缩写已被层叠样式脚本Cascading Style Sheets所用,所以改简称为XSS。也称跨站脚本或跨站脚本攻击。 原理:跨站脚本攻击XSS通过将恶…

SQLite如何处理CSV 虚拟表(三十七)

返回:SQLite—系列文章目录 上一篇:SQLite的DBSTAT 虚拟表(三十六) 下一篇:SQLite的扩展函数Carray()表值函数(三十八) ​ RFC4180格式是一种文本文件格式,被用于表格数据间的交互,也可将表格数据转化…

Java进阶-JINQ详解与使用

本文详细介绍了JINQ(Java Integrated Query),一种强化Java中数据查询能力的库,提供类SQL的查询语法和类型安全的操作。文章首先解释了JINQ的基本功能和应用,随后通过具体示例展示了如何使用JINQ进行数据过滤、投影、连…

Python自学篇3-PyCharm开发工具下载、安装及应用

一、Python开发工具 自学篇1中讲到了安装Python之后出现的几个应用程序,其中IDLE、Python.exe都可以用来编写python程序,也可以进行调试;但是比较基础,比较原始,调试不方便,界面也不友好,需要更…

天空卫士旗舰产品入选《网络安全专用产品指南》

权威认证 近日,中国网络安全产业联盟(CCIA)发布了第一版《网络安全专用产品指南》。这一权威指南中,天空卫士荣获殊荣,旗下三款尖端产品荣耀入选,分别是增强型Web安全网关(ASWG)、数…

解析Redis Key Prefix配置之谜:双冒号“::”的由来与作用

前言 在使用Spring Boot集成Redis进行应用开发时,为了增强缓存键的可读性和管理性,我们常常会在配置文件中设定一个全局的key-prefix。如果你发现存储至Redis的键自动附加了“::”,本文将深入探讨这一现象背后的原因,解析Spring …