三个小项目入门Go语言 | 青训营笔记

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
云解析DNS,个人版 1个月
简介: 今天的课程比较快速的讲解了go语言的入门,并配合三个小的项目实践梳理所学知识点,这里详细回顾一下这三个项目,并完成课后作业,以及分享一些自己的理解。

前言

今天的课程比较快速的讲解了go语言的入门,并配合三个小的项目实践梳理所学知识点,这里详细回顾一下这三个项目,结合课后作业要求做一些代码补充,并附上自己的分析。

项目仓库地址:https://github.com/wangkechun/go-by-example

实战

项目一:guessing-game

生成一个100以内随机数,玩家在控制台输入猜测的数字,程序会不断反馈猜测的值与生产值的大小关系,直到玩家输入正确,代码简单,这里直接贴出(需要注意不要忘记添加随机数种子):

image-20220507183655438

项目二:simpledict

先概述一下功能:用户将需要翻译的单词作为参数在命令行运行go的main函数,程序会返回翻译结果。通过下面的语句可以直接运行样例仓库代码中的main函数,得到翻译结果。

image-20220507184640950

那么程序是如何实现这个翻译功能的呢?它做了下面几件事:

  • 获取main函数运行时的参数hello作为需要翻译的单词(通过go的api获取)
  • 请求翻译软件的api获取结果数据:

    • 这个过程和爬虫的工作比较像,模拟用户在网页上提交翻译的请求,其本质上就是发送了一个http请求,携带需要翻译的单词信息,响应翻译结果的json并由浏览器解析,通过下图的copy as cURL可以将本次request的请求以cURL请求的方式拷贝。

    image-20220507185726072

    • 访问:https://curlconverter.com/#go,这个在线工具可以将curl命令转换成go语言代码(或者其他语言),将得到的代码直接复制到goland中运行就可以实现用go代码模拟请求这个翻译接口,得到响应数据(文本格式的json)

      image-20220507192208213

      image-20220507190940969

  • 解析结果数据

    • 此时得到的翻译数据是文本格式的json(就是byte数组,或者说字符串),因此需要将其反序列化为go的结构体,然后打印出我们需要的翻译信息。
    • 访问:https://oktools.net/json2go,这个在线工具可以将json转go的struct,然后将这个结构放入go代码中,使用json包的Unmarshal函数将json字符串字符串反序列化为结构体,后面就可以打印结构体中需要的属性(包含翻译结果)

      image-20220507203251798

      image-20220507191114812

  • 改进:用到两个翻译软件的接口,并且并发访问,思路是一样的,就是再找一个翻译软件的接口重复上面的操作,然后重点在于并发的实现,这里启用两个goroutine,借助sync包的WaitGroup,先初始化一个2的容量,然后在一个go程结束之后调用wg.Done(),只有全部容量次数的Done调用后wg.Wait()才会放行,否则任意一个go程未完成,主go程都不会继续执行(但是如果没有这个WaitGroup去限制,则在主go程结束时,因为由其创建的子go程可能并没有完成,但依旧会结束,而恰恰因为并发的关系,编码先后顺序的失去了作用,发生这种情况的概率很高)

image-20220507192736383

项目三:proxy

实现一个简易版的socks5的代理服务器,代理的工作流程如下:

image-20220507194934754

  • 本质就是客户端要先和代理服务器建立TCP连接,然后socks代理服务器和需要访问的目标服务器建立TCP连接,对于所有从客户端发来的请求由代理服务器转发给目标服务器,且目标服务器的响应数据也由代理服务器转发给客户端(socks5代理服务器就是以sock5s协议为标准去建立客户端和代理服务器的通信)
  • 观察proxy项目包的v4版本(clone地址已经给出),看到代理服务端的process函数如下:

    image-20220507195958463

    • 代理的工作由auth()认证和connect()连接两个部分组成,看一下最上面给出的代理工作流程图,可以看到对应着协商阶段和通信阶段。而我们发现,本实例的客户端发起的是一条curl --socks5 127.0.0.1:1080 -v https://www.qq.com,需要注意的细节是,auth和connect工作并不是一蹴而就的,它们从reader缓冲区读取客户端发送过来的数据,验证之后返回给客户端,然后再获取从客户端发送过来的数据,而客户端的这部分工作已经被curl工具隐藏,而非只是发起了一次请求。
    • 因为auth和connect函数中多次使用到的从缓冲区读取字节的这个api在缓冲区没有byte的时候,是会被阻塞的,因此会等待客户端发送数据,因此只要代理服务器遵守socks5协议规定的通信规则进行解析客户端的数据,发送指定的响应,而客户端也遵守这个规则解析和发送数据(本例就是curl --socks5 xxx帮我们完成了),就可以实现socks5代理服务器的工作模式
    • 因此我理解中的socks5代理服务器就是完全在socks5协议约束的基础上进行编码的一个服务器,之后的请求和响应转发则和socks5没关系了

结束语

对于第三个样例这里只是着重讲了一下我的一些理解,socks5代理部分还有很多值得深入学习的地方。关于后面课程的学习,也尽量会保证笔记的输出,欢迎各位一起探讨学习~

关注微信公众号【程序员白泽】,将同步更新字节青训营的学习笔记

相关文章
|
1天前
|
安全 Java Go
探索Go语言在高并发环境中的优势
在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
|
4天前
|
运维 Kubernetes Go
"解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
22 1
|
5天前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
12 1
|
5天前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
2天前
|
NoSQL Go Redis
Go语言中如何扫描Redis中大量的key
在Redis中,遍历大量键时直接使用`KEYS`命令会导致性能瓶颈,因为它会一次性返回所有匹配的键,可能阻塞Redis并影响服务稳定性。为解决此问题,Redis提供了`SCAN`命令来分批迭代键,避免一次性加载过多数据。本文通过两个Go语言示例演示如何使用`SCAN`命令:第一个示例展示了基本的手动迭代方式;第二个示例则利用`Iterator`简化迭代过程。这两种方法均有效地避免了`KEYS`命令的性能问题,并提高了遍历Redis键的效率。
9 0
|
3天前
|
监控 Serverless Go
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
|
4天前
|
关系型数据库 MySQL 数据库连接
Go语言中使用sqlx来操作事务
在应用中,数据库事务保证操作的ACID特性至关重要。`github.com/jmoiron/sqlx`简化了数据库操作。首先安装SQLX和MySQL驱动:`go get github.com/jmoiron/sqlx`和`go get github.com/go-sql-driver/mysql`。导入所需的包后,创建数据库连接并使用`Beginx()`方法开始事务。通过`tx.Commit()`提交或`tx.Rollback()`回滚事务以确保数据一致性和完整性。
8 0
【Go语言入门100题】026 I Love GPLT (5 分) Go语言 | Golang
L1-026 I Love GPLT (5 分) Go语言|Golang 这道超级简单的题目没有任何输入。 你只需要把这句很重要的话 —— “I Love GPLT”——竖着输出就可以了。 所谓“竖着输出”,是指每个字符占一行(包括空格),即每行只能有1个字符和回车。
558 0
|
存储 Go
【Go语言入门100题】023 输出GPLT (20 分) Go语言 | Golang
L1-023 输出GPLT (20 分) Go语言|Golang 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。 下面给出甲、乙两人的酒量(最多能喝多少杯不倒)和划拳记录,请你判断两个人谁先倒。
155 0
|
8天前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
go语言后端开发学习(四) —— 在go项目中使用Zap日志库