七月2026 2 条
摘录

养成费米估算的习惯,主动查证关键数据,并运用上下限分析法。我注意到许多我认识的最聪明的人都会这样做:他们不会轻信任何说辞,而是自行验证其合理性。例如,听到某个事实时,他们会亲自查证以确保属实 —— 因为人们引用的内容常常存在虚假或片面性。

大多数人根本不这样做 —— 他们不进行 “量化思考”,结果很容易上当受骗。推特上时不时会流行这样的梗:“如果伊隆把造火箭的钱分给每个美国人,等等” 这类言论会疯传,就是因为人们没有算账。

— Nabeel S. Qureshi

费米估算由物理学家费米提出,他曾在课堂上问学生:“芝加哥有多少钢琴调音师?”—— 没人能查数据,但通过拆解估算,答案数量级和实际值高度吻合 。

  • 芝加哥人口 ≈ 300 万
  • 平均家庭 4 人 → 75 万户
  • 约 1/3 户有钢琴 → 25 万台
  • 每台每年调 1 次 → 年需求 25 万次
  • 调音师每天 4 单、每年 200 天 → 每人年处理 800 单
  • 25 万 ÷ 800 ≈ ~300 人
  • 实际登记数约 200-300 人,数量级完全命中。

费米估算的原理:

  • 降维拆解:把未知问题拆成可拍脑袋的子问题
  • 数量级优先:关注 10^n,不纠结 ±30%
  • 交叉校验:用不同路径算同一件事,看是否落在同一量级
六月2026 6 条
摘录

定义你的,不是你的本质,而是你的所作所为。

— 《蝙蝠侠》

  • 虽然我做了坏事,但我内心是个好人。
  • 是生活所迫,让我做了这个那个,但我本质上是这个那个,现在不是真正的我。但依然有很多人为了面临更大压力的时候也从未妥协。选择妥协的那个,就是真正的你
五月2026 4 条
九月2025 1 条
八月2025 7 条
摘录

要锻炼出创造性的身体,去看电影、听音乐会、去美术馆、看别人的建筑,然后要有想做得比他们更好的意愿,超越前人的勇气,体力衰退了,竞争意识就会变弱。没有了创造性的身体,竞争意识就没了。这两个是一回事,要同时锻炼身体和意志。

— 安藤忠雄 《武士建筑师》

摘录

我捐出了所有来自苹果的财富,因为财富和权力并非我的追求。我享受生活的乐趣——在我的出生地圣何塞,我资助了许多重要的博物馆和艺术团体,他们以我的名字命名了一条街道以示认可。如今我从事公开演讲并成为行业顶尖,虽然不清楚具体资产数额,但经过 20 年的演讲事业,可能积累了约 1000 万美元和几处房产。我从不寻找任何避税手段,通过劳动获得的收入缴纳约 55%的综合税负。我是世界上最快乐的人。对我而言,生活从来不是关于成就,而是关于快乐,那正是笑容减去愁容的简单公式。这些人生理念在我 18 到 20 岁时就已形成,而我始终坚守至今。

— 沃兹尼亚克

最近看了《成为乔布斯》这本书以及听了播客半拿铁的《苹果简史》。对沃兹的印象就是他和乔布斯最开始的组合就是天使+魔鬼,沃兹是毫无疑问的赤子。沃兹的这个留言更加印证了这个印象。

今天恰好是 woz 的生日,看到了他在论坛上的留言,再次感叹他的人生态度。

摘录

我们做任何决定,最终都有可能会后悔会遗憾,但是面对多个选择时,我们应该选择让自己后悔或者遗憾最少的那个。

— 贝索斯

摘录

股市是世界上最可爱的东西。对于股市你可以随便怎么想,怎么想都可以,甚至觉得”川大智胜”和川普有关系都可以。

一切观点、一切想法都可以掏钱验证。如果你是对的,那就不光是对的,还能赚钱。所以如果你这么坚定地相信,就没道理不掏钱。除非,你其实也没那么相信。

