赞
踩
欢迎大家来到深度讲解Go语言的课堂。本课程将从基本语法讲起,逐渐深入,帮助同学深度理解Go语言面向接口,函数式编程,错误处理,测试,并行计算等元素,并带领大家实现一个分布式爬虫的实战项目。
下载:
国内:http://studygolang.com/dl
https://golang.org/dl/
# 设置国内镜像
go env -w GOPROXY=https://goproxy.cn,direct
# 开启 Go Module
go env -w GO111MODULE=on
# goimports
go get -v golang.org/x/tools/cmd/goimports
开发环境:vi, emacs, idea, eclipse, vs, sublime … + go 插件
IDE:Goland, liteIDE
文章视频链接
量,常量,类型,选择,循环,函数,指针,本章节带领大家学习一门新语言所需的必备语法知识。让大家对Go语言有一个初步的认识!
Go语言指针不能运算
Go 语言只有值传递一种方式
本章节我们来学习数组,切片,Map和字符串。在Go语言中,我们一般不直接使用数组,而是使用切片来管理线性表结构,它的语法类似python的list,不过更强大哦。当然,Map和字符串的学习也是必不可少。掌握至此,我们就可以写一些简单的算法了,刷刷leetcode不在话下,我们就来试一试。…
Go语言没有class,只有struct。我们来看看struct如何使用,Go语言给结构体定义类似方法或者成员函数的做法非常有特色。我们还将学习Go语言的包的概念,以及如何封装,如何扩展已有类型等。我们还将学习GOPATH和Go语言项目的目录结构,如何从网上下载依赖包等一系列项目相关的知识。我们将以“树”的结构和遍历作为贯穿本章…
不论地址还是结构本身,一律使用 . 来访问成员
结构创建在堆上还是栈上? 不需要知道 自动垃圾回收
可以使用指针作为方法的接收者
只有使用指针才可以改变结构体内容 nil 指针也可以调用方法 值接收者 vs 指针接收者
要改变内容必须使用指针接收者 结构体过大也考虑使用指针接收者(性能考虑) 一致性:如有指针接收者,最好都是指针接收者 值接收者是
go语言特有 值/指针接收者的方法都是使用 . 来调用
关于Go语言的依赖管理大有可用,只讲核心的,只学有用的,把时间投资在最有价值的学习上。
# 配置成GOPATH模式
go env # 查看配置项
go env -w GO111MODULE=off # 关闭go mod 模式,临时设置 export GO111MODULE=off
go env -w GOPATH=/root/go # 临时设置 export GOPATH=/root/go
# 需要在GOPATH目录下创建 src 文件夹,用于放置自己编写的代码
mkdir /root/go/src
# 安装测试依赖
go get -u go.uber.org/zap
go env -w GO111MODULE=on # 配置 go mode 模式
go env -w GOPROXY=https://goproxy.cn,direct # 使用国内源
go mode init [name], eg: go mode init gomodtest
, 执行命令后将生成 go.mod 文件go get -u go.uber.org/zap # 安装最新版本
go get go.uber.org/zap@1.11 # 安装指定版本
go get go.uber.org/zap@1.11 # 安装zap@1.11
go get go.uber.org/zap@1.12 # 更新到zap@1.12
go mod tidy # 重新整理依赖记录
go mod init [mod_name] # 初始化 go.mod 文件
go build ./... # 将所有项目依赖记录到go.mod中
这一章我们从duck typing的概念开始学起,还将探讨其他语言中对duck typing的支持,由此引出接口的概念。我们将深入理解Go语言接口的内部实现以及使用接口实现组合的模式。
在其他通用语言中,函数式编程是“高级”概念,但对于Go语言却非常基本。本章我们将讲解函数式编程的概念并且比较其他语言函数式编程的实现方法。我们将重点理解闭包。这章中我们将采用多样的例题来帮助大家更好的理解闭包,函数作为一等公民等及其常见概念和应用方法。…
这将是本课程最“无聊”的一章,但却是区分出优秀软件工程师的关键能力。Go语言独特的defer/panic/recover,以及错误机制,在社区有着广泛的争论。我们来深入理解Go语言的错误处理机制,看看Go语言如何区分错误以及异常。最后,我们实现一个Web应用微型项目,采用商业服务的错误处理思路,结合函数式编程,来演示Go语言错误…
Go语言的测试不同于其他如junit,Go语言采用“表格驱动测试”的理念。我们将学习和体会这样的理念,并用Go语言的测试支持库来实践表格驱动测试,并做代码覆盖和性能检测,通过內建的性能调优工具来优化我们之前的算法。最后演示了对http服务器的多种粒度的测试。…
这一章开始我们进入并发编程。我们讲解Goroutine,协程的概念,以及背后的Go语言调度器。
Channel是Goroutine之间通信的桥梁,它和函数一样是一等公民。在介绍完Channel的语法及运行方式后,我们将采用数个例题来演示Go语言并发编程中最常见的任务极其解决模式。
- Mutex 互斥锁
- Lock()
- UnLock()
- RWMutex 读写互斥锁
- Lock() 写的时候,排斥其他的写锁和读锁
- UnLock() 释放写锁
- Rlock() 在读取的时候 不会阻塞其他的读锁,但是会排斥写锁 Lock()
- RUnlock() 释放读锁
- Once Once.Do(一个函数) 这个方法无论被调用多少次,只会执行一次
- WaitGroup
- Add(delta int) 设定需要Done多少次
- Done() 没执行一次加1
- Wait() 阻塞到 执行Done() 的次数 和 Add(delta int)的delta次数相同
示例代码详见 chapter_11/02_channel_done/channelWaitGroup_2- Map 一个并发字典, 可并发读写
- Store(key, val) 写入字典中数据
- Load(key) 读取字段中数据
- LoadOrStore(key, defaultVal) 读不到设置key默认值defaultVal
- Range(func(key, value interface{}) bool {})
传入一个函数,遍历字典(函数每返回true, 开始遍历下一个元素,返回false终止遍历)- Delete(key) 删除字典中key
- Pool 并发池 通过Put 将数据丢到Pool中,然后Get() 但是没有顺序,可以用完再丢回去
- Put
- Get
- Cond 通知锁
- NewCond(lock) 创建一个Cond
- cond.L.Lock() ~ cond.L.Unlock() 创建一个锁区间 在区域内部可以cond.Wait()
- cond.Wait() 在锁区间内部可以cond.Wait()
- cond.Broadcast() 全部释放cond.Wait()
- cond.Signal() 解锁一个cond.Wait()
这章我们将综合运用学过的知识实现一个广度优先算法来解迷宫,为接下来的实战项目做好技术和算法上的准备。广度优先算法不仅是面试和工作中常用的技术,而且实现上相比大部分其它算法更为复杂,是检验是否熟练掌握一门语言的经典例题。让我们来试一试吧。…
这里我们简要介绍一下Go语言中非常重要而且封装良好的http标准库,回顾并实现http客户端和服务器。我们还介绍了Go语言中其他的标准库。
至此为止,恭喜同学完成了这门课Go语言部分的学习。接下来我们来进入实战项目。本章将介绍项目的具体内容,课题的选择,技术选型,总体架构,以及实现步骤。
在考虑性能之前我们首先应该考虑正确性。单任务版爬虫确保我们能够正确爬取我们所需的信息。我们应用了之前练习的广度优先算法,抽象出Parser和Fetcher,学习正则表达式,成功实现并运行单任务版爬虫。
为了提升爬虫性能,我们抽象出Worker的概念,并添加调度器,实现并发版爬虫。我们应用接口的概念,完成了由简至复杂的多个调度器的实现。同学可以在实战项目中更真实的体会并学习Go语言并发编程的多种模式。
是时候检验我们项目的成果了。我们将采用Docker+ElasticSearch来存储我们爬取的信息。在简单了解Docker和ElasticSearch后,我们将使用ElasticSearch的Go语言客户端将爬取数据写入。之后我们使用Go语言的模板引擎迅速实现前端网页展示。至此,我们已经可以尝试自己喜欢的搜索条件去查看数据啦。…
本章在简要介绍分布式概念后,将我们的并发爬虫改写成分布式。我们在很少改动的情况下,加入jsonrpc客户/服务端,实现并部署分布式爬虫。最后探讨实战项目的更多改进方案。
感谢同学们学到这里,恭喜同学们给自己的技术栈加上了非常重要的Go语言技能。希望同学们带着这门课上学到的知识,更好的参与到项目中去,共同推动Go语言的发展。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。