一文掌握cshell编程_1(概念、案例双管齐下)

2024-08-29 15:36

本文主要是介绍一文掌握cshell编程_1(概念、案例双管齐下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

相信在IC行业中不少公司使用cshell作为脚本语言之一,很不幸的是目前网络上cshell的中文介绍少之又少,绝大部分是bash的介绍。近期有幸阅读了一本cshell cookbook,故将个人的学习心得发布于此,也希望志同道合的朋友一起探讨一番。(从看cookbook到博文的发表历时4个月,每天下完班就瞌睡的很,icer sandman无疑了,当然也是创作不易呀)。
下面我将从cshell的变量,字符处理,文件处理和基本的语句结构进行介绍。本文假设读者对cshell脚本一无所知,sandman力求写一篇白菜教程。因此,仅仅需要读者了解如何跑cshell的脚本即可,即terminal中输入source xxxx.csh。现在知道也不迟的,详细仔细阅读这篇文章对于编写或者修改cshell脚本有较大的帮助。

shell selection(shell类型选择)

通常在cshell脚本的第一行,我们需要指明脚本的类型,这有助于UNIX系统去解析对应的脚本。换句话说,系统需要知道用户source的脚本是哪一种类型的,是perl,bash,cshell还是TCL(后续sandman会慢慢的更新,但是不知道何时有空更新,随缘吧)

#!/bin/csh   #注释:正常情况下写这一条代码就可以了,因为bin目录下一般会存在csh。

有了前面的铺垫后,下面开始进入正题:

变量

cshell的变量可以分为标量,数组和特殊变量。

  1. 标量(scalar)
    set是给标量赋值的关键字。cshell中没有字符串,整型,负数以及浮点型的区别,统一使用set为标量赋值,下面看几个例子。
set colour = blue
set title = "hello world"
set float_dat = 1.23E-09
set int_dat = 9
set int_dat_s = -9

由此可知,设置变量的范式如下所示。

set VAR_NAME = VALUE #VAR_NAME: 标量名称;VALUE:标量值

另外,在某些情况下可能需要移除某个标量,被移除的标量不能在后续的程序中使用。cshell脚本中使用unset便可实现。如移除colour。

set colour = blue
#标量参与了某件事情的处理
unset colour
#由于使用unset移除了colour,因此后续不能在使用 colour这个标量

值得注意的是:unset支持字符匹配的方式,表示匹配的标量都会被移除,如下所示。

unset iso_* #表示移除名称是以iso_为前缀的所有标量,如iso_a,iso_1, iso_1234等。

另外,可能还有setenv这个关键字,该关键字表示设置系统标量,即整个系统都可以看见。移除某个系统标量的关键字为unsetenv。那么两者的区别是什么呢?setsetenv两者的区别为:可见的范围不同。

  • set定义的标量仅仅是当前脚本可见。
  • setenv定义的变量是系统可见,可以用echo输出系统标量,即echo $SYS_VAR_NAME

个人建议少用系统标量,要用也应该避免和系统中以后的标量名重复。即,假设系统中有一个标量的名字为SYS,如果我们在编写xxx.csh脚本时,一步小心写setenv SYS = 1, 那么source xxx.csh后,原本的SYS将变成1,覆盖了之前的值,这可能是灾难性的后果。

这里介绍一个使用系统标量的实际案例。有些场景中需要在cshell中调用TCL,并且不是直接调用,中间可能还包了一层或者几层的其他脚本,如Makefile。然而,我们需要把cshell中的某个标量值传递给TCL,为了简单起见且修改最少的内容,我们可以把需要传递的标量定义为系统标量,这样在TCL中我们就可以直接使用。

setenv SWCH_ME = "ON" # 定义系统标量SWCH_ME
# 下面是TCL语句
set SWCH = $ENV{SWCH_ME} #TCL中引用系统标量SWCH_ME

我想关于标量的描述有这些就够了。

  1. 数组(array)
    数组可以简单的理解为多个标量组合。即通过括号将多个标量组合起来,并且使用空格作为分隔符。其中,一个数组里面可以包含不同类型的标量,如整型,浮点型,字符型等。另外如果数组中包含了带空格的字符串,那么一定需要使用双引号将字符串包起来,否则字符串会被解析器认为是数组中的多个元素。简单示例如下所示。
set coluors = (blue yellow green red pink)
set misc = ("hello world" blue 3 -4 1.34E09)

其中,hello world不采用“”包起来的话,那么解析器就会认为hello是数组misc的一个元素,world是数组的另一个元素。
数组的范式如下所示:
在这边插一个打印数组的方式,在debug期间经常会使用,当然后文会有较为详细的介绍。

echo "info coluors array: $coluors"
echo "info misc array: $misc"
set ARR_NAME = (ELEM1 ELEM2 ELEM3)

定义好数组后,更加关键的是如何使用。下面以一个实例详细的介绍数据的使用。
定义一个数组prime:

set prime = (1 2 3 4 5 6 7 8 9)
# $#prime的结果为9;
# $prime[*]的结果为:1 2 3 4 5 6 7 8 9;
# $prime[$]的结果为:9;
# $prime[3-5]的结果为:3 4 5;
# $prime[8-]的结果为:8 9

总结如下所述:

  • $#ARR_NAME表示数组的长度,即数据包含几个元素。
  • $ARR_NAME[*]表示数组的所有元素
  • $ARR_NAME[$]表示数组的最后一个元素。[Note: $通常都是用来表示最后一个object]
  • $ARR_NAME[M-N]表示数组的第M到第N个元素。其中,数组的索引下标是从1开始,而不是0;“-”是连接符。
  • $ARR_NAME[M-]表述数组的第M到最后一个元素。

某些场景下会使用到数组的拼接。如ARR1和ARR2拼接获得ARR3。如下所示:

set ARR1 = (1 2 3)
set ARR2 = ("hello world" blue)
set ARR3 = ($ARR2 $ARR1) # ARR3的结果为"hello world" blue 1 2 3

上述实例仅仅展示两个数组的拼接(应用了数组的所有元素),当然还可以选择数组的有个元素进行拼接。如下所示:

set ARR1 = (1 2 3 4 5 6)
set ARR2 = ("hello world" blue red yellow green)
set ARR3 = ($ARR2[1] $ARR1[3] $ARR1[4]) # ARR3的结果为 1 red 4
  1. 特殊字符(special characters)
    cshell定义了一些特殊的字符,或者称为元字符。如:*, ?, [],‘’, “”, **()**以及 ****。下面将逐个介绍:
  • *:通配符之一,表示任意多个字符。通常和unset搭配使用,如:unset iso_*(移除iso_为前缀的所有标量)
  • ?: 通配符之一,表示任意一个字符。通常和unset搭配使用,如:unset iso_?(移除iso_为前缀且"_"后只有一个字符的标量)
  • []: 用于数组的索引。如:ARR1[1](索引数组的第一个元素)
  • ‘’(单引号):用于定义字符串(不推荐使用),如:‘hello world’。另外``(在键盘~位置,即ESC下方的按键)用于包装命令,即让某些命令先执行(比较常见的一种使用方式)。如:set VAR = `echo $usr` 表示将标量usr的值赋值给标量VAR。其中usr为系统预定义的标量,后面将会介绍。
  • “”(双引号):用于定义字符串,如"hello world"。
  • (): 用于定义数组或者其他的语句结构,如if…then结构
  • \: 1. 转义元字符,如字符串中想表示*(星号),则采用\*。2. 用于长命令的连接,如一条命令太长了,想要分两行写,目的是便于阅读。其中,所有的元字符都可以使用“\”进行转义。

另外:特别说明一下单引号和双引号定义定义字符串是的区别。如下所示:

set five = 5
set VAR  = 'Give me $five' # VAR的结果为:Give me $five
set VAR2 = "Give me $five" # VAR2的结果为:Give me 5

明白了吧,换句话说,**单引号内的部分的元字符不具有特殊含义,双引号内的元字符仍旧具有特殊的含义。**我个人不建议使用单引号定义字符串,没有必要为难自己。

  1. 特殊变量(special variable)
    特殊变量顾名思义具有特殊含义的标量(变量)。在cshell中我们更加关心的是source脚本时跟随的参数以及脚本的名字。即脚本跟随了几个参数,分别是什么。如:
source run.csh -seed 20230727 -cover on -dump off

其中,"-seed 20230727 -cover on -dump off"都是脚本run.csh跟随的参数。下面我将结合上述的实例进行介绍。

  • ${0}: 脚本的名字。即,run.csh(♥♥♥);
  • $?VAR_NAME: 判断标量是否被定义,若定义,则返回结果为1,否则结果为0(♥♥♥♥);
  • $n: 脚本跟随的第n个参数(♥♥)。如$1表示-seed;$2表示20230727;
  • $argv[n]: 同上(♥)。
  • $#argv: 脚本跟随参数的个数(♥♥♥♥)。即,6个参数;
  • $*: 包含脚本名称以及脚本跟随的所有参数(♥)。即,7个参数。
  • $$: 脚本的进程号。一般作为文件的时间戳(♥♥♥)。
    需要特别提醒的是
  • ♥表示友好程度。
  • 脚本是在terminal中source的,但是上述提到的特殊变量是在脚本文件中直接使用的。当然有些特殊标量不好用($n,$argv[n])。为什么呢?你想啊,由上述可知每个参数的位置固定,不然就极有可能导致脚本出现非预期的结果。例如:
source run.csh -seed 20230727 -cover on -dump off
source run.csh -cover on -dump off -seed 20230727

显然,两个的$1不同,第一个的$1是"-seed";第二个的$1是"-cover"。若脚本中使用了$1那么不就存在问题了嘛。更合理的场景是参数的位置不需要固定,以及个数也需要固定(当然不能多于预定义的数量)。这个实现方式我们先按下不表,后续会有相应的介绍。

  1. cshell 预定义的变量(predefine variable)
    cshell中预定了部分变量,我们自己写脚本是应该要避免这些变量的定义。
set user    = "sandman" # 不推荐
set user_me = "sandman" # 推荐
  • cwd: 当前所在的目录
  • home: home目录
  • status: 最后一条命令的执行状态。0:完成;1:存在错误或者异常。
  • user:用户名
    个人感觉status和user比较有用。不过一般不太用得上。

字符串

cshell中字符串的处理往往可以借助三剑客(sed, grep, awk),感兴趣的朋友可以自行学习。三剑客的内容不是本文讨论的重点。这边介绍一下常用的字符处理手段,字符串拼接和拆分。

  • 时常出现需要将字符串拼接的操作,如将多个路径相对路径拼接成绝对路径。
set root_my = "/usr"
set user_my = "sandman"
set abs_dir = "$root_my/$user_my"  # 拼接两个字符
echo "info user path: $abs_dir" # 结果为:info user path: /usr/sandman 
  • 同样也时常需要将字符串按照某种格式进行拆分,如将时间拆分成时、分、秒,并且存放于数组中。这里借用了awk的split函数,所以说呀cshell的字符处理离不开三剑客。
set time = 12:34:56
set hms_arr = `echo $time | awk '{split($0, a, ":"); for(i=1; i<3; i++) print a[i]}' `

其中,split的函数格式为split(s, a, sep) s表示需要替换的字符串,a表示拆分结果存放的数组,sep表示按规定的符号拆分。对应上述的实例,则是$0代表$time(12:34:56) ; a表示拆分结果存放在数组a中;":“表示字符串按照”:"的形式拆分。值得注意的是最外层的反引号(`)用于封装等号右边的整体;单引号的作用域是”{}“(花括号)的语句;其本质是对语句做一个层次上的区分,提高可读性,也是awk语句不可缺少的一部分;花括号内的分号(;)表示语句的分割,这个Verilog等一众语言的作用一致。

文件处理

在cshell脚本中通常需要对文件进行处理,如获取文件的类型,文件名,路径以及带类型的文件名。以路径**/project/sandman/ug/cshell.docx**为例详细的解释上述的用法:

  • :e 获取文件类型。结果为:docx
  • :r 获取文件名字。结果为:cshell
  • :h 获取路径。结果为:/project/sandman/ug/
  • :t 获取文件类型和文件名。结果为:cshell.docx

其中,需要注意的是,“:e”和“:r”都是以句号(.)作为判断依据,若无句号,则“:e”返回空字符,“:r”返回完整的路径。如**/project/sandman/ug/cshell**,则“:e”返回的结果是空字符串;“:r”返回的结果是:/project/sandman/ug/cshell

另外,有时我们还需要对文件一些逻辑判断,这显然更加常用。如判断文件是否存在,是否为空文件,是否为目录等等。下面展示文件逻辑判断使用的选项。

  • -d 是否是目录。若为真,则为目录。
  • -e 是否存在文件。若为真,则存在文件。
  • -f 是否为普通文件。若为真,则是普通文件。(如何区别特殊文件和普通文件,我也不太清楚,有懂的大佬帮忙补充一下,多谢)
  • -o 我是否是文件的owner。若为真,则是owner。
  • -r 我对文件的属性是否是可读。若为真,则可读。
  • -w 我对文件的属性是否是可写。若为真,则可写。
  • -x 我对文件的属性是否是可执行。若为真,则可执行。
  • -z 文件是否是空文件。若为真,则文件是空文件。

以上就是对文件处理的常用操作了。

基本语法结构

下面我将介绍一些cshell中常见且重要的语句,这些语句在编写脚本时95%都用的上。将从最基础的打印字符开始介绍;并且随即深入到条件判读,循环结构以及switch的介绍;最后将给出一个完整的案例。相信了解本章之后对于编写简单甚至说复杂脚本都是足够的。简单提一句我个人对于cshell脚本是哦那个的看法,我个人觉得cshell用来做一些顶层的控制,即cshell脚本作为其他脚本的顶层。理由有以下两点:

  • cshell脚本可以认为是在command line(terminal)中输入多行命令,因此其他脚本可以在cshell脚本中轻松的被调用;
  • cshell脚本还可以调用系统提供的command,如具有UNIX三剑客之称的sed/grep/awk

其中,其他脚本可以是TCL类型的,Perl类型的,Makefile类型的,python类型的。

echo

echo类似于Perl的say,systemverilog的display。其本质是输出信息到屏幕或者指定的文件。其中,echo默认是带换行符的。所以说它类似Perl的say。下面举几个例子说明echo的用法。在实际中这个语句是非常好用的。

echo "hello world" # 打印"hello world"到屏幕,用于通知用户或者debug
echo "hello world" > log.txt # 打印"hello world"到log文件
echo "five plus five: $ans" #打印5+5的结果到屏幕,通常用于debug。

if

if语句是最常用的。if的语法结构如下所示:

if(condition) thenstatement
endif

含义:如果condition为真,那么执行statement,否则不执行。最后,特别提醒,if语句结构中的thenendif,这两个一定不能少,初学者需要特别的注意,并且statement后面是不带分号的,这个cshell的分割符有关系,可以简单的记忆为cshell是通过换行进行命令或者代码分割的。

if…else

if…else语句也是相当常见的。语法结构如下所示:

if(condition) thenstatement1
elsestatement2
endif

含义:如果condition为真,则执行statement1;如果condition是非真(即假),则执行statement2。

if…else if … else

有时我们还会使用else if的情况,从另一个角度来说if…else if…else是if语法中最复杂的结构了。语法结构如下所示:

if(condition1) thenstatement1
else if(condition2)statement2
elsestatement3
endif

含义:如果condition1为真,则执行statement1;如果仅仅condition2为真,则执行statement2;如果condition1和condition2都为假,则执行statement3。其中,仅仅condition2为真,表示condition1为假。比如说,condition1和condition2同时为真。从程序的执行角度来看,会进入第一级判读,因为condition1为真,所以会执行statement1(这点毫无疑问),但是condition2也为真,那么statement2会被执行吗?答案是不会。理由:if语句中,只要有条件成立则执行对应的语句,执行完后退出if。简单来说就是statement执行完了就会退出if语句,所以statement2不会被执行。

循环

前文中对if语句进行了较为详细的介绍,下面我们将详细的介绍循环语句,分别是while和foreach,请注意是foreach而不是for,在我的记忆中cshell中没有for。

while

某些场景下,我们希望某个事件或者条件为真时始终执行某个程序块(block or statement),事件或者条件为假时不在执行。这种场景下我们首选while循环。比如:我们需要指定statement执行的次数,即执行的次数已知。语法结构如下所示:

while (condition)statement
end

含义:首先进行condition的判断,若condition为真,则执行statement,当statement执行完成后,认为while循环第一次执行完成;随后,进行第二次condition的判断,若condition仍旧为真,则再一次执行statement,当statement执行完成后,认为while循环第二次执行完成;此后再次进行condition的判断,若condition为假,则直接退出while循环。
从上面的表述中可以清晰的看出,while循环存在始终执行的情况,或者称为死循环,即condition始终为真。通常我们需要写死循环时,condition为1即可。当然condition为100也可以,因为在cshell在解析condition时认为他是一个逻辑判断,从逻辑真假来看,非0即为真,仅仅是0是才会有假。
下面列举一个采用while循环执行循环次数的情况,其中涉及到数值计算写法,这个需要读者注意。

set cnt = 0
set sum = 0
while ($cnt <3)@ sum = $sum + $cnt@ cnt = $cnt + 1
end
echo "the sum is $sum" # 答案是0+1+2=3

上述的代码块介绍了一个非常简单的累加的功能,这个示例主要是想展示while循环和cshell中的数值计算。下面我们将详细的剖析这个过程:
首先,定义了cnt和sum两者标量,并且赋值为0,即初始化标量。
其次,判断while中的condition,因为0<3,所以condition为真,执行while内的语句。此时进行数值计算,sum为0,cnt为1。请注意数值计算的格式。抽象的格式如下所示:

@ VAR_NAME = $VAR_NAME +/-/*// $VAR_NAME(or constant) # @和VAR_NAME之间存在空格。

再者,再次判断while中的condition,因为1<3,所以condition为真,再次执行while内的语句,执行结果为sum为0+1=1,cnt为2;
随后,再次判断while中的condition,因为2<3,所以condition为真,再次执行while内的语句,执行结果为sum为0+1+2=3,cnt为3;
最后,,再次判断while中的condition,因为3<3,所以condition为退出while循环。
当然while还有一个更加重要的用法,也是最常用的用法之一,就是搭配switch语句,这个将在文末中给出,这边先按下不表。

foreach

还有一种非常重要且好用的循环结构foreach,顾名思义,遍历。那么它将会便利谁呢,显然是具有多个元素的内容,那前面介绍过的数组含有多个元素。对咯,foreach一般和数组搭配使用。不过从抽象的角度来看,foreach就是遍历容器中的所有元素,这就表明我不需要循环的此时,也不需要指定循环的次数,反正它会帮我们都执行一遍。 语法结构如下所示:

foreach SUB_ELEMENT (LIST)statement
end

含义:$SUB_ELEMENT为LIST中的某个元素,例如:LIST为(1 2 3 4)那么$SUB_ELEMENT将分别为1, 2, 3, 4,且对应每次循环。如第一次循环对应的值为1, 第二次循环对应的值为2。当然,LIST中可以是字符。如果LIST中只有3个元素,那么循环只执行三次,如果LIST有100个元素,那么循环就会执行100次。我觉的一个很典型的场景就是,验证人员可能会遇到这种情况,随着验证的不断深入testlist会不断的变大,比如group1由原来的2只case,变成20只case,并且这些case可能还会继续增加,但是在跑回归时,现有Group1的所有case都是要跑一遍(即遍历)的,我们就可以借助foreach循环来进行跑回归。伪代码如下所示:

foreach sub_case (group1)run sub_case
end

其中,run xxx表示执行某只case。run是封装好的cshell或者是其他脚本,sub_case是传入的参数。其中有一点需要了解的是cshell没有子函数一说,如果你需要实现子函数的功能,那你只能重新写一个cshell的脚本,把对应的功能封装起来。

switch

下面我们来聊一聊switch语句,switch语句可以认为是if语句的加强版。通常条件判断(condition)较多时选择使用switch,这样会使代码看起来更简洁,并且可读性更强。至于选择switch还是if完全取决于个人喜好,不过对于command line传递参数的场景,我个人建议使用switch。switch语句可以认为是一个逐个匹配的过程,直到匹配成功,当然可以匹配失败。例如:我只有一把钥匙,我尝试用这把钥匙去打开五间房间中的其中一间或者多间(一般是一间),并在打开后那一个物件。当然也可能一间房间也打不开。那我首先先尝试用这把钥匙去开第一间房间,发现打不开;那么我就尝试第二间房间,如果还是打不开,那我就继续往下尝试;如果到第四间房间的时候我打开了,那么我就进房间(即执行相应的代码);如果没有使用breaksw,则退出第四间房间后会继续尝试开第五间房间。通常switch和breaksw是一起使用的,即不会尝试开第五间房间。switch…endsw语句的结构如下所示:

switch(condition)case C1:statement1breakswcase C2:statement2breakswdefault:statement_defaultbreaksw
endsw

其中,condition就是钥匙,C1,C2,default就是房间。statement就是房间我需要的物件(羽毛球拍),即需要执行的代码。breaksw表示执行完对应的statement后退出switch语句,若没有这会继续往下匹配。default表示condition和C1、C2匹配不上时一定进入default分支。需要注意的时swich语句带有一个结尾的关键字endsw。具体的实例将在最后一章节中给出,融合while和shift一起介绍,也是switch…endsw最常见的应用场景之一。

shift

shift顾名思义,移动。操作的对象时数组,将数组的元素从左往右一个接一个的移出数组。语句结构如下所示:

set ARR1 = (1 2 3)
shift ARR1 # 数组中在的内容为2 3,1被移出数组

通常command line传入脚本的参数会被作为数组对待,因此常见的使用场景就是对参数做移动操作。其中,argv(在变量章节中有详细的介绍)是cshell预定义的参数数组,即command line传入的参数都存在放在argv数组中。

常见实例

假设我们现在需要编写一个run.csh脚本用于跑仿真,通过command line传递testcase,seed,cover和dump四个参数,分别用于指定测试名,种子,是否收集覆盖率,是否dump波形。当然还需要help选项,用于打印使用信息。因此我们的选项就可以总结为:

run -testcase TC_NAME -seed SEED -cover -dump
OR
run -help
#!/bin/csh # cshell声明行
# declare variable
set tc_name  = ""      # 默认名字为空
set tc_seed  = 1       # 默认种子为1
set tc_cover = "OFF"   # 默认关闭coverage选线
set tc_dump  = "OFF"   # 默认关闭dump波形功能set args = ($argv[1-]) # 获取除了脚本名字之外的所有参数# check that there are some arguments present
if($#args == 0 || $args[1] == "-help") thenecho "usage: run [-testcase  TESECASE NAME] [-seed SEED] \[-cover] [-dump] [-help]"
endif# process each of the arguments to the script
while($#args > 0 )switch($args[1])case -testcase:shift args # remove "-testcase" elementecho "testcase name is $args[1]"set tc_name = $args[1]breakswcase -seed:shift args # remove "-seed" elementecho "the run time seed is: $args[1]"set tc_seed = $args[1]breakswcase -cover:shift args # remove "-cover" elementecho "turn on cover option"set tc_cover = "ON"breakswcase -dump:shift args # remove "-dump" elementecho "turn on cover option"set tc_dump = "ON"breakswdefault:echo "option is error, please check, and try it again"exitbreakswendswshift # remove non-option element 
end# 下面就是针对具体仿真脚本的调用了,不是本文的重点 

这篇关于一文掌握cshell编程_1(概念、案例双管齐下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118253

相关文章

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

一文全面详解Python变量作用域

《一文全面详解Python变量作用域》变量作用域是Python中非常重要的概念,它决定了在哪里可以访问变量,下面我将用通俗易懂的方式,结合代码示例和图表,带你全面了解Python变量作用域,需要的朋友... 目录一、什么是变量作用域?二、python的四种作用域作用域查找顺序图示三、各作用域详解1. 局部作

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

一文彻底搞懂Java 中的 SPI 是什么

《一文彻底搞懂Java中的SPI是什么》:本文主要介绍Java中的SPI是什么,本篇文章将通过经典题目、实战解析和面试官视角,帮助你从容应对“SPI”相关问题,赢得技术面试的加分项,需要的朋... 目录一、面试主题概述二、高频面试题汇总三、重点题目详解✅ 面试题1:Java 的 SPI 是什么?如何实现一个

MySQL 事务的概念及ACID属性和使用详解

《MySQL事务的概念及ACID属性和使用详解》MySQL通过多线程实现存储工作,因此在并发访问场景中,事务确保了数据操作的一致性和可靠性,下面通过本文给大家介绍MySQL事务的概念及ACID属性和... 目录一、什么是事务二、事务的属性及使用2.1 事务的 ACID 属性2.2 为什么存在事务2.3 事务

Java Stream.reduce()方法操作实际案例讲解

《JavaStream.reduce()方法操作实际案例讲解》reduce是JavaStreamAPI中的一个核心操作,用于将流中的元素组合起来产生单个结果,:本文主要介绍JavaStream.... 目录一、reduce的基本概念1. 什么是reduce操作2. reduce方法的三种形式二、reduce

JDK9到JDK21中值得掌握的29个实用特性分享

《JDK9到JDK21中值得掌握的29个实用特性分享》Java的演进节奏从JDK9开始显著加快,每半年一个新版本的发布节奏为Java带来了大量的新特性,本文整理了29个JDK9到JDK21中值得掌握的... 目录JDK 9 模块化与API增强1. 集合工厂方法:一行代码创建不可变集合2. 私有接口方法:接口

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

一文详解PostgreSQL复制参数

《一文详解PostgreSQL复制参数》PostgreSQL作为一款功能强大的开源关系型数据库,其复制功能对于构建高可用性系统至关重要,本文给大家详细介绍了PostgreSQL的复制参数,需要的朋友可... 目录一、复制参数基础概念二、核心复制参数深度解析1. max_wal_seChina编程nders:WAL