Golang快速上手01/Golang基础
-
最近有需求,需要使用go,这几天快速过一遍基础语法,这是今天的总结
-
项目结构
1.变量与常量
1.1变量声明
// 标准声明
var 变量名 类型 = 表达式// 多变量声明
var (name string = "Go"version = 1.21 // 类型推断
)// 短变量声明(仅函数内)
func main() {a, b := 10, "text" // 同时声明多个变量_ = 20 // 丢弃值
}
1.2常量声明
const PI = 3.1415 // 无类型常量
const (STATUS_OK = 200MAX_SIZE = 1024 << 3 // 允许表达式
)
1.3包与导入
package main // 可执行程序必须的包声明// 单行导入
import "fmt"// 多行导入(推荐)
import ("time""log"
)
❗ 注意:导入的包必须被使用,否则编译报错
1.4函数特性
// 多返回值函数
func getData() (int, string) {return 200, "success"
}// 使用返回值
code, msg := getData()
_, status := getData() // 忽略第一个返回值
2.基本数据类型
类型 | 描述 | 范围示例 |
---|---|---|
int | 默认整数类型,系统相关 | 通常 32 或 64 位 |
int8 | 8 位有符号整数 | -128 至 127 |
int16 | 16 位有符号整数 | -32768 至 32767 |
int32 | 32 位有符号整数 | -2^31 至 2^31-1 |
int64 | 64 位有符号整数 | -2^63 至 2^63-1 |
uint | 无符号整数,系统相关 | 0 至 2^32-1 或 2^64-1 |
uint8 | 8 位无符号整数 | 0 至 255 |
uint16 | 16 位无符号整数 | 0 至 65535 |
uint32 | 32 位无符号整数 | 0 至 2^32-1 |
uint64 | 64 位无符号整数 | 0 至 2^64-1 |
byte | uint8 的别名, ASCII码 | 0 至 255 |
rune | int32 的别名,用于 Unicode 码点 | -2^31 至 2^31-1 |
-
复数类型
-
complex128:可以使用
a+bi
表示复数,如0.5+1.5i
var c complex128 = 0.5 + 1.5i
- 如果需要 complex64 类型,可以将 complex128 赋值给 complex64 变量,但可能会损失精度。
-
可以使用内置函数
func complex(r, i float64) complex128
构造复数类型。var c complex128 = complex(0.5, 1.5)
comple(r, i float64)
表明i和r都是float64
-
-
指针类型(uintptr/unsafe.Pointer)
任何类型不能强制转换为uintptr,uintptr可以与unsafe.Pointer,unsafe.Pointer可以转为任何数据类型(不安全)
a := "Hello World!" // string: "Hello World!" b := []byte(a) // []byte: [72 101 108 108 111 32 87 111 114 108 100 33] c := **(**int)(unsafe.Pointer(&a)) // int: 8022916924116329800
-
字符类型byte/rune
使用单引号,默认为rune类型,但如果再byte范围呢,也就是ASCII码范围内,可以相互转换两种类型,表达与
Clang
不同特性 byte (uint8) rune (int32) 底层类型 无符号8位整型 有符号32位整型 取值范围 0 ~ 255 -2^31 ~ 2^31-1 默认值 0 0 内存占用 1字节 4字节 主要用途 ASCII字符处理 Unicode字符处理 // 特殊表示法示例 a := '中' // Unicode字符直接表示 b := '\u4e2d' // Unicode码点表示(中文"中") c := '\377' // 八进制表示最大范围 d := '\x7F' // 十六进制表示ASCII字符 e := '\U0001F604' // 扩展Unicode表示(笑脸表情)
3.内置数据类型
特性 | 值类型 | 引用语义类型 | 指针类型 |
---|---|---|---|
内存分配位置 | 栈/数据段 | 堆 | 栈存储指针,堆存储数据 |
赋值操作 | 深度拷贝 | 浅拷贝(共享底层数据) | 地址拷贝 |
空值 | 类型零值 | nil | nil |
内存管理 | 自动回收 | GC管理 | GC管理 |
典型类型 | int, float, struct | slice, map, chan | *int, *struct |
函数参数传递 | 值副本传递 | 指针结构副本传递 | 地址副本传递 |
3.1 指针
-
code
package mainvar a int = 10 var ptr *int = &afunc main() {ptr2 := &aprintln(*ptr2)// 不能使用:=初始化为空指针,因为编译器无法推断类型var ptr1 *int = nilprintln(ptr1)// 结构体内方位属性中指针类型指向的指用. }
- 注意go中没有->
3.2结构体
-
code
package mainimport ("fmt" )type Book struct {name stringauthor stringsubject *string } var a Book // 初始化默认结构体 var s1 string = "Go 语言" var subject1 *string = &s1var b = Book{name: "Go", author: "www.runoob.com", subject: subject1} // 初始化结构体 var c = Book{author: "www.runoob.com", name: "Go"} // 局部初始化结构体 var e *Book = new(Book) // 使用指针type Book1 struct {stringint }var a1 Book1 = Book1{"Golang 入门经典", 10}var a2 = struct{name stringauthor string }{"Golang 入门经典", "Unknown"}type Cat struct {name stringage int }type Dog struct {name stringage int }func main() {d := Book{author: "www.runoob.com", name: "Go"} // :=println(a.name)println(*b.subject)println(c.name)println(d.name)println(e.name)fmt.Println("Hello, playground")fmt.Println(a1)fmt.Println(a2)println(a1.string)var car1 Catvar car2 Dogfmt.Println(car1)fmt.Println(car2)// 如果两个结构体具有完全相同的定义,它们可以进行显式类型转换。car1 = Cat(car2)fmt.Println(car1)}
-
结构体初始化方式
Go 提供多种初始化结构体的办法,代码片段中展示了多种示例:
-
零值初始化:
- 语法:var a Book
- 效果:所有字段被初始化为零值。根据字段类型,字符串为 “”,整数为 0,指针为 nil。
- 示例:var a Book 会让 a.name = “”,a.author = “”,a.subject = nil。
-
字段赋值初始化:
- 语法:var b = Book{name: “Go”, author: “www.runoob.com”, subject: subject1}
- 效果:指定字段名和值,未指定的字段为零值。代码中 subject1 是一个字符串指针,b.subject 被设置为该指针。
- 注意:字段顺序无关,Go 会根据字段名匹配。
-
部分初始化:
- 语法:var c = Book{author: “www.runoob.com”, name: “Go”}
- 效果:只指定部分字段,未指定的字段(如 subject)为零值,即 nil。
-
使用 new 函数:
- 语法:var e *Book = new(Book)
- 效果:new(Book) 分配内存,返回指向 Book 的指针,所有字段初始化为零值。访问字段用 e.name,Go 自动解引用。
- 与直接声明的区别:new 返回指针,适合需要传递指针的场景。
-
匿名结构体初始化:
- 语法:var a2 = struct{name string; author string}{“Golang 入门经典”, “Unknown”}
- 效果:定义并初始化一个匿名结构体,字段顺序初始化,适合临时使用的小型结构体。
-
-
匿名字段与访问
type Book1 struct {stringint }var a1 Book1 = Book1{"Golang 入门经典", 10}
-
匿名字段:字段没有显式名称,直接使用类型名作为字段名。在 Book1 中,字段名为 string 和 int,可以直接访问 a1.string 和 a1.int。
-
限制:每个属性的类型必须唯一,否则会冲突。例如,不能有多个 string 字段。
-
-
类型转换与字段一致性
type Cat struct {name stringage int }type Dog struct {name stringage int }var car1 Cat var car2 Dog car1 = Cat(car2) // 这行无法编译
-
类型转换规则:在 Go 中,即使两个结构体的字段完全相同(如 Cat 和 Dog 都有 name string 和 age int),如果它们是独立定义的类型,则被视为不同类型,不能直接转换。
-
需要手动赋值或者建构造函数
car1.name = car2.name car1.age = car1.agecar1 = Cat{name: car2.name, age: car2.age}
-
-
-
3.2.1嵌套与嵌入(类似继承)
-
嵌套结构体
-
定义:一个结构体包含另一个结构体作为字段。
-
示例:
type Address struct {street stringcity string }type Person struct {name stringaddress Address }
-
访问:使用点号访问嵌套字段,例如 person.address.street。
-
用途:适合表示层次化数据,如地址信息嵌套在人员信息中。
-
-
嵌入结构体(类似继承)
-
定义:通过嵌入实现类似继承的效果,一个结构体包含另一个结构体的匿名字段。
-
示例:
type Animal struct {name stringage int }type Cat struct {Animalcolor string }
-
访问:嵌入的字段可以直接访问,例如 cat.name 和 cat.age,无需通过 Animal 前缀。
-
方法继承:如果 Animal 有方法,Cat 也可以直接调用这些方法,类似于继承。
-
扩展:Cat 可以添加新字段(如 color)或覆盖方法(通过同名方法)。
-
3.3数组
-
code
package mainimport "fmt"// 定义数组 <定义变量关键字> <变量名> [数组长度] <数组元素类型> var a [3]int var b [3]int = [3]int{1, 2, 3} var c = [...]int{1, 2, 3} // [...]int是数组,不是切片func main() {fmt.Println(a)fmt.Println(b)d := [3]int{1, 2, 3}fmt.Println(d)// 数组名不会转换为指向数组首元素的指针,类似于std::array,所以会传递数组的时候会产生很开销,建议使用指针var a [3]int = [3]int{1, 2, 3}var p *[3]int = &a}
- 和结构体一样,如果直接初始化,就不要写类型声明
- 和cpp数组名的意义不同
3.4切片
3.4.1切片的定义
-
code
package mainimport "fmt"// 定义切片 var slice []int // 注意:[3]int / [...]int 都是数组不是切片 var a = []int{1, 2, 3, 4, 5}func main() {a := []int{1, 2, 3, 4, 5}fmt.Println(a)var b = make([]int, 5) // slice,map,channel,第一个参数为类型,第二个参数为长度,第三个参数为容量fmt.Println(b)}
- 和数组类似,只是数组里不要写数字
3.4.2切片介绍
-
slice
是对数据的引用,而非拷贝 -
切片是一种数据类型也是一种操作
func main() {// 切片操作var a = []int{1, 2, 3, 4, 5}fmt.Println(a[1:3]) // [2 3]fmt.Println(a[:3]) // [1 2 3]fmt.Println(a[1:]) // [2 3 4 5]fmt.Println(a[:]) // [1 2 3 4 5] }
-
append
和copy
-
都是对数据的拷贝,也叫深拷贝
var c = []int{1, 2} fmt.Println(c) // [1 2] var d = []int{3, 4, 5, 6} fmt.Println(d) // [3 4 5 6] var e []int = append(c, 3, 4, 5, 6) fmt.Println(e) // [1 2 3 4 5 6] var f []int = append(c, d...) // ...表示将切片d打散,解包 fmt.Println(f) // [1 2 3 4 5 6] var i int = copy(c, d) // 将切片d复制到切片c中,返回复制的元素个数,以长度短的为准 fmt.Println(i) // 2
-
-
原地删除操作
a = a[start:] // 删除前 start 个元素a = a[:end] // 保留前 end 个元素a = a[start:end] // 截取索引 [start, end) 元素a = append(a[:start], a[end:]...) // 删除索引 [start, end) 元素
-
原地插入
a = append(a, b...) // 原地末尾追加 a = append(b, a...) // 原地首部插入 a = append(append(a[:st], b...), a[st:]...) // 原地中间插入 a := []int{1, 2, 3, 4, 5} b := []int{10, 20, 30} st := 2 // 要插入的位置是索引 2 位置 // a = [1, 2, 10, 20, 30, 3, 4, 5]
3.5字符串
3.5.1字符串初始化
var a string = "Hello World!" // 显式类型
var b = "Golang 入门经典" // 类型推断
c := "abcABC123" // 短声明
- 与数组、切片、结构体类似,如果确定类型,可以直接类型推断,就是第二中初始化方法
- 字符串可以认为是一个静态切片类型,可以进行相应的切片操作。不可使用
append
和copy
函数。还需注意多字节字符(如中文)可能导致切片不完整。
3.5.2字符串的属性与操作
-
字符串不可变,意味着创建后无法直接修改内容。内部使用字节数组存储,结构为 StringHeader(包含数据指针和长度),类似 Java 的字符串。
type StringHeader struct {Data uintptrLen int }
-
字符串拼接
有三种拼接方式:
-
使用
+
运算符:c := a + b
,简单但效率低,适合少量拼接。 -
使用
strings.Join
:c = strings.Join([]string{a, b}, "")
,适合多个字符串拼接。 -
使用
strings.Builder
:推荐高效方式,示例:package mainimport ("fmt""strings" )func main() {var a string = "a"var b string = "b"var builder strings.Builderbuilder.WriteString(a)builder.WriteString(b)fmt.Println(builder.String()) }
-
-
字符串编码:把字符串转换为数组
c := []byte(a) fmt.Println(c) // [97] d := len(c) fmt.Println(d) // 1 e := []rune(a) fmt.Println(e) // [97]
3.5.3其它功能
-
字符串操作与转换功能
- 检查功能
以下是 strings 包中用于检查字符串的函数:
Function Description strings.Contains(s, substr) 返回 true 如果 s 包含 substr strings.HasPrefix(s, prefix) 返回 true 如果 s 以 prefix 开头 strings.HasSuffix(s, prefix) 返回 true 如果 s 以 prefix 结尾 strings.Index(s, substr) substr 在 s 中第一次出现的索引 strings.LastIndex(s, substr) substr 在 s 中最后次出现的索引 a := "hello, world" b := "hello" fmt.Println(strings.Contains(a, b)) // true fmt.Println(strings.Contains(a, "world")) // true fmt.Println(strings.HasPrefix(a, b)) // true fmt.Println(strings.HasSuffix(a, b)) // false fmt.Println(strings.Index(a, b)) // 0 fmt.Println(strings.LastIndex(a, b)) // 0
- 转换功能
以下是 strings 包中用于转换字符串大小写的函数:
Function Description strings.ToLower(s) 返回 s 的小写版本 strings.ToUpper(s) 返回 s 的大写版本 a := "hello, world" b := "hello" fmt.Println(strings.ToUpper(a)) // HELLO, WORLD fmt.Println(strings.ToLower(b)) // hello
- 分割与连接功能
以下是 strings 包中用于分割和连接字符串的函数:
Function Description strings.Split(s, sep) 根据 sep 将 s 分割为字符串切片 strings.Join(elem, sep) 使用 sep 连接 elem 中的元素 a := "hello, world" b := "hello" // split fmt.Println(strings.Split(a, ",")) // [hello world] // join fmt.Println(strings.Join([]string{"hello", "world"}, ",")) // hello,world
- 替换功能
以下是 strings 包中用于替换字符串的函数:
Function Description strings.Replace(s, old, new, n) 在 s 中替换前 n 次 old 为 new strings.ReplaceAll(s, old, new) 在 s 中替换所有 old 为 new a := "hello, world" b := "hello" // replace fmt.Println(strings.Replace(a, "world", "golang", 1)) // hello, golang // replace all fmt.Println(strings.ReplaceAll(b, "l", "x")) // hexxo
- 修剪功能
以下是 strings 包中用于修剪字符串的函数:
Function Description strings.TrimSpace(s) 去除 s 前后空白字符 strings.Trim(s, chars) 去除 s 前后 chars 中的字符 a := "hello, world" b := "hello" // trim fmt.Println(strings.Trim(" hello, world ", " ")) // hello, world // trim left fmt.Println(strings.TrimLeft(" hello, world ", " ")) // hello, world // trim right fmt.Println(strings.TrimRight(" hello, world ", " ")) // hello, world // TrimSpace fmt.Println(strings.TrimSpace(" hello, world ")) // hello, world // TrimPrefix fmt.Println(strings.TrimPrefix("hello, world", "hello")) // , world
-
字符串转换功能
以下是用于字符串转换的函数:
- 转为字符串
Function Description fmt.Sprint(a …any) 将任意类型转换为字符串 t := 1 // Sprint fmt.Sprint(t)
- 从字符串转换
Function Description strconv.ParseBool(s) 解析 s 为布尔值,返回 (bool, error) strconv.ParseComplex(s, bitSize) 解析 s 为复数,返回 (complex128, error) strconv.ParseFloat(s, bitSize) 解析 s 为浮点数,返回 (float64, error) strconv.ParseInt(s, base, bitSize) 解析 s 为整数,返回 (int64, error) strconv.ParseUint(s, base, bitSize) 解析 s 为无符号整数,返回 (uint64, error) a := "hello, world" b := "hello" // ParseBool fmt.Println(strconv.ParseBool("true")) // true <nil> // ParseInt fmt.Println(strconv.ParseInt("17", 10, 64)) // 17 <nil> // ParseFloat fmt.Println(strconv.ParseFloat("3.14", 64)) // 3.14 <nil> // ParseUint fmt.Println(strconv.ParseUint("17", 10, 64)) // 17 <nil> // ParseComplex fmt.Println(strconv.ParseComplex("1+2i", 64)) // (1+2i) <nil>
3.6channel
-
channel
用于多线程线程管道通信与同步package mainimport ("fmt" )func main() { // a := make(chan <type>, [<size>])a := make(chan int, 2) // 不允许直接转换的定义方法fmt.Println(a)a <- 1a <- 2 }
- 直接使用
var a chan int
是错误的,其没有构造chan
结构。因为这是一个引用数据类型 - 发送数据:channel <- data,如 a <- 1。
- 接收数据:data := <- channel,如 x := <- a。
- 直接使用
-
无缓冲通道的阻塞
无缓冲通道没有存储空间,发送操作会阻塞直到有一个接收操作准备好接收数据;同样,接收操作会阻塞直到有一个发送操作准备好提供数据。这意味着发送方和接收方必须同时准备好,数据才能传递。
b := make(chan int) //有缓冲区大小为2的 int 通道 select { case x := <- b:fmt.Println(x) default:// 无数据时执行 }
- 这允许程序检查数据而不等待
-
有缓冲通道的阻塞
有缓冲通道有一个固定大小的缓冲区,发送操作只有在缓冲区满时才会阻塞;接收操作只有在缓冲区空时才会阻塞。缓冲区允许发送和接收操作在不同时间发生,只要缓冲区有空间或数据即可。
-
意外细节
你可能不知道的是,即使有缓冲通道,如果接收操作先于发送操作执行且缓冲区空,接收操作也会阻塞,直到发送操作填入数据。这与无缓冲通道的同步性质类似,但缓冲区提供了更多灵活性。
3.7map
-
初始化map
// a := make(map[<keyType>]<valueType>) // b := map[<keyType>]<valueType>{<key>: <value>...} a := make(map[string]int) b := map[string]int{"a": 1, "b": 2, "c": 3} fmt.Println(a) fmt.Println(b)
- 和channel类似
-
crud
// crud // 改 b["d"] = 4 fmt.Println(b) // map[a:1 b:2 c:3 d:4] // 删 delete(b, "d") fmt.Println(b) // map[a:1 b:2 c:3] // 查看是否存在这个key,存在返回value,否则返回0 x := b["a"] fmt.Println(x) // 1// 遍历 for k, v := range b {fmt.Println(k, v) }for k := range b {fmt.Println(k) }for _, v := range b {fmt.Println(v) }
3.8函数
3.8.1函数的分类
- 具名函数
func <functionName>([parameterList...]) [returnTypes...] {<block>
}func add(x int, y int) (int a) {a := x + yreturn
}
-
匿名函数
<functionName>([parameterList...]) [returnTypes...] {<block> }a := add(x int, y int) (int a) {a := x + yreturn }
3.8.2函数传参
-
Golang中没有引用类型,所以避免拷贝请使用指针
-
Golang中
args...
是解包,...args
是封包package mainimport ("fmt" )func add(a ...int) int {s := 0for _, v := range a {s += v}return s }func main() {fmt.Println(add(1, 2, 3, 4, 5)) // 15fmt.Println(add([]int{1, 2, 3}...)) // 6 }
3.8.3函数返回
-
如果指定函数返回值名,直接使用
return
返回即可。此时函数返回值已定义,无需在函数体内定义。func <functionName>([parameterList...]) [returnTypes...] {<block> }func add(x int, y int) (int a) {a := x + yreturn }
这里直接return就好,因为指定了返回参数为a
3.9方法
-
golang实现了对象和方法的静态绑定,虽然golang没有类和对象的概念,方法是golang的类的面向对象实现
- 静态绑定:方法或函数的调用在编译时已确定,通常与方法重载或静态方法相关。
- 动态绑定:方法的调用在运行时决定,通常与方法重写(Override)相关。
-
方法的对象必须是本包结构体。例如
func (builder strings.Builder) <functionName>([parameterList...]) [returnTypes...]
是错误的,func (x int) <functionName>([parameterList...]) [returnTypes...]
是错误的。// 函数实现 type File struct {fd intflag uint }func open(file *File, fp string, mode string) {// ... }func close(file *File) {// ... }func main() {file := File{}open(&file, "data.txt", "w")close(&file) }// 方法实现 type File struct {fd intflag uint }func (file *File) open(fp string, mode string) error {// ... }func (file *File) close(fp string, mode string) error {// ... }func main() {file := File{}file.open("data.txt", "w")file.close() }
- 由此可见方法与函数绑定了
-
参考https://blog.csdn.net/TimeLies_Sea/article/details/131581569
相关文章:
Golang快速上手01/Golang基础
最近有需求,需要使用go,这几天快速过一遍基础语法,这是今天的总结 项目结构 #mermaid-svg-qpF09pnIik9bqQ4E {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qpF09pnIik9bqQ4E .e…...
[Web 安全] 反序列化漏洞 - 学习笔记
关注这个专栏的其他相关笔记:[Web 安全] Web 安全攻防 - 学习手册-CSDN博客 0x01:反序列化漏洞 — 漏洞介绍 反序列化漏洞是一种常见的安全漏洞,主要出现在应用程序将 序列化数据 重新转换为对象(即反序列化)的过程中…...

【学习笔记】Google的Lyra项目:基于神经网络的超低比特率语音编解码技术
一、引言:语音通信的带宽挑战与技术突破 在实时音视频通信占据全球数字化生活核心地位的今天,Google于2021年推出的Lyra编解码器标志着语音编码技术进入新的时代。这款基于机器学习的新型音频编解码器以3kbps的极低比特率实现接近原始音质的语音重建能力…...

Unity Dedicated Server 控制台 输出日志LOg 中文 乱码
现象: 中文乱码 原因: Unity打包出来的.exe文件,语言一栏是英文,VS控制台出来不一样 解决方案: 新建.bat文件 ,并使用命令chcp 65001,运行时启动.bat,而不是.exe, 改不了exe属性,虽然有点奇怪ÿ…...

【Excel】 Power Query抓取多页数据导入到Excel
抓取多页数据想必大多数人都会,只要会点编程技项的人都不会是难事儿。那么,如果只是单纯的利用Excel软件,我还真的没弄过。昨天,我就因为这个在网上找了好久发好久。 1、在数据-》新建查询-》从其他源-》自网站 ,如图 …...

去耦电容的作用详解
在霍尔元件的实际应用过程中,经常会用到去耦电容。去耦电容是电路中装设在元件的电源端的电容,其作用详解如下: 一、基本概念 去耦电容,也称退耦电容,是把输出信号的干扰作为滤除对象。它通常安装在集成电路…...

HTTPS 与 HTTP 的区别在哪?
HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈,采用经典客户端-服务…...

let、const【ES6】
“我唯一知道的就是我一无所知。” - 苏格拉底 目录 块级作用域:var、let、const的对比:Object.freeze(): 块级作用域: 块级作用域指由 {} 包围的代码块(如 if、for、while、单独代码块等)形成的独立作用…...

openharmony5.0中hdf框架中实现驱动程序的动态加载和管理的技术细节分析
在分析openharmony的hdf框架的设备驱动加载器(IDriverLoader)时发现在创建实例时会首先判断一下是否完成了驱动入口的构建(HdfDriverEntryConstruct),如果没有构建会重新构建,这与我开始以为的不一致(我一直以为是采用的linux内核方式,只是由…...

TVS管学习记录
文章目录 前言一、TVS是什么?二、TVS关键参数1.反向截至电压**实际意义** 2.钳位电压**定义与作用****选择依据** **4. 实际应用示例****场景:通信端口的ESD保护** 3.反向截至电压和钳位电压的关联和区别**. 小结** 三、实际应用电路举例总结 前言 TVS管…...

数据库表的各种设计
本篇文章,主要讲解项目开发时,遇到不同的情况,要学会对数据库的表进行合理设计。 1、将表的某个字段,存到一张新表中 ①情况描述 ②操作步骤 第一步:创建role表 第二步:在user表中,删除role字…...

JWT使用教程
目录 JWT (JSON Web Token)1. JWT简介(1) 什么是JWT(2) JWT有什么用(3) JWT认证方式 2. JWT的组成部分3. 签名的目的4. JWT与Token的区别5 JWT的优势6 JJWT签发与验证token(1) 引入依赖(2) 创建 Token(3) 解析Token(4) 设置过期时间(5) 自定义claims 7. JWT自定义工具类 JWT (J…...

【大模型系列篇】如何解决DeepSeek-R1结构化输出问题,使用PydanticAl和DeepSeek构建结构化Agent
今日号外:🔥🔥🔥 DeepSeek开源周:炸场!DeepSeek开源FlashMLA,提升GPU效率 下面我们开始今天的主题,deepseek官方明确表示deepseek-r1目前不支持json输出/function call,可…...

老旧android项目编译指南(持续更)
原因 编译了很多项目,找到了一些可观的解决办法 1. android studio里面的jdk版本切换 jdk版本切换在这里,一般安卓开发需要用到4个版本的jdk,jdk8, jdk11, jdk17, jdk21新版的android stuio是默认使用高版本的jdk,所以切换版本是很有必要的 2. 命令…...

linux中安装部署Jenkins,成功构建springboot项目详细教程
参考别人配置Jenkins的git地址为https,无法连上github拉取项目,所以本章节介绍通过配置SSH地址来连github拉取项目 目录: 1、springboot项目 1.1 创建名为springcloudproject的springboot项目工程 1.2 已将工程上传到github中,g…...

AI开发利器:Anaconda
在Python开发过程中,不同的项目可能会依赖不同版本的Python以及各种不同版本的库。比如,项目A可能依赖Python 3.8和某个特定版本的numpy、TensorFlow和PyTorch,而项目B可能需要Python 3.9以及另一个版本的numpy库。如果直接在系统中安装Pytho…...

java网络编程--基于TCP协议的网络编程
Scoket介绍 利用 TCP 协议进行通信的两个应用程序是有主次之分的, 一个是服务器程序,一个是客户端程序, 两者的功能和编写方法不太一样, 其中 ServerSocket 类表示 Socket 服务器端,Socket 类表示 Socket 客户端。 服…...
PageHelper新发现
PageHelper 背景解决reasonablepageSizeZero 背景 今天发现了一个很有趣的现象,接手一个很老的项目springmvc项目、使用PageHelper分页实现常见的后端接口分页功能。但是发现当页码参数大于实际的页码数时、正常不应该返回数据,但是目前确一直返回数据不…...
Redis 数据结构和使用详解(带示例)
Redis 支持的主要数据结构及其对应操作命令的详细解释,结合具体使用场景和示例: 1. 字符串(String) 用途:存储文本、数值或二进制数据,适用于缓存、计数器等。 常用命令: SET key value&#x…...

深度解读 Chinese CLIP 论文:开启中文视觉对比语言预训练
目录 论文概述1.论文摘要2.论文脑图3.论文创新3.1模型构建3.2训练方法3.3数据构建3.4部署优化 4.模型架构 论文解析1. 引言2. 方法2.1数据说明2.2预训练方法2.2.1模型初始化方法2.2.2两阶段预训练方法 2.3预训练细节2.3.1模型初始化2.3.2第一阶段预训练2.3.3第二阶段预训练2.3.…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...