1.1 Go语言上手-基础语法

课程源码:https://github.com/wangkechun/go-by-example/
短链接:https://hi-hi.cn/go

1 简介

1.1 什么是Go语言

  1. 高性能,高并发
  2. 语法简单,学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收
package main
import(
    "net/http"
)

func main(){
  http.Handle("/",http.FileServer(http.Dor(".")))
  http.ListenAndServe(":8080",nil)
}

1.2 哪些公司在使用Go语言

在这里插入图片描述

1.3 字节跳动为什么全面拥抱Go语言

  1. 最初使用的Python,由于性能问题换成了Go
  2. C++不太适合在线Web业务
  3. 早期团队非Java背景
  4. 性能比较好
  5. 部署简单,学习成本低
  6. 内部 RPC和HTTP框架的推广

2 入门

2.1 开发环境

  1. 安装Golang
    https://go.dev/
    https://studygolang.com/dl
    https://goproxy.cn/
  2. 配置集成开发环境
  3. 基于云的开发环境
    https://gitpod.io/#github.com/wangkechun/go-by-example
    短链接:https://hi-hi.cn/gitpod

2.2 基础语法和标准库

2.2.1 Hello World

package main

import (
	"fmt"
)

func main() {
	fmt.Println("hello world!")
}

运行结果

在这里插入图片描述

2.2.2 变量

goland中常量没有确定的类型,它会根据使用的上下文自动确定类型

package main

import (
	"fmt"
	"math"
)

func main() {
	var a = "initial"
	var b, c int = 1, 2
	var d = true
	var e float64
	f := float32(e)

	g := a + "foo"
	fmt.Println(a, b, c, d, e, f) //运行结果为:initial 1 2 true 0 0
	fmt.Println(g)                //运行结果为:initialfoo

	const s string = "constant"
	const h = 500000000
	const i = 3e20 / h
	fmt.Println(s, h, i, math.Sin(h)) //运行结果:constant 500000000 6e+11 -0.28470407323754404
}

2.2.3 if else

package main

import "fmt"

func main() {
	if 7%2 == 0 {
		fmt.Println("7 is even")
	} else {
		fmt.Println("7 is odd")
	}

	if 8%4 == 0 {
		fmt.Println("8 is divisible by 4")
	}

	if num := 9; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "has 1 digit")
	} else {
		fmt.Println(num, "has multiple digits")
	}
}

运行结果

在这里插入图片描述

2.2.4 循环

package main

import "fmt"

func main() {
	i := 1
	for {
		fmt.Println("loop")
		break
	}
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}

	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}

	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}

运行结果

在这里插入图片描述

2.2.5 switch

package main

import (
	"fmt"
	"time"
)

func main() {
	a := 2
	switch a {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	case 4, 5:
		fmt.Println("four or five")
	default:
		fmt.Println("other")
	}

	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("its before noon")
	default:
		fmt.Println("its after noon")
	}
}

运行结果

在这里插入图片描述

2.2.6 数组

package main

import "fmt"

func main() {
	var a [5]int
	a[4] = 100
	fmt.Println(a[4], len(a)) //输出为:100 5

	b := [5]int{1, 2, 3, 4, 5}
	fmt.Println(b) //输出为:[1 2 3 4 5]

	var twoD [2][3]int
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			twoD[i][j] = i + j
		}
	}
	fmt.Println("2d: ", twoD) //输出为:2d:  [[0 1 2] [1 2 3]]
}

2.2.7 切片

package main

import "fmt"

func main() {
	m := make(map[string]int)
	m["one"] = 1
	m["two"] = 2

	fmt.Println(m)           //输出为:map[one:1 two:2]
	fmt.Println(len(m))      //输出为:2
	fmt.Println(m["one"])    //输出为:1
	fmt.Println(m["unknow"]) //输出为:0

	r, ok := m["unknow"]
	fmt.Println(r, ok) //输出为:0 false

	delete(m, "one")

	m2 := map[string]int{"one": 1, "two": 2}
	var m3 = map[string]int{"one": 1, "two": 2}
	fmt.Println(m2, m3) //输出为:map[one:1 two:2] map[one:1 two:2]
}

2.2.8 range

package main

import "fmt"

func main() {
	nums := []int{2, 3, 4}
	sum := 0
	for i, num := range nums {
		sum += num
		if num == 2 {
			fmt.Println("index:", i, "num:", num) //输出为:index: 0 num: 2
		}
	}
	fmt.Println(sum) //输出为:9

	m := map[string]string{"a": "A", "b": "B"}
	for k, v := range m {
		fmt.Println(k, v) //输出为:a A  b B
	}
	for k := range m {
		fmt.Println("key", k) //输出为:key a  key b
	}
}

