<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[厦门暗游网络科技有限公司]]></title><description><![CDATA[游戏让生活更有趣，关注鸿蒙、Unity、Cocos、Laya、Egret、AR，影子工作室]]></description><link>http://xmanyou.com/</link><image><url>http://xmanyou.com/favicon.png</url><title>厦门暗游网络科技有限公司</title><link>http://xmanyou.com/</link></image><generator>Ghost 2.23</generator><lastBuildDate>Thu, 02 Apr 2026 09:02:34 GMT</lastBuildDate><atom:link href="http://xmanyou.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[企业微信邮箱如何设置pop/imap收信]]></title><description><![CDATA[要通过程序来收企业微信邮箱，需要经过2个步骤。]]></description><link>http://xmanyou.com/qi-ye-wei-xin-you-xiang-ru-he-she-zhi-pop3-imapshou-xin/</link><guid isPermaLink="false">699ff7dcfc9f4e0641f57dec</guid><category><![CDATA[杂七杂八]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Thu, 26 Feb 2026 08:00:49 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">问题</h2>
<p>想用第三方客户端或者程序收取企业微信邮箱的邮件，在企微的邮箱设置里找了半天都没有找到入口。网上搜了一下，也没有找到容易看懂的攻略。</p>
<p>后来才发现，企业微信邮箱是单独的一个应用，无法在企微里获取收信密码，需要登录去企业微信邮箱的后台去找：<a href="https://exmail.qq.com/">https://exmail.qq.com/</a></p>
<h2 id="">解决</h2>
<p>需要两个操作：</p>
<ol>
<li>企业微信管理员，开启客户端访问限制，允许使用pop/imap收信。</li>
<li>邮箱用户，去开启pop/imap服务，并获取访问密码。</li>
</ol>
<h3 id="">企业微信管理员允许客户端访问</h3>
<p>这个步骤由管理员在企业微信后台的操作，邮件 -&gt; 安全管理工具 -&gt; 客户端访问限制</p>
<p><img src="http://xmanyou.com/content/images/2026/02/qiye-weixin-mail-pop-imap-settings-04--1-.png" alt="qiye-weixin-mail-pop-imap-settings-04--1-"></p>
<p><img src="http://xmanyou.com/content/images/2026/02/qiye-weixin-mail-pop-imap-settings-05--1-.png" alt="qiye-weixin-mail-pop-imap-settings-05--1-"></p>
<h3 id="popimap">邮箱用户获取企业微信邮箱 pop/imap 访问密码</h3>
<ol>
<li>登录企业微信邮箱（微信企业邮），注意不是企业微信后台！地址：<a href="https://exmail.qq.com/">https://exmail.qq.com/</a></li>
</ol>
<p><img src="http://xmanyou.com/content/images/2026/02/qiye-weixin-mail-pop-imap-settings-03--1-.png" alt="qiye-weixin-mail-pop-imap-settings-03--1-"></p>
<ol start="2">
<li>设置(邮箱设置)-&gt;收发信设置-&gt;开启IMAP/SMTP服务（或者POP/SMTP服务）</li>
</ol>
<p><img src="http://xmanyou.com/content/images/2026/02/qiye-weixin-mail-pop-imap-settings-01.jpg" alt="qiye-weixin-mail-pop-imap-settings-01"></p>
<ol start="3">
<li>设置(邮箱设置)-&gt;邮箱绑定-&gt;生成新密码<br>
<img src="http://xmanyou.com/content/images/2026/02/qiye-weixin-mail-pop-imap-settings-02.jpg" alt="qiye-weixin-mail-pop-imap-settings-02"></li>
</ol>
<p>完成。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[用AI编写一个极简todo插件]]></title><description><![CDATA[用AI为自己开发一个任务清单插件，AI 含量: 99.9%]]></description><link>http://xmanyou.com/a-lightweight-todo-extension-built-with-ai/</link><guid isPermaLink="false">6989928ffc9f4e0641f57da3</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Mon, 09 Feb 2026 09:26:47 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><img src="http://xmanyou.com/content/images/2026/02/10dos-1.png" alt="10dos-1"></p>
<h2 id="">问题背景</h2>
<p>做这个项目主要有2个目的：</p>
<ul>
<li>测试 AI 编程的能力，积累与 AI 协作的经验</li>
<li>为自己开发一个实用工具</li>
</ul>
<p>一直以来，我都有一个想法：想要一个随手就能打开记录的任务清单。在试过很多清单工具后，我发现一个致命的问题，随着记录的任务越多，实际完成的任务越来越少。</p>
<p>为什么呢？<br>
我感觉，可能是因为中国的那句老话：虱子多了不痒。</p>
<p>有太多待完成的任务之后，反而不那么着急了。</p>
<p>所以，我就萌生出了一个想法，做一个极简的任务清单工具。</p>
<h2 id="">解决方法</h2>
<p>这个工具最好是在手边随时能打开，于是，浏览器插件，就是最好的形式。因为，毕竟大部分的时间都是上网摸鱼嘛。</p>
<p>开发工具嘛，就选我最熟悉的Cursor。</p>
<p><img src="http://xmanyou.com/content/images/2026/02/simple-todo-extension-built-with-ai.jpg" alt="simple-todo-extension-built-with-ai"></p>
<p>可能因为需求比较清晰，且功能比较简单，整个开发过程异常顺利。</p>
<p>核心功能：</p>
<ul>
<li>最多10个任务，多了就不能再添加</li>
<li>根据任务制定时间，显示紧急程度</li>
</ul>
<p>然后，最后我就把它发布到了chrome 商店：<br>
<a href="https://chromewebstore.google.com/detail/10dos/kcphneilcldimkjgfmoiffiklfapcopm">https://chromewebstore.google.com/detail/10dos/kcphneilcldimkjgfmoiffiklfapcopm</a></p>
<p><img src="http://xmanyou.com/content/images/2026/02/10dos-extension-2.jpg" alt="10dos-extension-in-chrome-store"></p>
<p>清单：</p>
<ul>
<li>项目地址：<a href="https://github.com/zhangzhibin/10dos">https://github.com/zhangzhibin/10dos</a></li>
<li>插件地址：<a href="https://chromewebstore.google.com/detail/10dos/kcphneilcldimkjgfmoiffiklfapcopm">https://chromewebstore.google.com/detail/10dos/kcphneilcldimkjgfmoiffiklfapcopm</a></li>
</ul>
<p>AI 含量：99.9%</p>
<h2 id="">小结</h2>
<p>AI编程技术已经越来越成熟，对于这样的需求明确，交互简单的产品，几乎可以完全独立完成。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[用AI编写一个在线CSV分享工具 tempcsv.com]]></title><description><![CDATA[分享tempcsv.com的实现过程。AI 编程肯定是大势所趋了，作为程序员，投身其中才能真正体会到这场变革的不可逆，并找到自己在这场变革中的位置。]]></description><link>http://xmanyou.com/building-tempcsv-with-ai/</link><guid isPermaLink="false">69806c87fc9f4e0641f57d26</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Mon, 02 Feb 2026 09:48:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">背景</h2>
<p>这几年，AI越来越走进工作生活的方方面面，作为一个程序员，AI对于编程的提升，所谓的Vibe Coding，已经从最早的智能提示，到现在直接完全替代手搓代码，几乎是一个翻天覆地的变化。</p>
<p>参与到这场工业革命最好的方法，就是亲自尝试，投入其中。</p>
<p>于是乎，我就临时起意，想了一个需求：在线查看和分享csv表格。</p>
<p>项目已经部署在：<a href="https://tempcsv.com">https://tempcsv.com</a><br>
代码分享在github： <a href="https://github.com/open4game/tempcsv">https://github.com/open4game/tempcsv</a></p>
<h2 id="">过程</h2>
<h3 id="cursor">第一个版本：Cursor 建功</h3>
<p>这个项目最早是2025年3月上传第一行代码。我选择的技术栈是</p>
<ul>
<li>Cursor：开发主力</li>
<li>Vue：前端</li>
<li>Hono：后端</li>
<li>CloudFlare：Worker + R2</li>
</ul>
<p><img src="http://xmanyou.com/content/images/2026/02/ai-coding-practice-tempcsv-01.png" alt="ai-coding-practice-tempcsv-01"></p>
<p>与几乎所有的AI项目一样，前面80%的代码都异常顺利，剩下的20%中的80%，只要可能花时间慢慢与AI进行battle，基本上都能搞定。</p>
<p>但是，最后的4%，纯靠AI + 一个半桶水的程序员，几乎是不可能完成的任务。</p>
<p>为了能确保上线，我选择了保守策略：精简需求 + 提高容忍度，简单说，能用就好。</p>
<p>所以，差不多也就两三天的功夫，第一个Vue版本的 tempcsv.com 上线了。</p>
<h3 id="cc">第二个版本：CC 重构</h3>
<p>过了大半年，我又重新拾起这个项目，然后用 Claude Code 对前端进行了重度的重构。这次，我一方面想修复一些小bug，另一方面也是为了测试 CC 的长任务能力。这半年里，AI编程的进化几乎是一日千里，与这个项目最初创建时，已经不可同日而语，而 CC 也超越 Cursor 成为 AI 编程的 C 位。</p>
<p>我先让 CC 阅读了项目代码，分析了 Vue 版本的前端实现，然后制定了 Next 版本的重构计划，并对测试和部署方案进行了一些修改。一切都很顺利，直到又再次最后的 20% 问题。</p>
<p><img src="http://xmanyou.com/content/images/2026/02/ai-coding-practice-tempcsv-02.png" alt="ai-coding-practice-tempcsv-02"></p>
<p>严格的说，这次 CC 遇到的问题比 Cursor 麻烦，因为 CC 对中国的限制访问，我只能用一些特殊方法，导致使用上非常不便，一直遇到奇怪的问题：</p>
<pre><code>API Error: Claude's response exceeded the 32000 output token maximum. To configure this behavior, set the CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable.
</code></pre>
<p>这个问题在最近一周持续困扰我，导致cc始终无法完成上线的最低需求。</p>
<h3 id="cursor">第三个版本：Cursor 接盘</h3>
<p>我尝试用Cursor来接盘 CC 的代码修复bug，完成上线。</p>
<p>这时候，意外发生了：Cursor 一打开 CC 改过的项目，就直接崩溃了……</p>
<p>最后，我只好重新拉取代码，这次Cursor 顺利打开，然后剩下就是 Cursor 的舒适区了：</p>
<p><img src="http://xmanyou.com/content/images/2026/02/ai-coding-practice-tempcsv-03.png" alt="ai-coding-practice-tempcsv-03"></p>
<p>于是乎，最终版本上线了。</p>
<p><img src="http://xmanyou.com/content/images/2026/02/ai-coding-practice-tempcsv-04.png" alt="ai-coding-practice-tempcsv-04"></p>
<p>虽然最终还是用 Cursor 完成了最后一公里，但是，今天的 Cursor 和一年前的 Cursor 其实也已经不可同日而语了。</p>
<h2 id="">总结</h2>
<p>AI 编程肯定是大势所趋了，作为程序员，投身其中才能真正体会到这场变革的不可逆，并找到自己在这场变革中的位置。</p>
<!--kg-card-end: markdown--><p></p>]]></content:encoded></item><item><title><![CDATA[AI时代的开发范式：规范驱动开发 (SDD)？]]></title><description><![CDATA[当AI的辅助编程和自动编程不可避免，是否需要引入新的编程范式？规范驱动开发尝试解决AI时代的开发问题。]]></description><link>http://xmanyou.com/ai-era-development-paradigm-specification-driven-development-sdd/</link><guid isPermaLink="false">68cd0c0bfc9f4e0641f57d06</guid><category><![CDATA[AI]]></category><category><![CDATA[开发笔记]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Fri, 19 Sep 2025 07:58:25 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>本文使用Cursor翻译，原文在：<a href="https://github.com/github/spec-kit/blob/main/spec-driven.md">https://github.com/github/spec-kit/blob/main/spec-driven.md</a></p>
<h1 id="sdd">规范驱动开发 (SDD)</h1>
<h2 id="">权力反转</h2>
<p>几十年来，代码一直是王者。规范服务于代码——它们是我们在构建完成后就丢弃的脚手架。我们编写 PRD 来指导开发，创建设计文档来告知实现，绘制图表来可视化架构。但这些总是从属于代码本身。代码就是真理。其他一切都是，最多只是良好的意图。代码是真理的源泉，随着它的发展，规范很少能跟上步伐。由于资产（代码）和实现是一体的，不尝试从代码构建就很难有并行实现。</p>
<p>规范驱动开发（SDD）颠覆了这种权力结构。规范不服务于代码——代码服务于规范。产品需求文档（PRD）不是实现的指南；它是生成实现的源泉。技术计划不是告知编码的文档；它们是产生代码的精确定义。这不是对软件构建方式的渐进式改进。这是对驱动开发的根本性重新思考。</p>
<p>规范与实现之间的差距自软件诞生以来就一直困扰着软件开发。我们试图通过更好的文档、更详细的需求、更严格的流程来弥合这一差距。这些方法失败了，因为它们接受差距是不可避免的。它们试图缩小差距但从未消除它。SDD 通过使规范及其从规范产生的具体实现计划可执行来消除差距。当规范和实现计划生成代码时，就没有差距——只有转换。</p>
<p>这种转换现在成为可能，因为 AI 能够理解和实现复杂的规范，并创建详细的实现计划。但没有结构的原始 AI 生成会产生混乱。SDD 通过提供足够精确、完整和明确的规范来生成工作系统，从而提供这种结构。规范成为主要工件。代码成为其在特定语言和框架中的表达（作为实现计划的实现）。</p>
<p>在这个新世界中，维护软件意味着发展规范。开发团队的意图用自然语言表达（&quot;<strong>意图驱动开发</strong>&quot;）、设计资产、核心原则和其他指导方针。开发的<strong>通用语言</strong>提升到更高层次，代码是最后一英里的方法。</p>
<p>调试意味着修复生成错误代码的规范和实现计划。重构意味着为清晰度而重新构建。整个开发工作流程围绕规范作为中央真理源重新组织，实现计划和代码作为持续重新生成的输出。用新功能更新应用程序或创建新的并行实现，因为我们是创造性的存在，意味着重新审视规范并创建新的实现计划。因此，这个过程是 0 -&gt; 1, (1', ..), 2, 3, N。</p>
<p>开发团队专注于他们的创造力、实验和批判性思维。</p>
<h2 id="sdd">SDD 工作流程实践</h2>
<p>工作流程从一个想法开始——通常是模糊和不完整的。通过与 AI 的迭代对话，这个想法成为一个全面的 PRD。AI 提出澄清问题，识别边缘情况，并帮助定义精确的验收标准。在传统开发中可能需要数天会议和文档的工作，在专注的规范工作中几小时内就能完成。这改变了传统的 SDLC——需求和设计成为持续活动而不是离散阶段。这支持<strong>团队流程</strong>，其中团队审查的规范被表达和版本化，在分支中创建并合并。</p>
<p>当产品经理更新验收标准时，实现计划自动标记受影响的技术决策。当架构师发现更好的模式时，PRD 更新以反映新的可能性。</p>
<p>在整个规范过程中，研究代理收集关键上下文。他们调查库兼容性、性能基准和安全影响。组织约束被自动发现和应用——您公司的数据库标准、认证要求和部署策略无缝集成到每个规范中。</p>
<p>从 PRD 开始，AI 生成将需求映射到技术决策的实现计划。每个技术选择都有文档化的理由。每个架构决策都追溯到特定需求。在整个过程中，一致性验证持续提高质量。AI 分析规范的模糊性、矛盾性和差距——不是作为一次性门控，而是作为持续的改进。</p>
<p>代码生成在规范和实现计划足够稳定时就开始，但它们不必&quot;完整&quot;。早期生成可能是探索性的——测试规范在实践中是否有意义。领域概念成为数据模型。用户故事成为 API 端点。验收场景成为测试。这通过规范合并了开发和测试——测试场景不是在代码之后编写的，它们是生成实现和测试的规范的一部分。</p>
<p>反馈循环延伸到初始开发之外。生产指标和事件不仅触发热修复——它们为下一次重新生成更新规范。性能瓶颈成为新的非功能性需求。安全漏洞成为影响所有未来生成的约束。规范、实现和运营现实之间的这种迭代舞蹈是真正理解出现的地方，也是传统 SDLC 转变为持续演进的地方。</p>
<h2 id="sdd">为什么 SDD 现在很重要</h2>
<p>三个趋势使 SDD 不仅可能而且必要：</p>
<p>首先，AI 能力已达到一个阈值，自然语言规范可以可靠地生成工作代码。这不是关于替换开发者——而是通过自动化从规范到实现的机械转换来放大他们的有效性。它可以放大探索和创造力，轻松支持&quot;重新开始&quot;，并支持加法、减法和批判性思维。</p>
<p>其次，软件复杂性继续呈指数级增长。现代系统集成了数十个服务、框架和依赖项。通过手动流程保持所有这些部分与原始意图对齐变得越来越困难。SDD 通过规范驱动生成提供系统对齐。框架可能演变为提供 AI 优先支持，而不是人类优先支持，或围绕可重用组件进行架构。</p>
<p>第三，变化速度加快。需求变化比以往任何时候都更加迅速。转向不再是例外——它是预期的。现代产品开发需要基于用户反馈、市场条件和竞争压力的快速迭代。传统开发将这些变化视为干扰。每次转向都需要手动将变化传播到文档、设计和代码中。结果要么是限制速度的缓慢、仔细的更新，要么是积累技术债务的快速、鲁莽的变化。</p>
<p>SDD 可以支持假设/模拟实验：&quot;如果我们需要重新实现或更改应用程序以促进销售更多 T 恤的商业需求，我们将如何实现和实验？&quot;</p>
<p>SDD 将需求变化从障碍转变为正常工作流程。当规范驱动实现时，转向成为系统重新生成而不是手动重写。在 PRD 中更改核心需求，受影响的实现计划自动更新。修改用户故事，相应的 API 端点重新生成。这不仅关乎初始开发——还关乎通过不可避免的变化保持工程速度。</p>
<h2 id="">核心原则</h2>
<p><strong>规范作为通用语言</strong>：规范成为主要工件。代码成为其在特定语言和框架中的表达。维护软件意味着发展规范。</p>
<p><strong>可执行规范</strong>：规范必须足够精确、完整和明确以生成工作系统。这消除了意图和实现之间的差距。</p>
<p><strong>持续改进</strong>：一致性验证持续进行，而不是作为一次性门控。AI 将规范分析模糊性、矛盾性和差距作为持续过程。</p>
<p><strong>研究驱动上下文</strong>：研究代理在整个规范过程中收集关键上下文，调查技术选项、性能影响和组织约束。</p>
<p><strong>双向反馈</strong>：生产现实告知规范演进。指标、事件和运营学习成为规范改进的输入。</p>
<p><strong>探索分支</strong>：从同一规范生成多种实现方法，以探索不同的优化目标——性能、可维护性、用户体验、成本。</p>
<h2 id="">实现方法</h2>
<p>今天，实践 SDD 需要组装现有工具并在整个过程中保持纪律。该方法可以通过以下方式实践：</p>
<ul>
<li>AI 助手用于迭代规范开发</li>
<li>研究代理用于收集技术上下文</li>
<li>代码生成工具用于将规范转换为实现</li>
<li>适应规范优先工作流程的版本控制系统</li>
<li>通过 AI 分析规范文档进行一致性检查</li>
</ul>
<p>关键是将规范视为真理源，代码作为服务于规范而不是相反方向的生成输出。</p>
<h2 id="sdd">通过命令简化 SDD</h2>
<p>SDD 方法通过三个强大的命令得到显著增强，这些命令自动化了规范 → 规划 → 任务工作流程：</p>
<h3 id="specify"><code>/specify</code> 命令</h3>
<p>此命令将简单的功能描述（用户提示）转换为完整的结构化规范，并具有自动仓库管理：</p>
<ol>
<li><strong>自动功能编号</strong>：扫描现有规范以确定下一个功能编号（例如，001、002、003）</li>
<li><strong>分支创建</strong>：从您的描述生成语义分支名称并自动创建</li>
<li><strong>基于模板的生成</strong>：复制并自定义功能规范模板与您的需求</li>
<li><strong>目录结构</strong>：为所有相关文档创建适当的 <code>specs/[branch-name]/</code> 结构</li>
</ol>
<h3 id="plan"><code>/plan</code> 命令</h3>
<p>一旦功能规范存在，此命令创建全面的实现计划：</p>
<ol>
<li><strong>规范分析</strong>：读取并理解功能需求、用户故事和验收标准</li>
<li><strong>宪法合规</strong>：确保与项目宪法和架构原则对齐</li>
<li><strong>技术转换</strong>：将业务需求转换为技术架构和实现细节</li>
<li><strong>详细文档</strong>：生成数据模型、API 合同和测试场景的支持文档</li>
<li><strong>快速开始验证</strong>：生成捕获关键验证场景的快速开始指南</li>
</ol>
<h3 id="tasks"><code>/tasks</code> 命令</h3>
<p>创建计划后，此命令分析计划和相关设计文档以生成可执行任务列表：</p>
<ol>
<li><strong>输入</strong>：读取 <code>plan.md</code>（必需）以及（如果存在）<code>data-model.md</code>、<code>contracts/</code> 和 <code>research.md</code></li>
<li><strong>任务派生</strong>：将合同、实体和场景转换为特定任务</li>
<li><strong>并行化</strong>：标记独立任务 <code>[P]</code> 并概述安全的并行组</li>
<li><strong>输出</strong>：在功能目录中写入 <code>tasks.md</code>，准备由任务代理执行</li>
</ol>
<h3 id="">示例：构建聊天功能</h3>
<p>以下是这些命令如何改变传统开发工作流程：</p>
<p><strong>传统方法：</strong></p>
<pre><code class="language-text">1. 在文档中编写PRD（2-3小时）
2. 创建设计文档（2-3小时）
3. 手动设置项目结构（30分钟）
4. 编写技术规范（3-4小时）
5. 创建测试计划（2小时）
总计：约12小时的文档工作
</code></pre>
<p><strong>使用命令的 SDD 方法：</strong></p>
<pre><code class="language-bash"># 步骤1：创建功能规范（5分钟）
/specify 具有消息历史和用户状态的实时聊天系统

# 这自动：
# - 创建分支 &quot;003-chat-system&quot;
# - 生成 specs/003-chat-system/spec.md
# - 用结构化需求填充它

# 步骤2：生成实现计划（5分钟）
/plan 用于实时消息的WebSocket，用于历史的PostgreSQL，用于状态的Redis

# 步骤3：生成可执行任务（5分钟）
/tasks

# 这自动创建：
# - specs/003-chat-system/plan.md
# - specs/003-chat-system/research.md（WebSocket库比较）
# - specs/003-chat-system/data-model.md（消息和用户模式）
# - specs/003-chat-system/contracts/（WebSocket事件，REST端点）
# - specs/003-chat-system/quickstart.md（关键验证场景）
# - specs/003-chat-system/tasks.md（从计划派生的任务列表）
</code></pre>
<p>在 15 分钟内，您拥有：</p>
<ul>
<li>具有用户故事和验收标准的完整功能规范</li>
<li>具有技术选择和理由的详细实现计划</li>
<li>准备代码生成的 API 合同和数据模型</li>
<li>用于自动和手动测试的综合测试场景</li>
<li>在功能分支中正确版本化的所有文档</li>
</ul>
<h3 id="">结构化自动化的力量</h3>
<p>这些命令不仅节省时间——它们还强制执行一致性和完整性：</p>
<ol>
<li><strong>无遗忘细节</strong>：模板确保考虑每个方面，从非功能性需求到错误处理</li>
<li><strong>可追溯决策</strong>：每个技术选择都链接回特定需求</li>
<li><strong>活文档</strong>：规范与代码保持同步，因为它们生成它</li>
<li><strong>快速迭代</strong>：更改需求并在几分钟内重新生成计划，而不是几天</li>
</ol>
<p>这些命令通过将规范视为可执行工件而不是静态文档来体现 SDD 原则。它们将规范过程从必要的邪恶转变为开发的驱动力。</p>
<h3 id="llm">模板驱动质量：结构如何约束 LLM 以获得更好的结果</h3>
<p>这些命令的真正力量不仅在于自动化，还在于模板如何引导 LLM 行为朝向更高质量的规范。模板充当复杂的提示，以生产性方式约束 LLM 的输出：</p>
<h4 id="1">1. <strong>防止过早的实现细节</strong></h4>
<p>功能规范模板明确指示：</p>
<pre><code class="language-text">- ✅ 专注于用户需要什么和为什么
- ❌ 避免如何实现（无技术栈、API、代码结构）
</code></pre>
<p>这种约束迫使 LLM 保持适当的抽象级别。当 LLM 可能自然地跳到&quot;使用 React 和 Redux 实现&quot;时，模板保持它专注于&quot;用户需要数据的实时更新&quot;。这种分离确保规范在实现技术变化时保持稳定。</p>
<h4 id="2uncertainty">2. <strong>强制明确的 uncertainty 标记</strong></h4>
<p>两个模板都强制使用 <code>[需要澄清]</code> 标记：</p>
<pre><code class="language-text">从用户提示创建此规范时：
1. **标记所有模糊性**：使用 [需要澄清：具体问题]
2. **不要猜测**：如果提示没有指定某些内容，请标记它
</code></pre>
<p>这防止了 LLM 做出合理但可能错误假设的常见行为。LLM 不能猜测&quot;登录系统&quot;使用电子邮件/密码认证，而必须将其标记为 <code>[需要澄清：未指定认证方法 - 电子邮件/密码、SSO、OAuth？]</code>。</p>
<h4 id="3">3. <strong>通过检查清单进行结构化思考</strong></h4>
<p>模板包含全面的检查清单，充当规范的&quot;单元测试&quot;：</p>
<pre><code class="language-markdown">### 需求完整性

- [ ] 没有 [需要澄清] 标记
- [ ] 需求是可测试和明确的
- [ ] 成功标准是可测量的
</code></pre>
<p>这些检查清单迫使 LLM 系统地自我审查其输出，捕获可能遗漏的差距。这就像给 LLM 一个质量保证框架。</p>
<h4 id="4">4. <strong>通过门控进行宪法合规</strong></h4>
<p>实现计划模板通过阶段门控强制执行架构原则：</p>
<pre><code class="language-markdown">### 阶段 -1：预实现门控

#### 简单性门控（第七条）

- [ ] 使用 ≤3 个项目？
- [ ] 没有未来验证？

#### 反抽象门控（第八条）

- [ ] 直接使用框架？
- [ ] 单一模型表示？
</code></pre>
<p>这些门控通过使 LLM 明确证明任何复杂性来防止过度工程。如果门控失败，LLM 必须在&quot;复杂性跟踪&quot;部分记录原因，为架构决策创建问责制。</p>
<h4 id="5">5. <strong>分层细节管理</strong></h4>
<p>模板强制执行适当的信息架构：</p>
<pre><code class="language-text">**重要**：此实现计划应保持高级和可读。
任何代码示例、详细算法或广泛的技术规范
必须放在适当的 `implementation-details/` 文件中
</code></pre>
<p>这防止了规范成为不可读代码转储的常见问题。LLM 学会维护适当的细节级别，将复杂性提取到单独文件，同时保持主文档可导航。</p>
<h4 id="6">6. <strong>测试优先思考</strong></h4>
<p>实现模板强制执行测试优先开发：</p>
<pre><code class="language-text">### 文件创建顺序
1. 创建带有API规范的 `contracts/`
2. 按顺序创建测试文件：合同 → 集成 → e2e → 单元
3. 创建源文件以使测试通过
</code></pre>
<p>这种排序约束确保 LLM 在实现之前考虑可测试性和合同，导致更强大和可验证的规范。</p>
<h4 id="7">7. <strong>防止投机功能</strong></h4>
<p>模板明确劝阻投机：</p>
<pre><code class="language-text">- [ ] 没有投机或&quot;可能需要&quot;的功能
- [ ] 所有阶段都有明确的前置条件和可交付成果
</code></pre>
<p>这阻止 LLM 添加使实现复杂化的&quot;锦上添花&quot;功能。每个功能都必须追溯到具有明确验收标准的具体用户故事。</p>
<h3 id="">复合效应</h3>
<p>这些约束共同产生：</p>
<ul>
<li><strong>完整</strong>：检查清单确保没有遗漏</li>
<li><strong>明确</strong>：强制澄清标记突出不确定性</li>
<li><strong>可测试</strong>：测试优先思考融入过程</li>
<li><strong>可维护</strong>：适当的抽象级别和信息层次结构</li>
<li><strong>可实现</strong>：具有具体可交付成果的清晰阶段</li>
</ul>
<p>模板将 LLM 从创意作家转变为纪律严明的规范工程师，引导其能力产生一致高质量、可执行的规范，真正驱动开发。</p>
<h2 id="">宪法基础：执行架构纪律</h2>
<p>SDD 的核心是宪法——一套管理规范如何成为代码的不变原则。宪法（<code>memory/constitution.md</code>）充当系统的架构 DNA，确保每个生成的实现保持一致性、简单性和质量。</p>
<h3 id="">开发的九条条款</h3>
<p>宪法定义了塑造开发过程每个方面的九条条款：</p>
<h4 id="">第一条：库优先原则</h4>
<p>每个功能必须作为独立库开始——没有例外。这从一开始就强制模块化设计：</p>
<pre><code class="language-text">Specify中的每个功能都必须作为独立库开始其存在。
任何功能都不得在首先抽象为可重用库组件之前
直接在应用程序代码中实现。
</code></pre>
<p>这一原则确保规范生成模块化、可重用的代码而不是单体应用程序。当 LLM 生成实现计划时，它必须将功能结构化为具有清晰边界和最小依赖的库。</p>
<h4 id="cli">第二条：CLI 接口授权</h4>
<p>每个库必须通过命令行接口暴露其功能：</p>
<pre><code class="language-text">所有CLI接口必须：
- 接受文本作为输入（通过stdin、参数或文件）
- 产生文本作为输出（通过stdout）
- 支持JSON格式进行结构化数据交换
</code></pre>
<p>这强制执行可观察性和可测试性。LLM 不能将功能隐藏在 opaque 类中——一切都必须通过基于文本的接口访问和验证。</p>
<h4 id="">第三条：测试优先命令</h4>
<p>最具变革性的条款——测试之前无代码：</p>
<pre><code class="language-text">这是不可协商的：所有实现必须遵循严格的测试驱动开发。
在以下之前不得编写实现代码：
1. 编写单元测试
2. 测试由用户验证和批准
3. 确认测试失败（红色阶段）
</code></pre>
<p>这完全颠覆了传统的 AI 代码生成。LLM 不是生成代码并希望它工作，而是必须首先生成定义行为的综合测试，获得批准，然后才生成实现。</p>
<h4 id="">第七条和第八条：简单性和反抽象</h4>
<p>这些配对条款对抗过度工程：</p>
<pre><code class="language-text">第7.3节：最小项目结构
- 初始实现最多3个项目
- 额外项目需要文档化理由

第8.1节：框架信任
- 直接使用框架功能而不是包装它们
</code></pre>
<p>当 LLM 可能自然地创建精心设计的抽象时，这些条款迫使它证明每一层复杂性的合理性。实现计划模板的&quot;阶段-1 门控&quot;直接执行这些原则。</p>
<h4 id="">第九条：集成优先测试</h4>
<p>优先考虑真实世界测试而不是隔离的单元测试：</p>
<pre><code class="language-text">测试必须使用真实环境：
- 优先使用真实数据库而不是模拟
- 使用实际服务实例而不是存根
- 实现前必须进行合同测试
</code></pre>
<p>这确保生成的代码在实践中工作，而不仅仅是在理论上。</p>
<h3 id="">通过模板进行宪法执行</h3>
<p>实现计划模板通过具体检查点操作化这些条款：</p>
<pre><code class="language-markdown">### 阶段 -1：预实现门控

#### 简单性门控（第七条）

- [ ] 使用 ≤3 个项目？
- [ ] 没有未来验证？

#### 反抽象门控（第八条）

- [ ] 直接使用框架？
- [ ] 单一模型表示？

#### 集成优先门控（第九条）

- [ ] 定义了合同？
- [ ] 编写了合同测试？
</code></pre>
<p>这些门控充当架构原则的编译时检查。LLM 不能在不通过门控或在&quot;复杂性跟踪&quot;部分记录合理例外的情况下继续。</p>
<h3 id="">不变原则的力量</h3>
<p>宪法的力量在于其不变性。虽然实现细节可以演进，但核心原则保持恒定。这提供：</p>
<ol>
<li><strong>跨时间一致性</strong>：今天生成的代码遵循与明年生成的代码相同的原则</li>
<li><strong>跨 LLM 一致性</strong>：不同的 AI 模型产生架构兼容的代码</li>
<li><strong>架构完整性</strong>：每个功能都强化而不是破坏系统设计</li>
<li><strong>质量保证</strong>：测试优先、库优先和简单性原则确保可维护的代码</li>
</ol>
<h3 id="">宪法演进</h3>
<p>虽然原则是不变的，但它们的应用可以演进：</p>
<pre><code class="language-text">第4.2节：修正过程
对此宪法的修改需要：
- 明确记录变更理由
- 项目维护者审查和批准
- 向后兼容性评估
</code></pre>
<p>这允许方法在保持稳定性的同时学习和改进。宪法显示其自身的演进，带有日期修正，展示如何基于真实世界经验完善原则。</p>
<h3 id="">超越规则：开发哲学</h3>
<p>宪法不仅仅是规则手册——它是塑造 LLM 如何思考代码生成的哲学：</p>
<ul>
<li><strong>可观察性优于不透明性</strong>：一切都必须通过 CLI 接口可检查</li>
<li><strong>简单性优于聪明性</strong>：从简单开始，只有在证明必要时才添加复杂性</li>
<li><strong>集成优于隔离</strong>：在真实环境中测试，而不是人工环境</li>
<li><strong>模块化优于单体</strong>：每个功能都是具有清晰边界的库</li>
</ul>
<p>通过将这些原则嵌入到规范和规划过程中，SDD 确保生成的代码不仅功能强大——而且可维护、可测试和架构健全。宪法将 AI 从代码生成器转变为尊重和强化系统设计原则的架构合作伙伴。</p>
<h2 id="">转变</h2>
<p>这不是关于替换开发者或自动化创造力。这是关于通过自动化机械转换来放大人类能力。这是关于创建一个紧密的反馈循环，其中规范、研究和代码共同演进，每次迭代都带来更深的理解和意图与实现之间更好的对齐。</p>
<p>软件开发需要更好的工具来维护意图和实现之间的对齐。SDD 通过可执行的规范提供实现这种对齐的方法，这些规范生成代码而不是仅仅指导它。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[#游戏推荐 《Friday Night Funkin'》——这个"男友"有点猛！]]></title><description><![CDATA[fnf: 好的创意加上开放的态度，真的可以创造奇迹。]]></description><link>http://xmanyou.com/friday-night-funkin-game-review/</link><guid isPermaLink="false">68c76fd5fc9f4e0641f57ca5</guid><category><![CDATA[游戏推荐]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Mon, 15 Sep 2025 03:19:12 GMT</pubDate><content:encoded><![CDATA[<p></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2025/09/friday-night-funkin-game-review-01.png" class="kg-image"></figure><!--kg-card-end: image--><p>嘿，听说过那个为了追妹子而疯狂打歌的"男友"吗？</p><p>没错，我说的就是《Friday Night Funkin'》（简称FNF，中文名《周五夜放克》）！这可不是什么普通的音乐游戏，而是一个关于"爱情"的疯狂故事。</p><p>想象一下：你是个叫Boyfriend的小伙子，好不容易遇到了心仪的Girlfriend，结果她老爸Daddy Dearest跳出来说："想追我女儿？先过我这关！"于是，一场史诗级的音乐大战就此展开...</p><h2 id="-">玩法？简单到让人怀疑人生！</h2><p></p><p>别被那些复杂的音乐游戏吓到，FNF的玩法简单到令人发指：</p><p>看着屏幕上的箭头（↑↓←→）</p><p>跟着节拍按对应的方向键</p><p>就这么简单！</p><p>但是！千万别小看这个"简单"，当你真正上手后会发现，这游戏简直有毒！一首歌下来，你的手指会不自觉地跟着节拍抖动，嘴里还会不自觉地哼着"beep bop"...</p><h2 id="-fnf-">为什么fnf这游戏这么火？</h2><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2025/09/friday-night-funkin-game-review-03.png" class="kg-image"></figure><!--kg-card-end: image--><h3 id="--1">完全免费，还开源！</h3><p>在这个什么都要钱的年代，FNF居然完全免费！而且代码还开源，这意味着什么？意味着全世界的玩家都在为这个游戏添砖加瓦！</p><h3 id="mod-">Mod多到爆炸！</h3><p>说到Mod，FNF的Mod生态简直是个奇迹：</p><p>VS Whitty：炸弹头，脾气火爆，歌曲难度爆表</p><p>VS Garcello：经典中的经典</p><p>VS Tabi：粉丝们的最爱</p><p>VS Agoti：挑战你的极限</p><p>每个Mod都像是给游戏换了个新皮肤，新角色、新音乐、新剧情...玩不完，根本玩不完！</p><h3 id="--2">系统要求？几乎为零！</h3><p>你的电脑只要能打开浏览器，就能玩FNF！什么显卡、什么内存，统统不需要！这就是开源游戏的魅力所在。</p><p><a href="https://friday-night-funkin.net/zh/game/fnf/">fnf网页版在线玩</a>：</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://xmanyou.com/content/images/2025/09/friday-night-funkin-game-review.png" class="kg-image"><figcaption>fnf在线玩：<a href="https://friday-night-funkin.net/zh/game/fnf/">https://friday-night-funkin.net/zh/game/fnf/</a></figcaption></figure><!--kg-card-end: image--><h3 id="--3">社区文化，绝了！</h3><p>FNF的粉丝社区是我见过最疯狂的：</p><ul><li>有人为了一个Mod熬夜三天</li><li>有人把游戏里的音乐做成remix</li><li>有人甚至用游戏角色做表情包</li><li>还有人在网上分享各种"邪道"玩法</li></ul><h2 id="--4">我的个人体验</h2><p>说实话，刚开始玩的时候我觉得这游戏有点"幼稚"，像素风格、简单的操作...但是当我真正投入进去后，我发现我错了！</p><p>这游戏有种魔力，让你一旦开始就停不下来。特别是当你终于完美通过一首高难度歌曲时，那种成就感...简直比中彩票还爽！</p><p>而且，FNF的Mod社区真的太强大了。每次打开游戏，都有新的内容等着你。昨天还在和Whitty斗歌，今天就要面对全新的挑战者。这种持续的新鲜感，是很多商业游戏都做不到的。</p><h2 id="--5">总结：这不仅仅是个游戏</h2><p>《Friday Night Funkin'》已经超越了游戏的范畴，它更像是一个文化现象。从最初的简单音乐游戏，到现在拥有无数Mod、无数粉丝的庞大生态，FNF证明了：好的创意加上开放的态度，真的可以创造奇迹。</p><p>所以，如果你还没玩过FNF，我强烈建议你试试。相信我，一旦你开始，就再也停不下来了！</p><p>P.S. 记得准备好纸巾，因为你的手指可能会因为按得太用力而疼...别问我怎么知道的！</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2025/09/friday-night-funkin-game-review-02.png" class="kg-image"></figure><!--kg-card-end: image--><h2 id="--6">参考链接</h2><!--kg-card-begin: markdown--><ul>
<li>制作组 funkin crew：<a href="https://funkin.me">https://funkin.me</a></li>
<li>itch 页面: <a href="https://ninja-muffin24.itch.io/funkin">https://ninja-muffin24.itch.io/funkin</a></li>
<li>github：<a href="https://github.com/FunkinCrew/Funkin">https://github.com/FunkinCrew/Funkin</a></li>
<li>粉丝制作的中文站 friday-night-funkin.net：<a href="https://friday-night-funkin.net/zh/">fnf粉丝站-中文</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[AI 实战：搭一个吉卜力风格的文档站]]></title><description><![CDATA[https://dns-over-https.org 是一个由AI辅助搭建的吉卜力风格的关于doh的资源站。本文总结了该项目的搭建经验。]]></description><link>http://xmanyou.com/ghibli-style-web-design-with-cursor-ai-dns-over-https-org/</link><guid isPermaLink="false">67e819c0fc9f4e0641f57c50</guid><category><![CDATA[AI]]></category><category><![CDATA[Cursor]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Sat, 29 Mar 2025 16:25:27 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><img src="http://xmanyou.com/content/images/2025/03/ghibli-style-web-design-dns-over-https-org.png" alt="ghibli-style-web-design-dns-over-https-org"></p>
<p>最近每天花大量时间在用AI编程，能不自己动手的，就绝不多写一行代码。我也逐渐沦为了：<strong>AI监工</strong>。</p>
<p>喏，花了2天，搭了一个，不对，让AI搭了一个 doh，也就是关于 DNS over HTTPS的文档站点。</p>
<p>技术架构：</p>
<ul>
<li><strong>框架</strong>: Astro</li>
<li><strong>样式</strong>: Tailwind CSS + shadcn/ui</li>
<li><strong>内容</strong>: Markdown</li>
<li><strong>国际化</strong>: 支持中文和英文，默认英文</li>
<li><strong>部署</strong>: 静态站点生成 (SSG)</li>
</ul>
<p>第一个版本几乎不到一个小时就弄好了。</p>
<p>然后，为了调亿点点细节，增加国际化功能，又调了一天多。</p>
<p>简单测试完，就上线了：<br>
<a href="https://dns-over-https.org">https://dns-over-https.org</a></p>
<p>闲着无聊，就让豆包点评了一下：</p>
<p><img src="http://xmanyou.com/content/images/2025/03/doubao-talk-about-dns-over-https-org.jpg" alt="doubao-talk-about-dns-over-https-org"></p>
<p>总结起来就是：就这？</p>
<p>这几天不是openai生成吉卜力风格图片大火吗？然后公众号上也有人推了用ai生成吉卜力风格的网页。</p>
<p>于是乎，我想试一下下。</p>
<p>然后，就是这个了：<br>
<img src="http://xmanyou.com/content/images/2025/03/ghibli-style-web-design-dns-over-https-org.png" alt="ghibli-style-web-design-dns-over-https-org"></p>
<p>网页风格设计是这次与ai协作的新尝试，遇到了不少坑，很多文字说不清楚的问题，只好截图让ai自己领会。</p>
<h2 id="">总结</h2>
<p>这次项目吸取了之前的经验，加上项目相对比较简单，所以完成的还算顺利。新增加的经验：</p>
<ul>
<li>提前规划好项目的核心功能，比如是不是要多语言，这种，对于项目的架构影响非常大。</li>
<li>如果不得不改到项目基础架构，可以先做减法，减掉一些不重要的模块，基础搭好以后再</li>
<li>遇到问题，让ai去找官方文档，不要用旧的训练数据死磕，有可能是一直都改不出来。</li>
<li>把经常要跟ai沟通的信息记录下来，可以用cursor的rule，也可以直接自己写文档，然后提问前作为附件。比如这个项目用的：</li>
</ul>
<pre><code class="language-ai-guide.md"># AI 协作文档

chat 使用中文

## 官方文档

遇到问题，先查阅官方文档，避免因为训练数据较旧，导致方案过时，引发问题。

### 国际化

- https://docs.astro.build/en/guides/internationalization/

### UI

- https://docs.astro.build/en/basics/astro-components/
- https://docs.astro.build/en/basics/layouts/

</code></pre>
<h2 id="">感谢</h2>
<p>感谢公众号 AI Interface 提供的思路：<br>
<a href="https://mp.weixin.qq.com/s/">https://mp.weixin.qq.com/s/</a><em>ph9</em>-V31TUclFWvzPPCbQ</p>
<p>以上。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[这款一次性邮箱神器，让你远离垃圾邮件！——推荐 tempmail100.com]]></title><description><![CDATA[如果你不想被垃圾邮件骚扰，也不想为了一个验证码填真实邮箱，推荐你试一下 tempmail100.com。]]></description><link>http://xmanyou.com/introducting-tempmail100-com/</link><guid isPermaLink="false">67e54975fc9f4e0641f57c38</guid><category><![CDATA[杂七杂八]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Thu, 27 Mar 2025 12:52:29 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><img src="https://tempmail100.com/assets/image/tempmail100.com.png" alt="tempmail100.com"></p>
<p>大家有没有遇到过这样的烦恼：为了下载个文件、领取个优惠券，或者注册个账号，网站要求你输入邮箱。结果，填完邮箱后，各种垃圾邮件就像洪水一样涌来，广告、推销、甚至诈骗邮件层出不穷，删都删不完！</p>
<p>我最近发现了一个神仙工具——<a href="https://tempmail100.com"><strong>tempmail100.com</strong></a>，它可以生成<strong>一次性邮箱</strong>，完美解决这个问题！</p>
<hr>
<h2 id="tempmail100com"><strong>为什么推荐 tempmail100.com？</strong></h2>
<h3 id="1">1️⃣ <strong>免注册，直接使用</strong></h3>
<p>打开网站就能随机生成一个临时邮箱，不需要填任何个人信息，想用就用，超级方便！</p>
<h3 id="2">2️⃣ <strong>即开即用，秒收邮件</strong></h3>
<p>很多一次性邮箱平台收邮件会有延迟，而 tempmail100.com 基本是<strong>秒收</strong>，验证码、确认邮件一键搞定！</p>
<h3 id="3">3️⃣ <strong>安全匿名，保护隐私</strong></h3>
<p>不用暴露自己的真实邮箱，避免信息泄露，也不用担心被各种广告邮件轰炸。</p>
<h3 id="4">4️⃣ <strong>免费 &amp; 无限使用</strong></h3>
<p>无需花钱，想用多少次就用多少次，邮箱用完可以直接丢弃，下次再换新的。</p>
<h3 id="5">5️⃣ <strong>支持多邮箱管理</strong></h3>
<p>有时候需要同时收多个验证码？没问题！这个网站可以<strong>同时管理多个临时邮箱</strong>，非常适合测试或者批量注册账号。</p>
<hr>
<h2 id=""><strong>如何使用？</strong></h2>
<p>超级简单！只要 3 步：</p>
<ol>
<li>打开 <a href="https://tempmail100.com">tempmail100.com</a></li>
<li>自动生成一个随机邮箱，复制它去使用</li>
<li>在页面上等待邮件到达，获取验证码或确认信息</li>
</ol>
<p>用完直接关掉网页，邮箱自动失效，不留痕迹！</p>
<hr>
<h2 id=""><strong>总结</strong></h2>
<p>如果你不想被垃圾邮件骚扰，也不想为了一个验证码填真实邮箱，那 <strong>tempmail100.com</strong> 绝对值得一试！无论是临时注册账号，还是下载资源，都能帮你轻松搞定。还在等什么？快去试试吧！💡🚀</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[靠AI解决实际问题：如何隐藏Mac系统桌面屏幕上出现的红色麦克风静音图标?]]></title><description><![CDATA[如果你刚好买了罗技MX键盘，那问题可能是Logitech Options+中的通知引起的。需要在软件的设置中关闭
Mic mute/unmute notification 设置。
]]></description><link>http://xmanyou.com/solved-by-ai-how-to-hide-red-muted-micphone-icon-on-mac-os-screen/</link><guid isPermaLink="false">67dcc008fc9f4e0641f57b99</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Fri, 21 Mar 2025 01:59:13 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">问题背景</h2>
<p>最近更换了一台 Mac Book Pro 2024版，用起来美滋滋。</p>
<p>但是，好景不长，发现桌面上突然出现了一个奇怪的图标，而且是浮在所有窗口的最上方，怎么也关不掉：<br>
<img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-01.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-01"></p>
<p>这是怎么一回事？</p>
<p>我在系统设置里找了一堆跟语音、麦克风、输入法有关系的设置，没有一个有效果！</p>
<p>怎么办？</p>
<h2 id="">解决方法</h2>
<p>我知道，我现在遇到的问题，大部分别人都遇到过，而且大部分都有解决方法。所以，按照我以前的习惯，大概会去谷歌搜索相应的解决方法。</p>
<p>但是，现在不是AI比较流行了嘛，我突发奇想，能不能试试靠AI来解决这个实际问题呢？</p>
<p>于是乎，我打开了最近比较流行的AI搜索工具：perplexity</p>
<h3 id="1macos">步骤1，输入问题：mac最新os系统如何隐藏麦克风图标？</h3>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-02.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-02"></p>
<p>嗯……这些都是我已经试过的方法。</p>
<p>应该是我对问题的描述不够具体清晰，这时，我发现了一个相关问题：<br>
Mac桌面上的麦克风图标是如何出现的。</p>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-0301.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-0301"></p>
<h3 id="2mac">步骤2，搜索相关问题：Mac桌面上的麦克风图标是如何出现的</h3>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-03.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-03"></p>
<p>依旧没有什么用……</p>
<p>试试自己把问题描述的更清楚一些吧。</p>
<h3 id="3">步骤3，描述问题细节：我指的是显示在所有窗口最上层，在屏幕右上角的红色麦克风图标</h3>
<p>看搜索结果，感觉在接近真相了，但是，并没有提供有效的解决方法。答案呼之欲出，但是，又差了那么一点点。</p>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-0401.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-0401"></p>
<p>怎么办呢？</p>
<p>咦，试试上传截图给他参考怎么样呢？</p>
<h3 id="4">步骤4，进一步提供问题细节：上传截图，提问，如何隐藏这个图标</h3>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-05.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-05"></p>
<p>AI 定位到了问题：<br>
屏幕右上角显示的红色麦克风图标通常与 Logitech Options+ 软件有关。该图标表示麦克风处于静音状态，可能是由于使用了Logitech键盘（如MX系列）并意外触发了键盘上的麦克风静音快捷键（例如 F7 或 Fn+F7）。</p>
<p>并提供了3个方法，其中第2个就是解决方法：</p>
<p>关闭Logitech Options+中的通知:</p>
<ul>
<li>打开 Logi Options+ 软件。</li>
<li>进入设置（点击右上角的齿轮图标）。</li>
<li>向下滚动到最后，找到 Mic mute/unmute notification 设置。</li>
<li>将其切换为“关闭”（滑动到左侧），红色麦克风图标将消失.</li>
</ul>
<p>对了，为什么我知道这个比较可能是答案呢？<br>
因为，我刚好也买了新的罗技 Mx Keys 键盘，而红色麦克风图标出现的时候，我女儿正好在玩的新电脑和新键盘……</p>
<h3 id="5">步骤5，解决问题</h3>
<p>打开软件Logitech Options+，关掉通知。<br>
<img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-10.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-10"></p>
<p>整个世界清净了：<br>
<img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-11.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-11"></p>
<p>问题虽然解决了，但是我忍不住想知道，如果用传统的方法，是否也能解决呢？</p>
<h2 id="">对比</h2>
<h3 id="">用谷歌搜索解决红色麦克风图标问题</h3>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-06.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-06"></p>
<p>谷歌先给出了通用的解决方法，并不解决问题。</p>
<p>然而，在搜索结果里，苹果社区里有人提到了问题的关键细节：红色图标</p>
<p>打开后发现，问题描述的非常清晰，就是我遇到的相同问题：<br>
<img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen08.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen08"></p>
<p>然而……和很多社区一样，并没有回复：</p>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen-09.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen-09"></p>
<h3 id="">如果换成百度呢？</h3>
<p>即使是中文提问，百度的搜索结果也是没法和谷歌相比的。</p>
<p>百度已经远远背离里它的初心。</p>
<p><img src="http://xmanyou.com/content/images/2025/03/how-to-hide-red-muted-micphone-icon-on-mac-os-screen07.png" alt="how-to-hide-red-muted-micphone-icon-on-mac-os-screen07"></p>
<h2 id="">参考</h2>
<p>分享一下搜索的全过程，供参考：<br>
<a href="https://www.perplexity.ai/search/maczui-xin-osxi-tong-ru-he-yin-vWkVZLUATgK8SJDiZSZtpw">https://www.perplexity.ai/search/maczui-xin-osxi-tong-ru-he-yin-vWkVZLUATgK8SJDiZSZtpw</a></p>
<h2 id="">经验</h2>
<ul>
<li>不要用百度</li>
<li>不要用CSDN</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[AI] 实验用Cursor开发一个完整的项目：tempcsv.com]]></title><description><![CDATA[让AI从0开始开发一个完整的项目是什么体验？]]></description><link>http://xmanyou.com/develop-an-full-project-with-tempcsv-com/</link><guid isPermaLink="false">67d8d791fc9f4e0641f57ae4</guid><category><![CDATA[AI]]></category><category><![CDATA[Cursor]]></category><category><![CDATA[Cloudflare]]></category><category><![CDATA[Worker]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Tue, 18 Mar 2025 02:46:56 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">起因</h2>
<p>近来，AI 的发展异常迅猛，要想不被AI淘汰，最好的办法就是从现在开始拥抱AI。</p>
<p>我从两年前就开始订阅了github copliot pro，之前已经被copilot的智能提示深深折服。后来有同事推荐其他的编程AI，比如Bito, Cursor，开始我还不太想试。</p>
<p>我内心的想法是，微软 + Github + OpenAI + VSCode + 付费用户，这个组合，基本上算是编程界的最强组合了，还有人可以超越它吗？</p>
<p>直到我真的体验了一下 Cursor，然后我就再也没有打开过 VS Code。</p>
<h2 id="">实验</h2>
<p>Cursor，简单的说，与Copilot不同的是，它是一个完整的自动化编程的AI工具，而Copilot目前（截止2025年3月），还只是一个智能助手。</p>
<p>在使用Cursor的过程中，你的角色更像一个项目的管理者，你兼任项目经理+产品经理+程序员+QA，Cursor 则充当一个勤勤恳恳的执行者，负责功能实现和UI设计。</p>
<p>为了更深入的了解 Cursor 的能力边界，我做了一个大胆的实验：能否让 Cursor 完成所有的代码？</p>
<p>作为一个半桶水产品经理，我脑补了一个需求：在线分享csv文件。</p>
<p>经过几天的努力，我和Cursor完成这么一个产品：tempcsv.com</p>
<p><img src="http://xmanyou.com/content/images/2025/03/temcsv.com-screenshot.png" alt="temcsv.com-screenshot"></p>
<h2 id="">过程</h2>
<p>整个项目是一个从信心满满到烂尾的过程。</p>
<h3 id="">启动</h3>
<p>我和Cursor都信心满满，效率非常高。Cursor甚至还可以直接参考某个网站来设计UI。这让我对完成最后的项目充满了信心，甚至开始构思如何进行推广，获取流量变现。</p>
<h3 id="">挣扎</h3>
<p>我们遇到了一些bug，Cursor很努力地来来回回改了好几个版本，始终无法满意，最后不得不放弃一些需求，退而求其次。目标也从完美降低到了完成即可。</p>
<h3 id="">烂尾</h3>
<p>然而，随着项目需求随意的增减，代码进一步堆积，（是不是很眼熟？），这时候 Cursor 虽然没有任何怨言，但是已经心有余而力不足了。</p>
<p>最后，连打开项目都变得非常卡，而与Cursor的对话，也变得异常困难。</p>
<p>我当机立断，决定终止这个项目。</p>
<p>项目地址：<a href="https://github.com/open4game/tempcsv">https://github.com/open4game/tempcsv</a></p>
<h2 id="">结论</h2>
<ul>
<li>AI 很强大，每个人都要拥抱它。</li>
<li>项目要有规划，不可随心随性。</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[ApiSix 3.x 如何配置将根域名从定向到www子域名]]></title><description><![CDATA[要如何配置redirect插件呢？]]></description><link>http://xmanyou.com/apisix-how-to-redirect-from-root-domain-to-www-subdomain/</link><guid isPermaLink="false">664d8915fc9f4e0641f57ac3</guid><category><![CDATA[Apisix]]></category><dc:creator><![CDATA[影子工作室]]></dc:creator><pubDate>Wed, 22 May 2024 06:03:57 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">问题背景</h2>
<p>想要将根域名永久重定向到www子域名，例如：</p>
<ul>
<li>根域名：xmanyou.com</li>
<li>子域名: www.xmanyou.com</li>
</ul>
<h2 id="">解决方法</h2>
<p>这需要使用到ApiSix的redirect插件，在保留协议和请求路径的基础上，替换掉host。</p>
<p>步骤：</p>
<ol>
<li>从dashboard中，添加新路由</li>
<li>重定向选项中，选择 <strong>自定义</strong></li>
<li>自定义重定向
<ul>
<li>填写 <code>$scheme://www.xmanyou.com$request_uri</code></li>
<li>选择 301(永久重定向）</li>
</ul>
</li>
</ol>
<p><img src="http://xmanyou.com/content/images/2024/05/apisix-how-to-redirect-from-root-domain-to-www-subdomain.jpg" alt="apisix-how-to-redirect-from-root-domain-to-www-subdomain"></p>
<p>完毕。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[探索 Go 语言的 conc 并发库：提升并发编程的新工具]]></title><description><![CDATA[在 Go 语言的并发编程领域，Sourcegraph 公司开发的 conc 并发库为我们带来了新的视角。]]></description><link>http://xmanyou.com/introducing-conc-golang-lib/</link><guid isPermaLink="false">661e6a55fc9f4e0641f57ab0</guid><category><![CDATA[go]]></category><category><![CDATA[conc]]></category><dc:creator><![CDATA[影子工作室]]></dc:creator><pubDate>Tue, 16 Apr 2024 12:10:13 GMT</pubDate><content:encoded><![CDATA[<p>在 Go 语言的并发编程领域，Sourcegraph 公司开发的 conc 并发库为我们带来了新的视角。这个库的目标是提供更好的结构化并发支持，它不仅提供了并发控制的基本工具，还致力于简化低代码平台的开发。让我们通过一些代码示例来深入了解这个库的核心特性，并进一步探讨其优势和应用场景。</p><h2 id="1-waitgroup-panic-">1. WaitGroup 与 Panic 处理</h2><p><code>conc.WaitGroup</code> 扩展了 <code>sync.WaitGroup</code> 的功能，使得开发者能够更容易地管理并发任务，并且它还增加了对 panic 的处理能力。这意味着，即使在并发任务中发生 panic，也能够被捕获并适当地处理，而不会导致整个程序崩溃。以下是一个使用 <code>conc.WaitGroup</code> 的示例：</p><!--kg-card-begin: code--><pre><code class="language-go">package main

