<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Bai &#187; 并发</title>
	<atom:link href="http://tonybai.com/tag/%e5%b9%b6%e5%8f%91/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Sun, 12 Apr 2026 22:30:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>当 Go 还在追求极简时，C++ 26 却又加了四大“史诗级”新特性</title>
		<link>https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features/</link>
		<comments>https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features/#comments</comments>
		<pubDate>Mon, 30 Mar 2026 23:26:51 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AsynchronousModel]]></category>
		<category><![CDATA[C++26]]></category>
		<category><![CDATA[comptime]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Contracts]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GoLanguage]]></category>
		<category><![CDATA[Go语言]]></category>
		<category><![CDATA[HerbSutter]]></category>
		<category><![CDATA[HighPerformance]]></category>
		<category><![CDATA[MemorySafety]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[SenderReceiver]]></category>
		<category><![CDATA[standardlibrary]]></category>
		<category><![CDATA[SystemProgramming]]></category>
		<category><![CDATA[Templates]]></category>
		<category><![CDATA[UndefinedBehavior]]></category>
		<category><![CDATA[ZerocostAbstraction]]></category>
		<category><![CDATA[元编程]]></category>
		<category><![CDATA[内存安全]]></category>
		<category><![CDATA[反射]]></category>
		<category><![CDATA[契约编程]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[异步模型]]></category>
		<category><![CDATA[未定义行为]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[模板]]></category>
		<category><![CDATA[泛型]]></category>
		<category><![CDATA[系统级编程]]></category>
		<category><![CDATA[编译期计算]]></category>
		<category><![CDATA[零成本抽象]]></category>
		<category><![CDATA[高性能]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=6123</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features 大家好，我是Tony Bai。 在这个 Go、Zig 等“小而美”新语言颇受青睐的时代，如果你去技术社区里问一句：“C++ 这门语言怎么样？” 你大概率会得到一堆充满戏谑的回答：“太复杂了，别学”、“从入门到放弃”、“面试造火箭，工作拧螺丝”。 C++，这门诞生于上世纪 80 年代的编程语言，似乎早已被贴上了“老旧、臃肿、极其反人类”的标签。在很多新生代开发者眼里，它就像一头步履蹒跚的史前巨兽，理应被时代所淘汰。 但就在前天（2026年3月29日），这头“史前巨兽”不仅没有倒下，反而亮出了它那足以撕裂天空的獠牙。 C++ 标准委员会主席、C++ 界的“教父级”人物 Herb Sutter 亲自在博客上宣布：C++26 标准的技术工作，已正式完成！ Herb Sutter 还用极其兴奋的口吻将其定义为“自 C++11 以来最具冲击力的一次发布”。而这次更新的核心，是四个被他称为“Fab Four”（神奇四侠）的史诗级新特性。 当我耐着性子看完全部内容后，我脑子里只剩下四个字：叹为观止。 当 Go 语言的开发者还在为“是否要给语言增加一个三元表达式”，或泛型方法而激烈辩论时，C++ 却反其道而行之，给自己又加装了四门“宇宙级”的重型武器。这到底是 C++ 吹响的绝地反击号角，还是压垮骆驼的最后一根稻草？ 今天，我们就来硬核扒开 C++26 这四大“金刚”，看看它们到底有多强，以及它们将如何影响将来程序员对编程语言的选择。 第一门重炮：反射（Reflection）——“代码生成代码”的终极魔法 Herb Sutter 将反射放在了四大特性之首，并称之为“自模板（Templates）发明以来 C++ 最重要的升级”。 什么是C++ 的反射？简单来说，就是让代码在编译期拥有了“自我审视”和“自我创造”的能力。 在 C++26 之前，如果你想实现一个通用的 JSON 序列/反序列化库，你必须写大量重复的模板代码，或者用各种丑陋的宏来“欺骗”编译器。 但在 C++26 中，你可以像这样写出充满“神性”的代码（代码示意）： 这段代码，在编译的时候就能根据编译时的输入(test.json)自动分析JSON构造，并生成编译时用于计算的一个新类型。这在 Go [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/go-minimalism-vs-cpp26-epic-new-features-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features">本文永久链接</a> &#8211; https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features</p>
<p>大家好，我是Tony Bai。</p>
<p>在这个 Go、Zig 等“小而美”新语言颇受青睐的时代，如果你去技术社区里问一句：“C++ 这门语言怎么样？”</p>
<p>你大概率会得到一堆充满戏谑的回答：“太复杂了，别学”、“从入门到放弃”、“面试造火箭，工作拧螺丝”。</p>
<p>C++，这门诞生于上世纪 80 年代的编程语言，似乎早已被贴上了“老旧、臃肿、极其反人类”的标签。在很多新生代开发者眼里，它就像一头步履蹒跚的史前巨兽，理应被时代所淘汰。</p>
<p><strong>但就在前天（2026年3月29日），这头“史前巨兽”不仅没有倒下，反而亮出了它那足以撕裂天空的獠牙。</strong></p>
<p>C++ 标准委员会主席、C++ 界的“教父级”人物 <strong>Herb Sutter</strong> 亲自在博客上宣布：<a href="https://herbsutter.com/2026/03/29/c26-is-done-trip-report-march-2026-iso-c-standards-meeting-london-croydon-uk/">C++26 标准的技术工作，已正式完成！</a></p>
<p>Herb Sutter 还用极其兴奋的口吻将其定义为<strong>“自 C++11 以来最具冲击力的一次发布”</strong>。而这次更新的核心，是四个被他称为“Fab Four”（神奇四侠）的史诗级新特性。</p>
<p>当我耐着性子看完全部内容后，我脑子里只剩下四个字：<strong>叹为观止。</strong></p>
<p>当 Go 语言的开发者还在为“是否要给语言增加一个三元表达式”，或<a href="https://tonybai.com/2026/01/24/go-generics-finally-supports-generic-methods">泛型方法</a>而激烈辩论时，C++ 却反其道而行之，给自己又加装了四门“宇宙级”的重型武器。这到底是 C++ 吹响的绝地反击号角，还是压垮骆驼的最后一根稻草？</p>
<p>今天，我们就来硬核扒开 C++26 这四大“金刚”，看看它们到底有多强，以及它们将如何影响将来程序员对编程语言的选择。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/agentic-software-engineering-qr.png" alt="" /></p>
<h2>第一门重炮：反射（Reflection）——“代码生成代码”的终极魔法</h2>
<p>Herb Sutter 将<strong>反射</strong>放在了四大特性之首，并称之为“自模板（Templates）发明以来 C++ 最重要的升级”。</p>
<p>什么是C++ 的反射？简单来说，<strong>就是让代码在编译期拥有了“自我审视”和“自我创造”的能力。</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/go-minimalism-vs-cpp26-epic-new-features-2.png" alt="" /></p>
<p>在 C++26 之前，如果你想实现一个通用的 JSON 序列/反序列化库，你必须写大量重复的模板代码，或者用各种丑陋的宏来“欺骗”编译器。</p>
<p>但在 C++26 中，你可以像这样写出充满“神性”的代码（代码示意）：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/go-minimalism-vs-cpp26-epic-new-features-3.png" alt="" /></p>
<p>这段代码，在编译的时候就能根据编译时的输入(test.json)自动分析JSON构造，并生成编译时用于计算的一个新类型。<strong>这在 Go 语言里，需要借助 reflect 包在运行时（Runtime）以牺牲性能为代价才能做到。而 C++，直接在静态编译期（Compile-time）零成本搞定了！</strong></p>
<p>Herb Sutter 将其形容为“C++ 的十年火箭引擎”。这意味着，未来 C++ 社区将涌现出无数极其强大、但又极其复杂的元编程（Metaprogramming）库。C++ 的学习曲线，将再次被拉到一个新的高度。</p>
<h2>第二道防线：内存安全（Memory Safety）——“只需重编，安全自来”</h2>
<p>如果说反射让 C++ 的上限变得更加遥不可及，那么内存安全的提升，则是 C++ 在向 Go 和 Rust 的核心优势区发起的正面冲锋。</p>
<p>C++ 常年被诟病的核心痛点是什么？<strong>内存不安全</strong>。悬垂指针、未初始化变量读取（导致<a href="https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation">未定义行为</a>）……这些噩梦困扰了 C++ 程序员几十年。</p>
<p>C++26 给出了一个极其诱人的承诺：<strong>你的老代码一行都不用改，只要用 C++26 模式重新编译，就能自动获得大幅度的安全提升！</strong></p>
<p>这主要来源于两个方面的改进：</p>
<ol>
<li><strong>消灭未初始化变量的 UB</strong>：在 C++26 中，读取未初始化局部变量不再是“未定义行为（Undefined Behavior）”。这意味着困扰无数新手的、极其诡异的程序崩溃，将成为历史。</li>
<li><strong>“加固”的标准库</strong>：Google 和 Apple 已经将它们内部经过“加固（Hardened）”的标准库实现贡献给了 C++26。这意味着，当你使用 std::vector, std::string 等容器时，大量的边界检查会自动开启。</li>
</ol>
<p>Herb Sutter 引用了 Google 的内部数据：</p>
<blockquote>
<p>“仅在 Google，这项技术就已经修复了超过 1000 个 Bug，预计每年可以预防 1000 到 2000 个新 Bug 的产生，并将整个生产环境的段错误（Segfault）率降低了 30%。”</p>
</blockquote>
<p>这简直是在对 Go 说：<strong>“你用 GC 换来的那点可怜的安全性，我 C++ 现在也能做到了，而且依然是零成本的！”</strong></p>
<h2>第三把利剑：契约（Contracts）——代码里的“法律条文”</h2>
<p>如果你写过 Go，你一定对满屏的 if param == nil { return errors.New(&#8230;) } 感到厌烦。这种防御性编程，虽然有效，但极其啰嗦。</p>
<p>C++26 正式引入了语言级的<a href="https://tonybai.com/2025/12/13/from-eiffel-contract-to-go-interface">契约编程</a>。</p>
<p>你可以像签合同一样，为你的函数制定严格的法律条文：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/go-minimalism-vs-cpp26-epic-new-features-4.png" alt="" /></p>
<p>这些 pre 和 post 是编译器和运行时可以理解并强制执行的“法律”。如果调用者违反了前置条件，程序可以在开发阶段就立刻崩溃并给出明确的报错，而不是等到数据被污染后才在某个奇怪的地方爆炸。</p>
<p>虽然 Go 社区也在讨论类似的泛型断言，但 C++26 已经先行一步，将其做成了语言标准。</p>
<h2>第四个引擎：std::execution——C++ 的“亲儿子”协程模型</h2>
<p>在 C++20 中，虽然引入了 co_await 协程，但它只是一个语法糖，并没有提供一个统一的调度框架。</p>
<p>C++26 终于补上了这块短板，正式推出了 <strong>std::execution</strong>，也被称为 <strong>Sender/Receiver 模型</strong>。</p>
<p>这是一个极其强大、统一的异步模型框架。它让你能以一种声明式的方式，去描述、组合和调度复杂的并发任务流。</p>
<p>下面是一段使用std::execution的代码示例：</p>
<pre><code>// This is an example of a custom algorithm for starting work
// without allocations. This algorithm is also available in
// &lt;exec/start_now.hpp&gt;. (Users that don't write custom sender
// algorithms will not need to use receivers or call connect
// or start.)
template &lt;stdexec::sender_in&lt;stdexec::empty_env&gt; Sender&gt;
struct start_now {
  start_now(Sender sndr)
    : _op(stdexec::connect(std::move(sndr), _sink_rcvr())) {
    stdexec::start(_op);
  }
private:
  // start_now is implemented in terms of this custom receiver,
  // which is used to discard Sender's results.
  struct _sink_rcvr {
    using receiver_concept = stdexec::receiver_t;
    void set_value(auto&amp;&amp;...) noexcept {}
    void set_error(auto&amp;&amp;) noexcept {}
    void set_stopped() noexcept {}
  };
  stdexec::connect_result_t&lt;Sender, _sink_rcvr&gt; _op;
};

int main() {
  // A run loop is a fifo queue of work and a loop to execute the
  // work. It needs to be driven by calling its .run() member fn.
  stdexec::run_loop ctx;
  auto event_loop = ctx.get_scheduler();

  // Create two tasks that cooperatively multitask.
  auto task1 = stdexec::just()
             | stdexec::then([]{ std::puts("hello from task 1! suspending..."); })
             | stdexec::continue_on(event_loop) // suspend
             | exec::repeat_n(5)
             | stdexec::then([]{ std::puts("task 1 is done!"); });

  auto task2 = stdexec::just()
             | stdexec::then([]{ std::puts("hello from task 2! suspending..."); })
             | stdexec::continue_on(event_loop) // suspend
             | exec::repeat_n(8)
             | stdexec::then([]{ std::puts("task 2 is done!"); });

  // Start both tasks. This enqueues them for execution on the run loop.
  auto op1 = start_now(stdexec::start_on(event_loop, std::move(task1)));
  auto op2 = start_now(stdexec::start_on(event_loop, std::move(task2)));

  ctx.finish(); // tell the run loop to stop when the queue is empty
  ctx.run();    // tell the run loop to start executing work in the queue
}
</code></pre>
<p>这可以被看作是 C++ 对 Go 的 Goroutine + Channel 模型，以及 Rust 的 async/await + tokio 模型的终极回应。</p>
<p>它让 C++ 开发者第一次拥有了一套语言原生的、能够轻松编写“无数据竞争（Data-race-free by construction）”并发程序的“亲儿子”工具。</p>
<h2>小结：一场没有退路的豪赌</h2>
<p>反射、安全、契约、并发。C++26 的这四大金刚，每一个都足以在其他语言中引发一场大地震。</p>
<p>我们看到的是一头苏醒的巨兽。它没有选择像 Go 那样“断舍离”，也没有像 Rust 那样“偏执于安全”，而是极其贪婪地选择了：<strong>“我全都要！”</strong></p>
<p>它既想要极致的表达能力和零成本抽象（反射、模板），又想要与 Rust 媲美的内存安全（加固标准库），还想要不输 Go 的并发表达力（std::execution）。</p>
<p>C++26 给老兵们提供了前所未有的强大武器，但也把本就陡峭的学习曲线，又向上抬升了一个令人惊叹的高度，宇宙第一复杂的编程语言，实至名归！</p>
<p>当 Go 的开发者还在为“是否要加个三元表达式”而争论不休时，C++ 已经头也不回地奔向了“万神殿”。</p>
<p>或许，编程语言的终局，真的不是“大一统”，而是“两极分化”：一极是像 Go 一样追求极致简单的“工程师语言”；而另一极，则是像 C++ 这样，专为那 1% 的、追求极致性能和控制力的“宗师级”开发者准备的、布满荆棘的封神之路。</p>
<p><strong>C++26，欢迎来到神的世界，也欢迎来到神的炼狱。</strong></p>
<h2>参考资料</h2>
<ul>
<li>https://herbsutter.com/2026/03/29/c26-is-done-trip-report-march-2026-iso-c-standards-meeting-london-croydon-uk/</li>
<li>https://herbsutter.com/2025/06/21/trip-report-june-2025-iso-c-standards-meeting-sofia-bulgaria/ </li>
<li>https://herbsutter.com/2024/07/02/trip-report-summer-iso-c-standards-meeting-st-louis-mo-usa/</li>
<li>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html</li>
<li>https://www.youtube.com/watch?v=7z9NNrRDHQU</li>
<li>https://www.youtube.com/watch?v=oitYvDe4nps</li>
</ul>
<hr />
<p><strong>今日互动探讨：</strong></p>
<p>看完 C++26 的这四大“神仙”特性，你是感到兴奋，还是感到了深深的绝望？你觉得 C++ 的这种“大而全”的演进路线是对的，还是 Go 的“小而美”更代表未来？</p>
<p>欢迎在评论区分享你的看法！</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2026, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2026/03/31/go-minimalism-vs-cpp26-epic-new-features/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>降低 74% 的 P99 尾延迟：揭秘 Go HTTP 客户端的“请求对冲”魔法</title>
		<link>https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go/</link>
		<comments>https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go/#comments</comments>
		<pubDate>Mon, 30 Mar 2026 00:10:00 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Availability]]></category>
		<category><![CDATA[circuitbreaker]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Context]]></category>
		<category><![CDATA[DistributedSystems]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GoLanguage]]></category>
		<category><![CDATA[Go语言]]></category>
		<category><![CDATA[HedgeDelay]]></category>
		<category><![CDATA[HedgedRequests]]></category>
		<category><![CDATA[http.RoundTripper]]></category>
		<category><![CDATA[Idempotency]]></category>
		<category><![CDATA[LoadBalancing]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[P99Latency]]></category>
		<category><![CDATA[P99延迟]]></category>
		<category><![CDATA[RequestHedging]]></category>
		<category><![CDATA[standardlibrary]]></category>
		<category><![CDATA[SyncWaitGroup]]></category>
		<category><![CDATA[TailLatency]]></category>
		<category><![CDATA[Throttling]]></category>
		<category><![CDATA[Throughput]]></category>
		<category><![CDATA[TimeoutRetry]]></category>
		<category><![CDATA[上下文]]></category>
		<category><![CDATA[分布式系统]]></category>
		<category><![CDATA[可用性]]></category>
		<category><![CDATA[同步机制]]></category>
		<category><![CDATA[吞吐量]]></category>
		<category><![CDATA[对冲延迟]]></category>
		<category><![CDATA[尾延迟]]></category>
		<category><![CDATA[幂等性]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[熔断]]></category>
		<category><![CDATA[请求对冲]]></category>
		<category><![CDATA[负载均衡]]></category>
		<category><![CDATA[超时重试]]></category>
		<category><![CDATA[链路对冲]]></category>
		<category><![CDATA[限流]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=6119</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go 大家好，我是Tony Bai。 在微服务和分布式系统的世界里，我们常常会遇到一个令人头疼的现象：服务在大部分时间（如 P50 或 P90 指标）表现得非常丝滑，但总有那么一小撮请求（P99 甚至 P99.9 指标）慢得令人发指。 近日，在 Reddit 的 r/golang 社区中，一位开发者分享了他将 Go 服务的 P99 延迟降低了 74% 的经验。令人惊讶的是，他所使用的绝招并非升级硬件或重构业务逻辑，而是引入了一个名为 Request Hedging（请求对冲） 的策略。 面对高延迟，我们本能的反应是“重试（Retry）”。但正如这位开发者所发现的：单纯的重试不仅无助于解决长尾延迟，反而可能在系统高负载时雪上加霜。真正有效的方法是处理“落后者”，而不是“失败者”。 本文将带你重温 Google 关于分布式系统的经典论文，深入剖析 Request Hedging 的原理，并手把手教你如何仅使用 Go 标准库，为你的 HTTP 客户端插上“对冲”的翅膀。 尾延迟的诅咒：为什么重试不是万能药？ 在深入 Hedging 之前，我们必须先理解什么是尾延迟（Tail Latency）。 2013 年，Google 的两位大神 Jeffrey Dean 和 Luiz André Barroso 在《Communications of the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/reduced-p99-latency-by-request-hedging-in-go-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go">本文永久链接</a> &#8211; https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go</p>
<p>大家好，我是Tony Bai。</p>
<p>在微服务和分布式系统的世界里，我们常常会遇到一个令人头疼的现象：服务在大部分时间（如 P50 或 P90 指标）表现得非常丝滑，但总有那么一小撮请求（P99 甚至 P99.9 指标）慢得令人发指。</p>
<p>近日，在 Reddit 的 r/golang 社区中，一位开发者分享了他<a href="https://www.reddit.com/r/golang/comments/1s4mb10/reduced_p99_latency_by_74_in_go_learned_something/">将 Go 服务的 P99 延迟降低了 74% 的经验</a>。令人惊讶的是，他所使用的绝招并非升级硬件或重构业务逻辑，而是引入了一个名为 <strong>Request Hedging（请求对冲）</strong> 的策略。</p>
<p>面对高延迟，我们本能的反应是“重试（Retry）”。但正如这位开发者所发现的：单纯的重试不仅无助于解决长尾延迟，反而可能在系统高负载时雪上加霜。真正有效的方法是处理“落后者”，而不是“失败者”。</p>
<p>本文将带你重温 Google 关于分布式系统的<a href="https://research.google/pubs/the-tail-at-scale/">经典论文</a>，深入剖析 Request Hedging 的原理，并手把手教你如何仅使用 Go 标准库，为你的 HTTP 客户端插上“对冲”的翅膀。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/distributed-system-guide-qr.png" alt="" /></p>
<h2>尾延迟的诅咒：为什么重试不是万能药？</h2>
<p>在深入 Hedging 之前，我们必须先理解什么是<strong>尾延迟（Tail Latency）</strong>。</p>
<p>2013 年，Google 的两位大神 Jeffrey Dean 和 Luiz André Barroso 在《Communications of the ACM》上发表了一篇神级论文：<a href="https://cacm.acm.org/research/the-tail-at-scale/">《The Tail at Scale》</a>。在这篇Paper中，他们详细阐述了在大规模分布式系统中，为什么长尾延迟是不可避免的。</p>
<p>哪怕你拥有世界上最优秀的工程师，底层硬件的物理特性（如 CPU 降频、网络拥塞）、操作系统的后台任务（如 IO 调度）、以及语言运行时的特性（如 Go 的 GC 停顿），都会导致某些请求的处理时间远高于平均值。</p>
<p><strong>当你的服务需要并行调用多个下游服务时，这种局部的延迟波动会被急剧放大。</strong> 假设一个服务需要调用 100 个叶子节点，如果单个节点响应时间超过 1 秒的概率是 1%，那么整个请求超过 1 秒的概率将飙升至 63%！</p>
<blockquote>
<p>注：节点总数 n = 100 ，已知单个节点响应时间超过 1 秒的概率 为1%。单个节点响应时间不超过 1 秒（即正常响应）的概率为1-1% = 99% = 0.99。由于 100 个请求是并行的且相互独立，整个请求“正常”的前提是所有 100 个节点都必须在 1 秒内返回。这种概率为0.99^100=0.366。这样只要这 100 个节点中有任何一个掉链子，整个请求（作为整体）的耗时就会超过 1 秒。其概率为1-0.366≈0.63=63%。</p>
</blockquote>
<p><img src="https://tonybai.com/wp-content/uploads/2026/reduced-p99-latency-by-request-hedging-in-go-2.png" alt="" /><br />
<center>图：来自《The Tail at Scale》</center></p>
<p>这张图直观地展示了随着服务器数量（Fan-out）增加，哪怕单机变慢的概率极低，整体响应时间变慢的概率也会陡峭上升。</p>
<p>面对超时的请求，传统的做法是实施超时重试（Timeout &amp; Retry）。但重试存在致命缺陷：</p>
<ol>
<li><strong>你必须等待超时发生。</strong> 如果超时设置为 1 秒，那么重试的请求至少要经历 1 秒的延迟，这根本无法改善 P99 延迟。</li>
<li><strong>加剧雪崩。</strong> 当下游服务因为负载过高而变慢时，大量的重试请求会瞬间淹没下游，导致系统彻底崩溃。</li>
</ol>
<h2>Request Hedging：优雅地跑赢时间</h2>
<p>为了解决长尾延迟，Google 论文中提出了一种极具工程智慧的策略：<strong>Hedged Requests（请求对冲/对冲请求）</strong>。</p>
<p>其核心思想非常简单直白：</p>
<p><strong>客户端首先向目标服务器发送一个请求。如果该请求在预期的时间（即“对冲延迟阈值”，Hedging Delay）内没有返回，客户端不会等待其超时或失败，而是立即向另一个副本（或者同一个负载均衡器后的其他实例）发送一模一样的备份请求。客户端将使用最先返回的那个成功响应，并主动取消其余的未决请求。</strong></p>
<p>这种方法之所以有效，是因为导致请求变慢的因素通常是瞬时的且与特定机器相关的（如某台机器刚好在做 GC，或者刚好被一个大查询阻塞了队列）。第二个请求很大概率会被路由到一台健康的、空闲的机器上，从而快速返回。</p>
<p><strong>Hedging 与 Retry 的本质区别：</strong></p>
<ul>
<li><strong>Retry</strong>：针对的是<strong>失败（Failure）</strong>。必须等第一个请求彻底失败或超时，才发起第二个。</li>
<li><strong>Hedging</strong>：针对的是<strong>慢（Slowness）</strong>。第一个请求还在运行（没报错），第二个请求就已经出发了。它们是并行竞争的关系。</li>
</ul>
<p><img src="https://tonybai.com/wp-content/uploads/2026/reduced-p99-latency-by-request-hedging-in-go-3.png" alt="" /></p>
<p>虽然这听起来像是在浪费服务器资源，但 Google 的实践证明，如果将 Hedging Delay 设置为 P95 延迟（即 95% 的请求都能在这个时间内完成），那么<strong>只有 5% 的请求会触发对冲。这仅仅增加了 5% 的系统负载，却能将 P99 或 P99.9 的长尾延迟削减大半！</strong></p>
<p>在现代微服务生态中，<a href="https://grpc.io/docs/guides/request-hedging/">gRPC 已经在 Service Config 中原生支持了 Hedging 策略</a>，但对于广泛使用的 HTTP/REST 接口，我们通常需要自己实现。</p>
<h2>实战：构建可压测的 Hedging HTTP Client</h2>
<p>为了验证 Hedging 的威力，我们将使用 Go 原生标准库，从零实现一个带有对冲机制的 http.RoundTripper，并构建一个完整的压测实验环境。</p>
<h3>项目布局</h3>
<p>首先，创建一个新的 Go 项目：</p>
<pre><code class="bash">mkdir go-hedging-demo
cd go-hedging-demo
go mod init hedging-demo
</code></pre>
<p>我们将创建三个文件：</p>
<ul>
<li>hedge.go：包含核心的 Hedging 逻辑实现。</li>
<li>server.go：一个模拟真实分布式环境、带有随机高延迟的测试服务器。</li>
<li>main.go：客户端压测入口，用于对比普通请求和 Hedging 请求的性能差异。</li>
</ul>
<pre><code class="text">go-hedging-demo/
├── go.mod
├── hedge.go
├── server.go
└── main.go
</code></pre>
<h3>核心实现：hedge.go</h3>
<p>我们将通过实现 http.RoundTripper 接口，优雅地将对冲逻辑无缝注入到 Go 标准库的 http.Client 中。</p>
<pre><code class="go">// hedge.go
package main

import (
    "context"
    "errors"
    "net/http"
    "sync"
    "time"
)

// HedgedTransport 实现了 http.RoundTripper 接口
type HedgedTransport struct {
    Transport   http.RoundTripper // 底层真正的 Transport
    MaxAttempts int               // 最大并发请求数（包括最初的1次）
    HedgeDelay  time.Duration     // 触发对冲的延迟时间
}

func (ht *HedgedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    // 如果没有设置，使用默认行为
    transport := ht.Transport
    if transport == nil {
        transport = http.DefaultTransport
    }
    attempts := ht.MaxAttempts
    if attempts &lt;= 0 {
        attempts = 1
    }

    // 使用带有取消功能的 context 控制整个对冲生命周期
    ctx, cancel := context.WithCancel(req.Context())
    defer cancel()

    // 结果通道，用于接收第一个成功的响应或错误
    type result struct {
        resp *http.Response
        err  error
    }
    resCh := make(chan result, attempts)
    var wg sync.WaitGroup

    // 启动一个请求的闭包函数
    doRequest := func() {
        wg.Add(1)
        go func() {
            defer wg.Done()
            // 克隆请求，防止并发修改
            cloneReq := req.Clone(ctx)
            resp, err := transport.RoundTrip(cloneReq)

            // 只有当请求不是因为 context 取消而失败时，才尝试写入结果
            if !errors.Is(err, context.Canceled) {
                select {
                case resCh &lt;- result{resp: resp, err: err}:
                default:
                    // 通道已满或已不再需要，直接丢弃（如果 resp 不为空，需要关闭 Body 以防泄露）
                    if resp != nil &amp;&amp; resp.Body != nil {
                        resp.Body.Close()
                    }
                }
            }
        }()
    }

    // 1. 发起第一个请求
    doRequest()

    // 2. 控制对冲的定时器和尝试次数
    timer := time.NewTimer(ht.HedgeDelay)
    defer timer.Stop()

    errs := make([]error, 0, attempts)
    requestsSent := 1

    for {
        select {
        case res := &lt;-resCh:
            // 收到结果
            if res.err == nil {
                // 成功！立即取消其他还在飞行的请求
                cancel()
                // 等待后台 goroutine 清理完成 (可选，这里为了简单不阻塞)
                return res.resp, nil
            }
            // 如果这个请求失败了，记录错误
            errs = append(errs, res.err)
            // 如果所有发出的请求都失败了，且已经达到最大尝试次数，返回错误
            if len(errs) == attempts {
                return nil, errors.Join(errs...)
            }

            // 如果一个请求失败了，且还没达到最大尝试次数，我们不应该死等 Timer，
            // 而应该立刻触发下一个对冲请求（这里为了简化逻辑，依然依赖下一次 Timer 或失败循环）
            // 实际生产级实现可以在这里直接触发 doRequest()

        case &lt;-timer.C:
            // 对冲延迟到达
            if requestsSent &lt; attempts {
                // 触发对冲请求
                doRequest()
                requestsSent++
                // 重置定时器，准备下一次可能的对冲
                timer.Reset(ht.HedgeDelay)
            }

        case &lt;-ctx.Done():
            // 整个请求超时或被调用方取消
            return nil, ctx.Err()
        }
    }
}
</code></pre>
<p>这里，我们使用了 req.Clone(ctx) 来复制请求，确保并发安全。通过 context.WithCancel 控制所有的下游请求，一旦有一个请求成功返回（res.err == nil），立即调用 cancel() 取消其余正在运行（in-flight）的请求。</p>
<h3>测试服务器：模拟“长尾效应” server.go</h3>
<p>为了看到效果，我们编写一个简单的 HTTP 服务。它在 90% 的情况下在 50ms 内快速响应，但在 10% 的情况下会遇到长达 500ms 到 1s 的长尾延迟。</p>
<pre><code class="go">// server.go
package main

import (
    "fmt"
    "math/rand"
    "net/http"
    "time"
)

func startServer() {
    http.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
        // 模拟 10% 的长尾延迟
        if rand.Float32() &lt; 0.1 {
            // 长尾延迟：500ms - 1000ms
            delay := 500 + rand.Intn(500)
            time.Sleep(time.Duration(delay) * time.Millisecond)
        } else {
            // 正常响应：10ms - 50ms
            delay := 10 + rand.Intn(40)
            time.Sleep(time.Duration(delay) * time.Millisecond)
        }

        fmt.Fprintln(w, "OK")
    })

    go func() {
        err := http.ListenAndServe(":8080", nil)
        if err != nil {
            panic(err)
        }
    }()
    time.Sleep(100 * time.Millisecond) // 等待服务器启动
}
</code></pre>
<h3>压测入口：对比见真章 main.go</h3>
<p>最后，我们编写压测代码，分别使用普通 Client 和 Hedged Client 发送 1000 个并发请求，并统计 P99 延迟。</p>
<pre><code class="go">// main.go
package main