社会是一个周期更长的股市。每个人最终都会在这个股市里得到和自己的想法相匹配的回报,一切想法也最终都会变成收益或亏损。而且社会这个股市是由不得你不掏钱的,退不了,缩不了,怂不了。 不光是钱,你的整个人生都会被投入进去。所以收获的也不光是钱,是你整个人生的悲喜荣哀。

所以,你可以随便怎么想,怎么舒服怎么想,或者,认真地思考自己的每一个判断,每一个决定,想清楚自己要的到底是简单、爽,还是有更想要的东西。

— tombkeeper

三月2025 1 条
一月2025 1 条
文章 精选

从源码角度解读 enable_shared_from_this

我们在使用 C++ 的时候,有时会需要在类的内部获取自身的 shared_ptr,这就会用到 std::enable_shared_from_this。在实际使用过程中,std::enable_shared_from_this 有三个陷阱需要注意:

五月2024 1 条
十一月2023 3 条
七月2021 1 条
六月2021 2 条
文章 精选

一个 Gin 缓存中间件的设计与实现

我们在开发 HTTP Server 的时候,经常有对接口内容做缓存的需求。例如,对于某些热点内容,我们希望做 1 分钟内的缓存。短期内缓存相同内容不会对业务造成实质影响,同时也会降低系统的整体负载。

三月2021 1 条
文章 精选

高性能服务之优雅终止

「优雅终止」指的是当服务需要下线或者重启时,通过一些措施和手段,一方面能够让其他服务尽快的感知到当前服务的下线,另一方面也尽量减小对当前正在处理请求的影响。优雅终止可提升服务的高可用,减少下线造成的服务抖动,提升服务稳定性和用户体验。

二月2021 2 条
一月2021 1 条
八月2020 1 条
六月2020 1 条
文章

Golang 定时器底层实现深度剖析

本文将基于 Golang 源码对 Timer 的底层实现进行深度剖析。主要包含以下内容:

  1. Timer 和 Ticker 在 Golang 中的底层实现细节,包括数据结构等选型。
  2. 分析 time.Sleep 的实现细节,Golang 如何实现 Goroutine 的休眠。

注:本文基于 go-1.13 源码进行分析,而在 go 的 1.14 版本中,关于定时器的实现略有一些改变,以后会再专门写一篇文章进行分析。

三月2020 2 条
文章 精选

Elasticsearch 学习:入门篇

Elasticsearch 是一个分布式搜索引擎,底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节,提供了分布式特性,同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户,被用在网站搜索、日志分析等诸多方面。由于 ES 强大的横向扩展能力,甚至很多人也会直接把 ES 当做 NoSQL 来用。

文章 精选

个人博客及公众号常用工具

本文整理和记录下自己在运营 个人博客 以及公众号时常使用到的一些工具。主要包含以下方面:

  1. 中英文空格的自动排版
  2. 微信公众号如何使用 markdown 发布
  3. 绘图工具
  4. 图片压缩工具
  5. 如何测试网站的打开速度以及针对性优化
二月2020 1 条
文章

Golang channel 源码深度剖析

channel 是 Golang 中一个非常重要的特性,也是 Golang CSP 并发模型的一个重要体现。简单来说就是,goroutine 之间可以通过 channel 进行通信。

channel 在 Golang 如此重要,在代码中使用频率非常高,以至于不得不好奇其内部实现。本文将基于 go 1.13 的源码,分析 channel 的内部实现原理。

十二月2019 1 条
十一月2019 6 条
文章 精选

FileBeat-Log 相关配置指南

本文主要介绍 Filebeat 7.5 版本中 Log 相关的各个配置项的含义以及其应用场景。

一般情况下,我们使用 log input 的方式如下,只需要指定一系列 paths 即可。

