<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>吉吉博客</title>
  
  <subtitle>JiJi&#39;s blog</subtitle>
  <link href="https://mmdjiji.com/atom.xml" rel="self"/>
  
  <link href="https://mmdjiji.com/"/>
  <updated>2026-03-05T00:18:01.282Z</updated>
  <id>https://mmdjiji.com/</id>
  
  <author>
    <name>吉吉</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Readme</title>
    <link href="https://mmdjiji.com/readme/index.html"/>
    <id>https://mmdjiji.com/readme/index.html</id>
    <published>2076-12-31T16:00:00.000Z</published>
    <updated>2026-03-05T00:18:01.282Z</updated>
    
    <content type="html"><![CDATA[<p>欢迎来到我的博客！</p><h2 id="自我介绍"><a href="#自我介绍" class="headerlink" title="自我介绍"></a>自我介绍</h2><ul><li>我是热爱计算机和可爱的女孩子的萌萌哒吉吉</li><li>对计算机技术有执着的追求，喜欢写优雅的代码</li><li>超喜欢追番，欢迎查看<a href="/bangumis">我的追番列表</a></li><li>语言：中文、English、日本語（学習中）</li><li>共识：<a href="https://std.ac/helper/">《提问的智慧》</a>、 <a href="https://std.ac/helper/async/">《异步沟通》</a>、<a href="https://std.ac/helper/nonviolent/">《非暴力沟通》</a></li><li>联系方式：<a href="mailto:i@mmdjiji.com">i@mmdjiji.com</a></li></ul><h2 id="Badges"><a href="#Badges" class="headerlink" title="Badges"></a>Badges</h2><p><a href="https://github.com/mmdjiji"><img src="/images/badges.svg"></a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;欢迎来到我的博客！&lt;/p&gt;
&lt;h2 id=&quot;自我介绍&quot;&gt;&lt;a href=&quot;#自我介绍&quot; class=&quot;headerlink&quot; title=&quot;自我介绍&quot;&gt;&lt;/a&gt;自我介绍&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;我是热爱计算机和可爱的女孩子的萌萌哒吉吉&lt;/li&gt;
&lt;li&gt;对计算机技术有执着</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>用 Gemini 3 实现了飞书日历节假日同步</title>
    <link href="https://mmdjiji.com/2025/2.html"/>
    <id>https://mmdjiji.com/2025/2.html</id>
    <published>2025-12-26T07:27:31.000Z</published>
    <updated>2026-03-05T00:18:01.282Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>飞书日历一直以来有一个问题（其实有好多问题），例如不支持显示法定节假日，这样就会导致我在安排时间表的时候必须参考另外的日历——但飞书日历本身就是个日历，这样感觉很不优雅，直到我看到了<a href="https://www.feishu.cn/content/7328342783683969025">这篇文章</a>。但是它是采用的飞书内置的流程中心（需要付费），对于白嫖用户来说并不友好。幸运的是飞书官方支持<a href="https://open.feishu.cn/document/server-docs/calendar-v4/overview">日历的API</a>，所以我和 Gemini 一拍即合，打算尝试一下能不能只使用 AI Vibe Coding 来完成这个功能，最后我和 Gemini 总共花了 1h42m 就完成了这个项目的开发和调试（其实主要还是调试比较麻烦，因为时区问题导致了很多bug，虽然我觉得我手工写可能用不了一个小时）。</p><p>先附上效果图：</p><p><img src="/images/2025/12/1.png"></p><span id="more"></span><h2 id="一些小小的技术细节"><a href="#一些小小的技术细节" class="headerlink" title="一些小小的技术细节"></a>一些小小的技术细节</h2><p>我是采用的 <a href="https://cnb.cool/">CNB</a> 直接进行开发，代码完全没有落地，并且配了一个 <code>.cnb.yml</code> 让脚本每个月自动执行，这样就可以保持日历的更新：</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">main:</span><br>  <span class="hljs-comment"># 每月 1 日 7:30 自动执行</span><br>  <span class="hljs-string">&quot;crontab: 30 7 1 * *&quot;</span><span class="hljs-string">:</span><br>    <span class="hljs-attr">app:</span><br>      <span class="hljs-attr">git:</span><br>        <span class="hljs-attr">enable:</span> <span class="hljs-literal">true</span><br>        <span class="hljs-attr">submodules:</span> <span class="hljs-literal">true</span><br>      <span class="hljs-attr">stages:</span><br>        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">npm</span> <span class="hljs-string">start</span><br>          <span class="hljs-attr">image:</span> <span class="hljs-string">node:24</span><br>          <span class="hljs-attr">script:</span> <span class="hljs-string">|</span><br><span class="hljs-string">            npm install</span><br><span class="hljs-string">            npm start</span><br></code></pre></td></tr></table></figure><p>需要事先创建一个应用，并配置好 <code>app_id</code> 和 <code>app_secret</code>，且给这个应用开通日历相关的权限。</p><p><img src="/images/2025/12/3.png" alt="权限管理"></p><p>在执行完成后，理论上飞书就可以在日历的搜索中找到这个日历并直接订阅，你如果是组织的管理员还可以设置为全员日历，这样就可以优雅的以边车模式把法定节假日装载到你的飞书日历了。</p><div align="center"><img src="/images/2025/12/2.png"></img></div><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p>我是在 <code>node:24</code> 的环境中运行的：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm init -y<br>npm i axios dayis js-yaml node-ical<br></code></pre></td></tr></table></figure><p>config.yaml:</p><figure class="highlight yaml"><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><code class="hljs yaml"><span class="hljs-comment"># 飞书应用配置</span><br><span class="hljs-attr">feishu:</span><br>  <span class="hljs-attr">app_id:</span> <span class="hljs-string">&quot;cli_xxx&quot;</span><br>  <span class="hljs-attr">app_secret:</span> <span class="hljs-string">&quot;xxx&quot;</span><br><br><span class="hljs-comment"># 日历配置</span><br><span class="hljs-attr">calendar:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">&quot;中国法定节假日&quot;</span>             <span class="hljs-comment"># 想要创建/查找的日历名称</span><br>  <span class="hljs-attr">color:</span> <span class="hljs-number">-1</span>                        <span class="hljs-comment"># 日历颜色，-1为默认</span><br>  <span class="hljs-attr">summary_prefix:</span> <span class="hljs-string">&quot;&quot;</span>               <span class="hljs-comment"># 可选：给日程加前缀，如 &quot;[休]&quot;</span><br><br><span class="hljs-comment"># 数据源</span><br><span class="hljs-attr">source:</span><br>  <span class="hljs-attr">icloud_url:</span> <span class="hljs-string">&quot;https://calendars.icloud.com/holiday/cn_zh.ics&quot;</span><br></code></pre></td></tr></table></figure><p>index.js:</p><figure class="highlight js"><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><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;node:fs&#x27;</span>;<br><span class="hljs-keyword">import</span> yaml <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;js-yaml&#x27;</span>;<br><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;axios&#x27;</span>;<br><span class="hljs-keyword">import</span> ical <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;node-ical&#x27;</span>;<br><span class="hljs-keyword">import</span> dayjs <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;dayjs&#x27;</span>;<br><br><span class="hljs-comment">// 读取配置</span><br><span class="hljs-keyword">const</span> config = yaml.<span class="hljs-title function_">load</span>(fs.<span class="hljs-title function_">readFileSync</span>(<span class="hljs-string">&#x27;./config.yaml&#x27;</span>, <span class="hljs-string">&#x27;utf8&#x27;</span>));<br><br><span class="hljs-keyword">const</span> <span class="hljs-variable constant_">FEISHU_HOST</span> = <span class="hljs-string">&#x27;https://open.feishu.cn/open-apis&#x27;</span>;<br><span class="hljs-keyword">let</span> <span class="hljs-variable constant_">TENANT_ACCESS_TOKEN</span> = <span class="hljs-string">&#x27;&#x27;</span>;<br><br><span class="hljs-comment">// 1. 获取 Token</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">getAccessToken</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">try</span> &#123;<br>        <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">post</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/auth/v3/tenant_access_token/internal`</span>, &#123;<br>            <span class="hljs-attr">app_id</span>: config.<span class="hljs-property">feishu</span>.<span class="hljs-property">app_id</span>,<br>            <span class="hljs-attr">app_secret</span>: config.<span class="hljs-property">feishu</span>.<span class="hljs-property">app_secret</span><br>        &#125;);<br>        <span class="hljs-keyword">if</span> (res.<span class="hljs-property">data</span>.<span class="hljs-property">code</span> !== <span class="hljs-number">0</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(res.<span class="hljs-property">data</span>.<span class="hljs-property">msg</span>);<br>        <span class="hljs-variable constant_">TENANT_ACCESS_TOKEN</span> = res.<span class="hljs-property">data</span>.<span class="hljs-property">tenant_access_token</span>;<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;✅ 获取 Access Token 成功&#x27;</span>);<br>    &#125; <span class="hljs-keyword">catch</span> (e) &#123;<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&#x27;❌ 获取 Token 失败:&#x27;</span>, e.<span class="hljs-property">message</span>);<br>        process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">// 2. 获取或创建日历</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">getOrCreateCalendar</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">const</span> headers = &#123; <span class="hljs-title class_">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">$&#123;TENANT_ACCESS_TOKEN&#125;</span>`</span> &#125;;<br>    <span class="hljs-keyword">let</span> pageToken = <span class="hljs-string">&#x27;&#x27;</span>;<br>    <span class="hljs-keyword">let</span> foundCal = <span class="hljs-literal">null</span>;<br>    <br>    <span class="hljs-keyword">do</span> &#123;<br>        <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/calendar/v4/calendars`</span>, &#123;<br>            headers,<br>            <span class="hljs-attr">params</span>: &#123; <span class="hljs-attr">page_size</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">page_token</span>: pageToken &#125;<br>        &#125;);<br>        <span class="hljs-keyword">if</span> (res.<span class="hljs-property">data</span>.<span class="hljs-property">code</span> !== <span class="hljs-number">0</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(res.<span class="hljs-property">data</span>.<span class="hljs-property">msg</span>);<br>        foundCal = (res.<span class="hljs-property">data</span>.<span class="hljs-property">data</span>.<span class="hljs-property">calendar_list</span> || []).<span class="hljs-title function_">find</span>(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> c.<span class="hljs-property">summary</span> === config.<span class="hljs-property">calendar</span>.<span class="hljs-property">name</span>);<br>        pageToken = res.<span class="hljs-property">data</span>.<span class="hljs-property">data</span>.<span class="hljs-property">page_token</span>;<br>    &#125; <span class="hljs-keyword">while</span> (pageToken &amp;&amp; !foundCal);<br><br>    <span class="hljs-keyword">if</span> (foundCal) &#123;<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`✅ 找到日历: <span class="hljs-subst">$&#123;foundCal.summary&#125;</span>`</span>);<br>        <span class="hljs-keyword">return</span> foundCal.<span class="hljs-property">calendar_id</span>;<br>    &#125;<br><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`ℹ️ 创建新日历: <span class="hljs-subst">$&#123;config.calendar.name&#125;</span>...`</span>);<br>    <span class="hljs-keyword">const</span> createRes = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">post</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/calendar/v4/calendars`</span>, &#123;<br>        <span class="hljs-attr">summary</span>: config.<span class="hljs-property">calendar</span>.<span class="hljs-property">name</span>,<br>        <span class="hljs-attr">description</span>: <span class="hljs-string">&quot;自动同步的节假日日历&quot;</span>,<br>        <span class="hljs-attr">permissions</span>: <span class="hljs-string">&quot;public&quot;</span>,<br>        <span class="hljs-attr">color</span>: config.<span class="hljs-property">calendar</span>.<span class="hljs-property">color</span>, <br>        <span class="hljs-attr">summary_alias</span>: config.<span class="hljs-property">calendar</span>.<span class="hljs-property">name</span><br>    &#125;, &#123; headers &#125;);<br>    <span class="hljs-keyword">return</span> createRes.<span class="hljs-property">data</span>.<span class="hljs-property">data</span>.<span class="hljs-property">calendar</span>.<span class="hljs-property">calendar_id</span>;<br>&#125;<br><br><span class="hljs-comment">// 3. 获取 iCloud 数据 (已修复日期范围问题)</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fetchICloudEvents</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;⬇️ 正在下载 iCloud 数据...&#x27;</span>);<br>    <span class="hljs-keyword">const</span> events = <span class="hljs-keyword">await</span> ical.<span class="hljs-property">async</span>.<span class="hljs-title function_">fromURL</span>(config.<span class="hljs-property">source</span>.<span class="hljs-property">icloud_url</span>);<br>    <br>    <span class="hljs-keyword">const</span> validEvents = [];<br>    <span class="hljs-keyword">const</span> now = <span class="hljs-title function_">dayjs</span>().<span class="hljs-title function_">startOf</span>(<span class="hljs-string">&#x27;day&#x27;</span>);<br>    <span class="hljs-keyword">const</span> oneYearLater = now.<span class="hljs-title function_">add</span>(<span class="hljs-number">1</span>, <span class="hljs-string">&#x27;year&#x27;</span>).<span class="hljs-title function_">endOf</span>(<span class="hljs-string">&#x27;day&#x27;</span>);<br><br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> k <span class="hljs-keyword">in</span> events) &#123;<br>        <span class="hljs-keyword">const</span> ev = events[k];<br>        <span class="hljs-keyword">if</span> (ev.<span class="hljs-property">type</span> !== <span class="hljs-string">&#x27;VEVENT&#x27;</span>) <span class="hljs-keyword">continue</span>;<br><br>        <span class="hljs-comment">// 处理标题</span><br>        <span class="hljs-keyword">let</span> summaryText = <span class="hljs-string">&#x27;&#x27;</span>;<br>        <span class="hljs-keyword">if</span> (ev.<span class="hljs-property">summary</span> &amp;&amp; <span class="hljs-keyword">typeof</span> ev.<span class="hljs-property">summary</span> === <span class="hljs-string">&#x27;object&#x27;</span> &amp;&amp; ev.<span class="hljs-property">summary</span>.<span class="hljs-property">val</span>) &#123;<br>            summaryText = ev.<span class="hljs-property">summary</span>.<span class="hljs-property">val</span>;<br>        &#125; <span class="hljs-keyword">else</span> &#123;<br>            summaryText = <span class="hljs-title class_">String</span>(ev.<span class="hljs-property">summary</span> || <span class="hljs-string">&#x27;&#x27;</span>);<br>        &#125;<br><br>        <span class="hljs-keyword">const</span> startDate = <span class="hljs-title function_">dayjs</span>(ev.<span class="hljs-property">start</span>);<br>        <br>        <span class="hljs-keyword">let</span> endDate;<br>        <span class="hljs-keyword">if</span> (ev.<span class="hljs-property">end</span>) &#123;<br>            <span class="hljs-keyword">const</span> tempEnd = <span class="hljs-title function_">dayjs</span>(ev.<span class="hljs-property">end</span>);<br>            <span class="hljs-comment">// ics 协议中，全天日程 end 是独占的（即次日零点）。</span><br>            <span class="hljs-comment">// 飞书全天日程需要的是包含的结束日期。</span><br>            <span class="hljs-comment">// 所以，如果 end &gt; start，我们需要减去 1 天。</span><br>            <span class="hljs-keyword">if</span> (tempEnd.<span class="hljs-title function_">isAfter</span>(startDate, <span class="hljs-string">&#x27;day&#x27;</span>)) &#123;<br>                endDate = tempEnd.<span class="hljs-title function_">subtract</span>(<span class="hljs-number">1</span>, <span class="hljs-string">&#x27;day&#x27;</span>);<br>            &#125; <span class="hljs-keyword">else</span> &#123;<br>                <span class="hljs-comment">// 如果 end 和 start 是同一天（极少见），或者数据异常，保持原样</span><br>                endDate = tempEnd;<br>            &#125;<br>        &#125; <span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-comment">// 如果没有 end，默认为当天</span><br>            endDate = startDate;<br>        &#125;<br><br>        <span class="hljs-keyword">if</span> (startDate.<span class="hljs-title function_">isAfter</span>(now) &amp;&amp; startDate.<span class="hljs-title function_">isBefore</span>(oneYearLater)) &#123;<br>            validEvents.<span class="hljs-title function_">push</span>(&#123;<br>                <span class="hljs-attr">summary</span>: summaryText,<br>                <span class="hljs-attr">startDate</span>: startDate.<span class="hljs-title function_">format</span>(<span class="hljs-string">&#x27;YYYY-MM-DD&#x27;</span>),<br>                <span class="hljs-attr">endDate</span>: endDate.<span class="hljs-title function_">format</span>(<span class="hljs-string">&#x27;YYYY-MM-DD&#x27;</span>),<br>                <span class="hljs-attr">uid</span>: ev.<span class="hljs-property">uid</span><br>            &#125;);<br>        &#125;<br>    &#125;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`✅ 解析到源数据: <span class="hljs-subst">$&#123;validEvents.length&#125;</span> 条`</span>);<br>    <span class="hljs-keyword">return</span> validEvents;<br>&#125;<br><br><span class="hljs-comment">// 4. 获取飞书现有数据</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fetchFeishuEvents</span>(<span class="hljs-params">calendarId</span>) &#123;<br>    <span class="hljs-keyword">const</span> headers = &#123; <span class="hljs-title class_">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">$&#123;TENANT_ACCESS_TOKEN&#125;</span>`</span> &#125;;<br>    <span class="hljs-keyword">const</span> now = <span class="hljs-title function_">dayjs</span>().<span class="hljs-title function_">unix</span>();<br>    <span class="hljs-keyword">const</span> oneYearLater = <span class="hljs-title function_">dayjs</span>().<span class="hljs-title function_">add</span>(<span class="hljs-number">1</span>, <span class="hljs-string">&#x27;year&#x27;</span>).<span class="hljs-title function_">unix</span>();<br><br>    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/calendar/v4/calendars/<span class="hljs-subst">$&#123;calendarId&#125;</span>/events`</span>, &#123;<br>        headers,<br>        <span class="hljs-attr">params</span>: &#123; <span class="hljs-attr">start_time</span>: <span class="hljs-title class_">String</span>(now), <span class="hljs-attr">end_time</span>: <span class="hljs-title class_">String</span>(oneYearLater), <span class="hljs-attr">page_size</span>: <span class="hljs-number">500</span> &#125;<br>    &#125;);<br><br>    <span class="hljs-keyword">return</span> (res.<span class="hljs-property">data</span>.<span class="hljs-property">data</span>.<span class="hljs-property">items</span> || []).<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> (&#123;<br>        ...e,<br>        <span class="hljs-attr">event_id</span>: e.<span class="hljs-property">event_id</span>,<br>        <span class="hljs-attr">summary</span>: e.<span class="hljs-property">summary</span>,<br>        <span class="hljs-attr">startDate</span>: e.<span class="hljs-property">start_time</span>.<span class="hljs-property">date</span>,<br>        <span class="hljs-attr">endDate</span>: e.<span class="hljs-property">end_time</span>.<span class="hljs-property">date</span> <br>    &#125;));<br>&#125;<br><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">main</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">await</span> <span class="hljs-title function_">getAccessToken</span>();<br>    <span class="hljs-keyword">const</span> calendarId = <span class="hljs-keyword">await</span> <span class="hljs-title function_">getOrCreateCalendar</span>();<br>    <br>    <span class="hljs-keyword">const</span> sourceEvents = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetchICloudEvents</span>();<br>    <span class="hljs-keyword">const</span> existingEvents = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetchFeishuEvents</span>(calendarId);<br><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;sourceEvents:&#x27;</span>, sourceEvents);<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;existingEvents:&#x27;</span>, existingEvents);<br><br>    <span class="hljs-keyword">const</span> toCreate = [];<br>    <span class="hljs-keyword">const</span> toDelete = [];<br><br>    <span class="hljs-comment">// 1. 找出需要创建的</span><br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> src <span class="hljs-keyword">of</span> sourceEvents) &#123;<br>        <span class="hljs-keyword">const</span> exists = existingEvents.<span class="hljs-title function_">find</span>(<br>            <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.<span class="hljs-property">startDate</span> === src.<span class="hljs-property">startDate</span> &amp;&amp; <br>                <span class="hljs-comment">//  e.endDate === src.endDate &amp;&amp; </span><br>                 e.<span class="hljs-property">summary</span> === src.<span class="hljs-property">summary</span><br>        );<br>        <span class="hljs-keyword">if</span> (!exists) toCreate.<span class="hljs-title function_">push</span>(src);<br>    &#125;<br><br>    <span class="hljs-comment">// 2. 找出需要删除的</span><br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> exist <span class="hljs-keyword">of</span> existingEvents) &#123;<br>        <span class="hljs-keyword">const</span> inSource = sourceEvents.<span class="hljs-title function_">find</span>(<br>            <span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> s.<span class="hljs-property">startDate</span> === exist.<span class="hljs-property">startDate</span> &amp;&amp; <br>                <span class="hljs-comment">//  s.endDate === exist.endDate &amp;&amp; </span><br>                 s.<span class="hljs-property">summary</span> === exist.<span class="hljs-property">summary</span><br>        );<br>        <span class="hljs-keyword">if</span> (exist.<span class="hljs-property">status</span> === <span class="hljs-string">&#x27;confirmed&#x27;</span> &amp;&amp; !inSource) toDelete.<span class="hljs-title function_">push</span>(exist);<br>    &#125;<br><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;[toCreate]&#x27;</span>, toCreate);<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;[toDelete]&#x27;</span>, toDelete);<br><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`📊 变更计划: 新增/修正 <span class="hljs-subst">$&#123;toCreate.length&#125;</span>, 删除/清理 <span class="hljs-subst">$&#123;toDelete.length&#125;</span>`</span>);<br><br>    <span class="hljs-comment">// 执行删除</span><br>    <span class="hljs-keyword">if</span> (toDelete.<span class="hljs-property">length</span> &gt; <span class="hljs-number">0</span>) &#123;<br>        <span class="hljs-keyword">const</span> headers = &#123; <span class="hljs-title class_">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">$&#123;TENANT_ACCESS_TOKEN&#125;</span>`</span> &#125;;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> evt <span class="hljs-keyword">of</span> toDelete) &#123;<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">delete</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/calendar/v4/calendars/<span class="hljs-subst">$&#123;calendarId&#125;</span>/events/<span class="hljs-subst">$&#123;evt.event_id&#125;</span>`</span>, &#123; headers &#125;);<br>                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`  - 已删除旧日程: [<span class="hljs-subst">$&#123;evt.startDate&#125;</span> - <span class="hljs-subst">$&#123;evt.endDate&#125;</span>] <span class="hljs-subst">$&#123;evt.summary&#125;</span>`</span>);<br>            &#125; <span class="hljs-keyword">catch</span> (e) &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`  ! 删除失败: <span class="hljs-subst">$&#123;e.message&#125;</span>`</span>); &#125;<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">// 执行创建</span><br>    <span class="hljs-keyword">if</span> (toCreate.<span class="hljs-property">length</span> &gt; <span class="hljs-number">0</span>) &#123;<br>        <span class="hljs-keyword">const</span> headers = &#123; <span class="hljs-title class_">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">$&#123;TENANT_ACCESS_TOKEN&#125;</span>`</span> &#125;;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> evt <span class="hljs-keyword">of</span> toCreate) &#123;<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">post</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;FEISHU_HOST&#125;</span>/calendar/v4/calendars/<span class="hljs-subst">$&#123;calendarId&#125;</span>/events`</span>, &#123;<br>                    <span class="hljs-attr">summary</span>: evt.<span class="hljs-property">summary</span>,<br>                    <span class="hljs-attr">start_time</span>: &#123; <span class="hljs-attr">date</span>: evt.<span class="hljs-property">startDate</span> &#125;,<br>                    <span class="hljs-attr">end_time</span>: &#123; <span class="hljs-attr">date</span>: evt.<span class="hljs-property">endDate</span> &#125;, <br>                    <span class="hljs-attr">visibility</span>: <span class="hljs-string">&quot;public&quot;</span>,<br>                    <span class="hljs-attr">is_all_day_event</span>: <span class="hljs-literal">true</span><br>                &#125;, &#123; headers &#125;);<br>                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`  + 已创建: [<span class="hljs-subst">$&#123;evt.startDate&#125;</span><span class="hljs-subst">$&#123;evt.startDate === evt.endDate ? <span class="hljs-string">&#x27;&#x27;</span> : <span class="hljs-string">&#x27; -&gt; &#x27;</span> + evt.endDate&#125;</span>] <span class="hljs-subst">$&#123;evt.summary&#125;</span>`</span>);<br>            &#125; <span class="hljs-keyword">catch</span> (e) &#123;<br>                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`. ! 创建失败 [<span class="hljs-subst">$&#123;evt.startDate&#125;</span>]:`</span>, e.<span class="hljs-property">response</span>?.<span class="hljs-property">data</span>?.<span class="hljs-property">msg</span> || e.<span class="hljs-property">message</span>);<br>            &#125;<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;🎉 同步完成&#x27;</span>);<br>&#125;<br><br><span class="hljs-title function_">main</span>().<span class="hljs-title function_">catch</span>(<span class="hljs-variable language_">console</span>.<span class="hljs-property">error</span>);<br></code></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>感谢你看到这里！这是一个 AI Vibe Coding 的试验场景，我的确感受到了 AI Coding 的未来已到：</p><ol><li>目前 人工写需求 + AI 写代码 + 人工调试 的工作流已经初步可用，很多简单场景都可以借鉴这套模式，带来的收益是效率的绝对优势，虽然暂时不知道会不会有潜在的 bug；</li><li>在一些复杂的边界问题上，AI 可能会出错，我们需要一个规范性的说明，或者引入类似 AI friendly 架构来解决；</li><li>让 AI 自驱完成从需求、编码到测试的闭环，是未来非常值得期待的。</li></ol>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;背景&quot;&gt;&lt;a href=&quot;#背景&quot; class=&quot;headerlink&quot; title=&quot;背景&quot;&gt;&lt;/a&gt;背景&lt;/h2&gt;&lt;p&gt;飞书日历一直以来有一个问题（其实有好多问题），例如不支持显示法定节假日，这样就会导致我在安排时间表的时候必须参考另外的日历——但飞书日历本身就是个日历，这样感觉很不优雅，直到我看到了&lt;a href=&quot;https://www.feishu.cn/content/7328342783683969025&quot;&gt;这篇文章&lt;/a&gt;。但是它是采用的飞书内置的流程中心（需要付费），对于白嫖用户来说并不友好。幸运的是飞书官方支持&lt;a href=&quot;https://open.feishu.cn/document/server-docs/calendar-v4/overview&quot;&gt;日历的API&lt;/a&gt;，所以我和 Gemini 一拍即合，打算尝试一下能不能只使用 AI Vibe Coding 来完成这个功能，最后我和 Gemini 总共花了 1h42m 就完成了这个项目的开发和调试（其实主要还是调试比较麻烦，因为时区问题导致了很多bug，虽然我觉得我手工写可能用不了一个小时）。&lt;/p&gt;
&lt;p&gt;先附上效果图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/2025/12/1.png&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
  </entry>
  
  <entry>
    <title>个人重要数据自动化冷备份解决方案</title>
    <link href="https://mmdjiji.com/2025/1.html"/>
    <id>https://mmdjiji.com/2025/1.html</id>
    <published>2025-09-03T10:04:57.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>由于我使用自己的部署 GitLab，而仅仅使用一台从 ESXi 上虚拟化的 VM——我相信许多人都是这样的，甚至有些人会使用树莓派去搭建自己的 GitLab。但是这样做可能会产生数据安全问题，尤其是当存储意外损坏。我整理了一下需求，大概有以下几点：</p><ol><li>自动化，无需人工干预；</li><li>冷备份，存储服务器无需持续开机，省电也省磁盘寿命；</li><li>可观测，即备份结束后主动推送结果；</li><li>易回滚，每次备份自动做一个快照，可以回滚到任意时间点，也可以直接查看数据。</li></ol><span id="more"></span><h2 id="架构"><a href="#架构" class="headerlink" title="架构"></a>架构</h2><p>我采用了 TrueNAS 作为备份服务器，在需要备份的服务器上加载了 TrueNAS 的证书以使用基于 SSH 的 rsync 进行拉取。我单独编写了一个程序，首先在局域网里通过 WoL 唤醒 TrueNAS，再用 SSH 连接上 TrueNAS 执行 rsync，结束后调用 TrueNAS 的 API 打一个 snapshot，完成后自动关机，最后通过飞书的 webhook 推送备份结果。</p><p><img src="/images/2025/09/1.png"></p><p>需要注意的是，我备份了 <code>/var/lib/docker</code> 和 <code>/home/ubuntu</code>，原因是我的服务器都采用 Docker 管理各种服务，因此挂载点无非是 <code>/var/lib/docker/volumes</code> 或在 <code>/home/ubuntu/&lt;deployment&gt;/data</code>，而备份整个 Docker 文件夹的潜在目的是把镜像也备份一下，防止到时候因为找不到正确版本的镜像而被迫想办法对数据升级以匹配新的镜像。</p><p>另外，所有的 Docker 启动指令也应备份下来，这样恢复的工作流就简单许多，甚至可以启一台新的 VM，安装 Docker 后，只恢复 <code>/var/lib/docker/volumes</code> 和 <code>/home/ubuntu</code>，然后直接用原来的命令去启动新的容器即可。</p><p><img src="/images/2025/09/2.png" alt="飞书备份通知"></p><h2 id="讨论与展望"><a href="#讨论与展望" class="headerlink" title="讨论与展望"></a>讨论与展望</h2><h3 id="折腾这些的意义？"><a href="#折腾这些的意义？" class="headerlink" title="折腾这些的意义？"></a>折腾这些的意义？</h3><p>任何电子零件都是有寿命的，我们的确可以在其寿命耗尽前定期更换，但却不能预测它的意外损坏。</p><h3 id="高可用-vs-备份？"><a href="#高可用-vs-备份？" class="headerlink" title="高可用 vs 备份？"></a>高可用 vs 备份？</h3><p>许多人会采用 RAID 来避免因存储单点损坏造成的数据丢失，但我想说这和做备份并不冲突。</p><h3 id="一致性问题"><a href="#一致性问题" class="headerlink" title="一致性问题"></a>一致性问题</h3><p>单纯的使用 rsync 可能会出现一致性问题，容易造成一些问题，这是当前方案的缺陷。由于在备份的同时服务器极有可能还在写入，所以最好的办法是在备份前先把 Docker 服务停掉，虽然会造成备份期间业务不可用，但确保了一致性。要想理解如何产生一致性问题并不难，因为 ext4 文件系统不是写时复制（Copy On Write, COW）的，因此不能像 zfs 或者 btrfs 一样直接对某个时刻进行快照。当然对于 GitLab 和 Webdav 来说是低风险的，因为最重要的是 volumes 里的 Git 文件夹，这些的更新都不是很频繁，因此出现一致性问题的风险不大。</p><p>针对写时复制，它通过不修改原始数据块，而是将修改后的数据写入新的位置，从而确保文件在写入过程中始终处于一致状态，并能轻松创建数据快照和历史版本。由于 zfs 是写时复制的，我们在 TrueNAS 上创建的快照就具有一致性。</p><p>解决这个问题有两个思路，一个是把服务器或者备份更换成支持写时复制的文件系统，然后备份当前的镜像，还有一个方法是在备份前停止写入，例如加锁或者关闭服务。未来我解决了这个问题还会再写博文分享。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;背景&quot;&gt;&lt;a href=&quot;#背景&quot; class=&quot;headerlink&quot; title=&quot;背景&quot;&gt;&lt;/a&gt;背景&lt;/h2&gt;&lt;p&gt;由于我使用自己的部署 GitLab，而仅仅使用一台从 ESXi 上虚拟化的 VM——我相信许多人都是这样的，甚至有些人会使用树莓派去搭建自己的 GitLab。但是这样做可能会产生数据安全问题，尤其是当存储意外损坏。我整理了一下需求，大概有以下几点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;自动化，无需人工干预；&lt;/li&gt;
&lt;li&gt;冷备份，存储服务器无需持续开机，省电也省磁盘寿命；&lt;/li&gt;
&lt;li&gt;可观测，即备份结束后主动推送结果；&lt;/li&gt;
&lt;li&gt;易回滚，每次备份自动做一个快照，可以回滚到任意时间点，也可以直接查看数据。&lt;/li&gt;
&lt;/ol&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="运维" scheme="https://mmdjiji.com/tags/%E8%BF%90%E7%BB%B4/"/>
    
  </entry>
  
  <entry>
    <title>UPS 持续告警调查</title>
    <link href="https://mmdjiji.com/2024/3.html"/>
    <id>https://mmdjiji.com/2024/3.html</id>
    <published>2024-07-25T11:17:27.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>这件事从最开始发现到现在已经有将近一年了，而直到现在也不能得出100%确定的原因，本文中所得出的结论也只是我的推测。任何复杂的系统，都难以通过单方面的判断得出有效的结论，消融实验是必要的，而很多时候又没有做消融实验的条件和时机。谨以本篇文章，还原我从发现UPS不稳定，到得出结论的心路历程，希望能带给读者一些参考。如果有读者遇到类似的事件，不妨与我讨论。</p><span id="more"></span><p>本文中涉及的UPS型号为山特 SANTAK TG-BOX 850，但本文不认为该 UPS 有质量问题，甚至这个 UPS 质量非常好，精度非常高，我们会在后文讨论。</p><p><img src="/images/2024/07/1.jpg" alt="山特UPS购买记录"></p><blockquote><p>本文一切内容均来自个人经验，并非相关品牌专业人士的官方声明，请在专业人士指导下进行相关操作。</p></blockquote><h2 id="突如其来的告警"><a href="#突如其来的告警" class="headerlink" title="突如其来的告警"></a>突如其来的告警</h2><p>那是一个平凡的夏天，我正坐在电脑前吹着空调看着番剧吃着雪糕，几个告警突然从手机弹出：UPS is on battery power。</p><p><img src="/images/2024/07/5.jpg" alt="UPS的告警详情"></p><p>正当我困惑，家里没停电啊，为什么 UPS 进入电池模式了，难道是误报？突然又收到一条告警已清除的邮件，随后就来来回回不停地收到一堆“抖动”的告警。</p><p><img src="/images/2024/07/4.jpg" alt="“抖动”的告警"></p><p>我开始检查 NAS 的状况，我有理由怀疑是 NAS 因为莫名其妙的原因触发了告警，而实际上 UPS 并没有发出告警，因为实际上并没有断电。但我并没有什么方法从 NAS 上找到线索，因为它的配置似乎是正常的。UPS 触发 NAS 告警的原理应该是：UPS 通过 USB 协议向 NAS 发送通知，NAS 上的服务接收到通知后，通过 SMTP 发到我的邮箱里。现在 USB 协议这段出现了莫名其妙的故障，导致了误触发，至少我当时是这么考虑的。我甚至考虑过暂时性地把联动关闭，但是风险很大，所以我一开始也只是延长了从断电到关机的时间，以在“抖动”中寻求稳定和折中。</p><p><img src="/images/2024/07/2.png" alt="NAS的UPS配置"></p><p>我开始检查 UPS 的状况，发现好像确实在每次告警的时候，UPS 进入了电池模式，因为 UPS 的硬件告警灯亮了。这瞬间让我意识到没有关闭联动的必要性，如果我关闭了联动，而恰好 UPS 消耗光了电量，将会发生什么不可逆的后果。而调查也有了思路：线路故障，或者 UPS 本身故障。</p><h2 id="消融实验"><a href="#消融实验" class="headerlink" title="消融实验"></a>消融实验</h2><p>我一开始怀疑线路故障，因为插线板经常就会出现接触不良的问题，所以我在线更换了一个插线板，在更换完的一天内确实没有出现过告警，而之后又再次出现了，可以证明并非线路故障，因为该插线板在其他线路中工作正常。</p><p>随着告警越来越多，我在一次告警中观察到了长时间的 UPS 断电告警，我把 UPS 从系统中分离以进行进一步的测试。直到我把 UPS 插在我工作台的插座上，仍然提示告警，我坚信，这一定是 UPS 故障导致的。于是我立马联系 UPS 的售后，得知了这台 UPS 拥有三年质保，厂商的处理很迅速，从我寄过去到 UPS 寄回只用了不到一周时间。果然，新的 UPS 就再也没有发生过这种问题了。</p><p>然而，最近又开始断断续续地发生着告警，我很疑惑，所有的模块我都做过消融实验了啊，难道这个型号的 UPS 就有问题吗？但是既没有收到厂商对产品的召回，网络上也没有讨论相关话题的。</p><h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>直到我最近在小区的物业群里看到了有人在讨论最近小区电力不稳，一切都迎刃而解了。我迅速找到去年的告警，果然也是在夏天。这一切的一切，只有一个东西没有做过消融实验——那就是上游供电。我怎么就不能怀疑是它不稳导致的呢？但是我家里的另外两台 UPS 都工作正常，只有这台不正常，而且电脑也一直在持续稳定运行，因此我一开始就忽略掉了这个最不应该忽略的因素。因为电脑电源的电容很大所以稳定是正常的，而其他 UPS 可能对电压不稳并没有这么敏感，只有这台 UPS 的精度很高，对于哪怕电压出现的一丁点异常都能检测出来并及时接管供电。而都是发生在夏天，因为夏天大家都在使用，尤其是我发现天气越热就越容易出现这种情况，那一切就都解释清楚了。时间点也对得上，这些告警都是在晚上出现的，而晚上应该也是空调使用最多的时间段。</p><p><img src="/images/2024/07/6.jpg" alt="物业群的消息"></p><p><img src="/images/2024/07/3.jpg" alt="去年夏天的告警"></p><p>虽然我这么认为了，不过未来还会不会有其他证据推翻我的猜测呢？谁也不好说，因为没有确定性的证据，这些猜想，都只是我的一厢情愿，但姑且认为是这样子吧。我最近也开始在家里着手节能减排的规划了，先停掉了一个冰柜，然后将厨房的热水器也停掉了（冬天会改成定时运行），烧水器也改成只有白天运行了。虽然这并没有什么用，但我还是打算避免不必要的浪费。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;背景&quot;&gt;&lt;a href=&quot;#背景&quot; class=&quot;headerlink&quot; title=&quot;背景&quot;&gt;&lt;/a&gt;背景&lt;/h2&gt;&lt;p&gt;这件事从最开始发现到现在已经有将近一年了，而直到现在也不能得出100%确定的原因，本文中所得出的结论也只是我的推测。任何复杂的系统，都难以通过单方面的判断得出有效的结论，消融实验是必要的，而很多时候又没有做消融实验的条件和时机。谨以本篇文章，还原我从发现UPS不稳定，到得出结论的心路历程，希望能带给读者一些参考。如果有读者遇到类似的事件，不妨与我讨论。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="运维" scheme="https://mmdjiji.com/tags/%E8%BF%90%E7%BB%B4/"/>
    
  </entry>
  
  <entry>
    <title>用 pyenv 管理 Python 版本</title>
    <link href="https://mmdjiji.com/2024/2.html"/>
    <id>https://mmdjiji.com/2024/2.html</id>
    <published>2024-03-27T13:21:48.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<h2 id="缘起"><a href="#缘起" class="headerlink" title="缘起"></a>缘起</h2><p>笔者曾提到，<a href="https://mmdjiji.com/2022/6.html">Python 用 venv 创建虚拟环境</a>。的确，Python 中采用 venv 来管理虚拟环境是一个很棒的局部安装方案，类似 npm 的 node_modules 目录。但是该方案还尚且不能解决 Python 版本切换的问题，幸运的是，<a href="https://github.com/pyenv/pyenv">pyenv</a> 这个工具可以完美解决，类似 npm 中的 <a href="https://npm.im/n">n</a>，它可以使用简单的命令切换多个 Python 版本。</p><span id="more"></span><p>本文将以 Ubuntu 22.04 为例来介绍它的安装方法，虽然它原生并不支持 Windows，但是有人为 Windows 做了移植，见 <a href="https://github.com/pyenv-win/pyenv-win">pyenv-win</a>。</p><p>值得注意的是，这个项目有趣的地方在于，无论是安装还是使用，都是以用户权限都能完成的，非常适合当今多用户共享显卡的服务器。</p><blockquote><p>David Wheeler: Any problem in computer science can be solved by another layer of indirection.</p></blockquote><h2 id="安装方法-Ubuntu"><a href="#安装方法-Ubuntu" class="headerlink" title="安装方法 (Ubuntu)"></a>安装方法 (Ubuntu)</h2><p>首先安装依赖：</p><figure class="highlight q"><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><code class="hljs q">sudo apt <span class="hljs-keyword">update</span>; sudo apt install build-essential libssl-<span class="hljs-built_in">dev</span> zlib1g-<span class="hljs-built_in">dev</span> \<br>libbz2-<span class="hljs-built_in">dev</span> libreadline-<span class="hljs-built_in">dev</span> libsqlite3-<span class="hljs-built_in">dev</span> curl \<br>libncursesw5-<span class="hljs-built_in">dev</span> xz-utils tk-<span class="hljs-built_in">dev</span> libxml2-<span class="hljs-built_in">dev</span> libxmlsec1-<span class="hljs-built_in">dev</span> libffi-<span class="hljs-built_in">dev</span> liblzma-<span class="hljs-built_in">dev</span><br></code></pre></td></tr></table></figure><p>执行一键安装脚本：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">curl</span> https://pyenv.run | bash<br></code></pre></td></tr></table></figure><p>如果上面的失败可以试试下面这个：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">curl -L https:<span class="hljs-regexp">//gi</span>thub.com<span class="hljs-regexp">/pyenv/</span>pyenv-installer<span class="hljs-regexp">/raw/m</span>aster<span class="hljs-regexp">/bin/</span>pyenv-installer | bash<br></code></pre></td></tr></table></figure><p>然后把出现的一段放到 <code>.bashrc</code> 末尾：</p><figure class="highlight routeros"><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></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-comment"># Load pyenv automatically by appending</span><br><span class="hljs-comment"># the following to </span><br><span class="hljs-comment"># ~/.bash_profile if it exists, otherwise ~/.profile (for login shells)</span><br><span class="hljs-comment"># and ~/.bashrc (for interactive shells) :</span><br><br><span class="hljs-built_in">export</span> <span class="hljs-attribute">PYENV_ROOT</span>=<span class="hljs-string">&quot;<span class="hljs-variable">$HOME</span>/.pyenv&quot;</span><br>[[ -d <span class="hljs-variable">$PYENV_ROOT</span>/bin ]] &amp;&amp; <span class="hljs-built_in">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-string">&quot;<span class="hljs-variable">$PYENV_ROOT</span>/bin:<span class="hljs-variable">$PATH</span>&quot;</span><br>eval <span class="hljs-string">&quot;<span class="hljs-variable">$(pyenv init -)</span>&quot;</span><br><br><span class="hljs-comment"># Restart your shell for the changes to take effect.</span><br><br><span class="hljs-comment"># Load pyenv-virtualenv automatically by adding</span><br><span class="hljs-comment"># the following to ~/.bashrc:</span><br><br>eval <span class="hljs-string">&quot;<span class="hljs-variable">$(pyenv virtualenv-init -)</span>&quot;</span><br></code></pre></td></tr></table></figure><p>再执行 <code>. .bashrc</code> 重新加载配置文件，这样就安装好了。</p><h2 id="安装方法-Windows"><a href="#安装方法-Windows" class="headerlink" title="安装方法 (Windows)"></a>安装方法 (Windows)</h2><p>在 PowerShell 里运行如下:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">Invoke-WebRequest -UseBasicParsing -Uri <span class="hljs-string">&quot;https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1&quot;</span> -OutFile <span class="hljs-string">&quot;./install-pyenv-win.ps1&quot;</span>; &amp;<span class="hljs-string">&quot;./install-pyenv-win.ps1&quot;</span><br></code></pre></td></tr></table></figure><p>如果需要换源，对 <code>~/.pyenv/pyenv-win/.version_cache.xml</code> 文件进行一个全局替换，把 <code>https://www.python.org/ftp/python</code> 替换为 <code>https://cdn.npmmirror.com/binaries/python</code>，然后就可以正常使用啦！</p><p>需要注意的是，pyenv-win 相比于 pyenv 有一个区别：在 pyenv 中我们可以使用大版本号去进行前缀匹配，例如 <code>pyenv shell 3.7</code> 就可以自动定位到 3.7.x 版本（前提是只存在一个 3.7.x 版本），而在 pyenv-win 中则需要精确提供版本，不然会报 <code>pyenv specific python requisite didn&#39;t meet. Project is using different version of python.</code> 的错误。</p><p>幸运的是，经过测试，pyenv-win 对于 <code>.python-version</code> 的前缀匹配是完美兼容的，这意味着与 pyenv 具有很好的兼容性。</p><h2 id="用法"><a href="#用法" class="headerlink" title="用法"></a>用法</h2><figure class="highlight livecodeserver"><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><code class="hljs livecodeserver">pyenv install <span class="hljs-comment">--list # 列出可供安装的版本</span><br>pyenv install x.x.x  <span class="hljs-comment"># 安装指定版本</span><br>pyenv versions       <span class="hljs-comment"># 列出本地已安装的版本</span><br>pyenv <span class="hljs-built_in">shell</span> x.x.x    <span class="hljs-comment"># 切换到指定版本 (PYENV_VERSION)</span><br>pyenv <span class="hljs-built_in">local</span> x.x.x    <span class="hljs-comment"># 指定目录使用的特定版本 (./.python-version)</span><br>pyenv <span class="hljs-built_in">global</span> x.x.x   <span class="hljs-comment"># 指定全局使用的特定版本 (~/.pyenv/version)</span><br></code></pre></td></tr></table></figure><h2 id="推荐阅读"><a href="#推荐阅读" class="headerlink" title="推荐阅读"></a>推荐阅读</h2><ul><li><a href="https://cloud.tencent.com/developer/article/1593478">pyenv 神器原理分析-腾讯云开发者社区-腾讯云 (tencent.com)</a></li></ul><h2 id="哦对了"><a href="#哦对了" class="headerlink" title="哦对了"></a>哦对了</h2><p>千万不要手贱执行 <code>sudo apt remove python</code></p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;缘起&quot;&gt;&lt;a href=&quot;#缘起&quot; class=&quot;headerlink&quot; title=&quot;缘起&quot;&gt;&lt;/a&gt;缘起&lt;/h2&gt;&lt;p&gt;笔者曾提到，&lt;a href=&quot;https://mmdjiji.com/2022/6.html&quot;&gt;Python 用 venv 创建虚拟环境&lt;/a&gt;。的确，Python 中采用 venv 来管理虚拟环境是一个很棒的局部安装方案，类似 npm 的 node_modules 目录。但是该方案还尚且不能解决 Python 版本切换的问题，幸运的是，&lt;a href=&quot;https://github.com/pyenv/pyenv&quot;&gt;pyenv&lt;/a&gt; 这个工具可以完美解决，类似 npm 中的 &lt;a href=&quot;https://npm.im/n&quot;&gt;n&lt;/a&gt;，它可以使用简单的命令切换多个 Python 版本。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Linux" scheme="https://mmdjiji.com/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>为 Hexo 添加追番页面</title>
    <link href="https://mmdjiji.com/2024/1.html"/>
    <id>https://mmdjiji.com/2024/1.html</id>
    <published>2024-01-17T12:22:22.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p>作为一个老二次元，我经常看番，但随着自己看过的番剧数量增多，在与其他二次元同好交流喜欢的番剧时，往往都是听到一个番，啊这个我看过，那个我也看过，到了让你自己说出几个喜欢的番剧时，一个字都蹦不出来。如果俩人都是社恐，那场面就更尴尬了。</p><p>为了解决这个尴尬，我在博客里创建了一个追番列表，你可以访问这个网址来了解我都看过哪些番剧，这样交流起来是不是就容易多了呢？现在我每次遇到二次元同好，啥也不说，把这个网址发给人家，他就会指着这里面的番剧说：啊这个我看过，那个我也看过。对吧，有效地解决了社恐二次元的烦恼。</p><span id="more"></span><h2 id="预览"><a href="#预览" class="headerlink" title="预览"></a>预览</h2><p><img src="/images/2024/01/1.png"></p><h2 id="工具"><a href="#工具" class="headerlink" title="工具"></a>工具</h2><ul><li>Hexo番剧页面插件: <a href="https://github.com/mmdjiji/hexo-bangumis">https://github.com/mmdjiji/hexo-bangumis</a></li><li>番组计划: <a href="https://bangumi.tv/">https://bangumi.tv</a> 或 <a href="https://bgm.tv/">https://bgm.tv</a></li><li>自动更新番剧代码: <a href="https://github.com/mmdjiji/hexo-bangumis/blob/main/workflows-demo/auto-update.yml">https://github.com/mmdjiji/hexo-bangumis/blob/main/workflows-demo/auto-update.yml</a></li></ul><h2 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>在 Hexo 文件夹下执行:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install hexo-bangumis --save<br></code></pre></td></tr></table></figure><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p>将下面的配置写入 <strong>站点</strong> 的配置文件 <code>_config.yml</code> 中:</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">bangumis:</span><br>  <span class="hljs-attr">enable:</span> <span class="hljs-literal">true</span>              <span class="hljs-comment"># 是否启用</span><br>  <span class="hljs-attr">path:</span> <span class="hljs-string">bangumis/index.html</span> <span class="hljs-comment"># 生成追番页面的路径</span><br>  <span class="hljs-attr">show:</span> <span class="hljs-number">1</span>                   <span class="hljs-comment"># 想看，在看，看完</span><br>  <span class="hljs-attr">title:</span> <span class="hljs-string">&#x27;追番列表&#x27;</span>          <span class="hljs-comment"># 标题</span><br>  <span class="hljs-attr">quote:</span> <span class="hljs-string">&#x27;生命不息，追番不止&#x27;</span>  <span class="hljs-comment"># 格言</span><br>  <span class="hljs-attr">color_meta:</span> <span class="hljs-string">&quot;#555&quot;</span>        <span class="hljs-comment"># 追番项元数据的颜色</span><br>  <span class="hljs-attr">color_summary:</span> <span class="hljs-string">&quot;#555&quot;</span>     <span class="hljs-comment"># 追番项简介的颜色</span><br>  <span class="hljs-attr">bgmtv_uid:</span> <span class="hljs-string">mmdjiji</span>        <span class="hljs-comment"># bgm.tv的uid</span><br>  <span class="hljs-attr">download_image:</span> <span class="hljs-literal">true</span>      <span class="hljs-comment"># 下载图片并使用本地图片，否则使用bgm.tv提供的网络图源</span><br>  <span class="hljs-attr">image_level:</span> <span class="hljs-string">c</span>            <span class="hljs-comment"># 图片高清等级 (l, c, m, s, g)</span><br>  <span class="hljs-attr">lazyload:</span> <span class="hljs-literal">true</span>            <span class="hljs-comment"># 是否开启懒加载</span><br>  <span class="hljs-attr">margin:</span> <span class="hljs-string">20px</span>              <span class="hljs-comment"># 封面图的偏移量微调</span><br></code></pre></td></tr></table></figure><h3 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h3><p>更新追番数据:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">hexo bangumis -u<br></code></pre></td></tr></table></figure><p>删除追番数据:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">hexo bangumis -d<br></code></pre></td></tr></table></figure><h3 id="获取-bgm-tv-的-uid"><a href="#获取-bgm-tv-的-uid" class="headerlink" title="获取 bgm.tv 的 uid"></a>获取 <a href="https://bgm.tv/">bgm.tv</a> 的 uid</h3><p>登录 <a href="https://bgm.tv/">bgm.tv</a> 后打开控制台（快捷键 <code>Ctrl</code> + <code>Shift</code> + <code>J</code>），输入 <code>CHOBITS_UID</code> 后按回车，得到的数字就是 <code>uid</code> 啦~</p><h2 id="CI-CD"><a href="#CI-CD" class="headerlink" title="CI&#x2F;CD"></a>CI&#x2F;CD</h2><p>为了配合自动化运维，我特意编写了一份 GitHub Actions 脚本。你也不想每次在番组计划上添加完番剧还要手动在博客的仓库里更新番剧然后再构建一遍再推到服务器上吧，这种重复操作我们直接用脚本解决。</p><p>在 <code>.github/workflows</code> 目录里创建一个名为 <code>auto-update.yml</code> 的文件，内容如下：</p><figure class="highlight yaml"><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><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Auto</span> <span class="hljs-string">update</span><br><span class="hljs-attr">on:</span><br>  <span class="hljs-attr">workflow_dispatch:</span><br>  <span class="hljs-attr">schedule:</span><br>    <span class="hljs-bullet">-</span> <span class="hljs-attr">cron:</span> <span class="hljs-string">&#x27;0 0 * * *&#x27;</span> <span class="hljs-comment"># Every day</span><br><br><span class="hljs-attr">jobs:</span><br>  <span class="hljs-attr">meta:</span><br>    <span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">meta</span><br>    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span><br>    <span class="hljs-attr">timeout-minutes:</span> <span class="hljs-number">10</span><br>    <span class="hljs-attr">steps:</span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span><br>        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span><br>        <span class="hljs-attr">with:</span><br>          <span class="hljs-attr">ref:</span> <span class="hljs-string">main</span><br><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Do</span> <span class="hljs-string">meta</span> <span class="hljs-string">update</span><br>        <span class="hljs-attr">shell:</span> <span class="hljs-string">bash</span><br>        <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br><span class="hljs-string">          npm install</span><br><span class="hljs-string">          npx hexo bangumis -u || echo</span><br><span class="hljs-string"></span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Commit</span> <span class="hljs-string">files</span><br>        <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br><span class="hljs-string">          git config --local user.email &quot;41898282+github-actions[bot]@users.noreply.github.com&quot;</span><br><span class="hljs-string">          git config --local user.name &quot;github-actions[bot]&quot;</span><br><span class="hljs-string">          git add .</span><br><span class="hljs-string">          git commit -m &quot;Update meta on $(date &#x27;+%Y-%m-%d %H:%M:%S&#x27;)&quot; || echo</span><br><span class="hljs-string"></span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Push</span> <span class="hljs-string">changes</span><br>        <span class="hljs-attr">uses:</span> <span class="hljs-string">ad-m/github-push-action@master</span><br>        <span class="hljs-attr">with:</span><br>          <span class="hljs-attr">github_token:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">&#125;&#125;</span><br>          <span class="hljs-attr">branch:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">github.ref</span> <span class="hljs-string">&#125;&#125;</span><br><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Do</span> <span class="hljs-string">build</span><br>        <span class="hljs-attr">shell:</span> <span class="hljs-string">bash</span><br>        <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br><span class="hljs-string">          npm run build</span><br><span class="hljs-string"></span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">🚀</span><br>        <span class="hljs-attr">uses:</span> <span class="hljs-string">JamesIves/github-pages-deploy-action@releases/v3</span><br>        <span class="hljs-attr">with:</span><br>          <span class="hljs-attr">GITHUB_TOKEN:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">&#125;&#125;</span><br>          <span class="hljs-attr">BRANCH:</span> <span class="hljs-string">gh-pages</span> <span class="hljs-comment"># The branch the action should deploy to.</span><br>          <span class="hljs-attr">FOLDER:</span> <span class="hljs-string">public</span> <span class="hljs-comment"># The folder the action should deploy.</span><br></code></pre></td></tr></table></figure><h2 id="牛逼之处"><a href="#牛逼之处" class="headerlink" title="牛逼之处"></a>牛逼之处</h2><ul><li>使用 <a href="https://bgm.tv/">bgm.tv</a> 的官方 <a href="https://github.com/bangumi/api">API</a> 来进行爬取，番剧更多，可用性更高</li><li>支持数据缓存及番剧封面图本地化，防止因上游服务挂掉导致连锁效应，爬取好番剧后可纯离线场景下部署</li><li>极端条件下可通过编辑文件来自定义番剧列表，可自定义添加 <a href="https://bgm.tv/">bgm.tv</a> 没有的番剧</li><li>总的来说，只要你爬取过这个番剧，那么就算将来 <a href="https://bgm.tv/">bgm.tv</a> 上把这个番剧删掉了，你也可以继续使用这个番剧</li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;作为一个老二次元，我经常看番，但随着自己看过的番剧数量增多，在与其他二次元同好交流喜欢的番剧时，往往都是听到一个番，啊这个我看过，那个我也看过，到了让你自己说出几个喜欢的番剧时，一个字都蹦不出来。如果俩人都是社恐，那场面就更尴尬了。&lt;/p&gt;
&lt;p&gt;为了解决这个尴尬，我在博客里创建了一个追番列表，你可以访问这个网址来了解我都看过哪些番剧，这样交流起来是不是就容易多了呢？现在我每次遇到二次元同好，啥也不说，把这个网址发给人家，他就会指着这里面的番剧说：啊这个我看过，那个我也看过。对吧，有效地解决了社恐二次元的烦恼。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
  </entry>
  
  <entry>
    <title>GitHub 自动更新依赖</title>
    <link href="https://mmdjiji.com/2023/1.html"/>
    <id>https://mmdjiji.com/2023/1.html</id>
    <published>2023-01-31T13:55:42.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p>本文介绍了在 GitHub 中自动更新依赖（包括但不限与包管理器为 <code>pip</code>, <code>npm</code> 等）的方法。</p><span id="more"></span><h2 id="Dependabot"><a href="#Dependabot" class="headerlink" title="Dependabot"></a>Dependabot</h2><p><a href="https://github.com/dependabot/dependabot-core">Dependabot</a> 是 GitHub 官方的一款依赖更新工具，在配置好后，它会自动定期（周期可以自己配置）从包管理器中扫描最新依赖，与工程中使用的依赖进行比对，如果发现版本的升级，则提出一个 Pull Request 以用于更新依赖。</p><p>配置 Dependabot 的方法很简单，只需合理地编辑 <code>.github/dependabot.yml</code> 文件，官方参考文档<a href="https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file">在此</a>。</p><p>例如，项目的包管理器使用 <code>pip</code>，要求每周扫描一次更新，就可以按照如下进行配置：</p><figure class="highlight yml"><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><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-number">2</span><br><span class="hljs-attr">updates:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">package-ecosystem:</span> <span class="hljs-string">pip</span><br>    <span class="hljs-attr">directory:</span> <span class="hljs-string">/</span><br>    <span class="hljs-attr">schedule:</span><br>      <span class="hljs-attr">interval:</span> <span class="hljs-string">weekly</span><br></code></pre></td></tr></table></figure><h2 id="Auto-Merge"><a href="#Auto-Merge" class="headerlink" title="Auto Merge"></a>Auto Merge</h2><p>在提出 Pull Request 后，就需要使用 GitHub Actions 执行 CI 以合并分支，编辑 <code>.github/workflows/auto-merge.yml</code> 文件如下：</p><figure class="highlight yml"><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></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">name:</span> <span class="hljs-string">Dependabot</span> <span class="hljs-string">Auto</span> <span class="hljs-string">Merge</span><br><span class="hljs-attr">on:</span><br>  <span class="hljs-attr">pull_request:</span><br>    <span class="hljs-attr">types:</span> [ <span class="hljs-string">labeled</span>, <span class="hljs-string">edited</span> ]<br><br><span class="hljs-attr">jobs:</span><br>  <span class="hljs-attr">dependabot:</span><br>    <span class="hljs-attr">name:</span> <span class="hljs-string">Dependabot</span><br>    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span><br>    <span class="hljs-attr">permissions:</span> <span class="hljs-string">write-all</span><br>    <span class="hljs-attr">if:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">github.actor</span> <span class="hljs-string">==</span> <span class="hljs-string">&#x27;dependabot[bot]&#x27;</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">github.event_name</span> <span class="hljs-string">==</span> <span class="hljs-string">&#x27;pull_request&#x27;</span><span class="hljs-string">&#125;&#125;</span><br>    <span class="hljs-attr">steps:</span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Enable</span> <span class="hljs-string">auto-merge</span> <span class="hljs-string">for</span> <span class="hljs-string">Dependabot</span> <span class="hljs-string">PRs</span><br>        <span class="hljs-attr">run:</span> <span class="hljs-string">gh</span> <span class="hljs-string">pr</span> <span class="hljs-string">merge</span> <span class="hljs-string">--auto</span> <span class="hljs-string">--merge</span> <span class="hljs-string">&quot;$PR_URL&quot;</span><br>        <span class="hljs-attr">env:</span><br>          <span class="hljs-attr">PR_URL:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">github.event.pull_request.html_url</span> <span class="hljs-string">&#125;&#125;</span><br>          <span class="hljs-attr">GITHUB_TOKEN:</span> <span class="hljs-string">$&#123;&#123;</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">&#125;&#125;</span><br></code></pre></td></tr></table></figure><p>按照自动化运维的规范，应先进行测试再合并，以保证代码能适应新版本的依赖。自动化测试的代码应添加在 <code>steps</code> 的第一步（因为第一步也就是唯一的步骤就是合并分支）之前，确保能通过测试后，就可以放心进行分支的合并了。否则，应该 throw 一个错误出来，供开发人员查阅。</p><h2 id="优点与缺点"><a href="#优点与缺点" class="headerlink" title="优点与缺点"></a>优点与缺点</h2><p>优点是这种操作节约了时间，并可以持续确保依赖的最新性，非常适合模板的仓库，因为模板的仓库不是最新就没有意义了，没有人愿意从一段旧代码开始自己的工作。</p><p>缺点是如果测试不够规范，将会产生一些安全问题，包括但不限于有些开发人员在新版本的依赖中故意引入缺陷等行为。所以对于稍大规模的项目，仍然建议人工审查 Pull Request，尤其是这种由自动化方式创建的 Pull Request，它们的恶意行为最不易被察觉。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;本文介绍了在 GitHub 中自动更新依赖（包括但不限与包管理器为 &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt; 等）的方法。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
  </entry>
  
  <entry>
    <title>加入十年之约</title>
    <link href="https://mmdjiji.com/2023/forever-blog.html"/>
    <id>https://mmdjiji.com/2023/forever-blog.html</id>
    <published>2023-01-05T09:50:20.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://www.foreverblog.cn/blog/3934.html">大事记页面</a> | <a href="https://www.foreverblog.cn/">十年之约官网</a></p><p>本人于2023年1月1日申请加入十年之约，于今日正式签约，特此记录。</p><p>希望本博客能持之以恒地存在十年，也希望我能在未来十年能有充足的写作动力。时光不老，我们不散，愿博客长存。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://www.foreverblog.cn/blog/3934.html&quot;&gt;大事记页面&lt;/a&gt; | &lt;a href=&quot;https://www.foreverblog.cn/&quot;&gt;十年之约官网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本人于2023年1月1日申请加入十</summary>
      
    
    
    
    <category term="公告" scheme="https://mmdjiji.com/categories/%E5%85%AC%E5%91%8A/"/>
    
    
  </entry>
  
  <entry>
    <title>2022 年终总结</title>
    <link href="https://mmdjiji.com/2022/7.html"/>
    <id>https://mmdjiji.com/2022/7.html</id>
    <published>2022-12-31T15:59:59.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p>谨以此致敬 2022 的远去。</p><span id="more"></span><blockquote><p>我并不是非常注重仪式感的人，有时我甚至认为结婚是不需要结婚证与婚礼的，结婚证只是离婚和给娃上户口时使用的工具，而婚礼不过是获得大家的祝福。但随着年龄的增大，我发现经历本身才是最有意义的事，你一生对事物的经历和体验，是其他人难以复制的，是任何人花钱也买不到的。我想多记录些什么，以便索引。</p></blockquote><h2 id="技术大事记"><a href="#技术大事记" class="headerlink" title="技术大事记"></a>技术大事记</h2><blockquote><p>个人技术的进步，和公司、国家其实是一样的，都是螺旋式上升的过程。</p></blockquote><ul><li>完成家庭服务器基础设施，全面使用软路由，WiFi 6 全覆盖</li><li>对电子元件的贴片的探索来到了 QFN48，0402 级别</li><li>添置了一个新工作台，提升焊接效率，磨刀不误砍柴工</li><li>完成了 <a href="https://github.com/jmpsvr/jmpsvr">Jump Server</a> 的开发，可以用它看监控了</li><li>对博客进行了全面升级，包括 CI&#x2F;CD，CDN，图片懒加载以及全面的速度优化，把博客的组件全部解耦合</li><li>复现了 <a href="https://github.com/fdivitto/FabGL">FabGL</a> 的硬件</li><li>续费了三年的大学生活</li></ul><h2 id="生活大事记"><a href="#生活大事记" class="headerlink" title="生活大事记"></a>生活大事记</h2><blockquote><p>我们，还是得赶快学会生活啊。——《三体》法律系的妹子</p></blockquote><ul><li>把老旧照片的底片数字化保存</li><li>添置了手办柜，可以将手办与礼物等放入展示</li><li>添置了扫地机器人，解放生产力</li><li>安装了投影仪，增加了看番体验</li><li>疫情终于要结束了，期待明年的春天</li></ul><h2 id="番剧漫谈"><a href="#番剧漫谈" class="headerlink" title="番剧漫谈"></a>番剧漫谈</h2><p>今年印象最深的科幻番就是《我的三体》，因为艺画开天《三体》的放送，就去补了隔壁业余组神游八方《我的三体》，但其实业余组比专业组的质量好太多。“自然选择，前进四”是我最喜欢的一句台词，致敬对人类文明的延续。</p><p>三体中的黑暗森林法则，以及众多科幻内容，其实也在我对宇宙的思考之中。我一直认为，宇宙是嵌套的，而倘若真的存在智子展开，可能展开后的智子就是内层宇宙。我认为可以这样理解：“原子核内部可能是一个宇宙，我们破坏它轻而易举，因为我们是降维打击它。但又没有那么容易，我们不会因为打个喷嚏就让原子核崩坏。所以原子核内可以稳定地存在宇宙，只要我们没有发现它。而我们发现它又如海底捞针，只要原子核里面的宇宙隐藏好自己，那么就像黑暗森林一样，哪怕高等文明，也难以发现。”</p><p>当然，今年看了很多非常可爱而治愈的动漫！《孤独摇滚》、《向山进发》、《学园孤岛》、《龙与虎》、《莉可丽丝》、《租借女友 第二季》、《柑橘味香气》、《Love Live!》系列、《邻家的吸血鬼小妹》、《来自风平浪静的明天》、《来自多彩世界的明天》、《测不准的阿波连同学》、《女孩的钓鱼慢活》、《约定的梦幻岛》系列等等……来年再拿这些做文章。</p><h2 id="展望，2023"><a href="#展望，2023" class="headerlink" title="展望，2023"></a>展望，2023</h2><p>希望明年疫情会真正的过去，我们的生活可以恢复到 19 年之前的样子。那样，明年的春天，就可以去玉渊潭赏樱花🌸，可以去听房东的猫的演唱会，可以去二次元里圣地巡礼。</p><p>明年，也是时候为我的大学生涯画上一个逗号，为本科生涯画上一个句号了。说来也巧，我大一的时候疫情悄然而至，变成了大学生活的阴霾，如今已经大四迎来了毕业，希望疫情也就烟消云散了。</p><p>23 年对我来说也是一个奋斗之年，有很多要学习的东西，也有很多要做的事情。希望能在这一年里踏踏实实学习，不断地变强。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;谨以此致敬 2022 的远去。&lt;/p&gt;</summary>
    
    
    
    <category term="公告" scheme="https://mmdjiji.com/categories/%E5%85%AC%E5%91%8A/"/>
    
    
  </entry>
  
  <entry>
    <title>Python 用 venv 创建虚拟环境</title>
    <link href="https://mmdjiji.com/2022/6.html"/>
    <id>https://mmdjiji.com/2022/6.html</id>
    <published>2022-12-09T02:26:56.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p>venv 是 Python3.3 以后的功能，<a href="https://docs.python.org/3/library/venv.html">官方文档在此</a>。</p><span id="more"></span><h2 id="创建虚拟环境"><a href="#创建虚拟环境" class="headerlink" title="创建虚拟环境"></a>创建虚拟环境</h2><p>先创建一个目录，这个目录作为当前 Python 工程的根：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">jiji@play:~$ <span class="hljs-built_in">mkdir</span> pycode &amp;&amp; <span class="hljs-built_in">cd</span> pycode<br></code></pre></td></tr></table></figure><p>使用如下命令创建一个 venv 虚拟环境：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">jiji@play:~/pycode$ python -m venv .<br></code></pre></td></tr></table></figure><p>在 Debian&#x2F;Ubuntu 系统中，需要单独安装 venv 的依赖，使用 <code>sudo apt install python3.8-venv</code> 为 Python 3.8 安装依赖：</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><code class="hljs bash">jiji@play:~/pycode$ python -m venv .<br>The virtual environment was not created successfully because ensurepip is not<br>available.  On Debian/Ubuntu systems, you need to install the python3-venv<br>package using the following <span class="hljs-built_in">command</span>.<br><br>    apt install python3.8-venv<br><br>You may need to use sudo with that <span class="hljs-built_in">command</span>.  After installing the python3-venv<br>package, recreate your virtual environment.<br></code></pre></td></tr></table></figure><p>随后再执行该命令即可，创建完成后目录下会增加几个文件：</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><code class="hljs bash">jiji@play:~/pycode$ python -m venv .venv<br>jiji@play:~/pycode$ <span class="hljs-built_in">ls</span> -la<br>total 12<br>drwxrwxr-x  3 jiji jiji 4096 Dec  9 03:01 .<br>drwxr-xr-x 12 jiji jiji 4096 Dec  9 02:31 ..<br>drwxrwxr-x  6 jiji jiji 4096 Dec  9 03:01 .venv<br>jiji@play:~/pycode$ <span class="hljs-built_in">cd</span> .venv<br>jiji@play:~/pycode/.venv$ <span class="hljs-built_in">ls</span><br>bin  include  lib  lib64  pyvenv.cfg  share<br></code></pre></td></tr></table></figure><h2 id="进入虚拟环境"><a href="#进入虚拟环境" class="headerlink" title="进入虚拟环境"></a>进入虚拟环境</h2><h3 id="POSIX"><a href="#POSIX" class="headerlink" title="POSIX"></a>POSIX</h3><table><thead><tr><th>Shell</th><th>Command</th></tr></thead><tbody><tr><td><code>bash</code> &#x2F; <code>zsh</code></td><td><code>$ source .venv/bin/activate</code></td></tr><tr><td><code>fish</code></td><td><code>$ source .venv/bin/activate.fish</code></td></tr><tr><td><code>csh</code> &#x2F; <code>tcsh</code></td><td><code>$ source .venv/bin/activate.csh</code></td></tr><tr><td><code>PowerShell</code></td><td><code>$ .venv/bin/Activate.ps1</code></td></tr></tbody></table><h3 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h3><table><thead><tr><th>Shell</th><th>Command</th></tr></thead><tbody><tr><td><code>cmd.exe</code></td><td><code>C:\&gt; .venv\Scripts\activate.bat</code></td></tr><tr><td><code>PowerShell</code></td><td><code>PS C:\&gt; .venv\Scripts\Activate.ps1</code></td></tr></tbody></table><p>在输入相关脚本后，命令行前面新增了一个 <code>(.venv)</code>，这就表明我们当前的命令行在虚拟环境中，与全局的环境隔离：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">jiji@play:~/pycode$ <span class="hljs-built_in">source</span> .venv/bin/activate<br>(.venv) jiji@play:~/pycode$<br></code></pre></td></tr></table></figure><p>我们可以在 Python 文件的第一行前加上如下代码，即可在运行时自动使用虚拟环境运行：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#!/.venv/bin/python</span><br></code></pre></td></tr></table></figure><h2 id="退出虚拟环境"><a href="#退出虚拟环境" class="headerlink" title="退出虚拟环境"></a>退出虚拟环境</h2><p>在虚拟环境内输入 <code>deactivate</code> 命令就能退出：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">(.venv) jiji@play:~/pycode$ deactivate<br>jiji@play:~/pycode$<br></code></pre></td></tr></table></figure><h2 id="与-VSCode-配合使用"><a href="#与-VSCode-配合使用" class="headerlink" title="与 VSCode 配合使用"></a>与 VSCode 配合使用</h2><blockquote><p>这波与 VSCode 配合的很好捏~</p></blockquote><p>在安装了 Python 的扩展后，VSCode 可以自动检测到目录下的 venv 环境并自动载入之，唯一需要注意的是请打开整个工程文件夹。</p><h2 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h2><p>我们在内部使用 pip 安装的依赖，不会被同步到全局，而是只存在于当前工程。这种设计与 npm 中的局部安装 <code>node_modules</code> 文件夹是类似的。</p><p>这种设计可以更方便而干净的导出依赖。我们在完成一个工程时可能会用到一些依赖，为了方便其他人安装，通常都需要导出 <code>requirements.txt</code> 以便于其他人复现，但如果采用全局安装，导出时通常会导出一些不必要的依赖（除非你为每个项目都安装了自己的 Python），因为 Python 的依赖是全局安装的，所以导出时总会把全部依赖导出。倘若在虚拟环境内部导出，就只会导出当前项目的依赖了，这样就方便而干净。</p><p>这种设计更便于处理依赖冲突，倘若我们需要在 A 项目中使用 flask&#x3D;&#x3D;1.0 而在 B 项目中使用 flask&#x3D;&#x3D;2.0，就最好使用 venv 进行管理，为每个项目都创建一个独立的虚拟环境而安装不同的模块版本，这样就可以同时运行多个项目而不会冲突。</p><h2 id="优雅地使用"><a href="#优雅地使用" class="headerlink" title="优雅地使用"></a>优雅地使用</h2><p>虽然您认为 venv 是个好用的工具，使用 Python 的最佳实践就是用它来管理依赖，但您不能假设所有人都使用它，因为它仍未成为行业的标准，仍然有不少人在使用全局安装或者 <a href="https://www.anaconda.com/">Anaconda</a> 等方案进行依赖管理。</p><p>由于 venv 本身和系统环境耦合，为了解耦合，在使用 Git 时，您的最佳实践是将 <code>.venv/</code> 写入 <code>.gitignore</code>，避免将 <code>.venv/</code> 提交到 Git 上。</p><p>您可以在 venv 环境中使用如下命令以导出依赖：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">pip freeze &gt; requirements.txt<br></code></pre></td></tr></table></figure><p>您可以指导用户（当然，您也可以在 venv 中这么做）使用下面的命令来安装依赖：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">pip install -r requirements.txt<br></code></pre></td></tr></table></figure><h2 id="包管理的哲学"><a href="#包管理的哲学" class="headerlink" title="包管理的哲学"></a>包管理的哲学</h2><h3 id="依赖是包"><a href="#依赖是包" class="headerlink" title="依赖是包"></a>依赖是包</h3><p>任何情况下依赖就是包，所以任何一个工程也可以变成依赖。依赖暴露一些接口，而工程导入这些接口就可以调用。</p><h3 id="可索引的依赖"><a href="#可索引的依赖" class="headerlink" title="可索引的依赖"></a>可索引的依赖</h3><p>所有的依赖都应该通过一个文件来索引，这个文件应该具有可读性，可以手工编辑，并且可通过包管理器安全地一键安装依赖。安全地安装依赖指，在安装完成之后，当前的代码应能访问到索引文件中依赖的正确版本，且安装过程中不应该影响到任何其他文件夹的项目。</p><h3 id="依赖的具体文件不同步"><a href="#依赖的具体文件不同步" class="headerlink" title="依赖的具体文件不同步"></a>依赖的具体文件不同步</h3><p>任何时候，依赖的具体文件应该由包管理器通过索引文件来进行安装，不应被同步到其他设备。只有依赖的索引文件可被同步。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;venv 是 Python3.3 以后的功能，&lt;a href=&quot;https://docs.python.org/3/library/venv.html&quot;&gt;官方文档在此&lt;/a&gt;。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Linux" scheme="https://mmdjiji.com/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>K3s 集群的安装、配置与使用</title>
    <link href="https://mmdjiji.com/2022/5.html"/>
    <id>https://mmdjiji.com/2022/5.html</id>
    <published>2022-09-12T15:36:15.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p><a href="https://k3s.io/">英文官网</a> | <a href="https://www.rancher.cn/k3s/">中文官网</a> | <a href="https://docs.rancher.cn/docs/k3s/_index/">中文文档</a></p><p>K3s 是一个轻量级的 Kubernetes 发行版，它针对边缘计算、物联网等场景进行了高度优化。本文将安装并配置一个 K3s 集群，并测试其的使用。</p><p>值得注意的是，与 Kubernetes 不同，这里的 <code>Master</code> 节点叫 <code>Server</code> 节点，而 <code>Slave</code> 节点叫 <code>Agent</code> 节点。</p><span id="more"></span><h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><table><thead><tr><th>主机名</th><th>IP</th><th>Role</th><th>vCPUs</th><th>RAM</th></tr></thead><tbody><tr><td>k3s-server</td><td>10.0.0.39</td><td>Server</td><td>2</td><td>2G</td></tr><tr><td>k3s-agent-1</td><td>10.0.0.31</td><td>Agent</td><td>2</td><td>2G</td></tr><tr><td>k3s-agent-2</td><td>10.0.0.32</td><td>Agent</td><td>2</td><td>2G</td></tr></tbody></table><h2 id="网络与端口"><a href="#网络与端口" class="headerlink" title="网络与端口"></a>网络与端口</h2><p>k3s-server 需要 <code>6443</code> 端口才能被所有节点访问。</p><p>其他参考<a href="https://docs.rancher.cn/docs/k3s/installation/installation-requirements/_index#%E7%BD%91%E7%BB%9C">这里</a>。</p><h2 id="部署-Server-节点"><a href="#部署-Server-节点" class="headerlink" title="部署 Server 节点"></a>部署 Server 节点</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># curl -sfL https://get.k3s.io | sh -</span><br></code></pre></td></tr></table></figure><p>使用如下命令查看节点运行状态：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl get node</span><br>NAME         STATUS   ROLES                  AGE   VERSION<br>k3s-server   Ready    control-plane,master   20s   v1.24.4+k3s1<br></code></pre></td></tr></table></figure><p>使用如下命令获取 <code>node-token</code>：</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs ruby">root<span class="hljs-variable">@k3s</span>-<span class="hljs-symbol">server:</span>~<span class="hljs-comment"># cat /var/lib/rancher/k3s/server/node-token</span><br><span class="hljs-title class_">K101e23ad4c6b37c9fdf</span>****<span class="hljs-symbol">:</span><span class="hljs-symbol">:server</span><span class="hljs-symbol">:****f7538ded6</span><br></code></pre></td></tr></table></figure><p>这个 <code>node-token</code> 一会在部署 Agent 节点的时候需要用到。</p><h2 id="部署-Agent-节点"><a href="#部署-Agent-节点" class="headerlink" title="部署 Agent 节点"></a>部署 Agent 节点</h2><p>对于每个 Agent 节点，使用如下命令安装 K3s 并直接加入集群：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-agent-1:~<span class="hljs-comment"># curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -</span><br></code></pre></td></tr></table></figure><p>例如：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-agent-1:~<span class="hljs-comment"># curl -sfL https://get.k3s.io | K3S_URL=https://10.0.0.39:6443 K3S_TOKEN=K101e23ad4c6b37c9fdf****::server:****f7538ded6 sh -</span><br></code></pre></td></tr></table></figure><p>执行完成后，到 <code>Server</code> 节点查看所有节点状态：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl get node</span><br>NAME          STATUS   ROLES                  AGE   VERSION<br>k3s-server    Ready    control-plane,master   25m   v1.24.4+k3s1<br>k3s-agent-1   Ready    &lt;none&gt;                 18s   v1.24.4+k3s1<br></code></pre></td></tr></table></figure><p>同样，对于 <code>k3s-agent-2</code> 也做同样的部署，完成后节点状态如下：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl get node</span><br>NAME          STATUS   ROLES                  AGE     VERSION<br>k3s-server    Ready    control-plane,master   31m     v1.24.4+k3s1<br>k3s-agent-2   Ready    &lt;none&gt;                 3m36s   v1.24.4+k3s1<br>k3s-agent-1   Ready    &lt;none&gt;                 6m19s   v1.24.4+k3s1<br></code></pre></td></tr></table></figure><p>设置 <code>K3S_URL</code> 参数会使 K3s 以 worker 模式运行。K3s agent 将在所提供的 URL 上向监听的 K3s 服务器注册。<code>K3S_TOKEN</code> 使用的值存储在你的服务器节点上的 <code>/var/lib/rancher/k3s/server/node-token</code> 路径下。</p><h2 id="创建-Pod"><a href="#创建-Pod" class="headerlink" title="创建 Pod"></a>创建 Pod</h2><p>将以下代码写入 <code>nginx-pod.yaml</code>：</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span><br><span class="hljs-attr">kind:</span> <span class="hljs-string">Pod</span><br><span class="hljs-attr">metadata:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span><br><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">containers:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span><br>    <span class="hljs-attr">image:</span> <span class="hljs-string">nginx:latest</span><br>    <span class="hljs-attr">ports:</span><br>    <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span><br></code></pre></td></tr></table></figure><p>使用如下命令应用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl apply -f nginx-pod.yaml</span><br>pod/nginx created<br></code></pre></td></tr></table></figure><p>查看运行状态：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl get pod</span><br>NAME    READY   STATUS    RESTARTS   AGE<br>nginx   1/1     Running   0          11h<br></code></pre></td></tr></table></figure><blockquote><p>与 Docker 不同，这里进入容器的需要在命令前加上 <code>--</code></p></blockquote><p>进入 Pod 并测试访问：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl exec -it nginx -- /bin/bash</span><br>root@nginx:/<span class="hljs-comment"># curl localhost</span><br>&lt;!DOCTYPE html&gt;<br>&lt;html&gt;<br>&lt;<span class="hljs-built_in">head</span>&gt;<br>&lt;title&gt;Welcome to nginx!&lt;/title&gt;<br>&lt;style&gt;<br>html &#123; color-scheme: light dark; &#125;<br>body &#123; width: 35em; margin: 0 auto;<br>font-family: Tahoma, Verdana, Arial, sans-serif; &#125;<br>&lt;/style&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;h1&gt;Welcome to nginx!&lt;/h1&gt;<br>&lt;p&gt;If you see this page, the nginx web server is successfully installed and<br>working. Further configuration is required.&lt;/p&gt;<br><br>&lt;p&gt;For online documentation and support please refer to<br>&lt;a href=<span class="hljs-string">&quot;http://nginx.org/&quot;</span>&gt;nginx.org&lt;/a&gt;.&lt;br/&gt;<br>Commercial support is available at<br>&lt;a href=<span class="hljs-string">&quot;http://nginx.com/&quot;</span>&gt;nginx.com&lt;/a&gt;.&lt;/p&gt;<br><br>&lt;p&gt;&lt;em&gt;Thank you <span class="hljs-keyword">for</span> using nginx.&lt;/em&gt;&lt;/p&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;<br></code></pre></td></tr></table></figure><p>到此为止，我们创建了一个功能正常的 Pod。</p><h2 id="创建-Deployment"><a href="#创建-Deployment" class="headerlink" title="创建 Deployment"></a>创建 Deployment</h2><p>将以下代码写入 <code>nginx-deployment.yaml</code>：</p><figure class="highlight yaml"><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><code class="hljs yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span><br><span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span><br><span class="hljs-attr">metadata:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span><br><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">selector:</span><br>    <span class="hljs-attr">matchLabels:</span><br>      <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span><br>  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span><br>  <span class="hljs-attr">template:</span><br>    <span class="hljs-attr">metadata:</span><br>      <span class="hljs-attr">labels:</span><br>        <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span><br>    <span class="hljs-attr">spec:</span><br>      <span class="hljs-attr">containers:</span><br>      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span><br>        <span class="hljs-attr">image:</span> <span class="hljs-string">nginx:latest</span><br>        <span class="hljs-attr">ports:</span><br>        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span><br></code></pre></td></tr></table></figure><p>使用如下命令应用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl apply -f nginx-deployment.yaml</span><br>deployment.apps/nginx created<br></code></pre></td></tr></table></figure><p>查看运行状态：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl get deployment</span><br>NAME    READY   UP-TO-DATE   AVAILABLE   AGE<br>nginx   2/2     2            2           29s<br></code></pre></td></tr></table></figure><p>此时再查看 Pod，如下：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl get pod</span><br>NAME                     READY   STATUS    RESTARTS   AGE<br>nginx-544dc8b7c4-lzvz9   1/1     Running   0          3m4s<br>nginx-544dc8b7c4-5nbcw   1/1     Running   0          3m4s<br></code></pre></td></tr></table></figure><p>可以看到，由 Deployment 产生的 Pod 命名规则如下：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-variable">$&#123;DeploymentName&#125;</span>-<span class="hljs-variable">$&#123;DeploymentUid&#125;</span>-<span class="hljs-variable">$&#123;Hash&#125;</span><br></code></pre></td></tr></table></figure><p>在查看 Pod 的时候，如果加上 <code>-o wide</code> 参数，就可以查看更多信息：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl get pod -o wide</span><br>NAME                     READY   STATUS    RESTARTS   AGE     IP          NODE          NOMINATED NODE   READINESS GATES<br>nginx-544dc8b7c4-lzvz9   1/1     Running   0          9m30s   10.42.1.4   k3s-agent-1   &lt;none&gt;           &lt;none&gt;<br>nginx-544dc8b7c4-5nbcw   1/1     Running   0          9m30s   10.42.3.3   k3s-agent-2   &lt;none&gt;           &lt;none&gt;<br></code></pre></td></tr></table></figure><p>可以看到，该 nginx 被创建了两个 Pod 副本，分别部署在了 <code>k3s-agent-1</code> 和 <code>k3s-agent-2</code> 上面。</p><h2 id="创建-Service"><a href="#创建-Service" class="headerlink" title="创建 Service"></a>创建 Service</h2><p>Service，将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。</p><p>举个例子，考虑一个图片处理后端，它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化， 前端客户端不应该也没必要知道，而且也不需要跟踪这一组后端的状态。</p><p>Service 定义的抽象能够解耦这种关联。</p><p>Service 有两种类型，一种是 <code>NodePort</code>，选择该种类型的可直接通过 <code>$&#123;serverIP&#125;:$&#123;nodePort&#125;</code> 访问内部的服务；另一种是 <code>ClusterIP</code> 类型，它只会在集群内部可以访问到该 Pod，不会把 Pod 的内容映射在某一个外网可以访问的端口上，但这并不意味着不能对外提供服务，而是需要 Ingress 的帮助，来将外网的流量转发到 Service 上来。</p><h3 id="NodePort"><a href="#NodePort" class="headerlink" title="NodePort"></a>NodePort</h3><p>将以下代码写入 <code>nginx-service-nodeport.yaml</code>：</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span><br><span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span><br><span class="hljs-attr">metadata:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx-service</span><br><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">selector:</span><br>    <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span><br>  <span class="hljs-attr">ports:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span><br>    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span><br>    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span><br>    <span class="hljs-attr">nodePort:</span> <span class="hljs-number">30080</span><br>  <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span><br></code></pre></td></tr></table></figure><p>这里 <code>nodePort</code> 的范围是 <code>30000-32767</code>。</p><p>使用如下命令应用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl apply -f nginx-service-nodeport.yaml </span><br>service/nginx-service created<br></code></pre></td></tr></table></figure><p>现在访问 <code>http://10.0.0.39:30080</code>、 <code>http://10.0.0.31:30080</code> 与 <code>http://10.0.0.32:30080</code>，都可以正常访问到内容：</p><p><img src="/images/2022/09/1.png" alt="访问测试"></p><p>查看 Service：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl get service</span><br>NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE<br>kubernetes      ClusterIP   10.43.0.1      &lt;none&gt;        443/TCP        12h<br>nginx-service   NodePort    10.43.74.219   &lt;none&gt;        80:30080/TCP   7m21s<br></code></pre></td></tr></table></figure><h3 id="ClusterIP"><a href="#ClusterIP" class="headerlink" title="ClusterIP"></a>ClusterIP</h3><h4 id="Service"><a href="#Service" class="headerlink" title="Service"></a>Service</h4><p>将以下代码写入 <code>nginx-service-clusterip.yaml</code>：</p><figure class="highlight yaml"><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><code class="hljs yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span><br><span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span><br><span class="hljs-attr">metadata:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx-service</span><br><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">selector:</span><br>    <span class="hljs-attr">app:</span> <span class="hljs-string">nginx</span><br>  <span class="hljs-attr">ports:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span><br>    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span><br>    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span><br></code></pre></td></tr></table></figure><p>使用如下命令应用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl apply -f nginx-service-clusterip.yaml </span><br>service/nginx-service created<br></code></pre></td></tr></table></figure><p>这样就创建了 Service，但外部还不能访问，所以需要 Ingress。</p><h4 id="Ingress"><a href="#Ingress" class="headerlink" title="Ingress"></a>Ingress</h4><p>先做个 DNS 解析：</p><table><thead><tr><th>类型</th><th>名称</th><th>内容</th></tr></thead><tbody><tr><td>A</td><td>*.k3s.jiji.pro</td><td>10.0.0.39</td></tr><tr><td>A</td><td>*.k3s.jiji.pro</td><td>10.0.0.31</td></tr><tr><td>A</td><td>*.k3s.jiji.pro</td><td>10.0.0.32</td></tr></tbody></table><p>将以下代码写入 <code>nginx-ingress.yaml</code>：</p><figure class="highlight yaml"><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></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span><br><span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span><br><span class="hljs-attr">metadata:</span><br>  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx-ingress</span><br><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">rules:</span><br>    <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">nginx.k3s.jiji.pro</span><br>      <span class="hljs-attr">http:</span><br>        <span class="hljs-attr">paths:</span><br>          <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/</span><br>            <span class="hljs-attr">pathType:</span> <span class="hljs-string">Prefix</span><br>            <span class="hljs-attr">backend:</span> <br>              <span class="hljs-attr">service:</span><br>                <span class="hljs-attr">name:</span> <span class="hljs-string">nginx-service</span><br>                <span class="hljs-attr">port:</span><br>                  <span class="hljs-attr">number:</span> <span class="hljs-number">80</span><br></code></pre></td></tr></table></figure><p>使用如下命令应用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-server:~/k3s<span class="hljs-comment"># kubectl apply -f nginx-ingress.yaml </span><br>ingress.networking.k8s.io/nginx-ingress created<br></code></pre></td></tr></table></figure><p>现在访问 <code>http://nginx.k3s.jiji.pro</code> 即可访问到部署的服务：</p><p><img src="/images/2022/09/2.png" alt="访问测试"></p><p>尝试关掉 <code>k3s-agent-1</code>：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">root@k3s-agent-1:/home/jiji<span class="hljs-comment"># shutdown -h now</span><br></code></pre></td></tr></table></figure><p>证实 <code>k3s-agent-1</code> 确实下线了：</p><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl get node</span><br>NAME          STATUS     ROLES                  AGE   VERSION<br>k3s-server    Ready      control-plane,master   13h   v1.24.4+k3s1<br>k3s-agent-2   Ready      &lt;none&gt;                 12h   v1.24.4+k3s1<br>k3s-agent-1   NotReady   &lt;none&gt;                 12h   v1.24.4+k3s1<br></code></pre></td></tr></table></figure><p>再访问 <code>http://nginx.k3s.jiji.pro</code>，服务出现不可用，但刷新后也可访问正常。经过两次连续的 ping，我们发现 DNS 解析由原本失效的 <code>10.0.0.31</code>，变为了 <code>10.0.0.39</code>。这也就保证了在 Agent 宕机的情况下服务高可用。</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><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><code class="hljs sh">$ ping nginx.k3s.jiji.pro<br><br>正在 Ping nginx.k3s.jiji.pro [10.0.0.31] 具有 32 字节的数据:<br>来自 10.0.0.1 的回复: 无法访问目标主机。<br>来自 10.0.0.1 的回复: 无法访问目标主机。<br>来自 10.0.0.1 的回复: 无法访问目标主机。<br>来自 10.0.0.1 的回复: 无法访问目标主机。<br><br>10.0.0.31 的 Ping 统计信息:<br>    数据包: 已发送 = 4，已接收 = 4，丢失 = 0 (0% 丢失)，<br><br>$ ping nginx.k3s.jiji.pro<br><br>正在 Ping nginx.k3s.jiji.pro [10.0.0.39] 具有 32 字节的数据:<br>来自 10.0.0.39 的回复: 字节=32 时间=3ms TTL=63<br>来自 10.0.0.39 的回复: 字节=32 时间=5ms TTL=63<br>来自 10.0.0.39 的回复: 字节=32 时间=5ms TTL=63<br>来自 10.0.0.39 的回复: 字节=32 时间=12ms TTL=63<br><br>10.0.0.39 的 Ping 统计信息:<br>    数据包: 已发送 = 4，已接收 = 4，丢失 = 0 (0% 丢失)，<br>往返行程的估计时间(以毫秒为单位):<br>    最短 = 3ms，最长 = 12ms，平均 = 6ms<br></code></pre></td></tr></table></figure><p>但当我关闭 <code>k3s-server</code> 的时候，服务出现了不可用，且无自动切换。或许对于高可用 K3s 集群来说，需要至少两台 <code>Server</code> 节点。</p><h4 id="HTTPS"><a href="#HTTPS" class="headerlink" title="HTTPS"></a>HTTPS</h4><figure class="highlight bash"><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><code class="hljs bash">root@k3s-server:~<span class="hljs-comment"># kubectl create secret tls my-tls-secret \</span><br>  --cert=path/to/cert/file \<br>  --key=path/to/key/file<br></code></pre></td></tr></table></figure><p>在 <code>nginx-ingress.yaml</code> 中追加：</p><figure class="highlight yaml"><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><code class="hljs yaml"><span class="hljs-attr">spec:</span><br>  <span class="hljs-attr">tls:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">hosts:</span><br>    <span class="hljs-bullet">-</span> <span class="hljs-string">nginx.k3s.jiji.pro</span><br>    <span class="hljs-attr">secretName:</span> <span class="hljs-string">my-tls-secret</span><br></code></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://k3s.io/&quot;&gt;英文官网&lt;/a&gt; | &lt;a href=&quot;https://www.rancher.cn/k3s/&quot;&gt;中文官网&lt;/a&gt; | &lt;a href=&quot;https://docs.rancher.cn/docs/k3s/_index/&quot;&gt;中文文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;K3s 是一个轻量级的 Kubernetes 发行版，它针对边缘计算、物联网等场景进行了高度优化。本文将安装并配置一个 K3s 集群，并测试其的使用。&lt;/p&gt;
&lt;p&gt;值得注意的是，与 Kubernetes 不同，这里的 &lt;code&gt;Master&lt;/code&gt; 节点叫 &lt;code&gt;Server&lt;/code&gt; 节点，而 &lt;code&gt;Slave&lt;/code&gt; 节点叫 &lt;code&gt;Agent&lt;/code&gt; 节点。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="工具" scheme="https://mmdjiji.com/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Linux" scheme="https://mmdjiji.com/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>阿德勒心理学是一种哲学</title>
    <link href="https://mmdjiji.com/2022/4.html"/>
    <id>https://mmdjiji.com/2022/4.html</id>
    <published>2022-09-07T15:06:02.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<p>在开始讨论之前，不妨通过<a href="https://youtu.be/5cZxZCbcOQw">老高與小茉的影片</a>了解一下<a href="https://en.wikipedia.org/wiki/Alfred_Adler">阿德勒</a>和他的观点，本文将简单阐述他的观点，并聊一聊这是一种什么样的哲学。</p><span id="more"></span><h2 id="高内聚，低耦合"><a href="#高内聚，低耦合" class="headerlink" title="高内聚，低耦合"></a>高内聚，低耦合</h2><blockquote><p>哲人：是的。即使你能将其带到水边也无法强迫其喝水。——岸见一郎《幸福的勇气》</p></blockquote><p>在阿德勒看来，我们做任何事都应该“课题分离”，说白了就是不要多管闲事，自己管好自己的事。这种思想我相信没有人不知道，但是往往效果不是很好。很多情况下，你不得不去管别人的事——因为那件事切身地影响了你的利益，你和别人在某种程度上是一个命运共同体，无论是自愿还是被迫组成的。</p><p>在计算机工程中我们通常会把“课题分离”说成是“高内聚，低耦合”。什么是“高内聚”呢？就是尽可能只让一个模块负责一个功能。“低耦合”就是在说不要让两个负责不同业务的模块产生太多联系，应该尽可能地分离。这是一种设计模式——单一责任原则，其实就是计算机工程实践中的哲学。</p><p>之所以提出“高内聚，低耦合”，其实不难想象。计算机发展的这么些年里，肯定出现过很多糟糕而难以维护的代码，它们大多都是依赖于bug运行的，牵一发而动全身。想向这种烂代码里添加一个功能，就要冒着巨大的风险，有时候甚至还会把整个系统搞崩。其实这不是计算机的问题，这是人脑的缺陷，人脑很难同时处理太多的信息，而一个巨大的工程往往不可能被大脑同时处理，换句话说就是人脑的思考没有穷举代码的执行路径（当然这就需要测试），只是选择了当前认为的最优解（类似于贪心算法），所以经常会出现bug。</p><h2 id="命运共同体"><a href="#命运共同体" class="headerlink" title="命运共同体"></a>命运共同体</h2><p>理性人，都喜欢博弈论。而命运共同体，就是建立一个组织，组织内的人具有相同的目标，这样获得的利益最大，甚至大过背叛。这是一种非常好的合作形式，因为它往往比较稳定，适合长期协作。例如合作伙伴关系的公司，夫妻二人，甚至是原为冤家但因利益临时结盟的团体，都可以组成这种命运共同体。这种命运共同体甚至可以推广到大国博弈，有核国家之间都不愿发动核战争，因为核捆绑的缘故，所以不发动核战争的都是赢家。</p><p>要想保障这个命运共同体的可靠，就需要让这个命运共同体能为加入者带来的利益足够大。这就像“零信任网络”一样，之所以要建立安全加密的可信网络，就是因为我们身处“零信任”之中，我们的报文在每一级的路由转发中都是透明的，要想保证不被窃听、重放，就需要加密。正是因为利益足够大，所以命运共同体就足够可靠。是啊，我们信不过人性，还信不过利益吗？</p><h2 id="尊重和爱"><a href="#尊重和爱" class="headerlink" title="尊重和爱"></a>尊重和爱</h2><blockquote><p>哲人：例如，假设公司的领导是强势的独裁者，的确，员工们也许会无条件地服从命令，假装顺从。但是，这是基于恐惧的服从，根本没有一丁点尊重。即使领导高呼“必须尊重我”，也不会有人尊重，只会越来越离心。——岸见一郎《幸福的勇气》</p></blockquote><p>尊重和爱，就是一种充分地接纳。一个人并不完美，往往他具有的优点，而缺点并不都是有意的，很多也是由潜意识支配的。我们无法要求一个人能够支配潜意识，如果你能理解潜意识和意识的区别，想必也更能接纳一个人的缺点吧。要先尊重，再学会爱，要尊重ta的差异，并爱ta的所有。</p><h2 id="认知差别"><a href="#认知差别" class="headerlink" title="认知差别"></a>认知差别</h2><p>如果我问你：“一部智能手机和一束百合花（不是 <a href="https://en.wikipedia.org/wiki/Lesbian">Lesbian</a>）哪个更简单？”你会如何回答？</p><p>有的人会回答，那必然是百合花啊。花开花落，无非就是那么一束花，而智能手机结合网络，能够迅速了解时事。</p><p>也有的人会回答，那比如是手机啊。手机是人造的，总共也就那么些零件，而花是非常神奇的，我们至今都没有研究透所有花朵细胞与所有信号的传递过程，甚至对它的基因学研究也很有限。</p><p>这可能就是认知上的差别，不同的人对待同一事物的认知是不一样的，这可以说是思考角度的不同，但这必然是一个人的习惯的角度。每个人都有其自己独特思考问题的角度，如果不去相互尊重这种区别，非要步调一致地去思考问题，我想，那很多人思考和一个人思考又有什么区别呢？所以说我们需要充分尊重认知上的差异。</p><h2 id="任何人都可以随时获得幸福"><a href="#任何人都可以随时获得幸福" class="headerlink" title="任何人都可以随时获得幸福"></a>任何人都可以随时获得幸福</h2><p>转变观念，即可获得幸福。阿德勒心理学，其实更像是一种哲学。既然人的一切烦恼都来源于人际关系，那么我们就用课题分离的方法来解决这个问题，从而解决我们的烦恼。</p><h2 id="推荐阅读"><a href="#推荐阅读" class="headerlink" title="推荐阅读"></a>推荐阅读</h2><ul><li>岸见一郎 <a href="https://book.douban.com/subject/26369699/">《被讨厌的勇气》</a></li><li>岸见一郎 <a href="https://book.douban.com/subject/27039296/">《幸福的勇气》</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;在开始讨论之前，不妨通过&lt;a href=&quot;https://youtu.be/5cZxZCbcOQw&quot;&gt;老高與小茉的影片&lt;/a&gt;了解一下&lt;a href=&quot;https://en.wikipedia.org/wiki/Alfred_Adler&quot;&gt;阿德勒&lt;/a&gt;和他的观点，本文将简单阐述他的观点，并聊一聊这是一种什么样的哲学。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
  </entry>
  
  <entry>
    <title>《山田君与7个魔女》番评</title>
    <link href="https://mmdjiji.com/2022/3.html"/>
    <id>https://mmdjiji.com/2022/3.html</id>
    <published>2022-08-31T08:02:27.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>区区一只亚麻大</p></blockquote><h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>最近看了一部番，叫<a href="https://bgm.tv/subject/118906">《山田君与7个魔女》</a>，非常值得推荐给你。这部番与我之前看的<a href="https://bgm.tv/subject/120925">《Charlotte》</a>、<a href="https://bgm.tv/subject/1671">物语系列</a>、<a href="https://bgm.tv/subject/240038">《青春猪头少年》</a>都有一些共性，我们一会谈。我想先讲一下这部番的大致内容，第一集大概是讲述了一个不良少年，与校花在走楼梯的时候摔了不小心接吻了，然后这两人的身体就发生了互换，后来经过实验证实男主和谁接吻都可以进行身体互换，也就是说，交换身体，这是男主的超能力。</p><span id="more"></span><p>表面来看，男主的超能力是和别人交换身体，但是实际上拥有这个能力的却是校花，男主的能力更为强大，是可以复制别人的能力。这点与<a href="https://bgm.tv/subject/120925">《Charlotte》</a>就比较类似，男主的能力最初大家都认为是附身，但是最后发现男主只是通过附身别人来夺取别人能力的超能力。</p><h2 id="深入"><a href="#深入" class="headerlink" title="深入"></a>深入</h2><p>所以这部番的重点开始渐渐浮出水面，原来有7位魔女，她们拥有超能力，而校花的超能力是交换身体。于是在好奇心的驱使下他们便开始对超能力进行研究。他们逐渐认为，<strong>拥有超能力是因为一个人有痛苦的经历，拥有的超能力恰恰是为了弥补自己的痛苦，或者说是自卑</strong>。比如校花女主原本性格孤僻，没有朋友，经常受欺负，为了打发生活只好默默学习。但其实她特别希望交到朋友，也不希望受欺负，所以就获得了与他人交换身体的超能力，大概是希望可以和一个能帮助她的人交换，然后实现自己的愿望。而小田切宁宁想与别人竞争学生会长，于是获得了俘获的能力，可以俘获别人加入自己的势力。</p><p>就这个角度而言，每个人获得能力是因为自己需要得到救赎，作者行文思路与<a href="https://bgm.tv/subject/1671">物语系列</a>可以说是有异曲同工之妙。为什么我说<a href="https://bgm.tv/subject/1671">物语系列</a>？因为<a href="https://bgm.tv/subject/1671">物语系列</a>产生怪异的根本原因还是个人内心原因，比如说<a href="https://zh.moegirl.org.cn/index.php?title=%E9%98%BF%E8%89%AF%E8%89%AF%E6%9C%A8%E5%8E%86&oldid=6310347">阿良良木君</a>之所以遇到<a href="https://zh.moegirl.org.cn/index.php?title=%E5%85%AB%E4%B9%9D%E5%AF%BA%E7%9C%9F%E5%AE%B5&oldid=6266049">894</a>然后迷路就是因为他不想回家，所以跟着迷途之牛走，自然也就会迷路。</p><h2 id="超能力与我的思考"><a href="#超能力与我的思考" class="headerlink" title="超能力与我的思考"></a>超能力与我的思考</h2><p>再来说说超能力的问题。<a href="https://bgm.tv/subject/118906">《山田君与7个魔女》</a>这部番和<a href="https://bgm.tv/subject/120925">《Charlotte》</a>这部番里面的超能力很是相似。前者男主的超能力是复制别人的能力，后者男主的超能力是夺走别人的能力。而最开始男主都并没有想到这一点，只是以为自己能进行身体交换或者是附身。</p><p>关于这个超能力，我有个疑问吧算是，是不是只要出现了超能力，一定会有人利用超能力去统治他人，而还有一些人只会用超能力去解决苦痛，带来幸福呢？我注意到好像大多数的番剧都是这样的，只要出现了超能力，就一定会有好人和坏人，他们的界限就是，是不是在用超能力为人民谋幸福，为民族谋复兴。我觉得不只是超能力，<strong>只要有了权力，就必然会有“好人”和“坏人”，好人实现大家的欲望，坏人只实现自己的欲望</strong>。</p><p>那么我不禁开始思考，如果一个人遭遇痛苦经历，那么出现超能力对这个人来说是好事还是坏事呢？我想既然超能力在这里是一种补偿机制，我又想到了心理学中的一个观点：“一个人越是自卑，越是需要变得比别人更强大来证明自己”但这种补偿机制真的会让这个人更健康地发展吗？我个人认为短期内可能有好处，长期肯定百害而无一利。</p><p><a href="https://en.wikipedia.org/wiki/Alfred_Adler">阿德勒</a>说过，一切烦恼都来源于人际关系，其实这部番也正面地直接印证了这个观点。而解决这个烦恼的方法，同样也很简单，那就是<strong>不要为了别人而活，不要为了成为父母口中的乖孩子，成为老师口中的优秀生，成为公司里的好员工而活，而是要为了自己的幸福而活</strong>。好像有点儿跑题了，总之就是如果用阿德勒的观点来看待这件事，那么其实要获得幸福是不需要借助这些超能力的工具的，只要改变观念，就可以获得幸福。</p><p>而在番剧中，这个超能力的设定无疑是一个非常有趣的的卖点，同时也是一个将心理问题具象化的工具。说白了就是，超能力的使用过程，就是在弥补自己的自卑。而到了最后，超能力一定会消失，因为自己用不到超能力了，心结已经被解开了。所以不论是<a href="https://bgm.tv/subject/118906">《山田君与7个魔女》</a>、<a href="https://bgm.tv/subject/120925">《Charlotte》</a>、<a href="https://bgm.tv/subject/1671">物语系列</a>还是<a href="https://bgm.tv/subject/240038">《青春猪头少年》</a>，到最后超能力也好、怪异也好还是青春期综合症也好，都因为问题的解决而消失。</p><h2 id="尾声"><a href="#尾声" class="headerlink" title="尾声"></a>尾声</h2><p>就我个人而言，对这部番评价很高。就包括我对这个<a href="https://bgm.tv/subject/120925">《Charlotte》</a>、<a href="https://bgm.tv/subject/1671">物语系列</a>和<a href="https://bgm.tv/subject/240038">《青春猪头少年》</a>的评价都很高，它们给我们带来了非常多的思考。这些思考可能是沉重的，尚未解决的问题，有时候给我感觉真的是两难问题。但无不带来感动，就像<a href="https://bgm.tv/subject/120925">《Charlotte》</a>的男主一样：“我拯救了全世界，却唯独忘记了你。”</p>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;区区一只亚麻大&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h2&gt;&lt;p&gt;最近看了一部番，叫&lt;a href=&quot;https://bgm.tv/subject/118906&quot;&gt;《山田君与7个魔女》&lt;/a&gt;，非常值得推荐给你。这部番与我之前看的&lt;a href=&quot;https://bgm.tv/subject/120925&quot;&gt;《Charlotte》&lt;/a&gt;、&lt;a href=&quot;https://bgm.tv/subject/1671&quot;&gt;物语系列&lt;/a&gt;、&lt;a href=&quot;https://bgm.tv/subject/240038&quot;&gt;《青春猪头少年》&lt;/a&gt;都有一些共性，我们一会谈。我想先讲一下这部番的大致内容，第一集大概是讲述了一个不良少年，与校花在走楼梯的时候摔了不小心接吻了，然后这两人的身体就发生了互换，后来经过实验证实男主和谁接吻都可以进行身体互换，也就是说，交换身体，这是男主的超能力。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="二次元" scheme="https://mmdjiji.com/tags/%E4%BA%8C%E6%AC%A1%E5%85%83/"/>
    
  </entry>
  
  <entry>
    <title>我的宇宙观</title>
    <link href="https://mmdjiji.com/2022/2.html"/>
    <id>https://mmdjiji.com/2022/2.html</id>
    <published>2022-02-14T02:44:55.000Z</published>
    <updated>2026-03-05T00:18:01.281Z</updated>
    
    <content type="html"><![CDATA[<h2 id="缘起"><a href="#缘起" class="headerlink" title="缘起"></a>缘起</h2><blockquote><p>所谓科幻小说家，就是研究现在的宇宙，并提出了颠覆性的观点，但又不想被别人看成是疯子，于是写成小说以启示后人。而科学家，便是直视了这些颠覆性的观点，认为它们无不道理，展开激烈的证明与证伪，所以才会有人认为科学家是疯子。——吉吉</p></blockquote><p>我既没有科幻小说家的文笔，也没有科学家的能力，我只有一些一直以来坚信的想法。我认为我们研究宇宙的理论其实意义不大，并不能带来实质的改变，也就是满足我们的好奇心罢了。当然，你们不能认为我是疯子，至少当你阅读这篇文章时不会这么想，因为我会叫这么想的人不要阅读这篇文章，这样他就不能说我是疯子了。</p><span id="more"></span><h2 id="嵌套宇宙观"><a href="#嵌套宇宙观" class="headerlink" title="嵌套宇宙观"></a>嵌套宇宙观</h2><p>宇宙是可以被创造的。自从我玩 <a href="https://en.wikipedia.org/wiki/Minecraft">Minecraft</a> 以后，就对这个观点深信不疑，虽然直到今天我也还想不明白意识究竟是如何与人进行绑定的，但是我至少能够解释普遍的宇宙观了，当然一些其实都基于了一个数学原理——<a href="https://en.wikipedia.org/wiki/Turing_completeness">图灵完备</a>，当然在理解宇宙这个层面的时候，你可能需要把它推广。</p><p>当然就要提出这两个论断:</p><ol><li>图灵完备的性质：如果已知宇宙U图灵完备，那么由宇宙U可派生宇宙U’.</li><li>图灵完备的判定：如果存在宇宙U派生的宇宙U’，则宇宙U图灵完备.</li></ol><p>要想证明上面的两个论断，我们必须要明确宇宙的定义，根据维基百科上对<a href="https://en.wikipedia.org/wiki/Universe">宇宙</a>的定义:</p><blockquote><p>The universe (Latin: universus) is all of space and time and their contents, including planets, stars, galaxies, and all other forms of matter and energy.</p></blockquote><p>但是我觉得这个定义格局小了，凭什么宇宙里就必须得有planets, stars, galaxies之类的东西，凭什么宇宙里就必须要有能量。在我看来，就算是 Minecraft 里面的世界，也配称作一个宇宙，就算是<a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">生命游戏</a>，也配称作一个宇宙。因此我们格局要大，所以我修改了它的定义，并以此来论述后文:</p><blockquote><p>The universe (Chinese: 宇宙) is all of space or time or information, or each of their combination.</p></blockquote><p>是的，宇宙，是一切空间、时间、信息，或它们每一个的组合。这包含了生命游戏中的宇宙，是由信息+时间组成的，也包含了 Minecraft 中的宇宙，是空间+时间+信息。</p><p>对于论断1，我采用的证明就是举一个正例，因为我们知道一切图灵完备的宇宙中都可以编写一个生命游戏，而生命游戏是一个宇宙，所以论断1就得证了。</p><p>对于论断2，它可以算是宇宙图灵完备的一个定义，我不知道该怎么去证明它，也许它就是个公理。如果有高手知道，不妨教教我，在此提前感谢。</p><p>换句话说，图灵完备就是可派生宇宙的充分必要条件。</p><h2 id="光速"><a href="#光速" class="headerlink" title="光速"></a>光速</h2><p>如果你充分理解了我的宇宙观，那么解释光速是很容易的事。因为宇宙是嵌套的，所以我们假设我们所处的宇宙是U1，则必然存在我们的父宇宙U0。光速就是，U0给U1分配了多少计算资源。</p><p>如果你不理解计算资源，那么你一定用过电脑吧，有个叫 <a href="https://en.wikipedia.org/wiki/VMware_Workstation">VMware Workstation</a> 的软件，可以创建虚拟机，其虚拟机和实体机，都满足我们对宇宙的定义。所以你可以理解成，现在有一个人想创建一个虚拟机，它分配资源的时候，给这个虚拟机分配了2个CPU核心，总共3.6GHz，那么这个虚拟机的“光速”就是3.6GHz，里面不管怎么折腾，都不会超过这个数值。</p><h2 id="我们的宇宙由谁创造？为什么要被创造？"><a href="#我们的宇宙由谁创造？为什么要被创造？" class="headerlink" title="我们的宇宙由谁创造？为什么要被创造？"></a>我们的宇宙由谁创造？为什么要被创造？</h2><p>如果我们可以创造宇宙的话，那么我们就可以换位思考一下。我们可以创作一部电影，制作一款游戏，发明一种规则，那么我们玩什么要做这些事呢？没错，大多数情况下是为了娱乐。那么不妨猜想，我们的宇宙之所以被创造，就是有某种娱乐行为所带来的效果，换句话说，我们的宇宙是被在我们宇宙的上一级的一个实体（可能是生物也可能是别的什么物质）创造的，也许是为了娱乐，也许是为了进行某种研究。</p><p>有人说这是有神论，也不能算严格的错。但需要和现在的所谓的宗教信仰区分开，宗教是一种信仰，可能信仰的是神，但神一定是神，不会是某种机器或者数学原理。但我这里的宇宙观给出的结论是，宇宙确实是由某种“神”创造的，但是这种“神”不一定是那种人们想象中的观音菩萨状的神或是如来佛祖状的神，这种“神”很可能不会听你的愿望行事，也许这种“神”根本不理解人类的情感，但它创造了我们整个宇宙，给我们分配了约30万公里每秒的计算资源。</p><h2 id="如何解释外祖母悖论？平行宇宙观和以“我”为中心的宇宙观"><a href="#如何解释外祖母悖论？平行宇宙观和以“我”为中心的宇宙观" class="headerlink" title="如何解释外祖母悖论？平行宇宙观和以“我”为中心的宇宙观"></a>如何解释外祖母悖论？平行宇宙观和以“我”为中心的宇宙观</h2><p>平行宇宙观与嵌套宇宙观并不冲突，不如说嵌套宇宙观是基础，平行宇宙观是让宇宙丰富多彩的一个工具。对于平行宇宙的解释网上有很多文章，也有人提出以人的能力根本无法对平行宇宙证明或证伪，因此这是个假说。我们认为这个假说具有合理性，因为使用它就可以解释之前不能解释的一些悖论，比如<a href="https://en.wikipedia.org/wiki/Grandfather_paradox">外祖母悖论</a>。</p><blockquote><p>世界上最遥远的距离，是你在存档A，而我在存档B。——知乎网友</p></blockquote><p>但是要解释外祖母悖论，可能就会和我之前的理论产生冲突了，因为我之前说过，光速是无论如何都不可能超过的，那既然这样，也就不可能发明<a href="https://en.wikipedia.org/wiki/Time_travel">时光机</a>，不可能回到过去杀死外祖母。但是这里可能是一种特殊情况，也就是我后文提出的<a href="#%E6%B2%99%E7%9B%92%E9%80%83%E9%80%B8">沙盒逃逸</a>，如果我们真发明了时光机，一定是钻了个现在宇宙的空子，而不是采用正经的宇宙定律发明出来的（或者说是没有遵循宇宙设计者的意愿，有“黑客”发现了宇宙的某个漏洞）。正如<a href="https://bgm.tv/subject/10380">命运石之门</a>这个番里面采用了微波炉莫名其妙发明了时光机一样，当然这个番里面也有很多有意思的关于宇宙的观点，推荐读者观看。</p><p>如果说，真有人找到了宇宙的某个时间漏洞，发明出了时光机，然后坐着时光机（也有可能只是意识坐着时光机，或者只有短信坐着时光机回去了），在自己父母出生前把他们的父母杀死，你还会存在吗？我给出一个结论：会存在，并且不构成悖论。可以理解成，存档A的你跳跃到了存档B杀死了一个人，然后回到了存档A，这样存档A除了你的心理没有什么改变，存档B就是一个人莫名其妙地被杀死了，这两个存档是独立且隔离的。所以时光机的产生，并不会出现悖论，只是需要寻找到一个宇宙的时间漏洞。</p><p>平行宇宙是可能的，但无疑对计算资源是一个挑战，因为同时计算无穷级的宇宙，就算是上一层宇宙，我想也需要很大的算力吧。我在此又提出一个以“我”为中心的宇宙观。</p><p>什么叫以“我”为中心的宇宙观，就是除了“我”以外的人都是<a href="https://en.wikipedia.org/wiki/Non-player_character">NPC</a>，都是陪着“我”玩“地球OL”的一个个NPC。而这些NPC设计地非常真实，有的叫“动物”，有的叫“植物”，还有一些环境因素，这些全部都是为了“我”一个人虚拟出来的。所以说我们不知道是否身处某个“缸中之脑”，但却足矣提出这个假说。我这个观点是不可能被证伪的，因为你无法确定别人是不是NPC，你无法通感别人的意识（因为你所见到的别人，都是自己眼中的别人，自己意识感知到的别人的投影，并非真正的别人，当然我这里的“别人”除了指代人，还指代一切生物）。在这个观点中，我不认为任何除了“我”以外的生物具有意识，他们的表现机器人也可以胜任。哪怕有一天，就算将大脑研究地明明白白，你也只是知道，原来人类大脑是可以用工程学的方法去制造的，甚至可以直接3D打印，这还能更加印证我的观点。当然，你就是“我”，读者需要自行代入“我”，以体会我的言论是否合理。</p><h2 id="如何解释蝴蝶效应？线性同余法与随机链"><a href="#如何解释蝴蝶效应？线性同余法与随机链" class="headerlink" title="如何解释蝴蝶效应？线性同余法与随机链"></a>如何解释蝴蝶效应？线性同余法与随机链</h2><p><a href="https://en.wikipedia.org/wiki/Butterfly_effect">蝴蝶效应</a>是指一个微小的变化能影响事物的发展，证实了事物的发展具有复杂性。</p><blockquote><p>一只南美洲亚马逊河流域热带雨林中的蝴蝶，偶尔扇动几下翅膀，可以在两周以后引起美国得克萨斯州的一场龙卷风。</p></blockquote><p>但是在我看来，不管这只蝴蝶扇不扇动翅膀，两周以后美国得克萨斯州都会刮起龙卷风。或许在扇动翅膀的那个平行宇宙中，刮龙卷风的直接原因就是蝴蝶扇动翅膀导致的多米诺骨牌效应，但在那个蝴蝶未扇动翅膀的平行宇宙中，刮龙卷风的直接原因又恰恰是蝴蝶没扇动翅膀导致了蜻蜓扇动翅膀，又导致了多米诺骨牌效应，从而刮起龙卷风。这有点像宿命论，但比宿命论格局要大，因为宿命论只针对的是人的命运与当前的宇宙，我将其推广到了平行宇宙中。并且在这种观点里，也不完全是这样的，因为平行宇宙也存在了嵌套关系。</p><p>如果我们从家去学校，可以搭乘公交车、地铁或是开私家车，那么我们就有两个状态结点，一个是家，一个是学校，连接这两个结点的至少有三种交通工具:</p><p><img src="/images/2022/02/1.png" alt="从家到学校的选择"></p><p>而这种结点组存在很多，现实中可能存在多组这样的结点:</p><p><img src="/images/2022/02/2.png" alt="随机链"></p><p>我们都学过线性同余法生成随机数，本质上就是去计算这个式子:</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ini"><span class="hljs-attr">RandSeed</span> = (P * RandSeed + Q) % M<br></code></pre></td></tr></table></figure><p>所以我认为，上图中A结点就是最初的种子，B、C、D都是由A结点派生的。这种子结构，会在宇宙中频繁出现，递归出现。就像计算机中的二叉结构明明只定义了左孩子和右孩子，居然可以出现非常复杂的二叉树。使用这种子结构来回嵌套，便可以具有丰富多彩的平行宇宙。这个链，我给它取了个名字，叫随机链。</p><h2 id="沙盒逃逸"><a href="#沙盒逃逸" class="headerlink" title="沙盒逃逸"></a>沙盒逃逸</h2><p>后来我就在思考，我们的宇宙会不会发生沙盒逃逸现象？也就是我们的宇宙是否存在某个漏洞，能让我们逃逸到上层宇宙？对此我给出的解释是，如果你发现了0day，不妨卖给我，作为回报，我会教你如何利用好这个0day。</p><h2 id="意识从何而来？"><a href="#意识从何而来？" class="headerlink" title="意识从何而来？"></a>意识从何而来？</h2><p>根据宇宙嵌套理论，意识的来源是上一层宇宙的递归调用。如果不能理解的话，请允许我用docker来说明问题。</p><p>启动一个宇宙:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">jiji@server:~$ sudo docker run -itd --name universe mmdjiji/universe<br></code></pre></td></tr></table></figure><p>进入到一个宇宙:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">jiji@server:~$ sudo docker <span class="hljs-built_in">exec</span> -it universe /bin/bash<br>root@7bac35555ef3:/<span class="hljs-comment"># </span><br></code></pre></td></tr></table></figure><p>离开一个宇宙:</p><figure class="highlight bash"><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><code class="hljs bash">root@7bac35555ef3:/<span class="hljs-comment"># exit</span><br><span class="hljs-built_in">exit</span><br>jiji@server:~$ <br></code></pre></td></tr></table></figure><p>因此，意识来源于我们调用了上一层宇宙的 <code>docker exec</code> ，死亡意味着离开现在的宇宙。</p><blockquote><p>当我再次醒来，只见我回到了原始的宇宙，我逐渐想起了自己是谁。站着，看着眼前显示屏中的按钮，一动也不动：确认出生在“地球”上，基因随机选择。</p></blockquote><p>至于为什么进入了我们现在的宇宙没有了原始宇宙的记忆，我想这可能是上一级宇宙刻意做的某种隔离机制，类似于CPU进行堆栈调用时的寄存器保护机制。它这么做可能有它的原因，我推测就大概是为了能充分体验这个宇宙。</p><h2 id="预言"><a href="#预言" class="headerlink" title="预言"></a>预言</h2><p>我预言，不远的将来，人类会发明出来人造细胞，单器官克隆，实现脑机接口。人类未来的很长一段时间，物理学将没有什么质的突破，除非到发现宇宙漏洞的那一天。而人类医学领域将会有前所未有的突破，因为这些都是不违反物理定律的。人类光刻机技术会得到突破，计算机与虚拟化领域也会得到突破，很快就会出现成熟的自动驾驶，未来甚至可能有一些爱好者，常年生活在虚拟的宇宙中。你觉得长生不死是好事吗，但是意识大概是有寿命的，在没有研究明白意识之前，人类仍然不能长生不死。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;缘起&quot;&gt;&lt;a href=&quot;#缘起&quot; class=&quot;headerlink&quot; title=&quot;缘起&quot;&gt;&lt;/a&gt;缘起&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;所谓科幻小说家，就是研究现在的宇宙，并提出了颠覆性的观点，但又不想被别人看成是疯子，于是写成小说以启示后人。而科学家，便是直视了这些颠覆性的观点，认为它们无不道理，展开激烈的证明与证伪，所以才会有人认为科学家是疯子。——吉吉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我既没有科幻小说家的文笔，也没有科学家的能力，我只有一些一直以来坚信的想法。我认为我们研究宇宙的理论其实意义不大，并不能带来实质的改变，也就是满足我们的好奇心罢了。当然，你们不能认为我是疯子，至少当你阅读这篇文章时不会这么想，因为我会叫这么想的人不要阅读这篇文章，这样他就不能说我是疯子了。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
  </entry>
  
  <entry>
    <title>谈谈我对旅行的理解</title>
    <link href="https://mmdjiji.com/2022/1.html"/>
    <id>https://mmdjiji.com/2022/1.html</id>
    <published>2022-01-07T17:20:17.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<h2 id="米线"><a href="#米线" class="headerlink" title="米线"></a>米线</h2><p>开始之前，想分享我去云南昆明吃过的米线，无图无真相，上图！</p><span id="more"></span><p><img src="/images/2022/01/1.jpg" alt="云南米线"></p><p>生肉生菜，放进这刚出锅的热汤，不一会的工夫就熟了。但这个时候还不能直接喝汤，因为汤还很烫。您想想，把生的东西放进去就能煮熟的汤，它能不烫嘛！这个时候，适合夹起几片肉、几片菜来吃，非常的香啊。最后，汤已经逐渐冷却到了可以喝的温度，这时双手抱起大碗，吨吨吨。鲜美的味道流经了喉咙，我对云南美食的记忆，也就从米线开始。</p><h2 id="魔女之旅"><a href="#魔女之旅" class="headerlink" title="魔女之旅"></a><a href="https://www.bilibili.com/bangumi/media/md28229881/">魔女之旅</a></h2><blockquote><p>在和平国罗贝塔，出现了史上最年轻，十四岁就在魔法考试中合格，成为魔女见习生的少女。没错，就是我。——伊蕾娜</p><p>那么，问题来了。正准备前往充满杀戮的山岳地区，有着令人惊叹之美貌的魔女，究竟是谁呢？没错，就是18岁的我。——伊蕾娜</p></blockquote><p>我很喜欢这部番，并且非常期待这部番能有续作。这部番就非常像《小王子》，我不多说了想看的就自己去看吧，懂的都懂。做个白日梦，哪天自己能够去到世界各地旅游，能够经历许多故事，哪怕是以一名旁观者的身份，我想也可以从中学到很多。</p><h2 id="旅行"><a href="#旅行" class="headerlink" title="旅行"></a>旅行</h2><p>所以什么才是旅行呢？在继续往后阅读之前，不妨你也来思考一下这个问题，对于你来说，什么是旅行？旅行有什么意义？</p><p>在我看来，旅行就是去体验与平时不一样的事，吃平日里没吃过的食物，接触不熟悉的风土人情。所以说，旅行也是一种学习的过程，所谓“读万卷书，行万里路”，其实不无道理，这句话一方面可以广义地理解成我们学习了很多理论知识还要动手去实践，另一方面，从狭义的角度上，对于旅行本身就是可以学习到很多东西的。旅行，收获了知识、又收获了快乐，这才是最纯粹的学习啊。</p><p>我在旅行时有一些小爱好，比如给美丽的景色拍照，记录一下我还去过这么美丽的地方。或许过了一段时间再去翻看之前的照片，可以怀着某种心情，与人分享自己的经历。当然到不同地方旅行时可以品尝当地美食，谁又能拒绝美食呢？这也是我在文章一开始就举出了云南米线的例子，除此之外我喜欢的还有杭州的红烧肉（非常精致）、北京的烤鸭（鸭皮蘸白糖绝了）、内蒙的奶茶（不是那种奶茶店里买的特别甜的奶茶，是咸咸的味道）……</p><p>旅行的乐趣，除了美食，还可以了解当地人的生活方式。或许有的人并不满足于自己当下的生活方式，想要有所改变，又或者有的人比较喜欢钻研什么才是真正适合自己、适合他人的生活方式。去经历、去体验，可以为建立自己的成熟想法提供素材。当然，由于我旅行的经历也并不丰富，下面的例子也都是我结合了经历与传闻所举出的。像我去过上海，也去过北京，对比这两个城市，我发现在上海可以经常看到穿着洛丽塔服装的小姐姐，也有穿着汉服的小姐姐，我当时在夏天还看到了一个穿着羽绒服的小姐姐，而在北京却很少看到这些场景，大概上海的文化包容性要更强一点。可能，喜欢上海的这种生活方式的人，在接触新鲜事物时可能更容易上手吧。另外我还觉得南方人的生活节奏比北方人普遍要慢，当然这一点我觉得我能举出的例子不够充分，或许也有很多反例吧。</p><p>正如旅行的伊蕾娜一样，游历不同的国家，在实践中可以学习到很多，也可以认识志同道合的人，例如伊蕾娜认识了沙耶小姐。在旅行的路途中，一定会走出“舒适圈”，从而带来更多能力的增长。当然这也只是旅行意义的一部分，旅行最本质的意义就是让你知道别人在干什么，你评价一下别人干的怎么样，然后决定自己该做什么。我也很想骑着一把扫帚，来一场说走就走的旅行，如果没有会飞的扫帚，就请用任意门代替它。以后再来分享我的旅行经历吧，如果有机会。</p><p>最后，我想听听你对旅行的看法。如果没有什么成体系的想法，也不妨和我分享你的一次旅行见闻，也让我长长见识。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;米线&quot;&gt;&lt;a href=&quot;#米线&quot; class=&quot;headerlink&quot; title=&quot;米线&quot;&gt;&lt;/a&gt;米线&lt;/h2&gt;&lt;p&gt;开始之前，想分享我去云南昆明吃过的米线，无图无真相，上图！&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
    <category term="二次元" scheme="https://mmdjiji.com/tags/%E4%BA%8C%E6%AC%A1%E5%85%83/"/>
    
  </entry>
  
  <entry>
    <title>神仙代码之 C 语言求圆周率</title>
    <link href="https://mmdjiji.com/2021/21.html"/>
    <id>https://mmdjiji.com/2021/21.html</id>
    <published>2021-10-24T14:08:26.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight c++"><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><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-type">long</span> a=<span class="hljs-number">10000</span>,b=<span class="hljs-number">0</span>,c=<span class="hljs-number">10000</span>,d,e,f[<span class="hljs-number">10001</span>],g;<br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>  <span class="hljs-keyword">for</span>(;b != c; f[b++] = a/<span class="hljs-number">5</span>);<br>  <span class="hljs-keyword">for</span>(; d=<span class="hljs-number">0</span>,g=c*<span class="hljs-number">2</span>,c&gt;<span class="hljs-number">5000</span>; c--,<span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%.4d&quot;</span>,e+d/a),e=d%a)<br>  <span class="hljs-keyword">for</span>(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); <br>  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;figure class=&quot;highlight c++&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;</summary>
      
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="算法" scheme="https://mmdjiji.com/tags/%E7%AE%97%E6%B3%95/"/>
    
  </entry>
  
  <entry>
    <title>信念</title>
    <link href="https://mmdjiji.com/2021/20.html"/>
    <id>https://mmdjiji.com/2021/20.html</id>
    <published>2021-09-25T10:50:44.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<h2 id="信念"><a href="#信念" class="headerlink" title="信念"></a>信念</h2><p><del>上次思考这个问题，还是在上次。</del></p><p>第一次思考这个问题，还是在高考结束时。不知道你能不能明白，高考结束之后，压力突然小了很多，有时候会迷茫，不知道该做什么。</p><span id="more"></span><p>我来分享一下我高考结束后总共做了什么吧。首先我先去看了个电影，当时热播的《哆啦A梦：大雄的月球探险记》，虽然《哆啦A梦》剧场版的质量一直处于下降态势（《伴我同行》系列除外），但是作为一个资深哆啦粉还是不能错过每一场电影。后来我去初中和老师聊了很多过往，还帮当时的数学老师批改起了学生的作业。毕业典礼过后，我报名了业余无线电A类资格证的考试，随后当然顺利拿到执照。后来我买了台3D打印机，打印了一些想打印的东西。和朋友打了几天GTA5，和家人一块去浙江上海旅游，和朋友在北京自行车专用道上骑行。</p><p>但我一直是有信念的，曾经的我一直把研究计算机技术和电子技术作为第一要务，因此就算是失去了高考的压力，我也并没有陷入无事可做的局面，反而可以专心的做我想研究的事。所以我从高考结束到今天，技术方面的进步非常大，并且还长期保持很大的进步空间。</p><h2 id="思考"><a href="#思考" class="headerlink" title="思考"></a>思考</h2><p>也就是最近吧，我开始批判性地思考，我人生中最重要的事就是研究计算机技术和电子技术吗？</p><p>现在我可以给出一个确切的回答：否定。</p><p>我得出了一个结论：技术只是实现理想的工具，可以热爱某项技术，但人生不应该只有技术，人生应该活得更精彩些。</p><h2 id="Charlotte"><a href="#Charlotte" class="headerlink" title="Charlotte"></a><a href="https://www.bilibili.com/bangumi/play/ss2572">Charlotte</a></h2><p>说起来这部番脑洞奇大无比，而又十分感人。故事的女主叫友利奈绪，男主叫乙坂有宇。起因是超能力莫名其妙地在青春期少年中出现，男主的超能力是夺取别人的超能力（事实上男主前期误以为自己的超能力是附身别人身上5秒，但这只是夺走别人超能力的方法），超能力听起来本来是一件很酷的事情，但总是有邪恶的组织盯上这群有超能力的孩子并想要利用他们，这会给孩子们带来不幸。为了摆脱这个局面，男主决定把世界上所有人的超能力都夺走，这样就能保护所有超能力者。</p><p>女主在男主出发前给了男主一个单词本，还说“等你回来，我们就在一起”。男主一路上多次差点忘记自己要做什么，甚至差点黑化。这个单词本，正是男主最后的信念，让男主最终完成任务回到友利奈绪身边。</p><p>我刚开始对此是持怀疑态度的，一个人怎么会忘记自己要做什么呢？那种事想一想不就记起来了吗？但是经过深思熟虑，我悟了。男主并非是真的忘记了自己要做什么，而是在思考，事到如今，自己这么做下去真的有意义吗，不如趁着现在的机会做点别的事情，至少可以得到暂时的满足。但男主选择了继续下去，我不能说这是正确的，我只能说这是善始善终，不忘初心。</p><blockquote><p>因为失去我们伤怀，但也因为失去，我们才可以拥有新的未来。</p></blockquote><blockquote><p>如果从一开始就可平平淡淡过一生多好，何必经历那么多磨难？<br>经磨难后方知平淡是真。<br>还好，未来还在。</p></blockquote><h2 id="我的一些想法"><a href="#我的一些想法" class="headerlink" title="我的一些想法"></a>我的一些想法</h2><blockquote><p>之前和一位朋友聊过这件事，她当时告诉我大学最重要的可不一定是学习哦，还有很多很多别的事。</p></blockquote><p>后来我就打算开始把精力多放在生活上一点，不为别的，咱不能为了追求技术而忽略了生活，毕竟咱是热爱生活的人。</p><p>我脑海里一直有一幅理想的图景，那是在遥远的2077年的将来，我和恋爱了50年的老伴住在我亲手装修的精致的小屋里，温馨而亲切。里面有一个房间叫实验室，桌上放着热风枪、烙铁、加热台以及我的短波电台，旁边放着一个机柜，里面有家庭网络的交换机、UPS以及我心爱的戴尔服务器。还有一个房间叫书房，里面有我和老伴的各种藏书，用我亲手开发的图书管理系统来统一管理。还有一个房间是我和老伴一起睡觉的房间。要是我们都喜欢小孩，那我还得给未来的小孩准备一个房间。客厅中摆放着我亲手种的绿萝，还摆放着一架黑色钢琴。早上起床了，我便开着车带着老伴一起去呼伦贝尔的草原上，一起去捕捉天空中最纯粹的星空，一起去聆听动物的叫声，以及从我电台里发出的阵阵背噪。拿起电台，按下PTT键，向宇宙呼叫CQ，得不到任何回应，那想必是外星人在说：“不要回答！不要回答！不要回答！”</p><p>我要用接下来的时间，亲手实现这一切。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;信念&quot;&gt;&lt;a href=&quot;#信念&quot; class=&quot;headerlink&quot; title=&quot;信念&quot;&gt;&lt;/a&gt;信念&lt;/h2&gt;&lt;p&gt;&lt;del&gt;上次思考这个问题，还是在上次。&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;第一次思考这个问题，还是在高考结束时。不知道你能不能明白，高考结束之后，压力突然小了很多，有时候会迷茫，不知道该做什么。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
    <category term="二次元" scheme="https://mmdjiji.com/tags/%E4%BA%8C%E6%AC%A1%E5%85%83/"/>
    
  </entry>
  
  <entry>
    <title>无限长梯形网络等效电阻的求解</title>
    <link href="https://mmdjiji.com/2021/19.html"/>
    <id>https://mmdjiji.com/2021/19.html</id>
    <published>2021-08-14T08:24:18.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h3><p>现有以电阻 $r_1&#x3D;r_2&#x3D;r_3&#x3D;1\Omega$ 构成的一个无限长梯形网络（如图所示），求 $a,b$ 之间的等效电阻.</p><p><img src="/images/2021/08/1.png" alt="题图"></p><span id="more"></span><h3 id="常规解法"><a href="#常规解法" class="headerlink" title="常规解法"></a>常规解法</h3><p>将 $R_{ab}$ 去掉一个循环节的网络看作 $R_{ab}’$ ，如下图所示.</p><p><img src="/images/2021/08/2.png" alt="示意图"></p><p>根据电阻串并联的规律知 $R_{ab}&#x3D;r_1+\frac{r_2R_{ab}’}{r_2+R_{ab}’}+r_3$ .</p><p>由于有无穷多节，相差一节对电阻的影响微乎其微（可看作是无穷小），因此 $R_{ab}’&#x3D;R_{ab}$ .</p><p>将 $r_1&#x3D;r_2&#x3D;r_3&#x3D;1\Omega$ 代入后求得 $R_{ab}&#x3D;1+\sqrt3\ \Omega$ .</p><h3 id="常规解法的缺陷"><a href="#常规解法的缺陷" class="headerlink" title="常规解法的缺陷"></a>常规解法的缺陷</h3><p>常规解法虽然有一定道理，但使用“微乎其微”等形容词来描述不具有很强的说服力。另外，常规解法不能解决有限节梯形网络的问题，如果我们要求解的等效电阻并不是无穷多节的循环，而是有限节 $n$ 时的等效电阻，那么就不能使用常规解法来解决.</p><h3 id="新型解法"><a href="#新型解法" class="headerlink" title="新型解法"></a>新型解法</h3><p>我们不妨设这个梯形网络的节数为 $n$ ，此时 $a,b$ 之间的等效电阻为 $R_{ab}|_{n}$ ，观察下列情况</p><ul><li><p>当 $n&#x3D;1$ 时，$R_{ab}|_{n&#x3D;1}&#x3D;r_1+r_2+r_3$</p></li><li><p>当 $n&#x3D;2$ 时，$R_{ab}|_{n&#x3D;2}&#x3D;r_1+\frac{r_2R_{ab}|_{n&#x3D;1}}{r_2+R_{ab}|_{n&#x3D;1}}+r_3$</p></li><li><p>当 $n&#x3D;3$ 时，$R_{ab}|_{n&#x3D;3}&#x3D;r_1+\frac{r_2R_{ab}|_{n&#x3D;2}}{r_2+R_{ab}|_{n&#x3D;2}}+r_3$</p></li><li><p>……</p></li><li><p>当 $n&#x3D;n$ 时，$R_{ab}|_{n}&#x3D;r_1+\frac{r_2R_{ab}|_{n-1}}{r_2+R_{ab}|_{n-1}}+r_3$</p></li></ul><p>由此，我们发现了对于一般的 $n$ ，存在 $R_{ab}|_{n}$ 与 $R_{ab}|_{n-1}$ 之间的递推关系式.</p><p>为简化计算，我们将 $r_1&#x3D;r_2&#x3D;r_3&#x3D;1\Omega$ 代入，获得 $R_{ab}|_{n}$ 与 $R_{ab}|_{n-1}$ 之间的常量递推关系，并写以数列形式.</p><p>设$a_n&#x3D;R_{ab}|_{n}$ ，则$a_{n-1}&#x3D;R_{ab}|_{n-1}$ ，有 $a_n&#x3D;\frac{3a_{n-1}＋2}{a_{n-1}＋1}\ (n≥2)$ ，其中 $a_1&#x3D;3$ .</p><p>令 $x&#x3D;\frac{3x+2}{x+1}$ ，即 $x^2-2x-2&#x3D;0$ ，此方程存在两根 $x_1&#x3D;1-\sqrt3,\ x_2&#x3D;1+\sqrt3$ .</p><p>由于 $x_1≠x_2$ ，有 $\frac{a_{n}-x_1}{a_{n}-x_2}&#x3D;q\frac{a_{n-1}-x_1}{a_{n-1}-x_2}$ ，其中 $q&#x3D;\frac{3-x_1}{3-x_2}$ .</p><p>根据等比数列通项公式，知 $\frac{a_{n}-x_1}{a_{n}-x_2}&#x3D;(\frac{3-x_1}{3-x_2})^n&#x3D;(2+\sqrt3)^{2n}$ .</p><p>化简后求得 $a_n&#x3D;\frac{(2+\sqrt3)^{2n}(1+\sqrt3)-(1-\sqrt3)}{(2+\sqrt3)^{2n}-1}\ (n≥2)$ ，为 $a_n$ 的封闭表达式.</p><p>因此 $R_{ab}|_{n}&#x3D;a_n\ (\Omega)$ ，取极限 $R_{ab}&#x3D;\lim\limits_{x\rightarrow\infty}a_n\ (\Omega)$ 即为无穷多节梯形网络的等效电阻.</p><p>$\lim\limits_{x\rightarrow\infty}a_n&#x3D;\lim\limits_{x\rightarrow\infty}\frac{(2+\sqrt3)^{2n}(1+\sqrt3)-(1-\sqrt3)}{(2+\sqrt3)^{2n}-1}&#x3D;\lim\limits_{x\rightarrow\infty}\frac{1+\sqrt3-\frac{1-\sqrt3}{(2+\sqrt3)^{2n}}}{1-\frac{1}{(2+\sqrt3)^{2n}}}&#x3D;1+\sqrt3$ .</p><p>所以，对于有无穷多节的等效电阻 $R_{ab}&#x3D;1+\sqrt3\ \Omega$ .</p><h3 id="新型解法的优缺点"><a href="#新型解法的优缺点" class="headerlink" title="新型解法的优缺点"></a>新型解法的优缺点</h3><p>优点：对无限长梯形网络等效电阻问题给出了严谨的证明，且适用于一般有限节的情况.</p><p>缺点：过程较为复杂，求解难度大.</p>]]></content>
    
    
    <summary type="html">&lt;h3 id=&quot;题目&quot;&gt;&lt;a href=&quot;#题目&quot; class=&quot;headerlink&quot; title=&quot;题目&quot;&gt;&lt;/a&gt;题目&lt;/h3&gt;&lt;p&gt;现有以电阻 $r_1&amp;#x3D;r_2&amp;#x3D;r_3&amp;#x3D;1&#92;Omega$ 构成的一个无限长梯形网络（如图所示），求 $a,b$ 之间的等效电阻.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/2021/08/1.png&quot; alt=&quot;题图&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://mmdjiji.com/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="电子" scheme="https://mmdjiji.com/tags/%E7%94%B5%E5%AD%90/"/>
    
  </entry>
  
  <entry>
    <title>慢节奏生活，是一种心态</title>
    <link href="https://mmdjiji.com/2021/18.html"/>
    <id>https://mmdjiji.com/2021/18.html</id>
    <published>2021-05-26T14:02:11.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<p>不知道是不是我的偏见，我一直认为，南方人的生活节奏要比北方人慢。我并不是说哪种生活方式好，这是因人而异的，有的人适合慢节奏生活，有的人适合快节奏生活，还有的人喜欢SM……</p><h2 id="慢节奏-摸鱼"><a href="#慢节奏-摸鱼" class="headerlink" title="慢节奏&#x3D;&#x3D;摸鱼?"></a>慢节奏&#x3D;&#x3D;摸鱼?</h2><p>不知道你有没有看过这部番剧：<a href="https://www.bilibili.com/bangumi/play/ss38229">《打了300年的史莱姆，不知不觉就练到了满级》</a>，没有的话可以点进去看。</p><span id="more"></span><blockquote><p>普通的OL·相泽梓因过量工作而过劳死，在异世界转生成为不老不死的魔女亚梓莎。出于对前世的反省，她开始在边境的高原度过悠闲的慢生活。打倒史莱姆赚点小钱，像个魔女一样制作魔药提供给山麓的村子。其他就没什么特别的了。在持续过着这种生活的过程中，她开始被人称作「高原的魔女大人」并受到人们的喜爱。</p><p>在这之后过了300年。凭借不断打倒史莱姆获得的经验值，亚梓莎不知不觉间已经LV99&#x3D;成为了世界最强。这个传言开始扩散，对能力有自信的冒险者自不必说，就连前来挑起决斗的龙女以及称亚梓莎为母亲的怪物少女都找上门来——！？</p></blockquote><p>慢节奏可以成事。大多数情况下，事不是一朝一夕就能完成的，而是要经过长期量的积累，质变源于量变。因此成不成事与生活节奏的快慢无关，只与你能否坚持下来有关。慢节奏可以让你变得不那么浮躁，用心地把事做好。</p><h2 id="但是呢"><a href="#但是呢" class="headerlink" title="但是呢"></a>但是呢</h2><p>慢节奏不等于做什么事都不着急，总是等到deadline的时候才想起来去做 <del>（这叫拖延症）</del> 。这部番剧中的主人公之所以得以成为世界最强是因为她可以活300年！（事实上她可以活的更长）你我皆不能活这么长，因此在有限的时间内，我们要合理地分配，这样才能成为我们想成为的自己。</p><h2 id="读万卷书，行万里路"><a href="#读万卷书，行万里路" class="headerlink" title="读万卷书，行万里路"></a>读万卷书，行万里路</h2><p>以前我不能理解这句话的意义，可能是因为我对生命的意义不够理解。当时我就在想啊，我们人生的终极目标是什么。赚钱？搞研究造福全人类？成为明星在人群中闪耀？不，都不是，至少对我来说。之前看到过两位老人在地铁站，弹一架钢琴，我觉得，人生的意义也就是这了，操劳半生，只为了最后，能无忧无虑地，做着自己喜欢的事。</p><p>所以我觉得我开始渐渐理解为什么要行万里路了，那是去体验不同的生活方式，这样就能知道自己喜欢什么了，然后在无忧无虑的年纪，沐浴着美好的夕阳，做着自己最喜欢的事。</p><h2 id="学长的话"><a href="#学长的话" class="headerlink" title="学长的话"></a>学长的话</h2><p>偶然和学长聊起这个话题，他说：</p><blockquote><p>快节奏和慢节奏是相对的。什么叫快节奏呢？就是，你给别人干事儿，干了一整天。忙忙碌碌一个接一个，没有什么时间做自己的事儿，我个人理解啊，这就叫快节奏。</p><p>你比如说我小的时候，我喜欢做纸模型。就是拿一些纸壳去做一些赛车坦克飞机大炮啥的。这种事儿，你让我干一天，我也不觉得累。所以，即使我忙碌了一整天，我也依然觉得这个节奏是慢的。</p><p>但是你要是说今天去银行，明天跑科委，操碎了心，磨破了嘴，身板差点没累毁，还得给寡妇挑水，这种生活儿都是给别人忙活，你这一天才会觉得非常忙碌。</p><p>这个就得涉及到节奏快慢的定义，不同人可能对它的理解不同。我觉得什么叫快节奏，什么叫慢节奏，就是如果一个环境，一个气氛不能够让你紧张起来了。即使你很忙碌，这也是慢节奏。</p></blockquote><p>在我看来，学长对慢节奏的理解就是，做自己喜欢的事，就是慢节奏。我觉得这种观点挺好的，因为做自己喜欢的事，会令人舒适，心旷神怡。</p><h2 id="慢节奏生活"><a href="#慢节奏生活" class="headerlink" title="慢节奏生活"></a>慢节奏生活</h2><p>慢节奏生活，可能是一种心态，包含着你对自己喜欢做的事的向往。哪怕一时半会不能进入这种慢节奏的生活，但我希望有生之年，来到自己喜欢的事情面前，无忧无虑地忙碌起来。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;不知道是不是我的偏见，我一直认为，南方人的生活节奏要比北方人慢。我并不是说哪种生活方式好，这是因人而异的，有的人适合慢节奏生活，有的人适合快节奏生活，还有的人喜欢SM……&lt;/p&gt;
&lt;h2 id=&quot;慢节奏-摸鱼&quot;&gt;&lt;a href=&quot;#慢节奏-摸鱼&quot; class=&quot;headerlink&quot; title=&quot;慢节奏&amp;#x3D;&amp;#x3D;摸鱼?&quot;&gt;&lt;/a&gt;慢节奏&amp;#x3D;&amp;#x3D;摸鱼?&lt;/h2&gt;&lt;p&gt;不知道你有没有看过这部番剧：&lt;a href=&quot;https://www.bilibili.com/bangumi/play/ss38229&quot;&gt;《打了300年的史莱姆，不知不觉就练到了满级》&lt;/a&gt;，没有的话可以点进去看。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
    <category term="二次元" scheme="https://mmdjiji.com/tags/%E4%BA%8C%E6%AC%A1%E5%85%83/"/>
    
  </entry>
  
  <entry>
    <title>敬畏生命，敬畏自然</title>
    <link href="https://mmdjiji.com/2021/17.html"/>
    <id>https://mmdjiji.com/2021/17.html</id>
    <published>2021-04-03T15:23:22.000Z</published>
    <updated>2026-03-05T00:18:01.280Z</updated>
    
    <content type="html"><![CDATA[<h2 id="清明节"><a href="#清明节" class="headerlink" title="清明节"></a>清明节</h2><p>明天就是清明节了，今天我想聊聊这个节日。以下是我从《百度百科》上摘取的一段文字：</p><blockquote><p>清明节，又称踏青节、行清节、三月节、祭祖节等，节期在仲春与暮春之交。清明节源自上古时代的祖先信仰与春祭礼俗，兼具自然与人文两大内涵，既是自然节气点，也是传统节日。扫墓祭祖与踏青郊游是清明节的两大礼俗主题，这两大传统礼俗主题在中国自古传承，至今不辍。——《百度百科》</p></blockquote><p>说起来这个节日的主旋律是“扫墓祭祖”和“踏青旅游”。</p><span id="more"></span><h2 id="扫墓祭祖"><a href="#扫墓祭祖" class="headerlink" title="扫墓祭祖"></a>扫墓祭祖</h2><p>天下没有不散的宴席：人，出生了就会死，只有信息是得以永恒存在的。我们继承了祖先的知识，譬如牛顿的微积分、麦克斯韦的电磁波理论以及爱因斯坦的相对论，没有他们，我们就不可能有今天。扫墓祭祖时，我想也是为了表达对祖先的怀念与感谢。</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><p>最近我的一个朋友去世了，我从来都没有想到过。我非常懊悔，为什么他生前就没有留下一张两个人的合照呢？果然，人只有失去了才会懂得珍惜。</p><h2 id="我的宠物"><a href="#我的宠物" class="headerlink" title="我的宠物"></a>我的宠物</h2><p>我曾经养过一只狗，他非常可爱非常乖，虽然有时候很调皮不听话，叫他出来洗澡的时候还钻到沙发底下，用扫把扫沙发底下的时候还会咬住扫把，似乎在告诉我：这里是我的地盘。</p><p>后来在我上完OI的课回家后，听到了他去世的消息，痛哭了很多天。我那时就在想，彩虹桥是不是真的存在呢？</p><blockquote><p>在天堂靠近这里的一侧，有个地方叫彩虹桥。当一个动物死去的时候，要是他被这里某个人深爱着的话，他就会去彩虹桥。</p><p>那里有草地，有山坡，让我们深爱着的朋友们在一起奔跑和玩耍。那里阳光明媚，水草肥美，我们的朋友们过着温暖又舒适的日子。所有曾被疾病和衰老折磨的，都恢复了健康和活力。那些受伤或残疾的，又变得健全和强壮，就如同我们梦中。</p><p>在那些逝去的日子里，他们曾经的那样，他们快乐又幸福。只有一个小小的不足，他们每一个都在思念一个人啊，对他特别的那一个，却不得不被留在了那一边，他们整日在一起奔跑和玩耍。</p><p>直到有一天，其中的一个突然停下，凝视着远方。他明亮的眼眸变得热切，他渴望的身躯开始颤栗，突然他离群而出，开始奔跑，飞跑过草地，越来越快。他看见了你！你和你深爱的朋友终于相见，你们拥抱在一起，再也不分离。他快乐地不停舔着你的脸，你的手再次抚摸着他的头。你又能看着他的眼睛，那充满信任的眼睛，虽然曾经失去了那么久，却不曾片刻离开你的心。然后，你们一起跨过那彩虹桥。</p></blockquote><p>虽然我并不迷信，但我宁可希望有朝一日，我来到这座桥，一眼就看到了他，那金黄色的身躯，傲娇的脸庞，扑到我怀里。我抱着他，一起跨过这座桥。</p><h2 id="可塑性记忆"><a href="#可塑性记忆" class="headerlink" title="可塑性记忆"></a>可塑性记忆</h2><blockquote><p>愿你有一天能和你最重要的人重逢。——《可塑性记忆》弹幕</p></blockquote><p>就算是娱乐性的作品，也存在思想价值，例如《缘之空》就表达了不被他人理解的少数群体是否应该被伦理等规矩约束。有一部动漫作品，名为<a href="https://www.bilibili.com/bangumi/play/ss1552/">《可塑性记忆》</a>，则表达出了对生命的敬畏。我体会到了艾拉离开男主时，男主的感觉，和我的小狗离开我时我的感觉是一样的，何等的不舍。</p><h2 id="水果篮子"><a href="#水果篮子" class="headerlink" title="水果篮子"></a>水果篮子</h2><p><a href="https://www.bilibili.com/bangumi/play/ss26766">《水果篮子》</a>是一部动漫作品，它讲述的是关于十二生肖的故事。很久很久以前，有一位神明，这位神明非常非常孤独，因为没有人陪他玩。有一天，他还是一个人孤零零地，有一只猫向他走去，陪他玩，他们非常快乐。于是这位神明就在想，既然人类不陪我玩，那么动物是不是会陪我玩呢？于是他向动物们写信，邀请他们来参加宴会。宴会上来了十二个动物，第一个来的是老鼠，第二个来的是牛。他们经常开宴会，动物们一起和谐相处，神明非常开心。但是，天下哪有不散的宴席，猫的寿命到了，快要不行了。大家发现，这样下去，总有一天，大家都会一个个死去。于是神明将大家联系在一起，纵使转生，也能再次团聚。</p><p>这样的故事令人感动，但神明做的事给大家带来了困扰。猫在最后说，它不需要永远，它想让神明勇敢地接受这种结束。这话一出，神明听了很出乎意料，动物们很伤心，开始唾弃猫，认为猫背叛了他们。在他们转生后，认识了许多新的朋友，大家一起玩，也会十分快乐。而这种联系，似乎成了一种束缚、一种枷锁，转生后的十二生肖虽然变成了人，却无法挣脱，只能接受命运，和大家一起团聚，再次举办宴会。直到有一天，每个十二生肖都成长了，他们各自找到了陪伴自己的人，这种联系就断掉了，故事戛然而止。</p><p>于是我就在思考，生命到底应该何去何从，我们究竟要勇敢地接受结束，还是要永恒地活下去。</p><h2 id="宠物克隆"><a href="#宠物克隆" class="headerlink" title="宠物克隆"></a>宠物克隆</h2><p>我也不知何时听说有宠物克隆，后来查了一下确实是真的，并且已经民用了。有一家公司，叫“希诺谷”，目前就在搞这个产业。我也不评价这家公司怎样，我只是想谈谈“宠物克隆”这件事。</p><p>据我了解，宠物克隆，并不能克隆宠物的记忆。也就是说，当你接走克隆后的宠物，样子和原宠物小时候的样子一模一样，虽然基因一样，但如果经历不同，之后的性格也可能不同。但就算这样，也有许多人克隆他们心爱的宠物。这些人是放不下失去的心情，就算不是同一只，也要欺骗自己，这是它生命的延续，作为自己的精神寄托。</p><h2 id="敬畏自然"><a href="#敬畏自然" class="headerlink" title="敬畏自然"></a>敬畏自然</h2><p>我希望我的家人能够身体健康，我希望自己有能力，保护自己和爱的人、动物以及植物。说起来我还挺贪心的呢。</p><p>自然界非常神奇，直到现在我都没有想明白这个宇宙的运行原理。自然界存在了太多未知，如果我们还没有对它足够熟悉，就要心存敬畏。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;清明节&quot;&gt;&lt;a href=&quot;#清明节&quot; class=&quot;headerlink&quot; title=&quot;清明节&quot;&gt;&lt;/a&gt;清明节&lt;/h2&gt;&lt;p&gt;明天就是清明节了，今天我想聊聊这个节日。以下是我从《百度百科》上摘取的一段文字：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;清明节，又称踏青节、行清节、三月节、祭祖节等，节期在仲春与暮春之交。清明节源自上古时代的祖先信仰与春祭礼俗，兼具自然与人文两大内涵，既是自然节气点，也是传统节日。扫墓祭祖与踏青郊游是清明节的两大礼俗主题，这两大传统礼俗主题在中国自古传承，至今不辍。——《百度百科》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说起来这个节日的主旋律是“扫墓祭祖”和“踏青旅游”。&lt;/p&gt;</summary>
    
    
    
    <category term="随笔" scheme="https://mmdjiji.com/categories/%E9%9A%8F%E7%AC%94/"/>
    
    
    <category term="哲学" scheme="https://mmdjiji.com/tags/%E5%93%B2%E5%AD%A6/"/>
    
  </entry>
  
</feed>
