<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Siyang's Blog</title><link>/</link><description>Recent content on Siyang's Blog</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 28 Mar 2026 22:32:29 +0800</lastBuildDate><atom:link href="/index.xml" rel="self" type="application/rss+xml"/><item><title>【翻译】深入理解 Go 运行时：垃圾回收器</title><link>/posts/go-garbage-collector/</link><pubDate>Sat, 28 Mar 2026 22:32:29 +0800</pubDate><guid>/posts/go-garbage-collector/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文章为译文，原作者 Jesús Espino。在这里查看他关于 Go Runtime 的系列文章：&lt;a href="https://internals-for-interns.com/series/understanding-the-go-runtime/"&gt;Understanding the Go Runtime&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://i.imgur.com/1yVCPoI.webp" alt="首图"&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;a href="/posts/go-runtime-scheduler/"&gt;上一篇文章&lt;/a&gt; 中，我们探讨了 Go 调度器——goroutine 如何被多路复用到操作系统线程上、GMP 模型，以及运行时用来保持 CPU 忙碌的所有技巧。但我们还没有解决一个根本问题：所有这些 goroutine 都会分配内存，而&lt;em&gt;必须有人&lt;/em&gt;来清理它们。这就是垃圾回收器的工作，也是我们今天要探讨的内容。&lt;/p&gt;
&lt;p&gt;在本文中，我们将研究在 &lt;strong&gt;Go 1.26&lt;/strong&gt; 中运行的垃圾回收器，该版本引入了 &lt;strong&gt;GreenTea&lt;/strong&gt; GC。如果您使用的是更早版本的 Go，不用担心——整体结构是相同的。主要区别在于&lt;strong&gt;标记阶段&lt;/strong&gt;，当我们讲到那里时，会简要说明旧方法的差异。如果您想了解更多关于 GreenTea 的信息，Michael Knyszek 在 GopherCon 2025 上做了&lt;a href="https://www.youtube.com/watch?v=gPJkM95KpKo"&gt;一个关于它的精彩演讲&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Go 的垃圾回收器是一个&lt;strong&gt;非移动、并发、三色、标记-清除&lt;/strong&gt;的回收器。形容词很多——但它们都意味着什么呢？让我们逐一分解。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;非移动&lt;/strong&gt;意味着 GC 从不重新定位内存中的对象。一旦一个对象被分配到一个特定的地址，它将在其整个生命周期中保持不变。这是一件大事——它意味着指针保持有效，这使得像 &lt;code&gt;unsafe.Pointer&lt;/code&gt; 和 cgo 互操作这类事情简单得多。一些垃圾回收器（如 Java 的 G1 或 ZGC）&lt;em&gt;确实&lt;/em&gt;会移动对象以压缩内存并减少碎片，但 Go 采取了不同的方法：它依赖其 &lt;a href="/posts/go-memory-allocator/"&gt;基于大小类的分配器&lt;/a&gt; 来最小化碎片，而无需移动任何对象。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;并发&lt;/strong&gt;意味着 GC 的大部分工作是在&lt;em&gt;程序持续运行的同时&lt;/em&gt;完成的。它不会在整个回收周期中&lt;strong&gt;停止世界（stop the world）&lt;/strong&gt;（暂停所有 goroutine 以便只运行 GC）——只有两次非常短暂的暂停。其余时间，GC goroutine 与你的应用程序 goroutine 一起运行，共享 CPU 时间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;三色&lt;/strong&gt;指的是标记阶段使用的算法。每个对象在概念上被标记为白色、灰色或黑色——我们稍后会详细介绍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;标记-清除&lt;/strong&gt;描述了两种主要操作：首先，&lt;em&gt;标记&lt;/em&gt;所有仍然可达（存活）的对象；然后，&lt;em&gt;清除&lt;/em&gt;堆并回收任何未被标记的对象（垃圾）。概念上简单，但在实践中很棘手——尤其是当你的程序在 GC 试图追踪指针的同时还在修改指针时。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：本文引用了 Go 内存分配器的概念——特别是 span、size classes 以及 mcache/mcentral/mheap 层次结构。虽然并非严格要求的阅读材料，但我鼓励你先阅读 &lt;a href="/posts/go-memory-allocator/"&gt;内存分配器&lt;/a&gt; 这篇文章。&lt;/p&gt;</description></item><item><title>【翻译】深入理解 Go 运行时：调度器</title><link>/posts/go-runtime-scheduler/</link><pubDate>Mon, 16 Mar 2026 00:01:50 +0800</pubDate><guid>/posts/go-runtime-scheduler/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文章为译文，原作者 Jesús Espino。在这里查看他关于 Go Runtime 的系列文章：&lt;a href="https://internals-for-interns.com/series/understanding-the-go-runtime/"&gt;Understanding the Go Runtime&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://i.imgur.com/1yVCPoI.webp" alt="首图"&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;a href="https://internals-for-interns.com/posts/go-memory-allocator/"&gt;上一篇文章&lt;/a&gt; 中，我们探讨了 Go 的内存分配器 (memory allocator) 如何管理堆内存——从操作系统获取大块区域 (arenas)，将它们划分为 spans 和大小类 (size classes)，并使用三级层次结构 (mcache, mcentral, mheap) 使得大多数分配操作无需加锁。其中一个关键细节是每个 &lt;strong&gt;P&lt;/strong&gt;（处理器）都有自己的内存缓存。但我们从未真正解释过 P &lt;em&gt;是什么&lt;/em&gt;，或者运行时如何决定哪个 goroutine 在哪个线程上运行。这正是调度器的工作，也是我们今天要探讨的内容。&lt;/p&gt;
&lt;p&gt;调度器是运行时中负责回答一个看似简单的问题的组件： &lt;strong&gt;接下来该运行哪个 goroutine？&lt;/strong&gt; 你的程序中可能有成百上千甚至数百万个 goroutine，但 CPU 核心只有寥寥几个。调度器的工作就是将这些 goroutine 多路复用到少量的 OS 线程上，让每个核心都保持忙碌，同时确保没有 goroutine 会被饿死。&lt;/p&gt;
&lt;p&gt;如果你曾经使用过 goroutine 和 channel，那么你已经在不知不觉中受益于调度器了。每一个 &lt;code&gt;go&lt;/code&gt; 语句，每一次 channel 的发送和接收，每一个 &lt;code&gt;time.Sleep&lt;/code&gt; ——它们都与调度器交互。让我们来看看它是如何工作的。&lt;/p&gt;
&lt;p&gt;让我们从最基本的构建块开始——整个调度器所围绕的三个核心结构。&lt;/p&gt;
&lt;h2 id="gmp-模型"&gt;GMP 模型&lt;/h2&gt;
&lt;p&gt;调度器建立在三个概念之上，通常称为 &lt;strong&gt;GMP 模型&lt;/strong&gt; ： &lt;strong&gt;G&lt;/strong&gt;（goroutine）， &lt;strong&gt;M&lt;/strong&gt;（machine/OS 线程），以及 &lt;strong&gt;P&lt;/strong&gt;（处理器）。我们在启动引导那篇文章中曾简单提及，现在让我们来仔细看看它们。&lt;/p&gt;
&lt;p&gt;让我们逐一了解。&lt;/p&gt;
&lt;h3 id="g--goroutine"&gt;G — Goroutine&lt;/h3&gt;
&lt;p&gt;一个 &lt;strong&gt;G&lt;/strong&gt; 就是一个 goroutine——Go 运行时对一段并发工作的表示。每当你写下 &lt;code&gt;go f()&lt;/code&gt;，运行时就会创建一个（或复用一个）G 来跟踪该函数的执行。&lt;/p&gt;</description></item><item><title>【翻译】深入理解 Go 运行时：内存分配器</title><link>/posts/go-memory-allocator/</link><pubDate>Mon, 16 Mar 2026 00:01:49 +0800</pubDate><guid>/posts/go-memory-allocator/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文章为译文，原作者 Jesús Espino。在这里查看他关于 Go Runtime 的系列文章：&lt;a href="https://internals-for-interns.com/series/understanding-the-go-runtime/"&gt;Understanding the Go Runtime&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://i.imgur.com/1yVCPoI.webp" alt="首图"&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;a href="/posts/understanding-go-runtime/"&gt;上一篇文章&lt;/a&gt; 中，我们探讨了 Go 运行时如何引导自身 —— 从操作系统将控制权交给 Go 二进制文件，到你的 &lt;code&gt;func main()&lt;/code&gt; 开始运行。在引导过程中，运行时最先设置的事情之一就是 &lt;strong&gt;内存分配器（memory allocator）&lt;/strong&gt;。这就是我们今天要探索的内容。&lt;/p&gt;
&lt;p&gt;可以把内存分配器想象成一个仓库管理员。你的程序不断需要不同大小的箱子 —— 有时很小，有时很大 —— 而且需要 &lt;strong&gt;快速&lt;/strong&gt; 拿到它们。分配器的工作就是尽可能快地分发这些箱子，保持仓库井井有条以避免浪费，并与垃圾收集器协作，回收不再被使用的箱子。&lt;/p&gt;
&lt;p&gt;但在我们深入了解仓库本身之前，先来聊聊数据实际在何时被放到那里。&lt;/p&gt;
&lt;h2 id="何时发生内存分配"&gt;何时发生内存分配？&lt;/h2&gt;
&lt;p&gt;并非程序中的每个变量都会经过内存分配器。Go 有两个存放数据的地方：&lt;strong&gt;栈（stack）&lt;/strong&gt; 和 &lt;strong&gt;堆（heap）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;栈比较简单。每个函数调用都在栈上获得自己的一小块临时空间，当函数返回时，这块空间自动消失。它快速且简单 —— 无需记账。&lt;/p&gt;
&lt;p&gt;但有时，数据需要在创建它的函数结束后继续存在。也许你返回了一个指向某物的指针，或者存储了一个程序其他部分稍后会使用的值。这些数据不能存活在栈上 —— 当函数返回时它们就会消失。因此它们被放在 &lt;strong&gt;堆（heap）&lt;/strong&gt; 上，这是一个生命周期更长的内存区域。&lt;/p&gt;
&lt;p&gt;Go 编译器在这方面实际上非常智能。它在编译时分析你的代码，以决定哪些数据可以留在栈上，哪些需要进入堆 —— 这被称为 &lt;strong&gt;逃逸分析（escape analysis）&lt;/strong&gt;（我们在&lt;a href="https://internals-for-interns.com/posts/the-go-ir/"&gt;IR 文章&lt;/a&gt;中详细介绍过）。&lt;/p&gt;
&lt;p&gt;每次有数据最终进入堆时，就是内存分配器发挥作用的时候了。它是在堆上寻找空闲空间并将其交出去的系统。这就是本文剩余部分要讲的内容。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;一个小简化&lt;/strong&gt;：上面的描述并不完整。在 Go 中，goroutine 的栈实际上是从堆上分配的 —— 所以是内存分配器提供了栈所需的空间。但是一旦栈被分配，其上的变量管理与堆对象的管理方式截然不同：它们只是栈帧中的偏移量，每个变量的分配不涉及分配器。因此，虽然分配器负责栈的 &lt;strong&gt;内存&lt;/strong&gt;，但它不参与将单个变量放置到栈上。在本文中，我们将聚焦于堆这方面。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以分配器管理着堆内存。但这些内存最初又是从哪里来的呢？&lt;/p&gt;
&lt;h2 id="为什么不直接向操作系统请求"&gt;为什么不直接向操作系统请求？&lt;/h2&gt;
&lt;p&gt;当你的程序需要内存时，总得有人提供它。最终，这个人就是操作系统。操作系统管理着机器上的所有物理 RAM，任何需要内存的进程都必须通过系统调用（如 Linux/macOS 上的 &lt;code&gt;mmap&lt;/code&gt; 或 Windows 上的 &lt;code&gt;VirtualAlloc&lt;/code&gt;）向操作系统请求。&lt;/p&gt;</description></item><item><title>【翻译】深入理解 Go 运行时：引导启动 (Bootstrap)</title><link>/posts/understanding-go-runtime/</link><pubDate>Mon, 16 Mar 2026 00:01:48 +0800</pubDate><guid>/posts/understanding-go-runtime/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文章为译文，原作者 Jesús Espino。在这里查看他关于 Go Runtime 的系列文章：&lt;a href="https://internals-for-interns.com/series/understanding-the-go-runtime/"&gt;Understanding the Go Runtime&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://i.imgur.com/1yVCPoI.webp" alt="首图"&gt;&lt;/p&gt;
&lt;p&gt;当你编写 Go 代码时，背后发生了很多事情。goroutine 很轻量，channel 开箱即用，内存由运行时管理，你从来不需要考虑线程池。所有这一切都由 &lt;strong&gt;Go 运行时（Go runtime）&lt;/strong&gt; 驱动——它是一个复杂的基础设施，会被编译进每一个 Go 二进制文件中。&lt;/p&gt;
&lt;p&gt;这是本系列的第一篇文章，我们将从内部探究 Go 运行时。我们会研究 &lt;strong&gt;调度器（scheduler）&lt;/strong&gt; 如何将 goroutine 多路复用到操作系统线程上，&lt;strong&gt;内存分配器（memory allocator）&lt;/strong&gt; 如何实现无锁的快速路径分配，&lt;strong&gt;垃圾收集器（garbage collector）&lt;/strong&gt; 如何在减少停顿时间的同时并发运行，以及 &lt;strong&gt;系统监控器（system monitor）&lt;/strong&gt; 如何确保一切平稳运行。每个主题都将有各自深入的专门文章。&lt;/p&gt;
&lt;p&gt;但在这些机制开始工作之前，它们必须被初始化。这就是 &lt;strong&gt;引导启动（bootstrap）&lt;/strong&gt;——在操作系统启动你的二进制文件与你的 &lt;code&gt;func main()&lt;/code&gt; 获得控制权之间运行的过程。这就是我们今天要探索的内容。&lt;/p&gt;
&lt;p&gt;让我们从一个问题开始：Go 在“什么都不做”时有多快？&lt;/p&gt;
&lt;p&gt;下面是一个 C 程序，它什么都不做：&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;int&lt;/span&gt; &lt;span style="color:#000"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;return&lt;/span&gt; &lt;span style="color:#1c01ce"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是对应的 Go 程序：&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;package&lt;/span&gt; &lt;span style="color:#000"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;让我们编译两者并进行比较：&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gcc -o nothing_c nothing.c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ go build -o nothing_go nothing.go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ls -lh nothing_c nothing_go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-rwxrwxr-x &lt;span style="color:#1c01ce"&gt;1&lt;/span&gt; user user 16K Feb &lt;span style="color:#1c01ce"&gt;7&lt;/span&gt; 12:05 nothing_c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-rwxrwxr-x &lt;span style="color:#1c01ce"&gt;1&lt;/span&gt; user user 1.5M Feb &lt;span style="color:#1c01ce"&gt;7&lt;/span&gt; 12:05 nothing_go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ &lt;span style="color:#a90d91"&gt;time&lt;/span&gt; ./nothing_c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;real 0m0.001s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ &lt;span style="color:#a90d91"&gt;time&lt;/span&gt; ./nothing_go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;real 0m0.002s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Go 的二进制文件几乎 &lt;strong&gt;大了 100 倍&lt;/strong&gt;，运行时间大约 &lt;strong&gt;长了一倍&lt;/strong&gt;。而且我们做的还 &lt;strong&gt;什么都不做&lt;/strong&gt;。这是怎么回事？&lt;/p&gt;</description></item><item><title>关于一道面试题的分析：Batching HTTP 请求</title><link>/posts/interview-problem-batching-req/</link><pubDate>Fri, 27 Feb 2026 02:25:02 +0800</pubDate><guid>/posts/interview-problem-batching-req/</guid><description>&lt;p&gt;最近在找工作，其中一家公司提出这道题目。&lt;/p&gt;
&lt;p&gt;背景：&lt;code&gt;FacesDetact()&lt;/code&gt; 只能串行调用，现在希望为程序添加批量处理功能，但不允许设置 delay 时间窗口，来一个请求，处理一个请求&lt;/p&gt;
&lt;p&gt;分析：请求将会乱序到达，如果不设置数量或时间方面的窗口，其实程序需要处理的目标是积压态的网络请求（协程）&lt;/p&gt;
&lt;p&gt;思路：如果需要对分散且独立到达的事件（参RxTS）做批量处理，其中必然需要有一个收束的阶段。如果能意识到这种现象的存在，最好是能意识到，可以针对该渠道做 batching 处理。在积压出现的时候，把被积压的请求进行批量取出，批量调用，然后返回&lt;/p&gt;
&lt;p&gt;当时没有回答得很好，在处理请求装饰器的时候手忙脚乱，请求可以收拢，但生命周期如何管理呢？可能还是常见的编程范式用多了，哈哈，后来和 GPT 聊天，它虽然没有给出正确的答案，但它对 channel 的熟练运用到是给了我启发&lt;/p&gt;
&lt;p&gt;Go 有「share memory by communicating」，我们可以控制权逆转，让我们的 handler 陷入 &amp;lt;-chan 的等待状态（当时是预期进行接口 HiJack）&lt;/p&gt;
&lt;p&gt;后来想想，这不就是批量扇出扇入吗？查了下资料，的确是几乎完全一致的题目&lt;/p&gt;
&lt;p&gt;下附草稿解答&lt;/p&gt;


 


