182017
 

介绍 Go 1.7,testing 包在 T 和 B 类型上引入了一个 Run 方法,允许创建子测试和子基准测试。子测试和子基准测试的引入可以更好地处理故障(failures),细化控制从命令行运行的测试,并行控制,并且经常会使代码更简单、更易于维护。 Table-driven 测试 在详细介绍之前,首先讨论在 Go 中编写测试的常用方法。 一系列相关验证可以通过循环遍历一系列测试用例来实现: 通常称为 table-driven(表格驱动) 测试,相比每次测试重复相同代码,减少了重复代码的数量,并且可以直接添加更多的测试用例。 Table-driven 基准测试 在 Go 1.7 之前,不可能使用相同的 table-driven 方法进行基准测试。 基准测试对整个函数的性能进行测试,因此迭代

继续阅读...
092017
 

排序算法是一种采用列表或数组并以特定顺序对其元素进行重新排序的算法。有几十种不同的排序算法,如果你已经学习了计算机科学,那么你至少熟悉了其中的一些算法。 它们也是很受欢迎的面试问题,所以在重要面试前不要因为它而伤心。 这是一个大多数常见的排序算法的小型引擎,实例采用 Golang 实现。 冒泡排序 冒泡排序是最基本的就地排序算法,几乎每个人都很熟悉。 它具有 O(n²) 最坏情况和平均时间复杂度,这使得它在大型列表中效率低下。它的实现非常简单。 在循环中,从第一个元素到第 n 个(n = len(items))迭代数组。比较相邻的值,如果它们的顺序错误,交换它们。 您可以通过在每次迭代后将 n 递减 1 来优化算法。 时间复杂度: * 最坏情况下:O(n²) * 平均情况下:O(n²) *

继续阅读...
062017
 

我是 Prometheus 的大粉丝。 我在家庭和工作中都使用了很多,并且非常喜欢深入了解我的系统在任何时刻的工作情况。 最广泛使用的 Prometheus 商家之一是 node_exporter:可以从类 UNIX 机器中提取各种指标的守护进程。 在我浏览仓库时,我注意到 open issue,要求向 node_exporter 添加 WiFi 指标。 这个想法吸引了我,我意识到我一定会在我的 Linux 笔记本电脑上使用这样一个功能。 我开始探索在 Linux 上检索WiFi 设备信息的选项。 经过几周的实验(包括旧版 ioctl() 无线扩展 API),我创作了两个 Go 包,它们可以共同工作,在 Linux 上与 WiFi 设备进行交互: * netlink:提供对 Linux ne

继续阅读...
202017
 

静态站点生成器是一种工具,给一些输入(例如,markdown),使用HTML,CSS和JavaScript生成完全静态的网站。 为什么这很酷?一般来说,搭建一个静态网站更容易,而且通常运行也会比较快一些,同时占用资源也更少。虽然静态网站不是所有场景的最佳选择,但是对于大多数非交互型网站(如博客)来说,它们是非常好的。 在这篇文章中,我将讲述我用Go写的静态博客生成器。 动机 您可能熟悉静态站点生成器,比如伟大的Hugo,它具有关于静态站点生成的所有功能。 那么为什么我还要来编写另外一个功能较少的类似工具呢? 原因是双重的。 一个原因是我想深入了解Go,一个基于命令行的静态站点生成器似乎是磨练我技能很好的方式。 第二个原因就是我从来没有这样做过。 我已经完成了平常的Web开发工作,但是我从未创

继续阅读...
182017
 

Go 标准库有一个 expvar 包。 该软件包可以通过 JSON 格式的 HTTP API 公开您的应用程序和 Go 运行时的指标。 我认为这个软件包对于每个人 gopher 来说都是有用的。 但是,来自 godoc.org 的数据表明,没有多少人知道这个包。截止目前(2017-6-18),该包被公开的项目 import 2207 次,相比较而言,连 image 包被 import 3491 次之多。这篇文章,我想展示 expvar 包的工作原理,以及它的使用。 包简介 包 expvar 为公共变量提供了一个标准化的接口,如服务器中的操作计数器。它以 JSON 格式通过 /debug/vars 接口以 HTTP 的方式公开这些公共变量。 设置或修改这些公共变量的操作是原子的。 除了为程序增

