golang--2016gopher北京大会(2)

三、七牛老许

qlang: github qiniu/qlang

microservice architecture: http://martinfowler.com/articles/microservices.html

Service Governance

  • Authorization
  • Logging
  • Change management
  • Central configuration
  • Scale in and scale out
  • Overload Protection
  • Service degradation
  • Monitor performance and health
  • Manage how and by whom services are used 
  • Topology discovery and failure recovery

Overload Protection

  • N = Alert threshold
  • Important things
  • keep limit to N*2,not N
  • kill slow requests(SLA)

 

四、Dave Cheney 澳洲golang社区负责人,运行悉尼go用户组

http://dave.cheney.net/

Further reading: runtime/pprof

Further reading: Google Perf Tools

  • pprof

-memprofilerate=N adjusts the profile rate to 1/N

#visualise mem profile
go build -gcflags='-memprofile=/tmp/m.p'
go tool pprof --alloc_objects -svg $(go tool -n compile) /tmp/m.p > alloc_objects.svg
go tool pprof --inuse_objects -svg $(go tool -n compile) /tmp/m.p > alloc_objects.svg
  •  benchmarking
#fib.go:
func Fib(n int) int {
    if n<2 {
        return n
    }
    return Fib(n-1)+Fib(n-2)
}
#fib_test.go:
import "testing"
func BenchmarkFib(b *testing.B) {
    for n:=0;n<b.N;n++ {
        Fib(20)
    }
}
#go test -bench=. ./fib
    • do benchmark multiple times or use "-count=" flag
    • tools like rsc.io/benchstat are useful for comparing results
go test -bench=. -count=5 ./fib> old.txt 
go test -bench=. -count=5 ./fib |tee new.txt 
benchstat old.txt new.txt
benchstat {old,new}.txt
    •  how fast will this bench? I think it's super fast! 
package popcnt

import "testing"

const m1 = 0x5555555555
const m2 = 0x33333
const m4 = 0x0f0f0f
const h01 = 0x0101010101

func popcnt(x uint64) uint64 {
	x -= (x >> 1) & m1
	x = (x & m2) + ((x >> 2) & m2)
	x = (x + (x >> 4)) & m4
	return (x * h01) >> 56
}
func benchmarkPopcnt(b *testing.B) {
	for i := 0; i < b.N; i++ {
		popcnt(uint64(i)) //optimied away
	}
}
#go test -bench=. ./popcnt
    • 但是被优化没有效果,要改为如下才有bench的效果
#change it to this:
var result uint64
func benchmarkPopcnt(b *testing.B) {
    var r uint64
    for i:=0;i<b.N;i++ {
        r = popcnt(uint64(i))
    }
    result=r
}
    • 自己测试还是没效果,不知道为什么
  •  CPU profile
go test -run=XXX -bench=IndexByte -cpuprofile=/tmp/c.p bytes
go tool pprof bytes.test /tmp/c.p
#note: -run=XXX to disable test,you only need benchmark
  • godoc
cd godoc
golang.org/x/tools/cmd/godoc
vim main.go
   add one line in main--defer profile.Start().Stop()
   then exec in vim:GoImports
go install -v .
godoc -http=9000
open browser and open localhost:9000
go tool pprof $(which godoc) /var/...cpu.pprof
  •  enable output of GCloggin
env GODEBUG=gctrace=1 godoc -http=:8080
  • import net/http/pprof package will register a handler at /debug/pprof and default http.serveMux

it will visible if you use http.listenSndServe(adress,nil)

godoc -http:=8080,show /debug/pprof
  •  some slice and string translate...

五、晚场辩论

rust-lang.org

//GO
err := f(x)
if err != nil {
    retrun err;
}

//Rust
try!(f(x));
f(x)?

 一个关于冗长与magic的讨论

六、原射手CEO

gomobile和动态库的使用

 

七、米嘉

github.com/mijia/gobuildweb

github.com/mijia/web-starter-kit

@fswatch $(GO_FILES) $(TEMPLATES) | xargs -n1 -l{} make restart ||make kill
  • chubby--at the heart of google
  • go Proverbs: simple,Poetic,Pithy,no magic,composing,interface,adaptor
  • request --> onion --> response
  • basiclly we put a lot of things inside handler: like  parse request,query db,user auth, CRUD model objects, biz logic, then render the result to response xml,json etc. or panic/error.

  • go web packages:

dozens of frameworks

julienschmidt/httprouter

codegangstar/negroni

www.gorillatoolkit.org

  • go generate according to database scheme

github.com/mijia/modelg 

  • go benchmark

load_test.go//测试1000000LRUcache

