C++GO语言微服务项目之 go语言基础语法

news2025/5/10 0:30:05

目录

01 变量定义

02 自增语法

03 指针

04 go不支持的语法

05 string

06 定长数组-forrange

07 动态数组追加元素

08 切片截取-copy-make介绍

09 map介绍

10 函数

11 内存逃逸

12 import

13 命令行参数-switch

14 标签与continue-goto-break配合使用

15 枚举const-iota

16 结构体基本语法

17 init函数

18 defer-文件读取-匿名函数


01 变量定义

# 二、基础语法

## 1. 变量定义

```go
package main

import "fmt" //goland会帮我们自动导入程序中使用的包

func main() {
    //变量定义: var
    //常量定义: const

    //01-先定义变量,再赋值 var 变量名 数据类型
    var name string
    name = "duke" //Ctrl + Alt +l 可以快速格式化代码

    var age int
    age = 20

    fmt.Println("name:", name)
    fmt.Printf("name is :%s, %d\n", name, age)

    //02 定义时直接赋值
    var gender = "man"
    fmt.Println("gender:", gender)

    //03 定义直接赋值,使用自动推导 (最常用的)
    address := "北京"
    fmt.Println("address:", address)

    //灰色部分表示形参
    test(10, "str")

    //04-平行赋值
    i, j := 10, 20 //同时定义两个变量
    fmt.Println("变换前==》 i:", i, ", j:", j)

    i, j = j, i
    fmt.Println("变换后==》i:", i, ", j:", j)

}

func test(a int, b string) {
    fmt.Println(a)
    fmt.Println(b)
}

```

![1585881281278](assets/1585881281278.png)

02 自增语法

基础数据类型:

```go
int,int8 int16, int32, int64
uint8 ... uint64

float32
float64

true/false
```



## 2. 自增语法

c语言:i++, i--, --i, ++i

go语言:i++, i--, 没有--i,++i, 自增语法必须单独一行

```go
package main

import "fmt"

func main() {
    i := 20
    i++
    //++i //这个也是错的, 语义更加明确
    //fmt.Println("i:", i++)  //这是错误的,不允许和其他代码放在一起,必须单独一行
    fmt.Println("i:", i)

}

```

03 指针

## 3. 指针

```go
package main

import "fmt"

func main() {
    //go语义也有指针
    //结构体成员调用时:   c语言:   ptr->name  go语言:  ptr.name
    //go语言在使用指针时,会使用内部的垃圾回收机制(gc : garbage collector),开发人员不需要手动释放内存
    //c语言不允许返回栈上的指针,go语言可以返回栈上的指针,程序会在编译的时候就确定了变量的分配位置:
    //编译的时候,如果发现有必要的话,就将变量分配到堆上

    name := "lily"
    ptr := &name
    fmt.Println("name:", *ptr)
    fmt.Println("name ptr:", ptr)

    //02-使用new关键字定义
    name2Ptr := new(string)
    *name2Ptr = "Duke"

    fmt.Println("name2:", *name2Ptr)
    fmt.Println("name2 ptr:", name2Ptr)

    //可以返回栈上的指针,编译器在编译程序时,会自动判断这段代码,将city变量分配在堆上
    res := testPtr()
    fmt.Println("res city :", *res, ", address:", res)
    
    //空指针,在c语言: null, c++: nullptr,go: nil

    //if两端不用加()
    //即使有一行代码,也必须使用{}
    if res == nil {
        fmt.Println("res 是空,nil")
    } else {
        fmt.Println("res 是非空")
    }

}

//定义一个函数,返回一个string类型的指针, go语言返回写在参数列表后面
func testPtr() *string {
    city := "深圳"
    ptr := &city
    return ptr
}

04 go不支持的语法

## 4. 不支持的语法汇总

1. 自增--i, ++i不支持
2. 不支持地址加减
3. 不支持三目运算符 ? :
4. 只有false才能代码逻辑假,数字0和nil不能(只有false/true才能表示逻辑真假,数字不能代表逻辑值)

```go
package main

