《数据压缩入门》笔记-Part 2

news2024/11/16 19:33:10

一篇文章显得略长,本文对应原书6-10章。序言、前言、第1-5章,请参考Part 1,第11-15章,请参考Part 3。

自适应统计编码

位置对熵的重要性

统计编码有一个问题:在编码开始之前都需要遍历一次数据,以计算出各符号出现的概率。

随之而来有两个局限性:

  • 因为数据集的不同部分有着不同的概率特征,随着要压缩的数据集的变大,统计编码的结果与熵的偏差也会越来越大;
  • 流数据如音频流或视频流,由于整个数据集没有结尾的概念,无法遍历两次。

实际数据中总会存在某种类型的局部偏态(Locality Dependent Skewing),比如某些符号、想法或单词集中出现在数据集的某个子区间里,而在其他子区间则不会出现一次。

数据压缩领域内一个重要的理论,即局部性很重要(locality matters)。

问题变成,如何根据局部特性以最佳的方式分割数据流?

如果期望的熵与实际的符号平均二进制位数之间出现显著差异,则统计编码算法会重置概率表,并使用重置后的概率表进行编码。这种具有适应数据流熵的局部特性能力的统计编码算法,通常被称为动态或自适应统计编码算法。

自适应VLC编码

统计压缩有3个步骤:

  • 遍历数据流并计算各个符号的出现概率;
  • 根据概率为符号生成VLC;
  • 再次遍历数据流并输出对应的码字。

动态创建VLC表

自适应算术编码

要将算术编码变成自适应的很容易,这主要是因为其编码步骤与概率表之间的交互很简单。只要编码器与解码器在更新概率的正确顺序上达成一致,就能根据需要更新概率表。

自适应哈夫曼编码

哈夫曼树结构的处理比较复杂。最简单的想法,每遇到一个符号就去重新生成一棵完整的哈夫曼树;但这样做会极大地影响算法的性能。

自适应哈夫曼算法的做法是,在读取和处理符号时调整现有的树,包括如下操作:

  • 更新概率;
  • 对树的大量结点变换位置并重新排序,以使它们与概率的变化同步;
  • 使树的结构满足哈夫曼树的要求。

感觉和平衡二叉树在插入、删除结点后为了保持树的平衡,而进行的左旋转、右旋转比较类似。

自适应哈夫曼算法贡献者:Faller、高德纳、Vitter。

选择

动态改进的优点:

  • 有生成符号码字对应表的能力,无须将符号码字对应表显式地存储在数据流中。数据流变小后,计算性能就能有所提高;
  • 有实时压缩数据的能力,无须再将整个数据集作为一个整体来处理。可有效地处理更大数据集,甚至都不用事先知道要处理的数据集有多大;
  • 有适应信息局部性的能力,即邻近的符号会对码字的长度有影响,这可以显著提高压缩率。

字典转换

字典转换,Dictionary Transforms,所有的主流压缩算法(如GZIP、7-Zip)都会在核心转换步骤中使用字典转换。

基本字典转换

统计压缩主要关注数据流中单个符号的出现概率,且没有考虑周围可能出现的符号。忽略真实数据的基本属性:上下文及词语的组合,或者简单地说就是短语。

字典转换:给定源数据流,首先构建出单词字典(而不是符号字典),然后再将统计压缩应用到字典中的单词上。其目标不是替代统计编码,只是先应用到数据流上的一个转换,而后统计编码就能更有效地工作。
在这里插入图片描述
字典转换实际是一个数据流的预处理阶段,经过预处理后,生成的数据集更小,比源数据流压缩率更高。当能识别出那些经常重复使用的长字符串,并为它们分配最短的码字时,字典转换的效率最高。

所以问题变成,如何找出单词。

需要分词(tokenization)技术。

很难弄清楚怎样分析字符串才能创建出最佳大小的单词,因此,不适用于任何类型的实时处理。

LZ算法

LZ,缩写取自两位研究员Abraham Lempel和Jacob Ziv名字,他们于1987年和1988年提出几种解决理想分词问题的方法,因此称为LZ77和LZ78。

LZ77和LZ78算法产生一系列的衍生算法,包括GIF图像格式中使用的LZW(即Lempel-Ziv-Welch)算法,应用于7-Zip、xz等压缩工具的LZM(即Lempel-Ziv-Markov chain)算法。这些算法也同样应用于DEFLATE这样的压缩算法中,而DEFLATE又应用于PNG图像格式、PKZIP、GZIP等压缩工具及zlib库中。

