下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 32 | 所有任务完成
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

Go语言从入门到实战

共55讲 · 55课时,约700分钟
6092
免费
01 | Go语言课程介绍
免费
02 | 内容综述
免费
03 | Go语言简介:历史背景、发...
免费
04 | 编写第一个Go程序
免费
05 | 变量、常量以及与其他语言...
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言...
12 | 字符串
13 | Go语言的函数
14 | 可变参数和defer
15 | 行为的定义和实现
16 | Go语言的相关接口
17 | 扩展与复用
18 | 不一样的接口类型,一样的...
19 | 编写好的错误处理
20 | panic和recover
21 | 构建可复用的模块(包)
22 | 依赖管理
23 | 协程机制
24 | 共享内存并发机制
25 | CSP并发机制
26 | 多路选择和超时
27 | channel的关闭和广播
28 | 任务的取消
29 | Context与任务取消
30 | 只运行一次
31 | 仅需任意任务完成
32 | 所有任务完成
33 | 对象池
34 | sync.pool对象缓存
35 | 单元测试
36 | Benchmark
37 | BDD
38 | 反射编程
39 | 万能程序
40 | 不安全编程
41 | 实现pipe-filter framew...
42 | 实现micro-kernel frame...
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结束语
本节摘要
展开

精选留言(8)

  • 2019-04-01
    for i:=1;i<=10;i++{
        go func(){
            ch<-ret
        }
    }

    for i:=1;i<=10;i++{
       <-ch
    }

    老师 针对以上程序我有个疑问,怎样可以使用 for range 而不用以上的 for 递增循环,因为看到网上 有for range 遍历 channel
            for v:=range ch {
            fmt.Println(v)
        }
    其实我想问的是 这种情况下 在哪里close后 再进行for range 希望老师帮忙解答
    展开

    作者回复: 继续看我的close和广播那一节,你就会有答案

    1
  • 2019-03-26
    蔡老师您好:
    您这节课的代码 有没有可能会出现
    channel在取数的时候,上面的go协程还没跑完 ch里面还没有数据

    for i:0;i<10;i++{
        go func(){
            ch<-ret
        }
    }

    total=""
    for i:0;i<10;i++{
        total+=<-ch
    }
    展开

    作者回复: 主携程会阻塞等待接收10个ch传来的我数据。所以在循环退出前程序不会退出

    1
  • 2019-08-01
    老师 我按照这个代码发现每次打印出来每次开启的协程数目都不一致,是与我的硬件机器有关系吗

    作者回复: Before和After的一样吗?
    什么机器?

    1
  • 2019-04-08
    老师,我往channel里面放的生产的数量,比如初始化i:=5,然后消费哪里还是j:=0,生产的不够消费就会阻塞,出现死锁情况。channel信道的输入输出一般是 成对 出现的,如果不成对那边就会出现死锁的情况。但是我如果反过来,生产大于消费,它不会阻塞,这种情况怎么理解呢?
    func AllResponse() string {
        numOfRunner := 10
        ch := make(chan string, numOfRunner)
        for i := 5; i < numOfRunner; i++ {
            go func(i int) {
                ret := runTask(i)
                ch <- ret
            }(i)
        }
        finalRet := ""
        for j := 0; j < numOfRunner; j++ {
            finalRet += <-ch + "\n"
        }
        return finalRet
    }

    报错:fatal error: all goroutines are asleep - deadlock!
    展开

    作者回复: 当你的buffered chan满的时候生产者放不进东西一样阻塞,但是你要注意你的接受者是主协程,而你的生产者是其他协程,所以不管生产者协程是否被阻塞,主要外部主协程退出,就会整合都推出了

  • 2019-04-03
    想请教下老师学习go的话哪些书籍或者学习资料比较有用呢

    作者回复: 最有用的就是那本经典“Go programming”和Go的官方文档了。另外,youtube上有不少Go创始人的视频讲座都值得看看。

  • 2019-04-03
    @橙子 看了对象池这节中, 蓝士钦老哥的留言, 突然就明白该怎么写了. 老师说的去看 27 | channel的关闭和广播 这节也是有涉及这些内容, 只是一下子没找到重点(或者说关键点)在哪儿, 看完之后, 还是很懵, 一头雾水. 代码如下:
    var wg sync.WaitGroup

    func AllResponse() string {
        numOfRunner := 10
        ch := make(chan string, numOfRunner)
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func(i int) {
                ch <- runTask(i)
                wg.Done()
            }(i)
        }

        finalStr := ""
        // for i := 0; i < numOfRunner; i++ {
        //     finalStr += <-ch + "\n"
        // }
        go func() {
            for {
                if v, ok := <-ch; ok {
                    finalStr += v + "\n"
                } else {
                    break
                }
            }
        }()

        wg.Wait()

        return finalStr
    }

    func TestAllResponse(t *testing.T) {
        fmt.Print(AllResponse())
    }
    展开
  • 2019-04-02
    老师, 我又去看了close和广播的那节课, 然后改了下代码, 但是这个并不是安全的, 偶尔会有致命错误(fatal error: all goroutines are asleep - deadlock!), 希望老师能够指点一下, 是哪里需要调整, 谢谢您了! 麻烦您指点一下
    var wg sync.WaitGroup

    func AllResponse() string {
        numOfRunner := 10
        ch := make(chan string, numOfRunner)
        for i := 0; i < 10; i++ {
            go func(i int) {
                wg.Add(1)
                ch <- runTask(i)
            }(i)
        }

        finalStr := ""
        // for i := 0; i < numOfRunner; i++ {
        //     finalStr += <-ch + "\n"
        // }
        go func() {
            for {
                if v, ok := <-ch; ok {
                    fmt.Println(v, ok)
                    finalStr += v + "\n"
                } else {
                    break
                }
            }
            wg.Done()
        }()

        wg.Wait()

        return finalStr
    }

    func TestAllResponse(t *testing.T) {
        fmt.Print(AllResponse())
        time.Sleep(time.Second)
    }
    展开

    作者回复: 1. 你的wg.Add(1)要放在子线程的外面。你可以再仔细看看课程里的代码。
    2. 实际上你没有必要用wait group,利用chan的阻塞就不会推出,只有channel关闭时才会break循环
    3. 代码里没看见close啊

  • 2019-03-26
    1:45“aggregation(聚合,聚集)“