『No14: Go 工程管理』

go-14.png
14.png

大家好绕沈,我叫謝偉,是一名程序員帮寻。

最近比較低效...

今天的主題:工程管理

為了寫出這一章節(jié)乍狐,我翻閱了幾本書。書中整理的很好固逗,但對(duì)初學(xué)者不太友好浅蚪,意思是可能看完就知道個(gè)大概。還是不能理解工程管理的具體做法是什么烫罩。所以惜傲,我呢,摒棄了書中的組織方式嗡髓,轉(zhuǎn)而使用示例的形式操漠,從頭到尾的把工程管理這事說明白收津。但是考慮到實(shí)際中的使用可能不太會(huì)事無巨細(xì)饿这。希望大家理解。

工程管理主要包括這兩方面內(nèi)容:Go 命令行工具的使用撞秋、工程項(xiàng)目的組織

當(dāng)然长捧,我們這邊使用一個(gè)例子來演示:爬蟲。

兩首頁的標(biāo)題信息抓取下來吻贿。

主要的概況如下:

  • 項(xiàng)目的組織
  • 項(xiàng)目庫第三方庫下載 go get / gopm get -g
  • 編寫代碼
  • 測試 go test
  • 覆蓋率 go tool
  • 編譯 go build
  • 編譯并運(yùn)行 go run
  • 編譯并生成二進(jìn)制文件 go install
  • 包管理 govendor / vgo
  • 文檔 godoc

整體的流程串结,大致和我們的開發(fā)息息相關(guān)。


1. 項(xiàng)目組織

我們第一節(jié)已經(jīng)見過舅列,我們的工程是如何進(jìn)行組織的肌割?

1、 設(shè)置 GOPATH
2帐要、 GOPATH 下設(shè)置三個(gè)文件夾:bin把敞、pkg、src

工程的組織即在src 目錄下創(chuàng)建文件夾榨惠。

比如:這個(gè)專題所有的項(xiàng)目都組織在 src/go-example-for-live 目錄下

├─go-example-for-live
│  ├─eight
│  ├─eleven
│  │  ├─infra
│  │  └─main
│  ├─fifteen
│  │  ├─download
│  │  ├─engine
│  │  ├─main
│  │  └─parse
│  │      ├─jianshu
│  │      └─v2ex
│  ├─five
│  ├─four
│  ├─fourteen_client
│  │  └─main
│  ├─fourteen_server
│  │  ├─main
│  │  └─ui
│  │      └─api-server
│  ├─Image
│  ├─MarkDown
│  ├─nine
│  │  ├─domain
│  │  ├─download
│  │  ├─engine
│  │  ├─infra
│  │  ├─main
│  │  ├─parse
│  │  │  └─gocn
│  │  ├─static
│  │  │  ├─css
│  │  │  ├─html
│  │  │  └─js
│  │  └─ui
│  │      ├─api-server
│  │      └─parse
│  ├─PowerPoint
│  ├─restful
│  ├─second
│  ├─seven
│  │  ├─download
│  │  ├─engine
│  │  ├─infra
│  │  ├─main
│  │  └─parse
│  │      └─github
│  ├─six
│  ├─ten
│  │  ├─app
│  │  ├─config
│  │  │  └─user-cfg
│  │  ├─ConfigResume
│  │  │  ├─1
│  │  │  │  └─Resume
│  │  │  └─2
│  │  │      └─Resume
│  │  ├─domain
│  │  │  ├─constants
│  │  │  ├─objects
│  │  │  └─roles
│  │  ├─infra
│  │  │  └─golang
│  │  │      ├─execadapter
│  │  │      ├─ioutiladapter
│  │  │      ├─jsonadapter
│  │  │      ├─osadapater
│  │  │      │  └─xiewei
│  │  │      └─yamladapter
│  │  ├─main
│  │  ├─ui
│  │  │  └─service
│  │  └─vendor
│  │      ├─github.com
│  │      │  └─olebedev
│  │      │      └─config
│  │      └─gopkg.in
│  │          └─yaml.v2
│  ├─thirteen
│  │  ├─infra
│  │  └─main
│  ├─three
│  ├─twelve
│  │  └─main
│  └─vendor
│      └─github.com
│          └─urfave
│              └─cli

