GO学习记录

一、Go语言的源文件的拓展是.go

        开发环境和工具:GOLAND

个人版开发:

企业版开发:

二、Go语言结构

        1、package main  定义一个名为main的包名

        2、import "fmt"    添加fmt包

        3、func main()    是程序开始执行的函数

        4、定义变量:var  a  int  =  21  (和C不同,变量名放在了变量类型前面)

        5、//单行注释     /*......*/多行注释

  在goland编辑器中
    单行注释的快捷键是    Ctrl+/
    多行注释的快捷键是    Alt+Shift+/

        6、fmt.Println(...) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n

        7、当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:

                Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序

                需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小

                写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面

                向对象语言中 的 protected )

        注:

func main()  
{  // 错误,{ 不能在单独的行上
    fmt.Println("Hello, World!")
}

三、Go语言风格

        1.程序一般由关键字、常量、变量、运算符、类型和函数组成

        2.Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

            声明变量的一般形式是使用 var 关键字:

        3.常量是一个简单值的标识符,在程序运行时,不会被修改的量。

           常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

           例:显式类型定义: const b string = "abc"     隐式类型定义: const b = "abc"

       多重赋值const a, b, c = 1, false, "str" //多重赋值

                    多个相同类型的声明可以简写为:const c_name1, c_name2 = value1, value2

        4.常量还可以用作枚举:

const (
    Unknown = 0
    Female = 1
    Male = 2
)
数字 0、1 和 2 分别代表未知性别、女性和男性。

常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过

        5.iota,特殊常量,可以认为是一个可以被编译器修改的常量。

                iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行

                常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

                iota 可以被用作枚举值:

const (
    a = iota
    b = iota
    c = iota
)
第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;
所以 a=0, b=1, c=2 可以简写为如下形式:

const (
    a = iota
    b
    c
)

实例

package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}

        6.Go的算数运算符    A=10,B=20

运算符描述实例
+相加A + B 输出结果 30
-相减A - B 输出结果 -10
*相乘A * B 输出结果 200
/相除B / A 输出结果 2
%求余B % A 输出结果 0
++自增A++ 输出结果 11
--自减A-- 输出结果 9

        7.Go的关系运算符    A=10,B=20

运算符描述实例
==检查两个值是否相等,如果相等返回 True 否则返回 False。(A == B) 为 False
!=检查两个值是否不相等,如果不相等返回 True 否则返回 False。(A != B) 为 True
>检查左边值是否大于右边值,如果是返回 True 否则返回 False。(A > B) 为 False
<检查左边值是否小于右边值,如果是返回 True 否则返回 False。(A < B) 为 True
>=检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。(A >= B) 为 False
<=检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。(A <= B) 为 True

        8.Go的逻辑运算符

运算符描述实例
&&逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。(A && B) 为 False
||逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。(A || B) 为 True
!逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。!(A &

        9.Go的位运算符

Go 语言支持的位运算符如下表所示。假定 A 为60,B 为13:

运算符描述实例
&按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。(A & B) 结果为 12, 二进制为 0000 1100
|按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或(A | B) 结果为 61, 二进制为 0011 1101
^按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(A ^ B) 结果为 49, 二进制为 0011 0001
<<左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。A << 2 结果为 240 ,二进制为 1111 0000
>>右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。A >> 2 结果为 15 ,二进制为 0000 1111

        10.Go的赋值运算符

运算符描述实例
=简单的赋值运算符,将一个表达式的值赋给一个左值C = A + B 将 A + B 表达式结果赋值给 C
+=相加后再赋值C += A 等于 C = C + A
-=相减后再赋值C -= A 等于 C = C - A
*=相乘后再赋值C *= A 等于 C = C * A
/=相除后再赋值C /= A 等于 C = C / A
%=求余后再赋值C %= A 等于 C = C % A
<<=左移后赋值C <<= 2 等于 C = C << 2
>>=右移后赋值C >>= 2 等于 C = C >> 2
&=按位与后赋值C &= 2 等于 C = C & 2
^=按位异或后赋值C ^= 2 等于 C = C ^ 2
|=按位或后赋值C |= 2 等于 C = C | 2

11.Go的其它运算符

下表列出了Go语言的其他运算符。

运算符描述实例
&返回变量存储地址&a; 将给出变量的实际地址。
*指针变量。*a; 是一个指针变量

12.Go的运算符优先级

有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:

优先级运算符
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

四、Go语言条件语句

1.if语句

(if 语句 由一个布尔表达式后紧跟一个或多个语句组成)

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
}

