KKKZOZ’s Blog

Pass The Wall

“Across the Great Wall we can reach every corner in the world.”1 Remote Port Forwarding 让云服务器方便快捷地使用本地代理 建立远程端口转发 ssh -R 1082:127.0.0.1:1082 s2-ljy -p 22 配置云服务器的代理环境变量 export HTTP_PROXY="http://127.0.0.1:1082" export HTTPS_PROXY="http://127.0.0.1:1082" Caution 这是临时设置, 仅对当前终端生效, 如果想永久设置, 请编辑 ~/.bashrc ...

March 30, 2025 · 2 min · KKKZOZ

Docker Network Introduction

整理一下常见的 Docker Network 操作 Default Bridge Network After a fresh Docker installation, you can find a default bridge network up and running. docker network ls Docker uses a software-based bridge network that allows containers connected to the same bridge network to communicate while isolating them from other containers not running in the same bridge network. docker run -dit --name busybox1 busybox docker run -dit --name busybox2 busybox docker inspect busybox1 | jq -r ' [0].NetworkSettings.IPAddress' docker inspect busybox2 | jq -r '.[0].NetworkSettings.IPAddress' # OK docker exec -it busybox2 ping 172.17.0.3 # Error docker exec -it busybox2 ping busybox1 Conclusion All containers will automatically connect to this default bridge network. Default bridge network allows container communication using IP addresses. ...

March 29, 2025 · 3 min · KKKZOZ

Using Rust

记录一些在写 Rust 时遇到的错误和重构 Ownership let mut reader = BufReader::new(stream_reader); let mut buffer = String::new(); serde_json::to_writer(&mut stream, &cli.command).unwrap(); stream.flush().unwrap(); reader.read_line(&mut buffer).unwrap(); let response = buffer .trim_end() .to_string() .split(':') .collect::<Vec<&str>>(); 这段代码会在 .to_string() 这里报错, 因为 .trim_end() 返回一个 &str .to_string() 将这个 &str 转换为一个新的临时 String(拥有所有权的新字符串) 在这个临时 String 上调用 .split(’:’),这会返回一个迭代器,产生 &str 切片 临时 String 在语句结束时被丢弃,导致这些切片变成悬垂引用 修改思路有几种: 直接收集 String let response = buffer .trim_end() .split(':') .map(|s| s.to_string()) .collect::<Vec<String>>(); 直接引用原始的 buffer let response = buffer.trim_end().split(':').collect::<Vec<&str>>(); Generics fn create_engine(engine_name: &str) -> Result<Box<dyn KvsEngine>> { match engine_name { "kvs" => { let kvs = KvStore::open(current_dir()?)?; Ok(Box::new(kvs)) } "sled" => { let sled = SledKvsEngine::new(sled::open("kvs.db")?); Ok(Box::new(sled)) } _ => { panic!("Invalid engine name"); } } } 如果想用泛型的静态分配, 就必须分离引擎的创建逻辑 ...

March 26, 2025 · 7 min · KKKZOZ

100 Mistakes in Golang: Chapter 8 & 9

55: Mixing up concurrency and parallelism Concurrency enables parallelism. Concurrency provides a structure to solve a problem with parts that may be parallelized. Quote “Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.” ...

March 19, 2025 · 4 min · KKKZOZ

100 Exercises to Learn Rust Note

4 Traits To invoke a trait method, two things must be true: The type must implement the trait. The trait must be in scope. To satisfy the latter, you may have to add a use statement for the trait: use crate::MaybeZero; This is not necessary if: The trait is defined in the same module where the invocation occurs. The trait is defined in the standard library’s prelude. The prelude is a set of traits and types that are automatically imported into every Rust program. It’s as if use std::prelude::*; was added at the beginning of every Rust module. Orphan Rule When a type is defined in another crate (e.g. u32, from Rust’s standard library), you can’t directly define new methods for it. ...

March 13, 2025 · 5 min · KKKZOZ