vint--针对int型的压缩格式

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 vint是lucene所采用的针对int型的压缩方法。 对于绝大多数语言,int型都占4个字节,不论这个数据是100、1000、还是1000,000。vint的理念是采用可变长的字节,来表示一个整数。数值较大的数,使用较多的字节来表示,数值较少的数,使用较少的字节来表示。 2. vint的格式定义 A variable-length format for positive integers is defined where the high-order bit of each byte indicates whether more bytes remain to be read. The low-order seven bits are appended as increasingly more significant bits in the resulting integer value. Thus values from zero to 127 may be stored in a single byte, values from 128 to 16,383 may be stored in two bytes, and so on. ...

June 2, 2018 · 2 min

float型/int型数据和底层2进制表示互转

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 引言: 因为需要打印float型/int型二进制表示 这里封装了几个函数,方便日后使用。 struct_utils.py import struct def type2bin(num, fmt): ll = [bin(ord(c)) for c in struct.pack(fmt, num)] res = [] for item in ll: res.append(item.replace('0b', '').rjust(8, '0')) return ''.join(res) def bin2type(bits, fmt): return struct.unpack(fmt, struct.pack(fmt, int(bits, 2)))[0] def float2bin(num): return type2bin(num, '>f') def bin2float(bits): return bin2type(bits, '>f') def int2bin(num): return type2bin(num, '>i') def bin2int(bits): return bin2type(bits, '>i') def long2bin(num): return type2bin(num, '>q') def bin2long(bits): return bin2type(bits, '>q') if __name__ == '__main__': res = float2bin(5.5) print res res = bin2float(res) print res print '-----------------' res = int2bin(345) print res res = bin2int(res) print res print '-----------------' res = long2bin(345) print res res = bin2long(res) print res 请我喝瓶饮料

May 30, 2018 · 1 min

推荐点golang入门资料

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 一个大学同学在微信上发消息问我,有没有Golang入门的资料 1. 书籍 Golang入门书的话,对于有一定开发经验的我觉得 beego的作者的谢孟军 电子书地址 书名:《Go Web 编程》 推荐理由: golang入门书籍。作者是beego的作者的谢孟军,他的golang入门介绍很实用,并且谈了不少web开发中的技术要点 2. 开源项目 使用Golang很大程度就是为了高性能,所以必须要对性能这块格外关注 这里推荐几个开源项目 2.1 fasthttp valyala/fasthttp 高性能web框架,了解web框架的不二出路,号称相比官方库有10倍性能提升 关键词: 协程池 2.2 nsq nsqio/nsq 分布式的消息分发平台 多种worker内存中围绕着channel来工作 注意:这基本是大量Golang服务的常态,所以这个项目要特别关注 关键词: channel 2.3 open-falcon open-falcon 小米开源的监控系统 open-falcon里面保罗万象, 像一个小型的生态系统 open-falcon中多个系统的交互,大量使用RPC,另外open-falcon中各个组件的启停管理方式值得借鉴。 关键词: rpc heartbeat 3. 视频资源 Gopher大会视频 请我喝瓶饮料

May 4, 2018 · 1 min

算法题(9)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 问题描述 如下图所示,从矩阵(m*n)的(0, 0)出发,然后只能向下、向右,到达矩阵的对角(m-1, n-1) 求从(0,0)到(m-1, n-1) 一共有多少种走法 解题思路 解决这个问题,我们可以参考动态规划的思想 要到达(m-1, n-1), 就必须到达(m-2, n-1)或者(m-1, n-2) 从(m-2, n-1)到(m-1, n-1) 只有一种走法 从(m-1, n-2)到(m-1, n-1) 只有一种走法 那么从(0, 0)到(m-1, n-1)的走法数量 f(m-1, n-1) = f(m-2, n-1) + f(m-1, n-2) 递归算法 采用递归算法可以很容易写出代码 def try_walk(m, n): if m == 1 and n == 1: return 0 return walk(m -1, n -1) def walk(x, y): if x == 0 and y == 0: return 1 res = 0 if x - 1 >= 0: res += walk(x - 1, y) if y - 1 >= 0: res += walk(x, y - 1) return res if __name__ == '__main__': print (1,1), try_walk(1, 1) print (1,2), try_walk(1, 2) print (2,2), try_walk(2, 2) print (2,3), try_walk(2, 3) print (3,3), try_walk(3, 3) 参考动态规划的思想,可以记录cache (x,y)到(0,0) 走法的数量,加快速度 ...

May 4, 2018 · 2 min

算法题(8)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 问题描述 蛇形遍历矩阵 按下图的方法蛇形遍历矩阵 矩阵为m行n列 解题思路 观察可以发现 结论1. 在矩阵中移动的动作 只有以下4种 4种动作,对应的向量分别为 1)(0,1) 2) (1, -1) 3) (1, 0) 4) (-1, 1) 结论2 对于动作1和动作3 最多连续走一步 对于动作2和动作4,保持动作到矩阵边界 结论3 如果要变换方向则按照上次动作的Next动作开始尝试 沿着动作1、动作2、动作3、动作4的顺序进行尝试 完整程序 # -*- coding: utf-8 -*- actions = [(0,1), (1, -1), (1,0), (-1, 1)] def snake(matrix, m, n): # start # (0, 0) # end # (m - 1, n - 1) pos = (0, 0) num = 1 matrix[pos[0]][pos[1]] = num last_action_idx = None while pos != (m-1, n-1): num += 1 print "***************" print "current pos=", pos print "prepare to num", num, last_action_idx print "last action", last_action_idx print # 尝试走出一步 if last_action_idx is None: last_action_idx = 0 # 尝试继续按原动作前进且下一个位置也是合法的 # 继续走 elif last_action_idx in set([1, 3]) and valid(matrix, pos, actions[last_action_idx], m, n): pass else: # 必须要换方向 for i in xrange(4): last_action_idx = (last_action_idx + 1) % 4 if valid(matrix, pos, actions[last_action_idx], m, n): break print "execute action", last_action_idx action = actions[last_action_idx] pos = (pos[0] + action[0], pos[1] + action[1]) print 'track', pos, num matrix[pos[0]][pos[1]] = num def valid(matrix, pos, action, m, n): pos = (pos[0] + action[0], pos[1] + action[1]) # 不能超过边界,且从来没有走过 if pos[0] >= 0 and pos[0] < m and pos[1] >= 0 and\ pos[1] < n and matrix[pos[0]][pos[1]] == 0: return True return False def print_matrix(matrix): for line in matrix: for item in line: print item, print print '-' * 10 if __name__ == '__main__': matrix = [] matrix.append([0,0,0]) matrix.append([0,0,0]) matrix.append([0,0,0]) matrix.append([0,0,0]) snake(matrix, 4, 3) print "result", '=' * 10 print_matrix(matrix) 总结 这类问题的核心是寻找规律,规律找到了,问题也就迎刃而解了。与之类似的还有螺旋遍历2维数组。 ...

May 4, 2018 · 2 min

算法题(7)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 问题描述 在一个有序整型数组中,从其中任意挑2个数(不重复)相加等于目标值target 求所有这样的组合 比如有以下数组 case1: target=6 [1, 2, 3, 4, 5, 7, 9] 返回结果为 [(1,5), (2,4)] case2: target=6 [1, 7, 9] 返回结果为 [] case3: target=9 [1, 2, 3, 4, 5, 7, 9] 返回结果为 [(2,7)] 解题思路 对这个问题,我们可以这样思考,以case1 为例 如果对于1, 可以从右向左找,可以找到5,与1相加可以等于目标值6 这时候再看2有没有合适的值能够与之相加等于目标值的时候,我们只需要找 [3, 4]就可以了,这是因为左边的数增大了,右边已经查找过的数,显然已经太大 方案 1)设2个指针分别指向数组的最左和最右 2) 移动右边的指针直到无法找到合适的值或者已经找到合适的值 3)移动左边的指针 4)持续步骤2和3,直到左右2个指针重合 时间复杂度为O(n) 完整代码: def find(array, target): i = 0 j = len(array) - 1 res = [] while i < j: while i < j and array[j] > (target - array[i]): j -= 1 if (array[i] + array[j]) == target and i != j: res.append((i, j)) i += 1 return res def main(): a = [1,2,3,4,5,7] print find(a, 6) a = [1,7,9] print find(a, 6) a = [1, 2, 3, 5, 7, 9] print find(a, 9) if __name__ == "__main__": main() 请我喝瓶饮料

May 2, 2018 · 1 min

Golang中赋值会导致结构体复制

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 Golang很多语法特征都和C++非常相似, stuct对象的赋值操作,会导致struct被copy(浅拷贝) test_copy.go package main import "fmt" type Car struct{ Name string Age int XList []int } func main(){ a := Car{Name:"buick", Age: 10, XList:make([]int, 10)} b := a b.Age = 9 fmt.Printf("address a:%p\n", &a) fmt.Printf("address b:%p\n", &b) fmt.Println("----------------------") fmt.Printf("Car a:%v\n", a) fmt.Printf("Car a:%v\n", len(a.XList)) fmt.Printf("Car b:%v\n", b) fmt.Printf("Car b:%v\n", len(b.XList)) } 输出 address a:0xc420068180 address b:0xc4200681b0 ---------------------- Car a:{buick 10 [0 0 0 0 0 0 0 0 0 0]} Car a:10 Car b:{buick 9 [0 0 0 0 0 0 0 0 0 0]} Car b:10 可以看出a和b已经是完全不同的对象,对b的修改不会影响a ...

April 28, 2018 · 1 min

