Golang 【basic_leaming】2 语言容器

news2024/11/20 18:47:36

阅读目录

  • Go 语言数组_定义_初始化_遍历
    • 定义数组
    • Go 语言初始化数组
    • Go 语言遍历数组
    • 参考文献
  • Go 语言切片(Slice)初始化_删除元素_遍历
    • 什么是切片
    • 声明切片
    • 使用 make() 函数构造切片
    • 使用 append() 函数为切片添加元素
    • 从数组或切片生成新的切片
    • 从指定范围中生成切片
    • 重置切片
    • 复制切片元素到另一个切片
    • 从切片中删除元素
    • 参考文献
  • Go 语言字典 (Map)
    • 初始化字典 map
      • 字段 map 的另外一种初始化方式
    • 遍历字段 map
    • 删除字典 map 中键值对
    • 能够在并发环境下使用的字典 sync.Map
    • 参考文献
  • Go 语言 list (列表)_初始化_遍历_删除
    • 初始化 list (列表)
      • 1.1 通过 container/list 包中的 New 方法来初始化 list
      • 1.2 通过声明初始化 list
    • 向 list (列表) 中添加元素
    • 从 list (列表) 中删除元素
    • 遍历 list (列表)

Go 语言数组_定义_初始化_遍历

定义数组

定义数组的格式如下:

var 数组变量名 [元素数量]T

说明:

  • 数组变量名: 定义一个数组的变量 名;
  • 元素数量: 定义数组的大小;
  • T 可以是任意基本类型,甚至可以是数组本身,若为数组,则可以实现多维数组。

下面这段代码中,定义了一个变量为 arr, 成员类型为字符串 , 大小为 3 的数组:

package main

import (
	"fmt"
)

func main() {
	// 定义一个变量为 arr, 成员类型为 string, 大小为 3 的数组
	var arr [3]string

	// 赋值操作
	arr[0] = "wgchen."
	arr[1] = "blog.csdn"
	arr[2] = ".net"

	fmt.Println(arr)
}
PS E:\golang\src> go run .\main.go
[wgchen. blog.csdn .net]
PS E:\golang\src>

Go 语言初始化数组

var arr = [3]string{"www.", "wgchen", ".blog.csdn"}

这种写法需要保证大括号内的元素数量与数组的大小一致。

但是,还可以将定义数组大小的操作交给编译器,让编译器在编译时,根据元素的个数来确定大小:

var arr = [...]string{"www.", "wgchen", ".blog.csdn"}

... 表示让编译器来确定数组大小。
编译器会自动将这个数组的大小设置为 3。

Go 语言遍历数组

可以通过 for range 来遍历数组,代码如下:

package main

import (
	"fmt"
)

func main() {

	// var arr = [3]string{"www.", "wgchen", ".blog.csdn"}
	var arr = [...]string{"www.", "wgchen", ".blog.csdn"}

	for index, v := range arr {
		fmt.Printf("index: %d, value: %s\n", index, v)
	}
}
PS E:\golang\src> go run .\main.go
index: 0, value: www.
index: 1, value: wgchen
index: 2, value: .blog.csdn
PS E:\golang\src>

上面代码中,index 表示数组当前的下标, v 表示当前元素的值。

参考文献

Golang 【basic_leaming】数组
在这里插入图片描述

Go 语言切片(Slice)初始化_删除元素_遍历

什么是切片

切片和数组类似,都是 数据集合。和数组不同的是,切片是一块动态分配大小的连续空间。它和 Java 语言中的 AarryList 集合类似。

声明切片

切片的声明格式如下:

var name []T
  • name 表示切片变量 名;
  • T 表示切片类型。

下面是示例代码:

package main

import "fmt"

func main() {
	// 声明整型切片
	var numList []int

	// 声明字符串切片
	var strList []string

	// 声明一个空切片, {} 表示已经分配内存,但是切片里面的元素是空的
	var numListEmpty = []int{}

	// 输出3个切片
	fmt.Println(numList, strList, numListEmpty)

	// 输出3个切片大小
	fmt.Println(len(numList), len(strList), len(numListEmpty))

	// 切片判定是否为空结果
	fmt.Println(numList == nil)
	fmt.Println(strList == nil)
	fmt.Println(numListEmpty == nil)
}
PS E:\golang\src> go run .\main.go
[] [] []
0 0 0
true
true
false
PS E:\golang\src>

