May 29, 2023
Element # abstract class Element extends DiagnosticableTree implements BuildContext package:flutter/src/widgets/framework.dart
An instantiation of a [Widget] at a particular location in the tree. – 在树里的特定位置上的一个Widget的实例。
Widgets describe how to configure a subtree but the same widget can be used to configure multiple subtrees simultaneously because widgets are immutable. An [Element] represents the use of a widget to configure a specific location in the tree. Over time, the widget associated with a given element can change, for example, if the parent widget rebuilds and creates a new widget for this location.
...
May 16, 2023
What # mysqlrouter是一个代理,可以将查询转发到配置好的数据库服务里。
Why # 在办公室网络环境下基于win10 wsl2开发应用时,需要连接到主机所在局域网的其它机器上的数据库服务。
也就是说,存在机器:wsl2、主机、其它机器。
wsl2通过NAT网络模式与主机互通,并且wsl2可以访问外网。
但是wsl2不能访问到其它机器上的数据库服务,不知道是不是办公室网络环境存在限制。
为了使得wsl2能访问到其它机器上的数据库服务成立,在主机启动mysqlrouter充当代理,然后wsl2通过访问代理来访问其它机器。
Install # 可以使用mysql installer选择安装。
简单模式 # 配置文件(mysqlrouter.conf):
[DEFAULT] logging_folder = D:/Data/mysqlrouter/log plugin_folder = C:/Program Files/MySQL/MySQL Router 8.0/lib # 这里是插件所在目录,必须是mysqlrouter安装路径下的目录,否则报错找不到插件 config_folder = D:/Data/mysqlrouter/etc # 启动配置默认查找目录,会在目录里寻找mysqlrouter.conf文件 runtime_folder = D:/Data/mysqlrouter/run data_folder = D:/Data/mysqlrouter/data [logger] level = DEBUG [routing:primary] bind_address=172.20.96.1 # 主机ip地址 bind_port=6446 # 主机监听端口 destinations = 172.17.39.239:3306 # 目标机器,也就是实际执行查询的数据库服务所在机器的地址 mode = read-write connect_timeout = 10 启动:mysqlrouter -c D:\Data\mysqlrouter\etc\mysqlrouter.conf
关闭防火墙或者配置规则允许端口通过。
在wsl2机器上访问:mysql -h 172.
...
April 24, 2023
是什么? # Home, Github
NATS 是一个简单、安全和高性能的通信系统,适用于数字系统、服务和设备。
NATS 是一种允许以消息形式分段的数据交换的基础架构。
基于主题 # 发布者将消息发到主题;订阅者订阅主题,在有消息到来时消费该消息。
主题命名规则:
基本字符:a to z, A to Z and 0 to 9 (区分大小写,不能包含空白字符).
特殊字符: . (分割符,分割不同部分,每部分视为一个token); * 和 > (通配符,*表示匹配一个token,>表示匹配一或多个token).
保留主题名称: 以 $ 开头的用在系统内部 (如:$SYS, $JS, $KV …)
发布-订阅 # Core NATS: 一个主题,存在一个发布者,多个订阅者。
消息会复制到多个订阅者。
请求-响应 # A request is sent, and the application either waits on the response with a certain timeout, or receives a response asynchronously.
– 请求发出后,应用要不等待响应超时,要不就异步收到一个响应。
...
January 6, 2023
// NestedJoin like nested loop join func NestedJoin[J, K, R any]( left []J, right []K, match func(J, K) bool, mapper func(J, K) R, ) []R { var r = make([]R, 0, len(left)) for _, j := range left { for _, k := range right { if !match(j, k) { continue } r = append(r, mapper(j, k)) } } return r } // HashJoin like hash join func HashJoin[K comparable, LE, RE, R any]( left []LE, right []RE, lk func(item LE) K, rk func(item RE) K, mapper func(LE, RE) R, ) []R { var r = make([]R, 0, len(left)) rm := KeyBy(right, rk) for _, le := range left { k := lk(le) re := rm[k] r = append(r, mapper(le, re)) } return r } Code From
July 20, 2022
What’s Jump Table? # A jump table can be either an array of pointers to functions or an array of machine code jump instructions. If you have a relatively static set of functions (such as system calls or virtual functions for a class) then you can create this table once and call the functions using a simple index into the array. This would mean retrieving the pointer and calling a function or jumping to the machine code depending on the type of table used.
...
July 20, 2022
背景:分多次把一批货全部出清。
要求:需要确保这批货多次出清跟一次出清收的钱一样。
现有三个数字(可整数,可小数):a b c,其中:a 为数量,b 为价格,c 为折扣。
则总额为: t, t = a*b*c
假设分三次,每次数量为:a1 a2 a3,则有:a = a1 + a2 + a3
直接计算: 第 1 次.
a1*b*c 第 2 次.
a2*b*c 第 3 次.
a3*b*c (a1+a2+a3)bc 不就等于 abc 了吗?
但是,如果考虑到小数乘法计算时的精度,比如:1.22*2.33 相乘后再取精度(保留两位小数),不就会导致数量误差了吗?
那如果取精度导致结果误差,那我不取精度,直接用所有小数位数来计算呢。
虽说可以,但小数位数是有可能非常多的,占用的空间也是一笔不小的开销。
引入中间量(可称为’余额’): x y z x = a y = x*b z = y*c 第 1 次.
x1 = (x-a1) y1 = (y-y*a1/x) z1 = (z-z*a1/x) t1 = z*a1/x 第 2 次.
...
May 30, 2022
泛型 # 是什么? # Type parameter, 类型参数。func Add[T Number](x, y T) (r T),其中的T就是类型参数,它被接口Number所约束。
type Number interface { int | float32 } 调用方除了可自行决定参数值之外,还可以自行决定参数类型。Add[int](1, 2),在调用时指定T的类型为int,同时传入参数值1,2必须是int类型。
这样使得代码更灵活,更有扩展性,同时更安全。
Go泛型 # 为什么? # 静态语言,类型固定,比如这个函数:func Add(x, y int) int就要求参数和结果都必须是整型。
那如果后来又需要一个浮点数的加法呢?
那使用interface{}不也可以吗?
试看:
// 准确的描述出了参数和返回值的类型,非常方便 func Add(x, y int) int // 但也限制了Add函数的参数类型--只能接收`int` // Add(0.1, 0.2) // can't do that // 那怎么办呢?再写一个针对float64的呗 func AddFloat64(x, y float64) float64 AddFloat64(0.1, 0.2) // it's ok // 如果还要支持其它类型呢?再加一个吗,每多一种类型,就多加一个。。。 func AddInt8(x, y int8) int8 func AddInt32(x, y int32) int32 func AddFloat32(x, y float32) float32 // more.
...
May 27, 2022
根据二进制文件找出应用构建时使用的Go版本 # 使用 dlv:
dlv exec ./app > p runtime.buildVerion 或者,在代码里调用runtime.Version():
func main() { fmt.Println("go version:", runtime.Version()) } 参照
May 13, 2022
k8s是怎么维持pod的运行的呢? # 当接收了yaml配置的信息后,是怎么维持pod根据声明一直运行的呢?
让我们沿着命令执行的过程来一睹为快:kubectl apply -f pod.yaml.
源码位置:cmd/kubectl/kubectl.go -> staging/src/k8s.io/kubectl/pkg/cmd/cmd.go -> staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go
最终的执行方法:
func (o *ApplyOptions) Run() error { // 预处理 if o.PreProcessorFn != nil { klog.V(4).Infof("Running apply pre-processor function") if err := o.PreProcessorFn(); err != nil { return err } } // Enforce CLI specified namespace on server request. if o.EnforceNamespace { o.VisitedNamespaces.Insert(o.Namespace) } // Generates the objects using the resource builder if they have not // already been stored by calling "SetObjects()" in the pre-processor.
...
May 12, 2022
Go enum # Go是没有内置枚举类型的,那么,当需要使用枚举时,该怎么办呢?
枚举说白了,就是一连串互斥的值,每个值代表一样事物或一个类型。
比如,现在需要一个颜色枚举,可以这样定义:
const ( Red = "Red" // 红色 Blue = "Blue" // 蓝色 Green = "Green" // 绿色 ) 也有这样定义的:
type Color string // 定义一个特定类型 // 枚举常量均声明为该类型 const ( Red Color = "Red" // 红色 Blue Color = "Blue" // 蓝色 Green Color = "Green" // 绿色 ) 这样做的好处是可以通过这个类型来更明显的标记出枚举字段来:
type Car struct { Name string Color Color // 颜色字段声明为Color类型,在阅读代码的时候就能知道这个字段正常的可选值范围 } 但是,上面的做法都需要面临一个问题,就是我需要一个返回全部枚举值的集合时,需要这样做:
func All() []Color { return []Color{ Red, Blue, Green, } } func (color Color) Name() string { switch color { case Red: return "红色" case Blue: return "蓝色" case Green: return "绿色" } return "" } 当在定义处新增值时,All和Name也要同步添加,对于开发人员来说,非常容易遗漏。
...