Golang常見的坑和編程模式_第1頁
Golang常見的坑和編程模式_第2頁
Golang常見的坑和編程模式_第3頁
Golang常見的坑和編程模式_第4頁
Golang常見的坑和編程模式_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Golang中常見的坑與編碼模式劉奇新浪微博@goroutine與go一起的那些年2009相識(只是因為在人群中多看了go一眼,再也沒能忘掉go的容顏)2010-2011相知(紅塵之中知己難求,沙塵中呢?)2012相愛(帶刺的玫瑰)驚鴻一瞥為何偏偏愛上你良好的并發(fā)支持靜態(tài)鏈接簡潔直觀語言級的并發(fā)與自動化垃圾回收支持卓越的跨平臺支持Go語言的目標(理想是美好的)同時具備靜態(tài)語言的運行效率、動態(tài)語言的開發(fā)效率類型安全、內(nèi)存安全優(yōu)秀的并發(fā)與通信能力高效、無延遲的自動化垃圾收集高速編譯與靜態(tài)鏈接豐富、高質(zhì)量的包現(xiàn)實是湊合的Go是一門很二,很二的語言(是表揚,大家hold住雞蛋和西紅柿)成熟度不如erlang速度不如c,目前和java還有一點差距庫比不上java,python,c,cpp,nodejs簡潔不如ruby,python未來是美好的Golang正在快速進步庫越來越豐富性能越來越高Go的國學(xué)思維(中庸)幾乎每個方面都是第二陣營,所以玩鐵人三項才能拿冠軍(又一個小米手機?)所以成了集大成者那些年,那些坑總覺著踩到坑里了才算是真愛過有人說踩到的坑越多,愛得越深也有人說情越深,分得越快List的遍歷刪除錯誤寫法(簡潔,漂亮,但是。。。):fore:=l.Front();e!=nil;e=e.Next(){ l.Remove(e)}正確寫法varnext*Elementfore:=l.Front();e!=nil;e=next{ next=e.Next() l.Remove(e)}查找原因//看看具體實現(xiàn)代碼(container/list.go)func(l*List)remove(e*Element)*Element{ e.prev.next=e.next e.next.prev=e.prev e.next=nil//avoidmemoryleaks e.prev=nil//avoidmemoryleaks e.list=nil l.len-- returne}TimeFormatting/Parsingt:=time.Now()fmt.Println(t.Format("2006-01-02T15:04:05Z07:00"))親,記住了,只能用200601021504,別問我為什么,一個如此講究用戶體驗的好語言出現(xiàn)這個約束確實有點難以理解查找原因這里寫死了(time/format.go)const( ANSIC="MonJan_215:04:052006" UnixDate="MonJan_215:04:05MST2006" RubyDate="MonJan0215:04:05-07002006" RFC822="02Jan0615:04MST" RFC3339="2006-01-02T15:04:05Z07:00" ……)詳見nextStdChunk函數(shù)rangevalues:=[]string{"a","b","c"}for_,v:=rangevalues{ gofunc(){ fmt.Println(v) }()}輸出三個c,而不是順序的a,b,c查找原因values:=[]string{"a","b","c"}for_,v:=rangevalues{//(1) gofunc(){//(2) fmt.Println(v)

//隱式用v的地址傳遞 }()}(1)復(fù)用了臨時變量,只有一個臨時變量的空間(2)只是goroutine放到調(diào)度隊列,不是立刻運行,還要排隊先,等排到自己的時候,黃花菜已經(jīng)涼了解決方案for_,v:=rangevalues{gofunc(ustring){fmt.Println(u)}(v)//明確值復(fù)制,作為棧變量}類似的list:=make(map[int]*Link)

for_,lnk:=rangelinktree{

list[lnk.Code]=&lnk

}解決方案list:=make(map[int]*Link)

for_,lnk:=rangelinktree{

varlnk=linktree

list[lnk.Code]=&lnk

}Buildonce,runeverywhere?Buildonubuntu12.04(golangtipversion)Runoncentos5.6maypanic!未測試Golang1.1beta,目前還不穩(wěn)定,建議暫時不在生產(chǎn)環(huán)境使用原因Syscallnotmatch?解決方案UpdatecentoskernelOrbuildoncentos5.6Channel的喚醒時序當(dāng)多個channel都處于就緒狀態(tài)時,激活的channel是隨機的ATourofGo:A

select