filebeat.inputs:
- type: log
  paths:
    - /var/log/messages
    - /var/log/*.log

但其实除了基本的 paths 配置外,log input 还有大概十几个配置项需要我们关注。

这些配置项或多或少都会影响到 Filebeat 的使用方式以及性能。虽然其默认值基本足够日常使用,但是还是需要深刻理解每个配置项背后的含义,这样才能够对其完全把控。

同时,在 filebeat 的日常线上运维中,也会涉及到这些配置参数的调节。

文章 精选

Redis 事件循环器 (AE) 实现剖析

Redis 作为一个单线程高性能的内存缓存 Server 而被人熟知。作为一个典型的 Reactor 式网络应用,Redis 能够达到如此高的性能,必然要依靠足够可靠的事件循环库。 Redis 内置了一个高性能事件循环器,叫做 AE。其定义和实现可以在 ae*.h/cpp 这些文件中找到。

AE 本身就是 Redis 的一部分,所以整体设计原则就是够用就行。也正因为这个背景,AE 的代码才可以简短干净,非常适合阅读和学习。

本文将基于 Redis 5.0.6 的源码分析下其事件循环器 (AE) 的实现原理。

同时本人也提供了一个 Redis 注释版,用以辅助理解 Redis 的源码。

文章 精选

Elastic-Filebeat 实现原理剖析

Filebeat 是使用 Golang 实现的轻量型日志采集器,也是 Elasticsearch stack 里面的一员。本质上是一个 agent,可以安装在各个节点上,根据配置读取对应位置的日志,并上报到相应的地方去。

Filebeat 的可靠性很强,可以保证日志 At least once 的上报,同时也考虑了日志搜集中的各类问题,例如日志断点续读、文件名更改、日志 Truncated 等。

Filebeat 并不依赖于 Elasticsearch,可以单独存在。我们可以单独使用 Filebeat 进行日志的上报和搜集。filebeat 内置了常用的 Output 组件, 例如 kafka、Elasticsearch、redis 等。出于调试考虑,也可以输出到 console 和 file。我们可以利用现有的 Output 组件,将日志进行上报。

当然,我们也可以自定义 Output 组件,让 Filebeat 将日志转发到我们想要的地方。

filebeat 其实是 elastic/beats 的一员,除了 filebeat 外,还有 HeartBeat、PacketBeat。这些 beat 的实现都是基于 libbeat 框架。

文章

uber-go 漏桶限流器使用与原理分析

uber 在 Github 上开源了一套用于服务限流的 go 语言库 ratelimit, 该组件基于 Leaky Bucket(漏桶) 实现。

我在之前写过一篇 《Golang 限流器 time/rate 实现剖析》,分析了 Golang 标准库中基于 Token Bucket 实现限流组件的 time/rate 原理,同时也讲了限流的一些背景。

相比于 TokenBucket 中,只要桶内还有剩余令牌,调用方就可以一直消费的策略。Leaky Bucket 相对来说更加严格,调用方只能严格按照预定的间隔顺序进行消费调用。(虽然 uber-go 对这个限制也做了一些优化,具体可以看下文详解)

还是老规矩,在正式讲其实现之前,我们先看下 ratelimit 的使用方法。

文章

Golang 标准库限流器 time/rate 实现剖析

限流器是微服务中必不缺少的一环,可以起到保护下游服务,防止服务过载等作用。上一篇文章 《Golang 限流器 time/rate 使用介绍》 简单介绍了 time/rate 的使用方法,本文则着重分析下其实现原理。建议在正式阅读本文之前,先阅读下上一篇文章。

上一篇文章讲到,time/rate 是基于 Token Bucket(令牌桶) 算法实现的限流。本文将会基于源码,深入剖析下 Golang 是如何实现 Token Bucket 的。其代码也非常简洁,去除注释后,也就 200 行左右的代码量。

同时,我也提供了 time/rate 注释版,辅助大家理解该组件的实现。

文章 精选

Golang 标准库限流器 time/rate 使用介绍

本主题为系列文章,分上下两篇。本文主要介绍 time/rate 的具体使用方法,另外一篇文章 《Golang 限流器 time/rate 实现剖析》 则着重介绍其内部实现原理。

限流器是后台服务中的非常重要的组件,可以用来限制请求速率,保护服务,以免服务过载。 限流器的实现方法有很多种,例如滑动窗口法、Token Bucket、Leaky Bucket 等。

其实 Golang 标准库中就自带了限流算法的实现,即 golang.org/x/time/rate。该限流器是基于 Token Bucket(令牌桶) 实现的。

简单来说,令牌桶就是想象有一个固定大小的桶,系统会以恒定速率向桶中放 Token,桶满则暂时不放。 而用户则从桶中取 Token,如果有剩余 Token 就可以一直取。如果没有剩余 Token,则需要等到系统中被放置了 Token 才行。

十月2019 2 条
文章 精选

微信 libco 协程库源码分析

libco 是微信后台开发和使用的协程库,同时也是极少数的直接将 C/C++ 协程运用到如此大规模的生产环境中的案例。

《云风 coroutine 协程库源码分析》 中,介绍了有栈协程的实现原理。相比云风的 coroutine,libco 在性能上号称可以调度千万级协程。 从使用上来说,libco 不仅提供了一套类 pthread 的协程通信机制,同时可以零改造地将三方库的阻塞 IO 调用进行协程化。

本文将从源码角度着重分析 libco 的高效之道。

在正式阅读本文之前,如果对有栈协程的实现原理不是特别了解,建议提前阅读 《云风 coroutine 协程库源码分析》

同时,我也提供了 libco 注释版,用以辅助理解 libco 的源码

九月2019 2 条
文章 精选

C++ lambda 内 std::move 失效问题的思考

最近在写 C++ 时,有这样一个代码需求:在 lambda 中,将一个捕获参数 move 给另外一个变量。 看似一个很简单常规的操作,然而这个 move 动作却没有生效。

具体代码如下:

std::vector<int> vec = {1,2,3};

auto func = [=](){
    auto vec2 = std::move(vec);
    std::cout << vec.size() << std::endl; // 输出:3
    std::cout << vec2.size() << std::endl; // 输出:3
};

代码可在 wandbox 运行。

我们期望的是,将对变量 vec 调用 std::move 后,数据将会移动至变量 vec2, 此时 vec 里面应该没有数据了。但是通过打印 vec.size() 发现 vec 中的数据并没有按预期移走。

这也就意味着,构造 vec2 时并没有按预期调用移动构造函数,而是调用了拷贝构造函数。

为什么会造成这个问题呢, 我们需要结合 std::movelambda 的原理看下。(最终的解决方案可以直接看 这里

文章 精选

云风 coroutine 协程库源码分析

随着 Golang 的兴起,协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。

云风实现了一套 C 语言的协程库,整体背景可以参考其 博客

这个协程库非常轻量级,一共也才 200 多行代码,使用上更贴近于 lua 的写法(众所周知,云风是知名的 lua 粉)。整体基于 ucontext 和共享栈模型实现了有栈协程,代码质量毋庸置疑,本文将详细剖析该协程库的实现原理。

同时,我也提供了 coroutine 注释版,辅助大家理解 coroutine 的代码。

八月2019 1 条
十一月2018 1 条
文章 精选

深入理解网络 IO 模型

在进行 Linux 网络编程开发的时候,免不了会涉及到 IO 模型的讨论。《Unix 网络编程》一书中提到的几种 IO 模型,我们在开发过程中,讨论最多的应该就是三种: 阻塞 IO 非阻塞 IO 以及 异步 IO

本文试图理清楚几种 IO 模型的根本性区别,同时分析了为什么在 Linux 网络编程中最好要用非阻塞式 IO。

十月2018 1 条
文章 精选

客户端秒级时间同步方案

在客户端开发中,往往会有一些功能对时间要求比较严格,客户端需要获取到当前最准确的时间。但由于客户端环境多种多样,我们无法保证直接在客户端设备上获取到的时间是最准确的时间。 对于某些问题设备来说,设备时间与比当前实际的时间差了几个小时,甚至几天的情况都存在。倘若某功能依赖于当前时间,而客户端所提供的时间不准,就往往会给客户造成一些困扰。

那么,客户端如何能够获取到当前最准确的时间呢?

六月2018 1 条
文章 精选

muduo 源码剖析

muduo陈硕 大神个人开发的 C++ 的 TCP 网络编程库。muduo 基于 Reactor 模式实现,Reactor 模式也是目前大多数 Linux 端高性能网络编程框架和网络应用所选择的主要架构,例如 Redis 和 Java 的 Netty 库等。

陈硕的《Linux 多线程服务器端编程》一书对 muduo 整个架构进行了非常详尽的介绍和分析,可以说是学习 muduo 源码和设计理念最好的资料了。

而本文则主要是从源码角度辅助理解整个 muduo 的实现,同时也姑且算是对 muduo 的一个小小的补充。

同时我也提供了一个 muduo 注释版,用以辅助理解 muduo 的源码。

一月2018 2 条
文章 精选

自动生成数据库文档小工具的诞生

最近我用 Golang 开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时,经常需要为数据库写说明文档,对于稍微有些规模的项目来说,就动辄几十张上百张数据表,开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。

项目地址在 这里

文章 精选

ClassViewer 的介绍及实现

ClassViewer是我最近开发的一个用于展示 jvm class 字节码的小工具。它是一个单纯的静态网页,完全使用浏览器端的 Javascript 开发。之所以开发这款工具,是因为我在开发 ToyJVM 的时候,需要常常校验 class 文件某一部分的字节码, 所以如果一款工具能够很方便的显示 class 文件各个部分的信息和字节码,对于 ToyJVM 的开发将会是一个非常大的帮助。

在开始写代码之前调研了一些类似的产品,主要有 jdk 自带的 javap、国外的 Java-Class-Viewer 以及国人开发的 classpy,它们都是非常不错的 class 文件分析工具,但是也存在着一些算不上缺陷的小问题。所以最终还是决定自己写一个适合自己小工具,同时也加深下 class 结构的理解。

在调研了目前的产品后,我也更加清晰了自己的目标。首先它的受众应该是有兴趣研究 jvm 的程序员,而它应该有这些特性:

  • 不依赖于特定操作系统平台 它应该具备基本的跨平台的能力,因为程序员的 Mac 和 Linux 使用率很高。
  • 无需复杂的安装和编译,无需用户有特定的知识背景 我不太希望用户拿到我的代码后,还需要安装相应的环境、了解一堆无关知识。

最终实现出来的工具是这样的:

四月2017 1 条
文章 精选

首次半马记

4 月 9 号,在武汉参加了人生第一次半程马拉松,风里雨里的 21.0975 公里。虽然已时隔一周,但想到那天一路的奔跑、疲惫、欣喜,还是想记记这半马的流水账。

二月2017 1 条
文章 精选

结合 Guava 源码解读布隆过滤器

BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法。

在很多日常场景中,都大量存在着布隆过滤器的应用。例如:检查单词是否拼写正确、网络爬虫的 URL 去重、黑名单检验,微博中昵称不能重复的检测等。

九月2016 1 条
文章 精选

服务器校园网登录验证解决方案

前两天把实验室的一台旧台式机装上了 Ubuntu Server,打算当作测试服务器使用着玩。 装上之后意识到一个严重的问题:实验室电脑连接外网时候需要打开浏览器输入学号进行认证。

九月2015 1 条
文章 精选

第一篇博客

为什么会想到建立一个博客:

在此博客之前,我其实也用过新浪博客、CSDN、博客园,作为个人博客的载体,但对每个博客都并不是特别的满意。原因大概有下面几条:

  • 没有美观友好的支持代码。
  • 广告多。
  • 管理复杂,但可控性差。

目前该博客是使用 hexo+Next 主题 + Github 进行搭建。 事实上,当开始接触使用 hexo 时,我觉得满足了我对博客的诸多要求。我对它的为程序员而生、高度可定制性非常喜欢。而且,如有机会,可以自己写出满意的主题使用。