工程組織...

2. 獲取第三方庫

  • go get
  • gopm get

如果我們使用內(nèi)置庫呢奋早,編寫代碼的使用盛霎,直接import 庫路徑即可。這個(gè)路徑是在設(shè)置的GOROOT 下的 src 目錄下的庫耽装。

GOROOT=D:\1_System\2_Installation\G_go

D:\1_System\2_Installation\G_go\src

Make.dist         bootstrap.bash  clean.bat  context   expvar  image         make.bash      nacltest.bash  race.bat  runtime  testing
all.bash          bufio           clean.rc   crypto    flag    index         make.bat       net            reflect   sort     text
all.bat           buildall.bash   cmd        database  fmt     internal      make.rc        os             regexp    strconv  time
all.rc            builtin         cmp.bash   debug     go      io            math           path           run.bash  strings  unicode
androidtest.bash  bytes           compress   encoding  hash    iostest.bash  mime           plugin         run.bat   sync     unsafe
archive           clean.bash      container  errors    html    log           naclmake.bash  race.bash      run.rc    syscall  vendor

那獲取第三方庫呢愤炸,我們之前已經(jīng)講過,使用 go 的命令行工具即可:

go get ****

比如掉奄, 我們爬蟲借助了第三方庫:

go get github.com/PuerkitoBio/goquery

如果下載速度太慢呢规个,我們可以使用這個(gè)工具,gopm姓建。

首先它也是go 的一個(gè)第三庫绰姻,首先需要下載 gopm

go get -u github.com/gpmgo/gopm

再使用 gopm 下載

gopm get ****

一個(gè)字:快

3. 編寫代碼和測試

  • download
  • parse
  • engine
  • main

好,經(jīng)歷前面的學(xué)習(xí)引瀑,項(xiàng)目組織會(huì)了狂芋,下載第三方庫也會(huì)了。就差會(huì)寫代碼了憨栽。

首先我們分析下需求:抓取信息帜矾。

  • 獲取網(wǎng)頁信息:http 請(qǐng)求,返回信息
  • 解析需要的信息:正則屑柔、xpath屡萤、css 等獲取網(wǎng)頁字段

核心大概就這兩點(diǎn),便可以完成任務(wù)掸宛。但是我還是建議新手死陆,在寫代碼之前都能有一套好的項(xiàng)目的組織。

好的項(xiàng)目組織有什么好處呢唧瘾?

可以參看下這個(gè)視頻:https://www.youtube.com/watch?v=MzTcsI6tn-0

我提幾點(diǎn):

1措译、養(yǎng)成好的項(xiàng)目組織風(fēng)格
2、更好的寫代碼
3饰序、更好的理解(讀)代碼

經(jīng)過上文的分析:我們項(xiàng)目組織成這樣(之前的文章也提到過):

下載器:即獲取網(wǎng)頁源代碼

download
   download.go
   download_test.go
package download

import (
    "errors"
    "net/http"

    "github.com/PuerkitoBio/goquery"
)

var (
    ErrRequest  = errors.New("request error")
    ErrResponse = errors.New("response error")
)

func GetHtmlResponse(url string) (*goquery.Document, error) {
    var (
        request *http.Request
        err     error
    )
    request, err = http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, ErrRequest
    }

    request.Header.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")

    var client *http.Client
    client = http.DefaultClient

    var response *http.Response
    response, err = client.Do(request)
    if err != nil {
        return nil, ErrResponse
    }

    defer response.Body.Close()
    return goquery.NewDocumentFromReader(response.Body)
}


解析器:即解析網(wǎng)頁信息

parse
   v2ex
       job_parse.go
       job_parse_test.go
    jianshu
       info_parse.go
       info_parse_test.go
package v2ex

import (
    "github.com/PuerkitoBio/goquery"
)

