编程 Bun.js 的 Rust 重生:6天、96万行代码、Claude Code 亲手重写自己——AI 时代的软件工程范式转移(2026完全指南)

2026-06-26 04:13:40 +0800 CST views 9

Bun.js 的 Rust 重生:6天、96万行代码、Claude Code 亲手重写自己——AI 时代的软件工程范式转移(2026完全指南)

摘要:2026年5月,Bun.js 创始人 Jarred Sumner 在 X 上宣告:"如果我们合并 Rust 重写版本,这将是 Zig 的最后一个版本。" 这场从 Zig 到 Rust 的迁移,只花了大约六天,涉及 96 万行代码。更荒诞的是——Claude Code 被 Bun 的内存泄漏坑惨了,然后 Anthropic 让 Claude 去重写 Bun,最后 Bun 再继续回头支撑 Claude Code。本文深度解析这场重写的技术细节、架构决策、性能对比,以及它揭示的 AI 时代软件工程新范式。


目录

  1. 序幕:一条推文宣判了 Zig 的死刑
  2. Bun 是什么?为什么它举足轻重?
  3. 内存泄漏引发的连锁反应:Claude Code 的 14GB 噩梦
  4. Anthropic 收购 Bun:AI 驱动软件工程的基础设施
  5. 6天重写奇迹:从 Zig 到 Rust 的技术细节
  6. PORTING.md:一份 576 行的 AI 迁移指南
  7. Rust 版本的架构变化:Tagged Pointer 与 Trait 对象
  8. 性能对比:二进制体积、启动速度、内存占用
  9. 13,000 个 Unsafe 调用:代码质量的争议
  10. Zig 社区的抵制:No-AI Policy 与哲学决裂
  11. AI 重写软件的大趋势:Cloudflare、Ladybird 的案例
  12. 深度思考:未来开源可能禁止人类提交代码?
  13. 实战:如何从 Zig 迁移到 Rust——经验教训
  14. 总结与展望:软件工程的范式转移

1. 序幕:一条推文宣判了 Zig 的死刑

2026 年 5 月 11 日,Bun 创始人 Jarred Sumner 在 X 上发了一条推文:

"Bun v1.3.14 将于明日发布。如果我们合并 Rust 重写版本,这将是 Zig 的最后一个版本。"

就这么一句。

四年前,Bun 因为选择了 Zig 而显得特立独行——当全世界都在用 C++ 写运行时(Node.js)、用 Rust 写运行时(Deno)的时候,Bun 偏偏选中了这门还算小众的系统编程语言。

四年后,Zig 版本被它的创造者用一条推文宣告了终结。

这场从 Zig 到 Rust 的迁移,实际上只花了大约 六天,涉及 96 万行代码,并且在 Linux x64 glibc 环境下通过了现有测试套件的 99.8%

而六天前,Jarred 还在 Hacker News 上说这是一堆根本还跑不起来的代码,"最后被全部扔掉的概率非常高"。

六天后,同样的代码变成了"Zig 的最后一个版本"。

这种速度,人类做不到。做到这一切的,是 Claude Code。


2. Bun 是什么?为什么它举足轻重?

2.1 Bun 的核心定位

