Golang怪談

本文可以隨意轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)標(biāo)明作者和來(lái)源。

引子

本文題目凸顯一個(gè)‘怪’字,怪即為奇異,Go語(yǔ)言很多特點(diǎn)和特性可稱之為奇異,掌握了這些奇異之處,我們自然也就了解了Go語(yǔ)言的精髓。

概述

Go語(yǔ)言作為一門新時(shí)代的編譯語(yǔ)言,以排山倒海之勢(shì)迅速占領(lǐng)后臺(tái)服務(wù)開發(fā)陣地,在C++標(biāo)準(zhǔn)委員會(huì)急不可耐的把原本就極其復(fù)雜的C++語(yǔ)言用C++11變的更加復(fù)雜以后,作為面向過程、面向?qū)ο?、泛型編程語(yǔ)言的C++逐漸被追求最新技術(shù)的程序員所拋棄,而Go語(yǔ)言以其無(wú)比簡(jiǎn)單的語(yǔ)法,極其高效的運(yùn)行效率獲得了越來(lái)越多人的親睞,Go語(yǔ)言原生支持并發(fā)的特性使其在現(xiàn)今的并行計(jì)算時(shí)代更具有非凡意義。

本文主旨

本文主要通過簡(jiǎn)單的幾個(gè)例子的介紹,為讀者構(gòu)建一個(gè)Go語(yǔ)言的基本印象,本文不是Go語(yǔ)言教程,作者在這里僅用調(diào)侃的態(tài)度來(lái)給沒有接觸過Go語(yǔ)言的讀者提供一些Go語(yǔ)言特性的信息,希望在看到這些特性后,我能欣喜的看到有人可以捧起書真正進(jìn)入Go語(yǔ)言的世界。

第一怪:老朽偽裝小鮮肉

這么是說(shuō)誰(shuí)呢,其實(shí)呢,我去搜索Go語(yǔ)言介紹的時(shí)候,驚人的發(fā)現(xiàn)一個(gè)萌萌的年輕人坐在那里,然后我就以為這樣一個(gè)小鮮肉竟然發(fā)明了Go語(yǔ)言,真是“江山代有才人出,后浪死在沙灘上”。但是別急,再繼續(xù)搜索后我發(fā)現(xiàn),Go語(yǔ)言的創(chuàng)造者羅布·派克(Rob Pike)其實(shí)早就名聲斐然,出生于1965年的他并不年輕,他可是UTF-8設(shè)計(jì)者,同時(shí)羅布·派克跟Unix淵源極深,他和Ken Thompson以及 Dennis M.Ritche一起開發(fā)了Unix操作系統(tǒng),作為資深Geek,羅布·派克不忘在體育界刷存在感,他在1980年奧運(yùn)會(huì)上轉(zhuǎn)了一圈,拿了個(gè)射箭銀牌。閑著沒事他還在天文學(xué)那邊兒插一腳,真是程序員大師中的一朵奇葩。

萌rob.png

順便說(shuō)一句,由于Go語(yǔ)言在Google大行其勢(shì),原來(lái)的香餑餑Python之父吉多·范羅蘇姆(Guido Van Rossum) 于2012年底黯然離開谷歌加入到了Dropbox,這也暗示著python時(shí)代將要終結(jié),Go語(yǔ)言的時(shí)代正在到來(lái)。

老rob.png

第二怪:強(qiáng)迫癥晚期誰(shuí)來(lái)救

我們正式進(jìn)入到Go語(yǔ)言的世界,看看Go語(yǔ)言的一些特性,首先以一個(gè)例子開頭:

package main
import(
    "os"http://@1:先import進(jìn)來(lái),一會(huì)兒就發(fā)力
    "fmt"
)
func main()
{//@2:還是換個(gè)行吧,這樣看起來(lái)帥帥的
  x := 1//@3:我先占個(gè)座,一會(huì)來(lái)自習(xí)
  fmt.Println("我是第一個(gè)go程序")
}

