GO数组切片-线性数据结构
数据结构
类型
什么是类型 ?
内存中的二进制数据本身没有什么区别,就是一串0或1的组合。
内存中有一个字节内容是0x63,他究竟是深恶 字符串?字符?还是整数?
本来0x63表示数字 但是文字必须编码成为0和1的组合 才能记录在计算机系统中。在计算机世界里,一切都是数字,但是一定需要指定
类型才能正确的理解它的含义
如果0x63是整数,它就属于整数类型,它是整数类型的一个具体的实列 整数类型就是一个抽象的概念,他是对有一类有着共同特征的事务的抽象概念,
它就属于整数类型,它是整数类型的一个具体的实例。整数类型就是一个抽象的概念,它是对一类有着共同特征的事务的抽象概念。他展示出来就是99,因为多数情况下,程序按照人们习惯采用10进制输出
如果0x63时byte类型或者rune(字符int32)类型,在Go语言中,它是不同于整型的类型,但是展示出来同样时99.
如果0x63时string类型,则展示出一个字符的字符串"c"。
func main(){var a = 0x63 fmt.Printf("%T %[1]d %[1]c \n",a) //类型 数值 字符var b byte = 0x63fmt.Printf("%T %[1]d %[1]c\n",b) //uint8(字节) 99 cvar c rune = 0x63fmt.Printf("%T %[1]d %[1]c\n",c)// x:= '1' //单引号默认是字符类型d := "\x63" //定义字符串 fmt.Printf("%T %[1]s\n",d)fmt.Printf("%T %[1]s\n", string(a)) //将a 进行类型转换
}
//结果====>
/*
int 99 c
uint8 99 c
int32 99 c
string c
string c
*/
数值处理
math包的使用
取整
在fmt.Println(1/2, 3/2, 5/2) // "/" 整数除法,截取整数部分 "%"求模
fmt.Println(-1/2, -3/2, -5/2)
fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")
fmt.Println(math.Ceil(2.01), math.Ceil(2.5), math.Ceil(2.8)) //向上取整 2取3
fmt.Println(math.Ceil(-2.01), math.Ceil(-2.5), math.Ceil(-2.8))
fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")
fmt.Println(math.Floor(2.01), math.Floor(2.5), math.Floor(2.8)) //向下取整 -2. 取-2
fmt.Println(math.Floor(-2.01), math.Floor(-2.5), math.Floor(-2.8))
fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")
fmt.Println(math.Round(2.01), math.Round(2.5), math.Round(2.8)) //四舍五入
fmt.Println(math.Round(-2.01), math.Round(-2.5), math.Round(-2.8))
fmt.Println(math.Round(0.5), math.Round(1.5), math.Round(2.5),
math.Round(3.5))
运行结果
0 1 2
0 -1 -2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 3 3
-2 -2 -2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 2 2
-3 -3 -3
~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 3 3
-2 -3 -3
1 2 3 4
其他数值处理
fmt.Println(math.Abs(-2.7)) // 绝对值
fmt.Println(math.E, math.Pi) // 常数
fmt.Println(math.MaxInt16, math.MinInt16) // 常量,极值
fmt.Println(math.Log10(100), math.Log2(8)) // 对数
fmt.Println(math.Max(1, 2), math.Min(-2, 3)) // 最大值、最小值
fmt.Println(math.Pow(2, 3), math.Pow10(3)) // 幂
fmt.Println(math.Mod(5, 2), 5%2) // 取模
fmt.Println(math.Sqrt(2), math.Sqrt(3), math.Pow(2, 0.5)) // 开方
标准输入
Scan: 空白字符分割,回车提交。换行符当作空白字符
package main
import ("fmt"
)
func main() {var n intvar err errorvar word1, word2 stringfmt.Print("Plz input two words: ")n, err = fmt.Scan(&word1, &word2) // 控制台输入时,单词之间空白字符分割if err != nil {panic(err)}fmt.Println(n)fmt.Printf("%T %s, %T %s\n", word1, word1, word2, word2)fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")var i1, i2 intfmt.Println("Plz input two ints: ")n, err = fmt.Scan(&i1, &i2)if err != nil {panic(err)}fmt.Println(n)fmt.Printf("%T %[1]d, %T %[2]d", i1, i2)
}
如果少一个数据,Scan就会堵塞;如果输入数据多了,等下回Scan读取。例如,一次性输入a b 1 2 看看效果
我们发现 当一次性输入 a b 1 2 的时候 第二个Scan会被自动赋值为 1 2 ,无需再手动输入
Scanf: 读取输入,按照格式匹配解析。如果解析失败,立即报错,那么就会影响后面的Scanf。
package main
import ("fmt"
)
func main() {var n intvar err errorvar name stringvar age intfmt.Print("Plz input your name and age: ")n, err = fmt.Scanf("%s %d\n", &name, &age) // 这里要有\n以匹配回车if err != nil {panic(err)}fmt.Println(n, name, age)var weight, height intfmt.Print("weight and height: ")_, err = fmt.Scanf("%d %d", &weight, &height) //fmt.Scanf("%d,%d", &weight, &height)尽量不要使用这种if err != nil {panic(err)}fmt.Printf("%T %[1]d, %T %[2]d", weight, height)
}
线性数据结构
线性表:
- 线性表(简称表),是一种抽象的数学概念,是一组元素的系列的抽象,它由有穷个元素组成(0个或任意个)
- 顺序表:使用一大块连续的内存顺序存储表中的元素,这样实现的表称为顺序表,或称连续表
- 在顺序表中,元素的关系使用顺序表的存储顺序自然地表示
- 链接表:在存储空间中将分散存储的元素链接起来,这种称为链接表,简称链表
数组等类型,如同地铁站拍好的队伍,有序,可以插队,离队,可以进行索引
链表,就如同一串带线的珠子,随意摆放在桌子上 ,可以插队,离队,可以进行索引。
顺序表数据结构
可以看到 顺序表中的每一个元素的地址是依照顺序所排列的
链接表数据结构
链接表中的元素 并不是有顺序的排列 他的各个元素 分布在不同的内存地址上,在双向链表中 index(n) 和index(n+1)相互记录了双方的地址,比如index1<->index2,index2<->index3,在单向链表中 前一个元素只记录第二个元素的地址
我们对比一下 线性数据结构中 顺序表和线性表的增删改查
顺序表:- 知道某个元素的地址或者首地址,可以通过偏移量进行查找某个元素增加元素:- 尾部:直接在偏移量的内存位置放置 代价小 - 中间:相当于插队,此后所有的数据向后移- 头部:从头开始所有元素依次向后挪动修改元素:- 使用索引找到元素,最快,找到修改即可 删除元素:- 尾部: 如果是尾部 不需要挪动 - 中间或开头: 删除元素后 其元素需要要前挪动
链接表:- 单向链接表来看,从头开始 效率相对低于顺序表 - 知道其中一个元素或者开始地址,不能直接通过偏移量找到某个元素,需要从头遍历一遍 增加元素:- 尾部:尾巴指针增加元素,改改地址,效率高- 中间:遍历查找,找到插入点 断开小手 分别连接- 头部:改改地址 效率高 修改元素: - 使用索引查找元素,修改其内容,效率较高删除元素:- 定位元素,索引最快 - 删除元素,断开小手重新拉 很快
数组
· 长度不可变
· 内容可变
· 可索引
· 值类型
· 顺序表
定义
// 注意下面2种区别
var a0 [3]int // 零值初始化3个元素的数组 [0,0,0] 未赋值 默认0值
var a1 = [3]int{} // 零值初始化3个元素的数组 [0,0,0]
// [3]int是类型,[3]int{} 是字面量值
var a2 [3]int = [3]int{1, 3, 5} // 声明且初始化,不推荐,啰嗦
var a3 = [3]int{1, 3, 5} // 声明且初始化,推荐
count := 3
a4 := [count] int{1,3,5} // 错误的长度类型,必须是常量,换成const
fmt.Println(a2, a3)
const count = 3
a4 := [count]int{1, 3, 5} // 正确
fmt.Println(a2, a3, a4)
a5 := [...]int {10, 30, 50} // ...让编译器确定当前数组大小
a6 := [5]int{100, 200} // 顺序初始化前面的,其余用零值填充
a7 := [5]int{1: 300, 3: 400} // 指定索引位置初始化,其余用零值填充
// 二维数组
a8 := [2][3]int{{100}} // 两行三列 [[100 0 0] [0 0 0]]
// [[10 0 0] [11 12 0] [13 14 15] [16 0 0]]
// 多维数组,只有第一维才能用...推测
// 第一维有4个,第二维有3个。可以看做4行3列的表
a9 := [...][3]int{{10}, {11, 12}, {13, 14, 15}, {16}}
长度和容量
· cap即capacity,容量,表示给数组分配的内存空间可以容纳多少个元素
· len即length,长度,指的是容器中目前有几个元素
由于数组创建时就必须确定的元素个数,且不能改变长度,所以不需要预留多余的内存空间,因此cap和len对数组来说一样。
索引
Go语言不支持负索引。通过[index]来获取该位置上的值。索引范围就是[0, 长度-1]。
修改
func main(){//编译器定义数组长度var a1 = [...]int{1,2,3}a1[0] += 100 //[100,2,3]
}
遍历
索引遍历
func main(){//编译器定义数组长度var a1 = [...]int{1,2,3}a1[0] += 100 //[100,2,3]for i :=0;i<len(a1);i++{fmt.Println(i,a1[i])}
}
for-range 遍历
func main(){//编译器定义数组长度var a1 = [...]int{1,2,3}a1[0] += 100 //[100,2,3]//i 索引 v 元素值for i,v := range a1{fmt.Println(i,v)}
}
内存模型
func main(){var a [3]intfor i:=0;i<len(a);i++{fmt.Println(i,a[i],&a[i])}fmt.Printf("%p %p, %v\n", &a, &a[0], a)a[0] = 1000fmt.Printf("%p %p, %v\n", &a, &a[0], a)
}
===========================================================================
0 0 0xc0000ae078
1 0 0xc0000ae080
2 0 0xc0000ae088
0xc0000ae078 0xc0000ae078, [0 0 0] //数组地址 首元素地址 数组元素
0xc0000ae078 0xc0000ae078, [1000 0 0]上面的每个元素间隔8字节 正好是64位,符合int定义
· 数组必须在编译时就确定大小,之后不能改变大小
· 数组首地址就是数组地址
· 所有元素一个接一个顺序存在内存中
· 元素的值可以改变 但元素的地址不变
如果元素字符串类型呢?
func main() {var a = [3]string{"abc","xyzafsdfdsgdgdf","asd"}for i := 0; i < len(a); i++ {fmt.Println(i,a[i],&a[i])}fmt.Printf("%p %p, %v\n",&a,&a[0],a)
}
=======================================================================
0 abc 0xc000112480
1 xyzafsdfdsgdgdf 0xc000112490
2 asd 0xc0001124a0
0xc000112480 0xc000112480, [abc xyzafsdfdsgdgdf asd]· 数组首地址是第一个元素的地址
· 所有元素顺序存储在内存中
· 元素的值可以改变,但是元素地址不变我们可以发现 字符串数组每个元素的地址偏移量相差16个字节,这是为什么? 为什么第二个元素占了这么多位置,
还是和第三个元素相差16个字节?原因 :字符串实际上是引用类型,Go字符串默认内存中存储16字节,它的元素卸载了堆上
值类型
func main() {var a1 = [2]int{1,2}fmt.Printf("a1 %p %p\n",&a1,&a1[0])a2 := a1fmt.Printf("a2 %p %p\n",&a2,&a2[0])//调用函数 将a1做为实参传入showAddr(a1)
}
====================================================================================
a1 0xc0000140a0 0xc0000140a0
a2 0xc0000140d0 0xc0000140d0
a3 0xc0000140e0 0xc0000140e0可以看出a1,a2,a3的地址都不一样,a2:=a1的地址也不一样,这说明,Go语言在这些地方进行了
值拷贝,都生成了一份副本。
切片
· 长度可变
· 内容可变
· 引用类型
· 底层基于数组
func main() {//定义切片 var s1 []intvar s2 = []int{}var s3 = []int{1,2,3} //定义字面量 长度为3 容量为3var s4 = make([]int,3,5) //使用make定义切片 make([]type,len,cap) 数据类型是切片引用类型,长度为3 容量位5//s4 的结果是 [0,0,0]
}
内存模型
切片本质是对底层数组一个连续片段的引用,此片段可以是整个底层数组,也可以是起始和终止索引标识的一些项的子集。
//以下是go切片的结构体 他的属性成员是 底层数组的指针,长度,容量
// https://github.com/golang/go/blob/master/src/runtime/slice.go
type slice struct {array unsafe.Pointerlen intcap int
}
func main() {//定义切片 var s1 []int = []int{1,2,3}fmt.Printf("切片地址: %p 底层数组地址: %p",&s1,&s1[0])
}
---------------------------------------------------------------------
切片地址: 0xc00009e060 底层数组地址: 0xc0000ae078
引用类型
func showAddr(s []int) ([]int,error){fmt.Printf("s %p,%p,%d,%d,%v\n",&s,&s[0],len(s),cap(s))//修改一个元素 if len(s) <= 0 {return nil, errors.New("切片不应为空值")}else {s[0] = 100return s ,nil}
}func main() {s1 := []int{10,20,30}fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)s2 := s1 fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")s3,_:= showAddr(s1)fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Printf("s3 %p, %p, %d, %d, %v\n", &s3, &s3[0], len(s3), cap(s3), s3)
}
--------------------------------------------------------------------------------------
s1 0xc000004078, 0xc00000c198, 3, 3, [10 20 30]
s2 0xc0000040a8, 0xc00000c198, 3, 3, [10 20 30]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
s 0xc0000040f0,0xc00000c198,3,3,%!v(MISSING)
s1 0xc000004078, 0xc00000c198, 3, 3, [100 20 30]
s2 0xc0000040a8, 0xc00000c198, 3, 3, [100 20 30]
s3 0xc0000040d8, 0xc00000c198, 3, 3, [100 20 30]
可以发现 ,我们定义的这些切片 他们的header值都不一样,但是底层数组用的是同一个。
那如果在上面showAddr函数中对切片增加一个元素会怎么样呢?
我们学习下 如何对切片进行追加元素操作
append:在切片的尾部追加元素,长度加1。
增加元素后,有可能超过当前容量,导致切片扩容。func main() {//追加操作s1 := make([]int,3,5)fmt.Printf("s1 %p, %p, l=%-2d, c=%-2d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1) //[0,0,0]s2 := append(s1,1,2)fmt.Printf("s1 %p, %p, l=%-2d, c=%-2d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1) //[0,0,0]fmt.Printf("s2 %p, %p, l=%-2d, c=%-2d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2) //[0,0,0,1,2]s3 := append(s1,-1)fmt.Printf("s1 %p, %p, l=%-2d, c=%-2d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1) //[0,0,0]fmt.Printf("s2 %p, %p, l=%-2d, c=%-2d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2) //[0,0,0,-1,2]fmt.Printf("s3 %p, %p, l=%-2d, c=%-2d, %v\n", &s3, &s3[0], len(s3), cap(s3), s3) //[0,0,0,-1]s4 := append(s3,3,4,5)fmt.Printf("s1 %p, %p, l=%-2d, c=%-2d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1) //[0,0,0]fmt.Printf("s2 %p, %p, l=%-2d, c=%-2d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2) //[0,0,0,-1,2]fmt.Printf("s3 %p, %p, l=%-2d, c=%-2d, %v\n", &s3, &s3[0], len(s3), cap(s3), s3) //[0,0,0,-1]fmt.Printf("s4 %p, %p, l=%-2d, c=%-2d, %v\n", &s4, &s4[0], len(s4), cap(s4), s4)//[0,0,0,-1,3,4,5]
}
---------------------------------------------------------------------------------------------------------------
s1 0xc000004078, 0xc00000a450, l=3 , c=5 , [0 0 0]
s1 0xc000004078, 0xc00000a450, l=3 , c=5 , [0 0 0]
s2 0xc0000040a8, 0xc00000a450, l=5 , c=5 , [0 0 0 1 2]
s1 0xc000004078, 0xc00000a450, l=3 , c=5 , [0 0 0]
s2 0xc0000040a8, 0xc00000a450, l=5 , c=5 , [0 0 0 -1 2]
s3 0xc0000040f0, 0xc00000a450, l=4 , c=5 , [0 0 0 -1]
s1 0xc000004078, 0xc00000a450, l=3 , c=5 , [0 0 0]
s2 0xc0000040a8, 0xc00000a450, l=5 , c=5 , [0 0 0 -1 2]
s3 0xc0000040f0, 0xc00000a450, l=4 , c=5 , [0 0 0 -1]
s4 0xc000004150, 0xc00000e230, l=7 , c=10, [0 0 0 -1 3 4 5] //长度超过了底层数组的容量,底层数组变更了
· append一定返回一个新的切片
· append可以增加若干元素
- 如果增加元素时,当前长度+新增个数 <= cap则不扩容
原切片使用元来的底层数组,返回的新切片也使用这个底层数组
返回的新切片有新的长度
原切片长度不变 - 如果增加元素时,当前长度+新增个数 >cap 则进行扩容
生成新的底层数组,新生成的切片使用该新数组,将旧数组中的数据拷贝到新数组中,并且追加元素
原切片底层数组、长度、容量不变
扩容策略
(新版本1.18+)阈值变成了256,当扩容后的cap<256时,扩容翻倍,容量变成之前的2倍;当
cap>=256时, newcap += (newcap + 3*threshold) / 4 计算后就是 newcap = newcap +
newcap/4 + 192 ,即1.25倍后再加192。
扩容是创建新的内部数组,把原内存数据拷贝到新内存空间,然后在新内存空间上执行元素追加操作。
切片频繁扩容成本非常高,所以尽量早估算出使用的大小,一次性给够,建议使用make。
增加一个元素会导致扩容,会怎么样呢?请先在脑中思考
package main
import ("fmt"
)
func showAddr(s []int) []int {fmt.Printf("s %p, %p, %d, %d, %v\n", &s, &s[0], len(s), cap(s), s)// 修改一个元素if len(s) > 0 {s[0] = 123}return s
}
func main() {s1 := []int{10, 20, 33}fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)s2 := s1fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")s3 := showAddr(s1)fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Printf("s3 %p, %p, %d, %d, %v\n", &s3, &s3[0], len(s3), cap(s3), s3)
}
运行结果
s1 0xc000008078, 0xc0000101b0, 3, 3, [10 20 33]
s2 0xc0000080a8, 0xc0000101b0, 3, 3, [10 20 33]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
s 0xc0000080f0, 0xc0000101b0, 3, 3, [10 20 33]
s1 0xc000008078, 0xc0000101b0, 3, 3, [123 20 33]
s2 0xc0000080a8, 0xc0000101b0, 3, 3, [123 20 33]
s3 0xc0000080d8, 0xc0000101b0, 3, 3, [123 20 33]
这说明,底层数组是同一份,修改切片中的某个已有元素,那么所有切片都能看到。
那如果在上面showAddr函数中对切片增加一个元素会怎么样呢?
增加一个元素会导致扩容,会怎么样呢?
package main
import ("fmt"
)
func showAddr(s []int) []int {fmt.Printf("s %p, %p, %d, %d, %v\n", &s, &s[0], len(s), cap(s), s)// // 修改一个元素// if len(s) > 0 {// s[0] = 123// }s = append(s, 100, 200) // 覆盖s,请问s1会怎么样fmt.Printf("s %p, %p, %d, %d, %v\n", &s, &s[0], len(s), cap(s), s)return s
}
func main() {s1 := []int{10, 20, 30}fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)s2 := s1fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~")s3 := showAddr(s1)fmt.Printf("s1 %p, %p, %d, %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)fmt.Printf("s2 %p, %p, %d, %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)fmt.Printf("s3 %p, %p, %d, %d, %v\n", &s3, &s3[0], len(s3), cap(s3), s3)
}运行结果
s1 0xc000008078, 0xc0000101b0, 3, 3, [10 20 30]
s2 0xc0000080a8, 0xc0000101b0, 3, 3, [10 20 30]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
s 0xc0000080f0, 0xc0000101b0, 3, 3, [10 20 30]
s 0xc0000080f0, 0xc00000e390, 5, 6, [10 20 30 100 200]
s1 0xc000008078, 0xc0000101b0, 3, 3, [10 20 30]
s2 0xc0000080a8, 0xc0000101b0, 3, 3, [10 20 30]
s3 0xc0000080d8, 0xc00000e390, 5, 6, [10 20 30 100 200]
可以看到showAddr传入s1,但是返回的s3已经和s1不共用同一个底层数组了,分道扬镳了。
其实这里还是值拷贝,不过拷贝的是切片的标头值(Header)。标头值内指针也被复制,刚复制完大家
指向同一个底层数组罢了。但是仅仅知道这些不够,因为一旦操作切片时扩容了,或另一个切片增加元
素,那么就不能简单归结为“切片是引用类型,拷贝了地址”这样简单的话来解释了。要具体问题,具体
分析。
相关文章:
GO数组切片-线性数据结构
数据结构 类型 什么是类型 ? 内存中的二进制数据本身没有什么区别,就是一串0或1的组合。 内存中有一个字节内容是0x63,他究竟是深恶 字符串?字符?还是整数? 本来0x63表示数字 但是文字必须编码成为0和1的组合 才能记…...
C++ STL学习之【优先级队列】
✨个人主页: 北 海 🎉所属专栏: C修行之路 🎃操作环境: Visual Studio 2019 版本 16.11.17 文章目录 🌇前言🏙️正文1、优先级队列的使用1.1、基本功能1.2、优先级模式切换1.3、相关题目 2、模拟…...
keepalived脑裂现象
Keepealived最常见的问题是会出现脑裂现象: Master一直发送心跳消息给backup主机,如果中间的链路突然断掉,backup主机将无法收到master主机发送过来的心跳消息(也就是vrrp报文),backup这时候会立即抢占mas…...
[stable-diffusion-art] 指北-1
https://stable-diffusion-art.com/beginners-guide/https://stable-diffusion-art.com/beginners-guide/ Stable Diffusion教程目录 - 知乎按: 这个外国教程站中的文章太好了,数量适当,质量很高可惜博文只能按时间浏览,所以整理…...
「C/C++」C/C++预处理器
博客主页:何曾参静谧的博客 文章专栏:「C/C」C/C学习 目录 一、宏替换 #define1. 定义常量2. 定义函数3. 定义代码块 二、条件编译 #if1. 使用 #ifdef、 #else 和 #endif2. 使用 #if 、#elif、#else和 #endif 编译不同版本的代码3. 使用 #ifndef 和 #def…...
java语言入门教程文章
好的,以下是Java语言入门教程: Java是一种高级编程语言,由Sun Microsystems于1995年推出。Java语言具有良好的可移植性和安全性,因此被广泛应用于Web应用程序、移动应用程序、企业应用程序等各个领域。本教程将带领初学者快速入门…...
基于灰狼算法的极限学习机(ELM)回归预测-附代码
基于灰狼算法的极限学习机(ELM)回归预测 文章目录 基于灰狼算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于灰狼算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要:本文利用灰狼算法对极限学习机进行优化,并…...
【五一创作】ERP实施-委外业务-委外采购业务
委外业务主要有两种业务形态:委外采购和工序外协,委外采购主要是在MM模块中实现,工序外协主要由PP模块实现,工序外协中的采购订单创建和采购收货由MM模块实现。 委外采购概念 委外采购,有些企业也称为带料委外或者分包…...
DAY 54 数据库基础
数据库的基本概念 数据(Data): 描述事务的符号记录包括数字、文字、图形、图像、声音、档案记录以”记录“形式按统一的格式进行存储 表: 将不同的记录组织在一起用来存储具体数据 数据库: 表的集合,…...
网络编程 总结二
一、TCP TCP模型 1. TCP搭建相关函数: 套接字Socket 1)Socket函数: 2)bind 3)listen 4)accept 5)recv 注意: 1> TCP中的recv 可以替换成read; 2>TCP中的…...
消息称苹果Type-C口充电未设MFi限制,iOS17将更新Find My服务
根据国外科技媒体 iMore 报道,基于消息源 analyst941 透露的信息,苹果公司目前并未开发 MFi 限制。 根据推文信息内容,两款 iPhone 15 机型的最高充电功率为 20W,而 iPhone 15 Pro 机型的最高支持 27W 充电。 此前古尔曼表示苹…...
设计模式——工厂模式(简单工厂、工厂方法、抽象工厂)
是什么? 工厂模式的目的是将创建对象的具体过程隐藏起来,从而达到更高的灵活性 工厂模式分为:简单工厂模式、工厂方法模式、抽象工厂模式; 为什么? 在Java中,万物皆是对象,我们在使用的时候…...
《C语言技术体系》 学习路线总目录 + 思维导图
目录 前言 正文 思维导图 第1章 流程结构 1.1 初识C语言 1.2 流程结构 1.3 数据类型 1.4 运算符表达式 第2章 指针与数组 2.1 指针基本概念 2.2 一维数组 2.3 二维及多维数组 2.4 指针与数组 第3章 模块化重构 3.1 函数 3.2 typedef类型定义 3.3 enum枚举 3.…...
数字图像处理简答题
目录 1.人类视觉对颜色的主观感觉包括哪三类? 2. 图像成像的过程包括哪三步? 3.图像的采样和量化分别指什么? 4、取k8时,将下图用相应矩阵表示 5、简述当限定了数字图像的数据量时采样和量化参数的选择遵循哪两条原则&#x…...
【Java校招面试】基础知识(五)——GC
目录 前言一、基础概念二、垃圾回收算法三、垃圾收集器四、引用后记 前言 本篇主要介绍Java垃圾回收机制——GC的相关内容。 “基础知识”是本专栏的第一个部分,本篇博文是第五篇博文,如有需要,可: 点击这里,返回本专…...
使用CMake调用Makefile 项目
目录标题 基本示例Cmake传递lib给MakefileCmake传递参数给Makefile,比如make cleanWindows下使用Cmake调用Makefile 基本示例 如果项目是使用传统的Makefile构建的,并且您希望使用CMake调用这些Makefile,您可以使用CMake的add_custom_target…...
快速傅里叶变换FFT学习笔记
点值表示法 我们正常表示一个多项式的方式,形如 A ( x ) a 0 a 1 x a 2 x 2 . . . a n x n A(x)a_0a_1xa_2x^2...a_nx^n A(x)a0a1xa2x2...anxn,这是正常人容易看懂的,但是,我们还有一种表示法。 我们知道…...
如何下载安装驱动
1 打开浏览器 这里以Edge浏览器举例 第一步打开桌面上的Edge浏览器 如果您的桌面上没有 那么找到搜索栏 搜索Edge 然后打开 打开之后一般是这样 然后把我发送您的地址 驱动下载地址 https://t.lenovo.com.cn/yfeyfYyD (这个网址只是一个例子) 删除掉前…...
鸿蒙Hi3861学习四-Huawei LiteOS介绍
一、什么是LitesOS Huawei LiteOS是华为针对物联网领域推出的轻量级物联网操作系统,是华为物联网战略的重要组成部分,具备轻量级、低功耗、互联互通、组件丰富、快速开发等关键能力。基于物联网领域业务特征打造领域性技术栈,为开发者提供“一…...
Vue核心 收集表单数据 过滤器
1.14. 收集表单数据 收集表单数据: 若: ,则v-model收集的是value值,用户输入的就是value值。若: ,则v-model收集的是value值,且要给标签配置value值。若: 没有配置input的value属性,那么收集的就是checked(勾选 or 未…...
华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包
华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包-内有教程 特点: 1、适用于对应型号的电视盒子刷机; 2、开放原厂固件屏蔽的市场安装和u盘安装apk; 3、修改dns,三网通用; 4、大量精简内置的…...
数字化转型导师坚鹏:面向数字化转型的大数据顶层设计实践
面向数字化转型的大数据顶层设计实践 课程背景: 数字化背景下,很多企业存在以下问题: 不清楚大数据思维如何建立? 不清楚企业大数据分析方法? 不了解大数据应用成功案例? 课程特色: …...
day27_mysql
今日内容 零、 复习昨日 一、单表查询 二、多表联查 零、 复习昨日 1 DDL,DML,DQL是啥 DDL 数据定义语言(库,表,列)DML 数据操作语言(表内数据的操作增删改)DQL 数据查询语言(表内数据的查询&am…...
QwtPlotCurve使用说明
QwtPlotCurve是Qwt库中用于绘制曲线的类,可以在QwtPlot上绘制各种类型的曲线,如折线、样条线、散点等。以下是QwtPlotCurve的一些常用函数和使用说明: setSamples(const QPolygonF &samples):设置曲线的数据点,参数…...
JS逆向 -- 某平台登录加密分析
一、打开网站,使用账号密码登录 账号:aiyou123.com 密码:123456 二、通过F12抓包,抓到如下数据,发现密码加密了 三、加密结果是32位,首先考虑是md5加密。 四、全局搜索pwd,点击右上角…...
一分钟快速实现Flask框架的蓝图和视图
一分钟快速实现Flask框架的蓝图和视图 Flask是一个轻量级的Web应用框架,非常适合快速开发小型的Web应用。Flask框架使用蓝图(Blueprint)和视图(View)的概念来组织应用程序的代码。在本文中,我们将介绍如何…...
Mysql 约束练习【第13章_约束】
#第13章_约束 /* 基础知识 1.1 为什么需要约束? 为了保证数据的完整性! 1.2 什么叫约束?对表中字段的限制。 1.3 约束的分类: 角度1:约束的字段的个数 单列约束 vs 多列约束 角度2:约束的作用范围 列…...
java调用cmd命令
1.首先,我们需要了解一下 java是如何调用 cmd的: 6.在实际的开发中,我们有可能会遇到 java调用 cmd命令的情况: 7.对于一些特定的环境下,例如在嵌入式系统中,那么我们可以使用下面这种方式来调用 cmd命令&a…...
Qt音视频开发36-超时检测和自动重连的设计
一、前言 如果网络环境正常设备正常,视频监控系统一般都是按照正常运行下去,不会出现什么问题,但是实际情况会很不同,奇奇怪怪七七八八的问题都会出现,就比如网络出了问题都有很多情况(交换机故障、网线故障、带宽故障等),所以监控系统在运行过程中,还得做超时检测,…...
Reactor 第九篇 WebFlux重构个人中心,效果显著
1 重构背景 原有的开发人员早已离职,代码细节没人知道,经过了一段时间的维护,发现有以下问题: 个人中心系统的特征就是组装各个业务的接口,输出个人中心业务需要的数据,整个系统调用了几十个第三方业务线的…...
做网站图片素材在线编辑/网络推广网站排名
操作系统实 验 报 告课程名称操作系统实验实验项目名称磁盘调度算法学号班级姓名专业计算机科学与技术学生所在学院计算机科学与技术学院指导教师初妍实验室名称地点21#428哈尔滨工程大学计算机科学与技术学院第六讲 磁盘调度算法一、实验概述1. 实验名称磁盘调度算法2. 实验目…...
河北住房和城乡建设厅官方网站/关键词点击价格查询
作者:Baijayanta Roy来源:towardsdatascience编译&内容补充:早起Python在用python进行机器学习或者日常的数据处理中,pandas是最常用的Python库之一,熟练掌握pandas是每一个数据科学家的必备技能,本文将…...
网站建设flash/站长工具查询网
很累,很想早点休息,可是,还是有点不开心。 学习、修改,一晃又到了一点,我终于决定睡了。 有种绝望的伤感!转载于:https://www.cnblogs.com/cole2295/archive/2009/07/11/1521101.html...
宿迁公司做网站/百度搜索使用方法
最近做了一个项目,里面用到了视频播放这一块,当时想考虑Vitamio,demo也做了出来,但是后来发现它是商业收费的,并且收费相当可观,所以只能放弃了。然后找到了ijkPlayer,功能也很强大,…...
wordpress文章标题后显示栏目标题/郑州谷歌优化外包
火车实时管理系统模型 我先把代码和AKP文件链接贴出来apk文件代码,解压后用Android studio打开设计一套火车管理系统,并能合理的调度火车的运行系统,并能提供购票系统,用户邮箱能获得购票信息详细功能描述:该火车管理系…...
网站根目录在哪wordpress/seo项目经理
如题!转载于:https://www.cnblogs.com/chenge/archive/2008/02/26/1082721.html...