[{"content":"Rust Unlimited Intro - Three Times Failed Introduction Rust has topped Stack Overflow\u0026rsquo;s \u0026ldquo;most loved language\u0026rdquo; survey for years, but its learning curve is equally famous. I started and quit learning Rust three times since 2023 before finally getting past the initial barrier. This is the story of that journey.\nWhy Learn Rust? Performance \u0026amp; Safety: Memory safety without garbage collection — no more GC pause nightmares or segfaults Modern Toolchain: Cargo, rustfmt, and Clippy create a seamless build/test/lint experience that makes C++ tooling feel archaic Type System That Catches Bugs Early: The compiler catches an incredible amount of errors before runtime — fewer 3 AM on-call wake-ups Growing Industry Adoption: From Linux kernel modules to cloud infrastructure (AWS, Cloudflare), Rust is becoming the standard for systems-level work Three Attempts, Three Failures Attempt 1: Ownership sent me running The first three chapters of The Rust Book felt comfortable — modern syntax, immutability by default, elegant pattern matching. Then Chapter 4 on Ownership hit:\nfn main() { let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; // s1 is *moved* here // println!(\u0026#34;{}\u0026#34;, s1); // Compile error — s1 is no longer valid! } I genuinely couldn\u0026rsquo;t understand why a simple assignment would invalidate the original variable. I didn\u0026rsquo;t yet grasp that Rust was enforcing single-ownership at compile time to eliminate use-after-free. I closed the book.\nAttempt 2: Lifetimes broke me A few months later I tried again, grinding through ownership. Then lifetimes appeared:\nfn longest\u0026lt;\u0026#39;a\u0026gt;(x: \u0026amp;\u0026#39;a str, y: \u0026amp;\u0026#39;a str) -\u0026gt; \u0026amp;\u0026#39;a str { if x.len() \u0026gt; y.len() { x } else { y } } The 'a syntax felt like fighting the compiler rather than writing code. In hindsight, the borrow checker simply needs explicit annotations when it can\u0026rsquo;t infer which input the return value ties to — but at the time, it just felt hostile.\nAttempt 3: What finally worked On the third attempt, I changed strategy: stop trying to understand everything upfront. Just write code that works.\nUse .clone() liberally to get past ownership errors — ignore the \u0026ldquo;you\u0026rsquo;re wasting memory\u0026rdquo; guilt Start with small CLI tools, not performance-critical libraries Use owned types (String instead of \u0026amp;str) in structs to avoid lifetime headaches initially After writing a few hundred lines of working Rust, I went back and re-read the ownership and borrowing chapters. Suddenly they made sense: the compiler isn\u0026rsquo;t punishing you — it\u0026rsquo;s managing memory on your behalf at compile time.\nThe Three Core Rules Once it clicked, Rust\u0026rsquo;s constraints distill down to three simple rules:\nEach value has exactly one owner at a time At any given moment, you can have either one mutable reference OR any number of immutable references — never both References must always be valid (enforced by lifetimes) Master these three and most compiler errors become self-explanatory.\nRecommended Learning Path If you\u0026rsquo;re starting out:\nThe Rust Book — Chapters 1-6 are essential; the interactive code snippets in the browser are excellent Rustlings — Make tests pass by fixing code; the most hands-on way to learn Rust By Example — Learn syntax and standard library through annotated examples Exercism Rust Track — Community-reviewed exercises with mentor feedback Will This Time Stick? I\u0026rsquo;m setting a concrete goal: finish the entire Rust Book and build at least two small tools I\u0026rsquo;d actually use. The learning curve is real, but crossing it gives you something rare — genuine confidence that your code won\u0026rsquo;t blow up in production due to memory bugs.\nLearning in progress — more notes to come\u0026hellip;\n","permalink":"https://CoderAmedal.github.io/en/posts/three-times-rust-learning/","summary":"\u003ch1 id=\"rust-unlimited-intro---three-times-failed\"\u003eRust Unlimited Intro - Three Times Failed\u003c/h1\u003e\n\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eRust has topped Stack Overflow\u0026rsquo;s \u0026ldquo;most loved language\u0026rdquo; survey for years, but its learning curve is equally famous. I started and quit learning Rust three times since 2023 before finally getting past the initial barrier. This is the story of that journey.\u003c/p\u003e\n\u003ch2 id=\"why-learn-rust\"\u003eWhy Learn Rust?\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ePerformance \u0026amp; Safety\u003c/strong\u003e: Memory safety without garbage collection — no more GC pause nightmares or segfaults\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eModern Toolchain\u003c/strong\u003e: Cargo, rustfmt, and Clippy create a seamless build/test/lint experience that makes C++ tooling feel archaic\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eType System That Catches Bugs Early\u003c/strong\u003e: The compiler catches an incredible amount of errors before runtime — fewer 3 AM on-call wake-ups\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGrowing Industry Adoption\u003c/strong\u003e: From Linux kernel modules to cloud infrastructure (AWS, Cloudflare), Rust is becoming the standard for systems-level work\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"three-attempts-three-failures\"\u003eThree Attempts, Three Failures\u003c/h2\u003e\n\u003ch3 id=\"attempt-1-ownership-sent-me-running\"\u003eAttempt 1: Ownership sent me running\u003c/h3\u003e\n\u003cp\u003eThe first three chapters of The Rust Book felt comfortable — modern syntax, immutability by default, elegant pattern matching. Then Chapter 4 on Ownership hit:\u003c/p\u003e","title":"Rust Unlimited Intro - Three Times Failed"},{"content":"Java还有救吗？ 这个问题背后的情绪 每隔一段时间就会有\u0026quot;Java 已死\u0026quot;的讨论。坦白说，Java 确实有让人不爽的地方：代码冗长、启动慢、内存占用大、框架配置繁琐。和 Go 的简洁、Rust 的性能、Kotlin 的语法糖比起来，Java 显得有些老态龙钟。\n但我觉得这问题的前提就错了——语言不是用来比的，是用来干活儿的。\nJava 真正的竞争力是什么 三个字：生态、人才、兼容。\n生态 Spring Boot、MyBatis、Netty、Kafka、Elasticsearch、Hadoop、Flink……几乎所有中间件和基础设施都对 Java 有一流支持。这不是一朝一夕能追赶的。\n人才 Java 开发者的存量是其他语言难以比拟的。一个公司如果用 Go 或 Rust 创业，招人的难度和成本都会显著高于 Java。不是每个人都能为技术品味买单。\n兼容 Java 的向后兼容性是业界标杆。十年前写的代码今天还能跑，这在一些业务场景中是无价之宝。银行、保险、政务这些行业的系统换代周期极长，Java 的稳定性就是核心竞争力。\nJava 这几年的自救 Java 的演进速度最近明显加快了：\nJava 17/21 LTS：稳定可靠的新时代基线 虚拟线程（Project Loom）：彻底解决了\u0026quot;一个请求一个线程\u0026quot;的资源瓶颈，不需要再用 WebFlux 写回调地狱 Record 类：再也不用写 getter/setter/equals/hashCode 了 模式匹配 + switch 表达式：语法表达力大幅提升 Valhalla（值类型）：解决 Integer vs int 的装箱地狱，性能进一步提升 Panama（外部函数和内存 API）：告别 JNI 的噩梦 虚拟线程是真正意义上的 game changer——它能在一个 JVM 实例上跑数百万个轻量级线程，与 Go 的 goroutine 正面对标，还不需要破坏现有的 Thread API。\nJava 的短板在哪 启动慢、内存占用大：在 Serverless 场景中确实吃亏，不过 GraalVM 原生编译在逐步改善 语法负担：即使有了 Record 和 var，和 Kotlin/Scala 比还是冗长 学习曲线不低：Spring 全家桶加上 JVM 调优参数，够新人喝一壶的 云原生生态：Kubernetes health check、sidecar 模式等，Go 更原生地融入 我的结论 Java 不会是\u0026quot;最酷\u0026quot;的语言，但它一定会在未来很长时间内是最稳的选择之一。对于绝大多数业务系统来说，Java 的能力绰绰有余，而它的稳定性、人才储备和生态支持，是其他语言短期内无法取代的。\n如果你的目标是追求性能极致和底层控制——学 Rust。如果你的目标是云原生微服务和高并发——学 Go。如果你的目标是找一个能稳定交付业务价值、团队协作成本最低的技术栈——Java 仍然是一个非常合理的选择。\nJava 不是\u0026quot;有没有救\u0026quot;的问题，而是\u0026quot;你想用它解决什么问题\u0026quot;的问题。\n","permalink":"https://CoderAmedal.github.io/posts/java-future/","summary":"\u003ch1 id=\"java还有救吗\"\u003eJava还有救吗？\u003c/h1\u003e\n\u003ch2 id=\"这个问题背后的情绪\"\u003e这个问题背后的情绪\u003c/h2\u003e\n\u003cp\u003e每隔一段时间就会有\u0026quot;Java 已死\u0026quot;的讨论。坦白说，Java 确实有让人不爽的地方：代码冗长、启动慢、内存占用大、框架配置繁琐。和 Go 的简洁、Rust 的性能、Kotlin 的语法糖比起来，Java 显得有些老态龙钟。\u003c/p\u003e\n\u003cp\u003e但我觉得这问题的前提就错了——\u003cstrong\u003e语言不是用来比的，是用来干活儿的。\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"java-真正的竞争力是什么\"\u003eJava 真正的竞争力是什么\u003c/h2\u003e\n\u003cp\u003e三个字：\u003cstrong\u003e生态、人才、兼容。\u003c/strong\u003e\u003c/p\u003e\n\u003ch3 id=\"生态\"\u003e生态\u003c/h3\u003e\n\u003cp\u003eSpring Boot、MyBatis、Netty、Kafka、Elasticsearch、Hadoop、Flink……几乎所有中间件和基础设施都对 Java 有一流支持。这不是一朝一夕能追赶的。\u003c/p\u003e\n\u003ch3 id=\"人才\"\u003e人才\u003c/h3\u003e\n\u003cp\u003eJava 开发者的存量是其他语言难以比拟的。一个公司如果用 Go 或 Rust 创业，招人的难度和成本都会显著高于 Java。不是每个人都能为技术品味买单。\u003c/p\u003e\n\u003ch3 id=\"兼容\"\u003e兼容\u003c/h3\u003e\n\u003cp\u003eJava 的向后兼容性是业界标杆。十年前写的代码今天还能跑，这在一些业务场景中是无价之宝。银行、保险、政务这些行业的系统换代周期极长，Java 的稳定性就是核心竞争力。\u003c/p\u003e\n\u003ch2 id=\"java-这几年的自救\"\u003eJava 这几年的自救\u003c/h2\u003e\n\u003cp\u003eJava 的演进速度最近明显加快了：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eJava 17/21 LTS\u003c/strong\u003e：稳定可靠的新时代基线\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e虚拟线程（Project Loom）\u003c/strong\u003e：彻底解决了\u0026quot;一个请求一个线程\u0026quot;的资源瓶颈，不需要再用 WebFlux 写回调地狱\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRecord 类\u003c/strong\u003e：再也不用写 getter/setter/equals/hashCode 了\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e模式匹配 + switch 表达式\u003c/strong\u003e：语法表达力大幅提升\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eValhalla（值类型）\u003c/strong\u003e：解决 \u003ccode\u003eInteger\u003c/code\u003e vs \u003ccode\u003eint\u003c/code\u003e 的装箱地狱，性能进一步提升\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePanama（外部函数和内存 API）\u003c/strong\u003e：告别 JNI 的噩梦\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e虚拟线程是真正意义上的 game changer——它能在一个 JVM 实例上跑数百万个轻量级线程，与 Go 的 goroutine 正面对标，还不需要破坏现有的 \u003ccode\u003eThread\u003c/code\u003e API。\u003c/p\u003e","title":"Java还有救吗？"},{"content":"三入三废的Rust的入门 前言 Rust 连续多年在 Stack Overflow 的\u0026quot;最受喜爱语言\u0026quot;调查中排第一，但同样有名的还有它的学习曲线。我从 2023 年开始，前后三次打开 The Rust Book，又三次关上——直到最近才终于摸到了一点门道。这篇文章记录我反复放弃又重新开始的过程，以及这次觉得终于\u0026quot;入门了\u0026quot;的几个关键点。\n为什么要学 Rust 对我个人而言，有几个朴素的动机：\n写过高并发服务被 GC 停顿坑过：Rust 无 GC 的内存安全保证，解决了\u0026quot;要性能还是安全\u0026quot;的两难 Cargo 生态太舒服了：一个命令搞定构建、依赖、测试、发布，比 C++ 的 CMake 地狱友好太多 类型系统的安全感：Rust 的类型系统让很多 bug 在编译期就被拦截，而不是半夜被报警叫起来排查 三次放弃的心路历程 第一次：所有权直接劝退 第一次翻开 The Rust Book，前三章还挺舒服——语法挺现代的，变量默认不可变，模式匹配很优雅。到 第四章 所有权那里，一切戛然而止。\nfn main() { let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; println!(\u0026#34;{}\u0026#34;, s1); // 编译错误！ } 我真的愣住了，心想\u0026quot;凭什么赋值一下就把原变量废了？\u0026quot;——后来才明白这是 Rust 所有权转移（move） 的核心，目的是在编译期就标记哪些内存只能有一个 owner。当时理解不了这套心智模型，就放弃了。\n第二次：生命周期劝退 几个月后又鼓起勇气再读，这次咬着牙过了所有权。但到了生命周期标注，再次崩溃：\nfn longest\u0026lt;\u0026#39;a\u0026gt;(x: \u0026amp;\u0026#39;a str, y: \u0026amp;\u0026#39;a str) -\u0026gt; \u0026amp;\u0026#39;a str { if x.len() \u0026gt; y.len() { x } else { y } } 'a 是什么？为什么需要手动标？编译器不是能推导生命周期吗？——实际上编译器有时候确实搞不清返回的引用到底来自哪个参数，需要人工标注来约束。但当时的我不理解背后的借用检查器逻辑，只觉得是在和编译器打架。\n第三次：终于入门的转折点 第三次回头学 Rust 时，我换了一个策略：不要试图一次性理解所有概念，先写能跑的代码。\n先用 clone() 绕过所有权问题，不要怕\u0026quot;不高效\u0026quot;的批评 先去写小工具，不要一上来就写高性能库 遇到生命周期错误，先把 struct 改成存 owned 类型（String而非\u0026amp;str） 写了几百行能跑的代码之后，回过头再看所有权和借用——忽然觉得设计得很有道理：编译器不是在刁难你，它在帮你管理内存。\nRust 的核心心智模型：三条铁律 入门之后回头看，Rust 的核心约束其实就三条：\n一个值同时只能有一个 owner 同一时刻，要么一个可变引用，要么多个不可变引用——二者不能共存 引用必须始终有效（由生命周期保证） 理解了这三条，Rust 的大部分编译错误都能解释了。\n推荐的学习路径（如果你也想入门） The Rust Book（前六章必读）：官方入门书，质量非常高，每一章都可以在浏览器里直接运行示例 Rustlings：交互式练习项目，通过修改代码让测试通过来学习，非常适合动手党 Rust By Example：通过实例学习语法和标准库用法 Exercism Rust Track：有 mentor review 的练习题，能获得社区反馈 这次能坚持多久 这次写个 flag——至少读完 The Rust Book 全书，再用 Rust 写一两个自己能用的工具。Rust 的学习曲线确实陡峭，但跨过那道坎后，收获的是一种前所未有的\u0026quot;编译器帮我兜底\u0026quot;的踏实感。\n持续学习中，后续会更新学习笔记\u0026hellip;\n","permalink":"https://CoderAmedal.github.io/posts/three-times-rust-learning/","summary":"\u003ch1 id=\"三入三废的rust的入门\"\u003e三入三废的Rust的入门\u003c/h1\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003eRust 连续多年在 Stack Overflow 的\u0026quot;最受喜爱语言\u0026quot;调查中排第一，但同样有名的还有它的学习曲线。我从 2023 年开始，前后三次打开 The Rust Book，又三次关上——直到最近才终于摸到了一点门道。这篇文章记录我反复放弃又重新开始的过程，以及这次觉得终于\u0026quot;入门了\u0026quot;的几个关键点。\u003c/p\u003e\n\u003ch2 id=\"为什么要学-rust\"\u003e为什么要学 Rust\u003c/h2\u003e\n\u003cp\u003e对我个人而言，有几个朴素的动机：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e写过高并发服务被 GC 停顿坑过\u003c/strong\u003e：Rust 无 GC 的内存安全保证，解决了\u0026quot;要性能还是安全\u0026quot;的两难\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCargo 生态太舒服了\u003c/strong\u003e：一个命令搞定构建、依赖、测试、发布，比 C++ 的 CMake 地狱友好太多\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e类型系统的安全感\u003c/strong\u003e：Rust 的类型系统让很多 bug 在编译期就被拦截，而不是半夜被报警叫起来排查\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"三次放弃的心路历程\"\u003e三次放弃的心路历程\u003c/h2\u003e\n\u003ch3 id=\"第一次所有权直接劝退\"\u003e第一次：所有权直接劝退\u003c/h3\u003e\n\u003cp\u003e第一次翻开 The Rust Book，前三章还挺舒服——语法挺现代的，变量默认不可变，模式匹配很优雅。到 第四章 所有权那里，一切戛然而止。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003efn\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emain\u003c/span\u003e() {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e s1 \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e String::from(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e s2 \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e s1;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003eprintln!\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e{}\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e, s1); \u003cspan style=\"color:#75715e\"\u003e// 编译错误！\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我真的愣住了，心想\u0026quot;凭什么赋值一下就把原变量废了？\u0026quot;——后来才明白这是 Rust \u003cstrong\u003e所有权转移（move）\u003c/strong\u003e 的核心，目的是在编译期就标记哪些内存只能有一个 owner。当时理解不了这套心智模型，就放弃了。\u003c/p\u003e\n\u003ch3 id=\"第二次生命周期劝退\"\u003e第二次：生命周期劝退\u003c/h3\u003e\n\u003cp\u003e几个月后又鼓起勇气再读，这次咬着牙过了所有权。但到了生命周期标注，再次崩溃：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003efn\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elongest\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e\u0026lt;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003e\u0026#39;a\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u003c/span\u003e(x: \u003cspan style=\"color:#66d9ef\"\u003e\u0026amp;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003e\u0026#39;a\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003estr\u003c/span\u003e, y: \u003cspan style=\"color:#66d9ef\"\u003e\u0026amp;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003e\u0026#39;a\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003estr\u003c/span\u003e) -\u0026gt; \u003cspan style=\"color:#66d9ef\"\u003e\u0026amp;\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003e\u0026#39;a\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003estr\u003c/span\u003e {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e x.len() \u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u003c/span\u003e y.len() { x } \u003cspan style=\"color:#66d9ef\"\u003eelse\u003c/span\u003e { y }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003e'a\u003c/code\u003e 是什么？为什么需要手动标？编译器不是能推导生命周期吗？——实际上编译器有时候确实搞不清返回的引用到底来自哪个参数，需要人工标注来约束。但当时的我不理解背后的借用检查器逻辑，只觉得是在和编译器打架。\u003c/p\u003e","title":"三入三废的Rust的入门"},{"content":"绿导师：\u0026ldquo;数据即知识，压缩即智能\u0026quot;的个人解读 这句话从哪里来 这句话出自 Marcus Hutter（人称\u0026quot;绿导师\u0026rdquo;），他是 AIXI 理论模型的提出者，Hutter Prize（压缩人类知识竞赛）的发起人。原话大致是：\u0026ldquo;data is knowledge, compression is intelligence\u0026rdquo;。\n第一次听到这句话时我觉得它很玄学——压缩不就是 zip 吗，跟智能有什么关系？后来慢慢理解了其中的深意。\n压缩的本质是找规律 压缩算法做的事情很简单：找到数据中的冗余，用更短的符号表示它。\n举个例子：字符串 \u0026quot;ABABABABABAB\u0026quot;，可以压缩为 \u0026quot;AB×6\u0026quot;。这个压缩过程的前提是算法\u0026quot;发现\u0026quot;了重复模式 \u0026quot;AB\u0026quot;。\n这和智能有什么关系？智能的本质就是发现模式。 人类看到天空乌云密布就知道要下雨，这不是玄学，是因为我们的大脑从过去的经验数据中\u0026quot;压缩\u0026quot;出了一个模式：乌云 → 下雨。\n从信息论的角度看 Shannon 的信息论告诉我们：信息量 = 不确定性的大小。一个完全随机的序列无法被压缩，因为它没有规律。而一个能被高度压缩的数据集，说明它内部存在很强的规律性。\n这和机器学习的训练过程完全一致：\n模型训练 = 从海量数据中提取共同模式（压缩） 模型推理 = 用提取的模式来解释或预测新数据（解压） GPT 系列模型本质上做了一件事：用几十亿个参数将互联网上的文本压缩成了一个\u0026quot;世界模型\u0026quot;。参数越少、效果越好 = 压缩率越高、失真越低。\nHutter Prize 的启发 Hutter Prize 的规则很简单：谁能把 1GB 的维基百科文本压缩得最小，谁就拿奖。这背后是一个哲学假设：压缩能力 = 理解能力。\n一个只会做字符替换的压缩算法（比如 gzip）无法真正压缩维基百科到极致，因为它不理解语义。但一个理解\u0026quot;中国首都 = 北京\u0026quot;这个知识的人（或 AI），看到文中第三次出现\u0026quot;中国的首都是北京\u0026quot;时，就可以用极短的引用来代替。\n这和人类学习知识如出一辙：学得越透彻 = 能用越少的关键概念复述整个知识体系。\n对我日常工作的启发 写代码本质上也是一种压缩。 好的抽象就是对重复模式的压缩——把常见逻辑提取成函数、类、模块，本质上和 zip 做的是同一件事。DRY（Don\u0026rsquo;t Repeat Yourself）原则就是编程中的压缩原则。\n反过来看，如果我们发现某个模块难以抽象、代码总是重复——那可能是因为我们对业务模式本身的理解还不够深，还没能找到那个可以被压缩的规律。\n小结 \u0026ldquo;压缩即智能\u0026quot;不是一个可以写在简历上的实用技能，但它提供了一种理解 AI 和智能的元视角：智能 = 从经验中学习规律 = 压缩数据中的冗余。这个框架虽然简化了问题，但用来思考学习和知识体系构建，还是挺有用的。\n","permalink":"https://CoderAmedal.github.io/posts/data-compression-intelligence/","summary":"\u003ch1 id=\"绿导师数据即知识压缩即智能的个人解读\"\u003e绿导师：\u0026ldquo;数据即知识，压缩即智能\u0026quot;的个人解读\u003c/h1\u003e\n\u003ch2 id=\"这句话从哪里来\"\u003e这句话从哪里来\u003c/h2\u003e\n\u003cp\u003e这句话出自 Marcus Hutter（人称\u0026quot;绿导师\u0026rdquo;），他是 AIXI 理论模型的提出者，Hutter Prize（压缩人类知识竞赛）的发起人。原话大致是：\u0026ldquo;data is knowledge, compression is intelligence\u0026rdquo;。\u003c/p\u003e\n\u003cp\u003e第一次听到这句话时我觉得它很玄学——压缩不就是 zip 吗，跟智能有什么关系？后来慢慢理解了其中的深意。\u003c/p\u003e\n\u003ch2 id=\"压缩的本质是找规律\"\u003e压缩的本质是找规律\u003c/h2\u003e\n\u003cp\u003e压缩算法做的事情很简单：\u003cstrong\u003e找到数据中的冗余，用更短的符号表示它。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e举个例子：字符串 \u003ccode\u003e\u0026quot;ABABABABABAB\u0026quot;\u003c/code\u003e，可以压缩为 \u003ccode\u003e\u0026quot;AB×6\u0026quot;\u003c/code\u003e。这个压缩过程的前提是算法\u0026quot;发现\u0026quot;了重复模式 \u003ccode\u003e\u0026quot;AB\u0026quot;\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e这和智能有什么关系？\u003cstrong\u003e智能的本质就是发现模式。\u003c/strong\u003e 人类看到天空乌云密布就知道要下雨，这不是玄学，是因为我们的大脑从过去的经验数据中\u0026quot;压缩\u0026quot;出了一个模式：乌云 → 下雨。\u003c/p\u003e\n\u003ch2 id=\"从信息论的角度看\"\u003e从信息论的角度看\u003c/h2\u003e\n\u003cp\u003eShannon 的信息论告诉我们：\u003cstrong\u003e信息量 = 不确定性的大小\u003c/strong\u003e。一个完全随机的序列无法被压缩，因为它没有规律。而一个能被高度压缩的数据集，说明它内部存在很强的规律性。\u003c/p\u003e\n\u003cp\u003e这和机器学习的训练过程完全一致：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e模型训练 = 从海量数据中提取共同模式（压缩）\u003c/li\u003e\n\u003cli\u003e模型推理 = 用提取的模式来解释或预测新数据（解压）\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGPT 系列模型本质上做了一件事：\u003cstrong\u003e用几十亿个参数将互联网上的文本压缩成了一个\u0026quot;世界模型\u0026quot;\u003c/strong\u003e。参数越少、效果越好 = 压缩率越高、失真越低。\u003c/p\u003e\n\u003ch2 id=\"hutter-prize-的启发\"\u003eHutter Prize 的启发\u003c/h2\u003e\n\u003cp\u003eHutter Prize 的规则很简单：谁能把 1GB 的维基百科文本压缩得最小，谁就拿奖。这背后是一个哲学假设：\u003cstrong\u003e压缩能力 = 理解能力\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e一个只会做字符替换的压缩算法（比如 gzip）无法真正压缩维基百科到极致，因为它不理解语义。但一个理解\u0026quot;中国首都 = 北京\u0026quot;这个知识的人（或 AI），看到文中第三次出现\u0026quot;中国的首都是北京\u0026quot;时，就可以用极短的引用来代替。\u003c/p\u003e\n\u003cp\u003e这和人类学习知识如出一辙：\u003cstrong\u003e学得越透彻 = 能用越少的关键概念复述整个知识体系。\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"对我日常工作的启发\"\u003e对我日常工作的启发\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e写代码本质上也是一种压缩。\u003c/strong\u003e 好的抽象就是对重复模式的压缩——把常见逻辑提取成函数、类、模块，本质上和 zip 做的是同一件事。DRY（Don\u0026rsquo;t Repeat Yourself）原则就是编程中的压缩原则。\u003c/p\u003e\n\u003cp\u003e反过来看，如果我们发现某个模块难以抽象、代码总是重复——那可能是因为我们对业务模式本身的理解还不够深，还没能找到那个可以被压缩的规律。\u003c/p\u003e\n\u003ch2 id=\"小结\"\u003e小结\u003c/h2\u003e\n\u003cp\u003e\u0026ldquo;压缩即智能\u0026quot;不是一个可以写在简历上的实用技能，但它提供了一种理解 AI 和智能的元视角：\u003cstrong\u003e智能 = 从经验中学习规律 = 压缩数据中的冗余\u003c/strong\u003e。这个框架虽然简化了问题，但用来思考学习和知识体系构建，还是挺有用的。\u003c/p\u003e","title":"绿导师：\"数据即知识，压缩即智能\"的个人解读"},{"content":"Podman与Docker的架构分析 为什么要关注这个对比 Docker Desktop 从 2021 年起对大型企业收费，加上 Docker 本身的一些架构问题（守护进程单点故障、root 权限依赖），促使很多人开始考虑替代方案。Podman 是目前最成熟的替代者。\n我从一个日常使用容器的开发者的角度，聊聊这两个工具的核心差异。\n架构差异 Docker：守护进程模型 用户 → docker CLI → dockerd（守护进程）→ containerd → runc → 容器 Docker 的核心问题是所有操作都经过一个 root 权限的常驻守护进程（dockerd）。这意味着：\ndockerd 挂了，所有容器的管理能力就没了 dockerd 本身是 root 权限运行，是一个安全风险面 日志、网络等资源都受 dockerd 控制，难以用 systemd 等标准工具管理 Podman：无守护进程模型 用户 → podman CLI → 直接 fork → conmon → runc → 容器 Podman 没有后台守护进程。每次运行容器时，Podman 直接 fork 出一个子进程，通过 conmon 作为容器的监控进程。这意味着：\n没有单点故障 可以用 systemd 管理容器（配合 podman generate systemd） 天然支持 rootless rootless 容器的实际意义 Docker 也有 rootless 模式（Docker 19.03+ 引入），但是通过用户态模拟实现的，存在一些限制。Podman 的 rootless 模式从一开始就是核心设计目标，实现得更加成熟。\nrootless 容器意味着：\n容器内的 root 映射到宿主机的普通用户，即使容器被攻破，攻击者也只能获得普通用户权限 多租户环境：每个用户可以在自己的命名空间中运行容器，互不干扰 CI/CD 场景：不需要给 CI runner root 权限 命令兼容性 Podman 的设计目标之一就是兼容 Docker CLI。日常使用中，alias docker=podman 基本够用：\n# 基本操作几乎一致 podman build -t myapp . podman run -d -p 8080:80 myapp podman ps podman logs \u0026lt;container\u0026gt; Podman 独有的好功能 podman generate systemd：为容器生成 systemd 服务文件，让容器像普通服务一样由 systemd 管理，这是我觉得最实用的功能 podman play kube：直接用 Kubernetes YAML 定义运行容器，一站式从本地开发到 K8s 部署 podman machine：在 macOS/Windows 上提供虚拟机支持（不需要 Docker Desktop） 如何选择 场景 推荐 个人开发、学习容器 Podman（免费、rootless、systemd 集成） 团队已有 Docker 成熟工作流 继续用 Docker，迁移有成本 CI/CD 流水线 Podman（不需要持久守护进程） 需要 docker-compose 的项目 podman-compose 替代或直接用 docker-compose 生产环境容器编排 Kubernetes/containerd，Docker/Podman 都是本地开发工具 一点经验 我从 Docker 切到 Podman 的体验总体是顺畅的，99% 的命令可以直接 alias。唯一遇到问题的是个别镜像的 ENTRYPOINT 写法依赖 Docker 特定的行为，偶尔需要微调。另外 Podman 的 --network 行为和 Docker 略有差异（Podman 默认不创建 bridge 网络），了解这一点就不会被坑。\n总体来说，对于大多数开发场景，Podman 已经是一个可以直接替换 Docker 的选择。\n","permalink":"https://CoderAmedal.github.io/posts/podman-docker-architecture/","summary":"\u003ch1 id=\"podman与docker的架构分析\"\u003ePodman与Docker的架构分析\u003c/h1\u003e\n\u003ch2 id=\"为什么要关注这个对比\"\u003e为什么要关注这个对比\u003c/h2\u003e\n\u003cp\u003eDocker Desktop 从 2021 年起对大型企业收费，加上 Docker 本身的一些架构问题（守护进程单点故障、root 权限依赖），促使很多人开始考虑替代方案。Podman 是目前最成熟的替代者。\u003c/p\u003e\n\u003cp\u003e我从一个日常使用容器的开发者的角度，聊聊这两个工具的核心差异。\u003c/p\u003e\n\u003ch2 id=\"架构差异\"\u003e架构差异\u003c/h2\u003e\n\u003ch3 id=\"docker守护进程模型\"\u003eDocker：守护进程模型\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e用户 → docker CLI → dockerd（守护进程）→ containerd → runc → 容器\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eDocker 的核心问题是\u003cstrong\u003e所有操作都经过一个 root 权限的常驻守护进程（dockerd）\u003c/strong\u003e。这意味着：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edockerd 挂了，所有容器的管理能力就没了\u003c/li\u003e\n\u003cli\u003edockerd 本身是 root 权限运行，是一个安全风险面\u003c/li\u003e\n\u003cli\u003e日志、网络等资源都受 dockerd 控制，难以用 systemd 等标准工具管理\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"podman无守护进程模型\"\u003ePodman：无守护进程模型\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e用户 → podman CLI → 直接 fork → conmon → runc → 容器\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003ePodman 没有后台守护进程。每次运行容器时，Podman 直接 fork 出一个子进程，通过 conmon 作为容器的监控进程。这意味着：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e没有单点故障\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e可以用 systemd 管理容器\u003c/strong\u003e（配合 \u003ccode\u003epodman generate systemd\u003c/code\u003e）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e天然支持 rootless\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"rootless-容器的实际意义\"\u003erootless 容器的实际意义\u003c/h2\u003e\n\u003cp\u003eDocker 也有 rootless 模式（Docker 19.03+ 引入），但是通过用户态模拟实现的，存在一些限制。Podman 的 rootless 模式从一开始就是核心设计目标，实现得更加成熟。\u003c/p\u003e","title":"Podman与Docker的架构分析"},{"content":"初次使用Vibe Coding 带来的思考与反思 什么是 Vibe Coding Vibe Coding 是最近流行起来的一个说法，大致意思是：对着 AI 编程助手描述你想要的功能，然后让它生成代码，不满意就继续对话调整——整个过程像是在跟代码\u0026quot;聊天\u0026quot;，而不是在写代码。\n今年尝试了 Cursor 和 Claude 的编码助手之后，对 Vibe Coding 有了切身体验，这篇是我的个人反思。\n直观的感受：高效与不安并存 第一次用 AI 生成一个完整的 CRUD 接口时，我的感觉是震撼的——几行自然语言描述，几十行代码自动生成，import 全都正确，异常处理都帮我写好了。前后不到一分钟。\n但紧接着就是一种隐隐的不安：这段代码真的正确吗？每一行的意图我都理解吗？如果有隐蔽的 bug，我能发现吗？\n这种不安感其实很准确——AI 生成的代码看起来都对，但偶尔会在一些意想不到的地方出问题：\n生成的 SQL 没考虑到索引设计，在大表上会跑全表扫描 错误处理写得很\u0026quot;教科书\u0026quot;，但缺乏对业务异常场景的判断 并发场景下的代码往往有微妙的线程安全问题 Vibe Coding 最适合做什么 经过一段时间的实践，我觉得 AI 编码助理在以下几个场景中确实非常高效：\n1. 样板代码（boilerplate） CRUD、DTO 转换、配置解析、API 接入——这些重复性高、逻辑性低的工作，AI 完成得又快又好。我甚至不需要检查太多细节。\n2. 探索不熟悉的技术栈 想快速试一下某个框架的用法？让 AI 生成一段 demo 代码，比翻文档快得多。它可能不是最佳实践，但至少能让你快速看到效果。\n3. 单元测试编写 这是我觉得 AI 最有价值的用途之一。给定一个函数，让 AI 生成各种边界条件的测试用例，它往往能覆盖到一些你没想起来的场景。\n4. 代码审查辅助 把一段代码贴给 AI，让它分析潜在问题（安全漏洞、性能隐患、代码异味），作为人工审查的补充，效果意外地好。\nVibe Coding 最不适合做什么 1. 核心业务逻辑 涉及复杂的业务规则、状态机、事务处理时，AI 容易出错。而且错误的代价很高——测试不一定能抓到所有边界条件。\n2. 架构设计 AI 可以帮你实现一个具体的模块，但你让它设计一个系统的整体架构，它给出的往往是\u0026quot;大而全但不好用\u0026quot;的方案。架构设计需要权衡取舍，而这恰恰是当前 AI 的弱项。\n3. 性能优化 AI 对性能的理解比较\u0026quot;书本化\u0026quot;——它会告诉你用缓存、用异步、用索引，但真正的性能优化需要结合具体的使用场景、数据量、访问模式，而这需要人类的经验判断。\n对中级工程师的影响 我觉得 Vibe Coding 对中级工程师来说既是机会也是挑战：\n机会在于：它大幅降低了\u0026quot;做出来\u0026quot;的门槛。以前可能要研究半天才能写出一个能跑的原型，现在几分钟就有 MVP。这让中级工程师的生产力上限提高了不少。\n挑战在于：它可能掩盖成长的窟窿。如果一直依赖 AI 生成代码，那些需要亲自踩坑才能内化的经验（比如：为什么这个 SQL 慢？为什么这个锁设计有问题？）可能永远也学不到。\n我的原则：AI 生成的代码，每一行都要读过、理解过。不理解的东西不要提交。\n结语 Vibe Coding 是一个高效的辅助工具，但不是一个替代品。用它加速开发、探索新领域——没问题；把对代码质量的最终责任交给它——这是自欺欺人。\n工具在变，但一个不变的道理是：一个人技术水平的最终保障，是 ta 独立理解、分析和解决问题的能力。\n","permalink":"https://CoderAmedal.github.io/posts/vibe-coding-reflection/","summary":"\u003ch1 id=\"初次使用vibe-coding-带来的思考与反思\"\u003e初次使用Vibe Coding 带来的思考与反思\u003c/h1\u003e\n\u003ch2 id=\"什么是-vibe-coding\"\u003e什么是 Vibe Coding\u003c/h2\u003e\n\u003cp\u003eVibe Coding 是最近流行起来的一个说法，大致意思是：\u003cstrong\u003e对着 AI 编程助手描述你想要的功能，然后让它生成代码，不满意就继续对话调整——整个过程像是在跟代码\u0026quot;聊天\u0026quot;，而不是在写代码。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e今年尝试了 Cursor 和 Claude 的编码助手之后，对 Vibe Coding 有了切身体验，这篇是我的个人反思。\u003c/p\u003e\n\u003ch2 id=\"直观的感受高效与不安并存\"\u003e直观的感受：高效与不安并存\u003c/h2\u003e\n\u003cp\u003e第一次用 AI 生成一个完整的 CRUD 接口时，我的感觉是震撼的——几行自然语言描述，几十行代码自动生成，import 全都正确，异常处理都帮我写好了。前后不到一分钟。\u003c/p\u003e\n\u003cp\u003e但紧接着就是一种隐隐的不安：\u003cstrong\u003e这段代码真的正确吗？每一行的意图我都理解吗？如果有隐蔽的 bug，我能发现吗？\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这种不安感其实很准确——AI 生成的代码看起来都对，但偶尔会在一些意想不到的地方出问题：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e生成的 SQL 没考虑到索引设计，在大表上会跑全表扫描\u003c/li\u003e\n\u003cli\u003e错误处理写得很\u0026quot;教科书\u0026quot;，但缺乏对业务异常场景的判断\u003c/li\u003e\n\u003cli\u003e并发场景下的代码往往有微妙的线程安全问题\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"vibe-coding-最适合做什么\"\u003eVibe Coding 最适合做什么\u003c/h2\u003e\n\u003cp\u003e经过一段时间的实践，我觉得 AI 编码助理在以下几个场景中确实非常高效：\u003c/p\u003e\n\u003ch3 id=\"1-样板代码boilerplate\"\u003e1. 样板代码（boilerplate）\u003c/h3\u003e\n\u003cp\u003eCRUD、DTO 转换、配置解析、API 接入——这些重复性高、逻辑性低的工作，AI 完成得又快又好。我甚至不需要检查太多细节。\u003c/p\u003e\n\u003ch3 id=\"2-探索不熟悉的技术栈\"\u003e2. 探索不熟悉的技术栈\u003c/h3\u003e\n\u003cp\u003e想快速试一下某个框架的用法？让 AI 生成一段 demo 代码，比翻文档快得多。它可能不是最佳实践，但至少能让你快速看到效果。\u003c/p\u003e\n\u003ch3 id=\"3-单元测试编写\"\u003e3. 单元测试编写\u003c/h3\u003e\n\u003cp\u003e这是我觉得 AI 最有价值的用途之一。给定一个函数，让 AI 生成各种边界条件的测试用例，它往往能覆盖到一些你没想起来的场景。\u003c/p\u003e\n\u003ch3 id=\"4-代码审查辅助\"\u003e4. 代码审查辅助\u003c/h3\u003e\n\u003cp\u003e把一段代码贴给 AI，让它分析潜在问题（安全漏洞、性能隐患、代码异味），作为人工审查的补充，效果意外地好。\u003c/p\u003e\n\u003ch2 id=\"vibe-coding-最不适合做什么\"\u003eVibe Coding 最不适合做什么\u003c/h2\u003e\n\u003ch3 id=\"1-核心业务逻辑\"\u003e1. 核心业务逻辑\u003c/h3\u003e\n\u003cp\u003e涉及复杂的业务规则、状态机、事务处理时，AI 容易出错。而且错误的代价很高——测试不一定能抓到所有边界条件。\u003c/p\u003e","title":"Vibe Coding 带来的思考与反思"},{"content":"对计算机各个专业及面向的场景的理解与思考 前言 计算机专业在高校中已分化出十几个方向——计科、软工、网工、信安、物联网、大数据、人工智能……在校时总觉得这些专业各有千秋，毕业后才逐渐体会到，它们之间的界限在工作场景中其实相当模糊。这篇文章是我工作几年后对各专业方向的一些个人理解。\n计科 vs 软工：理论与工程的取舍 计算机科学与技术（计科） 偏重底层原理：操作系统、编译原理、体系结构、离散数学。学得扎实的同学，在面对性能调优、内存分析、并发模型这类问题时明显更从容——因为有底层心智模型支撑。\n软件工程（软工） 则更侧重重工程实践：设计模式、软件架构、敏捷流程、需求分析。毕业后的软工同学在团队协作和项目推进上往往有优势。\n实际工作中两者的界限并不重要。大多数后端/全栈岗位对这两类毕业生一视同仁，最终区分能力的是你能否独立拆解问题、设计实现方案。如果非要区分，需要啃底层（数据库内核、基础设施、编译器、嵌入式）的岗位计科更对口；需要快速交付业务的岗位软工更顺手。\n网络工程与信息安全：从通才到专才 网络工程专业的处境有些尴尬——纯网络运维的岗位越来越少，云原生和 SDN 让传统网工的技能包在缩水。但网络基础扎实的同学转 DevOps/SRE 其实有天然优势，因为排查线上问题时，网络层往往是第一层怀疑对象。\n信息安全在近五年迎来了爆发。从渗透测试、安全运维到安全开发（DevSecOps），岗位细化程度很高。不过有一点需要注意：安全是一个需要持续投入的方向，漏洞库和攻击手法每天都在更新，比起普通开发岗，它更接近\u0026quot;手艺活\u0026quot;——经验积累的边际收益极高。\n大数据与人工智能：热潮下的真实场景 大数据方向 的核心不是 Hadoop、Spark 这些工具本身（它们会更新换代），而是对分布式计算的思维方式——数据分片、shuffle、容错、流批统一。在实际工作中，大部分公司的大数据需求其实是\u0026quot;数据仓库 + ETL + 报表\u0026quot;，真正需要调优大规模集群的场景并没有想象中那么多。\n人工智能方向 这两年的人才供给已经远超需求。大多数 AI 岗位的实际工作内容是数据清洗、特征工程、模型调参，能真正从事算法创新或前沿研究的坑位极少。对于大多数公司来说，调个 API、fine-tune 一个开源模型就够用了。如果只是跟风选 AI，不如先问自己：你是喜欢调模型，还是喜欢解决业务问题？ 后者在任何一个方向都能走得远。\n物联网：软硬件的交叉地带 物联网是软硬件的交叉地带：嵌入式 C、RTOS、通信协议（MQTT、CoAP）、端侧推理。这个方向的岗位相对分散，大厂有专门的 IoT 部门，中小厂更多是在传统嵌入式开发上叠加联网能力。如果你喜欢可感知的物理世界反馈（点个灯、驱动个电机），这个方向会有很强的成就感。\n对我自己的反思 回头看，我觉得专业选择没有想象中那么重要——更重要的是在学习过程中形成的问题分解能力和学习习惯。工作中用到的具体技术，大部分都是现学的。所以比起纠结选哪个专业，不如关注能不能在某个方向上持续深度学习、积累可复用的方法论。\n这也是我写这个博客的初衷：记录学习过程中的思考，而不是搬运他人已有的知识。\n","permalink":"https://CoderAmedal.github.io/posts/cs-major-career-reflection/","summary":"\u003ch1 id=\"对计算机各个专业及面向的场景的理解与思考\"\u003e对计算机各个专业及面向的场景的理解与思考\u003c/h1\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e计算机专业在高校中已分化出十几个方向——计科、软工、网工、信安、物联网、大数据、人工智能……在校时总觉得这些专业各有千秋，毕业后才逐渐体会到，它们之间的界限在工作场景中其实相当模糊。这篇文章是我工作几年后对各专业方向的一些个人理解。\u003c/p\u003e\n\u003ch2 id=\"计科-vs-软工理论与工程的取舍\"\u003e计科 vs 软工：理论与工程的取舍\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e计算机科学与技术（计科）\u003c/strong\u003e 偏重底层原理：操作系统、编译原理、体系结构、离散数学。学得扎实的同学，在面对性能调优、内存分析、并发模型这类问题时明显更从容——因为有底层心智模型支撑。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e软件工程（软工）\u003c/strong\u003e 则更侧重重工程实践：设计模式、软件架构、敏捷流程、需求分析。毕业后的软工同学在团队协作和项目推进上往往有优势。\u003c/p\u003e\n\u003cp\u003e实际工作中两者的界限并不重要。大多数后端/全栈岗位对这两类毕业生一视同仁，最终区分能力的是你能否独立拆解问题、设计实现方案。如果非要区分，\u003cstrong\u003e需要啃底层（数据库内核、基础设施、编译器、嵌入式）的岗位计科更对口；需要快速交付业务的岗位软工更顺手。\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"网络工程与信息安全从通才到专才\"\u003e网络工程与信息安全：从通才到专才\u003c/h2\u003e\n\u003cp\u003e网络工程专业的处境有些尴尬——纯网络运维的岗位越来越少，云原生和 SDN 让传统网工的技能包在缩水。但网络基础扎实的同学转 DevOps/SRE 其实有天然优势，因为排查线上问题时，网络层往往是第一层怀疑对象。\u003c/p\u003e\n\u003cp\u003e信息安全在近五年迎来了爆发。从渗透测试、安全运维到安全开发（DevSecOps），岗位细化程度很高。不过有一点需要注意：安全是一个\u003cstrong\u003e需要持续投入\u003c/strong\u003e的方向，漏洞库和攻击手法每天都在更新，比起普通开发岗，它更接近\u0026quot;手艺活\u0026quot;——经验积累的边际收益极高。\u003c/p\u003e\n\u003ch2 id=\"大数据与人工智能热潮下的真实场景\"\u003e大数据与人工智能：热潮下的真实场景\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e大数据方向\u003c/strong\u003e 的核心不是 Hadoop、Spark 这些工具本身（它们会更新换代），而是对\u003cstrong\u003e分布式计算的思维方式\u003c/strong\u003e——数据分片、shuffle、容错、流批统一。在实际工作中，大部分公司的大数据需求其实是\u0026quot;数据仓库 + ETL + 报表\u0026quot;，真正需要调优大规模集群的场景并没有想象中那么多。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e人工智能方向\u003c/strong\u003e 这两年的人才供给已经远超需求。大多数 AI 岗位的实际工作内容是数据清洗、特征工程、模型调参，能真正从事算法创新或前沿研究的坑位极少。对于大多数公司来说，调个 API、fine-tune 一个开源模型就够用了。如果只是跟风选 AI，不如先问自己：\u003cstrong\u003e你是喜欢调模型，还是喜欢解决业务问题？\u003c/strong\u003e 后者在任何一个方向都能走得远。\u003c/p\u003e\n\u003ch2 id=\"物联网软硬件的交叉地带\"\u003e物联网：软硬件的交叉地带\u003c/h2\u003e\n\u003cp\u003e物联网是软硬件的交叉地带：嵌入式 C、RTOS、通信协议（MQTT、CoAP）、端侧推理。这个方向的岗位相对分散，大厂有专门的 IoT 部门，中小厂更多是在传统嵌入式开发上叠加联网能力。\u003cstrong\u003e如果你喜欢可感知的物理世界反馈（点个灯、驱动个电机），这个方向会有很强的成就感。\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"对我自己的反思\"\u003e对我自己的反思\u003c/h2\u003e\n\u003cp\u003e回头看，我觉得专业选择没有想象中那么重要——更重要的是在学习过程中形成的\u003cstrong\u003e问题分解能力和学习习惯\u003c/strong\u003e。工作中用到的具体技术，大部分都是现学的。所以比起纠结选哪个专业，不如关注能不能在某个方向上持续深度学习、积累可复用的方法论。\u003c/p\u003e\n\u003cp\u003e这也是我写这个博客的初衷：记录学习过程中的思考，而不是搬运他人已有的知识。\u003c/p\u003e","title":"对计算机各个专业及面向的场景的理解与思考"},{"content":"Neo4j图数据库的使用和常用场景分析 图数据库解决了什么关系型数据库做不好的事 关系型数据库用外键和 JOIN 来表达实体间的关系，这在关系层级较浅（一两层）时工作得很好。但当关系深度达到三四层甚至更多时，SQL 的 JOIN 会急剧膨胀，性能断崖式下降。\n举个例子：查找\u0026quot;和用户 A 有共同好友的所有用户\u0026quot;——在 SQL 中需要自连接好友表两次，而在 Neo4j 中，这只是一行自然表达的 Cypher 语句。\n图数据库的核心优势：关系是一等公民，遍历关系的成本是 O(1)，而不是 JOIN 的 O(n)。\n典型使用场景 1. 社交网络与推荐系统 最经典的场景。用户-好友-帖子-点赞-评论构成了一个天然的图。Neo4j 可以轻松查询：\n二度/三度人脉 共同好友推荐 基于\u0026quot;购买了 A 的人也购买了 B\u0026quot;的协同过滤 内容传播路径追踪 2. 反欺诈与风控 欺诈行为往往是团伙作案：一群虚假账户共享相似的设备、IP、银行卡。在关系型数据库中检测这种环形关联非常困难，但 Neo4j 可以用路径查询快速发现：\n资金环形流转检测 关联人/关联账户网络分析 多跳关联风险传播 3. 知识图谱 知识图谱本质就是实体-关系-实体的三元组。Neo4j 天然适合：\n企业知识管理（文档-知识点-部门-项目关联） 智能问答的后端存储 供应链追踪 4. 权限与组织架构 公司组织架构是天然的树/图结构。Neo4j 在处理：\n汇报链查询 权限继承 RBAC 角色层级 等场景时比递归 SQL 简洁得多。\n5. 网络与基础设施拓扑 CMDB、微服务依赖图、网络拓扑、路由分析——这些都是图结构的天然应用场景。用 Neo4j 存储后，可以通过路径查询快速回答\u0026quot;服务 A 宕机会影响哪些下游\u0026quot;这类问题。\nCypher 基础语法感受 Cypher 是 Neo4j 的查询语言，风格上有点像 SQL 但专门为图设计。几个基础操作：\n// 创建两个节点和一条关系 CREATE (a:Person {name: \u0026#39;张三\u0026#39;})-[r:KNOWS]-\u0026gt;(b:Person {name: \u0026#39;李四\u0026#39;}) // 查找朋友的朋友（两度关系） MATCH (a:Person {name: \u0026#39;张三\u0026#39;})-[:KNOWS*2]-(foaf) RETURN DISTINCT foaf.name // 最短路径 MATCH p=shortestPath((a:Person {name: \u0026#39;张三\u0026#39;})-[*]-(b:Person {name: \u0026#39;王五\u0026#39;})) RETURN p 语法设计得很直观，(节点)-[关系]-\u0026gt;(节点) 的模式匹配写法比 SQL 的 JOIN 更符合直觉。\n什么情况下不该用 Neo4j 不是所有数据都适合图数据库：\n简单的 CRUD 业务：用户管理系统、订单管理——用传统关系型数据库足够 以聚合统计为主的场景：BI 报表、大数据分析——列存数据库更合适 不需要关系查询的场景：日志存储、时序数据——图数据库没有优势 图数据库的性能优势在于关系遍历。如果你的业务逻辑中没有复杂的关系查询需求，引入 Neo4j 只会增加运维负担。\n总结 Neo4j 不是关系型数据库的替代品，而是特定场景下的补充方案。当你的业务中有大量关系查询（特别是多跳查询），且用 SQL 写起来已经很痛苦时，就是考虑引入图数据库的时机。\n","permalink":"https://CoderAmedal.github.io/posts/neo4j-usage-scenarios/","summary":"\u003ch1 id=\"neo4j图数据库的使用和常用场景分析\"\u003eNeo4j图数据库的使用和常用场景分析\u003c/h1\u003e\n\u003ch2 id=\"图数据库解决了什么关系型数据库做不好的事\"\u003e图数据库解决了什么关系型数据库做不好的事\u003c/h2\u003e\n\u003cp\u003e关系型数据库用外键和 JOIN 来表达实体间的关系，这在关系层级较浅（一两层）时工作得很好。但当关系深度达到三四层甚至更多时，SQL 的 JOIN 会急剧膨胀，性能断崖式下降。\u003c/p\u003e\n\u003cp\u003e举个例子：\u003cstrong\u003e查找\u0026quot;和用户 A 有共同好友的所有用户\u0026quot;\u003c/strong\u003e——在 SQL 中需要自连接好友表两次，而在 Neo4j 中，这只是一行自然表达的 Cypher 语句。\u003c/p\u003e\n\u003cp\u003e图数据库的核心优势：\u003cstrong\u003e关系是一等公民，遍历关系的成本是 O(1)\u003c/strong\u003e，而不是 JOIN 的 O(n)。\u003c/p\u003e\n\u003ch2 id=\"典型使用场景\"\u003e典型使用场景\u003c/h2\u003e\n\u003ch3 id=\"1-社交网络与推荐系统\"\u003e1. 社交网络与推荐系统\u003c/h3\u003e\n\u003cp\u003e最经典的场景。用户-好友-帖子-点赞-评论构成了一个天然的图。Neo4j 可以轻松查询：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e二度/三度人脉\u003c/li\u003e\n\u003cli\u003e共同好友推荐\u003c/li\u003e\n\u003cli\u003e基于\u0026quot;购买了 A 的人也购买了 B\u0026quot;的协同过滤\u003c/li\u003e\n\u003cli\u003e内容传播路径追踪\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"2-反欺诈与风控\"\u003e2. 反欺诈与风控\u003c/h3\u003e\n\u003cp\u003e欺诈行为往往是\u003cstrong\u003e团伙作案\u003c/strong\u003e：一群虚假账户共享相似的设备、IP、银行卡。在关系型数据库中检测这种环形关联非常困难，但 Neo4j 可以用路径查询快速发现：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e资金环形流转检测\u003c/li\u003e\n\u003cli\u003e关联人/关联账户网络分析\u003c/li\u003e\n\u003cli\u003e多跳关联风险传播\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"3-知识图谱\"\u003e3. 知识图谱\u003c/h3\u003e\n\u003cp\u003e知识图谱本质就是实体-关系-实体的三元组。Neo4j 天然适合：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e企业知识管理（文档-知识点-部门-项目关联）\u003c/li\u003e\n\u003cli\u003e智能问答的后端存储\u003c/li\u003e\n\u003cli\u003e供应链追踪\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"4-权限与组织架构\"\u003e4. 权限与组织架构\u003c/h3\u003e\n\u003cp\u003e公司组织架构是天然的树/图结构。Neo4j 在处理：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e汇报链查询\u003c/li\u003e\n\u003cli\u003e权限继承\u003c/li\u003e\n\u003cli\u003eRBAC 角色层级\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e等场景时比递归 SQL 简洁得多。\u003c/p\u003e\n\u003ch3 id=\"5-网络与基础设施拓扑\"\u003e5. 网络与基础设施拓扑\u003c/h3\u003e\n\u003cp\u003eCMDB、微服务依赖图、网络拓扑、路由分析——这些都是图结构的天然应用场景。用 Neo4j 存储后，可以通过路径查询快速回答\u0026quot;服务 A 宕机会影响哪些下游\u0026quot;这类问题。\u003c/p\u003e\n\u003ch2 id=\"cypher-基础语法感受\"\u003eCypher 基础语法感受\u003c/h2\u003e\n\u003cp\u003eCypher 是 Neo4j 的查询语言，风格上有点像 SQL 但专门为图设计。几个基础操作：\u003c/p\u003e","title":"Neo4j图数据库的使用和常用场景分析"},{"content":"《Java 并发编程的艺术》个人总结 为什么读这本书 工作中写并发代码的机会不少——线程池、缓存、异步处理——但遇到诡异的可见性问题或死锁时，往往只能靠加 synchronized 碰运气。这本书系统地梳理了 Java 内存模型和并发工具的设计原理，读完确实对调试并发问题有了更清晰的思路。\n核心知识点梳理 1. 并发编程的挑战 书中开篇说的三个核心问题：\n上下文切换：线程多了，CPU 花在切换上的时间比干活还多 死锁：互相等对方的锁 资源限制：硬件瓶颈不解决，加再多线程也没用 经验上，线程数 ≈ CPU 核数 × 2（取决于 IO 密集还是计算密集） 是一个比较可靠的起点。\n2. Java 内存模型（JMM） 这是全书最重要的一章。JMM 控制的是一个线程对共享变量的写入何时对另一个线程可见。核心概念：\nhappens-before 规则：程序顺序、volatile、锁、传递性等 volatile：保证可见性和禁止指令重排序，但不保证原子性 锁：synchronized 和 ReentrantLock 同时保证原子性和可见性 并发编程中大部分诡异 bug 的根因都是对 JMM 的理解不到位——以为一个线程写完了另一个线程就一定能读到。\n3. 并发基础组件 组件 核心作用 使用场景 volatile 轻量级可见性保证 状态标识位 synchronized 互斥 + 可见性 临界区保护 ReentrantLock 可中断/超时/公平锁 需要灵活锁控制的场景 AtomicInteger/Long/Reference CAS 无锁原子操作 计数器、状态机 CountDownLatch 等待多个线程完成 并行任务汇总 CyclicBarrier 多个线程互相等待 分阶段并行计算 Semaphore 流量控制 限流、资源池 4. 线程池 ThreadPoolExecutor 的核心参数关系：\ncorePoolSize/ maximumPoolSize：核心线程和最大线程数 keepAliveTime：非核心线程的空闲存活时间 workQueue：任务队列满了才会创建新线程（从核心数涨到最大数） 实践中常见的问题是队列设得太大——线程池永远只用核心线程，失去了弹性伸缩的意义。另外 Executors.newCachedThreadPool() 要慎用，它允许无限创建线程。\n5. 并发集合 ConcurrentHashMap：分段锁（JDK7）→ CAS + synchronized（JDK8），读不加锁 CopyOnWriteArrayList：写时复制，适合读多写少 BlockingQueue：生产者-消费者模式的基础 6. 锁优化 JVM 对 synchronized 做了大量优化：\n偏向锁：同一个线程反复获取锁，直接放行 轻量级锁：多线程交替执行，用 CAS 代替互斥 重量级锁：真正的线程阻塞 这也是为什么现在不需要一味追求 ReentrantLock——JVM 的 synchronized 优化已经足够好，除非你需要锁中断或超时。\n一点个人感悟 读完这本书最大的收获不是记住了多少 API，而是理解了 JMM 的 happens-before 规则后，排查并发问题有了一个系统的思维框架。不再是把 volatile、synchronized、Lock 当成\u0026quot;可能管用\u0026quot;的咒语到处乱加，而是能根据问题的性质（可见性？原子性？有序性？）针对性地选择工具。\n建议读完这本书后，再配合《Java Concurrency in Practice》一起看，两本书互为补充。\n","permalink":"https://CoderAmedal.github.io/posts/java-concurrency-art-summary/","summary":"\u003ch1 id=\"java-并发编程的艺术个人总结\"\u003e《Java 并发编程的艺术》个人总结\u003c/h1\u003e\n\u003ch2 id=\"为什么读这本书\"\u003e为什么读这本书\u003c/h2\u003e\n\u003cp\u003e工作中写并发代码的机会不少——线程池、缓存、异步处理——但遇到诡异的可见性问题或死锁时，往往只能靠加 \u003ccode\u003esynchronized\u003c/code\u003e 碰运气。这本书系统地梳理了 Java 内存模型和并发工具的设计原理，读完确实对调试并发问题有了更清晰的思路。\u003c/p\u003e\n\u003ch2 id=\"核心知识点梳理\"\u003e核心知识点梳理\u003c/h2\u003e\n\u003ch3 id=\"1-并发编程的挑战\"\u003e1. 并发编程的挑战\u003c/h3\u003e\n\u003cp\u003e书中开篇说的三个核心问题：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e上下文切换\u003c/strong\u003e：线程多了，CPU 花在切换上的时间比干活还多\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e死锁\u003c/strong\u003e：互相等对方的锁\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e资源限制\u003c/strong\u003e：硬件瓶颈不解决，加再多线程也没用\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e经验上，\u003cstrong\u003e线程数 ≈ CPU 核数 × 2（取决于 IO 密集还是计算密集）\u003c/strong\u003e 是一个比较可靠的起点。\u003c/p\u003e\n\u003ch3 id=\"2-java-内存模型jmm\"\u003e2. Java 内存模型（JMM）\u003c/h3\u003e\n\u003cp\u003e这是全书最重要的一章。JMM 控制的是\u003cstrong\u003e一个线程对共享变量的写入何时对另一个线程可见\u003c/strong\u003e。核心概念：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ehappens-before 规则\u003c/strong\u003e：程序顺序、volatile、锁、传递性等\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003evolatile\u003c/strong\u003e：保证可见性和禁止指令重排序，但不保证原子性\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e锁\u003c/strong\u003e：\u003ccode\u003esynchronized\u003c/code\u003e 和 \u003ccode\u003eReentrantLock\u003c/code\u003e 同时保证原子性和可见性\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e并发编程中大部分诡异 bug 的根因都是\u003cstrong\u003e对 JMM 的理解不到位\u003c/strong\u003e——以为一个线程写完了另一个线程就一定能读到。\u003c/p\u003e\n\u003ch3 id=\"3-并发基础组件\"\u003e3. 并发基础组件\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e组件\u003c/th\u003e\n          \u003cth\u003e核心作用\u003c/th\u003e\n          \u003cth\u003e使用场景\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003evolatile\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e轻量级可见性保证\u003c/td\u003e\n          \u003ctd\u003e状态标识位\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003esynchronized\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e互斥 + 可见性\u003c/td\u003e\n          \u003ctd\u003e临界区保护\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eReentrantLock\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e可中断/超时/公平锁\u003c/td\u003e\n          \u003ctd\u003e需要灵活锁控制的场景\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eAtomicInteger/Long/Reference\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCAS 无锁原子操作\u003c/td\u003e\n          \u003ctd\u003e计数器、状态机\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eCountDownLatch\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e等待多个线程完成\u003c/td\u003e\n          \u003ctd\u003e并行任务汇总\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eCyclicBarrier\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e多个线程互相等待\u003c/td\u003e\n          \u003ctd\u003e分阶段并行计算\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eSemaphore\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e流量控制\u003c/td\u003e\n          \u003ctd\u003e限流、资源池\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"4-线程池\"\u003e4. 线程池\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003eThreadPoolExecutor\u003c/code\u003e 的核心参数关系：\u003c/p\u003e","title":"《Java 并发编程的艺术》个人总结"},{"content":"主流关系型数据库的差异及性能分析 一份中立的对比 工作中先后接触过 MySQL、PostgreSQL、Oracle，也用过 SQL Server 和 SQLite。每个数据库都有自己的设计哲学和适用场景。这篇文章整理一下个人理解，不吹不黑，尽量实事求是。\n核心差异速览 MySQL：互联网的首选 核心优势：简单、运维成熟、社区庞大。\nMySQL 的设计哲学是\u0026quot;够用就好\u0026quot;。它不像 PostgreSQL 那样追求 SQL 标准的完备性，而是优先保证简单场景下的性能。InnoDB 存储引擎是绝大多数场景的唯一选择——B+ 树索引、MVCC、行级锁。\n需要注意的点：\n对复杂查询（窗口函数、CTE）的支持较晚，直到 8.0 才比较完善 JSON 支持和全文索引够用但不强 复制架构基于 binlog，GTID 复制在管理上很便利 幻读问题：InnoDB 在可重复读隔离级别下通过 Next-Key Lock 解决，但实际上还是可能发生（快照读 vs 当前读） 适用场景：OLTP、互联网业务、读写分离架构、中小规模数据。\nPostgreSQL：功能最完备的开源数据库 核心优势：SQL 标准兼容性最好、扩展性强、适合复杂查询。\nPostgreSQL 是一个\u0026quot;学院派\u0026quot;数据库，它的功能完备程度在某些方面甚至超过商业数据库：\n最完整的窗口函数、CTE、递归查询支持 优秀的 JSON/JSONB 支持（可以当半个文档数据库用） 丰富的索引类型：B-Tree、Hash、GiST、SP-GiST、GIN、BRIN 原生支持地理空间数据（PostGIS） 外键、触发器、函数等支持非常完整 MVCC 实现基于多版本行存储，会产生死元组，需要定期 VACUUM 需要注意的点：\n连接开销比 MySQL 大，高并发短连接场景需要连接池（PgBouncer） VACUUM 和 ANALYZE 需要关注，否则性能会逐渐下降 适用场景：复杂业务逻辑、数据分析、GIS、需要高度 SQL 标准兼容的场景。\nOracle：企业级标杆 核心优势：最成熟的优化器、最完善的高可用方案、最强的硬件利用率。\nOracle 的核心竞争力在于它的优化器和 RAC（Real Application Clusters）。Oracle 的 CBO 优化器的成熟度是其他数据库难以比拟的——同样的复杂查询，Oracle 往往能选出更优的执行计划。RAC 实现了多节点共享存储的集群架构，提供了极高的可用性。\n使用成本：商业授权昂贵，运维也需要专业知识。对于大多数中小企业来说，这是最大的障碍。\nSQL Server：微软生态的最佳拍档 核心优势：与 .NET/Azure 生态深度集成、SSMS 管理工具一流。\nSQL Server 的易用性很高，SSMS 的图形化管理工具至今没有对手。和 Azure 的集成让它在上云场景中有一席之地。底层架构与 Sybase 有历史渊源。\n适用场景：.NET 技术栈、微软生态、Windows Server 环境。\nSQLite：嵌入式的利器 别小看这个\u0026quot;玩具数据库\u0026quot;，它是世界上部署最广泛的数据库——每部手机里都有它。对于单机应用、移动端、测试环境，SQLite 是最省心的选择。它不需要服务进程，一个文件就是整个数据库。\n性能维度的对比 维度 MySQL PostgreSQL Oracle SQL Server 简单查询 优秀 良好 优秀 良好 复杂查询 一般 优秀 顶级 良好 写入性能 良好 一般 优秀 良好 并发读 优秀 良好 顶级 优秀 扩展性 良好 优秀 顶级 良好 注：以上对比基于默认配置下的主观经验总结，实际性能高度取决于数据量、索引设计、查询模式和硬件配置。\n选型建议 如果你在做一个新项目，选型优先级建议：\nPostgreSQL：现在没有明显短板，功能最全，社区活跃，是大多数新项目的默认选择 MySQL：如果团队有丰富的 MySQL 运维经验，或者需要使用大量 MySQL 生态工具 Oracle / SQL Server：预算充足、企业级需求、或已有相关技术栈 性能分析的底线提醒：数据库的真正瓶颈往往不在数据库本身，而在索引设计、查询质量、数据模型。换数据库解决不了的技术债，远比数据库之间的性能差异大得多。\n","permalink":"https://CoderAmedal.github.io/posts/rdbms-comparison-performance/","summary":"\u003ch1 id=\"主流关系型数据库的差异及性能分析\"\u003e主流关系型数据库的差异及性能分析\u003c/h1\u003e\n\u003ch2 id=\"一份中立的对比\"\u003e一份中立的对比\u003c/h2\u003e\n\u003cp\u003e工作中先后接触过 MySQL、PostgreSQL、Oracle，也用过 SQL Server 和 SQLite。每个数据库都有自己的设计哲学和适用场景。这篇文章整理一下个人理解，不吹不黑，尽量实事求是。\u003c/p\u003e\n\u003ch2 id=\"核心差异速览\"\u003e核心差异速览\u003c/h2\u003e\n\u003ch3 id=\"mysql互联网的首选\"\u003eMySQL：互联网的首选\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e核心优势\u003c/strong\u003e：简单、运维成熟、社区庞大。\u003c/p\u003e\n\u003cp\u003eMySQL 的设计哲学是\u0026quot;够用就好\u0026quot;。它不像 PostgreSQL 那样追求 SQL 标准的完备性，而是优先保证简单场景下的性能。InnoDB 存储引擎是绝大多数场景的唯一选择——B+ 树索引、MVCC、行级锁。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e需要注意的点\u003c/strong\u003e：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e对复杂查询（窗口函数、CTE）的支持较晚，直到 8.0 才比较完善\u003c/li\u003e\n\u003cli\u003eJSON 支持和全文索引够用但不强\u003c/li\u003e\n\u003cli\u003e复制架构基于 binlog，GTID 复制在管理上很便利\u003c/li\u003e\n\u003cli\u003e幻读问题：InnoDB 在可重复读隔离级别下通过 Next-Key Lock 解决，但实际上还是可能发生（快照读 vs 当前读）\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e适用场景\u003c/strong\u003e：OLTP、互联网业务、读写分离架构、中小规模数据。\u003c/p\u003e\n\u003ch3 id=\"postgresql功能最完备的开源数据库\"\u003ePostgreSQL：功能最完备的开源数据库\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e核心优势\u003c/strong\u003e：SQL 标准兼容性最好、扩展性强、适合复杂查询。\u003c/p\u003e\n\u003cp\u003ePostgreSQL 是一个\u0026quot;学院派\u0026quot;数据库，它的功能完备程度在某些方面甚至超过商业数据库：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e最完整的窗口函数、CTE、递归查询支持\u003c/li\u003e\n\u003cli\u003e优秀的 JSON/JSONB 支持（可以当半个文档数据库用）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e丰富的索引类型\u003c/strong\u003e：B-Tree、Hash、GiST、SP-GiST、GIN、BRIN\u003c/li\u003e\n\u003cli\u003e原生支持地理空间数据（PostGIS）\u003c/li\u003e\n\u003cli\u003e外键、触发器、函数等支持非常完整\u003c/li\u003e\n\u003cli\u003eMVCC 实现基于多版本行存储，会产生死元组，需要定期 VACUUM\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e需要注意的点\u003c/strong\u003e：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e连接开销比 MySQL 大，高并发短连接场景需要连接池（PgBouncer）\u003c/li\u003e\n\u003cli\u003eVACUUM 和 ANALYZE 需要关注，否则性能会逐渐下降\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e适用场景\u003c/strong\u003e：复杂业务逻辑、数据分析、GIS、需要高度 SQL 标准兼容的场景。\u003c/p\u003e\n\u003ch3 id=\"oracle企业级标杆\"\u003eOracle：企业级标杆\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e核心优势\u003c/strong\u003e：最成熟的优化器、最完善的高可用方案、最强的硬件利用率。\u003c/p\u003e\n\u003cp\u003eOracle 的核心竞争力在于它的优化器和 RAC（Real Application Clusters）。Oracle 的 CBO 优化器的成熟度是其他数据库难以比拟的——同样的复杂查询，Oracle 往往能选出更优的执行计划。RAC 实现了多节点共享存储的集群架构，提供了极高的可用性。\u003c/p\u003e","title":"主流关系型数据库的差异及性能分析"},{"content":"简历 软件开发工程师 - 袁小昆 下载简历 下载 PDF 简历\n","permalink":"https://CoderAmedal.github.io/resume/","summary":"\u003ch1 id=\"简历\"\u003e简历\u003c/h1\u003e\n\u003ch2 id=\"软件开发工程师---袁小昆\"\u003e软件开发工程师 - 袁小昆\u003c/h2\u003e\n\u003ch3 id=\"下载简历\"\u003e下载简历\u003c/h3\u003e\n\u003cp\u003e\u003ca href=\"/resume/%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88-%E8%A2%81%E5%B0%8F%E6%98%86.pdf\"\u003e下载 PDF 简历\u003c/a\u003e\u003c/p\u003e","title":"简历"}]