Writing

写作

2026-06-16
思考1 min

用勾股定理画脚踝

前两周,我在练球时扭伤了脚踝,歇了两周依然没好全,而且还出现一种我无法理解的症状「 走路的时候不疼,坐一会儿再站起来就又开始疼,接着走一会儿就又好了 」。出于好奇,我咨询了 AI,这是我们的 完整的对话 。关于脚踝的症状并没有什么值得在这里展开,让我真正感到惊讶的是,AI 为了向我说明「距腓前韧带」的位置,画了一张我在数学课上才会见到的图:

2026-03-02
实践3 min

我的第一个 AgentSkill

我在 Cambly 和外教上课时,多数时候用的是 Engoo Daily News 中的课程( 网站示例 、 课程示例 )。每节课程对应一篇英文时事新闻,上课的一般流程就是:课前准备 → 文章阅读 → 问题讨论,同时每节课程都标记有难度,从 Intermediate (Level 4-6)、Advanced (Level 7-8) 到 Proficient (Level 9),课程内容难度依次递增,具体体现在词汇难度、句子复杂度、讨论…

2026-02-02
思考3 min

AI 究竟在缩小还是放大软件工程师之间的差距?

有人认为,随着模型推理能力变强,写代码正在变得更容易,程序员之间的差距也会逐渐被拉平。新手能更快写出可用的代码,很多过去需要经验积累才能跨过的门槛,现在只要能写好提示词就能轻松迈过。 别妄想了,AI 一定不会拉平软件工程师之间的差距,差距只会越来越大,且越来越快,就像宇宙的加速膨胀。

2024-10-06
实践9 min

两年魔方速拧路,体验优化的艺术

魔方速拧之路 走上魔方速拧路既是机缘巧合,也是冥冥之中天意使然。2022 年 8 月 28 日,我见到郑天晴坐在地上摔打奶奶给她买的玩具魔方,忽然回忆起高中班上有个小伙子能在 3 分钟内复原一个魔方,令同学们既赞叹又羡慕,我心中的少年之火在这一瞬间被点燃,决定也试上一试。于是我找到了博主 LeesRandomVids 制作的保姆级教学视频「 How to Solve a Rubik's Cube, Step by Step Begin…

2023-10-27
思考2 min

为什么要「卷」

有一个问题困扰了我很久: 为什么公司里的团队要互相卷? 明明 X 团队已经造了轮子,为什么 Y 团队常常视而不见,吭哧吭哧地继续造?而且领导似乎也默许这种游戏规则?本来产研资源就贵,为什么要浪费在相似的工作上,而不节省资源去专心做业务?最近在这个问题上稍微有点心得,就先记录于此。

2023-10-04
实践1 min

赤道计划

多数人高估他们一年能做的事,却低估他们十年能的事(Most people overestimate what they can do in one year and underestimate what they can do in ten years)。 大概在两年前,我开始酝酿「赤道计划」:在人生结束之前跑完 40075 公里,这个距离正是赤道的周长。毛主席的「坐地日行八万里,巡天遥看一千河」也来源于它。如果每两天跑一次 5 公里…

2023-04-06
思考3 min

面向工程师的内部系统需要 Web 界面吗?

每个互联网公司内部都有一些 Web 界面是为工程师开发,比如 CMDB、容器平台、应用发布系统、可观测性平台、配置中心、数据库管理平台等等。这些界面往往设计风格不一致,功能简陋,易用性差强人意,简单概括就是「能用,但既不好看,也不好用」。

2023-01-07
实践3 min

我开发的口语跟读练习工具 RAM

平时,我习惯在跑步、散步或通勤时做一些口语跟读练习。散步或通勤时还好,在手机上来回播放、暂停音频即可,但这种方法不适合在跑步中使用。另外,北京入冬后,在室外这么干容易生冻疮。于是我就想:能不能让音频自动地播放一句,停留一段时间让我跟读,然后再播下一句?

2023-01-02
思考6 min

Software Engineering at Google - 阻碍工程师成长的几种想法

前言 从 2022 年 10 月中旬开始到 12 月中旬,日拱一卒,终于把「Software Engineering at Google」通读了一遍。书中介绍的是每个软件公司都会遇到的问题:如何培养好的工程师文化?如何共享知识?如何组建和带领工程师团队?如何长期维持软件质量?等等。同样的问题,在不同的规模、时间范围下的挑战不同,思考角度、解决方案、落地周期也都不同。这本书介绍的正是这家拥有 超过两万名工程师 的软件公司在这些问题上的思…

