Go语言基础项目 | 青训营笔记

100 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 2 天,今天主要对Go基础课程的词典项目进行总结。

Go基础课程项目

1. 项目回顾

第二节课中,老师带我们做了三个实战项目,其中第一个猜数项目较为简单,这里不再赘述。第三个项目涉及到的SOCKS5协议之前没有接触过且代码较为冗杂,因此暂时没有深究,只是大概看懂流程。而第二个翻译项目结果较为直观,且通过爬虫->请求代码生成->接收json结构的代码生成->解析输出结果这一流程,让我学习到了一些新知识。特别是代码生成技术,我之前从未接触过,之前在一些抓包的任务中,都是通过手工请求,手工解析结果的方式来满足需求,非常繁琐。今天学习到的通过浏览器curl信息生成对应语言的请求代码,并通过浏览器的响应生成对应语言的JSON处理代码,让我受益匪浅。

2. 课后作业

老师在课后布置了三个作业,前两个作业较为简单,第三个作业则需要增添一个翻译引擎,并且并发加快返回速度。

image.png

因为对Go并发编程略有生疏,因此这一部分的作业花费了较多的时间来处理并发请求。因此在这里进行总结,第三个作业主要的处理思路如下:

  1. 首先,我们根据老师教授的代码生成方法,抓取百度翻译的API,这一步只要按着课堂中的方法做没有问题。
  2. 由于需要并发运行两部分代码,因此在主函数中需要使用go func1(), go func2()的形式同时运行两个函数。
  3. 最后是作业的难点,对两个函数的运行进行并发地选择,哪个函数返回结果更快,则直接将最快查询得到的结果呈现给用户,从而达到了提升查询速度的目的。

对于最后一点,需要通过Go语言中的channel进行实现。具体的实现逻辑如下:

  1. 首先需要对翻译引擎进行一点小小的修改,把查询到的结果先保存到一个字符串中,随后将字符串送到channel中。
        // 彩云翻译引擎
        // 获取翻译引擎的查询结果
	rst := "彩云翻译:\n"
	rst += "UK:" + dictResponse.Dictionary.Prons.En + " US:" + dictResponse.Dictionary.Prons.EnUs
	rst += "\n"
	for _, item := range dictResponse.Dictionary.Explanations {
		rst += (item + "\n")
	}
	// 返回到通道中
	ch <- rst
        
        // 百度翻译引擎也与上面类似
	rst := "百度翻译:\n"
	for _, item := range dictResponse.Data {
		rst = rst + item.K + item.V + "\n"
	}
	ch <- rst
  1. 当公共channel一接收到其中一个引擎的结果,便立即打印显示结果,这样便实现了最快返回查询结果的目的。
	// 定义一个无缓冲区的公共channel,两个翻译引擎都将结果返回到该channel中
	ch := make(chan string)
	defer close(ch)
	go CaiYunQuery(word, ch)
	go BaiduQuery(word, ch)

	// 当channel中存在结果时,立即显示结果
	res := <-ch
	fmt.Println(res)