用MonkeyCode学Rust,一周写出了高性能服务器

用MonkeyCode学Rust,一周写出了高性能服务器

我之前一直想学Rust,但每次看《Rust程序设计语言》都看不下去。上个月,我决定换个方式:不做题,直接做项目,让MonkeyCode当我的「私人导师」。结果一周后,我写出了一个能用的高性能HTTP服务器。

传统学编程的方式,有什么问题?

先说说我之前学Rust的失败经历。

方式1:看书

《Rust程序设计语言》这本书,写得很认真,但太枯燥了。

我看到第3章「所有权」就看不下去了——概念太多,例子太少,看完不知道能干嘛。

方式2:做LeetCode题

刷了10道Rust题,学会了VecHashMap的用法,但依然不知道怎么写一个完整的程序。

方式3:看视频教程

看完了某个Rust入门系列,跟着敲了一遍,但离开视频就不会写了。

问题在哪?

传统学习方式,是「先学语法 → 再学项目」,中间有一道巨大的鸿沟。

你学了一堆语法,但不知道怎么用。等你真正做项目的时候,发现语法书里讲的很多东西,根本用不上。

换个方式:让AI当导师,边做边学

上个月,我决定换个方式:

不做题,直接做项目。遇到不懂的,直接问MonkeyCode。

我选的项目是:「写一个高性能HTTP服务器」。

为什么选这个?

  • 足够复杂(涉及网络编程、并发、内存管理)
  • 足够实用(做完能放到简历里)
  • 足够有挑战性(能逼着我学Rust的核心概念)

第一天:Hello World + 理解所有权

目标:写一个有基本框架的程序,理解Rust的所有权系统。

我让MonkeyCode帮我生成项目骨架:

「帮我用Rust创建一个HTTP服务器的项目骨架,使用tokio做异步运行时,hyper做HTTP服务器。项目结构要清晰,方便后续扩展。」

MonkeyCode给了我:

  • Cargo.toml配置(依赖项、特性配置)
  • src/main.rs(入口文件)
  • src/server.rs(服务器核心逻辑)
  • src/handler.rs(请求处理逻辑)
  • src/config.rs(配置管理)

然后我试着读代码,遇到了第一个拦路虎:所有权

let s1 = String::from("hello");
let s2 = s1;  // s1被移动了!
println!("{}", s1);  // 编译错误!

我直接问MonkeyCode:

「为什么s1不能用了?move语义到底是什么意思?能不能用通俗的话解释一下?」

MonkeyCode的回答:

「你可以把Rust的变量想象成「唯一的遥控器」。当你把s1赋值给s2,相当于把遥控器给了s2s1就不再拥有这个「电视」了。如果你想让s1继续能用,需要用clone()复制一份,或者用&借用来临时使用。」

这个比喻,让我瞬间懂了。

第二天:处理HTTP请求 + 生命周期

目标:实现基本的路由,理解生命周期。

我在handler.rs里写路由:

fn handle_request(req: Request) -> Response {
    match req.path() {
        "/" => index_handler(req),
        "/api/users" => users_handler(req),
        _ => not_found_handler(req),
    }
}

然后遇到了生命周期的问题:

fn index_handler(req: Request) -> &Response {  // 编译错误:缺少生命周期标注
    // ...
}

我又问MonkeyCode:

「生命周期标注到底干嘛用的?为什么返回引用就要标生命周期?」

MonkeyCode的回答:

「生命周期标注,就是告诉编译器:『这个引用,最短活多久。」就像你去借书,图书管理员要确认你能在归还日期前看完。如果返回引用不标生命周期,编译器不知道这个引用会不会变成悬垂引用(指向已经释放的内存)。」

然后它给了我正确的写法:

fn index_handler<'a>(req: Request) -> Response<'a> {
    // ...
}

虽然实际写Web服务时很少需要手写生命周期(因为异步函数和axum/actix-web帮我们处理了),但理解生命周期让我对Rust的内存模型有了更深的理解。

第三天:并发 + Async/Await

目标:理解Rust的并发模型,用tokio处理并发请求。

Rust的并发,跟Python/JS很不一样:

  • Python用线程池 + GIL(全局解释器锁)
  • JS用单线程 + 事件循环
  • **Rust用async/await + tokio(真正的多线程异步)

我让MonkeyCode帮我写一个并发处理的例子:

「帮我写一个Rust程序,用tokio同时处理100个HTTP请求,每个请求耗时1秒(模拟网络IO),看看总共需要多少时间。」

MonkeyCode给了我:

use tokio::time::{sleep, Duration};
use tokio::task;

#[tokio::main]
async fn main() {
    let start = std::time::Instant::now();
    
    let tasks: Vec<_> = (0..100)
        .map(|i| {
            task::spawn(async move {
                sleep(Duration::from_secs(1)).await;
                println!("Task {} done", i);
            })
        })
        .collect();
    
    for t in tasks {
        t.await.unwrap();
    }
    
    println!("Total time: {:?}", start.elapsed());
}

运行结果:总耗时约1秒(而不是100秒)。

这就是异步的威力。

第四天:写出可用的HTTP服务器

目标:把前三天学的东西整合起来,写出能用的HTTP服务器。

我把需求告诉MonkeyCode:

「帮我实现一个完整的HTTP服务器,功能包括:

  1. 路由(GET/POST)
  2. 中间件(日志、CORS)
  3. JSON响应
  4. 错误处理
    代码要符合Rust最佳实践。」

MonkeyCode给了我一个完整的实现,基于axum(Rust生态里最流行的Web框架)。

核心代码:

use axum::{
    routing::{get, post},
    Router,
    Json,
};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct User {
    id: u32,
    name: String,
}

async fn get_user() -> Json<User> {
    Json(User {
        id: 1,
        name: "Alice".to_string(),
    })
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/user", get(get_user));
    
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

跑起来,用curl测试:

$ curl <http://localhost:3000/user>
{"id":1,"name":"Alice"}

成了!

第五天:性能优化 + 压测

目标:优化服务器性能,做压测。

我用wrk做压测:

$ wrk -t12 -c400 -d30s <http://localhost:3000/user>

结果:

  • 吞吐量:约12万请求/秒
  • 平均延迟:约3ms

这个性能,已经跟Go写的服务器差不多了。

然后我让MonkeyCode帮我优化:

「帮我分析这个服务器的性能瓶颈,给出优化建议。」

MonkeyCode的建议:

  1. 使用Bytes减少内存拷贝
  2. 使用连接池(如果用数据库)
  3. 开启#![forbid(unstable_name_collisions)]检查潜在问题
  4. 使用jemalloc替代系统分配器(减少内存碎片)

我按建议改了,性能提升了约15%。

我学到了什么?

这周的学习,让我明白了几个道理:

1. 「边做边学」比「先学再做」效率高10倍

传统学习方式,是先学语法书,再学做项目。

但问题是:你学语法的时候,不知道哪些重要;你做项目的时候,发现语法书里讲的很多东西用不上。

「边做边学」,就是遇到什么学什么,学到的都是马上能用的。

2. AI导师 vs 书本导师

书本的优点是:系统、全面。

但缺点是:不够个性化,不能问问题。

AI导师的优点是:

  • 能回答你的具体问题
  • 能用你的背景知识来解释概念(比如我知道Python,它就用Python来类比Rust)
  • 能给你的代码提建议

对我来说,AI导师比书本更高效。

3. Rust没那么难,只是「要求严格」

很多人说Rust难学。

我觉得Rust不是「难」,而是「严格」:

  • 编译器会严格检查内存安全
  • 编译器会严格检查数据竞争
  • 编译器会严格检查生命周期

这些「严格」,是为了帮你避免bug。

一旦你理解了Rust的规则,写起来其实挺顺手的。

写在最后

用MonkeyCode学Rust,一周写出了高性能服务器。

不是因为我聪明,而是因为我换了一种学习方式:不做题,直接做项目,让AI当我的私人导师。

如果你也想学一门新技术,不妨试试用AI当导师。

MonkeyCode官网:https://monkeycode.ai

(PS:有同学问我「一周学完Rust,能找到Rust的工作吗?」我的回答是:不能。一周只能入门,真正找工作至少需要3-6个月的深入学习和项目积累。但不要因为「不能马上找到工作」就不开始学。)

posted @ 2026-05-26 12:21  机房管理员  阅读(15)  评论(0)    收藏  举报