<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Lisang</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://loslisang.github.io/</id>
  <link href="https://loslisang.github.io/" rel="alternate"/>
  <link href="https://loslisang.github.io/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Lisang</rights>
  <subtitle>从感性到因果，从因果到辩证，从辩证到系统</subtitle>
  <title>Lisang's Blog</title>
  <updated>2026-11-14T17:51:11.197Z</updated>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Google" scheme="https://loslisang.github.io/tags/Google/"/>
    <category term="订阅" scheme="https://loslisang.github.io/tags/%E8%AE%A2%E9%98%85/"/>
    <category term="学生认证" scheme="https://loslisang.github.io/tags/%E5%AD%A6%E7%94%9F%E8%AE%A4%E8%AF%81/"/>
    <content>
      <![CDATA[<h2 id="主要原理"><a href="#主要原理" class="headerlink" title="主要原理"></a>主要原理</h2><p>通过谷歌的学生认证, 实现部分地区的低价Pro订阅</p><h2 id="主要步骤"><a href="#主要步骤" class="headerlink" title="主要步骤"></a>主要步骤</h2><h3 id="前置内容"><a href="#前置内容" class="headerlink" title="前置内容"></a>前置内容</h3><ol><li>日本地区节点</li><li>Google账号</li><li>非中国大陆发行的Visa卡或万事达卡</li></ol><h3 id="1-准备一个日本地区的代理"><a href="#1-准备一个日本地区的代理" class="headerlink" title="1. 准备一个日本地区的代理"></a>1. 准备一个日本地区的代理</h3><p>这个很重要, 在我开通学生优惠的时候发现进去 <a href="https://one.google.com/ai-student">https://one.google.com/ai-student</a>, 如果计价单位不是日元是不行的. </p><p>如何做呢, 就是不论你是手机端还是网页端, 都使用日本代理, 最好是开全局, 这样比较稳健. </p><p>这边看的主要还是你的支付账单的方式是否是日本地区, 当然别的低价区「例如土耳其区」也是可以的, 但是日本地区的支付不会限制支付方式, 即使你用U卡支付也是可以的, 如果是土区的话就可能难以添加支付方式.</p><h3 id="2-验证学生身份-通常使用sheerid认证"><a href="#2-验证学生身份-通常使用sheerid认证" class="headerlink" title="2. 验证学生身份, 通常使用sheerid认证"></a>2. 验证学生身份, 通常使用sheerid认证</h3><p>通常使用sheerid认证, 这个认证过程需要你提供一些个人信息, 例如你的姓名, 学号等, 这些信息会被用来验证你的身份. 我自己在认证sheerID的时候感觉有点难, 所以就直接在tg上找了一个bot认证了. 大概5元左右.</p><p>如果你已经有Jio订阅的AI One Pro, 打开这个链接 <a href="https://one.google.com/ai-student">https://one.google.com/ai-student</a>, 你会看到一个已经认证好的界面, 需要取消掉原本的Jio吗你可以进入 <a href="https://myaccount.google.com/u/1/deleteservices">https://myaccount.google.com/u/1/deleteservices</a> 取消掉.</p><h3 id="3-准备支付方式"><a href="#3-准备支付方式" class="headerlink" title="3. 准备支付方式"></a>3. 准备支付方式</h3><p>这边通常是在Google Play上添加会比较方便, 谷歌 Play 商店 → 头像 → 设置 → 常规 → 账号和设备偏好设置 → 国家&#x2F;地区和个人资料。然后创建你的支付方式, 选择好支付卡和支付地区.</p><p>如果是网页端的话, 就打开<a href="https://payments.google.com/gp/w/home/settings">https://payments.google.com/gp/w/home/settings</a>添加日本地区的支付方式.</p><p>我自己使用的是虚拟U卡是可以的.</p><h3 id="4-订阅AI-One-Pro"><a href="#4-订阅AI-One-Pro" class="headerlink" title="4. 订阅AI One Pro"></a>4. 订阅AI One Pro</h3><p>这边日本地区就是720日元就可以拿下一个月的AI One Pro, 折合下来大概4.6美刀, 30人民币左右</p><h3 id="5-使用AGY"><a href="#5-使用AGY" class="headerlink" title="5. 使用AGY"></a>5. 使用AGY</h3><p>受限与之前的Jio羊毛风波, 现在Anti-Gravity 「AGY」 的风控变得更加严格了, 尽可能不要将AGY账号拿去反代, 否则就会像我一样喜提4个suspend, 然后去写保证书. </p><p>如果你的账号不能使用AGY, 提示: </p><p><code>error: Eligibility check failed: Your current account is not eligible for Antigravity, because it is not currently available in your location.</code></p><p>那就是你的个人账号地区设置不正确, 你可以在下面的链接检查或者切换你的地区: </p><p><a href="https://policies.google.com/country-association-form">https://policies.google.com/country-association-form</a></p><h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><h3 id="参考教程"><a href="#参考教程" class="headerlink" title="参考教程"></a>参考教程</h3><p><a href="https://x.com/mjjwiki/status/2115449169737548181">手把手教你合规低价订阅Gemini，可以在反重力Antigravity使用Gemini 4 Argon和Claude Opus 5.5 。</a></p><h3 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h3><p><a href="https://policies.google.com/country-association-form">谷歌地区检查</a></p><p><a href="https://docs.google.com/forms/d/e/1FAIpQLScOJWibQ_-hYuVv63kJTgEqlgAaOwRLGFTbXm-QY1gz8U0CGA/viewform">反重力保证书</a></p><p><a href="https://myaccount.google.com/u/1/deleteservices">删除服务</a></p>]]>
    </content>
    <id>https://loslisang.github.io/2026/11/03/%E6%8A%80%E6%9C%AF/google-ai-one-pro-5usd/</id>
    <link href="https://loslisang.github.io/2026/11/03/%E6%8A%80%E6%9C%AF/google-ai-one-pro-5usd/"/>
    <published>2026-11-03T15:59:00.000Z</published>
    <summary>日本节点 + 学生认证，约 720 日元每月订阅 Google AI One Pro</summary>
    <title>5 美元开通 Google AI One Pro</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="SOLID" scheme="https://loslisang.github.io/tags/SOLID/"/>
    <category term="软件工程" scheme="https://loslisang.github.io/tags/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/"/>
    <content>
      <![CDATA[<blockquote><p>在AI日渐强大的2026年，我发现有必要再认真学习一下SOLID这五条原则，因为人基本上不怎么写代码了，所以学会review代码就更重要了，在软件工程中SOLID 这一套经过时间沉淀的规则就有其存在的必要了。</p></blockquote><h2 id="认识一下SOLID"><a href="#认识一下SOLID" class="headerlink" title="认识一下SOLID"></a>认识一下SOLID</h2><h3 id="单一职责原则"><a href="#单一职责原则" class="headerlink" title="单一职责原则"></a>单一职责原则</h3><p>SRP 单一职责原则 (Single Responsibility Principle) 指的是一个类或者模块应该只负责一个功能，而不是多个功能。</p><h3 id="开放封闭原则"><a href="#开放封闭原则" class="headerlink" title="开放封闭原则"></a>开放封闭原则</h3><p>OCP 开放封闭原则 (Open Closed Principle) 指的是一个软件实体（类、模块、函数等）应该对扩展开放，对修改关闭。</p><h3 id="里氏替换原则"><a href="#里氏替换原则" class="headerlink" title="里氏替换原则"></a>里氏替换原则</h3><p>LSP 里氏替换原则 (Liskov Substitution Principle) 指的是子类应该能够替换父类，而不影响程序的正确性。</p><blockquote><p>这个很好理解，基本上只要是在面向对象语言中，子类都应该能够替换父类。</p></blockquote><h3 id="依赖倒置原则"><a href="#依赖倒置原则" class="headerlink" title="依赖倒置原则"></a>依赖倒置原则</h3><p>DIP 依赖倒置原则 (Dependency Inversion Principle) 指的是高层模块不应该依赖于低层模块，两者都应该依赖于抽象。</p><blockquote><p>例如，查询用户接口本身需要依赖于底层的数据库查询接口，而不是直接依赖于数据库</p></blockquote><blockquote><p>此外依赖注入不是依赖倒置, 依赖倒置是一种设计原则, 而依赖注入是一种实现方式。<br>还有IoC, 控制反转, 和依赖倒置也不是一个东西, IoC 体现的是谁负责依赖的注入</p></blockquote><p>他们的关系如下: </p><blockquote><p>DIP 说的是源码依赖指向哪里（静态结构），IoC 说的是谁调用谁、谁掌握控制权（运行时流程）。二者正交，DI 是把它们连起来的施工手段。<br>DIP 只有两条（Martin, 1996）：高层不依赖低层，两者都依赖抽象；抽象不依赖细节，细节依赖抽象。<br>IoC 是更泛的词：回调、事件循环、模板方法、框架生命周期、插件、DI 全算。共同点是「别打给我们，我们会打给你」——main 不再驱动一切，框架反过来调你。</p></blockquote><p>为了区分上述概念</p><ol><li>违反 DIP：字段类型就是具体类</li></ol><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">+------------------------+</span><br><span class="line">|  OrderService          |   high-level policy</span><br><span class="line">+------------------------+</span><br><span class="line">|  - repo : MySqlUserRepo|</span><br><span class="line">+------------------------+</span><br><span class="line">|  + placeOrder() : void |</span><br><span class="line">+------------------------+</span><br><span class="line">             |</span><br><span class="line">             | uses</span><br><span class="line">             v</span><br><span class="line">+------------------------+</span><br><span class="line">|  MySqlUserRepo         |   low-level detail</span><br><span class="line">+------------------------+</span><br><span class="line">|  + find(id) : User     |</span><br><span class="line">|  + save(u : User): void|</span><br><span class="line">+------------------------+</span><br><span class="line">             |</span><br><span class="line">             v</span><br><span class="line">        MySQL driver</span><br></pre></td></tr></table></figure><ol start="2"><li>符合 DIP：接口归高层，实现反向依赖</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">+------------------------+</span><br><span class="line">|  OrderService          |   domain (high-level)</span><br><span class="line">+------------------------+</span><br><span class="line">|  - repo : UserRepo     |</span><br><span class="line">+------------------------+</span><br><span class="line">|  + placeOrder() : void |</span><br><span class="line">+------------------------+</span><br><span class="line">             |</span><br><span class="line">             | uses</span><br><span class="line">             v</span><br><span class="line">+------------------------+</span><br><span class="line">|    &lt;&lt;interface&gt;&gt;       |</span><br><span class="line">|       UserRepo         |   domain (interface owned by high level)</span><br><span class="line">+------------------------+</span><br><span class="line">|  + find(id) : User     |</span><br><span class="line">|  + save(u : User): void|</span><br><span class="line">+------------------------+</span><br><span class="line">             ^</span><br><span class="line">             :</span><br><span class="line">             : implements</span><br><span class="line">             :</span><br><span class="line">+------------------------+</span><br><span class="line">|  MySqlUserRepo         |   infra (low-level)</span><br><span class="line">+------------------------+</span><br></pre></td></tr></table></figure><ol start="3"><li>倒置的是依赖方向，不是调用方向</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">运行时调用流                  编译期依赖流</span><br><span class="line">------------                  ------------</span><br><span class="line">OrderService                  OrderService</span><br><span class="line">     |                             |</span><br><span class="line">     | calls                       | uses</span><br><span class="line">     v                             v</span><br><span class="line">MySqlUserRepo                    UserRepo</span><br><span class="line">                                   ^</span><br><span class="line">                                   |</span><br><span class="line">                                   | implements</span><br><span class="line">                                   |</span><br><span class="line">                              MySqlUserRepo</span><br></pre></td></tr></table></figure><p>同一次协作里两条箭头方向相反，这才是 inversion 的含义。</p><ol start="4"><li>加容器：只填空隙，不改结构</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">+---------------------------------------+</span><br><span class="line">|  Container / main()                   |   composition root</span><br><span class="line">|  bind(UserRepo =&gt; MySqlUserRepo)      |</span><br><span class="line">+---------------------------------------+</span><br><span class="line">         |                     |</span><br><span class="line">  inject |                     | new</span><br><span class="line">         v                     v</span><br><span class="line">+----------------+   +------------------+</span><br><span class="line">|  OrderService  |   |  MySqlUserRepo   |</span><br><span class="line">+----------------+   +------------------+</span><br><span class="line">         |                     |</span><br><span class="line">         | uses                | implements</span><br><span class="line">         +----------+----------+</span><br><span class="line">                    |</span><br><span class="line">                    v</span><br><span class="line">       +-------------------------+</span><br><span class="line">       |      &lt;&lt;interface&gt;&gt;      |</span><br><span class="line">       |        UserRepo         |</span><br><span class="line">       +-------------------------+</span><br></pre></td></tr></table></figure><h3 id="接口隔离原则"><a href="#接口隔离原则" class="headerlink" title="接口隔离原则"></a>接口隔离原则</h3><p>ISP 接口隔离原则 (Interface Segregation Principle) 指的是客户端不应该依赖于它不需要的接口。</p><blockquote><p>处理这种文件的最简单方法就是拆分大接口成为一个个的小接口</p></blockquote>]]>
    </content>
    <id>https://loslisang.github.io/2026/11/02/%E6%8A%80%E6%9C%AF/solid-principles/</id>
    <link href="https://loslisang.github.io/2026/11/02/%E6%8A%80%E6%9C%AF/solid-principles/"/>
    <published>2026-11-01T16:48:35.000Z</published>
    <summary>在 AI 时代重新认识软件工程中的 SOLID 五大设计原则（SRP、OCP、LSP、DIP、ISP）以及 DIP、IoC 与 DI 的区别。</summary>
    <title>软件开发 SOLID 原则</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/LeetCode/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/tags/LeetCode/"/>
    <category term="数组" scheme="https://loslisang.github.io/tags/%E6%95%B0%E7%BB%84/"/>
    <category term="双指针" scheme="https://loslisang.github.io/tags/%E5%8F%8C%E6%8C%87%E9%92%88/"/>
    <content>
      <![CDATA[<h2 id="189-轮转数组"><a href="#189-轮转数组" class="headerlink" title="189. 轮转数组"></a>189. 轮转数组</h2><p><a href="https://leetcode.cn/problems/rotate-array/description/?envType=study-plan-v2&envId=top-100-liked">题目链接</a></p><p>LeetCode 189题 “轮转数组” (Rotate Array) 是一个非常经典的算法题。通常所谓的“数学解法”主要指代两种 $O(1)$ 空间复杂度的解法：</p><ol><li><strong>环状替换 (Cyclic Replacements)</strong>：这是最硬核的数学解法，涉及到数论中的“最大公约数” (GCD)。</li><li><strong>数组翻转 (Array Reversal)</strong>：这是最巧妙的解法，利用了翻转的性质。</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">rotate</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>], k: <span class="built_in">int</span></span>) -&gt; <span class="literal">None</span>:</span><br><span class="line">        <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">        Do not return anything, modify nums in-place instead.</span></span><br><span class="line"><span class="string">        &quot;&quot;&quot;</span></span><br><span class="line">        k = k % <span class="built_in">len</span>(nums)</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">rev</span>(<span class="params">nums: <span class="type">List</span>[<span class="built_in">int</span>], start: <span class="built_in">int</span>, end: <span class="built_in">int</span></span>) -&gt; <span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">while</span> start &lt; end:</span><br><span class="line">                nums[start], nums[end] = nums[end], nums[start]</span><br><span class="line">                start += <span class="number">1</span></span><br><span class="line">                end -= <span class="number">1</span></span><br><span class="line">        rev(nums, <span class="number">0</span>, <span class="built_in">len</span>(nums) - <span class="number">1</span>)</span><br><span class="line">        rev(nums, <span class="number">0</span>, k - <span class="number">1</span>)</span><br><span class="line">        rev(nums, k, <span class="built_in">len</span>(nums) - <span class="number">1</span>)</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://loslisang.github.io/2026/01/04/%E6%8A%80%E6%9C%AF/leetcode/189-rotate-array/</id>
    <link href="https://loslisang.github.io/2026/01/04/%E6%8A%80%E6%9C%AF/leetcode/189-rotate-array/"/>
    <published>2026-01-04T02:00:00.000Z</published>
    <summary>LeetCode 189. 轮转数组 O(1) 空间复杂度解法笔记</summary>
    <title>LeetCode 189. 轮转数组</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Docker" scheme="https://loslisang.github.io/tags/Docker/"/>
    <category term="Dockerfile" scheme="https://loslisang.github.io/tags/Dockerfile/"/>
    <category term="容器化" scheme="https://loslisang.github.io/tags/%E5%AE%B9%E5%99%A8%E5%8C%96/"/>
    <content>
      <![CDATA[<p>Docker 中的 <code>CMD</code> 和 <code>ENTRYPOINT</code> 经常让人迷糊，尤其是同时使用时，更容易出现“命令不按预期执行”“容器秒退”等问题。理解它们的本质差异，是写好 Dockerfile 的关键。</p><h2 id="核心理解：谁是“主角”，谁是“默认参数”"><a href="#核心理解：谁是“主角”，谁是“默认参数”" class="headerlink" title="核心理解：谁是“主角”，谁是“默认参数”"></a>核心理解：谁是“主角”，谁是“默认参数”</h2><p>在 Docker 里，可以简单地这样理解：</p><ul><li><code>ENTRYPOINT</code>：定义“这个镜像本质上是干什么的”，也就是<strong>固定的主命令 &#x2F; 主进程</strong>。</li><li><code>CMD</code>：为这个镜像提供<strong>默认参数</strong>，或者在没有 <code>ENTRYPOINT</code> 时，提供默认要执行的命令。</li></ul><p>当二者<strong>同时存在</strong>时：</p><ul><li>Docker 实际运行的是：<br><code>ENTRYPOINT + CMD</code></li><li>且 <code>CMD</code> <strong>会被当成是</strong> <code>ENTRYPOINT</code> <strong>的参数</strong>，而不是两个独立执行的命令。</li></ul><p>所以：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;top&quot;</span>]</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>, <span class="string">&quot;--help&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>真实执行的是：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">top curl --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><p>而不是先执行 <code>top</code> 再执行 <code>curl --help</code>，这也是许多初学者踩坑的地方。</p><hr><h2 id="三种经典写法与执行效果"><a href="#三种经典写法与执行效果" class="headerlink" title="三种经典写法与执行效果"></a>三种经典写法与执行效果</h2><p>Docker 支持两种语法风格：<strong>shell 形式</strong> 和 <strong>exec 形式</strong>。这里重点看更推荐、更直观的 exec 形式（JSON 数组写法）。</p><h3 id="1-只有-CMD"><a href="#1-只有-CMD" class="headerlink" title="1. 只有 CMD"></a>1. 只有 CMD</h3><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>, <span class="string">&quot;--help&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>执行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image</span><br></pre></td></tr></table></figure><p>实际命令是：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><p>如果你在 <code>docker run</code> 时追加了命令：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image curl https://example.com</span><br></pre></td></tr></table></figure><p>则会完全覆盖 <code>CMD</code>，真实运行的是：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl https://example.com</span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li>没有 <code>ENTRYPOINT</code> 时，<code>CMD</code> 是“默认要执行的命令”，可被运行时参数轻松覆盖。</li></ul><hr><h3 id="2-只有-ENTRYPOINT"><a href="#2-只有-ENTRYPOINT" class="headerlink" title="2. 只有 ENTRYPOINT"></a>2. 只有 ENTRYPOINT</h3><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>执行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><p>真实运行的是：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><p>再看一个例子：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image https://example.com</span><br></pre></td></tr></table></figure><p>真实运行的是：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl https://example.com</span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li><code>ENTRYPOINT</code> 定死了“主角”是 <code>curl</code>，无论你在 <code>docker run</code> 后面写什么，都是给 <code>curl</code> 当参数。</li><li>这种写法适合“就是要把这个镜像当作某个命令的专用工具”的场景，例如 CLI 工具封装。</li></ul><hr><h3 id="3-ENTRYPOINT-CMD-组合"><a href="#3-ENTRYPOINT-CMD-组合" class="headerlink" title="3. ENTRYPOINT + CMD 组合"></a>3. ENTRYPOINT + CMD 组合</h3><p>这是最容易踩坑但也最强大的用法。</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>]</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;--help&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>不加任何额外参数时：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image</span><br></pre></td></tr></table></figure><p>真实运行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><p>如果在运行时追加参数：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-image https://example.com</span><br></pre></td></tr></table></figure><p>真实运行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl https://example.com</span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li><code>CMD</code> 给 <code>ENTRYPOINT</code> 提供<strong>默认参数</strong>，在不传参时生效。</li><li>一旦运行时传入参数，就会<strong>覆盖 CMD</strong>，但不会覆盖 ENTRYPOINT。</li></ul><hr><h2 id="真实踩坑案例：为什么这段-Dockerfile-跑不起来？"><a href="#真实踩坑案例：为什么这段-Dockerfile-跑不起来？" class="headerlink" title="真实踩坑案例：为什么这段 Dockerfile 跑不起来？"></a>真实踩坑案例：为什么这段 Dockerfile 跑不起来？</h2><p>看下面这个例子（与前面提到的情况一致）：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl bash</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [ <span class="string">&quot;top&quot;</span> ]</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>, <span class="string">&quot;--help&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>表面期望：</p><ul><li><code>ENTRYPOINT</code> 跑 <code>top</code>，保持容器持续运行。</li><li><code>CMD</code> 跑 <code>curl --help</code>，在启动时打印帮助。</li></ul><p>实际发生的事：</p><ul><li>Docker 试图执行的命令是：<br><code>top curl --help</code></li><li><code>curl</code> 和 <code>--help</code> 被作为参数传给了 <code>top</code>。</li><li><code>top</code> 不认识 <code>curl</code> 这样的参数，于是报错退出，容器直接结束。</li></ul><p>也就是说：</p><ul><li>你原本以为是“先跑 top，再跑 curl –help”；</li><li>实际上是“用 top 去执行 curl –help 这种不合法的参数组合”。</li></ul><p><strong>根本原因</strong>：<code>CMD</code> 永远不会作为一个“第二条命令”被执行，它只是给 <code>ENTRYPOINT</code>（或默认 shell）提供参数。</p><hr><h2 id="想顺序执行多个命令应该怎么写？"><a href="#想顺序执行多个命令应该怎么写？" class="headerlink" title="想顺序执行多个命令应该怎么写？"></a>想顺序执行多个命令应该怎么写？</h2><p>如果希望：</p><ul><li>容器启动时执行一次 <code>curl --help</code>；</li><li>然后再启动一个“持续运行”的程序（例如 <code>top</code>），让容器不退出；</li></ul><p>有两种常见写法。</p><h3 id="方案-A：用脚本做真正的入口（推荐）"><a href="#方案-A：用脚本做真正的入口（推荐）" class="headerlink" title="方案 A：用脚本做真正的入口（推荐）"></a>方案 A：用脚本做真正的入口（推荐）</h3><p><code>entrypoint.sh</code>：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="built_in">set</span> -e</span><br><span class="line"></span><br><span class="line"><span class="comment"># 1. 执行一次性命令</span></span><br><span class="line">curl --<span class="built_in">help</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 启动一个长期运行的前台进程</span></span><br><span class="line">top</span><br></pre></td></tr></table></figure><p>Dockerfile：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl bash</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> entrypoint.sh /entrypoint.sh</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">chmod</span> +x /entrypoint.sh</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;/bin/bash&quot;</span>, <span class="string">&quot;/entrypoint.sh&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>特点：</p><ul><li>脚本的最后一个前台进程（这里是 <code>top</code>）会成为容器的 PID 1。</li><li>可以在脚本里写完整的业务逻辑、异常处理、日志输出等。</li></ul><hr><h3 id="方案-B：使用-sh-c-串联命令（方便测试）"><a href="#方案-B：使用-sh-c-串联命令（方便测试）" class="headerlink" title="方案 B：使用 sh -c 串联命令（方便测试）"></a>方案 B：使用 <code>sh -c</code> 串联命令（方便测试）</h3><p>如果只是做本地实验，图省事，可以直接在 <code>CMD</code> 里写一行 shell：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">FROM alpine:latest</span><br><span class="line"></span><br><span class="line">RUN apk --no-cache add curl bash</span><br><span class="line"></span><br><span class="line">CMD [<span class="string">&quot;sh&quot;</span>, <span class="string">&quot;-c&quot;</span>, <span class="string">&quot;curl --help &amp;&amp; top&quot;</span>]</span><br></pre></td></tr></table></figure><p>这里没有 <code>ENTRYPOINT</code>，容器启动时会执行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sh -c <span class="string">&quot;curl --help &amp;&amp; top&quot;</span></span><br></pre></td></tr></table></figure><p>执行顺序：</p><ol><li>先执行 <code>curl --help</code>，退出码为 0。</li><li>再执行 <code>top</code>，<code>top</code> 在前台运行，容器保持存活。</li></ol><p>缺点：</p><ul><li>复杂逻辑都堆在一行 shell 字符串里，可读性差。</li><li>不利于后期维护，生产环境更推荐脚本方式。</li></ul><hr><h2 id="常见使用场景与选择建议"><a href="#常见使用场景与选择建议" class="headerlink" title="常见使用场景与选择建议"></a>常见使用场景与选择建议</h2><h3 id="1-应用服务镜像（Web-后端服务）"><a href="#1-应用服务镜像（Web-后端服务）" class="headerlink" title="1. 应用服务镜像（Web&#x2F;后端服务）"></a>1. 应用服务镜像（Web&#x2F;后端服务）</h3><p>典型 Dockerfile：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> python:<span class="number">3.12</span>-slim</span><br><span class="line"></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /app</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> . /app</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> pip install -r requirements.txt</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;gunicorn&quot;</span>, <span class="string">&quot;-c&quot;</span>, <span class="string">&quot;gunicorn.conf.py&quot;</span>, <span class="string">&quot;app:app&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>建议：</p><ul><li>大多数 Web 服务只用 <code>CMD</code> 就够了。</li><li>如非必要，不要使用 <code>ENTRYPOINT</code>，保持灵活（方便在调试时覆盖为 <code>/bin/bash</code>）。</li></ul><hr><h3 id="2-CLI-工具型镜像"><a href="#2-CLI-工具型镜像" class="headerlink" title="2. CLI &#x2F; 工具型镜像"></a>2. CLI &#x2F; 工具型镜像</h3><p>典型 Dockerfile：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apk --no-cache add curl</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;curl&quot;</span>]</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;--help&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>特征：</p><ul><li>这个镜像“就是一个 curl 工具箱”。</li><li>直接 <code>docker run</code> 相当于执行 <code>curl --help</code>。</li><li>传参时可以很自然：</li></ul><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --<span class="built_in">rm</span> my-curl https://example.com</span><br></pre></td></tr></table></figure><hr><h3 id="3-多进程-复杂启动逻辑"><a href="#3-多进程-复杂启动逻辑" class="headerlink" title="3. 多进程 &#x2F; 复杂启动逻辑"></a>3. 多进程 &#x2F; 复杂启动逻辑</h3><p>典型需求：</p><ul><li>启动前做一些准备工作；</li><li>启动一个或多个长期服务；</li><li>监听信号，优雅退出。</li></ul><p>推荐：</p><ul><li>用脚本做 <code>ENTRYPOINT</code>，在里面管理所有流程。</li><li>或使用进程管理器（如 <code>tini</code>、<code>supervisord</code>），但这已经超出“简单 Dockerfile”的范畴。</li></ul><hr><h2 id="总结：如何简单记住它们？"><a href="#总结：如何简单记住它们？" class="headerlink" title="总结：如何简单记住它们？"></a>总结：如何简单记住它们？</h2><p>可以用一句话概括：</p><blockquote><p><code>ENTRYPOINT</code> 决定“这个镜像是谁”，<code>CMD</code> 决定“它默认怎么干活”。</p></blockquote><ul><li>只需要<strong>一个默认命令</strong>：用 <code>CMD</code>。</li><li>需要一个<strong>固定不变的主命令</strong>：用 <code>ENTRYPOINT</code>。</li><li>既要固定主命令，又要可配置默认参数：同时用 <code>ENTRYPOINT + CMD</code>，记住 CMD 是参数，不是另一条命令。</li><li>需要顺序执行多条命令：用脚本或 <code>sh -c</code>，不要指望多个 CMD&#x2F;ENTRYPOINT 帮你“自动依次执行”。</li></ul>]]>
    </content>
    <id>https://loslisang.github.io/2025/12/18/%E6%8A%80%E6%9C%AF/docker-cmd-vs-entrypoint/</id>
    <link href="https://loslisang.github.io/2025/12/18/%E6%8A%80%E6%9C%AF/docker-cmd-vs-entrypoint/"/>
    <published>2025-12-18T08:19:05.000Z</published>
    <summary>本文深入解析 Docker 中 CMD 和 ENTRYPOINT 的区别与联系，帮助读者理解它们的使用场景及最佳实践，避免常见的坑。</summary>
    <title>Docker 中 CMD 和 Entrypoint 的区别</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="API" scheme="https://loslisang.github.io/tags/API/"/>
    <category term="压测" scheme="https://loslisang.github.io/tags/%E5%8E%8B%E6%B5%8B/"/>
    <category term="wrk" scheme="https://loslisang.github.io/tags/wrk/"/>
    <content>
      <![CDATA[<p><a href="https://medium.com/@pankajgupta221b/performance-testing-with-apachebench-e2cef6882285">Performance Testing with Apache Bench | by Pankaj Gupta | Medium</a></p><p><a href="https://www.code-intelligence.com/blog/methods-for-api-testing-in-java">Top 9 Methods for API Testing in Java | Comprehensive Guide</a></p><p><a href="https://httpd.apache.org/docs/2.4/programs/ab.html">ab - Apache HTTP server benchmarking tool - Apache HTTP Server Version 2.4</a></p><p><a href="https://www.cnblogs.com/quanxiaoha/p/10661650.html">性能测试工具 wrk 使用教程 - 犬小哈 - 博客园</a></p><p><code>wrk</code> 是一款<strong>现代、轻量级且极高性能的 HTTP 基准测试工具</strong>（Benchmark Tool）。它最显著的特点是利用了异步事件驱动架构（如 Linux 的 epoll 或 macOS 的 kqueue），能用极少的线程在单机上产生巨大的并发压力。</p><p>简单来说，它是后端开发者用来<strong>压测接口 QPS (每秒查询率) 和 Latency (延迟)</strong> 的神器。</p><h2 id="为什么用-wrk-而不是-Apache-Bench-ab-或-JMeter？"><a href="#为什么用-wrk-而不是-Apache-Bench-ab-或-JMeter？" class="headerlink" title="为什么用 wrk 而不是 Apache Bench (ab) 或 JMeter？"></a>为什么用 wrk 而不是 Apache Bench (ab) 或 JMeter？</h2><ol><li><strong>性能更强</strong>：<code>wrk</code> 使用非阻塞 I&#x2F;O，能比 <code>ab</code> 产生更高的并发，更能榨干服务器性能。</li><li><strong>支持 Lua 脚本</strong>：这是 <code>wrk</code> 的杀手锏。你可以编写 Lua 脚本来构造复杂的请求（如生成动态 Token、随机参数、POST 复杂 JSON 等），而 <code>ab</code> 只能发静态请求。</li><li><strong>轻量</strong>：没有 JMeter 那么重的 GUI，纯命令行，适合服务器端直接跑。</li></ol><h2 id="常用命令示例"><a href="#常用命令示例" class="headerlink" title="常用命令示例"></a>常用命令示例</h2><p>最简单的压测命令：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wrk -t12 -c400 -d30s http://localhost:8080/api/v1/user</span><br></pre></td></tr></table></figure><ul><li><code>-t12</code>: 使用 12 个线程（一般设置为 CPU 核心数）。</li><li><code>-c400</code>: 保持 400 个 HTTP 连接（并发数）。</li><li><code>-d30s</code>: 持续压测 30 秒。</li><li><code>--latency</code>: (可选) 输出详细的延迟分布报告（P50, P90, P99）。</li></ul><h2 id="配合-Lua-脚本（进阶）"><a href="#配合-Lua-脚本（进阶）" class="headerlink" title="配合 Lua 脚本（进阶）"></a>配合 Lua 脚本（进阶）</h2><p>比如你要压测一个<strong>POST 接口</strong>，且需要<strong>JSON Body</strong>，可以写一个 <code>post.lua</code>：</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- post.lua</span></span><br><span class="line">wrk.method = <span class="string">&quot;POST&quot;</span></span><br><span class="line">wrk.body   = <span class="string">&#x27;&#123;&quot;billCheckId&quot;: 123, &quot;type&quot;: &quot;NC&quot;&#125;&#x27;</span></span><br><span class="line">wrk.headers[<span class="string">&quot;Content-Type&quot;</span>] = <span class="string">&quot;application/json&quot;</span></span><br></pre></td></tr></table></figure><p><code>wrk</code> 的强大之处就在于它嵌入了 LuaJIT 解释器。这意味着你可以完全控制 HTTP 请求的生成逻辑，包括<strong>随机化参数、动态生成 Body、随机 Header、甚至根据响应调整请求</strong>。</p><p>以下是几个实用的 Lua 脚本模板，专门解决“随机分布请求”的问题。</p><h3 id="1-基础随机：随机请求不同的-URL-路径"><a href="#1-基础随机：随机请求不同的-URL-路径" class="headerlink" title="1. 基础随机：随机请求不同的 URL 路径"></a>1. 基础随机：随机请求不同的 URL 路径</h3><p>比如你想压测 <code>/user/1001</code> 到 <code>/user/9999</code> 这样随机的用户详情页，防止服务器缓存热点。</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 在压测开始前初始化随机种子</span></span><br><span class="line"><span class="comment">-- 注意：每个线程都有独立的 Lua 虚拟机，所以每个线程都需要初始化一次</span></span><br><span class="line"><span class="built_in">math</span>.<span class="built_in">randomseed</span>(<span class="built_in">os</span>.<span class="built_in">time</span>())</span><br><span class="line"></span><br><span class="line">request = <span class="function"><span class="keyword">function</span><span class="params">()</span></span></span><br><span class="line">   <span class="comment">-- 生成 1 到 10000 之间的随机用户ID</span></span><br><span class="line">   <span class="keyword">local</span> user_id = <span class="built_in">math</span>.<span class="built_in">random</span>(<span class="number">1</span>, <span class="number">10000</span>)</span><br><span class="line">   <span class="comment">-- 拼接路径</span></span><br><span class="line">   <span class="keyword">local</span> <span class="built_in">path</span> = <span class="string">&quot;/user/&quot;</span> .. user_id</span><br><span class="line">   </span><br><span class="line">   <span class="comment">-- 返回定制的请求</span></span><br><span class="line">   <span class="comment">-- wrk.format(method, path, headers, body)</span></span><br><span class="line">   <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;GET&quot;</span>, <span class="built_in">path</span>)</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h3 id="2-权重随机：按比例访问不同接口"><a href="#2-权重随机：按比例访问不同接口" class="headerlink" title="2. 权重随机：按比例访问不同接口"></a>2. 权重随机：按比例访问不同接口</h3><p>真实场景通常是混合的：80% 读请求，20% 写请求。</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">math</span>.<span class="built_in">randomseed</span>(<span class="built_in">os</span>.<span class="built_in">time</span>())</span><br><span class="line"></span><br><span class="line"><span class="keyword">local</span> paths = &#123;</span><br><span class="line">   <span class="string">&quot;/products/list&quot;</span>,    <span class="comment">-- 读列表</span></span><br><span class="line">   <span class="string">&quot;/products/detail&quot;</span>,  <span class="comment">-- 读详情</span></span><br><span class="line">   <span class="string">&quot;/cart/add&quot;</span>          <span class="comment">-- 写操作（加购）</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">request = <span class="function"><span class="keyword">function</span><span class="params">()</span></span></span><br><span class="line">   <span class="keyword">local</span> r = <span class="built_in">math</span>.<span class="built_in">random</span>(<span class="number">1</span>, <span class="number">100</span>)</span><br><span class="line">   </span><br><span class="line">   <span class="keyword">if</span> r &lt;= <span class="number">60</span> <span class="keyword">then</span></span><br><span class="line">      <span class="comment">-- 60% 概率访问列表</span></span><br><span class="line">      <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;GET&quot;</span>, paths[<span class="number">1</span>])</span><br><span class="line">   <span class="keyword">elseif</span> r &lt;= <span class="number">90</span> <span class="keyword">then</span></span><br><span class="line">      <span class="comment">-- 30% 概率访问详情 (60-90)</span></span><br><span class="line">      <span class="keyword">local</span> pid = <span class="built_in">math</span>.<span class="built_in">random</span>(<span class="number">100</span>, <span class="number">500</span>)</span><br><span class="line">      <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;GET&quot;</span>, paths[<span class="number">2</span>] .. <span class="string">&quot;/&quot;</span> .. pid)</span><br><span class="line">   <span class="keyword">else</span></span><br><span class="line">      <span class="comment">-- 10% 概率添加购物车 (90-100)</span></span><br><span class="line">      <span class="keyword">local</span> body = <span class="string">&#x27;&#123;&quot;productId&quot;: &#x27;</span> .. <span class="built_in">math</span>.<span class="built_in">random</span>(<span class="number">100</span>, <span class="number">500</span>) .. <span class="string">&#x27;&#125;&#x27;</span></span><br><span class="line">      wrk.headers[<span class="string">&quot;Content-Type&quot;</span>] = <span class="string">&quot;application/json&quot;</span></span><br><span class="line">      <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;POST&quot;</span>, paths[<span class="number">3</span>], <span class="literal">nil</span>, body)</span><br><span class="line">   <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h3 id="3-POST-请求：随机-Body-内容"><a href="#3-POST-请求：随机-Body-内容" class="headerlink" title="3. POST 请求：随机 Body 内容"></a>3. POST 请求：随机 Body 内容</h3><p>压测“创建订单”或“短链接生成”接口时，每次 Body 必须不同，否则会被数据库唯一索引拦住。</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">math</span>.<span class="built_in">randomseed</span>(<span class="built_in">os</span>.<span class="built_in">time</span>())</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 辅助函数：生成随机字符串</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">random_str</span><span class="params">(length)</span></span></span><br><span class="line">   <span class="keyword">local</span> chars = <span class="string">&quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&quot;</span></span><br><span class="line">   <span class="keyword">local</span> res = <span class="string">&quot;&quot;</span></span><br><span class="line">   <span class="keyword">for</span> i = <span class="number">1</span>, length <span class="keyword">do</span></span><br><span class="line">      <span class="keyword">local</span> rand = <span class="built_in">math</span>.<span class="built_in">random</span>(#chars)</span><br><span class="line">      res = res .. <span class="built_in">string</span>.<span class="built_in">sub</span>(chars, rand, rand)</span><br><span class="line">   <span class="keyword">end</span></span><br><span class="line">   <span class="keyword">return</span> res</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">request = <span class="function"><span class="keyword">function</span><span class="params">()</span></span></span><br><span class="line">   <span class="comment">-- 动态生成 Body JSON</span></span><br><span class="line">   <span class="keyword">local</span> random_url = <span class="string">&quot;http://example.com/&quot;</span> .. random_str(<span class="number">8</span>)</span><br><span class="line">   <span class="keyword">local</span> body = <span class="string">&#x27;&#123;&quot;originalUrl&quot;: &quot;&#x27;</span> .. random_url .. <span class="string">&#x27;&quot;&#125;&#x27;</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">-- 设置 Header</span></span><br><span class="line">   wrk.headers[<span class="string">&quot;Content-Type&quot;</span>] = <span class="string">&quot;application/json&quot;</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">-- 发送 POST</span></span><br><span class="line">   <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;/create&quot;</span>, <span class="literal">nil</span>, body)</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h3 id="4-高级技巧：每个线程独立的“用户身份”-Token"><a href="#4-高级技巧：每个线程独立的“用户身份”-Token" class="headerlink" title="4. 高级技巧：每个线程独立的“用户身份” (Token)"></a>4. 高级技巧：每个线程独立的“用户身份” (Token)</h3><p>如果你要压测需要登录的接口，可以给每个线程分配不同的 Token。</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 每个线程启动时调用一次 setup</span></span><br><span class="line"><span class="comment">-- thread: 代表当前线程对象</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">setup</span><span class="params">(thread)</span></span></span><br><span class="line">   <span class="comment">-- 给每个线程分配一个唯一的 ID (1, 2, 3...)</span></span><br><span class="line">   thread:set(<span class="string">&quot;id&quot;</span>, <span class="built_in">_G</span>.thread_id_counter)</span><br><span class="line">   <span class="built_in">_G</span>.thread_id_counter = (<span class="built_in">_G</span>.thread_id_counter <span class="keyword">or</span> <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 线程初始化时运行</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">init</span><span class="params">(args)</span></span></span><br><span class="line">   <span class="comment">-- 根据线程 ID 生成伪造 Token</span></span><br><span class="line">   <span class="comment">-- 比如线程1用 user1_token，线程2用 user2_token</span></span><br><span class="line">   <span class="keyword">local</span> token = <span class="string">&quot;Bearer user_&quot;</span> .. id .. <span class="string">&quot;_token_secret&quot;</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">-- 设置全局默认 Header，该线程后续所有请求都会带上这个</span></span><br><span class="line">   wrk.headers[<span class="string">&quot;Authorization&quot;</span>] = token</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">request = <span class="function"><span class="keyword">function</span><span class="params">()</span></span></span><br><span class="line">   <span class="keyword">return</span> wrk.<span class="built_in">format</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/profile&quot;</span>)</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><ol><li><strong>随机 URL</strong>：在 <code>request()</code> 函数里拼装 <code>path</code>。</li><li><strong>随机 Body</strong>：在 <code>request()</code> 里拼装 JSON 字符串。</li><li><strong>按比例混合</strong>：用 <code>math.random(1, 100)</code> 做 if-else 分流。</li><li><strong>运行方式</strong>：一定要带上 <code>--script</code> 参数。</li></ol><h2 id="如何查看CPU核心数"><a href="#如何查看CPU核心数" class="headerlink" title="如何查看CPU核心数"></a>如何查看CPU核心数</h2><p><code>lscpu</code></p><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/20251209000431.png" alt="20251209000431.png"></p><p>可以看出一共有16个核心，每个核心可以当两个线程使用（Intel 的超线程技术）</p><blockquote><p>1. 为什么“1个核”能变“2个核”？</p><ul><li><strong>物理层面</strong>：你的 CPU 确实只有 <strong>16</strong> 个完整的物理核心（Physical Cores），也就是有 16 套独立的 ALU（运算单元）和缓存。</li><li><strong>逻辑层面</strong>：但是，物理核心内部的执行资源（如寄存器、指令队列）往往有富余。SMT 技术允许操作系统把 <strong>1 个物理核心</strong> 识别为 <strong>2 个逻辑核心</strong>。</li></ul></blockquote>]]>
    </content>
    <id>https://loslisang.github.io/2025/12/09/%E6%8A%80%E6%9C%AF/wrk-api-benchmark/</id>
    <link href="https://loslisang.github.io/2025/12/09/%E6%8A%80%E6%9C%AF/wrk-api-benchmark/"/>
    <published>2025-12-08T16:06:05.000Z</published>
    <summary>本文介绍如何使用高性能的 HTTP 压测工具 wrk，对 API 接口进行压力测试，包括基本用法和进阶的 Lua 脚本编写技巧。</summary>
    <title>如何压测 API 接口？—— 使用 wrk 工具进行高性能压测</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="WebDAV" scheme="https://loslisang.github.io/tags/WebDAV/"/>
    <category term="云盘" scheme="https://loslisang.github.io/tags/%E4%BA%91%E7%9B%98/"/>
    <category term="PikPak" scheme="https://loslisang.github.io/tags/PikPak/"/>
    <content>
      <![CDATA[<p>WebDAV（Web Distributed Authoring and Versioning）是一个非常经典且实用的协议。</p><p>简单一句话总结：<strong>它把远程的云端存储，通过 HTTP 协议，“映射”成你电脑上的一个本地硬盘。</strong></p><p>不用下载文件就能直接修改、播放视频，就像操作你 D 盘里的文件一样。</p><h2 id="1-WebDAV-是什么原理？"><a href="#1-WebDAV-是什么原理？" class="headerlink" title="1. WebDAV 是什么原理？"></a>1. WebDAV 是什么原理？</h2><p>WebDAV 是 <strong>HTTP 协议的扩展</strong>。</p><ul><li><strong>基础 HTTP</strong>：通常只支持 <code>GET</code>（获取网页&#x2F;文件）和 <code>POST</code>（提交数据）。</li><li><strong>WebDAV 的魔法</strong>：它给 HTTP 增加了几个新动词（Method）：<ul><li><code>PROPFIND</code>：查询文件属性（比如文件名、大小、目录结构）。</li><li><code>MKCOL</code>：创建文件夹。</li><li><code>COPY</code> &#x2F; <code>MOVE</code>：复制或移动文件。</li><li><code>LOCK</code> &#x2F; <code>UNLOCK</code>：文件加锁&#x2F;解锁（防止两个人同时改一个文件冲突）。</li></ul></li></ul><p><strong>工作流程：</strong></p><ol><li>你的操作系统（客户端）发起一个 HTTP 请求：“给我看看目录里有啥”。</li><li>WebDAV 服务器返回一段 XML 格式的数据，描述文件列表。</li><li>操作系统把这段 XML 渲染成你熟悉的“文件夹图标”。</li><li>当你双击打开文件时，系统按需下载；当你保存时，系统直接上传覆盖。</li></ol><hr><h2 id="2-在-Windows-上怎么用？"><a href="#2-在-Windows-上怎么用？" class="headerlink" title="2. 在 Windows 上怎么用？"></a>2. 在 Windows 上怎么用？</h2><p>Windows 对 WebDAV 的支持分为“原生”和“第三方工具”两种。</p><h3 id="方法-A：使用第三方工具-RaiDrive（强烈推荐）"><a href="#方法-A：使用第三方工具-RaiDrive（强烈推荐）" class="headerlink" title="方法 A：使用第三方工具 RaiDrive（强烈推荐）"></a>方法 A：使用第三方工具 <strong>RaiDrive</strong>（强烈推荐）</h3><p>Windows 自带的 WebDAV 客户端非常难用（速度慢、经常断连、有文件大小限制）。<strong>RaiDrive</strong> 是目前 Windows 上体验最好的挂载工具。</p><ol><li>下载并安装 <a href="https://www.raidrive.com/"><strong>RaiDrive</strong></a>。</li><li>点击右上角 <code>Add</code>。</li><li>选择 <code>NAS</code> -&gt; <code>WebDAV</code>。</li><li>填写地址（Address）、路径（Path）、账户（Account）和密码。</li><li>点击连接，你的“我的电脑”里就会多出一个网络磁盘（例如 Z: 盘），用起来和本地硬盘没区别。</li></ol><h3 id="方法-B：原生“映射网络驱动器”（不推荐，但可以用）"><a href="#方法-B：原生“映射网络驱动器”（不推荐，但可以用）" class="headerlink" title="方法 B：原生“映射网络驱动器”（不推荐，但可以用）"></a>方法 B：原生“映射网络驱动器”（不推荐，但可以用）</h3><ol><li>打开“文件资源管理器” -&gt; “此电脑”。</li><li>顶部工具栏点击“映射网络驱动器”。</li><li>在“文件夹”一栏输入 WebDAV 地址（例如 <code>http://192.168.1.100:5005/webdav</code>）。</li><li>输入用户名密码。<ul><li><em>坑点：Windows 原生限制单文件不能超过 50MB（需改注册表），且 HTTPS 证书不信任时会报错。</em></li></ul></li></ol><hr><h2 id="3-在-Linux-上怎么用？"><a href="#3-在-Linux-上怎么用？" class="headerlink" title="3. 在 Linux 上怎么用？"></a>3. 在 Linux 上怎么用？</h2><p>Linux 既有适合桌面的图形化方式，也有适合服务器的命令行方式。</p><h3 id="方法-A：图形界面（GNOME-KDE）"><a href="#方法-A：图形界面（GNOME-KDE）" class="headerlink" title="方法 A：图形界面（GNOME&#x2F;KDE）"></a>方法 A：图形界面（GNOME&#x2F;KDE）</h3><p>如果你用的是 Ubuntu Desktop (GNOME) 或其他桌面版：</p><ol><li>打开文件管理器（Nautilus）。</li><li>在左侧栏找到 “+ Other Locations” (其他位置)。</li><li>在底部的 “Connect to Server” 输入框填写地址：<ul><li>普通 HTTP：<code>dav://你的地址:端口/路径</code></li><li>加密 HTTPS：<code>davs://你的地址:端口/路径</code></li><li><em>(注意：这里用 dav:&#x2F;&#x2F; 代替 http:&#x2F;&#x2F;)</em></li></ul></li><li>输入密码，它就会挂载在侧边栏。</li></ol><h3 id="方法-B：命令行挂载-mount-davfs"><a href="#方法-B：命令行挂载-mount-davfs" class="headerlink" title="方法 B：命令行挂载 (mount.davfs)"></a>方法 B：命令行挂载 (mount.davfs)</h3><p>适合需要把网盘挂载到系统目录给程序用的场景。</p><ol><li><p>安装工具：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt install davfs2</span><br></pre></td></tr></table></figure></li><li><p>创建挂载点：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> <span class="built_in">mkdir</span> /mnt/webdav</span><br></pre></td></tr></table></figure></li><li><p>挂载：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> mount -t davfs http://你的地址:端口/webdav /mnt/webdav</span><br></pre></td></tr></table></figure><p><em>(系统会提示输入用户名密码)</em></p></li></ol><h3 id="方法-C：Rclone（极客与自动化首选）"><a href="#方法-C：Rclone（极客与自动化首选）" class="headerlink" title="方法 C：Rclone（极客与自动化首选）"></a>方法 C：Rclone（极客与自动化首选）</h3><p><strong>Rclone</strong> 是 Linux 下的神器，支持 WebDAV 且性能极好，支持缓存和加密。</p><ol><li><p>安装：<code>sudo apt install rclone</code> 或 <code>curl https://rclone.org/install.sh | sudo bash</code></p></li><li><p>配置：<code>rclone config</code> -&gt; 新建 -&gt; 选 WebDAV -&gt; 填地址密码。</p></li><li><p>挂载：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rclone mount 你的配置名:/ /mnt/webdav --daemon</span><br></pre></td></tr></table></figure></li></ol><hr><h2 id="实例：用-WSL2-挂载-PikPak-的-WebDAV"><a href="#实例：用-WSL2-挂载-PikPak-的-WebDAV" class="headerlink" title="实例：用 WSL2 挂载 PikPak 的 WebDAV"></a>实例：用 WSL2 挂载 PikPak 的 WebDAV</h2><p><a href="https://pikpak.io/">PikPak</a> 是一个非常实用的云盘服务，支持通过 WebDAV 访问。</p><ol><li><p>在 PikPak 网站开启 WebDAV 功能，获取地址、用户名和密码。</p></li><li><p>在WSL中安装 <code>rclone</code> 并配置好 PikPak 的 WebDAV。</p></li><li><p>挂载命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rclone mount pikpak:/ /mnt/pikpak --daemon</span><br></pre></td></tr></table></figure></li><li><p>现在你可以在 <code>/mnt/pikpak</code> 目录下直接访问你的 PikPak 云盘文件了。<br>效果如下图<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/20251206210916.png" alt="20251206210916.png"></p></li></ol><p>此外还可以用 <code>rclone copy /本地/源文件 配置名:远程路径 -P</code> 命令实现本地和云盘之间的文件同步，非常方便。</p><blockquote><p>但是要注意的一点是不能在Windows的文件管理器中直接访问WSL挂载的webdav目录，主要是因为Linux 文件权限隔离 和 FUSE 挂载机制的可见性<br>挂载命名空间的隔离：</p><p>WSL 2 和 Windows 之间的文件共享协议（Plan 9 服务器）默认运行在特定的用户上下文中。当你运行 rclone mount 时，默认情况下，这个挂载点只对运行该命令的当前 Linux 用户（通常是你的默认用户）可见，而对系统其他进程（包括负责与 Windows 通信的 Plan 9 服务进程）是不可见的。</p><p>FUSE 的安全限制：</p><p>WebDAV 挂载通常使用 FUSE（Filesystem in Userspace）。出于安全考虑，FUSE 默认不允许“其他用户”（other users）访问挂载点。即使是 root 用户或其他系统服务（如 WSL 的文件互通服务）也无法访问，除非显式开启权限。</p></blockquote><h2 id="总结与使用建议"><a href="#总结与使用建议" class="headerlink" title="总结与使用建议"></a>总结与使用建议</h2><ul><li><strong>核心优势</strong>：<strong>省空间</strong>。几十 TB 的云端资源，挂载后不占本地硬盘空间，用多少取多少。</li><li><strong>常见用途</strong>：<ul><li>配合 <strong>Alist</strong>：把百度网盘、阿里云盘转成 WebDAV，挂载到本地看视频。</li><li>配合 <strong>Obsidian &#x2F; Zotero</strong>：利用 WebDAV 同步笔记和文献。</li><li>配合 <strong>NAS</strong>：在外面通过 WebDAV 访问家里的硬盘。</li></ul></li><li><strong>注意</strong>：因为是基于 HTTP 的，如果是公网使用，强烈建议用 <strong>HTTPS</strong>，否则密码是明文传输的，很不安全。</li></ul>]]>
    </content>
    <id>https://loslisang.github.io/2025/12/06/%E6%8A%80%E6%9C%AF/webdav-pikpak/</id>
    <link href="https://loslisang.github.io/2025/12/06/%E6%8A%80%E6%9C%AF/webdav-pikpak/"/>
    <published>2025-12-06T13:00:05.000Z</published>
    <summary>WebDAV 是一个非常经典且实用的协议。简单一句话总结：它把远程的云端存储，通过 HTTP 协议，“映射”成你电脑上的一个本地硬盘。</summary>
    <title>WebDAV 入门指南：把云盘挂载成本地硬盘</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/LeetCode/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/tags/LeetCode/"/>
    <category term="动态规划" scheme="https://loslisang.github.io/tags/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
    <category term="前缀和" scheme="https://loslisang.github.io/tags/%E5%89%8D%E7%BC%80%E5%92%8C/"/>
    <content>
      <![CDATA[<blockquote><p>给你一个字符串 s ，你需要将它分割成一个或者更多的 平衡 子字符串。比方说，s &#x3D;&#x3D; “ababcc” 那么 (“abab”, “c”, “c”) ，(“ab”, “abc”, “c”) 和 (“ababcc”) 都是合法分割，但是 (“a”, “bab”, “cc”) ，(“aba”, “bc”, “c”) 和 (“ab”, “abcc”) 不是，不平衡的子字符串用粗体表示。<br>请你返回 s 最少 能分割成多少个平衡子字符串。</p></blockquote><p>样例:</p><blockquote><p>输入：s &#x3D; “fabccddg”<br>输出：3<br>解释：<br>我们可以将 s 分割成 3 个子字符串：(“fab, “ccdd”, “g”) 或者 (“fabc”, “cd”, “dg”) 。</p></blockquote><p>按照动态规划的思路来看, 把问题分割成一个个的子问题</p><p>假设dp[i] 表示s[i..]平衡子字符串的最少个数, 那么dp[i-1] &#x3D; min(dp[i] + 1, if 可以得到平衡子字符串 dp[i+1], dp[i+2], .. dp[n])</p><p>问题在于如何判断s[i..j] 是否是一个平衡子字符串</p><p>实现一个check函数</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">check</span>(chars: &amp;<span class="type">Vec</span>&lt;<span class="type">char</span>&gt;, i: <span class="type">usize</span>, j: <span class="type">usize</span>) <span class="punctuation">-&gt;</span> <span class="type">bool</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">cnt</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line">    <span class="keyword">for</span> <span class="variable">k</span> <span class="keyword">in</span> i..j&#123;</span><br><span class="line">        *cnt.<span class="title function_ invoke__">entry</span>(chars[k]).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>) += <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">max</span>() == cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">min</span>()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>代码</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">use</span> std::collections::&#123;HashMap&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">struct</span> <span class="title class_">Solution</span>;</span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">minimum_substrings_in_partition</span>(s: <span class="type">String</span>) <span class="punctuation">-&gt;</span> <span class="type">i32</span> &#123;</span><br><span class="line">        <span class="keyword">fn</span> <span class="title function_">check</span>(chars: &amp;<span class="type">Vec</span>&lt;<span class="type">char</span>&gt;, i: <span class="type">usize</span>, j: <span class="type">usize</span>) <span class="punctuation">-&gt;</span> <span class="type">bool</span>&#123;</span><br><span class="line">            <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">cnt</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line">            <span class="keyword">for</span> <span class="variable">k</span> <span class="keyword">in</span> i..j&#123;</span><br><span class="line">                *cnt.<span class="title function_ invoke__">entry</span>(chars[k]).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>) += <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">max</span>() == cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">min</span>()</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">let</span> <span class="variable">len</span> = s.<span class="title function_ invoke__">len</span>(); </span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">dp</span>:<span class="type">Vec</span>&lt;<span class="type">i32</span>&gt; = (<span class="number">0</span>..len <span class="keyword">as</span> <span class="type">i32</span> +<span class="number">1</span>).<span class="title function_ invoke__">collect</span>();</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">let</span> <span class="variable">chars</span>: <span class="type">Vec</span>&lt;<span class="type">char</span>&gt; = s.<span class="title function_ invoke__">chars</span>().<span class="title function_ invoke__">collect</span>();</span><br><span class="line">        <span class="keyword">for</span> <span class="variable">i</span> <span class="keyword">in</span> <span class="number">1</span>..len+<span class="number">1</span>&#123;</span><br><span class="line">            dp[i] = dp[i].<span class="title function_ invoke__">min</span>(dp[i-<span class="number">1</span>] + <span class="number">1</span>);</span><br><span class="line">            <span class="keyword">for</span> <span class="variable">j</span> <span class="keyword">in</span> <span class="number">0</span>..i&#123;</span><br><span class="line">                <span class="keyword">if</span> <span class="title function_ invoke__">check</span>(&amp;chars, i, j)&#123;</span><br><span class="line">                    dp[i] = dp[i].<span class="title function_ invoke__">min</span>(dp[j]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        dp[len]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>但是使用check函数会超时</p><p>进一步优化</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">use</span> std::collections::HashMap;</span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">minimum_substrings_in_partition</span>(s: <span class="type">String</span>) <span class="punctuation">-&gt;</span> <span class="type">i32</span> &#123;</span><br><span class="line">        <span class="keyword">let</span> <span class="variable">len</span> = s.<span class="title function_ invoke__">len</span>();</span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">dp</span>: <span class="type">Vec</span>&lt;<span class="type">i32</span>&gt; = (<span class="number">0</span>..len <span class="keyword">as</span> <span class="type">i32</span> + <span class="number">1</span>).<span class="title function_ invoke__">collect</span>();</span><br><span class="line">        <span class="keyword">let</span> <span class="variable">chars</span>: <span class="type">Vec</span>&lt;<span class="type">char</span>&gt; = s.<span class="title function_ invoke__">chars</span>().<span class="title function_ invoke__">collect</span>();</span><br><span class="line">        <span class="keyword">for</span> <span class="variable">i</span> <span class="keyword">in</span> <span class="number">1</span>..len &#123;</span><br><span class="line">            <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">cnt</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line">            <span class="keyword">for</span> <span class="variable">j</span> <span class="keyword">in</span> (<span class="number">0</span>..i+<span class="number">1</span>).<span class="title function_ invoke__">rev</span>() &#123;</span><br><span class="line">                *cnt.<span class="title function_ invoke__">entry</span>(chars[j]).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>) += <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">if</span> cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">max</span>() == cnt.<span class="title function_ invoke__">values</span>().<span class="title function_ invoke__">min</span>() &#123;</span><br><span class="line">                    dp[i+<span class="number">1</span>] = dp[i+<span class="number">1</span>].<span class="title function_ invoke__">min</span>(dp[j] + <span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        dp[len]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://loslisang.github.io/2024/08/28/%E6%8A%80%E6%9C%AF/leetcode/3144-minimum-substring-partitions/</id>
    <link href="https://loslisang.github.io/2024/08/28/%E6%8A%80%E6%9C%AF/leetcode/3144-minimum-substring-partitions/"/>
    <published>2024-08-28T08:00:30.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p>给你一个字符串 s ，你需要将它分割成一个或者更多的 平衡 子字符串。比方说，s &#x3D;&#x3D; “ababcc” 那么 (“abab”, “c”, “c”) ，(“ab”, “abc”, “c”) 和 (“ababcc”) 都是合法分割]]>
    </summary>
    <title>LeetCode 3144. 分割字符频率相等的最少子字符串</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/LeetCode/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/tags/LeetCode/"/>
    <category term="滑动窗口" scheme="https://loslisang.github.io/tags/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/"/>
    <category term="二分" scheme="https://loslisang.github.io/tags/%E4%BA%8C%E5%88%86/"/>
    <content>
      <![CDATA[<blockquote><ul><li><p>给你一个整数数组 nums 。数组 nums 的 唯一性数组 是一个按元素从小到大排序的数组，包含了 nums 的所有非空子数组中不同元素的个数。</p></li><li><p>换句话说，这是由所有 0 &lt;&#x3D; i &lt;&#x3D; j &lt; nums.length 的 distinct(nums[i..j]) 组成的递增数组。</p></li><li><p>其中，distinct(nums[i..j]) 表示从下标 i 到下标 j 的子数组中不同元素的数量。</p></li><li><p>返回 nums 唯一性数组 的 中位数 。</p></li><li><p>注意，数组的 中位数 定义为有序数组的中间元素。如果有两个中间元素，则取值较小的那个。</p></li></ul></blockquote><p>说实话题目意思都没看懂</p><ul><li>输入：nums &#x3D; [3,4,3,4,5]</li><li></li><li>输出：2</li><li></li><li>解释：</li><li></li><li>nums 的唯一性数组为 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3] 。唯一性数组的中位数为 2，因此答案是 2 。</li></ul><p>结合样例是大概看懂了:</p><p>题目的意思是说, 给定nums数组, 然后计算唯一性数组的中位数, 而唯一性数组要经过排序</p><p>原本对于nums&#x3D;[3,4,3,4,5], 在排序之前, 唯一性数组应该是这样的</p><blockquote><p>(现在规定distinct(nums[i..j])表示下标 i 到下标 j 的子数组中不同元素的数量, 例如distinct(nums[0..1]) 就是1, distinct(nums[0..2]) 就是2, distinct(nums[0..3]) 还是2 ,因为nums[0..3]是[3,4,3], 只有两个不同的元素)</p></blockquote><p><code>[distinct(nums[0..1]), distinct(nums[0..2]), distinct(nums[0..3]), distinct(nums[0..4]), distinct(nums[0..5]), distinct(nums[1..2]) .... distinct(nums[4..5])]</code> 一共10个元素 $\sum^{1}_{5}$</p><p>然后要对它进行排序</p><p>那我们先按照这个思路来做</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">use</span> std::collections::&#123;hash_map, HashMap&#125;;</span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">median_of_uniqueness_array</span>(nums: <span class="type">Vec</span>&lt;<span class="type">i32</span>&gt;) <span class="punctuation">-&gt;</span> <span class="type">i32</span> &#123;</span><br><span class="line">        <span class="comment">// 唯一性数组</span></span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">distinct</span> = <span class="type">Vec</span>::<span class="title function_ invoke__">new</span>();</span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">hash_map</span>:HashMap&lt;&amp;<span class="type">i32</span>, <span class="type">i32</span>&gt; = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line">        <span class="keyword">let</span> <span class="variable">len</span> =  nums.<span class="title function_ invoke__">len</span>();</span><br><span class="line">        <span class="keyword">for</span> <span class="variable">i</span> <span class="keyword">in</span> <span class="number">0</span>..len&#123;</span><br><span class="line">            hash_map.<span class="title function_ invoke__">clear</span>();</span><br><span class="line">            <span class="keyword">for</span> <span class="variable">j</span> <span class="keyword">in</span> i..len&#123;</span><br><span class="line">                <span class="keyword">if</span> hash_map.<span class="title function_ invoke__">contains_key</span>(&amp;nums[j])&#123;</span><br><span class="line">                    <span class="keyword">let</span> <span class="variable">temp</span> = hash_map.<span class="title function_ invoke__">get</span>(&amp;nums[j]);</span><br><span class="line">                    <span class="keyword">let</span> <span class="variable">a</span> = temp.<span class="title function_ invoke__">unwrap</span>() + <span class="number">1</span>;</span><br><span class="line">                    hash_map.<span class="title function_ invoke__">insert</span>(&amp;nums[j], a);</span><br><span class="line">                &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                    hash_map.<span class="title function_ invoke__">insert</span>(&amp;nums[j], <span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line">                distinct.<span class="title function_ invoke__">push</span>(hash_map.<span class="title function_ invoke__">len</span>());        </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        distinct.<span class="title function_ invoke__">sort</span>();</span><br><span class="line">        <span class="built_in">println!</span>(<span class="string">&quot;&#123;:?&#125;&quot;</span>, distinct);</span><br><span class="line">        distinct[(distinct.<span class="title function_ invoke__">len</span>() + <span class="number">1</span>) / <span class="number">2</span> - <span class="number">1</span>] <span class="keyword">as</span> <span class="type">i32</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>初步得到的代码, 但是很显然, <code>O(n*n)</code>的时间复杂度, 超时了</p><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/20240827145806.png" alt="20240827145806"></p><p>如何优化?</p><p>没思路了</p><p>直接看题解</p><p>二分查找优化, 问题在于如何定义这个二分?</p><p>我们直接看官方给出的题解代码</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">impl</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">median_of_uniqueness_array</span>(nums: <span class="type">Vec</span>&lt;<span class="type">i32</span>&gt;) <span class="punctuation">-&gt;</span> <span class="type">i32</span> &#123;</span><br><span class="line">        <span class="keyword">let</span> <span class="variable">n</span> = nums.<span class="title function_ invoke__">len</span>() <span class="keyword">as</span> <span class="type">i64</span>;</span><br><span class="line">        <span class="keyword">let</span> <span class="variable">median</span> = ((n * (n  + <span class="number">1</span>) / <span class="number">2</span> + <span class="number">1</span>) / <span class="number">2</span>) <span class="keyword">as</span> <span class="type">i64</span>;</span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">res</span> = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">lo</span> = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">hi</span> = n <span class="keyword">as</span> <span class="type">i32</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 检测数组中不同元素数目小于等于 t 的连续子数组数目是否大于等于 median</span></span><br><span class="line">        <span class="keyword">fn</span> <span class="title function_">check</span>(nums: &amp;[<span class="type">i32</span>], t: <span class="type">usize</span>, median: <span class="type">i64</span>) <span class="punctuation">-&gt;</span> <span class="type">bool</span> &#123;</span><br><span class="line">            <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">cnt</span>: HashMap&lt;<span class="type">i32</span>, <span class="type">i32</span>&gt; = HashMap::<span class="title function_ invoke__">new</span>(); <span class="comment">// 子数组中不同元素的个数</span></span><br><span class="line">            <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">j</span> = <span class="number">0</span>; </span><br><span class="line">            <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">tot</span> = <span class="number">0</span> <span class="keyword">as</span> <span class="type">i64</span>; <span class="comment">// 这样的子数组的个数</span></span><br><span class="line">            <span class="keyword">for</span> (i, &amp;v) <span class="keyword">in</span> nums.<span class="title function_ invoke__">iter</span>().<span class="title function_ invoke__">enumerate</span>() &#123;</span><br><span class="line">                *cnt.<span class="title function_ invoke__">entry</span>(v).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>) += <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">while</span> cnt.<span class="title function_ invoke__">len</span>() &gt; t &#123;</span><br><span class="line">                    *cnt.<span class="title function_ invoke__">entry</span>(nums[j]).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>) -= <span class="number">1</span>;</span><br><span class="line">                    <span class="keyword">if</span> *cnt.<span class="title function_ invoke__">get</span>(&amp;nums[j]).<span class="title function_ invoke__">unwrap_or</span>(&amp;<span class="number">0</span>) == <span class="number">0</span> &#123;</span><br><span class="line">                        cnt.<span class="title function_ invoke__">remove</span>(&amp;nums[j]);</span><br><span class="line">                    &#125;</span><br><span class="line">                    j += <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                tot += (i - j + <span class="number">1</span>) <span class="keyword">as</span> <span class="type">i64</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            tot &gt;= median</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> lo &lt;= hi &#123;</span><br><span class="line">            <span class="keyword">let</span> <span class="variable">mid</span> = (lo + hi) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> <span class="title function_ invoke__">check</span>(&amp;nums, mid <span class="keyword">as</span> <span class="type">usize</span>, median) &#123;</span><br><span class="line">                res = mid;</span><br><span class="line">                hi = mid - <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                lo = mid + <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        res</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>要求中位数 其实就是要求 子数组中不同元素的个数.</p><p>假设我们给定一个数median, 就是中位数的位置, 就是说有子数组不同元素的个数要少于n, 这样的子数组的个数要大于 median</p><p>总结:</p><p>二分还是很要思路的, 还要多练</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/08/27/%E6%8A%80%E6%9C%AF/leetcode/3134-median-of-uniqueness-array/</id>
    <link href="https://loslisang.github.io/2024/08/27/%E6%8A%80%E6%9C%AF/leetcode/3134-median-of-uniqueness-array/"/>
    <published>2024-08-27T06:20:31.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<ul>
<li><p>给你一个整数数组 nums 。数组 nums 的 唯一性数组 是一个按元素从小到大排序的数组，包含了 nums 的所有非空子数组中不同元素的个数。</p>
</li>
<li><p>换句话说，这是由所有 0 &lt;&#x3D;]]>
    </summary>
    <title>LeetCode 3134. 找出唯一性数组的中位数</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="随笔" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E9%9A%8F%E7%AC%94/"/>
    <category term="思考" scheme="https://loslisang.github.io/tags/%E6%80%9D%E8%80%83/"/>
    <content>
      <![CDATA[<h2 id="思考自己"><a href="#思考自己" class="headerlink" title="思考自己"></a>思考自己</h2><p>要做些什么才能改变自己，让自己变成自己的喜欢的样子呢？</p><p>我想变成什么样子的人呢，我自己天天想着有这种习惯那种习惯，总喜欢说从小事情开始做起，忽略了大事情，</p><p>我也是一个很矛盾的人。</p><p>我似乎也是一个完美主义的人，为什么要用似乎，是因为我甚至不愿意承认我是一个完美主义的人</p><p>我也是一个固执的人，</p><p>我不认为我是一个懒惰的人</p><p>我是一个理性的人还是一个感性的人？</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/08/24/%E7%94%9F%E6%B4%BB/2024-08-24-thoughts/</id>
    <link href="https://loslisang.github.io/2024/08/24/%E7%94%9F%E6%B4%BB/2024-08-24-thoughts/"/>
    <published>2024-08-24T14:54:29.000Z</published>
    <summary>
      <![CDATA[<h2 id="思考自己"><a href="#思考自己" class="headerlink" title="思考自己"></a>思考自己</h2><p>要做些什么才能改变自己，让自己变成自己的喜欢的样子呢？</p>
<p>我想变成什么样子的人呢，我自己天天想着有这种习惯那种习]]>
    </summary>
    <title>2024-08-24 思考</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="随笔" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E9%9A%8F%E7%AC%94/"/>
    <category term="思考" scheme="https://loslisang.github.io/tags/%E6%80%9D%E8%80%83/"/>
    <content>
      <![CDATA[<h2 id="晚上的一点小小的思考"><a href="#晚上的一点小小的思考" class="headerlink" title="晚上的一点小小的思考"></a>晚上的一点小小的思考</h2><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>这里的总结不是说我想总结什么东西, 而是是我对”总结”这一行为的思考</p><h4 id="为什么会有这样的思考"><a href="#为什么会有这样的思考" class="headerlink" title="为什么会有这样的思考"></a>为什么会有这样的思考</h4><p>其一是因为晚上睡不着, 开始思考了, 思考过程中就觉得这几天基本上啥都没做, 从21号回家到现在已经10天了, 什么关键的事情都没有完成, 和我想要的目标差距太大了</p><p>其二是对彼女回家进行考研复习的一点点思考, 看着她打算回家复习, 但是到现在也看着基本上没啥进展, 由此想到了自己这几天的进展, 我这几天也是基本上啥都没做, 想着我们两者是否有一些相同点.</p><p>当你发现自己的钱花的太快了的时候你还会回头看一看自己的账单, 同样的类比, 当你发现自己的时间虚度光阴的时候, 你也必须回头看一看自己这几天到底在干什么, 才能有所改变, 这就需要”总结”这一行为</p><h4 id="什么时候该总结"><a href="#什么时候该总结" class="headerlink" title="什么时候该总结"></a>什么时候该总结</h4><ol><li>当你觉得开始虚度光阴的时候, 你就有必要思考这几天你到底再做什么,</li><li>当没有人监督你的时候, 你就需要自己监督自己, 这就需要”总结”这一行为</li><li>当外界没有压力的时候, 你就需要自己给自己一些压力, 这同样也需要”总结”这一行为</li></ol><h4 id="怎么总结"><a href="#怎么总结" class="headerlink" title="怎么总结"></a>怎么总结</h4><p>就我现在来看, 以我现在的认知, 应该只能停留再每天 或者每几天总结一下这几天从头到尾到底做了什么, 就像流水账一样, 虽然我觉得流水账不太好, 但是这是我现在能做到的最好的总结方式了</p><p>至于以后也可以给自己加一些目标啥的, 这都是后话了, 现在就先从最基本的开始吧</p><p>流水账有一个重点, 就是实事求是, 做了什么就写什么(只要是能写的), 就算是不好的事情也要写, 这样才能让自己看到自己的问题, 才能有所改变</p><h4 id="举个例子"><a href="#举个例子" class="headerlink" title="举个例子"></a>举个例子</h4><ol><li>2024年7月21号晚上在外婆家吃饭</li><li>从2024年7月22号上午到2024年7月24日下午, 去了赣州玩</li><li>2024年7月24号下午整理客厅, 稍微弄家里的卫生, 还有电瓶车(最烦的一集)</li><li>2024年7月25号晚上姐姐回家, 彼女也回家了, 晚上和姐姐的婆家吃饭</li><li>2024年7月26号去中午外婆家吃饭(也是做饭吧), 然后就理了一个寸头!(最大改变), 晚上玩游戏没啥好说的(饭都是姐姐带的)</li><li>2024年7月27号去中午姐姐婆家吃饭, 下午晚上玩游戏(饭都是姐姐带的)</li><li>2024年7月28号去中午外婆家吃饭, 上午赖翔来了, 下午睡觉, (去了配锁, 一把没配到)晚上出去玩了一会, (彼女这个时候拔火罐, 累的要死, 明天就感冒了)</li><li>2024年7月29号去中午姐姐婆家吃饭, 下午睡觉, 晚上玩游戏(姐姐带的饭)</li><li>2024年7月30号自己做饭, 下午睡觉, 晚上玩《不要践踏天使的羽毛》, 晚上彼女开始背单词好好学习了</li></ol><blockquote><p>这几天得总结: 除了和彼女一起4天(22-25), 剩下五天, 要么出去吃饭, 要么玩游戏, 要么睡觉, 除了26号理了个寸头, 还打扫了卫生, 30号自己做了饭, 这就是我这几天的总结</p></blockquote><p>但是感觉这样写不是很清晰, 还是有点乱, 要动一点脑子才看得懂</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/07/31/%E7%94%9F%E6%B4%BB/2024-07-31-thoughts/</id>
    <link href="https://loslisang.github.io/2024/07/31/%E7%94%9F%E6%B4%BB/2024-07-31-thoughts/"/>
    <published>2024-07-30T17:54:10.000Z</published>
    <summary>
      <![CDATA[<h2 id="晚上的一点小小的思考"><a href="#晚上的一点小小的思考" class="headerlink" title="晚上的一点小小的思考"></a>晚上的一点小小的思考</h2><h3 id="总结"><a href="#总结" class="headerli]]>
    </summary>
    <title>2024-07-31 思考</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="读书" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E8%AF%BB%E4%B9%A6/"/>
    <category term="读书笔记" scheme="https://loslisang.github.io/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    <content>
      <![CDATA[<p>今年第一篇读书笔记<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/20240729102228.png" alt="20240729102228"></p><h2 id="这是一篇什么样的书"><a href="#这是一篇什么样的书" class="headerlink" title="这是一篇什么样的书"></a>这是一篇什么样的书</h2><p>这是一篇悬疑解密类型的书籍，相当好看，值得一读，引人入胜。</p><h2 id="这篇书讲了些什么东西"><a href="#这篇书讲了些什么东西" class="headerlink" title="这篇书讲了些什么东西"></a>这篇书讲了些什么东西</h2><p>通过叙述三条线，在最后三条线交织在一起，讲述了一个完整的故事。</p><p>第一条线: 杨莫失踪</p><ol><li>杨莫, 杨远家庭</li><li>许安正, 许恩怀家庭</li></ol><p>第二条线: 袁午藏尸</p><ol><li>袁午父子家庭</li></ol><p>第三条线: 楚萍侵犯事件调查</p><ol><li>楚萍家庭</li><li>阿俊</li></ol><p>这本书最精彩的地方就是在于三条线的交织, 以及最后的结局, 虽然剧情上存在一些时间线的错位, 但是真的十分精彩</p><h3 id="剧透警告"><a href="#剧透警告" class="headerlink" title="剧透警告"></a>剧透警告</h3><p>故事的起因可以不断往前追踪, 最初是从501杨莫的失踪开始, 然后是许安正, 许恩华两人, 随着调查得继续, 张叶等人锁定了许安正, 杨莫就是走进了401, 但是阴差阳错的袁午的住所就在许安正的家附近402. 杨莫就是不小心走进了402</p><p>而为什么401和402是相通的呢, 这就要从楚萍侵犯事件开始, 楚萍是袁午的房东, 也就是说楚萍的房子就是402, 半年前楚萍还是住在这里的, 但是发生了一次侵犯事件, 从此楚萍就搬走了, 这个房子就空了下来, 袁午父子就搬了进来. 这个事件由楚萍的哥哥开始调查, 锁定了楚萍的同事阿俊, 但是阿俊不是凶手, 于是阿俊也帮忙一起调查, 然后锁定了楚萍的各个, 但是楚萍的哥哥也不是凶手. 楚萍线也差不多到这里</p><p>然后是袁午线, 他本身是个赌徒, 前半辈子都是由他的母亲一手安排, 但是当他的母亲过世之后, 他就不知道该做什么了, 于是去赌, 把妻女气走了, 房子也用于抵债了, 他和父亲住在了402, 他父亲是个老人, 他们父子两就靠父亲的养老金生活, 但是有一天父亲过世, 为了父亲的养老金, 他打算藏尸, 正巧藏尸的过程被杨莫看到了, 也被许安正知道了</p><p>最后就是许安正这一条线, 他是一个只顾自己生活的人, 他和他的前妻和平离婚, 而他的女儿基本上在杨莫家, 似乎妻女都是他的累赘, 在半年前, 他对402的楚萍垂涎已久, 用书里的话来说, 就是楚萍和他一点关系都没有, 是一个完美的”玩具”(许安正真是人渣!!用安正这里名字也是反讽吧), 他在401和402之间做了一个单向门, 只能从401到402, 以此实现侵犯行为.</p><p>总的来说, 主要剧情就是上述这些</p><h2 id="我的思考"><a href="#我的思考" class="headerlink" title="我的思考"></a>我的思考</h2><p>如果是对于书籍本身的思考, 对不起, 我是个糙人, 我只觉得它好看, 要说深层次的思考, 就是许恩怀最后的开放性结局了, 这一切究竟是不是她一手策划的, 其实全靠读者自己去揣摩了.</p><p>但是这毕竟是第一次写读书笔记, 对于读书笔记的思考, 我还是能小说上几句的</p><p>感触最深的就是 写书评也不简单呀, 要找一个好的角度去描述这本书的剧情真的不简单, 往往就是不知道如何下笔, 我是在2024年7月十几号看完的这本书, 现在再回去看这本书的内容, 仍然觉得剧情引人入胜, 有继续阅读下去的动力</p><p>写读书笔记的时候, 究竟是写自己的感受, 还是写书的内容, 还是写对结局的看法, 还是对任务的看法, 还是总体来写对书的评价. 其实这些角度都不错, 只是因为第一次写, 所以有点不知所措, 还是会害怕自己写的不够完美, 导致无从下笔</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/07/29/%E7%94%9F%E6%B4%BB/book-%E6%B5%B7%E8%91%B5/</id>
    <link href="https://loslisang.github.io/2024/07/29/%E7%94%9F%E6%B4%BB/book-%E6%B5%B7%E8%91%B5/"/>
    <published>2024-07-29T02:20:54.000Z</published>
    <summary>
      <![CDATA[<p>今年第一篇读书笔记<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/20240729102228.png" alt="20240729102228"></p>
<h2 id="这是一篇什]]>
    </summary>
    <title>《海葵》读书笔记</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="随笔" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E9%9A%8F%E7%AC%94/"/>
    <category term="随笔" scheme="https://loslisang.github.io/tags/%E9%9A%8F%E7%AC%94/"/>
    <content>
      <![CDATA[<h2 id="创新思维夏令营总结"><a href="#创新思维夏令营总结" class="headerlink" title="创新思维夏令营总结"></a>创新思维夏令营总结</h2><p>今天是7月18号，来瓶窑的第12天，总算快要结束了，我只能说这俩周的备课和教学真的是太累了，相当的幸苦，<del>虽然很多课都不是我备的</del>，但是毕竟课是我上的，其中的辛苦也是我也是真的体会到的，一点一点地理解了老师这个职业，也更加尊重了老师这个职业。</p><h3 id="事件1"><a href="#事件1" class="headerlink" title="事件1"></a>事件1</h3><p>恰好今天，和同学有一点不合，主要原因是他们上课不认真听讲，总是交头接耳，然后还抄答案，这是我不愿意看到的，我对上课的看法就是：你既然来了上我的课，你就必须学一点东西再下课，不能说来了和没来没啥区别。最后的导火索还是因为三番五次地不听劝，我就在课上说了他们几句，内容大概是：</p><blockquote><p>我已经三番五次地提醒你们了，多次强调了课堂纪律，你们还是把我的话当耳旁风，有的时候我是知道那些同学是不认真听的，我觉得直接处罚你们会伤你们的面子，就一直都是口头提醒，不指名道姓，这种行为说难听点，其实就是”给脸不要脸”.</p></blockquote><p>最后还是把这几个同学给叫出去了，因为我真的想和他们聊一聊，哎，4、5年级的小学生可真难带呀</p><h3 id="对小学生在信息奥数课上玩游戏的看法"><a href="#对小学生在信息奥数课上玩游戏的看法" class="headerlink" title="对小学生在信息奥数课上玩游戏的看法"></a>对小学生在信息奥数课上玩游戏的看法</h3><p>我倒是不介意他们在玩游戏，毕竟游戏里的很多是他们接触不到的，有利于拓张见识；此外，游戏的目标性也会让他们去思考如何达成他们想要的目的，这种追求目的的思考在生活中也是少见的，同时这也是一种思维锻炼，至少在我看来，玩游戏好的人成绩不一定好，但是成绩好的人玩游戏一定不差，<del>但是也要看是什么游戏哈</del>。</p><p>但是问题在于：</p><ol><li>大部分小学生的自我掌控能力不强，容易玩物丧志，不听讲，以至于忘记了自己来上课的目的</li><li>有的时候玩游戏会影响到其他同学的学习，小学生是对新事物很感兴趣的，一旦有人玩游戏，其他人也会跟着玩，这是制止不住</li></ol><p>在今后的课堂教学，我有两条路可以选，一是保持课堂清净，不容许游戏的存在，二是只允许固定时间，所有人都相同，而且必须是课堂的最后时间。但是一切的一切都是要有一个前提，他们必须要听从课堂安排，遵从课堂秩序，这是底线！！</p><h3 id="有什么提升呢"><a href="#有什么提升呢" class="headerlink" title="有什么提升呢"></a>有什么提升呢</h3><p>上面就说过，上完课之后我更加理解老师这个职业了，我学生时代的每一个老师都有自己管理学生的方式，每次我当老师的时候，我就不由自主的拿他们当例子。仔细想想，我最喜欢的老师，其实还是我高中的数学老师。因为它幽默，讲课有趣，他对于学生的提问是提示性的，导致我在我自己身上看到了他的影子。</p><p>我还记得我高中的时候，很喜欢什么问题都找他，但是他也会表现得有些不耐烦<del>因为我确实问过一些很笨的问题，而且作为班上成绩偏好的同学，还总是占用他的时间，现在我自己也感觉很不好意思</del>，但是他还是会指导我，这就很像现在的我指导班上那些很积极学习的学生。我不认为他的做法有什么不妥，理由大概就是我认同他吧<del>实在是推理不动了，全是自己的看法，这甚至都说服不了我自己</del>。</p><p>其次的提升就只能是编码方面的提升了，其中我编码的能力肯定有所上升，但是也可能只是局限于循环为之，只能说任重而道远吧。</p><p>更多的提升我倒没有别的感觉了</p><h3 id="对于上面的描述有什么计划呢"><a href="#对于上面的描述有什么计划呢" class="headerlink" title="对于上面的描述有什么计划呢"></a>对于上面的描述有什么计划呢</h3><ol><li>第一个自然是编码能力啦，只是我现在在Vscode上对C++Debug的时候，环境还是有一些小问题，其次是究竟是用cpp刷题还是rust刷题，用洛谷还是leetcode刷题</li><li>第二个就是对于每一个活动，每一个任务，我都希望我能从中学到一些东西，这就需要我认真对待这件事情</li></ol><h2 id="一点小小的思考"><a href="#一点小小的思考" class="headerlink" title="一点小小的思考"></a>一点小小的思考</h2><h3 id="何为博客"><a href="#何为博客" class="headerlink" title="何为博客"></a>何为博客</h3><p>在14号的时候我看到一篇<a href="https://lutaonan.com/blog/reason-why-your-blog-is-not-alive/">文章</a>，讲的就是为什么要写Blog，以及一些对Blog的一些看法</p><h4 id="观点其一"><a href="#观点其一" class="headerlink" title="观点其一"></a>观点其一</h4><p>你一定要去思考为什么你要写Blog，单纯就是想模仿别人的Blog？还是想把Blog当成自己的学习笔记，甚至是第二大脑，那会不会其他的工具会更好：例如Notion和Obsidian？是为了为自己看还是为了给别人看？这些都是要思考的，虽然不重要，但是思考了就会让你的写作更有目的性。</p><p>我觉得这篇文章真的很适合每一位想写Blog的人看看</p><p>就我自己而言，我一开始写blog只是想说我就必须要有这么一个个人网站，没有去想要拿这个网站来做什么，这个时期就是计算机专业的学生这个身份让我觉得我应该通过自己的技术得到一个博客，再往后就是试图将blog当作知识平台，想把一些常用的操作写在blog上，再到现在真的只是想写作，想抒发自己的表达欲。截至目前我也已经尝试了很多次搭建网站实现Blog，也有想过在CSDN、洛谷、Leetcode甚至是微信公众号上写文章，不排除有技术上的原因，过去的尝试都一一没有持续下去。</p><p>现在我写blog的想法是：我要强化我的语言表达能力，所以我的blog是要给别人看到的，这个网站它不是朋友圈，不是微博，不适合发短文章，不仅要陈述现象和我自己的观点，还要仔细思考，要有自己的思考，当别人看到你的文章的时候，他们也就能理解你的想法，单纯的倾泻自己的情绪，不适合朋友圈。</p><p>我要通过Blog这么一个平台，分享我自己，分享我的思考，分享我的观点，分享我的生活，分享我的学习，分享我的编程，分享我的一切，这就是我写Blog的目的。（<del>这一段来自Copilot，写的还挺好QAQ</del>）</p><h4 id="观点其二"><a href="#观点其二" class="headerlink" title="观点其二"></a>观点其二</h4><p>不必在乎Blog的更新频率，也不要在乎Blog是否有人在看，这些都是次要的，重要的是你要靠你的个人Blog让别人能直接看到你的思考，可以认识你这个人。</p><blockquote><p>记住，一个博客的死掉不是不再更新，而是无法访问。</p></blockquote><p>不去在乎这些外在的数据和看法，只要达成了自己的目的，那就足够了</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>身为一个计算机专业出身的同学（<del>多次强调</del>），我也有一个参与到开源项目的梦，可惜知识储备不够，能力也不行，所以我要不断提升，提升自己的平台。</p><p>上一个开源之夏我错过了，那个时候我还没认识到我自己的地位，现在开始我要认真，认真对待每一个事情。</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/07/18/%E7%94%9F%E6%B4%BB/2024-07-midmonth/</id>
    <link href="https://loslisang.github.io/2024/07/18/%E7%94%9F%E6%B4%BB/2024-07-midmonth/"/>
    <published>2024-07-18T15:15:43.000Z</published>
    <summary>
      <![CDATA[<h2 id="创新思维夏令营总结"><a href="#创新思维夏令营总结" class="headerlink" title="创新思维夏令营总结"></a>创新思维夏令营总结</h2><p>今天是7月18号，来瓶窑的第12天，总算快要结束了，我只能说这俩周的备课和教学真的是]]>
    </summary>
    <title>7月中小记</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="磁力链接" scheme="https://loslisang.github.io/tags/%E7%A3%81%E5%8A%9B%E9%93%BE%E6%8E%A5/"/>
    <category term="P2P" scheme="https://loslisang.github.io/tags/P2P/"/>
    <content>
      <![CDATA[<h2 id="magnet链接是什么"><a href="#magnet链接是什么" class="headerlink" title="magnet链接是什么"></a>magnet链接是什么</h2><h2 id="我想怎么使用磁力链接"><a href="#我想怎么使用磁力链接" class="headerlink" title="我想怎么使用磁力链接"></a>我想怎么使用磁力链接</h2><p>我在我的旧电脑上部署了qbittorrent, 想将旧电脑作为一个下载机器, 用来下载一些资源, 让后通过alist对外提供文件访问的服务</p><p>对外提供服务, 实际上是通过wireguard实现的, 利用服务器的公网ip将我的旧电脑, 新电脑和平板连接在一个局域网中, 具体实现以后写一个文章看看</p><h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>问题1: 磁力链接下载经常下载不动, 如果总是出现这种问题, 我觉得还不如去花点小钱使用pikpak, <a href="https://mypikpak.com/">pikpak</a>的下载很稳定, 不管是多老的资源, 都能下载下来</p><p>可以有的解决办法很多, 但是还是得要知道磁力链接的原理</p><p>问题2: 找资源不方便, 还要去找磁力链接, 找到磁力链接还要再打开qbittorrent, 粘贴磁力链接, 然后再下载, 这个过程很繁琐, 我想用脚本封装这些操作</p><p>可以的解决方法有: bat脚本, python脚本, 甚至是go脚本, 或者是使用qbittorrent的api搭建一个web服务, 通过web服务来下载资源, 再或者是使用Electron来封装一个桌面应用</p>]]>
    </content>
    <id>https://loslisang.github.io/2024/07/14/%E6%8A%80%E6%9C%AF/magnet-link/</id>
    <link href="https://loslisang.github.io/2024/07/14/%E6%8A%80%E6%9C%AF/magnet-link/"/>
    <published>2024-07-13T18:20:50.000Z</published>
    <summary>
      <![CDATA[<h2 id="magnet链接是什么"><a href="#magnet链接是什么" class="headerlink" title="magnet链接是什么"></a>magnet链接是什么</h2><h2 id="我想怎么使用磁力链接"><a href="#我想怎么使用磁]]>
    </summary>
    <title>对磁力链接的思考</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="图床" scheme="https://loslisang.github.io/tags/%E5%9B%BE%E5%BA%8A/"/>
    <category term="PicGo" scheme="https://loslisang.github.io/tags/PicGo/"/>
    <category term="GitHub" scheme="https://loslisang.github.io/tags/GitHub/"/>
    <content>
      <![CDATA[<p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/gentu.png" alt="image"></p><h2 id="需求和问题"><a href="#需求和问题" class="headerlink" title="需求和问题"></a>需求和问题</h2><p>写博客的时候总是要想到图片的问题，之前我的图片展示是放在Obsidian的目录下，也就是和md文件放在一起，这样的好处是方便管理，但是缺点也很明显，就是图片的链接是本地的，如果要发布到博客上，就需要手动修改图片的链接，这样就很麻烦。所以我决定将图片放到图床上，这样就可以直接引用图片链接了。</p><p><del>其实我根本就懒得调整图片的链接</del></p><p>例如这张图片: <img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/image.png" alt="image"></p><h2 id="解决办法"><a href="#解决办法" class="headerlink" title="解决办法"></a>解决办法</h2><p>其一: 使用Picgo作为图床软件, Picgo的原理是将图片上传到图床，然后将图片链接复制到剪贴板，这样就可以直接粘贴到md文件中了。</p><p>在使用Picgo之前需要配置好图床，这里我选择了Github作为图床，因为Github 免费 <del>绝对不是我想白嫖</del></p><h3 id="配置Github图床的步骤"><a href="#配置Github图床的步骤" class="headerlink" title="配置Github图床的步骤"></a>配置Github图床的步骤</h3><ol><li>创建Github Repository(<strong>注意仓库 可见性 必须是 public</strong> 否则会因为token过期而访问不到图片)<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/image-1.png" alt="image-1"></li><li>创建Personal Access Token <a href="https://github.com/settings/tokens?type=beta">Fine-grained Personal Access Tokens (github.com)</a><br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/!%5Balt%20text%5D(image-2.png).png" alt="image-2.png"></li><li>配置Picgo<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/image-2.png" alt="image-2"></li></ol><h3 id="使用vscode作为md编辑器"><a href="#使用vscode作为md编辑器" class="headerlink" title="使用vscode作为md编辑器"></a>使用vscode作为md编辑器</h3><p>如果使用vscode作为md编辑器, 则可以使用插件 <code>Markdown All in One</code> 来预览图片, 还有插件 <code>vs-picgo</code>来上传图片特别方便, 只要选择之前的配置就可以上传图片了。<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/image-4.png" alt="image-4"></p><h4 id="vs-picgo配置"><a href="#vs-picgo配置" class="headerlink" title="vs-picgo配置"></a>vs-picgo配置</h4><p>基础配置就不多说了, 主要是快捷键 Ctrl + Alt + U 上传图片, 然后会自动复制图片链接到剪贴板, 这样就可以直接粘贴到md文件中了。</p><p>但是我不喜欢这样写, 我还是想用Ctrl + V的方式来粘贴图片, 无奈Ctrl + V的快捷键会有冲突, 因为文本复制的快捷键也是是Ctrl + V, 经常会出现粘贴不了的情况, 所以我选择了将vs-picgo的快捷键改为Ctrl + K  Ctrl + V, 这样就不会和文本复制的快捷键冲突了。</p><p>之后希望用一种方法实现它的自动粘贴功能, 很简单的逻辑:</p><p><code>当检测到粘贴板是图片时, 才使用Picgo的上传功能, 否则使用默认的文本粘贴功能。</code></p>]]>
    </content>
    <id>https://loslisang.github.io/2024/07/13/%E6%8A%80%E6%9C%AF/picgo-image-hosting/</id>
    <link href="https://loslisang.github.io/2024/07/13/%E6%8A%80%E6%9C%AF/picgo-image-hosting/"/>
    <published>2024-07-13T09:27:31.000Z</published>
    <summary>
      <![CDATA[<p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/gentu.png" alt="image"></p>
<h2 id="需求和问题"><a href="#需求和问题" class="heade]]>
    </summary>
    <title>使用 PicGo 配置 GitHub 图床上传图片</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/LeetCode/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/tags/LeetCode/"/>
    <category term="双指针" scheme="https://loslisang.github.io/tags/%E5%8F%8C%E6%8C%87%E9%92%88/"/>
    <category term="链表" scheme="https://loslisang.github.io/tags/%E9%93%BE%E8%A1%A8/"/>
    <content>
      <![CDATA[<p><a href="https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/">82. 删除排序链表中的重复元素 II</a></p><h2 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a>题目描述</h2><p>给定一个已排序的链表的头 <code>head</code> ， <em>删除原始链表中所有重复数字的节点，只留下不同的数字</em> 。返回 <em>已排序的链表</em> 。</p><h3 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h3><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/Pasted%20image%2020240115145926.png" alt="Pasted image 20240115145926"></p><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><p>首先，链表是排序过的，所以相同的节点肯定是连续的，只需要遍历一遍就能把所有相同的节点删除</p><p>记pre为去重链表的遍历节点itr的前一个节点。（我们从前往后遍历，前面的链表就是去除过后的链表）</p><ol><li>如果itr.val &#x3D;&#x3D; itr.next.val，那我们就记flag为当前遍历节点的值，令<code>flag=itr.val</code>，不断向后遍历令itr &#x3D; itr.next，直到，itr.next.val !&#x3D; flag 或者 itr.next &#x3D;&#x3D; null。然后让pre.next &#x3D; itr.next</li><li>如果itr.val !&#x3D; itr.next.val，那么就说明itr不是冗余节点，则不必删除，让pre &#x3D; itr即可</li></ol><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>&#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">deleteDuplicates</span><span class="params">(ListNode head)</span>&#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">flag</span> <span class="operator">=</span> -<span class="number">101</span>;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">dummyNode</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>();</span><br><span class="line">        dummyNode.next = head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">pre</span> <span class="operator">=</span> dummyNode;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">itr</span> <span class="operator">=</span> pre.next;</span><br><span class="line">        <span class="keyword">while</span>(itr != <span class="literal">null</span> &amp;&amp; itr.next != <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(itr.val == itr.next.val)&#123;</span><br><span class="line">                flag = itr.val;</span><br><span class="line">                <span class="keyword">while</span>(itr.next != <span class="literal">null</span> &amp;&amp; itr.next.val == flag)&#123;</span><br><span class="line">                    itr = itr.next;</span><br><span class="line">                &#125;</span><br><span class="line">                pre.next = itr.next;</span><br><span class="line">                itr = pre.next;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                pre = itr;</span><br><span class="line">                itr = itr.next;</span><br><span class="line">            &#125;   </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dummyNode.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>时间复杂度 O(n), 空间复杂度O(1)</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>链表的题通常需要注意两点：</p><ol><li>舍得用变量，千万别想着节省变量，否则容易被逻辑绕晕</li><li>head 有可能需要改动时，先增加一个 假head，返回的时候直接取 假head.next，这样就不需要为修改 head 增加一大堆逻辑了。</li></ol>]]>
    </content>
    <id>https://loslisang.github.io/2024/01/15/%E6%8A%80%E6%9C%AF/leetcode/82-remove-duplicates-from-sorted-list-ii/</id>
    <link href="https://loslisang.github.io/2024/01/15/%E6%8A%80%E6%9C%AF/leetcode/82-remove-duplicates-from-sorted-list-ii/"/>
    <published>2024-01-15T11:40:04.000Z</published>
    <summary>82. 删除排序链表中的重复元素 II</summary>
    <title>LeetCode 82. 删除排序链表中的重复元素 II</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/LeetCode/"/>
    <category term="LeetCode" scheme="https://loslisang.github.io/tags/LeetCode/"/>
    <category term="双指针" scheme="https://loslisang.github.io/tags/%E5%8F%8C%E6%8C%87%E9%92%88/"/>
    <category term="链表" scheme="https://loslisang.github.io/tags/%E9%93%BE%E8%A1%A8/"/>
    <content>
      <![CDATA[<h2 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a>题目描述</h2><p>给定一个单链表 <code>L</code> 的头节点 <code>head</code> ，单链表 <code>L</code> 表示为：</p><blockquote><p>L0 → L1 → … → Ln - 1 → Ln</p></blockquote><p>请将其重新排列后变为：</p><blockquote><p>L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …</p></blockquote><p>不能只是单纯的改变节点内部的值，而是需要实际的进行节点交换。<br><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/Pasted%20image%2020240115180529%201.png" alt="Pasted image 20240115180529 1"></p><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><h3 id="解法一：暴力解"><a href="#解法一：暴力解" class="headerlink" title="解法一：暴力解"></a>解法一：暴力解</h3><p>第i次循环都把最后一个节点移动到第<code>2*i-1</code>个节点后面，当然不是用for循环，只是代码运行的时候链表内部是这样的过程。</p><p>记itr为从前往后遍历的节点，只要itr.next不为null，就一直做以下循环</p><ol><li>找到最后一个节点的前一个节点记为pre，最后一个节点记为last &#x3D; pre.next</li><li>把最后一个节点删除，插入到第itr的后面</li><li>令itr前移动两个单位itr &#x3D; itr.next.next</li></ol><p>步骤2的Code</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">pre.next = last.next;</span><br><span class="line">last.next = itr.next;</span><br><span class="line">itr.next = last</span><br></pre></td></tr></table></figure><h4 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">lastPre</span><span class="params">(ListNode head)</span>&#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">itr</span> <span class="operator">=</span> head;</span><br><span class="line">        <span class="keyword">while</span> (itr.next.next != <span class="literal">null</span>) &#123;</span><br><span class="line">            itr = itr.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> itr;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">reorderList</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">itr</span> <span class="operator">=</span> head;</span><br><span class="line">        <span class="keyword">while</span>(itr != <span class="literal">null</span> &amp;&amp; itr.next != <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="type">ListNode</span> <span class="variable">pre</span> <span class="operator">=</span> lastPre(head);</span><br><span class="line">            <span class="type">ListNode</span> <span class="variable">last</span> <span class="operator">=</span> pre.next;</span><br><span class="line">            pre.next = last.next;</span><br><span class="line">            last.next = itr.next;</span><br><span class="line">            itr.next = last;</span><br><span class="line">            itr = itr.next.next;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>时间复杂度 $O(N^2)$</p><h3 id="解法二"><a href="#解法二" class="headerlink" title="解法二"></a>解法二</h3><ol><li>找中点，拆分链表</li><li>倒置后半段链表</li><li>合并两段链表</li></ol><h4 id="找中点（快慢指针法）"><a href="#找中点（快慢指针法）" class="headerlink" title="找中点（快慢指针法）"></a>找中点（快慢指针法）</h4><h5 id="eg1"><a href="#eg1" class="headerlink" title="eg1"></a>eg1</h5><p>1-&gt;2-&gt;3-&gt;4</p><p>fast:1    slow:1</p><p>fast:3    slow:2</p><p>fast.next.next为null，终止循环</p><p>那么中点就记为mid &#x3D; slow.next 为 3</p><h5 id="eg2"><a href="#eg2" class="headerlink" title="eg2"></a>eg2</h5><p>1-&gt;2-&gt;3-&gt;4-&gt;5</p><p>fast:1    slow:1</p><p>fast:3    slow:2</p><p>fast:5    slow:3</p><p>fast.next为null，终止循环</p><p>那么中点就记为mid &#x3D; slow.next 为 4</p><p>拆分链表，slow.next &#x3D; null;</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> ListNode <span class="title function_">getMid</span><span class="params">(ListNode head)</span>&#123;</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">slow</span> <span class="operator">=</span> head, fast = head;</span><br><span class="line">    <span class="keyword">while</span>(fast != <span class="literal">null</span> &amp;&amp; fast.next != <span class="literal">null</span>)&#123;</span><br><span class="line">        slow = slow.next;</span><br><span class="line">        fast = fast.next.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> slow;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="倒置链表"><a href="#倒置链表" class="headerlink" title="倒置链表"></a>倒置链表</h4><p>记后半段链表为back，前半段链表为front</p><p>倒置链表使用前插法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> ListNode <span class="title function_">reverse</span><span class="params">(ListNode head)</span>&#123;</span><br><span class="line">     <span class="type">ListNode</span> <span class="variable">itr</span> <span class="operator">=</span> head;</span><br><span class="line">     <span class="type">ListNode</span> <span class="variable">dummyHead</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>();</span><br><span class="line">     <span class="keyword">while</span>(itr != <span class="literal">null</span>)&#123;</span><br><span class="line">         <span class="type">ListNode</span> <span class="variable">temp</span> <span class="operator">=</span> itr.next;</span><br><span class="line">         itr.next = dummyHead.next;</span><br><span class="line">         dummyHead.next = itr;</span><br><span class="line">         itr = temp;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dummyHead.next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="合并链表"><a href="#合并链表" class="headerlink" title="合并链表"></a>合并链表</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> ListNode <span class="title function_">merge</span> <span class="params">(ListNode l1, ListNode l2)</span> &#123;</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">head</span> <span class="operator">=</span> l1;</span><br><span class="line">    <span class="keyword">while</span>(l2 != <span class="literal">null</span> &amp;&amp; l1 != <span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">l1Next</span> <span class="operator">=</span> l1.next;</span><br><span class="line">        l1.next = l2;   </span><br><span class="line">        l2 = l2.next;</span><br><span class="line">        l1.next.next = l1Next;</span><br><span class="line">        l1 = l1.next.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> head;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ol><li>链表的赋值，其实和变量交换很类似，都是需要备份的。</li><li>封装好功能的函数，远远比一整段写出来的代码要更好理解！！</li><li>不用害怕定义变量，但是前提是你要知道这个变量是用来做什么的</li></ol>]]>
    </content>
    <id>https://loslisang.github.io/2024/01/15/%E6%8A%80%E6%9C%AF/leetcode/143-reorder-list/</id>
    <link href="https://loslisang.github.io/2024/01/15/%E6%8A%80%E6%9C%AF/leetcode/143-reorder-list/"/>
    <published>2024-01-15T11:32:06.000Z</published>
    <summary>LeetCode 143. 重排链表</summary>
    <title>LeetCode 143. 重排链表</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="总结" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E6%80%BB%E7%BB%93/"/>
    <category term="总结" scheme="https://loslisang.github.io/tags/%E6%80%BB%E7%BB%93/"/>
    <category term="教学" scheme="https://loslisang.github.io/tags/%E6%95%99%E5%AD%A6/"/>
    <content>
      <![CDATA[<p>说实话当一个老师还是不错的，但是前提是教的不是小学生。</p><h2 id="教学的收获"><a href="#教学的收获" class="headerlink" title="教学的收获"></a>教学的收获</h2><h3 id="编程能力上的收获"><a href="#编程能力上的收获" class="headerlink" title="编程能力上的收获"></a>编程能力上的收获</h3><p>感触最大的就是我有了一个大致的知识框架，什么OJ，无非就是学习基本语法之后去学数据结构和算法。我自己也在暑假的时候复习了一下动态规划和图的搜索，这一个是我编程能里最大的提升。CSP考试用的主要是C++语言，我不是很熟悉C++的语法和容器，有些代码就写的比较复杂。做题量其实也不算大，</p><h3 id="教学上的收获"><a href="#教学上的收获" class="headerlink" title="教学上的收获"></a>教学上的收获</h3><p>因为我是作为一个老师去教学C++的知识，现在还主要是语法阶段，我感觉我教的就不算特别好，有些东西如果不在脑子里思考过一遍，还真的不一定能讲出来。</p><p>有一次就是讲”添加逗号”的问题，我就语塞了，之前只是自己做出来了，但是根本没想过怎么讲这道题目，这是最大的问题。自己理解了，但是还没有理解完全，不能够正常讲出来，让同学们听懂。</p><p>而且大班教学，很容易就产生能力不均匀的情况，很想把同学们统一起来讲，但是大家能力参差不齐，就会导致有些同学觉得太简单然后不听，进一步导致重要的东西他们没听到，我其实也很苦恼。</p><p>之后我教课的流程应该会大大改变，例如：强调做题，强调理解，而不是抄代码，当然让他们不得不抄代码就是因为我教的不算好。</p><p>讲题的步骤也可以进行改变，例如先做5min，然后讲思路，不写代码，再让他们做一会，最后写代码，不过这种教学方式应该对题目的要求比较大。</p><p>让他们做笔记，我自己也可以把笔记再课堂上做好然后发给他们，当作上课的讲义嘛。</p><h2 id="遇到的一些事情"><a href="#遇到的一些事情" class="headerlink" title="遇到的一些事情"></a>遇到的一些事情</h2><h3 id="事件"><a href="#事件" class="headerlink" title="事件"></a>事件</h3><p>这之中我遇到了一个同学，他上课看起来是在认真听课，但是实际上不是，也经常经常请假，导致在本身基础就不算好的情况，就完全跟不上课程的进度了。在最后的器模测试中，甚至连<code>cout &lt;&lt; &quot;ABCCD&quot;;</code>都写不出来，最后呢，他被其他同学说是“零分大王”，虽然其他同学并不知道他是谁，但是就在教室里一直讲，这一点非常不好，但是我却默许了这种行为，我觉得我做的实在是太差劲了，没能制止其他同学对他的霸凌，最后下课的路上，他打了其他同学一拳，这个时候我还不知道，然后我才发现他不对劲了，他很委屈。我真的需要对此做出反思。</p><h3 id="反思"><a href="#反思" class="headerlink" title="反思"></a>反思</h3><p>如果要反思的话，首先得要怪我。我自己不是很懂小学生的思维，作为一个老师我是不合格的，我对我的教学对象的心理了解的太少了，这是最基本的。</p><p>其次，绰号什么的，只有亲近的人说才会觉得舒服，如果是一个不认识的人这样说，只会认为是在嘲讽自己，我没有带入到他的处境里。现在仔细想想，给他起绰号的同学其实没啥恶意，但是没有把握好距离，如果他们俩是好朋友的话那应该没关系，问题就在于他们不是盆友。</p><h2 id="之后的打算"><a href="#之后的打算" class="headerlink" title="之后的打算"></a>之后的打算</h2><p>教学可能确实不太适合我，但是我从中得到了很多锻炼，很多是为人处世的，和很多家长进行沟通，教导小学生，这都不简单。</p><p>之后我要提升自己的程序设计能力，就是多做OJ题，还要<strong>多写题解</strong>，争取让不懂的人也能看懂，这才是一个做老师的正确姿势。</p><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/102238754_p0.png" alt="102238754_p0"></p>]]>
    </content>
    <id>https://loslisang.github.io/2024/01/14/%E7%94%9F%E6%B4%BB/2023-teaching-summary/</id>
    <link href="https://loslisang.github.io/2024/01/14/%E7%94%9F%E6%B4%BB/2023-teaching-summary/"/>
    <published>2024-01-14T10:38:40.000Z</published>
    <summary>23年信息奥数教学总结</summary>
    <title>2023 年信息奥数教学总结</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="生活" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/"/>
    <category term="总结" scheme="https://loslisang.github.io/categories/%E7%94%9F%E6%B4%BB/%E6%80%BB%E7%BB%93/"/>
    <category term="总结" scheme="https://loslisang.github.io/tags/%E6%80%BB%E7%BB%93/"/>
    <category term="年度总结" scheme="https://loslisang.github.io/tags/%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93/"/>
    <content>
      <![CDATA[<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>23年是我本科毕业地一年，是疫情结束的一年，研究生入学的一年。今年我读了很多本书，和她去了很多地方，我觉得这就是我这一年最宝贵的，最有价值的东西。</p><h3 id="书籍"><a href="#书籍" class="headerlink" title="书籍"></a>书籍</h3><p>就微信读书上，我就读了8本书《球状闪电》、《蛙》、《可能性的艺术》、《浅薄》、《浪潮之巅》、《置身事内》、《今日简史》等等，还有一些轻小说就不必翻出来讲了。其中大部分都是和社会相关的，批判现实的不公、贫富差距过大，还有讲述历史的优秀书籍。</p><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/book.png?token=AMSNNOZFZ6PTPGWBWKFCW3TGSABBA" alt="置身事内"></p><h3 id="旅游"><a href="#旅游" class="headerlink" title="旅游"></a>旅游</h3><p>今年去了赣州、广州、舟山、宁波、青岛、长沙、桂林、阳朔、柳州，很可惜我不是一个喜欢拍照的人，没有保留几张好看的照片，就用文字浅浅地记录一下今年地旅行。</p><p>为什么要去广州呢？因为她在，不在乎什么地点，其实只要有她就行，虽然去了很多次广州，但是丝毫没有厌倦这个城市，现在我还是怀念广州的美食：隆江猪脚饭、猪杂汤粉、牛肉稞条等等。最想的事情就是和她去吃海底捞，不知为什么，就是觉得在海底捞会很放松。广州的风土人情总让人很惬意。</p><p>舟山，在舟山我的印象估计只有那次早早起床去海边看的日出了吧，很震惊呀，感觉生活就是为此而存在的。日出和大海，总给人一种希望，一天刚刚开始，一切皆有可能。</p><p>宁波，我对宁波的印象估计也没啥，就只有酒店了吧😂。</p><p>青岛，青岛是我夏天去过最舒服的地方了吧，沙滩，海风，和舒适的气温，真想一辈子在青岛玩了，可惜就是青岛是个旅游城市，人真的很多。</p><p>长沙，橘子洲头，越往后人们应该会越来越想你吧。臭豆腐，黑色经典，传世美味，没有任何一个地摊能模仿。</p><p>桂林、阳朔、柳州。山和水确实好看，别的话就是骑着小电动兜风，让我有在农村的感觉。</p><h2 id="展望"><a href="#展望" class="headerlink" title="展望"></a>展望</h2><p>最近正在认真学习日语，认真地改变自己，我希望在明年的这个时候，也就是25年初我写年度总结的时候，我可以不看字幕地听懂同人音声（毕竟我学日语的初心就是同人音声），至少在多邻国学完第四章吧，学三章。</p><p>我知道我的文笔很差劲，经常是上文不接下文，思维跳转很快，就多多看书、写文字，明年至少看个12本书吧🤭，写24篇博客哈🙂。</p><p>学术进展缓慢，职业规划不完全。我身边有很多值得我学习的同学，值得我追赶的同学，以他们为榜样，加油💪。</p><p>24年，少打一点游戏，如果不行就用VB脚本好好惩罚自己，毕竟VB确实很难关掉。</p><p><img src="https://raw.githubusercontent.com/LosLiSang/picgo/main/roxy.png?token=AMSNNO2YIGE4Y2VFVFQSLE3GSAAT2" alt="roxy"></p>]]>
    </content>
    <id>https://loslisang.github.io/2024/01/12/%E7%94%9F%E6%B4%BB/2023-summary/</id>
    <link href="https://loslisang.github.io/2024/01/12/%E7%94%9F%E6%B4%BB/2023-summary/"/>
    <published>2024-01-11T16:00:00.000Z</published>
    <summary>Summary Myself</summary>
    <title>2023 Summary</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
  <entry>
    <author>
      <name>Lisang</name>
    </author>
    <category term="技术" scheme="https://loslisang.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Git" scheme="https://loslisang.github.io/tags/Git/"/>
    <content>
      <![CDATA[<h2 id="创建一个git仓库"><a href="#创建一个git仓库" class="headerlink" title="创建一个git仓库"></a>创建一个git仓库</h2><p><code>git init</code></p><p><code>git add (.)</code> 提交到暂存区</p><p><code>git commit -m &lt;&gt;</code></p><p><code>git log &lt;--stat&gt;</code></p><p><code>git diff &lt;commit-id&gt;</code></p><p><code>git reset --hard &lt;commit-id&gt;</code></p><p><code>git checkout &lt;commit-id&gt;</code></p><p><code>git branch</code></p><p><code>git checkout -b develop</code></p><p><code>$master git merge develop</code></p><h2 id="git-config"><a href="#git-config" class="headerlink" title="git config"></a>git config</h2><h3 id="修改某些属性"><a href="#修改某些属性" class="headerlink" title="修改某些属性"></a>修改某些属性</h3><p><code>git config --global &lt;properity&gt; &lt;value&gt;</code></p><p>eg:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.name</span><br><span class="line"></span><br><span class="line">git config --global user.email</span><br><span class="line"></span><br><span class="line">git config --global http.sslverify <span class="literal">false</span> 关闭验证ssl证书</span><br><span class="line"></span><br><span class="line">git config --global http.sslBackend schannel </span><br></pre></td></tr></table></figure><h3 id="查看属性"><a href="#查看属性" class="headerlink" title="查看属性"></a>查看属性</h3><p><code>git config --list --show-origin</code></p><h2 id="git-clone"><a href="#git-clone" class="headerlink" title="git clone"></a>git clone</h2><h3 id="携带参数"><a href="#携带参数" class="headerlink" title="携带参数"></a>携带参数</h3><p>eg:<br><code>git -c http.sslVerify=false clone &lt;URL&gt;</code></p><h2 id="本地仓库和远程仓库绑定-远程分支"><a href="#本地仓库和远程仓库绑定-远程分支" class="headerlink" title="本地仓库和远程仓库绑定(远程分支)"></a>本地仓库和远程仓库绑定(远程分支)</h2><p><code>git remote remove origin</code></p><p><code>git remote add origin &quot;https://github.com/LosLiSang/loslisang.github.io.git&quot;</code></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://xugaoxiang.com/2021/03/17/git-clone-ssl-certificate-problem-unable-to-get-local-issuer-certificate/">迷途小书童的Note迷途小书童的Note (xugaoxiang.com)</a></p>]]>
    </content>
    <id>https://loslisang.github.io/2024/01/11/%E6%8A%80%E6%9C%AF/git-basics/</id>
    <link href="https://loslisang.github.io/2024/01/11/%E6%8A%80%E6%9C%AF/git-basics/"/>
    <published>2024-01-10T16:00:00.000Z</published>
    <summary>git分布式管理工具使用</summary>
    <title>Git 分布式管理工具使用</title>
    <updated>2026-11-14T17:51:11.197Z</updated>
  </entry>
</feed>