LZ算法尝试在读取字符串过程中,向前寻找当前单词是否出现过(能否匹配)而进行分词。

LZ算法将数据流分成两部分:

  • 数据流的左半部分通常被称为搜索缓冲区(search buffer),包含的是已经读过并处理过的符号;
  • 数据流的右半部分则被称为先行缓冲区(look ahead buffer),包含的是将要编码的符号。

搜索缓冲区通常只会包含32KB已经处理过的字符。在处理大规模数据或流数据时,引入滑动窗口(sliding window)思想。滑动窗口的好处:

  • 查找匹配时,不会出现性能问题;
  • 考虑到局部性原理,即在给定的数据集中相关的数据很可能分布在相似的局部区域。

它可以和统计编码结合使用。可以将记号中的偏移量、长度值以及字面值分开后,再按照类型合并,组成单独的偏移量集、长度值集和字面值集,然后再对这些数据集进行统计压缩。

3个数据集:

  • 偏移量集
  • 长度值集
  • 字面值集

变体

LZ77算法及其变体图谱:
在这里插入图片描述
LZ78算法及其变体图谱:
在这里插入图片描述
注:各个算法标注的数字表示其提出的年度。

LZ77,也叫LZ1算法,会将先行缓冲区中下一个符号的字面值作为第三个值输出。

LZSS与LZ77的主要差别:LZ77算法中,字典引用可能会比其替换的字符串还长;在LZSS中,如果被替换的字符串长度值小于收支平衡点,则这样的引用就会被忽略。此外,LZSS还会用一个标志位来区分后面的数据是字面值还是偏移量–长度值二元组这样的引用。很多流行的压缩工具比如PKZip、ARJ、RAR、ZOO和LHarc使用LZSS算法,并将其作为主要的压缩算法。值得一提的是,Game BoyAdvance游戏机的BIOS就自带解码改进后的LZSS格式补丁等功能。

LZ78或LZ2,不用距搜索缓冲区结尾的偏移量来指示匹配的位置,而是根据输入流创建字典然后再引用。

LZW:Lempel-Ziv-Welch,由Terry Welch于1984年提出,采用LZ78算法的思想,其工作原理:

  • LZW算法将字典初始化为包含所有可能的输入字符,如果用到了清空和停止符号(clear and stop codes),那么这两个符号也包括在其中;
  • 该算法扫描输入字符串以寻找更长的连续子串,直到它发现该子串在字典中不存在;
  • 当发现这样的子串时,去掉它的最后一个符号(这样它就变成当前字典中最长的子串),然后从字典中找出其索引并输出;
  • 将该子串(此时包括最后一个符号)加入字典作为新的词条;
  • 将该子串的最后一个符号作为起点,重新扫描下一个子串。

用这种方法,连续更长的子串就会作为新的词条加入字典,同时也让后续字符串编码为单值输出成为可能。该算法最适用于那些连续出现重复的数据,因为在数据的初始部分,基本看不到什么压缩,但是随着数据的增多,压缩率逐渐趋于最大值。

LZW算法成为首个在计算机中广泛采用的通用数据压缩方法。公共领域程序“compress”也采用了LZW算法,并在1986年前后就基本成为UNIX系统的标准应用程序。

后来,compress从很多UNIX分发中消失:

  • 侵犯LZW的专利权;
  • GZIP的压缩率更高,使用的是基于LZ77的DEFLATE算法。

尽可能了解数据

潜在的输入数据集的量是很大的,而每个数据集都可能以一种特殊的方式去响应一种算法。对数据集越了解,你就越能从中选择出最适合的LZ变换。

上下文数据转换

数据变换的方法有很多种,但其中有3种对现代的数据压缩来说最为重要:

  • RLE:Run Length Encoding,行程编码
  • DC:Delta Coding
  • BWT:Burrows-Wheeler transform,伯罗斯–惠勒变换

RLE

主要针对的是连续出现的相同符号聚类的现象,它会用包含符号值及其重复出现次数的元组,来替换某个符号一段连续的行程(run)

RLE算法最适用于大多数符号都连续重复出现的数据集。

需要将数据集分成两部分:字面值流和行程长度流。

通常认为RLE是单字符上下文模型,也就是说,对任何给定的符号,在编码时我们都只考虑它的前一个符号,如果这两个符号是相同的,那么行程继续;如果不相同,那么当前行程终止。

