ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字节后端训练营——Go由浅入深

2022-01-25 17:33:00  阅读:154  来源: 互联网

标签:由浅入深 int 训练营 Println func Go fmt append make


\(\color{blue}{容器:数组、切片、映射}\)

\(\color{purple}{Array}\)

var num1 [10]int
var num2 [5]int
var num3 [5]int32

(1)三种各不相同,只有元素类型和长度都完全相同,数组类型才相同

var num1 [3]int
num2 := [3]int{1,2,3}
num3 := [...]int{1,2,3}

(2)三种初始化方法
(3)数组类型是值类型,不是引用类型(函数传递后只操纵数组的备份)

\(\color{purple}{Slice}\)

type Slice struct{
	Data unsafe.Pointer
	Len int
	Cap int
}

(1)切片定义的几种方法

var aa []int
aa = make([]int,4)
bb := make([]int,4,6)
var num = [10]int{0,1,2,3,4,5,6,7,8,9}
slice1 := num[2:5:8] // [2,3,4],len = 3,cap = 6
slice2 := num[2:5] // 这里要注意slice之间的互相影响
slice3 := num[2:]
slice := num[:5]// [0,1,2,3,4]
slice := num[:]

(2)切片拷贝

slice2 := make([]int ,3)
copy(slice2,slice1[1:4])

(3)常用函数

// append 会自动扩容,但会影响性能,通常来说1024以下扩容翻一倍,以上增加1/4
slice1 := make([]int,0,2)
slice1 = append(slice1,1,2,3)
// range 遍历 事实上是一种拷贝,并不影响原来的切片
for _,n := range slice {
	n = n * 2
}

\(\color{purple}{Map}\)

映射的构成,和映射键值对的插入删除

students := make(map[string]int)
students["Jack"] = 10
delete(students , "Jack")

实现set:

map[string]struct{}

\(\color{purple}{Struct}\)

结构体的定义

type Gender int
struct{
	Female Gender = 0
	Male Gender = 1
}
type Person struct {
	Name string `json : "person_name" ` 
	Age int32
	Sex Gender
}

方法和函数的区别

func(p Person) ShowInfo(){
	if p.Sex == Female {
		fmt.Println("Her name is Alice")
	}else {
		fmt.Println("His name is Daniel")
	}
}

结构体的初始化法方法
这里注意到无论是指针还是结构体都是用.

// 1.直接初始化
// 2.使用&返回指针
// 3.使用new,返回结构体指针

\(\color{purple}{Interface}\)

描述某个类型有哪些方法。或者说一个接口类型,定义了一个方法集
空接口可以被认为是其他语言的“any”类型(Println()为什么什么东西都能打?)
类型断言

func main(){
	var x interface{} = 123
	// 1
	n,ok := x.(int)
	fmt.Println(n,ok) // 123 true
	// 2
	a,ok := x.(float64)
	fmt.Println(a,ok) // 0 false
	// 3
	a := x.(float64) //产生一个panic
}

\(\color{purple}{Goroutine}\)

func main(){
	fmt.Println("主协程开始")
	go func(){
		time.sleep(1*time.Second)
		fmt.Println("print log")
		time.Sleep(1*time.Second)
	}
	fmt.Println("主协程结束")
}

这里注意到主协程一旦结束其他都结束
JMP模型
协程与线程最好是N:M的关系
协程的调度器的设计策略(如何减少开销)
(1)复用线程
(2)利用并行
(3)抢占:限制协程执行时长
(4)全局协程队列:链表实现
常用的同步控制机制:WaitGroup

func main(){
	var wg sync.WaitGroup;
	for i := 0;i < 3;i++{
		wg.Add(1)
		go func(i int){
			t := rand.Intn(3)
			time.Sleep(time.Duration(t)*time.Second)
			wg.Done()
		}(i)
	}
	wg.wait()
}

\(\color{purple}{Channel}\)

并发模型CSP
管道的操作有:读写关闭

ch := make(chan string)
a = <-ch
ch <- "Hello" // 写一个已经关闭的channel就会引发panic

管道分类:无缓冲的管道(没有额外的拷贝,读在等写)和有缓冲的管道(会发生额外的拷贝,缓冲区的最大是65535)
交替打印A和B,(1)B发出信号(2)A打印,向B传信号(3)B...(4)打印完结束向主协程发信号

package main
import "fmt"
func main() {
	ch1 := make(chan string)
	ch2 := make(chan string)
	ch3 := make(chan string)
	go printA(ch1, ch2)
	go printB(ch1, ch2, ch3)
	<-ch3
}
func printA(ch1, ch2 chan string) {
	for i := 0; i < 100; i++ {
		<-ch2
		fmt.Println(i, "A")
		ch1 <- "print A"
	}
}
func printB(ch1, ch2, ch3 chan string) {
	ch2 <- "begin"
	for i := 0; i < 100; i++ {
		<-ch1
		fmt.Println(i, "B")
		if i != 99 {
			ch2 <- "print B"
		} else {
			ch3 <- "end"
		}
	}
}

\(\color{purple}{几项最佳实践}\)

(1) init()执行晚于变量的初始化而早于main()函数
(2) 关于切片追加,append的结果最好保留在相同的切片,如果要用新的切片,建议使用copy

func main(){
	x := []int{}
	x = append(x,0)// 1 1
	x = append(x,1)// 2 2
	y := append(x,3)//3 4
	z := append(x,4)//3 4 它影响到了y
	fmt.Println(x,y,z) // 都是[0 1 2] [0 1 2 4] [0 1 2 4]
}

(3)关于切片的构建
如果能预知切片的大小最好是预先设置,避免append的扩容带来的开销

size := 3
data := make([]int,size) // 使用data := make([]int,0,size)则可以,这样size只是cap
data = append(data,2) // [0,0,0,2]

(4)关于指针
Golang中两种指针1.限制型指针(只能寻址,但不能加减地址)2.无限制指针(unsafe.pointer)(可以任意写内存)
什么时候用指针(1.需要修改,不用的时候建议不用指针 2.容器占内存较大(提高性能)(这里注意到容器较小时因为有逃逸分析指针未必节省时间))
(5)关于panic
可以主动使用panic,常常和defer一起使用

func main(){
	go some()
	go func(){
		defer func(){
			if err := recover();err != nil{
				fmt.Println("panic is recovering")
			}
		}()
		panic("This is a panic")
	}
	time.Sleep(2*time.Second)
	fmt.Println("end")
}

标签:由浅入深,int,训练营,Println,func,Go,fmt,append,make
来源: https://www.cnblogs.com/OceanCT/p/15843815.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有