import (
    "fmt"
    "io"
    "net/http"
    "sort"
    "sync"
    "time"
)

const RequestCount = 1000

func main() {
    startServer()

    fmt.Println("开始压测普通 HTTP Client...")
    normalClient := &amp;http.Client{
        Timeout: 2 * time.Second,
    }
    normalLatencies := runBenchmark(normalClient)

    fmt.Println("\n开始压测 Hedged HTTP Client...")
    hedgedClient := &amp;http.Client{
        Timeout: 2 * time.Second,
        Transport: &amp;HedgedTransport{
            Transport:   http.DefaultTransport,
            MaxAttempts: 3,                 // 最多发送3个请求
            HedgeDelay:  80 * time.Millisecond, // P95 延迟设为触发点（我们服务器正常响应 &lt; 50ms）
        },
    }
    hedgedLatencies := runBenchmark(hedgedClient)

    // 打印统计结果
    printStats("Normal Client", normalLatencies)
    printStats("Hedged Client", hedgedLatencies)
}

func runBenchmark(client *http.Client) []time.Duration {
    var wg sync.WaitGroup
    latencies := make([]time.Duration, RequestCount)

    for i := 0; i &lt; RequestCount; i++ {
        wg.Add(1)
        go func(index int) {
            defer wg.Done()

            start := time.Now()
            resp, err := client.Get("http://localhost:8080/data")
            if err != nil {
                fmt.Printf("Request failed: %v\n", err)
                return
            }
            io.Copy(io.Discard, resp.Body)
            resp.Body.Close()

            latencies[index] = time.Since(start)
        }(i)
    }

    wg.Wait()
    return latencies
}

func printStats(name string, latencies []time.Duration) {
    // 去除可能的失败请求（0值）
    valid := make([]time.Duration, 0, len(latencies))
    for _, l := range latencies {
        if l &gt; 0 {
            valid = append(valid, l)
        }
    }

    sort.Slice(valid, func(i, j int) bool {
        return valid[i] &lt; valid[j]
    })

    if len(valid) == 0 {
        fmt.Printf("No valid responses for %s\n", name)
        return
    }

    p50 := valid[len(valid)/2]
    p95 := valid[int(float64(len(valid))*0.95)]
    p99 := valid[int(float64(len(valid))*0.99)]

    fmt.Printf("\n=== %s 统计 ===\n", name)
    fmt.Printf("请求总数: %d\n", len(valid))
    fmt.Printf("P50 延迟: %v\n", p50)
    fmt.Printf("P95 延迟: %v\n", p95)
    fmt.Printf("P99 延迟: %v\n", p99)
}
</code></pre>
<h3>运行与验证</h3>
<p>在本地 MacBook Pro 的终端上执行 go run .，我得到了以下真实的性能对决：</p>
<pre><code class="text">$go run .
开始压测普通 HTTP Client...

开始压测 Hedged HTTP Client...

=== Normal Client 统计 ===
请求总数: 1000
P50 延迟: 115.226929ms
P95 延迟: 850.768537ms &lt;-- 注意看这里
P99 延迟: 1.045720114s &lt;-- 长尾效应严重