這是我們的第一個(gè)例子,對(duì)于熟悉其他語(yǔ)言的人來(lái)說(shuō),這看起來(lái)是一個(gè)最正常不過的例子,但是其實(shí)這個(gè)例子中有三處語(yǔ)法錯(cuò)誤,你們先找茬,我先簡(jiǎn)單介紹一下Go語(yǔ)言的基本語(yǔ)法,文件開頭一般要命名一個(gè)包名(package),相同包名即是一家子,如果有package main即為主執(zhí)行程序,通過go install命令即可進(jìn)行安裝,生成可執(zhí)行二進(jìn)制,第二行的import說(shuō)明需要import的包,如果只有一行可以使用類似import "fmt"這種語(yǔ)法,這個(gè)程序的例子多個(gè)import括號(hào)方式會(huì)比較簡(jiǎn)潔,Go語(yǔ)言的函數(shù)是以func開始,局部變量使用:=運(yùn)算符時(shí),編譯器可以自動(dòng)推導(dǎo)出變量的類型。說(shuō)了這么多,我們?cè)摪颜Z(yǔ)法錯(cuò)誤指出來(lái)了,@1這一處錯(cuò)誤是因?yàn)?,在程序文件中,根本沒有使用os包的位置,由于其多余,Go語(yǔ)言強(qiáng)行定義其為語(yǔ)法錯(cuò)誤;@2這一處更加體現(xiàn)了羅布·派克強(qiáng)迫癥晚期患者的癥狀,他要求如第7行的大括號(hào)必須緊跟在main()的后面,否則就是語(yǔ)法錯(cuò)誤;@3和@1類似,這是變量級(jí)別的使用要求,不允許任何變量定義未使用。

羅布·派克定義了大量的規(guī)則用來(lái)保證程序員少犯錯(cuò),這大概是其見過太多C和C++過于自由的導(dǎo)致其難用的最痛的領(lǐng)悟吧。

第三怪:匿名字段真不賴

直接上例子:

package main
import "fmt"

type Human struct{
  name string
  age int
  weight int
}
type Student struct{
  Human //@1
  speciality string
}

func main(){
  mark := Student{Human{"Mark", 25, 120}, "e-commerce"}
  fmt.Println(mark.name, mark.age, mark.weight, mark.speciality)//@2
}

這個(gè)例子講的是Go語(yǔ)言中的struct,Go語(yǔ)言的struct和C++的class比較相似,但是你們可能會(huì)奇怪第@1行的Human是要鬧哪樣,你的對(duì)象呢,你的對(duì)象呢?其實(shí)這里就到Go語(yǔ)言中的匿名字段的神奇之處了。在講匿名字段之前,需要解釋個(gè)事情,Go語(yǔ)言變量命名方式是絕無(wú)僅有的奇葩,聰明的你應(yīng)該已經(jīng)發(fā)現(xiàn)了,這里面變量都是在類型前面,導(dǎo)致如果你給變量附初值時(shí)會(huì)出現(xiàn)var i int=8這種看起來(lái)很欠揍的語(yǔ)法,不過用習(xí)慣也就沒什么了,語(yǔ)言本身就是一堆規(guī)則,大師制定規(guī)則,碼農(nóng)按照規(guī)則拉磨。

我們言歸正傳,繼續(xù)講struct,匿名字段其實(shí)相當(dāng)于在Student使用Human類型時(shí),默認(rèn)編譯器將Human自動(dòng)展開,我們看第@2行即可以發(fā)現(xiàn)Human.name直接過繼給了Student,匿名字段就是可以把兒子變孫子,這種奇葩的事情羅布.派克不是首創(chuàng),咱們中國(guó)老祖宗唐德宗就有認(rèn)自己的孫子為兒子的事兒,這里面有啥八卦隱情這里不表,估計(jì)羅布.派克也不知道這事兒。有的人可能一定要問了,如果倆孫子重名可咋辦,萬(wàn)一孫子跟兒子重名不也亂套了么,這個(gè)你不用著急,如果發(fā)生這種情況,編譯器還是會(huì)及時(shí)發(fā)現(xiàn),星星還是那顆星星,兒子還是那個(gè)兒子,具體可以做實(shí)驗(yàn)去體驗(yàn)吧。

第四怪:interface你陷害

Go語(yǔ)言的interface可以說(shuō)是面向?qū)ο笤O(shè)計(jì)中極其巧妙的實(shí)現(xiàn),其隱含接口實(shí)現(xiàn)不但使得代碼簡(jiǎn)潔,同時(shí)內(nèi)容組織無(wú)與倫比的方便。繼續(xù)讀代碼說(shuō)話:

package main
import(
  "fmt"
  "math"
)
type geometry interface {
  area() float64
  perim() float64
}
type square struct{
  width, height float64
}
func (s square) area() float64{
  return s.width * s.height
}
func (s square) perim() float64{
  return 2*s.width + 2*s.height
}
type circle struct{
  radius float64
}
func (c circle) area() float64{
  return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64{
  return 2*math.Pi*c.radius
}
func measure(g geometry){
  fmt.Println(g)
  fmt.Println(g.area())
  fmt.Println(g.perim())
}
func main(){
  c := circle{radius:3}
  s := square{width:4.0, height:5.0}
  measure(c)
  measure(s)
}

這個(gè)例子略長(zhǎng),前面介紹的struct我們現(xiàn)在已經(jīng)熟悉了,重點(diǎn)看一下interface的定義和實(shí)現(xiàn)。我們可以看到一個(gè)geometry interface的定義,這個(gè)接口里定義了areaperim兩個(gè)方法。重點(diǎn)看一下成員函數(shù)的實(shí)現(xiàn)方法,Go語(yǔ)言成員函數(shù)與struct也是松耦合的,這里我們要重點(diǎn)關(guān)注的是括號(hào),以squarearea方法為例,我先看第一個(gè)括號(hào),我們把類型square s稱為這個(gè)方法接收者,其實(shí)就是C++的成員函數(shù)的不同表征方法,在python中,一般是用傳入self來(lái)實(shí)現(xiàn)的。第二括號(hào)才是方法自己的括號(hào),這里我們沒有帶參數(shù),最后一個(gè)float64是返回值類型,如果有多個(gè)返回值需要用括號(hào)括起來(lái)。那么問題來(lái)了,一個(gè)成員方法你最多可以看到多少括號(hào),其實(shí)可能不止三個(gè),但是會(huì)有三部分。

到此有人可能會(huì)問了,interface你陷害,你瞎掰吧,說(shuō)了這么多,還不說(shuō)陷害的事兒。我們言歸正傳,為什么說(shuō)interface陷害呢,因?yàn)橐粋€(gè)struct的方法只要實(shí)現(xiàn)了interface的方法組合,那么Go語(yǔ)言就認(rèn)為我們實(shí)現(xiàn)了這個(gè)接口,這中關(guān)聯(lián)是隱式的,也就是說(shuō),你寫了一個(gè)struct,實(shí)現(xiàn)了一堆方法,可能你就順便實(shí)現(xiàn)了另外一堆接口,這些接口可能連你都不知道。我們看measure方法定義,其接受的參數(shù)是一個(gè)geometry接口,可以直接傳入circlesquare對(duì)象,因?yàn)檫@兩個(gè)struct都實(shí)現(xiàn)了areaperim方法,那么他們就實(shí)現(xiàn)了geometry接口,這兩個(gè)struct啥都沒說(shuō),就被陷害說(shuō)他們實(shí)現(xiàn)了geometry接口。
實(shí)際上在fmt.Println接收的參數(shù)就是不定長(zhǎng)interface參數(shù)Stringer,其定義為:type Stringer interface { String() string },由此我們可以看出,只要你的struct實(shí)現(xiàn)了String方法,那么你就實(shí)現(xiàn)了Stringer接口,也就是說(shuō),這樣你就可以打印這個(gè)struct對(duì)象了,這有點(diǎn)兒類似Java中的toString,但是實(shí)現(xiàn)的優(yōu)雅程度就是云泥之別了。順便說(shuō)一句,所有的類型都實(shí)現(xiàn)了空接口interface{},也就是說(shuō),如果一個(gè)函數(shù)參數(shù)為空接口interface{}類型,那么這個(gè)函數(shù)可以接受任何參數(shù),這有點(diǎn)兒像C語(yǔ)言的void,但是Go語(yǔ)言要更加強(qiáng)大。

interface的設(shè)計(jì)是Go語(yǔ)言的神來(lái)之筆,使用過程中你會(huì)越來(lái)越體會(huì)到interface之精妙。

第五怪:加鎖啥的都狗帶