Bun 是一个 All-in-One JavaScript 运行时,它的目标是从根本上替代 Node.js。与 Node.js 不同,Bun 不仅仅是一个运行时,它还包含了:

  • 运行时:执行 JavaScript/TypeScript 代码(基于 JavaScriptCore,而非 V8)
  • 包管理器:替代 npm/yarn/pnpm(bun install 比 npm 快 20-100 倍)
  • 打包器:替代 Webpack/esbuild(bun bundle
  • 测试框架:替代 Jest/Vitest(bun test
  • CLI 工具:直接运行 TypeScript 无需编译

2.2 为什么选择 Zig?

Bun 最初选择 Zig 作为实现语言,有几个关键原因:

  1. 性能可控:Zig 允许手动管理内存,没有垃圾回收的停顿
  2. 与 C 互操作方便:Zig 可以直接导入 C 头文件,调用 C 函数
  3. 编译时执行:Zig 的 comptime 允许在编译期执行代码,生成高度优化的机器码
  4. 现代化工具链:Zig 自带跨平台交叉编译,一条命令编译到任何目标平台
// Zig 的 comptime 示例:编译期计算斐波那契数列
fn fibonacci(comptime n: u64) u64 {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

const result = comptime fibonacci(50); // 编译期计算,运行时零成本

2.3 Bun 的性能数据

Bun 官方宣称的性能数据(与 Node.js 对比):

操作Node.jsBun加速比
启动时间~45ms~3ms15x
包安装~30s~1s30x
文件读取~400μs~150μs2.7x
HTTP 服务~15k req/s~80k req/s5.3x

这些数据让 Bun 在 2023-2025 年间迅速崛起,成为 Node.js 最有潜力的挑战者。


3. 内存泄漏引发的连锁反应:Claude Code 的 14GB 噩梦

3.1 问题的根源

Bun 虽然性能优秀,但有一个长期困扰开发者的问题:内存泄漏

2026 年 3 月 12 日,一个编号 #33453 的 Issue 被提交到 Claude Code 仓库:

"Claude Code 的主进程表现出严重的内存泄漏,RSS 内存在约 3 小时的短会话中从约 1.7GB 增长到 14GB 以上。泄漏位于 Bun 运行时的 WebKit Malloc 分配器中,而非用户空间的 JavaScript 分配。"

3.2 Claude Code 与 Bun 的紧密耦合

Claude Code 是以 Bun 可执行文件的形式发布的。当你安装 Claude Code 时,你实际上也在运行 Bun。

这并非简单的合作关系,而是紧密的依赖关系:

Claude Code (AI 编程助手)
    ↓ 基于
Bun Runtime (JavaScript 运行时)
    ↓ 使用
WebKit Malloc (内存分配器)

Anthropic Claude Code 负责人 Boris Cherney 曾解释:

"我们当初在开发 Claude Code 时,评估了很多运行时方案,Bun 几乎是毫无悬念的胜者。它的启动时间大概只有 3 毫秒,而 Python 要慢 15 倍左右。对于 CLI 工具来说,这意味着用户体验是'丝滑响应',还是'明显卡顿'。"

3.3 荒诞的循环

于是现在出现了一个非常荒诞的循环:

  1. Claude Code 被 Bun 的内存泄漏坑惨了
  2. Anthropic 让 Claude 去重写 Bun
  3. Bun 再继续回头支撑 Claude Code

甚至已经有开发者开始半开玩笑地担心:

"Bun 已经嵌入到 Claude Code 中。Claude Code 看起来糟透了。所以现在我担心 Bun 也可能糟透了。"


4. Anthropic 收购 Bun:AI 驱动软件工程的基础设施

4.1 收购背景

2025 年 12 月,Anthropic 收购了 Bun。官方说法是"加速 Claude Code 能力"。

本质上是要让 Bun 成为 Claude Code 背后的:

  • 运行时(Runtime)
  • 包管理器(Package Manager)
  • 打包器(Bundler)
  • 测试工具(Test Runner)

Anthropic 将 Bun 定义为 "AI 驱动软件工程的重要基础设施",并认为它能够帮助开发者以前所未有的速度构建和测试应用。

4.2 收购后的矛盾

收购完成后,一个深层的矛盾逐渐显现:

  • Anthropic 是整个 AI Coding 浪潮最激进的推动者之一
  • Claude Code 深度依赖 Bun runtime
  • Zig 社区 全面封禁 AI 生成代码(No-AI Policy)

这种冲突,在 Anthropic 收购 Bun 后开始显得格外讽刺。


5. 6天重写奇迹:从 Zig 到 Rust 的技术细节

5.1 时间线

日期事件
2026-05-07Jarred 发推:Rust 迁移涉及约 4000 次 commit、96 万行代码,只剩 3 个编译错误
2026-05-09Rust 版本通过 Bun 测试套件的 99.8%
2026-05-11Jarred 发推:如果合并 Rust 版本,将是 Zig 的最后一个版本
2026-05-14Bun v1.3.14 发布,包含 Rust 重写版本

5.2 3天写代码,2天测试

Jarred 在推特上透露,整个过程大约是:

  • 前 3 天:让 Claude 生成 Rust 代码
  • 后 2 天:让 Claude 跑测试套件并修复失败用例

有开发者惊呼:"Claude 难道只用了三天就把 Zig 版 Bun 重写成 Rust 了吗?"

Jarred 回复说:"按代码量来看,这个说法准确。"

5.3 代码规模对比

指标Zig 版本Rust 版本
代码行数~96 万行~96 万行
Commit 数量-~4000 次
测试通过率基线99.8%
二进制体积基线缩小 3-8 MB

6. PORTING.md:一份 576 行的 AI 迁移指南

6.1 文档结构

claude/phase-a-port 分支中,有一份长达 576 行PORTING.md 文档。这不是给人类看的,而是给 Claude Code 看的迁移指南

文档把迁移拆成两个阶段:

Phase A:语义保真移植

  • 逐文件忠实保留 Zig 的逻辑
  • 即便 Rust 代码暂时不能编译也没关系
  • 不允许使用 tokio/rayon/hyper/futures
  • 不允许 async fn(Bun 使用自己的事件循环)
  • unsafe 必须写明 SAFETY 注释
  • 遇到不确定逻辑时,宁可留下 TODO,也不要让 AI 自行猜测

Phase B:编译与优化

  • 逐个 crate 解决编译问题
  • 让测试套件通过
  • 性能调优

6.2 为什么禁止 Async Fn?

Bun 使用自己实现的事件循环(基于 epoll/kqueue/IOCP),而不是 Rust 生态中常见的 tokio

// ❌ 不允许这样(Phase A)
async fn read_file(path: &str) -> Result<Vec<u8>> {
    // ...
}

// ✅ 必须这样(使用自己的事件循环)
fn read_file(path: &str, callback: impl Fn(Result<Vec<u8>>)) {
    // 提交到 Bun 的事件循环
}

这种限制确保了 Rust 版本的行为与 Zig 版本高度一致。


7. Rust 版本的架构变化:Tagged Pointer 与 Trait 对象

7.1 Zig 的 Tagged Pointer 技巧

Zig 版本的 Bun 大量使用 Tagged Pointer 来优化性能:

// Zig 中的 Tagged Pointer 示例
// 利用指针的低比特位存储额外信息(因为指针对齐后低几位永远是 0)
fn Task(comptime T: type) type {
    return struct {
        // 指针的低 2 位存储任务类型
        ptr: *T align(4),
        
        fn init(ptr: *T, task_type: u2) @This() {
            var self = @This(){
                .ptr = ptr,
            };
            // 将 task_type 编码到指针的低比特位
            self.ptr = @intToPtr(*T, @ptrToInt(ptr) | task_type);
            return self;
        }
        
        fn get_type(self: @This()) u2 {
            return @truncate(u2, @ptrToInt(self.ptr));
        }
        
        fn get_ptr(self: @This()) *T {
            return @intToPtr(*T, @ptrToInt(self.ptr) & ~@as(usize, 0b11));
        }
    };
}

这种技巧在 Zig/C/C++ 中很常见,但在 Rust 中直接这样做会违反引用对齐规则。

7.2 Rust 中的替代方案

Jarred 在 X 上向 Rust 社区请教更底层的问题:

"Bun 原来的 Zig 代码大量使用 tagged pointer 来处理 event loop task、进程退出回调、非阻塞文件 I/O 等接口;迁到 Rust 后,如果直接用 trait 或函数指针,可能会带来额外开销。我还在寻找一种既不影响性能、又更适合 Rust 的实现方式。"

社区给出的建议包括:

  1. 使用 NonZero 指针类型 + 手动编码标签
  2. 使用枚举 + Box(会有额外分配)
  3. 使用 unsafe 手动操作指针(最接近原实现)
// Rust 中的 Tagged Pointer 实现(unsafe)
use std::ptr::NonNull;

struct TaggedPointer<T> {
    ptr: NonNull<u8>, // 低 2 位存储标签
    _marker: std::marker::PhantomData<T>,
}

impl<T> TaggedPointer<T> {
    const TAG_MASK: usize = 0b11;
    
    fn new(ptr: *mut T, tag: u2) -> Self {
        let addr = (ptr as usize) | (tag as usize);
        // SAFETY: 调用者必须确保 ptr 是对齐的(低 2 位为 0)
        unsafe {
            Self {
                ptr: NonNull::new_unchecked(addr as *mut u8),
                _marker: std::marker::PhantomData,
            }
        }
    }
    
    fn get_ptr(&self) -> *mut T {
        // SAFETY: 低 2 位被掩码掉,恢复原始指针对齐
        ((self.ptr.as_ptr() as usize) & !Self::TAG_MASK) as *mut T
    }
    
    fn get_tag(&self) -> u2 {
        (self.ptr.as_ptr() as usize) as u2 & Self::TAG_MASK
    }
}

8. 性能对比:二进制体积、启动速度、内存占用

8.1 二进制体积

Rust 重写版本的最直接改进:二进制体积缩小 3-8 MB

这主要是因为:

  1. Rust 的泛型在单态化时会产生多个副本,但 Bun 的场景中泛型使用较少
  2. Rust 的 LLVM 后端在 dead code elimination 上更激进
  3. Zig 版本中包含了大量调试符号和未优化的路径

8.2 启动速度

Bun 的核心优势之一是 极快的启动速度(~3ms)。

Rust 版本在启动速度上:

  • Linux x64:与 Zig 版本持平(~3ms)
  • macOS ARM:略有提升(~2.8ms)
  • Windows x64:提升明显(从 ~8ms 降到 ~4ms)

8.3 内存占用

这是 Rust 版本改进最明显的地方:

场景Zig 版本Rust 版本改进
空闲状态~45MB~38MB-16%
执行 bun install~180MB~140MB-22%
长时间运行(3小时)持续增长稳定无泄漏

Rust 的所有权系统帮助捕获了 Zig 版本中的多个内存泄漏点。


9. 13,000 个 Unsafe 调用:代码质量的争议

9.1 Theo 的质疑

2026 年 5 月 12 日,Theo(t3.gg 创始人)在 X 上抛出了一组对比数据:

"uv 包含 35 万行 Rust 代码,以及 73 个 unsafe 调用
Bun Rust 移植版已经有 68.1 万行 Rust 代码,并且有 超过 13,000 个 unsafe 调用。"

73 vs 13,000,差了接近 180 倍

9.2 Jarred 的回应

Jarred 几乎立刻回应:

"今天已经下降了大约 2000。我预计它会稳定在 1 万左右,因为 Bun 的大部分内容都是用 C 和 C++ 编写的,这种情况不会改变。"

9.3 为什么 Bun 需要这么多 Unsafe?

平心而论,这种对比确实不完全公平:

  1. uv(Astral 的 Python 包管理器)是一个相对纯粹的 Rust 项目
  2. Bun 需要与大量底层 C/C++ 代码打交道:
    • JavaScriptCore(WebKit 的 JS 引擎)
    • 文件系统操作
    • 网络 I/O(基于系统调用)
    • 内存分配器(WebKit Malloc → 迁移到 jemalloc/mimalloc)

这些场景都绕不开 unsafe

// Bun 中典型的 unsafe 使用场景
unsafe extern "C" {
    // 调用 JavaScriptCore C API
    fn JSValueMakeFromJSONString(
        ctx: JSContextRef,
        string: JSStringRef
    ) -> JSValueRef;
    
    // 调用系统调用
    fn kevent(
        kq: c_int,
        changelist: *const kevent,
        nchanges: c_int,
        eventlist: *mut kevent,
        nevents: c_int,
        timeout: *const timespec
    ) -> c_int;
}

// 在 Rust 中包装这些调用
impl JSCContext {
    unsafe fn eval_json(&self, json: &str) -> Result<JSCValue> {
        let js_string = JSStringCreateWithUTF8CString(json.as_ptr() as *const c_char);
        let js_value = JSValueMakeFromJSONString(self.ctx, js_string);
        // SAFETY: js_value 由 JSC 管理生命周期,我们通过 Rust 类型系统跟踪
        Ok(JSCValue::from_ref(js_value))
    }
}

9.4 社区的担忧

尽管 Jarred 的解释有道理,但网友们在意的不仅仅是数字。

开发者 Aashish Ranjan Singh 在 X 上写道:

"UV rust 是由真正的开发人员编写的,每一行代码都经过了审查。
Bun rust 由 Agents 编写,由 Agents 审核,并由 Agents 批准和合并。
完全在意料之中的结果。"

这句话精准地刺中了许多人的不安。


10. Zig 社区的抵制:No-AI Policy 与哲学决裂

10.1 Zig 的 No-AI Policy

Zig 社区有一个极其严格的规则:禁止 AI 生成 issue、PR 甚至评论

Zig 基金会成员 Loris Cro 曾公开表示:

"大量 LLM 贡献只会制造'幻觉 PR'、'垃圾噪音'以及动辄上万行、根本无法维护的提交。"

10.2 Bun 与 Zig 社区的裂痕

Bun 团队此前其实已经 fork 过 Zig。他们曾宣称,通过在 macOS 与 Linux 上引入 LLVM 并行代码生成,debug 编译速度提升了四倍。

但这些优化始终无法 upstream 回 Zig 官方,其中一个关键原因,就是 Zig 社区的 No-AI Policy——而 Bun 团队已经开始大量使用 AI 辅助开发。

10.3 哲学决裂

这种冲突,在 Anthropic 收购 Bun 后开始显得格外讽刺:

  • 一边是 Zig 社区 全面封禁 AI 生成代码
  • 另一边是 Bun 团队 开始用 Claude agent 大规模把 Zig 本身迁移出 Zig

某种意义上,这已经不仅仅是一次语言切换,而更像是 两种软件工程哲学的正面碰撞


11. AI 重写软件的大趋势:Cloudflare、Ladybird 的案例

11.1 Cloudflare 的 Next.js 重写

Cloudflare 曾在一周内借助 AI 重新实现了 Next.js API 的大部分能力。

他们的做法是:

  1. 用 AI 分析 Next.js 的源码,提取核心 API 语义
  2. 用 AI 生成 Cloudflare Workers 上的兼容实现
  3. 人工审查关键路径,AI 处理边界情况

结果:一周完成,代码质量"出乎意料的好"。

11.2 Ladybird 浏览器的 JavaScript 引擎迁移

Ladybird 浏览器(由前 Apple Safari 工程师开发)在 两周内 将自己的 JavaScript 引擎从 C++ 迁移到了 Rust。

项目负责人在博客中写道:

"如果靠人工慢慢迁移,可能需要 6-12 个月。但借助 AI 辅助,我们在两周内完成了核心迁移,并且测试通过率达到 97%。"

11.3 Jarred 的预言

Jarred 自己在 5 月 3 日发过一条推文:

"这种 pipeline,任何 VC 支持的 OSS 或者有大量 GitHub issues 的公司都能搭建。更普遍地说,它可以用于自动修复用户报告的 bug。Opus 4.7、4.6 甚至 4.5 都能轻松做到。"

他还更早的时候预言过:

"我预计开源软件会走向完全相反的方向——未来甚至可能变成'禁止人类贡献代码'。人类依然会负责讨论问题、决定优先级,但真正写代码、提交 PR、回复和处理反馈、完成实现的工作,最终都会由 LLM 来完成。"

Bun 的这次重写,正是这句话的第一次大规模公开演练。


12. 深度思考:未来开源可能禁止人类提交代码?

12.1 AI 的优势

AI 在软件重写/迁移场景中的优势是明显的:

  1. 速度:6 天 vs 6 个月
  2. 一致性:AI 不会疲劳,不会遗漏边界情况
  3. 覆盖率:96 万行代码,每一行都被处理过
  4. 测试驱动:AI 可以同时生成代码和测试

12.2 AI 的劣势

但 AI 的劣势同样明显:

  1. 缺少架构判断:AI 不知道什么时候该重构,什么时候该保持原样
  2. Unsafe 泛滥:如 Bun 案例中的 13,000 个 unsafe 调用
  3. 不可解释性:当 AI 生成的代码出现 bug,人类很难调试
  4. 依赖模型训练数据:如果训练数据不包含最新的语言特性,生成的代码可能过时

12.3 人类的新角色

如果 Jarred 的预言成真,"人类不得提交代码",那么人类开发者的新角色可能是:

  1. 架构师:决定"做什么"和"为什么做"
  2. 审查者:审查 AI 生成的代码的关键路径
  3. 调试者:当 AI 生成的代码出现诡异 bug 时介入
  4. 伦理把关者:确保代码不包含安全漏洞或恶意逻辑

13. 实战:如何从 Zig 迁移到 Rust——经验教训

13.1 准备工作

如果你也想尝试用 AI 辅助进行语言迁移,以下是 Bun 案例中的经验教训:

1. 编写详细的迁移指南

不要只是说"把它从 X 语言迁移到 Y 语言"。你需要:

  • 逐文件指定迁移优先级
  • 明确禁止使用的依赖(如 Bun 禁止 tokio)
  • 指定代码风格和命名规范
  • 规定 unsafe 的使用场景和文档要求

2. 分阶段进行

Phase 1: 让 AI 生成能编译的代码(不必正确)
Phase 2: 让 AI 让代码正确(通过测试套件)
Phase 3: 人工审查关键路径
Phase 4: 性能调优

3. 保持测试套件不变

Bun 能够如此快速地完成迁移,一个重要原因是 测试套件非常完善

Rust 版本必须通过 原有测试套件 的 99.8%。这意味着:

  • 行为一致性有保证
  • 回归问题能被快速发现
  • AI 可以自由尝试,不怕破坏功能

13.2 技术陷阱

陷阱 1:所有权模型差异

Zig 是手动管理内存的,而 Rust 有所有权系统。直接翻译可能导致:

// Zig 代码(手动管理内存)
fn process(data: []u8) []u8 {
    let result = allocate(sizeof(u8) * data.len);
    // 调用者负责释放 result
    return result;
}

// 直接翻译成 Rust(编译错误)
fn process(data: &[u8]) -> &[u8] {
    let mut result = Vec::with_capacity(data.len());
    // ...
    &result // ❌ 返回指向局部变量的引用
}

正确做法:使用 VecBox 转移所有权。

陷阱 2:错误处理语义

Zig 使用 error union 类型,而 Rust 使用 Result

// Zig 的错误处理
fn read_file(path: []const u8) ![]u8 {
    const file = try std.fs.openFile(path, .{});
    defer file.close();
    return try file.readToEndAlloc(allocator, std.math.maxInt(usize));
}
// Rust 的等价实现
fn read_file(path: &str) -> Result<Vec<u8>, std::io::Error> {
    let mut file = File::open(path)?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer)?;
    Ok(buffer)
}

AI 在翻译时,需要理解两种错误处理模型的语义差异。


14. 总结与展望:软件工程的范式转移

14.1 Bun 案例的启示

Bun 的 6 天 Rust 重写,不仅仅是一次语言迁移,它揭示了几个重要趋势:

  1. AI 已经成为生产力工具:6 天、96 万行代码,这个数字背后是 AI 辅助开发的真实能力
  2. 质量 vs 速度的平衡:13,000 个 unsafe 调用提醒我们,速度的提升可能伴随质量的下降
  3. 开源社区的文化冲突:Zig 的 No-AI Policy vs Bun 的 AI-Driven Development

14.2 对开发者的建议

在这个 AI 重写软件的时代,作为开发者,你应该:

  1. 掌握多种语言:这样你才能判断 AI 生成的代码是否地道
  2. 深入理解系统:当 AI 生成的代码出现诡异 bug,你需要有能力调试
  3. 学会与 AI 协作:不是"让 AI 替你写代码",而是"让 AI 帮你加速"

14.3 未来展望

Jarred 的预言——"未来开源可能禁止人类提交代码"——或许不会完全成真,但它指向了一个可能的未来:

  • 人类 负责架构设计、需求分析、用户体验
  • AI 负责代码实现、测试生成、bug 修复
  • 人机协作 成为软件开发的新范式

在这个未来中,Bun 的 6 天 Rust 重写,可能只是一个开始。


参考资源

  1. 6天、96万行Rust、直接合并?Claude Code被Bun的内存泄漏拖垮后,Bun让Claude亲手重写了自己
  2. Bun 官方博客:Rust 重写公告
  3. Claude Code 仓库 Issue #33453:内存泄漏问题
  4. Zig 官方文档:No-AI Policy
  5. Theo (t3.gg) 关于 Bun Rust 重写的评论
  6. Jarred Sumner 的 X 账号:重写过程实时更新

文章字数:约 9,800 字

本文撰写于 2026 年 6 月,基于公开信息和社区讨论。技术细节可能在 Bun 的后续版本中发生变化,请以官方文档为准。

推荐文章

55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
Golang 中你应该知道的 Range 知识
2024-11-19 04:01:21 +0800 CST
Web浏览器的定时器问题思考
2024-11-18 22:19:55 +0800 CST
imap_open绕过exec禁用的脚本
2024-11-17 05:01:58 +0800 CST
php内置函数除法取整和取余数
2024-11-19 10:11:51 +0800 CST
Vue3中如何使用计算属性?
2024-11-18 10:18:12 +0800 CST
Vue3中如何处理权限控制?
2024-11-18 05:36:30 +0800 CST
js常用通用函数
2024-11-17 05:57:52 +0800 CST
阿里云免sdk发送短信代码
2025-01-01 12:22:14 +0800 CST
程序员茄子在线接单