STM32—SPI通讯协议
前言
由于I2C开漏外加上拉电阻的电路结构,使得通信线高电平的驱动能力比较弱,这就会号致,通信线由候电平变到高电平的时候,这个上升沿耗时比较长,这会限制I2C的最大通信速度,
所以,I2C的标准模式,只有100KHz的时钟频率,I2C的快速模式,也只有400KHZ,虽然I2C协议之后又通过改进电路的方式,设计出了高速模式,可以达到3.4MHZ,但是高速模式目前普及程度不是很高,所以一般情况下,我们认为I2C的时钟速度最多就是400KHZ,这个速度,相比较SPI而言,还是慢了很多的
1.SPI通信
- SPl(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线
- 四根通信线:SCK(SerialClock)、MOSl(Master Output SlaveInput)、MISO(Master Input Slave Output)、SS(Slave Select),
- SPl的主机表示,有几个从机,就开几条SS,所有从机,一人一根,都别抢,给你低电平,就说明我要找你了
- 同步,全双工
- 支持总线挂载多设备(一主多从)
- 传输速率块,SPl协议并没有严格规定最大传输速度,这个最大传输速度取决于芯片厂商的设计需求
- SPl的硬件开销比较大,通信线的个数比较多,并且通信过程中,经常会有资源浪赛的现象
SPI没有应答机制的设计,发送数据就发送,接收数据就接收,至于对面是不是存在,SPl是不管的
第一个图型号是W25Q64,是一个Flash存储器,这个模块的引脚,可以看到和刚才说的并不一样,这里CLK,就是SCK,DI和DO,就是MOSI和MISO,那D到底是MOSl还是MISO呢,我们要看一下这个芯片的身份,显然,这个芯片接在STM32上,应该是从机的身份,所以这里的Dl,数据输入,就是从机的数据输入Sl,对应需要接在主机的MO上,所以,这里的Dl就是MOSI,那另一个DO,就是MISO了,一般在这种始终作为从机的设备上,可能会用DI和DO的简写,像STM32这种,可以进行身份转换的设备,般都会把MOSI、MISO的全程写完整,那最后一个CS片选,其实就是SS从机选择了
第三个是一个2.4G元线通信模块,芯片型号是NRF24L01,这个芯片使用的就是SPI通信协议,要想使用这个芯片来进行无线通信,那就需要利用SPI,来读写这个芯片
最后一个就是常见的Micro SD卡了,这个SD卡,官方的通信协议是SDIO,但是它也是支持SPl协议的,我们可以利用SPI,对这个SD卡进行读写操作
2.硬件电路
- 所有SPI设备的SCK、MOSI、MISO分别连在一起
- 主机另外引出多条SS控制线,分别接到各从机的SS脚
- 输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
左边这里,是SPI主机,主号整个SP总线,主机,一般都是控制器来作,比如STM32,下面这里,SPI从机1、2、3,就是挂载在主机上的从设备了,比如存储器、显示屏、通信模块、传感器等等,左边SPI主机实际上引出了6根通信线,因为有3个从机,所以SS线需要3根,再加SCK、MOSI、MISO,就是6根通信线,当然SPI所有通信线都是单端信号,它们的高低电平都是相对GND的电压差,所以,单端信号,所有的设备还需要共地,这里GND的线没画出来,但是是必须要接的,然后如果从机没有独立供电的话,主机还需要再额外引出电源正极VCC,给从机供电
然后我们看一下这几根通信线,首先,SCK时钟线,时钟线完全由主机掌控,所以对于主机来说,时钟线为输出,对于所有从机来说,时钟线都为输入,这样主机的同步时钟,就能送到各个从机了,然后下一个,MOSI,主机输出从机输入,这里左边是主机,所以就对应MO,主机输出,下面三个都是从机,所以就对应S1,从机输入,数据传输方向是,主机通过MOSI输出,所有从机通过MOSI输入,接着下一个,MISO,主机输入从机输出,左边是主机,对应MI,下面三个是从机,对应SO,数据传输方向是,三个从机通过MISO输出,主机通过MISO输入
12C并不是不想使用更快的推挽输出,而是12C要实现半双工,经常要切换输入输出,另外I2C又要实现多主机的时钟同步和总线体裁,这些功能,都不允许12C使用推挽输出,要不然一不小心,就电源短路了,所以,12C选择了更多的功能,自然就要放弃更强的性能了
对SPI来说,首先SPI不支持多主机,然后SPI又是全双工,SPI的输出引脚始终是输出,输入引脚始终是输入,基本不会出现冲突,所以SPI可以大胆地使用推挽输出,不过当然,SPl实还是有一个冲突点的,就是图上的MISO引脚,主机一个是输入,但是三个从机全都是输出,如果三个从机都始终是推挽输出,势必会导致冲突,所以在SPIl协议里,有一条规定,就是,当从机的SS引l脚为高电平,也就是从机未被选中时,它的MISO引脚,必须切换为高阻态,高阻态就相当于引脚断开,不输出任何电平,这样就可以防止,一条线有多个输出,而导致的电平冲突的问题了,在SS为低电平时,MISO才允许变为推挽输出,这就是SPl对这个可能的冲突做出的规定,一般是写在从机里,所以我们主机的程序中,并不需要关注这个问题
3.移位示意图
这个移位示意图是SPI硬件电路设计的核心,只要你把这个移位示意图搞懂了,那无论是上面的硬件电路,还是我们等会学习的软件时序,理解起来都会更加轻松,SPl的基本收发电路,就是使用了这样一个移位的模型,左边是SPI主机,里面有一个8位的移位寄存器,右边是SP从机,里面也有一个8位的移位寄存器,左侧的移位寄存器有一个时钟输入端,因为SPI一般都是高位先行的,所以,每来一个时钟,移位寄存器都会向左进行移位,从机中的移位寄存器也是同理,然后呢,移位寄存器的时钟源,是由主机提供的,这里叫作波特率发生器,它产生的时钟驱动主机的移位寄存器进行移位,同时,这个时钟也通过SCK引脚进行输出,接到从机的移位寄存器里
之后,上面移位寄存器的接法是主机移位寄存器左边移出去的数据,通过MOSO引脚,输入到从机移位寄存器的右边,从机移位寄存器左边移出去的数据,通过MISO引脚,输入到主机移位寄存器的右边
工作流程:首先,我们规定波特率发生器时钟的上升沿,所有移位寄存器向左移动一位,移出去的位放到引脚上,波特率发生器时钟的下降沿,引脚上的位,采样输入到移位寄存器的最低位,接下来,假设主机有个数据10101010要发送到从机,同时,从机有个数据01010101要发送到主机,那我们就可以驱动时钟先产生一个上升沿,这时,所有的位,就会像这样,往左移动一次,那从最高位移出去的数据就会放到通讯线上,数据放到通信线上,实际上是放到了输出数据寄存器,此时MOSI数据是1,所以MOSl的电平就是高电平,这就是第一个时钟上升沿执行的结果 之后,时钟继续运行,上升沿之后,下一个边沿就是下降沿,在下降沿时,主机和从机内,都会进行数据采样输入,也就是,MOSI的1,会采样输入到从机这里的最低位,MISO的0,会采样输入到主机这里的最低位,这就是第一个时钟结束后的现象
下一个上升沿,同样的操作,移位输出,SPl的运行过程就是这样,SPl的数据收发,都是基于字节交换,这个基本单元来进行的,当主机需要发送一个字节,并且同时需要接收一个字节时,就可以执行一下字节交换的时序,这就完成了发送同时接收的目的
如果我只想发送,不想接收,怎么办呢,其实很简单,我们仍然调用交换字节的时序,发送,同时接收,只是,这个接收到的数据,我们不看它就行了,那如果我只想接收,不想发送,怎么办呢,同理,我们还是调用交换字节的时序,发送,同时接收,只是,我们会随便发送一个数据,只要能把从机的数据置换过来就行了,我们读取置换过来的数据,不就是接收了嘛,这里我们随便发过去的数据,从机也不会去看它,当然这个随便发送的数据并不是真的随便发,般在接收的时候,我们会统一发送0x00或OxFF去跟从机换数据
4.SPI时序基本单元
期间一直都是低电平
CPOL(Clock Polarity)时钟极性、和CPHA(Clock Phase)时钟相位
模式0和1的区别:模式0把这个数据变化的时机给提前了,在实际应用中,模式0的应用是最多的
4.1 模式0
与模式一区别CPHA=1,就是这个模武0的数据移出移入的时机,会提取半个时钟,也就是相位提前了,模式0在SCK第一个边沿就要移入数据,但是数据总得先移出,才能移入,对吧,所以在模式0的配置下,SCK第一个边沿之前,就要提前开始移出数据了,或者把它称作是在第0个边沿移出,第1个边沿移入
时序:首先,SS下降沿开始通信,现在SCK还没有变化,但是SCK一旦开始变化,就要移入数据了,所以此时趁SCK还没有变化,SS下降沿时,就要立刻触发移位输出,所以这里MOSI和MISO的输出,是对齐到SS的下降沿的,或者说,这里把SS的下降沿,也当作时钟的一部分了,那SS下降沿触发了输出,SCK上升沿,就可以采样输入数据了,这样B7就传输完毕,之后,SCK下降沿,移出B6,上升沿移入数据,最终在第8个上升沿时最终在第8个上升沿时,整个字节交换完成,之后,SCK还有一个下降沿,如果主机只需要交换一个字节就结束,那在这个下降沿时,MOSI可以置回默认电平,或者不去管它,MISO也会变化一次,这一位,实际上是下一个字节的B7
因为这个相位提前了,所以下一个字节的B7会露个头,如果不需要的话,SS上升沿之后,从机MISO置回高阻态,这是交换一个字节就结束,如果主机想交换多个字节的话,那就继续调用,从这里到这里的时序,在随后一个下降沿,主机放下一个字节的B7,从机也放下一个字节的B7,SCK上升沿,正好接着采样第二个字节的B7.这样时序才能拼接的上,对吧
4.2 模式1
在SS未被选中时,SCK默认是低电平的,然后CPHA=1,表示SCK第一个边沿移出数据,第二个边沿移入数据(采样),
第一个SS,从机选择在通信开始前,SS为高电平,在通信过程中,SS始终保持低电平,通信结束,SS恢复高电平
然后最下面一个MISO这是主机输入,从机输出,因为有多个从机输出连在了一起,如果同时开启输出,会造成冲突,所以,我们的解决方法是,在SS未被选中的状态,从机的MISO引脚必须关断输出,即配置输出为高阻状态,SS高电平时,MISO用一条中间的线,表示高阻态,SS下降沿之后,从机的MISO被允许开启输出,SS上升沿之后,从机的MISO必须置回高阻态
然后,我们看一下移位传输的操作,因为CPHA=1,SCK第一个边沿移出数据,所以这里可以看出,SCK第一个边沿,就是上升沿,主机和从机同时移出数据,主机通过MOSI移出最高位,此时MOSl的电型就表示了主机要发送数据的B7,从机通过MISO移出最高位,此时MISO表示从机要发送数据的B7,然后时钟运行,产生下降沿,此时主机和从机同时移入数据,也就是进行数据采样,这里主机移出的B7,进入从机移位寄存器的最低位,从机移出的B7,进入主机移位寄存器的最低位,这样,一个时钟脉冲产生完毕,一个数据位传输完毕,接下来就是同样的过程,最后一个下降沿,数据B0传输完成,至此,主机和从机就完成了一个字节的数据交换如果主机只想交换一个字节,那这时就可以置SS为高电平,结束通信了,在SS的上升沿,MOSl还还可以再变化一次,将MOSI置到一个默认的高电平或低电平,当然也可以不去管,因为SPI也没有硬性规定MOSI的默认电平,然后MISO,从机必须得置回高阻态,此时如果主机的MISO为上拉输入的话,那MISO引脚的电平就是默认的高电平,如果主机MISO为浮空输入那MISO引脚的电平不确定,这是交换一个字节就结束的流程
那如果主机还想继续交换字节呢,在此时,主机就不必把SS置回高电平了,直接重复一下,从这里到这里,交换一个字节的时序,这样就可以交换多个字节了
4.3 模式2
模式0和2的区别:就是SCK的极性取反一下,剩下的流程上的东西,完全一致
4.4 模式3
模式1和3的区别:也是模武1的CPOL=0,模式3的CPOL=1,两者的波形,也是SCK的极性取反一下
这个CPHA表示的是时钟相位,决定是第一个时钟采样移入还是第二个时钟采样移入,并不是规定上升沿采样还是下降沿采样的,当然,在CPOL确定的情况下,CPHA确实会改变采样时刻的上升沿和下降沿,比如,模式0的时候,是SCK上升沿采样移入,模式1的时候,是SCK下降沿采样移入,这个了解一下,CPHA决定是第几个边沿采样,并不能单独决定是上升沿还是下降沿
然后在这4种模式里模式0和模式3,都是SCK上升沿采样,模式1和模式2,都是SCK下降沿采样
5.SPI时序(W26Q86)
当然每个芯片对SPI时序字节流功能的定义不一样,在这里,我是以我们本课程使用的芯片W25Q64,SPIl对字节流功能的规定,不像12C那样,12C的规定一般是,有效数据流第一个字节是寄存器地址,之后依次是读写的数据,使用的是读写寄存器的模型
而在SPI中,通常采用的是指令码加读写数据的模型,这个过程就是,SPl起始后,第一个交换发送给从机的数据,一般叫作指令码,在从机中,对应的会定义一个指令集,当我们需要发送什么指令时,就可以在起始后第一个字节,发送指令集里面的数据,这样就能指导从机完成相应的功能了,不同的指令,可以有不同的数据个数,有的指定,只需要一个字节的指令码就可以完成,比如W25Q64的写使能、写失能等指令,而有的指令,后面就需要再跟要读写的数据,比如W25Q64的写数据、读数据等,写数据,指令后面就得跟上,我要在哪里写,我要写什么,对吧,读数据,指令后面就得跟上,我要在那里读,我读到的是什么,对吧,这就是指令码加读写数据的模型,在SPI从机的芯片手册里,都会定义好指令集,什么指令对应什么功能,什么指令,后面得跟上什么数据
5.1 发送指令
首先是SPI发送指令,这个指令的功能是向SS指定的设备,发送指令(0x06),指令0x06,到底代表什么意思,可以由芯片厂商自己规定,在W25Q64芯片里,这个0x06代表的是写使能
在这里,我们使用的是SPI模式0,在空闲状态时,SS为高电平,SCK为低电平,MOSI和MISO的默认电平没有严格规定,然后,SS产生下降沿,时序开始,在这个下降沿时刻,MOSI和MISO就要开始变换数据了,MOSl,由于指令码最高位仍然是0,所以这里保持低电平不变,MISO,从机现在没有数据发给主机,引脚电平没有变换,实际上W25Q64不需要回传数据时,手册里规定的是MISO仍然是高阻态,从机并没有开启输出,不过这也没问题,反正这个数据我们也不要看,那这里因为STM32的MISO是上拉输入,所以这里MISO呈现高电平,之后,SCK第一个上升沿,进行数据采样,我这里画了一条绿线,从机采样输入,得到0,主机采样输入,得到1,之后继续,第二个时钟,主机数据位仍然是0所以波形仍然没有变化,然后这样一位一位地发送、接收、发送、接收,
到这一位,数据才开始变化,主机要发送数据1,下降沿,数据移出,主机将1移出到MOSl,MOSI变为高电平,这里因为是软件模拟的时序,所以MOSl的数据变化有些延迟,没有紧贴SCK的下降沿,不过这也没关系,时钟是主机控制的,我们只要在下一个SCK上升沿之前完成变化就行了,然后,SCK上升沿,数据采样输入,在最后一位呢,下降沿,数据变化,MOSI变为0,上升沿,数据采样,从机接收数据,SCK低电平是变化的时期,高电平是读取的时期
时序SCK最后一个上升沿结束,一个字节就交换完毕了,因为写使能是单独的指令,不需要跟随数据,SPI只需要交换一个字节就完事了,所以最后,在SCK下降沿之后,SS置回高电平,结束通信,总结一下,就是主机用0x06换来了从机的0xFF,当然实际上从机并没有输出,这个0xFF是默认的高电平,不过,这个0xFF,没有意义,我们不用管,那整个时序的功能,就是发送指令,指令码是0x06,从机一比对事先定义好的指令集,发现0x06是写使能的指令,那从机就会控制硬件,进行写使能,这样一个指令从发送到执行,就完成了,这就是发送单字节指令的时序
5.2 指定地址写
因为我们这个W25Q64芯片有8M字节的存储空间,一个字节的8位地址肯定不够,所以这里地址是24位的,分3个字节传输
首先,SS下降沿,开始时序,这里,MOS|空闲时是高电平,所以在下降沿之后,SCK第一个时钟之前,可以看到,MOSI变换数据,由高电平变为低电平,然后SCK上升沿,数据采样输入,后面还是一样,下降沿变换数据,上升沿采样数据,8个时钟之后,一个字节交换完成,我们用0x02,换来了0xFF,其中发送的0x02,是一条指令,代表这是一个写数据的时序,接收的0xFF,不需要看,那既然是写数据的时序,后面必然还要跟着写的地址和数据了,所以在最后一个下降沿时刻,因为我们后续还要继续交换字节,所以在这个下降沿,我们要把下一个字节的最高位放到MOSI上,当然下一个字节的最高位仍然是0,所以这里数据没有变化,之后还是同样的流程,交换一个字节,第二个字节,我们用0x12,换来了0xFF,根据W25Q64芯片的规定,写指令之后的字节,定义为地址高位,所以这个0x12,就表示发送地址的23~16位,
之后继续,看一下,交换1个字节,发送的是0x34,这个就表示发送地址的15~8位,之后还是交换一个字节,发送的是0x56,这个表示发送地址的7~0位,24位地址就发送完毕了,从机收到的24位地址是0x123456,
那3位地址结束后就要发送写入指定地址的内容了,我们继续调用交换一个字节,发送数据,这里的波形是0x55,这就表示,我要在0x123456地址下,写入0x55这个数据,最后,如果只想写入一个数据的话,就可以SS置高电平,结束通信了,当然,这里也可以继续发送数据,SPI里,也会有和I2C一样的地址指针,每读写一个字节,地址指针自动加1,如果发送一个字节之后,不终止,继续发送的字节就会依次写入到后续的存储空间里,这样就可以实现从指定地址开始,写入多个字了,这就是SPI写入的时序
由于SPI没有应答机制,所以交换一个字节后,就立刻交换下一个字节就行了,然后这条指令,我们还可以看出,由于整个流程,我们只需要发送的功能,并没有接收的需求,所以MISO这条接收的线路,就始终处于“挂机”的状态,我们并没有用到,这就是SPI指定地址写的逻辑,当然不同的芯片肯定有不同的规定了,我们这个存储器的容量大,所以需要连续指定3个字节的地址,如果容量小的话,可能1个字节的地址就够了,或者有的芯片会直接把地址给融合到指令码里去
5.3 指定地址读
所以这里,3个字节地址交换完之后,我们要把从机的数据搞过来,我们还是交换一个数据,来个抛砖引玉,我们随便给从机一个数据,当然一般给FF就行了,然后从机,此时不传,更待何时啊,这时从机就会乖乖地把0x123456地址下的数据通过MISO发给主机,可以看到,这样的波形,就表示指定地址下的数据是0x55,这样主机就实现了指定地址读一个字节的目的,然后如果我们继续抛砖引玉,那么从机内部的地址指针自动加1,从机就会继续把指定地址下一个位置的数据发过来,这样依次进行,就可以实现指定地址接收多个字节的目的了,然后最后,数据传输完毕,
SS置回高电平,时序结束
当然,时序这里也会有一些细节,比如,由于MISO是硬件控制的波形,所以它的数据变化,都可以紧贴时钟下降沿,另外,我们可以看到,MISO数据的最高位实际上是在上一个字节,最后一个下降沿,提前发生的,因为这是SPI模式0,所以数据变化都要提前半个周期
相关文章:

STM32—SPI通讯协议
前言 由于I2C开漏外加上拉电阻的电路结构,使得通信线高电平的驱动能力比较弱,这就会号致,通信线由候电平变到高电平的时候,这个上升沿耗时比较长,这会限制I2C的最大通信速度, 所以,I2C的标准模…...

Android 安装过程五 MSG_INSTALL消息的处理 安装
现在马上进入正式的安装流程。 从前面文章 Android 安装过程四 MSG_INSTALL消息的处理 安装之前的验证知道,在验证之后没有什么问题的情况下,会回调onVerificationComplete()方法,它位于PackageInstallerSession类中。 private void onVe…...

大数据开发--1.3 Linux的常用命令大全
目录 一. 终端命令格式 命令格式 说明: 二. 显示文件列表命令 -ls 作用 格式 ls常用选项 案例 三. 目录操作命令 -pwd 作用 格式 案例 四. 目录操作命令 -cd 作用 格式 案例 五. 目录操作命令 -mkdir 作用 格式 案…...

使用PuTTY连接到Amazon Linux实例
PuTTY 是一款免费的 SSH 客户端,广泛用于从 Windows 系统连接到 Linux 实例。如果你使用的是 Windows Server 2019 或更高版本,可以考虑使用内置的 OpenSSH 工具,但 PuTTY 依然是一个非常受欢迎的选择。 一、先决条件 在使用 PuTTY 连接到 …...

Nexus搭建maven私有仓库
内网访问,内网团队使用一个服务缓存节省外网宽带。 微服务开发中加速 Maven 项目构建,加快团队合作,提高工作效率 允许上传和下载私有库,并且不被外部访问,安全 稳定。 方便内部项目服务的依赖引用,而不需要…...

留存率的定义与SQL实现
1.什么是留存率 留存率是指在特定时间段内,仍然继续使用某项产品或服务的用户占用户总数的百分比。 通常,留存率会以日,周,或月为单位进行统计和分析。 2.SQL留存率常见问题 1.计算新用户登录的日期的次日留存率以及3日留存率 …...

Java的锁机制详解
在并发编程中,锁 是用于控制多个线程对共享资源进行访问的工具。Java提供了多种锁机制,从最基础的 synchronized 到高级的 ReentrantLock,这些锁帮助我们确保线程安全,并能有效避免数据竞争和死锁问题。 1. synchronized 关键字…...

用户登录与信息管理:实现小程序登录与用户信息存储
用户登录与信息管理:实现小程序登录与用户信息存储 在现代的移动应用中,用户登录与信息管理是构建个性化用户体验的基础。小程序作为轻量级的应用形式,在简化开发流程的同时,也需要我们妥善管理用户的登录状态与用户信息。本文将…...

Java如何调用构造函数和方法以及使用
调用构造函数的格式 构造函数在创建新对象时被调用。调用格式如下: ClassName objectName new ClassName(parameters); ClassName:你需要创建其实例的类的名称。 objectName:你将创建的对象的名称。 parameters:如果你使用的是…...

TFBoys谁最重
题目 使用go语言设计一个程序计算TFBoys谁最重,要求使用结构体表示TFBoys三个成员,设计函数计算三个重量的最大值。 程序 package main import ("fmt") type Person struct {Name stringWeight float64} func (p Person) GetWeigh…...

scp 通过中间机器进行远程拷贝
有时候,我们想要通过 scp将一台机器上的文件拷贝至另外一台机器,但这两台机器可能没有直接联通,需要通过中间机器进行跳转才能访问,一个麻烦的办法就是,先将文件拷贝至中间机器,然后再从中间机器拷贝至另外…...

探索 Python 高精度计算的奥秘:mpmath 库全解析
文章目录 探索 Python 高精度计算的奥秘:mpmath 库全解析背景:为何选择 mpmath?第二部分:mpmath 是什么?第三部分:如何安装 mpmath?第四部分:mpmath 函数使用示例第五部分࿱…...

<<迷雾>> 第10章 用机器做一连串的加法(1)--使用两排开关分别给出被加数和加数 示例电路
info::操作说明 鼠标单击逻辑输入切换 0|1 状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch10-01-5-bit-adder.txt 原图...

Stable Diffusion最新版nowebui的api使用详解
最近在使用stable diffusion最新版的Stable Diffusion WebUI Forge进行api调用,下面来一步一步的进行展开吧!!! 1、下载lllyasviel/stable-diffusion-webui-forge GitHub - lllyasviel/stable-diffusion-webui-forgeContribute to lllyasviel/stable-diffusion-webui-for…...

云服务器架构详解:X86计算_ARM_GPU/FPGA/ASIC_裸金属_超级计算集群
阿里云服务器架构有什么区别?X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、超级计算集群有什么区别?阿里云服务器网aliyunfuwuqi.com分享云服务器ECS架构详细说明: 阿里云服务器ECS架构说明 阿里云服务器ECS架构 X86计算 X86计算架…...

高级java每日一道面试题-2024年10月4日-数据库篇-MySQL索引底层结构为什么使用B+树?
如果有遗漏,评论区告诉我进行补充 面试官: MySQL索引底层结构为什么使用B树? 我回答: 该面试题本质还是在考察B树的数据结构和在数据库系统中的应用,下边是详细的回答。 B树的基本特性 B 树的结构特点 非叶子节点只存储键值信息,不存储…...

【JVM】内存分析工具JConsole/Visual VM
1 缘起 日常补充JVM调优,调优实践前需要学习一些理论做支撑, JVM调优三步:理论>GC分析>JVM调优, 我们会有一些玩笑话说,做了这么久Java开发,做过JVM调优吗? 做过,面试时。当然…...

一静 、二平 、三忍 、四让、五淡
一静 、二平 、三忍 、四让、五淡。 作者:儒风君 来源:儒风大家(ID: rufengdajia) 古人为人、处事、修身,都有独特的章法。 一静、二平、三忍、四让、五淡。 说透中国人的大智慧。 1 静 《道德经》里讲:“清静为天下正。”…...

js 深入理解函数(一):函数的本质
目录 概述1. 箭头函数2. 函数名 :指向函数的指针3. 理解参数3.1 arguments 对象的作用3.2 arguments 的注意点3.3 箭头函数中的参数 4. 没有重载5. 默认参数值5.1 ES 6 支持显示定义默认参数5.2 传 undefined 等于没有传值5.3 arguments 不反映参数默认值5.4 默认值…...

MySql表结构设计
创建 create table 表名(字段1 字段类型 [约束] [comment 字段1注释],...) [comment 表注释];约束是作用于表中字段上的规则,用于限制存储在表中的数据。它的目的是保证数据库中数据的正确性、有效性和完整性。 约束描述关键字非空约束限制该字段不能为nullnot nu…...

java:pdfbox 3.0 去除扫描版PDF中文本水印
官网下载 https://pdfbox.apache.org/download.html下载 pdfbox-app-3.0.3.jar cd D:\pdfbox 运行 java -jar pdfbox-app-3.0.3.jar java -jar pdfbox-app-3.0.3.jar Usage: pdfbox [COMMAND] [OPTIONS] Commands:debug Analyzes and inspects the internal structu…...

python知识点100篇系列(17)-替换requests的python库httpx
Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,使用Requests可以轻而易举的完成浏览器可有的任何操作。 但是在python3.6之后,出现了一个requests的替代选项; httpx httpx是Python新一代的网络请求库…...

python 实现graph list图列算法
graph list图列算法介绍 图列(Graph List)算法通常指的是在图的表示中,使用列表(List)或更具体地说,邻接表(Adjacency List)来表示图的一种算法。邻接表是图的一种常见表示方法&…...

LFU算法 初始频率 动态频率
LFU(Least Frequently Used)算法是一种缓存淘汰策略,其核心思想是根据数据的访问频率来决定淘汰哪些数据。具体来说, LFU算法认为如果一个数据在过去一段时间内被访问的次数很少,那么它在未来被再次访问的概率也…...

Spring Boot 进阶-详解SpringBoot的复杂数据校验规则
在之前的文章中,我们介绍了SpringBoot整合JSR-303规则来完成数据校验操作。接下来我们来聊一聊关于数据校验的具体用法。 之前的文章中举过一个简单的例子通过学生信息提交的例子来介绍了关于数据校验如何去做。那么接下来这篇文章,我们就来看看对于一些复杂的数据校验如何完…...

wsl环境下安装Ubuntu,并下载MySQL5.7
安装操作需root权限,切换root用户有两种方式: 1-通过 sudo su - ,切换到root用户(登录后长期有效)。 2-在每一个命令前加上sudo,临时提升权限(仅对一条命令有效)。 1、下载apt仓库…...

倪师学习笔记-天纪-01
一、概要 介绍课程内容,介绍部分概念 二、具体内容 1、天纪内容 天机道:看象,使用斗数等工具人间道:看卦,使用易经地脉道:看风水地理 2、神 神与形对应,形是神的实例,神是形的…...

深入理解缓存穿透、缓存击穿和缓存雪崩
在现代分布式系统中,缓存是提升系统性能和减轻数据库负载的重要组件。然而,在实际应用中,我们可能会遇到一些缓存问题,如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。 一,…...

【玩转动态规划专题】70. 爬楼梯【简单】
【玩转动态规划专题】70. 爬楼梯【简单】 1、力扣链接 https://leetcode.cn/problems/climbing-stairs/description/ 2、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1&…...

前端开发设计模式——组合模式
目录 一、组合模式的定义和特点 1.定义 2.特点: 二、组合模式的实现方式 1.定义抽象组件类 2.创建叶节点类 3.创建组合类: 三、组合模式的应用场景 1.界面布局管理 2.菜单系统构建 3.组件库开发 四、组合模式的优点 1.简化客户端代码 2.增…...