2.2.9 函数

package main

import "fmt"

func add(a int, b int) int {
	return a + b
}

func add2(a, b int) int {
	return a + b
}

//ok 表示是否存在
func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}

func main() {
	res := add(1, 2)
	fmt.Println(res) //输出为:3

	v, ok := exists(map[string]string{"a": "A"}, "a")
	fmt.Println(v, ok) //输出为:A true
}

2.2.10 指针

package main

import "fmt"

//此方法无效
func add2(n int) {
	n += 2
}

func add2ptr(n *int) {
	*n += 2
}

func main() {
	n := 5
	add2(n)
	fmt.Println(n) //运行结果:5
	add2ptr(&n)
	fmt.Println(n) //运行结果:7
}

2.2.11 结构体

package main

import "fmt"

type user struct {
	name     string
	password string
}

func main() {
	a := user{name: "wang", password: "1024"}
	b := user{"wang", "1024"}
	c := user{name: "wang"}
	c.password = "1024"
	var d user
	d.name = "wang"
	d.password = "1024"

	fmt.Println(a, b, c, d)                 //输出为:{wang 1024} {wang 1024} {wang 1024} {wang 1024}
	fmt.Println(checkPassword(a, "haha"))   //输出为:false
	fmt.Println(checkPassword2(&a, "haha")) //输出为:false
}

func checkPassword(u user, password string) bool {
	return u.password == password
}

func checkPassword2(u *user, password string) bool {
	return u.password == password
}

2.2.12 结构体方法

package main

import "fmt"

type user struct {
	name     string
	password string
}

func (u user) checkPassword(password string) bool {
	return u.password == password
}

func (u *user) resetPassword(password string) {
	u.password = password
}

func main() {
	a := user{name: "wang", password: "1024"}
	a.resetPassword("2048")
	fmt.Println(a.checkPassword("2048")) //输出为:true
}

2.2.13 错误处理

package main

import (
	"errors"
	"fmt"
)

type user struct {
	name     string
	password string
}

//函数中加一个err 表示函数会返回错误
func findUser(users []user, name string) (v *user, err error) {
	for _, u := range users {
		if u.name == name {
			return &u, nil
		}
	}
	return nil, errors.New("not found")
}

func main() {
	u, err := findUser([]user{{"wang", "1024"}}, "wang")
	//必须先判断err是否为空
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(u.name) //输出为:wang

	//另一种写法
	if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
		fmt.Println(err) //输出为: not found
		return
	} else {
		fmt.Println(u.name)
	}
}

2.2.14 字符串操作

package main

import (
	"fmt"
	"strings"
)

func main() {
	a := "hello"
	//是否包含一个字符串
	fmt.Println(strings.Contains(a, "ll")) //输出为:true
	//字符串计数
	fmt.Println(strings.Count(a, "l")) //输出为:2
	//是否以某个字符串开头
	fmt.Println(strings.HasPrefix(a, "he")) //输出为:true
	//是否以某个字符串结尾
	fmt.Println(strings.HasSuffix(a, "llo")) //输出为:true
	//查找某个字符串的位置
	fmt.Println(strings.Index(a, "ll")) //输出为:2
	//连接多个字符串
	fmt.Println(strings.Join([]string{"he", "llo"}, "-")) //输出为:he-llo
	//重复多个字符串
	fmt.Println(strings.Repeat(a, 2)) //输出为:hellohello
	//替换字符串
	fmt.Println(strings.Replace(a, "e", "E", -1)) //输出为:hEllo
	//将分隔符去除
	fmt.Println(strings.Split("a-b-c", "-")) //输出为:[a b c]
	//全部变为小写字母
	fmt.Println(strings.ToLower(a))          //输出为:hello
	//全部变为大写字母
	fmt.Println(strings.ToUpper(a))          //输出为:HELLO
	fmt.Println(len(a))                      //输出为:5
	b := "你好"
	fmt.Println(len(b)) //输出为:6
}

2.2.15 字符串格式化

package main

import "fmt"

type point struct {
	x, y int
}

func main() {
	s := "hello"
	n := 123
	p := point{1, 2}
	fmt.Println(s, n) //输出为:hello 123
	fmt.Println(p)    //输出为:{1 2}

	fmt.Printf("s=%v\n", s) //输出为:s=hello
	fmt.Printf("n=%v\n", n) //输出为:n=123
	fmt.Printf("p=%v\n", p) //输出为:p={1 2}
	//打印的详细,将字段名打印出来
	fmt.Printf("p=%+v\n", p) //输出为:p={x:1 y:2}
	//将整个结构体的类型名称,字段名打印出来
	fmt.Printf("p=%#v\n", p) //输出为:p=main.point{x:1, y:2}

	f := 3.141592653
	fmt.Println(f)          //输出为:3.141592653
	fmt.Printf("%.2f\n", f) //输出为:3.14
}

