后端基础班Day1-课后作业思路 | 青训营笔记

184 阅读2分钟

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

本篇笔记主要讲解一下课后作业的思路

Part 1

image.png

这个比较简单,其实没有什么特殊需要注意的。

func main() {
   maxNum := 100
   rand.Seed(time.Now().UnixNano())
   secretNumber := rand.Intn(maxNum)
   // fmt.Println("The secret number is ", secretNumber)

   fmt.Println("Please input your guess")
   //reader := bufio.NewReader(os.Stdin)
   var str string // 存储输入值
   for {
      //input, err := reader.ReadString('\n')
      _, err := fmt.Scan(&str)
      if err != nil {
         fmt.Println("An error occured while reading input. Please try again", err)
         continue
      }
      str = strings.Trim(str, "\r\n") // 消去无用换行

      guess, err := strconv.Atoi(str) // 转类型
      if err != nil {
         fmt.Println("Invalid input. Please enter an integer value")
         continue
      }
      fmt.Println("You guess is", guess)
      if guess > secretNumber {
         fmt.Println("Your guess is bigger than the secret number. Please try again")
      } else if guess < secretNumber {
         fmt.Println("Your guess is smaller than the secret number. Please try again")
      } else {
         fmt.Println("Correct, you Legend!")
         break
      }
   }
}

个人用的是string类型去读,可以尽可能的接近原来的版本,并且有进行非法输入的判断。

Part 2

image.png

这里主要要寻找方便的搜索引擎支持,找了好多种,也尝试了多种搜索引擎,有百度翻译、有道翻译、搜狗翻译、360翻译等等,但是现在目前基本上都有进行保护,不能像原来的代码一样直接进行API请求获取到数据。最后采用的是金山词霸的API,需要对特殊参数进行解析才能成功获取到请求返回。

func demoByKingSoftQuery(word string) {
   client := &http.Client{}

   // 为了成功获取信息,组装请求中的会变化的timestamp和signature
   timestamp := strconv.FormatInt(time.Now().Unix(), 10)
   signature := generatorMD5("/dictionary/word/query/web" + "61000006" + timestamp + word + "7ece94d9f9c202b0d2ec557dg4r9bc")

   url := "http://dict.iciba.com/dictionary/word/query/web?client=6&key=1000006&timestamp=" + timestamp + "&word=" + word + "&signature=" + signature

   req, err := http.NewRequest("GET", url, nil)
   if err != nil {
      log.Fatal(err)
   }
   /*
   .....请求头.....
   */
   resp, err := client.Do(req)
   if err != nil {
      log.Fatal(err)
   }
   defer resp.Body.Close()
   bodyText, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatal(err)
   }
   if resp.StatusCode != 200 {
      log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
   }

   //fmt.Println(string(bodyText))    // 打印全文进行检验
   var dictResponse KingSoftDictResponse
   err = json.Unmarshal(bodyText, &dictResponse)
   if err != nil {
      log.Fatal(err)
   }
   // 音标输出
   for _, item := range dictResponse.Message.BaesInfo.Symbols {
      fmt.Printf(word + " UK:[" + item.PhEn + "] US:[" + item.PhAm + "]\n")
   }
   // 音译输出
   for _, item := range dictResponse.Message.BaesInfo.Symbols {
      for _, part := range item.Parts {
         fmt.Printf("%s", part.Part)
         for _, mean := range part.Means {
            fmt.Printf("%s;", mean)
         }
         fmt.Println()
      }
   }
   fmt.Println("****************************分割线****************************")
   waitGroup.Done()
}

根据注解可以知道,时间戳和signature是特殊参数,需要对其进行解析,这就是不断去搜索里面的JavaScript文件,去打断点寻找到函数运行,然后去知道特殊参数的加密是如何加密的。

Part 3

image.png

因为Go语言的特性,感觉直接开协程就可以完成这个需求。直接使用Sync包下的waitgroup计数器进行控制,等到两个协程全部完成之后主线程才结束。

func main() {
   if len(os.Args) != 2 {
      fmt.Fprintf(os.Stderr, `usage: simpleDict WORD example: simpleDict hello`)
      os.Exit(1)
   }
   word := os.Args[1]
   waitGroup.Add(2)
   go demoByKingSoftQuery(word)
   go demoByLingoCloudQuery(word)
   waitGroup.Wait()
}

其中waitGroup.Done()在各自函数结束的时候调用即可将计数器自减1。

PS:课程用的转化得到的结构体有时候需要进行修饰一下,可以更好用,如果还是不行的话可以去寻找其他类似的网站,比如(json2struct.mervine.net/)

人生苦短,不如go浪一下。