使用 make() 函数构造切片

可以通过 make() 函数动态的创建一个切片,格式如下:

make( []T, size, cap )
  • T : 切片中元素的类型;
  • size : 表示为这个类型分配多少个元素;
  • cap : 预分配的元素数量,该值设定后不影响 size, 表示提前分配的空间,设置它主要用于降低动态扩容时,造成的性能问题。

示例代码如下:

package main

import "fmt"

func main() {
	a := make([]int, 4)
	b := make([]int, 4, 10)

	fmt.Println(a, b)
	fmt.Println(len(a), len(b))
}
PS E:\golang\src> go run .\main.go
[0 0 0 0] [0 0 0 0]
4 4
PS E:\golang\src>

a 和 b 切片均为大小为 2, 不同的是 b 内存空间预分配了 10 个,但是实际只使用了 2 个元素。

len() 函数计算的是元素的个数,与切片容量无关。

使用 append() 函数为切片添加元素

Go 语言 中的内置函数 append() 可以为切片动态添加元素, 示例代码如下:

package main

import "fmt"

func main() {
	// 声明一个字符串类型的切片
	var strList []string

	// 循环动态向 strList 切片中添加 20 个元素,并打印相关参数
	for i := 0; i < 10; i++ {
		line := fmt.Sprintf("wgchen.blog.csdn.net %d", i)
		strList = append(strList, line)

		fmt.Printf("len: %d, cap: %d, pointer: %p, content: %s\n", len(strList), cap(strList), strList, strList[i])
	}
}
PS E:\golang\src> go run .\main.go
len: 1, cap: 1, pointer: 0xc000088220, content: wgchen.blog.csdn.net 0
len: 2, cap: 2, pointer: 0xc0000a03c0, content: wgchen.blog.csdn.net 1
len: 3, cap: 4, pointer: 0xc0000d4000, content: wgchen.blog.csdn.net 2
len: 4, cap: 4, pointer: 0xc0000d4000, content: wgchen.blog.csdn.net 3
len: 5, cap: 8, pointer: 0xc0000d6000, content: wgchen.blog.csdn.net 4
len: 6, cap: 8, pointer: 0xc0000d6000, content: wgchen.blog.csdn.net 5
len: 7, cap: 8, pointer: 0xc0000d6000, content: wgchen.blog.csdn.net 6
len: 8, cap: 8, pointer: 0xc0000d6000, content: wgchen.blog.csdn.net 7
len: 9, cap: 16, pointer: 0xc0000d8000, content: wgchen.blog.csdn.net 8
len: 10, cap: 16, pointer: 0xc0000d8000, content: wgchen.blog.csdn.net 9
PS E:\golang\src>

通过上面的代码输出,会发现 len() 并不等于 cap。

这是因为当切片空间不足以容纳足够多的元素时,切片会自动进行扩容操作, 扩容规律按切片容量的 2 倍进行扩容,如 1、2、4、8、16 ....

PS: 扩容一般发生在 append() 函数调用时。

另外,append() 函数除了添加一个元素外,还能一次性添加多个元素:

package main

import "fmt"

func main() {
	var strList []string

	// 添加一个元素
	strList = append(strList, "wgchen")

	// 添加多个元素
	strList = append(strList, "www", "wgchen", "com")

	// 添加切片
	list := []string{"知其黑", "受其白"}
	// list 后面的 ... 表示将 list 整个添加到 strList 切片中
	strList = append(strList, list...)

	fmt.Println(strList)
}
PS E:\golang\src> go run .\main.go
[wgchen www wgchen com 知其黑 受其白]
PS E:\golang\src>

从数组或切片生成新的切片

从数组或切片生成新的切片是很常见的操作,格式如下:

slice [开始位置:结束位置]
  • slice 表示切片目标;
  • 开始位置和结束位置对应目标切片的下标。

从数组中生成切片:

package main

import "fmt"

func main() {
	var arr = [3]int{1, 2, 3}

	fmt.Println(arr, arr[1:2])
}
PS E:\golang\src> go run .\main.go
[1 2 3] [2]
PS E:\golang\src>