TurboRLE,RLE的变体。

增量编码

增量编码的思想:给定一组数据,相关的或相似的数据往往会集中在一起。如果这样,计算两个相邻值之间的差,就可以用其中一个值以及该差值来表示另外一个值。

增量编码的目的就是缩小数据集的变化范围。更确切地说,是为了减少表示数据集中的每个值所需要的二进制位数。

原始编码:[1,3,10,8,6]
增量编码:[1,3-1,10-3,8-10,6-8]→[1,2,7,-2,-2]

最适用于处理时间序列数据、音频和图像数据。

XOR增量编码

减法增量编码算法的问题是,结果中可能会出现负数,进而产生各种问题:

  • 在存储时需要额外的二进制位;
  • 可能会增大数据的变化范围。

可通过使用按位异或运算(bitwise exclusive OR,XOR)代替减法运算来解决这一问题。XOR会独立地对每个二进制位进行操作。XOR是一种逻辑运算,仅当两个输入不相同时结果为真。

还是以[1,3,10,8,6]为例,计算步骤示意:
在这里插入图片描述

参照系增量编码

修正的参照系增量编码

PFOR:Patched Frame of Reference Delta Coding,工作原理如下步骤所示:

  • 选择一个位宽度;
  • 遍历数据并用位对每个值编码;
  • 当遇到的值所需的编码位数大于时,将这样的离群值存储在单独的位置。

两个问题:

  • 如何选择 b b b值:使大多数值在编码时需要的位数不超过 b b b,并且可以通过它识别出那些离群值。
  • 怎样处理离群值

压缩增量编码后的数据

文本有效性

可以工作,但是由于英语文本中使用最多的是还是字母表中两头的字母,因此得到的数据中会出现很多正负数交替的情况。对于英语文本,LZ这样的算法可能会做得更好。

MTF

前移编码(move-to-front coding,MTF)。

消除捣乱符号的影响

MTF的问题:有一些捣乱的符号会打乱前面存在的符号流。一种解决方法:不是一读到某个符号就将它移到最前面,而是采取一些探索式方法慢慢地将它移到最前面。

压缩MTF

BWT

所有其他的压缩算法通常可以归为两类:统计压缩(即VLC)和字典压缩如LZ78

数据建模

多上下文编码算法:考虑最后观察到的几个符号以确定当前符号的理想编码位数。这种基于统计观察的相邻关系,通常也被称作预测编码器。也可以认为是统计压缩器的加强(on-steroids)版。它将自适应模型和多种符号码字对应表结合起来,根据前面观察到的符号,为当前符号生成尽可能短的码字。

马尔可夫链

马尔可夫链,Markov Chain,定义:马尔可夫链是一种离散的随机过程,其未来的状态只取决于现在,而与过去的历史无关。

二阶上下文,second-order context;一阶数据,first order data,context-1 data;二阶数据,second order data,context-2 data。例子如下:
在这里插入图片描述
类似地,有三阶上下文和三阶数据。

每个上下文都在某种程度上描述状态之间的转移,也可将它可视化为一棵树,每个节点代表一个活动,每次转移则有相应的概率。

一棵三阶马尔可夫链树形图
在这里插入图片描述
事件选择概率:Probabilistic Event Selection,

PageRank算法就是以马尔可夫链为基础,状态是互联网上总数大约400亿的网页,转移则是网页之间的链接。这个算法就是为了计算如果用户随机浏览,他看到每个网页的概率是多少。

马尔可夫链与压缩

部分匹配预测算法

PPM:Prediction by Partial Matching,部分匹配预测算法,John Cleary与和Ian Witten于1984年提出的马尔可夫链算法的一种具体实现。在内存消耗与计算性能方面表现都还不错。与马尔可夫链类似,PPM算法同样通过前 N N N个符号的上下文来决定第 N + 1 N+1 N+1个符号最有效的编码方式。

简单马尔可夫链会采用比较直接的实现方式,即读取当前符号并判断它是否是现有链条的延续,PPM算法的实现恰好相反。给定输入流中的当前符号,PPM算法会向前扫描 N N N个符号,并根据前 N N N个符号的上下文来决定当前符号的出现概率。如果在 N N N个符号的上下文中,当前符号的出现概率为0,PPM算法就会将上下文符号的个数减少为 N − 1 N-1 N1。为如果没有在任何上下文中发现匹配,就会做出固定的预测。