func JobParse(response *goquery.Document) []string {

    var title []string

    response.Find("div#Main div.box div.cell.item").Each(func(i int, selection *goquery.Selection) {
        text := selection.Find("table tbody tr td").Eq(2).Find("span a").Text()
        //fmt.Println(text)
        title = append(title, text)
    })
    return title
}

調(diào)度器:即調(diào)度下載器和解析器领虹,完成指定的網(wǎng)頁信息的解析

engine
   engine.go
   engine_test.go
package engine

import (
    "go-example-for-live/fifteen/download"

    "errors"
    "fmt"

    "github.com/PuerkitoBio/goquery"
)

type Request struct {
    Url       string
    ParseFunc func(*goquery.Document) []string
}

type Requests []Request

var (
    ErrDownload = errors.New("download err")
)

func Run(seeds ...Request) {
    var requests Requests
    for _, seed := range seeds {
        requests = append(requests, seed)
    }

    for len(requests) > 0 {
        r := requests[0]
        requests = requests[1:]

        body, err := download.GetHtmlResponse(r.Url)
        if err != nil {
            fmt.Println(ErrDownload)
            continue
        }
        fmt.Println(r.ParseFunc(body))

    }

}

程序入口:main.go

main
   main.go
package main

import (
    "go-example-for-live/fifteen/engine"
    "go-example-for-live/fifteen/parse/jianshu"
    "go-example-for-live/fifteen/parse/v2ex"
)

func main() {
    engine.Run(
        engine.Request{
            Url:       "https://www.v2ex.com/?tab=jobs",
            ParseFunc: v2ex.JobParse,
        },
        engine.Request{
            Url:       "http://www.reibang.com/u/58f0817209aa",
            ParseFunc: jianshu.InfoParse,
        },
    )
}

單元測試,我們不詳細(xì)列舉了求豫∷ィ可以使用傳統(tǒng)的方法也可以使用表格驅(qū)動(dòng)法,也可以使用第三方庫 GoConvey.

4. 運(yùn)行相關(guān)

  • go fmt
  • go build
  • go install
  • go run
  • go test
  • go tool

1蝠嘉、優(yōu)化代碼

go fmt ****
  • 調(diào)整語句位置
  • 調(diào)整縮進(jìn)
  • 調(diào)整花括號(hào)的位置
  • 調(diào)整空格等

2最疆、構(gòu)建
好,在上文我們編寫完代碼和測試用例之后蚤告,我們?nèi)绾伟殉绦蚍职l(fā)出去給別人使用的呢努酸?

go build

go build ****

根據(jù)庫的名稱自動(dòng)編譯出符合平臺(tái)的二進(jìn)制文件。

比如 在 main 目錄下

go build 

則目錄下自動(dòng)生存 main.exe 文件罩缴。運(yùn)行即可蚊逢。

main.exe