import (
    "conc"
    "fmt"
)

func main() {
    wg := conc.NewWaitGroup()
    wg.Go(func() {
        // 模拟并发任务
        fmt.Println("Concurrent task running...")
        // 这里可能会发生 panic
        panic("something went wrong")
    })

    // 等待所有并发任务完成或发生 panic
    err := wg.Wait()
    if err != nil {
        fmt.Println("Recovered from panic:", err)
    }
}
</code></pre><!--kg-card-end: code--><h2 id="2-foreach-map-">2. ForEach 与 Map 操作</h2><p><code>conc</code> 库的 <code>ForEach</code> 和 <code>Map</code> 函数提供了迭代和映射的泛型实现，这使得对集合进行操作变得更加简洁和直观。这种抽象层次的提升减少了模板代码的数量，让开发者能够专注于业务逻辑的实现。以下是一个使用 <code>ForEach</code> 的示例：</p><!--kg-card-begin: code--><pre><code class="language-go">package main

import (
    "conc"
    "fmt"
)

func handle(value int) {
    fmt.Println("Handling value:", value)
}

func main() {
    values := []int{1, 2, 3, 4, 5}
    conc.ForEach(values, handle)
}
</code></pre><!--kg-card-end: code--><h2 id="3-pool-stream">3. Pool 与 Stream</h2><p><code>conc.Pool</code> 提供了一个强大的并发任务执行框架，它允许开发者定义任务并将其提交到池中，同时可以控制并发执行的数量。这种设计不仅提高了资源的利用率，还简化了并发任务的管理。以下是一个使用 <code>conc.Pool</code> 的例子：</p><!--kg-card-begin: code--><pre><code class="language-go">package main