[2] 是 arr[1:2] 切片操作的结果。
注意取出的元素不包括结束位置的元素。

从指定范围中生成切片

package main

import "fmt"

func main() {
	var arr = [20]int{}

	// 向数组中添加元素
	for i := 0; i < 20; i++ {
		arr[i] = i + 1
	}

	// 指定区间
	fmt.Println(arr[8:15])

	// 中间到尾部所有元素
	fmt.Println(arr[10:])

	// 开头到中间所有元素
	fmt.Println(arr[:10])

	// 切片本身
	fmt.Println(arr[:])
}
PS E:\golang\src> go run .\main.go
[9 10 11 12 13 14 15]
[11 12 13 14 15 16 17 18 19 20]
[1 2 3 4 5 6 7 8 9 10]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
PS E:\golang\src>
  • 若不填写结束位置,如 arr[10:], 则表示从下标 10 置到数组的结束位置。
  • 若不填写开始位置,如 arr[:10],则表示从 0 到下标 10 的位置。
  • 若开始位置和结束位置都不填写,如 arr[:], 则会生成一个和原有切片一样的切片。

重置切片

若把切片的开始位置和结束位置都设置为 0, 则会生成一个空的切片:

package main

import "fmt"

func main() {
	var arr = [20]int{}

	// 向数组中添加元素
	for i := 0; i < 20; i++ {
		arr[i] = i + 1
	}

	fmt.Println(arr[0:0])
}
PS E:\golang\src> go run .\main.go
[]
PS E:\golang\src>

复制切片元素到另一个切片

Go 语言内置函数 copy() 可以将一个切片中的数据复制到另一个切片中,使用格式如下:

copy( destSlice, srcSlice []T) int
  • srcSlice 代表源切片;
  • destSlice 代表目标切片。
    注意,目标切片必须有足够的空间来装载源切片的元素个数。返回值为整型,表示实际发生复制的元素个数。

演示代码如下:

package main

import "fmt"

func main() {
	// 设置元素数量为 10
	const count = 10

	// 源分片
	srcSlice := make([]int, count)

	// 给源分片赋值
	for i := 0; i < count; i++ {
		srcSlice[i] = i
	}

	// 目标分片
	destSlice := make([]int, count)

	// 将 srcSlice 分片的数据复制到 destSlice 中
	copy(destSlice, srcSlice)

	fmt.Println(srcSlice)
	fmt.Println(destSlice)
}
PS E:\golang\src> go run .\main.go
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
PS E:\golang\src>

另外,我们还可以复制指定范围的数据:

// 将 srcSlice 分片中指定范围的数据复制到 destSlice 中
copy(destSlice, srcSlice[4:8])

fmt.Println(srcSlice)
fmt.Println(destSlice)
[0 1 2 3 4 5 6 7 8 9]
[4 5 6 7 0 0 0 0 0 0]

从切片中删除元素

Go 语言中并没有提供特定的函数来删除切片中元素,但是可以利用切片的特性来达到目的:

package main

import "fmt"

func main() {
	// 声明一个字符串类型的切片
	arr := []string{"q", "u", "a", "n", "x", "i", "a", "o", "h", "a"}

	// 指定删除位置,也就是 u 元素
	index := 1

	// 打印删除位置之前和之后的元素, arr[:index] 表示的是被删除元素的前面部分数据,arr[index+1:] 表示的是被删除元素后面的数据
	fmt.Println(arr[:index], arr[index+1:])

	// 将删除点前后的元素拼接起来
	arr = append(arr[:index], arr[index+1:]...)

	fmt.Println(arr)
}
[q] [a n x i a o h a]
[q a n x i a o h a]

总结:Go 语言中切片删除元素的本质即 以被删除元素为分界点, 将前后两个部分的内存重新连接起来。

参考文献

Golang 【basic_leaming】切片
在这里插入图片描述

Go 语言字典 (Map)

初始化字典 map

Go 语言中定义字典 map 格式如下:

map [keyType]valueType
  • keyType 表示键类型;
  • valueType 表示键对应的值类型;

注意:键和键对应的值总是以一对一的形式存在。

下面是一段 map 的示例代码:

package main

import "fmt"