2.2.16 JSON处理

package main

import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	//使用json.Marshal将a序列化
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}

	fmt.Println(buf)
	fmt.Println(string(buf))

	//json.MarshalIndent:按照indent格式化输出
	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	var b userInfo
	//json.Unmarshal:将序列化的数据反序列化到一个空的变量中
	err = json.Unmarshal(buf, &b)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b)
}

运行结果

在这里插入图片描述

2.2.17 时间处理

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now) //输出为:2022-05-09 15:23:49.6706407 +0800 CST m=+0.001026201

	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t)                                                  //输出为:2022-03-27 01:25:36 +0000 UTC
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) //输出为:2022 March 27 1 25
	fmt.Println(t.Format("2006-01-02 15:04:05"))                    //输出为:2022-03-27 01:25:36
	//两个时间段进行减法
	diff := t2.Sub(t)
	fmt.Println(diff)                           //输出为:1h5m0s
	fmt.Println(diff.Minutes(), diff.Seconds()) //输出为:65 3900
	//Parse()函数用于解析格式化的字符串,然后查找它形成的时间值
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-07 01:25:36")
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t) //输出为:false
	//now.Unix()获取时间戳
	fmt.Println(now.Unix()) //输出为:1652081029
}

2.2.18 数字解析

字符串和数字的转换

package main

import (
	"fmt"
	"strconv"
)

func main() {
	f, _ := strconv.ParseFloat("1.234", 64)
	fmt.Println(f) //输出为:1.234

	//10进制 返回的是64位精度的整数
	n, _ := strconv.ParseInt("111", 10, 64)
	fmt.Println(n) //输出为:111

	n1, _ := strconv.ParseInt("0x1000", 0, 64)
	fmt.Println(n1) //输出为:4096

	n2, _ := strconv.Atoi("123")
	fmt.Println(n2) //输出为:4096

	n3, err := strconv.Atoi("AAA")
	fmt.Println(n3, err) //输出为:0 strconv.Atoi: parsing "AAA": invalid syntax
}

2.2.19 进程信息

package main

import (
	"fmt"
	"os"
	"os/exec"
)

func main() {

	//进程在执行时候的一些命令和参数
	fmt.Println(os.Args)
	//获取环境变量
	fmt.Println(os.Getenv("PATH"))
	//写入环境变量
	fmt.Println(os.Setenv("AA", "BB"))

	//快速启动子进程,获取其输入输出
	buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))
}

3 实战

3.1 猜谜游戏

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	//设置一个随机数
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	fmt.Println("The secret mumber is ", secretNumber)

	//获取输入
	fmt.Println("Please input your guess")
	reader := bufio.NewReader(os.Stdin)
	for {
		//读取一行输入
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("An error occured while reading input.Please try again",err)
		return
			continue
		}
		//去掉换行符
		input = strings.TrimSuffix(input, "\n")
		//input = strings.TrimSuffix(input, "\r")

		//转换成数字
		guess, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid input.Please enter an integer value",err)
		return
			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
		}
	}
}

运行结果

在这里插入图片描述
使用 fmt.Scanf 来简化代码实现:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	//设置一个随机数
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	fmt.Println("The secret mumber is ", secretNumber)

	for {
		fmt.Println("Please input your number: ")
		//获取输入
		var count int
		fmt.Scanf("%d", &count)
		fmt.Println("You guess is", count)

		if count > secretNumber{
			fmt.Println("your guess is bigger than the secret number. Please try again")
		}else if count < secretNumber{
			fmt.Println("your guess is smaller than the secret number. Please try again")
		}else{
			fmt.Println("correct,you legend")
			break
		}
	}
}

3.2 命令行词典

  • 抓包
    彩云小译 :https://fanyi.caiyunapp.com/
  • 代码生成
    将curl命令转为Go:https://curlconverter.com/#go
  • 生成request body
  • 解析response body
    JSON转Golang Struct:https://oktools.net/json2go
  • 打印结果
  • 完善代码

