<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on </title>
    <link>http://blog.chuckchan.top/posts/</link>
    <description>Recent content in Posts on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-cn</language>
    <copyright>© 2026 Chuck Chan</copyright>
    <lastBuildDate>Sun, 24 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://blog.chuckchan.top/posts/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>VibeCoding个人配置</title>
      <link>http://blog.chuckchan.top/posts/vibecoding/vibecoding%E4%B8%AA%E4%BA%BA%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/vibecoding/vibecoding%E4%B8%AA%E4%BA%BA%E9%85%8D%E7%BD%AE/</guid>
      <description>&lt;blockquote&gt;&lt;p&gt;工欲善其事，必先利其器&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;status line.sh&lt;/p&gt;&#xA;&lt;p&gt;Superpowers&lt;/p&gt;&#xA;&lt;p&gt;Notification&lt;/p&gt;&#xA;&lt;p&gt;cc switch&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>过目不忘：CLAUDE</title>
      <link>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E8%BF%87%E7%9B%AE%E4%B8%8D%E5%BF%98claude/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E8%BF%87%E7%9B%AE%E4%B8%8D%E5%BF%98claude/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;核心概念&#xA;    &lt;div id=&#34;核心概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a0%b8%e5%bf%83%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;CLAUDE.md是Claude Code的核心配置文件，它相当于项目的**”说明书”**，告诉Claude如何理解和处理你的代码库。一个好的CLAUDE.md可以显著提升AI的理解准确性和工作效率。我结合自己的项目来说明如何写一个配置。&lt;/p&gt;&#xA;&lt;p&gt;其作用如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;上下文设置&lt;/strong&gt;：为Claude提供项目背景、技术栈、架构信息&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;约束定义&lt;/strong&gt;：设定开发规范、代码风格、质量标准&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;任务指导&lt;/strong&gt;：提供明确的执行指令和优先级&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;知识传承&lt;/strong&gt;：保存项目的重要决策和设计理念&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;为什么重要？&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;减少沟通成本&lt;/strong&gt;：避免重复解释项目背景&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;提升准确性&lt;/strong&gt;：使Claude更好地理解你的意图&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;保持一致性&lt;/strong&gt;：确保所有修改都符合项目规范，在团队合作中保持代码的一致性&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;加速开发&lt;/strong&gt;：减少调试和返工时间&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;工作原理&#xA;    &lt;div id=&#34;工作原理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a5%e4%bd%9c%e5%8e%9f%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;当你在项目目录启动 Claude Code 时，发生的“记忆系统初始化”过程如下图所示。&lt;/p&gt;&#xA;&lt;img src=&#34;https://static001.geekbang.org/resource/image/d1/c0/d1a847a91839b94cdd4dc7aac5fdacc0.jpg?wh=2548x1574&#34; style=&#34;zoom: 25%;&#34; /&gt;&#xA;&lt;p&gt;CLAUDE.md 的内容会&lt;strong&gt;每次对话都加载&lt;/strong&gt;，所以要&lt;strong&gt;精简&lt;/strong&gt;。把“每次都需要”的内容放这里，把“偶尔需要”的内容放到 Skills 或文档里。&lt;/p&gt;&#xA;&lt;p&gt;Claude Code 支持五个层级的记忆，就像洋葱一样，从外到内，按层级结构组织——高层级的文件优先加载，为底层文件提供基础：&lt;/p&gt;&#xA;&lt;img src=&#34;https://static001.geekbang.org/resource/image/77/35/77cc990d2b8c5d906e82e9abd17c3835.jpg?wh=4108x1868&#34; style=&#34;zoom: 15%;&#34; /&gt;&#xA;&lt;p&gt;其中每个层级都有其用途及使用场景，如下所示：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;记忆类型&lt;/th&gt;&#xA;          &lt;th&gt;位置&lt;/th&gt;&#xA;          &lt;th&gt;用途&lt;/th&gt;&#xA;          &lt;th&gt;使用场景&lt;/th&gt;&#xA;          &lt;th&gt;共享范围&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;企业策略&lt;/td&gt;&#xA;          &lt;td&gt;macOS:/Library/ApplicationSupport/ClaudeCode/CLAUDE.md&lt;br /&gt;Linux: /etc/claude-code/CLAUDE.md&lt;br /&gt;Windows: C:\Program Files\ClaudeCode\CLAUDE.md&lt;/td&gt;&#xA;          &lt;td&gt;组织级指令，由 IT/Devops管理&lt;/td&gt;&#xA;          &lt;td&gt;公司编码标准、安全策略、合规要求&lt;/td&gt;&#xA;          &lt;td&gt;组织内所有用户&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;项目记忆&lt;/td&gt;&#xA;          &lt;td&gt;./CLAUDE.md或者./claude/CLAUDE.md（&lt;strong&gt;必须提交到git&lt;/strong&gt;）&lt;/td&gt;&#xA;          &lt;td&gt;团队共享的项目指令&lt;/td&gt;&#xA;          &lt;td&gt;项目架构，编码标准，常用工作流&lt;/td&gt;&#xA;          &lt;td&gt;通关版本管理与团队成员共享&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;模块记忆&lt;/td&gt;&#xA;          &lt;td&gt;./claude/rules/*.md&lt;/td&gt;&#xA;          &lt;td&gt;模块化的、特定主题的项目指令&lt;/td&gt;&#xA;          &lt;td&gt;语言特定指南、测试规范、API标准&lt;/td&gt;&#xA;          &lt;td&gt;通关版本管理与团队成员共享&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;用户记忆&lt;/td&gt;&#xA;          &lt;td&gt;~/.claude/CLAUDE.md&lt;/td&gt;&#xA;          &lt;td&gt;跨所有项目的个人偏好&lt;/td&gt;&#xA;          &lt;td&gt;代码风格偏好、个人工具快捷方式&lt;/td&gt;&#xA;          &lt;td&gt;仅自己&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;项目本地&lt;/td&gt;&#xA;          &lt;td&gt;./CLAUDE.local.md（&lt;strong&gt;记得把他加到.gitignore&lt;/strong&gt;）&lt;/td&gt;&#xA;          &lt;td&gt;跨所有项目的个人偏好&lt;/td&gt;&#xA;          &lt;td&gt;你的沙箱URL、偏好的测试数据&lt;/td&gt;&#xA;          &lt;td&gt;仅自己&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;基础结构&#xA;    &lt;div id=&#34;基础结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9f%ba%e7%a1%80%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;项目记忆一般来说是整个开发过程中最常用的“说明书”了，一个完整的项目CLAUDE.md文件包含以下几个部分：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>gmview设计</title>
      <link>http://blog.chuckchan.top/posts/golang/gmview%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/gmview%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;背景&#xA;    &lt;div id=&#34;背景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%83%8c%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;profobuf公共大仓与本地引用的protobuf官方库依赖的底层的grpc库会产生冲突，因为不同版本的grpc库的函数签名不同，新版本的不兼容历史版本（相信不少人都遇过底层依赖etcd函数报错的问题，真是苦天下久诶），所以萌生了一个go mod依赖可视化的想法。其实早在2024年就已经实现了一版，但苦于工作繁忙没有继续完善，现在有时间了利用AI重新完善一版。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;设计&#xA;    &lt;div id=&#34;设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;gmview意为 go mod view，即go引用库的可视化视图，其核心步骤就两个：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;获取当前go引用库的依赖关系&lt;/li&gt;&#xA;&lt;li&gt;在页面中展示这个依赖关系&lt;/li&gt;&#xA;&lt;/ol&gt;</description>
      
    </item>
    
    <item>
      <title>git删除远程文件</title>
      <link>http://blog.chuckchan.top/posts/tool/git%E5%88%A0%E9%99%A4%E8%BF%9C%E7%A8%8B%E6%96%87%E4%BB%B6/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/git%E5%88%A0%E9%99%A4%E8%BF%9C%E7%A8%8B%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;why&#xA;    &lt;div id=&#34;why&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#why&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;需要删除远程仓库的一些文件，例如一些本地文件&lt;/li&gt;&#xA;&lt;li&gt;不小心把一些ide配置文件发到远程git仓库。例如 .idea   .vscode&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;how&#xA;    &lt;div id=&#34;how&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#how&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;针对第一个种情况，需要删除本地文件&amp;amp;远程文件&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#删除本地 &amp;amp; 远程&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git rm 文件 //本地中该文件会被删除&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git rm -r 文件夹 //删除文件夹&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;删除某个文件&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git push &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;如果是像第二种情况，只是不想把ide文件传上去，在本地还是需要保存的，那么只删远程文件即可&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#删除远程&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git rm --cached 文件 //本地中该文件不会被删除&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git rm -r  --cached  文件夹 //删除文件夹&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;删除某个文件&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git push &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;当然，记得新增一个.gitignore，防止再次将.idea上传。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>触类旁通：Skill</title>
      <link>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E8%A7%A6%E7%B1%BB%E6%97%81%E9%80%9Askill/</link>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E8%A7%A6%E7%B1%BB%E6%97%81%E9%80%9Askill/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Skill的背景&#xA;    &lt;div id=&#34;skill的背景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#skill%e7%9a%84%e8%83%8c%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;每个公司每个团队都与自己的一套规范，例如代码风格规范、API设计规范、安全审查清单规范、部署流程规范，这些规则并不复杂，但是数量很多。开发者通常不可能将他们全部记忆下来，大部分工程师的做法是：需要时再查阅。&lt;/p&gt;&#xA;&lt;p&gt;如果我们把 Claude 当作真正的工程助手，它也会面临同样的问题。最直接的做法，是把所有团队规范写进 CLAUDE.md，让模型每次对话都读取这些内容。短期看这是可行的。但当知识规模扩大到几十页甚至上百页时，问题就出现了——每一次对话都在为“可能用不到的知识”支付上下文成本。这不仅消耗 token，更重要的是，它会稀释模型的注意力。真正需要用到的规则，反而&lt;strong&gt;淹没在冗余信息里&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;Skills的出现解决了这一问题。Skills 并不是简单的“能力扩展机制”，它本质上是一种&lt;strong&gt;按需加载&lt;/strong&gt;的认知结构。与其把所有知识常驻在上下文中，不如把它们封装成可独立触发的能力单元。当模型判断当前任务涉及某个特定领域时，再加载对应的知识与操作流程。Skills 解决的核心问题是，在有限的上下文窗口中，让 Agent 在正确的时刻拥有正确的领域知识。&lt;/p&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;对于企业来说，把专业流程、领域知识和行动判断封装成可复用的能力单元，然后让智能体按需加载和调用，这是一种让通用模型具备专业化、按需调用能力的通用设计模式。类似 Skills 的模块化能力已经被用于数据分析、校验、报告生成等任务，把自然语言指令转化成结构化的专业工作流；也有技术方案将企业组件库、开发规范等封装成“技能包”，让模型自动发现、理解并正确应用这些业务能力。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;正因为“模型调度能力”和“可操作知识”的重要性，Skills 已经逐渐脱离了 Claude 的语境，成了 Agent 生态中的通用概念。“技能化”思路正在从 Claude 系统扩展到其他智能体平台，以及 AI 赋能的工程工具中。在 Claude 发布的 Agent Skills 公用仓库中，集成了大量可复用的能力。Coze 也推出了技能商店，为 Coze 智能体生态提供即插即用的能力组件。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;Skill的类型&#xA;    &lt;div id=&#34;skill的类型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#skill%e7%9a%84%e7%b1%bb%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;从工程角度，Skill 内容分为两类，&lt;strong&gt;参考型&lt;/strong&gt;和&lt;strong&gt;任务型&lt;/strong&gt;。参考型 Skill 影响“&lt;em&gt;怎么做&lt;/em&gt;”，任务型 Skill 决定“&lt;em&gt;做什么&lt;/em&gt;”。前者是语义环境，后者是具体行动。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;参考型&#xA;    &lt;div id=&#34;参考型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%82%e8%80%83%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;参考型 Skill 更像组织的行为规范层。它定义“在这个世界里，什么是正确的做法”——例如 &lt;em&gt;API 设计标准&lt;/em&gt;、&lt;em&gt;代码风格&lt;/em&gt;、&lt;em&gt;错误处理约定&lt;/em&gt;。这类 Skill 通常由模型根据语义&lt;strong&gt;自动判断&lt;/strong&gt;是否加载，它不主导行动，而是塑造行动的方式。它属于“世界规则”。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>防微杜渐：Hook</title>
      <link>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E9%98%B2%E5%BE%AE%E6%9D%9C%E6%B8%90hook/</link>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E9%98%B2%E5%BE%AE%E6%9D%9C%E6%B8%90hook/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Hook出现背景&#xA;    &lt;div id=&#34;hook出现背景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hook%e5%87%ba%e7%8e%b0%e8%83%8c%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;如果你有 Web 开发经验，你一定熟悉中间件（Middleware）的概念。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;请求 → 中间件1 → 中间件2 → 中间件3 → 处理函数 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 ↓ 认证、日志、限流&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;中间件在请求到达最终处理函数之前插入检查和处理，实现横切关注点（Cross-cutting Concerns）。这些逻辑不属于任何一个业务功能，但又必须贯穿所有请求——认证要每个接口都检查，日志要每个操作都记录，限流要每个入口都控制。&lt;/p&gt;&#xA;&lt;p&gt;Claude Code 的 Hooks 机制与此异曲同工，但它针对的不是 HTTP 请求，而是  AI Agent 的工具调用。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;用户请求 → Claude 决策 → [PreToolUse Hook] → 工具执行 → [PostToolUse Hook] → 响应 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                               ↓ 权限检查、拦截                 ↓格式化、验证、日志&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;Hooks 是 AI 助手的中间件——拦截、监控、增强每一次交互。这个类比不仅是形象上的相似。Web 中间件解决的核心问题是“业务代码不应该操心安全和日志”，Hooks 解决的核心问题也一样——Claude 不应该操心格式化和权限检查，它只管写好代码就行。安全防线、质量守卫、审计日志，全部由 Hooks 在“幕后”自动完成。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;Hook事件&#xA;    &lt;div id=&#34;hook事件&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hook%e4%ba%8b%e4%bb%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;截至 2026 年 3 月，根据  Anthropic 官方文档，Claude Code 支持  17 种 Hook 事件，覆盖了从会话启动到结束的完整生命周期：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Hello World</title>
      <link>http://blog.chuckchan.top/posts/hello-world/</link>
      <pubDate>Wed, 29 Apr 2026 16:51:06 +0800</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/hello-world/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;你好&#xA;    &lt;div id=&#34;你好&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bd%a0%e5%a5%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;吃饭&lt;/li&gt;&#xA;&lt;li&gt;睡觉&lt;/li&gt;&#xA;&lt;li&gt;无聊&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;我好&#xA;    &lt;div id=&#34;我好&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%88%91%e5%a5%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;对&lt;/th&gt;&#xA;          &lt;th&gt;与&lt;/th&gt;&#xA;          &lt;th&gt;错&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;23&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;wera&lt;/td&gt;&#xA;          &lt;td&gt;e w er&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Sofa&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;大家好&#xA;    &lt;div id=&#34;大家好&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a4%a7%e5%ae%b6%e5%a5%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hellow world&amp;#34;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>各司其职：SubAgent</title>
      <link>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E5%90%84%E5%8F%B8%E5%85%B6%E8%81%8Csubagent/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/vibecoding/claude-code-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E6%88%98/%E5%90%84%E5%8F%B8%E5%85%B6%E8%81%8Csubagent/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;为什么需要SubAgent&#xA;    &lt;div id=&#34;为什么需要subagent&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81subagent&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;我们先从一个常见场景开启今天的内容。&lt;/p&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;某天，你让 Claude Code 帮你跑一个测试套件，结果输出了 500 行日志；然后你想让它分析一下代码结构，又输出了 200 行；接着你想让它改一个 bug……这时候，你的对话上下文已经被各种“中间过程”塞满了，真正重要的信息被淹没在茫茫的输出海洋里。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;其实，究其根本。如果你觉得 Claude Code 越用越“健忘”，并不是模型退化了，而是你的对话上下文，已经被&lt;strong&gt;一次次中间过程污染了&lt;/strong&gt;,这正是子代理要解决的&lt;strong&gt;核心问题&lt;/strong&gt;。因为只有子代理，才在系统层面天然拥有一个独立的上下文窗口。不是因为它“聪明”，不是因为它“更强”， 而是因为它是 Claude Code 里唯一一个，结构上允许“执行完即丢弃”的东西。&lt;/p&gt;&#xA;&lt;p&gt;在前面的现象里，上下文里充斥着这些内容：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;跑测试 → 500 行日志。&lt;/li&gt;&#xA;&lt;li&gt;搜索代码 → 200 行 grep。&lt;/li&gt;&#xA;&lt;li&gt;分析错误 → 一堆中间推理过程&amp;hellip;&amp;hellip;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这些信息有一个共同特征：它们对“当下执行”是必要的，但对“后续决策”是噪声。而 Claude Code 的主对话上下文是线性追加的，不会自动过期，默认“都当成重要记忆”。所以问题不是 Claude 突然不聪明了 ，而是它把临时执行数据，当成了长期决策记忆。 这在工程上，本来就一定会“炸”。&lt;/p&gt;&#xA;&lt;p&gt;而子代理，通过上下文隔离，让专业的 Agent 做专业的事儿，不是为了让 Claude 做得更多， 而是为了让 Claude &lt;strong&gt;记得更少，但记得对。&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;什么是SubAgent&#xA;    &lt;div id=&#34;什么是subagent&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%80%e4%b9%88%e6%98%afsubagent&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;SubAgent当于一个“专职小助手”，它拥有独立的：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>15. 交易树与收据树</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/15.-%E4%BA%A4%E6%98%93%E6%A0%91%E4%B8%8E%E6%94%B6%E6%8D%AE%E6%A0%91/</link>
      <pubDate>Sat, 29 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/15.-%E4%BA%A4%E6%98%93%E6%A0%91%E4%B8%8E%E6%94%B6%E6%8D%AE%E6%A0%91/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;交易树与收据树&#xA;    &lt;div id=&#34;交易树与收据树&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%ba%a4%e6%98%93%e6%a0%91%e4%b8%8e%e6%94%b6%e6%8d%ae%e6%a0%91&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;上篇文章中讲了数据结构MPT及状态树，这篇文章再来讲交易树与收据树。交易树与收据树同样基于MPT，分别用于存储区块内的交易信息与交易执行结果，是保证以太坊数据可验证性和透明性的关键组件。二者均与区块一一对应，其根哈希会被记录在区块头中，确保数据不可篡改。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;交易树&#xA;    &lt;div id=&#34;交易树&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%ba%a4%e6%98%93%e6%a0%91&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;交易树是每个区块内所有交易的结构化存储载体，本质是一棵以&lt;strong&gt;交易在区块中的序号为键&lt;/strong&gt;的 MPT。&lt;/p&gt;&#xA;&lt;p&gt;其核心作用：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;记录区块内所有交易的完整信息，包括发送方、接收方、转账金额、Gas 设置、智能合约调用数据等。&lt;/li&gt;&#xA;&lt;li&gt;生成&lt;strong&gt;交易根哈希&lt;/strong&gt;并写入区块头，任何人可通过该哈希验证区块内交易是否被篡改，也可通过Merkle Proof快速验证某笔交易是否存在于区块中。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;结构特点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;交易的索引（在区块中的序号）会被 RLP 编码后作为 MPT 的键，由于交易序号是连续的数字，其路径前缀共享的概率极低，因此交易树的 MPT 路径压缩特性几乎无法体现，但仍保留 MPT 的密码学验证能力。&lt;/li&gt;&#xA;&lt;li&gt;与状态树不同，每个区块的交易树仅包含相关的交易，不同区块的交易树不会共享节点。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;收据树&#xA;    &lt;div id=&#34;收据树&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%94%b6%e6%8d%ae%e6%a0%91&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;收据树也叫回执树，存储每笔交易执行后的结果信息，同样是基于 MPT 构建，且与交易树的节点一一对应。&lt;/p&gt;&#xA;&lt;p&gt;核心作用：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;记录交易执行的最终状态，包括交易是否成功、消耗的 Gas 量、智能合约触发的事件日志（Log）、区块哈希与交易哈希关联信息等。&lt;/li&gt;&#xA;&lt;li&gt;生成&lt;strong&gt;收据根哈希&lt;/strong&gt;写入区块头，为轻节点验证交易执行结果提供依据，比如钱包可通过收据树验证转账是否到账、智能合约事件是否触发。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;结构特点：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>16. 以太坊的共识协议</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/16.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E5%85%B1%E8%AF%86%E5%8D%8F%E8%AE%AE/</link>
      <pubDate>Sat, 29 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/16.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E5%85%B1%E8%AF%86%E5%8D%8F%E8%AE%AE/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;前言&#xA;    &lt;div id=&#34;前言&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%89%8d%e8%a8%80&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面的文章中说过比特币的出块时间在10m左右，且需要经过多个区块确认后才能认为交易已完成（一般是6个区块，主要是为了防止临时性分叉）。这也就意味着在比特币中大概要1h左右才能确保交易已完成。而以太坊的出块时间降到了15s左右，大大提升了以太坊的吞吐与效率，但是出块时间太快又会带来临时性分叉的问题，导致那些符合难度要求但没有成为最长合法链区块被抛弃，严重影响了矿工的积极性。对此以太坊使用了改进版的&lt;strong&gt;GHOST协议&lt;/strong&gt;来解决这一问题。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;GHOST协议&#xA;    &lt;div id=&#34;ghost协议&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#ghost%e5%8d%8f%e8%ae%ae&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;GHOST（Greedy Heaviest-Observed Sub-Tree，贪婪最重可观测子树）是区块链共识优化机制，核心是在快速出块场景下将孤块 “叔块” 纳入权重与奖励，提升安全性与吞吐量。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>14. 以太坊的状态树</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/14.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E7%8A%B6%E6%80%81%E6%A0%91/</link>
      <pubDate>Sun, 23 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/14.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E7%8A%B6%E6%80%81%E6%A0%91/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;以太坊的状态树&#xA;    &lt;div id=&#34;以太坊的状态树&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%a5%e5%a4%aa%e5%9d%8a%e7%9a%84%e7%8a%b6%e6%80%81%e6%a0%91&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;上一篇文章中我们说了每个以太坊账户中有余额、nonce、code、storage等属性，这篇文章就是讲用什么数据结构，将用户地址与这些属性关联起来。简单来说就是如何存储 address -&amp;gt; state 映射关系。首先要明确这个数据结构需要实现的目的：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;给手机钱包等轻节点提供Merkle Proof验证，能够验证任意用户的状态。&lt;/li&gt;&#xA;&lt;li&gt;保证账户状态的防篡改与可验证性，任意微小的改变都能被感知。&lt;/li&gt;&#xA;&lt;li&gt;适配以太坊的状态模型与性能需求，以高效快捷的方式在各节点之前同步及验证状态。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;方案1:  哈希表&#xA;    &lt;div id=&#34;方案1--哈希表&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%96%b9%e6%a1%881--%e5%93%88%e5%b8%8c%e8%a1%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;既然是映射，一个直观的想法是哈希表，即系统中的全节点维护一个哈希表，查询与操作的时间复杂度都是O(1)，简单又高效。但是缺点也很明显，哈希表没法提供地址状态的Merkle Proof。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;方案2: Merkle Tree&#xA;    &lt;div id=&#34;方案2-merkle-tree&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%96%b9%e6%a1%882-merkle-tree&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;既然要满足Merkle Proof，那能Merkle Tree就天然地满足了这个需求，能跟比特币一样否直接使用Merkle Tree？答案是NO。&lt;/p&gt;&#xA;&lt;p&gt;为什么比特币中能使用Merkle Proof，而以太坊不行呢？是因为比特币中用Merkle Tree存储的是一个区块的交易数据，前面我们分析过大概是4000个交易。而以太坊需要存储的是&lt;strong&gt;所有用户的状态数据&lt;/strong&gt;，这里可能是千万量级的，如果每次发布区块都要重新构建这个Merkle Tree，从效率上来说并不可行，实际上每次发布区块只涉及部分地址的状态变更，从这点来看重建Merkle Tree的&lt;strong&gt;性价比也太低了&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;另外，每个节点打包时虽然状态一样，但是只要叶子节点顺序不一致，那Merkle Tree的&lt;strong&gt;根哈希值也不一样&lt;/strong&gt;，无法做到节点之间同步。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\13. 以太坊账户\merkle树.png&#34; style=&#34;zoom: 33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;如上图所示，虽然两个节点打包的都是ABCD四个账户的状态数据，但最后他们的根哈希值并不相同。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>11.比特币思考</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/11.%E6%AF%94%E7%89%B9%E5%B8%81%E6%80%9D%E8%80%83/</link>
      <pubDate>Sat, 22 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/11.%E6%AF%94%E7%89%B9%E5%B8%81%E6%80%9D%E8%80%83/</guid>
      <description>&lt;h3 class=&#34;relative group&#34;&gt;哈希指针&#xA;    &lt;div id=&#34;哈希指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%93%88%e5%b8%8c%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币系统中很多地方都用到了哈希指针，但是指针是只指向某个内存地址的，这个指针只有在本地计算机才有意义，如果一个新的区块发布，区块里的哈希指针在其他的节点中并不适用，那么比特币是如何设计这个哈希指针的呢？&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\11. 比特币思考\哈希表.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;实际中，比特中的哈希指针&lt;strong&gt;只有哈希，没有指针&lt;/strong&gt;。全节点一般将区块存储于一个kv数据库（如上图所示）中，key为哈希，value为区块内容，一个常用的kv数据库是levelDB。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;区块恋&#xA;    &lt;div id=&#34;区块恋&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8c%ba%e5%9d%97%e6%81%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;有的情侣共用一个账户购买比特币，账户的私钥一人保管一半，如果两人感情一直好，则可以一直维持，但一旦两人感情破裂，那这些比特币将会变成死钱，永远取不出来。同样的，如果一个商铺有四个合伙人，每人保管1/4的私钥，这样也会带来一些列问题：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;其中一个人忘记私钥，将永久无法交易，买的币将永久存于UTXO集合，对矿工不友好。&lt;/li&gt;&#xA;&lt;li&gt;截断私钥长度会降低安全性，128位密钥的破解难度要远小于256位的密钥，假设有三个合伙人串通起来瞒着另一个合伙人将钱取出来，那他们&lt;strong&gt;只需要尝试2^64次&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;分布式共识&#xA;    &lt;div id=&#34;分布式共识&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%86%e5%b8%83%e5%bc%8f%e5%85%b1%e8%af%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;从理论上来说，分布式系统中取得共识是不可能的，那比特币为什么能够取得共识呢？&lt;strong&gt;严格地说，比特币并没有取得真正意义上的共识，因为取得的共识随时都有可能被推翻&lt;/strong&gt;。比如分叉攻击，本来以为已经达成了某个共识，分叉攻击后，系统会回滚到前一个状态。&lt;/p&gt;&#xA;&lt;p&gt;此外，理论与实际之间存在差异，在实际中窒只需要把模型稍微改改，就能够变得适用。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;比特币的稀缺性&#xA;    &lt;div id=&#34;比特币的稀缺性&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e7%9a%84%e7%a8%80%e7%bc%ba%e6%80%a7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;前面我们说过，比特币的总量在2100万个，并且每隔一个周期，出块奖励都会减半，这样会导致越到后面比特币会越稀缺，但是实际上是&lt;strong&gt;稀缺的东西是不适合用来做货币的&lt;/strong&gt;。我们可以参考黄金，黄金在很长一段时间作为货币在使用，但是现代社会基本都抛弃了金本位，因为现实中每年黄金产量要远远小于社会产生的财富，如果继续用黄金作为货币，那么黄金会变得越来越值钱，以致于前期拥有黄金的人会一直在食物链顶端，后面的人怎么怎么赶也赶不上，个人奋斗将变得毫无意义，一个健康向上的社会不应该出现这种情况。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;量子计算&#xA;    &lt;div id=&#34;量子计算&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%87%8f%e5%ad%90%e8%ae%a1%e7%ae%97&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币是建立在密码学的基础上的，量子计算起来之后这些加密货币会不会变得不安全？&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>12. 以太坊</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/12.-%E4%BB%A5%E5%A4%AA%E5%9D%8A/</link>
      <pubDate>Sat, 22 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/12.-%E4%BB%A5%E5%A4%AA%E5%9D%8A/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;概述&#xA;    &lt;div id=&#34;概述&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e8%bf%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;比特币跟以太坊是两种最主要的加密货币，以太坊可以说是比特币的2.0版本，相较于比特币，其做了如下改进。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;核心功能&#xA;    &lt;div id=&#34;核心功能&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a0%b8%e5%bf%83%e5%8a%9f%e8%83%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币的核心仅支持简单的价值转移交易，协议逻辑简洁，只能实现去中心化支付相关功能，无法承载复杂业务逻辑。以太坊引入了&lt;strong&gt;智能合约&lt;/strong&gt;和&lt;strong&gt;以太坊虚拟机（EVM）&lt;/strong&gt;，能实现任意复杂的逻辑运算。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;共识机制&#xA;    &lt;div id=&#34;共识机制&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%85%b1%e8%af%86%e6%9c%ba%e5%88%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;特币采用工作量证明（PoW）机制，节点需通过大量算力运算竞争记账权，而ASIC芯片的出现将挖矿算力集中化，已经偏离了比特币最开始的设计。以太坊使用的是&lt;strong&gt;权益证明（PoS）机制&lt;/strong&gt;，验证者无需靠算力竞争，而是通过质押 ETH 获取记账和验证资格。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;经济模型&#xA;    &lt;div id=&#34;经济模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%8f%e6%b5%8e%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币总量固定为 2100 万枚，采用固定的挖矿奖励减半机制，经济模型核心围绕 “稀缺性” 设计，以太坊&lt;strong&gt;无固定总量上限，但通过 PoS 机制减少发行量&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;性能与扩展&#xA;    &lt;div id=&#34;性能与扩展&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%80%a7%e8%83%bd%e4%b8%8e%e6%89%a9%e5%b1%95&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币区块大小和出块时间固定，导致网络吞吐量极低，仅能满足少量交易需求，一旦交易激增就会出现拥堵，且手续费大幅上涨。以太坊将区块链&lt;strong&gt;拆分为多个平行分片，并行处理交易&lt;/strong&gt;，理论上大幅提升吞吐量。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>13. 以太坊的账户</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/13.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E8%B4%A6%E6%88%B7/</link>
      <pubDate>Sat, 22 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/13.-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E7%9A%84%E8%B4%A6%E6%88%B7/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;前言&#xA;    &lt;div id=&#34;前言&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%89%8d%e8%a8%80&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在讲以太坊的账户之前，先说下比特币的账户有哪些缺点，再来讲以太坊跟比特币账户模式的不同点。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;比特币账户&#xA;    &lt;div id=&#34;比特币账户&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e8%b4%a6%e6%88%b7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面我们说过，比特币中账户就是一个私钥地址，且账户并没有&lt;strong&gt;显式的余额&lt;/strong&gt;的概念，余额是通过UTXO集合算出来的。此外，在比特币的一次转账中，必须要一次性的把一个UTXO集合的输出全部花掉。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\13. 以太坊账户\比特币交易.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;例如上图所示，如果A的UTXO输出有10个比特币，要转3个比特币转给B，那么A要把剩下的7个毕业币转给自己的另外一个账户A&amp;rsquo;，否则那7个比特币就变成给矿工的手续费了。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;以太坊账户&#xA;    &lt;div id=&#34;以太坊账户&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%a5%e5%a4%aa%e5%9d%8a%e8%b4%a6%e6%88%b7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在以太坊中账户与现在的银行账户模式类似，都是显式地记录了账户的余额，转账只需要查询转账者的账户中是否有足够余额的钱。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\13. 以太坊账户\以太币交易.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;这种模式的好处是：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;转账变得简单清晰，不再需要将余额转给自己的另一个账号。&lt;/li&gt;&#xA;&lt;li&gt;天然地防范了 Double Spending 攻击，因为花两次，就会扣账户两次的钱 。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以太坊的账户模式解决了比特币中的Double Spending 攻击，但又会带来另一种问题，就是Replay 攻击。以上图来举例，假如B是有恶意的，将A-&amp;gt;B的这个交易再广播给其他的节点，那么A的钱会被再扣一次，B的钱会再加一次。其实可以看出Replay 攻击跟Double Spending 攻击是对称的，前者是收款人有恶意，后者是付款人有恶意。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;如何解决&#xA;    &lt;div id=&#34;如何解决&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e8%a7%a3%e5%86%b3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;以太坊中是引入&lt;strong&gt;nonce值&lt;/strong&gt;来解决Replay 攻击的。在以太坊的每个交易中不仅有交易相关的信息，而且有一个nonce值，其是一个&lt;strong&gt;连续递增的整数&lt;/strong&gt;，nonce值可以理解为账号的第几次交易。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>10. 比特币匿名性</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/10.-%E6%AF%94%E7%89%B9%E5%B8%81%E5%8C%BF%E5%90%8D%E6%80%A7/</link>
      <pubDate>Sat, 15 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/10.-%E6%AF%94%E7%89%B9%E5%B8%81%E5%8C%BF%E5%90%8D%E6%80%A7/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;比特币的匿名性&#xA;    &lt;div id=&#34;比特币的匿名性&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e7%9a%84%e5%8c%bf%e5%90%8d%e6%80%a7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;比特币的 “匿名性” 是一个&lt;strong&gt;被广泛误解的核心特性&lt;/strong&gt;—— 它并非绝对匿名，而是一种&lt;strong&gt;伪匿名&lt;/strong&gt;，更准确的描述是&lt;strong&gt;地址匿名、交易公开可追溯&lt;/strong&gt;。甚至与纸币相比，纸币的匿名性更好，因为纸币上面没有任何任何个人相关的信息。&lt;/p&gt;&#xA;&lt;p&gt;下面分别从几个角度分析下比特币匿名的局限性。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;账号关联&#xA;    &lt;div id=&#34;账号关联&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%b4%a6%e5%8f%b7%e5%85%b3%e8%81%94&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在一次比特币交易中，通常会有多个输入及多个输出。我们前面说过，比特币基于utxo集合，在现实世界中很少某个utxo输出刚好等于你要交易的金额，这就意味着某笔交易可能需要多个utxo输出及&amp;quot;找零&amp;quot;的情况。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\10.比特币匿名性\账号关联.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;在上面的情况中，输入的两个账号很可能都是同一个人的，很可能该人同时用于这两个账号的私钥，从而发起的交易。同样的，account_4也很可能是找零的地址，account_3是实际的交易金额（为什么不是反过来？因为如果实际交易金额是account_3的3个比特币的话，那account_1跟account_2单个账号金额就足够了，也没必要用两个账号了）。&lt;/p&gt;&#xA;&lt;p&gt;由上，能由交易的账号信息，从而将这些账号进行关联。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;身份关联&#xA;    &lt;div id=&#34;身份关联&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ba%ab%e4%bb%bd%e5%85%b3%e8%81%94&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;任何使得比特币和实体世界中关联的操作都有可能泄露用户真实身份，其中最典型的就是比特币与法币的交易。例如在钱包软件中使用法币购买比特币，或者将比特币出售以换取法币（但对于大额法币的转入与转出，很难逃避司法机构的监管）。&lt;/p&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;监管机构通过链上分析工具已破获多起利用比特币洗钱的案件 比较著名的有&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%B5%B2%E8%B7%AF_%28%E8%B3%BC%E7%89%A9%E7%B6%B2%E7%AB%99%29&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;silk road事件&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;实际上，很难不让比特币与现实世界产生关联，除非，你完全不使用比特币。这样的人也不是没有，比特币的发明人中本聪就是其中一个（传闻他有大量比特币，但从未使用过）。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;如何提高匿名性&#xA;    &lt;div id=&#34;如何提高匿名性&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e6%8f%90%e9%ab%98%e5%8c%bf%e5%90%8d%e6%80%a7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;如果要提高比特币的匿名性，可以从两个方向来实现，一个是网络层，一个是应用层。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>4. 比特币挖矿</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/4.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF/</link>
      <pubDate>Sat, 15 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/4.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;比特币共识&#xA;    &lt;div id=&#34;比特币共识&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e5%85%b1%e8%af%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在文章开始之前，必须先聊聊共识。共识是在某个群体或系统中，针对特定问题或规则达成的&lt;strong&gt;普遍一致意见或共同认识&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;为什么需要共识&#xA;    &lt;div id=&#34;为什么需要共识&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81%e5%85%b1%e8%af%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;通过前面的知识我们知道，比特币是一个去中心化的账本，在这个世界上的每一个节点都可以打包交易的信息，即获得&lt;strong&gt;比特币的记账权&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;究竟以哪个节点打包的信息为主？&lt;/li&gt;&#xA;&lt;li&gt;如何让所有用户都认可某个节点打包的账单信息？&lt;/li&gt;&#xA;&lt;li&gt;打包交易有什么利可图？&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;如何达成共识&#xA;    &lt;div id=&#34;如何达成共识&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e8%be%be%e6%88%90%e5%85%b1%e8%af%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在日常生活中，投票是一个达成共识的好办法。那在比特币中能否使让用户投票，来决定记账权呢？答案自然是否定的，因为在比特币中的账号可以&lt;strong&gt;无限产生&lt;/strong&gt;，只要生成一对公私钥对就相当于生成了一个账户，如果有人恶意生成足够多账户，那他就可以控制投票的结果（女巫攻击）。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\4.比特币挖矿\共识.png&#34; style=&#34;zoom: 25%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;在比特币中也是利用投票机制，但不是按照账户投票，而是按照&lt;strong&gt;计算力来投票&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;挖矿&#xA;    &lt;div id=&#34;挖矿&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8c%96%e7%9f%bf&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;发行货币&#xA;    &lt;div id=&#34;发行货币&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%91%e8%a1%8c%e8%b4%a7%e5%b8%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在讨论挖矿之前，我们先来说说如何发行比特币。前面的文章中我们讨论的交易都是在两个用户之间进行的，例如A转给B，B转给C，但在这些交易自始至终都没有产生新的货币，那这些货币最开始是从哪里产生的呢？答案就是&lt;strong&gt;出块奖励&lt;/strong&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>9. 比特币分叉</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/9.-%E6%AF%94%E7%89%B9%E5%B8%81%E5%88%86%E5%8F%89/</link>
      <pubDate>Sat, 15 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/9.-%E6%AF%94%E7%89%B9%E5%B8%81%E5%88%86%E5%8F%89/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;什么是分叉&#xA;    &lt;div id=&#34;什么是分叉&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%80%e4%b9%88%e6%98%af%e5%88%86%e5%8f%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;比特币分叉的本质是区块链因&lt;strong&gt;规则变更&lt;/strong&gt;或&lt;strong&gt;数据一致性冲突&lt;/strong&gt;，导致原本单一的区块链分裂成为两条甚至多条独立的链。分叉的核心原因是比特币网络中不同节点对 “交易验证规则”“区块结构” 等核心协议产生分歧，且无法达成统一共识，最终各自遵循新规则继续记账，形成并行的区块链。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;软分叉与硬分叉&#xA;    &lt;div id=&#34;软分叉与硬分叉&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bd%af%e5%88%86%e5%8f%89%e4%b8%8e%e7%a1%ac%e5%88%86%e5%8f%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;根据分叉的性质、触发方式及对网络的影响，主要分为两大类：&lt;strong&gt;软分叉&lt;/strong&gt;和&lt;strong&gt;硬分叉&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;硬分叉&#xA;    &lt;div id=&#34;硬分叉&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%a1%ac%e5%88%86%e5%8f%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;hard fork 即硬分叉，是对现有协议的&lt;strong&gt;非向后兼容式修改&lt;/strong&gt;，新规则与旧规则完全冲突，遵循旧规则的节点无法识别新规则的区块，最终网络会&lt;strong&gt;永久分裂&lt;/strong&gt;为两条独立的链，各自拥有独立的代币、交易历史和社区。&lt;/p&gt;&#xA;&lt;p&gt;例如，当比特币中出现协议更新，但并非所有节点都认同这个协议更新时，就会出现硬分叉。我们前面提过，每个区块的大小的上限是1MB，假设每笔交易大小占250KB，那么一个区块大概能容纳4000个交易。按照每10分钟出一个区块，那么每秒仅能写入7个交易，这跟现有的中心化的金融体系的每秒交易数量差了好几个数量级。&lt;/p&gt;&#xA;&lt;p&gt;假设有人提议修改比特币协议，将每个区块的容量上限从1MB改成4MB，那么同意新协议的节点跟不同意的节点将会产生硬分叉。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;D:%5cNotePitcure%5c9.%e6%af%94%e7%89%b9%e5%b8%81%e5%88%86%e5%8f%89%5c%e7%a1%ac%e5%88%86%e5%8f%89.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;在上图中，上限1MB的节点收到上限4MB的节点不会认同，会认为他是一个非法的区块，下面这条链&lt;strong&gt;永远&lt;/strong&gt;不会认同上限4MB的区块。而上限4MB的节点收到一个上限1MB的区块会认同（因为其上限没有超过4MB），但下面的链&lt;strong&gt;永远&lt;/strong&gt;不会认可上面这条链，因为其始终认为上面的链是非法的。&lt;/p&gt;&#xA;&lt;p&gt;典型案例&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;2017 年因 “区块大小扩容” 争议引发的硬分叉。原比特币区块大小上限为 1MB，部分社区认为这一限制导致交易拥堵，主张将区块大小提升至 8MB。由于与另一部分社区无法达成共识，支持扩容的节点和算力分裂出去，基于原比特币区块链在特定高度分叉，形成新的加密货币 BCH，原链则继续作为比特币（BTC）存在。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;软分叉&#xA;    &lt;div id=&#34;软分叉&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bd%af%e5%88%86%e5%8f%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;软分叉是对现有协议的&lt;strong&gt;向后兼容式修改&lt;/strong&gt;，新规则发布后，遵循旧规则的节点仍能识别和验证遵循新规则的区块，&lt;strong&gt;不会导致网络永久分裂&lt;/strong&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>3. 比特币的交易</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/3.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%9A%84%E4%BA%A4%E6%98%93/</link>
      <pubDate>Sat, 08 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/3.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%9A%84%E4%BA%A4%E6%98%93/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;UTOX模型&#xA;    &lt;div id=&#34;utox模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#utox%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在讲比特币交易之前，必须先理解比特币的交易模型。在比特币的交易体系中，并没有“余额”这一概念，它使用的是utxo模型（unspent transaction outputs，未使用过的交易输出）来记录用户的交易信息。我们在交易过程中经常说的钱包余额，实际上是一个钱包地址的utxo集合。所以，在比特币中，余额是&lt;strong&gt;实际上是别人转给你的，且未使用的额度&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;这样说还是比较抽象，举个日常生活中的例子来说明，假如B、C给A分别转账20元，10元，那么用户A的钱包里有30元，这30元是A钱包里的余额。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\3.比特币的交易\钱包余额.png&#34; style=&#34;zoom: 33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;我们将这个场景类比到比特币交易中，假如B、C给A分别转账20个比特币，10个比特币，那么用户A的钱包里有30个比特币，但这30个比特币不是直接得出来得，而是通过计算获取出来得。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\3.比特币的交易\比特币余额.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;当A把币花掉后，就会在utxo集合里删除。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\3.比特币的交易\钱包余额2.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;简单来说，传统的账户系统中存在这一个&lt;strong&gt;余额变量&lt;/strong&gt;，每当产生交易时都会对这个余额变量进行修改，用户想要获取余额时直接读取整个余额变量即可。但在比特币的系统中并没有这个余额变量，而是每次都通过&lt;strong&gt;求和自己收到并且未花的钱&lt;/strong&gt;来获取余额（当然一些钱包软件可能会对这个余额做一些缓存）。&lt;/p&gt;&#xA;&lt;p&gt;我们上面所说的utxo集合都是用户自己相关的utxo集合，这种数据一般会单独保存在钱包软件中。其实在全节点中我们还保留一个比特币系统中&lt;u&gt;所有交易的utxo集合&lt;/u&gt;，用户之间的交易要通过挖矿机制同步到这个完整的utxo集合中去，这样用户之间的交易才能被同步到其他用户那里去（后续我们会逐步提到这一机制）。&lt;/p&gt;&#xA;&lt;p&gt;为什么要使用utxo模型，相对于传统的账户模型，有什么好处？&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;增强隐私性&lt;/strong&gt;：utxo模型使得交易与账户分离，增加了追踪资金流动的难度，从而保护用户身份。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;可拓展性&lt;/strong&gt;：utxo模型支持并行处理交易，提高了网络的扩展性。每个节点只需要验证自己的收到的uxto，而不需要处理整个账户的余额。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;安全性&lt;/strong&gt;：utxo模型通过验证每笔交易的输入，确保&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;了解了比特币得交易模型，接下来再思考讨论下比特币交易相关的一些问题。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;传统的中心化交易&#xA;    &lt;div id=&#34;传统的中心化交易&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bc%a0%e7%bb%9f%e7%9a%84%e4%b8%ad%e5%bf%83%e5%8c%96%e4%ba%a4%e6%98%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在中心化的交易系统，例如支付宝中，必须有一个中心化的数据库，其记录了用户有多少余额，这样可以确保交易的绝对准确性，不会出现一份钱花两次等问题（依赖于第三方服务，例如支付宝、微信等，保证账户的钱不会多花、漏花）。其次，货币的发行由中心化的机构（例如央行）来决定。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;去中心化交易&#xA;    &lt;div id=&#34;去中心化交易&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8e%bb%e4%b8%ad%e5%bf%83%e5%8c%96%e4%ba%a4%e6%98%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在去中心化的交易系统中，并没有一个中心化的机制来帮我们保证交易的准确性，即比特币系统中任需要解决如下问题：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如何发行货币&lt;/li&gt;&#xA;&lt;li&gt;如何解决双花攻击&lt;/li&gt;&#xA;&lt;li&gt;如何避免冒名顶替&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;双花攻击&#xA;    &lt;div id=&#34;双花攻击&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%8c%e8%8a%b1%e6%94%bb%e5%87%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;第一个问题后面会详细讨论，先来看下比特币中是如何解决双花攻击的。首先，每一个比特币交易都包含输入跟输出两个部分：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>8. 比特币脚本</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/8.-%E6%AF%94%E7%89%B9%E5%B8%81%E8%84%9A%E6%9C%AC/</link>
      <pubDate>Sat, 08 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/8.-%E6%AF%94%E7%89%B9%E5%B8%81%E8%84%9A%E6%9C%AC/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title>5. 比特币挖矿难度</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/5.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF%E9%9A%BE%E5%BA%A6/</link>
      <pubDate>Sat, 18 Oct 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/5.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF%E9%9A%BE%E5%BA%A6/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;挖矿难度&#xA;    &lt;div id=&#34;挖矿难度&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8c%96%e7%9f%bf%e9%9a%be%e5%ba%a6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面提到了挖矿是不断地调整 block header 中的nonce值，使得 hash(block_header) 的值小于等于一个目标值target。可以看出，&lt;strong&gt;target越小，挖矿的难度越大&lt;/strong&gt;，他们之间是反比的关系。&#xA;$$&#xA;difficulty = \frac{difficulty1(最小挖矿难度)}{target}&#xA;$$&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;调整挖矿难度原因&#xA;    &lt;div id=&#34;调整挖矿难度原因&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%b0%83%e6%95%b4%e6%8c%96%e7%9f%bf%e9%9a%be%e5%ba%a6%e5%8e%9f%e5%9b%a0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在比特币系统中，出块的平均时间保持在10min左右，但随着参加挖矿的人增加及设备性能的提升，系统的总算力会不断地增强，出块的时间会越来越短，挖矿的难度越来越低。实际上，在比特币系统开发过程中，中本聪便考虑到了这个问题，&lt;strong&gt;并设计了一个相应的难度调整算法&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;出块时间太短会带来什么问题？&#xA;    &lt;div id=&#34;出块时间太短会带来什么问题&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%ba%e5%9d%97%e6%97%b6%e9%97%b4%e5%a4%aa%e7%9f%ad%e4%bc%9a%e5%b8%a6%e6%9d%a5%e4%bb%80%e4%b9%88%e9%97%ae%e9%a2%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;出块时间太短，会导致区块链分叉过多，不利于系统达成共识，会让各个节点处于不一致的状态，且会造成算力分散，大大降低了黑客发动51%攻击的成本。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;出块时间10min是最优解吗？&#xA;    &lt;div id=&#34;出块时间10min是最优解吗&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%ba%e5%9d%97%e6%97%b6%e9%97%b410min%e6%98%af%e6%9c%80%e4%bc%98%e8%a7%a3%e5%90%97&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;不一定，比特币选择 10 分钟作为出块时间，是中本聪在设计时权衡多方面因素的结果，10 分钟的间隔让交易有足够时间在全网传播，同时又降低了上述分叉攻击带来的风险。但是无论如何，这个出块时间都要维持在一个稳定的值。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>0. 说明</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/0.-%E8%AF%B4%E6%98%8E/</link>
      <pubDate>Thu, 09 Oct 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/0.-%E8%AF%B4%E6%98%8E/</guid>
      <description>&lt;p&gt;本系列文章是基于北京大学肖臻老师《区块链技术与应用》做的笔记，文章将会从多个角度来探讨区块链技术，在课程的基础上会加入自己的一些理解。文章的整体风格尽量遵循3W原则，即：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Why：为什么&lt;/li&gt;&#xA;&lt;li&gt;How：如何做&lt;/li&gt;&#xA;&lt;li&gt;What：是什么&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;本文不会做过多繁杂概念的介绍，主要内容为一些理解性的内容，概念性的东西大家可以自行google。此外笔记的顺序也不完全按照肖臻老师的课程章节顺序&lt;/p&gt;&#xA;&lt;p&gt;另外，区块链并不等于比特币，&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>6. 比特币挖矿设备及矿池</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/6.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF%E8%AE%BE%E5%A4%87%E5%8F%8A%E7%9F%BF%E6%B1%A0/</link>
      <pubDate>Thu, 09 Oct 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/6.-%E6%AF%94%E7%89%B9%E5%B8%81%E6%8C%96%E7%9F%BF%E8%AE%BE%E5%A4%87%E5%8F%8A%E7%9F%BF%E6%B1%A0/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;全节点与轻节点&#xA;    &lt;div id=&#34;全节点与轻节点&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%85%a8%e8%8a%82%e7%82%b9%e4%b8%8e%e8%bd%bb%e8%8a%82%e7%82%b9&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面我们说过比特币的节点分为全节点和轻节点，全节点包含了区块的header及body，轻节点只包含header，下面我们详细地来对比下他们之间的异同。&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;&lt;/th&gt;&#xA;          &lt;th&gt;轻节点&lt;/th&gt;&#xA;          &lt;th&gt;全节点&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;是否一直在线&lt;/td&gt;&#xA;          &lt;td&gt;不是一直在线&lt;/td&gt;&#xA;          &lt;td&gt;一直在线&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;包含信息&lt;/td&gt;&#xA;          &lt;td&gt;在本地硬盘保存完整的区块信息&lt;/td&gt;&#xA;          &lt;td&gt;只保存每个区块的块头&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;交易信息&lt;/td&gt;&#xA;          &lt;td&gt;在内存中保存完整的utxo集合&lt;/td&gt;&#xA;          &lt;td&gt;不保存全部交易，只保存和自己有关的交易&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;合法性校验&lt;/td&gt;&#xA;          &lt;td&gt;监听比特币网络上的交易信息， 验证每个交易的合法性&lt;/td&gt;&#xA;          &lt;td&gt;无法验证大多数交易的合法性，只能验证与自己有关的交易的合法性&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;打包交易&lt;/td&gt;&#xA;          &lt;td&gt;决定哪些交易会打包到区块中&lt;/td&gt;&#xA;          &lt;td&gt;无法检测网上发布的区块的正确性&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;合法性&lt;/td&gt;&#xA;          &lt;td&gt;监听其他矿工挖出的区块，验证其合法性&lt;/td&gt;&#xA;          &lt;td&gt;仅可以验证挖矿难度&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;挖矿&lt;/td&gt;&#xA;          &lt;td&gt;决定沿着哪条链挖下去&amp;amp;当出现等长分叉，选择哪一个分叉&lt;/td&gt;&#xA;          &lt;td&gt;只能检测哪个是最长链，不知道哪个是最扯昂合法链&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;比特币网络中大部分节点都是轻节点，在挖矿过程中，如果监听到别人已经挖出一个新的区块，延申了最长合法链，那么应该重新组装一个新的候选区块，重新开始挖矿。这样做是不是有些可惜？并不，因为挖矿是无记忆性的，每一次nonce值的尝试，都不会对下一次的尝试造成影响。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;挖矿设备&#xA;    &lt;div id=&#34;挖矿设备&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8c%96%e7%9f%bf%e8%ae%be%e5%a4%87&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;挖矿设备的演化趋势是越来越趋于专业化，从普通的家用电脑，到如今的ASIC矿机。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;一代设备：CPU&#xA;    &lt;div id=&#34;一代设备cpu&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%80%e4%bb%a3%e8%ae%be%e5%a4%87cpu&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;开始的时候大家用普通的家庭电脑的CPU来进行挖矿，但实际上使用家用电脑来挖矿是十分不划算的，因为在挖矿过程只用到了电脑的一部份资源，大部分内存、CPU资源都是在闲置的。如果用通用计算机来挖矿，那么挖矿很快会变得无利可图，因为性价比太低。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>7. 比特币网络</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/7.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%BD%91%E7%BB%9C/</link>
      <pubDate>Thu, 09 Oct 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/7.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%BD%91%E7%BB%9C/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;比特币网络&#xA;    &lt;div id=&#34;比特币网络&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e7%bd%91%e7%bb%9c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;上篇文章中说到用户打包交易发布到区块链网络中去，那么新发布的区块是如何传播到其他节点上去呢？&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;比特币网络&#xA;    &lt;div id=&#34;比特币网络-1&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%af%94%e7%89%b9%e5%b8%81%e7%bd%91%e7%bb%9c-1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币协议工作在应用层，其底层是一个 &lt;em&gt;P2P Overlay Network&lt;/em&gt;（P2P覆盖网络）。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\7.比特币网络\比特币网络.png&#34; style=&#34;zoom: 33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;比特币系统中所有节点完全平等，没有所谓的超级节点，要加入这个P2P网络，首先至少要知道一个种子节点，通过种子节点来获取其他节点的信息。节点之间是通过TCP协议进行通信，方便穿透防火墙。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;设计原则&#xA;    &lt;div id=&#34;设计原则&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%be%e8%ae%a1%e5%8e%9f%e5%88%99&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;比特币网络的设计原则是&lt;strong&gt;简单、鲁棒&lt;/strong&gt;，而不是&lt;strong&gt;高效&lt;/strong&gt;，消息在节点中传播是使用flooding的方式，当某个节点收到消息时，会把这个消息传播个他的邻居节点，同时标记该消息已经接收过，避免重复接收消息。邻居节点的选举是随机的，并不是考虑实际的网络拓扑结构，这样做的好处是可以增强鲁棒性。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\7.比特币网络\flooding传播.png&#34; style=&#34;zoom: 33%;&#34; /&gt;&#xD;&#xA;&lt;p&gt;在比特币的每个节点中都要维护一个等待上链的交易集合，第一次收到交易消息，验证完其合法性后，需要将这个消息放到这个集合中，并且通知其他的邻居节点。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;交易冲突&#xA;    &lt;div id=&#34;交易冲突&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%ba%a4%e6%98%93%e5%86%b2%e7%aa%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;假设有A -&amp;gt; B，A -&amp;gt; C两笔交易（A为同一笔交易的UTXO输出），同时广播到网络上，每个节点在网络中的位置不同，有些节点可能先收到A -&amp;gt; B，有些节点可能先收到A -&amp;gt; C。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>2. 比特币的数据结构</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/2.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</link>
      <pubDate>Thu, 02 Oct 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/2.-%E6%AF%94%E7%89%B9%E5%B8%81%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;整体结构&#xA;    &lt;div id=&#34;整体结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%95%b4%e4%bd%93%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;比特币中的一个最基本的数据结构就是区块链，即一个一个区块组成的链表。其中，每个区块又可以分为&lt;strong&gt;header&lt;/strong&gt;跟&lt;strong&gt;body&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\2\块头与块身.png&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;header里存储这个区块的一些元信息，例如版本、时间戳等。body里则存储区块里包含的具体交易。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;全节点跟轻节点&#xA;    &lt;div id=&#34;全节点跟轻节点&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%85%a8%e8%8a%82%e7%82%b9%e8%b7%9f%e8%bd%bb%e8%8a%82%e7%82%b9&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;节点是指接入比特币网络的计算机（或设备），它们通过运行比特币客户端软件参与网络维护、数据同步和交易处理。（了解P2P的同学应该很容易理解节点）&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\2\全节点与轻节点.png&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;比特币中的节点又分为全节点和轻节点，全节点指存储了整个区块的节点（包括&lt;strong&gt;header与body&lt;/strong&gt;，一般为矿工节点、交易所节点等）。轻节点指仅存储区块部分数据的节点（仅&lt;strong&gt;header&lt;/strong&gt;，一般为手机钱包）。后续我们会再详细述说全节点与轻节点区别，这里只要有个大致的概念即可。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;哈希指针&#xA;    &lt;div id=&#34;哈希指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%93%88%e5%b8%8c%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面说过区块链是由一个个区块组成的，跟普通的链表用普通指针来连接数据不一样的是，区块之间是通过&lt;strong&gt;哈希指针&lt;/strong&gt;来连接区块的。&lt;/p&gt;&#xA;&lt;img src=&#34;D:\NotePitcure\2\哈希指针.png&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;哈希指针会将前一个区块的哈希值存入当前区块中，并且使用&lt;strong&gt;指针指向前一个区块&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;为什么需要哈希指针&#xA;    &lt;div id=&#34;为什么需要哈希指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81%e5%93%88%e5%b8%8c%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;防止区块内容被篡改&lt;/p&gt;&#xA;&lt;p&gt;在普通的链表中，指针指向的数据是可以被修改&amp;amp;替换的。而比特币这样一个去中心化的系统中，区块里的数据都是一笔笔已经发生的交易，是不应该被篡改的。哈希指针在通过指针找到前一个区块的时候，会对前一个区块进行hash运算，并且与当前存储的前一个指针的hash值做对比。假如有人恶意篡改了前一个区块的数据，那么与当前存储的hash值会不一致，则证明了前一个区块被篡改。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>1. 哈希与签名</title>
      <link>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.-%E5%93%88%E5%B8%8C%E4%B8%8E%E7%AD%BE%E5%90%8D/</link>
      <pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/web3/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.-%E5%93%88%E5%B8%8C%E4%B8%8E%E7%AD%BE%E5%90%8D/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;什么是哈希&#xA;    &lt;div id=&#34;什么是哈希&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%80%e4%b9%88%e6%98%af%e5%93%88%e5%b8%8c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;简单来说就是把任意输入 通过特定方式（hash函数） 处理后 生成一个值。或者说，对一个数据生成其对应的摘要。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;我的截图&#34;&#xA;    src=&#34;D:%5cNotePitcure%5c1%5chash.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;哈希特性&#xA;    &lt;div id=&#34;哈希特性&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%93%88%e5%b8%8c%e7%89%b9%e6%80%a7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;##抗碰撞性&#xA;指极难找到两个输入，他们的经过哈希函数处理后的哈希值相同。&lt;/p&gt;&#xA;&lt;p&gt;注意，这里是极难，&lt;strong&gt;但并非不可能&lt;/strong&gt;（找出哈希碰撞的两个输入的代价，要远远大于碰撞带来的收益，所以这里可以近似地认为不可能）&lt;/p&gt;&#xA;&lt;p&gt;##不可逆性&#xA;简单来说，就是对于一个哈希函数，不能根据他的输出，去反推他的输入&lt;/p&gt;&#xA;&lt;p&gt;##难题友好&#xA;指哈希值的计算不可预测，仅跟据输入很难预测输出，例如：我们需要一个哈希值，存在于某一个范围内，只能通过不停运算查找出来。该性质保证了比特币系统中，只能通过“挖矿”获得比特币。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;什么是签名&#xA;    &lt;div id=&#34;什么是签名&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%80%e4%b9%88%e6%98%af%e7%ad%be%e5%90%8d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;在中心化的系统中，通常有一个账号来代表用户的身份。例如支付宝中的支付系统，用户需要登录自己的账号，再输入支付密码，才能完成一笔交易。但在比特币的世界中，并没有中心化系统中的“账号”、“密码” 这一概念。那么，比特币系统是如何唯一标识用户的呢？答案就是签名。&lt;/p&gt;&#xA;&lt;p&gt;我们通常会在写信的时候附上自己的签名，其作用是证明这封信是出自此人之手（实际并不能完全证明，签名是可以伪造的，对吧）。并且，信的内容与签名并无直接关联。&lt;/p&gt;&#xA;&lt;p&gt;在比特币的交易中，需要对每一笔交易生成一个签名，但与写信不同，我们需要生成的签名，是根据交易内容来生成的，并且证明交易是由你发起的。&lt;/p&gt;&#xA;&lt;p&gt;在比特币系统中，也需要一个“账号”来证明这比交易是由你本人发起的（即对这笔交易进行签名），这个“账号”就是私钥&amp;amp;私钥对。总之，这对密钥就代表了比特币系统中的一个账户，如果其中私钥泄露，则相当于泄露了银行卡的密码。从另一个角度看，只有用于私钥，才能对比特币进行交易，保证了交易的安全性。&lt;/p&gt;&#xA;&lt;p&gt;这里关于公钥&amp;amp;私钥&amp;amp;签名&amp;amp;验签的内容不再详细赘述，有需要可以参考&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>pprof抓包教程</title>
      <link>http://blog.chuckchan.top/posts/tool/pprof%E6%8A%93%E5%8C%85%E6%95%99%E7%A8%8B/</link>
      <pubDate>Fri, 28 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/pprof%E6%8A%93%E5%8C%85%E6%95%99%E7%A8%8B/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title>无头service</title>
      <link>http://blog.chuckchan.top/posts/middleware/k8s/%E6%97%A0%E5%A4%B4service/</link>
      <pubDate>Fri, 08 Nov 2024 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/k8s/%E6%97%A0%E5%A4%B4service/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title>Promise详解</title>
      <link>http://blog.chuckchan.top/posts/frontend/promise%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Thu, 26 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/frontend/promise%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;背景&#xA;    &lt;div id=&#34;背景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%83%8c%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;在JavaScript的世界中，所有代码都是单线程执行的。由于这个“缺陷”，导致JavaScript的所有网络操作，浏览器事件，都必须是异步执行。假设有这么一个场景，在一个电商系统中，需要根据userId查询到用户购买的商品信息，其步骤如下:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;查询用户服务，根据userId查询到用户信息（orderId）&lt;/li&gt;&#xA;&lt;li&gt;查询订单服务，根据orderId查询到订单信息（productId）&lt;/li&gt;&#xA;&lt;li&gt;查询商品服务，根据productId查询到商品信息&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;在ES6之前，我们只能使用回调函数来实现这个功能，其代码示例如下:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;XMLHttpRequest&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://api.com/user&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;onreadystatechange&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;readyState&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;status&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;responseText&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xhr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>influx初学</title>
      <link>http://blog.chuckchan.top/posts/middleware/influx/influx%E5%88%9D%E5%AD%A6/</link>
      <pubDate>Tue, 25 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/influx/influx%E5%88%9D%E5%AD%A6/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. introduce&#xA;    &lt;div id=&#34;1-introduce&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-introduce&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;InfluxDB是一个用于存储和分析时间序列数据的开源数据库。&#xA;主要特性有：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;内置HTTP接口，使用方便&lt;/li&gt;&#xA;&lt;li&gt;数据可以打标记，这样查询可以很灵活&lt;/li&gt;&#xA;&lt;li&gt;类SQL的查询语句&lt;/li&gt;&#xA;&lt;li&gt;安装管理很简单，并且读写数据很高效&lt;/li&gt;&#xA;&lt;li&gt;能够实时查询，数据在写入时被索引后就能够被立即查出&lt;/li&gt;&#xA;&lt;li&gt;&amp;hellip;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;2. concept&#xA;    &lt;div id=&#34;2-concept&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-concept&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name: census&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-————————————&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time                    butterflies     &#x9;&#x9;&#x9;honeybees     &#x9;&#x9;&#x9;&#x9;location     &#x9;&#x9;&#x9;scientist&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T00:00:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;                   &#x9;&lt;span style=&#34;color:#ae81ff&#34;&gt;23&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                 langstroth&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T00:00:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                 perpetua&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T00:06:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt;                   &#x9;&lt;span style=&#34;color:#ae81ff&#34;&gt;28&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                 langstroth&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T00:06:00Z   &#x9;&#x9;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;28&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                 perpetua&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T05:54:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;                 langstroth&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T06:00:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;                 langstroth&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T06:06:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;23&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;                 perpetua&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-08-18T06:12:00Z      &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;                     &lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;                    &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;                 perpetua&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;其中census是&lt;code&gt;measurement&lt;/code&gt;，butterflies和honeybees是&lt;code&gt;field key&lt;/code&gt;，location和scientist是&lt;code&gt;tag key&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;measurement可以理解为表名，这里的measurement为census，可以表示为统计表。&lt;/li&gt;&#xA;&lt;li&gt;field为列，butterflies&lt;code&gt;和&lt;/code&gt;honeybees 都是列，称为fields，fields由field key和field value组成。field key(&lt;code&gt;butterflies&lt;/code&gt;和&lt;code&gt;honeybees&lt;/code&gt;)都是字符串，他们存储元数据；field key &lt;code&gt;butterflies&lt;/code&gt;告诉我们蝴蝶的计数从12到7；field key &lt;code&gt;honeybees&lt;/code&gt;告诉我们蜜蜂的计数从23变到22。field value就是你的数据，它们可以是字符串、浮点数、整数、布尔值，因为InfluxDB是时间序列数据库，所以field value总是和时间戳相关联。field是InfluxDB数据结构所必需的一部分——在InfluxDB中不能没有field。还要注意，field是没有索引的。如果使用field value作为过滤条件来查询，则必须扫描其他条件匹配后的所有值。因此，这些查询相对于tag上的查询（下文会介绍tag的查询）性能会低很多。 一般来说，字段不应包含常用来查询的元数据。&lt;/li&gt;&#xA;&lt;li&gt;样本数据中的最后两列（&lt;code&gt;location&lt;/code&gt;和&lt;code&gt;scientist&lt;/code&gt;）就是tag。 tag由tag key和tag value组成。tag key和tag value都作为字符串存储，并记录在元数据中。示例数据中的tag key是&lt;code&gt;location&lt;/code&gt;和&lt;code&gt;scientist&lt;/code&gt;。 &lt;code&gt;location&lt;/code&gt;有两个tag value：&lt;code&gt;1&lt;/code&gt;和&lt;code&gt;2&lt;/code&gt;。&lt;code&gt;scientist&lt;/code&gt;还有两个tag value：&lt;code&gt;langstroth&lt;/code&gt;和&lt;code&gt;perpetua&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;series是共同retention policy，measurement和tag set的集合&lt;/li&gt;&#xA;&lt;li&gt;point简单地理解为时间轴上的一个数据点，即一行数据。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;3. grammar&#xA;    &lt;div id=&#34;3-grammar&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#3-grammar&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;读取数据 -&amp;gt; InfluxQL的&lt;code&gt;select&lt;/code&gt;语句来自于SQL中的&lt;code&gt;select&lt;/code&gt;形式：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>MongoDB常用的curd操作</title>
      <link>http://blog.chuckchan.top/posts/middleware/mongodb/%E5%B8%B8%E7%94%A8%E7%9A%84crud%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Mon, 10 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mongodb/%E5%B8%B8%E7%94%A8%E7%9A%84crud%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;连接mongo&#xA;    &lt;div id=&#34;连接mongo&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%9e%e6%8e%a5mongo&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#连接mongo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mongo $url&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#选择数据库&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;use $database&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;索引相关&#xA;    &lt;div id=&#34;索引相关&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b4%a2%e5%bc%95%e7%9b%b8%e5%85%b3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#查询已有的索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.collection.getIndexes&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#创建索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.createIndex&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;$field: 1&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;crud相关&#xA;    &lt;div id=&#34;crud相关&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#crud%e7%9b%b8%e5%85%b3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#查询文档数量&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.countDocuments&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;k: v&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt; // mongodb &amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; v4.0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.count&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;k: v&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt; // mongodb &amp;lt; v4.0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#查询文档&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.find&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;k: v&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.find&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$and&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f92672&#34;&gt;[{&lt;/span&gt;k1: v1&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;k2: v2&lt;span style=&#34;color:#f92672&#34;&gt;}]})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.collection.find&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  upload_type: 3,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  $or: &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;audit_record.label&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;正常&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;audit_record.label&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;轻度违规&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt;.limit&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;.pretty&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#删除文档&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.deleteOne&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;k: v&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.deleteMany&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;k: v&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#新增文档&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#更新文档&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#获取索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.$collection.getIndexes&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>重学prometheus</title>
      <link>http://blog.chuckchan.top/posts/tool/%E9%87%8D%E5%AD%A6prometheus/</link>
      <pubDate>Wed, 05 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/%E9%87%8D%E5%AD%A6prometheus/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. 数据是如何存储的&#xA;    &lt;div id=&#34;1-数据是如何存储的&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e6%95%b0%e6%8d%ae%e6%98%af%e5%a6%82%e4%bd%95%e5%ad%98%e5%82%a8%e7%9a%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;无论是哪种metrics类型，prometheus在底层都会将所有采集到的样本数据以时间序列的方式存储在内存数据库中，并定时保存到硬盘上。如下图，可以理解为一个以时间为X轴的数字矩阵:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ^&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │   . . . . . . . . . . . . . . . . .   . .   node_cpu_seconds_total{cpu=&amp;#34;cpu0&amp;#34;,mode=&amp;#34;idle&amp;#34;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │     . . . . . . . . . . . . . . . . . . .   node_cpu_seconds_total{cpu=&amp;#34;cpu0&amp;#34;,mode=&amp;#34;system&amp;#34;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │     . . . . . . . . . .   . . . . . . . .   node_load1{}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │     . . . . . . . . . . . . . . . .   . .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  v&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;------------------ 时间 ----------------&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;如图，横轴为即时间，矩阵中的点称为一个样本，样本由以下三个部分组成:&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之系统排查</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E7%B3%BB%E7%BB%9F%E6%8E%92%E6%9F%A5/</link>
      <pubDate>Thu, 12 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E7%B3%BB%E7%BB%9F%E6%8E%92%E6%9F%A5/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;系统排查&#xA;    &lt;div id=&#34;系统排查&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b3%bb%e7%bb%9f%e6%8e%92%e6%9f%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;1. 先确定出现问题的进程&#xA;    &lt;div id=&#34;1-先确定出现问题的进程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e5%85%88%e7%a1%ae%e5%ae%9a%e5%87%ba%e7%8e%b0%e9%97%ae%e9%a2%98%e7%9a%84%e8%bf%9b%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;先排查是否因为程序服务导致的CPU/内存保障，可以使用top命令来排查。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;top&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;确定是服务出问题后，可以使用如下命令持续监测服务进程，$pid即为服务进程的pid。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;top -Hp $pid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;可以使用top默认根据CPU使用率来排序，可以使用shitft + m 改成使用内存占用率来排序。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;2. 使用PProf排查程序内部的问题&#xA;    &lt;div id=&#34;2-使用pprof排查程序内部的问题&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e4%bd%bf%e7%94%a8pprof%e6%8e%92%e6%9f%a5%e7%a8%8b%e5%ba%8f%e5%86%85%e9%83%a8%e7%9a%84%e9%97%ae%e9%a2%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;确定了服务进程的问题后，就可以通过PProf来排查CPU、内存、互斥锁、Goroutines的问题了。下面展示一个demo来简单使用PProf。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;net/http/pprof&amp;#34;&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;do something...&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Sleep&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Second&lt;/span&gt; )&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ListenAndServe&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.0.0.0:6060&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;//pprof包的init函数里注册了handler &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;使用web界面查看pprof信息&#xA;    &lt;div id=&#34;使用web界面查看pprof信息&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bd%bf%e7%94%a8web%e7%95%8c%e9%9d%a2%e6%9f%a5%e7%9c%8bpprof%e4%bf%a1%e6%81%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;经过上述步骤后，在浏览器打开http://127.0.0.1:6060/debug/pprof/，就能看到pprof界面了。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之内存管理</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/</link>
      <pubDate>Mon, 10 Apr 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之内存管理&#xA;    &lt;div id=&#34;golang之内存管理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8b%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;概述&#xA;    &lt;div id=&#34;概述&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e8%bf%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Go的内存分配借鉴了Google的TMalloc，其核心思想是&lt;strong&gt;内存池+多级对象管理&lt;/strong&gt;，&lt;strong&gt;能加快分配速度，降低资源竞争。&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;内存分配的方法&#xA;    &lt;div id=&#34;内存分配的方法&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e5%88%86%e9%85%8d%e7%9a%84%e6%96%b9%e6%b3%95&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;线性分配法&lt;/strong&gt;：只需要在内存中维护一个指针，这个指针指向下一片未使用内存的起始位置，如果程序需要新分配一片内存，只要找到这个指针直接分配内存即可。&#xA;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-06-20_12-25-14.jpg&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-06-20_12-25-14.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&#xA;这种方法实现虽然简单，但有一个致命的缺点，就是无法利用曾经使用过但后面被释放的内存。&#xA;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-06-20_12-25-29.jpg&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-06-20_12-25-29.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;空闲链表分配法&lt;/strong&gt;：会在内部维护一个类似链表的数据结构，当程序需要申请内存时，空闲链表分配器会一次遍历空闲的内存块，找到足够大的内存，然后申请新的资源并修改链表。&#xA;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-06-20_12-26-39.jpg&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-06-20_12-26-39.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Go使用的是空闲链表分配法，再配合&lt;strong&gt;隔离适应策略&lt;/strong&gt;，将内存分割成多个链表，每个链表中内存块大小相等，申请内存时先找到合适的链表，再在链表中找到合适的内存块。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-06-20_12-26-07.jpg&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-06-20_12-26-07.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;基础结构&#xA;    &lt;div id=&#34;基础结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9f%ba%e7%a1%80%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;内存单元相关&lt;/strong&gt;：mspan、arena&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;内存池相关&lt;/strong&gt;：mcache、mcentral、mheap&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h5 class=&#34;relative group&#34;&gt;内存单元&#xA;    &lt;div id=&#34;内存单元&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e5%8d%95%e5%85%83&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h5&gt;&#xA;&lt;p&gt;首先，在Go程序初始化时，会先将申请到的虚拟内存分为如下几个部分。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之内存逃逸</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E9%80%83%E9%80%B8/</link>
      <pubDate>Mon, 10 Apr 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E9%80%83%E9%80%B8/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之内存逃逸&#xA;    &lt;div id=&#34;golang之内存逃逸&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8b%e5%86%85%e5%ad%98%e9%80%83%e9%80%b8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;内存分配&#xA;    &lt;div id=&#34;内存分配&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e5%88%86%e9%85%8d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在Golang中，程序申请的一个对象，是在栈上分配，还是在堆上分配，&lt;strong&gt;这个是由编译器决定的&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;在栈上分配&lt;/strong&gt;：在程序中，每个函数块都会有自己的内存区域来存储局部变量、返回值等数据，这一块内存区域有特定的数据结构与存储方式，其大小在程序编译的时候就已经分配好了，且这块区域寻址快，开销少，这块内存区域就称为栈区。因为栈的大小在编译的时候就已经确定了，所以当栈存储的数据过大时，会发生“栈溢出”。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;在堆上分配&lt;/strong&gt;：在程序中，全局变量，内存占用大的局部变量，发生了内存逃逸的局部变量就分配在堆上，这一块内存区域没有特定的结构，也没有固定的大小，可以根据需要进行调整。当一个变量分配在堆上的时候，开销会比较大，对Golang这种自带GC的语言来说，会增加GC压力，同时也会带来内存碎片。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;内存逃逸&#xA;    &lt;div id=&#34;内存逃逸&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e9%80%83%e9%80%b8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在计算机语言编译器优化原理中，逃逸分析是指分析指针动态范围的方法，它同编译器优化原理的指针分析和外形分析相关联。当变量（或者对象）在方法中分配后，其指针有可能被返回或者被全局引用，这样就会被其他过程或者线程所引用，这种现象称作指针（或者引用）的逃逸（Escape）。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;Golang中的内存逃逸&#xA;    &lt;div id=&#34;golang中的内存逃逸&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b8%ad%e7%9a%84%e5%86%85%e5%ad%98%e9%80%83%e9%80%b8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在Golang中可以使用go run -gcflags &amp;ldquo;-m -l&amp;rdquo; (-m打印逃逸分析信息，-l禁止内联编译)来分析内存逃逸。使用如下代码来分析内存逃逸：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;执行结果如下：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Oauth2.0</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/oauth2.0/</link>
      <pubDate>Tue, 28 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/oauth2.0/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;cat Oauth2.0&#xA;    &lt;div id=&#34;cat-oauth20&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#cat-oauth20&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;OAuth2.0协议是一个开放标准，允许用户授权第三方程序访问他们存储在另外的服务提供者上的信息，而不需要将用户和密码提供给第三方应用或分享他们数据的所有内容。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;运用场景&#xA;    &lt;div id=&#34;运用场景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%90%e7%94%a8%e5%9c%ba%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;几乎每个人在使用一个APP或网页应用的时候都看过他们支持第三方登录比如微信登录、 QQ 登录、微博登录、 Google 账号登录、github 授权登录等等。这些都是典型的 OAuth2 使用场景。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/v2-896097e280d052d9c91b9d1433b72bd4_1440w.webp&#34; alt=&#34;v2-896097e280d052d9c91b9d1433b72bd4_1440w&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;授权流程&#xA;    &lt;div id=&#34;授权流程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8e%88%e6%9d%83%e6%b5%81%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;这里以网页应用微信授权登录为例。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;准备工作&#xA;    &lt;div id=&#34;准备工作&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在进行微信OAuth2.0授权登录接入之前，在微信开放平台注册开发者帐号，并拥有一个已审核通过的网站应用，并获得相应的 AppID 和AppSecret，申请微信登录且通过审核后，可开始接入流程。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>NSQ设计</title>
      <link>http://blog.chuckchan.top/posts/middleware/nsq/nsq%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Mon, 27 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/nsq/nsq%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;nsq&#xA;    &lt;div id=&#34;nsq&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#nsq&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;NSQ是实时的分布式消息处理平台，其设计的目的是用来大规模地处理每天数以十亿计级别 的消息。NSQ具有分布式和去中心化拓扑结构，该结构具有无单点故障、故障容错、高可用性以及能够保证消息的可靠传递的特征，是一个成熟的、已在大规模生成环境下应用的产品。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;组成&#xA;    &lt;div id=&#34;组成&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%84%e6%88%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;NSQ由三个守护进程够成：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;nsqd：用于接收保存和传送消息到客户端的守护进程。&lt;/li&gt;&#xA;&lt;li&gt;nsqlookupd：是管理拓扑信息，维护着所有的nsqd的状态，并提供最终一致发现服务的守护进程。&lt;/li&gt;&#xA;&lt;li&gt;nsqadmin：一个 Web UI 来实时监控集群和执行各种管理任务。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;142017298_1_20180822103321301&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/142017298_1_20180822103321301.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;概念&#xA;    &lt;div id=&#34;概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;topic：生产者将消息写入topic中，一个topic下可以有多个channel，每个channel都是topic完整的副本。&lt;/li&gt;&#xA;&lt;li&gt;channel：消费者从channel处订阅消息，如果有多个消费者订阅同一个channel，那么channel中的消息会被随机传递到其中的一个消费者上。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-11-24_10-35-52.jpg&#34; alt=&#34;Xnip2022-11-24_10-35-52&#34; style=&#34;zoom:50%;&#34; /&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之内存泄漏</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F/</link>
      <pubDate>Sat, 18 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之内存泄漏&#xA;    &lt;div id=&#34;golang之内存泄漏&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8b%e5%86%85%e5%ad%98%e6%b3%84%e6%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;内存泄漏&#xA;    &lt;div id=&#34;内存泄漏&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e6%b3%84%e6%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;内存泄漏说白了就是分配的内存(或者变量)不再使用，但是并没有被gc回收，而是继续占用内存。在Golang中内存泄漏大部分都跟channel的不正确使用有关。泄漏的原因是goroutine操作channel后，处于发送阻塞或者接收阻塞状态，而channel处于满或者空的状态，一直得不到改变。同时，垃圾回收器也不会回收此类资源，进而导致goroutine会处于一个一直等待的队列中，不见天日。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;场景分析&#xA;    &lt;div id=&#34;场景分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&#xA;&lt;h5 class=&#34;relative group&#34;&gt;案例1: channel没有接收者&#xA;    &lt;div id=&#34;案例1-channel没有接收者&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a1%88%e4%be%8b1-channel%e6%b2%a1%e6%9c%89%e6%8e%a5%e6%94%b6%e8%80%85&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h5&gt;&#xA;&lt;p&gt;下面这段程序展示了并发地向3个站点请求资源，接收者只接收最快返回的那个。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;goroutineLeak1&lt;/span&gt;() &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;//正确姿势：responses := make(chan string, 3)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//3个发送者&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; {&lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;asia.gopl.io&amp;#34;&lt;/span&gt;)}()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; {&lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;europe.gopl.io&amp;#34;&lt;/span&gt;)}()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; {&lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;americas.gopl.io&amp;#34;&lt;/span&gt;)}()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//1个接收者&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;goroutineLeak1能正确地接收到最快返回的站点资源，但两个慢的goroutien会因为没有人接收而永远卡住，造成这两个goroutine永远没法被回收。正确的姿势是创建一个带3个buffer的channel，可以回收两个返回比较慢的goroutine。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>系统与网络排查工具</title>
      <link>http://blog.chuckchan.top/posts/tool/%E7%B3%BB%E7%BB%9F%E4%B8%8E%E7%BD%91%E7%BB%9C%E6%8E%92%E6%9F%A5%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Tue, 14 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/%E7%B3%BB%E7%BB%9F%E4%B8%8E%E7%BD%91%E7%BB%9C%E6%8E%92%E6%9F%A5%E5%B7%A5%E5%85%B7/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title>Mongodb架构设计</title>
      <link>http://blog.chuckchan.top/posts/middleware/mongodb/mongodb%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Fri, 10 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mongodb/mongodb%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Mongodb&#xA;    &lt;div id=&#34;mongodb&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#mongodb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 简介&#xA;    &lt;div id=&#34;1-简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;MongoDB 是一个&lt;strong&gt;基于分布式文件存储的数据库&lt;/strong&gt;。它具有开源、&lt;strong&gt;高性能&lt;/strong&gt;、&lt;strong&gt;无模式&lt;/strong&gt;等优点，由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像关系数据库的。MongoDB支持的数据结构类似于JSON，叫做 BSON，所以它既可以存储比较复杂的数据类型，又相当的灵活。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 关系型与非关系型数据库&#xA;    &lt;div id=&#34;2-关系型与非关系型数据库&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e5%85%b3%e7%b3%bb%e5%9e%8b%e4%b8%8e%e9%9d%9e%e5%85%b3%e7%b3%bb%e5%9e%8b%e6%95%b0%e6%8d%ae%e5%ba%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/281e605b476e424fba0d9f417e7545d5.png&#34; alt=&#34;281e605b476e424fba0d9f417e7545d5&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;3. 高可用架构&#xA;    &lt;div id=&#34;3-高可用架构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#3-%e9%ab%98%e5%8f%af%e7%94%a8%e6%9e%b6%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;高可用性 HA（High Availability）指的是缩短因&lt;strong&gt;正常运维&lt;/strong&gt;或者&lt;strong&gt;非预期故障&lt;/strong&gt;而导致的停机时间，提高系统可用性。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Kafaka之简介</title>
      <link>http://blog.chuckchan.top/posts/middleware/kafka/kafaka%E4%B9%8B%E7%AE%80%E4%BB%8B/</link>
      <pubDate>Thu, 09 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/kafka/kafaka%E4%B9%8B%E7%AE%80%E4%BB%8B/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Kafaka简介&#xA;    &lt;div id=&#34;kafaka简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#kafaka%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 简介&#xA;    &lt;div id=&#34;1-简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Kafka 是一个分布式的基于发布/订阅模式的消息队列（Message Queue），主要应用与大数据实时处理领域。其主要设计目标如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;以时间复杂度为O(1)的方式提供消息持久化能力，即使对TB级以上数据也能保证常数时间的访问性能。&lt;/li&gt;&#xA;&lt;li&gt;高吞吐率。即使在非常廉价的机器上也能做到单机支持每秒100K条消息的传输。&lt;/li&gt;&#xA;&lt;li&gt;支持消息分区及分布式消费，同时保证每个partition内的消息顺序传输，同时支持离线数据处理和实时数据处理&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 组件&#xA;    &lt;div id=&#34;2-组件&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e7%bb%84%e4%bb%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Broker：一台 Kafka 机器就是一个 Broker。一个集群是由多个 Broker 组成的且一个 Broker 可以容纳多个 Topic。&lt;/li&gt;&#xA;&lt;li&gt;Topic：可以简单理解为队列，Topic 将消息分类，生产者和消费者面向的都是同一个 Topic。&lt;/li&gt;&#xA;&lt;li&gt;Producer：即消息生产者，向 Kafka Broker 发消息的客户端。&lt;/li&gt;&#xA;&lt;li&gt;Consumer Group：即消费者组，消费者组内每个消费者负责&lt;strong&gt;消费不同分区的数据，以提高消费能力&lt;/strong&gt;。&lt;strong&gt;一个分区只能由组内一个消费者消费，不同消费者组之间互不影响&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;Partition：为了实现Topic扩展性，提高并发能力，一个非常大的 Topic 可以分布到多个 Broker 上，一个 Topic 可以分为多个 Partition 进行存储，每个 Partition 是一个有序的队列。&lt;/li&gt;&#xA;&lt;li&gt;Replica：即副本，为实现数据备份的功能，保证集群中的某个节点发生故障时，该节点上的 Partition 数据不丢失，且 Kafka 仍然能够继续工作，为此Kafka提供了副本机制，一个 Topic 的每个 Partition 都有若干个副本，一个 Leader 副本和若干个 Follower 副本。我们的 &lt;strong&gt;Producer 端在发送数据的时候，只能发送到Leader Partition里面 ，然后Follower Partition会去Leader那自行同步数据, Consumer 消费数据的时候，也只能从 Leader 副本那去消费数据的&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;Leader：即每个分区多个副本的主副本，&lt;strong&gt;生产者发送数据的对象，以及消费者消费数据的对象，都是 Leader&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;Offset：消费者消费的位置信息，监控数据消费到什么位置，当消费者挂掉再重新恢复的时候，可以从消费位置继续消费。&lt;/li&gt;&#xA;&lt;li&gt;ZooKeeper服务：Kafka 集群能够正常工作，需要依赖于 ZooKeeper，ZooKeeper 帮助 Kafka 存储和管理集群元数据信息。在最新版本中, 已经慢慢要脱离 ZooKeeper。&lt;/li&gt;&#xA;&lt;li&gt;Controller: 其实就是一个 Kafka 集群中一台 Broker。它除了具有普通Broker 的消息发送、消费、同步功能之外，还需承担一些额外的工作。Kafka 使用公平竞选的方式来确定 Controller ，最先在 ZooKeeper 成功创建临时节点 /controller 的Broker会成为 Controller ，一般而言，Kafka集群中第一台启动的 Broker 会成为Controller，并将自身 Broker 编号等信息写入ZooKeeper临时节点/controller。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;3. 集群架构&#xA;    &lt;div id=&#34;3-集群架构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#3-%e9%9b%86%e7%be%a4%e6%9e%b6%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;![640 (6)](&lt;a href=&#34;http://storage.chuckchan.top/uploads/640&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;http://storage.chuckchan.top/uploads/640&lt;/a&gt; (6).png)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>GPM&lt;4&gt;-场景分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm4-%E5%9C%BA%E6%99%AF%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 08 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm4-%E5%9C%BA%E6%99%AF%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;GPM&amp;lt;4&amp;gt;场景分析&#xA;    &lt;div id=&#34;gpm4场景分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpm4%e5%9c%ba%e6%99%af%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;场景分析&#xA;    &lt;div id=&#34;场景分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;场景一: 创建/执行G&#xA;    &lt;div id=&#34;场景一-创建执行g&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e4%b8%80-%e5%88%9b%e5%bb%ba%e6%89%a7%e8%a1%8cg&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;当某个G1创建一个新的G2时：&lt;/p&gt;&#xA;&lt;p&gt;1.运行一个G&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/34db10cbbff2208498f39e38f30a487a.png&#34; alt=&#34;34db10cbbff2208498f39e38f30a487a.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&lt;p&gt;2.当本地队列未满，则直接加入本地队列(满足局部性)&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/1919bb661a05f0dd8737e40411276c5f.png&#34; alt=&#34;1919bb661a05f0dd8737e40411276c5f.png&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;3.如果本地队列已满，则将P1本地队列中的 前一半(G3/G4)+G7顺序打乱，一同放到全局队列中去。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/8196d1a3ed00915544d679c1f8b4fd25.png&#34; alt=&#34;8196d1a3ed00915544d679c1f8b4fd25.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;场景二: 唤醒正在休眠的M&#xA;    &lt;div id=&#34;场景二-唤醒正在休眠的m&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e4%ba%8c-%e5%94%a4%e9%86%92%e6%ad%a3%e5%9c%a8%e4%bc%91%e7%9c%a0%e7%9a%84m&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;当创建一个G时，会尝试唤醒M的休眠队列，假定G2唤醒了M2，M2绑定了P2，此时P2本地队列里没有G，M2此时为&lt;strong&gt;自旋线程&lt;/strong&gt;（没有G可以运行，不断地寻找可运行的G）。&lt;strong&gt;自旋线程的存在是为了通过短期的自旋来防止线程被销毁。但过多的自旋线程会白白浪费CPU，所以结合两种情况，系统中最多存在GOMAXPROCS个自旋线程。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/151aa47f882f1b5ca92cffb7cc097a9c.png&#34; alt=&#34;151aa47f882f1b5ca92cffb7cc097a9c.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;场景三: 被唤醒的M从全局队列取G&#xA;    &lt;div id=&#34;场景三-被唤醒的m从全局队列取g&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e4%b8%89-%e8%a2%ab%e5%94%a4%e9%86%92%e7%9a%84m%e4%bb%8e%e5%85%a8%e5%b1%80%e9%98%9f%e5%88%97%e5%8f%96g&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;在场景二中被唤醒的M会从全局队列取出n个G来运行，n的计算法则：n = min(len(GQ)/GOMAXPROCS + 1, len(GQ/2))，至少从全局队列取1个G，但每次不要从全局队列移动太多的G到P本地队列，这是&lt;strong&gt;从全局队列到P本地队列的负载均衡&lt;/strong&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>熔断与限流</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E7%86%94%E6%96%AD%E4%B8%8E%E9%99%90%E6%B5%81/</link>
      <pubDate>Wed, 08 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E7%86%94%E6%96%AD%E4%B8%8E%E9%99%90%E6%B5%81/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;微服务限流&#xA;    &lt;div id=&#34;微服务限流&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%be%ae%e6%9c%8d%e5%8a%a1%e9%99%90%e6%b5%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;&lt;strong&gt;限流&lt;/strong&gt;顾名思义，就是对请求或并发数进行限制；通过对一个时间窗口内的请求量进行限制来保障系统的正常运行。如果我们的服务资源有限、处理能力有限，就需要对调用我们服务的上游请求进行限制，以防止自身服务由于资源耗尽而停止服务。在限流中有两个概念需要了解：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;阈值&lt;/strong&gt;：在一个单位时间内允许的请求量。如 &lt;a href=&#34;https://so.csdn.net/so/search?q=QPS&amp;amp;spm=1001.2101.3001.7020&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;QPS&lt;/a&gt; 限制为10，说明 1 秒内最多接受 10 次请求。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;拒绝策略&lt;/strong&gt;：超过阈值的请求的拒绝策略，常见的拒绝策略有直接拒绝、排队等待等。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 固定窗口算法&#xA;    &lt;div id=&#34;1-固定窗口算法&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e5%9b%ba%e5%ae%9a%e7%aa%97%e5%8f%a3%e7%ae%97%e6%b3%95&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;固定窗口算法&lt;/strong&gt;又叫&lt;strong&gt;计数器算法&lt;/strong&gt;，是一种&lt;strong&gt;简单&lt;/strong&gt;方便的限流算法。主要通过一个支持&lt;strong&gt;原子操作&lt;/strong&gt;的计数器来累计 1 秒内的请求次数，当 1 秒内计数达到限流阈值时触发拒绝策略。每过 1 秒，计数器重置为 0 开始重新计数。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之gin源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bgin%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bgin%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;gin&#xA;    &lt;div id=&#34;gin&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gin&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;gin是一个用Go语言编写的web框架。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;demo&#xA;    &lt;div id=&#34;demo&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#demo&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;github.com/gin-gonic/gin&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Default&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;r&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GET&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/ping&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Context&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;JSON&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;H&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pong&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        })&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    })&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;r&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Run&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;流程分析&#xA;    &lt;div id=&#34;流程分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%b5%81%e7%a8%8b%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;以下分析基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;github.com/gin-gonic/gin v1.5.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;1. 创建Engin&#xA;    &lt;div id=&#34;1-创建engin&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e5%88%9b%e5%bb%baengin&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Engin即引擎，Engin是 Web Server 的基础支持，也是&lt;strong&gt;服务的入口&lt;/strong&gt;和&lt;strong&gt;根级的数据结构&lt;/strong&gt;。下面是Engin的定义。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之slice</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bslice/</link>
      <pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bslice/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;slice&#xA;    &lt;div id=&#34;slice&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#slice&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;本文旨在讲解slice的数据结构及扩容策略，以下内容基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go version go1.16.2 darwin/amd64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;slice数据结构&#xA;    &lt;div id=&#34;slice数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#slice%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;slice&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;array&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;unsafe&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Pointer&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//指向底层数组的指针&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;len&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//slice的长度 len(s)的返回值 for range 遍历slice的话也是以这个为终点&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;cap&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//slice的容量 cap(s)的返回值&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;slice扩容策略&#xA;    &lt;div id=&#34;slice扩容策略&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#slice%e6%89%a9%e5%ae%b9%e7%ad%96%e7%95%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;可以使用append函数给slice添加元素&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>pod流程状态</title>
      <link>http://blog.chuckchan.top/posts/middleware/k8s/pod%E6%B5%81%E7%A8%8B%E7%8A%B6%E6%80%81/</link>
      <pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/k8s/pod%E6%B5%81%E7%A8%8B%E7%8A%B6%E6%80%81/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;pod状态分析&#xA;    &lt;div id=&#34;pod状态分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#pod%e7%8a%b6%e6%80%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 一个pod的状态之旅&#xA;    &lt;div id=&#34;1-一个pod的状态之旅&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e4%b8%80%e4%b8%aapod%e7%9a%84%e7%8a%b6%e6%80%81%e4%b9%8b%e6%97%85&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;从宏观的角度上来看，pod的一生要经历以下5个状态：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Pending&lt;/strong&gt;：Pod被K8s创建出来后，起始于Pending阶段。在Pending阶段，Pod将经过调度，被分配至目标节点开始拉取镜像、加载依赖项、创建容器。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Running&lt;/strong&gt;：当Pod所有容器都已被创建，且至少一个容器已经在运行中，Pod将进入Running阶段。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Succeeded&lt;/strong&gt;：当Pod中的所有容器都执行完成后终止，并且不会再重启，Pod将进入Succeeded阶段。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Failed&lt;/strong&gt;：若Pod中的所有容器都已终止，并且至少有一个容器是因为失败终止，也就是说容器以非0状态异常退出或被系统终止，Pod将进入Failed阶段。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Unkonwn&lt;/strong&gt;：因为某些原因无法取得 Pod 状态，这种情况Pod将被置为Unkonwn状态。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;一般来说，对于Job类型的负载，Pod在成功执行完任务之后将会以Succeeded状态为终态。而对于Deployment等负载，一般期望Pod能够持续提供服务，直到Pod因删除消失，或者因异常退出/被系统终止而进入Failed阶段。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/v2-c1f0ef376ba1a8b5661d8c4c7939b8f4_1440w.jpg&#34; alt=&#34;v2-c1f0ef376ba1a8b5661d8c4c7939b8f4_1440w&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. pod的异常场景&#xA;    &lt;div id=&#34;2-pod的异常场景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-pod%e7%9a%84%e5%bc%82%e5%b8%b8%e5%9c%ba%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;上面从宏观角度上介绍了pod的几种状态，但pod还有一些细分的状态如：Ready/NotReady、Initialized、 PodScheduled/Unschedulable 等等。这些细分状态描述造成Pod所处阶段的具体成因是什么。比如，Pod 当前阶段是Pending，对应的细分状态是 Unschedulable，这就意味着Pod调度出现了问题。&lt;/p&gt;&#xA;&lt;p&gt;与此同时，容器也有自己的生命周期：Waiting、Running和 Terminated，并且也有其对应的状态原因（Reason），例如ContainerCreating、Error、OOMKilled、CrashLoopBackOff、Completd等。而对于发生过重启或终止的容器，上一个状态（LastState）字段不仅包含状态原因，还包含上一次退出的状态码（Exit Code）。例如容器上一次退出状态码是137，状态原因是OOMKilled，说明容器是因为OOM被系统强行终止。在异常诊断过程中，&lt;strong&gt;容器的退出状态&lt;/strong&gt;是至关重要的信息。&lt;/p&gt;&#xA;&lt;p&gt;Pod在其生命周期的许多时间点可能发生不同的异常，按照Pod容器是否运行为标志点，我们将异常场景大致分为两类：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;在pod进行调度并创建容器的过程中发生异常，此时pod将卡在pending阶段。&lt;/li&gt;&#xA;&lt;li&gt;在pod容器运行中发生异常，此时pod按照具体的场景处于不同的阶段。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/v2-fcfebbc2fbcafff21d56c94cf7590c99_1440w (1).webp&#34; alt=&#34;v2-fcfebbc2fbcafff21d56c94cf7590c99_1440w (1)&#34; style=&#34;zoom:67%;&#34; /&gt;&#xA;&lt;p&gt;具体场景分析：&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;pod异常场景&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/pod%e5%bc%82%e5%b8%b8%e5%9c%ba%e6%99%af.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>一致性哈希</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E4%B8%80%E8%87%B4%E6%80%A7%E5%93%88%E5%B8%8C/</link>
      <pubDate>Mon, 06 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E4%B8%80%E8%87%B4%E6%80%A7%E5%93%88%E5%B8%8C/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;一致性hash&#xA;    &lt;div id=&#34;一致性hash&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%80%e8%87%b4%e6%80%a7hash&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;如何分配请求&#xA;    &lt;div id=&#34;如何分配请求&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e5%88%86%e9%85%8d%e8%af%b7%e6%b1%82&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;当数据库的量太大时，可能会考虑分库分表，当分库分表之后，那就需要考虑对应的数据如何存储的问题。这里以用户库分表为例。当一个获取用户信息的请求过来，如何根据user_id去对应的表找对应的用户信息？&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-07-27_10-18-23&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-07-27_10-18-23.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;其实不仅是分库分表，在一些负载均衡中间件里，也有同样的问题（比如利用用户ip来决定请求流量往哪个服务器走）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-07-27_10-28-58&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-07-27_10-28-58.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;普通哈希&#xA;    &lt;div id=&#34;普通哈希&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%99%ae%e9%80%9a%e5%93%88%e5%b8%8c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;很容易想到，解决请求如何分配的一个解决方法就是将sharding_key哈希，得到hash值后对节点数进行取模运算。获取节点的公式即为：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hash(key) % num_of_nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;还是以用户表为例子，假设有将用户表分成三个表，分别是user_table_1，user_table_2，user_table_3。具体计算流程如图所示。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-07-27_10-52-10&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-07-27_10-52-10.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;普通哈希的方法根据user_id定位到具体的表，这样看似是解决了问题，但是如果用户量突然增长，需要再加一张表时，原先的表数量将由3变成4，sharding的计算方式也变hash(user_id)%4，并且需要进行大量的数据迁移。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-07-27_11-03-01&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-07-27_11-03-01.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;要解决这个问题，需要对user表的数据重新按照节点4进行迁移，&lt;strong&gt;坏情况下所有数据都需要迁移，所以它的数据迁移规模是 O(M)&lt;/strong&gt;，这样数据的迁移成本太高了。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;一致性哈希&#xA;    &lt;div id=&#34;一致性哈希&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%80%e8%87%b4%e6%80%a7%e5%93%88%e5%b8%8c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;一致性哈希可以解决我们当节点变化时数据迁移量太大的问题。**一致性哈希的也是用取模的方法，但它不是对节点数取模，而是对2^64-1取模。**一致性哈希将哈希值对2^64-1所有的结果组织成一个圆环，称为哈希环。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>web安全</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/web%E5%AE%89%E5%85%A8/</link>
      <pubDate>Thu, 02 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/web%E5%AE%89%E5%85%A8/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;web安全&#xA;    &lt;div id=&#34;web安全&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#web%e5%ae%89%e5%85%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. CSRF攻击&#xA;    &lt;div id=&#34;1-csrf攻击&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-csrf%e6%94%bb%e5%87%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;CSRF&lt;/strong&gt;是跨站请求伪造的缩写，也被称为&lt;strong&gt;XSRF&lt;/strong&gt;， 是一种挟制用户在当前已登录的&lt;strong&gt;Web&lt;/strong&gt;应用程序上执行非本意的操作的攻击方法。**因为CSRF攻击利用的是冲着浏览器分不清发起请求是不是真正的用户本人。**也就是说，简单的身份验证只能保证请求发自某个用户的浏览器，却不能保证请求本身是用户自愿发出的。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;a. CSRF的基本攻击原理&#xA;    &lt;div id=&#34;a-csrf的基本攻击原理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a-csrf%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%94%bb%e5%87%bb%e5%8e%9f%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;用户Alice登录和访问某银行网站A，保留&lt;strong&gt;cookie&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;Alice被某些信息诱导访问危险网站B。&lt;/li&gt;&#xA;&lt;li&gt;危险网站B上有一个&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;标签：&lt;img src=&#34;http://www.examplebank.com/account=Alice&amp;amount=1000&amp;payfor=Badman&#34; &gt;&lt;/li&gt;&#xA;&lt;li&gt;这个标签的src不指向一张图片，而是一个http请求，这个请求向银行要求将Alice的1000元转给Badman，由于Alice的浏览器上有&lt;strong&gt;cookie&lt;/strong&gt;，这样浏览器发出的这个请求就能得到响应执行。&lt;/li&gt;&#xA;&lt;li&gt;这样Alice的钱就被偷了。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;b. CSRF的防范&#xA;    &lt;div id=&#34;b-csrf的防范&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#b-csrf%e7%9a%84%e9%98%b2%e8%8c%83&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;黑客仅仅靠CSRF发起攻击，他只能借助受害者的cookie骗取服务器的信任，但是黑客并不能凭借拿到cookie，也看不到 cookie的内容。这就告诉我们，我们要保护的对象是那些可以直接产生数据改变的服务，而对于读取数据的服务，则不需要进行csrf的保护。而保护的关键，是 &lt;strong&gt;在请求中放入黑客所不能伪造的信息&lt;/strong&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Kafaka之数据消费</title>
      <link>http://blog.chuckchan.top/posts/middleware/kafka/kafaka%E4%B9%8B%E6%95%B0%E6%8D%AE%E6%B6%88%E8%B4%B9/</link>
      <pubDate>Wed, 01 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/kafka/kafaka%E4%B9%8B%E6%95%B0%E6%8D%AE%E6%B6%88%E8%B4%B9/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;kafaka之消费数据&#xA;    &lt;div id=&#34;kafaka之消费数据&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#kafaka%e4%b9%8b%e6%b6%88%e8%b4%b9%e6%95%b0%e6%8d%ae&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;消费方式&#xA;    &lt;div id=&#34;消费方式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%b6%88%e8%b4%b9%e6%96%b9%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;我们知道消息队列一般有两种实现方式,(1)Push(推模式) (2)Pull(拉模式)，那么 Kafka Consumer 究竟采用哪种方式进行消费的呢？&lt;strong&gt;其实 Kafka Consumer 采用的是主动拉取 Broker 数据进行消费的即 Pull 模式&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;推模式： Push 模式最大缺点就是 Broker 不清楚 Consumer 的消费速度，且推送速率是 Broker 进行控制的， 这样很容易造成消息堆积，如果 Consumer 中执行的任务操作是比较耗时的，那么 Consumer 就会处理的很慢， 严重情况可能会导致系统 Crash。&lt;/li&gt;&#xA;&lt;li&gt;拉模式：如果选择 Pull 模式，这时 Consumer 可以根据自己的情况和状态来拉取数据, 也可以进行延迟处理。但是如果 Kafka Broker 没有消息，这时每次 Consumer 拉取的都是空数据, 可能会一直循环返回空数据。 针对这个问题，Consumer 在每次调用 Poll() 消费数据的时候，顺带一个 timeout 参数，当返回空数据的时候，会在 Long Polling 中进行阻塞，等待 timeout 再去消费，直到数据到达。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;消费者组&#xA;    &lt;div id=&#34;消费者组&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%b6%88%e8%b4%b9%e8%80%85%e7%bb%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;为什么 Kafka 要设计 Consumer Group, 只有 Consumer 不可以吗？&lt;/strong&gt; 我们知道 Kafka 是一款高吞吐量，低延迟，高并发, 高可扩展性的消息队列产品， 那么如果某个 Topic 拥有数百万到数千万的数据量， 仅仅依靠 Consumer 进程消费， 消费速度可想而知， 所以需要一个扩展性较好的机制来保障消费进度， 这个时候 Consumer Group 应运而生， &lt;strong&gt;Consumer Group 是 Kafka 提供的可扩展且具有容错性的消费者机制。&lt;/strong&gt;  &lt;strong&gt;Kafka Consumer Group 特点如下:&lt;/strong&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>k8s组件</title>
      <link>http://blog.chuckchan.top/posts/middleware/k8s/k8s%E7%BB%84%E4%BB%B6/</link>
      <pubDate>Mon, 27 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/k8s/k8s%E7%BB%84%E4%BB%B6/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;k8s组件&#xA;    &lt;div id=&#34;k8s组件&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#k8s%e7%bb%84%e4%bb%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 控制平面与工作节点&#xA;    &lt;div id=&#34;1-控制平面与工作节点&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e6%8e%a7%e5%88%b6%e5%b9%b3%e9%9d%a2%e4%b8%8e%e5%b7%a5%e4%bd%9c%e8%8a%82%e7%82%b9&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;一组工作机器，称为&lt;em&gt;节点&lt;/em&gt;， &lt;em&gt;节点&lt;/em&gt;会运行容器化的应用程序。整个k8s集群由控制平面（master节点）与worker节点构成。&lt;/p&gt;&#xA;&lt;p&gt;控制平面的组件用来存储、管理集群状态，其中包括：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;etcd分布式持久化存储&lt;/li&gt;&#xA;&lt;li&gt;API服务器&lt;/li&gt;&#xA;&lt;li&gt;调度器&lt;/li&gt;&#xA;&lt;li&gt;控制器管理器&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;而运行容器的任务依赖千每个工作节点上运行的组件：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Kubelet&lt;/li&gt;&#xA;&lt;li&gt;Kubelet服务代理( kube-proxy)&lt;/li&gt;&#xA;&lt;li&gt;容器运行时(Docker、rkt或者其他）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;出了这些组件外，还有一些附加组件，他们共同构成了整个k8s集群。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Kubemetes DNS服务器&lt;/li&gt;&#xA;&lt;li&gt;仪表板&lt;/li&gt;&#xA;&lt;li&gt;Ingress控制器&lt;/li&gt;&#xA;&lt;li&gt;Heapster (容器集群监控）&lt;/li&gt;&#xA;&lt;li&gt;容器网络接口插件&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;整体构造入下图所示：&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-12-17_15-30-10.jpg&#34; alt=&#34;Xnip2022-12-17_15-30-10&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&lt;p&gt;可以使用如下命令来查看当前k8s集群的组件状态：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubect1 get componentstatuses&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 组件分析&#xA;    &lt;div id=&#34;2-组件分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e7%bb%84%e4%bb%b6%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;2.1 etcd&#xA;    &lt;div id=&#34;21-etcd&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#21-etcd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;负责存储集群中各种资源对象的信息，k/v方式存储，所有的 k8s 集群数据存放在此&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>MySQL之explain</title>
      <link>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bexplain/</link>
      <pubDate>Mon, 27 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bexplain/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Explain&#xA;    &lt;div id=&#34;explain&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#explain&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;MySQL 提供了一个 &lt;strong&gt;EXPALIN&lt;/strong&gt; 命令，可以用于对 &lt;strong&gt;SELECT 语句&lt;/strong&gt; 的执行计划进行分析，并详细的输出分析结果，供开发人员进行针对性的优化。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;字段介绍&#xA;    &lt;div id=&#34;字段介绍&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ad%97%e6%ae%b5%e4%bb%8b%e7%bb%8d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;u&gt;id&lt;/u&gt;: SELECT查询序列号，即为sql语句执行的顺序&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;select_type&lt;/u&gt;:  SELECT的类型，他有以下几种类型：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;simple&lt;/em&gt;: 最简单的select，表示没有union与子查询&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;primary&lt;/em&gt;: 在有子查询的语句中，外面的那一层select即为primary&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;union&lt;/em&gt;: union查询语句的第二个语句，即为union&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;union result&lt;/em&gt;: union语句的结果&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;table&lt;/u&gt;: 所用到的表&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;type&lt;/u&gt;: 连接类型，后面再详细介绍&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;possible_keys&lt;/u&gt;: 可能使用到的索引&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;key&lt;/u&gt;: 实际选择的索引&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;key_len&lt;/u&gt;: 使用的索引长度&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;ref&lt;/u&gt;: 索引的哪一列被使用了&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;rows&lt;/u&gt;: 估计要扫描的行，数字越大select的效率越低&lt;/li&gt;&#xA;&lt;li&gt;&lt;u&gt;extra&lt;/u&gt;: 额外信息，后面再详细介绍&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;type详解&#xA;    &lt;div id=&#34;type详解&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#type%e8%af%a6%e8%a7%a3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;type表示SQL语句对表的访问方式（MySQL在表中找到所需行的方式），又称访问类型，通常用type的值来判断SQL语句是否使用到索引。type的值有以下几种，由好到差依次是：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之GC</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bgc/</link>
      <pubDate>Thu, 23 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bgc/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之GC&#xA;    &lt;div id=&#34;golang之gc&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bgc&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;为什么要有GC&#xA;    &lt;div id=&#34;为什么要有gc&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e6%9c%89gc&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;当程序启动的时候，操作系统会给程序分配堆区与栈区，栈区里的内存是可以自动管理的，当栈区变量的作用域结束，可以被自动收回。堆区属于程序员自己管理的区域，即使堆区变量的作用域结束，后续可能继续使用。所以对于堆区的内存，程序员需要实时关注，如果内存一直增长没有释放，则会溢出，如果内存释放后还继续访问，则会出现非法访问。那有没有一种机制能够让堆区的闲置的内存自动回收？GC可以帮我们做到。GC(Ggrbage Collect)即垃圾回收，它可以通过一定的策略，让程序自动管理内存，让开发者更增加专注业务的开发。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;GC常用的策略&#xA;    &lt;div id=&#34;gc常用的策略&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gc%e5%b8%b8%e7%94%a8%e7%9a%84%e7%ad%96%e7%95%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;引用计数法&lt;/strong&gt;。引用计数法为对象维护一个计数器，当对象被引用时，计数器加1，引用被释放，计数器减1，当计数器为0时，表示没有被引用，清除这个对象。引用计数法实现简单，但频繁更新计数器会带来一定开销，且无法解决循环引用的弊端。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;标记-清除法&lt;/strong&gt;。标记-清除法是对对象定时进行标记，标记为“正在使用”与“没有被使用”两种，标记完后对标记为“没有被使用”的进行清除。由于程序是动态在运行的，随时有可能改变对象引用指向，因此，在标记的时候需要STW(Stop The World)，即程序停止一段时间，这段时间专门用来做标记。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;Golang中的GC策略&#xA;    &lt;div id=&#34;golang中的gc策略&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b8%ad%e7%9a%84gc%e7%ad%96%e7%95%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Golang在v1.5之前是使用&lt;strong&gt;清除-标记法&lt;/strong&gt;的策略进行GC，但v1.5使用了&lt;strong&gt;三色标记法&lt;/strong&gt;，所谓三色标记法就是通过三个阶段来去定对象的状态（黑色/白色/灰色分别代表三个不同的状态）。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;白色：初始对象&lt;/li&gt;&#xA;&lt;li&gt;灰色：要被清除的对象&lt;/li&gt;&#xA;&lt;li&gt;黑色：任然在使用的对象&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;1.创建新对象，全部为白色&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;096d844d693cc098943cc0f29e774e9c.png&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/096d844d693cc098943cc0f29e774e9c.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Etcd</title>
      <link>http://blog.chuckchan.top/posts/middleware/etcd/etcd/</link>
      <pubDate>Wed, 22 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/etcd/etcd/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;etcd&#xA;    &lt;div id=&#34;etcd&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#etcd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;​    etcd是CoreOS基于Raft协议开发的&lt;a href=&#34;https://so.csdn.net/so/search?q=%e5%88%86%e5%b8%83%e5%bc%8f&amp;amp;spm=1001.2101.3001.7020&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;分布式&lt;/a&gt;key-value存储，可用于服务发现、共享配置以及一致性保障（如数据库选主、分布式锁等）。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;简单：&lt;a href=&#34;https://so.csdn.net/so/search?q=curl&amp;amp;spm=1001.2101.3001.7020&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;curl&lt;/a&gt;可访问的用户的API（HTTP + JSON）&lt;/li&gt;&#xA;&lt;li&gt;安全：可选的SSL客户端证书认证&lt;/li&gt;&#xA;&lt;li&gt;快速： 单实例每秒1000次写操作&lt;/li&gt;&#xA;&lt;li&gt;可靠：使用Raft算法保证一致性&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;架构&#xA;    &lt;div id=&#34;架构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%9e%b6%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;Xnip2022-09-08_11-13-48&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-09-08_11-13-48.jpg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Client层&lt;/strong&gt;：client层包括client v2和v3两个⼤版本API客⼾端库，提供了简洁易⽤的API，同时⽀持负载均衡、节点间故障⾃动转移，可极⼤降低业务使⽤etcd复杂度，提升开发效率、服务可⽤性。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;API网络层&lt;/strong&gt;：API⽹络层主要包括client访问server和server节点之间的通信协议。⼀⽅⾯，client访问etcd server的API分为v2和v3两个⼤版本。v2 API使⽤HTTP/1.x协议，v3 API使⽤gRPC协议。同时v3通过etcd grpc-gateway组件也⽀持HTTP/1.x协议，便于各种语⾔的服务调⽤。另⼀⽅⾯，server之间通信协议， 是指节点间通过Raft算法实现数据复制和Leader选举等功能时使⽤的HTTP/2协议。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Raft算法层&lt;/strong&gt;：Raft算法层实现了Leader选举、⽇志复制、ReadIndex等核⼼算法特性，⽤于保障etcd多个etcd是典型的读多&lt;/p&gt;&#xA;&lt;p&gt;节点间的数据⼀致性、提升服务可⽤性等，是etcd的基⽯和亮点。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;功能逻辑层&lt;/strong&gt;：etcd核⼼特性实现层，如典型的KVServer模块、MVCC模块、Auth鉴权模块、Lease租约模 块、Compactor压缩模块等，其中MVCC模块主要由treeIndex模块和boltdb模块组成。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;存储层&lt;/strong&gt;：存储层包含预写⽇志(WAL)模块、快照(Snapshot)模块、boltdb模块。其中WAL可保障etcd crash后数据不丢失，boltdb则保存了集群元数据和⽤⼾写⼊的数据。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;读取数据&#xA;    &lt;div id=&#34;读取数据&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%af%bb%e5%8f%96%e6%95%b0%e6%8d%ae&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;etcd有两种读取数据的模式，分别是&lt;strong&gt;串行读&lt;/strong&gt;与&lt;strong&gt;线性读&lt;/strong&gt;，其中线性读是&lt;strong&gt;默认&lt;/strong&gt;的读取方式。再说读取数据之前先简单说明下写的流程。当client发起⼀个更新hello为 world请求后，若Leader收到写请求，它会将此请求持久化到WAL⽇志，并⼴播给各个节点，若⼀半以上节点持久化成功，则该请求对应的⽇志条⽬被标识为已提交，etcdserver模块异步从Raft模块获取已提交的⽇志条⽬，应⽤到状态机(boltdb等)。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>GeoHash算法</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/geohash%E7%AE%97%E6%B3%95/</link>
      <pubDate>Wed, 22 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/geohash%E7%AE%97%E6%B3%95/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;GeoHash&#xA;    &lt;div id=&#34;geohash&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#geohash&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;背景&#xA;    &lt;div id=&#34;背景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%83%8c%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;经纬度是经度与纬度的合称组成一个坐标系统，称为地理坐标系统，它是一种利用三度空间的球面来定义地球上的空间的球面坐标系统，能够标示地球上的任何一个位置。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;57eb711c1d9cded841228b29b821eeba&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/57eb711c1d9cded841228b29b821eeba.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;GeoHash&#xA;    &lt;div id=&#34;geohash-1&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#geohash-1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;GeoHash是空间索引的一种方式，其基本原理是将地球理解为一个二维平面，通过把二维的空间经纬度数据编码为一个字符串，可以把平面递归分解成更小的子块，每个子块在一定经纬度范围内拥有相同的编码。简单地说就是&lt;strong&gt;将二维的坐标转换成一维坐标，从而提高对位置数据的检索效率。&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;编码规则&#xA;    &lt;div id=&#34;编码规则&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bc%96%e7%a0%81%e8%a7%84%e5%88%99&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;先将纬度范围(-90, 90)平分成两个区间(-90, 0)和(0, 90)，如果目标维度位于前一个区间，则编码为0，否则编码为1，然后根据目标纬度所落的区间再平均分成两个区间进行编码，以此类推，直到精度满足要求，经度也用同样的算法，对(-180, 180)依次细分，然后合并经度和纬度的编码，奇数位放纬度，偶数位放经度，组成一串新的二进制编码，按照Base32进行编码。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;编码示例&#xA;    &lt;div id=&#34;编码示例&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bc%96%e7%a0%81%e7%a4%ba%e4%be%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;以经纬度值：（116.389550， 39.928167）进行算法说明，对纬度39.928167进行逼近编码 (地球纬度区间是[-90,90]）&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之channel源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bchannel%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bchannel%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之channel源码分析&#xA;    &lt;div id=&#34;golang之channel源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bchannel%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1.  channel&#xA;    &lt;div id=&#34;1--channel&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1--channel&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;channel是支撑Go语言高性能并发编程模型的重要结构，channel是一个用于同步和通信的&lt;strong&gt;有锁环形队列&lt;/strong&gt;，使用互斥锁解决程序中可能存在的线程竞争问题。以下内容基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go version go1.16.2 darwin/amd64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. channel的数据结构&#xA;    &lt;div id=&#34;2-channel的数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-channel%e7%9a%84%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;channel其是用runtime.hchan来表示的。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;hchan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;qcount&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;uint&lt;/span&gt;           &lt;span style=&#34;color:#75715e&#34;&gt;// 缓冲区buffer里有几个元素&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;dataqsiz&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint&lt;/span&gt;           &lt;span style=&#34;color:#75715e&#34;&gt;// 缓冲区buffer最多有几个元素 即缓冲区大小&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;buf&lt;/span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;unsafe&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Pointer&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// 指向底层循环数组的指针&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;elemsize&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint16&lt;/span&gt;         &lt;span style=&#34;color:#75715e&#34;&gt;// 元素大小&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;closed&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 是否关闭&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;elemtype&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;_type&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 元素的类型&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;sendx&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint&lt;/span&gt;         &lt;span style=&#34;color:#75715e&#34;&gt;// 已发送元素在环形数组中的索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;recvx&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint&lt;/span&gt;         &lt;span style=&#34;color:#75715e&#34;&gt;// 已接收元素在环形数组中的索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;recvq&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;waitq&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 等待接收的goroutine队列&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;sendq&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;waitq&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 待发送的goroutine队列&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;lock&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex&lt;/span&gt;            &lt;span style=&#34;color:#75715e&#34;&gt;//锁 保护数据&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;recvq与sendq是waitq类型的数据，分别代表接受的g队列与发送的g队列，waitq是一个双端链表。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>设计模式之简介</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%AE%80%E4%BB%8B/</link>
      <pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%AE%80%E4%BB%8B/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;设计模式&#xA;    &lt;div id=&#34;设计模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;什么是设计模式？&lt;/p&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;“软件设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结，使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。”&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;一句大白话可以总结：“在一定环境下，用固定套路解决问题。”&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;分类&#xA;    &lt;div id=&#34;分类&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%86%e7%b1%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;常用的设计模式共有23种，其中包括：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;创建型(Creational)模式：如何创建对象；&#xA;&lt;ol&gt;&#xA;&lt;li&gt;单例模式&lt;/li&gt;&#xA;&lt;li&gt;简单工厂模式&lt;/li&gt;&#xA;&lt;li&gt;工厂方法模式&lt;/li&gt;&#xA;&lt;li&gt;抽象工厂模式&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;结构型(Structural )模式：如何实现类或对象的组合；&#xA;&lt;ol&gt;&#xA;&lt;li&gt;代理模式&lt;/li&gt;&#xA;&lt;li&gt;装饰模式&lt;/li&gt;&#xA;&lt;li&gt;适配器模式&lt;/li&gt;&#xA;&lt;li&gt;外观模式&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;行为型(Behavioral)模式：类或对象怎样交互以及怎样分配职责。&#xA;&lt;ol&gt;&#xA;&lt;li&gt;模版方法模式&lt;/li&gt;&#xA;&lt;li&gt;命令模式&lt;/li&gt;&#xA;&lt;li&gt;外观模式&lt;/li&gt;&#xA;&lt;li&gt;观察者模式&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;原则&#xA;    &lt;div id=&#34;原则&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8e%9f%e5%88%99&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;名称&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;定义&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;单一职责原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;类的职责单一，对外只提供一种功能，而引起类变化的原因都应该只有一个。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;开闭原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;类的改动是通过增加代码进行的，而不是修改源代码。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;里氏代换原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;任何抽象类（interface接口）出现的地方都可以用他的实现类进行替换，实际就是虚拟机制，语言级别实现面向对象功能。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;依赖倒转原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;依赖于抽象(接口)，不要依赖具体的实现(类)，也就是针对接口编程。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;接口隔离原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;不应该强迫用户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能，不应该把所有操作都封装到一个接口中去。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;合成复用原则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;如果使用继承，会导致父类的任何变换都可能影响到子类的行为。如果使用对象组合，就降低了这种依赖关系。对于继承和组合，优先使用组合。&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;迪米特法则&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;一个对象应当对其他对象尽可能少的了解，从而降低各个对象之间的耦合，提高系统的可维护性（黑盒原理）&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之boltdb源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bboltdb%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bboltdb%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;blotdb&#xA;    &lt;div id=&#34;blotdb&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#blotdb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 简介&#xA;    &lt;div id=&#34;1-简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;boltdb是一个纯go编写的支持事务的文件型单机kv数据库。&lt;/strong&gt; 其具有以下特点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;单机部署：不需要考虑&lt;strong&gt;CAP&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;支持事物：仅允许&lt;strong&gt;多个只读事务和最多一个读写事务&lt;/strong&gt;同时运行&lt;/li&gt;&#xA;&lt;li&gt;索引结构：因为是kv型的数据库，所以天然地只有主键索引（&lt;strong&gt;B+树实现&lt;/strong&gt;），减少了磁盘IO&lt;/li&gt;&#xA;&lt;li&gt;缓存管理：仅管理写缓存，利用&lt;strong&gt;mmap&lt;/strong&gt;管理读缓存&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 核心数据结构分析&#xA;    &lt;div id=&#34;2-核心数据结构分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e6%a0%b8%e5%bf%83%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;先从介绍一下bolt使用的一些底层的数据结构。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;db&lt;/li&gt;&#xA;&lt;li&gt;page&lt;/li&gt;&#xA;&lt;li&gt;node&lt;/li&gt;&#xA;&lt;li&gt;bucket&lt;/li&gt;&#xA;&lt;li&gt;cursor&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;u&gt;&lt;em&gt;1. db&lt;/em&gt;&lt;/u&gt;&#xA;    &lt;div id=&#34;1-db&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-db&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在boltdb中，它的数据全部都是存储在文件上，一个db对应一个真实的磁盘文件。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之context源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bcontext%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bcontext%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之context源码分析&#xA;    &lt;div id=&#34;golang之context源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bcontext%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;Context是什么&#xA;    &lt;div id=&#34;context是什么&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#context%e6%98%af%e4%bb%80%e4%b9%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Context是Golang中独特的数据结构，可以用来设置截至日期、同步信号、传递请求相关值，&lt;strong&gt;总地来说就是在goroutine构成的树形结构中对信号进行同步以减少计算资源的浪费&lt;/strong&gt;。以下内容基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go version go1.16.2 darwin/amd64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;Context的数据结构&#xA;    &lt;div id=&#34;context的数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#context%e7%9a%84%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Context是一个接口，来看下它的接口定义&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Context&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//Deadline方法是获取设置的截至时间，到了这个截至时间，&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//Context会自动发起取消，第二个返回值ok代表是否有设置&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//截至时间&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Deadline&lt;/span&gt;() (&lt;span style=&#34;color:#a6e22e&#34;&gt;deadline&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Time&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;) &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//Done方法返回一个只读的chan，当这个chan收到消息时代&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//表Parent Context已经发起了取消请求，当前goroutine&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//要开始做清理操作了&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Done&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt;{} &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//Err返回Context被取消的原因&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Err&lt;/span&gt;() &lt;span style=&#34;color:#66d9ef&#34;&gt;error&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//Value方法返回Context绑定的对应的key的值，这个是线程安全的&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Value&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;key&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt;{}) &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt;{}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;context包提供了6种创建Context的方法。每个方法都会返回一种类型的结构体，这些结构体都实现了Context接口。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之map源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bmap%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bmap%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之map源码分析&#xA;    &lt;div id=&#34;golang之map源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bmap%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;哈希表&#xA;    &lt;div id=&#34;哈希表&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%93%88%e5%b8%8c%e8%a1%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;map即哈希表，也称为散列表，是根据关键码值(key value)而直接进行访问的数据结构。也就是说，它通过把关键码值映射（哈希函数）到表中一个位置来访问记录，以加快查找的速度。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;哈希碰撞&#xA;    &lt;div id=&#34;哈希碰撞&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%93%88%e5%b8%8c%e7%a2%b0%e6%92%9e&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;哈希函数是整个哈希表的关键。所以为了更好的性能，我们希望在尽可能短的时间内，相同的key经过哈希函数的计算，可以得到相同的索引，不同的key经过哈希函数的计算，可以得到不同的索引，但在实际中往往事与愿违，不同的key小概率会计算出相同的索引，这就是哈希冲突（collision），几乎所有的哈希函数都存在这个问题。常见的解决哈希冲突的方法有：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;em&gt;开放寻址法&lt;/em&gt;：开放寻址法是如果通过哈希函数计算出的key所对应的空间已经被占用了，就从数组尾部再找一个还没被占用的空间将数据存进去。&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;拉链法&lt;/em&gt;：实现拉链法一般会使用数组加上链表，数组的每个索引位置装的是一个链表，当发生hash冲突时，将新的kv挂在这个链表的尾部。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;版本&#xA;    &lt;div id=&#34;版本&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%89%88%e6%9c%ac&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;以下内容基于&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go version go1.16.2 darwin/amd64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;map的数据结构&#xA;    &lt;div id=&#34;map的数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#map%e7%9a%84%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Golang里map由runtime.hmap实现。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之sync.Once源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bsync.once%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bsync.once%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之sync.Once源码分析&#xA;    &lt;div id=&#34;golang之synconce源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bsynconce%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;sync.Once简介&#xA;    &lt;div id=&#34;synconce简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#synconce%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;sync.Once 是 Go 语言实现的一种对象，用来**保证某种行为只会被执行一次。**sync.Once通常用来实现单例模式的初始化。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;源码分析&#xA;    &lt;div id=&#34;源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;以下内容基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go version go1.16.2 darwin/amd64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;sync.Once结构&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Once&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;done&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//用来表示是否已经执行 0-未执行 1-以执行&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;m&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;Mutex&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//互斥锁&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;Sync.Once只提供了一个Do的方法。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;o&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Once&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Do&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 一种错误的方式是使用cas锁 atomic.CompareAndSwapUint32&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//&#x9;if atomic.CompareAndSwapUint32(&amp;amp;o.done, 0, 1) {&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//&#x9;&#x9;f()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//&#x9;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// cas锁虽然保证了原子操作，但可能会出现Do里的流程还没执行完就返回的情况&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 比如：A号groutine先执行了cas操作，将o.done改为1，然后执行Do流程，B号goroutine&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 也执行cas操作，发现o.done已经为1了，直接返回，但这时Do流程可能还未执行完！sync.Once&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 是要保证函数返回后Do流程一定是执行完的，所以这违反了它设计的原则。&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;atomic&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;LoadUint32&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;o&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;done&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; { &lt;span style=&#34;color:#75715e&#34;&gt;//如果 o.done==1 则说明方法已执行 直接返回 &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;// 如果是0 说明还未执行 进入执行doSlow流程（注意！！！这里可能有好几个goroutine进入这里去执行）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;o&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;doSlow&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;once.doSlow是正真执行Do流程的函数。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>延迟队列</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E5%BB%B6%E8%BF%9F%E9%98%9F%E5%88%97/</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E5%BB%B6%E8%BF%9F%E9%98%9F%E5%88%97/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;延迟队列&#xA;    &lt;div id=&#34;延迟队列&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%bb%b6%e8%bf%9f%e9%98%9f%e5%88%97&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;定义&#xA;    &lt;div id=&#34;定义&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%9a%e4%b9%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;队列是一种FIFO的数据结构，即先进队的数据先出队。延时队列相对于普通队列的来说，最大的区别在于他的延迟属性。延迟队列在入队的时候会指定一个延迟时间，表示其希望在经过改指定时间后处理这个任务。从某种意义上来讲，延迟队列的结构并不像一个队列，而更像一种以时间为权重的有序堆结构。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;应用场景&#xA;    &lt;div id=&#34;应用场景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;在淘宝、京东等购物平台上下单，15分钟内未付款，订单会自动取消。&lt;/li&gt;&#xA;&lt;li&gt;打车的时候，在规定时间没有车主接单，平台会取消你的单并提醒你暂时没有车主接单。&lt;/li&gt;&#xA;&lt;li&gt;点外卖的时候，如果商家在10分钟还没接单，就会自动取消订单。&lt;/li&gt;&#xA;&lt;li&gt;收快递的时候，如果我们没有点确认收货，在一段时间后程序会自动完成订单。&lt;/li&gt;&#xA;&lt;li&gt;在平台完成订单后，如果我们没有在规定时间评论商品，会自动默认买家不评论。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;如何实现&#xA;    &lt;div id=&#34;如何实现&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e5%ae%9e%e7%8e%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;如果是数据量较小且时实时性不高的场景，可以使用轮询的方式，比如每秒轮询数据库的所有数据，然后处理到期的任务。轮询的方式只能处理数据量较小且实时性不高的数据，如果像处理淘宝订单15分钟内未付款自动取消订单这种任务，就需要更加高效的处理方式了。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;em&gt;1. Redis的Zset&lt;/em&gt;&#xA;    &lt;div id=&#34;1-redis的zset&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-redis%e7%9a%84zset&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Redis中有一种有序集合的数据结构zset，zset中每一个元素都有对应的score，zset中所有的数据都是按照score来排序的。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>分布式理论</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E5%88%86%E5%B8%83%E5%BC%8F%E7%90%86%E8%AE%BA/</link>
      <pubDate>Tue, 14 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E5%88%86%E5%B8%83%E5%BC%8F%E7%90%86%E8%AE%BA/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;分布式理论&#xA;    &lt;div id=&#34;分布式理论&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%86%e5%b8%83%e5%bc%8f%e7%90%86%e8%ae%ba&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;CAP理论&#xA;    &lt;div id=&#34;cap理论&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#cap%e7%90%86%e8%ae%ba&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;C：Consistency，即一致性。所有节点都访问同一份数据节点。&lt;/li&gt;&#xA;&lt;li&gt;A：Availability，即可用性。每次请求都能获取到非错的响应，但不保证获取的数据为最新的数据。&lt;/li&gt;&#xA;&lt;li&gt;P：Partition tolerence，即分区容错性。在某个节点或者网络分区故障的时候，仍然能够对外提供一致性和可用性服务，也就是说部分故障不影响整体的使用。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;根据定理，&lt;strong&gt;分布式系统只能满足三项中的两项而不可能满足全部三项&lt;/strong&gt;。理解CAP理论的最简单方式是想像两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致，即丧失了C性质。如果为了保证数据一致性，将分区一侧的节点设置为不可用，那么又丧失了A性质。除非两个节点可以互相通信，才能既保证C又保证A，这又会导致丧失P性质。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;BASE理论&#xA;    &lt;div id=&#34;base理论&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#base%e7%90%86%e8%ae%ba&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;BASE是对CAP中一致性和可用性权衡的结果，其来源于对大规模互联网分布式系统实践的总结，是基于CAP定律逐步演化而来。其核心思想是&lt;strong&gt;即使无法做到强一致性，但每个应用都可以根据自身业务特点，才用适当的方式来使系统打到最终一致性&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;BA：Basically Available，即基本可用。假设系统某个模块出现了不可预知的故障，但其他模块依然可用。如双十一活动时，评论模块出现故障，但不会影响交易、商品等核心模块的使用。&lt;/li&gt;&#xA;&lt;li&gt;S：Soft Status，即软状态。指允许系统中出现中间状态，并认为该状态不影响系统的整体可用性，即允许系统在多个不同节点的数据副本存在数据延时。&lt;/li&gt;&#xA;&lt;li&gt;E：Eventually Consistent，即最终一致。上面讲到的软状态不可能一直是软状态，必须有时间期限。在期限过后，应当保证所有副本保持数据一致性，从而达到数据的最终一致性，因此所有客户端对系统的数据访问最终都能够获取到最新的值，而这个时间期限取决于网络延时，系统负载，数据复制方案等因素。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;总的来说，BASE 理论面向的是大型高可用可扩展的分布式系统，和传统事务的 ACID 是相反的，它完全不同于 ACID 的强一致性模型，而是通过&lt;strong&gt;牺牲强一致性来获得可用性，并允许数据在一段时间是不一致的&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Raft协议&#xA;    &lt;div id=&#34;raft协议&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#raft%e5%8d%8f%e8%ae%ae&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;分布式存统通常通过维护多个副本来进行容错，提高系统的可用性。要实现此目标，就必须要解决分布式系统的最核心问题：维护多个副本的一致性。Raft协议将一致性协议的核心内容分拆成为几个关键阶段，以简化流程，提高协议的可理解性。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之sync.Map源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bsync.map%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Mon, 13 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bsync.map%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之sync.Map源码分析&#xA;    &lt;div id=&#34;golang之syncmap源码分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bsyncmap%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;map的并发操作&#xA;    &lt;div id=&#34;map的并发操作&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#map%e7%9a%84%e5%b9%b6%e5%8f%91%e6%93%8d%e4%bd%9c&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;从前面文章的分析可以看到，原生的map如果并发读写的话，会抛出异常。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;h&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;flags&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;hashWriting&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;throw&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;concurrent map read and map write&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;也就是说原生的map不是并发安全的。如果要实现并发安全，可以在操作map的时候加一把mutex锁。但官方提供了更高效的sync.Map，使其能在并发安全的前提下更加高效地读写。sync.Map使用了&lt;strong&gt;写时复制（即Copy On Write）技术&lt;/strong&gt;来实现安全的高并发的map。sync.Map适用于&lt;strong&gt;读多写少&lt;/strong&gt;的场景。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;sync.Map数据结构&#xA;    &lt;div id=&#34;syncmap数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#syncmap%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Map&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mu&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Mutex&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//互斥锁 保护dirty字段&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;read&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;atomic&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Value&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//只读数据 实际类型为sync.readOnly&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;dirty&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt;{}]&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;entry&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//写入数据 操作前需先加锁&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;misses&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//每次从read读取失败（read穿透） misses+1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;其中sync.readOnly的数据结构&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>GPM&lt;1&gt;-进程-线程-协程</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm1-%E8%BF%9B%E7%A8%8B-%E7%BA%BF%E7%A8%8B-%E5%8D%8F%E7%A8%8B/</link>
      <pubDate>Thu, 09 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm1-%E8%BF%9B%E7%A8%8B-%E7%BA%BF%E7%A8%8B-%E5%8D%8F%E7%A8%8B/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;GPM&amp;lt;1&amp;gt;  进程/线程/协程&#xA;    &lt;div id=&#34;gpm1--进程线程协程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpm1--%e8%bf%9b%e7%a8%8b%e7%ba%bf%e7%a8%8b%e5%8d%8f%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;进程/线程/协程&#xA;    &lt;div id=&#34;进程线程协程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%9b%e7%a8%8b%e7%ba%bf%e7%a8%8b%e5%8d%8f%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;进程&#xA;    &lt;div id=&#34;进程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%9b%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程，&lt;strong&gt;是操作系统进行资源分配和调度的一个独立单位&lt;/strong&gt;，是应用程序运行的载体。每一个进程都有自己独立的地址空间。&lt;/p&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;线程&#xA;    &lt;div id=&#34;线程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ba%bf%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;线程是进程的一个实体，&lt;strong&gt;是CPU调度和分派的基本单位&lt;/strong&gt;，线程自己基本上不拥有系统资源，但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程的上下文切换比进程的上下文切换快得多，所以对他的调度的开销会小很多，从而提高系统资源的利用率和吞吐量。&lt;/p&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;进程/线程联系与区别&#xA;    &lt;div id=&#34;进程线程联系与区别&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%9b%e7%a8%8b%e7%ba%bf%e7%a8%8b%e8%81%94%e7%b3%bb%e4%b8%8e%e5%8c%ba%e5%88%ab&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;其实Linux下并没有线程，只是为了迎合开发口味，搞了个轻量级进程出来就叫做了线程。轻量级进程和进程一样，都有自己独立的task_struct进程描述符，也都有自己独立的pid。&lt;strong&gt;从操作系统视角看，调度上和进程没有什么区别，都是在等待队列的双向链表里选择一个task_struct切到运行态而已&lt;/strong&gt;。只不过轻量级进程和普通进程的区别是可以共享同一&lt;strong&gt;内存地址空间、代码段、全局变量、同一打开文件集合&lt;/strong&gt;而已。线程切换和进程切换之间的主要区别在于，在线程切换期间，&lt;strong&gt;虚拟内存空间保持不变&lt;/strong&gt;，而在进程切换期间则不然。那么CPU从一个task_struct切换到另一个task_struct时，是如何断定它进程间切换还是线程间切换呢？我我们可以通过task_struct里的&lt;strong&gt;tgid&lt;/strong&gt; （thread group id）这个字段来判断。&lt;strong&gt;tgid&lt;/strong&gt;这个字段在task_struct里代表线程的组id，即同一组（同一进程下）的线程拥有相同的tgid，当CPU切换task_struct时发现两个task_struct的tgid不同，则认为是进程切换，&lt;strong&gt;需要重新加载虚拟内存空间&lt;/strong&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>GPM&lt;2&gt;-协程的实现</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm2-%E5%8D%8F%E7%A8%8B%E7%9A%84%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Thu, 09 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm2-%E5%8D%8F%E7%A8%8B%E7%9A%84%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;GPM&amp;lt;2&amp;gt; 协程的实现&#xA;    &lt;div id=&#34;gpm2-协程的实现&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpm2-%e5%8d%8f%e7%a8%8b%e7%9a%84%e5%ae%9e%e7%8e%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;协程的实现&#xA;    &lt;div id=&#34;协程的实现&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8d%8f%e7%a8%8b%e7%9a%84%e5%ae%9e%e7%8e%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;协程&#xA;    &lt;div id=&#34;协程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8d%8f%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;前面我们说过利用协程具有轻量/上下文切换成本低等特点，那么他是如何在计算机中体现的? 到底协程是在那里被承载的?&lt;/p&gt;&#xA;&lt;p&gt;线程分为&lt;strong&gt;用户态线程&lt;/strong&gt;与&lt;strong&gt;内核态线程&lt;/strong&gt;，一个用户态线程必须绑定一个内核态线程，但CPU并不知道用户态线程的存在，也就是说CPU没法管到用户空间的事。既然CPU管不到用户空间的事，那用户空间就成了“三不管”地带了，那就决定在用户空间搞点事情。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/9a93c749faa8d17d91fbdbf7d6bdc954.png&#34; alt=&#34;9a93c749faa8d17d91fbdbf7d6bdc954.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&lt;p&gt;这样内核线程依然叫“线程”，用户线程就叫“协程”。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/Xnip2022-04-20_15-49-10.jpg&#34; alt=&#34;Xnip2022-04-20_15-49-10.jpg&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;既然一个协程能绑定到一个线程上，那为什么不能将多个协程绑定到一个或多个线程上呢？下面分析三种协程与线程的绑定关系。&lt;/p&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;N:1模式&#xA;    &lt;div id=&#34;n1模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#n1%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;N个协程绑定在一个线程上，优点是协程的切换都在用户态，不用陷入内核态，切换迅速且切换的成本低。但其也有很明显的缺点。&lt;/p&gt;&#xA;&lt;p&gt;因为N个协程都绑定到一个线程上了，即使是多核的计算也没有办法实现并行，&lt;strong&gt;浪费了计算机的性能&lt;/strong&gt;。一旦某个协程阻塞，本线程下的其他协程都无法执行，&lt;strong&gt;没有了并发能力&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/N_1.jpg&#34; alt=&#34;N_1.jpg&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;1:1模式&#xA;    &lt;div id=&#34;11模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#11%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;解决了N:1模式没有并发能力的不足，但每次切换协程都要切换线程，&lt;strong&gt;成本太高&lt;/strong&gt;，&lt;strong&gt;失去了协程存在的意义。&lt;/strong&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>GPM&lt;3&gt;-调度设计</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm3-%E8%B0%83%E5%BA%A6%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Thu, 09 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/gpm3-%E8%B0%83%E5%BA%A6%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;GPM&amp;lt;3&amp;gt; 调度设计&#xA;    &lt;div id=&#34;gpm3-调度设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpm3-%e8%b0%83%e5%ba%a6%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;GPM&#xA;    &lt;div id=&#34;gpm&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpm&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;&lt;strong&gt;G:&lt;/strong&gt; Goroutine，Goroutine这个概念来自协程，一个Goroutine必须必须绑定到P上才能被CPU执行。Goroutine非常轻量，创建一个Goroutine只需要几kb的内存资源(实际上这个内存资源是动态的，如果有需要runtime会为goroutine自动分配资源)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;P:&lt;/strong&gt; Processer, 即为G和M的调度对象，用来调度G和M之间的关联关系，其数量可通过GOMAXPROCS()来设置，默认为CPU核心数。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;M:&lt;/strong&gt; Machine, OS &lt;strong&gt;内核线程&lt;/strong&gt;抽象，代表着真正执行计算的资源，在绑定有效的 P 后，执行P调度出来的G。M的数量由runtime决定(默认最大1000)。M 并不保留 G 状态，这是 G 可以跨 M 调度的基础。&lt;/p&gt;&#xA;&lt;p&gt;Go调度器的是由GPM构成的。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/5222b5764897654fbf27748150333658.png&#34; alt=&#34;5222b5764897654fbf27748150333658.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;调度器初期设计&#xA;    &lt;div id=&#34;调度器初期设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%b0%83%e5%ba%a6%e5%99%a8%e5%88%9d%e6%9c%9f%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;调度器初期的设计是并没有P，仅有G与M，造成了如下弊端。&lt;/p&gt;&#xA;&lt;p&gt;1.如每次M调度G都需要获G全局队列的锁，造成了激烈的锁竞争。&lt;/p&gt;&#xA;&lt;p&gt;2.无法实现G的局部性（即从当M1执行G1时，G1创建出来的G1&amp;rsquo;无法保证任然被M1执行）&lt;/p&gt;&#xA;&lt;p&gt;3.M需要经常互相传递可运行的 G，引入了大量的延迟；&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/ecf0f428060329355a09d01e8f9423a9.png&#34; alt=&#34;ecf0f428060329355a09d01e8f9423a9.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;调度器进阶设计&#xA;    &lt;div id=&#34;调度器进阶设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%b0%83%e5%ba%a6%e5%99%a8%e8%bf%9b%e9%98%b6%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;基于旧的调度器的弊端，Go设计了一个全新的调度器。再新的调度器中，加入了P。M是G运行的实体，P负责把G分配到M上进行执行，M才是真真正正的“干活者”。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之内存管理2</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%862/</link>
      <pubDate>Wed, 08 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%862/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之内存管理&#xA;    &lt;div id=&#34;golang之内存管理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8b%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;概述&#xA;    &lt;div id=&#34;概述&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e8%bf%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Golang的内存分配借鉴了Google的TMalloc，其核心思想是&lt;strong&gt;内存池+多级对象管理&lt;/strong&gt;，&lt;strong&gt;能加快分配速度，降低资源竞争。&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Golang内存模型层次结构&#xA;    &lt;div id=&#34;golang内存模型层次结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e5%86%85%e5%ad%98%e6%a8%a1%e5%9e%8b%e5%b1%82%e6%ac%a1%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/image.png&#34; alt=&#34;image&#34; style=&#34;zoom: 33%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;MCache&#xA;    &lt;div id=&#34;mcache&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#mcache&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;访问mcache依然不需要加锁而是直接访问，且MCache中依然保存各种大小的Span。MCache是与Golang协程调度模型GPM中的P所绑定，而不是和线程绑定。因为Golang调度的GPM模型，真正可运行的线程M的数量与P的数量一致，即GOMAXPROCS个，所以MCache与P进行绑定更能节省内存空间使用，可以保证每个G使用MCache时&lt;strong&gt;不需要加锁&lt;/strong&gt;就可以获取到内存。&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/image (1).png&#34; alt=&#34;image (1)&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;MCentral&#xA;    &lt;div id=&#34;mcentral&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#mcentral&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;当MCache中某个Size Class对应的Span被一次次Object被上层取走后，如果出现当前Size Class的Span空缺情况，MCache则会向MCentral申请对应的Span。Goroutine、MCache、MCentral、MHeap互相交换的内存单位是不同，向Mcentral申请内存是&lt;strong&gt;需要加锁&lt;/strong&gt;的。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之内存对齐</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90/</link>
      <pubDate>Tue, 07 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8B%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之内存对齐&#xA;    &lt;div id=&#34;golang之内存对齐&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8b%e5%86%85%e5%ad%98%e5%af%b9%e9%bd%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;现象&#xA;    &lt;div id=&#34;现象&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%8e%b0%e8%b1%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//1字节&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//4字节&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int8&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//1字节&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int64&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//8字节&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;byte&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//1字节&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;{}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;size of foo: &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;unsafe&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Sizeof&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;这个输出结果是各个字段占用内存的和15字节吗？答案并不是，输出的结果是32字节，要大于所有字段占用内存大小的总和15字节。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;内存对齐&#xA;    &lt;div id=&#34;内存对齐&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%86%85%e5%ad%98%e5%af%b9%e9%bd%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;可能很多人认为在结构体中各个字段的内存是连续的，cpu按各个字段的大小按需读取相应的值。&lt;/p&gt;&#xA;&lt;img src=&#34;image/.png&#34; alt=&#34;.png&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&lt;p&gt;但实际上，cpu读取内存是以块为单位的，块的大小可以为 2、4、6、8、16 字节等大小（也称为内存粒度），cpu每次都读去内存里的“若干块”数据。在内存分布上，内存也是“一块一块”分布的，数据不是按照其本身的大小排布，而是按照内存粒度的来排布，以方便cpu快速读取数据，这就是内存对齐。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;为什么需要内存对齐？&#xA;    &lt;div id=&#34;为什么需要内存对齐&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81%e5%86%85%e5%ad%98%e5%af%b9%e9%bd%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;1.平台原因：不是所有硬件平台都能访问任意地址上的任意数据。例如：特定的硬件平台只允许在特定地址获取特定类型的数据，否则会导致异常情况。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之mutex源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bmutex%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Fri, 03 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bmutex%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之mutex&#xA;    &lt;div id=&#34;golang之mutex&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bmutex&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;互斥锁Mutex&#xA;    &lt;div id=&#34;互斥锁mutex&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%ba%92%e6%96%a5%e9%94%81mutex&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在Golang中用于表示互斥锁的是sync.Lock，其作用是保护临界区，确保任意时间只有一个goroutine能拿到锁。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;正常模式&amp;amp;饥饿模式&#xA;    &lt;div id=&#34;正常模式饥饿模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%ad%a3%e5%b8%b8%e6%a8%a1%e5%bc%8f%e9%a5%a5%e9%a5%bf%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;为了保证公平性，Golang在v1.9的互斥锁版本中引入了&lt;strong&gt;饥饿模式&lt;/strong&gt;与&lt;strong&gt;正常模式&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;如果当前锁正在被持有，抢不到锁就会进入一个等待的队列，当锁被释放后，从这个队列的队头里唤醒一个goroutine（等待者），但是锁不会直接给这个等待者，而是必须与&lt;strong&gt;正在获取锁但还未进入等待队列&lt;/strong&gt;的goroutine竞争这把锁，与刚唤醒的等待者相比，这个goroutine正持有CPU，所以获取到锁的概率较大。如果等待者抢锁失败，那么它就会被放回队列头部，如果它超过1ms都还没获取到锁，就从&lt;strong&gt;正常模式&lt;/strong&gt;切换为&lt;strong&gt;饥饿模式&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;在饥饿模式下，当锁释放后，锁会直接交给等待队列的第一个等待者，不必再与新来的goroutine竞争，新来的goroutine会直接加到等待队列的队尾。当满足以下两个条件时，&lt;strong&gt;饥饿模式&lt;/strong&gt;将切换回&lt;strong&gt;正常模式&lt;/strong&gt;。&#xA;（1）当前被唤醒的等待者获得锁后，发现队列只剩它自己一个了，那么&lt;strong&gt;切换回正常模式&lt;/strong&gt;。&#xA;（2）当前被唤醒的等待者获得锁后，发现自己的等待时间不超过1ms，那么&lt;strong&gt;切换回正常模式&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;在正常模式下，当前拥有CPU的goroutine比起等待队列里的goroutine&lt;strong&gt;有很大几率获得锁&lt;/strong&gt;，&lt;strong&gt;这样可以避免协程上下文的频繁切换&lt;/strong&gt;。但这样又会导致等待队列里的goroutine活活“饿死”，所以又必须有饥饿模式，保证等待已久的goroutine能够获取到锁，&lt;strong&gt;以保证公平性&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;sync.Lock&#xA;    &lt;div id=&#34;synclock&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#synclock&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Mutex&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;state&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//表示锁的状态，有锁定、饥饿、唤醒等状态&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;sema&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//表示信号量 用于实现mutex阻塞队列的定位&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mutexLocked&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;iota&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//1 state &amp;amp; 1 == 1 表示上锁状态&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mutexWoken&lt;/span&gt;&#x9;            &lt;span style=&#34;color:#75715e&#34;&gt;//2 state &amp;amp; 2 == 1 表示唤醒状态 &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mutexStarving&lt;/span&gt;           &lt;span style=&#34;color:#75715e&#34;&gt;//4 state &amp;amp; 4 == 1 表示饥饿状态&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mutexWaiterShift&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;iota&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//3 state &amp;gt;&amp;gt; 3 获取等待者的数量&#x9;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;starvationThresholdNs&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;1e6&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//进入饥饿状态的阈值&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;state字段总共占用32个bit，其中用前三位表示三个状态，后29个bit表示等待的goroutine个数。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之ants源码分析</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bants%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</link>
      <pubDate>Tue, 24 Jan 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bants%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;ants&#xA;    &lt;div id=&#34;ants&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#ants&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 简介&#xA;    &lt;div id=&#34;1-简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;ants 是一个高性能的协程池，实现了对大规模 goroutine 的调度管理、goroutine 复用，允许使用者在开发并发程序的时候限制协程数量，复用资源，达到更高效执行任务的效果。其具体特点如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;自动调度海量的 goroutines，复用 goroutines&lt;/li&gt;&#xA;&lt;li&gt;定期清理过期的 goroutines，进一步节省资源&lt;/li&gt;&#xA;&lt;li&gt;提供了大量有用的接口：任务提交、获取运行中的 goroutine 数量、动态调整 Pool 大小、释放 Pool、重启 Pool&lt;/li&gt;&#xA;&lt;li&gt;优雅处理 panic，防止程序崩溃&lt;/li&gt;&#xA;&lt;li&gt;资源复用，极大节省内存使用量；在大规模批量并发任务场景下比原生 goroutine 并发具有更高的性能&lt;/li&gt;&#xA;&lt;li&gt;非阻塞机制&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;本文从pool顶层方法开始，到底层workArray的实现，由上至下分析整个ants的工作流程。以下代码分析基于：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;github.com/panjf2000/ants/v2 v2.6.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 项目结构&#xA;    &lt;div id=&#34;2-项目结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e9%a1%b9%e7%9b%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ants                &#x9;&#x9;       root directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── interal                    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── spinlock                  自实现的自旋锁&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── ants.go                 &#x9;&#x9;  定义常量、errors显示、默认goroutine池、封装一些方便用户操作查看goroutine池的函数&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── options.go                    goroutine池的相关配置&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── pool.go &#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;普通pool&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;不绑定特定函数&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;的创建以及对pool相关的操作&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── pool_func.go                  创建绑定某个特定函数的pool以及对pool相关的操作&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── worker.go                     goWorker的定义及方法&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── worker_array.go               workerArray的接口和一个能返回实现该接口的函数&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── worker_loop_queue.go &#x9;&#x9;&#x9;&#x9;&#x9;loopQueue的定义及方法 loopQueue实现了workerArray&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── worker_stack.go               workerStack的定义及方法 workerStack实现了workerArray&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;3. 数据结构及实现原理&#xA;    &lt;div id=&#34;3-数据结构及实现原理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#3-%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84%e5%8f%8a%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;3.1 概念&#xA;    &lt;div id=&#34;31-概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#31-%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;首先需要明白ants代码两个概念，worker及task（任务）&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>k8s服务发现</title>
      <link>http://blog.chuckchan.top/posts/middleware/k8s/k8s%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0/</link>
      <pubDate>Sat, 07 Jan 2023 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/k8s/k8s%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;K8S之服务发现&#xA;    &lt;div id=&#34;k8s之服务发现&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#k8s%e4%b9%8b%e6%9c%8d%e5%8a%a1%e5%8f%91%e7%8e%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Serivce&#xA;    &lt;div id=&#34;serivce&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#serivce&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;概念&#xA;    &lt;div id=&#34;概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Pod存在生命周期，有销毁，有重建，无法提供一个固定的访问接口给客户端。并且为了同类的Pod都能够实现工作负载的价值，由此Service资源出现了，可以为一类Pod资源对象提供一个固定的访问接口和负载均衡。当Pod宕机后重新生成时，其IP等状态信息可能会变动，Service会根据Pod的Label对这些状态信息进行监控和变更，保证上游服务不受Pod的变动而影响。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;类型&#xA;    &lt;div id=&#34;类型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Service一共有四种类型，分别是ClusterIP、NodePort、LoadBalancer、ExternaName。&lt;/p&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;&lt;em&gt;1.ClusterIP&lt;/em&gt;&#xA;    &lt;div id=&#34;1clusterip&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1clusterip&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;默认类型，自动分配一个仅Cluster内部可以访问的虚拟IP。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>DDD领域驱动设计</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/ddd%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Thu, 22 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/ddd%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;领域驱动设计&#xA;    &lt;div id=&#34;领域驱动设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%a2%86%e5%9f%9f%e9%a9%b1%e5%8a%a8%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1.分层架构&#xA;    &lt;div id=&#34;1分层架构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1%e5%88%86%e5%b1%82%e6%9e%b6%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/640.jpeg&#34; alt=&#34;640&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;用户界面层：网络协议的转化/统一鉴权/Session 管理/限流配置/前置缓存/异常转换&lt;/li&gt;&#xA;&lt;li&gt;应用层：&lt;strong&gt;业务流程编排（仅编排，不能存在业务逻辑）&lt;/strong&gt;/ DTO 出入转化&lt;/li&gt;&#xA;&lt;li&gt;领域层：领域模型/领域服务/仓储和防腐层的接口定义&lt;/li&gt;&#xA;&lt;li&gt;基础设施层：仓储和防腐层接口实现/存储等基础层能力&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. todo&amp;hellip;&#xA;    &lt;div id=&#34;2-todo&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-todo&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;</description>
      
    </item>
    
    <item>
      <title>MySQL之mvcc</title>
      <link>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bmvcc/</link>
      <pubDate>Sun, 04 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bmvcc/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;MVCC&#xA;    &lt;div id=&#34;mvcc&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#mvcc&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h5 class=&#34;relative group&#34;&gt;&lt;strong&gt;概念&lt;/strong&gt;&#xA;    &lt;div id=&#34;概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h5&gt;&#xA;&lt;p&gt;MVCC 的英文全称是 Multiversion Concurrency Control ，中文意思是多版本并发控制技术。原理是，通过数据行的多个版本管理来实现数据库的并发控制，简单来说就是保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。&lt;/p&gt;&#xA;&lt;p&gt;MVCC是如何实现的？&lt;/p&gt;&#xA;&lt;p&gt;我们需要先了解两个知识：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Read View 中四个字段作用；&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;聚簇索引记录中两个跟事务有关的隐藏列；&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;em&gt;隐藏列&lt;/em&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;InnoDB 里面每个事务有一个唯一的事务 ID，叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的，是按申请顺序严格递增的。而每行数据也都是有多个版本的。每次事务更新数据的时候，都会生成一个新的数据版本，并且把 transaction id 赋值给这个数据版本的事务 ID，记为 row trx_id。同时，旧的数据版本要保留，并且在新的数据版本中，能够有信息可以直接拿到它。也就是说，数据表中的一行记录，其实可能有多个版本 (row)，每个版本有自己的 row trx_id。每个版本之间可以用回滚指针相连接。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/2022-04-08-15-31-58-image.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;对于使用 InnoDB 存储引擎的数据库表，它的聚簇索引记录中都包含下面两个隐藏列：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;trx_id，当一个事务对某条聚簇索引记录进行改动时，就会&lt;strong&gt;把该事务的事务 id 记录在 trx_id 隐藏列里&lt;/strong&gt;；&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;roll_pointer，每次对某条聚簇索引记录进行改动时，都会把旧版本的记录写入到 undo 日志中，然后&lt;strong&gt;这个隐藏列是个指针，指向每一个旧版本记录&lt;/strong&gt;，于是就可以通过它找到修改前的记录。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>MySQL之死锁</title>
      <link>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8B%E6%AD%BB%E9%94%81/</link>
      <pubDate>Sun, 04 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8B%E6%AD%BB%E9%94%81/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;死锁&#xA;    &lt;div id=&#34;死锁&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%ad%bb%e9%94%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;概念&#xA;    &lt;div id=&#34;概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;死锁是并发系统中常见的问题，同样也会出现在数据库MySQL的并发读写请求场景中。当两个及以上的事务，双方都在等待对方释放已经持有的锁或因为加锁顺序不一致造成循环等待锁资源，就会出现“死锁”。常见的报错信息为 &lt;code&gt;Deadlock found when trying to get lock...&lt;/code&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;检测语句&#xA;    &lt;div id=&#34;检测语句&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a3%80%e6%b5%8b%e8%af%ad%e5%8f%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;可以使用下面这条命令来查看MySQL最近的一次死锁日志：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;show&lt;/span&gt; engine innodb status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;查看当前执行的事务：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; information_schema.innodb_trx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;查看当正在等锁的事务：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; information_schema.innodb_lock_waits&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;场景分析&#xA;    &lt;div id=&#34;场景分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;sql准备：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>MySQL之索引调优</title>
      <link>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8B%E7%B4%A2%E5%BC%95%E8%B0%83%E4%BC%98/</link>
      <pubDate>Sun, 04 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8B%E7%B4%A2%E5%BC%95%E8%B0%83%E4%BC%98/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;索引&#xA;    &lt;div id=&#34;索引&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b4%a2%e5%bc%95&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;索引是什么？&#xA;    &lt;div id=&#34;索引是什么&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b4%a2%e5%bc%95%e6%98%af%e4%bb%80%e4%b9%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;索引是提升查询速度的一种数据结构&lt;/strong&gt;。索引之所以能提升查询速度，在于它在插入时对数据进行了排序（显而易见，它的缺点是影响插入或者更新的性能）。InnoDB 存储引擎支持的索引有 B+ 树索引、全文索引、R 树索引。这里讲使用最广泛的 B+ 树索引。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>设计模式之行为型模式</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E8%A1%8C%E4%B8%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Tue, 15 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E8%A1%8C%E4%B8%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;行为型模式&#xA;    &lt;div id=&#34;行为型模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%a1%8c%e4%b8%ba%e5%9e%8b%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;&lt;em&gt;&lt;u&gt;1.模版方法模式&lt;/u&gt;&lt;/em&gt;&#xA;    &lt;div id=&#34;&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;在模板模式（Template Pattern）中，一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现，但调用将以抽象类中定义的方式进行。模版方法模式中的角色与职责如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;AbstractClass（抽象类）：在抽象类中定义了一系列基本操作(PrimitiveOperations)，这些基本操作可以是具体的，也可以是抽象的，每一个基本操作对应算法的一个步骤，在其子类中可以重定义或实现这些步骤。同时，在抽象类中实现了一个模板方法(Template Method)，用于定义一个算法的框架，模板方法不仅可以调用在抽象类中实现的基本方法，也可以调用在抽象类的子类中实现的基本方法，还可以调用其他对象中的方法。&lt;/li&gt;&#xA;&lt;li&gt;ConcreteClass（具体子类）：它是抽象类的子类，用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤，也可以覆盖在父类中已经实现的具体基本操作。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;WorkInterface&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;GetUp&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Work&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Sleep&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;worker&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;WorkInterface&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewWorker&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;WorkInterface&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;worker&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;worker&lt;/span&gt;{&lt;span style=&#34;color:#a6e22e&#34;&gt;WorkInterface&lt;/span&gt;: &lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;worker&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Daily&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetUp&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Work&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Sleep&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//具体子类&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Coder&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Coder&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;GetUp&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;coder get up&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Coder&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Work&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;coder work&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Coder&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Sleep&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;coder sleep&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Farmer&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Farmer&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;GetUp&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;farmer get up&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Farmer&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Work&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;farmer work&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;Farmer&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Sleep&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;farmer sleep&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;worker1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewWorker&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;Coder&lt;/span&gt;{})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;worker1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Daily&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---------------&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;worker2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewWorker&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;Farmer&lt;/span&gt;{})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;worker2&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Daily&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;优点：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Nginx</title>
      <link>http://blog.chuckchan.top/posts/tool/nginx/</link>
      <pubDate>Mon, 14 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/nginx/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Nginx&#xA;    &lt;div id=&#34;nginx&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#nginx&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 常用命令&#xA;    &lt;div id=&#34;1-常用命令&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s stop  快速关闭nginx，可能不保存相关信息，并迅速终止web服务&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s quit  平稳关闭nginx，保存相关信息，有安排的结束web服务&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s reload  因改变了Nginx相关配置，需要重新加载配置而重载&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s reopen 重新打开日志文件&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s filename 为 Nginx 指定一个配置文件，来代替缺省的&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -s test 不运行，仅仅测试配置文件。nginx 将检查配置文件的语法的正确性，并尝试打开配置文件中所引用到的文件&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -v 显示 nginx 的版本&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nginx -V 显示 nginx 的版本，编译器版本和配置参数&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 实战&#xA;    &lt;div id=&#34;2-实战&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e5%ae%9e%e6%88%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;em&gt;a. 反向代理&lt;/em&gt;&#xA;    &lt;div id=&#34;a-反向代理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a-%e5%8f%8d%e5%90%91%e4%bb%a3%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#user  nobody;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;worker_processes  1;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#error_log  logs/error.log;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#error_log  logs/error.log  notice;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#error_log  logs/error.log  info;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pid        logs/nginx.pid;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;events &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  worker_connections  1024;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;http &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  include       mime.types;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  default_type  application/octet-stream;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#log_format  main  &amp;#39;$remote_addr - $remote_user [$time_local] &amp;#34;$request&amp;#34; &amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#                  &amp;#39;$status $body_bytes_sent &amp;#34;$http_referer&amp;#34; &amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#                  &amp;#39;&amp;#34;$http_user_agent&amp;#34; &amp;#34;$http_x_forwarded_for&amp;#34;&amp;#39;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#access_log  logs/access.log  main;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  sendfile        on;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#tcp_nopush     on;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#keepalive_timeout  0;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  keepalive_timeout  65;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#gzip  on;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#上游服务器&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  upstream my_server&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server  localhost:8081;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server  localhost:8082;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  server &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    listen       8080;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_name  localhost;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    location / &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      root   html;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      index  index.html index.htm;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      proxy_pass http://my_server;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      proxy_set_header Host $host;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  include servers/*;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;em&gt;b. 负载均衡&lt;/em&gt;&#xA;    &lt;div id=&#34;b-负载均衡&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#b-%e8%b4%9f%e8%bd%bd%e5%9d%87%e8%a1%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在前面反向代理的基础上，可以拓展出请求上游服务器负载均衡的策略。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>git代码管理工具</title>
      <link>http://blog.chuckchan.top/posts/tool/git%E4%BB%A3%E7%A0%81%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/git%E4%BB%A3%E7%A0%81%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;git&#xA;    &lt;div id=&#34;git&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#git&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Git是目前世界上最先进的分布式版本控制系统。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;工作流程&#xA;    &lt;div id=&#34;工作流程&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a5%e4%bd%9c%e6%b5%81%e7%a8%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;v2-4f61dac0b425ebe34efc88d11a68f27b_1440w&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/v2-4f61dac0b425ebe34efc88d11a68f27b_1440w.webp&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Workspace：工作区&lt;/li&gt;&#xA;&lt;li&gt;Index / Stage：暂存区&lt;/li&gt;&#xA;&lt;li&gt;Repository：仓库区（或本地仓库）&lt;/li&gt;&#xA;&lt;li&gt;Remote：远程&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>wrk性能测试工具</title>
      <link>http://blog.chuckchan.top/posts/tool/wrk%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/tool/wrk%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;wrk&#xA;    &lt;div id=&#34;wrk&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#wrk&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;wrk 是一款针对 Http 协议的基准测试工具，它能够在单机多核 CPU 的条件下，使用系统自带的高性能 I/O 机制，如 epoll，kqueue 等，通过多线程和事件模式，对目标机器产生大量的负载。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;使用&#xA;    &lt;div id=&#34;使用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bd%bf%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;基本命令&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Usage: wrk &amp;lt;options&amp;gt; &amp;lt;url&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Options:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -c, --connections &amp;lt;N&amp;gt;  总的http连接数&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -d, --duration    &amp;lt;T&amp;gt;  压测时间&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -t, --threads     &amp;lt;N&amp;gt;  使用多少个线程进行压测&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -s, --script      &amp;lt;S&amp;gt;  指定lua脚本路径&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -H, --header      &amp;lt;H&amp;gt;  为每一个http请求添加http头部&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        --latency          在压测结束后，打印延迟统计信息&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        --timeout     &amp;lt;T&amp;gt;  超时时间&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -v, --version          版本信息&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;N&amp;gt;代表数字参数，支持国际单位 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;1k, 1M, 1G&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;T&amp;gt;代表时间参数，支持时间单位 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;2s, 2m, 2h&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;测试报告&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>缓存策略</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E7%BC%93%E5%AD%98%E7%AD%96%E7%95%A5/</link>
      <pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E7%BC%93%E5%AD%98%E7%AD%96%E7%95%A5/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;缓存策略&#xA;    &lt;div id=&#34;缓存策略&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bc%93%e5%ad%98%e7%ad%96%e7%95%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;&lt;u&gt;1. 双写策略&lt;/u&gt;&#xA;    &lt;div id=&#34;1-双写策略&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e5%8f%8c%e5%86%99%e7%ad%96%e7%95%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;双写即当数据修改时，即要更新数据库也要更新缓存。下面看看具体的双写的两种场景。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;em&gt;a. 先更新数据库，再更新缓存&lt;/em&gt;&#xA;    &lt;div id=&#34;a-先更新数据库再更新缓存&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a-%e5%85%88%e6%9b%b4%e6%96%b0%e6%95%b0%e6%8d%ae%e5%ba%93%e5%86%8d%e6%9b%b4%e6%96%b0%e7%bc%93%e5%ad%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/8febac10b14bed16cb96d1d944cd08da.png&#34; alt=&#34;8febac10b14bed16cb96d1d944cd08da&#34; style=&#34;zoom: 67%;&#34; /&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;请求A先更数据库为1&lt;/li&gt;&#xA;&lt;li&gt;请求B更新数据库为2&lt;/li&gt;&#xA;&lt;li&gt;请求B先更新缓存为2&lt;/li&gt;&#xA;&lt;li&gt;请求A更新缓存为1&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;u&gt;先更新数据库，再更新缓存&lt;/u&gt;这种策略会导致数据库与缓存不一致&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;&lt;em&gt;b. 先更新缓存，再更新数据库&lt;/em&gt;&#xA;    &lt;div id=&#34;b-先更新缓存再更新数据库&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#b-%e5%85%88%e6%9b%b4%e6%96%b0%e7%bc%93%e5%ad%98%e5%86%8d%e6%9b%b4%e6%96%b0%e6%95%b0%e6%8d%ae%e5%ba%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/454a8228a6549176ad7e0484fba3c92b.png&#34; alt=&#34;454a8228a6549176ad7e0484fba3c92b&#34; style=&#34;zoom:67%;&#34; /&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;请求A先更新缓存为1&lt;/li&gt;&#xA;&lt;li&gt;请求B更新缓存为2&lt;/li&gt;&#xA;&lt;li&gt;请求B先更新数据库为2&lt;/li&gt;&#xA;&lt;li&gt;请求A更新数据库为1&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;与&lt;u&gt;先更新数据库，再更新缓存&lt;/u&gt;这种策略一样，&lt;u&gt;先更新缓存，再更新数据库&lt;/u&gt;会因为并发原因导致数据库与缓存数据不一致。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>设计模式之创建型模式</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Tue, 01 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;创建型模式&#xA;    &lt;div id=&#34;创建型模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%9b%e5%bb%ba%e5%9e%8b%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;&lt;em&gt;&lt;u&gt;1.单例模式&lt;/u&gt;&lt;/em&gt;&#xA;    &lt;div id=&#34;&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;单例模式保证知有一个类、只有一个实例存在，同时提供能对该实例加以访问的全局访问方法。单例模式的三个要点：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;这个类只能有一个实例&lt;/li&gt;&#xA;&lt;li&gt;这个类必须自己创建这个实例&lt;/li&gt;&#xA;&lt;li&gt;这个类必须自行向整个系统提供这个实例&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;下面是一个单例模式的demo&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Foo&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;call singleton.Foo&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Bar&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;call singleton.Bar&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;instance&lt;/span&gt; = new(&lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;GetInstance&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;instance&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//.... in main.go&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;s&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;singelton&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetInstance&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;s&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Foo&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;s&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Bar&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;上面这个demo模式展示了单例模式的一种，属于&lt;strong&gt;饿汉模式&lt;/strong&gt;。其含义是在初始化单例唯一指针的时候，就已经提前开辟好了一个对象，申请了内存。饿汉式的好处是，不会出现线程并发创建，导致多个单例的出现，但是缺点是如果这个单例对象在业务逻辑没有被使用，也会客观的创建一块内存对象。那么与之对应的模式叫&lt;strong&gt;懒汉模式&lt;/strong&gt;，代码如下：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>幂等设计</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E5%B9%82%E7%AD%89%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Wed, 26 Oct 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E5%B9%82%E7%AD%89%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;幂等设计&#xA;    &lt;div id=&#34;幂等设计&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b9%82%e7%ad%89%e8%ae%be%e8%ae%a1&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;什么是幂等？&#xA;    &lt;div id=&#34;什么是幂等&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%80%e4%b9%88%e6%98%af%e5%b9%82%e7%ad%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;幂等指的是对某个资源来说，一次请求与多次请求，具有相同的副作用。用数学的语言的来表示就是f(x) = f(f(x))。为什么需要幂等？当我们将系统节藕隔离后，服务间的调用可能有三种状态：&lt;em&gt;成功&lt;/em&gt;、&lt;em&gt;失败&lt;/em&gt;、&lt;em&gt;超时&lt;/em&gt;。前两者是明确的状态，而超时则是一种不明确的状态，可能这个请求还没到达服务端就已经超时了，也有可能请求已经到服务端，但是在返回给客户端的过程中超时或者丢包了，客户端完全不知道服务端是否有接受到数据。举几个例子：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;订单支付时，第一次支付超时了，然后客户端再次调用，是否会多扣一次钱？&lt;/li&gt;&#xA;&lt;li&gt;在页面提交form表单时，保存按钮不小心快速按了两次，表中产生了两条重复的数据数据。&lt;/li&gt;&#xA;&lt;li&gt;mq消费的时候，有时候会读取到重复的消息，造成重复消费。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;接口性幂等是指用户对于同一操作发起的一次请求或者多次请求的结果是一致的，不会因为多次点击而产生了副作用。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;如何保证幂等？&#xA;    &lt;div id=&#34;如何保证幂等&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a6%82%e4%bd%95%e4%bf%9d%e8%af%81%e5%b9%82%e7%ad%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;1. insert前先select&#xA;    &lt;div id=&#34;1-insert前先select&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-insert%e5%89%8d%e5%85%88select&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;在insert数据前，先用唯一id（例如订单id）查询一下数据库是否有这个订单记录，如果没有则insert，否则返回订单信息。这种方法很简单，但是很明显，在并发的情况下一样会有产生重复订单。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;640&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/640.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;2. 悲观锁&#xA;    &lt;div id=&#34;2-悲观锁&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e6%82%b2%e8%a7%82%e9%94%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;当有多个重复请求到达时，只有一个请求能够进行操作。比如在支付场景中，用户A的账户中有150元，某个请求扣件100元后，此时账户还剩50元。如果出现多次重复的请求，那么用户的余额可能出现负数。为了解决这个问题，可以使用悲观锁先锁住用户的账号，MySQL中可以用如下sql语句锁住数据。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>设计模式之结构型模式</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Wed, 26 Oct 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;&lt;strong&gt;结构型模式&lt;/strong&gt;&#xA;    &lt;div id=&#34;结构型模式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%93%e6%9e%84%e5%9e%8b%e6%a8%a1%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;&lt;em&gt;&lt;u&gt;1.代理模式&lt;/u&gt;&lt;/em&gt;&#xA;    &lt;div id=&#34;&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;p&gt;代理模式可以为其他对象提供一种代理以控制对这个对象的访问。所谓代理，是指具有与代理元（被代理的对象）具有相同的接口的类，客户端必须通过代理与被代理的目标类交互，而代理一般在交互的过程中（交互前后），进行某些特别的处理。代理模式的角色与职责如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Subject（抽象主题角色）：真实主题与代理主题的共同接口。&lt;/li&gt;&#xA;&lt;li&gt;RealSubject（真实主题角色）：定义了代理角色所代表的真实对象。&lt;/li&gt;&#xA;&lt;li&gt;Proxy（代理主题角色）：含有对真实主题角色的引用，代理角色通常在将客户端调用传递给真实主题对象之前或者之后执行某些操作，而不是单纯返回真实的对象。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//商品种类&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//商品真伪&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// =========== 抽象层 ===========&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//抽象的购物主题Subject&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Shopping&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;//某任务&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// =========== 实现层 ===========&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;KoreaShopping&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;ks&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;KoreaShopping&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;去韩国进行了购物, 买了 &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;AmericanShopping&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;AmericanShopping&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;去美国进行了购物, 买了 &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;AfricaShopping&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;AfricaShopping&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;去非洲进行了购物, 买了 &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//代理层&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;shopping&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Shopping&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//代理某个主题，这里是抽象类型&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewProxy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;shopping&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Shopping&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;shopping&lt;/span&gt;: &lt;span style=&#34;color:#a6e22e&#34;&gt;shopping&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;)  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;distinguish&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;) { &lt;span style=&#34;color:#75715e&#34;&gt;//代理验货&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;shopping&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;//进行购买 调用真实主题角色的具体任务&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;check&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;//海关安检&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//代理验货&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;distinguish&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;对[&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;]进行了辨别真伪.&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;发现假货&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;, 不应该购买。&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//安检流程&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;op&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;OverseasProxy&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;check&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;对[&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;goods&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;] 进行了海关检查， 成功的带回祖国&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;{&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;韩国面膜&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;g2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Goods&lt;/span&gt;{&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;米国鞋子&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//不使用代理模式&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;koreaShopping&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;KoreaShopping&lt;/span&gt;{}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Fact&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;对[&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;]进行了辨别真伪.&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;koreaShopping&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;对[&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Kind&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;] 进行了海关检查， 成功的带回祖国&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//使用代理模式&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;proxy1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewProxy&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;KoreaShopping&lt;/span&gt;{})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;proxy1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;g1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;proxy2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewProxy&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;AmericanShopping&lt;/span&gt;{})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;proxy2&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Buy&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;g2&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;优点：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>MySQL之next-key lock</title>
      <link>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bnext-key-lock/</link>
      <pubDate>Mon, 24 Oct 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/mysql/mysql%E4%B9%8Bnext-key-lock/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Next-key lock&#xA;    &lt;div id=&#34;next-key-lock&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#next-key-lock&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;strong&gt;Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题，就引出了 next-key 锁&lt;/strong&gt;，就是记录锁和间隙锁的组合。这里强调**「当前读」&lt;strong&gt;，是因为在&lt;/strong&gt;「快照读」&lt;strong&gt;的情况下，由mvcc来保证不会产生幻读。mvcc相关的内容具体可以参考&lt;a href=&#34;https://github.com/chuckchann/nine-legged-essay-notes/blob/master/%E4%B9%9D%E8%82%A1%E6%96%87%E4%B9%8BMySQL/MySQL%E4%B9%8Bmvcc.md&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;另一篇文章&lt;/a&gt;。这里只讨论&lt;/strong&gt;「当前读」&lt;strong&gt;的情况。以下内容全部基于&lt;/strong&gt;「可重复读」隔离级别**。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;记录锁&amp;amp;间隙锁&#xA;    &lt;div id=&#34;记录锁间隙锁&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%b0%e5%bd%95%e9%94%81%e9%97%b4%e9%9a%99%e9%94%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;记录锁，锁的是记录本身；&lt;/li&gt;&#xA;&lt;li&gt;间隙锁，锁的就是两个值之间的空隙，以防止其他事务在这个空隙间插入新的数据，从而避免幻读现象。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;加锁规则&#xA;    &lt;div id=&#34;加锁规则&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8a%a0%e9%94%81%e8%a7%84%e5%88%99&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;对记录加锁时，&lt;strong&gt;加锁的基本单位是 next-key lock&lt;/strong&gt;，它是由记录锁和间隙锁组合而成的，&lt;strong&gt;next-key lock 是前开后闭区间，而间隙锁是前开后开区间&lt;/strong&gt;。但是，next-key lock 在一些场景下会退化成记录锁或间隙锁。另外，文章后面提到的&lt;strong&gt;next-key lock、间隙锁、记录锁都是加在索引上的，而不是加在数据行上的&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;场景分析&#xA;    &lt;div id=&#34;场景分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%ba%e6%99%af%e5%88%86%e6%9e%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;先准备测试表，其中id为主键（&lt;u&gt;唯一索引&lt;/u&gt;），age上有一个&lt;u&gt;普通索引&lt;/u&gt;，name上没有索引&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>分布式ID</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E5%88%86%E5%B8%83%E5%BC%8Fid/</link>
      <pubDate>Thu, 13 Oct 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E5%88%86%E5%B8%83%E5%BC%8Fid/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;分布式ID&#xA;    &lt;div id=&#34;分布式id&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%86%e5%b8%83%e5%bc%8fid&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1. 什么是分布式ID&#xA;    &lt;div id=&#34;1-什么是分布式id&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e4%bb%80%e4%b9%88%e6%98%af%e5%88%86%e5%b8%83%e5%bc%8fid&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在我们业务数据量不大的时候，单库单表完全可以支撑现有业务，数据再大一点搞个MySQL主从同步读写分离也能对付。但随着数据日渐增长，主从同步也扛不住了，就需要对数据库进行分库分表，但分库分表后需要有一个唯一ID来标识一条数据，数据库的自增ID显然不能满足需求。特别一点的如订单、优惠券也都需要有&lt;code&gt;唯一ID&lt;/code&gt;做标识。此时一个能够生成&lt;code&gt;全局唯一ID&lt;/code&gt;的系统是非常必要的。那么这个&lt;code&gt;全局唯一ID&lt;/code&gt;就叫&lt;code&gt;分布式ID&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;分布式ID需要满足哪些条件？&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;全局唯一：必须保证ID是全局性唯一的，基本要求&lt;/li&gt;&#xA;&lt;li&gt;高性能：高可用低延时，ID生成响应要块，否则反倒会成为业务瓶颈&lt;/li&gt;&#xA;&lt;li&gt;高可用：100%的可用性是骗人的，但是也要无限接近于100%的可用性&lt;/li&gt;&#xA;&lt;li&gt;好接入：要秉着拿来即用的设计原则，在系统设计和实现上要尽可能的简单&lt;/li&gt;&#xA;&lt;li&gt;趋势递增：最好趋势递增（防止索引数据页频繁发生页分裂），这个要求就得看具体业务场景了，一般不严格要求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2. 如何生成分布式ID&#xA;    &lt;div id=&#34;2-如何生成分布式id&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e5%a6%82%e4%bd%95%e7%94%9f%e6%88%90%e5%88%86%e5%b8%83%e5%bc%8fid&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;a. &lt;em&gt;&lt;u&gt;uuid&lt;/u&gt;&lt;/em&gt;&#xA;    &lt;div id=&#34;a&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;想要得到一个具有唯一性的ID，首先被想到可能就是UUID，毕竟它有着全球唯一的特性。那么UUID可以做分布式ID吗？答案是可以的，但是并不推荐。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;生成足够简单，本地生成无网络消耗，具有唯一性&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>LSM树</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/lsm%E6%A0%91/</link>
      <pubDate>Mon, 10 Oct 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/lsm%E6%A0%91/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;LSM树&#xA;    &lt;div id=&#34;lsm树&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#lsm%e6%a0%91&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;LSM树，即日志结构合并树(Log-Structured Merge-Tree)。其实它并不属于一个具体的数据结构，它更多是一种数据结构的设计思想。大多NoSQL数据库核心思想都是基于LSM来做的，只是具体的实现不同。传统关系型数据库使用btree或一些变体作为存储结构，能高效进行查找。但保存在磁盘中时它也有一个明显的缺陷，那就是逻辑上相离很近但物理却可能相隔很远，这就可能造成大量的磁盘随机读写。随机读写比顺序读写慢很多，为了提升IO性能，&lt;strong&gt;我们需要一种能将随机操作变为顺序操作的机制&lt;/strong&gt;，于是便有了LSM树。LSM树能让我们进行顺序写磁盘，从而大幅提升写操作，&lt;strong&gt;作为代价的是牺牲了一些读性能&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;定义&#xA;    &lt;div id=&#34;定义&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%9a%e4%b9%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;LSM树是一个横跨内存和磁盘的，包含多颗&amp;quot;子树&amp;quot;的一个森林。&lt;/li&gt;&#xA;&lt;li&gt;LSM树分为Level 0，Level 1，Level 2 &amp;hellip; Level n 多颗子树，其中只有Level 0在内存中，其余Level 1-n在磁盘中。&lt;/li&gt;&#xA;&lt;li&gt;内存中的Level 0子树一般采用排序树（红黑树/AVL树）、跳表或者TreeMap等这类有序的数据结构，方便后续顺序写磁盘。&lt;/li&gt;&#xA;&lt;li&gt;磁盘中的Level 1-n子树，本质是数据排好序后顺序写到磁盘上的文件，只是叫做树而已。&lt;/li&gt;&#xA;&lt;li&gt;每一层的子树都有一个阈值大小，达到阈值后会进行合并，合并结果写入下一层。&lt;/li&gt;&#xA;&lt;li&gt;每一层的子树都有一个阈值大小，达到阈值后会进行合并，合并结果写入下一层。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/v2-9359003a0c88626b33979b784982e9ab_1440w.jpeg&#34; alt=&#34;v2-9359003a0c88626b33979b784982e9ab_1440w&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;LSM树的增删改查&#xA;    &lt;div id=&#34;lsm树的增删改查&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#lsm%e6%a0%91%e7%9a%84%e5%a2%9e%e5%88%a0%e6%94%b9%e6%9f%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;1.  增加&#xA;    &lt;div id=&#34;1--增加&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1--%e5%a2%9e%e5%8a%a0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;插入比较简单，直接在level 0 树插入即可，因为level 0 树是有序的，并且level 0 树是在内存中，所以插入的速度快，时间复杂度为o(logn)，如果插入的key已经存在，那么直接转换为更新操作。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golang之defer</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bdefer/</link>
      <pubDate>Sun, 18 Sep 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golang%E4%B9%8Bdefer/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之defer&#xA;    &lt;div id=&#34;golang之defer&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8bdefer&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;defer&#xA;    &lt;div id=&#34;defer&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#defer&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Golang的defer会在函数返回前去执行传入的函数，它会经常被用于关闭文件描述符、关闭数据库连接以及解锁资源。&lt;/p&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;常见使用场景&#xA;    &lt;div id=&#34;常见使用场景&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b8%b8%e8%a7%81%e4%bd%bf%e7%94%a8%e5%9c%ba%e6%99%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;1.关闭文件&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo1&lt;/span&gt;()  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;file&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;os&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;OpenFile&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;your file path&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;os&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;O_RDONLY&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0755&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;file&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Close&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//use file do something&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;2.解锁&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo2&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;mu&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sync&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Mutex&lt;/span&gt;)  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;mu&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Lock&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mu&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Unlock&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//do something&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h4 class=&#34;relative group&#34;&gt;defer数据结构&#xA;    &lt;div id=&#34;defer数据结构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#defer%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h4&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_defer&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;siz&lt;/span&gt;       &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//参数和结果的内存大小&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;sp&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;uintptr&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//栈指针&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;pc&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;uintptr&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//调用方的程序计数器&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;fn&lt;/span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;funcval&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//defer中传入的函数&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;_panic&lt;/span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;_panic&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//触发延迟调用的结构体，可能为空&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;link&lt;/span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;_defer&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//指向下一个defer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h3 class=&#34;relative group&#34;&gt;defer调用链&#xA;    &lt;div id=&#34;defer调用链&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#defer%e8%b0%83%e7%94%a8%e9%93%be&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h3&gt;&#xA;&lt;p&gt;当goroutine获取到一个defer，就会创建一个runtime._defer结构体，然后将runtime._defer追加到当前goroutine的defer链表的最前面。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>布隆过滤器</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8/</link>
      <pubDate>Sun, 18 Sep 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;布隆过滤器&#xA;    &lt;div id=&#34;布隆过滤器&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b8%83%e9%9a%86%e8%bf%87%e6%bb%a4%e5%99%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;简介&#xA;    &lt;div id=&#34;简介&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%80%e4%bb%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;本质上布隆过滤器是一种数据结构，比较巧妙的概率型数据结构（probabilistic data structure），特点是高效地插入和查询，可以用来告诉你 &lt;strong&gt;“某样东西一定不存在或者可能存在”&lt;/strong&gt;。相比于传统的 List、Set、Map 等数据结构，&lt;strong&gt;它更高效、占用空间更少&lt;/strong&gt;，但是缺点是其返回的&lt;strong&gt;结果是概率性的，而不是确切的&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;HashMap&#xA;    &lt;div id=&#34;hashmap&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hashmap&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;在讲布隆过滤器之前，我们先想有一下，判断某个元素是否存在用什么数据结构？HashMap是一个好选择，HashMap能在o(1)的时间复杂度内判断一个元素在不在，效率极高。如果数据量很小，那么HashMap确实是一个最佳选择，但是如果HashMap里存储的是上亿的key，那么他就有点力不从心了。存储上亿key的HashMap需要占用大量的空间内存，并且如果HashMap触发rehash，对那么多的key进行迁移必然会导致内存抖动。所以，HashMap并不适合存放亿级别的key。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Bloom Filter&#xA;    &lt;div id=&#34;bloom-filter&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#bloom-filter&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;前面说了HashMap不合适存放数量过多的key，那么有什么可以存放大数量的key且不会占用大量的内存？可以使用bit数组，也叫bitmap，布隆过滤器就是用bitmap来存储数据的。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;v2-530c9d4478398718c15632b9aa025c36_720w&#34;&#xA;    src=&#34;http://storage.chuckchan.top/uploads/v2-530c9d4478398718c15632b9aa025c36_720w.jpeg&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;如果我们要讲一个数据添加到布隆过滤器中，我们需要多个hash函数生成多个哈希值，再将这些hash值映射到对应的bit数组对的bit上，将这个bit置为1。例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7，则上图转变为：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Golnag之interface</title>
      <link>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golnag%E4%B9%8Binterface/</link>
      <pubDate>Tue, 23 Aug 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/golang/%E6%BA%90%E7%A0%81%E7%B3%BB%E5%88%97/golnag%E4%B9%8Binterface/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Golang之interface&#xA;    &lt;div id=&#34;golang之interface&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#golang%e4%b9%8binterface&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;接口&#xA;    &lt;div id=&#34;接口&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8e%a5%e5%8f%a3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;接口（interface）是一组仅包含方法名、参数、返回值的&lt;strong&gt;未具体实现的方法的集合&lt;/strong&gt;。接口只定义规范而不去实现，细节由具体的对象来实现。Golang中&lt;strong&gt;接口是一种抽象的类型&lt;/strong&gt;。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;实现&#xA;    &lt;div id=&#34;实现&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%9e%e7%8e%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Golang中interface通常分为两大类，一种是空接口，这种接口不带任何方法。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;另一种是非空接口，这种接口带有方法&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;duck&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;quack&lt;/span&gt;()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;这两种类型的接口底层分别对应两个不同的结构，空接口对应runtime.eface，非空接口对应runtime.iface&lt;/p&gt;&#xA;&lt;img src=&#34;http://storage.chuckchan.top/uploads/Golang之内存管理.jpeg&#34; alt=&#34;Golang之内存管理&#34; style=&#34;zoom:50%;&#34; /&gt;&#xA;&lt;p&gt;eface的定义如下&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;eface&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;_type&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;_type&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//记录类型信息（_type是GO语言中所有类型的公共描述，Go语言几乎所有的数据结构都可以抽象成 _type，是所有类型的公共描述，type负责决定data应该如何解释和操作）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;data&lt;/span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;unsafe&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Pointer&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//指向数据的指针&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;iface的定义如下&lt;/p&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;iface&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a6e22e&#34;&gt;tab&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;itab&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;//&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&#x9;data unsafe.Pointer //指向数据的指针&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;p&gt;itab是最重要的结构，每一个 &lt;code&gt;itab&lt;/code&gt; 都占 32 字节的空间。itab里面包含了interface的一些关键信息，比如method的具体实现。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Prometheus</title>
      <link>http://blog.chuckchan.top/posts/systemdesign/prometheus/</link>
      <pubDate>Tue, 16 Aug 2022 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/systemdesign/prometheus/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%851.-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E8%A1%8C%E4%B8%9A%E5%88%86%E6%9E%90/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%851.-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E8%A1%8C%E4%B8%9A%E5%88%86%E6%9E%90/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%852.-%E4%BB%8E%E6%8F%90%E7%A4%BA%E8%AF%8D%E5%88%B0rag%E6%9E%84%E5%BB%BA%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%9A%84%E7%9F%A5%E8%AF%86%E4%B8%8E%E4%BA%A4%E4%BA%92%E5%9F%BA%E7%A1%80/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%852.-%E4%BB%8E%E6%8F%90%E7%A4%BA%E8%AF%8D%E5%88%B0rag%E6%9E%84%E5%BB%BA%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%9A%84%E7%9F%A5%E8%AF%86%E4%B8%8E%E4%BA%A4%E4%BA%92%E5%9F%BA%E7%A1%80/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. 提示词&#xA;    &lt;div id=&#34;1-提示词&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e6%8f%90%e7%a4%ba%e8%af%8d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;提示词也叫Prompt，是我们与大模型应用交互的唯一桥梁，简单来说就是我们给大模型的&lt;strong&gt;输入&lt;/strong&gt;，例如我们在ChatGPT里的提问的问题，就是一个提示词：&lt;/p&gt;&#xA;&lt;img src=&#34;D:\学习\AI\AI课程资料\1.提示词和RAG\用户提示词.png&#34; style=&#34;zoom:33%;&#34; /&gt;&#xA;&lt;p&gt;用户提示词，除了用户提示词外，还有系统提示词。系统提示词可以简单地理解为一个自我介绍，例如扣子平台上的人设与回复逻辑：&lt;/p&gt;&#xA;&lt;img src=&#34;D:\学习\AI\AI课程资料\1.提示词和RAG\系统提示词.png&#34; style=&#34;zoom: 50%;&#34; /&gt;&#xA;&lt;p&gt;提示词是贯通整个大模型应用的灵魂，所有应用层的技术，都是为了拼出一条&lt;strong&gt;合适的Prompt&lt;/strong&gt;，在应用技术层无论我们做多炫酷的设计，最终都是为了传递合适的Prompt给大模型。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Prompt分类&#xA;    &lt;div id=&#34;prompt分类&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#prompt%e5%88%86%e7%b1%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Prompt的内容可以大致分为以下几类：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;身份设定：例如“你是一个法律领域的智能助手”&lt;/li&gt;&#xA;&lt;li&gt;背景设定：例如“你的年龄是在20岁左右的女生”&lt;/li&gt;&#xA;&lt;li&gt;参考资料：例如“请你参考xx资料”&lt;/li&gt;&#xA;&lt;li&gt;样例：例如一些门店提前准备的样例话术，下面会举例说明&lt;/li&gt;&#xA;&lt;li&gt;指令：例如“请你帮我总结一些这段文本”&lt;/li&gt;&#xA;&lt;li&gt;条件限制：例如“回答的时候不要超过200个字，尽量口语化”&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;在这些内容中，&lt;strong&gt;参考&lt;/strong&gt;跟&lt;strong&gt;样例&lt;/strong&gt;是比较重要的两个点，如果可以，提问的时候尽量将这两个内容加入Prompt中。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Zero-Shot、One-Shot、Few-Show&#xA;    &lt;div id=&#34;zero-shotone-shotfew-show&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#zero-shotone-shotfew-show&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;我们以Prompt中&lt;strong&gt;样例的数量&lt;/strong&gt;给Prompt划分为三种类型：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Zero-Shot：没有一条样例&lt;/li&gt;&#xA;&lt;li&gt;One-Shot：仅有一条样例&lt;/li&gt;&#xA;&lt;li&gt;Few-Show：有多条样例&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;我们可以使用扣子平台来搭建一个Sony智能销售的客服，来看看不同的样例数对大模型的输出会造成什么影响。假设我们有以下一个场景：&lt;/p&gt;&#xA;&lt;p&gt;场景：妈妈在给小孩挑游戏机做礼物，正在比较Switch和PS5&#xA;用户：感觉价格方面，Switch性价比高，PS5要贵不少吧？&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;D:%5c%e5%ad%a6%e4%b9%a0%5cAI%5cAI%e8%af%be%e7%a8%8b%e8%b5%84%e6%96%99%5c1.%e6%8f%90%e7%a4%ba%e8%af%8d%e5%92%8cRAG%5czero_shot.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;来看下没有样例的回答，这个回答不能说错，但是算不上出色，其回答仅仅基于大模型在其训练的数据组装而成，并没有对问题本身做一些针对性的回答（从表面上看，用户可能是价格敏感性的）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;D:%5c%e5%ad%a6%e4%b9%a0%5cAI%5cAI%e8%af%be%e7%a8%8b%e8%b5%84%e6%96%99%5c1.%e6%8f%90%e7%a4%ba%e8%af%8d%e5%92%8cRAG%5cfew_shot.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%853.-agent%E4%BB%8E%E5%8F%AF%E6%8E%A7%E6%80%A7%E5%88%B0%E8%87%AA%E4%B8%BB%E5%8F%8D%E6%80%9D/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%853.-agent%E4%BB%8E%E5%8F%AF%E6%8E%A7%E6%80%A7%E5%88%B0%E8%87%AA%E4%B8%BB%E5%8F%8D%E6%80%9D/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. 什么是Agent&#xA;    &lt;div id=&#34;1-什么是agent&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e4%bb%80%e4%b9%88%e6%98%afagent&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Agent 就是&lt;strong&gt;能像 “人” 一样自主完成任务的 AI 程序&lt;/strong&gt;：你只需要告诉它 &lt;strong&gt;“要做什么（目标）”&lt;/strong&gt;，不用告诉它**“怎么做（步骤）”**，它会自己规划步骤、调用工具、解决问题、完成目标，甚至中途遇到问题会自主调整策略。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;维度&lt;/th&gt;&#xA;          &lt;th&gt;普通大模型（如 ChatGPT）&lt;/th&gt;&#xA;          &lt;th&gt;RAG&lt;/th&gt;&#xA;          &lt;th&gt;AI Agent&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;核心能力&lt;/td&gt;&#xA;          &lt;td&gt;理解 + 生成文本，无自主规划 / 工具调用&lt;/td&gt;&#xA;          &lt;td&gt;大模型 + 知识库检索，补全知识&lt;/td&gt;&#xA;          &lt;td&gt;规划 + 工具 + 记忆 + 执行，自主完成任务&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;交互方式&lt;/td&gt;&#xA;          &lt;td&gt;被动响应&lt;strong&gt;单步指令&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;被动响应&lt;strong&gt;问答需求&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;主动承接&lt;strong&gt;整体目标&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;任务处理&lt;/td&gt;&#xA;          &lt;td&gt;单步、简单、无依赖的任务&lt;/td&gt;&#xA;          &lt;td&gt;知识类问答任务&lt;/td&gt;&#xA;          &lt;td&gt;多步、复杂、有依赖的复合任务&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;你需要做的事&lt;/td&gt;&#xA;          &lt;td&gt;拆解步骤，一步步指挥&lt;/td&gt;&#xA;          &lt;td&gt;准备知识库，提精准问题&lt;/td&gt;&#xA;          &lt;td&gt;只给目标，无需拆解步骤&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;核心定位&lt;/td&gt;&#xA;          &lt;td&gt;「AI 聊天助手」&lt;/td&gt;&#xA;          &lt;td&gt;「AI 知识问答助手」&lt;/td&gt;&#xA;          &lt;td&gt;「AI 工作伙伴 / 执行者」&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Agent可以大致分为Workflow Agent 与 ReAct Agent 两种。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%854.-%E5%A4%9A%E6%A8%A1%E6%80%81%E5%89%8D%E6%B2%BF%E4%BB%8Eagent%E6%9E%84%E5%BB%BA%E5%88%B0%E8%A7%86%E9%A2%91aigc/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%854.-%E5%A4%9A%E6%A8%A1%E6%80%81%E5%89%8D%E6%B2%BF%E4%BB%8Eagent%E6%9E%84%E5%BB%BA%E5%88%B0%E8%A7%86%E9%A2%91aigc/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. 视觉和语言的打通&#xA;    &lt;div id=&#34;1-视觉和语言的打通&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e8%a7%86%e8%a7%89%e5%92%8c%e8%af%ad%e8%a8%80%e7%9a%84%e6%89%93%e9%80%9a&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;如何打通：一个模型，能同时看懂语言和视觉&lt;/p&gt;&#xA;&lt;p&gt;进阶能力：能输出文字，也能输出图片、视频&lt;/p&gt;&#xA;&lt;p&gt;好处：视觉转译、融合推理、视觉编辑&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;2. 视觉识别 与 视觉推理&#xA;    &lt;div id=&#34;2-视觉识别-与-视觉推理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e8%a7%86%e8%a7%89%e8%af%86%e5%88%ab-%e4%b8%8e-%e8%a7%86%e8%a7%89%e6%8e%a8%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;传统视觉识别模型 vs 多模态模型&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;&lt;/th&gt;&#xA;          &lt;th&gt;传统视觉识别模型&lt;/th&gt;&#xA;          &lt;th&gt;多模态模型&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;产品&lt;/td&gt;&#xA;          &lt;td&gt;Yolo、UNet&lt;/td&gt;&#xA;          &lt;td&gt;Gemini、GPT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;优势&lt;/td&gt;&#xA;          &lt;td&gt;模型小、部署和使用成本低、识别精度高&lt;/td&gt;&#xA;          &lt;td&gt;无需标注、无需训练、直接使用、有推理能力&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;劣势&lt;/td&gt;&#xA;          &lt;td&gt;需要单独标注数据、训练模型&lt;/td&gt;&#xA;          &lt;td&gt;部署和使用成本较高，精度中等&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;3. 视觉生成&#xA;    &lt;div id=&#34;3-视觉生成&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#3-%e8%a7%86%e8%a7%89%e7%94%9f%e6%88%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;模型能力不足：只是写提示词给模型，生成的视频&amp;amp;图片无法满足需求。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;3.1 用AI做海报&#xA;    &lt;div id=&#34;31-用ai做海报&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#31-%e7%94%a8ai%e5%81%9a%e6%b5%b7%e6%8a%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%855.-langchain%E5%A4%9A%E4%BB%BB%E5%8A%A1%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%855.-langchain%E5%A4%9A%E4%BB%BB%E5%8A%A1%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. LangChain&#xA;    &lt;div id=&#34;1-langchain&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-langchain&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;LangChain 是一套开源的 Python/JavaScript 框架，核心是通过模块化组件与可组合的链（Chain）将大语言模型（LLM）与外部数据源、工具（如搜索、数据库、API）连接，实现上下文管理、多步推理、智能交互等复杂 AI 应用的快速开发。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;代码地址：https://github.com/langchain-ai/langchain&lt;/li&gt;&#xA;&lt;li&gt;官方文档：https://docs.langchain.com/&lt;/li&gt;&#xA;&lt;li&gt;中文文档：https://langchain-doc.cn/ （机翻，凑合着看）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;LangChain的一些组件：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Models：模型，比如GPT-4o&lt;/li&gt;&#xA;&lt;li&gt;Prompts：提示，包括提示管理、提示优化和提示序列化&lt;/li&gt;&#xA;&lt;li&gt;Memory：记忆，用来保存和模型交互时的上下文&lt;/li&gt;&#xA;&lt;li&gt;Indexes：索引，用于结构化文档，方便和模型交互如果要构建自己的知识库，就需要各种类型文档的加载，转换，长文本切割，文本向量计算，向量索引存储查询等&lt;/li&gt;&#xA;&lt;li&gt;Chains：链，一系列对各种组件的调用&lt;/li&gt;&#xA;&lt;li&gt;Agents：代理，决定模型采取哪些行动，执行并且观察流程，直到完成&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;2. 核心组件&#xA;    &lt;div id=&#34;2-核心组件&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e6%a0%b8%e5%bf%83%e7%bb%84%e4%bb%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;代理&#xA;    &lt;div id=&#34;代理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bb%a3%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;代理即Agent，其将语言模型与&lt;a href=&#34;https://langchain-doc.cn/v1/python/langchain/tools&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;工具&lt;/a&gt;结合，创建能够对任务&lt;strong&gt;进行推理、决定使用哪些工具&lt;/strong&gt;并迭代寻求解决方案的系统，简单来说，Agent像“人”一样能够通过思考来解决问题。&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;模型&#xA;    &lt;div id=&#34;模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;模型即我们常说的大模型（如ChatGPT、Deepseek），能够像人类一样理解和生成文本。它们用途广泛，可用于撰写内容、翻译语言、总结信息和回答问题，而无需针对每项任务进行专门训练，模型是整个Langchain框架的大脑。模型可以通过两种方式使用：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%856.-ai%E6%A1%86%E6%9E%B6%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E9%80%89%E5%9E%8B/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%856.-ai%E6%A1%86%E6%9E%B6%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E9%80%89%E5%9E%8B/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. 主流Agent框架&#xA;    &lt;div id=&#34;1-主流agent框架&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-%e4%b8%bb%e6%b5%81agent%e6%a1%86%e6%9e%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;框架&lt;/th&gt;&#xA;          &lt;th&gt;优势&lt;/th&gt;&#xA;          &lt;th&gt;适用场景&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;LangChain+LangGraph&lt;/td&gt;&#xA;          &lt;td&gt;全能型框架，管道式编排与丰富生态&lt;/td&gt;&#xA;          &lt;td&gt;企业级复杂应用、RAG + 工具混合&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;AutoGen&lt;/td&gt;&#xA;          &lt;td&gt;对话式多 Agent&lt;/td&gt;&#xA;          &lt;td&gt;科研、代码生成、多角色辩论&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Qwen-Agent&lt;/td&gt;&#xA;          &lt;td&gt;针对中文场景优化，对长文本友好&lt;/td&gt;&#xA;          &lt;td&gt;私有化部署、对接通义千问 / 阿里云生态&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Coze/Dify&lt;/td&gt;&#xA;          &lt;td&gt;低代码可视化&lt;/td&gt;&#xA;          &lt;td&gt;业务人员快速搭建应用&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;这里仅仅列举了几个不同类型的框架，另外还有CrewAI、Semantic Kernel等一系列框架，不再一一列举。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;2. Agent框架功能&#xA;    &lt;div id=&#34;2-agent框架功能&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-agent%e6%a1%86%e6%9e%b6%e5%8a%9f%e8%83%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;一个Agent框架需要有哪些功能，解决哪些核心问题？&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;1.1 LLM层适配&#xA;    &lt;div id=&#34;11-llm层适配&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#11-llm%e5%b1%82%e9%80%82%e9%85%8d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;LLM是Agent框架的&lt;strong&gt;大脑&lt;/strong&gt;，一个Agent框架首先要具有LLM适配功能。一般来说，框架都具有以下特性：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;统一调用方式&lt;/li&gt;&#xA;&lt;li&gt;统一了参数配置（如 temperature）&lt;/li&gt;&#xA;&lt;li&gt;输出格式（统一转为 Message 对象）&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;具体例子可以查看上一篇，这里不再赘述如何调用LLM。简单来说，就是各家LLM都定义了自己的一套API接口，如果要开发者自己去集成这些API，会花费很多功夫，所以这些框架都会在API层的基础上再包装一层，以适配不同的LLM。当开发者需要修改模型时，只需要修改对应的参数即可。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%857.-huggingface%E7%94%9F%E6%80%81%E5%AE%9E%E6%88%98%E4%BB%8E%E6%A8%A1%E5%9E%8B%E5%BA%94%E7%94%A8%E5%88%B0%E9%AB%98%E6%95%88%E5%BE%AE%E8%B0%83/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%857.-huggingface%E7%94%9F%E6%80%81%E5%AE%9E%E6%88%98%E4%BB%8E%E6%A8%A1%E5%9E%8B%E5%BA%94%E7%94%A8%E5%88%B0%E9%AB%98%E6%95%88%E5%BE%AE%E8%B0%83/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Hugging Face&#xA;    &lt;div id=&#34;hugging-face&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hugging-face&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://huggingface.co/&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;Hugging Face&lt;/a&gt; 是什么？你可以把HuggingFace看成：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;AI 界的 GitHub：程序员找代码去 GitHub，AI 工程师找模型和数据去 HuggingFace，它托管了全球最主流的开源模型（Llama, BERT, Stable Diffusion 等）。&lt;/li&gt;&#xA;&lt;li&gt;AI 界的 App Store：它提供了很多现成的 Pipeline，你不需要懂原理，就能在你的代码里跑起来（比如一键实现情感分析）。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;Hugging Face 的核心&#xA;    &lt;div id=&#34;hugging-face-的核心&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hugging-face-%e7%9a%84%e6%a0%b8%e5%bf%83&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;1）Transformers (库)：&lt;/p&gt;&#xA;&lt;p&gt;工具箱。提供了统一的 Python 接口，可以用几乎相同的代码加载 BERT、GPT 或 Llama。&lt;/p&gt;&#xA;&lt;p&gt;2）Model Hub (网站)：&lt;/p&gt;&#xA;&lt;p&gt;仓库。存放模型权重文件（.bin 或 .safetensors）和配置文件（config.json）。&lt;/p&gt;&#xA;&lt;p&gt;3）Datasets (库)：&lt;/p&gt;&#xA;&lt;p&gt;燃料库。一键下载维基百科、医疗问答、电商评论等海量数据集，并自动处理成模型能读的格式。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;Hugging Face 中常用的模型&#xA;    &lt;div id=&#34;hugging-face-中常用的模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#hugging-face-%e4%b8%ad%e5%b8%b8%e7%94%a8%e7%9a%84%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;NLP（自然语言处理）领域&#xA;    &lt;div id=&#34;nlp自然语言处理领域&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#nlp%e8%87%aa%e7%84%b6%e8%af%ad%e8%a8%80%e5%a4%84%e7%90%86%e9%a2%86%e5%9f%9f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;u&gt;基础理解类（Encoder-Only&lt;/u&gt;）：&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%858.-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BE%AE%E8%B0%83/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E4%B9%8B%E6%97%858.-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BE%AE%E8%B0%83/</guid>
      <description></description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E7%95%AA%E5%A4%961.-transformer%E7%9C%9F%E9%9D%A2%E7%9B%AE1/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E7%95%AA%E5%A4%961.-transformer%E7%9C%9F%E9%9D%A2%E7%9B%AE1/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;1. Transformer模型&#xA;    &lt;div id=&#34;1-transformer模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#1-transformer%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;在深度学习序列建模的发展中，RNN、LSTM等传统模型因&lt;strong&gt;难以捕捉长距离依赖、无法并行计算的瓶颈&lt;/strong&gt;，难以满足大规模数据处理需求，Transformer模型应运而生。2017年，Google Brain团队发表《Attention Is All You Need》，正式提出这一纯注意力架构，打破循环结构的局限；历经多年演进，它从机器翻译任务起步，衍生出BERT、GPT等经典模型，如今已成为所有现代大模型的核心基础，支撑着多模态、千亿级参数模型的发展，奠定了当前人工智能产业化的技术根基。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;2. 模型架构&#xA;    &lt;div id=&#34;2-模型架构&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#2-%e6%a8%a1%e5%9e%8b%e6%9e%b6%e6%9e%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Transformer模型的架构图如下所示，总共可以分成6个步骤&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Tokenization：文本变成token&lt;/li&gt;&#xA;&lt;li&gt;Embedding：token变成向量&lt;/li&gt;&#xA;&lt;li&gt;Positional Encoding：在向量中加入位置信息&lt;/li&gt;&#xA;&lt;li&gt;Encoder &amp;amp; Decoder：深度理解语义&lt;/li&gt;&#xA;&lt;li&gt;Linear：生成“下一个字”的权重分布&lt;/li&gt;&#xA;&lt;li&gt;Softmax：将权重分布转换成概率分布&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;2.1  Tokenization&#xA;    &lt;div id=&#34;21--tokenization&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#21--tokenization&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;第一步要做的是Tokenization，即把一段文本（这里应该叫输入更合适，但为了好理解还是用文本吧），变成一组Token。⽐如：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;ldquo;subword&amp;quot;这个词，可以拆分成&amp;quot;sub&amp;quot;和&amp;quot;word&amp;quot;两个⼦词&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;encoded&amp;quot;可以拆解为&amp;quot;encod&amp;rdquo;+&amp;ldquo;ed&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;encoding&amp;quot;可以拆解为“encod”+&amp;ldquo;ing&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;使用OpenAI的tiktoken对“海南麒麟瓜”进行词元化，输出如下：&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;D:%5c%e5%ad%a6%e4%b9%a0%5cAI%5cAI%e8%af%be%e7%a8%8b%e8%b5%84%e6%96%99%5c%e5%8e%9f%e7%90%86%e8%af%be3-%e7%a7%98Transformer%e7%9a%84%e7%9c%9f%e9%9d%a2%e7%9b%ae-1%5c%e8%af%8d%e5%85%83%e5%8c%96.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;可见通过GPT-3.5模型拆分出来的token跟中文汉字的UTF-8编码并不是一一对应的。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/llm/llm%E7%95%AA%E5%A4%962.-transformer%E8%87%AA%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/llm/llm%E7%95%AA%E5%A4%962.-transformer%E8%87%AA%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;传统模型&#xA;    &lt;div id=&#34;传统模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bc%a0%e7%bb%9f%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;上一篇文章中我们说过，相较于现今的大语言模型，传统的模型使用的是RNN循环神经网络&lt;/p&gt;&#xA;&lt;p&gt;&lt;figure&gt;&lt;img&#xA;    class=&#34;my-0 rounded-md&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&#xA;    fetchpriority=&#34;low&#34;&#xA;    alt=&#34;&#34;&#xA;    src=&#34;D:%5c%e5%ad%a6%e4%b9%a0%5cAI%5cAI%e8%af%be%e7%a8%8b%e8%b5%84%e6%96%99%5c%e5%8e%9f%e7%90%86%e8%af%be4-%e6%8f%ad%e7%a7%98Transformer%e7%9c%9f%e9%9d%a2%e7%9b%ae-2%5c%e5%be%aa%e7%8e%af%e7%a5%9e%e7%bb%8f%e7%bd%91%e7%bb%9c.png&#34;&#xA;    &gt;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;这种神经网络模式有几个缺点：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;信息丢失&lt;/li&gt;&#xA;&lt;li&gt;无法处理较长句子&lt;/li&gt;&#xA;&lt;li&gt;不能并行计算&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;注意力机制&#xA;    &lt;div id=&#34;注意力机制&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%b3%a8%e6%84%8f%e5%8a%9b%e6%9c%ba%e5%88%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;什么叫注意力机制？&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/middleware/es/es%E5%B8%B8%E7%94%A8%E7%9A%84curl%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/es/es%E5%B8%B8%E7%94%A8%E7%9A%84curl%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;索引相关&#xA;    &lt;div id=&#34;索引相关&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b4%a2%e5%bc%95%e7%9b%b8%e5%85%b3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 创建索引 并设置mapping&amp;amp;分片数&amp;amp;副本数&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XPUT &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://user:password@url:9200/books&amp;#39;&lt;/span&gt; -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; -d&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;settings&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      &amp;#34;number_of_shards&amp;#34;: 3,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      &amp;#34;number_of_replicas&amp;#34;: 1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;mappings&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      &amp;#34;properties&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          &amp;#34;book_id&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;              &amp;#34;type&amp;#34;: &amp;#34;keyword&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          &amp;#34;book_name&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;              &amp;#34;analyzer&amp;#34;: &amp;#34;standard&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                  &amp;#34;type&amp;#34;: &amp;#34;text&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          &amp;#34;update_time&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            &amp;#34;type&amp;#34;: &amp;#34;date&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;create_time&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          &amp;#34;type&amp;#34;: &amp;#34;date&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        }    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  }&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 查询索引 &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XGET &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://user:password@url:9200/books?pretty&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 删除索引&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XDELETE &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://user:password@url:9200/books&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 查询索引 &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  curl -XGET &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://user:password@url:9200/books?pretty&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;查询相关&#xA;    &lt;div id=&#34;查询相关&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%9f%a5%e8%af%a2%e7%9b%b8%e5%85%b3&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight-wrapper&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/middleware/es/es%E5%BE%97%E5%88%86%E6%9C%BA%E5%88%B6/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/middleware/es/es%E5%BE%97%E5%88%86%E6%9C%BA%E5%88%B6/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;前言&#xA;    &lt;div id=&#34;前言&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%89%8d%e8%a8%80&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Elasticsearch是基于Lucene的，所以它的评分机制也是基于Lucene的。在Lucene中把这种相关性称为得分（score），确定文档和查询有多大相关性的过程被称为打分（scoring）。&lt;/p&gt;&#xA;&lt;p&gt;ES最常用的评分模型是 TF/IDF和BM25，TF-IDF属于向量空间模型，而BM25属于概率模型，但是他们的评分公式差别并不大，都使用IDF方法和TF方法的某种乘积来定义单个词项的权重，然后把和查询匹配的词项的权重相加作为整篇文档的分数。&lt;/p&gt;&#xA;&lt;p&gt;ES v5.0 之前使用TF/IDF算法，之后的版本使用BM25算法。&lt;/p&gt;&#xA;&#xA;&lt;h1 class=&#34;relative group&#34;&gt;名词解释&#xA;    &lt;div id=&#34;名词解释&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%90%8d%e8%af%8d%e8%a7%a3%e9%87%8a&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;</description>
      
    </item>
    
    <item>
      <title></title>
      <link>http://blog.chuckchan.top/posts/pmp/pmp%E9%A2%98%E7%BA%B2/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://blog.chuckchan.top/posts/pmp/pmp%E9%A2%98%E7%BA%B2/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;pmp题纲&#xA;    &lt;div id=&#34;pmp题纲&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#pmp%e9%a2%98%e7%ba%b2&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;情景模拟学习法&#xA;    &lt;div id=&#34;情景模拟学习法&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%83%85%e6%99%af%e6%a8%a1%e6%8b%9f%e5%ad%a6%e4%b9%a0%e6%b3%95&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;识别时间点&#xA;&lt;ul&gt;&#xA;&lt;li&gt;问现在&#xA;&lt;ul&gt;&#xA;&lt;li&gt;重要优先&lt;/li&gt;&#xA;&lt;li&gt;识别方法&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;项目经理现在应该做什么？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;项目经理能够如何完成这项工作？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;项目经理应该使用什么来进行回复？&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;应对思路&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;重要优先： 如果多个答案都合理，选择其中最重要的，最能解决问题的方法&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;原则优先：选择最符合PMI价值观的方法&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;合规优先：必须遵守规则、流程和计划&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;4&#34;&gt;&#xA;&lt;li&gt;响应题目：对于题目中给出的制约因素，要进行考虑和响应&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;问首先（步骤在前）&#xA;&lt;ul&gt;&#xA;&lt;li&gt;识别方法&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;项目经理首先应该做什么&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;项目经理下一步应该做什么&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;项目经理应该指示团队下一步做什么&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;应对思路&#xA;&lt;ul&gt;&#xA;&lt;li&gt;1.如果多个选项都是正确的行为，要选择其中执行顺序在前的&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;问事先（规避防范）&#xA;&lt;ul&gt;&#xA;&lt;li&gt;识别方法&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;项目经理事先应该采取什么不同的做法&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;项目经理要如何在项目开始时管理此情形&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;若要避免这种情况，项目经理应该做什么&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;下列哪一项可以预防该问题&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;应对思路&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;先分析问题的根本原因，再从根源上和流程制度上消除这个原因&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;主要的解决办法&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;a. 制定正确的计划和过程&lt;/li&gt;&#xA;&lt;li&gt;b. 确保执行正确的计划和过程&lt;/li&gt;&#xA;&lt;li&gt;c. 让相关方尽早参与&lt;/li&gt;&#xA;&lt;li&gt;d. 充分识别风险并制定对应的计划&lt;/li&gt;&#xA;&lt;li&gt;e.  充分收集需求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;问未来（积累经验）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;识别项目阶段&#xA;&lt;ul&gt;&#xA;&lt;li&gt;启动阶段&lt;/li&gt;&#xA;&lt;li&gt;规划阶段&lt;/li&gt;&#xA;&lt;li&gt;执行阶段&lt;/li&gt;&#xA;&lt;li&gt;收尾阶段&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;识别典型场景&#xA;&lt;ul&gt;&#xA;&lt;li&gt;要求变更/私自变更&lt;/li&gt;&#xA;&lt;li&gt;资源短缺/技能不足&lt;/li&gt;&#xA;&lt;li&gt;新节点&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;解析pmi核心价值观&#xA;    &lt;div id=&#34;解析pmi核心价值观&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%a7%a3%e6%9e%90pmi%e6%a0%b8%e5%bf%83%e4%bb%b7%e5%80%bc%e8%a7%82&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;新节点&lt;/li&gt;&#xA;&lt;li&gt;新节点&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;问题解决的思维模型&#xA;    &lt;div id=&#34;问题解决的思维模型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3%e7%9a%84%e6%80%9d%e7%bb%b4%e6%a8%a1%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;</description>
      
    </item>
    
  </channel>
</rss>