通過通信來(lái)共享內(nèi)存,而非通過共享內(nèi)存來(lái)通信,Go語(yǔ)言原生支持并發(fā),并通過goroutinechannel將并發(fā)編程的簡(jiǎn)潔性和高效性體現(xiàn)的淋漓盡致,我們?cè)僖膊挥脫?dān)心加鎖問題了,在程序員上空死鎖的陰云散去(其實(shí)還是會(huì)寫出死鎖的程序,具體可以查找相關(guān)聊),抬頭再看,并發(fā)編程一片晴空。我們以生產(chǎn)者消費(fèi)者問題舉例,我們會(huì)發(fā)現(xiàn)gorutine實(shí)現(xiàn)并發(fā)是怎樣一種優(yōu)雅:

package main
import "fmt"
import "time"
func producer(id int, item chan int) {
    for i := 0; i < 10; i++ {
        item <- i
        fmt.Printf("producer %d produces data: %d\n", id, i)
        time.Sleep(1*time.Second)
    }
}
func consumer(id int, item chan int) {
    for i := 0; i < 20; i++ {
        c_item := <-item
        fmt.Printf("consumer %d get data: %d\n", id, c_item)
        time.Sleep(1*time.Second)
    }
}
func main() {
    item := make(chan int, 6)//@1
    go producer(1, item)
    go producer(2, item)
    go consumer(1, item)
    time.Sleep(30 * time.Second)//等待其他goroutine都執(zhí)行完退出
}

我們看@1行,我們通過make語(yǔ)法建立了一個(gè)緩沖為6的int管道,生產(chǎn)者只需要關(guān)心生產(chǎn),把生產(chǎn)好的數(shù)據(jù)直接扔進(jìn)管道,消費(fèi)者呢,不用關(guān)心生產(chǎn)者的任何細(xì)節(jié),只需要從管道里取數(shù)據(jù),生產(chǎn)端和消費(fèi)端都是阻塞的,當(dāng)管道為空時(shí),消費(fèi)端阻塞,當(dāng)管道滿時(shí),生產(chǎn)端阻塞。關(guān)鍵字go定義我們新開了一個(gè)goroutine,每個(gè)goroutine你可以理解成線程,但是goroutine更加輕量和高效,一個(gè)程序起成千上萬(wàn)個(gè)goroutine毫無(wú)壓力。
我們剛剛看到有緩沖channel類似于消息隊(duì)列的神勇表現(xiàn),接下來(lái)我們看看無(wú)緩沖channel在多個(gè)goroutine同步的精彩演繹:

package main
import "fmt"
func fibonacci(c, quit chan int){
    x,y := 1,1
    for{
        select{
            case c<-x:
                x,y = y,x+y
            case <-quit:
                fmt.Println("quit")
                return
        }
    }
}
func main(){
    c := make(chan int)
    quit := make(chan int)
    go func(){
        for i:=0; i<10; i++{
            fmt.Println(<-c)
        }
        quit <-0
    }()
    fibonacci(c, quit)
}

我們這個(gè)程序用了一個(gè)select關(guān)鍵字,沒錯(cuò),這個(gè)select的作用跟網(wǎng)絡(luò)通信模型的select非常相似,select監(jiān)聽channel中的數(shù)據(jù)流,默認(rèn)select是阻塞的,當(dāng)管道中有發(fā)送或者接收行為時(shí),select才會(huì)執(zhí)行,當(dāng)有多個(gè)管道都準(zhǔn)備好時(shí),select會(huì)從中隨機(jī)取一個(gè)執(zhí)行,這個(gè)程序我們不需要用time.Sleep等待其他goroutine退出,在quit管道被寫入0之后,select偵測(cè)到,執(zhí)行case <-quit后程序退出。

Go語(yǔ)言并發(fā)編程有效利用多核CPU,把比thread更加輕量、高效的goroutine與管道相結(jié)合,極度優(yōu)雅的實(shí)現(xiàn)數(shù)據(jù)共享和同步,加鎖什么的確實(shí)可以狗帶了。

第六怪:靜態(tài)編譯沒依賴

