去哪儿面试题 (Golang实现)多线程顺序输出1-75

FredricZhu · 2019-06-06 19:32:39 · 4818 次点击 · 预计阅读时间不到 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-06-06 19:32:39 的文章,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
    "sync"
    "time"
)

var waiter sync.WaitGroup

func print5(i int) {
    j := i
    for j < i+5 {
        fmt.Println(j)
        j++
    }
    waiter.Done()
}

func main() {
    fmt.Println("Start print 75")
    waiter = sync.WaitGroup{}
    waiter.Add(15)

    for i := 1; i < 75; i += 5 {
        go print5(i)
        time.Sleep(1 * time.Nanosecond)
    }

    waiter.Wait()
    fmt.Println("End print 75")
}

程序输出如下,


image.png

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:FredricZhu

查看原文:去哪儿面试题 (Golang实现)多线程顺序输出1-75

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4818 次点击  
加入收藏 微博
13 回复  |  直到 2022-07-14 11:09:20
ska-guilinstyle
ska-guilinstyle · #1 · 6年之前
var a struct {

    Mu sync.RWMutex

    Count int

}


var wg sync.WaitGroup


func main()  {

    wg = sync.WaitGroup{}

    wg.Add(75)

    for i:=1; i<=75; i++ {

        go Add()

    }
    wg.Wait()
}

func Add()  {

    defer wg.Done()

    a.Mu.Lock()

    a.Count++

    fmt.Println(a.Count)

    a.Mu.Unlock()

}
yidane
yidane · #2 · 6年之前

输出结果不稳定,也就是说结果不对

izhaoyun
izhaoyun · #3 · 6年之前

没有明白意思,是要控制goroutine输出顺序吗?

yidane
yidane · #4 · 6年之前
package main

import (
    "fmt"
)

var ch = make(chan int)

func print5(i int) {
    <-ch
    fmt.Println(i)
}

func main() {
    fmt.Println("Start print 75")

    for i := 1; i <= 75; i ++ {
        go print5(i)
        ch <- 1
    }

    fmt.Println("End print 75")
}
yidane
yidane · #5 · 6年之前
izhaoyunizhaoyun #3 回复

没有明白意思,是要控制goroutine输出顺序吗?

意思是通过携程输出1-75,要求结果顺序连续。

Ayyouy
Ayyouy · #6 · 3年之前
yidaneyidane #5 回复

#3楼 @izhaoyun 意思是通过携程输出1-75,要求结果顺序连续。

最后一种我试了不行,前面几种我试了都不行,我重新写的:

// 1、多线程顺序输出 1~75 var wg sync.WaitGroup

func print5(i int) { j := i for j < i+5 { time.Sleep(1 * time.Second) // 这个是为了缓慢输出 fmt.Println(j) j++ } wg.Done() }

func print75() { fmt.Println("Start Print 1~75 !") wg = sync.WaitGroup{} wg.Add(15) for i := 1; i < 75; i += 5 { time.Sleep(8 * time.Second) // 这个是为了缓慢输出 go print5(i) } wg.Wait() fmt.Println("End Print 1~75 !") }

Ayyouy
Ayyouy · #7 · 3年之前

var cv = make(chan int)

func print5_1() { fmt.Println(<-cv) time.Sleep(1 * time.Second) wg.Done() }

func print75_1() { wg.Add(75) for i := 1; i <= 75; i++ { time.Sleep(2 * time.Second) go print5_1() cv <- i } wg.Wait() }

Srim_ycb
Srim_ycb · #8 · 3年之前
type Num struct {
  val int
  mu  sync.RWMutex
}

func main() {
  num := new(Num)

  wg := sync.WaitGroup{}
  add := func() {
    num.mu.Lock()
    num.val++
    fmt.Println(num.val)
    num.mu.Unlock()
    wg.Done()
  }

  for i := 0; i < 75; i++ {
    wg.Add(1)
    go add()
  }
  wg.Wait()
}
hshd123
hshd123 · #9 · 3年之前

这道题感觉就是傻逼题目,go 协程 刻意就是没有顺序的,在怎么控制,效率都没高多少,用加锁的形式输出,还不如主线程速度快,控制顺序 逃不了 要抢锁别无他法

goxiaoxu
goxiaoxu · #10 · 3年之前

估计就是考验面试者,对goroutine和channel理解,和使用程度

etog
etog · #11 · 3年之前

给他上个链表 :dog:

package main

import (
    "fmt"
    "time"
)

type null struct{}

func main() {

    n := 75
    current := make(chan null)
    next := make(chan null)
    head := current
    for i := 0; i < n; i++ {
        go print(i, current, next)
        current = next
        next = make(chan null)
    }
    close(head)
    time.Sleep(time.Second)
}

func print(i int, r, s chan null) {
    _, ok := <-r
    if !ok {
        fmt.Println(i + 1)
        if s != nil {
            close(s)
        }
    }
}
arcwim
arcwim · #12 · 3年之前

这题目是考察任务编排吧

func main() {
    const max = 75
    chs := make([]chan struct{}, max)
    for i := 0; i < max; i++ {
        chs[i] = make(chan struct{})
    }

    for i := 0; i < max; i++ {
        go print5(i+1, chs[i], chs[(i+1)%max])
    }

    chs[0] <- struct{}{}

    time.Sleep(time.Minute)
}

func print5(i int, ch, chNext chan struct{}) {
    <-ch
    fmt.Println(i)
    chNext <- struct{}{}
}
zzustu
zzustu · #13 · 3年之前

你看下面这代码,满足了题目中的要求,也做到了简单易懂。可是还是对题目用意一脸懵逼

func main() {
    var wg sync.WaitGroup
    for i := 1; i < 76; i++ {
        wg.Add(1)
        go printN(&wg, i)
        wg.Wait()
    }
}

func printN(wg *sync.WaitGroup, i int) {
    fmt.Println(i)
    wg.Done()
}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传