=== Hedged Client 统计 ===
请求总数: 1000
P50 延迟: 138.930108ms &lt;-- P50 轻微损耗
P95 延迟: 360.607686ms &lt;-- 巨大的改善！
P99 延迟: 376.98949ms  &lt;-- P99 降低了将近 70%！
</code></pre>
<p>正如你所见：</p>
<ul>
<li>P99 巨幅改善：对冲机制成功将 P99 延迟降低了 64%。原本需要 1 秒以上的极端慢请求，现在被控制在了 400ms 以内。</li>
<li>P50 轻微损耗：由于请求克隆、Context 管理以及本地 CPU 调度多出一倍请求的竞争，P50 上升了约 23ms。</li>
</ul>
<p>结论：在典型的分布式系统中，这种权衡是极度划算的。我们用极小的平均延迟上升，换取了尾部延迟的高稳定性。</p>
<h2>生产环境的避坑指南</h2>
<p>Request Hedging 虽好，但绝非能随意滥用的“银弹”。在将其部署到生产环境之前，你必须考虑以下几个核心约束：</p>
<ol>
<li><strong>绝对的幂等性（Idempotency）</strong>：对冲意味着同一笔请求可能同时发送给后端的两个节点。如果这是个 POST 扣款请求，而你的后端没有做好幂等性控制，这将会是一场灾难。<strong>Hedging 最好只用于幂等的只读请求（如 GET），或者有严格全局事务 ID 兜底的写入操作。</strong></li>
<li><strong>Hedge Delay 的设定</strong>：这是最考验架构师的参数。设得太短，所有的请求都会变成双倍发送，瞬间打挂后端（这叫放大攻击）；设得太长，起不到降低长尾的作用。最佳实践是通过 Prometheus 等监控工具，计算出该接口过去的 <strong>P95 响应时间</strong>，将其作为 Hedging Delay 的基准值。</li>
<li><strong>熔断与限流（Throttling）</strong>：如果下游服务整体宕机，所有的请求都会变慢，此时触发所有的对冲请求只会加速死亡。因此，正如 gRPC 规范中要求的，Hedging 必须与限流（Throttling）结合。例如，计算一个“对冲令牌池”，只有当成功请求大于失败请求达到一定比例时，才允许发送对冲请求。</li>
</ol>
<h2>小结</h2>
<p>软件工程是一门关于权衡的艺术。在追求极致性能的道路上，我们往往将目光局限于优化数据库索引、压缩 JSON 序列化，却忽视了分布式系统固有的宏观不确定性。</p>
<p>Request Hedging 是从宏观架构层面给出的一记漂亮的防守反击。通过上面几百行的 Go 代码，我们成功复现了 Google 级别的架构优化。下一次，当你的监控大盘上 P99 曲线再次异常抖动时，不妨收起单纯的“超时重试”，尝试给你的 Go 客户端加一点“对冲”的魔法吧。</p>
<p>本文中涉及的代码可以在<a href="https://github.com/bigwhite/experiments/tree/master/go-hedging-demo">这里</a>下载。https://github.com/bigwhite/experiments/tree/master/go-hedging-demo</p>
<p>资料链接：</p>
<ul>
<li>https://www.reddit.com/r/golang/comments/1s4mb10/reduced_p99_latency_by_74_in_go_learned_something/</li>
<li>https://grpc.io/docs/guides/request-hedging/</li>
<li>https://research.google/pubs/the-tail-at-scale/</li>
</ul>
<hr />
<p><strong>你的 P99 达标了吗？</strong></p>
<p>尾延迟是分布式系统中最难缠的对手。在你的项目中，主要的长尾延迟来源是什么？你会为了降低那 1% 的极端慢请求，而接受 5% 的额外系统负载吗？</p>
<p>欢迎在评论区分享你的性能调优“必杀技”！</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2026, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2026/03/30/reduced-p99-latency-by-request-hedging-in-go/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>真相调查：Go 语言真的消灭了 Undefined Behavior 吗？</title>
		<link>https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation/</link>
		<comments>https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation/#comments</comments>
		<pubDate>Mon, 16 Mar 2026 00:27:35 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[ArrayIndexOutOfBounds]]></category>
		<category><![CDATA[BufferOverflow]]></category>
		<category><![CDATA[CompilerOptimization]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[DataRace]]></category>
		<category><![CDATA[DaveCheney]]></category>
		<category><![CDATA[Determinism]]></category>
		<category><![CDATA[EngineeringTradeoffs]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GoLanguage]]></category>
		<category><![CDATA[Go语言]]></category>
		<category><![CDATA[IanLanceTaylor]]></category>
		<category><![CDATA[IntegerOverflow]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[memorymodel]]></category>
		<category><![CDATA[MemorySafety]]></category>
		<category><![CDATA[MultiwordDataStructures]]></category>
		<category><![CDATA[NilPointerDereference]]></category>
		<category><![CDATA[RaceDetection]]></category>
		<category><![CDATA[RuntimeChecks]]></category>
		<category><![CDATA[Slice]]></category>
		<category><![CDATA[TypeConfusion]]></category>
		<category><![CDATA[UndefinedBehavior]]></category>
		<category><![CDATA[UnspecifiedBehavior]]></category>
		<category><![CDATA[内存安全]]></category>
		<category><![CDATA[内存模型]]></category>
		<category><![CDATA[切片]]></category>
		<category><![CDATA[多字数据结构]]></category>
		<category><![CDATA[工程权衡]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[接口]]></category>
		<category><![CDATA[数据竞争]]></category>
		<category><![CDATA[数组越界]]></category>
		<category><![CDATA[整数溢出]]></category>
		<category><![CDATA[未定义行为]]></category>
		<category><![CDATA[未指明行为]]></category>
		<category><![CDATA[确定性]]></category>
		<category><![CDATA[空指针解引用]]></category>
		<category><![CDATA[竞态检测]]></category>
		<category><![CDATA[类型混淆]]></category>
		<category><![CDATA[缓冲区溢出]]></category>
		<category><![CDATA[编译器优化]]></category>
		<category><![CDATA[运行时检查]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=6045</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation 大家好，我是Tony Bai。 在系统编程的古老传说中，流传着一个关于“鼻恶魔”（Nasal Demons）的笑话。 这个梗源自 comp.std.c 新闻组，它是对 C/C++ 语言中“未定义行为”（Undefined Behavior，以下简称 UB）最生动也最恐怖的诠释。根据 ISO C++ 标准，如果你的代码触犯了 UB（例如数组越界、有符号整数溢出、空指针解引用），编译器可以“为所欲为”。 这种“为所欲为”不仅包括程序崩溃，还包括产生错误的结果、损坏数据，甚至——虽然只是笑话——让恶魔从你的鼻孔里飞出来。换句话说，一旦触碰 UB，程序的所有保证瞬间失效。 2009 年，Go 语言横空出世，高举“云原生时代系统语言”的旗帜，承诺提供比 C++ 更高的安全性、更快的编译速度和更简单的并发模型。Go 的拥趸们津津乐道于它的内存安全特性，仿佛 Go 已经彻底终结了 UB 的噩梦。 但真相果真如此吗？ 近日，我翻阅了一份珍贵的历史资料——2013 年发生在 golang-nuts 邮件组的一场深度辩论。对话的一方是 Go 语言曾经的顶级贡献者 Dave Cheney，另一方是 Go 核心团队成员、gccgo 的作者 Ian Lance Taylor。 这场发生在这个语言童年时期的对话，揭示了一个令人背脊发凉又引人深思的事实：Go 并没有完全消灭未定义行为，它只是将 UB 赶进了一个更隐秘、更危险的角落——并发。 本文将带你层层剥开 Go 语言规范的表皮，调查“未定义行为”在 Go 中的真实生存状态，并探讨这对我们编写高质量代码意味着什么。 用“定义”换取“安全”——Go [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/go-language-eliminated-undefined-behavior-truth-investigation-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation">本文永久链接</a> &#8211; https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation</p>
<p>大家好，我是Tony Bai。</p>
<p>在系统编程的古老传说中，流传着一个关于“鼻恶魔”（Nasal Demons）的笑话。</p>
<p>这个梗源自 comp.std.c 新闻组，它是对 C/C++ 语言中“未定义行为”（Undefined Behavior，以下简称 UB）最生动也最恐怖的诠释。根据 ISO C++ 标准，如果你的代码触犯了 UB（例如数组越界、有符号整数溢出、空指针解引用），编译器可以“为所欲为”。</p>
<p>这种“为所欲为”不仅包括程序崩溃，还包括产生错误的结果、损坏数据，甚至——虽然只是笑话——让恶魔从你的鼻孔里飞出来。换句话说，一旦触碰 UB，程序的所有保证瞬间失效。</p>
<p>2009 年，Go 语言横空出世，高举“云原生时代系统语言”的旗帜，承诺提供比 C++ 更高的安全性、更快的编译速度和更简单的并发模型。Go 的拥趸们津津乐道于它的内存安全特性，仿佛 Go 已经彻底终结了 UB 的噩梦。</p>
<p><strong>但真相果真如此吗？</strong></p>
<p>近日，我翻阅了一份珍贵的历史资料——2013 年发生在 golang-nuts 邮件组的<a href="https://groups.google.com/g/golang-nuts/c/MB1QmhDd_Rk">一场深度辩论</a>。对话的一方是 Go 语言曾经的顶级贡献者 Dave Cheney，另一方是 Go 核心团队成员、gccgo 的作者 Ian Lance Taylor。</p>
<p>这场发生在这个语言童年时期的对话，揭示了一个令人背脊发凉又引人深思的事实：<strong>Go 并没有完全消灭未定义行为</strong>，它只是将 UB 赶进了一个更隐秘、更危险的角落——并发。</p>
<p>本文将带你层层剥开 Go 语言规范的表皮，调查“未定义行为”在 Go 中的真实生存状态，并探讨这对我们编写高质量代码意味着什么。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/agentic-software-engineering-qr.png" alt="" /></p>
<h2>用“定义”换取“安全”——Go 的显式哲学</h2>
<p>要理解 Go 做了什么，我们首先得明白 C/C++ 为什么保留 UB。Ian Lance Taylor 指出，C/C++ 保留 UB 本质上是为了<strong>性能</strong>——允许编译器假设“坏事永远不会发生”，从而进行激进的优化。</p>
<p>Dave Cheney 的疑问直击灵魂：“Go 规范中几乎看不到‘undefined’这个词，这种设计如何影响了 Go 的安全性与性能？”</p>
<p>答案是：Go 选择了一条确定性（Determinism）优先的道路。Go 语言规范以一种近乎偏执的态度，将绝大多数在 C/C++ 中属于 UB 的行为，都进行了严格的“定义”。即便是在错误场景下，Go 也要保证行为是<strong>可预测的</strong>。</p>
<h3>整数溢出的“确定性”承诺</h3>
<p>在 C 语言中，有符号整数（Signed Integer）的溢出是经典的 UB。编译器有权假设溢出永远不会发生，从而将 x + 1 > x 优化为恒真（Always True），这曾导致过无数的安全漏洞。</p>
<p>但在 Go 语言规范中，对此有着截然不同的定义：</p>
<blockquote>
<p>无符号整数：运算结果严格按照 2^n 取模。这意味着高位被丢弃，程序可以依赖这种“回绕（Wrap-around）”行为。</p>
<p>有符号整数：运算可以合法地溢出（legally overflow）。结果由有符号整数的表示方式（通常是补码）、运算类型和操作数确定性地定义。溢出不会导致运行时 Panic。</p>
</blockquote>
<p>最关键的是，Go 规范明确禁止编译器进行危险的假设：“编译器不得假设溢出不会发生。例如，它不得假设 x &lt; x + 1 总是为真。”</p>
<p><strong>代码实证：</strong></p>
<pre><code class="go">// https://go.dev/play/p/5CZVVU-SITX
package main

import "fmt"

func main() {
    // 1. 有符号整数溢出 (Signed Overflow)
    var a int8 = 127
    // 在 C 语言中这是 UB，但在 Go 中这是明确定义的
    b := a + 1
    fmt.Printf("int8: %d + 1 = %d\n", a, b)
    // 输出: 127 + 1 = -128 (确定性的回绕)

    // 2. 编译器禁止做的优化
    // 如果编译器假设溢出不发生，它会把这个判断优化掉
    if b &lt; a {
        fmt.Println("发生溢出：b 确实小于 a")
    } else {
        fmt.Println("未发生溢出逻辑（Go 中不会走到这里）")
    }

    // 3. 无符号整数溢出 (Unsigned Overflow)
    var c uint8 = 255
    d := c + 1
    fmt.Printf("uint8: %d + 1 = %d\n", c, d)
    // 输出: 255 + 1 = 0 (严格的 Modulo 2^n)
}
</code></pre>
<p>Go这么做的代价是Go 编译器失去了一些数学优化机会（例如不能简单地消除某些循环边界检查）。但也消除了因编译器“自作聪明”而导致的逻辑崩塌，保证了不同平台下的行为一致性。</p>
<h3>数组越界的“必杀令”</h3>
<p>缓冲区溢出（Buffer Overflow）是网络安全史上最大的杀手。C/C++ 将越界访问视为 UB，允许攻击者通过越界读取敏感内存或覆盖返回地址，进而控制系统。</p>
<p>Go 对此零容忍：<strong>越界必须触发 Panic。</strong></p>
<p>无论是在栈上分配的数组，还是在堆上分配的切片，Go 编译器都会在每一次访问操作前（除非能静态证明安全）插入一段 Bounds Check（边界检查）指令。一旦越界，程序立即停止，绝不含糊。</p>
<p><strong>代码实证：</strong></p>
<pre><code class="go">// https://go.dev/play/p/-CqDpIDr0BC
package main

import "fmt"

func main() {
    // 定义一个长度为 3 的切片
    s := []int{1, 2, 3}

    // 模拟一个动态索引（避免编译器在编译期直接报错）
    index := getIndex() 

    fmt.Println("尝试访问索引:", index)

    // 这里会触发 Runtime Panic
    // 错误信息明确：runtime error: index out of range [3] with length 3
    val := s[index] 

    fmt.Println("这行代码永远不会执行", val)
}

func getIndex() int {
    return 3
}
</code></pre>
<p>这种边界检查是在运行时（Runtime）介入，抛出 Panic，打印堆栈信息。因此会带来运行时性能损耗。虽然现代 Go 编译器引入了 BCA（边界检查消除）技术，但在无法静态分析的场景下，这就是必须缴纳的“安全税”。</p>
<h3>空指针的“硬着陆”</h3>
<p>在 C 语言中，解引用一个空指针是 UB。编译器有时会优化掉判空逻辑，因为它认为“既然你解引用了，那指针肯定不为空”，导致后续的安全检查失效。</p>
<p>Go 规定：<strong>解引用 nil 指针必须触发 Panic。</strong></p>
<p>这通常是通过 CPU 的硬件异常（SIGSEGV）来捕获的。Go 运行时会接管这个硬件信号，并将其转化为一个可恢复的 Go Panic，而不是让进程直接 Core Dump 或进入不可预测的僵死状态。</p>
<p><strong>代码实证：</strong></p>
<pre><code class="go">// https://go.dev/play/p/hlyZks1dGRf
package main

import "fmt"

type User struct {
    Name string
}

func main() {
    var u *User // u 默认为 nil

    fmt.Println("准备访问 nil 指针...")

    // 在 C 中这是 UB，可能导致程序崩溃或更糟的情况
    // 在 Go 中，这不仅会 Panic，还可以被 Recover 捕获
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到恐慌:", r)
            // 输出: runtime error: invalid memory address or nil pointer dereference
        }
    }()

    // 触发 Panic
    fmt.Println(u.Name)
}
</code></pre>
<p>综上，我们可知：在单线程维度，Go 确实几乎消灭了 Undefined Behavior。它通过强制规定行为（Wrapping, Panicking），将“未定义”变成了“定义明确的错误”。<strong>即使程序写错了，它的错误方式也是确定的，而非随机的。</strong></p>
<h2>房间里的大象——数据竞争</h2>
<p>如果文章到这里结束，那么 Go 就是一个完美的、绝对安全的语言。</p>
<p>但 Ian Lance Taylor 随后抛出了一个重磅炸弹：</p>
<blockquote>
<p><strong>“However, Go does have undefined behavior: if your program has a race condition, the behaviour is undefined.”</strong><br />
  <strong>（然而，Go 确实存在未定义行为：如果你的程序存在数据竞争，那么行为就是未定义的。）</strong></p>
</blockquote>
<p>这就是 Go 语言安全神话中最大的裂痕。</p>
<p>在 Rust 中，编译器借用检查器（Borrow Checker）会在编译期阻止数据竞争，因此 Rust 可以自豪地宣称“无数据竞争”。但 Go 选择了更简单的并发模型，允许 Goroutine 共享内存。</p>
<p>一旦发生数据竞争（Data Race），即多个 Goroutine 同时访问同一块内存且至少有一个是写操作，Go 就不再提供任何保证。</p>
<p><strong>为什么数据竞争是真正的 UB？</strong></p>
<p>很多 Gopher 认为数据竞争只是“读到了旧数据”或者“计数器少加了 1”。这是一种极其危险的误解。在多核 CPU 和现代编译器优化的加持下，数据竞争在 Go 中可能导致<strong>内存安全破坏</strong>。</p>
<p>这主要源于 Go 的<strong>多字数据结构（Multi-word Data Structures）</strong>。</p>
<h3>接口（Interface）的“撕裂”</h3>
<p>Go 的 interface 在底层是由两个机器字组成的：{type_ptr, data_ptr}。</p>
<ul>
<li>type_ptr 指向具体类型的元数据（如方法表）。</li>
<li>data_ptr 指向具体的数据值。</li>
</ul>
<p>假设我们有一个全局接口变量 var i interface{}，以及两个实现类型 type A 和 type B。</p>
<ul>
<li>Goroutine 1 试图将 i 赋值为 A{}。</li>
<li>Goroutine 2 试图将 i 赋值为 B{}。</li>
</ul>
<p>如果没有加锁，Goroutine 3 可能会读到一个“弗兰肯斯坦”般的怪物接口：<strong>它的 type_ptr 来自 A，但 data_ptr 却指向 B 的数据！</strong></p>
<p>当你调用这个接口的方法时，程序会尝试用 A 的方法表去操作 B 的内存布局。这会导致什么？</p>
<p>如果运气好，你会得到Panic（类型断言失败或非法内存访问）。</p>
<p>反之，如果运气不好，那远程代码执行（RCE）的攻击者可以精心构造内存布局，利用这种类型混淆（Type Confusion）来劫持控制流。</p>
<h3>切片（Slice）的“越界”</h3>
<p>切片由 {ptr, len, cap} 三个字组成。数据竞争可能导致你读到了新的 len（变得很大），但 ptr 还是旧的（指向一个小数组）。结果是你拥有了一个长度远超底层数组容量的切片，这让你能够读取甚至修改不属于该切片的任意内存——这正是 C 语言缓冲区溢出的翻版。</p>
<p><strong>这，就是 Go 中的 Undefined Behavior。</strong> 它不是“鼻恶魔”，但它是真实存在的安全黑洞。</p>
<h2>那些“未指明”的灰色地带</h2>
<p>除了致命的 UB，讨论中还涉及了 Go 语言规范中的另一种存在：<strong>未指明行为（Unspecified Behavior）</strong> 或 <strong>实现定义行为（Implementation-Defined Behavior）</strong>。</p>
<p>这些行为虽然不会导致内存破坏，但同样破坏了程序的“确定性”。</p>
<h3>Map 的迭代顺序</h3>
<p>在 Go 中，for k, v := range m 的顺序是<strong>故意</strong>未定义的。</p>
<p>Ian 解释说，这是为了防止开发者依赖某种特定的哈希实现顺序。Go 运行时甚至在每次迭代开始时引入了随机种子(迭代器会在map bucket 数组中随机选取一个起始位置向后遍历)，强制让顺序变得不可预测。</p>
<p>这是一个非常有智慧的设计：通过强制随机化，逼迫开发者编写不依赖顺序的健壮代码。</p>
<h3>表达式求值顺序：在“确定”与“未指明”之间</h3>
<p>在 C/C++ 中，f(g(), h()) 中 g() 和 h() 谁先执行是未定义的（Undefined Behavior 或 Unspecified Behavior），这取决于编译器实现。</p>
<p>Go 语言规范对此做了更严格的规定，但依然保留了一块微妙的“灰色地带”。</p>
<p><strong>确定的部分（Defined）：</strong></p>
<p>Go 规定，在求值表达式的操作数、赋值语句或返回语句时，所有的函数调用、方法调用和通信操作（Channel receive）都必须按照<strong>词法上从左到右</strong>的顺序执行。</p>
<p>例如，在赋值语句 y[f()], ok = g(h(), i()+x[j()], &lt;-c), k() 中，函数调用和通信的发生顺序被严格锁定为：</p>
<p>f() -> h() -> i() -> j() -> <-c -> g() -> k()。</p>
<p><strong>未指明的部分（Unspecified）：</strong></p>
<p>然而，规范同时也指出：<strong>并没有规定</strong>上述事件与表达式求值、索引操作、以及变量 y 的求值之间的顺序。</p>
<p>这意味着，虽然函数调用的相对顺序是固定的，但涉及副作用（Side Effects）的变量读写顺序可能是不确定的。来看 Spec 中的经典反例：</p>
<pre><code class="go">a := 1
f := func() int { a++; return a }

// x 可能是 [1, 2] 也可能是 [2, 2]
// 因为 a 的求值与 f() 的执行顺序未定义
x := []int{a, f()}
println(a, x)

// --- 示例：map 字面量中 key/value 的求值顺序未定义 ---
b := 1
g := func() int { b++; return b } // g() 会修改 b