在彩云小译上:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type DictResponse struct {
	Rc int `json:"rc"`
	Wiki struct {
		KnownInLaguages int `json:"known_in_laguages"`
		Description struct {
			Source string `json:"source"`
			Target interface{} `json:"target"`
		} `json:"description"`
		ID string `json:"id"`
		Item struct {
			Source string `json:"source"`
			Target string `json:"target"`
		} `json:"item"`
		ImageURL string `json:"image_url"`
		IsSubject string `json:"is_subject"`
		Sitelink string `json:"sitelink"`
	} `json:"wiki"`
	Dictionary struct {
		Prons struct {
			EnUs string `json:"en-us"`
			En string `json:"en"`
		} `json:"prons"`
		Explanations []string `json:"explanations"`
		Synonym []string `json:"synonym"`
		Antonym []string `json:"antonym"`
		WqxExample [][]string `json:"wqx_example"`
		Entry string `json:"entry"`
		Type string `json:"type"`
		Related []interface{} `json:"related"`
		Source string `json:"source"`
	} `json:"dictionary"`
}

type DictRequest struct{
	TransType string `json:"trans_type"`
	Source string `json:"source"`
	UserID string `json:"user_id"`
}

func query(word string) {
	client := &http.Client{}
	//var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
	//request := DictRequest{TransType: "en2zh",Source: "good"}
	request := DictRequest{TransType: "en2zh",Source: word}
	buf,err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewBuffer(buf)
	//创建请求
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
	if err != nil {
		log.Fatal(err)
	}
	//设置请求头
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	req.Header.Set("Sec-Fetch-Dest", "empty")
	req.Header.Set("Sec-Fetch-Mode", "cors")
	req.Header.Set("Sec-Fetch-Site", "cross-site")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("app-name", "xy")
	req.Header.Set("os-type", "web")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	//发起请求
	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("bod StatusCode:",resp.StatusCode,"body",string(bodyText))
	}

	//fmt.Printf("%s\n", bodyText)
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText,&dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("%#v\n",dictResponse)
	fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)
	for _,item := range dictResponse.Dictionary.Explanations{
		fmt.Println(item)
	}
}

func main(){
	//if len(os.Args) != 2{
	//	fmt.Fprintf(os.Stderr,`usage:simpleDict WORD example:simpleDict hello`)
	//	os.Exit(1)
	//}
	word := "study"
	query(word)
}

运行结果

在这里插入图片描述

换成火山翻译:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)
type DictRequest_huoshan struct{
	Text string`json:"text"`
	Language string `json:"language"`
}

type DictResponse_huoshan struct {
	Words []struct {
		Source int `json:"source"`
		Text string `json:"text"`
		PosList []struct {
			Type int `json:"type"`
			Phonetics []struct {
				Type int `json:"type"`
				Text string `json:"text"`
			} `json:"phonetics"`
			Explanations []struct {
				Text string `json:"text"`
				Examples []struct {
					Type int `json:"type"`
					Sentences []struct {
						Text string `json:"text"`
						TransText string `json:"trans_text"`
					} `json:"sentences"`
				} `json:"examples"`
				Synonyms []interface{} `json:"synonyms"`
			} `json:"explanations"`
			Relevancys []interface{} `json:"relevancys"`
		} `json:"pos_list"`
	} `json:"words"`
	Phrases []interface{} `json:"phrases"`
	BaseResp struct {
		StatusCode int `json:"status_code"`
		StatusMessage string `json:"status_message"`
	} `json:"base_resp"`
}

func query_huoshan(word string) {
	client := &http.Client{}
	//var data = strings.NewReader(`{"text":"good\n\n\n\n","language":"en"}`)

	request := DictRequest_huoshan{Text: word,Language: "en"}
	buf,err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewBuffer(buf)

	req, err := http.NewRequest("POST", "https://translate.volcengine.com/web/dict/match/v1/?msToken=&X-Bogus=DFSzswVLQDcxI/5eSWCfZe9WX7rO&_signature=_02B4Z6wo00001yJiofgAAIDDomBbucDo8ysiYqVAAKru0cXDAbBoE-KWOV4RH4C2aGbXqF6VyKkuAlg88RPMWAF0u4SfdJLSBKPcaqDJFC3nUa1fTmHLL9zziNhAy0Mfz2so9Z5c2gFFpZ9gec", data)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("authority", "translate.volcengine.com")
	req.Header.Set("accept", "application/json, text/plain, */*")
	req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
	req.Header.Set("content-type", "application/json")
	req.Header.Set("cookie", "x-jupiter-uuid=16522388961382340; i18next=zh-CN; s_v_web_id=verify_f65798b1ef5fb225931a8abb23bfee94; _tea_utm_cache_2018=undefined; ttcid=777643f23e7945069ab8946fd6a19f9c36; tt_scid=RhMZ-Kl5n0RzvNN0.c5vnhxMdlLjWm8Rrd6qz0LL9d-qL8wx6COhFnA0oeQBKFIebb37")
	req.Header.Set("origin", "https://translate.volcengine.com")
	req.Header.Set("referer", "https://translate.volcengine.com/translate?category=&home_language=zh&source_language=detect&target_language=zh&text=good%0A%0A%0A%0A")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	req.Header.Set("sec-fetch-dest", "empty")
	req.Header.Set("sec-fetch-mode", "cors")
	req.Header.Set("sec-fetch-site", "same-origin")
	req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
	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)
	}
	//fmt.Printf("%s\n", bodyText)
	if resp.StatusCode != 200 {
		log.Fatal("bod StatusCode:",resp.StatusCode,"body",string(bodyText))
	}

	//fmt.Printf("%s\n", bodyText)
	var dictResponse DictResponse_huoshan
	err = json.Unmarshal(bodyText,&dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("%#v\n",dictResponse)
	//fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)
	//for _,item := range dictResponse.Dictionary.Explanations{
	//	fmt.Println(item)
	//}
	for _,word := range  dictResponse.Words{
		for _,polist := range word.PosList{
			for _, explanation := range polist.Explanations {
				fmt.Println(explanation.Text)
			}
		}
	}
}