import "fmt"

func main() {
    //if 0 {
    //    fmt.Println("hello")
    //}

    //if nil {
    //    fmt.Println("hello")
    //}

    if true {
        fmt.Println("hello")
    }

    //a, b := 1, 2
    //x := a > b ? 0:-1
}
```



## 5. 字符串string

```go
package main

import "fmt"

func main() {
    //1- 定义
    name := "duke"

    //需要换行,原生输出字符串时,使用反引号``
    usage := `./a.out <option> 
         -h   help 
         -a  xxxx`
    //c语言使用单引号 + \来解决
    fmt.Println("name :", name)
    fmt.Println("usage :", usage)

    //2. 长度,访问
    //C++:   name.length
    //GO: string没有.length方法,可以使用自由函数len()进行处理
    //len: 很常用
    l1 := len(name)
    fmt.Println("l1:", l1)

    //不需要加()
    for i := 0; i < len(name); i++ {
        fmt.Printf("i: %d, v: %c\n", i, name[i])
    }

    //3-拼接
    i, j := "hello", "world"
    fmt.Println("i+j=", i+j)

    //使用const修饰为常量,不能修改
    const address = "beijing" //在编译期就确定了类型,是预处理,所以不需要推导
    const test = 100
    //address = "上海"
    fmt.Println("address:", address)
    
    //可以直接对比字符串,使用ASCII的值进行比较
    if i > j {
        ;
    }
}

```

05 string

## 5. 定长数组

```go
package main

import "fmt"

func main() {

    //1-定义,定义一个具有10个数字的数组
    //c语言定义: int nums[10] ={1,2,3,4}
    //go语言定义:
    //     nums := [10]int{1,2,3,4} (常用方式)
    //  var nums = [10]int{1,2,3,4}
    // var nums [10]int = [10]int{1,2,3,4}

    nums := [10]int{1, 2, 3, 4,0,0,0,0}

    //2-遍历,方式一
    for i := 0; i < len(nums); i++ {
        fmt.Println("i:", i, ", j:", nums[i])
    }

    //方式二: for range   ===> python支持
    //key是数组下标,value是数组的值
    for key, value := range nums {
        //key=0, value=1  => nums[0]
        value += 1
        //value全程只是一个临时变量,不断的被重新赋值,修改它不会修改原始数组
        fmt.Println("key:", key, ", value:", value, "num:", nums[key])
    }

    //在go语言中,如果想忽略一个值,可以使用_
    //如果两个都忽略,那么 就不能使用 := ,而应该直接使用 =
    for _, value := range nums {
        fmt.Println("_忽略key, value:", value)
    }

    //不定长数组定义
    //3-使用make进行创建数组
}
```

06 定长数组-forrange

## 6. 不定长数组(切片、slice)

切片:slice,它的底层也是数组,可以动态改变长度

### - 切片1:

```go
package main

import "fmt"

func main() {
    //切片:slice,它的底层也是数组,可以动态改变长度
    //定义一个切片,包含多个地名
    //names := [10]string{"北京", "上海", "广州", "深圳"}
    names := []string{"北京", "上海", "广州", "深圳"}
    for i, v := range names {
        fmt.Println("i:", i, "v:", v)
    }

    //1.追加数据
    names1 := append(names, "海南")
    fmt.Println("names:", names)
    fmt.Println("names1:", names1)

    fmt.Println("追加元素前,name的长度:", len(names), ",容量:", cap(names))
    names = append(names, "海南")
    //fmt.Println("names追加元素后赋值给自己:", names)
    fmt.Println("追加元素后,name的长度:", len(names), ",容量:", cap(names))

    names = append(names, "西藏")
    fmt.Println("追加元素后,name的长度:", len(names), ",容量:", cap(names))

    //2.对于一个切片,不仅有'长度'的概念len(),还有一个'容量'的概念cap()
    nums := []int{}
    for i := 0; i < 50; i++ {
        nums = append(nums, i)
        fmt.Println("len:", len(nums), ", cap:", cap(nums))
    }
}

