Yifei Kong

Jul 15, 2018

Go语言读写文件相关函数对比

文件 IO

io.Readerio.Writer。这两个是两个特别重要的 interface。一般来说凡是可以抽象为输入的 IO 操作都会使用 io.Reader。凡是可以抽象为输出的 IO 操作都会使用 io.Writer。

io/ioutil

对于配置文件等等比较小的常规文件,一般来说我们可以使用 io/ioutil 包中的辅助函数操作就好了,比较快捷方便。

函数签名 说明
func NopCloser(r io.Reader) io.ReadCloser 把 io.Reader 包装成一个 io.ReadWriter
func ReadAll(r io.Reader) ([]byte, error) 读取所有字符 …

Jul 15, 2018

Go语言处理 CSV 文件

在 Go 语言中可以使用 encoding/csv 包来处理 csv 文件。

csv 包中主要有两个 struct,Reader 和 Writer。Reader 从一个 io.Reader 中读取每一行的内容,同时提供了一些设置的选项。Writer 用来写入 csv 文件。

Reader

r := csv.NewReader(strings.NewReader(in))

for {
    record, err := r.Read()
    if err == io.EOF {
        break
    }
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(record …

May 02, 2018

Go 语言初体验

安装

安装 go 很简单,在 mac 上直接使用 brew install go 就可以了。注意的是需要设定GOPATH这个环境变量,这里设定到了 ~/.go 这个目录。

export GOPATH=$HOME/.go

语法和风格

Golang的整个语法还是极其简单的,基本是 C 和 Python 的混合体。Go 语言详尽地规定了代码的风格,所以就不用为了大括号究竟是放在哪儿而开始圣战了。Go 语言对程序员的约束很强,不容易犯错

Go 语言官方提供了一个工具 goimports 用来管理 import 语句,还不错。

比如import进来的包必须使用,声明的变量也必须使用。import 语句必须在 package 语句后面.虽然有大括号,但是大括号的位置也是指定的。

类型

几乎所有的值提供了默认都会初始化到对应的零值,即使没有初始化 …

Apr 29, 2018

Python coroutine 以及和 Goroutine 的对比

Python 中的 coroutine

Python 3.5 中终于引入了 asyncawait 关键字,算是在语言层次上支持了 coroutine。

coroutine 基础

coroutine 又被称为用户级线程,也就是可以在一个系统线程中模拟多个线程构成的并发操作,对于有 GIL 的 Python 来说,反正线程也是费了,不失为多了一种选择,使用 asyncio 来爬取网页可以这样写:

首先,pip install pulsar lxml。pulsar 是一个异步版的 http 库。

import asyncio
from pulsar.apps import http

client = http.HttpClient()

async def fetch …

Apr 09, 2018

Go 语言和爬虫

爬虫的算法

广度遍历

如果把每一个页面看做一个节点,把每个链接看做一个有向边,那么网页之间就构成了一个有向图。爬虫的核心就是对这个图做一个广度优先的遍历:

func breadthFirst(visit func(item, string) []string, worklist []string) {
    seen := make(map[string]bool)
    for len(worklist) > 0 {
        items := worklist
        worklist = nil
        for _, items := range items {
            if !seen[item] {
                seen[item] = true
                worklist = append(worklist, visit(item)...)
            }
        }
    }
}

终止条件

如果我们面对的是一个有限的图,那么用广度遍历一定可以停下来。但是对于互联网来说,甚至于对于某个网站来说,页面的数量都可能是无限的 …

Apr 04, 2018

Go 语言数据库教程

在学习 Go 的过程中重新思考了数据库相关的一些知识,之前认为数据库的驱动就是应该有一个 conn 对象表示连接, 然后再有一个 cursor 对象来具体操作。但是 Go 完全没有这么来,而是直接生成一个 db 对象来操作,开始觉得不适应,然而后来我也实在想不起来为什么需要用两个对象了。

另外,为什么要用 ORM 呢?之前用 Django 的ORM比较多,因为生成后台非常方便,而且自己对 SQL 也不是很熟悉,对数据库的操作基本上都在使用这个ORM。然而,现在感觉到如果想要自己的代码性能比较高的话,自己手工写 SQL 几乎是不可避免的,而且 SQL 其实也没有那么吓人。

Go语言中的 database/sql 包提供了一个数据库的访问接口,但是对于不同的数据库,还需要不同的驱动。

一些常见的数据库的驱动参见这里:http://golang.org/s/sqldrivers。

连接数据库 …