Support Statistics
¥.00 ·
0times
Text Preview (First 20 pages)
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
Page
1
(This page has no text content)
Page
2
目录 封面 前言 本书的版本历程 上卷 语言详解 第1章 概述 1.1 特征 1.2 简介 第2章 类型 2.1 变量 2.2 命名 2.3 常量 2.4 基本类型 2.5 引用类型 2.6 类型转换 2.7 自定义类型 第3章 表达式 3.1 保留字 3.2 运算符 3.3 初始化 3.4 流控制 第4章 函数
Page
3
4.1 定义 4.2 参数 4.3 返回值 4.4 匿名函数 4.5 延迟调用 4.6 错误处理 第5章 数据 5.1 字符串 5.2 数组 5.3 切片 5.4 字典 5.5 结构 第6章 方法 6.1 定义 6.2 匿名字段 6.3 方法集 6.4 表达式 第7章 接口 7.1 定义 7.2 执行机制 7.3 类型转换 7.4 技巧 第8章 并发 8.1 并发的含义
Page
4
8.2 通道 8.3 同步 第9章 包结构 9.1 工作空间 9.2 导入包 9.3 组织结构 9.4 依赖管理 第10章 反射 10.1 类型 10.2 值 10.3 方法 10.4 构建 10.5 性能 第11章 测试 11.1 单元测试 11.2 性能测试 11.3 代码覆盖率 11.4 性能监控 第12章 工具链 12.1 安装 12.2 工具 12.3 编译 下卷 源码剖析 第13章 准备
Page
5
第14章 引导 第15章 初始化 第16章 内存分配 16.1 概述 16.2 初始化 16.3 分配 16.4 回收 16.5 释放 16.6 其他 第17章 垃圾回收 17.1 概述 17.2 初始化 17.3 启动 17.4 标记 17.5 清理 17.6 监控 17.7 其他 第18章 并发调度 18.1 概述 18.2 初始化 18.3 任务 18.4 线程 18.5 执行 18.6 连续栈
Page
6
18.7 系统调用 18.8 监控 18.9 其他 第19章 通道 19.1 创建 19.2 收发 19.3 选择 第20章 延迟 20.1 定义 20.2 性能 20.3 错误 第21章 析构 21.1 设置 21.2 清理 21.3 执行 第22章 缓存池 22.1 初始化 22.2 操作 22.3 清理
Page
7
本书由“ePUBw.COM”整理,ePUBw.COM 提供最新最全的优质 电子书下载!!! 封面
Page
8
(This page has no text content)
Page
9
本书由“ePUBw.COM”整理,ePUBw.COM 提供最新最全的优质 电子书下载!!! 前言 前两天忙里偷闲将第五版《Go学习笔记》上下册合并,预备交给出版社编辑。不经 意扫了一眼更新记录,才发觉四年光阴恍然而过。不知从何时起,岁月流逝的速度 越来越快,抓不得,留不住。 我很擅长坚持,不知是因为笨,还是性情迟钝的缘故。在给编辑写作者简介时,我 努力回忆自己最近二十年的经历,好像除了些纷扰的人和事外,就是一段段在不同 技术圈子里日夜探索的记忆,历久弥新。 现在带了些学生,每每交流时,总偷偷庆幸自己是个先行者,没有互联网的“黑暗 时代”反而造就了踏实的基础,远不是现今乱花迷眼的境况。看着他们对于具体实 现“懵懂无知”的表现,我对于写书这事就愈发虔诚,生怕误了别人的光阴和热 情。似乎《学习笔记》这个名字才是最好的诠释,立不得案头,权作闲书,稍能观 感一二即可。 因喜爱C,故对Go关注得很早。观望良久,终究受不住诱惑,一头栽了进去。边学边 记,于是有了最早的《学习笔记》。只因错漏过多,发到某论坛着实没砸出什么水 花来。此后,对于宣传也淡了心思,再不愿出去,只自己默默更新,或发到微博, 给一些熟识尚惦记这事的人打个招呼。
Page
10
某日,一编辑发来消息,询问我是否出版,才恍然知道这书原也是可印的,好像自 己从没想过。犹豫再三,且将几本笔记从GitHub下架。只可惜,因某些理念不同, 最终未能如愿,这一拖就是许多时日。 去年受老谢的邀请,前往上海参加Gopher China大会。期间多次被问及何时能有实 体书出版,熄了许久的心思方又活过来。年中,重新写了书稿,年底几乎又重来一 遍,心底对于出书总有些忐忑。直到圣诞节,才放了下册出来。幸好,并没有人出 来指责我粗制滥造,方得心安。 我儿小乖还太小,于是猴年我一人回老家过年。也许是在外面太久,对搬进城里的 老家全然陌生,每日里除了陪父母吃饭外,其他时间都用来写上册书稿。偶尔透过 窗看见远处的山影,才找回些幼时记忆。书写得意外顺利,即便网络不算通畅也未 能影响到我。回京路上,我彻底定了主意,准备交付出版。 节后忙于培训一事,书稿校对稍稍拖后了些。边按章节调整,边请群里的伙伴们帮 忙审校,所幸赶在截止日期前完成。样稿交到编辑手里,虽尚有些收尾工作,但总 算能放轻松些。这于我是个解脱,困于此的心思总算少了一大半。 依惯例,需在此感谢很多人。其中自然少不了对我多加鼓励的家中太上领导和惦记 良久的网络众位大仙们。当然,最需感谢的是群里帮忙校对的小伙伴们,有溺水的 鱼、大内总管、starchou、老虎、日下、小E、春婶、奋斗娃等等。 读者定位 本书并不适合用作编程初学者入门,因内容和文体都太过简练了些。我厚脸推荐给 有实际经验或正用Go工作的人群,可于路途中当闲书翻看几页。
Page
11
联系方式 鉴于能力有限,书中难免错漏。如您看到任何问题,请与我联系,以便更正。谢 谢! ● 微博:weibo.com/qyuhen ● 邮件:qyuhen@hotmail.com ● 社区:qyuhen.bearychat.com 雨痕 二〇一六年春 本书由“ePUBw.COM”整理,ePUBw.COM 提供最新最全的优质 电子书下载!!! 本书的版本历程 2012-01-11 开始学习Go。 2012-01-15 第一版,基于R60。 2012-03-29 升级到1.0。 2012-06-15 升级到1.0.2。
Page
12
2013-03-26 升级到1.1。 2013-12-12 第二版,基于1.2。 2014-05-22 第三版,基于1.3。 2014-12-20 第四版,基于1.4。 2015-06-15 第五版,基于1.5。 2015-11-01 全新《学习笔记.第五版》。 2015-12-09 下卷《源码剖析》截稿,基于1.5.1。 2016-04-01 上卷《语言详解》截稿,基于1.6。 本书由“ePUBw.COM”整理,ePUBw.COM 提供最新最全的优质 电子书下载!!! 上卷 语言详解 基于Go 1.6 第1章 概述 对我而言,Go是一门很有意思的编程语言。虽算不得优雅,但也不浅薄。自C一脉相 承,又吸收了些时髦的东西。最重要的是,它依旧简单。我喜欢简单,平日里也是
Page
13
竭尽所能将复杂的东西简单化。 有关Go的宣传语已经太多,优点或缺点都能罗列出长长的清单。我甚至不知道该如 何做才能堆砌出本章内容,所以一直拖到全书的最后才去完成。 1.1 特征 我并不想,似乎也没资格为Go增添什么新的荣誉。在此仅从这几年的使用经验说说 个人看法,一如书名《学习笔记》那样。 语法简单 抛开语法样式不谈,单就类型和规则而言,Go与C99、C11相似之处颇多,这也是我 能接受它被冠以“NextC”名号的重要原因。 即便我是个坚定的C拥趸,也不得不承认,它处于简单和复杂的两极。C简单到你每 写下一行代码,都能在脑中想象出编译后的模样,指令如何执行,内存如何分配, 等等。而C的复杂在于,它有太多隐晦而不着边际的规则,着实让人头疼。相比较而 言,Go从零开始,没有历史包袱,在汲取众多经验教训后,可从头规划一个规则严 谨、条理简单的世界。 人们习惯拿关键字和控制语句的数量来作为Go简单的例证,我倒觉着这并不合适。 诚然,更少的语言规则有助于入门学习,这无可厚非。但更重要的在于,语言规则 严谨,没有歧义,更没什么黑魔法变异用法。任何人写出的代码都基本一致,这才 是简单的本质。放弃部分“灵活”和“自由”,换来更好的维护性,我觉得是值得 的。 将“++”、“--”从运算符降级为语句,保留指针,但默认阻止指针运算。初时的
Page
14
不习惯,并不能掩盖它们带来的长期的好处。还有,将切片和字典作为内置类型, 从运行时的层面进行优化,这也算是一种“简单”。 并发模型 时至今日,并发编程已成为程序员的基本技能,在各个技术社区都能看到诸多与之 相关的讨论主题。究竟哪种方式是最佳并发编程体验,或许会一直争论下去。但Go 却一反常态做了件极大胆的事,从根子上将一切都并发化,运行时用Goroutine运 行所有的一切,包括main.main入口函数。 可以说,Goroutine是Go最显著的特征。它用类协程的方式来处理并发单元,却又 在运行时层面做了更深度的优化处理。这使得语法上的并发编程变得极为容易,无 须处理回调,无须关注执行绪切换,仅一个关键字,简单而自然。 搭配channel,实现CSP模型。将并发单元间的数据耦合拆解开来,各司其职,这对 所有纠结于内存共享、锁粒度的开发人员都是一个可期盼的解脱。若说有所不足, 那就是应该有个更大的计划,将通信从进程内拓展到进程外,实现真正意义上的分 布式。 内存分配 将一切并发化固然是好,但带来的问题同样很多。如何实现高并发下的内存分配和 管理就是个难题。好在Go选择了tcmalloc,它本就是为并发而设计的高性能内存分 配组件。 可以说,内存分配器是运行时三大组件里变化最少的部分。刨去因配合垃圾回收器 而修改的内容,内存分配器完整保留了tcmalloc的原始架构。使用cache为当前执
Page
15
行线程提供无锁分配,多个central在不同线程间平衡内存单元复用。在更高层次 里,heap则管理着大块内存,用以切分成不同等级的复用内存块。快速分配和二级 内存平衡机制,让内存分配器能优秀地完成高压力下的内存管理任务。 在最近几个版本中,编译器优化卓有成效。它会竭力将对象分配在栈上,以降低垃 圾回收压力,减少管理消耗,提升执行性能。可以说,除偶尔因性能问题而被迫采 用对象池和自主内存管理外,我们基本无须参与内存管理操作。 垃圾回收 垃圾回收一直是个难题。早年间,Java就因垃圾回收低效被嘲笑了许久,后来Sun 连续收纳了好多人和技术才发展到今天。可即便如此,在Hadoop等大内存应用场景 下,垃圾回收依旧捉襟见肘、步履维艰。 相比Java, Go面临的困难要更多。因指针的存在,所以回收内存不能做收缩处理。 幸好,指针运算被阻止,否则要做到精确回收都难。 每次升级,垃圾回收器必然是核心组件里修改最多的部分。从并发清理,到降低STW 时间,直到Go的1.5版本实现并发标记,逐步引入三色标记和写屏障等等,都是为了 能让垃圾回收在不影响用户逻辑的情况下更好地工作。尽管有了努力,当前版本的 垃圾回收算法也只能说堪用,离好用尚有不少距离。可对一个从R60一路跟踪源码走 过来的程序员而言,我目睹了Go Team为此所付出的全部努力。我在此表达敬意, 以及对未来某个飞跃的预期。 静态链接 Go刚发布时,静态链接被当作优点宣传。只须编译后的一个可执行文件,无须附加
Page
16
任何东西就能部署。这似乎很不错,只是后来风气变了。连着几个版本,编译器都 在完善动态库buildmode功能,场面一时变得有些尴尬。 暂不说未完工的buildmode模式,静态编译的好处显而易见。将运行时、依赖库直 接打包到可执行文件内部,简化了部署和发布操作,无须事先安装运行环境和下载 诸多第三方库。这种简单方式对于编写系统软件有着极大好处,因为库依赖一直都 是个麻烦。事实上,我们也能看到越来越多的工具采用Go开发,其中恐怕就有此等 原因。 标准库 学习编程语言,早已不是学一点语法规则那么简单。现在更习惯称作选择 Ecosystem(生态圈),而这其中标准库的作用和分量尤为明显。 功能完善、质量可靠的标准库为编程语言提供了充足动力。在不借助第三方扩展的 情况下,就可完成大部分基础功能开发,这大大降低了学习和使用成本。最关键的 是,标准库有升级和修复保障,还能从运行时获得深层次优化的便利,这是第三方 库所不具备的。 Go标准库虽称不得完全覆盖,但也算极为丰富。其中值得称道的是net/http,仅须 简单几条语句就能实现一个高性能Web Server,这从来都是宣传的亮点。更何况大 批基于此的优秀第三方Framework更是将Go推到Web/Microservice开发标准之一 的位置。 当然,优秀第三方资源也是语言生态圈的重要组成部分。近年来崛起的几门语言 中,Go算是独树一帜,大批优秀作品频繁涌现,这也给我们学习Go提供了很好的参 照。
Page
17
工具链 完整工具链对于日常开发极为重要。Go在此做得相当不错,无论是编译、格式化、 错误检查、帮助文档,还是第三方包下载、更新都有对应工具。其功能未必完善, 但起码算得上简单易用。 内置完整测试框架,其中包括单元测试、性能测试、代码覆盖率、数据竞争,以及 用来调优的pprof,这些都是保障代码能正确而稳定运行的必备利器。 除此之外,还可通过环境变量输出运行时监控信息,尤其是垃圾回收和并发调度跟 踪,可进一步帮助我们改进算法,获得更佳的运行期表现。 遗憾的是,发展6年的Go依然缺少一个真正意义上的调试器,对此我个人颇有怨念。 另外,依赖包管理也是社区争论的焦点之一。 1.2 简介 本节简单预览一下语言功能,有个相对完整的印象更利于学习后续知识。 可依照第12章安装配置编译环境。 本书相关内容和示例运行环境: ● Mac OS X EI Capitan 10.11.4 ● Ubuntu Server 14.04 x86_64 ● GNU gcc 5.3/gdb 7.7 ● Go 1.6 amd64
Page
18
源文件 源码文件使用UTF-8编码,对Unicode支持良好。每个源文件都属于包的一部分,在 文件头部用package声明所属包名称。 test.go package main func main() { println("hello,world!") } 以“.go”作为文件扩展名,语句结束分号会被默认省略,支持C样式注释。入口函 数main没有参数,且必须放在main包中。 用import导入标准库或第三方包。 package main import( "fmt" ) func main() { fmt.Println("hello,world!") } 请删除未使用的导入,否则编译器会将其当作错误。 可直接运行,或编译为可执行文件。 $go run main.go hello,world! 变量 使用var定义变量,支持类型推断。基础数据类型划分清晰明确,有助于编写跨平台 应用。编译器确保变量总是被初始化为零值,避免出现意外状况。 package main func main() { var x int32 var s= "hello,world!" println(x,s) }
Page
19
在函数内部,还可省略var关键字,使用更简单的定义模式。 package main func main() { x:=100 // 注意,赋值符号不同 println(x) } 编译器将未使用的局部变量定义当作错误。 表达式 Go仅有三种流控制语句,与大多数语言相比,都可称得上简单。 if func main() { x:=100 if x>0{ println("x") }else if x<0{ println("- x") }else{ println("0") } } switch func main() { x:=100 switch{ case x>0: println("x") case x<0: println("-x") default: println("0") } } for func main() { for i:=0;i<5;i++ { println(i) } for i:=4;i>=0;i-- { println(i) } } func main() { x:=0 for x<5{ // 相当于while(x<5) { ... } println(x) x++ } } func main() { x:=4 for{ // 相当于while(true) { ... } println(x) x-- if x<0{ break } } }
Page
20
在迭代遍历时,for...range除元素外,还可返回索引。 func main() { x:= []int{100,101,102} for i,n:=range x{ println(i, ":",n) } } 输出: 0:100 1:101 2:102 函数 函数可定义多个返回值,甚至对其命名。 package main import( "errors" "fmt" ) func div(a,b int) (int,error) { if b==0{ return 0,errors.New("division by zero") } return a/b,nil } func main() { a,b:=10,2 // 定义多个变量 c,err:=div(a,b) // 接收多 返回值 fmt.Println(c,err) } 函数是第一类型,可作为参数或返回值。 func test(x int)func() { // 返回函数类型 return func() { // 匿名函数 println(x) // 闭包 } } func main() { x:=100 f:=test(x) f() } 用defer定义延迟调用,无论函数是否出错,它都确保结束前被调用。 package main func test(a,b int) { defer println("dispose...") // 常 用来释放资源、解除锁定,或执行一些清理操作 // 可定义多个defer,按FILO顺 序执行 println(a/b) } func main() { test(10,0) }
Comments 0
Loading comments...
Reply to Comment
Edit Comment