```

![1585895660673](assets/1585895660673.png)

小结:

1. 可以使用append进行追加数据
2. len获取长度,cap获取容量
3. 如果容量不足,再次追加数据时,会动态分配2倍空间

### 

07 动态数组追加元素

### - ==切片2:==

```go
package main

import "fmt"

func main() {
    names := [7]string{"北京", "上海", "广州", "深圳", "洛阳", "南京", "秦皇岛"}

    //想基于names创建一个新的数组
    names1 := [3]string{}
    names1[0] = names[0]
    names1[1] = names[1]
    names1[2] = names[2]

    //切片可以基于一个数组,灵活的创建新的数组
    names2 := names[0:3] //左闭右开
    fmt.Println("names2:", names2)

    names2[2] = "Hello"
    fmt.Println("修改names[2]之后, names2:", names2)
    fmt.Println("修改names[2]之后, names:", names)

    //1. 如果从0元素开始截取,那么冒号左边的数字可以省略
    names3 := names[:5]
    fmt.Println("name3:", names3)

    //2. 如果截取到数组最后一个元素,那么冒号右边的数字可以省略
    names4 := names[5:]
    fmt.Println("name4:", names4)

    //3. 如果想从左至右全部使用,那么冒号左右两边的数字都可以省略
    names5 := names[:]
    fmt.Println("name5:", names5)

    //4. 也可以基于一个字符串进行切片截取 : 取字符串的字串 helloworld
    sub1 := "helloworld"[5:7]
    fmt.Println("sub1:", sub1) //'wo'

    //5. 可以在创建空切片的时候,明确指定切片的容量,这样可以提高运行效率
    //创建一个容量是20,当前长度是0的string类型切片
    //make的时候,初始的值都是对应类型的零值 : bool ==> false, 数字==> 0, 字符串 ==> 空
    str2 := make([]string, 10, 20) //第三个参数不是必须的,如果没填写,则默认与长度相同
    fmt.Println("str2:", &str2[0])

    fmt.Println("str2: len:", len(str2), ", cap:", cap(str2))
    str2[0] = "hello"
    str2[1] = "world"

    //6.如果想让切片完全独立于原始数组,可以使用copy()函数来完成
    namesCopy := make([]string, len(names))
    //func copy(dst, src []Type) int
    //names是一个数组,copy函数介收的参数类型是切片,所以需要使用[:]将数组变成切片
    copy(namesCopy, names[:])
    namesCopy[0] = "香港"
    fmt.Println("namesCopy:", namesCopy)
    fmt.Println("naemes本身:", names)

}
```

08 切片截取-copy-make介绍

![1585898372086](assets/1585898372086.png)



## 7.字典(map)

哈希表 , key=>value, 存储的key是经过哈希运算的

```go
package main

import "fmt"

func main() {
    //1. 定义一个字典
    //学生id ==> 学生名字  idNames
    var idNames map[int]string //定义一个map,此时这个map是不能直接赋值的,它是空的

    idNames[0] = "duke"
    idNames[1] = "lily"

    for key, value := range idNames {
        fmt.Println("key:", key, ", value:", value)
    }
}

```



![1585898733163](assets/1585898733163.png)



2. 使用map之前,一定要对map进行分配空间

```go
package main

import "fmt"