[應(yīng)屆生在深圳找不到工作求職DeweyLiuwinglight2016 [杭州][可遠(yuǎn)程] 一只公司招聘前端...

go install

如何你設(shè)置了GOBIN 层扶,即GOPATH 目錄下的bin 文件夾。

則運(yùn)行該命令烙荷,自動(dòng)會(huì)在 GOBIN 目錄下編譯出同文件的二進(jìn)制文件

# GOBIN
main.exe

go run

編譯后運(yùn)行镜会。即編譯完成后,立即執(zhí)行程序终抽。

go run main.go

好戳表。上文都是編譯和運(yùn)行相關(guān)的命令。那測試如何運(yùn)行昼伴?

go test

go test download_test.go 只運(yùn)行這一個(gè)測試文件

go test ./... 運(yùn)行整個(gè)項(xiàng)目下測試文件

λ go test ./...
ok      go-example-for-live/fifteen/download    1.436s
ok      go-example-for-live/fifteen/engine      0.701s
?       go-example-for-live/fifteen/main        [no test files]
ok      go-example-for-live/fifteen/parse/jianshu       0.690s
ok      go-example-for-live/fifteen/parse/v2ex  0.761s
go test -run=TestDownload -v  download_test.go 根據(jù)匹配規(guī)則運(yùn)行廁所文件內(nèi)的測試函數(shù)

go test -v ./... -cover

獲取測試代碼覆蓋率匾旭。

5. 包管理

  • govendor
  • vgo

項(xiàng)目中使用到了第三方庫,如果代碼分發(fā)出去圃郊,不把第三方庫文件置入項(xiàng)目中价涝,則他們不能使用,除非重新下載第三方庫持舆。

那么如何進(jìn)行庫或者包的管理色瘩?

  • govendor

1、下載 govendor
2逸寓、 項(xiàng)目下 govendor init
3居兆、govendor add +external

即將第三方庫拷貝至項(xiàng)目內(nèi)新建的目錄 vendor 下。

├─download
├─engine
├─main
├─parse
│  ├─jianshu
│  └─v2ex
└─vendor
    ├─github.com
    │  └─PuerkitoBio
    │      └─goquery
    └─golang.org

  • vgo

官方主推的工具竹伸,我還不太會(huì)用泥栖。

https://zhuanlan.zhihu.com/p/33926171

6. 文檔

  • godoc -http=:6060 -goroot="."

如果你寫的代碼注釋比較好,或者你go 官網(wǎng)上不去勋篓,僅僅只是想離線觀看 go 源代碼的文檔吧享。

godoc -http:=6060

本地訪問 localhost:6060 即可查看所有項(xiàng)目(包括內(nèi)置庫)的文檔。


有任何疑問生巡,可以查看所有工具的幫助文檔耙蔑。

  • go help
  • go tool help
  • govendor help
  • vogo help
  • gopm help

本節(jié)完,再會(huì)孤荣。

希望你們喜歡。我是謝偉须揣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盐股,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子耻卡,更是在濱河造成了極大的恐慌疯汁,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卵酪,死亡現(xiàn)場離奇詭異幌蚊,居然都是意外死亡谤碳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門溢豆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜒简,“玉大人,你說我怎么就攤上這事漩仙〈瓴纾” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵队他,是天一觀的道長卷仑。 經(jīng)常有香客問我,道長麸折,這世上最難降的妖魔是什么锡凝? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮垢啼,結(jié)果婚禮上私爷,老公的妹妹穿的比我還像新娘。我一直安慰自己膊夹,他們只是感情好衬浑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著放刨,像睡著了一般工秩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上进统,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天助币,我揣著相機(jī)與錄音,去河邊找鬼螟碎。 笑死眉菱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掉分。 我是一名探鬼主播俭缓,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酥郭!你這毒婦竟也來了华坦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤不从,失蹤者是張志新(化名)和其女友劉穎惜姐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椿息,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歹袁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年坷衍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片条舔。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡枫耳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逞刷,到底是詐尸還是另有隱情嘉涌,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布夸浅,位于F島的核電站仑最,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏帆喇。R本人自食惡果不足惜警医,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坯钦。 院中可真熱鬧预皇,春花似錦、人聲如沸婉刀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽突颊。三九已至鲁豪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間律秃,已是汗流浹背爬橡。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棒动,地道東北人糙申。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像船惨,于是被迫代替她去往敵國和親柜裸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • 1掷漱、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,982評(píng)論 3 119
  • 月餅甚多粘室,吃之. 久嚼生香,津液肆下卜范,餡油香而不膩,餅干酥而不硬鹿榜。 我不知道月餅這個(gè)東西是不是也和我的普通話一樣帶...
    大丑豬閱讀 378評(píng)論 0 0
  • 德國有一本非常出名的繪本《一生氣就大吼大叫的媽媽》海雪,是一只可愛的企鵝寶寶向我們講述了它和它媽媽之間的非凡經(jīng)歷锦爵。 “...
    孫瑞華閱讀 188評(píng)論 0 0
  • 用瑞士奶酪法來充分利用零碎時(shí)間。 1.嵌入式:當(dāng)人們從一線工作轉(zhuǎn)向另一項(xiàng)工作時(shí)奥裸,中間往往會(huì)出現(xiàn)一片空白地帶险掀,對(duì)于這...
    靜靜的葉子閱讀 166評(píng)論 0 0