赞
踩
相互转化
[:]
方式将数组转换成切片。// 初始化一个数组
a0 := [2]int{1, 2}
// 初始化一个切片
s1 := make([]int, 5, 5)
fmt.Println(a0)
fmt.Println(s1)
// 无法将 'a0' (类型 [2]int) 用作类型 []int
// s1 = a0
// 无法将 's1' (类型 []int) 用作类型 [2]int
// a0 = s1
// 可以使用[:]方式将数组转换成切片
fmt.Println(copy(s1, a0[:]))
fmt.Println(a0)
fmt.Println(s1)
fmt.Println(copy(a0[:], s1))
fmt.Println(a0)
fmt.Println(s1)
类型 | 长度(字节) | 默认值(零值) | 说明 |
---|---|---|---|
bool | 1 | false | |
byte | 1 | 0 | uint8 |
rune | 4 | 0 | Unicode Code Point, int32 |
int, uint | 4或8 | 0 | 32 或 64 位 |
int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255,byte是uint8 的别名 |
int16, uint16 | 2 | 0 | -32768 ~ 32767, 0 ~ 65535 |
int32, uint32 | 4 | 0 | -21亿~ 21亿, 0 ~ 42亿,rune是int32 的别名 |
int64, uint64 | 8 | 0 | |
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | |
complex64 | 8 | ||
complex128 | 16 | ||
uintptr | 4或8 | 以存储指针的 uint32 或 uint64 整数 | |
array | 值类型 | ||
struct | 值类型 | ||
string | “” | UTF-8 字符串 | |
slice | nil | 引用类型 | |
map | nil | 引用类型 | |
channel | nil | 引用类型 | |
interface | nil | 接口 | |
function | nil | 函数 |
sync.map
则是一种并发安全的 map(Go 1.9 引入)。GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW)。
GC期间,任何在栈上创建的新对象,均为黑色。
被删除的对象标记为灰色。
被添加的对象标记为灰色。
Go 1.3 - 普通标记清除法,整体过程需要启动STW,效率极低。
Go 1.5 - 三色标记法,堆空间启动写屏障,栈空间不启动,全部扫描之后,需要重新扫描一次栈(需要STW),效率普通。
Go 1.8 - 三色标记法,混合写屏障机制,栈空间不启动,堆空间启动。整个过程几乎不需要STW,效率较高。
Go语言中实现了两种并发模型,一种线程与锁并发模型,另一种是CSP(communicating sequential processes)通信顺序进程模型。
用户线程由用户空间的代码创建、管理和销毁,线程的调度由用户空间的线程库完成(可能是编程语言层次的线程库),无需切换内核态,资源消耗少且高效。对 CPU 的竞争是以所属进程的维度参与的,同一进程下的所有用户级线程只能分时复用进程被分配的 CPU 时间片,所以无法很好利用 CPU 多核运算的优势。我们一般情况下说的线程其实是指用户线程;
内核线程由操作系统管理和调度,能够直接操作计算机底层的资源,线程切换的时候 CPU 需要切换到内核态。它能够很好利用多核 CPU 并行计算的优势,开发人员可以通过系统调用使用内核线程。
两级线程模型相当于用户级线程和内核级线程的结合,一个进程将会对应多个内核线程,由进程内的调度器决定进程内的线程如何与申请的内核线程对应。
MPG 线程模型对两级线程模型进行一定程度的改进
如果 slice == nil,那么 len、cap 结果都等于 0。
s00 := make([]int, 0)
fmt.Println(len(s00))
fmt.Println(cap(s00))
var s01 []int
fmt.Println(len(s01))
fmt.Println(cap(s01))
0
0
0
0
使用:=创建切片,cap、len的结果为切片的长度。
// 使用:=创建切片
s1 := []int{1, 2, 3}
fmt.Println(len(s1))
fmt.Println(cap(s1))
3
3
使用make创建切片,若指定cap,则cap为指定的cap;若未指定cap,则cap等于len。切片容量 ≥ 切片长度。
// 使用make创建切片
var s2 = make([]int, 3)
fmt.Println(len(s2))
fmt.Println(cap(s2))
var s3 = make([]int, 3, 5)
fmt.Println(len(s3))
fmt.Println(cap(s3))
3
3
3
5
当切片的底层数组不足以容纳所有给定值时,它就会分配一个更大的数组,切片会指向这个新分配的数组(通常以 2 倍容量重新分配底层数组)。
// 切片扩容
var s4 = make([]int, 3, 5)
fmt.Println(len(s4))
fmt.Println(cap(s4))
s4 = append(s4, 1,2,3,4,5,6)
fmt.Println(len(s4))
fmt.Println(cap(s4))
3
5
9
10
在大批量添加数据时,建议一次性分配足够大的空间,以减少内存分配和数据复制开销。或初始化足够长的 len 属性,改用索引号进行操作。及时释放不再使用的 slice 对象,避免持有过期数组,造成 GC 无法回收。
go build [-o output] [-i] [build flags] [packages]
-o:指定输出目录与打包后的文件名,代替默认的包名。
-i:安装作为目标的依赖关系的包(用于增量编译提速)
set GOARCH=amd64
set GOOS=windows
go build main.go
set GOARCH=amd64
set GOOS=linux
go build main.go
GOOS:目标操作系统
- darwin
- freebsd
- linux
- windows
- android
- dragonfly
- netbsd
- openbsd
- plan9
- solaris
GOARCH:目标处理器的架构
- arm
- arm64
- 386
- amd64
- ppc64
- ppc64le
- mips64
- mips64le
- s390x
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。
算法名称 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 | 备注 |
---|---|---|---|---|---|---|
选择排序 | n 2 n^2 n2 | n 2 n^2 n2 | n 2 n^2 n2 | 1 1 1 | 不稳定 | |
冒泡排序 | n 2 n^2 n2 | n 2 n^2 n2 | n n n | 1 1 1 | 稳定 | |
插入排序 | n 2 n^2 n2 | n 2 n^2 n2 | n n n | 1 1 1 | 稳定 | |
堆排序 | n l o g 2 n nlog_2n nlog2n | n l o g 2 n nlog_2n nlog2n | n l o g 2 n nlog_2n nlog2n | 1 1 1 | 不稳定 | |
希尔排序 | n 1.3 n^{1.3} n1.3 | n 2 n^2 n2 | n n n | 1 1 1 | 不稳定 | |
归并排序 | n l o g 2 n nlog_2n nlog2n | n l o g 2 n nlog_2n nlog2n | n l o g 2 n nlog_2n nlog2n | n n n | 稳定 | |
快速排序 | n l o g 2 n nlog_2n nlog2n | n 2 n^2 n2 | n l o g 2 n nlog_2n nlog2n | n l o g 2 n nlog_2n nlog2n | 不稳定 | |
桶排序 | n + k n+k n+k | n 2 n^2 n2 | n n n | n + k n+k n+k | 稳定 | |
计数排序 | n + k n+k n+k | n + k n+k n+k | n + k n+k n+k | n + k n+k n+k | 稳定 | |
基数排序 | n ∗ k n*k n∗k | n ∗ k n*k n∗k | n ∗ k n*k n∗k | n + k n+k n+k | 稳定 |
法一:
- 以100为粒度寻找对应得百区间
- 以10为粒度寻找对应得十区间
- 以1为粒度寻找对应得个区间
法二:
二分查找
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠连接,不使用流量控制和拥塞控制 | 可靠连接,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一、一对多、多对一和多对多交互通信 | 只能一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部开销最小20字节、最大60字节 |
适用场景 | 适用实时应用(IP电话、视频会议、直播) | 适用于要求可靠传输的应用,如文件传输 |
这是个挖坑的问题!!!
只能说自己没努力,任何客观的解释都无效!
加班!!!
https://www.cnblogs.com/HinaChan/p/14842521.html#
https://cloud.tencent.com/developer/article/1444356
https://www.topgoer.com/go%E5%9F%BA%E7%A1%80/%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B.html
http://dockone.io/article/10491
https://blog.csdn.net/qq_40694036/article/details/101170698
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。