import (
    "conc"
    "fmt"
    "time"
)

func task() {
    fmt.Println("Concurrent task running...")
    time.Sleep(1 * time.Second) // 模拟耗时操作
}

func main() {
    p := conc.NewPool()
    for i := 0; i &lt; 5; i++ {
        p.Go(task)
    }

    // 等待所有任务完成
    results, _ := p.Wait()
    fmt.Println("All tasks completed:", results)
}
</code></pre><!--kg-card-end: code--><h2 id="4-">4. 适用性与局限性</h2><p><code>conc</code> 库的设计哲学是提供足够的灵活性来适应不同的并发需求。虽然它目前主要关注前端页面的低代码开发能力，但其协议设计使得理论上可以扩展到其他类型的开发，如后端 API 和移动应用。这种灵活性意味着 <code>conc</code> 库可以作为一个强大的基础工具，帮助开发者构建各种并发应用程序。</p><h2 id="5-">5. 总结</h2><p><code>conc</code> 库通过提供一套清晰的接口和泛型支持，简化了并发编程的复杂性。它的设计理念是将并发控制与业务逻辑分离，从而使得并发程序更易于编写和维护。尽管它还在发展中，且文档和示例有待完善，但它已经展示出了强大的潜力。对于寻求简化并发编程的开发者来说，<code>conc</code> 库是一个值得尝试的工具。然而，我们也应认识到，并不是所有的场景都需要自定义并发库——在许多情况下，现有的解决方案已经足够好。在选择是否使用 <code>conc</code> 库时，开发者应该权衡其带来的便利性和项目的具体需求。</p><h2 id="6-">6. 参考</h2><ul><li><a href="https://github.com/sourcegraph/conc" rel="noreferrer">https://github.com/sourcegraph/conc</a></li><li><a href="https://u3du.com/introduction-of-conc-a-concurrency-library-in-go/">https://u3du.com/introduction-of-conc-a-concurrency-library-in-go/</a></li></ul>]]></content:encoded></item><item><title><![CDATA[三步用kimi 写总结 by u3du.com]]></title><description><![CDATA[只需要3步，你信吗？]]></description><link>http://xmanyou.com/kimi-tu/</link><guid isPermaLink="false">661b46e3fc9f4e0641f57a94</guid><category><![CDATA[AI]]></category><category><![CDATA[Kimi]]></category><dc:creator><![CDATA[影子工作室]]></dc:creator><pubDate>Sun, 14 Apr 2024 03:02:43 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>原文发表在u3du.com:<br>
《仅三步，使用AI kimi辅助编写每周技术分享》<br>
<a href="https://u3du.com/three-simple-steps-to-using-ai-kimi-for-weekly-tech-sharing/">https://u3du.com/three-simple-steps-to-using-ai-kimi-for-weekly-tech-sharing/</a></p>
<!--kg-card-end: markdown--><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2024/04/three-simple-steps-to-using-ai-kimi-for-weekly-tech-sharing-01.png" class="kg-image"></figure><!--kg-card-end: image--><p></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2024/04/three-simple-steps-to-using-ai-kimi-for-weekly-tech-sharing-02.png" class="kg-image"></figure><!--kg-card-end: image--><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="http://xmanyou.com/content/images/2024/04/three-simple-steps-to-using-ai-kimi-for-weekly-tech-sharing-03.png" class="kg-image"></figure><!--kg-card-end: image-->]]></content:encoded></item><item><title><![CDATA[如何为Docusaurus站点接入AdSense广告SDK]]></title><description><![CDATA[Docusaurus是一个基于React的快速建站工具，与基于Vue的快速建站工具VuePress有很多相似之处。该项目由Facebook团队开发，并开源。本文介绍如何自己编写一个简单的AdSense插件plugin来引入AdSense SDK。]]></description><link>http://xmanyou.com/how-to-add-adsense-for-docusaurus-site/</link><guid isPermaLink="false">64fda574fc9f4e0641f579c0</guid><category><![CDATA[Docusaurus]]></category><category><![CDATA[开发笔记]]></category><dc:creator><![CDATA[影子工作室]]></dc:creator><pubDate>Sun, 10 Sep 2023 11:44:17 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Docusaurus是一个基于React的快速建站工具，与基于Vue的快速建站工具VuePress有很多相似之处。该项目由Facebook团队开发，并开源。</p>
<p><img src="http://xmanyou.com/content/images/2023/09/docusaurus.png" alt="docusaurus"></p>
<p>与VuePress一样，Docusaurus支持通过Markdown格式编写网页，并可以基于文件系统的目录结构生产对应的路由，而且也支持通过插件的方式来扩展功能。</p>
<h2 id="">问题背景</h2>
<p>Docusaurus官方提供了一些常见的插件，包括谷歌统计ga4，或者google tag manager，但是却没有提供AdSense变现SDK的插件。</p>
<p>网站建设好后，想要通过AdSense进行变现，该如何添加呢？</p>
<p>如果不想花大力气去修改主题，最便捷的方法莫过于自己编写一个简单的AdSense插件plugin了。</p>
<h2 id="">解决方法</h2>
<h3 id="myadsenseplugin">第一步，编写My AdSense Plugin</h3>
<p><strong>官方文档</strong></p>
<blockquote>
<p><a href="https://docusaurus.io/docs/advanced/plugins">https://docusaurus.io/docs/advanced/plugins</a></p>
</blockquote>
<p>Docusaurus支持多种创建插件的方法：</p>
<ul>
<li>直接使用匿名函数</li>
<li>使用独立模块</li>
</ul>
<p>为了方便维护，本例使用第二种。</p>
<ul>
<li>
<p>首先，在项目的根目录下创建插件目录，并添加插件的入口文件index.js：<code>my-plugin/index.js</code></p>
</li>
<li>
<p>编写plugin对应的生命周期接口方法<br>
plugin支持的接口，参考文档：</p>
</li>
</ul>
<blockquote>
<p><a href="https://docusaurus.io/docs/api/plugin-methods/lifecycle-apis">https://docusaurus.io/docs/api/plugin-methods/lifecycle-apis</a></p>
</blockquote>
<p>为了引入AdSense SDK需要使用<code>injectHtmlTags</code><br>
示例代码：</p>
<pre><code>module.exports = async function myAdSensePlugin(context, options) {
  // ...
  return {
    name: 'adsense-plugin', // 插件的名称
    injectHtmlTags({content}) {
      // console.info(&quot;===&gt; adsesne-plugin injectHtmlTags&quot;)
      clientID = options.clientID; // 读取配置的AdSense id
      return {
        headTags: [  // 插入到header部分的代码
          {
            tagName: 'script',
            attributes: {
              async: true,
              crossorigin: 'anonymous',
              src: `https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${clientID}`,
            },
          },
        ],
      };
    },    
  };
};
</code></pre>
<h3 id="adsense">第二步，引入插件并设置AdSense变现账号</h3>
<p>为了灵活使用，一般把可变参数作为插件的配置项。上边的代码中，我们用clientID作为AdSense的id，并在代码中引入。</p>
<p>插件代码编写好后，需要在docuraurus.config.js中的plugins项中引入插件:</p>
<pre><code>  plugins: [
    ['./adsense-plugin', // 要引入的插件的目录
    { 
      clientID: '&lt;这里填AdSense id&gt;', // 设置参数
    }],
  ],
