无知的 tonyseek

Yet Another Seeker

矩阵的四个基础子空间

这是十周年重修工科数学系列课程之… 线性代数基础。重修这件事,有效缓解了焦虑和失眠,让自己觉得,生活除了吃饭睡觉和想象空间愈发匮乏的工作,还是有一些其他内容的。

向量空间和其(线性)子空间的定义

线性空间需要满足加法封闭和数乘封闭:

加法封闭(可加性)
空间内任意两向量相加(减),结果必须还在空间中:aRn,bRn(a+b)Rna \in \mathbb{R}^n, b \in \mathbb{R}^n \Rightarrow (a+b) \in \mathbb{R}^n

GraphQL 和服务化随想碎片

我大概 2015 年时候对 GraphQL 有过一些想法,当时还在从事用户产品研发,想法主要还是围绕业务公网 API 的。现在我的工作有很长一段时间是围绕服务化相关问题,视角也就有所改变了。加之重温了华翼老师当年的 slide,产生了一些随想。很碎,但是记录下来。

优点

  • 将数据获取需求一步送到服务端,减少 IO 往返次数
  • 涉及数据过滤、剪裁时,使用简单(和 SQL 类似),下游可以较少考虑 RPC 开销优化之类的问题
  • 灵活,下游无须为了新需求而请求上游排期开发、部署特定接口,自己就可以搞掂(同时也是缺点)

缺点

  • 接口语义模糊,太过于“通用”,抽象泄漏
  • 难以设计服务端缓存(无法预知查询语句)
  • 难以治理(完全由用户定制查询类型,服务端难以做监控、告警、QoS 和保护熔断等 ...

ZooKeeper Session ID 的组成

ZooKeeper 的 Session ID 是每个会话的唯一标识,记录为一个 64 位的长整型。 只要对应会话未被服务器端主动关闭,它就一定能唯一关联上。且会话初次建立时 Session ID 会被写入 transaction log,这意味着会话是跨节点共享的。 客户端和一个节点断开连接后,只要会话还没过期,就仍然可以使用相同的 Session ID 连到另一个节点。这个会话创建的所有临时 ZNodes 也会相应保留。

指标显示 ZooKeeper 经常出现大量 outstanding requests (即节点上排队待处理的请求) 时,我们就需要诊断大量请求来自哪个 ZooKeeper 节点。无论是 leader、follower 还是 observer 节点都在本地处理读请求而将写请求转发给 leader 发起投票,所以节点自身的 outstanding requests 指标可能因参与投票而不是处理本节点的请求而飙高, 从而不一定能准确体现出请求来源。这个时候从 ...

GraphQL vs RESTful API 的一些想法

嗯其实又是一篇早就写了的碎碎念, 在我的 simplenote 里躺了有一年了。也发出来充数吧,好显得我并没有把这个博客弃坑…

GraphQL 出来的时候似乎有老司机说它会“重新定义后端”,当然我们心里知道这实际上是重新定义了重新定义。综合官方文章来看,它要解决的问题都很明确 —— 我认为在 HTTP 1.1 时代它是很有工业价值的。然而它并非唯一的解决方案,RESTful API + HTTP/2 就是一种不错的备选。

Git 中的状态

嗯,这是去年 lttxzmj 初学 Git 的时候写给她的小纸条。两年没写博客了,发出来充个数…

杀死 subprocess.Popen 的子子孙孙

Python 标准库 subprocess.Popen 是 shellout 一个外部进程的首选,它在 Linux/Unix 平台下的实现方式是 fork 产生子进程然后 exec 载入外部可执行程序。

于是问题就来了,如果我们需要一个类似“夹具”的子进程(比如运行 Web 集成测试的时候跑起来的那个被测试 Server), 那么就需要在退出上下文的时候清理现场,也就是结束被跑起来的子进程。

最简单粗暴的做法可以是这样:

process_fixture.py
 @contextlib.contextmanager
 def process_fixture(shell_args):
     proc = subprocess.Popen(shell_args)
     try:
         yield
     finally:
         # 无论是否发生异常,现场都是需要清理的
         proc.terminate()
         proc.wait()


 if __name__ == '__main__':
     with ...

Flask 的 Context 机制

用过 Flask 做 Web 开发的同学应该不会不记得 App Context 和 Request Context 这两个名字——这两个 Context 算是 Flask 中比较特色的设计。[1]

从一个 Flask App 读入配置并启动开始,就进入了 App Context,在其中我们可以访问配置文件、打开资源文件、通过路由规则反向构造 URL。[2] 当一个请求进入开始被处理时,就进入了 Request Context,在其中我们可以访问请求携带的信息,比如 HTTP Method、表单域等。[3]

所以,这两个 Context 也成了 Flask 框架复杂度比较集中的地方,对此有评价认为 Flask 的这种设计比 Django、Tornado ...

Git 忽略某个目录

有时候我们在给开源项目贡献代码的时候,会使用自己熟悉的工具链。比如 Python 项目,我可能就用 tox 来构建发型包并运行单元测试。或者有不习惯用 pyenv 或者 virtualenvwrapper 的同学,就可能直接使用 virtualenv 命令创建一个隔离的环境。