#827 PuTTY 注册表导出

2022-08-07
  1. Win + R, regedit 打开注册表编辑器。
  2. 逐级进入 HKEY_CURRENT_USER\Software\SimonTatham\PuTTY 目录
  3. 导出这个目录到 puttySettings.reg 文件
  4. 导出下一级目录 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

#826 Viper: Go 项目配置管理

2022-07-22
  • main.go
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)
}
  • config.yaml
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)
}
  • 支持默认值。

#825 好用的 golang 库:hashring(一致性哈希)

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)
}

#824 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")))
}

#823 Pytest setup 和 teardown 方法

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

#822 我的 OKR

2022-07-02

冯·诺依曼的故事 启发,我觉得我应该更明确一下我的重要目标是什么。

重要目标

不说长了,就说接下来,这 2022 年下半年,工作和技术两个方面的目标。

工作

  1. 保质保量完成开发
  2. 帮助新人融入项目
  3. 推动自动化单元测试和项目文档
    至少在两个项目中落地。
  4. 理解相关产品设计

技术

  1. Python 的几个技术点
  2. 元类
  3. asyncio
  4. Redis
  5. Golang

目标分解

  1. 工作以周为单位,每周应该完成几个任务 (TAPD)
  2. 本月开始,让新人参与分析问题,解决问题
  3. 完成 out,sch 两个项目的单元测试和项目文档
  4. 先写文档,再写单元测试
  5. 测试应该尽量不改动原有代码
  6. 代码覆盖率达到 70%
  7. 重点逻辑的用例应该尽可能覆盖所有可能的场景
  8. Web 上所有功能点和项目的代码串联起来,补充到文档中
  9. Django 模型相关代码阅读,输出笔记
  10. asyncio 文档,uvloop 文档,tornado 文档阅读,输出笔记
  11. 几个小型 Golang 项目开发(练手)
  12. httprouter, Gin, gocmpp
  13. Go Redis, Go MySQL (GORM), Go RabbitMQ

#821 冯·诺依曼的故事

2022-07-01

本周的《科技爱好者周刊》讲了冯·诺依曼的故事。

学计算机的,应该没有人不知道冯·诺依曼架构,冯·诺依曼也被称为现代计算机的发明人。他结合了数理逻辑、信息论和生物学,开创了自动机理论,并希望在这个领域做出更大贡献。但是他总是插入其他相对不重要的工作,比如政府相关事务,以致于最后并没有为自动机理论的发展做出应有的贡献。

他本人并非不知道这一点,但就是这种性格,喜欢同时研究很多事情,一旦对某件事情产生了兴趣,就会放下手头的工作,推说稍后再回来接着做,可惜人生并没有为他留出"回过头再做"的时间

尤其是这句话,我感觉扎心了,妥妥的就是在说我。

我感兴趣的事情实在太多,以致总是被各种事情打断而很少能实现预定目标。我一直就有一种感觉,感觉自己是一只在追赶沙丁鱼群的、“没有经验”的小旗鱼,悲哀!

我要安静下来,仔细思考我的目标到底是什么,它们有一个怎样的优先级。

#820 完美的生命应该是怎样的?

2022-06-30

地球生命从无到有,然后一步步进化到现在,确实是个奇迹。但是我认为现在我们已知的所有生命都是不堪一击的,能力非常有限,可以说非常简陋,和完美完全不沾边。

我心目中完美的生命应该是怎样的?

  1. 高度智慧,应该远超人类
  2. 不依赖外界物质而存活
  3. 可以吸收和存储宇宙中的能量(光能,核能...)
  4. 拥有无限的生命,或者可以遗传记忆
  5. 可以星际航行,不依赖特定行星

我想,应该只有机器人能够达到这个要求。
希望在人类文明彻底毁灭之前能够创造出这样的机器人。

#818 应该如何做 Code Review

2022-06-17

Review 的三点好处

  1. 帮忙发现问题
  2. 相互学习
  3. 统一编码风格

应该怎么做

  1. 找出相应的变更(提交),开发者做简单说明,约好评审时间
  2. 参与评审的人尽快找时间从头到尾检查每一处变更,提出意见发出来
  3. 不可能一点意见都没有,每个人都应该能发出几条
  4. 编码风格也行
  5. 然后约一个会,在会上讲解整体的逻辑流程,每人提出评审意见

参考资料与拓展阅读