動(dòng)態(tài)鏈接庫(kù)在計(jì)算機(jī)的蠻荒年代起了非常大的作用,那時(shí)的內(nèi)存還是論K的,硬盤是論M的,動(dòng)態(tài)鏈接庫(kù)可以在不同進(jìn)程間通過共享代碼來(lái)節(jié)省內(nèi)存,使用動(dòng)態(tài)鏈接庫(kù)編譯出的二進(jìn)制也非常小,這就使得磁盤空間使用和拷貝代價(jià)很低。但是動(dòng)態(tài)鏈接庫(kù)的缺點(diǎn)也是顯而易見的,甚至因?yàn)閯?dòng)態(tài)鏈接庫(kù)過于混亂產(chǎn)生了專門的名詞,相關(guān)性依賴地獄(dependence hell),不同程序之間的依賴讓無(wú)數(shù)程序員徹夜調(diào)試,而動(dòng)態(tài)鏈接庫(kù)給我們帶來(lái)的好處在今天看來(lái)實(shí)在是不值得的,它為我們節(jié)省的內(nèi)存和磁盤空間實(shí)在微不足道,動(dòng)態(tài)鏈接沖突導(dǎo)致的問題跟帶來(lái)的好處比起來(lái)就太大了,可以說(shuō),現(xiàn)在如果還抱著動(dòng)態(tài)鏈接庫(kù)不放就是丟西瓜撿芝麻完全是得不償失。

Go語(yǔ)言作者羅布·派克顯然也看到了這一點(diǎn),他的解決方案非常簡(jiǎn)單,二進(jìn)制不依賴任何動(dòng)態(tài)鏈接庫(kù),所有的編譯都是靜態(tài)鏈接,我們?cè)僖膊挥脫?dān)心換了一臺(tái)機(jī)器運(yùn)行程序無(wú)法執(zhí)行的問題了,這種做法只是損失了很少的內(nèi)存和磁盤空間,但是帶來(lái)整體性(integrity)的極大好處。

第七怪:編碼運(yùn)行真是快

有人把Go語(yǔ)言稱為21世紀(jì)的C語(yǔ)言,跟C語(yǔ)言相比,Go語(yǔ)言的運(yùn)行效率當(dāng)之無(wú)愧,但是如果把C語(yǔ)言的編碼效率與Go語(yǔ)言相比,C語(yǔ)言會(huì)被甩出好幾條街,可以這么說(shuō),Go語(yǔ)言是python和C的合體,它兼顧了C語(yǔ)言的運(yùn)行效率和python的編碼效率。Go語(yǔ)言的關(guān)鍵字只有25個(gè),Go語(yǔ)言的所有循環(huán)的寫法只有一個(gè)for把其他語(yǔ)言的while、foreach等一堆亂七八糟的命名整合成一個(gè),使用極其簡(jiǎn)潔。其運(yùn)行效率到底有多高呢,下圖是benchmarksgame網(wǎng)站上對(duì)比Go語(yǔ)言和C執(zhí)行不同算法執(zhí)行效率,除了個(gè)別算法運(yùn)行效率差別較大,大部分算法Go語(yǔ)言執(zhí)行效率跟C相差可以忽略不計(jì)。

2016-06-08 12_45_09-Go vs C gcc (64-bit Ubuntu quad core) _ Computer Language Benchmarks Game.png

我們這種對(duì)比雖然可能不一定公平,我們可以直觀上感受Go語(yǔ)言運(yùn)行的高效。

第八怪:異常處理沒有try

“作為現(xiàn)代編程語(yǔ)言一枚,try-catch都沒有,你還想讓我在編程界混么”,Go語(yǔ)言的內(nèi)心OS一定是這樣。現(xiàn)實(shí)是羅布·派克根本不想讓try-catch出現(xiàn),原因我們來(lái)看一段python代碼:

def main():
    try:
        check_filename()
        check_filesize()
        check_filelines()
        read_file()
    except:
        exit(1)
#endf main


if __name__ == "__init__":
    main()

可能有人會(huì)說(shuō),這代碼挺正常啊,出問題就退出唄,這么寫代碼的人真是被python給慣的太懶了,多少行代碼都能用一個(gè)try-catch給包起來(lái),根本不仔細(xì)考量到底可能會(huì)發(fā)生哪些異常,這些所謂的異??赡芨静皇钱惓?,曾經(jīng)見過在python有人用try-catch代替if-else來(lái)對(duì)類似于字段個(gè)數(shù)判斷處理,這種程序執(zhí)行結(jié)果是沒有錯(cuò),但是無(wú)論是執(zhí)行效率還是代碼可讀性以及代碼可維護(hù)性上都會(huì)有問題。羅布·派克強(qiáng)制讓編碼人員仔細(xì)考慮邏輯,對(duì)于可以預(yù)期的異常就不應(yīng)該用try-catch來(lái)處理,直接就是代碼處理邏輯分支,而不可預(yù)期的異常就應(yīng)該拋出來(lái),所以在Go語(yǔ)言中遇到數(shù)組越界程序就會(huì)直接painc程序退出,另外Go語(yǔ)言還有個(gè)recover機(jī)制,通過調(diào)用recover捕獲到panic的輸入值,恢復(fù)正常的執(zhí)行。