如果一个符号之前没有出现过,那么PPM算法会在输出最后一个字面值符号之前将 N N N个转义码输出。这一算法很多变体(包括PPMA、PPMB、PPMC、PPMP和PPMX)之间的主要区别,就在于它们在处理转义码过程中的细微差别。

单词查找树

要实现PPM算法,我们遇到的首要问题是如何创建一种数据结构,可以将从输入流中读取的每个字符的所有上下文(阶)存储起来,并且在需要时能快速定位到。在简单的情况下,可以通过一种被称为单词查找树(trie)的特殊树结构来实现这样的需求,这种树的每个分支都表示一种上下文。

字符的压缩

选择一个合理的 N N N

PPM算法会选择一个值,然后再根据这样的上下文长度去寻找匹配。如果没有找到匹配,就会选择更短的上下文继续寻找。这样看来,似乎上下文越长(也就是的取值越大),预测的效果越好。然而,大多数PPM算法的实现在综合考虑所需内存、处理速度以及压缩率后,将的值设定为5或者6。

一些PPM算法变体,如PPM*,尝试设置很大的 N N N值。缺点是:需要一种新的查找树结构,需要的计算资源也远比PPM多;优点是其结果比PPM算法好,能多节省约6%的存储空间。

处理未知的符号

零频问题:Zero Frequency Problem,。

几种解决方法:

  • 使用拉普拉斯估计(Laplace estimator),赋给所有“从没见过”的符号相同的伪计数值1;
  • PPMD:从没见过的符号每使用一次,伪计数值就加1。即,PPMD算法是这样估算新出现符号的概率的,即新符号的概率等于不同符号的个数与观察到的所有符号的出现次数之比。
  • PPMZ:刚开始时它的处理方式与PPM* 相同,都试图在阶上下文下找出当前符号的匹配。当找不到这样的匹配时,它就会换上完全不同的算法局部阶估计法(Local-Order-Estimator),而使用的还是基本的PPM模型,只不过预测的算法完全不同。

上下文混合算法

上下文混合算法,Context Mixing,为了找出给定符号的最佳编码,会使用两个或更多的统计模型。

上下文混合算法的两个问题:

  • 应该使用什么样的模型?
  • 应该怎样将这些模型结合起来?

模型类型

LZ、RLE、增量编码、BWT等算法基于的假设:数据的相邻性与它的最佳编码方式有关。

相邻性和局部性都只是上下文的最简单形式,而绝不是唯一的形式。

作为上下文混合算法的先驱压缩器之一,PAQ包含以下模型:

  • n n n元语法: n − g r a m s n-grams ngrams,上下文是指在被预测符号之前的个字符,与 PPM算法相同;
  • 整词 n n n元语法:whole-word n − g r a m s n-grams ngrams,忽略大小写和非字母字符(对文本文件很有用);
  • 稀疏上下文:如,被预测符号之前的第二个和第四个字节(对某些二进制文件很有用);
  • 模拟上下文:由前面的8位或16位字节的高字节位组成,对多媒体文件很有用;
  • 二维上下文:对图像、表和电子表格很有用,行的长度由找出的重复字节模式的步长决定;
  • 只针对特定文件类型的特殊模型:如x86可执行文件,BMP、TIFF或JPEG格式的图片。

PAQ在大文本压缩基准测试中经常排名靠前,最新版本之一ZPAQ在压缩人类DNA信息的比赛中获得第二名。

混合类型

将不同模型的输出结合起来有以下两种方法:

  • 线性混合:Linear Mixing,将各个模型的预测值加权平均的过程,最终的值则取决于证据权重。没有反馈回路来说明在预测如何压缩数据时我们赋给一个模型的权重是否正确。因此,当输入数据流变化时,模型的权重保持不变,最终得到的结果不但没有压缩,反而比原来需要的空间还大。
  • 逻辑混合:使用神经网络来更新权重,更新的依据则是哪个模型在过去给出最准确的预测。可解决线性混合的问题,但也有缺点:在进行数据压缩时,它需要消耗大量的内存,同时运行的时间也较长。

下一代技术

由于需要大量的内存和运行时间,这就使得上下文混合算法很难适用于移动设备。只有当需要处理的数据量很大、数据很复杂并且一直在变化时,上下文混合算法才能真正发挥作用。

换个话题