2022-10-30
实践3 min

纸牌游戏:24

可能是太想排到车号了,最近上下班路上总是盯着过往车辆的号牌。盯着盯着就会下意识地思考:「怎么用上面的数字经过加、减、乘、除得到 24」,比如下面这个车牌:

2022-10-09
思考5 min

猫和女儿教会我的道理

没有屏蔽我朋友圈的人估计都知道,我有一只帅气的猫叫郑小钱,一个可爱的女儿叫郑天晴。小钱已经快 5 岁了,天晴刚刚 1 岁 3 个月,她们和我 (爸爸)、我媳妇 (妈妈) 以及我妈妈 (奶奶),4 人 1 猫生活在北京租住的一套小房子里。 都说养猫是养娃的演习,这话颇有道理。二者的确有很多相似的地方,比如我们会忍不住给她们买玩具,花时间陪她们玩耍,给她们准备饭菜与零食,管她们拉屎撒尿。最有意思的,也是我和媳妇经常讨论的一点就是「她们跟谁…

2022-09-29
思考7 min

面试官毁掉技术面试的三大法宝

在伴鱼的三年,我作为面试官参与超过 100 场面试,遇到许多风格各异的候选人;最近的两个月里,我也作为候选人参与将近 30 轮面试,见过不少形形色色的面试官。在参与这些面试的过程中,我心中逐渐累积了一些对面试的看法,本文我想站在面试官的角度,谈一谈面试官毁掉技术面试的三大法宝。

2022-08-06
实践12 min

从 MapReduce 到 SQL

在最近的工作中,为了做数据分析,我开始写一些复杂的 HiveSQL。每次执行 HiveSQL 时,都会看到 Map/Reduce jobs 被调度、执行,直到最后展示出数据。渐渐地我心中多了两个疑问: MapReduce 引擎如何工作? SQL 是如何被翻译成 MapReduce job 的? 为了解决这两个疑问,我用比较熟悉的 Go 语言实现了一个玩具版本的 MapReduce 引擎,然后基于此实现基本的 select,join。 …

2022-07-04
实践9 min

一次实验、两种错误、三个直觉

最近,我们在公司内部做了一些 Hacking Growth 方向的探索,我们团队俨然成了增长团队,从用户增长、转化的各个环节上尝试不同的策略,拉新、激活、留存、促活、商业化,整个核心流程是一个大漏斗,不同的阶段和渠道又可以拆分成不同的小漏斗,哪个环节损失大就优化哪个。但无论做何种尝试,都绕不开 A/B 测试。

2022-05-23
思考2 min

捋一捋 Accuracy 与 Precision 间的区别和联系

Accuracy 和 Precision 是在科学技术领域中经常出现的两个概念,本文将通过一张图来捋一捋二者之间的区别与联系。

2022-05-15
思考2 min

我明明是福建人,为什么别人以为我是胡建人?

在和不同地区的人聊天时,我们常常会有疑惑:为什么有些人说话时分不清 x 和 y?这里的 x 和 y 可能是拼音中的 f 和 h,l 和 n,l 和 r,z 和 zh,ang 和 an。比如,我明明是福建人,为什么别人以为我是胡建人?在最近刚刚读完的一本书《Fluent Forever》中,有两张图片正好能解释这个问题。

2022-04-13
实践9 min

中小型 Go 语言项目应该如何布局?

每个工程师来到新环境,大概率需要从维护老项目开始切入,逐渐熟悉公司的技术栈和效率工具。这时候,老项目的一些习惯,如命名、布局、错误处理等等,不论好坏,都会不自觉地影响新人,形成路径依赖。在这个过程中,如果没有人主动去思考为什么,这些习惯也将被无理由地继承下去。

2022-02-26
思考6 min

复利的隐喻

💡 人们常常高估自己一年能成就之事,而低估自己十年能成就之事 尽管我的博客中绝大多数内容都与计算机相关,但实际上我还有另一个身份:经济学学士。在对外经贸大学度过的四年,是我对人生的认识井喷的四年。毕业之后选择计算机,并不是因为我厌恶经济学。相反,在学习经济学的过程中建立起的心智模式,一直对我的学习和实践产生着指导性作用。 在货币银行学中,有一个与金钱的时间价值紧密相关的概念: 复利 ,即本金产生的利息会在下一个计息周期成为本金的一部…

2022-02-20
实践13 min

从头开始实现 RNN