func main() {
	// 定义一个键类型为字符串,值类型为整型的 map
	m := make(map[string]int)

	// 向 map 中添加一个键为 “知其黑,受其白”,值为 1 的映射关系
	key := "知其黑,受其白"
	m[key] = 1

	// 输出 map 中键为 “知其黑,受其白” 对应的值
	fmt.Println(m[key])

	// 尝试输出一个不能存在的键,会输出该值类型的默认值
	n := m["知其黑,受其白2"]

	fmt.Println(n)
}
PS E:\golang\src> go run .\main.go
1
0
PS E:\golang\src>

上面代码最后,我们尝试从 map 中获取一个并不存在的键(key), 此时会输出值类型的默认值,整型的默认值为 0 。

当我们需要明确知道 map 中是否存在某个键(key)时,可以使用下面这种写法:

// 声明一个 ok 变量,用来接收对应键是否存在于 map 中
value, ok := m["知其黑,受其白2"]

// 如果值不存在,则输出值
if !ok {
  fmt.Println(value)
}

字段 map 的另外一种初始化方式

字典 map 还存在另外一种初始化方式, 代码如下:

import "fmt"

func main() {
	m := map[int](string){
		1: "wgchen",
		2: ".blog.csdn.",
		3: "net",
	}
	fmt.Println(m)
}
PS E:\golang\src> go run .\main.go
map[1:wgchen 2:.blog.csdn. 3:net]
PS E:\golang\src>

上面的这段代码并没有使用 make(), 而是通过大括号的方式来初始化字典 map, 有点像 JSON 格式一样,冒号左边的是键(key) , 右边的是值(value) ,键值对之间使用逗号分隔。

遍历字段 map

Go 语言中字典 map 的遍历需要使用 for range 循环,代码如下:

package main

import "fmt"

func main() {
	m := map[int](string){
		1: "wgchen",
		2: ".blog.csdn.",
		3: "net",
	}
	// 通过 for range 遍历, 获取 key, value 值并打印
	for key, value := range m {
		fmt.Printf("key: %d, value: %s\n", key, value)
	}
}
PS E:\golang\src> go run .\main.go
key: 2, value: .blog.csdn.
key: 3, value: net
key: 1, value: wgchen
PS E:\golang\src>

如果只需要遍历值,也可以通过 Go 语言变量 小节中说到的匿名变量来实现:

for _, value := range m {
	fmt.Printf("value: %s\n", value)
}

只遍历键时,通过下面这种方式:

for key := range m {
	fmt.Printf("key: %d\n", key)
}

注意: 字典 map 是一种无序的数据结构,不要期望输出时按照一定顺序输出。如果需要按顺序输出,请使用切片 来完成。

删除字典 map 中键值对

通过内置函数 delete() 来删除键值对,格式如下:

delete(map,)
  • map 表示要删除的目标 map 对象;
  • 键表示要删除的 map 中 key 键。

示例代码如下:

package main

import "fmt"

func main() {
	m := map[int](string){
		1: "wgchen.",
		2: "blog.csdn",
		3: ".net",
	}

	// 删除 map 中键为 1 的键值对
	delete(m, 1)

	// 通过 for range 遍历, 获取 key, value 值并打印
	for key, value := range m {
		fmt.Println(key, value)
	}
}
PS E:\golang\src> go run .\main.go
2 blog.csdn
3 .net
PS E:\golang\src>

能够在并发环境下使用的字典 sync.Map

Go 语言中的 map 在并发环境下,只读是线程安全的,同时读写是线程不安全的。

下面这段代码演示了并发环境下读写 map 会出现的问题,代码如下:

package main

func main() {
	// 初始化一个键为整型,值也为整型的 map
	m := make(map[int]int)

	// 开启一段并发代码
	go func() {
		// 无限循环往 map 里写值
		for {
			m[1] = 1
		}
	}()

	// 开启一段并发代码
	go func() {
		// 无限循环读取 map 数据
		for {
			_ = m[1]
		}
	}()

	// 死循环,让上面的并发代码在后台执行
	for {
	}
}

运行上面的代码,会报错如下:

fatal error: concurrent map read and map write

错误提示:因为并发的对 map 进行读写。

两个并发函数不断的对 map 进行读写发生了竞态问题。

map 内部会对这种并发操作进行检查并提前发现。

