文章索引
全部文章
首页2026
银行卡交易剖析——从刷卡到结算
收银台显示支付成功时,商户收到钱了吗?跟着一笔 29.99 美元的消费,看银行卡交易如何获批、入账,又如何处理退货与消费纠纷。
企鹅岛上的鱼指导
人生暂时没有答案,不过今天还有题。
毕业典礼随想:站在聚光灯外的人
世上的人很多,能站在台上的总是少数。台下的人也要生活。
在桌面应用中使用反向代理实现网页预览
在桌面应用里预览网页,为什么一个 iframe 不够?拆解 MrRSS 的反向代理、资源重写与动态请求拦截方案。
2025
Vibe Coding 一个复杂项目——问题与经验分享
AI 能很快写出一个功能,却未必能维护好一整个项目。以 MrRSS 的开发为例,谈如何让生成的代码经得起持续迭代。
越过长城,走向世界——翻墙协议的历史与原理浅析
加密藏住了内容,却未必藏得住流量特征。看看代理协议如何在一次次封锁中改变伪装,以及这些设计为何仍会暴露。
弹簧摆
《算法笔记》第 4 篇:弹簧一边伸缩、一边摆动,轨迹该怎么算?把系统的能量写成运动方程,再让数值计算还原它的运动。
波函数坍缩与程序化生成
《算法笔记》第 3 篇:几块样本图案,怎样拼出一张完整地图?用波函数坍缩算法逐步确定局部选择,让相邻约束塑造整体图案。
形式化理解零知识证明
如何严格证明一个协议“没有泄露秘密”?用模拟器刻画验证者获得的信息,让零知识证明的直觉落到数学定义上。
Chrome 原生 AI API 开发实践
模型搬进浏览器后,翻译和摘要可以直接在本地完成。用可运行的 JavaScript 示例,尝试 Chrome 不依赖远程接口的 AI 功能。
如何在半年内给 3 个开源项目骗到 100+ stars?
在 GitHub 种下三个项目,终于等到星星落下来。聊聊选题、开发与运营,也聊聊热闹之后的困惑。
从 C10K 到 C10M——从源码深入 I/O 模型的演进
连接越来越多,服务器的时间花在哪里?逐段阅读 Linux 源码,看 I/O 接口如何减少无效遍历与数据搬运,撑起更高并发。
如何组织一个 Go 项目?
Go 项目的目录该怎么分?结合开源项目,讨论入口、内部实现与公共库的边界,以及目录约定背后的取舍。
AI时代的爱情
技术让每个人获得了最适合自己的位置。我的位置,是白色房间里的一张椅子。
ReDos——低效的正则表达式
一次 CodeQL 告警引出的 ReDoS 问题:看正则表达式如何陷入大量回溯,以及哪些写法容易拖垮匹配性能。
git diff 是如何实现的?
《算法笔记》第 2 篇:两个文件之间,最少要改几处?把差异比较画成网格上的寻路问题,看 Myers 算法如何避开大面积的无用计算。
告别 JavaScript : 现代 CSS 特性
组件随容器变宽、动画随页面滚动,这些效果还需要写 JavaScript 吗?用可运行示例尝试 CSS 能独立完成的布局与交互。
消息队列——原理与对比
消息发出后,怎样才算真正送达?比较三种常用消息队列如何保存、确认和重试消息,理解可靠投递背后的取舍。
Redis 事件循环
《深入 Redis 源码》第 6 篇:多个客户端同时连接,Redis 怎样避免等在某一次读写上?追踪事件循环,看就绪通知如何驱动请求处理。
Redis 集群
《深入 Redis 源码》第 5 篇:有了磁盘备份,主机宕机后仍可能无法服务。看 Redis 如何让副本接管请求,并把单机装不下的数据分给多个节点。
Redis 持久化
《深入 Redis 源码》第 4 篇:内存里的数据怎样经得起重启?对照 Redis 落盘与恢复的源码,看少丢数据、少阻塞请求和快速恢复之间的取舍。
一觉醒来,全球计算机水平上升1000倍
传统时间复杂度势力妄图开历史倒车。
Redis 数据库
《深入 Redis 源码》第 3 篇:键到期了,内存就会立刻释放吗?追踪 Redis 管理键的源码,看它如何控制清理开销,并在内存不足时决定淘汰谁。
Redis 数据结构
《深入 Redis 源码》第 2 篇:Redis 的快不只因为数据在内存里。看看底层结构如何通过紧凑存储与渐进式扩容,在访问速度和空间占用间做取舍。
Redis 对象
《深入 Redis 源码》第 1 篇:同一种 Redis 对象,底层为什么会有不同编码?跟着命令查看数据的实际存法,理解编码为何随内容和规模变化。
2024
搜索树
《算法笔记》第 1 篇:树越矮,查找就一定越划算吗?对照几种搜索树的实现,看维护平衡的开销与节点的存储方式如何影响选择。
部署一个 Docker Registry
Docker Hub 连不上,拉镜像成了部署的阻碍。搭一个能缓存公共镜像、存放私有镜像的仓库,把这条下载路径掌握在自己手里。
静态网页加载速度优化实践
静态博客为什么也会加载缓慢?调整 CDN 缓存与图片、字体、脚本的加载方式,逐项减少传输量和等待时间。
Python 的 import 陷阱
《Python 指北》第 2 篇:同一份 Python 代码,换个启动方式就导入失败了?用具体例子说明模块所在目录与包身份为什么不是一回事。
浅析 C 中函数返回值的一例 UB
本该返回整数的 C 函数漏写 return,会发生什么?从 GCC 生成的汇编追踪返回值,并观察优化选项的影响。
MySQL——从实践到原理
一条查询为什么会慢,一次更新又如何保证可靠?把 SQL 的使用与底层执行联系起来,理解 MySQL 的索引选择和事务设计。
Elastic Stack
搜索一个词,难道要把所有文档读一遍?用 Elasticsearch 建立可查询的文档库,理解它如何找到匹配项并排出相关结果。
PDB入门
《Python 指北》第 1 篇:程序跑到一半,变量究竟变成了什么?用 PDB 暂停 Python 程序,在现场执行表达式、验证猜测。
系统内核,启动!
《MiniOS64》第 4 篇:引导程序终于要把控制权交给内核了。用 C 写出第一行屏幕输出,并让构建脚本自动算好内核该从磁盘读多少。
从32位到64位
《MiniOS64》第 3 篇:CPU 支持 64 位,还要做什么才能真正用上?为引导程序建立地址映射,完成进入长模式所需的准备与切换。
从16位到32位
《MiniOS64》第 2 篇:离开 16 位实模式,原来的 BIOS 打印办法也不能照搬了。切入保护模式后,亲手向显存写出第一行字。
操作系统,启动!
《MiniOS64》第 1 篇:没有操作系统时,第一段代码由谁加载?写一个 512 字节的引导扇区,让计算机显示文字,再去磁盘寻找后续代码。
再谈 git——我的工作流
提交错了怎么撤销,分支改完怎样合并?记录我的 Git 与 GitHub 工作流,也谈仓库规范和自动化配置。
前端框架是怎么实现的?
写好的组件如何变成浏览器里的页面?梳理前端框架的打包过程,比较 SPA 与 SSR 的加载和渲染流程。
Github Pages DNS 配置
用 Cloudflare 为 GitHub Pages 配置自定义域名,让主域、www 和博客子域分别指向对应站点。
WSL 安装 BCC 指南
在 WSL2 中编译并配置内核,补齐 BCC 所需环境,记录安装过程中内核头文件与工具链的处理步骤。
WSL2 网络设置指南
通过 .wslconfig 配置镜像网络、DNS 隧道与自动代理,让 WSL2 复用 Windows 宿主机的网络设置。
MyBatis
《深入 Spring 源码》第 6 篇:把一条 SQL 变成一次 Java 方法调用,少写重复的数据库操作代码。实践 MyBatis 映射,并为应用接入登录与权限控制。
Spring Boot
《深入 Spring 源码》第 5 篇:一个启动类为何能带起整个应用?追踪 Spring Boot 源码,看框架怎样按条件补齐配置,把繁琐的启动工作接过去。
Spring MVC
《深入 Spring 源码》第 4 篇:一次 HTTP 请求如何变成 Java 方法调用?追踪框架调度源码,看请求怎样找到处理者,再把结果交还客户端。
JDBC 和事务
《深入 Spring 源码》第 3 篇:余额扣了,库存却没减成功,这笔操作该怎么算?追踪 Spring 事务源码,看一组数据库修改如何共同提交或回滚。
AOP
《深入 Spring 源码》第 2 篇:业务方法没有改,调用时却多出了日志和事务。追踪 Spring 代理的创建过程,看这些额外逻辑在何时被接入。
IoC
《深入 Spring 源码》第 1 篇:对象不再亲手创建,它依赖的对象由谁准备?跟着 Spring 源码看容器如何识别、组装并管理它们。
Redis 运维
《深入 Redis 源码》第 7 篇:缓存本来替数据库挡流量,失效时却可能把压力集中打回去。讨论 Redis 使用中这类故障的预防与处理。
JVM 原理与使用
《深入 Java》第 4 篇:JVM 如何执行字节码,又如何回收不再使用的对象?弄清程序运行时发生的事,才知道性能调优该观察什么。
Java 集合
《深入 Java》第 3 篇:同样是存取一组数据,换个容器为什么就会变快或变慢?借源码理解 Java 集合的成本,按访问方式选择容器。
Java 并发编程
《深入 Java》第 2 篇:多个线程各自执行正确,合在一起为什么会出错?理解共享数据的可见性与操作原子性,再看 Java 如何协调线程。
Java 进阶
《深入 Java》第 1 篇:运行中的 Java 程序如何检查一个类、调用未知的方法?以反射和注解为重点,补齐阅读框架代码常用的语言知识。
2023
NAT穿透——原理与实践
内网设备发得出请求,外网却未必能主动连回来。借 NAT 的映射规则理解打洞何时可行,以及哪些网络需要依靠中继。
格式化字符串漏洞
一个 printf,为什么能读写不该访问的内存?拆解参数读取方式,用实例解释格式化字符串漏洞的成因。
国密 SSL
国密 SSL 为什么要准备两张证书?实际生成证书并建立 TLCP 连接,理解身份认证与密钥交换的分工,以及接入时的兼容障碍。
PKI 和 OpenSSL——原理与应用
公钥也可能被人掉包,加密后的消息未必发给了正确的人。亲手用 OpenSSL 签发和验证证书,看信任如何沿证书链传递。
Docker 底层原理浅析
同一份代码,怎样连同运行环境一起交付?跟着一次开发与测试的争执使用 Docker,再看容器为何能兼顾环境隔离与轻量运行。
树莓派安装使用
给树莓派 4B 做一次无显示器安装:烧录 Raspberry Pi OS,配置远程连接,再装 Docker 和 ngrok。
最小的 Hello World
一个 Hello World 能有多小?从 C、汇编到手写 ELF,逐步裁去冗余,把 64 位可执行文件压到 140 字节。
分布式理论与实践
网络会断,节点会停,多台机器却要对外表现得像一个系统。结合具体实现,讨论分布式系统为一致性和可用性付出的代价。
2022
Terraria 破解
拆解 Terraria 人物存档的 AES 加密与二进制结构,用代码解密存档并修改背包物品。
Virtual Private Network (VPN)
《SEEDLabs》第 14 篇:亲手用 Python 写一个 VPN,让通过验证的用户经加密隧道访问内网,再把单用户程序扩展到多人同时使用。
VPN Tunneling
《SEEDLabs》第 13 篇:一个发往私网的 IP 包,怎样穿过另一个网络?搭建可双向转发的隧道,观察虚拟网卡如何把数据包交给用户程序。
TLS
《SEEDLabs》第 12 篇:TLS 连接加密了,怎样确认对端身份也可信?编写通信程序并改变证书验证条件,观察连接何时成功、何时被拒绝。
TCP Attacks
《SEEDLabs》第 11 篇:在实验网络中复现 SYN 泛洪、RST 注入与会话劫持,观察 TCP 状态和 SYN Cookie 的作用。
PKI
《SEEDLabs》第 10 篇:浏览器信任的 CA 如果出了问题,会怎样?在实验环境中自建证书体系,再让伪造的网站通过验证,观察信任根失守的后果。
Packet Sniffing and Spoofing
《SEEDLabs》第 9 篇:收到 ping 的回应,就说明目标真的在线吗?用 Scapy 捕获请求并伪造响应,观察报文内容与真实来源的差别。
ICMP Redirect Attack
《SEEDLabs》第 8 篇:伪造 ICMP 重定向消息改变实验主机的路由,再观察流量如何被引向中间人。
ARP Cache Poisoning
《SEEDLabs》第 7 篇:通过伪造 ARP 报文污染缓存,在实验网络中截获并修改 Telnet 与 Netcat 的通信。
GPS 扩频——原理与实现
接收机怎样认出某颗 GPS 卫星的信号?生成扩频码并观察相关峰,理解接收端如何找到目标信号、逐步对齐码相位。
伪随机数算法
同一个种子总能算出同一串数,它为什么还能叫随机数?拆开常用生成算法,看看确定性的运算如何产生近似随机的序列。
Snort 和 Scapy
配置 Snort 并编写检测规则,再用 Scapy 构造和发送报文,验证规则能否触发告警。
星座图解释与应用
星座图上的一个点,代表怎样的信号?结合幅度、相位与 IQ 调制解调,用 MATLAB 模拟不同调制方式。
类型推导
C++11/14/17 学习第 2 篇:写下 auto 后,原本的引用还在吗?逐例检查推导结果,弄清编译器何时保留类型信息、何时将它丢掉。
2021
拜占庭容错
当节点会出错甚至说谎,系统如何达成共识?解释拜占庭容错的条件,以及 PBFT 各阶段的处理流程。
汇编中的神奇除法
除法为什么被编译成乘法和移位?推导整数除法的魔法数字,再看 Quake III 的快速平方根倒数算法。
右值的应用
C++11/14/17 学习第 1 篇:调用 move 就一定会移动对象吗?厘清左值、右值与引用,解释移动语义和完美转发。
信号与线性系统笔记
给系统一个输入,怎样求出它的响应?这份课程笔记整理时域与变换域的计算方法,让同一个问题可以换一种形式求解。
考《计算机网络安全导论》有感
有些人自以为“通”,那是因为他连“通”“不通”都不了然的缘故。
动手修改 Linux 内核
一次 Linux 内核实验:编译内核、添加系统调用,并修改进程管理逻辑,实现按进程或用户隐藏进程信息。
密码学笔记
消息怎样既不被偷看,又能让接收者确认来源?这份密码学笔记整理常用算法的计算过程,区分不同安全目标所需的手段。
对偶问题解释
不直接求解,怎样先给最优值划一道界限?借约束的几何意义理解对偶问题,并讨论这道界何时能碰到真正的最优值。
区块链是什么?
没有中心机构,大家如何共同维护一本可信的账?解释区块链的结构,以及密码学和共识机制各自的作用。
频谱是什么?
频谱图上的几根线,怎么就能代表一个信号?借正弦波叠加理解傅里叶变换,解释幅度、相位与复数的含义。
正定矩阵
矩阵的“正定”究竟在说什么?用线性变换后向量的夹角与投影,解释正定和半正定的几何意义。
2020
MD5 Collision
《SEEDLabs》第 6 篇:构造内容不同却具有相同 MD5 的文件,再让哈希相同的两个可执行程序表现出不同行为。
SQL injection
《SEEDLabs》第 5 篇:在实验应用中复现登录绕过与数据篡改,再用预处理语句验证 SQL 注入的防御方式。
XSS
《SEEDLabs》第 4 篇:浏览一次个人主页,为什么会替别人传播恶意脚本?在实验站点复现 XSS 蠕虫,观察用户内容变成可执行代码的后果。
CSRF
《SEEDLabs》第 3 篇:只是打开一个网页,账户资料却被改了?在实验站点观察浏览器如何带着登录身份发出伪造请求,再验证防护措施。
Return-to-libc Attack and ROP
《SEEDLabs》第 2 篇:栈上的代码不能执行,溢出攻击就结束了吗?在实验中把返回地址指向已有代码,理解返回 libc 与 ROP 的复用思路。
Buffer-Overflow Attack
《SEEDLabs》第 1 篇:输入长一点,为什么就能改写程序的执行流程?观察栈溢出如何覆盖控制数据,再逐项开启防护,比较实验结果。
CMake 学习
源文件散在不同目录,还依赖自己写的库,怎样统一构建?用 CMake 描述目标之间的关系,让工具安排编译与链接。
网络空间安全数学基础笔记
给密码学课程备一份数学工具箱:整理模运算与有限代数结构的计算方法,并用具体加密算法说明它们如何派上用场。
概率论笔记
随机现象如何用数学描述,有限样本又能告诉我们多少?这份概率统计笔记整理建立模型与推断总体时常用的公式和方法。
2019
x86汇编学习
一段程序落到机器上,数据怎样存取,执行又怎样跳转?用 32 位 x86 汇编的小例子,把这些操作对应到具体指令。
过往归档13 篇
浅谈 MCP 和 A2A
给模型接上工具,为什么还需要一层协议?围绕 MCP 与 A2A 的调用过程,讨论它们解决了什么,又把哪些难题留给使用者。
我的服务器成了 DDoS 的肉鸡!
VPS 上传流量突然暴涨,抓包后发现异常 DNS 请求。记录一次疑似反射放大攻击的排查,以及收紧防火墙的临时处置。
大模型越狱攻击初探
同一个请求,换种表达就可能得到不同回答。用 GPT-4o 的实测记录,观察提示词如何影响模型的拒答边界。
Zeek 使用
配置并部署 Zeek 网络监测工具,编写事件处理脚本,分析流量并生成日志。
正则表达式学习
一条规则为什么多匹配或少匹配了字符?用正反例逐项验证正则的含义,学会把文本条件写成准确的匹配规则。
DefendTheWeb
页面上看不见的密码,可能正躺在源码里。记录 DefendTheWeb 的部分解题过程,练习检查浏览器实际收到了什么、又信任了什么。
jekyll
用 Jekyll 搭建个人博客,记录 Ruby 环境安装、主题配置、本地预览与 GitHub Pages 发布的步骤。
WeChall
一道题未必只有一种解法。记录 WeChall 部分关卡的分析过程,尝试把线索写成可验证的脚本,并比较不同语言的做法。
Try2Hack
Try2Hack 部分关卡题解,从网页源码、脚本和请求中寻找密码,记录绕过前端限制的思路。
Narnia
《OverTheWire》第 3 篇:分析 Narnia 首关的 C 程序,用缓冲区溢出覆盖变量,观察栈布局与小端字节序。
Crypton
《OverTheWire》第 2 篇:不知道密钥,还能读出密文吗?跟着 Krypton 关卡,利用字符频率与重复模式寻找古典密码留下的线索。
Bandit
《OverTheWire》第 1 篇:下一关的密码藏在服务器里,手边只有命令行。跟着 Bandit 逐关寻找线索,练习组合 Linux 工具解决具体问题。
Nazo
Nazo 网页解谜记录:从文字、图像和源码中寻找线索,借助编码、逻辑与一点脑洞逐关推理。
共 109 篇文章