PuTTY
2022-08-07
- Win + R, regedit 打开注册表编辑器。
- 逐级进入 HKEY_CURRENT_USER\Software\SimonTatham\PuTTY 目录
- 导出这个目录到 puttySettings.reg 文件
- 导出下一级目录 Sessions 为 puttySessions.reg 文件
regExport.bat:
reg export HKEY_CURRENT_USER\Software\SimonTatham\PuTTY "%USERPROFILE%\Desktop\puttySettings.reg"
reg export HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions "%USERPROFILE%\Desktop\puttySessions.reg"
或者:
regedit /e "%USERPROFILE%\Desktop\puttySettings.reg" HKEY_CURRENT_USER\Software\SimonTatham\PuTTY
regedit /e "%USERPROFILE%\Desktop\puttySessions.reg" HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions
Golang Viper
2022-07-22
package main
import (
"fmt"
"os"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func main() {
// 1. 设置 Viper 配置
viper.SetConfigName("config") // 配置文件名(不带后缀)
viper.AddConfigPath(".") // 配置文件路径
viper.SetConfigType("yaml") // 配置文件类型
viper.AutomaticEnv() // 自动读取环境变量
// 2. 设置命令行参数
pflag.String("name", "", "project name")
pflag.String("host", "", "host address")
pflag.String("port", "", "port number")
pflag.String("config", "./config.yaml", "config file") // 配置文件参数
pflag.Parse()
viper.BindPFlags(pflag.CommandLine) // 将命令行参数绑定到 Viper
// 3. 读取配置文件
if configFile := viper.GetString("config"); configFile != "" {
fmt.Println(configFile)
if err := viper.ReadInConfig(); err != nil {
fmt.Fprintf(os.Stderr, "读取配置文件失败:%v\n", err)
os.Exit(1)
}
}
// 4. 读取配置项
projectName := viper.GetString("name")
port := viper.GetInt("port")
fmt.Printf("ProjectName: %s, Port: %d\n", projectName, port)
}
name: hello
host: 10.10.0.172
port: 9090
- 支持环境变量、命令行参数、配置文件。
- 支持多种配置文件,包括 JSON,YAML,TOML,INI 等。
- 支持监控配置文件的变化,会自动加载新的配置。
- 支持从远程加载配置,比如 etcd、zk、consul、redis 等,
也可以通过 RemoteProvider 接口自定义远程数据源:
type RemoteProvider interface {
Set(key string, value []byte) error
Watch(key string) (chan *RemoteResponse, chan error)
Get(key string) ([]byte, error)
}
Golang
2022-07-20
通过对 key 做哈希,来实现 Redis 服务器的分片。
用这个例子来演示这个小库的用法:
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"log"
"time"
"github.com/go-redis/redis"
"github.com/serialx/hashring"
)
func RandomString(length int) (string, error) {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(b)[:length], nil
}
func main() {
redisServers := map[string]int{
"redis1:6379": 200,
"redis2:6379": 100,
}
redisClients := []*redis.Client{}
for uri, _ := range redisServers {
redisClients = append(redisClients, redis.NewClient(&redis.Options{Addr: uri}))
}
log.Println(redisServers)
ring := hashring.NewWithWeights(redisServers)
stat := map[string]int{}
for uri, _ := range redisServers {
stat[uri] = 0
}
for i := 0; i < 100; i++ {
randstr, _ := RandomString(8)
key := "test:randkey:" + randstr
node, ok := ring.GetNode(key)
if !ok {
log.Panicf("cannot assign a redis client by key: %#v", key)
}
log.Printf("%s -> %s", key, node)
stat[node]++
var client *redis.Client
for _, _client := range redisClients {
if node == _client.Options().Addr {
client = _client
break
}
}
if client == nil {
log.Panicf("redis client assigned error: %#v", node)
}
client.Set(key, 1, time.Minute)
}
fmt.Println(stat)
}
Golang
2022-07-19
https://github.com/bits-and-blooms/bloom/v3