正常情况下,针对并发读写的场景,是需要加锁处理的。但是加锁就意味了性能不高。Go 语言在 1.9 版本中提供了一种高效率的并发安全的 sync.Map。

sync.Map 有以下特性:

  • 无需初始化,直接声明即可;
  • sync.Map 不能使用 map 的方式进行取值、设置等操作,而是使用 sync.Map 提供的方法进行调用,如:Store 表示存储,Load 表示获取,Delete 表示删除。
  • 针对遍历操作,需要使用 Range 配合一个回调函数,回调函数会返回内部遍历出来的值。Range 参数中的回调函数返回值功能是: 需要继续遍历时,返回 true;终止遍历时,返回 false。

示例代码如下:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var m sync.Map

	// 添加一些键值对到 map 中
	m.Store(1, "wgchen")
	m.Store(2, ".blog.csdn.")
	m.Store(3, "net")

	// 从 sync.Map 中获取键为 2 的值
	fmt.Println(m.Load(2))

	// 删除键值对
	m.Delete(1)

	// 遍历 sync.Map 中的键值对
	m.Range(func(key, value interface{}) bool {
		fmt.Printf("key: %d, value: %s\n", key, value)
		return true
	})
}
PS E:\golang\src> go run .\main.go
.blog.csdn. true
key: 2, value: .blog.csdn.
key: 3, value: net
PS E:\golang\src>

注意: sync.Map 没有提供获取 map 元素数量的方法,你需要自行遍历计数。

参考文献

Golang 【basic_leaming】map 详解
在这里插入图片描述

Go 语言 list (列表)_初始化_遍历_删除

列表 (list) 是一种非连续存储的容器,又多个节点组成,节点通过一些变量将彼此串联起来。

列表(list)底层常见的数据结构有: 单链表、双链表等。

在 Go 语言 中,列表的实现都在 container/list 包中,内部实现原理是双链表。

列表(list)能够方便高效地进行元素的删除、插入操作。

初始化 list (列表)

list 的初始化方法有两种:New声明
两者的效果是一样的。

1.1 通过 container/list 包中的 New 方法来初始化 list

格式如下:

变量名 := list.New()

1.2 通过声明初始化 list

格式如下:

var 变量名 = list.List

PS: 列表和 map (字典) 有什么区别?

相比较 map (字典),列表没有具体元素类型的限制,也就是说,你可以添加任意类型到 list 容器中,如 字符串 、整型 等。

这带来了一些便利,但是也存在一些问题:给一个列表添加了非期望类型的值后,在取值时,将 interface{} 转换为期望类型时会发生宕机。

向 list (列表) 中添加元素

双链表支持往队列前面或后面添加元素,对应的方法分别是:

  • PushFront
  • PushBack

示例代码如下:

l := list.New()
l.PushFront("知其黑,受其白")
l.PushBack("wgchen.blog.csdn.net")

关于 list (列表) 插入元素的方法,如下表所示:

方法功能
InsertAfter(v interface{}, mark *Element) *Element在 mark 点后面插入元素
InsertBefore(v interface{}, mark *Element) *Element在 mark 点前面插入元素
PushFrontList(other *List)添加 other 列表中的元素到头部
PushBackList(other *List)添加 other 列表中的元素到尾部

从 list (列表) 中删除元素

list (列表) 的插入函数的返回值是一个 *list.Element 结构,通过它来完成对列表元素的删除:

package main

import (
	"container/list"
)

func main() {
	l := list.New()

	// 头部添加字符串
	l.PushFront("知其黑,受其白")

	// 尾部添加字符串
	l.PushBack("wgchen.blog.csdn.net")

	// 尾部添加一个整型,并保持元素句柄
	element := l.PushBack(1)

	// 在 1 之后添加字符串 2
	l.InsertAfter("2", element)

	// 在 1 之前添加字符串 0
	l.InsertBefore("0", element)

	// 删除 element 对应的元素
	l.Remove(element)
}

遍历 list (列表)

遍历 list (列表) 需要搭配 Front() 函数获取头元素,遍历过程中,只要元素不为空则可继续调用 Next 函数往下遍历:

package main

import (
	"container/list"
	"fmt"
)