blocksuntiloneofitscasescanrun,thenitexecutesthatcase.Itchoosesoneatrandomifmultipleareready切勿想當(dāng)然的認為先來后到queueGolang沒有直接的queue可以預(yù)期queue長度的情況下用channel無法預(yù)期長度是用list當(dāng)作隊列用也可以根據(jù)實際情況,將list作為channel的二級隊列(sometimesyoumayneedit)解決方案需要嚴格順序處理的都放入一個channel設(shè)計系統(tǒng)時需要仔細考慮時序的影響,特別是并發(fā)環(huán)境下讓人又愛又恨的GC愛她的輕柔和美麗:代碼看起來干凈,整潔恨她關(guān)鍵時刻停下來了:pauseonmarkingandsweeping,比如網(wǎng)游和人pk的時候,或者實時系統(tǒng),試想如果汽車剎車的時候剛好觸發(fā)gc,后果很嚴重原因原始的標記清掃算法,一次完成整個標記清掃過程,沒有分代(分生存期)。想想每天洗一件衣服和一周洗一次衣服的差別程序產(chǎn)生大量的臨時垃圾,引用關(guān)系復(fù)雜解決方案Golang1.1:已經(jīng)支持并行g(shù)c,有較大改善使用c模塊來管理內(nèi)存,c.malloc和c.freeObjectpool,bufferpoolGolang編碼模式驚艷的deferfuncFileOp(){f:=os.Open(file)deferf.Close()//writedata...}常用來做資源清理、關(guān)閉文件、解鎖、記錄執(zhí)行時間等Defer:來自標準庫io.pipe的例子func(p*pipe)read(b[]byte)(nint,errerror){ //Onereaderatatime. p.rl.Lock() deferp.rl.Unlock() p.l.Lock() deferp.l.Unlock()……}Defer:來自標準庫的例子sql.go

連接池資源管理ci,err:=db.conn()iferr!=nil{ returnnil,err}deferfunc(){//簡潔,優(yōu)雅 db.putConn(ci,err)}()……Defer:一句話給函數(shù)計時funcf(){ defertimeoutCheck(“xxslow”,time.Now())}functimeoutCheck(tagstring,starttime.Time){ dis:=time.Since(start).Seconds() ifdis>1{ log.Println(tag,dis,"s") }}Functiondesigntryingtoreturnerrorifyoucanfunc(nsNullString)Value()(driver.Value,error){ if!ns.Valid{ returnnil,nil } returnns.String,nil}讓import更美觀import( "encoding/json" "fmt" "net")而不是import"encoding/json"import"fmt"import"net"避免大對象的拷貝如果map的value較大,通常應(yīng)該使用指針來存儲,以避免性能問題,類似的還有channel,slice等避免[]byte和string的反復(fù)來回轉(zhuǎn)換AboutpanicAboutpanicPanicifandonlyifyoucan’thandleitWorkpoolfuncworker(jobs<-chanint,resultschan<-int){ forj:=rangejobs{ results<-xx }}forw:=1;w<=100;w++{

goworker(w,jobs,results)}Objectpool&bufferpool一個簡單的Connectionpoolfunc(p*ConnectionPool)InitPool(sizeint,fFactoryMethod){p.conn=make(chaninterface{},size)fori:=0;i<size;i++{p.conn<-f()}p.size=size}

func(p*ConnectionPool)Get()interface{}{ return<-p.conn }

func(p*ConnectionPool)Put(conninterface{}){p.conn<-conn}Connectionpool一個更加完善的例子/p/vitess/source/browse/go/pools/roundrobin.go來自youtube的開源項目vtoccgoroutineGoroutineischeap,notfree(每個goroutine約占用6k的內(nèi)存,實際代碼很容易達到15-30K)設(shè)計系統(tǒng)時要能預(yù)見并控制goroutine的總數(shù),必要時可以發(fā)放ticket來控制資源避免濫用goroutine,不合理的并行會帶來更多的bug,也讓問題難以復(fù)現(xiàn)和調(diào)試及時,批處理模式arr:=make([]int,8192)for{ select{ casex:=<-ch: //waitforfirstjob count:=1 arr[0]=x L: for;count<MAX;count++{ //checkifwecanhandlemore select{ casee:=<-ch: arr[count]=e default: breakL } } …… }}Gofmtyourcode通過http接口監(jiān)控程序import_"net/http/pprof“gofunc(){http.ListenAndServe("localhost:

6060",nil)}()隨時觀察程序狀態(tài)(goroutine,heap,thread)隨時可以profile程序(gotoolpprofhttp://localhost:6060/debug/pprof)來個素

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論