简单博客

flutter Widget Element

May 29, 2023
Flutter, Widget, Element
Flutter

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. ...

mysqlrouter使用

May 16, 2023
Mysql, Router
Mysqlrouter

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. ...

NATS

April 24, 2023
Go, NATS
NATS

是什么? # 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. – 请求发出后,应用要不等待响应超时,要不就异步收到一个响应。 ...

Go Generic Join

January 6, 2023
Go, Generic, Join
Join

// 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

Jump Table

July 20, 2022
Structure
Jump Table

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
Number
Calculate

背景:分多次把一批货全部出清。 要求:需要确保这批货多次出清跟一次出清收的钱一样。 现有三个数字(可整数,可小数):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
Go, TypeScript
Generic

泛型 # 是什么? # 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. ...

Find out which Go version built your binary

May 27, 2022
Go
Version

根据二进制文件找出应用构建时使用的Go版本 # 使用 dlv: dlv exec ./app > p runtime.buildVerion 或者,在代码里调用runtime.Version(): func main() { fmt.Println("go version:", runtime.Version()) } 参照

k8s是怎么维持pod的运行的呢?

May 13, 2022
K8s
Pod

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. ...

Go enum

May 12, 2022
Go
Enum

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也要同步添加,对于开发人员来说,非常容易遗漏。 ...