• go从入门到进阶的笔记


    做个流水账样式的笔记吧。在工作中用到go,但毕竟不是主力语言,有些地方可能用不到。

    业务需要又必须有地方用到go,最近打算改造现有的c++服务,用go替换其中的业务部分。

    最近看了徐波老师的go从入门到进阶。做了个流水笔记。

    根据这些知识点写了一堆代码,比较丑陋,我就不贴了啊。

    # 知识点大全

    ## 1 初始语言

    新,简单,快,风格清晰,标准库强大

    ## 2 基本语法

    变量的声明,赋值

    匿名变量

    数据类型:整型,浮点型,布尔型,字符串,
    字符,
    切片

    类型转换

    指针:类型指针,切片

    1 声明指针
    2 new()

    变量生命周期:栈,堆

    逃逸分析:自动决定变量分配方式,提高运行效率

    1 分析逃逸 -gcflags "-m -l"
    2 取址发生逃逸分析
    3 原则
    1 变量是否被取地址
    2 变量是否发生了逃逸

    字符串提供的操作

    长度,取地址,连接

    格式化

    %v %+v %#v $T %% %b %o %d %x $X %U %f %p

    常量const

    枚举iota

    类型别名和类型定义

    type NewInt int
    type IntAlias = int

    非本地类型无法添加方法

    ## 3 容器:存储和组织数据的方式

    数组:固定长度的连续内存区域

    切片:动态分配大小的连续空间

    1 数组或者切片产生
    2 make
    3 append copy 删除:

    map

    1 make
    2 range
    3 delete
    4 清除,依赖垃圾回收

    sync.Map

    1 初始化
    2 Store, Load, Delete
    3 Range

    container/list

    1 初始化list.New()
    2 PushBack PushFront
    3 Next

    ## 4 流程控制

    if
    for

    for range【array slice string map channel】

    switch fallthrough

    goto break continue


    ## 5 函数

    函数一等公民: 值传递,匿名函数,闭包,满足接口

    声明函数

    1函数支持多值返回值
    2支持直接返回变量

    结构体在函数中是值传递

    函数可以当做值

    匿名函数

    函数类型实现接口,函数赋值给接口

    闭包:函数+引用环境

    可变参数

    ...interface{}

    延迟执行语句 defer

    错误无处理 error

    type error interface{Error() string}

    panic 恐慌和recover


    ## 6 结构体

    new 或 & 类型的指针

    定义结构体

    实例化结构体

    1 var v1 T
    2 new(T)
    3 &T{}

    初始化结构体的成员变量

    1 初始多个值
    2 初始化匿名对象

    模拟构造函数

    嵌入式模拟父级构造函数

    方法

    func (接收器类型) 方法名(参数列表)(返回参数){}

    方法接收器

    1 指针接收器

    定义基本类型同名类型,添加方法

    类型内嵌

    1 可以直接访问内嵌的成员变量
    2 字段名就是它的类型名

    内嵌的组合


    ## 7 接口

    声明接口,接口的命名规范

    接口的实现条件:1 格式完全一样 2 方法都被实现

    类型和接口的关系

    使用接口抽象业务逻辑

    接口嵌套

    接口和类型间的转换:接口转类型,类型转接口

    t := i.(T)

    空接口类型 interface{}

    1 值存储到空接口
    2 空接口取值 i.(int)

    空接口值比较

    1 不同类比较结果不同,不能比较动态值

    空类分支 (interface{}).(type)

    ## 8 包

    GOPATH环境变量,提供项目的工作目录

    多个GOPATH

    创建包package

    1 一个目录下的同级文件归属一个包
    2 包名可以与目录不同
    3 无main包不输出可执行文件

    导出标识符:大写

    导入包import

    1 包别名 name xxx
    2 匿名导入包 _ "xxx"

    包的初始化 init

    1 一个包一个
    2 初始化顺序

    工厂模式管理多个包的结构体


    ## 9 并发

    创建协程go

    使用匿名函数创建协程

    runtime.GOMAXPROCS()设置核心数量


    通道chan

    make(chan XX)

    通道发送数据:通道<-数据

    通道接收数据:数据 :=<-通道

    data,ok :=<-ch
    for data :=range ch{}

    单向通道 只发送:chan<-

    单向通道 只接收:<-chan

    带缓存的通道

    通道的多路复用select

    time.After 计时器

    time.NewTicker 定点计时器

    关闭通道 close


    go run -race 检测竞争


    同步之atomic

    同步之互斥锁 sync.Mutex

    sync.Mutex
    sync.RWMutex


    同步之等待组 sync.WaitGroup


    ## 10 反射

    反射是指在程序运行期间对程序本身进行访问和修改的能力。

    反射的类型对象 reflect.Type

    reflect.TypeOf(a)

    反射的类型Type,系统原生类型

    反射的种类Kind,类型归属的种类

    reflect.Elem获取指针指向的元素的类型

    反射获取结果提的成员

    Field(i)StructField
    NumField()int
    FieldByName(name)(StructField,bool)
    FieldByIndex(index []int) StructField
    FieldByNameFunc(match func(string)bool)(StructField,bool)

    StructField

    Name,PkgPath, Type, Tag, Index, Anonymous

    StructTag

    Get(key)string, Lookup(key)(string,bool)

    反射的值对象reflect.Value

    使用反射对象包装任意值 reflect.ValueOf(rawValue)

    从反射值获取被包装的值

    Interface()interface{}
    Int(),Uint(),Float(),Bool(),Bytes(),String()

    使用反射访问结构体的成员字段的值

    Field(i)Value
    NumberField()
    FieldByName(name)Value
    FieldByIndex(index []int)Value
    FieldByNameFunc(match func(string)bool)Value

    反射对象的空和有效性判断

    isNil, isValid

    使用反射值对象获取变量的值【先寻址,再修改】

    Elem()类似*
    Addr()类似&
    CanAddr()bool
    CanSet()bool

    使用反射值对象修改相关的方法

    SetInt,SetUint,SetFloat,SetBool,
    SetBytes,SetString

    通过类型创建类型的实例

    1 reflect.New(typeOfA)

    使用反射调用函数

    funcValue.Call(xx)


    ## 11 编译与工具

    go build

    -v 包名
    -p 并发编译
    -a 强制重新构建
    -race 开启竞态检测

    go run

    go install 编译并安装

    go get

    go test

    文件 XX_test
    方法 TestXX(t *testing.T)

    test指定方法

    go test -v -run TestA xxxx_test.go

    终止测试 t.FailNow()

    基准测试

    Benchmark_Add(b *testing.B) b.N
    go test -v -bench=. xxxx_test.go

    自定义bench时间 -bench -benchtime=5s

    测试内存 -bench=Alloc -benchmem xxx_test.go

    控制计时器

    b.ResetTimer() 重置
    b.StopTimer() 停止
    b.StartTimer() 开始

    性能分析 go pprof

    1 安装Graphviz 图形的工具包
    2 runtime.pprof可以使用,但是不太方便
    3 go get github.com/pkg/profile
    4 go build
    5 go tool pprof --pdf xxx xx.pprof > xx.pdf

    ## 12 避坑与技巧

    ### 合理地使用并发特性

    1 了解goroutine的生命期再创建goroutine

    创建,退出

    2 避免在不必要的地方使用通道

    1 通道为了保证goroutine并发访问,也需要做锁操作

    3 反射:性能和灵活性的双刃剑

    1 使用原生代码,避免反射
    2 提前缓存反射对象对性能帮助较大
    3 避免使用反射函数调用,实在需要时,提前缓冲函数参数列表,并尽量少使用返回值

    4 nil只能被赋值给指针和接口

    接口底层 type和data,都为nil是才是nil

    发现返回nil时直接返回nil


    基于哈希值的多键索引及查询

    1 字符串转哈希值
    2 查询键值


    优雅的处理TCP粘包


  • 相关阅读:
    hcharts实现堆叠柱形图
    程序员常用的六大技术博客类
    程序员常用的六大技术博客类
    程序员常用的六大技术博客类
    程序员常用的六大技术博客类
    前端几个常用简单的开发手册拿走不谢
    web开发快速提高工作效率的一些资源
    web开发快速提高工作效率的一些资源
    基础知识(5)- 继承
    51 NOD 1384 全排列(STL 搜索)
  • 原文地址:https://www.cnblogs.com/beckbi/p/11619288.html
Copyright © 2020-2023  润新知