例子:
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 10
 
   /* 使用 if 语句判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" )
   }
   fmt.Printf("a 的值为 : %d\n", a)
}

以上代码执行结果为:

a 小于 20
a 的值为 : 10

2.if..else语句

(if 语句后可以使用可选的else语句,else语句中的表达式在布尔表达式为 false 时执行)

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else {
  /* 在布尔表达式为 false 时执行 */
}

例子:
package main

import "fmt"

func main() {
   /* 局部变量定义 */
   var a int = 100;
 
   /* 判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" );
   } else {
       /* 如果条件为 false 则执行以下语句 */
       fmt.Printf("a 不小于 20\n" );
   }
   fmt.Printf("a 的值为 : %d\n", a);

}

以上代码执行结果为:

a 不小于 20
a 的值为 : 100

3.if嵌套语句

(可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句)

if 布尔表达式 1 {
   /* 在布尔表达式 1 为 true 时执行 */
   if 布尔表达式 2 {
      /* 在布尔表达式 2 为 true 时执行 */
   }
}

例子:
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int = 200
 
   /* 判断条件 */
   if a == 100 {
       /* if 条件语句为 true 执行 */
       if b == 200 {
          /* if 条件语句为 true 执行 */
          fmt.Printf("a 的值为 100 , b 的值为 200\n" );
       }
   }
   fmt.Printf("a 值为 : %d\n", a );
   fmt.Printf("b 值为 : %d\n", b );
}

以上代码执行结果为:

a 的值为 100 , b 的值为 200
a 值为 : 100
b 值为 : 200

4.switch语句

( 用于基于不同条件执行不同动作)

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

实例:
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }

   switch {
      case grade == "A" :
         fmt.Printf("优秀!\n" )    
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" );
   }
   fmt.Printf("你的等级是 %s\n", grade );      
}

以上代码执行结果为:

优秀!
你的等级是 A

         switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。

Type Switch 语法格式如下:

switch x.(type){
    case type:
       statement(s);      
    case type:
       statement(s); 
    /* 你可以定义任意个数的case */
    default: /* 可选 */
       statement(s);
}
实例
package main

import "fmt"

func main() {
   var x interface{}
     
   switch i := x.(type) {
      case nil:  
         fmt.Printf(" x 的类型 :%T",i)                
      case int:  
         fmt.Printf("x 是 int 型")                      
      case float64:
         fmt.Printf("x 是 float64 型")          
      case func(int) float64:
         fmt.Printf("x 是 func(int) 型")                      
      case bool, string:
         fmt.Printf("x 是 bool 或 string 型" )      
      default:
         fmt.Printf("未知型")    
   }  
}
以上代码执行结果为:

x 的类型 :<nil>

         使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。

实例
package main

import "fmt"

func main() {

    switch {
    case false:
            fmt.Println("1、case 条件语句为 false")
            fallthrough
    case true:
            fmt.Println("2、case 条件语句为 true")
            fallthrough
    case false:
            fmt.Println("3、case 条件语句为 false")
            fallthrough
    case true:
            fmt.Println("4、case 条件语句为 true")
    case false:
            fmt.Println("5、case 条件语句为 false")
            fallthrough
    default:
            fmt.Println("6、默认 case")
    }
}
以上代码执行结果为:

2、case 条件语句为 true
3、case 条件语句为 false
4、case 条件语句为 true

        总结从以上代码输出的结果可以看出:switch 从第一个判断表达式为 true 的 case 开始执行,如果 case 带有 fallthrough,程序会继续执行下一条 case,且它不会去判断下一个 case 的表达式是否为 true。 

5.select语句

(select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行 )

select {
  case <- channel1:
    // 执行的代码
  case value := <- channel2:
    // 执行的代码
  case channel3 <- value:
    // 执行的代码

    // 你可以定义任意数量的 case

  default:
    // 所有通道都没有准备好,执行的代码
}

实例::::::
package main

import (
    "fmt"
    "time"
)