What I cannot create, I do not understand. -- Richard Feynman Andrej Karpathy 在 2015 年发表了题为 The Unreasonable Effectiveness of Recurrent Neural Networks 的博客,并配套开源了其中实验所用的 char-rnn 代码仓库 ,以及用 numpy 手写的 gist: min-char-rnn ,…

2022-02-07
实践4 min

翻译能有多快?在 Mac 上实现一键翻译

因为平时需要阅读大量的英文资料,翻译对我来说是一个高频需求,但我一直没能找到一个足够趁手的工具。对于一个理想的翻译工具,我有三点期望: 翻译准确:翻译的结果与原文贴合不显得尴尬 触发简单:复制到剪贴板后快速触发翻译指令 响应迅速:发起翻译请求到获得结果小于一秒

2022-01-03
实践3 min

从头开始构建一个 Pascal 的解释器

前阵子无意中发现了一个系列教程:「 Let's Build A Simple Interpreter 」,简称 lsbasi。本来只是随便翻翻,但刚看完 Part-1 就发现作者 Ruslan Spivak 不仅是一个出色的软件工程师,文笔也相当不错,更难得的是他对学习这件事本身有着很深入的理解,这些见解甚至反馈到了这套教程的设计上。

2021-11-28
思考7 min

Make It Stick - 学习本身是一件值得思考的事情

前段时间,我的朋友「肚子」向我推荐了 Make It Stick: The Science of Successful Learning 这本书 (以下简称 MIS),读毕感觉相见恨晚。该书的讨论主题是学习这件事情本身,即研究人类学习的特点,找到适合人类的高效学习策略。如果用一句话向其它朋友推荐这本书,我想这句话一定是: 学习本身是一件值得思考的事情 。

2021-07-24
思考16 min

对话系统-101

今年 6 月底,由于工作需要,花了两周时间调研对话系统,并在公司内部做了一次调研报告。本文意在将此报告整理成文字版,算是对这段时间付出的一个交代。

2021-05-23
思考7 min

Born a Crime - 崔娃语录谈

因为之前在 Youtube 和 B 站上零星地看了一些 Trevor Noah 的 stand-up 和 Daily Show,加上最近在伴鱼 App 上与来自南非的老师学英语,我在大约四月中旬决定读一读「Born a Crime」这本书,书的内容本来并不多,但个人时间安排原因使得这个过程变得很长,直到昨天终于读完。

2021-05-09
思考23 min

代码搜索引擎:基础篇

Google 内部曾对工程师做一次 调研 ,发现平均每位工程师每天会进行 5.3 次代码搜索会话 (session),执行 12 个代码搜索请求;在 Github/Gitlab 等仓库托管服务中,搜索是工程师最常用的功能之一。

2021-03-04
实践14 min

调用链追踪系统在伴鱼:实践篇

此文同时发表在 伴鱼技术博客 上 在 理论篇 中,我们介绍了伴鱼在调用链追踪领域的调研工作,本篇继续介绍伴鱼的调用链追踪实践。在正式介绍前,简单交代一下背景:2015 年,在伴鱼服务端起步之时,技术团队就做出统一使用 Go 语言的决定。这个决定的影响主要体现在: 内部基础设施无需做跨语言支持 技术选型会有轻微的语言倾向

2020-12-20
思考22 min

调用链追踪系统的设计维度

本文将调用链追踪系统的设计维度归结于以下 5 个:调用链数据模型、元数据结构、因果关系、采样策略以及数据可视化。我们可以把这 5 个维度当作一个分析框架,用它帮助我们在理论上解构市面上任意一个调用链追踪系统,在实践中根据使用场景进行技术选型和系统设计。如果你对调研相关系统很感兴趣,也欢迎参与到 Database of Tracing Systems 项目中,一起调研市面上的项目,建立起调用链追踪系统的数据库。

2020-11-29
思考24 min

So, you want to trace your distributed system? Key design insights from years of practical experience (2014)

本文主要介绍一篇关于调用链追踪系统设计的论文。行文会尊从原论文的结构,但不是逐字翻译,以意译和加入个人理解的转述为主。

2020-10-05
实践9 min

如何在 Golang 项目中处理好错误

造一辆能跑在路上的车并非难事,但要这辆车能在各种路况、气候和突发事件下安全行驶,事情就不再简单。如果把写程序比喻成造车,构建程序的主要功能就是让车跑起来,而处理好错误就是让车安全地跑。 错误是程序的重要组成部分,能否在程序中处理好错误决定了软件的质量上限 。在这篇博客中,我将介绍个人在 Golang 项目中错误处理的思考。

