任何包系统设计的目的都是为了简化大型程序的设计和维护工作,通过将一组相关的特性放进一个独立的单元以便于理解和更新,在每个单元更新的同时保持和程序中其它单元的相对独立性。

Go语言的闪电般的编译速度主要得益于三个语言特性。第一点,所有导入的包必须在每个文件的开头显式声明,这样的话编译器就没有必要读取和分析整个源文件来判断包的依赖关系。第二点,禁止包的环状依赖,因为没有循环依赖,包的依赖关系形成一个有向无环图,每个包可以被独立编译,而且很可能是被并发编译。第三点,编译后包的目标文件不仅仅记录包本身的导出信息,目标文件同时还记录了包的依赖关系。因此,在编译一个包的时候,编译器只需要读取每个直接导入包的目标文件,而不需要遍历所有依赖的的文件。

Go语言的规范并没有指明包的导入路径字符串的具体含义,导入路径的具体含义是由构建工具来解释的。

在每个Go语言源文件的开头都必须有包声明语句。包声明语句的主要目的是确定当前包被其它包导入时默认的标识符(也称为包名)。

包所在的目录中可能有一些文件名是以_test.go为后缀的Go源文件(译注:前面必须有其它的字符,因为以_.开头的源文件会被构建工具忽略),并且这些源文件声明的包名也是以_test为后缀名的。这种目录可以包含两种包:一种是普通包,另一种则是测试的外部扩展包。所有以_test为后缀包名的测试外部扩展包都由go test命令独立编译,普通包和测试的外部扩展包是相互独立的。

如果我们想同时导入两个有着名字相同的包,例如math/rand包和crypto/rand包,那么导入声明必须至少为一个同名包指定一个新的包名以避免冲突。这叫做导入包的重命名。

import ("crypto/rand"mrand "math/rand" // alternative name mrand avoids conflict
)

每个导入声明语句都明确指定了当前包和被导入包之间的依赖关系。如果遇到包循环导入的情况,Go语言的构建工具将报告错误。

如果只是导入一个包而并不使用导入的包将会导致一个编译错误。但是有时候我们只是想利用导入包而产生的副作用:它会计算包级变量的初始化表达式和执行导入包的init初始化函数(§2.6.2)。这时候我们需要抑制“unused import”编译错误,我们可以用下划线_来重命名导入的包。

import _ "image/png" // register PNG decoder

其中有两种技术在实践中证明是比较有效的。第一种是代码在被正式部署前需要进行代码评审。第二种则是测试,也就是本章的讨论主题。

Go语言的测试技术是相对低级的。它依赖一个go test测试命令和一组按照约定方式编写的测试函数,测试命令可以运行这些测试函数。

go test命令是一个按照一定的约定和组织来测试代码的程序。在包目录内,所有以_test.go为后缀名的源文件在执行go build时不会被构建成包的一部分,它们是go test测试的一部分。

*_test.go文件中,有三种类型的函数:测试函数、基准测试(benchmark)函数、示例函数。一个测试函数是以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确;go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。基准测试函数是以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准测试函数以计算一个平均的执行时间。示例函数是以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档。

表格驱动的测试