func main() {
    // 定义两个通道
    c1 := make(chan string)
    c2 := make(chan string)

    // 启动两个 goroutine(协程),分别从两个通道中获取数据
    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()
    
    // 使用 select 语句非阻塞地从两个通道中获取数据
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        //default:
             如果两个通道都没有可用的数据,则执行这里的语句
            //fmt.Println("no message received")
        }
    }
}


以上代码执行结果为:

received one
received two

五、Go语言循环语句

1. for循环语句 (重复执行语句块)

        for循环的三种形式:

①.和C一样

for init; condition; post { }

②.和C的while一样

for condition { }

③.和C的for(;;)一样

for { }
  • init: 一般为赋值表达式,给控制变量赋初值;
  • condition: 关系表达式或逻辑表达式,循环控制条件;
  • post: 一般为赋值表达式,给控制变量增量或减量。

 六、Go语言函数

go语言的函数格式:

func function_name( [parameter list] ) [return_types] { 
    函数体 
}


/*
函数定义解析: 
func:函数由 func 开始声明 
function_name:函数名称,参数列表和返回值类型构成了函数签名。 
parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。 return_types:返回类型,函数返回一列值。
return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 
return_types 不是必须的。 函数体:函数定义的代码集合。
*/


Go 函数可以返回多个值,例如:

实例:
package main

import "fmt"

func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("Google", "Runoob")
   fmt.Println(a, b)
}


以上实例执行结果为:

Runoob Google

七、Go语言数组

1.基础知识:数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1

2.声明数组:

Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:

var variable_name [SIZE] variable_type

实例:var balance [10] float32

3.初始化数组:

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

1.如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度:

var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
或
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

2.如果设置了数组的长度,我们还可以通过指定下标来初始化元素:

//  将索引为 1 和 3 的元素初始化
balance := [5]float32{1:2.0,3:7.0}

注:初始化数组中 {} 中的元素个数不能大于 [] 中的数字/如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小

八、Go语言指针

        说明:一个指针变量指向了一个值的内存地址

声明格式如下:

var var_name *var-type

实例:这是一个指向 int 和 float32 的指针
var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

九、Go语言切片(简单来说就是动态数组,数组长度可变)

1.定义切片

        ①声明一个未指定大小的数组(切片不需要说明长度)

var identifier [ ]type

        ②使用make 函数来创建切片

var slices [ ]type = make([ ] type,len)

简写:slices := make([ ]type,len)

        ③指容量,其中capacity为可数参数

make([ ]T,length,capacity)

2.切片初始化

①直接初始化切片,[ ]表示切片类型,初始化值依次为1,2,3,其中cap = len = 3

s := [ ]int {1,2,3}

②初始化切片s,是数组arr的引用

s := arr[ : ] 

 ③将数组从下标索引startindex到endindex-1下的元素创建为一个新的切片

s := arr[ startIndex:endIndex ]

④默认endIndex时将表示一直到arr数组最后一个元素表示为一个切片

s := arr[startIndex :]

⑤默认startIndex时将表示从arr的第一个元素开始

s:= arr[ : endIndex]

⑥通过切片s初始化切片s1

s1 = s[startIndex : endIndex]

⑦通过内置函数make()初始化切片s,[]int标识为其元素类型类型为int的切片

s := make([ ]int,len,cap) 

十、结构体字段命名及使用范围

package main

import "fmt"

// 定义一个名为 Person 的结构体
type Person struct {
    Name string // 可导出的字段
    age  int    // 私有的字段
}

func main() {
    // 创建 Person 结构体的实例
    p := Person{
        Name: "Alice",
        age:  25,
    }

    fmt.Println(p.Name) // 可以访问可导出的字段
    // fmt.Println(p.age)  // 无法访问私有的字段,会编译错误
}

十一、goland的重构快捷键

十一、函数和接口的区别

  • 函数是一段可执行的代码块,用于实现特定的功能,而接口是一种抽象的类型,用于定义一组方法的集合。
  • 函数可以独立定义和调用,而接口需要被类型实现才能使用。
  • 函数可以接收参数和返回结果,而接口只定义方法的签名,不包含具体的实现。
  • 函数通常用于封装可重用的代码逻辑,而接口用于定义多个类型之间的共享行为。

可以使用以下生动的比喻来说明它们之间的区别:

想象一下你是一家快递公司的老板,而函数就像是你的员工,而接口则是你制定的一套操作规范。

  • 函数(function)就像是你的员工。每个函数都是一个独立的工作人员,他们各自有自己的任务和职责。你可以将特定的任务分配给不同的函数,并在需要时调用他们。每个函数相当于执行某项具体任务的工人。

  • 接口(interface)就像是你制定的操作规范。接口是一套定义了一组方法的规则,描述了工人应该具备的共同行为。你可以制定一份规范,例如所有的工人都必须具备“送货”和“签收”这两种行为。每个工人只要按照规范实现这两个方法,就可以成为符合规范的工人。

使用快递公司的例子,可以更容易理解函数和接口的区别。函数就像是具体的工人,而接口则是定义了工人应该有的共同行为的规范。这样,你可以根据具体的需求,雇佣不同的工人来完成不同的任务。而接口规范则确保了无论是哪位工人,他们都能完成规定的任务,从而保证了快递服务的质量和一致性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《对话品牌》——活到老“养”到老

本期节目《对话品牌》栏目组邀请到了深圳壹常青健康管理有限公司董事长邬锡娣女士参加栏目录制&#xff0c;分享其企业故事&#xff0c;树立品牌形象&#xff0c;提升品牌价值&#xff01; 节目嘉宾&#xff1a;邬锡娣女士 节目主持人&#xff1a;董倩 节目播出平台&#xf…

【K8S 二进制部署】部署单Master Kurbernetes集群

目录 一、基本架构和系统初始化 1、集群架构&#xff1a; 2、操作系统初始化配置&#xff1a; 2.1、关闭防火墙和安全机制&#xff1a; 2.2、关闭swap 2.3、根据规划设置主机名 2.4、三台主机全部互相映射 2.5、调整内核参数 3、时间同步&#xff08;所有节点时间必须同…

iframe展示pdf、png、jpg

iframe展示pdf、png、jpg&#xff1a; 1、前端定义div&#xff1a; <div id"pdf-container"></div>/*dpf的div*/ <iframe id"imageFrame"></iframe>/*图片的div*/2、后端查询base64的流&#xff0c;前端页面初始化js方法&#x…

upset 绘制

好久没有更新,今天来一个upset图的绘制 1.1 安装包 #绘制upset的包现在看来有三个 ## UpSet ### 最基本的upsetR包,使用方便,但是扩展不方便 devtools::install_github("hms-dbmi/UpSetR") ## complex-upset ### UpSet的升级款 支持ggplot2 devtools::install_git…

什么是服务器迁移?

服务器迁移一般来说是将物理服务器从一个地点&#xff08;物理机房&#xff09;移动到另一个地点&#xff0c;或将数据从一台服务器移动到另一台服务器的过程。 机房搬迁&#xff1a;当公司办公场所发生变化&#xff0c;原有机房无法继续使用时&#xff0c;需要将服务器迁移到…

计算机报错x3daudio1_7.dll怎么修复,其实很简单

游戏已经成为了人们休闲娱乐的重要方式之一。然而&#xff0c;有时候我们在玩游戏的过程中会遇到一些错误提示&#xff0c;比如“玩游戏报错x3daudio1_7.dll怎么办”。这个问题可能会导致游戏无法正常运行等问题。x3daudio1_7.dll是DirectX Audio API的一部分&#xff0c;它是D…

腾讯云跨云迁移工具案例实践:阿里云迁移到腾讯云

对于阿里云批量迁移到腾讯云&#xff0c;HyperMotion可以支持批量一键式安装Agent软件&#xff0c;做到了操作步骤简单化、自动化&#xff0c;可以满足常见源端操作系统类型。 例如&#xff1a;Windows 2003-2019&#xff0c;CentOS、RedHat 6.x-7.x、Ubuntu 14.x - 16.x、SUS…

为什么TCP会粘包

硬核图解|tcp为什么会粘包&#xff1f;背后的原因让人暖心 数据包报文格式&#xff08;IP包、TCP报头、UDP报头&#xff09; TCP&#xff0c;Transmission Control Protocol。传输控制协议&#xff0c;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP粘包是指发…

【五】【C语言\动态规划】删除并获得点数、粉刷房子、买卖股票的最佳时机含冷冻期,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

fork函数详解【Linux】