继续阅读...
062017
 

如何同时提高一个软件系统的可维护性(Maintainability)和可复用性(Reuseability)是面向对象的设计要解决的核心问题。 面向对象设计中,设计模式被提及的比较多,然而,大家对在设计模式背后、更深层的、更具有普遍性的、共同的思想原则提及却较少。但它们是比设计模式本身更加基本和单纯的设计思想。 面向对象的设计原则包括:“开-闭”原则(OCP)、里氏代换原则(LSP)、依赖倒转原则(DIP)、接口隔离原则(ISP)、合成/聚合复用原则(CARP)、迪米特法则(LoD)。 这些面向对象设计原则是提高软件兄的可维护性和可复用性的指导性原则。在有现成的设计模式的地方,设计模式就是这些设计原则在具体问题的体现;在没有现成的设计模式的地方,这些设计原则也一样适用,同样可以对系统设计发挥指

继续阅读...
092016
 

本文介绍 Unix I/O 模型中的4个通用系统调用:open()、read()、write()和close() 的 Go 语言封装。 1、Linux 中 open 系统调用的定义 2、Go 中 open 系统调用的封装 一般的,我们使用 os 标准库的 Open/Create 方法来间接调用 open 系统调用,跟踪代码,找到 Go 中 open 系统调用的封装: 2.1 openat 又是什么呢? 从 2.6.16 (Go 支持的 Linux 版本是 2.6.23)开始,Linux 内核提供了一系列新的系统调用(以at结尾),它们在执行与传统系统调用相似任务的同时,还提供了一些附加功能,对某些程序非常有用,这些系统调用使用目录文件描述符来解释相对路径。 可见,openat 系统调用和 o

继续阅读...
082016
 

一、系统调用概述 系统调用是受控的内核入口,借助于这一机制,进程可以请求内核以自己的名义去执行某些动作。Linux 内核以 C 语言语法 API 接口形式(头文件),提供有一系列服务供程序访问。可以通过 man 2 syscall 查看系统调用信息。 关于系统调用,需要注意以下几点: 1、系统调用将处理器从用户态切换到核心态,以便 CPU 访问受到保护的内核内存; 2、系统调用的组成是固定的,每个系统调用都由一个唯一的数字来标识; 3、每个系统调用可辅之以一套参数,对用户控件(进程虚拟地址控件)与内核空间之间(相互)传递的信息加以规范; 以C语言为例,执行系统调用时,幕后会历经诸多步骤。以 x86-32 平台为例,按时间发生顺序对这些步骤加以分析: 1、应用程序通过 C 语言函数库中的外壳(

继续阅读...
142016
 

用过PHP的人都知道,PHP处理JSON数据那是相当方便,json_encode和json_decode两个函数搞定一切。那么在Go中该怎么处理JSON呢? 一、encoding/json标准库 学习 json 库应该先了解 Go 中的 struct tag、reflect等知识。 1、概述 json包实现了json对象的编解码,参见RFC 4627。Json对象和go类型的映射关系请参见Marshal和Unmarshal函数的文档。 参见”JSON and Go”获取本包的一个介绍:http://golang.org/doc/articles/json_and_go.html 这是官方的一篇博文。 2、核心函数和类型 对于函数和类型,我们关注经常使用的。 1)Mar

继续阅读...
132015
 
curl https 返回 errno 35(ssl connect error) 错误

微信支付获取 prepay id 偶尔失败问题总结。 微信支付会要求先从微信服务器获取 prepay id (https://api.mch.weixin.qq.com/pay/unifiedorder)。我们开发完成后(语言是PHP,使用微信的支付SDK,请求时使用curl),在测试环境的机器上,基本没有发现请求失败的情况,上线后,却发现经常出现错误,概率1/5甚至更高。开始没有深究原因,采用重试的方式,不过发现,只要失败了,重试也会失败。 记录下 curl 的错误是:errno:35, error: SSL Connect Error。 网上查相关资料,没有找到解决方案。联系微信技术支持,他们没有任何建议,觉得是我们的问题,让我们自己查。 在我们服务器上通过 tcpdump 抓包:tcp

继续阅读...