package demo1

import (
    "fmt"
    "testing"
    "time"
)

//TestPutPerf load tests
func TestPutPerf(t *testing.T) {
    fmt.Printf("load testing on 1M size cache\n")
    size := 1000000
    cache := newLRUCache(size)
    start := time.Now()
    for i,td := range testData {
        if i%10000 == 0 {
            end := time.Now()
            fmt.Printf("Num: %d, Used time: %v\n", i, end.Sub(start))
            start = end
        }
        cache.Put(td.url,td.body)
    }
}

 

go test -c
./demo1.test -test.run=Perf
//lru_cache_test.go
package demo1
import (
    "fmt"
    "testing"
)

type testDataType struct {
    url string
    body string
}

var testData []testDataType

const testDataSize = 10000100

func init () {
    testData = make([]testDataType, testDataSize)
    for i:= 0; i< testDataSize; i++ {
        url := fmt.Sprintf("www.fake.com/%d",i)
       testData[i] = testDataType {
            url: url,
            body: fmt.Sprintf("This is page <b>%s</b>!",url),
       }
    }
}

func TestBasics(t *testing.T) {
    cache := newLRUCache(2)
    cache.Put("1","1")
    cache.Put("2","2")
    res, ok := cache.Get("1")
    if !ok := || res != "1" {
        t.Errorf("unexpected!")
    }
    cache.Put("4","4")
    if _, ok := cache.Get("2");ok {
        t.Errorf("unexpected")
    }
}

//go tool pprof
func BenchmarkCacheFull1KSize(b *test.B) {
    benchmarkCacheFull(b,1000)
}
func BenchmarkCacheFull1MSize(b *testing.B) {
    benchmarkCacheFull(b,1000000)
}
func benchmarkCacheFull(b *testing.B, size int) {
    cache := newLRUCache(size)
    for i :=0;i<size;i++ {
        cache.Put(testData[i].url,testData[i].body)
    }
//两个Put之间有noise必须先做profiling,
//go tool pprof demo1.test prof.out -->#web
    f, _ := os.Create("prof.out")
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()
//先填满,之后测试每push 一个item需要多长时间
    b.ResetTimer()
    for i :=0; i< b.N; i++ {
        c:=(i+size) % testDataSize
        cache.Put(testData[c].url, testData[c].body)
    }
}

//demo2
//go test -v . -run XXX -bench Mill
//./demo2.test -test.run XXX -test.bench Milli -test.cpuprofile=prof.out
//go tool pprof demo2.test prof.out --> web

 

./demo1.test -test.run=xxx -test.bench Full
#./demo1.test -test.run=xxx -test.bench Full -test.cpuprofile=prof.out 这是不准确的,因为有很多noise,用上面方法

 

 

八、Marcel van Lohuizen -- Google Go team

golang.org/x/text 实现

  • I18n and L10n 国际化与本地化

搜索排序,大小写,双向文本,注入翻译,数字货币,日期,单位转换

  • Go uses UTF-8
const beijing="北京市"
for index,runeValue :=range beijing {
fmt.Printf("%#U 从第%d字节开始\n",runeValue,index)
}
//北从0,京从3,市从6
  • 文本的序列本质
const flags="🇪🇭🇹🇻" //国家代码mc+nl
fmt.Println(flags[4:])
  • Transformer 接口
type Transformer interface {
    Transform(dst,src []byte, atEOF bool) (nDst, nSrc int, err error)
    Reset()
}
  • Normalization 以NFC格式向w写入文本流

norm.NFC.Writer(w) 

  • 不同语言不同大小写算法
toTitle:=cases.Title(language.Dutch)
fmt.Println(toTitle.String("'n ijsberg"))
//'n IJsberg
  •  多语言搜索与排序

e<ℨ<f

ª==aa

search

m:search.New(language.Danish,search.IgnoreCase,search.IgnoreDiacritics)
start,end:=m.IndexString(text,s)
match:=s[start:end]
  •  collate Example
import (
"fmt"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)

func main () {
  a:=[]string("北京市","上海市","广州市")
  for _,tag := range []string{"en","zh","zh-u-co-stroke"} {
    collate.New(language.Make(tag)).SortStrings(a)
    fmt.Println(a)
  }
}

// 上 北 广;北广上;上广北

 语言匹配

import (
 "http"
 "golang.org/x/text/language"
)

var matcher = language.NewMatcher([]language.Tag{
    language.SimplifiedChinese,
    language.AmericanEnglish,
})

