Go - Map
定义
map 表示一组无序的键值对,map 中每个 Key 都是唯一的
Key 和 Value 的类型不要求相同,如果 Key 类型和 Value 类型都相同,map 类型才是等价的
12345m1 := map[string]string{}m2 := make(map[int]string)fmt.Printf("%T\n", m1) // map[string]stringfmt.Printf("%T\n", m2) // map[int]string
对 Value 类型没有限制,但对 Key 类型有严格限制因为 map 类型要保证 Key 类型的唯一性,因此,Key 类型必须支持 == 和 != 两种比较操作
在 Go 中, slice、map、func都只支持与 nil 比较,并不支持同类型变量比较,因此不能作为 map 类型的 Key
1234567891011s1 := make([]int, 1)s2 := make([]int, 1)fmt.Println(s1 == s2) // invalid opera ...
Go - Array + Slice
数组逻辑定义
Go 数组:一个长度固定,由同构类型元素组成的连续序列
123// 声明了一个数组变量 arr,其类型为 [5]int,其中元素的类型为 int,数组的长度为 5var arr [5]int = [5]int{1, 2, 3, 4, 5}fmt.Println(arr) // [1 2 3 4 5]
数组元素的类型可以为任意 Go 原生类型或者自定义类型
数组的长度必须在声明数组变量时提供
Go 编译器需要在编译阶段就知道数组类型的长度(整型数字字面值 or 常量表达式)
如果两个数组类型的元素类型 T 和数组长度 N 都是一样的,那么两个数组类型是等价的
12345678910111213141516func f(arr [5]int) {}func main() { var arr1 [5]int var arr2 [6]int var arr3 [5]string fmt.Printf("%T\n", arr1) // [5]int fmt.Printf("%T ...
Go - Constant
原生概述
Go 常量是一种在源码编译期间被创建的语法元素
该元素的值可以像变量那么被初始化,但初始化表达式必须在编译期可以求值
Go 常量一旦声明并被初始化,它的值在整个程序的生命周期内便保持不变
在并发设计时不需要考虑常量访问的同步
并且被创建并初始化后的常量可以作为其它常量的初始化表达式的一部分
Go 引入 const 关键字声明常量,与 var 类似
123456const Pi float64 = 3.14159265358979323846const ( size int64 = 1024 i, j, s = 1, 2, "str")
Go 常量的类型仅限于基本数据类型:数值类型、字符串类型、布尔类型
C
C 语言原生不支持常量
在 C 语言中,字面值担负着常量的角色
为了不让字面值以魔数的形式分布于源码各处,早期 C 语言的常用实践是使用宏(macro),即宏定义常量
使用宏定义常量一直是 C 编码中的主流风格,即便后续的 C 标准中提供了 const 关键字
123#define FILE_MAX_LEN 0x100 ...
Go - Primitive Type
数值整型平台无关整型
在任何 CPU 架构和任何操作系统下面,长度都是固定不变的
有符号整型 vs 无符号整型
Go 采用补码作为整型的比特位编码方法:原码逐位取反后加 1
平台相关整型
长度会根据运行平台的改变而改变,在编写移植性要求的代码时,不要依赖下述类型的长度
123456a, b := int(5), uint(6)p := 0x12345678fmt.Println(unsafe.Sizeof(a)) // 8fmt.Println(unsafe.Sizeof(b)) // 8fmt.Println(unsafe.Sizeof(p)) // 8
溢出1234567var s int8 = 127s += 1fmt.Println(s) // -128var u uint8 = 1u -= 2fmt.Println(u) // 255
字面值1234567891011a := 53 // 十进制b := 0700 // 八进制,以 0 开头c1 := 0xaabbcc // 十六进制,以 0x 开头c2 := 0Xddeeff // 十六进制,以 ...
Security - OPA Operation
ConfigurationExample1$ opa run -s -c config.yaml
12345678910111213$ opa run --server \--log-format=json-pretty \--set=decision_logs.console=true \--set=services.A.url=http://my-bundles:8080/api/opa/bundle/ \--set=bundles.A.service=A \--set=bundles.A.polling.long_polling_timeout_seconds=45 \--set=bundles.A.resource=A.tar.gz \--set=services.B.url=http://my-bundles:8080/api/opa/bundle/ \--set=bundles.B.service=B \--set=bundles.B.polling.long_polling_timeout_seconds=45 \--set=bundles.B.resource=B.tar.gz \
c ...
Security - OPA Management
Overview & Architecture
OPA exposes a set of APIs that enable unified, logically centralized policy management.
Read this page if you are interested in how to build a control plane around OPA that enables policy distribution and collection of important telemetry data like decision logs.
OPA enables low-latency, highly-available policy enforcement by providing a lightweight engine for distributed architectures.By default, all of the policy and data that OPA uses to make decisions is kept in-memory.
...
Security - OPA Gatekeeper
Overview & Architecture
In Kubernetes, Admission Controllers enforce policies on objects during create, update, and delete operations.Admission control is fundamental to policy enforcement in Kubernetes.
For example, by deploying OPA as an admission controller you can
Require specific labels on all resources.
Require container images come from the corporate image registry.
Require all Pods specify resource requests and limits.
Prevent conflicting Ingress objects from being created.
Admission con ...
Security - OPA Core
Glance
Use OPA for a unified toolset and framework for policy across the cloud native stack.
Use OPA to decouple policy from the service’s code so you can release, analyze, and review policies without sacrificing availability or performance.
Declarative
Express policy in a high-level, declarative language that promotes safe, performant, fine-grained controls.
Use a language purpose-built for policy in a world where JSON is pervasive.
Iterate, traverse hierarchies, and apply 150+ built-ins like string manipu ...
Go - Block + Scope
Variable Shadowing1234567891011121314151617package mainimport "fmt"var a = 11func foo(n int) { // 局部变量遮蔽了同名的包级变量 a := 1 a += n}func main() { fmt.Println(a) // 11 foo(5) fmt.Println(a) // 11}
BlockExplicit Block
大括号包裹
12345678func foo() { // Block 1 { // Block 2 { // Block 3 { // Block 4 } } }}
Explicit Block 是包裹在大括号内部的声明和语句序列
如果一对大括号内没有任何声明和其它语句,为空 Block
Block 支持嵌套
Implicit ...
Go - Variable
内存边界
在编程语言中,为了方便操作内存特定位置的数据,使用变量与特定位置的内存绑定
编译器或者解析器需要知道变量所能引用的内存区域边界
动态语言
解析器可以在运行时通过对变量赋值的分析,自动确定变量的边界
一个变量可以在运行时被赋予大小不同的边界
静态语言
编译器必须明确知道一个变量的边界才允许使用该变量
但编译器无法自动分析,因此边界信息必须由开发者提供 - 变量声明
在具体实现层面,边界信息由变量的类型属性赋予
变量声明
Go 是静态语言,所有变量在使用前必须先进行声明声明:告诉编译器该变量可以操作的内存的边界信息(由变量类型信息提供)
通用
变量声明形式与主流静态语言的差异 - 将变量名放在了类型前面(方便语法糖移除 type)
如果没有显式为变量赋予初值,Go 编译器会为变量赋予类型零值
1var a int // a 的初值为 int 类型的零值 0
Go 的每种原生类型都有其默认值,即类型零值复合类型(array、struct)变量的类型零值为组成元素都为零值的结果
原生类型
类型零值
整型
0
浮点
0.0
布尔
FALSE
字符串
& ...