fork函数详解【Linux】 fork函数的概念fork调用后的底层细节解释fork学习中的一些笔记和问题fork的写实拷贝深拷贝的策略 fork调用失败的原因 fork函数的概念 调用fork函数可以在已存在的进程中创建一个子进程&#xff0c;此时&#xff0c;新进程叫做子进程&#xff0c;原进程叫…

k8s二进制部署--部署高可用

连接上文 notready是因为没有网络&#xff0c;因此无法创建pod k8s的CNI网络插件模式 1.pod内部&#xff0c;容器与容器之间的通信。 在同一个pod中的容器共享资源和网络&#xff0c;使用同一个网络命名空间。 2.同一个node节点之内&#xff0c;不同pod之间的通信。 每个pod都…

element ui Checkbox 多选框组件 lable不支持Object类型的值的问题

浅浅记录一下&#xff0c;遇到这个问题的心理路程吧&#xff0c;首先我遇到的问题是多选框的值回显不打对勾&#xff0c;&#xff08;例如&#xff1a;你新增的时候多选&#xff0c;然后点击编辑的时候选过的值没有被勾选&#xff0c;其实是被勾选上了&#xff0c;但是没有显示…

Linux操作系统——进程(六) 进程地址空间

进程地址空间 C/C程序员一般将我们所写的程序看成如下这种结构&#xff1a; 我们所写的程序通过编译编译之后就可以以这样的方式进行分布. 我们先通过编写一段C语言代码来进行验证&#xff1a; 运行结果&#xff1a; 我们可以看出来上述地址遵循的就是我们上面画的一种结构。…

【附视频解析】Jmeter接口之间关联调用(获取上一个接口的返回值作为下一个接口的请求参数)

正则表达式&#xff1a; 具体如何操作&#xff1a; 1. 草稿保存&#xff0c; 此请求的响应数据的id 为发布总结的请求参数draft_id 2. 草稿保存的响应数据 3.在草稿保存的请求中&#xff0c;添加后置处理器- 正则表达式提取器&#xff0c; 提取响应数据的id信息 4. 发布总结请…

Java 缓存中间件

Java 缓存中间件 关键词&#xff1a;Spring Cache、J2Cache、JetCache 一 、JSR 107 JSR107 中制订了 Java 缓存的规范。 因此&#xff0c;在很多缓存框架、缓存库中&#xff0c;其 API 都参考了 JSR 107 规范。 img Java Caching 定义了 5 个核心接口 CachingProvider - 定义…

私有部署ELK,搭建自己的日志中心(三)-- Logstash的安装与使用

一、部署ELK 上文把采集端filebeat如何使用介绍完&#xff0c;现在随着数据的链路&#xff0c;继续~~ 同样&#xff0c;使用docker-compose部署&#xff1a; version: "3" services:elasticsearch:container_name: elasticsearchimage: elastic/elasticsearch:7.9…

Kafka学习笔记1(千峰教育)

Kafka学习笔记1&#xff08;千峰教育&#xff09; 一、为什么使用消息队列1.使用同步的通信方式来解决多个服务之间的通信2.使用异步的通信方式 二、消息队列的流派1.有broker2.无broker 三、Kafka的基本知识1.Kafk2a的安装2.Kafka中的一些基本概念3.创建topic4.发送消息5.消费…

sonarqube安装踩坑记录

如果用java1.8和mysql&#xff0c;则sonarqube版本不能超过7.8&#xff0c;看这里。 sonarqube7.8安装包地址&#xff1a; https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.8.zip 安装步骤&#xff1a; 1、下载sonarqube安装包 wget https://binari…

【PowerMockito:编写单元测试过程中采用when打桩失效的问题】

问题描述 正如上图所示&#xff0c;采用when打桩了&#xff0c;但是&#xff0c;实际执行的时候还是返回null。 解决方案 打桩时直接用any() 但是这样可能出现一个mybatisplus的异常&#xff0c;所以在测试类中需要加入以下代码片段&#xff1a; Beforepublic void setUp() …

软件测试/测试开发丨Pytest 参数化用例

参数化 通过参数的方式传递数据&#xff0c;从而实现数据和脚本分离。并且可以实现用例的重复生成与执行。 参数化应用场景 测试登录场景 测试登录成功&#xff0c;登录失败(账号错误&#xff0c;密码错误)创建多种账号: 中⽂文账号&#xff0c;英⽂文账号 普通测试用例方法 …