并行在线词典 | 青训营笔记

62 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第3天

前言

不知不觉已经2月1日,青训营开营也有好多天了。但我竟然还在写第一天的作业。但无论如何,从现在做起还是比什么都不做都好的。

猜谜游戏

顺便把猜谜游戏写一下吧。比较简单,所以标题里面没有提及。

maxNum := 100
rand.Seed(time.Now().UnixNano())
serectNum := rand.Intn(maxNum)
fmt.Println(serectNum)
var s int
var count int
fmt.Println("请输入0-100的正整数")
for {
   _, err := fmt.Scanf("%d", &s)
   if err != nil {
      fmt.Println("输入不合法,请重试", err)
      continue
   }
   count++
   fmt.Println("您猜的数为;", s)
   if s < serectNum {
      fmt.Println("您猜小了,请再次尝试吧")
   } else if s > serectNum {
      fmt.Println("您猜大了,请再次尝试吧")
   } else {
      fmt.Printf("您猜对了,总共用了%d次,恭喜您!\n", count)
      break
   }
}

核心逻辑其实蛮简单了,但是遇到了不少问题。fmt.Scanf函数在window环境下不能正常使用,在linux环境下正常。我使用的wsl,用着还蛮舒服的。相关问题已经有人提了issue,但是我一直没能打开。链接贴着这里,有需同学可以查看。issue5391

并行在线字典

讲下我的思路。首先将之前的运行时添加参数来查询改为了命令行窗口输入来执行,更加符合我的个人逻辑。在对多个翻译引擎进行并行翻译时,我采用的是不同翻译的协程将翻译的结果传入定义好的channel。也看了其他同学的做法是运用了waitGroup的锁来实现。我现在的理解还比较浅显,不知道两种实现方式的优劣。

  • 主要逻辑部分的代码
var s string
result := make(chan string)
for {
   _, err := fmt.Scanf("%s", &s)
   if err != nil {
      log.Fatal(err)
   }
   go query(s, result)
   go query2(s, result)
   go func() {
      for i := range result {
         fmt.Println(i)
      }
   }()

}
  • 运行时截图

image.png 百度翻译和彩云小译的输出顺序并不相同,与其响应速度相关。

问题与思考

即使写两个这样的很小的程序,我也遇到了不少问题的。在写猜谜游戏时,代码量比较小,没什么问题。但是在写并行词典时,还是会遇到命名的问题。回头看代码时,发现命名的很随意,其表现力并不是很清晰,代码规范的能力还是需要加强。 另外的问题就是爬一些别的搜索引擎时,有的引擎不会爬,有的爬到了,返回的json十分复杂,是在基础的结构上,有一串特别长的string。 最后的实现是调用了百度翻译的api,但是是基础版,没有音标这些内容。所以上面的代码示例也没有对齐。 总得来说,写的代码还是有许多改进的地方,继续学习吧。