2020-09-20
思考10 min

TiDB 为什么要用 Apache Arrow - 一个门外汉的思考

最近在阅读 TiDB 源码 util/chunk package 的过程中,看到了 Apache Arrow 这个项目 (下文简称 Arrow): // Chunk stores multiple rows of data in Apache Arrow format. // See https://arrow.apache.org/docs/format/Columnar.html#physical-memory-layout //…

2020-07-21
思考22 min

The Anatomy of a Large-Scale Hypertextual Web Search Engine (1998)

引言 最近因为工作的关系接触 ElasticSearch,发现搜索引擎也是计算机应用的一个有意思的分支。于是通过 Freiburg 的 Information Retrieval 公开课开始系统地了解信息检索这个领域,感觉收获颇丰。周末一时兴起,上 Google Research 找到了 Google 的开山之作,近距离地感受一下 19800+ 引用量、造就如今 Google 万亿市值的这篇文章。

2020-07-12
思考10 min

I ❤ Logs - 以日志为中心的系统设计理念

I ❤ Logs 出版于 2014 年,是一本很短小的书,100 页不到,利用这周的零散时间就看完了。作者 Jay Kreps ,是前 LinkedIn 的 Principal Staff Engineer,也是 LinkedIn 许多著名开源项目的负责人及联合作者,如 Kafka、Voldemort 等。他是现任 Confluent 的 CEO,主要工作在于围绕实时数据提供企业级服务支持。这本书算是 Jay Kreps 过去多年实践…

2020-06-21
思考8 min

Jaeger 的 Go 客户端的源码导读

Jaeger Walkthrough 系列文章之一,旨在深入理解 Jaeger 项目内部的实现细节。本文介绍的是 Jaeger 的 Go 客户端, jaeger-client-go 。

2020-06-13
思考9 min

Prometheus Alertmanager 的源码导读

Alertmanager 是 Prometheus 提供的报警分发平台,它主要满足的是报警的路由、分组、抑制、去重等常见需求。

2020-06-07
思考3 min

最美的程序:用 Lisp 写的 Lisp 解释器

本文来自于 2017 年 PWL NYC Meetup,作者的简介如下: William E. Byrd (@webyrd) is a Research Assistant Professor in the School of Computing at the University of Utah. He is co-author of 'The Reasoned Schemer', and is co-designer of the…

2020-05-10
实践11 min

报警平台的匹配器演进

简介 本文介绍伴鱼内部服务报警平台中匹配器模块的演进,及其利用 Lex 和 Yacc 同类工具构建 DSL 编译器的过程。是我和团队成员在伴鱼的质量工程小组的一小部分工作。

2020-04-05
思考30 min

What's Really New with NewSQL (2016)

在进入文章之前,应该先介绍两位重量级作者: Andrew Pavlo 和 Matthew Aslett 。Andrew 在 CMU 的计算机科学学院任教,主攻方向包括内存数据库、自动驾驶系统架构、事务处理系统和海量数据分析,他是 CMU Database Group 的核心成员,在 CMU 开设的两门课程 Database Systems (15-445/645) 和 Advanced Database System (15-721)…

2020-03-22
思考8 min

分布式锁方案:效率与正确的权衡

提到分布式锁,很多人也许会脱口而出 redis ,可见利用 redis 实现分布式锁已被认为是最佳实践。这两天有个同事问我一个问题:“如果某个服务拿着分布式锁的时候,redis 实例挂了怎么办?重启以后锁丢了怎么办?利用主从可以吗?加 fsync 可以吗?” 因此我决定深究这个话题。

2020-03-15
思考14 min

Kafka: a Distributed Messaging System for Log Processing (2011)

论文引用量:744 (截止至 2020-03-15) Kafka 是开发者耳熟能详的开源项目,它已经成为近年来互联网公司必不可少的基础组件。Kafka 得名于作家 Franz Kafka,大概是因为二者都比较擅长写日志 : )。它孵化于 LinkedIn 内部,在 2011 年被捐赠给 Apache 基金会,2012 年末正式从 Apache Incubator 中毕业。本文于 2011 年发表于 NetDB workshop,如今原…

2020-03-08
思考10 min

Scaling Memcache at Facebook (2013)

