这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
篇幅目录
- Go基础学习
- 基础项目实战
- 课后作业
Go基础学习
第一部分的内容建议快速学习适应,老师讲的太快了,光看视频肯定是跟不上的,建议自己可以结合一些视频和书籍进行理解。
推荐视频
快速入门视频,时间比较短,基础语法都有涉猎。
推荐书籍
掘金推荐的入门书籍,每一节的例子也很多,查询和检索都挺不错的。
课程项目实战
项目的学习总体上由易到难,主要是API的熟悉和理解的过程,老师逐步对项目进行改进,层层递进,但受限于时间,自己还是需要花一些时间去理解。同时Go语言中有很多对error的处理,这点是值得注意的。
猜谜游戏
第一个项目是猜谜游戏,主要是考察了基本的语法和常用的包,有其他语言基础的情况,比较好理解,值得注意的是,在windows下,每一行的input应该去除尾部\r\n。
input = strings.TrimSuffix(input, "\r\n")
命令行字典
命令行字典主要涉及HTTP请求和响应的过程。先随机输入翻译,并在F12开发者工具的NETWORK中,找到对应的HTTP请求和响应的消息,如下图dict所示。
其后右键选择的dict->Copy->Copy as cURL(bash),交由Convert curl commands to Go将curl解析为go代码。
//& 应该是让堆空间地址复用
client := &http.Client{}
//var data = strings.NewReader(`{"trans_type":"en2zh","source":"reject"}`)
request := CYDictRequest{TransType: "en2zh", Source: word}
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buf)
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
...
// 解析响应
var dictResponce DictResponce
err = json.Unmarshal(bodyText, &dictResponce)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", dictResponce)
因为命令行的需求,我们需要定义请求的参数采用结构体定义请求参数,并用交给json解析,同时在上图Preview中定义了响应的json结构,我们可以通过# JSON转Golang Struct获取响应体数据结构。剩下根据老师的教学,不会有太大的问题。
SOCKS5代理
socks5代理整体上比前两个项目都难,如果能跟老师一步一步敲代码也能逐步理解,主要分为auth(), connect(), process(), main()4个函数,main()负责监听socket,process()负责完成代理,auth()用于认证,connect()负责连接,发送响应的过程。具体可以参考ppt和给的代码。
主要的注意点有两个:
- windows下没有nc命令,需要自己下载使用。
- GoLand默认采用
powershell作为控制台,curl命令不能正确的使用,可以在setting中修改控制台为cmd,或参考网络中其他方法。
课后作业
1. 修改第一个例子猜谜游戏里面的,使用 fmt.Scanf 来简化代码实现
主要代码如下所示
var guess int
_, err := fmt.Scanf("%d\n", &guess)
2. 修改第二个例子命令行词典代码,增加另一种翻译引擎的支持
我采用的是火山翻译的例子,具体过程与课程学习中一致,唯一值得注意的是需要选择正确的http消息,不然通过网址解析的json格式不正确。可以参考下述的请求结构体的属性。
// DictRequest 发送请求
type HSDictRequest struct {
Text string `json:"text"`
Language string `json:"language"`
}
3. 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度
这一项是利用WaitGroup实现,将两种查询函数写在util包下,用两个goroutine去实现。
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "usage: simpleDict WORD example: false")
os.Exit(1)
}
var wg sync.WaitGroup
for _, word := range os.Args[1:] {
wg.Add(2)
go func() {
defer wg.Done()
util.HSQuery(word)
}()
go func() {
defer wg.Done()
util.CYQuery(word)
}()
}
wg.Wait()
fmt.Println("over")
}
结果如下: