<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>编程沉思录 - Featured</title><description>我自己比较满意、愿意推荐给你看的文章。</description><link>https://cyhone.com/</link><item><title>博客升级了~</title><link>https://cyhone.com/articles/blog-upgrade/</link><guid isPermaLink="true">https://cyhone.com/articles/blog-upgrade/</guid><description>基于Astro，从零重新实现</description><pubDate>Sat, 09 May 2026 13:30:19 GMT</pubDate></item><item><title>C++如何计算普通类型的 Hash 值：基于 gcc/clang 源码分析</title><link>https://cyhone.com/articles/hash-key/</link><guid isPermaLink="true">https://cyhone.com/articles/hash-key/</guid><description>当 int/long/float/指针/std::string 作为 `std::unordered_map` 的 key 时，C++底层是如何计算 hash 值的？

gcc/clang 作为使用最多的两种编译器和标准库，它们在这个问题的实现上略有差异。本文将基于二者的源码进行对比分析。
&lt;!--more--&gt;

## std::string
在深入讨论其他类型的 hash 实现之前，我们首先分</description><pubDate>Sat, 06 Sep 2025 21:08:06 GMT</pubDate></item><item><title>std::any 的性能开销：基于 libstd++ 源码分析</title><link>https://cyhone.com/articles/std-any/</link><guid isPermaLink="true">https://cyhone.com/articles/std-any/</guid><description>C++17 中引入了 `std::any`，可以非常方便地将任意类型的变量放到其中，做到安全的类型擦除。然而万物皆有代价，这种灵活性背后必然伴随着性能取舍。