func handle(w http.ResponseWriter, r* http.Request){
    prefs,_,_:=language.ParseAcceptLanguage(r.Header.Get("Accept-Languge"))

    tag,_,_:=matcher.Match(prefs...)
    //use tag: it includes carried over user preference
}

 在代码中插入翻译结果

import "golang.org/x/text/message"
message.SetString(language.Dutch,"%s went to %s","%s is in %s geweest.")
message.SetString(language.SimplifiedChinese,"%s went to %s","%s 去了 %s ")

 

  • 参考

godoc.org/golang.org/x/text

blog.golang.org/matchlang

blog.golang.org/normalization

blog.golang.org/strings

golang.org/issue

 

九、毛剑--bilibili

bfs分布式小文件存储: github.com/Terry-Mao/bfs

基于facebook Haystack Paper 

  • 核心:proxy、directory、pitchfork、store
  • 运维:ops
  • 依赖:Hbase用户数据 zookeeper元数据
  • 流量走向 proxy->directory->store

 

十、李炳毅--百度

if r<= 0x7F {
    switch 
    case '0' <= r && r <= '9':
        return false
    case 'a' <= r && r <= 'z':
        return false
    case 'A' <= r && r <= 'Z':
        return false
    case ==
        return false
    return true
}
if unicode.IsLetter(r) || unicode.IsDigit(r) {
    return false  
}

 

十一、TiDB PingCAP创始人

  • 1.interface 性能问题
var val interface{}
val = int64(10)

把整形赋值给interface会触法一次内存分配,会有一个数量级的开销

var d Datum
d.SetInt64(10)

换成struct提升10倍以上

  • 2.Protobuf Go默认实现性能低,推荐gogo替代
  • 3.跨数据中心复制,Raft(Port from etcd) 作者Diego Ongaro。相对multi-paxos简单成熟稳定

 

十二、陈辉-人工智能初创公司

  • 1.悟空搜索:github.com/huichen/wukong

主协程,用于收发用户请求。分词器协程,负责分词。索引器协程,负责查找索引。排序器。

package  main
import (
"github.com/huichen/wukong/engine"
"github.com/huichen/wukong/types"
"log"
)

var(
//searcher是协程安全的
searcher = engine.Engine{}
)

func main() {
searcher.Init(types.EngineInitOptions{SegmentedDictionaries:"github.com/huichen/wukong/data/dictionary.txt"})
defer searcher.Close()

searcher.IndexDocument(0,types.DocumentIndexData{Content: " XXXXX"})
searcher.IndexDocument(1,types.DocumentIndexData{Content: " XXXXX"})
searcher.IndexDocument(2,types.DocumentIndexData{Content: " XXXXX"})

searcher.FlushIndex()

log.Print(searcher.Search(types.SearchRequest{Text:"XX"}))

}

 基于悟空搜索的计算技术 AHA: Ad Hoc Analytics引擎

github.com/huichen/aha

  • 2.sego分词:huichen/sego
package main

import (
"fmt"
"github.com/huichen/sego"
)

func main() {
//dictionary
var segmenter sego.Segmenter
segmenter.LoadDictionary("github.com/huichen/sego/data/dictionary.txt")

//分词
text := []byte("北京市东城区XXXX")
segments := segmenter.Segment(text)

//处理分词结果
fmt.Println(sego.SegmentsToString(segments,false))

}

 Double-Array Trie实现是一般Trie两倍效率

github.com/adamzy/cedar-go

  •  3.弥勒佛机器学习:huichen/mlf

监督式学习:最大熵分类模型,决策树模型

非监督式学习:聚类问题

在线学习:在线梯度递降模型

神经网络:Restricted Boltzmann machine

var (
libsvm_file = flag.String("input","","libsvm格式数据文件,训练数据")
model = flag.String("model","model.mlf","写入的模型文件")

//机器学习参数
learning_rate = flag.Float64("learning_rate",0.01,"学习率")
batch_size = flag.Int("batch_size",100,"梯度递降法的batch尺寸:1为stochasitic,其它值为mini batch")
delta = flag.Float64("delta",1e-4,"权重变化量和权重比值,dw/w 的绝对值,小于此值为收敛")
maxIter = flag.Int("max_iter",0,"优化器最多迭代多少次")
hidden = flag.Int("hidden",10,"多少个隐藏单元")
numCD = flag.Int("cd",1,"CD次数")
useBinary = flag.Bool("binary_hidden",true,"是否使用抽样隐藏单元")
)

 

代码over,郑重声明:部分代码已测试, 但以上代码均不保证可运行,不保证无错误,并仅用于总结演讲ppt。

 

posted @ 2016-04-25 00:06  zzuse  阅读(663)  评论(0编辑  收藏  举报