func main() {
    //1. 定义一个字典
    //学生id ==> 学生名字  idNames
    var idNames map[int]string //定义一个map,此时这个map是不能直接赋值的,它是空的

    //2. 分配空间,使用make,可以不指定长度,但是建议直接指定长度,性能更好
    idScore := make(map[int]float64)   //这个也是正确的
    idNames = make(map[int]string, 10) //建议使用这种方式

    //3. 定义时直接分配空间
    //idNames1 := make(map[int]string, 10) //这是最常用的方法

    idNames[0] = "duke"
    idNames[1] = "lily"

    //4. 遍历map
    for key, value := range idNames {
        fmt.Println("key:", key, ", value:", value)
    }

    //5. 如何确定一个key是否存在map中
    //在map中不存在访问越界的问题,它认为所有的key都是有效的,所以访问一个不存在的key不会崩溃,返回这个类型的零值
    //零值:  bool=》false, 数字=》0,字符串=》空
    name9 := idNames[9]
    fmt.Println("name9:", name9)               //空
    fmt.Println("idScore[100]:", idScore[100]) //0

    //无法通过获取value来判断一个key是否存在,因此我们需要一个能够校验key是否存在的方式
    value, ok := idNames[1] //如果id=1是存在的,那么value就是key=1对应值,ok返回true, 反之返回零值,false
    if ok {
        fmt.Println("id=1这个key是存在的,value为:", value)
    }

    value, ok = idNames[10]
    if ok {
        fmt.Println("id=10这个key是存在的,value为:", value)
    } else {
        fmt.Println("id=10这个key不存在,value为:", value)
    }

    //6. 删除map中的元素
    //使用自由函数delete来删除指定的key
    fmt.Println("idNames删除前:", idNames)
    delete(idNames, 1)   //"lily"被kill
    delete(idNames, 100) //不会报错
    fmt.Println("idNames删除后:", idNames)

    //并发任务处理的时候,需要对map进行上锁 //TODO
}

```

![1585899844151](assets/1585899844151.png)

09 map介绍

## 8. 函数

```go
package main

import "fmt"

//1.函数返回值在参数列表之后
//2.如果有多个返回值,需要使用圆括号包裹,多个参数之间使用,分割
func test2(a int, b int, c string) (int, string, bool) {
    return a + b, c, true
}

func test3(a, b int, c string) (res int, str string, bl bool) {

    var i, j, k int
    i = 1
    j = 2
    k = 3
    fmt.Println(i, j, k)

    //直接使用返回值的变量名字参与运算
    res = a + b
    str = c
    bl = true

    //当返回值有名字的时候,可以直接简写return
    return

    //return a + b, c, true
}

//如果返回值只有一个参数,并且没有名字,那么不需要加圆括号
func test4() int {
    return 10
}

func main() {
    v1, s1, _ := test2(10, 20, "hello")
    fmt.Println("v1:", v1, ",s1:", s1)

    v3, s3, _ := test3(20, 30, "world")
    fmt.Println("v3:", v3, ", s3:", s3)
}

```

10 函数

内存逃逸:

```go
package main

import "fmt"

func main() {
    p1 := testPtr1()
    fmt.Println("*p1:", *p1)
}

//定义一个函数,返回一个string类型的指针, go语言返回写在参数列表后面
func testPtr1() *string {
    name := "Duke"
    p0 := &name
    fmt.Println("*p0:", *p0)

    city := "深圳"
    ptr := &city
    return ptr
}

```

```go
go build -o test.exe --gcflags "-m -m -l" 11-内存逃逸.go  > 1.txt  2>&1

grep -E "name|city" 1.txt --color
```

![1585902031122](assets/1585902031122.png)



## 9. import

创建目录结构:

![1585903432739](assets/1585903432739.png)



add.go

```go
package add

func add(a, b int) int {
    return a + b
}
```

sub.go

```go
package sub

//在go语言中,同一层级目录,不允许出现多个包名
func Sub(a, b int) int {
    test4() //由于test4与sub.go在同一个包下面,所以可以使用,并且不需要sub.形式
    return a - b
}
```

11 内存逃逸

utils.go

```go
package sub

//package utils //不允许出现多个包名

import "fmt"

func test4() {
    fmt.Println("this is test4() in sub/utils!")
}
```

main.go

```go
package main

import (
    SUB "12-import/sub" //SUB是我们自己重命名的包名
    //"12-import/sub" //sub是文件名,同时也是包名
    . "12-import/sub" //.代表用户在调用这个包里面的函数时,不需要使用包名.的形式,不见一使用的
    "fmt"
)