func main() {
	l := list.New()

	// 头部添加字符串
	l.PushFront("知其黑,受其白")

	// 尾部添加字符串
	l.PushBack("wgchen.blog.csdn.net")

	// 遍历
	for i := l.Front(); i != nil; i = i.Next() {
		fmt.Println(i.Value)
	}
}
PS E:\golang\src> go run .\main.go
知其黑,受其白
wgchen.blog.csdn.net
PS E:\golang\src>

注意,在 for 语句遍历中:

  • 其中 i := l.Front() 表示初始赋值,用来获取列表的头部下标;
  • 然后每次会循环会判断 i != nil,若等于空,则会退出循环,否则执行 i.Next() 继续循环下一个元素;

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

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

相关文章

Unreal Engine中的UHT和UBT

UBT&#xff1a;附加在引擎之外的一个自定义工具&#xff0c;用于管理跨各种构建配置&#xff0c;来配置和构建UE源码的过程。 UHT&#xff1a; 目录 UBT&#xff08;UnrealBuilderTool&#xff09; UHT&#xff08;UnrealHeadTool&#xff09; UBT&#xff08;UnrealBuilder…

《第三堂棒球课》:MLB棒球创造营·棒球名人堂

田中将大 田中将大(Tanaka Masahiro)&#xff0c;1988年11月1日出生于兵库县伊丹市&#xff0c;日本职业棒球运动员。 在2006年日本职棒高中生选秀会上被东北乐天金鹰队第一指选中&#xff0c;此后开始职业生涯。在2014年被纽约洋基队以上亿巨额签约&#xff0c;期限为七年。…

混合云运维,实现批量自动化配置

随着企业业务规模扩大和复杂化及云计算、大数据等技术不断发展&#xff0c;企业希望通过上云加速其数字化转型&#xff0c;以私有云为数据存储&#xff0c;保障安全&#xff0c;同时兼顾公有云的计算资源&#xff0c;公有云和私有云融合&#xff0c;混合云逐渐成为企业的大多数…

SpringBoot改动后0.03秒启动

SpringBoot改动后0.03秒启动 一、概述 GraalVM 是一种高性能运行时&#xff0c;可显着提高应用程序性能和效率&#xff0c;非常适合微服务. 对于 Java 程序 GraalVM 负责将 Java 字节码编译成机器码&#xff0c;映像生成过程使用静态分析来查找可从主 Java 方法访问的任何代码…

详细讲解MySQL在Linux中的部署(Centos为例)

本篇文章详解Mysql在Linux中的部署&#xff0c;以便于能够在SQLyog中远程连接MySQL服务&#xff0c;具体步骤如下所示&#xff1a; 1.查找并卸载mariadb 由于Centos7中自带mariadb&#xff0c;而mariadb是MySQL的一个分支&#xff0c;因此&#xff0c;按照MySQL前必须卸载mar…

【C++初阶】string的模拟实现

文章目录string的介绍string的模拟实现string类的成员变量Member functionsconstructor&#xff08;构造函数&#xff09;destructor&#xff08;析构函数&#xff09;operator(给创建出来的对象赋值)Iterators&#xff08;迭代器&#xff09;beginendCapacitysizecapacityrese…

Oracle --- 基础

目录 启动Oracle Oracle监听 监听服务的主要文件 listener.ora tnsnames.ora sqlnet.ora Oracle用户 创建用户 启动Oracle 四步 su - oracle # 切换用户&#xff0c;进入oracle的用户&#xff0c;读取oracle的配置文件lsnrctl start # 启…

手把手教您从建模到仿真计算优化改进新能源汽车电驱动系统转子冲片强度

导读&#xff1a;新能源汽车电驱动系统的主驱电机&#xff0c;正在向高功率密度、高扭矩密度、高效率、低成本、低损耗、轻量化、小型化、集成化、系列化等方向发展。这给各大零部件供应商&#xff0c;提出了一个又一个的新问题和新挑战。 为了降低结构尺寸、重量、原材料成本…

帮你拿下offer的软件测试面试技巧 赶紧码住!

想要进入一家软件类公司&#xff0c;拿到软件测试这方面岗位的offer&#xff0c;除了专业的技术知识过硬之外&#xff0c;必要的软件测试面试技巧也是少不了的&#xff0c;那么测试人们在面试过程中又应该如何作答呢&#xff1f; 这些可以帮你拿下offer的软件测试面试技巧记得不…