// 若 b 先被求值：key=1, value=2  → m = {1: 2}
// 若 g() 先被执行：key=2, value=2 → m = {2: 2}
// Go 规范不保证 key 表达式与 value 表达式谁先求值
m2 := map[int]int{b: g()}
println(b, m2[b])
</code></pre>
<p>虽然 Go 比 C/C++ 确定得多，但在编写依赖于求值顺序的副作用代码（例如在参数列表中修改全局变量）时，依然可能会掉进“未指明行为”的陷阱。因此，最好不要在单行表达式中依赖复杂的副作用顺序。</p>
<h3>浮点数转换的幽灵</h3>
<p>讨论中有开发者 提到了 float64 转换为 uint8 的行为。在早期的 Go 版本中，对于溢出值的处理可能依赖于底层硬件指令（x86 vs ARM），从而表现出不一致。</p>
<p>虽然 Go 正在逐步收紧这些规范，例如 <a href="https://tonybai.com/2026/01/11/proposal-float-to-int-conversions-should-saturate-on-overflow/">#76264 提案</a>(尚未落地)正试图统一浮点转整数的饱和行为，但这提醒我们：即使是强类型语言，在跨平台移植时也可能遇到底层架构带来的“方言”差异。</p>
<h2>如何在充满 UB 的世界里生存？</h2>
<p>既然 Go 没有彻底消灭 UB，作为开发者，我们该如何自保？</p>
<h3>视 -race 为生命线</h3>
<p>Ian Lance Taylor 的警告应该被打印在每个 Go 开发者的工位上。</p>
<p><strong>建议</strong>：</p>
<ul>
<li>单元测试必须开启 -race 标志运行。</li>
<li>在 CI/CD 流水线中，竞态检测是不可跳过的阻断性步骤。</li>
<li>不要相信“我的并发逻辑很简单，不会出错”，人脑无法模拟现代 CPU 的乱序执行。</li>
</ul>
<h3>敬畏 unsafe</h3>
<p>Go 的 unsafe 包是通往 C 语言 UB 世界的后门。使用 unsafe.Pointer 进行类型转换时，你实际上是在对编译器说：“我知道我在做什么，出了事我负责。”</p>
<p>除非你是编写底层运行时或极致性能库的专家，否则在业务代码中绝对禁止使用 unsafe。一旦使用，你必须熟读《<a href="https://go.dev/ref/mem">Go 内存模型</a>》和《<a href="https://go.dev/doc/gc-guide">垃圾回收器写屏障规则</a>》。</p>
<h3>理解“实现定义”与“未定义”的区别</h3>
<ul>
<li>未定义（UB）：可能导致 Crash、数据损坏、安全漏洞（如数据竞争）。零容忍。</li>
<li>未指明/实现定义：不同版本或平台可能表现不同（如 Map 顺序）。不要依赖它。</li>
<li>已定义：Go 承诺的行为（如整数回绕）。可以依赖，但需知晓代价。</li>
</ul>
<h2>小结：完美的幻象与工程的现实</h2>
<p>通过这次“真相调查”，我们得出的结论可能有些令人沮丧，但也足够清醒：</p>
<p><strong>Go 语言并没有彻底消灭 Undefined Behavior。它只是通过牺牲一部分性能和增加运行时检查，将 UB 的“攻击范围”从 C/C++ 的“随处可见”缩小到了“并发数据竞争”和“不安全代码”这两个特定的领域。</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2026/go-language-eliminated-undefined-behavior-truth-investigation-2.png" alt="" /></p>
<p>这是一种极其成功的工程权衡。它让 Go 在保持高性能的同时，为 99% 的日常编码提供了坚实的安全保障。</p>
<p>然而，作为 Gopher，我们不能沉浸在“绝对安全”的幻象中。我们必须意识到，当我们敲下 go func() 的那一刻，当我们试图共享一个指针的那一刻，我们正行走在悬崖的边缘。</p>
<p>Go 给了我们围栏（定义明确的行为），但也给了我们梯子（并发与 Unsafe）。能否不跌入 UB 的深渊，最终取决于我们是否遵守工程的纪律。</p>
<p>资料链接：https://groups.google.com/g/golang-nuts/c/MB1QmhDd_Rk</p>
<hr />
<p><strong>你遇到过“鼻恶魔”吗？</strong></p>
<p>哪怕是 Go 这样严谨的语言，在并发面前也会露出锋利的牙齿。在你的开发生涯中，是否遇到过那种因为没开 -race 而在生产环境产生的“灵异事件”？你对 Go 这种“用性能换确定性”的哲学怎么看？</p>
<p>欢迎在评论区分享你的“探案”心得！</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2026, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2026/03/16/go-language-eliminated-undefined-behavior-truth-investigation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>刚刚，Claude Code 作者曝光了自己的“私房”配置：原来顶尖高手是这样用 AI 写代码的！</title>
		<link>https://tonybai.com/2026/01/05/httpstonybai-com20260105claude-code-author-reveals-private-ai-coding-config/</link>
		<comments>https://tonybai.com/2026/01/05/httpstonybai-com20260105claude-code-author-reveals-private-ai-coding-config/#comments</comments>
		<pubDate>Mon, 05 Jan 2026 00:08:04 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AIArchitect]]></category>
		<category><![CDATA[AINativeDevelopment]]></category>
		<category><![CDATA[AI原生开发]]></category>
		<category><![CDATA[AI架构师]]></category>
		<category><![CDATA[AI编程]]></category>
		<category><![CDATA[Allowlist]]></category>
		<category><![CDATA[Anthropic]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[BorisCherny]]></category>
		<category><![CDATA[Claude.md]]></category>
		<category><![CDATA[ClaudeCode]]></category>
		<category><![CDATA[Headless]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[Parallel]]></category>
		<category><![CDATA[PostToolUse]]></category>
		<category><![CDATA[SDD]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SlashCommands]]></category>
		<category><![CDATA[SoftwareEngineeringParadigm]]></category>
		<category><![CDATA[SpecDrivenDevelopment]]></category>
		<category><![CDATA[Subagents]]></category>
		<category><![CDATA[workflow]]></category>
		<category><![CDATA[子智能体]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[工作流]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[斜杠指令]]></category>
		<category><![CDATA[权限白名单]]></category>
		<category><![CDATA[自动化]]></category>
		<category><![CDATA[自动化流水线]]></category>
		<category><![CDATA[规约驱动开发]]></category>
		<category><![CDATA[软件工程范式]]></category>
		<category><![CDATA[钩子机制]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5670</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2026/01/05/claude-code-author-reveals-private-ai-coding-config 大家好，我是Tony Bai。 自从 Claude Code 发布以来，我和大家一样，都在探索这个“终端里的 AI 智能体”到底能爆发出多大的能量。 就在昨天，Claude Code 的创造者、Anthropic 的核心工程师 Boris Cherny 在社交媒体上毫无保留地晒出了他自己的 Claude Code Setup（配置与工作流）。 看完他的分享，我最大的感受是：英雄所见略同！ Boris 的很多“私房技巧”，不仅验证了 AI 原生开发的高效性，更令人惊喜的是，其中 80% 的核心实践，竟然都与我的专栏《AI 原生开发工作流实战》中的教学内容完美印证。 今天，我就带大家深度拆解一下这位“Claude Code 之父”的开发心法，结合他晒出的真实配置代码，看看Claude Code作者们都是如何驾驭 AI 的。 心法一：多线程并发 —— 做 AI 的“指挥家” Boris 分享的第一个技巧就非常硬核： “I run 5 Claudes in parallel in my terminal&#8230; I also run 5-10 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2026/claude-code-author-reveals-private-ai-coding-config-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2026/01/05/claude-code-author-reveals-private-ai-coding-config">本文永久链接</a> &#8211; https://tonybai.com/2026/01/05/claude-code-author-reveals-private-ai-coding-config</p>
<p>大家好，我是Tony Bai。</p>
<p>自从 Claude Code 发布以来，我和大家一样，都在探索这个“终端里的 AI 智能体”到底能爆发出多大的能量。</p>
<p>就在昨天，Claude Code 的创造者、Anthropic 的核心工程师 <strong>Boris Cherny</strong> 在社交媒体上毫无保留地<a href="https://x.com/bcherny/status/2007179832300581177">晒出了他自己的 <strong>Claude Code Setup（配置与工作流）</strong></a>。</p>
<p>看完他的分享，我最大的感受是：<strong>英雄所见略同！</strong></p>
<p>Boris 的很多“私房技巧”，不仅验证了 AI 原生开发的高效性，更令人惊喜的是，<strong>其中 80% 的核心实践，竟然都与我的专栏《<a href="http://gk.link/a/12EPd">AI 原生开发工作流实战</a>》中的教学内容完美印证。</strong></p>
<p>今天，我就带大家深度拆解一下这位“Claude Code 之父”的开发心法，结合他晒出的真实配置代码，看看Claude Code作者们都是如何驾驭 AI 的。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/gemini-cli-starting-guide-qr.png" alt="img{512x368}" /></p>
<h2>心法一：多线程并发 —— 做 AI 的“指挥家”</h2>
<p>Boris 分享的第一个技巧就非常硬核：</p>
<blockquote>
<p><strong>“I run 5 Claudes in parallel in my terminal&#8230; I also run 5-10 Claudes on claude.ai/code.”</strong><br />
  （我在终端里并行运行 5 个 Claude&#8230; 同时在网页端也运行 5-10 个。）</p>
</blockquote>
<p>这意味着什么？这意味着他把自己变成了一个“任务调度器”。</p>
<p>这正是我们在专栏 <strong>“<a href="https://time.geekbang.org/column/article/924970">概念篇</a>”</strong> 中反复强调的开发者角色转型：<strong>从“代码的生产者”转变为“工作流的指挥家”</strong>。</p>
<p>在 Boris 的截图中，我们可以清晰地看到他正在运行多个独立的 Session，其中一个正在处理复杂的类型检查和构建任务：</p>
<pre><code class="bash">Bash(bun run typecheck 2&gt;&amp;1 | head -100)
Bash(bun run build:agent-sdk-typings &amp;&amp; tsc ...)
# ... AI 正在自主修复类型错误 ...
</code></pre>
<p>在 AI 原生时代，我们的生产力不再受限于打字速度，而是受限于<strong>并发管理能力</strong>。你可以同时开启多个 Session：1 号 Claude 负责修 Bug，2 号 Claude 负责写测试，3 号 Claude 负责重构。你不再是自己在写代码，你是在指挥一个“虚拟团队”。</p>
<h2>心法二：上下文的艺术 —— 极简主义的 CLAUDE.md</h2>
<p>Boris 也晒出了他的 CLAUDE.md 文件。出乎意料的是，它非常简洁，没有任何冗余的废话。</p>
<p><strong>Boris 的 CLAUDE.md 真实代码：</strong></p>
<pre><code class="markdown"># Development Workflow

**Always use bun, not npm.**

```sh
# 1. Make changes

# 2. Typecheck (fast)
bun run typecheck

# 3. Run tests
bun run test -- -t "test name"  # Single suite
bun run test:file -- "glob"     # Specific files

# 4. Lint before committing
bun run lint:file -- "file1.ts" # Specific files
bun run lint                    # All files

# 5. Before creating PR
bun run lint:claude &amp;&amp; bun run test
</code></pre>
<p>这完美印证了我们在专栏 <strong>第 06 讲《<a href="https://time.geekbang.org/column/article/927870">上下文的艺术（上）：详解CLAUDE.md 与 AGENTS.md</a>》</strong> 中的观点：<strong>CLAUDE.md 是 AI 的操作手册，必须精准、可执行。</strong></p>
<p>注意看他的第一句：<strong>Always use bun, not npm.</strong> —— 这是一个典型的“负向约束”。他在教 AI “做什么”的同时，更明确了“不做什么”，这能极大地减少 AI 犯错的概率。</p>
<h2>心法三：将经验“代码化” —— Slash Commands 与 Sub-agents</h2>
<p>Boris 提到他极度依赖 <strong>Slash Commands（斜杠指令）</strong> 和 <strong>Sub-agents（子智能体）</strong>：</p>
<blockquote>
<p><strong>“I use slash commands for every &#8216;inner loop&#8217; workflow&#8230; This saves me from repeated prompting.”</strong><br />
  （我把所有高频工作流都封装成了 Slash Commands，这让我免于重复写 Prompt。）</p>
</blockquote>
<p>他展示的 .claude/commands/ 目录结构简直就是我们专栏 <strong><a href="https://time.geekbang.org/column/article/928747">第 08 讲 自定义指令：精通Slash Commands，打造你的私人命令集</a></strong> 的最佳教具：</p>
<pre><code class="text">.claude/
  commands/
    build-validator.md   # 专门负责构建验证的指令
    code-architect.md    # 专门负责架构设计的指令
  agents/
    code-simplifier.md   # 一个专门负责简化代码的 Sub-agent
    verify-app.md        # 一个专门负责全链路测试的 Sub-agent
</code></pre>
<p>他把“架构设计”、“代码简化”、“应用验证”这些复杂的脑力劳动，全部封装成了可一键调用的指令和专家分身。<strong>把你的经验变成代码，让 AI 替你执行经验</strong>，这才是高阶玩家的玩法。</p>
<h2>心法四：自动化收尾 —— Hooks 的妙用</h2>
<p>这也是我最喜欢的一部分。Boris 展示了一个非常漂亮的 <strong>PostToolUse Hook</strong> 配置，用来解决代码格式化问题：</p>
<p><strong>Boris 的 settings.json 配置片段：</strong></p>
<pre><code class="json">"PostToolUse": [
  {
    "matcher": "Write|Edit",
    "hooks": [
      {
        "type": "command",
        "command": "bun run format || true"
      }
    ]
  }
]
</code></pre>
<p><strong>这段配置的含义是：</strong> 每当 AI 使用 Write 或 Edit 工具修改了文件后，<strong>立刻、自动</strong>执行 bun run format。</p>
<p>他的逻辑非常清晰：<strong>AI 负责写逻辑，Hook 负责格式化。</strong> AI 生成的代码可能有格式问题，但通过 Hook 自动运行 prettier 或 gofmt，就能解决这“最后的 10%”。</p>
<p>这完全对应了我们专栏 <strong>第 11 讲《<a href="https://time.geekbang.org/column/article/931222">事件驱动：详解Hooks机制，让AI在关键节点自动触发</a>》</strong> 的实战案例。我们当时也演示了如何用 Hook 实现 Go 代码的自动格式化，简直是异曲同工！</p>
<h2>心法五：安全第一 —— 拒绝 YOLO</h2>
<p>最后，Boris 特别展示了他的权限配置搜索界面，并强调：</p>
<blockquote>
<p><strong>“I don&#8217;t use &#8211;dangerously-skip-permissions. Instead, I use /permissions.”</strong><br />
  （我从不使用危险的跳过权限模式，而是使用权限白名单。）</p>
</blockquote>
<p>即使是工具的开发者本人，也对安全保持着绝对的敬畏。他展示的权限白名单列表（Allowlist）非常详细：</p>
<pre><code class="text">Bash(bq query:*)
Bash(bun run build:*)
Bash(bun run lint:*)
Bash(bun run test:*)
...
Bash(cc:*)
Bash(comm:*)
</code></pre>
<p>他宁愿多花点时间把常用的 bun run、bq query 命令一条条加入白名单，也不愿意让 AI 在“裸奔”状态下运行。</p>
<p>这也正是我们在 <strong>第 09 讲《<a href="https://time.geekbang.org/column/article/928995">安全基石（上）：用权限控制与沙箱为AI戴上“安全镣铐”</a>》</strong> 中苦口婆心强调的：<strong>没有安全，就没有生产力。</strong> 盲目追求全自动（YOLO 模式），是在给未来埋雷。</p>
<hr />
<h2>小结：未来已来，你准备好了吗？</h2>
<p>看完 Boris 的分享，我更加确信：<strong>我们正在经历一场软件工程范式的彻底重塑。</strong></p>
<p>Boris Cherny 是这个工具的创造者，他定义了“<strong>上限</strong>”；而我们作为使用者，需要通过系统的学习，去触达这个上限。</p>
<p>如果你也想：</p>
<ul>
<li>像 Boris 一样，构建一套属于自己的 <strong>AI 驾驶舱</strong>；</li>
<li>掌握 <strong>Slash Commands</strong> 和 <strong>Hooks</strong>，让 AI 乖乖听话；</li>
<li>学会 <strong>SDD（规约驱动开发）</strong>，让代码生成一次做对；</li>
<li>搭建 <strong>Headless 自动化流水线</strong>，让 AI 在你睡觉时也能干活&#8230;</li>
</ul>
<p>那么，欢迎加入我的极客时间新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI 原生开发工作流实战</a>》</strong>。</p>
<p>在这门课里，我不只会教你工具的用法，更会带你像 Boris 一样思考——<strong>如何用 AI 重塑你的开发习惯，成为新一代的“AI 架构师”</strong>。</p>
<p><strong>扫描下方二维码，让我们一起，站在巨人的肩膀上，开启 AI 原生开发之旅！</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<p><em>(P.S. 专栏内容偏实战，以 Go 语言项目为例，但方法论通用于所有语言。Claude Code 也是一个刚刚诞生不到一年的新物种，我们都是探索者，期待在课程里与你交流碰撞！)</em></p>
<p>资料链接：https://x.com/bcherny/status/2007179832300581177</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2026, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2026/01/05/httpstonybai-com20260105claude-code-author-reveals-private-ai-coding-config/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go 语言的“反模式”清单：来自资深 Gopher 血泪教训的 10 条“不要做”</title>
		<link>https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts/</link>
		<comments>https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts/#comments</comments>
		<pubDate>Sun, 14 Dec 2025 23:42:30 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AcceptInterfacesReturnStructs]]></category>
		<category><![CDATA[AntiPattern]]></category>
		<category><![CDATA[BestPractice]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[Codereview]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Context]]></category>
		<category><![CDATA[CopyPaste]]></category>
		<category><![CDATA[DependencyManagement]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[OverPackaging]]></category>
		<category><![CDATA[PullRequest]]></category>
		<category><![CDATA[reddit]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[SyncCond]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[YAGNI]]></category>
		<category><![CDATA[代码可读性]]></category>
		<category><![CDATA[依赖倒置]]></category>
		<category><![CDATA[包管理]]></category>
		<category><![CDATA[反模式]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[最佳实践]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[重构]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5538</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts 大家好，我是Tony Bai。 “有哪些‘不要做’的教训，是你花了好几年才学会的？” 近日，在 r/golang 社区，这个简单的问题，引爆了一场关于 Go 语言“反模式”与“最佳实践”的集体反思。帖子下数百条评论，汇集了无数 Gopher 在真实项目中用“血与泪”换来的宝贵经验。这些教训，往往不是关于某个高深的算法，而是关于那些看似“理所当然”，却在不经意间为代码埋下地雷的日常习惯。 这篇文章，正是对这场集体智慧的一次系统性梳理。我们从中提炼出 10 条最核心的“不要做”法则，它们如同一份“避坑指南”，能帮助你绕开那些最常见的陷阱，更快地从一名“会写 Go 的程序员”，成长为一名“懂 Go 的工程师”。 不要过度封装包 Don&#8217;t overpackage things 初学者往往有一种冲动，想把代码组织成“语义化”的、层层嵌套的包结构。internal/models, internal/services, internal/repositories…… 这种源自其他语言（如 Java）的模式，在 Go 的世界里，往往是一种过早的、不必要的复杂性。 社区忠告：从一个 main.go 文件开始。努力思考，是否真的有必要将代码拆分到多个文件/包中。Go 的包，其主要目的是封装和依赖管理，而不是单纯的文件夹分类。在小型或中型项目中，一个清晰的、扁平的包结构，远比一个复杂的“企业级”目录树更易于维护。 不要滥用 channel 和 goroutine Don&#8217;t just add in channels 并发是 Go 的“名片”，这使得许多开发者（尤其是新手）有一种“锤子心态”——看到任何问题，都想用 goroutine 和 channel 来解决。然而，不必要的并发，是复杂性和 bug 的温床。 社区忠告： 先问“是否需要”：你真的需要并发吗？如果不需要在线程间传递消息，你可能根本不需要 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-language-anti-patterns-10-donts-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts">本文永久链接</a> &#8211; https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts</p>
<p>大家好，我是Tony Bai。</p>
<p>“有哪些‘不要做’的教训，是你花了好几年才学会的？”</p>
<p>近日，在 r/golang 社区，这个简单的问题，引爆了一场关于 Go 语言“反模式”与“最佳实践”的<a href="https://www.reddit.com/r/golang/comments/1pib68y/whats_a_dont_do_this_lesson_that_took_you_years/">集体反思</a>。帖子下数百条评论，汇集了无数 Gopher 在真实项目中用“血与泪”换来的宝贵经验。这些教训，往往不是关于某个高深的算法，而是关于那些看似“理所当然”，却在不经意间为代码埋下地雷的日常习惯。</p>
<p>这篇文章，正是对这场集体智慧的一次系统性梳理。我们从中提炼出 10 条最核心的“不要做”法则，它们如同一份“避坑指南”，能帮助你绕开那些最常见的陷阱，更快地从一名“会写 Go 的程序员”，成长为一名“懂 Go 的工程师”。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/api-design-pattern-and-implementation-qr.png" alt="" /></p>
<h2>不要过度封装包</h2>
<p><em>Don&#8217;t overpackage things</em></p>
<p>初学者往往有一种冲动，想把代码组织成“语义化”的、层层嵌套的包结构。internal/models, internal/services, internal/repositories…… 这种源自其他语言（如 Java）的模式，在 Go 的世界里，往往是一种<strong>过早的、不必要的复杂性</strong>。</p>
<p><strong>社区忠告</strong>：从一个 main.go 文件开始。努力思考，是否真的有必要将代码拆分到多个文件/包中。Go 的包，其主要目的是<strong>封装和依赖管理</strong>，而不是单纯的文件夹分类。在小型或中型项目中，一个清晰的、扁平的包结构，远比一个复杂的“企业级”目录树更易于维护。</p>
<h2>不要滥用 channel 和 goroutine</h2>
<p><em>Don&#8217;t just add in channels</em></p>
<p>并发是 Go 的“名片”，这使得许多开发者（尤其是新手）有一种“锤子心态”——看到任何问题，都想用 goroutine 和 channel 来解决。然而，不必要的并发，是复杂性和 bug 的温床。</p>
<p><strong>社区忠告</strong>：</p>
<ul>
<li><strong>先问“是否需要”</strong>：你真的需要并发吗？如果不需要在线程间传递消息，你可能根本不需要 channel。一个简单的 sync.WaitGroup 或 sync.Mutex，在很多场景下都比 channel 更简单、更直接。</li>
<li><strong>并发不是免费的</strong>：Go 让创建 goroutine 变得异常简单，但这并不意味着它是零成本的。过多的 goroutine 会增加调度器的负担，而 channel 的滥用则会使数据流变得难以追踪和调试。</li>
</ul>
<h2>不要盲目追求 DRY</h2>
<p><em>Don&#8217;t be zealous about DRY</em></p>
<p>DRY 是编程的基本原则，但在 Go 的哲学中，它有一个更重要的“上级”——<strong>清晰性</strong>。为了消除几行重复代码，而引入一个复杂的接口或一个晦涩的辅助函数，往往得不偿失。</p>
<p><strong>社区忠告</strong>：“<strong>一点点复制，胜过一点点依赖 (a little copy-paste is better than a little dependency)。</strong>” 当你发现自己在为了 DRY 而绞尽脑汁时，请停下来问问自己：这份重复，是否真的带来了维护上的痛苦？如果不是，那么接受它，可能是一个更明智的选择。</p>
<h2>不要在同一个 PR 中既重构又添加新功能</h2>
<p><em>Don&#8217;t refactor and add features in the same PR</em></p>
<p>在添加一个新功能时，顺手“优化”一下周围的代码，这看起来很高效。但实际上，这会让 Code Review 变得异常痛苦。Reviewer 无法清晰地分辨，哪些改动是为新功能服务的，哪些是纯粹的重构。这不仅增加了审查的难度，也提高了引入新 Bug 的风险。</p>
<p><strong>社区忠告</strong>：遵循“童子军军规”——“让营地比你来时更干净”——是好的。但请将它分解为<strong>两个独立的、目标明确的 PR</strong>：一个只做重构，另一个（基于重构后的代码）只添加新功能。</p>
<h2>不要跳过写测试，“就这一次”</h2>
<p><em>Don&#8217;t skip writing tests “just this once”</em></p>
<p>这是所有开发者都曾屈服过的诱惑。“这个改动太小了”、“我百分之百确定它是对的”、“项目赶时间”…… 每一次“就这一次”的妥协，都在为未来的“技术雪崩”添砖加瓦。</p>
<p><strong>社区忠告</strong>：将测试视为代码不可分割的一部分。在 Go 中，编写测试是如此简单和自然，以至于没有任何借口可以跳过它。你今天节省下来的 10 分钟，可能会在未来，让你或你的同事，花费数天时间去调试一个本可避免的生产问题。</p>
<h2>不要害怕使用 sync.Cond</h2>
<p>channel 非常强大，但它并非解决所有并发同步问题的“银弹”。社区中有一种“反 sync”的情绪，认为所有同步都应该用 channel 来完成。</p>
<p><strong>社区忠告</strong>：sync.Cond 是一个被低估了的、极其强大的并发原语。当你需要<strong>基于某个特定条件来唤醒一个或多个等待的 goroutine</strong> 时（例如，一个任务队列的消费者在队列为空时等待），sync.Cond 往往比用 channel 实现的复杂信令机制，要<strong>更简单、更高效</strong>。不要因为不熟悉，就回避它。</p>
<h2>不要返回接口</h2>
<p><em>Returning interfaces. Don&#8217;t do it.</em></p>
<p>在函数签名中返回一个接口，看似遵循了“依赖倒置”的高级原则，甚至觉得这样更“灵活”。但实际上，这往往是一种<strong>过早的、有害的抽象</strong>。它剥夺了用户访问底层具体类型特有功能的能力，并且如果未来需要添加新方法，接口的变更会极其痛苦。</p>
<p><strong>社区忠告</strong>：遵循 Go 的经典谚语：“<strong>接收接口，返回结构体 (Accept interfaces, return structs)。</strong>”</p>
<ul>
<li><strong>接收接口</strong>：让你的函数接收一个只包含其所需最小方法集的接口作为参数。这使得你的函数更容易被测试和复用（你可以传入任何满足该接口的实现，包括 Mock 对象）。</li>
<li><strong>返回结构体</strong>：让你的函数返回一个具体的类型（通常是指针）。这给了调用者最大的灵活性。</li>
</ul>
<p><strong>经典范例</strong>：</p>
<p>看看标准库中的 os.Open，它返回的是 *os.File（具体结构体），而不是 io.Reader（接口）。<br />
*   <strong>为什么这样做？</strong> 因为 *os.File 不仅能读（Read），还能关闭（Close）、获取状态（Stat）、甚至改变权限（Chmod）。<br />
*   <strong>灵活性</strong>：如果它返回的是接口，用户就无法使用 Chmod 等特有功能了。而返回结构体，用户既可以使用其全部功能，也可以在需要时，轻松地将其赋值给 io.Reader 接口来使用。这就是“返回结构体”带来的自由。</p>
<p><em>(注：只有当返回的类型是包内私有的、不希望外部直接访问的实现细节时，返回接口才是有意义的，例如 context.WithCancel 返回的是 Context 接口。)</em></p>
<h2>不要过度依赖依赖</h2>
<p><em>Don&#8217;t add dependencies without vetting</em></p>
<p>为了解决一个小问题，而引入一个庞大的、闪亮的第三方库。这在 Node.js 生态中很常见，但在 Go 社区，这通常被视为一种“危险信号”。</p>
<p><strong>社区忠告</strong>：</p>
<ul>
<li><strong>先求诸标准库</strong>：在引入任何依赖之前，先问问自己：这个问题，标准库真的解决不了吗？</li>
<li><strong>审慎评估</strong>：如果必须引入依赖，请仔细评估它：它的依赖树有多深？社区是否活跃？维护者是否可靠？一个简单的依赖，可能会为你整个项目，带来潜在的供应链安全风险和维护噩梦。</li>
</ul>
<h2>不要盲从</h2>
<p><em>Don&#8217;t do [or not do] something simply because an authoritative voice recommended it</em></p>
<p>盲目地遵循某个“大神”、某篇“爆款”博客文章、或者某个“权威”推荐的模式，而没有结合自己的具体场景进行批判性思考。</p>
<p><strong>社区忠告</strong>：上下文决定一切。YAGNI (You Aren&#8217;t Gonna Need It) 是一个好原则，但有时你确实需要提前设计。微服务很好，但有时单体就是最佳选择。没有银弹。<strong>最好的实践，是那些在你的团队、你的项目中，被证明行之有效的实践。</strong></p>
<h2>不要忘记，代码是给人读的</h2>
<p>忘记了代码的最终读者是人类，而不是编译器。编写只有自己能看懂的“聪明”代码，或者忽略文档和注释的重要性。</p>
<p><strong>社区忠告</strong>：</p>
<ul>
<li><strong>编写能让你的未来“自已”不会痛骂你的代码。</strong></li>
<li><strong>好的设计不是增加，而是保持本质的简单。代码即是负债 (Code is liability)。</strong></li>
<li><strong>不要忽视清晰文档的重要性。</strong></li>
</ul>
<h2>小结：在“坑”里成长</h2>
<p>这份清单，远非全部。社区的讨论中还充满了诸如“不要用 singleton 来做 mock”、“不要滥用 init 函数”、“不要在疲劳时 Review 代码”等无数宝贵的经验。</p>
<p>它们共同指向了一个核心思想：成为一名优秀的 Go 工程师，其过程不仅仅是学习语言的特性，更是一个不断反思、不断“踩坑”、并从“坑”中总结出属于自己“不要做”清单的修炼过程。希望这份来自社区的集体智慧，能让你在这条路上，走得更稳、也更远。</p>
<p>资料链接：https://www.reddit.com/r/golang/comments/1pib68y/whats_a_dont_do_this_lesson_that_took_you_years/</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/12/15/go-language-anti-patterns-10-donts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>霸榜 GitHub 一周！Google 开源 ADK for Go，彻底终结 AI“炼丹”时代？</title>
		<link>https://tonybai.com/2025/11/24/google-adk-go-in-action/</link>
		<comments>https://tonybai.com/2025/11/24/google-adk-go-in-action/#comments</comments>
		<pubDate>Mon, 24 Nov 2025 00:15:27 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[ADK]]></category>
		<category><![CDATA[ADKforGo]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AgentDevelopmentKit]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ClaudeCode]]></category>
		<category><![CDATA[CodeFirst]]></category>
		<category><![CDATA[Codereview]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Gin]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[gotest]]></category>
		<category><![CDATA[Go代码]]></category>
		<category><![CDATA[gRPC]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Memory]]></category>
		<category><![CDATA[Mock]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[TonyBai]]></category>
		<category><![CDATA[workflowagents]]></category>
		<category><![CDATA[二进制文件]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[付费微专栏]]></category>
		<category><![CDATA[代码优先]]></category>
		<category><![CDATA[公众号]]></category>
		<category><![CDATA[函数]]></category>
		<category><![CDATA[单元测试]]></category>
		<category><![CDATA[可测试]]></category>
		<category><![CDATA[可维护]]></category>
		<category><![CDATA[可部署]]></category>
		<category><![CDATA[咖啡]]></category>
		<category><![CDATA[学伴]]></category>
		<category><![CDATA[工作流指挥家]]></category>
		<category><![CDATA[工作流自动化]]></category>
		<category><![CDATA[工程]]></category>
		<category><![CDATA[工程纪律]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[开发范式]]></category>
		<category><![CDATA[开源]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[思维升级]]></category>
		<category><![CDATA[技能跃迁]]></category>
		<category><![CDATA[探索者]]></category>
		<category><![CDATA[智能体]]></category>
		<category><![CDATA[构建方法论]]></category>
		<category><![CDATA[消息]]></category>
		<category><![CDATA[深度长文]]></category>
		<category><![CDATA[炼丹时代]]></category>
		<category><![CDATA[版本管理]]></category>
		<category><![CDATA[生存指南]]></category>
		<category><![CDATA[短期记忆]]></category>
		<category><![CDATA[航海日志]]></category>
		<category><![CDATA[评估体系]]></category>
		<category><![CDATA[软件工程]]></category>
		<category><![CDATA[长期记忆]]></category>
		<category><![CDATA[霸榜]]></category>
		<category><![CDATA[静态编译]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5431</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/24/google-adk-go-in-action 大家好，我是Tony Bai。 上周，我花了一个下午，仅仅是为了让一个Python写的Agent能稳定地调用我Go服务里的一个简单函数。在那一刻，看着屏幕上纠缠的gRPC、Python虚拟环境和混乱的日志，我脑海里只有一个念头：这不对劲，这绝对不是软件工程该有的样子！ 显然，不仅仅是我一个人在为此焦虑。 就在最近，一个名为 google/adk-go 的项目悄然开源，并迅速霸榜 GitHub Go 语言趋势榜长达一周之久！ 全球的 Gopher 似乎都在用脚投票，表达着同一个渴望：我们受够了“炼丹”，我们要回归工程！ 过去的一年，AI 的浪潮席卷了整个技术圈。我们 Gopher，作为构建云原生世界的中坚力量，看着 Python 社区在 AI 领域“杀”得热火朝天，心中或许都有一个共同的疑问： “这场 AI 的盛宴，我们 Gopher 的主菜在哪儿？” 我们习惯了用 goroutine 优雅地处理并发，用 channel 安全地传递消息，用静态编译的单个二进制文件征服任何服务器。我们是天生的“工程师”，我们信奉的是可测试、可维护、可部署的软件工程哲学。 然而，当我们尝试踏入 AI Agent 的世界时，却常常感觉自己像一个闯入了“炼丹房”的“机械师”。面对那些需要反复“吟唱咒语”（调 Prompt）、结果飘忽不定的“丹炉”（模型），我们不禁会问： 我的 Agent 行为不稳定，怎么写单元测试？ Prompt 稍微一改，整个“丹方”都可能失效，版本管理怎么做？ 我如何将这个“充满魔法”的 Python 脚本，与我现有的 Go 微服务体系优雅地集成，而不是变成一坨无法维护的“耦合怪”？ 这些问题，不是因为我们不懂 AI，而是因为我们太懂工程。我们厌倦了“炼丹”式的不确定性，我们渴望一种能将 AI 的强大能力，用严谨的工程纪律约束起来的解决方案。 现在，Google 亲自下场，为我们递来了“工程图纸”。 Google [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/google-adk-go-in-action-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/24/google-adk-go-in-action">本文永久链接</a> &#8211; https://tonybai.com/2025/11/24/google-adk-go-in-action</p>
<p>大家好，我是Tony Bai。</p>
<p>上周，我花了一个下午，仅仅是为了让一个Python写的Agent能稳定地调用我Go服务里的一个简单函数。在那一刻，看着屏幕上纠缠的gRPC、Python虚拟环境和混乱的日志，我脑海里只有一个念头：这不对劲，这绝对不是软件工程该有的样子！</p>
<p>显然，不仅仅是我一个人在为此焦虑。</p>
<p><strong>就在最近，一个名为 google/adk-go 的项目悄然开源，并迅速霸榜 GitHub Go 语言趋势榜长达一周之久！</strong> 全球的 Gopher 似乎都在用脚投票，表达着同一个渴望：我们受够了“炼丹”，我们要回归工程！</p>
<p>过去的一年，AI 的浪潮席卷了整个技术圈。我们 Gopher，作为构建云原生世界的中坚力量，看着 Python 社区在 AI 领域“杀”得热火朝天，心中或许都有一个共同的疑问：</p>
<p><strong>“这场 AI 的盛宴，我们 Gopher 的主菜在哪儿？”</strong></p>
<p>我们习惯了用 goroutine 优雅地处理并发，用 channel 安全地传递消息，用静态编译的单个二进制文件征服任何服务器。我们是天生的<strong>“工程师”</strong>，我们信奉的是<strong>可测试、可维护、可部署</strong>的软件工程哲学。</p>
<p>然而，当我们尝试踏入 AI Agent 的世界时，却常常感觉自己像一个闯入了“炼丹房”的“机械师”。面对那些需要反复“吟唱咒语”（调 Prompt）、结果飘忽不定的“丹炉”（模型），我们不禁会问：</p>
<ul>
<li><strong>我的 Agent 行为不稳定，怎么写单元测试？</strong></li>
<li><strong>Prompt 稍微一改，整个“丹方”都可能失效，版本管理怎么做？</strong></li>
<li><strong>我如何将这个“充满魔法”的 Python 脚本，与我现有的 Go 微服务体系优雅地集成，而不是变成一坨无法维护的“耦合怪”？</strong></li>
</ul>
<p>这些问题，不是因为我们不懂 AI，而是因为我们太懂<strong>工程</strong>。我们厌倦了“炼丹”式的不确定性，我们渴望一种能将 AI 的强大能力，<strong>用严谨的工程纪律约束起来</strong>的解决方案。</p>
<p><strong>现在，Google 亲自下场，为我们递来了“工程图纸”。</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/google-adk-in-action-qr.png" alt="" /></p>
<h2>Google ADK for Go：写给工程师的 AI Agent 开发框架</h2>
<p>这个霸榜的项目，全称是 <strong><a href="https://github.com/google/adk-go">Agent Development Kit (ADK) for Go</a></strong>。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/google-adk-go-in-action-2.png" alt="" /></p>
<p>这不是又一个“玩具”或“研究性”框架。从它的设计理念中，我看到了一个清晰而坚定的信号——<strong>AI Agent 开发，正在从“炼丹”式的“艺术创作”，全面进入“工程化”的“工业生产”时代。</strong></p>
<p>而 ADK for Go 的核心哲学，与我们 Gopher 的信仰不谋而合，那就是——<strong>代码优先 (Code-First)</strong>。</p>
<ul>
<li><strong>你的 Agent，就是你的 Go 代码：</strong> 不再有晦涩的 YAML，不再有天书般的“链”，Agent 的所有逻辑、决策、工作流，都由你亲手编写的、地地道道的 Go 代码来定义。</li>
<li><strong>天生的可测试性：</strong> 你的 Agent 就是一个实现了 agent.Agent 接口的 struct。这意味着什么？你可以像测试任何 Go 代码一样，go test 走起！Mock 依赖、断言行为，所有你熟悉的工程实践，全部回归。</li>
<li><strong>Git 即版本管理：</strong> Agent 的每一次进化，都是一次清晰的 git commit。Code Review、版本回滚，一切都尽在掌握。</li>
<li><strong>云原生无缝集成：</strong> 它就是一个标准的 Go 模块，可以被无缝地集成到你的 Gin/gRPC 服务中，打包成一个极小的 Docker 镜像，部署到任何 K8s 集群。</li>
</ul>
<p><strong>这就是为什么它能霸榜 GitHub 的原因——它不是在教你如何更好地“调优 Prompt”，而是在教你如何用坚实的工程代码，去彻底终结那个不可控的“炼丹”时代。</strong></p>
<p>Google的adk-go，就是那座连接 Gopher 工程世界与 AI Agent 智能世界的桥梁。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/google-adk-go-in-action-3.png" alt="" /></p>
<h2>和我一起，从零开始“造”一个真正的 AI Agent</h2>
<p>坦白说，ADK for Go 刚刚推出，市面上的教程几乎一片空白。文档虽有，但如何将其与真实的工程场景结合，如何理解其设计背后的权衡，如何避开那些必将遇到的“坑”——这些都需要有人去<strong>探索</strong>，去<strong>趟路</strong>。</p>
<p><strong>所以，我决定做这件事。</strong></p>
<p>我将以一个<strong>“学伴”</strong>和<strong>“探索者”</strong>的身份，推出我的全新付费微专栏：</p>
<p><strong>《Google ADK 实战：用 Go 构建可靠的AI Agent》</strong></p>
<p>在这个专栏里，我不会扮演一个无所不知的专家。相反，我会将我从零开始学习、实践、踩坑、顿悟的全过程，毫无保留地分享给你。</p>
<p>我们将一起，手把手地、<strong>从一个空 main.go 文件开始</strong>，完成一次令人兴奋的创造之旅：</p>
<ul>
<li>
<p><strong>第 1-2 讲：思维转变与灵魂注入</strong><br />
我们将彻底理解“代码优先”的哲学，拆解adk-go，了解其中的概念、架构和核心组件，并亲手定义出第一个实现了 agent.Agent 核心接口的智能体。</p>
</li>
<li>
<p><strong>第 3 讲：为 Agent 插上“手臂”：</strong> 让你的Agent能调用任何Go函数，像操作自己的手脚一样自如<br />
我们将学会 ADK 的“魔法”函数 functiontool.New，将一个普通的 Go 函数，零成本地转化为 Agent 可用的工具。</p>
</li>
<li>
<p><strong>第 4 讲：赋予 Agent “双核记忆”</strong><br />
我们将深入 session（短期记忆）和 memory（长期记忆），让我们的 Agent 能够理解上下文，并记起与你的历史交互。</p>
</li>
<li>
<p><strong>第 5 讲：从“单兵”到“军团”：</strong> 构建一个懂分工、会协作的Agent团队，自动化完成复杂任务<br />
我们将学习 workflowagents，通过编排多个专家 Agent，构建一个强大的“代码生成-审查-重构”自动化流水线。</p>
</li>
<li>
<p><strong>第 6 讲：从“原型”到“产品”</strong><br />
我们将为 Agent 建立科学的<strong>评估体系</strong>，并最终将其打包成 Docker 镜像，部署到通用的 Kubernetes 环境中。</p>
</li>
</ul>
<p>学完这个专栏，你将收获的，不仅是一个能跑起来的酷炫 AI 项目，更是一套<strong>可复用的、工程化的 AI Agent 构建方法论</strong>，以及在 AI 新浪潮中，属于我们 Gopher 的那份自信和底气。</p>
<h2>加入这场 Gopher 的 AI 工程化之旅</h2>
<p>这个微专栏，是我为你，也为我自己准备的一份“AI 时代 Gopher 生存指南”。它凝聚了我对 Go 工程哲学的理解，和我对 AI Agent 未来的全部热情。</p>
<p>微专栏共 <strong>6 篇深度长文</strong>，每一篇都是我亲手实践、细节满满的 step-by-step “航海日志”。</p>
<p>我没有设定一个高昂的价格，而是希望与更多志同道合的 Gopher 一起探索。所以，订阅这份专栏，<strong>仅需你一杯咖啡的诚意</strong>。</p>
<p>花一杯咖啡的时间，你或许能得到片刻的清醒；而用同样的价格投入到这里，我希望能为你带来一次<strong>思维的升级</strong>和<strong>技能的跃迁</strong>。</p>
<p><strong>点击<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4266729696274251779#wechat_redirect">这里</a>，或扫描二维码，立即加入。</strong></p>
<p><strong>让我们一起，用代码，构建智能。</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/google-adk-in-action-qr.png" alt="" /></p>
<p><strong>P.S.</strong> 如果你对 AI Agent、Go 语言或者这个微专栏有任何问题，欢迎在评论区留言，我们一起交流探讨！</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/11/24/google-adk-go-in-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为什么 Go 在悄悄地做 Rust 做不到的事：保持简单</title>
		<link>https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple/</link>
		<comments>https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple/#comments</comments>
		<pubDate>Fri, 21 Nov 2025 00:29:50 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[build.rs]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cargo]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[crates]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[monad]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[slack]]></category>
		<category><![CDATA[Swiggy]]></category>
		<category><![CDATA[SystemProgramming]]></category>
		<category><![CDATA[TonyBai]]></category>
		<category><![CDATA[Zig]]></category>
		<category><![CDATA[二进制简洁性]]></category>
		<category><![CDATA[借用检查器]]></category>
		<category><![CDATA[内存安全]]></category>
		<category><![CDATA[团队]]></category>
		<category><![CDATA[复杂性]]></category>
		<category><![CDATA[安全性]]></category>
		<category><![CDATA[工程化实践]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[所有权]]></category>
		<category><![CDATA[抽象]]></category>
		<category><![CDATA[显式优于隐式]]></category>
		<category><![CDATA[权力]]></category>
		<category><![CDATA[构建系统]]></category>
		<category><![CDATA[清晰]]></category>
		<category><![CDATA[炒作]]></category>
		<category><![CDATA[生产环境]]></category>
		<category><![CDATA[知识体系]]></category>
		<category><![CDATA[确定性构建系统]]></category>
		<category><![CDATA[简单]]></category>
		<category><![CDATA[系统编程]]></category>
		<category><![CDATA[编译速度]]></category>
		<category><![CDATA[舒适]]></category>
		<category><![CDATA[认知税]]></category>
		<category><![CDATA[设计哲学]]></category>
		<category><![CDATA[软件设计]]></category>
		<category><![CDATA[重构]]></category>
		<category><![CDATA[错误处理]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5418</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple 大家好，我是Tony Bai。 近日，一篇题为《为什么 Zig 在悄悄地做 Rust 做不到的事：保持简单》的文章在开发者社区引发了热议。文章以其辛辣、富有煽动性的文风，将 Zig 描绘成 Rust 复杂性的“解毒剂”，是“一个终于接受了心理治疗的 C 项目”，并引发了关于“简单性”与“安全性”的深刻辩论。 这不禁让我们——作为 Go 社区的观察者——产生了一个有趣的想法：如果我们将文中的主角 Zig，完全替换为 Go，这篇文章的论点是否依然成立？ Go 语言，在其诞生之初，同样被视为对 C++ 等语言复杂性的“反叛”。它与 Zig 在追求编译速度、二进制简洁性以及“显式优于隐式”的哲学上，有着惊人的相似之处。 于是，我们进行了一次大胆的“思想实验”：在保留原文犀利风格和核心论证结构的前提下，将所有关于 Zig 的部分都替换为 Go，并将代码示例“翻译”为地道的 Go 代码。 这并非意在挑起 Go 与 Rust 之间的“战争”，而是希望通过这样一次“角色扮演”，从一个全新的、极具张力的视角，来重新审视 Go 语言的设计哲学，以及它在现代编程语言光谱中所占据的那个独特、宝贵且时常被误解的位置。 以下，便是这次思想实验的成果。各位小伙伴儿品一品，这样替换后，是不是不仅完美地道出了 Go 在“简单”与“显式”上的坚持，更说出了许多 Gopher 心里想说，却又不好意思直接对 Rust 爱好者说出口的‘真心话’？ Rust 对安全性大声疾呼。Go 只是把它构建了进去——没有那些仪式感、没有那些说教、也没有那 15 分钟的编译时间。 引子 我第一次写 Go [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/why-go-is-quietly-doing-what-rust-couldnt-staying-simple-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple">本文永久链接</a> &#8211; https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple</p>
<p>大家好，我是Tony Bai。</p>
<p>近日，一篇题为《<a href="https://freedium-mirror.cfd/@daxx5/why-zig-is-quietly-doing-what-rust-couldnt-staying-simple-a47f86b3a58a">为什么 Zig 在悄悄地做 Rust 做不到的事：保持简单</a>》的文章在开发者社区引发了热议。文章以其辛辣、富有煽动性的文风，将 Zig 描绘成 Rust 复杂性的“解毒剂”，是“一个终于接受了心理治疗的 C 项目”，并引发了关于“简单性”与“安全性”的深刻辩论。</p>
<p>这不禁让我们——作为 Go 社区的观察者——产生了一个有趣的想法：<strong>如果我们将文中的主角 Zig，完全替换为 Go，这篇文章的论点是否依然成立？</strong></p>
<p>Go 语言，在其诞生之初，同样被视为对 C++ 等语言复杂性的“反叛”。它与 Zig 在追求编译速度、二进制简洁性以及“显式优于隐式”的哲学上，有着惊人的相似之处。</p>
<p>于是，我们进行了一次大胆的“思想实验”：在保留原文犀利风格和核心论证结构的前提下，将所有关于 Zig 的部分都替换为 Go，并将代码示例“翻译”为地道的 Go 代码。</p>
<p>这并非意在挑起 Go 与 Rust 之间的“战争”，而是希望通过这样一次“角色扮演”，从一个全新的、极具张力的视角，来重新审视 Go 语言的设计哲学，以及它在现代编程语言光谱中所占据的那个独特、宝贵且时常被误解的位置。</p>
<p>以下，便是这次思想实验的成果。各位小伙伴儿品一品，这样替换后，是不是不仅完美地道出了 Go 在“简单”与“显式”上的坚持，<strong>更说出了许多 Gopher 心里想说，却又不好意思直接对 Rust 爱好者说出口的‘真心话’？</strong></p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-testing-journey-qr.png" alt="" /></p>
<hr />
<p>Rust 对安全性大声疾呼。Go 只是把它构建了进去——没有那些仪式感、没有那些说教、也没有那 15 分钟的编译时间。</p>
<h2>引子</h2>
<p>我第一次写 Go 代码的时候，忍不住笑出声来。不是因为它好笑——而是因为我不敢相信，在现代编程世界里，还存在着如此……<strong>安静</strong>的东西。</p>
<p>在与 Rust “搏斗”多年之后——那门承诺将我们从 C 的苦海中拯救出来，却不知怎的变成了一场性格测试的语言——Go 感觉就像是 Rust 霓虹闪烁的都市中心里，一间温暖、极简的小木屋。</p>
<p>而这，正是关键所在。</p>
<p>Go 并非试图成为未来。它只是想保持理智。</p>
<hr />
<h2>Rust 承诺了天堂，却给了我们一堆文书工作</h2>
<p>还记得那股炒作的热潮吗？Rust 是“C 语言杀手”，是内存安全的“弥赛亚”，是<a href="https://tonybai.com/2025/09/01/system-programming-in-go">系统编程</a>的“救世主”。</p>
<p>平心而论，Rust 确实……算是兑现了。你可以写出快如闪电的安全代码——<strong>在你向借用检查器献祭了三只山羊和整个周末的心智健全之后</strong>。</p>
<p>你看着这样的代码：</p>
<pre><code class="rust">// Rust
fn main() {
    let mut data = vec![1, 2, 3];
    let ref1 = &amp;data;
    data.push(4); // 借用检查器：“凡人，你不能这么做。”
    println!("{:?}", ref1);
}
</code></pre>
<p>你会想，<strong>为什么？为什么我的编译器听起来像我的前任在解释情感边界？</strong></p>
<p>Rust 像一个严厉的治疗师一样教你所有权。而 Go 呢，只是耸耸肩说：<strong>“你搞坏了，你修好它。”</strong></p>
<p>这就是哲学的分水岭。<strong>Rust 假设你不可信。Go 假设你是个成年人。</strong></p>
<p>Rust 的才华毋庸置疑——安全、并发、无畏的重构。但它也……让人筋疲力尽。那些仪式感。那些工具链。那种将过度工程伪装成纯粹性的文化。</p>
<p>而 Go 呢，穿着连帽衫，拿着半个三明治出现，说：“嘿，想不想直接把该死的二进制文件构建出来？”</p>
<hr />
<h2>无聊之美</h2>
<p>这是大多数人忽略的一点：<strong>简单不是一个特性。它是一种反叛。</strong></p>
<p>Go 看起来很无聊。感觉也很无聊。读起来就像一个终于接受了心理治疗的 C 项目。</p>
<pre><code class="go">// Go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
</code></pre>
<p>就是这样。没有宏。没有 build.rs。没有 Cargo 尖叫着说哪个 crate 过期了。</p>
<p><strong>仅仅。一个。编译器。</strong></p>
<p>其底层呢？一个能让你团队喜极而泣的设计：</p>
<ul>
<li><strong>没有隐藏的控制流。</strong></li>
<li><strong>没有未定义行为。</strong></li>
<li>** 没有运行时的“惊吓” (No runtime surprises)**。（即，没有像 JIT 或复杂后台进程那样，会产生不可预测行为的“魔法”运行时）</li>
<li><strong>一个像钟表一样精确工作的确定性构建系统。</strong></li>
</ul>
<p>你可以去读 Go 编译器的源码，并且<strong>真的能读懂它</strong>。你去试试读 Rust 的编译器源码，那你需要咖啡因、心理治疗和一个祈祷小组。</p>
<p>Go 不性感。它很实用。它是那种你会忘记你正在使用的语言——而这，是最高的赞美。</p>
<hr />
<h2>Rust 扩展了代码库，Go 扩展了人类</h2>
<p>说实话吧——Rust 最大的优点也是它最大的诅咒：<strong>它迫使你思考。不停地思考。</strong></p>
<p>每一行代码都是一场关于生命周期、可变性和宇宙正义的哲学辩论。</p>
<p>Go 呢？Go 就像是说：“嘿，这是内存。别把自己捅了就行。” (笔者注：Go是GC语言，这句直接替换zig后的表达可能不是很契合)</p>
<p>这很重要。尤其是在团队中。</p>
<p>Rust 感觉像学术界——人们在 Slack 上辩论着 monad，而功能的截止日期却在悄悄溜走。Go 感觉像那个穿着脏兮兮运动鞋、代码却能跑起来的初创公司工程师。</p>
<p>在 Swiggy 这样的规模下，<strong>Go 取代了 Java 后端，因为它扩展了开发团队</strong>。Go 也许正在悄悄地为系统编程做同样的事情——不是因为它“更好”，而是因为它<strong>更人性化</strong>。 (笔者注：由于有特定背景局限，这里将zig替换为Go后可能也不是很契合了)</p>
<p>你不需要一块精神白板来在脑中记住 12 条借用规则。你只需要……写。</p>
<hr />
<h2>讽刺的转折：Go 才是 Rust 假装要成为的样子</h2>
<p>Rust 将自己营销为“安全的系统编程”。但它实际上是——一个<strong>系统框架</strong>。</p>
<p>Cargo、crates、宏、过程魔法——这是一个生态系统，而不是一门语言。华丽，但沉重。</p>
<p>Go 把所有这些都剥离了。</p>
<p>没有依赖爆炸。没有语言版本混乱。没有每夜构建的轮盘赌。</p>
<p>最关键的是——Go 的构建系统是如此集成，如此具有确定性，以至于整个 CI/CD 的设置都感觉更清爽了。</p>
<p><strong>Rust 像一座现代大教堂一样构建。Go 像一条工具腰带一样构建。</strong></p>
<blockquote>
<p>“Go 不试图保护你。它试图赋予你力量。”</p>
</blockquote>
<p>这就是那场安静的反叛。Go 相信你知道自己在做什么——它只给你足够的绳子让你把事情绑在一起，而不是让你上吊。</p>
<p>而讽刺的是什么？Go 中那些“不安全”的部分，在实践中往往最终更安全，因为<strong>你能看到一切</strong>。没有魔法。没有语法糖。只有原始的意图。</p>
<hr />
<h2>当炒作退去，简单性胜出</h2>
<p>每个技术周期都以同样的方式结束。</p>
<p>炒作机器火力全开。Medium 上的文章成倍增加。Meme 如潮水般涌来。然后有一天——凌晨两点，生产环境着火了，你只想知道为什么该死的二进制文件崩溃了。</p>
<p><strong>Rust 给了你安全。但 Go 给了你清晰。</strong></p>
<pre><code class="go">// Go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Create("output.txt")
    if err != nil {
        // 你能清晰地看到错误处理
        panic(err)
    }
    defer file.Close()

    _, err = file.WriteString("Explicit is better than implicit.")
    if err != nil {
        panic(err)
    }
}
</code></pre>
<p>你简直可以追踪到每一个字节。没有隐藏的分配器。没有神秘之处。</p>
<p>这正是老派 C 开发者所怀念的那种控制感——但现代开发者却忘记了自己也需要这种感觉。</p>
<h2>这场安静革命的教训</h2>
<ul>
<li><strong>简单是一种权力</strong>。你的语言越可预测，你付出的认知税就越少。</li>
<li><strong>安全不是舒适</strong>。Rust 让你感到安全，但筋疲力尽。Go 让你感到暴露，但一切尽在掌握。</li>
<li><strong>你不需要另一个抽象。你需要更少的抽象。</strong></li>
<li><strong>有时，无聊会赢</strong>。因为无聊的东西能扩展、能调试、能交付。</li>
</ul>
<h2>最后的思考</h2>
<p>Rust 将继续演进。它配得上它的王座。但在某个地方，有一支小团队正在用 Go 构建——没有炒作，没有技术大会演讲，没有花哨的市场营销。</p>
<p>只是在悄悄地编写着那些永不崩溃、编译只需几秒、在生产环境中如幽灵般运行的干净的二进制文件。</p>
<p>这就是没人预见到的转折。Go 并非在与 Rust 的未来竞争。它在复活编程的过去——我们早已遗忘的那些美好部分。</p>
<p>而且，也许，仅仅是也许，这就是它最终获胜的方式。</p>
<p>资料链接：https://freedium-mirror.cfd/@daxx5/why-zig-is-quietly-doing-what-rust-couldnt-staying-simple-a47f86b3a58a</p>
<hr />
<p>还在为“复制粘贴喂AI”而烦恼？我的新专栏 <strong>《<a href="http://gk.link/a/12EPd">AI原生开发工作流实战</a>》</strong> 将带你：</p>
<ul>
<li>告别低效，重塑开发范式</li>
<li>驾驭AI Agent(Claude Code)，实现工作流自动化</li>
<li>从“AI使用者”进化为规范驱动开发的“工作流指挥家”</li>
</ul>
<p>扫描下方二维码，开启你的AI原生开发之旅。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/ai-native-dev-workflow-qr.png" alt="" /></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/11/21/why-go-is-quietly-doing-what-rust-couldnt-staying-simple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go 的甜蜜16 岁：一份来自官方的年度成绩单与未来路线图</title>
		<link>https://tonybai.com/2025/11/15/go-turns-16/</link>
		<comments>https://tonybai.com/2025/11/15/go-turns-16/#comments</comments>
		<pubDate>Sat, 15 Nov 2025 00:38:33 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[ADKGo]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AgentDevelopmentKit]]></category>
		<category><![CDATA[AIassistant]]></category>
		<category><![CDATA[AIcodingassistants]]></category>
		<category><![CDATA[AI助手]]></category>
		<category><![CDATA[AI时代]]></category>
		<category><![CDATA[AI编码助手]]></category>
		<category><![CDATA[AI集成]]></category>
		<category><![CDATA[Anthropic]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[AustinClements]]></category>
		<category><![CDATA[AVX-512vectorinstructions]]></category>
		<category><![CDATA[CAVP]]></category>
		<category><![CDATA[codemodernizationtools]]></category>
		<category><![CDATA[compatibilitypromise]]></category>
		<category><![CDATA[containerawarescheduling]]></category>
		<category><![CDATA[CPUthrottling]]></category>
		<category><![CDATA[CPU节流]]></category>
		<category><![CDATA[encoding/json]]></category>
		<category><![CDATA[executiontracer]]></category>
		<category><![CDATA[FIPS]]></category>
		<category><![CDATA[FIPS140-3]]></category>
		<category><![CDATA[FIPS140compliance]]></category>
		<category><![CDATA[FIPS140合规性]]></category>
		<category><![CDATA[FIPS认证]]></category>
		<category><![CDATA[FlightRecorder]]></category>
		<category><![CDATA[Geomys]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.0]]></category>
		<category><![CDATA[Go1.0之前的根源]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[go1.25]]></category>
		<category><![CDATA[go1.26]]></category>
		<category><![CDATA[GoCommunity]]></category>
		<category><![CDATA[gofix]]></category>
		<category><![CDATA[gofix命令]]></category>
		<category><![CDATA[GoLanguageAdvancedCourse]]></category>
		<category><![CDATA[Golanguageentryleveltreasure]]></category>
		<category><![CDATA[Golanguagefirstlesson]]></category>
		<category><![CDATA[GoMCPSDK]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Goopensourceproject]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[goplsfeaturedocumentation]]></category>
		<category><![CDATA[goplsfeatures]]></category>
		<category><![CDATA[goplslanguageserver]]></category>
		<category><![CDATA[goprimer]]></category>
		<category><![CDATA[goroutineleakanalysis]]></category>
		<category><![CDATA[GoTeam]]></category>
		<category><![CDATA[Go专家]]></category>
		<category><![CDATA[Go代码]]></category>
		<category><![CDATA[Go开源项目]]></category>
		<category><![CDATA[Go熟练工]]></category>
		<category><![CDATA[greentea]]></category>
		<category><![CDATA[GreenTeaGC]]></category>
		<category><![CDATA[HashTable]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JoeTsai]]></category>
		<category><![CDATA[KnowledgePlanet]]></category>
		<category><![CDATA[LSP]]></category>
		<category><![CDATA[LSPbasededitors]]></category>
		<category><![CDATA[mapimplementation]]></category>
		<category><![CDATA[map实现]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[MCPserver]]></category>
		<category><![CDATA[ModelContextProtocol]]></category>
		<category><![CDATA[ModelContextProtocolMCP]]></category>
		<category><![CDATA[net/http]]></category>
		<category><![CDATA[officialGoSDK]]></category>
		<category><![CDATA[osRoot]]></category>
		<category><![CDATA[SIMD]]></category>
		<category><![CDATA[SIMDhardwarecapabilities]]></category>
		<category><![CDATA[staticanalysistools]]></category>
		<category><![CDATA[synctest]]></category>
		<category><![CDATA[testing/synctest]]></category>
		<category><![CDATA[testingBLoop]]></category>
		<category><![CDATA[testingBN]]></category>
		<category><![CDATA[testingTContext]]></category>
		<category><![CDATA[testingTOutput]]></category>
		<category><![CDATA[TonyBaiGolanguageadvancedcourse]]></category>
		<category><![CDATA[TrailofBits]]></category>
		<category><![CDATA[traversalresistantfilesystemaccess]]></category>
		<category><![CDATA[uber]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[v0.17.0]]></category>
		<category><![CDATA[v0.18.0]]></category>
		<category><![CDATA[v0.19.0]]></category>
		<category><![CDATA[v0.20.0]]></category>
		<category><![CDATA[v1.0.0]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[WeChatQR]]></category>
		<category><![CDATA[健壮可靠软件]]></category>
		<category><![CDATA[兼容性承诺]]></category>
		<category><![CDATA[内存节省]]></category>
		<category><![CDATA[分析器]]></category>
		<category><![CDATA[功能]]></category>
		<category><![CDATA[功能性]]></category>
		<category><![CDATA[单指令多数据]]></category>
		<category><![CDATA[原生加密包]]></category>
		<category><![CDATA[发布节奏]]></category>
		<category><![CDATA[发布速度]]></category>
		<category><![CDATA[可靠性]]></category>
		<category><![CDATA[合规性]]></category>
		<category><![CDATA[向量指令]]></category>
		<category><![CDATA[哈希表]]></category>
		<category><![CDATA[垃圾回收器]]></category>
		<category><![CDATA[垃圾回收开销]]></category>
		<category><![CDATA[基准测试]]></category>
		<category><![CDATA[基础包]]></category>
		<category><![CDATA[基础设施]]></category>
		<category><![CDATA[多智能体应用程序]]></category>
		<category><![CDATA[大规模多核硬件]]></category>
		<category><![CDATA[安全体系]]></category>
		<category><![CDATA[安全审计]]></category>
		<category><![CDATA[安全软件开发]]></category>
		<category><![CDATA[官方GoSDK]]></category>
		<category><![CDATA[容器化技术]]></category>
		<category><![CDATA[容器感知调度]]></category>
		<category><![CDATA[尾部延迟]]></category>
		<category><![CDATA[工具链]]></category>
		<category><![CDATA[年度成绩单]]></category>
		<category><![CDATA[年度报告]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[并发异步代码]]></category>
		<category><![CDATA[并行度]]></category>
		<category><![CDATA[底层改进]]></category>
		<category><![CDATA[开发流程]]></category>
		<category><![CDATA[开发者体验]]></category>
		<category><![CDATA[开发者生产力]]></category>
		<category><![CDATA[开源发布]]></category>
		<category><![CDATA[开源智能体生态系统]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[战略简报]]></category>
		<category><![CDATA[执行追踪器]]></category>
		<category><![CDATA[技术负责人]]></category>
		<category><![CDATA[抗遍历的文件系统访问]]></category>
		<category><![CDATA[改进]]></category>
		<category><![CDATA[新惯用法]]></category>
		<category><![CDATA[旧惯用法]]></category>
		<category><![CDATA[智能体应用程序]]></category>
		<category><![CDATA[未来路线图]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[核心语言]]></category>
		<category><![CDATA[核心语言和库]]></category>
		<category><![CDATA[模型上下文协议]]></category>
		<category><![CDATA[泄露goroutine分析]]></category>
		<category><![CDATA[漏洞]]></category>
		<category><![CDATA[生产效率]]></category>
		<category><![CDATA[生产栈库]]></category>
		<category><![CDATA[生产系统]]></category>
		<category><![CDATA[生产级AI开发]]></category>
		<category><![CDATA[生成式AI]]></category>
		<category><![CDATA[用户群]]></category>
		<category><![CDATA[硬件]]></category>
		<category><![CDATA[硬件功能]]></category>
		<category><![CDATA[编码标准]]></category>
		<category><![CDATA[网络服务]]></category>
		<category><![CDATA[自动代码现代化工具]]></category>
		<category><![CDATA[藏宝图]]></category>
		<category><![CDATA[虚拟化时间]]></category>
		<category><![CDATA[设计安全]]></category>
		<category><![CDATA[设计空间]]></category>
		<category><![CDATA[诊断工具]]></category>
		<category><![CDATA[语言服务器]]></category>
		<category><![CDATA[贡献者社区]]></category>
		<category><![CDATA[软件开发栈]]></category>
		<category><![CDATA[软件开发集成方法]]></category>
		<category><![CDATA[软件行业]]></category>
		<category><![CDATA[运行时]]></category>
		<category><![CDATA[重构]]></category>
		<category><![CDATA[静态分析工具]]></category>
		<category><![CDATA[飞行记录器]]></category>
		<category><![CDATA[默认安全]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5390</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/15/go-turns-16 大家好，我是Tony Bai。 今年的 Go 官方16岁“庆生”文章，来得比以往时候都要晚一些。 往年，我们总能在 11 月 10 日或 11 日，准时收到这份来自 Go 团队的年度“家庭来信”。但今年，日历翻过了好几天，官方博客却依旧静悄悄。前几天，我还在知识星球上和星友们“抱怨”：“今年 Go 官方居然没有发 16 周年庆生纪念文章，比较反常啊！是忙忘了？还是没人有空写？” 现在回头看，这份“迟到”的生日礼物，或许恰恰反映了 Go 团队当前的状态。与其说是“忙忘了”，我更倾向于相信，这是新任技术负责人 Austin Clements 那种众所周知的严谨风格的体现——在没有将过去一年的所有重要进展都梳理清晰、打磨完美之前，宁愿延迟，也绝不仓促发文。抑或是，随着 Go 在 AI 时代的责任日益重大，团队的每一个字，都变得更加审慎和深思熟虑。 那么，这份姗姗来迟的“年度报告”，又为何值得我们全文翻译，并分享给大家呢？ 因为这不仅仅是一篇生日贺文，它更是一份极其珍贵的、信息密度极高的官方“战略简报”。 在这篇文章里，Go 团队不仅系统性地盘点了过去一年中，从核心语言、安全体系到工具链的所有重大成果（synctest, Green Tea GC, FIPS 认证, go fix&#8230;），更重要的是，它首次清晰地、成体系地阐述了 Go 在 AI 时代的定位与雄心。它告诉我们，Go 团队正在如何将 Go 语言独特的并发、性能和可靠性优势，注入到 AI 集成、Agent 和基础设施的构建中。 对于我们每一位 Gopher 而言，这篇文章就是一张官方的“藏宝图”。它不仅能帮助我们快速跟上 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/go-turns-16-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/15/go-turns-16">本文永久链接</a> &#8211; https://tonybai.com/2025/11/15/go-turns-16</p>
<p>大家好，我是Tony Bai。</p>
<p>今年的 Go 官方16岁“庆生”文章，来得比以往时候都要晚一些。</p>
<p>往年，我们总能在 11 月 10 日或 11 日，准时收到这份来自 Go 团队的年度“家庭来信”。但今年，日历翻过了好几天，官方博客却依旧静悄悄。前几天，我还在<a href="https://public.zsxq.com/groups/51284458844544">知识星球</a>上和星友们“抱怨”：“今年 Go 官方居然没有发 16 周年庆生纪念文章，比较反常啊！是忙忘了？还是没人有空写？”</p>
<p>现在回头看，这份“迟到”的生日礼物，或许恰恰反映了 Go 团队当前的状态。与其说是“忙忘了”，我更倾向于相信，这是新任技术负责人 Austin Clements 那种众所周知的严谨风格的体现——<strong>在没有将过去一年的所有重要进展都梳理清晰、打磨完美之前，宁愿延迟，也绝不仓促发文</strong>。抑或是，随着 Go 在 AI 时代的责任日益重大，团队的每一个字，都变得更加审慎和深思熟虑。</p>
<p>那么，这份姗姗来迟的“年度报告”，又为何值得我们全文翻译，并分享给大家呢？</p>
<p><strong>因为这不仅仅是一篇生日贺文，它更是一份极其珍贵的、信息密度极高的官方“战略简报”。</strong></p>
<p>在这篇文章里，Go 团队不仅系统性地盘点了过去一年中，从核心语言、安全体系到工具链的<strong>所有重大成果</strong>（synctest, Green Tea GC, FIPS 认证, go fix&#8230;），更重要的是，它<strong>首次清晰地、成体系地阐述了 Go 在 AI 时代的定位与雄心</strong>。它告诉我们，Go 团队正在如何将 Go 语言独特的并发、性能和可靠性优势，注入到 AI 集成、Agent 和基础设施的构建中。</p>
<p>对于我们每一位 Gopher 而言，这篇文章就是一张<strong>官方的“藏宝图”</strong>。它不仅能帮助我们快速跟上 Go 的最新动态，更能让我们洞察这门语言未来的发展方向，从而在技术浪潮中，做出更明智的学习和职业决策。</p>
<p>下面，就让我们一同深入这份迟到但分量十足的“生日礼物”。以下是文章全文。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-micro-column-2025-pr.png" alt="" /></p>
<hr />
<p>刚刚过去的周一，11 月 10 日，我们庆祝了 Go <a href="https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html">开源发布</a> 16 周年！</p>
<p>我们遵循了现在已经非常成熟和可靠的发布节奏，在<a href="https://tonybai.com/2025/02/16/some-changes-in-go-1-24">二月份发布了 Go 1.24</a>，并在<a href="https://tonybai.com/2025/08/15/some-changes-in-go-1-25">八月份发布了 Go 1.25</a>。为了继续我们构建最高效的生产系统语言平台的使命，这些版本包含了用于构建健壮可靠软件的新 API，在 Go 构建安全软件的记录上取得了显著进展，以及一些重要的底层改进。与此同时，没有人能忽视生成式 AI 给我们行业带来的巨大变革。Go 团队正以深思熟虑且毫不妥协的思维方式应对这一充满活力的领域中的挑战和机遇，致力于将 Go 的生产就绪方法应用于构建健壮的 AI 集成、产品、智能体和基础设施。</p>
<h2>核心语言和库的改进</h2>
<p>新的 <a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4017357519222882315#wechat_redirect">testing/synctest</a> 包在 Go 1.24 中作为实验性功能首次发布，然后在 Go 1.25 中正式毕业，它极大地简化了为<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIyNzM0MDk0Mg==&amp;action=getalbum&amp;album_id=4017357519222882315#wechat_redirect">并发、异步代码</a>编写测试的过程。这类代码在网络服务中尤为常见，并且传统上很难进行良好的测试。<a href="https://tonybai.com/2025/09/29/synctest-bugs-in-go-1-25/">synctest 包</a>通过虚拟化时间本身来工作。它将过去缓慢、不稳定或两者兼有的测试，转变为易于重写成可靠且几乎瞬时完成的测试，通常只需增加几行代码。这也是 Go 软件开发集成方法的一个绝佳例子：在一个几乎微不足道的 API 背后，synctest 包隐藏了与 Go 运行时和标准库其他部分的深度集成。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-concurrent-test-qr.png" alt="img{512x368}" /></p>
<p>这并非过去一年中 testing 包得到的唯一增强。新的 <a href="https://pkg.go.dev/testing#B.Loop">testing.B.Loop</a> API 不仅比原来的 testing.B.N API 更易于使用，还解决了编写 Go 基准测试时许多传统的——且常常是不可见的！——<a href="https://go.dev/blog/testing-b-loop">陷阱</a>。testing 包还新增了 API，可以<a href="https://pkg.go.dev/testing#T.Context">轻松地在使用 Context 的测试中进行清理</a>，以及<a href="https://pkg.go.dev/testing#T.Output">轻松地向测试日志写入内容</a>。</p>
<p>Go 和容器化技术一同成长，并彼此配合得很好。Go 1.25 推出了<a href="https://tonybai.com/2025/04/09/gomaxprocs-defaults-add-cgroup-aware">容器感知调度</a>，使这对组合更加强大。开发者无需任何操作，它就能透明地调整在容器中运行的 Go 工作负载的并行度，防止可能影响尾部延迟的 CPU 节流，并提升了 Go 开箱即用的生产就绪性。</p>
<p>Go 1.25 的新<a href="https://tonybai.com/2025/07/11/net-http-pprof-v2/">飞行记录器(flight recorder)</a>建立在我们本已强大的执行追踪器之上，能够深入洞察生产系统的动态行为。执行追踪器通常会收集过多的信息，在长期运行的生产服务中不太实用，而飞行记录器则像一个小小的时光机，允许服务在出现问题之后，以极高的细节快照最近发生的事件。</p>
<h2>安全软件开发</h2>
<p>Go 继续加强其对安全软件开发的承诺，在其<a href="https://tonybai.com/2024/10/19/go-crypto-package-design-deep-dive">原生加密包</a>方面取得了重大进展，并演进其标准库以增强安全性。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/go-crypto-101-qr.png" alt="img{512x368}" /></p>
<p>Go 在标准库中附带了一整套原生加密包，这些包在过去一年中达到了两个重要的里程碑。由独立安全公司 <a href="https://www.trailofbits.com/">Trail of Bits</a> 进行的安全审计取得了<a href="https://tonybai.com/2025/05/21/go-crypto-audit">优异的结果</a>，仅有一个低严重性的发现。此外，通过 Go 安全团队与 <a href="https://geomys.org/">Geomys</a> 的合作，这些包获得了 CAVP 认证，为<a href="https://tonybai.com/2024/11/16/go-crypto-and-fips-140">完整的 FIPS 140-3 认证</a>铺平了道路。这对于在某些受监管环境中的 Go 用户来说是一项至关重要的进展。FIPS 140 合规性，以往由于需要使用不受支持的解决方案而成为一个摩擦点，现在将被无缝集成，解决了与安全性、开发者体验、功能性、发布速度和合规性相关的问题。</p>
<p>Go 标准库持续演进，以实现默认安全和设计安全。例如，Go 1.24 中添加的 <a href="https://pkg.go.dev/os#Root">os.Root</a> API 实现了<a href="https://go.dev/blog/osroot">抗遍历的文件系统访问</a>，有效地对抗了一类漏洞，即攻击者可能操纵程序访问本应不可访问的文件。这类漏洞在没有底层平台和操作系统支持的情况下极具挑战性，而新的 <a href="https://pkg.go.dev/os#Root">os.Root</a> API 提供了一个直接、一致且可移植的解决方案。</p>
<h2>底层改进</h2>
<p>除了用户可见的更改，Go 在过去一年中还在底层做了重大改进。</p>
<p>在 Go 1.24 中，我们完全<a href="https://tonybai.com/2024/11/14/go-map-use-swiss-table/">重新设计了 map 的实现</a>，借鉴了哈希表设计中最新、最伟大的思想。这一更改是完全透明的，并为 map 的性能带来了显著提升，降低了 map 操作的尾部延迟，在某些情况下甚至带来了显著的内存节省。</p>
<p>Go 1.25 包含了一个实验性的、在 Go 垃圾回收器方面的重大进步，名为 <a href="https://tonybai.com/2025/10/31/deep-into-go-green-tea-gc/">Green Tea</a>。Green Tea 在许多应用程序中将垃圾回收开销减少了至少 10%，有时甚至高达 40%。它使用了一种专为当今硬件的能力和限制而设计的新颖算法，并开辟了一个我们正热切探索的新设计空间。例如，在即将发布的 Go 1.26 版本中，Green Tea 将在<a href="https://tonybai.com/2025/08/22/go-simd-package-preview">支持 AVX-512 向量指令</a>的硬件上额外实现 10% 的垃圾回收器开销降低——这在旧算法中几乎是不可能的。Green Tea 将在 Go 1.26 中默认启用；用户只需升级他们的 Go 版本即可受益。</p>
<h2>进一步发展软件开发栈</h2>
<p>Go 远不止于语言和标准库。它是一个软件开发平台，在过去一年里，我们还对 <a href="https://go.dev/gopls">gopls 语言服务器</a>进行了四次常规发布，并建立了合作伙伴关系以支持新兴的智能体应用程序新框架。</p>
<p>Gopls 为 VS Code 和其他基于 LSP 的编辑器和 IDE 提供 Go 支持。每个版本都有一系列的功能和改进，提升了阅读和编写 Go 代码的体验（详情请见 <a href="https://go.dev/gopls/release/v0.17.0">v0.17.0</a>、<a href="https://go.dev/gopls/release/v0.18.0">v0.18.0</a>、<a href="https://go.dev/gopls/release/v0.19.0">v0.19.0</a> 和 <a href="https://go.dev/gopls/release/v0.20.0">v0.20.0</a> 的发布说明，或我们新的 <a href="https://go.dev/gopls/features">gopls 功能文档</a>！）。一些亮点包括：许多新增和增强的分析器，帮助开发者编写更地道和健壮的 Go 代码；对变量提取、变量内联和 JSON 结构体标签的重构支持；以及一个<a href="https://go.dev/gopls/features/mcp">实验性的内置MCP服务器</a>，用于模型上下文协议（MCP），它以 MCP 工具的形式向 AI 助手暴露了 gopls 的一部分功能。</p>
<p>从 gopls v0.18.0 开始，我们开始探索自动代码现代化工具。随着 Go 的演进，每个版本都带来了新的能力和新的惯用法；Go 程序员一直在寻找其他方法来做的事情，现在有了新的、更好的方法。Go 坚守其<a href="https://go.dev/doc/go1compat">兼容性承诺</a>——旧的方式将永远有效——但尽管如此，这在旧惯用法和新惯用法之间造成了分歧。现代化工具是静态分析工具，它们能识别旧的惯用法，并建议更快、更可读、更安全、更现代的替代方案，并且能一键可靠地完成。我们希望现代化工具能像 gofmt 为<a href="https://go.dev/blog/gofmt">风格一致性</a>所做的那样，为惯用法一致性做出贡献。我们将现代化工具集成为 IDE 的建议，在那里它们不仅能帮助开发者维护更一致的编码标准，我们相信它们还能帮助开发者发现新功能并跟上最新技术。我们相信现代化工具还能帮助 AI 编码助手跟上最新技术，并对抗它们倾向于强化关于 Go 语言、API 和惯用法的过时知识。即将到来的 Go 1.26 版本将包括<a href="https://tonybai.com/2025/07/28/go-fix-reborn">对长期休眠的 go fix 命令的全面改造</a>，使其能够批量应用全套的现代化工具，回归其<a href="https://go.dev/blog/introducing-gofix">Go 1.0 之前的根源</a>。</p>
<p>九月底，我们与 <a href="https://www.anthropic.com/">Anthropic</a> 和 Go 社区合作，发布了<a href="https://modelcontextprotocol.io/">模型上下文协议（MCP）</a>的<a href="https://tonybai.com/2025/07/10/mcp-official-go-sdk">官方 Go SDK</a> 的 <a href="https://github.com/modelcontextprotocol/go-sdk/releases/tag/v1.0.0">v1.0.0</a>。这个 SDK 支持 MCP 客户端和 MCP 服务器，并支撑着 gopls 中新的 MCP 功能。将这项工作开源，有助于赋能围绕 Go 构建的日益增长的开源智能体生态系统的其他领域，例如最近由 <a href="https://www.google.com/">Google</a> 发布的<a href="https://github.com/google/adk-go">Agent Development Kit (ADK) for Go</a>。ADK Go 建立在 Go MCP SDK 之上，为构建模块化的多智能体应用程序和系统提供了一个地道的框架。Go MCP SDK 和 ADK Go 展示了 Go 在并发、性能和可靠性方面的独特优势如何使 Go 在生产级 AI 开发中脱颖而出，我们预计未来几年会有更多的 AI 工作负载用 Go 编写。</p>
<h2>展望未来</h2>
<p>Go 前方是激动人心的一年。</p>
<p>我们正在通过全新的 go fix 命令、对 AI 编码助手的更深层次支持，以及对 gopls 和 VS Code Go 的持续改进，来提升开发者的生产力。Green Tea 垃圾回收器的正式可用、对<a href="https://tonybai.com/2025/06/09/go-simd-intrinsics/">单指令多数据（SIMD）硬件功能的原生支持</a>，以及运行时和标准库对编写能更好地扩展到大规模多核硬件代码的支持，将继续使 Go 与现代硬件保持一致，并提高生产效率。我们正专注于 Go 的“生产栈”库和诊断工具，包括由 Joe Tsai 和 Go 社区成员共同推动的、对 encoding/json 的一次大规模（且酝酿已久）的<a href="https://go.dev/issue/71497">升级</a>；由 <a href="https://www.uber.com/us/en/about/">Uber</a> 的编程系统团队贡献的<a href="https://tonybai.com/2025/07/24/deadlock-detection-by-gc/">泄露 goroutine 分析</a>；以及对 net/http、unicode 和其他基础包的许多其他改进。我们正致力于为使用 Go 和 AI 构建提供清晰的路径，谨慎地演进语言平台以适应当今开发者不断变化的需求，并构建能够同时帮助人类开发者和 AI 助手及系统的工具和能力。</p>
<p>在 Go 开源发布 16 周年之际，我们也在展望 Go 开源项目本身的未来。从其<a href="https://www.youtube.com/watch?v=wwoWei-GAPo">卑微的开端</a>开始，Go 已经形成了一个蓬勃发展的贡献者社区。为了继续最好地满足我们不断扩大的用户群的需求，尤其是在软件行业动荡的时期，我们正在研究如何更好地扩展 Go 的开发流程——同时不失 Go 的基本原则——并更深入地让我们的优秀贡献者社区参与进来。</p>
<p>没有我们卓越的用户和贡献者社区，Go 就不可能有今天的成就。我们祝愿大家在新的一年里一切顺利！</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p><strong>想系统学习Go，构建扎实的知识体系？</strong></p>
<p>我的新书《<a href="https://book.douban.com/subject/37499496/">Go语言第一课</a>》是你的首选。源自2.4万人好评的极客时间专栏，内容全面升级，同步至Go 1.24。首发期有专属五折优惠，不到40元即可入手，扫码即可拥有这本300页的Go语言入门宝典，即刻开启你的Go语言高效学习之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-primer-published-4.png" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/11/15/go-turns-16/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go 的 16 年：一门为持久而生的编程语言</title>
		<link>https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last/</link>
		<comments>https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last/#comments</comments>
		<pubDate>Wed, 12 Nov 2025 00:25:02 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI基础设施]]></category>
		<category><![CDATA[AI服务]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ArdanLabs]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[DWARF5]]></category>
		<category><![CDATA[encoding/json/v2]]></category>
		<category><![CDATA[FlightRecorder]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go1.0]]></category>
		<category><![CDATA[go1.18]]></category>
		<category><![CDATA[go1.25]]></category>
		<category><![CDATA[godoc]]></category>
		<category><![CDATA[gofmt]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GOMAXPROCS]]></category>
		<category><![CDATA[gomod]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[goroutine]]></category>
		<category><![CDATA[gotest]]></category>
		<category><![CDATA[goversion]]></category>
		<category><![CDATA[govet]]></category>
		<category><![CDATA[Go语言]]></category>
		<category><![CDATA[GreenTeaGC]]></category>
		<category><![CDATA[ignore指令]]></category>
		<category><![CDATA[KenThompson]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[macOS12]]></category>
		<category><![CDATA[prometheus]]></category>
		<category><![CDATA[reddit]]></category>
		<category><![CDATA[RobertGriesemer]]></category>
		<category><![CDATA[RobPike]]></category>
		<category><![CDATA[terraform]]></category>
		<category><![CDATA[testing/synctest]]></category>
		<category><![CDATA[Web服务器]]></category>
		<category><![CDATA[WindowsARM]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[停顿时间]]></category>
		<category><![CDATA[克制]]></category>
		<category><![CDATA[分布式系统]]></category>
		<category><![CDATA[创新]]></category>
		<category><![CDATA[可观测性]]></category>
		<category><![CDATA[可靠]]></category>
		<category><![CDATA[后端系统]]></category>
		<category><![CDATA[向后兼容]]></category>
		<category><![CDATA[垃圾回收器]]></category>
		<category><![CDATA[安全性]]></category>
		<category><![CDATA[实用性]]></category>
		<category><![CDATA[容器感知]]></category>
		<category><![CDATA[工具链]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[快速]]></category>
		<category><![CDATA[快速编译]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[性能分析]]></category>
		<category><![CDATA[持久]]></category>
		<category><![CDATA[数据流]]></category>
		<category><![CDATA[标准库]]></category>
		<category><![CDATA[核心类型]]></category>
		<category><![CDATA[泛型]]></category>
		<category><![CDATA[清晰]]></category>
		<category><![CDATA[稳定性]]></category>
		<category><![CDATA[空指针]]></category>
		<category><![CDATA[简洁]]></category>
		<category><![CDATA[简洁性]]></category>
		<category><![CDATA[类型推断]]></category>
		<category><![CDATA[编程语言]]></category>
		<category><![CDATA[编译器]]></category>
		<category><![CDATA[设计哲学]]></category>
		<category><![CDATA[调试信息]]></category>
		<category><![CDATA[边缘计算]]></category>
		<category><![CDATA[运行时]]></category>
		<category><![CDATA[追踪]]></category>
		<category><![CDATA[遥测]]></category>
		<category><![CDATA[里程碑]]></category>
		<category><![CDATA[链接器]]></category>
		<category><![CDATA[长远思考]]></category>
		<category><![CDATA[静态类型]]></category>
		<category><![CDATA[高性能]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5380</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last 大家好，我是Tony Bai。 每年的十一月，对于全球的 Gopher 而言，都是一个值得纪念的特殊时刻。今年，我们迎来了 Go 语言公开发布的第 16 个年头。 在众多的庆祝文章中，来自 Go 社区的知名组织 Ardan Labs 发布的这篇《Go 的 16 年：一门为持久而生的编程语言》，以其深邃的洞察力和饱满的情感，深深地打动了我们。 这篇文章不仅仅是对 Go 历史里程碑的简单罗列，更是一次对 Go 设计哲学——克制、清晰与长远思考——的深刻致敬。文章精准地捕捉了 Go 从解决 Google 内部的工程困境，到成为现代云原生基石的宏大叙事。我们相信，无论对于已经与 Go 同行多年的资深开发者，还是刚刚踏上 Gopher 之旅的新人，这篇文章都能带来启发与共鸣。 为此，我特将其全文翻译为中文，希望能与中文 Go 社区的各位一同分享这份喜悦与思考。以下是正文： 每年的十一月，Go 社区都会为我们这个时代最具悄然变革力量的编程语言之一，庆祝又一个里程碑。 诞生于 Google 并于 2009 年向世界发布的 Go，旨在解决大规模软件构建、庞大代码库、分布式系统以及跨大洲团队协作的复杂性。十六年后的今天，Go 诞生之初秉持的原则——简洁、快速和可靠——依然指导着它的发展。 正如 Go 团队在去年的周年纪念博文中所写：“Go 是为 2007 年的软件工程问题而构建的，但它仍在解决 2024 年的挑战，以及那些尚未到来的挑战。” 起源故事 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/16-years-of-go-a-programming-language-built-to-last-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last">本文永久链接</a> &#8211; https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last</p>
<p>大家好，我是Tony Bai。</p>
<p>每年的十一月，对于全球的 Gopher 而言，都是一个值得纪念的特殊时刻。今年，我们迎来了 Go 语言公开发布的第 16 个年头。</p>
<p>在众多的庆祝文章中，来自 Go 社区的知名组织 Ardan Labs 发布的这篇《<a href="https://www.ardanlabs.com/news/2025/16-years-of-go-a-programming-language-built-to-last">Go 的 16 年：一门为持久而生的编程语言</a>》，以其深邃的洞察力和饱满的情感，深深地打动了我们。</p>
<p>这篇文章不仅仅是对 Go 历史里程碑的简单罗列，更是一次对 Go 设计哲学——克制、清晰与长远思考——的深刻致敬。文章精准地捕捉了 Go 从解决 Google 内部的工程困境，到成为现代云原生基石的宏大叙事。我们相信，无论对于已经与 Go 同行多年的资深开发者，还是刚刚踏上 Gopher 之旅的新人，这篇文章都能带来启发与共鸣。</p>
<p>为此，我特将其全文翻译为中文，希望能与中文 Go 社区的各位一同分享这份喜悦与思考。以下是正文：</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/the-ultimate-guide-to-go-module-qr.png" alt="" /></p>
<hr />
<p>每年的十一月，Go 社区都会为我们这个时代最具悄然变革力量的编程语言之一，庆祝又一个里程碑。</p>
<p>诞生于 Google 并于 <strong>2009</strong> 年向世界发布的 Go，旨在解决大规模软件构建、庞大代码库、分布式系统以及跨大洲团队协作的复杂性。十六年后的今天，Go 诞生之初秉持的原则——<strong>简洁、快速和可靠</strong>——依然指导着它的发展。</p>
<p>正如 <a href="https://tonybai.com/2024/11/12/go-turns-15">Go 团队在去年的周年纪念博文</a>中所写：“Go 是为 2007 年的软件工程问题而构建的，但它仍在解决 2024 年的挑战，以及那些尚未到来的挑战。”</p>
<h2>起源故事</h2>
<p>这门语言源于 Google 三位工程师——<strong>Robert Griesemer, Rob Pike, 和 Ken Thompson</strong>——的挫败感，他们想要一门像 C 一样快、像 Python 一样高效、并且能满足 Google 基础设施规模化需求的语言。</p>
<p>他们并不想彻底革新编程，他们只是想让编程再次变得令人愉悦。</p>
<p>正如Rob Pike曾经说过的那样，“Go 是一次关于我们能去除什么的实验。”他们去除的过度复杂性、无休止的编译时间和混乱的依赖关系，反而成为了 Go 最大的优势。</p>
<h2>Go 编程语言为何能迅速走红</h2>
<p>Go 不仅仅是又一门新语言；它是对<strong>过度工程化的一次宣言</strong>。其设计目标使其脱颖而出：</p>
<ul>
<li><strong>快速编译</strong>：代码在数秒内完成构建，而非数分钟。</li>
<li><strong>简洁性</strong>：极简的特性集，强调清晰与可读性。</li>
<li><strong>并发</strong>：轻量级的 goroutine，使并发编程变得实用。</li>
<li><strong>静态类型 + 安全性</strong>：在不牺牲开发速度的前提下，保证类型安全。</li>
<li><strong>一流的工具链</strong>：go fmt、go test、go mod 及其他工具，塑造了 Go 的工匠精神文化。</li>
</ul>
<p>这些价值观深深地触动了那些厌倦了语言功能蔓延的工程师们，也触动了那些需要稳定、可维护系统的公司。</p>
<h2>现实世界中的 Go</h2>
<p>多年来，Go 已悄然成为现代Web的支柱。它驱动着 <strong>Docker、Kubernetes、Terraform 和 Prometheus</strong>——当今云原生生态系统的根基。</p>
<p>在 Google 内部，它在后端系统中每秒处理数十亿次请求。在 Google 之外，它已成为初创公司构建分布式系统和企业级工具的首选，这些场景都要求在没有摩擦的情况下获得高性能。</p>
<blockquote>
<p>“Go 诞生于 14 年前，至今它仍是唯一一门让并发感觉如此简单的语言。”</p>
</blockquote>
<p>这种观点体现了 Go 在开发者领域中的独特地位：它既足够古老，经受住了考验，又足够现代，能够不断演进发展。</p>
<h2>值得庆祝的里程碑</h2>
<p>Go 的时间线上，点缀着一些关键时刻，展示了这门语言是如何有意识地演进的：</p>
<ul>
<li><strong>2009年</strong>：Google 正式公开发布 Go语言。</li>
<li><strong>2012年</strong>：Go 1.0 发布，并作出了向后兼容的承诺。</li>
<li><strong>2015–2018年</strong>：Go 成为容器化工具和微服务的标准。</li>
<li><strong>2022年</strong>：泛型在 Go 1.18 中到来——一个期待已久的里程碑。</li>
<li><strong>2024年</strong>：Go 位列全球最常用的十大语言之一，并在 AI 服务和边缘计算领域的采用率迅速增长。</li>
</ul>
<p>正是这种稳定性，加上审慎的创新，让 Go 得以经久不衰。当其他语言追逐潮流时，Go 始终立足于实用性。</p>
<h2>是什么让 Go 与众不同</h2>
<p>与许多在每个新版本中不断膨胀的现代语言不同，Go 的演进一直很保守，而这种克制最终得到了回报。</p>
<p>Go 团队保持了一种罕见的、对向后兼容的承诺。十年前编写的代码，今天依然可以编译和运行。对于那些需要跨越数年甚至数十年维护生产系统的组织来说，这种信任是无价的。</p>
<p>Go 的简洁性也促进了团队协作。开发者可以快速上手代码库并投入工作。没有无休止的语法或模式争论，只有简洁、直接且高效的代码。</p>
<p>这种清晰性塑造了一个重视协作而非“炫技”的社区。</p>
<h2>社区的经验教训</h2>
<p>在一份以前的 <a href="https://www.reddit.com/r/golang/comments/17rx47o/go_was_announced_exactly_14_years_ago_happy/">Reddit 周年纪念帖子</a> 中，开发者们回顾了 Go 是如何改变他们职业生涯的：</p>
<blockquote>
<p>“Go 让我重新爱上了编程。”</p>
<p>“它不花哨，但它能搞定事情，这就是我爱它的地方。”</p>
</blockquote>
<p>这些故事体现了 Go 的不朽精神；与其说是炒作，不如说是把工作做好。</p>
<h2>下一章</h2>
<p>Go 的下一个十年，将不仅仅是关于 Web 服务器和 API。其生态系统正在扩展到<strong>AI 基础设施、数据流</strong>和<strong>边缘计算</strong>等领域，在这些地方，性能、并发和简洁性至关重要。</p>
<p>根据 Go 团队的 15 周年博文，当前的工作重点是：</p>
<ul>
<li>利用现代 CPU 架构，优化运行时性能。</li>
<li>改进生产系统中的遥测、可观测性和性能分析。</li>
<li>确保 Go 能够随着下一代硬件的发展而持续扩展。</li>
</ul>
<p>对于押注 Go 的开发者和组织来说，这意味着一件事：这门语言没有放慢脚步，它正在升级。</p>
<h2>Go的2025年：稳步求精，基础更牢固</h2>
<p>发布于 2025 年 8 月的 Go 1.25 版本，体现了这门语言标志性的演进方式——安静、审慎的改进，而非颠覆。虽然没有破坏性变更，但几项更新有意义地加固了 Go 的基础。通过移除旧的“core type”概念，语言规范得以简化，澄清了类型推断和泛型的工作方式。工具链变得更精简、更快速，工具现在按需构建，go.mod 中加入了新的ignore指令，同时 go vet, go doc, 和 go version 等命令也得到了增强。</p>
<p>在底层，运行时获得了容器感知能力，能够根据 CPU 限制自动调整 GOMAXPROCS，使 Go 在云和边缘环境中更加高效。一个新的实验性垃圾回收器（greenteagc）提供了明显更低的停顿时间，而“ Flight Recorder”追踪则引入了持续的、低开销的可观测性。编译器和链接器现在能生成 DWARF 5 调试信息，以获得更小的二进制文件和更快的构建速度，同时修复了一个微妙的空指针 bug，提升了运行时安全。</p>
<p>在标准库中，开发者现在可以通过 testing/synctest 更容易地测试并发代码，并可以试用更快、更灵活的 encoding/json/v2 包。平台支持也向前迈进——现在要求 macOS 12 或更新版本，而 32 位 Windows ARM 将在此版本后停止支持。</p>
<p>总而言之，Go 1.25 提醒了我们这门语言为何能经久不衰：它在不破坏信任的前提下演进，用稳定、有影响力的进步，取代了喧嚣的炒作。</p>
<p>（来源: <a href="https://go.dev/doc/go1.25?utm_source=chatgpt.com">go.dev/doc/go1.25</a>）</p>
<h2>为 Go 干杯</h2>
<p>在 Go 语言诞生 16 周年之际，我们不妨停下来，细细品味它所代表的意义。它不仅仅是一门编程语言，更是一种工程理念，其核心在于克制、清晰和长远思考。</p>
<p>在 Ardan Labs，我们亲眼见证了 Go 如何帮助团队构建可靠、可扩展的系统，从企业平台到初创原型，无所不包。它帮助工程师专注于真正重要的事情：解决实际问题，而不是与工具较劲。</p>
<p>祝愿 Go 语言再创辉煌一年。</p>
<p><strong>不追逐潮流的语言，才能超越潮流而长存。</strong></p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p><strong>想系统学习Go，构建扎实的知识体系？</strong></p>
<p>我的新书《<a href="https://book.douban.com/subject/37499496/">Go语言第一课</a>》是你的首选。源自2.4万人好评的极客时间专栏，内容全面升级，同步至Go 1.24。首发期有专属五折优惠，不到40元即可入手，扫码即可拥有这本300页的Go语言入门宝典，即刻开启你的Go语言高效学习之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-primer-published-4.png" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/11/12/16-years-of-go-a-programming-language-built-to-last/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>从 Python 到 Go：我们失去了什么，又得到了什么？</title>
		<link>https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained/</link>
		<comments>https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained/#comments</comments>
		<pubDate>Fri, 31 Oct 2025 23:17:11 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI/ML]]></category>
		<category><![CDATA[DataFrame]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[JupyterNotebooks]]></category>
		<category><![CDATA[NumPy]]></category>
		<category><![CDATA[pandas]]></category>
		<category><![CDATA[pip]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[PyTorch]]></category>
		<category><![CDATA[venv]]></category>
		<category><![CDATA[动态语言]]></category>
		<category><![CDATA[容器镜像]]></category>
		<category><![CDATA[工程纪律]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[得与失]]></category>
		<category><![CDATA[技术迁徙]]></category>
		<category><![CDATA[探索式编程]]></category>
		<category><![CDATA[数据科学]]></category>
		<category><![CDATA[权衡]]></category>
		<category><![CDATA[清晰性]]></category>
		<category><![CDATA[猴子补丁]]></category>
		<category><![CDATA[生态系统]]></category>
		<category><![CDATA[确定性]]></category>
		<category><![CDATA[编译期检查]]></category>
		<category><![CDATA[网络编程]]></category>
		<category><![CDATA[装饰器]]></category>
		<category><![CDATA[运维]]></category>
		<category><![CDATA[静态二进制文件]]></category>
		<category><![CDATA[静态类型]]></category>
		<category><![CDATA[静态语言]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=5338</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained 大家好，我是Tony Bai。 在当代软件工程师的职业生涯中，从一门动态语言（如 Python）转向一门静态语言（如 Go），已成为一条日益普遍的技术迁徙路径。这条路充满了新奇的发现，也伴随着对旧日“舒适区”的丝丝怀念。 近日，在 r/golang 社区，一个关于“与 Python 相比，Go 缺失了什么？”的提问，引发了一场关于这种技术迁徙中“得与失”的深刻对话。这场讨论，与其说是在评判语言的优劣，不如说是一次集体反思：当我们选择 Go 时，我们究竟是为了什么而放弃了另一些东西？ 在这篇文章中，我们就来深入剖析这场技术迁徙中的“得”与“失”，看看当我们拥抱 Go 的严谨与高效时，究竟告别了怎样的风景。 失去的乐园 —— 那些我们留在 Python 世界的“玩具” 对于许多从 Python 迁徙而来的 Gopher 而言，“失去”的感觉是真实存在的。我们失去的，是一个极其成熟、包罗万象，且为“探索”与“便利”而生的生态系统。 失去了“数据科学的权杖” 这是最令人痛心疾首的“失物”。Python 在数据处理、科学计算和 AI/ML 领域的统治地位是毋庸置疑的。 数据操作的魔力：我们失去了像 Pandas 这样的库，它提供了极其强大和富有表现力的数据框 (DataFrame) 操作能力。一位开发者坦言，尽管他相信错误优于异常，但如果让他每天用 Go 写 50 遍类似 Pandas 的链式 groupby().aggregate().reset_index() 操作，他会“疯掉”。 AI/ML 的“护城河”：我们暂时告别了由 NumPy, PyTorch 等框架构筑的、无与伦比的 AI 算法生态。尽管 Go [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2025/from-python-to-go-what-we-lost-and-gained-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained">本文永久链接</a> &#8211; https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained</p>
<p>大家好，我是Tony Bai。</p>
<p>在当代软件工程师的职业生涯中，从一门动态语言（如 Python）转向一门静态语言（如 Go），已成为一条日益普遍的技术迁徙路径。这条路充满了新奇的发现，也伴随着对旧日“舒适区”的丝丝怀念。</p>
<p>近日，在 r/golang 社区，一个<a href="https://www.reddit.com/r/golang/comments/1odb9pg/what_are_you_missing_in_go_compared_to_python/">关于“与 Python 相比，Go 缺失了什么？”的提问</a>，引发了一场关于这种技术迁徙中“得与失”的深刻对话。这场讨论，与其说是在评判语言的优劣，不如说是一次集体反思：当我们选择 Go 时，我们究竟是为了什么而放弃了另一些东西？</p>
<p>在这篇文章中，我们就来深入剖析这场技术迁徙中的<strong>“得”与“失”</strong>，看看当我们拥抱 Go 的严谨与高效时，究竟告别了怎样的风景。</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/paid/the-ultimate-guide-to-go-module-qr.png" alt="" /></p>
<h2>失去的乐园 —— 那些我们留在 Python 世界的“玩具”</h2>
<p>对于许多从 Python 迁徙而来的 Gopher 而言，“失去”的感觉是真实存在的。我们失去的，是一个极其成熟、包罗万象，且为“探索”与“便利”而生的生态系统。</p>
<h3>失去了“数据科学的权杖”</h3>
<p>这是最令人痛心疾首的“失物”。Python 在数据处理、科学计算和 AI/ML 领域的统治地位是毋庸置疑的。</p>
<ul>
<li><strong>数据操作的魔力</strong>：我们失去了像 <strong>Pandas</strong> 这样的库，它提供了极其强大和富有表现力的数据框 (DataFrame) 操作能力。一位开发者坦言，尽管他相信错误优于异常，但如果让他每天用 Go 写 50 遍类似 Pandas 的链式 groupby().aggregate().reset_index() 操作，他会“疯掉”。</li>
<li><strong>AI/ML 的“护城河”</strong>：我们暂时告别了由 <strong>NumPy</strong>, <strong>PyTorch</strong> 等框架构筑的、无与伦比的 AI 算法生态。尽管 Go 凭借其并发能力在 AI 基础设施中大放异彩，但在核心模型与算法层面，我们失去了一片广阔的“成熟林地”。</li>
</ul>
<h3>失去了“探索式编程的自由”</h3>
<p>我们也失去了一种无拘无束、即时反馈的探索乐趣。</p>
<ul>
<li><strong>Jupyter Notebooks 的沉浸体验</strong>：我们失去了一个与数据科学工作流完美融合的交互式环境。虽然 Go 也可以在 Jupyter 中运行，但那种原生、无缝的数据探索与可视化体验，至今仍是 Python 的专属。</li>
<li><strong>动态语言的“魔法”</strong>：我们失去了那些在原型验证和测试中极其便利的“黑魔法”，如<strong>猴子补丁 (monkey patching)</strong> 和<strong>装饰器 (decorators)</strong>。这些“玩具”虽然危险，但在特定场景下，它们确实能让代码变得更紧凑、更灵活。</li>
</ul>
<h2>得到的磐石 —— Go 赋予我们的“信任”与“确定性”</h2>
<p>然而，有失必有得。当我们告别 Python 的“乐园”时，我们得到的是一些在构建大型、严肃的软件系统时，更为宝贵的东西：<strong>信任、可预测性和朴素的工程纪律</strong>。</p>
<h3>得到了“免于午夜惊魂的权利”</h3>
<p>这是“得到”清单上最重要的一项。一位来自 Java 和 Python 背景的开发者的高赞评论一语中的：</p>
<blockquote>
<p>“像猴子补丁和装饰器这样的东西看起来很聪明，直到你在凌晨 2 点调试时，想不通为什么你的函数突然变成了别的东西。<strong>Go 给你的玩具可能更少，但至少你可以相信，它们不会在调试时反咬你一口。</strong>”</p>
</blockquote>
<p>我们得到的，是<strong>静态类型</strong>和<strong>编译期检查</strong>所带来的坚如磐石的<strong>确定性</strong>。我们彻底告别了“&#8217;NoneType&#8217; has no attribute &#8216;X&#8217;”这类只有在运行时才会暴露的、最常见的 Python 错误。我们得到的，是一种可以安心入睡的信心：只要代码能够编译通过，一整类低级错误就已经被消除了。</p>
<h3>得到了“清晰压倒一切”的朴素哲学</h3>
<p>我们得到了一种新的审美观：<strong>清晰性远比表现力更重要</strong>。另一位评论者的比喻十分精妙：</p>
<blockquote>
<p>Go 允许你用最多 3 个词的简单句子来表达。为了说出有意义的话，你需要写很多无聊的句子，但它更容易学习和理解。</p>
</blockquote>
<p>我们失去了编写单行“炫技”代码的乐趣，却得到了一个<strong>整个团队都能轻松阅读和维护</strong>的代码库。我们得到的，是 if err != nil 的冗长所换来的、对每一个错误路径的明确掌控。</p>
<h3>得到了“摆脱环境与依赖之苦”的解脱</h3>
<p>我们得到了一个极其简化的运维世界。</p>
<ul>
<li><strong>单一的静态二进制文件</strong>：我们告别了 Python 的 venv、pip 和复杂的依赖树，得到了一个可以被轻松复制到任何地方、无需任何运行时依赖就能运行的程序。</li>
<li><strong>轻量级的容器镜像</strong>：我们得到的，是数十兆字节大小的、干净的 Docker 镜像，而不是动辄数百兆甚至上G的、包含了整个 Python 解释器和众多依赖的臃肿镜像。</li>
</ul>
<h2>小结：一次自觉的“断舍离”</h2>
<p>从 Python 到 Go 的旅程，并非一次简单的“语言切换”，而是一次深刻的<strong>“哲学选择”</strong>和自觉的<strong>“断舍离”</strong>。</p>
<p>我们<strong>失去</strong>了 Python 生态的广度、动态语言的灵活性和探索式编程的即时乐趣。</p>
<p>但我们<strong>得到</strong>了 Go 的深度——在并发和网络编程领域的专注；得到了静态语言的严谨性、编译期的安全保障；得到了一个极其简约、高度可预测、易于大规模协作的工程环境。</p>
<p>这并非一次升级或降级，而是一次<strong>权衡 (Trade-off)</strong>。</p>
<ul>
<li><strong>Python</strong> 是一把功能丰富的<strong>瑞士军刀</strong>，是探索未知、快速验证想法的最佳伴侣。</li>
<li><strong>Go</strong> 则更像一把坚固、可靠、专为特定任务打造的<strong>工程师锤</strong>，是构建需要长期服役的、坚固可靠的“建筑”的不二之选。</li>
</ul>
<p>理解了这一点，我们便能欣赏两种语言各自的美，并在合适的场景下，做出最明智的、无悔的选择。</p>
<p>资料链接：https://www.reddit.com/r/golang/comments/1odb9pg/what_are_you_missing_in_go_compared_to_python/</p>
<hr />
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img src="https://tonybai.com/wp-content/uploads/course-card/iamtonybai-banner-2.gif" alt="" /></p>
<hr />
<p><strong>想系统学习Go，构建扎实的知识体系？</strong></p>
<p>我的新书《<a href="https://book.douban.com/subject/37499496/">Go语言第一课</a>》是你的首选。源自2.4万人好评的极客时间专栏，内容全面升级，同步至Go 1.24。首发期有专属五折优惠，不到40元即可入手，扫码即可拥有这本300页的Go语言入门宝典，即刻开启你的Go语言高效学习之旅！</p>
<p><img src="https://tonybai.com/wp-content/uploads/2025/go-primer-published-4.png" alt="" /></p>
<hr />
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/11/01/from-python-to-go-what-we-lost-and-gained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