imroc/req 连接池使用须知

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 imroc/req 作为目前最好用的request库深受Gopher的喜爱,但是它的连接池,在使用时仍然有些要注意的事项。 2. 简述 imroc/req内部仍然使用的是标准库net/http来管理连接 所以我们首先要理解net/http 是如何管理连接池的 transport.go type Transport struct { idleMu sync.Mutex wantIdle bool // user has requested to close all idle conns idleConn map[connectMethodKey][]*persistConn // most recently used at end idleConnCh map[connectMethodKey]chan *persistConn // MaxIdleConns controls the maximum number of idle (keep-alive) // connections across all hosts. Zero means no limit. MaxIdleConns int // MaxIdleConnsPerHost, if non-zero, controls the maximum idle // (keep-alive) connections to keep per-host. If zero, // DefaultMaxIdleConnsPerHost is used. MaxIdleConnsPerHost int 这里的 connectMethodKey可以用来标识一个目标 显然它是proxy,scheme, addr 构成的三元组 MaxIdleConnsPerHost限制的是相同connectMethodKey的空闲连接数量 DefaultMaxIdleConnsPerHost的默认值是2,这对一个大并发的场景是完全不够用的。 ...

April 20, 2018 · 3 min

CHANNEL在GOLANG中的有趣用法(2)-对象池

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 Golang常常被用在对性能有较高需求的场景。为了避免高频的创建对象和GC我们,需要使用对象池,可以使用它默认提供的sync.pool。 但是每次gc时,sync.pool中的cache的对象都会被释放,如果我们对性能的要求更高,且需求更加明确,我们可以使用自定义的对象池 实现 下面对象池的简易实现,大家可以参考 package main import ( "fmt" ) type Car struct { name string age int } type CarPool struct { Cached chan *Car Size int } func NewCarPool(size int) *CarPool { x := CarPool{} x.Cached = make(chan *Car, size) x.Size = size return &x } func (c *CarPool) Get() *Car { var res *Car select { case res = <-c.Cached: fmt.Println("---get--") default: fmt.Println("---create one--") res = &Car{} } return res } func (p *CarPool) Put(c *Car) { select { case p.Cached <- c: fmt.Println("---put--") default: c = nil fmt.Println("---destroy--") } } func main() { carPool := NewCarPool(3) for i := 0; i < 5; i++ { x := carPool.Get() carPool.Put(x) } } 参考资料: 1.广发证券Go在证券行情系统中的应用 ...

April 3, 2018 · 1 min

json-iterator 使用要注意的大坑

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 众所周知, Golang标准库"encoding/json"的性能并不好,现在比较热的替代库是"json-iterator/go" 传送门: json-iterator/go 我们的日志打成json格式,然后做集中收集,为了提高性能用json-iterator替换encoding/json。打火焰图,却发现(JSON序列化日志)耗时占总时间的比重没有下降 2. 重新测试 难道json-iterator出的性能压测数据都是吹牛逼,只要自己又重新测试了一下,以下是测试代码 json_test.go package tjson import ( "testing" "encoding/json" jsoniter "github.com/json-iterator/go" ) type Car struct { Name string Name1 string Name2 string Name3 string } func BenchmarkStructJsoniter(b *testing.B) { c := Car{Name1:"xxxxxxxxxxxxx", Name2:"xxxxxxxxxxxxxxxxxxxx", Name3:"xxxxxxxxxxxxxxxxxx", Name: "buickxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} for i := 0; i < b.N; i++ { //use b.N for looping jsoniter.Marshal(&c) } } func BenchmarkStructStd(b *testing.B) { c := Car{Name1:"xxxxxxxxxxxxx", Name2:"xxxxxxxxxxxxxxxxxxxx", Name3:"xxxxxxxxxxxxxxxxxx", Name: "buickxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} for i := 0; i < b.N; i++ { //use b.N for looping json.Marshal(&c) } } func BenchmarkMapJsoniter(b *testing.B) { mymap := make(map[string]string, 10000) mymap["Name1"] = "xxxxxxxxxxxxx" mymap["Name2"] = "xxxxxxxxxxxxxxxxxxxx" mymap["Name3"] = "xxxxxxxxxxxxxxxxxx" mymap["Name"] = "buickxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" for i := 0; i < b.N; i++ { //use b.N for looping jsoniter.Marshal(&mymap) } } func BenchmarkMapStd(b *testing.B) { mymap := make(map[string]string, 10000) mymap["Name1"] = "xxxxxxxxxxxxx" mymap["Name2"] = "xxxxxxxxxxxxxxxxxxxx" mymap["Name3"] = "xxxxxxxxxxxxxxxxxx" mymap["Name"] = "buickxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" for i := 0; i < b.N; i++ { //use b.N for looping json.Marshal(&mymap) } } BenchMark脚本 ...

March 28, 2018 · 2 min