func main(){
	//if len(os.Args) != 2{
	//	fmt.Fprintf(os.Stderr,`usage:simpleDict WORD example:simpleDict hello`)
	//	os.Exit(1)
	//}
	word := "good"
	query_huoshan(word)
}

运行结果
在这里插入图片描述
实现并行请求两个翻译引擎来提高响应速度:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"
)
type DictRequest_huoshan struct{
	Text string`json:"text"`
	Language string `json:"language"`
}
type DictRequest_caiyun struct{
	TransType string `json:"trans_type"`
	Source string `json:"source"`
	UserID string `json:"user_id"`
}
type DictResponse_huoshan struct {
	Words []struct {
		Source int `json:"source"`
		Text string `json:"text"`
		PosList []struct {
			Type int `json:"type"`
			Phonetics []struct {
				Type int `json:"type"`
				Text string `json:"text"`
			} `json:"phonetics"`
			Explanations []struct {
				Text string `json:"text"`
				Examples []struct {
					Type int `json:"type"`
					Sentences []struct {
						Text string `json:"text"`
						TransText string `json:"trans_text"`
					} `json:"sentences"`
				} `json:"examples"`
				Synonyms []interface{} `json:"synonyms"`
			} `json:"explanations"`
			Relevancys []interface{} `json:"relevancys"`
		} `json:"pos_list"`
	} `json:"words"`
	Phrases []interface{} `json:"phrases"`
	BaseResp struct {
		StatusCode int `json:"status_code"`
		StatusMessage string `json:"status_message"`
	} `json:"base_resp"`
}
type DictResponse_caiyun struct {
	Rc int `json:"rc"`
	Wiki struct {
		KnownInLaguages int `json:"known_in_laguages"`
		Description struct {
			Source string `json:"source"`
			Target interface{} `json:"target"`
		} `json:"description"`
		ID string `json:"id"`
		Item struct {
			Source string `json:"source"`
			Target string `json:"target"`
		} `json:"item"`
		ImageURL string `json:"image_url"`
		IsSubject string `json:"is_subject"`
		Sitelink string `json:"sitelink"`
	} `json:"wiki"`
	Dictionary struct {
		Prons struct {
			EnUs string `json:"en-us"`
			En string `json:"en"`
		} `json:"prons"`
		Explanations []string `json:"explanations"`
		Synonym []string `json:"synonym"`
		Antonym []string `json:"antonym"`
		WqxExample [][]string `json:"wqx_example"`
		Entry string `json:"entry"`
		Type string `json:"type"`
		Related []interface{} `json:"related"`
		Source string `json:"source"`
	} `json:"dictionary"`
}
func query_huoshan(word string,wg *sync.WaitGroup) {
	defer wg.Done() //当执行完函数,调用  把wg的等待组-1
	client := &http.Client{}
	//var data = strings.NewReader(`{"text":"good\n\n\n\n","language":"en"}`)

	request := DictRequest_huoshan{Text: word,Language: "en"}
	buf,err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewBuffer(buf)

	req, err := http.NewRequest("POST", "https://translate.volcengine.com/web/dict/match/v1/?msToken=&X-Bogus=DFSzswVLQDcxI/5eSWCfZe9WX7rO&_signature=_02B4Z6wo00001yJiofgAAIDDomBbucDo8ysiYqVAAKru0cXDAbBoE-KWOV4RH4C2aGbXqF6VyKkuAlg88RPMWAF0u4SfdJLSBKPcaqDJFC3nUa1fTmHLL9zziNhAy0Mfz2so9Z5c2gFFpZ9gec", data)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("authority", "translate.volcengine.com")
	req.Header.Set("accept", "application/json, text/plain, */*")
	req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
	req.Header.Set("content-type", "application/json")
	req.Header.Set("cookie", "x-jupiter-uuid=16522388961382340; i18next=zh-CN; s_v_web_id=verify_f65798b1ef5fb225931a8abb23bfee94; _tea_utm_cache_2018=undefined; ttcid=777643f23e7945069ab8946fd6a19f9c36; tt_scid=RhMZ-Kl5n0RzvNN0.c5vnhxMdlLjWm8Rrd6qz0LL9d-qL8wx6COhFnA0oeQBKFIebb37")
	req.Header.Set("origin", "https://translate.volcengine.com")
	req.Header.Set("referer", "https://translate.volcengine.com/translate?category=&home_language=zh&source_language=detect&target_language=zh&text=good%0A%0A%0A%0A")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	req.Header.Set("sec-fetch-dest", "empty")
	req.Header.Set("sec-fetch-mode", "cors")
	req.Header.Set("sec-fetch-site", "same-origin")
	req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
	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)
	}
	//fmt.Printf("%s\n", bodyText)
	if resp.StatusCode != 200 {
		log.Fatal("bod StatusCode:",resp.StatusCode,"body",string(bodyText))
	}

	//fmt.Printf("%s\n", bodyText)
	var dictResponse DictResponse_huoshan
	err = json.Unmarshal(bodyText,&dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("%#v\n",dictResponse)
	//fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)
	//for _,item := range dictResponse.Dictionary.Explanations{
	//	fmt.Println(item)
	//}
	for _,word := range  dictResponse.Words{
		for _,polist := range word.PosList{
			for _, explanation := range polist.Explanations {
				fmt.Println(explanation.Text)
			}
		}
	}
}