package main
import (
"fmt"
"github.com/bits-and-blooms/bloom/v3"
)
func main() {
filter := bloom.New(1000000, 5)
filter.Add([]byte("apple"))
filter.Add([]byte("banana"))
filter.Add([]byte("orange"))
fmt.Println(filter.Test([]byte("apple")))
fmt.Println(filter.Test([]byte("banana")))
fmt.Println(filter.Test([]byte("orange")))
fmt.Println(filter.Test([]byte("grape")))
fmt.Println(filter.Test([]byte("watermelon")))
}
Python 测试 pytest
2022-07-12
- 全局
setup_module(module) / teardown_module(module) 引入包的时候执行
setup_function(function) / teardown_function(function)
- 模块级别
setup() / teardown() 测试模块载入的时候执行
- 类级别
setup_class(cls) / teardown_class(cls)
setup_method(self, method) / teardown_method(self, method)
setup(self) / teardown(self) nose 语法,会被上面两个方法覆盖
Supported nose Idioms
setup() and teardown() at module/class/method level: any function or method called setup will be called during the setup phase for each test, same for teardown.
SkipTest exceptions and markers
- setup/teardown decorators
__test__ attribute on modules/classes/functions
- general usage of nose utilities
个人
2022-07-02
受 冯·诺依曼的故事 启发,我觉得我应该更明确一下我的重要目标是什么。
重要目标
不说长了,就说接下来,这 2022 年下半年,工作和技术两个方面的目标。
工作
- 保质保量完成开发
- 帮助新人融入项目
- 推动自动化单元测试和项目文档
至少在两个项目中落地。
- 理解相关产品设计
技术
- Python 的几个技术点
- 元类
- asyncio
- Redis
- Golang
目标分解
- 工作以周为单位,每周应该完成几个任务 (TAPD)
- 本月开始,让新人参与分析问题,解决问题
- 完成 out,sch 两个项目的单元测试和项目文档
- 先写文档,再写单元测试
- 测试应该尽量不改动原有代码
- 代码覆盖率达到 70%
- 重点逻辑的用例应该尽可能覆盖所有可能的场景
- Web 上所有功能点和项目的代码串联起来,补充到文档中
- Django 模型相关代码阅读,输出笔记
- asyncio 文档,uvloop 文档,tornado 文档阅读,输出笔记
- 几个小型 Golang 项目开发(练手)
- httprouter, Gin, gocmpp
- Go Redis, Go MySQL (GORM), Go RabbitMQ
个人 阮一峰
2022-07-01
本周的《科技爱好者周刊》讲了冯·诺依曼的故事。
学计算机的,应该没有人不知道冯·诺依曼架构,冯·诺依曼也被称为现代计算机的发明人。他结合了数理逻辑、信息论和生物学,开创了自动机理论,并希望在这个领域做出更大贡献。但是他总是插入其他相对不重要的工作,比如政府相关事务,以致于最后并没有为自动机理论的发展做出应有的贡献。
他本人并非不知道这一点,但就是这种性格,喜欢同时研究很多事情,一旦对某件事情产生了兴趣,就会放下手头的工作,推说稍后再回来接着做,可惜人生并没有为他留出"回过头再做"的时间。
尤其是这句话,我感觉扎心了,妥妥的就是在说我。
我感兴趣的事情实在太多,以致总是被各种事情打断而很少能实现预定目标。我一直就有一种感觉,感觉自己是一只在追赶沙丁鱼群的、“没有经验”的小旗鱼,悲哀!
我要安静下来,仔细思考我的目标到底是什么,它们有一个怎样的优先级。

幻想
2022-06-30
地球生命从无到有,然后一步步进化到现在,确实是个奇迹。但是我认为现在我们已知的所有生命都是不堪一击的,能力非常有限,可以说非常简陋,和完美完全不沾边。
我心目中完美的生命应该是怎样的?
- 高度智慧,应该远超人类
- 不依赖外界物质而存活
- 可以吸收和存储宇宙中的能量(光能,核能...)
- 拥有无限的生命,或者可以遗传记忆
- 可以星际航行,不依赖特定行星
我想,应该只有机器人能够达到这个要求。
希望在人类文明彻底毁灭之前能够创造出这样的机器人。
Golang GUI
2022-06-20
明显,fyne 遥遥领先。
开发者
2022-06-17
Review 的三点好处
- 帮忙发现问题
- 相互学习
- 统一编码风格
应该怎么做
- 找出相应的变更(提交),开发者做简单说明,约好评审时间
- 参与评审的人尽快找时间从头到尾检查每一处变更,提出意见发出来
- 不可能一点意见都没有,每个人都应该能发出几条
- 编码风格也行
- 然后约一个会,在会上讲解整体的逻辑流程,每人提出评审意见
参考资料与拓展阅读