音频可视化:采样、频率和傅里叶变换

印象中使用的第一个 PC 音乐播放器是「千千静听」,大概是 08 年左右。我还清楚地记得它自带了一首梁静茹的歌「Love is everything」,动听的旋律至今萦绕耳旁。

千千静听的左上角有一组随着音乐跳动的柱子,我想大家都习以为常了,很多播放器都有这功能。但是其实有没有想过,这是怎么实现的?

要理解这个问题,我们首先要理解声音是什么。

2021.08.07
热重载 C

热重载是一个非常好用的功能,可以在不重启的情况下更新应用,从而大大提高开发效率。

前端的 Wepback,后端的 Ruby/Python/Elixir,移动端的 Flutter 都有热重载,属于用过以后就回不去的 Killer Feature。

在我之前的认识中,一直认为只有脚本语言才可以支持热重载,因为虚拟机让热重载的实现变得非常简单,重新运行代码即可。

直到有一天,Casey 在 HandmadeHero 项目中用非常少的代码演示了怎样热重载 C,我才恍然大悟,编译语言一样可以热重载。

2021.06.10
消失的除法指令:Part1

之前学汇编的时候观察到一个现象,我在 C 语言中写了一个函数进行除法操作,但是编译得到的汇编代码中却没有除法指令,取而代之的是一条乘法指令。

图片对应的 GodBolt 地址在 这里,可以看到有一个 imulq 指令,这是一个乘法指令,乘了一个奇怪的数字 1431655766。

为什么编译器要这样操作?为什么能这样操作?1431655766 这个数字又是怎么来的?

2021.03.16
安全背后: 浏览器是如何校验证书的

现如今的 Web,HTTPS 早已经成为标配,公开的 HTTP 网站已经和 Flash 一样,慢慢在消亡了。

启用 HTTPS 的核心是一个叫做 证书 的东西。不知道大家是否有留意,前几年上 12306 的时候,浏览器都会提示「您的链接不是私密链接」,这其实就是因为 12306 的证书有问题。如果点击「继续前往」,打开 12306 网站,它会提示你下载安装它提供的“根证书”。

那么,证书是什么?里面含有什么内容?浏览器为什么会不信任 12306 的证书?为什么下载 12306 提供的根证书就可以解决这个问题?根证书又是什么?

2021.03.02
编写一个最小的 64 位 Hello World

Hello World 应该是每一位程序员的启蒙程序,出自于 Brian KernighanDennis Ritchie 的一代经典著作 The C Programming Language

// hello.c
#include <stdio.h>

int main() {
  printf("hello, world\n");
  return 0;
}

这段代码我想大家应该都太熟悉了,熟悉到可以默写出来。虽然是非常简单的代码,但是如果细究起来,里面却隐含着很多细节:

  • #include <stdio.h>#include "stdio.h" 有什么区别?
  • stdio.h 文件在哪里?里面是什么内容?
  • 为什么入口是 main 函数?可以写一个程序入口不是 main 吗?
  • main 的 int 返回值有什么用?是谁在处理 main 的返回值?
  • printf 是谁实现的?如果不用 printf 可以做到在终端中打印字符吗?
2020.12.10
tinyTorrent: 从头写一个 Deno 的 BitTorrent 下载器

BitTorrent 想必大家应该都不陌生,中文名叫做“种子”。

“种子”到底是什么?我一直不太清楚。在写这个项目之前,我对“种子”的认识停留在使用层面。

当我想找一个资源的时候,我会搜索 xxx 种子,一般会在一些非常不知名的小网站里面获取到以 .torrent 结尾的种子文件,然后使用迅雷或者 uTorrent 这样的下载器来下载。

如果迅雷有一点速度,哪怕几 kb,那么大概率我充个会员就搞定了。这个软件就是这么的恶心,不用有时候又没办法,像极了人生。

其他下载器比如 uTorrent 的话就一切随缘了,有些资源非常快,有些资源非常慢,有些一开始慢后来快。

这些问题是怎么回事?有没有改进的办法?在读 Jesse Li 的 Building a BitTorrent client from the ground up in Go 之前,我从没想过。

2020.10.31
CS107e: 树莓派,ARM 和操作系统

2020.10.09 更新:最近收到了一封官方的邮件,希望我把仓库隐藏起来,避免新同学直接 copy 我的代码。既然是来自官方的要求,自然毫不犹豫地配合。仓库和我归档的 Winter 2020 课程现在都不可见了,想要学习这门课程的同学可以直接去官方站点学习,祝大家学习愉快~

CS107e 全称为 CS107e: Computer Systems from the Ground Up,是斯坦福大学的一门计算机课程,也是我目前为止发现的最好的关于硬件、底层和 C 的一门课程。

在课程学习过程中,我们会一步一步地从头开始使用 C 为树莓派开发一个操作系统核心。

根据官方的介绍,这门课程主要学习目标有两个:

  1. To understand how computers represent information, execute programs, and control peripherals. 理解计算机是怎样存储信息,执行程序以及控制外围设备。
  2. To master command-line programming tools and the C programming language. 掌握命令行编程工具和 C 语言。
2020.09.11
Shell 启动类型探究 ── login && interactive

Shell 对程序员来说是必不可少的生产力工具。

$ figlet <<< "Hello Shell"
 _   _      _ _         ____  _          _ _
| | | | ___| | | ___   / ___|| |__   ___| | |
| |_| |/ _ \ | |/ _ \  \___ \| '_ \ / _ \ | |
|  _  |  __/ | | (_) |  ___) | | | |  __/ | |
|_| |_|\___|_|_|\___/  |____/|_| |_|\___|_|_|
2020.08.16
斗鱼关注人数爬取 ── 字体反爬的攻与防

之前因为业务原因需要爬取一批斗鱼主播的相关数据,在这过程中我发现斗鱼使用了一种很有意思的反爬技术,字体反爬。

打开任何一个斗鱼主播的直播间,例如 这个主播,他的关注人数数据显示在右上角:

斗鱼在关注数据这里使用了字体反爬。什么是字体反爬?也就是通过自定义字体来自定义字符与渲染图形的映射。比如,字符 1 实际渲染的是 9,那么如果 HTML 中的数字是 111,实际显示就是 999。

在这种技术下,传统的通过解析 HTML 文档获取数据的方式就失效了,因为获取到的数据并不是真实数据。

2020.07.01
用 C 实现一个 CHIP-8 模拟器

很早之前我就想写一个 GBA 模拟器,因为小时候的 GBA 游戏给我留下了深刻的印象。

口袋妖怪、孤岛求生、牧场物语这些 GBA 的经典游戏,在那个时候还玩着小霸王的我眼中,无异于打开了新世界的大门,原来游戏可以这样的有趣。

因为对 GBA 的喜欢,所以有了编写一个 GBA 模拟器的想法。看过一些资料以后,我决定从最简单的 CHIP-8 开始练手。CHIP-8 是一个功能完整的平台,可以运行多个游戏,同时它的设计又非常简单,很适合新手入门。

2020.06.07
Prev
1 / 4
Next