&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;display:grid;"&gt;&lt;code class="language-golang" data-lang="golang"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;package&lt;/span&gt; &lt;span style="color:#000"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;encoding/json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;math&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;sync&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#c41a16"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 10&lt;/span&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 11&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 12&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 13&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;HandleFunc&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;/faces:detact&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;FacesDetactHandler&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 14&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;HandleFunc&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;/faces:detactv2&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;FacesDetactHandlerV2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 15&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 16&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;const&lt;/span&gt; &lt;span style="color:#000"&gt;listenAt&lt;/span&gt; = &lt;span style="color:#c41a16"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 17&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;fmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Printf&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;serve at %s\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;listenAt&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 18&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;ListenAndServe&lt;/span&gt;(&lt;span style="color:#000"&gt;listenAt&lt;/span&gt;, &lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;DefaultServeMux&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 19&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 20&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 21&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;fmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Printf&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;http.ListenAndServe failed: %+v\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 22&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 23&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 24&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 25&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;Image&lt;/span&gt; []&lt;span style="color:#a90d91"&gt;byte&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 26&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 27&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;Face&lt;/span&gt; &lt;span style="color:#a90d91"&gt;struct&lt;/span&gt;{} &lt;span style="color:#177500"&gt;/* position etc. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 28&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 29&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;DetactResult&lt;/span&gt; &lt;span style="color:#a90d91"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 30&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;Faces&lt;/span&gt; []&lt;span style="color:#000"&gt;Face&lt;/span&gt; &lt;span style="color:#c41a16"&gt;`json:&amp;#34;faces&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 31&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 32&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 33&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetactHandler&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt; &lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;ResponseWriter&lt;/span&gt;, &lt;span style="color:#000"&gt;r&lt;/span&gt; &lt;span style="color:#000"&gt;*&lt;/span&gt;&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;Request&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 34&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;Req&lt;/span&gt; &lt;span style="color:#a90d91"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 35&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;Image&lt;/span&gt; &lt;span style="color:#000"&gt;Image&lt;/span&gt; &lt;span style="color:#c41a16"&gt;`json:&amp;#34;image&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 36&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 37&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;req&lt;/span&gt; &lt;span style="color:#000"&gt;Req&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 38&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#a90d91"&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 39&lt;/span&gt;&lt;span&gt;	{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 40&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;json&lt;/span&gt;.&lt;span style="color:#000"&gt;NewDecoder&lt;/span&gt;(&lt;span style="color:#000"&gt;r&lt;/span&gt;.&lt;span style="color:#000"&gt;Body&lt;/span&gt;).&lt;span style="color:#000"&gt;Decode&lt;/span&gt;(&lt;span style="color:#000"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#000"&gt;req&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 41&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 42&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#000"&gt;w&lt;/span&gt;.&lt;span style="color:#000"&gt;WriteHeader&lt;/span&gt;(&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;StatusBadRequest&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 43&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#000"&gt;fmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Fprintf&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt;, &lt;span style="color:#c41a16"&gt;&amp;#34;error: %+v&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 44&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#a90d91"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 45&lt;/span&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 46&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 47&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 48&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;result&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetact&lt;/span&gt;([]&lt;span style="color:#000"&gt;Image&lt;/span&gt;{&lt;span style="color:#000"&gt;req&lt;/span&gt;.&lt;span style="color:#000"&gt;Image&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 49&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 50&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;json&lt;/span&gt;.&lt;span style="color:#000"&gt;NewEncoder&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt;).&lt;span style="color:#000"&gt;Encode&lt;/span&gt;(&lt;span style="color:#000"&gt;result&lt;/span&gt;[&lt;span style="color:#1c01ce"&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 51&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 52&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 53&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;QueueItem&lt;/span&gt; &lt;span style="color:#a90d91"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 54&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;Image&lt;/span&gt; &lt;span style="color:#000"&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 55&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;ResultWriteTo&lt;/span&gt; &lt;span style="color:#a90d91"&gt;chan&lt;/span&gt;&lt;span style="color:#000"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#000"&gt;DetactResult&lt;/span&gt; &lt;span style="color:#177500"&gt;// FIXME 可以根据情况分析有没有必要配置 len=1 的 buffer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 56&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 57&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 58&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;queue&lt;/span&gt; &lt;span style="color:#a90d91"&gt;chan&lt;/span&gt; &lt;span style="color:#000"&gt;QueueItem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 59&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 60&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetactHandlerV2Initial&lt;/span&gt; = &lt;span style="color:#000"&gt;sync&lt;/span&gt;.&lt;span style="color:#000"&gt;OnceFunc&lt;/span&gt;(&lt;span style="color:#a90d91"&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 61&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;const&lt;/span&gt; &lt;span style="color:#000"&gt;maxBatchSize&lt;/span&gt; = &lt;span style="color:#1c01ce"&gt;128&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 62&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;queue&lt;/span&gt; = &lt;span style="color:#a90d91"&gt;make&lt;/span&gt;(&lt;span style="color:#a90d91"&gt;chan&lt;/span&gt; &lt;span style="color:#000"&gt;QueueItem&lt;/span&gt;, &lt;span style="color:#000"&gt;maxBatchSize&lt;/span&gt;&lt;span style="color:#000"&gt;+&lt;/span&gt;&lt;span style="color:#1c01ce"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 63&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;go&lt;/span&gt; &lt;span style="color:#a90d91"&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 64&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 65&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; &lt;span style="color:#000"&gt;queueIten&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;range&lt;/span&gt; &lt;span style="color:#000"&gt;queue&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 66&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;todo&lt;/span&gt; = []&lt;span style="color:#000"&gt;QueueItem&lt;/span&gt;{&lt;span style="color:#000"&gt;queueIten&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 67&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;queue&lt;/span&gt;) &amp;gt; &lt;span style="color:#1c01ce"&gt;0&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 68&lt;/span&gt;&lt;span&gt;					&lt;span style="color:#000"&gt;consumeQuota&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;maxBatchSize&lt;/span&gt; &lt;span style="color:#000"&gt;-&lt;/span&gt; &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;todo&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 69&lt;/span&gt;&lt;span&gt;					&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;consumeQuota&lt;/span&gt; &amp;gt; &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;queue&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 70&lt;/span&gt;&lt;span&gt;						&lt;span style="color:#000"&gt;consumeQuota&lt;/span&gt; = &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;queue&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 71&lt;/span&gt;&lt;span&gt;					}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 72&lt;/span&gt;&lt;span&gt;					&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; &lt;span style="color:#000"&gt;i&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#1c01ce"&gt;0&lt;/span&gt;; &lt;span style="color:#000"&gt;i&lt;/span&gt; &amp;lt; &lt;span style="color:#000"&gt;consumeQuota&lt;/span&gt;; &lt;span style="color:#000"&gt;i&lt;/span&gt;&lt;span style="color:#000"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 73&lt;/span&gt;&lt;span&gt;						&lt;span style="color:#000"&gt;todo&lt;/span&gt; = &lt;span style="color:#a90d91"&gt;append&lt;/span&gt;(&lt;span style="color:#000"&gt;todo&lt;/span&gt;, &lt;span style="color:#000"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#000"&gt;queue&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 74&lt;/span&gt;&lt;span&gt;					}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 75&lt;/span&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 76&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 77&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;args&lt;/span&gt; []&lt;span style="color:#000"&gt;Image&lt;/span&gt; = &lt;span style="color:#a90d91"&gt;make&lt;/span&gt;([]&lt;span style="color:#000"&gt;Image&lt;/span&gt;, &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;todo&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 78&lt;/span&gt;&lt;span&gt;				{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 79&lt;/span&gt;&lt;span&gt;					&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; &lt;span style="color:#000"&gt;index&lt;/span&gt;, &lt;span style="color:#000"&gt;req&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;range&lt;/span&gt; &lt;span style="color:#000"&gt;todo&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 80&lt;/span&gt;&lt;span&gt;						&lt;span style="color:#000"&gt;args&lt;/span&gt;[&lt;span style="color:#000"&gt;index&lt;/span&gt;] = &lt;span style="color:#000"&gt;req&lt;/span&gt;.&lt;span style="color:#000"&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 81&lt;/span&gt;&lt;span&gt;					}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 82&lt;/span&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 83&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 84&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#177500"&gt;// enable to check how many req has been batching&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 85&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#177500"&gt;// fmt.Printf(&amp;#34;args.length = %d\n&amp;#34;, len(args))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 86&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#000"&gt;results&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetact&lt;/span&gt;(&lt;span style="color:#000"&gt;args&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 87&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 88&lt;/span&gt;&lt;span&gt;				&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; &lt;span style="color:#000"&gt;index&lt;/span&gt;, &lt;span style="color:#000"&gt;result&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;range&lt;/span&gt; &lt;span style="color:#000"&gt;results&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 89&lt;/span&gt;&lt;span&gt;					&lt;span style="color:#000"&gt;todo&lt;/span&gt;[&lt;span style="color:#000"&gt;index&lt;/span&gt;].&lt;span style="color:#000"&gt;ResultWriteTo&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#000"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 90&lt;/span&gt;&lt;span&gt;				}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 91&lt;/span&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 92&lt;/span&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#e5e5e5"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 93&lt;/span&gt;&lt;span&gt;	}()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 94&lt;/span&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 95&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 96&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetactHandlerV2&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt; &lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;ResponseWriter&lt;/span&gt;, &lt;span style="color:#000"&gt;r&lt;/span&gt; &lt;span style="color:#000"&gt;*&lt;/span&gt;&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;Request&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 97&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;type&lt;/span&gt; &lt;span style="color:#000"&gt;Req&lt;/span&gt; &lt;span style="color:#a90d91"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 98&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;Image&lt;/span&gt; &lt;span style="color:#000"&gt;Image&lt;/span&gt; &lt;span style="color:#c41a16"&gt;`json:&amp;#34;image&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 99&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;100&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;req&lt;/span&gt; &lt;span style="color:#000"&gt;Req&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;101&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#a90d91"&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;102&lt;/span&gt;&lt;span&gt;	{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;103&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;json&lt;/span&gt;.&lt;span style="color:#000"&gt;NewDecoder&lt;/span&gt;(&lt;span style="color:#000"&gt;r&lt;/span&gt;.&lt;span style="color:#000"&gt;Body&lt;/span&gt;).&lt;span style="color:#000"&gt;Decode&lt;/span&gt;(&lt;span style="color:#000"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#000"&gt;req&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;104&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;105&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#000"&gt;w&lt;/span&gt;.&lt;span style="color:#000"&gt;WriteHeader&lt;/span&gt;(&lt;span style="color:#000"&gt;http&lt;/span&gt;.&lt;span style="color:#000"&gt;StatusBadRequest&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;106&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#000"&gt;fmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Fprintf&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt;, &lt;span style="color:#c41a16"&gt;&amp;#34;error: %+v&amp;#34;&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;107&lt;/span&gt;&lt;span&gt;			&lt;span style="color:#a90d91"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;108&lt;/span&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;109&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;110&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;111&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;FacesDetactHandlerV2Initial&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;112&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;113&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;resultQueue&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;make&lt;/span&gt;(&lt;span style="color:#a90d91"&gt;chan&lt;/span&gt; &lt;span style="color:#000"&gt;DetactResult&lt;/span&gt;, &lt;span style="color:#1c01ce"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;114&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;115&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;queueReq&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;QueueItem&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;116&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;Image&lt;/span&gt;: &lt;span style="color:#000"&gt;req&lt;/span&gt;.&lt;span style="color:#000"&gt;Image&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;117&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#000"&gt;ResultWriteTo&lt;/span&gt;: &lt;span style="color:#000"&gt;resultQueue&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;118&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;119&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;120&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;queue&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#000"&gt;queueReq&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;121&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;122&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;result&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#000"&gt;resultQueue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;123&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;124&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;json&lt;/span&gt;.&lt;span style="color:#000"&gt;NewEncoder&lt;/span&gt;(&lt;span style="color:#000"&gt;w&lt;/span&gt;).&lt;span style="color:#000"&gt;Encode&lt;/span&gt;(&lt;span style="color:#000"&gt;result&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;125&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;126&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;127&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;var&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetactLocker&lt;/span&gt; &lt;span style="color:#000"&gt;sync&lt;/span&gt;.&lt;span style="color:#000"&gt;Mutex&lt;/span&gt; &lt;span style="color:#177500"&gt;// 以防外部函数错误并行调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;128&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;129&lt;/span&gt;&lt;span&gt;&lt;span style="color:#177500"&gt;// FacesDetact 执行图像序列处理，因 GPU 底层限制，本函数不支持并行调用，请注意&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;130&lt;/span&gt;&lt;span&gt;&lt;span style="color:#177500"&gt;// images 与 results 为一对一的关系。本函数有冷启动时间，处理时间随图像数量近双曲线&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;131&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetact&lt;/span&gt;(&lt;span style="color:#000"&gt;images&lt;/span&gt; []&lt;span style="color:#000"&gt;Image&lt;/span&gt;) (&lt;span style="color:#000"&gt;results&lt;/span&gt; []&lt;span style="color:#000"&gt;DetactResult&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;132&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;images&lt;/span&gt;) &lt;span style="color:#000"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#1c01ce"&gt;0&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;133&lt;/span&gt;&lt;span&gt;		&lt;span style="color:#a90d91"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;134&lt;/span&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;135&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;FacesDetactLocker&lt;/span&gt;.&lt;span style="color:#000"&gt;Lock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;136&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;defer&lt;/span&gt; &lt;span style="color:#000"&gt;FacesDetactLocker&lt;/span&gt;.&lt;span style="color:#000"&gt;Unlock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;137&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;138&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;results&lt;/span&gt; = &lt;span style="color:#a90d91"&gt;make&lt;/span&gt;([]&lt;span style="color:#000"&gt;DetactResult&lt;/span&gt;, &lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;images&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;139&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;140&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#000"&gt;time&lt;/span&gt;.&lt;span style="color:#000"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#000"&gt;time&lt;/span&gt;.&lt;span style="color:#000"&gt;Duration&lt;/span&gt;(&lt;span style="color:#000"&gt;math&lt;/span&gt;.&lt;span style="color:#000"&gt;Pow&lt;/span&gt;(&lt;span style="color:#a90d91"&gt;float64&lt;/span&gt;(&lt;span style="color:#a90d91"&gt;len&lt;/span&gt;(&lt;span style="color:#000"&gt;images&lt;/span&gt;)), &lt;span style="color:#1c01ce"&gt;0.1&lt;/span&gt;)) &lt;span style="color:#000"&gt;*&lt;/span&gt; &lt;span style="color:#1c01ce"&gt;100&lt;/span&gt; &lt;span style="color:#000"&gt;*&lt;/span&gt; &lt;span style="color:#000"&gt;time&lt;/span&gt;.&lt;span style="color:#000"&gt;Millisecond&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;141&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;142&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#a90d91"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;143&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在面试结束后重写优化以及调试的时候，观察数据会很有趣，因为机械压测带来的流量（like wrk but wrk2）很有规律，联合起 poolSize、具体耗时曲线、请求到达频次、放行逻辑，它们组成了一个可供线性规划的区域。&lt;/p&gt;</description></item><item><title>【翻译】软件工程中的认知负担（认知负荷才是关键）</title><link>/posts/cognitive-load/</link><pubDate>Sun, 07 Sep 2025 12:09:00 +0800</pubDate><guid>/posts/cognitive-load/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这篇译文是 &lt;a href="https://github.com/n1k0ver3E"&gt;n1k0ver3E&lt;/a&gt; 和我一起 &lt;a href="https://github.com/zakirullin/cognitive-load/pull/52"&gt;翻译&lt;/a&gt; 的，这里存档一下，他也完成了很多细致的审校工作，在这里对他表示感谢。如果读者想要阅读，推荐查看 &lt;a href="https://github.com/zakirullin/cognitive-load/blob/main/README.zh-cn.md"&gt;最新的版本&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="简介introduction"&gt;简介(Introduction)&lt;/h2&gt;
&lt;p&gt;这世上充斥着各种流行术语与“最佳实践”，但大多数最终都失灵了。我们需要更基础、更不可能出错的东西。&lt;/p&gt;
&lt;p&gt;有时我们在阅读代码时会感到困惑。困惑消耗时间和金钱。困惑源于过高的“认知负荷”。它不是某种花哨的抽象概念，而是&lt;strong&gt;人类的一种基本约束&lt;/strong&gt;。它不是臆想出来的，它的确存在，而且我们能真切感受到。&lt;/p&gt;
&lt;p&gt;鉴于我们在阅读与理解代码上所花费的时间远多于书写代码所花费的，我们应当持续地自省：我们是否正在把过多的认知负荷添加到代码中。&lt;/p&gt;
&lt;h2 id="认知负荷cognitive-load"&gt;认知负荷(Cognitive load)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;认知负荷是指开发者为了完成一项任务需要动多少脑子。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;阅读代码时，你会把变量的取值、控制流逻辑、调用序列等“装”进脑子里。普通人的工作记忆大约能同时容纳&lt;a href="https://github.com/zakirullin/cognitive-load/issues/16"&gt;四个这样的信息块&lt;/a&gt;。一旦认知负荷接近这个阈值，理解就会变得困难得多。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;假设我们被要求去修补一个完全陌生的项目。有人告诉我们，之前有位非常聪明的开发者贡献过：用了很多酷炫的架构、花哨的库、时髦的技术。也就是说，&lt;strong&gt;作者为我们制造了极高的认知负荷。&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;我们应该尽可能降低项目中的认知负荷。&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;blockquote&gt;
&lt;p&gt;我们会以一种非正式的方式使用“认知负荷”这个术语；有时它与认知负荷的科学概念一致，但我们并不确切知道在哪些地方一致、哪些地方不一致。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="认知负荷的类型types-of-cognitive-load"&gt;认知负荷的类型(Types of cognitive load)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;内在负荷(Intrinsic)&lt;/strong&gt;——由任务本身的固有难度引起。它不可消减，是软件开发的核心所在。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;外在负荷(Extraneous)&lt;/strong&gt;——由信息的呈现方式引入。由与任务不直接相关的因素造成，比如“聪明作者”的各种癖好。它可以被大幅削减。本文将聚焦于这种外在认知负荷。&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;下面直接看一些外在认知负荷的具体、可操作的例子。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;我们将这样标注认知负荷的程度：&lt;br&gt;
&lt;code&gt;🧠&lt;/code&gt;：工作记忆刚刚清空，认知负荷为零&lt;br&gt;
&lt;code&gt;🧠++&lt;/code&gt;：工作记忆里已经有两个事实，认知负荷上升&lt;br&gt;
&lt;code&gt;🤯&lt;/code&gt;：认知过载，超过 4 个事实&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们的大脑远比这复杂且尚未被充分理解，但这个简化模型足以用来说明问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="复杂的条件控制complex-conditionals"&gt;复杂的条件控制(Complex conditionals)&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;val&lt;/span&gt; &amp;gt; &lt;span style="color:#000"&gt;someConstant&lt;/span&gt; &lt;span style="color:#177500"&gt;// 🧠+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; (&lt;span style="color:#000"&gt;condition2&lt;/span&gt; &lt;span style="color:#000"&gt;||&lt;/span&gt; &lt;span style="color:#000"&gt;condition3&lt;/span&gt;) &lt;span style="color:#177500"&gt;// 🧠+++, 前置条件需为 true，c2 或 c3 必须其一为 true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; (&lt;span style="color:#000"&gt;condition4&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; !&lt;span style="color:#000"&gt;condition5&lt;/span&gt;) { &lt;span style="color:#177500"&gt;// 🤯, 到这一步我们基本已经被绕晕了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用有意义的中间变量重构：&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;isValid&lt;/span&gt; = &lt;span style="color:#000"&gt;val&lt;/span&gt; &amp;gt; &lt;span style="color:#000"&gt;someConstant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;isAllowed&lt;/span&gt; = &lt;span style="color:#000"&gt;condition2&lt;/span&gt; &lt;span style="color:#000"&gt;||&lt;/span&gt; &lt;span style="color:#000"&gt;condition3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;isSecure&lt;/span&gt; = &lt;span style="color:#000"&gt;condition4&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; !&lt;span style="color:#000"&gt;condition5&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#177500"&gt;// 🧠，无需死记条件表达式，变量名已自描述&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;isValid&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#000"&gt;isAllowed&lt;/span&gt; &lt;span style="color:#000"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#000"&gt;isSecure&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="多层嵌套的-if-判断nested-ifs"&gt;多层嵌套的 if 判断(Nested ifs)&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;isValid&lt;/span&gt; { &lt;span style="color:#177500"&gt;// 🧠+, 嵌套代码仅适用于有效输入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;isSecure&lt;/span&gt; { &lt;span style="color:#177500"&gt;// 🧠++, 仅对有效且安全的输入执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;stuff&lt;/span&gt; &lt;span style="color:#177500"&gt;// 🧠+++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对比一下“提前返回”式的：&lt;/p&gt;</description></item><item><title>为什么再次书写博客</title><link>/posts/why/</link><pubDate>Tue, 10 Dec 2024 01:17:13 +0800</pubDate><guid>/posts/why/</guid><description>&lt;p&gt;上一篇博客说到，看到互联网，所思所想。&lt;/p&gt;
&lt;p&gt;背后的原因其实非常多。这涉及到我对“搭子”的理解，对互联网世界话语权的认识，对当今网络人群的见识。&lt;/p&gt;
&lt;p&gt;最近几天一直在写日记，终于在昨天又搭建起这个博客。&lt;/p&gt;
&lt;p&gt;其实我的一些想法在中间也陆陆续续在 Github 的 issue 区记录过。&lt;/p&gt;
&lt;p&gt;前段时间又觉得，今天这样，明天那样，十年之后不知道什么样。既然以后可能对今日之事理所当然，那么为什么不在今天这个当下就记录下当局人的所思所想？&lt;/p&gt;
&lt;p&gt;今晚就先写到这里吧，后面再修改。&lt;/p&gt;</description></item><item><title>似乎是时候重启博客</title><link>/posts/reload/</link><pubDate>Mon, 09 Dec 2024 01:12:53 +0800</pubDate><guid>/posts/reload/</guid><description>&lt;p&gt;翻找记录，博客已经写了不止一次，最近看到互联网，所思所想。&lt;/p&gt;
&lt;p&gt;还是再写起来吧。&lt;/p&gt;
&lt;p&gt;但初心是再一次地新。&lt;/p&gt;</description></item></channel></rss>