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

继续阅读...
062015
 

做过 Web 开发的,应该都用过或听过 jQuery,它提供了方便的操作 DOM 的 API。使用 Go 语言做服务器端开发,有时候需要解析 HTML 文件,比如抓取网站内容、写一个爬虫等。这时候如果有一个类似 jQuery 的库可以使用,操作 DOM 会很方便,而且,上手也会很快。github.com/PuerkitoBio/goquery 这个库就实现了类似 jQuery 的功能,让你能方便的使用 Go 语言操作 HTML 文档。 1 概述 Go 实现了类似 jQuery 的功能,包括链式操作语法、操作和查询 HTML 文档。它基于 Go net/html 包和 CSS 选择器库 cascadia。由于 net/html 解析器返回的是 DOM 节点,而不是完整的 DOM 树,因此,jQ

继续阅读...
032014
 

工作中碰到这样一个问题: 有一个文本文件,有上亿行数据,每行数据是 unsigned int。现在需要将其中可能重复的数只保留一个,同时和另外一个或多个这样的文件进行排重(即和它们做差集)。要求尽可能快的筛选出来。 开始实现比较简单粗暴,将数据直接通过 LOAD DATA INFILE 导入 MySQL 表中,然后多表之间做 LEFT JOIN。数据不是特别大,比如几千万,且就要排重的文件不多时,比如一个,速度还可以接受。然而,当数据上亿,且有多个文件需要排重时,性能急剧下降,必须进行优化。而这,正是 Bitmap 的应用场景。 1、Bitmap 概念 Bitmap 是一个十分有用的数据结构。所谓的 Bit-map 就是用一个 bit 位来标记某个元素对应的 Value,而 Key 即是该元

继续阅读...
132014
 

热爱Go语言,一直使用着、关注着。那么如何获取Go最新动态,使用它最新的特性能? 1、获取最新动态 获取Go语言的最新动态有以下几种方法。 1.1 最直接最原始的方式 —— 官方源码库(hg clone https://code.google.com/p/go/),即 tip。关注Go开发者们提交代码的注释、代码diff。 1.2 关注 golang-dev 讨论组。Go开发者会在这上面讨论Go语言的开发 1.3 关注 issues,以及代码review 1.4 通过 Go dashboard 了解 Go 某个版本的 issues 解决情况(链接最后修改为相应版本即可) 1.5 Go官方网站对应的 tip 版 1.6 关注国内 Go 社区的一些信息 2、使用最新特性 在新版本还未发布时,可能

继续阅读...
132014
 
Go语言:安装多版本

在开发或者自己学习Go的过程中,可能会对比不同版本Go语言的特性、性能等,特别是可能想提前用上tip版本的一些特性,这个时候,系统中可能需要多个Go版本。那么该如何处理这个问题呢? 一般地,我觉得有两种处理方法。 1、目录改名法 比如 Go 版本(go1.3)安装在 /usr/local/go 目录中,并配置了 GOROOT(GOROOT=/usr/local/go)和 PATH (PATH=$PATH:$GOROOT/bin),这时,我们想安装一个Go1.2版本,比如放在了 /usr/local/go1.2 中。 通常,我们都在使用 Go1.3,但某个时候,我们想使用 Go1.2,这个时候,可以将 /usr/local/go 改名为 /usr/local/go1.3,同时将 /usr/lo

继续阅读...
222014
 

1、cron 表达式的基本格式 用过 linux 的应该对 cron 有所了解。linux 中可以通过 crontab -e 来配置定时任务。不过,linux 中的 cron 只能精确到分钟。而我们这里要讨论的 Go 实现的 cron 可以精确到秒,除了这点比较大的区别外,cron 表达式的基本语法是类似的。(如果使用过 Java 中的 Quartz,对 cron 表达式应该比较了解,而且它和这里我们将要讨论的 Go 版 cron 很像,也都精确到秒) cron(计划任务),顾名思义,按照约定的时间,定时的执行特定的任务(job)。cron 表达式 表达了这种约定。 cron 表达式代表了一个时间集合,使用 6 个空格分隔的字段表示。 字段名 是否必须 允许的值 允许的特定字符 秒(Seco

继续阅读...