这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记。参加了青训营才懂,学习原来可以如此充实。两个小时的课程可以消化好久。(也可能是比较菜,hhhh)看到一个弹幕觉得很有趣:在字节的一节课等于外面课程一个月的课。太卷啦。
一.go语言基础
一些小小体会
1.语法规则
go中语句结束不需要分号
2.变量
go中变量定义一种是直接定义变量类型,另一种是用var := 变量值
maxNum := 100
3.循环
go中循环只有for循环, for循环的初始条件什么的都不需要需要括号
4.函数
go函数中的变量类型是后置的,同函数名-参数列表-返回值
func add(a int, b int) (int) {
return a+b
}
5.切片
和数组类似,但是不同于数组可以任意改变长度
使用appedn()函数可以增加元素,如果长度不够会添加
c :=make([]string ,6)
//赋值回给自己
c=append(c,'s')
6.err错误
错误处理机制,在使用函数时使用
可以找到错误并返回错误
nil代表null
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("返回错误", err)
return
}
二.课程例子以及作业实现
1.猜谜游戏
这个感觉就是带领入门,基本的函数使用。
不过这里好像有个坑,在Windows中读入会多读入一个/r回车,所以这里改成/r/n
课后作业是换一种输入方式
func main() {
//定义最大随机数
maxNum := 100
//初始化随机数种子
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
//输出正确答案
fmt.Println("The secret number is ", secretNumber)
for {
fmt.Println("Please input your guess")
//使用Scanf()函数输入
var guess int
//坑在这↓↓↓↓↓↓
fmt.Scanf("%v\r\n", &guess)
//坑在这↓↓↓↓↓↓
// input = strings.TrimSuffix(input, "\r\n")
// guess, err := strconv.Atoi(input)
// if err != nil {
// fmt.Println("Invalid input. Please enter an integer value")
// return
// }
//输出判断大小
fmt.Println("You guess is", guess)
if guess > secretNumber {
fmt.Println("your guees bigger num")
} else if guess < secretNumber {
fmt.Println("your guees smaller num")
} else {
fmt.Println("your exactness")
break
}
}
}
2.在线词典
这个感觉比较有意思,学到了很多,现在来看看具体步骤
1.抓包
找到翻译接口的POST请求,然后获取它的翻译请求URL
然后去到请求代码生成网站获取请求函数,运行看返回的是否是json数据
2.生成结构体
返回数据无误,将数据转换生成结构体,封装进程序。
解析数据网站
3输出所需信息
因为返回的信息很多,并不全是所需要的,根据结构体输出所需信息。最后是封装请求函数,将之前的请求函数改为可带参数的函数,观察请求函数的创建请求部分,更改请求的单词为参数。
下面只贴出一些关键代码
func queryCaiYun(word string) {
//创建请求接口
client := &http.Client{}
//保存接口数据还有读入的单词
request := DictRequest{TransType: "en2zh", Source: word}
//把请求数据转换成json格式
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
//data转换成一个输入输出流
var data = bytes.NewReader(buf)
//req为返回数据,一串json格式数据
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
//发送请求
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
//函数结束后关闭连接
defer resp.Body.Close()
//bodeText为接收到的json数据
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
//把接收的json封装到结构体dictResponse
var dictResponse DictCaiyun
//Unmarshal()函数把bodyText内的数据转换到结构体dictResponse中
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
//按照格式输出所需要的结构中的信息
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
}
}
课后作业:增加另一个翻译接口,并且并行请求两个翻译引擎 实现另一个接口方法已经说明了,下面是并行请求方法
//定义一个WaitGroup对象,WaitGroup对象相当于计数器
var wg sync.WaitGroup
//设置计数值为2
wg.Add(2)
//使用go goroutine并行执行两个翻译函数
go func() {
//wg.Done()函数在运行结束后wg-1
defer wg.Done()
queryCaiYun(word)
}()
go func() {
//wg.Done()函数在运行结束后wg-1
defer wg.Done()
queryYouDao(word)
}()
//wg.Wait()函数使主线程一直等待,当wg为0时才结束
wg.Wait()
3.SOCKS5代理
首先是基础版的监听端口,并返回输入数据。分析都在代码注解里
func main() {
//server创建监听
server, err := net.Listen("tcp", "127.0.0.1:1080")
if err != nil {
panic(err)
}
for {
//client用来接收server的监听
//Accept()函数接收监听
client, err := server.Accept()
if err != nil {
log.Panicln("Accept failed %v", err)
continue
}
go process(client)
}
}
func process(conn net.Conn) {
//conn.Close()函数作用
//在这个函数结束时关闭与网站的链接
defer conn.Close()
//读取从网址返回的数据流
reader := bufio.NewReader(conn)
for {
//以字节读入b
b, err := reader.ReadByte()
if err != nil {
break
}
//写入输出框,转换成字节数组
_, err = conn.Write([]byte{b})
if err != nil {
break
}
}
}
然后是进阶版的,代码太多,以能力还实现不了,但是跟着流程理了个大概思路,代码就不贴出来了。
三.课后总结和体会
刚开始对于go的语法不熟悉,一共花了两天才消化完。对一些网络请求方面知识的发觉有些欠缺,还要恶补。相信可以随着更深的接触完善知识面的缺口。