OPA-重新定义规则引擎-入门篇

OPA,全称OpenPolicyAgent, 底层用Go实现,它灵活而强大的声明式语言全面支持通用策略定义。

而且,2019年4月2号OPA正式进入了CNCF,作为孵化级托管项目,详见声明

目前国内资料还比较少。

个人因为工作接触比较多,打算陆续分享些教程介绍下。

私以为策略引擎的技术选型完全可以多这个选择~~

什么是OPA

具体看官方文档 OPA philosophy docs

主要关键词是:

  • 轻量级的通用策略引擎
  • 可与服务共存
  • 集成方式可以是sidecar、主机级守护进程或库引入

opa

Read More

Dig101-Go之读懂interface的底层设计

Dig101: dig more, simplified more and know more

今天我们聊聊万物皆可为的接口(interface)的底层设计。

interface被定义为一组方法的签名。

有了它,我们可以订立方法契约,去抽象和约束实现。

而Go的基础类型,可以认为是没有实现任何方法的空interface,也就是万物皆为的interface。

(Go语言没有泛型,接口可以作为一种替代实现)

接口也被寄予厚望,主力开发Russ Cox曾说过:

从语言设计的角度来看,Go的接口是静态的,在编译时检查过的,在需要时是动态的。如果我可以将Go的一个特性导出到其他语言中,那就是接口。
Go Data Structures: Interfaces

那到底interface是怎么设计的底层结构呢?

又怎么支持的duck typing

在类型断言时又发生了什么?

带着这些问题,我们往下看

Read More

Tips-如何优雅的使用GDB调试Go

Tips: all for hands-free.

Tips 系列:记录日常解决问题、解放双手的一些小技巧。

目的只有一个:不被重复的琐事麻痹,能偷懒的绝不手软。


今天聊聊如何优雅的使用GDB调试Go程序。

GDB有啥用?

想了解代码底层的话,它是一大利器,更别说定位问题啥的。

具体骚操作见曹大的使用 debugger 学习 golang

但GDB从安装到可用,可能有一大堆问题要解决(尤其在Mac上),我们怎么能优雅的使用它,避免陷入问题中,是本文的重点。

(涉及Docker和Mac两个平台上运行)

Read More

Tips-如何批量将Word表格转为Excel

Tips: all for hands-free.

Tips 系列:记录日常解决问题、解放双手的一些小技巧。

目的只有一个:不被重复的琐事麻痹,能偷懒的绝不手软。


今天展示的是Mac上如何批量将Word(.doc)表格转换为Excel。

先上效果图:
批量将Word(.doc)表格转换为Excel

第一次选择目录后需要点击授权目录权限。
Word另存运行过程在后台,动图上没显示出来,实际Word窗口会一次次打开-另存-关闭。

Read More

Dig101-Go之聊聊struct的内存对齐

Update:

增加Go夜读slide


Dig101: dig more, simplified more and know more

经过前边几篇文章,相信你也发现了,struct几乎无处不在。

string,slice和map底层都用到了struct。

今天我们来重点关注下struct的内存对齐,

理解它,对更好的运用struct和读懂一些源码库的实现会有很大的帮助。

Read More

Dig101:Go之读懂map的底层设计

Dig101: dig more, simplified more and know more

在golang中,map是一个不可或缺的存在。

它作为哈希表,简单易用,既能自动处理哈希碰撞,又能自动扩容或重新内存整理,避免读写性能的下降。

这些都要归功于其内部实现的精妙。本文尝试去通过源码去分析一下其背后的故事。

我们不会过多在源码分析上展开,只结合代码示例对其背后设计实现上做些总结,希望可以简单明了一些。

希望看完后,会让你对 map 的理解有一些帮助。网上也有很多不错的源码分析,会附到文末,感兴趣的同学自行查看下。

(本文分析基于 Mac 平台上go1.14beta1版本。长文预警 … )

Read More

Dig101-Go之灵活的slice

Dig101: dig more, simplified more and know more

Slice作为go常用的数据类型,在日常编码中非常常见。
相对于数组的定长不可变,slice使用起来就灵活了许多。

0x01 slice 到底是什么?

首先我们看下源码中slice结构的定义

1
2
3
4
5
6
// src/runtime/slice.go
type slice struct {
array unsafe.Pointer
len int
cap int
}

slice数据结构如上,Data指向底层引用的数组内存地址, len是已用长度,cap是总容量。
为验证如上所述,我们尝试声明一个slice a,获取 a的sliceHeader头信息,并用%p获取&a, sh, a, a[0]的地址
看看他们的地址是否相同。

1
2
3
4
5
6
7
8
a := make([]int, 1, 3)
//reflect.SliceHeader 为 slice运行时数据结构
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
fmt.Printf("slice header: %#v\naddress of a: %p &a[0]: %p | &a: %p sh:%p ",
sh, a, &a[0],&a, sh)

//slice header: &reflect.SliceHeader{Data:0xc000018260, Len:1, Cap:3}
//address of a: 0xc000018260 &a[0]: 0xc000018260 | &a: 0xc00000c080 sh:0xc00000c080

结果发现a和&a[0]地址相同。 这个好理解,切片指向地址即对应底层引用数组首个元素地址
&a和sh及sh.Data指向地址相同。这个是因为这三个地址是指slice自身地址。
这里【slice自身地址不同于slice指向的底层数据结构地址】, 清楚这一点对于后边的一些问题会更容易判断。

Read More

Dig101-Go之for-range排坑指南

好久没写了,打算今年做个Dig101系列,挖一挖技术背后的故事。

Dig101: dig more, simplified more and know more

golang常用的遍历方式,有两种: for 和 for-range。
而for-range使用中有些坑常会遇到,今天我们一起来捋一捋。

0x01 遍历取不到所有元素指针?

如下代码想从数组遍历获取一个指针元素切片集合

1
2
3
4
5
6
7
8
arr := [2]int{1, 2}
res := []*int{}
for _, v := range arr {
res = append(res, &v)
}
//expect: 1 2
fmt.Println(*res[0],*res[1])
//but output: 2 2

答案是【取不到】
同样代码对切片[]int{1, 2}map[int]int{1:1, 2:2}遍历也不符合预期。
问题出在哪里?

Read More