func query_caiyun(word string,wg *sync.WaitGroup) {
	defer wg.Done() //当执行完函数,调用  把wg的等待组-1
	client := &http.Client{}
	//var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
	//request := DictRequest{TransType: "en2zh",Source: "good"}
	request := DictRequest_caiyun{TransType: "en2zh",Source: word}
	buf,err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewBuffer(buf)
	//创建请求
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
	if err != nil {
		log.Fatal(err)
	}
	//设置请求头
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	req.Header.Set("Sec-Fetch-Dest", "empty")
	req.Header.Set("Sec-Fetch-Mode", "cors")
	req.Header.Set("Sec-Fetch-Site", "cross-site")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("app-name", "xy")
	req.Header.Set("os-type", "web")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	//发起请求
	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("bod StatusCode:",resp.StatusCode,"body",string(bodyText))
	}

	//fmt.Printf("%s\n", bodyText)
	var dictResponse DictResponse_caiyun
	err = json.Unmarshal(bodyText,&dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("%#v\n",dictResponse)
	fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)
	for _,item := range dictResponse.Dictionary.Explanations{
		fmt.Println(item)
	}
}

func main(){
	fmt.Println(os.Args)
	if len(os.Args) != 2{
		fmt.Fprintf(os.Stderr,`usage:simpleDict WORD example:simpleDict hello`)
		os.Exit(1)
	}
	//word := "good"
	//query_huoshan(word)
	word := os.Args[1]
	wg := sync.WaitGroup{} //创建等待线程组
	wg.Add(2)  //等待组的计数器 +2
	go query_huoshan(word,&wg)  //调用线程,维护公共变量 wg
	go query_caiyun(word,&wg) //调用线程,维护公共变量 wg
	wg.Wait() //当等待组计数器不等于0时阻塞直到变0
}

运行结果
在这里插入图片描述

在这里插入图片描述

3.3 SOCKS5代理

原理:
四个阶段:

  1. 协商/握手阶段
  2. 认证阶段【本示例不加密,没有此阶段】
  3. 请求阶段
  4. relay阶段

在这里插入图片描述

第一步:SOCKS5 代理 -TCP echo server

package main

import (
	"bufio"
	"log"
	"net"
)

func main(){
	server,err := net.Listen("tcp","127.0.0.1:1080")
	if err != nil {
		panic(err)
	}

	for {
		client,err := server.Accept()
		if err != nil {
			log.Printf("Accept failed %v",err)
			continue
		}
		go process(client)
	}
}

func process(conn net.Conn){
	defer conn.Close()
	reader := bufio.NewReader(conn)
	for  {
		b,err := reader.ReadByte()
		if err != nil {
			break
		}

		_,err = conn.Write([] byte{b})
		if err != nil{
			break
		}
	}
}