</code></pre>
<p>如何引入和配置插件，参考文档：</p>
<h3 id="">第三步，重新编译并发布站点</h3>
<p>一切就绪，重新编译并发布，在网络请求中就可以看到对应的请求了。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[#SuperSet 解决除数为0报错 Error: division by zero]]></title><description><![CDATA[使用NULLIF函数可以解决除数为0的情况。]]></description><link>http://xmanyou.com/superset-resolve-error-division-by-zero/</link><guid isPermaLink="false">6483019dfc9f4e0641f5799c</guid><category><![CDATA[SuperSet]]></category><category><![CDATA[数据分析]]></category><category><![CDATA[mysql]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Fri, 09 Jun 2023 10:47:40 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">问题背景</h2>
<p>用SuperSet进行数据分析时，有时候需要将2列的值相除，此时，如果除数为0，则会报错：</p>
<pre><code>Error: division by zero
</code></pre>
<p>比如想用earnings和page_views计算网页价值:</p>
<pre><code>page_rpm = earnings / page_views
</code></pre>
<p>如果page_views为0，就会报上边提到的错误。</p>
<p>这可怎么办呢？</p>
<h2 id="">解决方法</h2>
<p>这其实不是superset的问题，而是SQL语句的问题。</p>
<p>针对这种情况，可以使用<code>NULLIF</code>这个SQL函数。</p>
<h3 id="nullif">NULLIF 用法</h3>
<p>NULLIF需要传入两个参数，然后比较这两个参数的值，如果相同，则返回NULL。</p>
<p>而除数为NULL是可以正常处理返回NULL。</p>
<p>所以，解决方法：</p>
<pre><code>page_rpm = earnings / NULLIF(page_views, 0)
</code></pre>
<p>以上</p>
<h2 id="">参考</h2>
<ul>
<li><a href="https://stackoverflow.com/questions/10964627/division-by-zero-error-when-trying-to-divide-data">https://stackoverflow.com/questions/10964627/division-by-zero-error-when-trying-to-divide-data</a></li>
<li><a href="https://learnsql.com/cookbook/how-to-handle-divide-by-zero-in-sql/#:~:text=If%20you'd%20like%20to,it%20returns%20the%20first%20argument">https://learnsql.com/cookbook/how-to-handle-divide-by-zero-in-sql/#:~:text=If you'd like to,it returns the first argument</a>.</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[#Ghost 如何正确添加ads.txt避免404错误?]]></title><description><![CDATA[本文介绍如何不配置网关，直接使用ghost建站工具解析静态文件。]]></description><link>http://xmanyou.com/ghost-ru-he-zheng-que-tian-jia-ads-txtbi-mian-404/</link><guid isPermaLink="false">64821e3cfc9f4e0641f57965</guid><category><![CDATA[ghost]]></category><dc:creator><![CDATA[阿斌]]></dc:creator><pubDate>Thu, 08 Jun 2023 18:43:26 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="">问题背景</h2>
<p>ghost是一款开源的建站工具，与历史悠久的wordpress不同，它使用Node.js开发。wordpress经过了这么多年，已经建立了非常完善的生态系统，这是ghost做为后起之秀，相比之下最为薄弱的环节。</p>
<p>ads.txt是网站进行广告变现很重要的工具，它可以用来证明你对网站的所有权，只有添加到该文件中的广告账号才可以在该网站进行变现。</p>
<p>通常ads.txt需要添加到网站的域名根目录，比如<code>https://xmanyou.com/ads.txt</code></p>
<p>那么，问题来了，ghost要如何添加ads.txt呢？</p>
<p>特别的，如果没有正确添加，ghost默认会把<br>
<code>https://xmanyou.com/ads.txt</code><br>
重定向到<br>
<code>https://xmanyou.com/ads.txt/</code><br>
从而出现404错误。</p>
<h2 id="">解决方法</h2>
<h3 id="1nginxadstxt">方法1. 使用nginx等自行解析ads.txt</h3>
<p>如果你使用nginx作为ghost的网关，那么，你可以在nginx里自己添加一条ads.txt的解析。</p>
<p>例如：假设你的ads.txt文件存放在<code>/var/www/html/ads.txt</code>，那么</p>
<pre><code>    location ~ ^/(ads.txt) {
        add_header Content-Type text/plain;
        root /var/www/html;
    }
</code></pre>
<h3 id="2ghostadstxt">方案2. 使用ghost解析ads.txt</h3>
<p>其实，ghost官方也支持静态文件解析，默认的路径是当前主题所在的目录，所以只需要将ads.txt添加到主题包里，然后重新激活就可以了。</p>
<p>具体步骤如下：</p>
<ul>
<li>1). 下载当前所用的主题zip包</li>
<li>2). 解压，并添加ads.txt到解压后的主题目录</li>
<li>3). 重新打包主题zip包</li>
<li>4). 上传添加了ads.txt的主题包</li>
<li>5). 激活该主题</li>
</ul>
<p>这样就完成了。</p>
<p>同样的，利用该方法，还可以让ghost解析别的静态文件，比如app-ads.txt等。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>