func main() {
    //res := sub.Sub(20, 10) //包名.函数去调用
    res := SUB.Sub(20, 10) //包名.函数去调用
    fmt.Println("sub.Sub(20,10) =", res)

    res1 := Sub(30, 20)
    fmt.Println("Sub(30, 20) :", res1)

    //这个无法被调用,是因为函数的首写字母是小写的
    //如果一个包里面的函数想对外提供访问权限,那么一定要首写字母大写,
    // 大写字母开头的函数相当于 public,
    // 小写字母开头的函数相当于 private, 只有相同包名的文件才能使用
    //add.add(10,20)
}
```



结果:

![1585903519834](assets/1585903519834.png)

12 import

13 命令行参数-switch

5. 案例:递归遍历指定目录的文件!

```sh
#!/bin/bash

#案例:递归遍历指定目录的文件!
#目录由用户通过命令行传入:

#./recursive.sh ..

recursive()
{
    #接收用户输入的目录
    #currDir="$1"
    local currDir="$1"
    echo "====> 当前目录为:" "$currDir"

    #遍历当前目录
    for i in `ls $currDir`
    do
        #这样才是有效的路径,后续才能正确判断性质
        #item="$currDir+"/"+$i"  <<=== 这是错误的,  /usr/+/+test.txt
        item="$currDir/$i"
        #echo "item: " $item

        #如果i是文件,则打印
        if [ -f "$item" ]; then
            echo "文件找到: $item"
        elif [ -d "$item" ];then
        #如果i是文件夹,则递归遍历
            echo "文件夹找到:" "$item"
            recursive $item
        else
            echo "未知文件:" "$item"
        fi
    done
}

14 标签与continue-goto-break配合使用