运行结果
下载netcat,在对应文件下cmd
在这里插入图片描述
第二步:SOCKS5 代理-auth

package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
)

const socks5Ver = 0x05
const cmdBind = 0x01
const atypIPV4 = 0x01
const atypeHOST = 0x03
const atypeIPV6 = 0x04

func main(){
	server,err := net.Listen("tcp","127.0.0.1:1080")
	if err != nil {
		panic(err)
	}

	for {
		client,err := server.Accept()
		if err != nil {
			log.Printf("Accept failed %v",err)
			continue
		}
		go process(client)
	}
}

func process(conn net.Conn){
	defer conn.Close()
	reader := bufio.NewReader(conn)
	err := auth(reader,conn)
	if err != nil {
		log.Printf("client %v auth failed:%v",conn.RemoteAddr(),err)
		return
	}
	log.Println("auth success")
}

func auth(reader *bufio.Reader,conn net.Conn)(err error){
	//VER   NMETHODS  METHODS
	//1         1      1 to 255
	//VER:协议版本,socks5为0x05
	//NMETHODS:支持认证的方法数量
	//NMETHODS:对应NMETHODS,NMETHODS的值为多少,NMETHODS就有多少个字节,RFC预定义了一些值的含义,内容如下:
	//X'00' NO AUTHENTICATION REQUIRED
	//X'02' USERNAME/PASSWORD

	ver,err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read ver failed:%w",err)
	}

	if ver != socks5Ver {
		return fmt.Errorf("not supported ver:%v",err)
	}
	methodSize,err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read methodSize failed:%w",err)
	}

	method := make([]byte,methodSize)
	_,err = io.ReadFull(reader,method)
	if err != nil {
		return fmt.Errorf("read method failed:%w",err)
	}
	log.Println("Ver",ver,"method",method)

	//VER  METHOD
	// 1     1
	_,err = conn.Write([]byte{socks5Ver,0x00})
	if err != nil {
		return fmt.Errorf("write failed:%w",err)
	}
	return nil
}

运行结果

下载curl,在对应文件下cmd ,同时运行程序

在这里插入图片描述

在这里插入图片描述
在程序控制台中

在这里插入图片描述
第三步:SOCKS5 代理 -请求阶段

package main

import (
	"bufio"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
)

const socks5Ver = 0x05
const cmdBind = 0x01
const atypIPV4 = 0x01
const atypeHOST = 0x03
const atypeIPV6 = 0x04

func main(){
	server,err := net.Listen("tcp","127.0.0.1:1080")
	if err != nil {
		panic(err)
	}

	for {
		client,err := server.Accept()
		if err != nil {
			log.Printf("Accept failed %v",err)
			continue
		}
		go process(client)
	}
}

func process(conn net.Conn){
	defer conn.Close()
	reader := bufio.NewReader(conn)
	err := auth(reader,conn)
	if err != nil {
		log.Printf("client %v auth failed:%v",conn.RemoteAddr(),err)
		return
	}
	//log.Println("auth success")
	err = connect(reader,conn)
	if err != nil{
		log.Printf("client %v auth failed :%v",conn.RemoteAddr(),err)
		return
	}
}

func auth(reader *bufio.Reader,conn net.Conn)(err error){
	//VER   NMETHODS  METHODS
	//1         1      1 to 255
	//VER:协议版本,socks5为0x05
	//NMETHODS:支持认证的方法数量
	//NMETHODS:对应NMETHODS,NMETHODS的值为多少,NMETHODS就有多少个字节,RFC预定义了一些值的含义,内容如下:
	//X'00' NO AUTHENTICATION REQUIRED
	//X'02' USERNAME/PASSWORD

	ver,err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read ver failed:%w",err)
	}

	if ver != socks5Ver {
		return fmt.Errorf("not supported ver:%v",err)
	}
	methodSize,err := reader.ReadByte()
	if err != nil {
		return fmt.Errorf("read methodSize failed:%w",err)
	}

	method := make([]byte,methodSize)
	_,err = io.ReadFull(reader,method)
	if err != nil {
		return fmt.Errorf("read method failed:%w",err)
	}
	log.Println("Ver",ver,"method",method)

	//VER  METHOD
	// 1     1
	_,err = conn.Write([]byte{socks5Ver,0x00})
	if err != nil {
		return fmt.Errorf("write failed:%w",err)
	}
	return nil
}