std::any 的实现本身也并不复杂，本文将基于 [libstd++ 标准库源码](https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/an</description><pubDate>Tue, 04 Mar 2025 09:41:54 GMT</pubDate></item><item><title>从源码角度解读 enable_shared_from_this</title><link>https://cyhone.com/articles/enable_shared_from_this/</link><guid isPermaLink="true">https://cyhone.com/articles/enable_shared_from_this/</guid><description>我们在使用 C++ 的时候，有时会需要在类的内部获取自身的 shared_ptr，这就会用到 `std::enable_shared_from_this`。在实际使用过程中，`std::enable_shared_from_this` 有三个陷阱需要注意：
&lt;!--more--&gt;
1. 不能在构造函数中使用 shared_from_this(), 否则会抛出 std::bad_weak_ptr 异</description><pubDate>Fri, 03 Jan 2025 22:41:54 GMT</pubDate></item><item><title>Context的错误使用引发Panic的问题复盘</title><link>https://cyhone.com/articles/context-to-panic/</link><guid isPermaLink="true">https://cyhone.com/articles/context-to-panic/</guid><description>我们有这么一段业务代码，在 Gin 的 API Handler 中，开了一个子 goroutine 写 DB，代码大概是这样：
&lt;!--more--&gt;

```go
package main

import (
    &quot;github.com/gin-gonic/gin&quot;
    &quot;gorm.io/gorm&quot;
)

var db *gorm.DB

func ServerHandler(c *gi</description><pubDate>Mon, 06 May 2024 17:25:54 GMT</pubDate></item><item><title>Go 1.22 可能将改变 for 循环变量的语义</title><link>https://cyhone.com/articles/go-for-loop-var/</link><guid isPermaLink="true">https://cyhone.com/articles/go-for-loop-var/</guid><description>几乎世界上每个 Golang 程序员都踩过一遍 for 循环变量的坑，而这个坑的解决方案已经作为实验特性加入到了 Go 1.21 中，并且有望在 Go 1.22 中完全开放。
&lt;!--more--&gt;
举个例子，有这么段代码：
```go
var ids []*int
for i := 0; i &lt; 10; i++ {
	ids = append(ids, &amp;i)
}

for _, item :=</description><pubDate>Wed, 29 Nov 2023 13:05:01 GMT</pubDate></item><item><title>剖析Golang Bigcache的极致性能优化</title><link>https://cyhone.com/articles/bigcache/</link><guid isPermaLink="true">https://cyhone.com/articles/bigcache/</guid><description>[Bigcache](https://github.com/allegro/bigcache)是用Golang实现的本地内存缓存的开源库，主打的就是**可缓存数据量大，查询速度快。** 在其官方的介绍文章[《Writing a very fast cache service with millions of entries in Go》](https://blog.allegro.tech/201</description><pubDate>Sat, 25 Nov 2023 19:25:54 GMT</pubDate></item><item><title>os.Chmod 时到底用 777 还是 0777？</title><link>https://cyhone.com/articles/0777-or-777/</link><guid isPermaLink="true">https://cyhone.com/articles/0777-or-777/</guid><description>问题是这样的：我在代码里面调用了 `os.Chmod(&quot;test.txt&quot;, 777)`，希望把该文件的读写及执行权限对所有用户开放。
&lt;!--more--&gt;

执行完代码，顺手 ls 看了下。如下：
```shell
$ ls -l test.txt
-r----x--x  1 cyhone  1085706827  0 Jun 20 13:27 test.txt
```
结果出乎意料，不仅文件</description><pubDate>Sun, 20 Jun 2021 13:30:19 GMT</pubDate></item><item><title>一个 Gin 缓存中间件的设计与实现</title><link>https://cyhone.com/articles/gin-cache/</link><guid isPermaLink="true">https://cyhone.com/articles/gin-cache/</guid><description>我们在开发 HTTP Server 的时候，经常有对接口内容做缓存的需求。例如，对于某些热点内容，我们希望做 1 分钟内的缓存。短期内缓存相同内容不会对业务造成实质影响，同时也会降低系统的整体负载。
&lt;!--more--&gt;

有时我们需要把缓存逻辑放在 Server 内部，而非网关侧如 Nginx 等，是因为这样我们可以根据需要便捷地清除缓存，或者可以使用 Redis 等其他存储介质作为缓存后端。</description><pubDate>Mon, 14 Jun 2021 21:40:06 GMT</pubDate></item><item><title>高性能服务之优雅终止</title><link>https://cyhone.com/articles/service-graceful-shutdown/</link><guid isPermaLink="true">https://cyhone.com/articles/service-graceful-shutdown/</guid><description>「优雅终止」指的是当服务需要下线或者重启时，通过一些措施和手段，一方面能够让其他服务尽快的感知到当前服务的下线，另一方面也尽量减小对当前正在处理请求的影响。优雅终止可提升服务的高可用，减少下线造成的服务抖动，提升服务稳定性和用户体验。
&lt;!--more--&gt;

下线服务不仅仅是运维层面的工作，需要整个 RPC 实现、服务架构以及运维体系的配合，才能完美的实现服务的优雅下线。本文将基于服务下线的整个</description><pubDate>Thu, 18 Mar 2021 20:55:19 GMT</pubDate></item><item><title>Elasticsearch 学习：入门篇</title><link>https://cyhone.com/articles/introduction-of-elasticsearch/</link><guid isPermaLink="true">https://cyhone.com/articles/introduction-of-elasticsearch/</guid><description>Elasticsearch 是一个分布式搜索引擎，底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节，提供了分布式特性，同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户，被用在网站搜索、日志分析等诸多方面。由于 ES 强大的横向扩展能力，甚至很多人也会直接把 ES 当做 NoSQL 来用。
&lt;!--more--</description><pubDate>Wed, 11 Mar 2020 13:00:54 GMT</pubDate></item><item><title>个人博客及公众号常用工具</title><link>https://cyhone.com/articles/blog-tools/</link><guid isPermaLink="true">https://cyhone.com/articles/blog-tools/</guid><description>本文整理和记录下自己在运营 [个人博客](cyhone.com) 以及公众号时常使用到的一些工具。主要包含以下方面：
1. 中英文空格的自动排版
2. 微信公众号如何使用 markdown 发布
3. 绘图工具
4. 图片压缩工具
5. 如何测试网站的打开速度以及针对性优化

&lt;!--more--&gt;
# 中英文排版及相关工具
在中英文排版最重要的就是中英文之间的空格，Github 有一个热门仓库《</description><pubDate>Sun, 08 Mar 2020 16:58:54 GMT</pubDate></item><item><title>libco 的定时器实现：时间轮</title><link>https://cyhone.com/articles/time-wheel-in-libco/</link><guid isPermaLink="true">https://cyhone.com/articles/time-wheel-in-libco/</guid><description>定时器是网络框架中非常重要的组成部分，往往可以利用定时器做一些超时事件的判断或者定时清理任务等。
&lt;!--more--&gt;

定时器有许多经典高效的实现。例如，libevent 采用了最小堆实现定时器，redis 则结合自己场景直接使用了简单粗暴的双向链表。

时间轮也是一种非常经典的定时器实现方法。Linux 2.6 内核之前就采用了多级时间轮作为其低精度定时器的实现。而在微信的协程库 libco</description><pubDate>Sun, 15 Dec 2019 13:17:26 GMT</pubDate></item><item><title>FileBeat-Log 相关配置指南</title><link>https://cyhone.com/articles/usage-of-filebeat-log-config/</link><guid isPermaLink="true">https://cyhone.com/articles/usage-of-filebeat-log-config/</guid><description>本文主要介绍 Filebeat 7.5 版本中 Log 相关的各个配置项的含义以及其应用场景。

一般情况下，我们使用 log input 的方式如下，只需要指定一系列 paths 即可。
```yaml
filebeat.inputs:
- type: log
  paths:
    - /var/log/messages
    - /var/log/*.log
```
但其实除了基本的 p</description><pubDate>Tue, 26 Nov 2019 20:36:54 GMT</pubDate></item><item><title>Redis 事件循环器 (AE) 实现剖析</title><link>https://cyhone.com/articles/analysis-of-redis-ae/</link><guid isPermaLink="true">https://cyhone.com/articles/analysis-of-redis-ae/</guid><description>Redis 作为一个单线程高性能的内存缓存 Server 而被人熟知。作为一个典型的 Reactor 式网络应用，Redis 能够达到如此高的性能，必然要依靠足够可靠的事件循环库。
Redis 内置了一个高性能事件循环器，叫做 AE。其定义和实现可以在 `ae*.h/cpp` 这些文件中找到。

AE 本身就是 Redis 的一部分，所以整体设计原则就是够用就行。也正因为这个背景，AE 的代码才可</description><pubDate>Wed, 20 Nov 2019 11:16:54 GMT</pubDate></item><item><title>Elastic-Filebeat 实现原理剖析</title><link>https://cyhone.com/articles/analysis-of-filebeat/</link><guid isPermaLink="true">https://cyhone.com/articles/analysis-of-filebeat/</guid><description>Filebeat 是使用 Golang 实现的轻量型日志采集器，也是 Elasticsearch stack 里面的一员。本质上是一个 agent，可以安装在各个节点上，根据配置读取对应位置的日志，并上报到相应的地方去。

Filebeat 的可靠性很强，可以保证日志 At least once 的上报，同时也考虑了日志搜集中的各类问题，例如日志断点续读、文件名更改、日志 Truncated 等。</description><pubDate>Fri, 15 Nov 2019 02:55:00 GMT</pubDate></item><item><title>Golang 标准库限流器 time/rate 使用介绍</title><link>https://cyhone.com/articles/usage-of-golang-rate/</link><guid isPermaLink="true">https://cyhone.com/articles/usage-of-golang-rate/</guid><description>&gt; 本主题为系列文章，分上下两篇。本文主要介绍 `time/rate` 的具体使用方法，另外一篇文章 [《Golang 限流器 time/rate 实现剖析》](https://www.cyhone.com/articles/analisys-of-golang-rate/) 则着重介绍其内部实现原理。

限流器是后台服务中的非常重要的组件，可以用来限制请求速率，保护服务，以免服务过载。
限流器的</description><pubDate>Sat, 02 Nov 2019 20:21:54 GMT</pubDate></item><item><title>微信 libco 协程库源码分析</title><link>https://cyhone.com/articles/analysis-of-libco/</link><guid isPermaLink="true">https://cyhone.com/articles/analysis-of-libco/</guid><description>libco 是微信后台开发和使用的协程库，同时也是极少数的直接将 C/C++ 协程运用到如此大规模的生产环境中的案例。

在 [《云风 coroutine 协程库源码分析》](http://www.cyhone.com/articles/analysis-of-cloudwu-coroutine/) 中，介绍了有栈协程的实现原理。相比云风的 coroutine，libco 在性能上号称可以调度千万</description><pubDate>Tue, 08 Oct 2019 17:58:26 GMT</pubDate></item><item><title>C++ 智能指针的正确使用方式</title><link>https://cyhone.com/articles/right-way-to-use-cpp-smart-pointer/</link><guid isPermaLink="true">https://cyhone.com/articles/right-way-to-use-cpp-smart-pointer/</guid><description>C++11 中推出了三种智能指针，unique_ptr、shared_ptr 和 weak_ptr，同时也将 auto_ptr 置为废弃 (deprecated)。
&lt;!--more--&gt;

但是在实际的使用过程中，很多人都会有这样的问题：
1. 不知道三种智能指针的具体使用场景
2. 无脑只使用 shared_ptr
3. 认为应该禁用 raw pointer(裸指针，即 Widget * 这种</description><pubDate>Sat, 05 Oct 2019 11:00:54 GMT</pubDate></item><item><title>C++ lambda 内 std::move 失效问题的思考</title><link>https://cyhone.com/articles/why-move-no-work-in-lambda/</link><guid isPermaLink="true">https://cyhone.com/articles/why-move-no-work-in-lambda/</guid><description>最近在写 C++ 时，有这样一个代码需求：在 lambda 中，将一个捕获参数 move 给另外一个变量。
看似一个很简单常规的操作，然而这个 move 动作却没有生效。

具体代码如下：

```cpp
std::vector&lt;int&gt; vec = {1,2,3};

auto func = [=](){
    auto vec2 = std::move(vec);
    std::cout</description><pubDate>Sun, 29 Sep 2019 18:07:00 GMT</pubDate></item><item><title>云风 coroutine 协程库源码分析</title><link>https://cyhone.com/articles/analysis-of-cloudwu-coroutine/</link><guid isPermaLink="true">https://cyhone.com/articles/analysis-of-cloudwu-coroutine/</guid><description>随着 Golang 的兴起，协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。

云风实现了一套 [C 语言的协程库](https://github.com/cloudwu/coroutine/)，整体背景可以参考其 [博客](https://blog.codingnow.com/2012/07/c_coroutine.html</description><pubDate>Thu, 19 Sep 2019 14:26:19 GMT</pubDate></item><item><title>WebSocket 订单推送稳定性优化方案</title><link>https://cyhone.com/articles/optimization-of-websocket-push-system/</link><guid isPermaLink="true">https://cyhone.com/articles/optimization-of-websocket-push-system/</guid><description>[微信云支付 Android 智能 POS](https://cloud.tencent.com/document/product/569/33102) 使用 WebSocket 实现了用户订单的实时推送。即，顾客在扫描了门店的付款码，客户端会随即进行语音播报和打印等动作。
&lt;!--more--&gt;

客户端利用 WebSocket 与后端维持长连接，当后端收到该门店订单时，即将成功态的订单通过对应</description><pubDate>Sat, 17 Aug 2019 14:36:12 GMT</pubDate></item><item><title>深入理解网络 IO 模型</title><link>https://cyhone.com/articles/reunderstanding-of-non-blocking-io/</link><guid isPermaLink="true">https://cyhone.com/articles/reunderstanding-of-non-blocking-io/</guid><description>在进行 Linux 网络编程开发的时候，免不了会涉及到 IO 模型的讨论。《Unix 网络编程》一书中提到的几种 IO 模型，我们在开发过程中，讨论最多的应该就是三种： ` 阻塞 IO`、` 非阻塞 IO` 以及 ` 异步 IO`。

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

# 网络 IO 概念准备
</description><pubDate>Sun, 04 Nov 2018 02:50:00 GMT</pubDate></item><item><title>客户端秒级时间同步方案</title><link>https://cyhone.com/articles/client-time-calibration/</link><guid isPermaLink="true">https://cyhone.com/articles/client-time-calibration/</guid><description>在客户端开发中，往往会有一些功能对时间要求比较严格，客户端需要获取到当前最准确的时间。但由于客户端环境多种多样，我们无法保证直接在客户端设备上获取到的时间是最准确的时间。
对于某些问题设备来说，设备时间与比当前实际的时间差了几个小时，甚至几天的情况都存在。倘若某功能依赖于当前时间，而客户端所提供的时间不准，就往往会给客户造成一些困扰。

那么，客户端如何能够获取到当前最准确的时间呢？
&lt;!--mo</description><pubDate>Thu, 25 Oct 2018 20:08:06 GMT</pubDate></item><item><title>muduo 源码剖析</title><link>https://cyhone.com/articles/analysis-of-muduo/</link><guid isPermaLink="true">https://cyhone.com/articles/analysis-of-muduo/</guid><description>[muduo](https://github.com/chenshuo/muduo)是 [陈硕](http://chenshuo.com) 大神个人开发的 C++ 的 TCP 网络编程库。muduo 基于 Reactor 模式实现，Reactor 模式也是目前大多数 Linux 端高性能网络编程框架和网络应用所选择的主要架构，例如 Redis 和 Java 的 Netty 库等。

陈硕的《Lin</description><pubDate>Tue, 12 Jun 2018 23:51:37 GMT</pubDate></item><item><title>自动生成数据库文档小工具的诞生</title><link>https://cyhone.com/articles/db-doc-generator/</link><guid isPermaLink="true">https://cyhone.com/articles/db-doc-generator/</guid><description>最近我用 Golang 开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时，经常需要为数据库写说明文档，对于稍微有些规模的项目来说，就动辄几十张上百张数据表，开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。

项目地址在 [这里](https://github.com/chenyahui/db_doc_gen</description><pubDate>Tue, 30 Jan 2018 19:00:54 GMT</pubDate></item><item><title>ClassViewer 的介绍及实现</title><link>https://cyhone.com/articles/classviewer/</link><guid isPermaLink="true">https://cyhone.com/articles/classviewer/</guid><description>[ClassViewer](https://chenyahui.github.io/ClassViewer)是我最近开发的一个用于展示 jvm class 字节码的小工具。它是一个单纯的静态网页，完全使用浏览器端的 Javascript 开发。之所以开发这款工具，是因为我在开发 [ToyJVM](https://github.com/chenyahui/ToyJVM) 的时候，需要常常校验 cla</description><pubDate>Mon, 01 Jan 2018 11:45:00 GMT</pubDate></item><item><title>首次半马记</title><link>https://cyhone.com/articles/my-first-half-marathon/</link><guid isPermaLink="true">https://cyhone.com/articles/my-first-half-marathon/</guid><description>4 月 9 号，在武汉参加了人生第一次半程马拉松，风里雨里的 21.0975 公里。虽然已时隔一周，但想到那天一路的奔跑、疲惫、欣喜，还是想记记这半马的流水账。
&lt;!--more--&gt;

# 赛前训练
关于赛前训练这一块，我自己真的是非常的汗颜，被自己的记性给坑了一把。本来 4 月 9 号的马拉松，硬是记成了 5 月 9 号。所以本来安排的提前 1 个月训练半马，也恰好完美地错过。汉马马拉松官网提</description><pubDate>Mon, 17 Apr 2017 22:20:47 GMT</pubDate></item><item><title>结合 Guava 源码解读布隆过滤器</title><link>https://cyhone.com/articles/introduction-of-bloomfilter/</link><guid isPermaLink="true">https://cyhone.com/articles/introduction-of-bloomfilter/</guid><description>&gt; BloomFilter（布隆过滤器）是一种可以高效地判断元素是否在某个集合中的算法。

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


在工业界中，Google 著名的分布式数据库 BigTable 也用了布隆过滤器来查找不存在的行或列，以减少磁盘查找的 IO 次数；</description><pubDate>Tue, 07 Feb 2017 16:51:51 GMT</pubDate></item><item><title>服务器校园网登录验证解决方案</title><link>https://cyhone.com/articles/whu-cs-network-auth/</link><guid isPermaLink="true">https://cyhone.com/articles/whu-cs-network-auth/</guid><description>前两天把实验室的一台旧台式机装上了 Ubuntu Server，打算当作测试服务器使用着玩。
装上之后意识到一个严重的问题：实验室电脑连接外网时候需要打开浏览器输入学号进行认证。

&lt;!-- more --&gt;

而对于服务器版的 Ubuntu Server 来说只有黑乎乎的命令行界面。根本没有浏览器可以打开，所以网络认证就无从谈起。。

就在准备打算重装一个 Ubuntu Desktop 的时候，</description><pubDate>Sun, 25 Sep 2016 22:28:54 GMT</pubDate></item><item><title>第一篇博客</title><link>https://cyhone.com/articles/hello-world/</link><guid isPermaLink="true">https://cyhone.com/articles/hello-world/</guid><description>## 为什么会想到建立一个博客:
在此博客之前，我其实也用过新浪博客、CSDN、博客园，作为个人博客的载体，但对每个博客都并不是特别的满意。原因大概有下面几条：
+ 没有美观友好的支持代码。
+ 广告多。
+ 管理复杂，但可控性差。

目前该博客是使用 hexo+Next 主题 + Github 进行搭建。
事实上，当开始接触使用 hexo 时，我觉得满足了我对博客的诸多要求。我对它的为程序员而生</description><pubDate>Wed, 16 Sep 2015 16:08:06 GMT</pubDate></item></channel></rss>