当前位置: 首页 > news >正文

做电影资讯网站算侵权吗网页布局设计说明

做电影资讯网站算侵权吗,网页布局设计说明,医院门户网站模板下载,搜索引擎优化的例子协程面试题交替打印奇数和偶数N个协程打印1到maxVal交替打印字符和数字交替打印字符串三个协程打印ABCChannel练习交替打印奇数和偶数 下面让我们一起来看看golang当中常见的算法面试题 使用两个goroutine交替打印1-100之间的奇数和偶数, 输出时按照从小到大输出. 方法一&…

协程面试题

  • 交替打印奇数和偶数
  • N个协程打印1到maxVal
  • 交替打印字符和数字
  • 交替打印字符串
  • 三个协程打印ABC
  • Channel练习

交替打印奇数和偶数

下面让我们一起来看看golang当中常见的算法面试题
使用两个goroutine交替打印1-100之间的奇数和偶数, 输出时按照从小到大输出.
方法一:使用无缓冲的channel进行协程间通信

package mainimport ("fmt""sync"
)// PrintOddAndEven1 /*
func PrintOddAndEven1() {//方法一,使用无缓冲的channel进行通信var wg = new(sync.WaitGroup) //注意这里需要是指针go语言当中都是值传递wg.Add(2)ch := make(chan struct{}) //无缓冲channeldefer close(ch)maxVal := 100go func() {defer wg.Done()for i := 1; i <= maxVal; i++ {ch <- struct{}{}if i%2 == 1 { //奇数fmt.Printf("the odd is %d\n", i)}}}()go func() {defer wg.Done()for i := 1; i <= maxVal; i++ {<-ch          //从管道当中读取一个数据if i%2 == 0 { //偶数fmt.Printf("the even is %d\n", i)}}}()wg.Wait()}
func main() {PrintOddAndEven1()fmt.Println("over")
}

下面博主来解释一下这个的原理 首先因为变量ch是一个无缓冲的channel, 所以只有读写同时就绪时才不会阻塞。所以两个goroutine会同时进入各自的 if 语句(此时 i 是相同的),但是此时只能有一个 if 是成立的,不管goroutine快,都会由于读channel或写channel导致阻塞,因此程序会交替打印1-100且有顺序。

方法二:使用有缓冲的channel

func PrintOddAndEven2() {var wg = new(sync.WaitGroup) //注意这里需要是指针go语言当中都是值传递wg.Add(2)oddChan := make(chan struct{}, 1)eveChan := make(chan struct{}, 1)defer close(oddChan)defer close(eveChan)oddChan <- struct{}{}maxVal := 20go func() { //奇数协程defer wg.Done()for i := 1; i <= maxVal; i += 2 {<-oddChanfmt.Printf("the odd print %d\n", i)eveChan <- struct{}{} //通知偶数协程}}()go func() {//偶数协程defer wg.Done()for i := 2; i <= maxVal; i += 2 {<-eveChanfmt.Printf("the even print %d\n", i)oddChan <- struct{}{} //通知奇数协程可以打印了}}()wg.Wait()}func main() {PrintOddAndEven2()fmt.Println("over")
}

第二个方法使用这个有缓冲的channel。有缓冲的channel当容量没有达到上限时写入不会阻塞在这里奇数协程的channel容量为1我们提前给他写入了一个数据因此当偶数和奇数协程都开始读取数据时,首先读取到数据的是奇数协程,奇数协程打印完之后在通知偶数协程打印,偶数协程打印完成之后在通知奇数协程重复下去就实现了交替打印的效果。

N个协程打印1到maxVal

题目描述非常的简单就是N个协程交替打印1到maxVal。比如N=3,maxVal是这个100效果应该是第一个协程打印1,第二个协程打印2,第三个协程打印3,第一个协程打印4这样的效果。
这道题看起来非常的复杂,博主第一次看到这个题的时候也感觉很复杂但是仔细想一下其实并没有那么复杂和上面两题的解题思路是一样的。下面我们看看这个代码如何实现

package mainimport ("fmt""sync"
)func main() {maxVal := 10res := 0                        //用于打印数字N := 3                          //协程的数量exitChan := make(chan struct{}) //用于退出chanArr := make([]chan struct{}, N)for i := 0; i < N; i++ {//使用无缓冲的channelchanArr[i] = make(chan struct{}, 1)}num := 0 //记录轮到那个协程开始打印了chanArr[0] <- struct{}{}for i := 0; i < N; i++ {go func(i int) {for {<-chanArr[i]if res >= maxVal {exitChan <- struct{}{}break}fmt.Printf("第%d个协程打印%d\n", i, res)if num == N-1 {//已经循环一轮了轮到第0个协程打印数据了num = 0} else {num++}res++chanArr[num] <- struct{}{} //第num个协程可以打印数据了}}(i)}<-exitChanfor i := 0; i < N; i++ {close(chanArr[i]) //将管道全部关闭否则会有协程泄漏}}

其实也非常的简单也是利用channel来进行这个协程之间的通信,由于是N个协程之间进行通信所以了我们定义一个channel的切片首先往第一个channel当中写入一个数据其他管道没有写入数据那么最先打印的一定是这个第一个协程然后我们在利用一个计数器通知其他协程打印。最后需要注意的是主协程退出时需要将管道全部关闭否则其他协程一致阻塞在那里就会引起协程泄漏,就只能等到gc的时候才能回收。

交替打印字符和数字

问题描述: 使用两个 goroutine 交替打印序列,一个 goroutinue 打印数字, 另外一个goroutine打印字母, 最终效果如下 12AB34CD56EF78GH910IJ 。
如果铁子们上面两题会了那么这道题就是有手就行的那种和第一道题没有啥区别

func main() {numChan := make(chan struct{}, 1)chChan := make(chan struct{}, 1)defer close(numChan)defer close(chChan)var wg sync.WaitGroupwg.Add(2)numChan <- struct{}{}go func() {defer wg.Done()for num := 1; num <= 26; num++ {<-numChanfmt.Printf("%d", num)chChan <- struct{}{}}}()go func() {defer wg.Done()for ch := 'A'; ch <= 'Z'; ch++ {<-chChanfmt.Printf("%s", string(ch))numChan <- struct{}{}}}()wg.Wait()}

同样的也是利用这个channe进行通信,利用有缓冲的channel进行通信。当然也能使用这个无缓冲的channel进行通信

func main() {numChan := make(chan struct{})defer close(numChan)var wg sync.WaitGroupwg.Add(2)go func() {defer wg.Done()for num := 1; num <= 26; num++ {numChan <- struct{}{}fmt.Printf("%d", num)}}()go func() {defer wg.Done()for ch := 'A'; ch <= 'Z'; ch++ {<-numChanfmt.Printf("%s", string(ch))}}()wg.Wait()

交替打印字符串

题目描述,给定一个字符串使用两个协程交替打印它。
如果老铁们上面的拿到题都会了这道题不就是和第一道题是这个一模一样的吗?废话不多说直接上代码
方法一使用无缓冲的channel


func main() {chChan := make(chan struct{})defer close(chChan)var wg = new(sync.WaitGroup)wg.Add(2)str := "hello world"N := len(str)go func() {defer wg.Done()for i := 0; i < N; i++ {chChan <- struct{}{}if i%2 == 0 {fmt.Println(string(str[i]))}}}()go func() {defer wg.Done()for i := 0; i < N; i++ {<-chChanif i%2 == 1 {fmt.Println(string(str[i]))}}}()wg.Wait()}

当然也可以使用有缓冲的channel在这里铁子们可以自行编写上面写的太多了。

三个协程打印ABC

题目描述使用三个协程分别打印A,B,C打印这个100次。
本题的难度和上面那几个题完全是一个货色,我们可以使用三个有缓冲的channel就可以达到目的了。具体细节请看代码

package mainimport ("fmt""sync"
)func main() {Achan := make(chan struct{}, 1)Bchan := make(chan struct{}, 1)Cchan := make(chan struct{}, 1)defer close(Achan)defer close(Bchan)defer close(Cchan)Achan <- struct{}{}counter := 0maxVal := 10exitChan := make(chan struct{}) //用于退出go func() {for {<-Achanif counter >= maxVal {exitChan <- struct{}{}break}fmt.Printf("%s ", "A")counter++Bchan <- struct{}{}}}()go func() {for {<-Bchanif counter >= maxVal {exitChan <- struct{}{}break}fmt.Printf("%s ", "B")counter++Cchan <- struct{}{}}}()go func() {for {<-Cchanif counter >= maxVal {exitChan <- struct{}{}break}fmt.Printf("%s ", "C")counter++Achan <- struct{}{}}}()<-exitChan
}

在这里需要注意的点是我们需要close掉这个管道当达到临界值时,主协程退出但是defer方法会执行这个时候管道一关闭所有协程都会收到退出信号,另外两个阻塞在那里的协程就会退出这样就没有这个协程泄漏了。

##并发将多个文件合并到一个文件当中
MergeFile 把多个文件合成一个文件,并发实现子协程优雅退出。采用并发的方式
本题的解题思路同样的也非常的简单我们可以定义一个管道并发的读取文件写入到管道当中然后再并发的写入到文件当中。非常的简单

package mainimport ("bufio""fmt""io""os""strconv""sync"
)// MergeFile 把多个文件合成一个文件,并发实现子协程优雅退出var fileChan = make(chan string, 10000)
var writeFish = make(chan struct{})
var wg sync.WaitGroupfunc readFile(fileName string) {fin, err := os.Open(fileName)if err != nil {fmt.Println(err.Error())return}defer fin.Close()defer wg.Done()reader := bufio.NewReader(fin)for {line, err := reader.ReadString('\n') //注意已经包含换行符了if err != nil {if err == io.EOF {if len(line) > 0 {line += "\n"fileChan <- line}break} else {fmt.Println(err)break}} else if line == "\r\n" {fmt.Println("进来")continue} else {fileChan <- line}}}
func writeFile(fileName string) {fout, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)if err != nil {fmt.Println(err)return}defer fout.Close()defer func() {close(writeFish)}()writer := bufio.NewWriter(fout)//LOOP://	for {//		select {//		case <-readFish://			close(fileChan)//注意需要关闭因为已经没有人往里面写了//			for line:=range fileChan{//				writer.WriteString(line) //读取时候已经包含换行符了//			}//			break LOOP//		case line := <-fileChan://			writer.WriteString(line) //读取时候已经包含换行符了//		}////	}for {if line, ok := <-fileChan; ok {if line != "\r\n" {writer.WriteString(line)}} else {break}}writer.Flush() //刷新}func main() {wg.Add(3)for i := 1; i <= 3; i++ {fileName := "Dir/" + strconv.Itoa(i)go readFile(fileName)}go writeFile("Dir/merge")wg.Wait()close(fileChan)<-writeFish}

Channel练习

启动一个协程生成100个数发送到ch1管道当中,再启动一个协程从ch1当中取值然后计算平方将其放入ch2管道当中主协程打印

package mainimport ("fmt""sync"
)var wg sync.WaitGroupfunc f1(ch1 chan int) {defer wg.Done()for i := 0; i < 50; i++ {ch1 <- i}close(ch1)
}
func f2(ch2 chan int, ch1 chan int) {defer wg.Done()defer close(ch2)for x := range ch1 {ch2 <- x * x}
}
func main() {wg.Add(2)a := make(chan int, 50)b := make(chan int, 50)go f1(a)go f2(b, a)wg.Wait()for x := range b {fmt.Println(x)}}
http://www.yayakq.cn/news/20322/

相关文章:

  • 公司网站开发找哪家网站自助建站软件
  • 咖啡厅网站开发目标炒域名 网站
  • 商业网站建设案例课程 下载网站不在首页显示出来
  • 重庆网站运营公司做混剪素材下载网站
  • wordpress渐隐渐现页面过渡效果搜索引擎推广seo
  • 江苏省公路与水路建设网站横沥镇网站建设公司
  • 软文网站如何做一个网站
  • 做软件的网站php商务网站建设与维护补考试卷
  • 网站导航栏固定wordpress 酷播
  • 百川网站维护wp上的wordpress
  • 网站设计全包旅游网站信息门户建设方案
  • 做中文网站的公司网站制作加盟
  • 网站建设拍金手指谷哥12如何做ppt的模板下载网站
  • 外包公司做网站价格手机网站如何更改
  • 公司做网站app入什么科目企业邮箱888
  • 做网站用c语言吗西安免费网站建设
  • 网站vr视角怎么做网站asp代码
  • php网站开发招聘需求铜川网站建设公司电话
  • 开发公司网站wordpress制作简易前台会员中心
  • 智能建站系统排行郴州品牌网站建设推广
  • wordpress百度推送代码加统计广州网站优化系统
  • 一个服务器多个网站好吗网站建设工资郑州
  • 京东联盟网站怎么做自己做简单网站
  • 福永网站建设seo网络培训学校
  • 单页网站的域名官网用wordpress
  • 河北搜恒不给做网站淮北市建市
  • 医院网站制作公司wordpress主页怎么做
  • 南京做网站课程网站建设论文
  • 国内可以做网页的网站自己做都网站怎么发朋友圈
  • 哈尔滨模板建站推荐青岛seo招聘