本文介绍 FB 基于 memcached 构建统一缓存层的最佳实践。全文递进式地讲述 单集群 (Single Front-end Cluster) 、 多集群 (Multiple Front-end Clusters) 、 多区域 (Multiple Regions) 环境下遇到的问题和相应的解决方案。尽管整个解决方案以 memcached 为基本单元,但我们可以任意地将 memcached 替换成 redis、boltDB、leve…

2020-02-27
思考12 min

Prometheus TSDB 的存储层演进 —— PromConf 演讲笔记

注:如果只想了解 Prometheus TSDB 的存储层现状,可以直接移步 Ganesh Vernekar 的博客 ,他写了 7 篇系列文章介绍这个主题。 Prometheus 无疑是时下最流行的监控平台,它负责定期从不同的采集目标拉取样本数据,然后持久化到内建的时序数据库中,向外部提供便捷的查询接口。本文主要探讨的是 Prometheus 存储层的演进过程,整理自 Prometheus 团队在历届 PromConf 上的分享以及相…

2020-02-26
思考9 min

用 LSM Tree 实现一个键值数据库 —— GopherConf 2017 演讲笔记

Background 数据库中的各种奇技淫巧,实际上都来自于内存与磁盘的读写模式和性能区别。

2020-02-19
思考13 min

缓存管理策略综述

在计算机系统设计实践中,我们常常会遇到下图所示架构: 为了解决单个存储器读吞吐无法满足要求的问题,常常需要在存储器上面增加一个或多个缓存。但由于相同的数据被复制到一个或多个地方,就容易引发数据一致性问题。

2020-02-18
思考4 min

Consistent Hashing and Random Trees (1997)

论文作者的贡献主要包含两部分:Consistent Hashing 和 Random Trees。Consistent Hashing 主要用于解决分布式哈希表 (Distributed Hash Table, DHT) 的桶增减带来的重新哈希问题;Random Trees 主要用于分布式缓存中的热点问题,它利用了 Consistent Hashing。下文主要关注 Consistent Hashing。

2020-02-18
思考3 min

Dynamic Hash Tables (1988)

摘要 Linear Hashing 和 Spiral Storage 是两种动态哈希算法。这两种算法最初都是为了优化外部存储 (secondary/external storage) 数据访问而设计的。本文将这两种算法引入到内存中,即键值数据可以一次性读入内存的场景,对比、分析二者之间,以及与其它动态哈希算法的性能。实验结果表明:Linear Hashing 的性能上要优于 Spiral Storage,实现难度上要小于 Spiral…

2020-02-17
思考6 min

Dapper, a Large-Scale Distributed Systems Tracing Infrastructure (2010)

早在 2008 年,Google 就已开始分布式调用链追踪的工作,经过两年的打磨后,Dapper 系统问世,并通过这篇文章将其设计公之于众。遗憾的是,Dapper 并不是开源项目,但它的设计理念依然深刻影响到后来的 Jaeger、Zipkin 等开源分布式追踪项目,以及相关的标准 Opentracing、OpenTelemetry。 本文不是原文的精准翻译,而是一次重述和简述,旨在记录分布式调用链追踪要解决的核心问题和潜在解决方案。

2020-02-17
思考4 min

LFU Implementation With O(1) Complexity (2010)

Abstract 缓存置换算法 (Cache Eviction Algorithm) 在操作系统、数据库以及其它系统中被广泛用于缓存置换模块,当缓存空间不足时,它利用局部性原理 (Principle of Locality) 预测未来数据的使用模式,将最不可能被访问的数据清出从而提高缓存命中率。目前已经存在的缓存置换算法包括 MRU (Most Recently Used)、MFU (Most Frequently Used)、LRU…

2020-02-17
思考10 min

Time, Clocks, and the Ordering of Events in a Distributed System (1978)

简介 本文是分布式系统理论的开山鼻祖、2013 年图灵奖获得者 Lamport 的成名作,也是分布式计算领域杰出论文最佳影响力奖 Dijkstra Prize 的第一篇论文,高达 11692 的引用量(截至 2019/12/08)足以证明其广泛的影响力: 本文主要讨论 3 个话题: 分布式系统中的事件偏序 利用逻辑时钟实现事件偏序 利用逻辑时钟实现事件全序

2020-02-16
思考13 min

Gorilla: A Fast, Scalable, In-Memory Time Series Database (2015)

Abstract 在大型微服务架构中,服务监控和实时分析需要大量的时序数据。存储这些时序数据最高效的方案就是使用时序数据库 (TSDB)。设计时序数据库的重要挑战之一便是在效率、扩展性和可靠性中找到平衡。