Astro 接入 Google Analytics (Tag Manager)
3 min在将博客迁移至 Astro 框架后,常规的 Google Analytics 接入方法因性能因素而不再适用。尽管可以在 head 标签中直接添加 js 代码进行事件上报,这会影响页面性能。为了保持 Astro 的高效表现,采用了 partytown 技术,将脚本从主线程中剥离,确保加载过程不受影响。在此基础上,结合 demo 代码成功实现了 Google Analytics 的无缝接入,达成了性能与数据分析的平衡。
游记:近畿地方 (2025.4)
10 min4 月的一个周末,同事说,我们去日本玩吧,于是,我们就去了日本。
上海杭州异地组网记录
12 min随着工作调动,npy 从北京迁至上海,顺便处理了宽带安装。尽管选择了电信500M的宽带,费用却高于杭州的1000M,令人无奈。在此背景下,我决定构建一个跨城市的网络环境,期望实现上海透明代理、部分流量从杭州出口及两地局域网互通的目标。杭州的网络架构相对简单,通过软路由与无线AP的组合,搭建了一套可以支持日常流量回家的系统,准备迎接接下来的网络挑战。
My heart beats for U —— 心率同步 Grafana 展示
3 min通过将苹果健康的心率数据定时同步到服务器,使用 Grafana 进行可视化展示,创造了一种直观的健康监测方式。利用 Health Auto Export 应用的 Restful API,将心率信息发送到指定的 http 接口,存储在 InfluxDB 中,最终在 Grafana 中呈现出清晰的看板,便于追踪和分析个人的心率变化。
语法分析中类型名-变量名歧义消除
14 min在语法分析过程中,用户自定义类型名与普通变量名的混淆成为一大难题。特别是在某些情况下,如 `a*b;`,该语句既可能被解读为数学表达式,也可能被视为类型声明。这种模糊性源于语法规则的设计,特别是涉及类型说明符的部分,可能会导致变量名被误认作类型名,影响代码的正确性与可读性。随着无初始化变量定义的普遍存在,这一问题在源码中愈发明显。
VPS 套 Warp 分流指定出口 IPv6
3 min在一个平常的下午,Telegram 推送消息引发了对一个新套餐的热情,电信 CN2 直连、2.5G 带宽的优惠让人兴奋不已。这个套餐自带 IPv6,适合解锁流媒体,但仍需谨慎使用,毕竟并不是所有流量都需要通过 Warp 来处理。先前使用的脚本虽然方便,但在速度和流量分配上存在不足,显然需要寻找更灵活的解决方案。
在 VitePress 中实现一个动态说说功能
23 min在构建动态博客时,添加说说功能能显著提升用户体验。相比静态博客的繁琐流程,这种功能允许用户随时随地分享短小的想法,降低了发文的心理负担。通过利用 CloudFlare Workers 实现后端逻辑,并结合 KV 存储,开发者能够轻松管理说说内容。前端则通过 VitePress 框架和 Vue 组件的嵌入,快捷地展示这些动态信息,为博客增添了生动的交互性。
实现 OPNsense 透明代理+分流
12 minOPNsense 作为一款开源的防火墙和路由系统,因其美观的用户界面和全面的功能而备受关注。在经历了一系列路由方案后,用户们逐渐认识到其在透明代理和流量分流方面的强大潜力。通过结合 BGP 分流转发方式,OPNsense 提供了更高的安全性和稳定性,成为了理想的网络管理解决方案。尤其是其自动更新 IP 列表的功能,使得网络管理变得更加便捷。
更精确的基于 BGP 的国内外 IP 分流
5 min基于 BGP 的国内外 IP 分流方案,提升了透明代理的效率和精准度。通过对国外 IP 进行 FakeIP 标记,主路由能够更智能地进行流量分流,确保网络连接的顺畅性。sing-box 的 DNS 模块配置也进行了相应优化,使得在处理 DNS 请求时,更加灵活且高效,进一步提升整体网络体验。
在字节工作三年的同时仍保持一定程度的心理健康其实也并非完全不可能
14 min在字节工作三年,时间的流逝仿佛在无形中加速。尽管身处快速变化的环境,仍能找到一丝心理平衡。回想起刚入职时的懵懂,那个年轻的自己在杭州八方城的阳台上,眺望着远方的山脉,心中对未来充满期待与好奇。随着时间的推移,职场的挑战与成长交织,形成了一段独特而丰富的经历,让人学会在忙碌中寻找属于自己的节奏。
慢性胃炎治疗之路
4 min慢性胃炎的治疗之路充满波折,经历了儿时的肠胃不适到大学期间的神奇恢复,再到职场生活中的放纵与反复发作,胃部的痛苦成为了生活中的常态。尽管早年的症状在一段时间内神奇消失,但随着熬夜与饮酒的习惯加重,胃的警报再次响起,频繁的恶心和反胃让生活变得难以忍受。在经历了多次的医疗检查与反思后,终于开始认真对待这段漫长而复杂的治疗过程。
基于 FakeIP 的透明代理分流
13 min基于 FakeIP 的透明代理分流方案旨在解决传统旁路由的单点故障、性能不足及复杂的端口映射问题。通过引入新的代理内核 sing-box,不仅提升了转发性能,还简化了配置流程。sing-box 提供了更丰富的协议支持,其优化效果明显优于原先的 clash,成为实现高效透明代理的新选择。虽然这也可以通过 clash 实现,但 sing-box 的引入无疑为用户带来了更灵活的体验。
旁路由端口映射失效解决
5 min在使用旁路由配置的情况下,主路由上的端口映射往往会失效。这是因为旁路由网关的设置改变了流量的转发路径,使得原本依赖于主路由的端口映射无法正常工作。网关的主要功能是进行地址转换,将内网流量转发到外网,而每个内网设备都需要一个网关来实现与外部的通信。理解这一机制,有助于更好地解决端口映射失效的问题。
debian 旁路由方案
16 minDebian 旁路由方案为用户提供了一种更为稳定和灵活的选择,摆脱了对 OpenWRT 和 LuCI 的依赖。通过直接在 Debian 上进行配置,用户可以享受更高的系统控制权,避免了 GUI 带来的种种限制和不稳定性。相比于常见的旁路由方案,Debian 的方法使得透明代理的设置更加可靠,为那些追求性能和效率的用户提供了新的可能性。
GFW 原理考
24 minGFW 的运作机制并非简单的出口网关监控,而是通过旁路监听技术对国际流量进行审查。这种方式使得所有出入境的 IP 包都被复制到 GFW 集群,进行深度分析和过滤。了解这一点,对于研究翻墙方法至关重要,因为它揭示了封锁的具体路径和技术手段。深入探讨 GFW 的网络拓扑,有助于更有效地应对和规避网络审查。
2024 学习计划
1 min2024年的学习计划明确而具体,目标包括日语达到N2水平,完成SICP和TAPL的学习,深入操作系统的知识以实现一个完整的POSIX内核,同时也计划更新博客主题。这些目标不仅具挑战性,也为个人成长和技能提升提供了清晰的方向。
RISC-V 工具链与模拟器(emulator)的安装
3 min在安装 RISC-V 工具链时,首先需要获取 riscv-gnu-toolchain 的源码,建议使用带有 `--depth=1` 的 clone 命令,以减少下载体积。安装过程中,注意查看 README 中的 Prerequisites 部分,确保前置依赖都已正确安装。在 Debian 系统中,可以通过简单的命令安装所需的依赖包,确保工具链的顺利搭建。
漫谈编程语言
32 min设计一门新的编程语言是一项既挑战又有趣的任务。通过简化复杂的编译原理和特性实现,重点关注代码如何在计算机系统中运行,能够帮助我们更清晰地理解编程语言的构建过程。以 RISC-VI 指令集为基础,探索语言设计的底层架构,揭示了计算机系统的分层结构和虚拟机模型,这不仅是对技术的探讨,还是对编程语言本质的深刻反思。
一次失败的项目实践——春节七天乐(不起来)
13 min在一次春节假期中,灵感悄然降临。高铁上偶然阅读了关于在裸机上运行Go程序的文章,激发了对底层系统接口的探索欲望。作者的成功实践和实现,让人对将高级语言与操作系统结合的可能性感到兴奋。随着对相关研究的深入,发现这一概念早已有先例,这股热情在潜移默化中积聚,最终演变成了一场充满期待却未能如愿的项目实践。
6.5840 实验 2a —— Leader 选举
18 min实验 2a 专注于实现 Raft 算法中的 Leader 选举和心跳机制,旨在确保在各种极端情况下的正常换届和选举。这一实验是后续分布式KV存储实现的基础,包含了四个步骤,通过无锁版本的设计简化了 Raft 结构体的复杂性。实验指导书提供了必要的背景资料,但与前一实验相比,本次几乎不依赖参考资料,强调了独立实现的重要性。
Raft 论文阅读
29 minRaft 是一种旨在提高日志复制效率的共识算法,特别适用于多机集群环境,确保在部分机器故障时仍能提供服务。这种算法通过复制状态机模型实现,利用日志记录指令顺序,使得集群各机器能够达到一致的状态。论文《In Search of an Understandable Consensus Algorithm》深入探讨了 Raft 的设计理念和与 Paxos 的对比,突显了其易于理解的特点,为构建可靠的大规模软件系统提供了基础。本文记录了对该论文的阅读笔记,旨在帮助理解其核心概念与应用。
golang 支持不同类型结构体间的深拷贝
4 min在系统重构的过程中,面对分层架构中不同实体间的转换问题,深拷贝成为一项挑战。以商品为例,视图层的商品 VO、领域层的商品 entity 以及存储层的商品 PO 结构虽相似,但细微的差别如数据类型的不同,常常使得直接转换变得复杂且麻烦。为此,尝试利用反射实现一个通用的转换方法,旨在简化这一过程,减少繁琐的 assembler 方法,提升代码的可维护性与灵活性。
Java 中 this 关键字导致编译期常量传播优化失效的问题
4 min在 Java 中,使用 `this` 关键字时,编译器对常量的优化可能会失效。代码示例中,尽管 `ab1` 和 `ab2` 看似引用了相同的 `final` 静态变量 `s`,但在比较时却产生了不同的结果。`ab1` 通过直接引用静态变量进行字符串连接,而 `ab2` 则是通过 `this` 关键字,导致编译器无法进行相同的常量传播优化,从而影响了字符串的比较结果。这一现象揭示了在 Java 中细微的语法差异可能引发的编译行为变化。
《三体》中的“大多数人”
15 min在《三体》中,刘慈欣通过浩瀚的历史叙述,探索了个体与集体之间的复杂关系。他对西式民主的质疑贯穿始终,反映出对大多数人自决命运的不安。书中众多英雄的努力与牺牲,最终却在历史的洪流中显得微不足道,彰显了个体在面对历史巨变时的无力感。故事从文化大革命的动荡开始,暗示着精英与平庸大众之间的深刻冲突,折射出对人性和社会的深刻思考。
6.5840 实验一 —— MapReduce
11 min实验一的目标是实现一个 MapReduce 系统,分为 master 和 worker 两个核心部分。这个过程对 golang 的 RPC 和并发编程要求较高,同时需要深入理解 MapReduce 的流程。实验经历了两个版本的实现,从基于 mutex 锁的版本到更优雅的基于 channel 的无锁版本,后者的设计更加简洁明了。理解实验的关键在于认真阅读相关文档,特别是其中的流程图和说明。
MapReduce 论文阅读
7 minMapReduce 是一种高效的并行计算模型,旨在简化大规模数据集的处理。通过定义 Map 和 Reduce 两个关键函数,用户能轻松地将复杂任务分解为简单的操作。该模型的架构能够自动管理数据分发和任务调度,使得开发者可以专注于算法本身,而无需过多关注底层细节。这种方法在分布式系统中的广泛应用,展现了其强大的灵活性和实用性。
提问的智慧
86 min提问的智慧在于理解如何有效地表达自己的疑问,以便获得更有价值的回应。通过明确问题的背景,提供必要的上下文,以及展现出对问题的思考,提问者能够更容易地引导出专业和有深度的答案。这不仅是对他人时间的尊重,也是提升自我学习能力的重要途径。正确的提问方式能够加深交流,促进更深入的讨论。
CSAPP LAB 环境搭建
9 min在学习 CSAPP 的过程中,实验环节的重要性不可忽视。然而,许多学生在搭建 Linux 环境时遇到各种麻烦,尤其是在使用虚拟机的情况下。诸如安装错误、兼容性问题、网络连接不畅等问题层出不穷,往往让人望而却步。为了解决这些障碍,WSL(Windows Subsystem for Linux)成为了一个理想的选择,尤其适用于 Windows 10 版本 2004 及以上的用户。WSL 提供了一个更为简洁、直接的方式来体验 Linux 环境,同时避免了虚拟机带来的复杂性和性能瓶颈。
MYDB 10. 服务端客户端的实现及其通信规则
6 minMYDB 采用 C/S 结构,类似于 MySQL,允许多个客户端通过 socket 连接到服务器,执行 SQL 查询并返回结果。通信采用了一种特殊的二进制格式,尽管也可以选择明文传输,以简化实现。服务端与客户端之间的基本传输结构确保了数据的有效交流和处理。
MYDB 9. 字段与表管理
7 min表管理器(TBM)的职责是管理字段和表结构。通过对类 SQL 语句的结构化解析,Parser 能将语句信息封装为相应的类,从而简化后续操作。章节内容也包括 MYDB 使用的 SQL 语句语法,为理解整个管理过程提供了基础。
MYDB 8. 索引管理
6 minMYDB 基于 B+ 树实现了聚簇索引。通过 IM 直接与数据管理(DM)交互,省略了版本管理(VM)层,确保索引数据直接写入数据库文件。章节中详细描述了二叉树索引的结构,涵盖节点的基本组成元素,包括叶子标记、键数量及兄弟节点标识等,为实现索引查找提供了基础框架。
MYDB 7. 死锁检测与 VM 的实现
10 minVM 需要处理 MVCC 导致的版本跳跃及死锁问题。通过简单的标记方式,MYDB 能轻松撤销或回滚事务,确保 aborted 事务的数据不会影响其他事务。这种设计使得事务在处理并发时更为高效和可靠,避免了传统 2PL 方法常见的死锁风险,提升了整体系统的稳定性和性能。
MYDB 6. 记录的版本与事务隔离
14 minVM 通过两段锁协议确保调度序列的可串行化,并引入多版本并发控制(MVCC),以消除读写阻塞问题。此外还定义了数据库操作中的冲突,特别关注更新与读取操作的相互影响,为理解事务间的隔离级别奠定基础。
MYDB 5. 页面索引与 DM 的实现
9 min页面索引是 DM 层的重要组成部分,通过缓存每一页的空闲空间来优化插入操作。这一机制使得上层模块能够迅速定位合适的页面,避免了冗长的搜索过程,提高了数据处理的效率。在实现方面,页面索引与数据项(DataItem)的抽象紧密结合,为数据库的高效运行提供了支撑。
MYDB 4. 日志文件与恢复策略
12 min在 MYDB 的设计中,日志文件扮演着至关重要的角色,确保数据在崩溃后能够顺利恢复。每次操作底层数据时,DM 层都会生成并记录日志,形成一条连续的日志链。这些日志以特定的二进制格式存储,包含校验和和各个操作记录,确保在系统重启时能够精准地重建数据状态,维护数据的一致性与完整性。
MYDB 3. 数据页的缓存与管理
7 minDM 模块将文件系统抽象为页面,并以此为单位进行数据的读写和缓存。默认设置的数据页大小为8K,便于在高负载情况下提升写入性能。借助已实现的通用缓存框架,接下来将专注于具体定义页面结构,以实现高效的页面缓存管理。
MYDB 2. 引用计数缓存框架和共享内存数组
9 min数据管理器(DM)作为上层模块与文件系统之间的桥梁,负责分页和缓存管理,同时确保数据安全与恢复能力。特别是,在缓存策略上,DM 采用了引用计数的框架,而非传统的 LRU,旨在提升缓存的通用性与效率,为后续的数据操作奠定基础。
MYDB 1. 从最简单的 TM 开始
7 minMYDB 中,事务的管理是通过 XID 文件实现的,每个事务都有一个唯一的 XID,从 1 开始递增,XID 0 被定义为超级事务,状态始终为已提交。TransactionManager 负责维护这一文件,并记录事务的三种状态:活动、已提交和已中止。这一机制确保了事务的状态能够被准确查询和管理,为系统的稳定性和可靠性提供了基础。
MYDB 0. 项目结构和一些不得不说的话
9 minMYDB 项目是一个旨在探索和实现数据库基本原理的个人作品,经历了大半个月的努力,在闲暇时间逐步完成。我在学校学习数据库系统的过程中,积累了一些基础知识,尽管在实习期间更多是借机“摸鱼”。在面试时的坦诚回答虽未造成太大影响,但也促使他重新审视数据库的知识,决定主动学习和实践,从而推动了这个项目的诞生。