#判读输入参数的个数
if [ $# -ne 1 ];then
    echo "Usage: recursive <文件目录>"
    exit
fi

recursive $1
```



## 调试

shell调试参数:

- -n 帮助我们快速检查脚本的语法,而不是逐条执行

  - 脚本如果很大,中间执行过程很长,如果不能实现发现脚本错误,会浪费时间

  - ```sh
     bash -n ./recursive.sh
    ```

  - ![1585713051107](assets/1585713051107.png)



- -x,执行脚本的同时将代码执行过程打印到屏幕,便于追踪

  - bash -x recursive.sh  ==》 作用于整个脚本

  - 可以在代码中,对指定的代码段进行调试  

    - set -x  ==> 启动调试

    - xxxx

    - set +x  ==> 停止调试

      ![1585713439412](assets/1585713439412.png)

- -v,一边执行脚本,一边打印错误输出(很少用)



shift 8  ==> *, 快速定位当前光标所值单词(向下寻找,n)

shift 3 ==> #,  快速定位当前光标所值单词(向上寻找,n)
 

15 枚举const-iota

# 三、正则表达式

1. 以S开头的字符串

   1. ^: 可以限定一个字符开头 

   2. ```sh
      目标:ShelloShello world
      表达式:^Shello
      ```



2. 以数字结尾的字符串

   1. $:可以限定结尾
   2. 表示数字方式:
      1. [0123456789]
      2. [0-9]

   2. ```sh
      目标:helloworld9
      表达式:helloworld[0-9]$
      ```

      

3. 匹配空字符串(没有任何字符)

   1. ^$

4. 字符串只包含三个数字

   1. 三个数字:\[0-9\]\[0-9\]\[0-9\]

5. 字符串只有3到5个字母

   1. 字母表示:
      1. [a-zA-Z], 中间不要加空格
      2. 三个到五个字母:[a-zA-Z]{3,5}
   2. 重复次数{m, n}: 
      1. 匹配前面修饰字符的次数,最少m次,最多n次

6.  匹配不是a-z的任意字符

   1. ^ 在[]内部的时候,表示取反(注意,不是限定开头)
   2. ^[^0-9\] :  以非数字开头的字符
   3. 内反,外头
   4. [^a-z\]    <<<===

7. 字符串有0到1个数字或者字母或者下划线

   1. 表示0-1的方法

      1. {0,1}
      2. ? : 表示0,1个

   2. [a-zA-Z0-9_]?

   3. ```sh
      内容
      hello
      hello1
      hello*
      
      正则:
      hello[a-zA-Z0-9_]?
      
      匹配结果:
      hello
      hello1
      hello
      ```

16 结构体基本语法

2. 字符串有1个或多个空白符号(\t\n\r等)

   1. \s  ==》 代表空格

   2. +:一个或多个

   3. ```h
      内容:hello      world
      
      正则:hello\s+world
      
      结果:hello      world
      ```

3. 字符串有0个或者若干个任意字符(除了\n)

   1.  .: 点,代表任意字符,除了\n

   2. *:星号,重复前一个字符0-n次

   3. 匹配任意字符,任意次数:通常做法,是:   .*   ==> 相当于通配符里面的 *

   4. ```sh
      内容:hello     asdfaasdfasdfadfasdfasdf asdfasdfasdf   world
      正则:hello.*world
      结果:hello     asdfaasdfasdfadfasdfasdf asdfasdfasdf   world
      ```

   5. .{,}  ==> 与 .*效果相同

4. 小结:

   1.  ?    ===> 重复前面一个字符0-1
   2. \+     ===> 重复前面一个字符1-n
   3. \*     ===> 重复前面一个字符0-n
   4. .     ===> 表示任意字符
   5. ^    ===> 限定以某个字符开头
   6. [^a-z] ===> 在方括号内,表示取反(非a-z的任意字符)
   7. $   ===> 限定以某个字符结尾
   8. 数字 ====》 [0123456789]  或[0-9]
   9. 字母 ===> [abcd]  [a-zA-Z]

5. 匹配0或任意多组ABC,比如ABC,ABCABCABC

   1. 使用()进行分组,组成新的匹配单元
   2. (ABC)*

6. 字符串要么是ABC,要么是123

   1. (ABC|123)

   2. ```sh
      内容:
      ABC
      ABCABCABCD 
      123456
      hellowlrd
      
      
      正则:(ABC|123)
      ```

17 init函数

7. 字符串只有一个点号 

   1. ^\\.$

8. 匹配十进制3位整数  :

   1. 0~999 , 5,  10 , 200, 999
   2. 分段匹配:
      1. 一位数:
         1.  [0-9]
      2. 二位数:
         1. [1-9]\[0-9\]
      3. 三位数:
         1. \[1-9\][0-9]{2}
      4. 整合:
         1. ^ ([0-9]|[1-9]\[0-9\]{1,2})$

9. 匹配0-255的整数, ip地址

   1. 分段
      1. 一位:[0-9]
      2. 二位:[1-9]\[0-9\]
      3. 三位:
         - 100- 199
           - 1[0-9]{2}
         - 200-249
           - 2[0-4]\[0-9\]
         - 250-255
           - 25[0-5]
      4. 整合:
         - `^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
         - 192.168.1.1

10. 匹配端口号

    1. 0~65536

11. email

    ```sh
    [\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?
    ```

18 defer-文件读取-匿名函数

三种正则表达式:

1. 基础正则:(不使用)  ==》 +?* 都当成普通字符来处理

2. 扩展正则:(我们默认使用这个)==》 +?*  当成特殊字符

3. Perl正则:

   1. +?*是特殊字符

   2. \d ==》 数字 [0-9]

   3. \w ==> 字符[a-zA-Z] 

   4. 用法\d{3}\w    可以匹配:212c

      

# 四、其他命令

## sort(排序)

```sh
-f 忽略字符大小写
-n 按照数值比较
-t 分割字符
-k 指定分割之后比较的字段
-u 只显示一次
-r 反向排序
```

使用:分割之后,截取第三段,以数字的值进行比较,反向打印

```sh
 sort passwd -t: -k3 -n -r
```



## uniq(删除重复)

uniq.txt

```sh
xiaoliu 99 man 25
xiaowen 98 man 24
xiaoliu 99 man 25
```

去重方式,需要重复的两行挨着才能去重,一般和sort配合使用

```sh
cat uniq.txt | sort | uniq
```

![1585728928962](assets/1585728928962.png)



## wc

-l: 统计文件的行数   <==最常用

-c:统计字符

-w:统计单词数量

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

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

相关文章

最新字节跳动运维云原生面经分享

继续分享最新的go面经。 今天分享的是组织内部的朋友在字节的go运维工程师岗位的云原生方向的面经&#xff0c;涉及Prometheus、Kubernetes、CI/CD、网络代理、MySQL主从、Redis哨兵、系统调优及基础命令行工具等知识点&#xff0c;问题我都整理在下面了 面经详解 Prometheus …

理解 Elasticsearch 的评分机制和 Explain API

作者&#xff1a;来自 Elastic Kofi Bartlett 深入了解 Elasticsearch 的评分机制并探索 Explain API。 想获得 Elastic 认证吗&#xff1f;查看下一期 Elasticsearch Engineer 培训的时间&#xff01; Elasticsearch 拥有大量新功能&#xff0c;帮助你为你的使用场景构建最佳…

视频编解码学习三之显示器

整理自&#xff1a;显示器_百度百科&#xff0c;触摸屏_百度百科,百度安全验证 分为阴极射线管显示器&#xff08;CRT&#xff09;&#xff0c;等离子显示器PDP&#xff0c;液晶显示器LCD 液晶显示器的组成。一般来说&#xff0c;液晶显示器由以下几个部分组成&#xff1a; […

K8s网络从0到1

K8s网络从0到1 前言 K8s是一个强大的平台&#xff0c;但它的网络比较复杂&#xff0c;涉及很多概念&#xff0c;例如Pod网络&#xff0c;Service网络&#xff0c;Cluster IPs&#xff0c;NodePort&#xff0c;LoadBalancer和Ingress等等。为了帮助大家理解&#xff0c;模仿TC…

13.Excel:分列

一 分列的作用 将一个单元格中的内容拆分到两个或多个单元格当中。 二 如何使用 1.常规分列使用 注意&#xff1a;分列功能一次只能拆分一列。 长度一致或者数据间有分隔符。 补充&#xff1a;快速选择一列。 CTRL shift 向下箭头。 补充&#xff1a;中英文逗号不同。 可以先通…

计算机网络应用层(5)-- P2P文件分发视频流和内容分发网

&#x1f493;个人主页&#xff1a;mooridy &#x1f493;专栏地址&#xff1a;《计算机网络&#xff1a;自顶向下方法》 大纲式阅读笔记_mooridy的博客-CSDN博客 &#x1f493;本博客内容为《计算机网络&#xff1a;自顶向下方法》第二章应用层第五、六节知识梳理 关注我&…

Gin优雅关闭 graceful-shutdown

文章目录 优雅关闭示例 - Close 方法项目结构使用方法代码如下代码说明如果去掉代码中的数字1&#xff0c;会发生什么 优雅关闭示例项目结构使用方法使用上下文通知不使用上下文通知 代码 notify-without-context-server.go代码说明 代码 notify-with-context-server.go代码说明…

五子棋html

<!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width, initial-scale1" /> <title>五子棋游戏</title> <style>bo…

JavaWeb:后端web基础(TomcatServletHTTP)

一、今日内容 二、Tomcat 介绍与使用 介绍 基本使用 小结 配置 配置 查找进程 三、Servlet 什么是Servlet 快速入门 需求 步骤 1.新建工程-模块&#xff08;Maven&#xff09; 2.修改打包方式-war 3.编写代码 /*** 可以选择继承HttpServlet*/ WebServlet("/hello&q…

缓存(1):三级缓存

三级缓存是指什么 我们常说的三级缓存如下&#xff1a; CPU三级缓存Spring三级缓存应用架构&#xff08;JVM、分布式缓存、db&#xff09;三级缓存 CPU 基本概念 CPU 的访问速度每 18 个月就会翻 倍&#xff0c;相当于每年增⻓ 60% 左右&#xff0c;内存的速度当然也会不断…

Cursor —— AI编辑器 使用详解

Cursor - The AI Code Editor 一、Cursor 是什么&#xff1f; Cursor 是一款优秀的AI代码编辑器&#xff0c;它内置了 Deepseek-R1、GPT-4、Claude等 AI 模型。 简单说&#xff0c;就是&#xff1a;Cursor VS Code 编辑器 AI 大模型 Cursor 功能特性&#xff08;代码补全、…

Pytorch-CUDA版本环境配置

Pytorch-CUDA版本环境配置 电脑如果是Windows平台下的Nvidia GPU的用户&#xff0c;需配置Pytorch的CUDA版本&#xff0c;分为三步&#xff1a; 1. 安装或更新NVIDA显卡驱动 官方驱动下载地址&#xff1a; https://www.nvidia.cn/Download/index.aspx?langcn 2. 安装CUDA Too…

OpenCV 图形API(77)图像与通道拼接函数-----对图像进行几何变换函数remap()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对图像应用一个通用的几何变换。 函数 remap 使用指定的映射对源图像进行变换&#xff1a; dst ( x , y ) src ( m a p x ( x , y ) , m a p y…

Spring AI 入门(持续更新)

介绍 Spring AI 是 Spring 项目中一个面向 AI 应用的模块&#xff0c;旨在通过集成开源框架、提供标准化的工具和便捷的开发体验&#xff0c;加速 AI 应用程序的构建和部署。 依赖 <!-- 基于 WebFlux 的响应式 SSE 传输 --> <dependency><groupId>org.spr…

QUIC协议优化:HTTP_3环境下的超高速异步抓取方案

摘要 随着 QUIC 和 HTTP/3 的普及&#xff0c;基于 UDP 的连接复用与内置加密带来了远超 HTTP/2 的性能提升&#xff0c;可显著降低连接握手与拥塞恢复的开销。本文以爬取知乎热榜数据为目标&#xff0c;提出一种基于 HTTPX aioquic 的异步抓取方案&#xff0c;并结合代理 IP设…

uni-app实现完成任务解锁拼图功能

界面如下 代码如下 <template><view class"puzzle-container"><view class"puzzle-title">任务进度 {{completedCount}}/{{totalPieces}}</view><view class"puzzle-grid"><viewv-for"(piece, index) in…

数据链路层(MAC 地址)

目录 一、前言&#xff1a; 二、以太网&#xff1a; 三、MAC 地址的作用&#xff1a; 四、ARP协议&#xff1a; 一、前言&#xff1a; 数据链路层主要负责相邻两个节点之间的数据传输&#xff0c;其中&#xff0c;最常见数据链路层的协议有 以太网&#xff08;通过光纤 / 网…

基于DQN的自动驾驶小车绕圈任务

1.任务介绍 任务来源: DQN: Deep Q Learning &#xff5c;自动驾驶入门&#xff08;&#xff1f;&#xff09; &#xff5c;算法与实现 任务原始代码: self-driving car 最终效果&#xff1a; 以下所有内容&#xff0c;都是对上面DQN代码的改进&#…

【Linux】Linux工具(1)

3.Linux工具&#xff08;1&#xff09; 文章目录 3.Linux工具&#xff08;1&#xff09;Linux 软件包管理器 yum什么是软件包关于 rzsz查看软件包——yum list命令如何安装软件如何卸载软件补充——yum如何找到要安装软件的下载地址 Linux开发工具Linux编辑器-vim使用1.vim的基…

基于 Spring Boot 瑞吉外卖系统开发(十一)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;十一&#xff09; 菜品启售和停售 “批量启售”、“批量停售”、操作列的售卖状态绑定单击事件&#xff0c;触发单击事件时&#xff0c;最终携带需要修改售卖状态的菜品id以post请求方式向“/dish/status/{params.status}”发送…