func TestIsPalindrome(t *testing.T) {var tests = []struct {input stringwant  bool}{{"", true},{"a", true},{"aa", true},{"ab", false},{"kayak", true},{"detartrated", true},{"A man, a plan, a canal: Panama", true},{"Evil I did dwell; lewd did I live.", true},{"Able was I ere I saw Elba", true},{"été", true},{"Et se resservir, ivresse reste.", true},{"palindrome", false}, // non-palindrome{"desserts", false},   // semi-palindrome}for _, test := range tests {if got := IsPalindrome(test.input); got != test.want {t.Errorf("IsPalindrome(%q) = %v", test.input, got)}}
}

模拟行为--当我们准备TestEcho测试的时候,我们修改了echo函数使用包级的out变量作为输出对象,因此测试代码可以用另一个实现代替标准输出,这样可以方便对比echo输出的数据。使用类似的技术,我们可以将产品代码的其他部分也替换为一个容易测试的伪对象。使用伪对象的好处是我们可以方便配置,容易预测,更可靠,也更容易观察。同时也可以避免一些不良的副作用,例如更新生产数据库或信用卡消费行为。(面向测试编程)

为了解决包之间的循环依赖问题,引入外部测试包。外部测试包名添加’_test’,文件和源码放入同一个文件夹中。

使用以下三个命令可以查看源文件,内部测试代码和外部测试代码(以fmt包为例)

go list -f={{.GoFiles}} fmt
go list -f={{.TestGoFiles}} fmt
go list -f={{.XTestGoFiles}} fmt

对待测程序执行的测试的程度称为测试的覆盖率。

这些启发式方法中,语句的覆盖率是最简单和最广泛使用的。语句的覆盖率是指在测试中至少被运行一次的代码占总代码数的比例。在本节中,我们使用go test命令中集成的测试覆盖率工具,来度量下面代码的测试覆盖率,帮助我们识别测试和我们期望间的差距。

在测试环节生成统计覆盖率的文件

go test -run=Coverage -coverprofile=c.out gopl.io/ch7/eval

运行了测试覆盖率工具,打印了测试日志,生成一个HTML报告,然后在浏览器中打开

go tool cover -html=c.out

基准测试是测量一个程序在固定工作负载下的性能。在Go语言中,基准测试函数和普通测试函数写法类似,但是以Benchmark为前缀名,并且带有一个*testing.B类型的参数;*testing.B参数除了提供和*testing.T类似的方法,还有额外一些和性能测量相关的方法。

和普通测试不同的是,默认情况下不运行任何基准测试。我们需要通过-bench命令行标志参数手工指定要运行的基准测试函数。

go test -bench=.

快的程序往往是伴随着较少的内存分配。-benchmem命令行标志参数将在报告中包含内存的分配数据统计。

go test -bench=. -benchmem

当我们想仔细观察我们程序的运行速度的时候,最好的方法是性能剖析。剖析技术是基于程序执行期间一些自动抽样,然后在收尾时进行推断;最后产生的统计结果就称为剖析数据。

CPU剖析数据标识了最耗CPU时间的函数。在每个CPU上运行的线程在每隔几毫秒都会遇到操作系统的中断事件,每次中断时都会记录一个剖析数据然后恢复正常的运行。

堆剖析则标识了最耗内存的语句。剖析库会记录调用内部内存分配的操作,平均每512KB的内存申请会触发一个剖析数据。

阻塞剖析则记录阻塞goroutine最久的操作,例如系统调用、管道发送和接收,还有获取锁等。每当goroutine被这些操作阻塞时,剖析库都会记录相应的事件。

$ go test -cpuprofile=cpu.out
$ go test -blockprofile=block.out
$ go test -memprofile=mem.out

包和工具(读书笔记)相关推荐

  1. 人生效率手册:如何卓有成效地过好每一天--By张萌姐姐--读书笔记

    读书笔记:<人生效率手册>:如何卓有成效地过好每一天--By张萌姐姐... 整本书看完的感受: 这本书主要讲的是生活中我们需要给自己一个目标,然后通过自己的努力去实现这个目标,书中说的很多 ...

  2. 人生效率手册---读书笔记

    基本信息介绍 出版年: 2017-7 类型:时间管理 页数:322 阅读时长:8小时 阅读目的 初认识张萌姐是在樊登读书的作者分享节目.只听她讲了一句话就被这个温文尔雅的姐姐所吸引,视频中她说道,上学 ...

  3. 黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第三章 网络工程-原始套接字与嗅探(1)主机发现工具与包嗅探

    黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第三章 网络工程-原始套接字与嗅探(1)主机发现工具 文章目录 黑帽python第二版(Black Ha ...

  4. 《Go语言圣经》学习笔记 第十章 包和工具

    <Go语言圣经>学习笔记 第十章 包和工具 目录 包简介 导入路径 包声明 导入声明 包的匿名导入 包和命名 工具 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. G ...

  5. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...

  6. 《深入浅出DPDK》读书笔记(十三):DPDK虚拟化技术篇(加速包处理的vhost优化方案)

    Table of Contents 加速包处理的vhost优化方案 142.vhost的演进和原理 143.Qemu与virtio-net 144.Linux内核态vhost-net 145.用户态v ...

  7. 《深入浅出DPDK》读书笔记(七):PCIe与包处理I/O

    本文内容为读书笔记,摘自<深入浅出DPDK> 74.PCIe概览 PCI Express(Peripheral Component Interconnect Express)又称PCIe, ...

  8. 每个人的商学院--管理基础(第三章:管理工具)--读书笔记

    第三章:管理工具 面向业绩:梦想归梦想,绩效归绩效 读书笔记: 管理工作并非总能收获大团圆的结局,还要时常做出真正艰难的决定. 管理只对绩效负责. 绩效就是达成公司的经营目标. 公司里的两层关系:第一 ...

  9. python3第三方库手册_python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑...

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...

  10. 小啊呜产品读书笔记001:《邱岳的产品手记-02》 开篇词 产品经理的世界没有对错 01讲 验证码是个好设计吗 02讲 产品经理工具指南 03讲 产品案例分析·Trigraphy的设计哲学

    小啊呜产品读书笔记001:<邱岳的产品手记-02> 开篇词 产品经理的世界没有对错 & 01讲 验证码是个好设计吗 & 02讲 产品经理工具指南 & 03讲 产品案 ...

最新文章

  1. 客快物流大数据项目(十一):Docker应用部署
  2. 常见排序算法复杂度总结
  3. 【软考-软件设计师】校验码
  4. 压测工具下载地址说明及汇总
  5. linux下 mysql5.5数据库迁移操作
  6. 视频主观质量评价方法
  7. Delphi编程分割图片的方法
  8. 二重指针、二维数组及二者如何进行赋值
  9. 视频图片音乐音效工具等素材网汇总
  10. HTML期末学生大作业:中华传统文化【苏绣手工艺】带psd设计图(15页)
  11. java 时间显示毫秒_Java程序以毫秒为单位显示日期和时间
  12. 企业微信回调实现(java)
  13. 嵌入式主板有哪些特点?
  14. 树莓派3B+实现TM1637驱动数码管
  15. unsigned long long 与 long long
  16. 电影挖掘机 搜索各大视频网站API接口 自动搜索全网所有电影
  17. c语言追光篮球程序,追光篮球游戏下载-追光篮球苹果版v1.0_6137游戏网
  18. 即将取代Maven和Gradle的新一代更强更快的构建工具(至尊典藏版)
  19. 2018.09.25软件更新公告
  20. HDU 4937Lucky Number

热门文章

  1. 2023江苏大学计算机考研信息汇总
  2. win10自带Groove音乐不能播放CUE和APE文件的一种曲线救国办法,自己创建aimppack插件包,AIMP安装DSP插件
  3. JavaWeb学习-AJAX-3-练习:验证用户名是否存在
  4. Python 蓝桥杯试题 基础练习 特殊回文数
  5. python网盘搜索引擎_打造一个蓝奏云网盘搜索引擎
  6. k8s集群svc端口范围,nfs做StorageClass运行故障
  7. Root后安装Xposed框架卡Logo问题
  8. 解决Could not resolve XXX
  9. 【雕爷学编程】Arduino动手做(2)---光敏电阻模块
  10. 转载:国学与古代文学的关系