压缩可以分为两类:

  • 多媒体数据压缩:Media Specific Compression
  • 通用压缩:General Purpose Compression

多媒体数据压缩

多媒体数据压缩工具是专门设计用来压缩图像、音频、视频等多媒体数据的。

有损压缩指的是为了使数据压缩得更小,可以牺牲多媒体的质量这样的数据转换。有损数据转换的种类特别多,每一种都针对特定的多媒体文件(针对图像文件的就不太适用于音频文件)和内容类型(灰度图像与全彩图像使用的压缩算法同样不同)。

通用压缩

通用压缩工具是设计用来压缩除多媒体数据以外的其他数据。像DEFLATE、GZIP、BZIP2、LZMA和PAQ等算法,都是将各种无损转换结合起来,用来压缩诸如文本、源代码、序列化数据、二进制内容等其他不能使用有损压缩工具压缩的非多媒体文件。

大文本压缩基准测试。

谷歌对GZIP算法的改进已产生一系列压缩工具,如Snappy、Zopfli、Gipfeli、Brotli,这些工具的努力方向:更好的压缩率、更小的内存需求、更快的解压速度,每个侧重点不同。

标准的HTTP协议栈允许数据包使用GZIP和BZIP、Brotli(需要服务器端和客户端都支持)。

回报率递减困境:通过观察基准测试,经过大量努力后,只能在现有算法的基础上提高2%~10%。

实践中的数据压缩

实践出真知。

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

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

相关文章

Linux:八种重定向详解(万字长文警告)

相关阅读Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 本文将讨论Linux中的重定向相关问题,在阅读本文前,强烈建议先学习文件描述符的相关内容Linux:文件描述符详解。 重定向分为两类&#x…

智能感知,主动防御:移动云态势感知为政企安全护航

数字化时代,网络安全已成为企业持续运营和发展的重要基石。随着业务扩展,企业资产的数量急剧增加,且分布日益分散,如何全面、准确地掌握和管理资产成为众多政企单位的难题。同时,传统安全手段又难以有效应对新型、隐蔽…

【unity进阶知识1】最详细的单例模式的设计和应用,继承和不继承MonoBehaviour的单例模式,及泛型单例基类的编写

文章目录 前言一、不使用单例二、普通单例模式1、单例模式介绍实现步骤:单例模式分为饿汉式和懒汉式两种。 2、不继承MonoBehaviour的单例模式2.1、基本实现2.2、防止外部实例化对象2.3、最终代码 3、继承MonoBehaviour的单例模式3.1、基本实现3.2、自动创建和挂载单…

苏轼为何要写石钟山记?时间节点是关键

《石钟山记》不仅是苏轼的旅行笔记,亦是其人生哲学与思想的深邃自省。文中不仅详述了他对石钟山的实地勘察,亦体现了其对历史、自然及人生之独到见解。黄州生涯及其对政治与文化的洞悉,为这篇作品注入了深厚底蕴。 苏轼的黄州岁月 黄州期间…

后端回写前端日期格式化

问题 不进行格式化处理&#xff0c;就会导致传递的字符串很奇怪 解决方案 注解&#xff08;字段&#xff09; <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</…

9.创新与未来:ChatGPT的新功能和趋势【9/10】

创新与未来&#xff1a;ChatGPT的新功能和趋势 引言 在探讨人工智能的发展历程时&#xff0c;我们可以看到它已经从早期的图灵机和人工神经网络模型&#xff0c;发展到了今天能够模拟人类智能的复杂系统。人工智能的起源可以追溯到20世纪40年代&#xff0c;而它的重要里程碑包…

构建预测睡眠质量模型_相关性分析,多变量分析和聚类分析

数据入口&#xff1a;睡眠质量记录数据集 - Heywhale.com 本数据集目的是探究不同因素是如何影响睡眠质量和整体健康的。 数据说明 字段说明Heart Rate Variability心率变异性&#xff1a;心跳时间间隔的模拟变化Body Temperature体温&#xff1a;以摄氏度为单位的人工生成体…

Multisim简体中文版百度云下载(含安装步骤)

如大家所熟悉的&#xff0c;Multisim是一款基于电路仿真的软件&#xff0c;可用于电子工程师、电子爱好者和学生进行电路设计、分析和调试。Multisim具有完整的电路设计和仿真功能&#xff0c;可支持模拟电路、数字电路&#xff0c;以及混合电路。 Multisim可以模拟不同电路的…