func connect(reader *bufio.Reader,conn net.Conn)(err error){
	// VER  CMD  RSV  ATYP  DST.ADDR  DST.PORT
	//  1    1  X'00'   1   Variable     2
	//VER 版本号,socks5的值为0x05
	//CMD 0x01表示CONNECT请求
	//RSV 保留字段 值为0x00
	//ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型
	//   0x01表示IPv4地址,DST.ADDR为4个字节
	//   0x03表示域名,DST.ADDR是一个可变长度的域名
	//DST.ADDR 一个可变长度的值
	//DST.PORT 目标端口,固定2个字节

	buf := make([]byte,4)
	_,err = io.ReadFull(reader,buf)
	if err != nil {
		return fmt.Errorf("read header failed:%w",err)
	}
	ver,cmd,atyp := buf[0],buf[1],buf[3]
	if ver != socks5Ver{
		return fmt.Errorf("not supported ver:%v",ver)
	}
	if cmd != cmdBind{
		return fmt.Errorf("not supported cmd:%v",ver)
	}

	addr := ""
	switch atyp{
	case atypIPV4:
		_,err = io.ReadFull(reader,buf)
		if err != nil{
			return fmt.Errorf("read atyp failed:%w",err)
		}
		addr = fmt.Sprintf("%d.%d.%d.%d",buf[0],buf[1],buf[2],buf[3])
	case atypeHOST:
		hostSize,err := reader.ReadByte()
		if err != nil{
			return fmt.Errorf("read hostSize failed:%w",err)
		}
		host := make([]byte,hostSize)
		_,err = io.ReadFull(reader,host)
		if err != nil{
			return fmt.Errorf("read host failed:%w",err)
		}
		addr = string(host)
	case atypeIPV6:
		return errors.New("IPv6:no supported yet")
	default:
		return errors.New("invalid atyp")
	}

	_,err = io.ReadFull(reader,buf[:2])
	if err != nil{
		return fmt.Errorf("read port failed:%w",err)
	}
	port := binary.BigEndian.Uint16(buf[:2])

	log.Println("dial",addr,port)

	// VER  REP  RSV  ATYP  BND.ADDR  BND.PORT
	//  1    1  X'00'   1   Variable     2
	//VER 版本号,socks5的值为0x05
	//REP Relay field,内容取值如下 X‘00’ succeeded
	//RSV 保留字段
	//ATYP 地址类型
	//BND.ADDR 服务绑定的地址
	//BND.PORT 服务绑定的短裤DST.PORT

	_,err = conn.Write([]byte{0x05,0x00,0x00,0x01,0,0,0,0,0,0})
	if err != nil {
		return fmt.Errorf("write failed:%w",err)
	}
	return nil
}

运行结果

下载curl,在对应文件下cmd ,同时运行程序
在这里插入图片描述
在这里插入图片描述
如果将atypeIPV6代码改为atypeIPV4一样:
在这里插入图片描述
结果为:
在这里插入图片描述

在这里插入图片描述
第四步:SOCKS5 代理 -relay阶段

在上面的基础上添加下面代码:
在这里插入图片描述
在这里插入图片描述

3.高质量编程与性能调优实战

4.高性能Go语言发行版优化与落地实践

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我无法直接编写前110页的内容,但我可以给你一些基本的Python编程知识和示例代码,以帮助你开始自动化繁琐的工作。 1. 使用Python打开文件 ``` # 打开一个文件 f = open('file.txt', 'r') # 读取文件内容 content = f.read() # 关闭文件 f.close() ``` 2. 使用Python写入文件 ``` # 打开一个文件 f = open('file.txt', 'w') # 写入内容 f.write('Hello, World!') # 关闭文件 f.close() ``` 3. 使用Python处理Excel文件 ``` # 导入 openpyxl 库 import openpyxl # 打开 Excel 文件 wb = openpyxl.load_workbook('example.xlsx') # 获取表格 sheet = wb['Sheet1'] # 读取单元格的值 value = sheet['A1'].value # 写入单元格的值 sheet['A1'] = 'Hello, World!' # 保存文件 wb.save('example.xlsx') ``` 4. 使用Python发送邮件 ``` # 导入 smtplib 库 import smtplib # 连接邮箱服务器 server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() # 登录邮箱账号 server.login('your_email@gmail.com', 'your_password') # 发送邮件 msg = 'Hello, World!' server.sendmail('your_email@gmail.com', 'recipient_email@gmail.com', msg) # 关闭连接 server.quit() ``` 5. 使用Python处理文本 ``` # 读取文本文件 f = open('file.txt', 'r') content = f.read() f.close() # 替换文本 new_content = content.replace('Hello', 'Hi') # 写入文本文件 f = open('file.txt', 'w') f.write(new_content) f.close() ``` 这些示例代码只是Python编程的基础,还有很多其他的功能和库可以用于自动化繁琐的工作。希望这些代码可以帮助你入门Python编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值