go-cmp 对象比较

简介 我们经常有深度比较两个 Object 是否相等的场景,比如: 1 如服务重构,新旧服务回包对比; 2 单测验证实际的返回值,标准库提供了 reflect.DeepEqual; 但是相对的,reflect.DeepEqual不够灵活,无法提供选项实现我们想要的行为,例如允许浮点数误差。所以今天的主角 go-cmp 登场了。 go-cmp 是 Google 开源的比较库,它提供了丰富的选项。最初定位是用在测试中。 1 快速使用 先安装: go get -u github.com/google/go-cmp/cmp Equal Diff 总结 go-cmp 非常适合对两个同类型的值进行比较。源码中大量使用熟知的 Option 模式,提供给使用者简洁、一致的接口。这种设计思想也值得我们学……

阅读全文

Xcode 编译 swift 项目

常见问题 1 如何调整依赖的系统版本macOS Deployment Target? A: 双击编辑器的项目名,然后调整。 ctrl+b 编译 2 Debug Or Release 编译? 选择 Product->Scheme->Edit Scheme,将编译配置改为 Release。 3 编译后,输出的App路径? 输出目录:~/Library/Developer/Xcode/DerivedData + 项目名。 比如: ~/Library/Developer/Xcode/DerivedData/Hidden_Bar-xxxx/Build/Products/Debug……

阅读全文

如何实现 SQL 用户标签的查询?

1 Preface

在社交 APP 中,经常会看到用户标签功能,那么这个功能如何实现呢? 如微信的用户标签。

user-label

考虑两种情况:

  1. 标签的量级较大,我们需要基于 ES 来加速查询;
  2. 标签量级较小,可以使用数据库实现一个简易版的标签功能;

下面我们使用数据库,实现一个简易的标签功能;

……

阅读全文

Proto oneof schema 的使用

1 Preface protobuf 提供了 oneof 语义,表示任选其一;类似于C语言的 union 关键字。 于是想了解下 oneof 语义在 golang 中是如何实现的,下面我们来一探究竟。 具体的用法如下: 1 2 3 4 5 6 7 8 9 10 11 message WechatPay { int64 uuid = 1; } message HelloRequest { string msg = 1; oneof one_of_pay { string noop = 2; WechatPay wx = 3; } } 2 stub 代码分析 使用 protoc 工具会生成如下代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 定义一个接口,用于类型断言 type isHelloRequest_OneOfPay interface { isHelloRequest_OneOfPay() } type HelloRequest_Noop struct { Noop string `protobuf:"bytes,2,opt,name=noop,proto3,oneof"` } type HelloRequest_Wx struct { Wx *WechatPay `protobuf:"bytes,3,opt,name=wx,proto3,oneof"` } // 接口实现 empty // implements isHelloRequest_OneOfPay interface func (*HelloRequest_Noop) isHelloRequest_OneOfPay() {} // 接口实现 empty // implements isHelloRequest_OneOfPay interface func (*HelloRequest_Wx) isHelloRequest_OneOfPay() {} 3 总结 在 Golang 中, oneof 语义基于一个类型接口,oneof 的每个成员都实现这个接口,方便在Ge……

阅读全文

多个集合,取交集

1 Preface 最近在一直采用 go 语言进行项目开发,遇到一个比较有意思的问题: 多个集合,计算交集,哪种计算方法最高效? 假定集合采用 HashMap 来实现,那么每次查询的时间复杂度为 O(1) 考虑最简单的情况,假定有2个集合A和B,A 的元素个数为2, B 的元素个数为10。 计算A和B的交集有 2 个方案: 方案一:先遍历A,在B中查找是否存在,时间复杂度为 2*O(1) 方案二:时间复杂度为 10*O(1) 于是得出结论: 每次遍历最小的集合去计算交集,总的时间复杂度最小。 2 寻找已有的轮子 由于 go 标准库,并不提供 set 数据结构;先尝试用 google 搜索,fatih/set 出镜率比较高。 于是……

阅读全文

业务缓存之可行性?

1 Preface 在业务系统中,为了提高服务的性能,降低平均时延,一个常用的手段:增加cache。 鲁迅:-)人们发明一种方法解决一个问题,而几乎总是会引入另一个问题。 那么可能会问:Cache 要加在哪里,要缓存多久,才会更有效? 下面就拿一个例子,来展开看看。 2 分析 一般而言,需要对执行频率高,耗时占比大的逻辑,优先增加Cache。 但是要注意:增加 Cache 不能影响到业务的正确性。 适用场景:数据变化不频繁,因为一旦数据发生变化,Cache可能产生不一致。 对于不一致,还需要设计一个合理的失效时间,在业务可接受的误差之内增加c……

阅读全文

基于 go 的 wireshark 插件实现方案

1 背景 在业务服务重构过程中,发现后台一些RPC服务,使用的自定义的应用层协议(七层)。 为了方便验证重构逻辑,想在在海量的请求中,快速找到某一类业务请求包。 2 思考 一般来说简单的协议使用 lua 实现即可,但是遇到 pb/thrift 等 tlv 类型的协议就比较麻烦了; 比较友好的是,目前有 lua-protobuf 这样的库,可以在lua中解析PB协议, 只需要提供proto即可; 但是对于内部的 tlv 协议,由于本人不太会使用lua去封装c库; 突然萌生了一个想法,能不能用 golang 来开发 wireshark 插件? 是否可以让 lua5.2 直接调用cgo? 3 定制目标(okr) 定位: 本地的报文分析工具 1 当业务……

阅读全文

wireshark lua 插件tcp报文分段(desegment)?

缘起 我们知道 一般网路中 以太网的帧长度不超过 1500字节(MTU),所以单个 tcp segment 最大为1460; 如果我们业务报文超过 1420 字节(tcp payload),就会被分成多个 segment。 那么如何在 编写 wireshark 插件时,拿到一个完整的业务报文呢? 解决办法 通过goolge,发现解决办法非常简单,只需要为pinfo.desegment_len 还需要的字节长度即可。 1 2 3 4 5 6 7 8 9 10 11 -- 在入口处 function slicer.dissector(tvb, pinfo, tree) ... local pdu_length = get_pdu_length(...) if pdu_length > tvb:len() then pinfo.desegment_len = pdu_length - tvb:len() else do_dissection(tvb, pifo, tree) end return end 如果不知道明确的长度,那我们也可以: 1 pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT 总结 通过 wireshark lua 插件的编写,发现很……

阅读全文

wireshark lua 插件之 tvb():string()

缘起 最近在编写 lua 插件时,遇到一个问题:发现tvb中的字节码,传入 lua-protobuf 中,部分报文解码失败。 于是经过一顿debug,最后将字节码写入文件,对比 lua-protobuf 中的字节码和 tvb 中的字节码,发现不一致。 解决办法 通过 goolge 找到了如下一篇文章,wireshark-lua-stringbyte-error 不应该使用 tvb_range:string() 这个方法默认是带字符集转换的,要想将原始的bytes转为 lua string,需要使用raw方法。 1 2 -- local lua_str = tvb_range:string() local lua_str = tvb_range:raw(tvb_range:offset(), tvb_range:len()) 总结 这个问题,本质还是没有仔细阅读 wireshark lua 插件关于 tvb 的API文档导致的。 有时候遇到问题,我们可以先通过 google……

阅读全文

最近文章

分类

友情链接

标签

其它