• 【字节青训营后端专场】Go 语言上手 工程实践


    并发编程

    并发vs并行
    并发:多线程在一个核的cpu运行
    并行:多线程在多个核的cpu运行

    Goroutine

    func hello(i int){
        .......
    }
    func HelloGoRoutine(){
        for i:=0;i<5;i++{
            go func (j int){
                hello(j)
            }(i)
        }
        time.Sleep(time.Second)//防止协程结束前 主进程结束
    }
    

    CSP 协程之间的通信

    go提倡通过通信共享内存

    Channel

    make(chan int)//无缓冲通道
    make(chan int,2)//有缓冲通道
    

    无缓冲通道:同步通道,发送接收几乎同时
    有缓冲通道:取走才能放
    考虑子协程A,B A发送数字,B计算数字的平方,主协程输出
    发现最终输出有序

    func CalSquare(){
        src:=make(chan int)
        dest:=make(chan int,3)//考虑主协程中的“消费”操作更加复杂,为解决“生产”和“消费”速率不均衡带来的效率问题,使用缓冲
        go func(){
            defer close(src)//延迟的资源关闭
            for i := 0; i < 10; i++ {
                src <- i
            }
        }()
        go func(){
            defer close(dest)
            for i := range src {
                dest <- i * i
            }
        }()
        for i := range dest {
            println(i)
        }
    }
    

    并发安全 Lock

    var {
        x int64
        lock sync.Mutex
    }
    func addWithLock() {
        for i := 0; i < 2000; i++ {
            lock.Lock()
            x+=1
            lock.Unlock()
        }
    }
    func addWithoutLock(){
        for i := 0; i < 2000; i++ {
            x+=1
        }
    }
    func Add(){
        x = 0
        for i := 0;i < 5; i++ {
            go addWithoutLock()
        }
        time.Sleep(time.Second)
        println(x)//10000
        x = 0
        for i := 0;i < 5; i++ {
            go addWithoutLock()
        }
        time.Sleep(time.Second)
        println(x)//可能<10000
    }
    

    WaitGroup

    Add(delta int)//计数器+delta
    Done()//计数器-1
    Wait()//阻塞直到计数器为0

    func hello(i int){
        .......
    }
    func HelloGoRoutine(){
        var wg sync.WaitGroup
        wg.Add(5)
        for i:=0;i<5;i++{
            go func (j int){
                defer wg.Done()
                hello(j)
            }(i)
        }
        wg.Wait()
        time.Sleep(time.Second)//防止协程结束前 主进程结束
    }
    

    依赖管理

    GOPATH

    环境变量 其下有
    bin目录:项目编译的二进制文件
    pkg目录:项目编译的中间产物,加速编译
    src目录:项目源码

    项目代码直接依赖src下的代码
    go get下载最新版本的包到src目录下
    无法实现package的多版本控制(package版本更新)

    Go Vendor

    增加vendor文件夹 先在vendor下寻找,再去GOPATH下寻找
    依赖冲突导致编译错误

    Go Module

    通过go.mod文件管理依赖包版本
    通过go get/go mod指令工具管理依赖包
    go.mod:配置文件,描述依赖
    Proxy:中心仓库管理依赖库
    go get/go mod:本地工具

    单元测试

    规则

    测试文件以_test.go结尾
    func TestXxx( * testing.T)
    初始化逻辑放到TestMain中

    func HelloTom() string {
        return "Jerry"
    }
    
    
    
    func TestHelloTom(t *testing.T) {
        output := HelloTom()
        expectOutput := "Tom"
        if output != expectOutput {
            t.Error("Expected %s do not match actual %s",expectOutput,output)
        }
    }
    

    覆盖率

    反映被测试函数被测试的函数占比
    较高 80%+

    项目实践

  • 相关阅读:
    mongodb.conf配置文件
    mongodb创建普通角色和普通用户
    add unique index 注意事项
    error: src refspec master does not match any
    innodb_data_file_path配置变更引发mysql重启失败
    time_zone参数配置
    主键有无检测
    gdb在线修改mysql变量
    mybatis连接数据库
    mongo登录
  • 原文地址:https://www.cnblogs.com/lsgjcya/p/16247532.html
Copyright © 2020-2023  润新知