北斗导航 | ION GNSS+ 2014到 ION GNSS+ 2017会议论文下载:ION 美国导航学会

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 后文有 ION GNSS+ 2014、2015、2016、2017论文下载百度云链接美国导航学…

路由选择协议(计算机网络)

目录 理想的路由算法 关于最佳路由 从路由算法的自适应性考虑 互联网分层路由 分层路由和自治系统 边界网关协议 BGP 理想的路由算法 算法必须是正确的和完整的 算法在计算上应简单 算法应能适应通信量和网络拓扑的变化&#xff0c;这就是说&#xff0c;要有自适应性 算法…

Java高效率复习-MyBatis[MyBatis]

前言 ORM是持久化映射框架&#xff0c;但是MyBatis的本质并不是ORM框架。 如何使用MyBatis执行数据库语句 依赖导入 首先如果是Maven工程&#xff0c;则导入JDBC的依赖以及MyBaits的核心依赖。 <packaging>jar</packaging> <dependencies><dependenc…

Struts2漏洞 - Struts2-015 Struts2-016 Struts2-045

文章目录Struts2简介Struts2历史漏洞Struts2历史漏洞发现Struts2框架识别Struts2历史漏洞利用Struts2-015漏洞简介影响范围环境搭建漏洞复现Struts2-016漏洞简介影响范围环境搭建漏洞复现Struts2-045漏洞简介影响范围环境搭建漏洞复现Struts2简介 Apache Struts是美国阿帕奇&a…

制造管理系统在企业生产中的应用——百数制造系统

随着经济全球化程度的加深&#xff0c;企业对信息化的需求大大增加&#xff0c;对信息的集成度和管理要求也更加严格&#xff0c;信息化已经成为制造企业持续提升核心竞争力的必然趋势。数字化的制造管理系统在多年前一出现就赢得不少企业管理者的认可&#xff0c;再加上数字化…

Spark的宽窄依赖

依赖关系 RDD会不断进行转换处理&#xff0c;得到新的RDD 每个RDD之间就产生了依赖关系 窄依赖 一个Stage内部的计算都是窄依赖的过程&#xff0c;全部在内存中完成 定义&#xff1a;父RDD的一个分区的数据给子RDD的一个分区【不需要调用Shuffle的分区器】 特点&#xff1a; …

浅谈ReentrantLock的公平锁和非公平锁的区别

前言 最近在看java并发编程这本书&#xff0c;已经看了点ReentrantLock的源码&#xff0c;以及之前有面试官问&#xff0c;公平锁和非公平锁有啥区别&#xff0c;我就只是从源码层面说了一下区别&#xff0c;但在性能上也有区别&#xff0c;今天就来说道说道。 公平与非公平 …

Exponentiation

Exponentiation is a mathematical operation, written as bn, involving two numbers, the base b and the exponent or power n, and pronounced as “b (raised) to the (power of) n”.[1] When n is a positive integer, exponentiation corresponds to repeated multipli…

Mac卸载mysql并重新安装mysql

一、Mac卸载mysql 1、在系统偏好设置找到MySQL服务—>停止 2、打开终端 sudo rm /usr/local/mysql sudo rm -rf /usr/local/var/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf /Library/StartupItems/MySQLCOM sudo rm -rf /Library/PreferencePanes/My* vim /etc/ho…

财务分析和经营分析有什么区别和联系

财务分析是基础&#xff0c;经营分析是建立在财务分析基础之上的专项分析。财务分析做诊断&#xff0c;经营分析要治病。财务分析旨在通过财务指标发现和洞察问题&#xff0c;经营分析针对财务分析发现的问题进行深入的重点分析&#xff0c;以解决最终问题为目标。 财务分析 -…

世界上最伟大最邪恶的软件发明

有这么一个伟大而“邪恶”的软件发明&#xff0c;它被安装在超过10亿台电脑中&#xff0c;每天被使用超过3000万次。世界上几乎每个组织都在使用它&#xff0c;不仅有大大小小的公司&#xff0c;还有企业家、艺术家、非营利组织、学校、政府和宗教领袖&#xff0c;它已经成了公…