#791 我的 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

#790 冯·诺依曼的故事

2022-07-01

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

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

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

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

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

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

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

2022-06-30

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

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

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

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

#787 应该如何做 Code Review

2022-06-17

Review 的三点好处

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

应该怎么做

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

参考资料与拓展阅读

#786 一些微不足道的开发经验

2022-06-17

设计

  1. 方案设计要留有余地,在满足需求的前提下,尽量更加通用一点。
    前提是要认真理解需求,认真理解现有的架构,多想想,再多想想。
  2. 但是也要避免过早地、过度地优化。
    我们应该了解对团队来说更有价值的事情是什么,然后把主要的精力放在更加有价值的业务上。
    基于这个认知,我们就能更清楚需求到底是什么,应该如何去设计。

编码

  1. 遵守业界通用的编码规范非常重要。
  2. 代码可读性非常重要,简洁、美观。
  3. 如果一个逻辑有好多步骤,尽量分成几个更小的单元实现。
  4. 避免写重复的代码,将重复的部分抽离出来(有时需要考验设计能力)。
  5. 关键的点打印日志很重要,尤其是功能刚上线的时候,嫌多的话可以后面调整。

协作

  1. 沟通非常重要,沟通非常重要,沟通非常重要。
  2. 要通知到相关人,不只是消息发送出去就行,要确保他们真的理解你的意思。
    有些时候,作为经手人,还需要继续跟踪,了解他们的后续操作以及整件事情的进展。
  3. 对接时须对细节再三确认,然后形成约定,比如接口提供方将小数统一整理成保留两位,接口提供方应该保证默认排序规则。
    如果不确认,形成约定,日后有变更,可能就是意想不到的坑。
    如果是一些简单的工作,两边都处理一下也未尝不可。

工程

  1. 开发的预估时间往往是比较保守,及时你认为这个时间绝对没问题,也往往免不了延期。
  2. 可能是需求会变化,可能是方案的实现中会遇到一些变数,还可能是有别的事情会占用时间。
  3. 即便是在公开会议上也应该顶住压力,留有余地。如果真的是非常紧急,至少需要确保优先级真的比较高。

#785 号称 Redis 25 倍性能的 DragonflyDB

2022-06-13

之前的 KeyDB 宣称是 Redis 的 5 倍性能,这次可好,DragonflyDB 说是 25 倍。

相对于 Redis 服务,主要的改进是自带集群,可以利用多核,接口层面完全兼容 Redis (还支持 Memcached API,只是默认关闭)。
而 Redis 需要利用好多核就必须要有丰富的经验、额外的配置,以及更复杂的集群管理。
所以我觉得这个 DragonflyDB 是非常有意义的。

https://github.com/dragonflydb/dragonfly
https://dragonflydb.io/

docker run --network=host --ulimit memlock=-1 docker.dragonflydb.io/dragonflydb/dragonfly

https://zhuanlan.zhihu.com/p/554409312
是什么让Redis“气急败坏”回击:13年来,总有人想替Redis换套新架构

#784 Go iota

2022-06-10
type Weekday int

const (
    Sunday Weekday = iota // 0
    Monday                // 1
    Tuesday               // 2
    Wednesday             // 3
    Thursday              // 4
    Friday                // 5
    Saturday              // 6
)

func (day Weekday) String() string {
    names := [...]string{
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
    }

    if day < Sunday || day > Saturday {
        return "Unknown"
    }

    return names[day]
}
type FileSizeUnit int

const (
    _ = iota // 忽略第一个值 0,让后续常量从 1 开始递增
    KB FileSizeUnit = 1 << (10 * iota)  // 1 << (10*1) = 1 << 10 = 1024
    MB                                  // 1 << (10*2) = 1 << 20 = 1048576
    GB                                  // 1 << (10*3) = 1 << 30 = 1073741824
    TB                                  // 1 << (10*4) = 1 << 40 = 1099511627776
)
package main

import "fmt"

func main() {
    {
        const (
            a = iota
            b
            c
        )
        fmt.Printf("%+v\n", []int{a, b, c})
        // [0 1 2]
    }
    {
        const (
            a = 1
            b = iota
            c
        )
        fmt.Printf("%+v\n", []int{a, b, c})
        // [1 1 2]
    }
    {
        const (
            a = 1
            b = 2
            c = iota
        )
        fmt.Printf("%+v\n", []int{a, b, c})
        // [1 2 2]
    }
    {
        const (
            a = 1
            b = iota
            c = iota
        )
        fmt.Printf("%+v\n", []int{a, b, c})
        // [1 1 2]
    }
}

总结

  1. 首次出现是这个常量块中变量的顺序(0 开始)
  2. 后面的常量如果没有定义,就表示是按照前面的常量定义来,只是 iota 代表的值 + 1 了
  3. 如果想跳过一个值,可以使用下划线

#782 winget: Windows 包管理工具

2022-06-04
winget list
winget list -?
winget search xxx     # 搜索
winget install xxx    # 安装
winget upgrade        # 列出 upgradable 包
winget upgrade xxx    # 升级指定包
winget upgrade --all  # 升级
winget
Windows 程序包管理器 v1.3.2691
版权所有 (C) Microsoft Corporation。保留所有权利。

WinGet 命令行实用工具可从命令行安装应用程序和其他程序包。

使用情况: winget [<命令>] [<选项>]

下列命令有效:
  install    安装给定的程序包
  show       显示包的相关信息
  source     管理程序包的来源
  search     查找并显示程序包的基本信息
  list       显示已安装的程序包
  upgrade    显示并执行可用升级
  uninstall  卸载给定的程序包
  hash       哈希安装程序的帮助程序
  validate   验证清单文件
  settings   打开设置或设置管理员设置
  features   显示实验性功能的状态
  export     导出已安装程序包的列表
  import     安装文件中的所有程序包

如需特定命令的更多详细信息,请向其传递帮助参数。 [-?]

下列选项可用:
  -v,--version  显示工具的版本
  --info        显示工具的常规信息

可在此找到更多帮助: https://aka.ms/winget-command-help