博客升级了~
基于Astro,从零重新实现
基于Astro,从零重新实现
当 int/long/float/指针/std::string 作为 `std::unordered_map` 的 key 时,C++底层是如何计算 hash 值的? gcc/clang 作为使用最多的两种编译器和标准库,它们在这个问题的实现上略有差异。本文将基于二者的源码进行对比分析。 <!--more--> ## std::string 在深入讨论其他类型的 hash 实现之前,我们首先分
C++17 中引入了 `std::any`,可以非常方便地将任意类型的变量放到其中,做到安全的类型擦除。然而万物皆有代价,这种灵活性背后必然伴随着性能取舍。 std::any 的实现本身也并不复杂,本文将基于 [libstd++ 标准库源码](https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/an
我们在使用 C++ 的时候,有时会需要在类的内部获取自身的 shared_ptr,这就会用到 `std::enable_shared_from_this`。在实际使用过程中,`std::enable_shared_from_this` 有三个陷阱需要注意: <!--more--> 1. 不能在构造函数中使用 shared_from_this(), 否则会抛出 std::bad_weak_ptr 异
我们有这么一段业务代码,在 Gin 的 API Handler 中,开了一个子 goroutine 写 DB,代码大概是这样: <!--more--> ```go package main import ( "github.com/gin-gonic/gin" "gorm.io/gorm" ) var db *gorm.DB func ServerHandler(c *gi
几乎世界上每个 Golang 程序员都踩过一遍 for 循环变量的坑,而这个坑的解决方案已经作为实验特性加入到了 Go 1.21 中,并且有望在 Go 1.22 中完全开放。 <!--more--> 举个例子,有这么段代码: ```go var ids []*int for i := 0; i < 10; i++ { ids = append(ids, &i) } for _, item :=
[Bigcache](https://github.com/allegro/bigcache)是用Golang实现的本地内存缓存的开源库,主打的就是**可缓存数据量大,查询速度快。** 在其官方的介绍文章[《Writing a very fast cache service with millions of entries in Go》](https://blog.allegro.tech/201
问题是这样的:我在代码里面调用了 `os.Chmod("test.txt", 777)`,希望把该文件的读写及执行权限对所有用户开放。 <!--more--> 执行完代码,顺手 ls 看了下。如下: ```shell $ ls -l test.txt -r----x--x 1 cyhone 1085706827 0 Jun 20 13:27 test.txt ``` 结果出乎意料,不仅文件
我们在开发 HTTP Server 的时候,经常有对接口内容做缓存的需求。例如,对于某些热点内容,我们希望做 1 分钟内的缓存。短期内缓存相同内容不会对业务造成实质影响,同时也会降低系统的整体负载。 <!--more--> 有时我们需要把缓存逻辑放在 Server 内部,而非网关侧如 Nginx 等,是因为这样我们可以根据需要便捷地清除缓存,或者可以使用 Redis 等其他存储介质作为缓存后端。
「优雅终止」指的是当服务需要下线或者重启时,通过一些措施和手段,一方面能够让其他服务尽快的感知到当前服务的下线,另一方面也尽量减小对当前正在处理请求的影响。优雅终止可提升服务的高可用,减少下线造成的服务抖动,提升服务稳定性和用户体验。 <!--more--> 下线服务不仅仅是运维层面的工作,需要整个 RPC 实现、服务架构以及运维体系的配合,才能完美的实现服务的优雅下线。本文将基于服务下线的整个
Elasticsearch 是一个分布式搜索引擎,底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节,提供了分布式特性,同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户,被用在网站搜索、日志分析等诸多方面。由于 ES 强大的横向扩展能力,甚至很多人也会直接把 ES 当做 NoSQL 来用。 <!--more--
本文整理和记录下自己在运营 [个人博客](cyhone.com) 以及公众号时常使用到的一些工具。主要包含以下方面: 1. 中英文空格的自动排版 2. 微信公众号如何使用 markdown 发布 3. 绘图工具 4. 图片压缩工具 5. 如何测试网站的打开速度以及针对性优化 <!--more--> # 中英文排版及相关工具 在中英文排版最重要的就是中英文之间的空格,Github 有一个热门仓库《
定时器是网络框架中非常重要的组成部分,往往可以利用定时器做一些超时事件的判断或者定时清理任务等。 <!--more--> 定时器有许多经典高效的实现。例如,libevent 采用了最小堆实现定时器,redis 则结合自己场景直接使用了简单粗暴的双向链表。 时间轮也是一种非常经典的定时器实现方法。Linux 2.6 内核之前就采用了多级时间轮作为其低精度定时器的实现。而在微信的协程库 libco
本文主要介绍 Filebeat 7.5 版本中 Log 相关的各个配置项的含义以及其应用场景。 一般情况下,我们使用 log input 的方式如下,只需要指定一系列 paths 即可。 ```yaml filebeat.inputs: - type: log paths: - /var/log/messages - /var/log/*.log ``` 但其实除了基本的 p
Redis 作为一个单线程高性能的内存缓存 Server 而被人熟知。作为一个典型的 Reactor 式网络应用,Redis 能够达到如此高的性能,必然要依靠足够可靠的事件循环库。 Redis 内置了一个高性能事件循环器,叫做 AE。其定义和实现可以在 `ae*.h/cpp` 这些文件中找到。 AE 本身就是 Redis 的一部分,所以整体设计原则就是够用就行。也正因为这个背景,AE 的代码才可
Filebeat 是使用 Golang 实现的轻量型日志采集器,也是 Elasticsearch stack 里面的一员。本质上是一个 agent,可以安装在各个节点上,根据配置读取对应位置的日志,并上报到相应的地方去。 Filebeat 的可靠性很强,可以保证日志 At least once 的上报,同时也考虑了日志搜集中的各类问题,例如日志断点续读、文件名更改、日志 Truncated 等。
> 本主题为系列文章,分上下两篇。本文主要介绍 `time/rate` 的具体使用方法,另外一篇文章 [《Golang 限流器 time/rate 实现剖析》](https://www.cyhone.com/articles/analisys-of-golang-rate/) 则着重介绍其内部实现原理。 限流器是后台服务中的非常重要的组件,可以用来限制请求速率,保护服务,以免服务过载。 限流器的
libco 是微信后台开发和使用的协程库,同时也是极少数的直接将 C/C++ 协程运用到如此大规模的生产环境中的案例。 在 [《云风 coroutine 协程库源码分析》](http://www.cyhone.com/articles/analysis-of-cloudwu-coroutine/) 中,介绍了有栈协程的实现原理。相比云风的 coroutine,libco 在性能上号称可以调度千万
C++11 中推出了三种智能指针,unique_ptr、shared_ptr 和 weak_ptr,同时也将 auto_ptr 置为废弃 (deprecated)。 <!--more--> 但是在实际的使用过程中,很多人都会有这样的问题: 1. 不知道三种智能指针的具体使用场景 2. 无脑只使用 shared_ptr 3. 认为应该禁用 raw pointer(裸指针,即 Widget * 这种
最近在写 C++ 时,有这样一个代码需求:在 lambda 中,将一个捕获参数 move 给另外一个变量。 看似一个很简单常规的操作,然而这个 move 动作却没有生效。 具体代码如下: ```cpp std::vector<int> vec = {1,2,3}; auto func = [=](){ auto vec2 = std::move(vec); std::cout
随着 Golang 的兴起,协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。 云风实现了一套 [C 语言的协程库](https://github.com/cloudwu/coroutine/),整体背景可以参考其 [博客](https://blog.codingnow.com/2012/07/c_coroutine.html
[微信云支付 Android 智能 POS](https://cloud.tencent.com/document/product/569/33102) 使用 WebSocket 实现了用户订单的实时推送。即,顾客在扫描了门店的付款码,客户端会随即进行语音播报和打印等动作。 <!--more--> 客户端利用 WebSocket 与后端维持长连接,当后端收到该门店订单时,即将成功态的订单通过对应
在进行 Linux 网络编程开发的时候,免不了会涉及到 IO 模型的讨论。《Unix 网络编程》一书中提到的几种 IO 模型,我们在开发过程中,讨论最多的应该就是三种: ` 阻塞 IO`、` 非阻塞 IO` 以及 ` 异步 IO`。 本文试图理清楚几种 IO 模型的根本性区别,同时分析了为什么在 Linux 网络编程中最好要用非阻塞式 IO。 <!--more--> # 网络 IO 概念准备
在客户端开发中,往往会有一些功能对时间要求比较严格,客户端需要获取到当前最准确的时间。但由于客户端环境多种多样,我们无法保证直接在客户端设备上获取到的时间是最准确的时间。 对于某些问题设备来说,设备时间与比当前实际的时间差了几个小时,甚至几天的情况都存在。倘若某功能依赖于当前时间,而客户端所提供的时间不准,就往往会给客户造成一些困扰。 那么,客户端如何能够获取到当前最准确的时间呢? <!--mo
[muduo](https://github.com/chenshuo/muduo)是 [陈硕](http://chenshuo.com) 大神个人开发的 C++ 的 TCP 网络编程库。muduo 基于 Reactor 模式实现,Reactor 模式也是目前大多数 Linux 端高性能网络编程框架和网络应用所选择的主要架构,例如 Redis 和 Java 的 Netty 库等。 陈硕的《Lin
最近我用 Golang 开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时,经常需要为数据库写说明文档,对于稍微有些规模的项目来说,就动辄几十张上百张数据表,开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。 项目地址在 [这里](https://github.com/chenyahui/db_doc_gen
[ClassViewer](https://chenyahui.github.io/ClassViewer)是我最近开发的一个用于展示 jvm class 字节码的小工具。它是一个单纯的静态网页,完全使用浏览器端的 Javascript 开发。之所以开发这款工具,是因为我在开发 [ToyJVM](https://github.com/chenyahui/ToyJVM) 的时候,需要常常校验 cla
4 月 9 号,在武汉参加了人生第一次半程马拉松,风里雨里的 21.0975 公里。虽然已时隔一周,但想到那天一路的奔跑、疲惫、欣喜,还是想记记这半马的流水账。 <!--more--> # 赛前训练 关于赛前训练这一块,我自己真的是非常的汗颜,被自己的记性给坑了一把。本来 4 月 9 号的马拉松,硬是记成了 5 月 9 号。所以本来安排的提前 1 个月训练半马,也恰好完美地错过。汉马马拉松官网提
> BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法。 在很多日常场景中,都大量存在着布隆过滤器的应用。例如:检查单词是否拼写正确、网络爬虫的 URL 去重、黑名单检验,微博中昵称不能重复的检测等。 <!-- more --> 在工业界中,Google 著名的分布式数据库 BigTable 也用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的 IO 次数;
前两天把实验室的一台旧台式机装上了 Ubuntu Server,打算当作测试服务器使用着玩。 装上之后意识到一个严重的问题:实验室电脑连接外网时候需要打开浏览器输入学号进行认证。 <!-- more --> 而对于服务器版的 Ubuntu Server 来说只有黑乎乎的命令行界面。根本没有浏览器可以打开,所以网络认证就无从谈起。。 就在准备打算重装一个 Ubuntu Desktop 的时候,
## 为什么会想到建立一个博客: 在此博客之前,我其实也用过新浪博客、CSDN、博客园,作为个人博客的载体,但对每个博客都并不是特别的满意。原因大概有下面几条: + 没有美观友好的支持代码。 + 广告多。 + 管理复杂,但可控性差。 目前该博客是使用 hexo+Next 主题 + Github 进行搭建。 事实上,当开始接触使用 hexo 时,我觉得满足了我对博客的诸多要求。我对它的为程序员而生