golang知识点

1.“=”和“:=”

在golang中“=”是赋值(使用=号赋值必须先var声明使用)

var a
a = 100
var b = 100
var c int =100

“:=”是声明变量后并赋值(:= 是声明并赋值并且系统自动推断类型,不需要var关键字)系统做了判断类型的工作

str := "hello"
d := 100

2.关于数组

//数组的长度必须是常量,并且长度是数组类型的一部分,长度不能改变 var a[5] int 和var b[6] int是不同的类型
var a [5] int
//

3.Slice切片

切片是一个拥有相同类型元素的可变长度的序列,它是机遇数组类型的一层封装,切片是一个引用类型它的内部结构为指向数组的地址、长度、容量。

a:=[5]int{1,2,3,4,5}
s:=a[1:3] // s为2,3 索引从0开始,索引范围(左包含右不包含)长度为3-1
s2:=make([]string,2,10)
//切片是引用类型,切片之间是不能使用==操作符来判断两个切片是否包含相同的元素,判断一个切片是否为空要用leng(s)==0来判断,不能用s==nil来判断
var a []int
a = make([]int, 0, 10) //make进行初始化一个切片 不然panlic 长度len为0 容量capacity为10
// a[0] = 1
// fmt.Println(a) //这样就panlic了 因为长度为0 导致的 index out of range
//不过我们可以使用 append 方法进行给切片追加元素,通过var声明的零值切片可以在append()函数直接使用无需初始化
a = append(a, 1)
fmt.Println(len(a), cap(a)) //查看下长度和 容量

切片的容量扩容策略

首先判断新申请的容量是否大于2倍的旧容量,如果大于新申请的容量就是最终容量。否则判断旧切片的容量是否小于1024,如果小于则最终容量就是旧容量的2倍,如果旧切片的容量大于1024则最终容量从旧容量开始循环增加原来的0.25倍直到最终容量等于新申请的容量,如果计算溢出,则最终容量就是新申请容量。

4.map

map是一种无序的机遇key-value的数据结构,map的key是唯一的不能重复(剔除重复值通常把值存入一个map的key中来判断),Go语言中的map是引用类型必须初始化。

5.函数

//test:函数名 a:参数 b:返回值
func test(a int)b int
{
	fmt.Println(a)
}

6.new和make

new函数得到的是一个类型的指针,并且该指针对应的值是该类型的零值

make也是用于内存分配make只用于slcie、map、chanel它返回的就是类型本身

7.类型定义和类型别名

//类型定义
type Newint int
//类型定义
type myint = int

类型别名只会在代码中存在,编译完成后就会消失不会有。

8.深拷贝和浅拷贝

深拷贝是拷的备份修改不会影响原来类型的值,浅拷贝拷的是指针地址修改会改变原来的值。

9.指针类型的接收者和值类型的接收者

由于指针的特性调用方法时,修改接收者指针的任意成员变量,在方法结束后修改都是有效的。

当方法作用于值类型接收者时,GO语言会在代码运行时将接收者的值复制一份,修改只是修改的复本

什么时候应该使用指针类型的接收者?

需要修改接收者中的值,接收者时拷贝代价比较大的对象,为了保证一致性,如果一个方法使用了指针,那么其他方法也应该使用。

10.Error接口和错误处理

go语言中的错误处理鱼其他语言不太一样,它把错误当成一种值来处理,更强调判断错误、处理错误而不是try catch捕获异常。

由于error是一个接口类型,默认值为nil所以我们通常将调用函数返回的错误与nil进行比较

自定义error可以使用errors.New("自定义的错误")或者定义一个错误变量var EOF = errors.New("EOF")

11.反射

go程序在运行期间使用reflect包访问程序的反射信息

任意接口值在反射中都可以理解为由reflect.TypeOf()和reflect.ValueOf()两部分组成

12.并发

串行:指从一到二再到三,顺序执行

并发:同一时间段内执行多个任务

并行:同一时刻执行多个任务

Go语言中的并发程序主要是通过基于CSP(Communicating Sequential Process)通信-顺序-进程模型的goroutine和channel来实现

goroutine是go语言支持并发的核心,在一个go程序中可以创建成百上千个goroutine,一个goroutine一般只需要2kb的内存,区别于操作系统的线程由系统内核进行调度,goroutine是由go运行时runtime负责调度。它会智能的将m哥goroutine合理分配给n个内核操作,也就是m:n

goroutine调度采用GPM也叫GMP模型

G:表示gotoutine,每执行一次go旧创建一个G,包含要执行的函数和上下文信息。

P:代表processsor处理数,可以通过runtime.GOMAXPROCS()设置个数,

M:代表thread线程,线程想要运行任务就得从P本地队列获取G,当P的本地队列为空时,尝试从全局队列或者其他P的队列获取G,M运行G,G执行之后M会从P中获取下一个G,不断重复。

运行图为最底层是硬件CPU核数>往上系统调度器>内核线程M(由系统给go程序动态分配)>P(processsor处理数)

每个P里面有多个goroutine队列,每个p不能存放超过256个goroutine,goroutine优先放入P中,如果满了放入全局队列,一个P同时只能执行一个goroutine,如果其中一个goroutine在m中阻塞了,会自动创建一个新的thread M把P和goroutine挪过去,阻塞线睡眠或者销毁,这是复用线程。

posted @   白黑黑  阅读(88)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示