【数据结构】排序算法系列——归并排序(附源码+图解)

归并排序 归并排序从字面上来看&#xff0c;它的大致核心应与归并有关——归并拆分开来&#xff0c;变成归类和合并&#xff0c;归类则是将数组进行有序化&#xff0c;合并则是将两个有序的数组进行合并变成一个有序的数组。 它的特点在于并不是一开始就将整个数组进行归类和…

MODBUS TCP 转 CANOpen

产品概述 SG-TCP-COE-210 网关可以实现将 CANOpen 接口设备连接到 MODBUS TCP 网络中。用户不需要了解具体的 CANOpen 和 Modbus TCP 协议即可实现将CANOpen 设备挂载到 MODBUS TCP 接口的 PLC 上&#xff0c;并和 CANOpen 设备进行数据交互。 产品特点 &#xf…

Qt 构建目录

Qt Creator新建项目时&#xff0c;选择构建套件是必要的一环&#xff1a; 构建目录的默认设置 在Qt Creator中&#xff0c;项目的构建目录通常是默认设置的&#xff0c;位于项目文件夹内的一个子文件夹中&#xff0c;如&#xff1a;build-项目名-Desktop_Qt_版本号_编译器类型_…

【Linux-基础IO】文件描述符重定向原理缓冲区

文件描述符 文件描述符的概念和原理 通过上述内容&#xff0c;我们知道使用 open 系统调用打开文件时&#xff0c;系统会返回一个文件描述符。这个描述符用于后续的文件操作。 在C语言中默认会打开三个输入输出流&#xff0c;分别是stdin&#xff0c;stdout&#xff0c;stde…

JSP(Java Server Pages)基础使用二

简单练习在jsp页面上输出出乘法口诀表 既然大家都是来看这种代码的人了&#xff0c;那么这种输出乘法口诀表的这种简单算法肯定是难不住大家了&#xff0c;所以这次主要是来说jsp的使用格式问题。 <%--Created by IntelliJ IDEA.User: ***Date: 2024/7/18Time: 11:26To ch…

Web端云剪辑解决方案,提供多轨视频、音频、特效、字幕轨道可视化编辑

传统视频剪辑软件的繁琐安装、高昂硬件要求以及跨平台协作的局限性&#xff0c;让无数创意者望而却步。美摄科技作为云端视频编辑技术的领航者&#xff0c;携其革命性的Web端云剪辑解决方案&#xff0c;正重新定义视频创作的边界&#xff0c;让专业级视频剪辑触手可及&#xff…

LeetCode 909. 蛇梯棋

LeetCode 909. 蛇梯棋 给你一个大小为 n x n 的整数矩阵 board &#xff0c;方格按从 1 到 n2 编号&#xff0c;编号遵循 转行交替方式 &#xff0c;从左下角开始 &#xff08;即&#xff0c;从 board[n - 1][0] 开始&#xff09;的每一行改变方向。 你一开始位于棋盘上的方格 …

微服务(一)

目录 一、概念 1、单体架构 2、微服务 3、springcloud 二、微服务的拆分 1、微服务的拆分原则 1.1 什么时候拆 1.2 怎么拆 2、服务调用 2.1 resttemplate 2.2 远程调用 一、概念 1、单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名…

项目启动卡住不动Property ‘mapperLocations‘ was not specified.

问题如上图所示&#xff1b; 原因&#xff1a;在mapper打了个断点&#xff01;

js实现多行文本控件textarea,根据文本内容自适应窗口全部显示

概述 本人在使用html控件textarea&#xff0c;多行显示的时候&#xff0c;希望根据后台实际的文本&#xff0c;来全部显示文本内容&#xff0c;而不用再去操作滚动条查看全部文本。 本功能实现的难点在于&#xff0c;计算当前文本显示有多少行。 软件环境 编辑器&#xff1a…

8.11Zero Crossing Detection (零交叉检测)

基本概念 零交叉检测是一种基于二阶导数的边缘检测方法&#xff0c;它通过查找二阶导数过零点来定位边缘。 注意: OpenCV没有直接提供这种检测方法&#xff0c;但可以通过结合其他函数来实现。 在OpenCV中&#xff0c;基于C的Zero Crossing Detection&#xff08;零交叉检测&…

关于PHP方面需要掌握的一些基础语法

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于【PHP的基础语法】相关内容&#xff01;…