沒有try-catch機(jī)制實(shí)際上是對(duì)程序員的嚴(yán)格要求,這也是對(duì)程序的一種保護(hù)。panicrecover在使用時(shí)都應(yīng)該慎之又慎,作為程序員的我們最重要的是嚴(yán)謹(jǐn)?shù)目紤]代碼邏輯,盡量避免panic。

回顧

本文從8個(gè)不同角度介紹了Go語(yǔ)言的由來(lái)和設(shè)計(jì),它們分別是:

第一怪:老朽偽裝小鮮肉
第二怪:強(qiáng)迫癥晚期誰(shuí)來(lái)救
第三怪:匿名字段真不賴
第四怪:interface你陷害
第五怪:加鎖啥的都狗帶
第六怪:靜態(tài)編譯沒依賴
第七怪:編碼運(yùn)行真是快
第八怪:異常處理沒有try

總結(jié)

Go語(yǔ)言作者羅布·派克作為貝爾實(shí)驗(yàn)室Unix先驅(qū),看慣了各種編程語(yǔ)言刀光劍影、鼓角爭(zhēng)鳴,各種語(yǔ)言你方唱罷我登場(chǎng),它們雖然在一定程度上解決了之前使用語(yǔ)言的一些弊端,如C++語(yǔ)言把面向?qū)ο笠M(jìn),Java把設(shè)計(jì)模式發(fā)揚(yáng)光大,python使寫代碼接近自然語(yǔ)言,但是他們的時(shí)代畢竟要過去,Go語(yǔ)言簡(jiǎn)潔的語(yǔ)法,原生的并發(fā)支持,interface是精妙設(shè)計(jì)無(wú)一不顯示了作者對(duì)編程語(yǔ)言的全新的設(shè)計(jì)和理解,羅布·派克把我們帶入了一個(gè)新的編程語(yǔ)言世界,在這里,我們用簡(jiǎn)單嚴(yán)謹(jǐn)?shù)恼Z(yǔ)法書寫程序藝術(shù),而Go語(yǔ)言以其高效運(yùn)行來(lái)回報(bào)我們,生活在Go語(yǔ)言的世界里是程序員的幸福,用時(shí)下流行的話來(lái)說(shuō),用Go語(yǔ)言編程的人運(yùn)氣都不會(huì)太壞。

注:本文大部分代碼來(lái)自謝孟軍的《Go web編程》一書。

參考文獻(xiàn):

  1. Go web 編程
  2. 維基百科
  3. 酷殼-程序語(yǔ)言性能比拼
  4. golang并發(fā)編程之生產(chǎn)者消費(fèi)者模式
    ~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官方網(wǎng)站:https://golang.org/標(biāo)準(zhǔn)庫(kù)文檔:https://golang.org/pkg/在線編碼...
    技術(shù)學(xué)習(xí)閱讀 2,414評(píng)論 2 39
  • 能力模型 選擇題 [primary] 下面屬于關(guān)鍵字的是()A. funcB. defC. structD. cl...
    _張曉龍_閱讀 25,130評(píng)論 14 224
  • 控制并發(fā)有三種種經(jīng)典的方式,一種是通過channel通知實(shí)現(xiàn)并發(fā)控制 一種是WaitGroup,另外一種就是Con...
    wiseAaron閱讀 10,826評(píng)論 4 34
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,539評(píng)論 19 139
  • 今天朋友問我上海有什么好的,是呀,上海有什么好,以至于很多人來(lái)到這個(gè)城市,有的甚至愛上這座城市。坦白講,一開始來(lái)到...
    給我一只猴子閱讀 388評(píng)論 0 1

友情鏈接更多精彩內(nèi)容