好好学习,天天向上

channel 是 golang 并发编程的极其重要的组成部分之一。但是关于 channel 的一些特性,如果不熟记于心,那么,可是会陷入莫名其妙的问题中无法自拔。下面,是关于 channel 你可能会踩到的雷…… 当 channel 为 nil 时... 当你声明一个 channel 并且不进行任何初始化动作的时候,恭喜你,你就获得了一个 nil channel: 1 var c chan struct{} 在 golang 中,从一个 nil channel 接收数据,以及往一个 nil channel 发送数据都会天荒地老地阻塞。 这看起来并没有什么。但是,地雷暗藏其中。
阅读全文 »

原文:The Go Object Lifecycle 尽管 Go 是门如此简单的语言,Go 开发者还是发现了大量创建和使用对象的方法。在这篇文章中,我们将会看到对象管理的三步法:实例化、初始化和启动。我们还会将其与其他创建和使用对象的方法进行对比,并回顾每种方法的优缺点。 目的 这似乎是个很蠢的问题,但是,我们在 Go 中创建和使用对象的目的是什么呢?为了与 Go 的风格保持一致,我优先考虑以下几点: 1. 简单 2. 灵活 3. 文档友好 此外,还应该说明哪些不是我们的目标。应该假设我们的最终用户具有基本的能力,因而不需要提供过多的防护。我们的代码用户可以 RTFM(假
阅读全文 »

根据 go spec 中对于处理 panic 的描述: > 当执行一个函数 F 时,显式调用 panic 或者运行时的 panic 都会终止函数 F 的执行。此时,函数 F 中 defer 的函数会照常执行。接下来,执行函数 F 的调用者中 defer 的函数,依此执行至当前 goroutine 顶层 defer 的函数。执行完后,退出程序,并报告异常(包括 panic 函数的值) 换句话说,当 panic 出现时,会沿调用堆栈向上执行 defer 函数。这里要特别特别特别注意的是,只会执行当前 goroutine 的调用堆栈。也就是说,生成该 goroutine 的那个 goroutine
阅读全文 »

原文:SecurityBrief Europe - New study details how easy it is for hackers to steal your data Exabeam 的一份新报告详细说明了,网络犯罪分子要入侵你的生活有多容易。 web 浏览器存储大量有关用户的敏感信息并非什么秘密,而网站开发人员使用各种各样的方式来定制这种体验。广告商也使用这些功能来最大限度地提高网站上展示的广告的影响力。 结果就是,浏览器深藏着你的大量信息。Exabeam 高级威胁研究员 Ryan Benson 表示,黑客可能会以多种方式利用这些信息。所有类型的个人信息,包括位置信息
阅读全文 »

在实现一些服务的过程中,我们需要对内部处理时间进行控制,以防客户端一直在等待响应。 select-case 实现的超时控制 在 go 中,利用 select + case + time 包,就可以很轻松实现超时控制。我们修改Go by Example: Timeouts中的一个例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package main import ( "time" "fmt" ) func ma
阅读全文 »

某次测试一个用 Go 编写的 HTTP 服务(使用 nginx 进行了反向代理)的时候,发现请求直接返回了 400 Bad Request: invalid header value。而在 handler 入口处的调试日志并没有打印。同时,nginx 日志显示,请求已经被转发到了后面的 HTTP 服务。也就是说,这个 400 错误是 Go 在接受请求后,进入 handler 之前返回的。故而在此记录下,Go 的 HTTP 标准库对请求 header 的处理方式。 httplex golang 的标准库 net/http 使用 golang.org/x/net/lex/httplex 对请求头
阅读全文 »

encoding/json包在web开发的过程中,占据着相当重要的角色。然而角色有多重,坑就有多大。下面记录的便是在踩json雷中的辛酸泪(>﹏<) 反序列化时的数值处理及float64精度问题 众所周知(其实是最近才知道),golang原生的encoding/json在反序列化的时候,默认情况下会把所有数值类型转成float64类型。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import "fmt" import "encoding/json" func test_std_json(){ var m []interface{} if err :
阅读全文 »

前段时间需要利用fastdfs来实现文件的上传操作。但是fastdfs官方并不提供golang客户端。但是github大法好呀。于是言小白屁颠屁颠地在github上找到了一个fastdfs的第三方实现golang客户端:tRavAsty/fdfs_client。 一切开发就绪,但是在测试阶段总会偶然的出现在对fastdfs发起上传文件请求的时候hang住的情况。 在加了无数次debug日志,以及最后祭出gdb的情况下,终于将问题范围缩小到connection.go中的相关实现上。 这个文件提供了连接池的相关操作。在此客户端中,一切与fastdfs的实际交互都会通过连接池中的连接进行。
阅读全文 »

并发 并发编程是一个很大的主题,这里之提一些Go特有的重点 #### 通过通信共享 共享值通过channel进行传递。在任意给定的时间内,只有一个goroutine可以访问到该值。在设计上,不会出现数据竞争。即 不通过共享内存通信,相反,通过通信来共享内存 还可以再过些。例如,也许最好将一个mutext放在一个整型变量附近来实现引用计数。但是,作为高级方法,使用channel来控制访问,会使得编写清晰正确的程序更容易。 关于这样一个模型,想象一下:有一个在单CPU上运行的典型的单线程程序。它无需同步原语。现在,运行另一个这样的实例,它也无需同步。然后,让这两个实例进行通信。如果这样的通信
阅读全文 »

空白符(blank identifier) 在Go中,空白符可以被赋予/声明为任何类型的任何值,其值可以被无害丢弃。就像python中的空白符一样,它表示一个只写值,在那些需要变量,但是变量的真实值无关紧要的地方被用作占位符。 多重赋值中的空白符 如果某赋值的左边要求有多个值,但是其中一个值不会被程序所使用到,那么,在该赋值的左边放一个空白符,可以避免创建一个哑变量,并且可以更清晰地表明该值将被丢弃。例如: 1 2 3 4 // 下面调用中,只有err是重要的,因此使用空白符来丢弃无需用到的值 if _, err := os.Stat(path); os.IsNotExist(err)
阅读全文 »