<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>FishCat233&apos;s Blog</title><description>A blog site about FishCat233, who is a cross-disciplinary learner who cross-disciplinary and life-time learner.</description><link>https://www.aaafishcat.top</link><item><title>域名解析</title><link>https://www.aaafishcat.top/posts/dns-resolve</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/dns-resolve</guid><description>我最近买了个域名（whispery.top），在域名注册商那里配置的时候看到了一些参数，好奇的查了一下，在这里小记一下查询到的简单解释。</description><pubDate>Sat, 09 Mar 2024 18:09:47 GMT</pubDate><content:encoded>&lt;p&gt;:::warning
截止 2026-05-04 15:48&lt;/p&gt;
&lt;p&gt;我的域名已经被因为忘记续费被收回了，为此默哀 3s，感谢它的两年陪伴.&lt;/p&gt;
&lt;p&gt;下一刻，登场的新域名是 &lt;code&gt;aaafishcat.top&lt;/code&gt;!
:::&lt;/p&gt;
&lt;p&gt;我最近买了个域名（whispery.top），在域名注册商那里配置的时候看到了一些参数，好奇的查了一下，在这里小记一下查询到的简单解释。&lt;/p&gt;
&lt;p&gt;下面会以我的域名 whispery.top 为前提讲解。&lt;/p&gt;
&lt;h2&gt;HOSTNAME 域名&lt;/h2&gt;
&lt;p&gt;主要是操作下级域名的规则，例如我有 whispery.top 域名，在配置界面一条记录中的hostname设置为www，那么那条记录就会对 www.whispery.top 生效；如果hostname设置为home，那么就会对 home.whipery.top 生效。&lt;/p&gt;
&lt;h2&gt;TYPE 域名记录类型&lt;/h2&gt;
&lt;h3&gt;A 记录&lt;/h3&gt;
&lt;p&gt;A 其实是 Address 的缩写，A记录是用来指定hostname对应的IP记录。&lt;/p&gt;
&lt;h3&gt;AAAA 记录&lt;/h3&gt;
&lt;p&gt;ipv6 版本的 A 记录。&lt;/p&gt;
&lt;h3&gt;CNAME 记录&lt;/h3&gt;
&lt;p&gt;别名记录。hostname是CNAME的别名，例如hostname为www，记录类型cname，设置的值(value)是github.io，那么就会解析 www.whispery.top 为 github.io 的别名。&lt;/p&gt;
&lt;h3&gt;MX 记录&lt;/h3&gt;
&lt;p&gt;暂时没有看。&lt;/p&gt;
&lt;h3&gt;NS 记录&lt;/h3&gt;
&lt;p&gt;解析服务器记录。对于hostname，会使用特定值（value）的解析服务器&lt;/p&gt;
&lt;h2&gt;TTL（Time To Live）&lt;/h2&gt;
&lt;p&gt;域名解析记录在DNS服务器中的存留时间。&lt;/p&gt;
&lt;p&gt;在各DNS服务器对域名进行解析后，会把解析结果留存在DNS服务器上一段时间，这段时间的长度就是TTL的值。&lt;/p&gt;
&lt;p&gt;TTL的值是以秒为单位计算的，例如当TTL的值为3600秒时，那么当DNS服务器自保存记录后3600秒（1小时），DNS服务器就会重新向NS服务器要解析结果。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>详解极大似然估计和最大后验估计</title><link>https://www.aaafishcat.top/posts/a-detailed-explanation-of-maximum-likelihood-estimation-and-maximum-a-posteriori-estimation</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/a-detailed-explanation-of-maximum-likelihood-estimation-and-maximum-a-posteriori-estimation</guid><description>最大似然估计（Maximum likelihood estimation, MLE） 和 最大后验概率估计（Maximum a posteriori estimation, MAP） 是很常用的两种参数估计方法。本文将详解MLE和MAP的思路和区别。</description><pubDate>Sat, 09 Mar 2024 23:30:57 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;最大似然估计（Maximum likelihood estimation, MLE）&lt;/strong&gt; 和 &lt;strong&gt;最大后验概率估计（Maximum a posteriori estimation, MAP）&lt;/strong&gt; 是很常用的两种参数估计方法。本文将详解MLE和MAP的思路和区别。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;在此之前&lt;/h1&gt;
&lt;h2&gt;概率与统计&lt;/h2&gt;
&lt;p&gt;首先我们要搞清楚MLE和MAP到底是什么方法，研究什么问题，用途是什么。而在此前要了解概率和统计的区别。&lt;/p&gt;
&lt;p&gt;概率和统计是关系密切的概念，但是两者对问题的关注方向不同。&lt;/p&gt;
&lt;p&gt;网上关于两者的关系和区别有很多说法和比喻，我在这里说一下我个人的理解： &lt;strong&gt;概率关注问题的结果，统计关注问题的过程。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;比如说，我有一个随机数生成器，它的原理是以某种特定的方法生成0或1，概率学会关注生成0或1的概率，而统计学会关注生成结果的方法——也就是生成随机数的过程。&lt;/p&gt;
&lt;p&gt;上面的例子可能还是有点绕，不如更现实一些。例如学校课堂上老师用座位表随机点人，问题是我会不会被老师点到，那么概率学会关注我有多少可能会被点，而统计会关注老师点人的习惯特点（例如老师因为右手拿座位表手指会挡住一些人名导致那个位置的人几乎不会被点）&lt;/p&gt;
&lt;p&gt;回到MLE和MAP上，MLE和MAP是统计领域的问题，这两种方法能够根据统计估计假设模型中的参数。&lt;/p&gt;
&lt;h2&gt;贝叶斯定理&lt;/h2&gt;
&lt;p&gt;在了解MLE和MAP之前，你还得了解 &lt;strong&gt;贝叶斯定理（Bayes’ Theorem）&lt;/strong&gt; ：&lt;/p&gt;
&lt;p&gt;$$P(A|B)=\frac{P(B|A)P(A)}{P(B)}$$&lt;/p&gt;
&lt;p&gt;别慌，贝叶斯定理其实是条件概率和联合概率公式推来的。&lt;/p&gt;
&lt;p&gt;我们可以浅显的从现实去看这个公式——假设在小区的白天，电动车响了，会不会是有人在偷车？令有人在偷车为事件A，电动车响了为事件B。等式左边，$P(A|B)$表示电动车响是有人在偷车的概率；等式右边，$P(B|A)$表示有人偷车的时候电动车响了，$P(A)$表示有人在偷车，$P(B)$表示电动车响了。&lt;/p&gt;
&lt;p&gt;当电动车发出声响的时候，大部分人都不会觉得是有人在偷车，为什么呢？因为我们知道：虽然$P(B|A)$偷车的时候电动车会响的概率很大，但是有人偷电动车这一事件发生$P(A)$的概率本身会较小，而且同时$P(B)$电动车会响的事情会很大——电动车发出响声再平常不过了。因此总体而言$P(A|B)$的概率就小了，也就是电动车响了的时候有人在偷车的概率小了。&lt;/p&gt;
&lt;p&gt;回到公式上，贝叶斯定理描述了 &lt;strong&gt;在考虑事情本身发生及其前提发生的可能性后，发生的概率会有多大？&lt;/strong&gt; ，或者说： &lt;strong&gt;你有多大把握相信一件事会发生。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;还不理解？不妨将上面那个例子设置得极端一些：假如说世道混乱，&amp;lt;span class=&quot;heimu&quot; title=&quot;民 风 淳 朴&quot;&amp;gt;&lt;s&gt;民风淳朴&lt;/s&gt;&amp;lt;/span&amp;gt;，你觉得偷电动车再常见不过，那么在你眼里$P(A)$有人偷电动车的概率很大，那么$P(A|B)$总体就会更大了。又或者小区里的电动车都很乖，平时正常使用都不怎么响的，那么$P(B)$电动车响声的概率就很小，总体而言$P(A|B)$总体就会更大，当响声时你也会觉得是不是有人在偷车。又或者知道电动车的警报系统很拉跨，很多时候即使有人偷车也不会响，那么$P(B|A)$很小，那么总体而言$P(A|B)$变小，偶尔响一下也不会觉得是有人在偷车，因为觉得大部分小偷偷车的时候都不响，警报系统没有可信度，现在响也不能证明有人在偷车。&lt;/p&gt;
&lt;p&gt;这就是我关于现实视角下的贝叶斯定理的解释和理解。&lt;/p&gt;
&lt;h2&gt;似然函数&lt;/h2&gt;
&lt;p&gt;极大似然估计（MLE），我们可以猜，极大就是最大值或者很大数的意思，而估计则可以从概率与统计中得到答案——估计模型的参数……那么，似然是什么？&lt;/p&gt;
&lt;p&gt;为此，要说说似然函数。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&quot;https://blog.csdn.net/u011508640/article/details/72815981&quot;&gt;参考文章&lt;/a&gt;里，我找到了一个很好的解释。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;似然（likelihood）这个词其实和概率（probability）是差不多的意思，Colins字典这么解释：The likelihood of something happening is how likely it is to happen. 你把likelihood换成probability，这解释也读得通。但是在统计里面，似然函数和概率函数却是两个不同的概念（其实也很相近就是了）。&lt;/p&gt;
&lt;p&gt;对于这个函数（或者你可以理解为一个抽象没有具体形态的方程，描述了模型参数 $\theta$ 和结果$x$的关系）：&lt;/p&gt;
&lt;p&gt;$P(x|\theta)$&lt;/p&gt;
&lt;p&gt;输入有两个：$x$表示某一个具体的数据； $\theta$ 表示模型的参数。&lt;/p&gt;
&lt;p&gt;如果 $\theta$ 是已知确定的，$x$是变量，这个函数叫做概率函数(probability function)，它描述对于不同的样本点$x$，其出现概率是多少。&lt;/p&gt;
&lt;p&gt;如果$x$是已知确定的， $\theta$ 是变量，这个函数叫做似然函数(likelihood function), 它描述对于不同的模型参数，出现$x$这个样本点的概率是多少。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可以回到上面那个关于概率和统计那个随机数生成器的例子，生成器随机生成0和1，我们假设生成器用的是某种模型，然后模型通过一个参数 $\theta$ 随机生成0和1。那么当 $\theta$ 已知时，令生成的结果$x$为变量，这时候$P(x|\theta)$就是概率函数，描述了0和1出现的概率分布。而当$x$已知时，令 $\theta$ 为变量，这时候$P(x|\theta)$就是似然函数，其表述了在生成器设置不同的参数 $\theta$ 下，已知的$x$出现的概率。&lt;/p&gt;
&lt;h1&gt;MLE与MAP&lt;/h1&gt;
&lt;h2&gt;最大似然估计 MLE&lt;/h2&gt;
&lt;p&gt;终于要写这部分了。&lt;/p&gt;
&lt;p&gt;想象面前有两个箱子，一个箱子装满了红球，一个箱子装满了白球。&lt;/p&gt;
&lt;p&gt;再想象我们有台机器，它会按照随机地从两个箱子里抽出一个球。&lt;/p&gt;
&lt;p&gt;我们先假设一个简单的模型来描述这个过程：&lt;/p&gt;
&lt;p&gt;$$f(x)=\begin{cases}
机器选择抽红球, &amp;amp; \theta &amp;gt; x &amp;gt; 0 \
机器选择抽白球, &amp;amp; 1 &amp;gt; x &amp;gt; \theta
\end{cases}$$&lt;/p&gt;
&lt;p&gt;机器产生从0到1的随机数x，然后判断$x$是比 $\theta$ 大还是小来决定是抽红球还是白球。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题来了，我们怎么找到最切合实际的模型参数 $\theta$ 呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答案是通过实际实验来找。&lt;/p&gt;
&lt;p&gt;那么现在开始抽球，让机器抽了10个球，实验结果 $x_0$ 是：红白红红白红白白红红。&lt;/p&gt;
&lt;p&gt;回到先前那个奇怪的函数$P(x|\theta)$，在抽象层面上，现在我们知道了结果$x$，可以通过这个函数（方程）求出 $\theta$ ——不过在此之前，我们要先求出这个函数在当前问题下的具体形式才能进行求解——也就是求出出现实验结果 $x_0$ 的似然函数。&lt;/p&gt;
&lt;p&gt;根据上面假设的模型，我们知道这是简单的几何概型（不知道几何概型也没关系），抽出红球的概率是 $\theta$ ，抽出白球的概率是$1-\theta$，那么出现结果 $x_0$ 的似然函数可以简单的推导出来：&lt;/p&gt;
&lt;p&gt;$P(x_0|\theta)=\theta\times(1-\theta)\times\theta\times\theta\times(1-\theta)\times\theta\times(1-\theta)\times(1-\theta)\times\theta\times\theta$&lt;/p&gt;
&lt;p&gt;化简得&lt;/p&gt;
&lt;p&gt;$P(x_0|\theta)=\theta^6(1-\theta)^4$&lt;/p&gt;
&lt;p&gt;这就是结果为 $x_0$ 时关于变量 $\theta$ 似然函数，$\theta$在我们假设的模型中则是模型的参数，我们可以画出函数图来看一下这玩意长什么样。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E8%AF%A6%E8%A7%A3%E6%9E%81%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1%E5%92%8C%E6%9C%80%E5%A4%A7%E5%90%8E%E9%AA%8C%E4%BC%B0%E8%AE%A1/%E4%BC%BC%E7%84%B6%E5%87%BD%E6%95%B0.png&quot; alt=&quot;函数图像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;长这样。&lt;/p&gt;
&lt;p&gt;横轴是 $\theta$ ，而纵轴则是$P(x_0|\theta)$，也就是在不同 $\theta$ 下出现抽球结果 $x_0$ （注意在上面的求似然函数的过程中，我们考虑了全部十次抽球结果， $x_0$ 代表了十次结果整体而不是分开的一次次结果）的概率。&lt;/p&gt;
&lt;p&gt;我们可以发现，当模型参数 $\theta$ 为$0.0011944$时，抽球抽出结果 $x_0$ 的概率最大。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;也就是说，我们模型里的参数 $\theta$ 为0.0011944时，最贴合实验结果 $x_0$ 。通过似然函数和已知的实验结果，求似然函数最大值对应的 $\theta$ 的方法，我们知道了给模型取什么样的参数 $\theta$ 最能贴合实验结果的方法，这个方法就是最大似然估计MLE。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;最大后验概率估计&lt;/h2&gt;
&lt;p&gt;好消息，&amp;lt;span class=heimu title=你知道的太多了&amp;gt;&lt;s&gt;在特异能力者对机器的读心实验中&lt;/s&gt;&amp;lt;/span&amp;gt;，我们知道了更多关于这台机器的情报，我们知道模型参数 $\theta$ 更有可能会是0.3——我们得到了关于 $\theta$ 的概率分布函数$P(\theta)$，这个函数告诉了我们实际的 $\theta$ 有可能会是什么，也就是“ $\theta$ 等于某个数x”成立的概率，根据情报，我们知道了 $P(\theta)=\frac{1}{\sqrt{2\pi}a}\exp\left(-\frac{\left(x-b\right)^{2}}{2a^{2}}\right)$。&lt;/p&gt;
&lt;p&gt;长这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E8%AF%A6%E8%A7%A3%E6%9E%81%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1%E5%92%8C%E6%9C%80%E5%A4%A7%E5%90%8E%E9%AA%8C%E4%BC%B0%E8%AE%A1/%E5%85%88%E9%AA%8C%E6%A6%82%E7%8E%87.png&quot; alt=&quot;$P(heta)$函数图像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;好吧这里面有很多槽点和漏洞，但是让我们别管它们！&lt;/p&gt;
&lt;p&gt;我们该怎么把新得到的情报引入我们的最大似然估计呢？答案是贝叶斯定理！&lt;strong&gt;在考虑事情本身发生及其前提发生的可能性后，发生的概率会有多大？&lt;/strong&gt;——我们不只参考了实验结果，也参考了 $\theta$ 本身等于某个数的概率$P(\theta)$。&lt;/p&gt;
&lt;p&gt;在最大似然估计中，我们通过取最大$P(x|\theta)$来获得最切合的模型参数 $\theta$ ，我们可以用条件概率表示$P(\theta|x)$当实验结果为x时参数为 $\theta$ 的概率。&lt;/p&gt;
&lt;p&gt;根据贝叶斯定理，可知：&lt;/p&gt;
&lt;p&gt;$$P(\theta|x)=\frac{P(x|\theta)P(\theta)}{P(x)}$$&lt;/p&gt;
&lt;p&gt;当$P(\theta|x)$函数值最大的时候，也就是 $\theta$ 最有可能取得的数。因此我们找到$P(\theta|x)$最大时对应的 $\theta$ 就可以求得在考虑了新情报的情况下最合适实验结果的 $\theta$ 。&lt;/p&gt;
&lt;p&gt;在实际问题中我们已知实验结果，变量时 $\theta$ ，因此$x$为定量，则$P(x)$也为定量，因此想找等式左边的最大值，只需要关注右边分子的最大值，问题变成了找$P(x|\theta)P(\theta)$最大时对应的x。&lt;/p&gt;
&lt;p&gt;在前面我们知道了$P(x_0|\theta)=\theta^6(1-\theta)^4$，根据后来的情报我们又知道了$P(\theta)=\frac{1}{\sqrt{2\pi}a}\exp\left(-\frac{\left(x-b\right)^{2}}{2a^{2}}\right)$，那么$P(x|\theta)P(\theta)$不就是将两者乘起来了嘛！&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;通过计算机&amp;lt;/span&amp;gt;轻松画出函数图像找到最大值。（其实在实际计算中不用画图像也能求最大值）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E8%AF%A6%E8%A7%A3%E6%9E%81%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1%E5%92%8C%E6%9C%80%E5%A4%A7%E5%90%8E%E9%AA%8C%E4%BC%B0%E8%AE%A1/%E5%90%8E%E9%AA%8C%E6%A6%82%E7%8E%87.png&quot; alt=&quot;后验概率&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我们可以找到函数最大时 $\theta$ 对应的值：$0.581$。&lt;/p&gt;
&lt;p&gt;这就是考虑了新情报以后最切合实验结果的模型参数。&lt;/p&gt;
&lt;p&gt;回到上面的公式 $P(\theta|x)=\frac{P(x|\theta)P(\theta)}{P(x)}$ 上，根据先验概率和后验概率的定义，我们知道在公式中，$P(\theta)$是先验概率，而$P(\theta|x)$是后验概率。在我们上面求最切合的模型参数的方法里，我们把求最切合模型参数的问题转换成了求解后验概率$P(\theta|x)$的最大值的问题——这就是“最大后验估计”。&lt;/p&gt;
&lt;h1&gt;后话&lt;/h1&gt;
&lt;p&gt;需要知道的是，不管是最大似然估计还是最大后验估计，我们都是在求我们所假设的模型的最佳参数，由于模型本身是假设的，所以结果可不可靠除了参数以外，也要选择切合实际的模型。在上面的例子中，万一机器抽球原理不是我们假设的模型而是其他的呢？&lt;/p&gt;
&lt;p&gt;而在最大后验估计中，“新情报”（也就是先验概率）的可靠程度也影响了最大后验估计的结果，有时候不一定是什么都加入考虑加入计算就能得出最贴合实际的模型和参数。同样还是上面那个例子，如果异能者为了拖延我们对机器的研究，故意造假给出了先验概率$P(\theta)$呢，那么我们的计算结果就会受到假信息的干扰，从而难以得到正确的结果。&lt;/p&gt;
&lt;p&gt;&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;或许我们应该调查一下那一名异能者。&lt;/s&gt;&amp;lt;/span&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;参考文章&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/u011508640/article/details/72815981&quot;&gt;详解最大似然估计（MLE）、最大后验概率估计（MAP），以及贝叶斯公式的理解&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><author>FishCat233</author></item><item><title>热烈庆祝博客1000天——</title><link>https://www.aaafishcat.top/posts/blog-celebrate-for-1000-days</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/blog-celebrate-for-1000-days</guid><description>啊？这就1000天了？——我呕心沥血的折腾博客史，堂堂连载！</description><pubDate>Sun, 10 Mar 2024 16:36:40 GMT</pubDate><content:encoded>&lt;p&gt;啊？这就1000天了？&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;疑惑&lt;/h1&gt;
&lt;p&gt;我相信绝大多数&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;（其实是100%）&lt;/s&gt;&amp;lt;/span&amp;gt;的人都有对标题有疑问：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最近&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;（前天/昨天）&lt;/s&gt;&amp;lt;/span&amp;gt;才刚听说你小子的博客，今天就告诉我你的博客1000天了？？？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;得得得，其实是我在吹逼了&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;标题党&lt;/s&gt;&amp;lt;/span&amp;gt;，事情是这样：&lt;/p&gt;
&lt;p&gt;对于这个新博客来说，今天确实是第三天，拿出来给人看的第二天。而对于295天前左右听说我在折腾博客的人来说，这是第295天。对于1000天前听说我在尝试建站的人来说，这是第1000天。&lt;/p&gt;
&lt;p&gt;好吧其实后面两类人除了我一个人也没有——因为&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;害羞&lt;/s&gt;&amp;lt;/span&amp;gt;当时还搞不懂建站的七七八八就搁置了，并且我也没有什么想写的东西。&lt;/p&gt;
&lt;p&gt;写一篇博文纪念一下过去吧，至少如今实现了以前的愿想——虽然不知道会持续多久。&lt;/p&gt;
&lt;h1&gt;Wordpress 与 那年的我&lt;/h1&gt;
&lt;p&gt;今天是2024年3月10日，在1000天前，也就是2021年6月14日，在那个无聊的暑假&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;&lt;s&gt;也许是暑假吧&lt;/s&gt;&amp;lt;/span&amp;gt;，&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;由于现实条件受限&amp;lt;/span&amp;gt;，我折腾起ksweb——一款将手机变为服务器搭建web环境，在我的手机上面，我跑起了 Wordpress 来当我的博客，但是因为我对于网络和建站的相关知识完完全全是零，并且我因为是学生党，资金匮乏，最终在一番折腾以后，因为没有域名的问题以及各种让我头疼的技术问题，这个博客不得不搁置了起来。&lt;/p&gt;
&lt;p&gt;我因为ksweb了解到了Wordpress，又因Wordpress了解到了“个人博客”这个概念。&lt;/p&gt;
&lt;p&gt;在2022年的某天&amp;lt;span class=&quot;heimu&quot; title=&quot;你知道的太多了&quot;&amp;gt;（我也不记得哪天了，后续我再从日记里查证吧）&amp;lt;/span&amp;gt;，我从网上了解到了有大佬做二级域名的分发（迷迭香的二级域名），在这里感谢那个大佬。虽然到最后我也不懂那个域名怎么用，只是按着网上的教程照猫画虎、瞎猫碰死耗子地瞎配置，花了很多精力以后，最后才成功。&lt;/p&gt;
&lt;p&gt;尽管配置成了，但是因为要用手机保持web服务器运行以及公网ip（那个时候我远程访问靠的都是ipv6），再加上我折腾个人博客的主要原因只是折腾而不是真的想要去做个人博客（虽然我在做的时候告诉我我可以写点东西到这个博客里面，但是最后还是没有什么想写的东西）&lt;/p&gt;
&lt;p&gt;所以我很快就把注意力放到了搭建个人博客以外的事情上，因此这个项目彻底搁置了，甚至随着时间渐渐沉入了记忆的深处，被遗忘了。&lt;/p&gt;
&lt;p&gt;直到我今天在图床网站上看到了2021年上传的图片才想起来这个博客。&lt;/p&gt;
&lt;h1&gt;初见 Hexo，Github Pages&lt;/h1&gt;
&lt;p&gt;2024年5月20日，我从一个本地知名学校的匿名墙网站上了解到了 Hexo 和 Github Pages 这两样东西，当我知道 Hexo 可以用来做个人博客，而且 Hexo 搭配 Github Pages 的方案还是免费时，我 belike：&lt;/p&gt;
&lt;p&gt;个人博客，我来啦！&lt;/p&gt;
&lt;p&gt;——当时我大概是这么想的，总之动手就做，反复折腾，来回试了很多个主题，比如说 Icarus、NexT、Butterfly ，不过我的相关技术知识还是很贫弱，当时为了能研究怎么插入本地图片，我折腾了好几天也没搞清楚，最后就搁置了。&lt;/p&gt;
&lt;p&gt;一是没法插入本地图片，我也不喜欢什么都传到图床，再是我还是不知道我写什么、该怎么写，所以多个因素叠加的最终结果就是——&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;鸽了！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不过是 Hexo &amp;amp; Github Pages 的组合，网站还是在的。&lt;/p&gt;
&lt;h1&gt;现在 实现最初的愿景&lt;/h1&gt;
&lt;p&gt;很庆幸我前些天产生了“我要不要重新折腾博客”的想法，不然也不会看到博客现在的样子。&lt;/p&gt;
&lt;p&gt;虽然我还是学生，但是现在的我相比当初，有了一小部分省下来的闲钱可以去做到一些简单的事情，这些年折腾的结果，包括我主动学习了解了一些相关知识，也能简单地去折腾博客了——至少比当时只会循规蹈矩的跟着教程，我有了能自己查证部分出错原因的能力。&lt;/p&gt;
&lt;p&gt;还等什么，动手做！——域名？买！域名记录？做！CDN？配！博文？写！&lt;/p&gt;
&lt;p&gt;这就是这个博客现在的形态，有如当年我所期望的形态：一个属于自己的博客，上面写着一些自己觉得很棒的文章，记着很酷的事情。&lt;/p&gt;
&lt;h1&gt;在未来&lt;/h1&gt;
&lt;p&gt;距离那年初见已经 1000 天了，不禁有些感慨了。在多年后，不只是博客，当年那些我所期望的觉得很酷很赞的事情，我现在正在或有意识或无意识中一个个实现。&lt;/p&gt;
&lt;p&gt;我觉得与其说无意识，倒不如说是我当时的那颗心——初心沉入了记忆深处，或许我忘了当时自己的那些折腾，吃的那些错误，花上好久去尝试处理一个现在看起来很简单的错误的过程，但是我依然记得“我想要做这个”这个愿望。&lt;/p&gt;
&lt;p&gt;幸运的是，未来的我实现了过去的我的愿望。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>统计学习三要素</title><link>https://www.aaafishcat.top/posts/a-brief-note-of-statical-learning-book-part-1</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/a-brief-note-of-statical-learning-book-part-1</guid><description>《统计学习方法》读书小记 其一</description><pubDate>Mon, 11 Mar 2024 12:21:34 GMT</pubDate><content:encoded>&lt;h1&gt;统计学习三要素&lt;/h1&gt;
&lt;p&gt;统计学习方法都是由 &lt;strong&gt;模型、策略和算法&lt;/strong&gt; 构成的，这就是统计学习三要素，它们之间的关系可以表示为：&lt;/p&gt;
&lt;p&gt;$$ 方法 = 模型 + 策略 + 算法 $$&lt;/p&gt;
&lt;h2&gt;模型&lt;/h2&gt;
&lt;p&gt;在监督学习中，模型就是所要学习（模仿）的条件概率分布或决策函数。&lt;/p&gt;
&lt;p&gt;在参考文章中看到一个很通俗的例子来解释什么是模型：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;想象你正在尝试为一堆乱飞的鸟找一个轨迹。模型就像你选择的特定的路径或形状，例如你认为它们是按照直线、圆形或某种波浪线飞行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型是对现象背后原理的猜想。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;而模型多是带有参数的，不同参数可以产生不同效果的模型，&lt;strong&gt;而所有参数各自的模型的总和则构成了假设空间。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;借上面那个乱飞鸟的例子，例如模型（猜想）是鸟是匀速圆形飞行的，那么参数就可以是圆形的半径，鸟的速度。不同的半径和速度构成的具体轨迹都是不同的，因此对鸟飞行轨迹的预测产生了不同的结果，而所有半径和速度可能取得的值的组合所产生的多个模型构成的总和就是假设空间。&lt;/p&gt;
&lt;h2&gt;策略&lt;/h2&gt;
&lt;p&gt;策略，即模型的学习策略，换句话说是从假设空间中所有可能的模型里挑选模型的策略。&lt;/p&gt;
&lt;p&gt;目标是选择最优的模型，也就是最能准确预测乱飞鸟轨迹的模型。&lt;/p&gt;
&lt;p&gt;假设空间里面充斥着各种参数组合产生的模型，我们可以通过对比各种模型所给出的预测值和真实值的差距来筛选出最优的模型。&lt;strong&gt;这个用于计算预测值和真实值差距的函数就是损失函数——又或叫代价函数。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;损失函数可以用来测量模型的错误程度，从而评估模型的准确度。&lt;/p&gt;
&lt;p&gt;不过单计算当前情况下的损失值是不够的，因为由于实际情况下多变复杂，不同情况下同一个模型的损失（即错误程度）可能不同，因此应该考虑在所有情况下损失都能维持较小的模型——也就是令损失函数期望值较小的模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;损失函数的期望值代表了所有情况下的平均意义下的损失，称为期望损失或风险函数。&lt;/strong&gt;&lt;/p&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;
&lt;p&gt;但是不可能简简单单的根据飞一次的差值来评估自己的“理论”（模型）的好坏，因为有可能不同情况下不同“理论”的适用程度不同，这个模型能预测好这次的飞行，但不一定能预测好下一次的飞行。&lt;/p&gt;
&lt;p&gt;因此你会考虑记录多次飞行的结果和预测结果的差值，最终算出各个模型差值的平均数，然后选平均差值最小的那个。&lt;/p&gt;
&lt;p&gt;这个平均差值就是期望损失（风险函数）。&lt;/p&gt;
&lt;h2&gt;算法&lt;/h2&gt;
&lt;p&gt;算法是学习的主干，在确定模型和评估模型好坏的方法（策略）后，&lt;strong&gt;还需要一个寻找最优模型的方法——这就是算法。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例如在上面的纸飞机中，你可以随便选参数一个个评估来寻找最好的“理论”（不过那样会很慢！），也可以一步步的让参数递增来寻找。&lt;/p&gt;
&lt;h1&gt;三要素与统计学习方法&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;统计学习方法之间的不同，主要来自于模型、策略、算法的不同。确定了模型、策略、算法，统计学习方法也就确定了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;后话（博主的话）&lt;/h1&gt;
&lt;p&gt;作为小记，我尽量使用了较为简洁的语言去阐明三者的关系，但是受限于我个人的理解水平和表述水平，有些地方可能还是勉勉强强甚至有理解错误的情况，因此如果有听不懂的，可以在试着在评论区问，看到了的我应该会回。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;参考文章&lt;/h1&gt;
&lt;p&gt;农凡.&lt;a href=&quot;https://zhuanlan.zhihu.com/p/654174621&quot;&gt;1-3 统计学习三要素(模型、策略与算法)&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>小记渲染管线</title><link>https://www.aaafishcat.top/posts/note-of-render-pipeline</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/note-of-render-pipeline</guid><description>最近简单了解了一些渲染管线的知识，故作小记。</description><pubDate>Wed, 20 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;小记渲染管线，不会涉及复杂的底层原理，仅供简单概念理解。&lt;/p&gt;
&lt;p&gt;本文将以游戏中常见的3D模型渲染出画面的过程为例，讲述什么是渲染管线。&lt;/p&gt;
&lt;h1&gt;在了解渲染管线前&lt;/h1&gt;
&lt;p&gt;在电脑中，整个绘制工作一般由CPU指挥GPU进行——CPU会提供具体任务和数据，而GPU负责执行和计算。&lt;/p&gt;
&lt;h2&gt;为了绘制所要准备的那些数据&lt;/h2&gt;
&lt;p&gt;电脑所要渲染的三维物体，其实是由模型和材质贴图构成，而模型在电脑中则是由一个个点以及点上的数据（例如uv信息、法线等等），这些数据被称为&lt;strong&gt;顶点缓存（Vertex Buffer）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;由点可以构成面，但是很多面都是形状各异的，为此可以通过顶点组合的方式将面分成数个三角形面进行绘制，例如一个正方形可以通过选中4个顶点的3个绘制三角形，然后再绘制另一个三角形，组合起来便可形成一个完整的正方形，这样所有形状各异的面都会被分割成为数个可以绘制的三角形。&lt;/p&gt;
&lt;p&gt;不过因为分解和绘制是分开的（CPU不会进行绘制），因此和顶点缓存一样，分出来的三角面的数据也要存储，具体些则是顶点组合需要存储，而在顶点组合中，记录的不是具体顶点的坐标，而是顶点的索引（代号），因此存储的数据会被称为&lt;strong&gt;索引缓冲（Index Buffer）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;除此之外，在游戏中还有摄像机相关的数据以及光照相关的数据需要一并准备。&lt;/p&gt;
&lt;p&gt;还有一个更重要且较为耳熟能详的东西，就是着色器（Shader）——可以草率理解为一些用于对模型贴图进行处理的代码脚本。也是在绘制前需要准备的数据。&lt;/p&gt;
&lt;h1&gt;渲染管线&lt;/h1&gt;
&lt;p&gt;从CPU将绘制所需要的数据给GPU后，GPU通过对数据的处理并绘制的过程，则是&lt;strong&gt;渲染管线&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;值得一提的是，广义上的渲染管线也包括了CPU准备数据的阶段。&lt;/p&gt;
&lt;h2&gt;开始绘制&lt;/h2&gt;
&lt;p&gt;GPU收到了CPU的数据，开始绘制，其中有几个重要的流程，下面会按顺序进行介绍。&lt;/p&gt;
&lt;h3&gt;顶点着色 Vertex Shader&lt;/h3&gt;
&lt;p&gt;在这一步，GPU会按照着色器里写的脚本对顶点缓冲里的数据进行额外处理。例如将模型的顶点坐标变换为屏幕上的坐标。&lt;/p&gt;
&lt;h3&gt;Triangle Processing&lt;/h3&gt;
&lt;p&gt;在这一步，GPU会绘制上面提到的三角形面。&lt;/p&gt;
&lt;h3&gt;光栅化 Rasterization&lt;/h3&gt;
&lt;p&gt;因为屏幕是一个个像素组成，因此GPU会将三角面变为具体的像素。&lt;/p&gt;
&lt;p&gt;同时在这一步GPU会进行深度测试——也就是判断三角面之前的遮挡关系。&lt;/p&gt;
&lt;h3&gt;像素着色 Pixel Shader&lt;/h3&gt;
&lt;p&gt;在这一步，GPU会根据Shader给模型上材质或者是上光影效果。&lt;/p&gt;
&lt;h3&gt;Frame Buffer&lt;/h3&gt;
&lt;p&gt;在这一步，GPU会添加一些后处理手段，例如抗锯齿、辉光之类的效果。&lt;/p&gt;
&lt;h1&gt;参考文章&lt;/h1&gt;
&lt;p&gt;业余蚊子.&lt;a href=&quot;https://www.bilibili.com/video/BV1qY4y1V79z/&quot;&gt;【游戏开发基础知识】什么是渲染管线？如何绘制3D物体？&lt;/a&gt;&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>小记滑动窗口</title><link>https://www.aaafishcat.top/posts/algorithm-slide-windows</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/algorithm-slide-windows</guid><description>滑动窗口法可用于特定条件下的数组问题。本文小记一下使用过程中的感受。</description><pubDate>Wed, 03 Jul 2024 10:45:53 GMT</pubDate><content:encoded>&lt;h1&gt;滑动窗口法&lt;/h1&gt;
&lt;h2&gt;所需变量&lt;/h2&gt;
&lt;p&gt;滑动窗口由三部分构成：边界，条件相关变量，需求记录变量。&lt;/p&gt;
&lt;h3&gt;边界&lt;/h3&gt;
&lt;p&gt;边界由两个指针构成，分别称为左边界和右边界。&lt;/p&gt;
&lt;h3&gt;条件相关变量&lt;/h3&gt;
&lt;p&gt;条件相关变量是用于存储题目所需条件数值的变量。（例如区间和，区间长）&lt;/p&gt;
&lt;h3&gt;需求记录变量&lt;/h3&gt;
&lt;p&gt;需求记录变量是用于算法计划返回的变量，也是题目需求的变量，通常是最大值或最小值（例如区间和最大值，或是满足条件的区间最长长度）&lt;/p&gt;
&lt;h2&gt;方法步骤&lt;/h2&gt;
&lt;p&gt;&lt;s&gt;听好了，我只写一遍。&lt;/s&gt;&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;li&gt;需求记录变量为所求&lt;/li&gt;
&lt;li&gt;&lt;s&gt;去跟小伙伴们吹逼&lt;/s&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;更加易懂的代码版本（也就是模板代码）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def sumWindow(nums: List[int]) -&amp;gt; nums:
    # 窗口左右边界
    left = 0
    right = 0
    # 条件相关变量
    sum = 0     # 以窗口内元素总和为示例
    res = 0     # 以求最大元素总和为例

    # 遍历
    while right &amp;lt; len(nums):
        # 更新值
        sum += nums[right]

        # 如果满足条件，则左边界移动，遍历并记录，直至破坏条件
        while sum &amp;gt; target:
            # 记录最大值
            res = max(sum,res)
            # 左边界移动，更新 sum
            sum -= nums[left]
            left += 1

        # 右边界移动
        right += 1

    return res      # 别高兴到忘了返回...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;论为什么滑动窗口比暴力快&lt;/h2&gt;
&lt;p&gt;猜测上，滑动窗口采用了一种特别的遍历方法，能够在有效排除不符合条件的组合的同时不排除满足条件的组合。&lt;/p&gt;
&lt;p&gt;由于满足条件的数组之间存在有一定相似性，滑动窗口法通过利用这个相似性——在两端移动过程中处于满足条件和不满足条件之间反复横跳，以高效遍历所有可能的组合。&lt;/p&gt;
&lt;h1&gt;经典为例&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://leetcode.cn/problems/minimum-size-subarray-sum/&quot;&gt;长度最小的子数组&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;给定一个含有 n 个正整数的数组和一个正整数 target。找出该数组中满足其总和大于等于 target 的长度最小的子数组&lt;code&gt;[numsl, numsl+1, ..., numsr-1, numsr]&lt;/code&gt;，并返回其长度。如果不存在符合条件的子数组，返回 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;示例 1：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;输入：target = 7, nums = [2,3,1,2,4,3]&lt;/p&gt;
&lt;p&gt;输出：2&lt;/p&gt;
&lt;p&gt;解释：子数组 [4,3] 是该条件下的长度最小的子数组。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;显然可以使用暴力解法，但是本文在此不做提及。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -&amp;gt; int:
        # 滑动窗口法
        left = 0    # 左边界
        right = 0   # 右边界
        sum = 0     # 条件相关变量（区间和）
        ret = 0     # 需求记录变量（区间和最大值）
        length = len(nums)

        while right &amp;lt; length:
            # 稳定往窗口加数
            # 右边界无条件移动，并且移动时计算当前的条件相关变量值
            sum += nums[right]
            right += 1

            # 满足题目条件记录下来，然后 持续 往窗口减数
            # 仅在条件相关变量满足条件时执行，左边界移动，破坏满足的条件，并记录需求记录变量
            while sum &amp;gt;= target:
                # 记录
                if ret == 0:
                    ret = right - left
                else:
                    ret = min(ret, right - left)
                
                # 减数
                sum -= nums[left]
                left += 1
        
        return ret
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><author>FishCat233</author></item><item><title>剧情情节与矛盾论</title><link>https://www.aaafishcat.top/posts/novel-plot-with-contradictions</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/novel-plot-with-contradictions</guid><description>尝试从矛盾论的角度来看待剧情情节.</description><pubDate>Wed, 23 Oct 2024 17:54:29 GMT</pubDate><content:encoded>&lt;h1&gt;「剧情情节」与「矛盾论」&lt;/h1&gt;
&lt;p&gt;最近看了一篇文章，文章内容讲述关于情节发展和矛盾论的关系，以及如何运用矛盾论来推动剧情。读文后有所感触，故作此文。&lt;/p&gt;
&lt;p&gt;提前打一针预防针，我对矛盾论和剧情情节创作造诣颇浅，如果有误，欢迎指出。&lt;/p&gt;
&lt;h2&gt;矛盾论&lt;/h2&gt;
&lt;h3&gt;矛盾与「对立与统一」&lt;/h3&gt;
&lt;p&gt;哲学中的「矛盾」显然是和生活用语中的「矛盾」是不同的，因此首先需要说明什么是「矛盾」。「矛盾」是一种关系（也有说是一种状态），不论是关系还是状态，「矛盾」都指向于表达一种事物间的「对立与统一」的关系。在这里，会将矛盾定义为事物间的关一种关系。&lt;/p&gt;
&lt;p&gt;「对立」，指的是矛盾的事物各方相互对立，如同数轴的两头，各占一方。其他事物如同数轴上的点，在一端便不能在另一端，如同正数和负数，没有交集。&lt;/p&gt;
&lt;p&gt;「统一」，或我所习惯的称呼为「相对性」，指的是矛盾的事物各方是相对的，而非绝对的属于任何一方。矛盾各方的对立与正负数这种二元对立不同，各方的对立是相对对立。&lt;/p&gt;
&lt;p&gt;比如说将数轴上的数分为大数和小数，是大数，就不会是小数，但是大小本身是相对的，大是相对大（较大），小是相对小（较小）。组合起来便是矛盾——一种「对立与统一」的关系。&lt;/p&gt;
&lt;h3&gt;矛盾的「普遍性」&lt;/h3&gt;
&lt;p&gt;矛盾是「普遍的」。矛盾普遍地存在于事物之中，如同数学所表达的关系一样普遍。&lt;/p&gt;
&lt;h3&gt;矛盾的发展&lt;/h3&gt;
&lt;p&gt;矛盾不会消失，也无法消灭，矛盾以「转化」为主——一个矛盾转化为另一个矛盾，又或是再问题中由主要矛盾变为次要矛盾。&lt;/p&gt;
&lt;h2&gt;「剧情情节」与「矛盾论」&lt;/h2&gt;
&lt;p&gt;理论是抽象的，回归现实能更好理解。于是这就讨论如何应用矛盾论来辅助情节创作。&lt;/p&gt;
&lt;h3&gt;矛盾推动剧情情节&lt;/h3&gt;
&lt;p&gt;直接说答案：矛盾通过产生问题来推动情节。&lt;/p&gt;
&lt;p&gt;矛盾如同地基，有了矛盾就会有问题，有了问题就有主角的动机， 主角去尝试解决不可避的问题，剧情就推动了。&lt;/p&gt;
&lt;h3&gt;从普遍的矛盾到有用的矛盾&lt;/h3&gt;
&lt;p&gt;由于矛盾的普遍性，在小说世界中有无数的矛盾，但是对于情节创作来说，往往「较大的矛盾」才能易于为创作所使用。&lt;/p&gt;
&lt;p&gt;例如人与人之间普遍存在的生存竞争——活的好或死的坏。在人人都能被满足时，这个矛盾是「较小的」，人们不会为了生存竞争而相互斗争，也就不会产生「大问题」。而当所有人陷入困境，物质无法满足所有人时，这个矛盾便变得足够大，甚至使得人与人之间相互残杀。就像反派将几个相互至亲之人关入房间，告知只有一人能走出房间一样，人人生存竞争的矛盾由小变大，便有了背叛贪婪等等人人相残的大问题，情节也由此推动了。&lt;/p&gt;
&lt;h3&gt;动态的矛盾&lt;/h3&gt;
&lt;p&gt;正如先前所说，矛盾是会发展的，会变化的。在主角解决问题后，矛盾不会消失，而是会转化——这也是为什么在看一些小说情节时会发现作者能将一个个问题连在一起。比如说，主角在出手低级越阶斩杀高级角色后，原先的矛盾「高级角色想要杀主角」则可以转化为「主角实力底牌暴露」，又或者「被更强大的角色盯上」，「战后负伤战斗力不断下降」等等。&lt;/p&gt;
&lt;p&gt;总而言之，在解决问题后，原先的矛盾转化为了其他的矛盾，或让它们变大，或让它们变小，而又能产生新的问题。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>SSH 连不上 github 怎么办啊？</title><link>https://www.aaafishcat.top/posts/debug-git-ssh-config</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/debug-git-ssh-config</guid><description>Proxy 也连不上嘞？——可能是没配置好 Proxy</description><pubDate>Fri, 07 Feb 2025 15:55:11 GMT</pubDate><content:encoded>&lt;p&gt;我不造啊。突然间就连不上了，变量也忒多了，于是不得不花几个钟上网到处找才解决问题。&lt;/p&gt;
&lt;h1&gt;代理在干嘛？有没有发力？&lt;/h1&gt;
&lt;p&gt;首先检查的就是代理程序是不是只进行了HTTP代理。虽然暂时不是很懂代理原理，但是显然不对SSH进行代理配置是不行的，于是我上网寻找如何给SSH进行代理。&lt;/p&gt;
&lt;p&gt;忍不住吐槽的是，网上搜出来的东西全是前篇一律：如何在 Mac 上给 ssh 配置代理？如何在 Linux 上给 ssh 配置代理？搜出来的几百篇（夸张）文章都是同一样的图和同一样的命令……甚至同一样的文本（这是真的）。&lt;/p&gt;
&lt;p&gt;在我以为&lt;s&gt;很小众的&lt;/s&gt; Windows 用户在这鬼打墙一样的互联网上没有容身之所、要颠沛流离的时候，我找到了&lt;a href=&quot;https://blog.imyan.ren/posts/4d70a82d/&quot;&gt;这个&lt;/a&gt;，跟着博客成功配置了代理。为了防止失联，所以我还是把方法重新整理一下吧。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先就像正常配置ssh一样打开配置文件。&lt;/p&gt;
&lt;p&gt;什么？你不会？ssh配置文件应该在 &lt;code&gt;~/.ssh&lt;/code&gt;(git bash)，或者 &lt;code&gt;C:\Users\用户名\.ssh&lt;/code&gt;(Windows) 目录下，这个目录下有个&lt;code&gt;config&lt;/code&gt;的文件（细节没有.xxx扩展名，此外如果没有这个文件你可以创建一个）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写入配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
    ProxyCommand &quot;ProxyCommand &quot;C:\Program Files\Git\mingw64\bin\connect.exe&quot; -S 127.0.0.1:10808 %h %p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一行意思是对 github.com 有效，第二行则是：代理的程序（我这里的&lt;code&gt;connect.exe&lt;/code&gt;就是 git bash的东东），-S 代表 Sockets5 代理，然后后面是代理的地址和端口，最后 &lt;code&gt;%h %p&lt;/code&gt;照抄就行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存，然后 &lt;code&gt;ssh -T git@github.com&lt;/code&gt;试试，如果正常连接上就说明没问题，你可以收工了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;唉，端口22&lt;/h1&gt;
&lt;p&gt;如果还有问题——像我一样的&lt;code&gt;kex_exchange_identification: Connection closed by remote host&lt;/code&gt;，那你有福了。&lt;/p&gt;
&lt;p&gt;我直接放参考资料吧，最后是我自己的从参考资料里面找到有效的解法：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/orgs/community/discussions/55269&quot;&gt;kex_exchange_identification: Connection closed by remote host · community · Discussion #55269&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.github.com/en/authentication/troubleshooting-ssh/using-ssh-over-the-https-port&quot;&gt;Using SSH over the HTTPS port - GitHub Docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;你可以试试这条命令是否能连上&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -T -p 443 git@ssh.github.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果能连上那应该用我同样的方法是可以的。简单说就是把 22 端口改成 443 端口，直接改 ssh的 &lt;code&gt;config&lt;/code&gt; 就行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
    ProxyCommand &quot;ProxyCommand &quot;C:\Program Files\Git\mingw64\bin\connect.exe&quot; -S 127.0.0.1:10808 %h %p
    Hostname ssh.github.com
    Port 443
    User git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;具体参数意思懒得写了（猜也能猜出来），不懂就问 ai 吧。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>git clone 报错什么 RPC failed 啊怎么办？</title><link>https://www.aaafishcat.top/posts/debug-git-rpc-failed</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/debug-git-rpc-failed</guid><description>此事在白咕咕的debug记录中亦有记载。</description><pubDate>Sat, 08 Feb 2025 15:55:40 GMT</pubDate><content:encoded>&lt;p&gt;在使用conda和pip安装某仓库环境的时候报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
  error: 30 bytes of body are still expected
  fetch-pack: unexpected disconnect while reading sideband packet
  fatal: early EOF
  fatal: fetch-pack: invalid index-pack output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看不懂，干脆问ai，然后在ai的答案里面找到了解药。&lt;/p&gt;
&lt;p&gt;我选择的方法是把http更换成ssh（&lt;a href=&quot;https://blog.whispery.top/2025/02/2025020701/&quot;&gt;毕竟昨天刚解决ssh的连接问题&lt;/a&gt;）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 尝试SSH协议（需提前配置SSH key）
git config --global url.&quot;git@github.com:&quot;.insteadOf &quot;https://github.com/&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就，解决了。&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;下面是 DeepSeek 的回答，其中，我采取了更换协议的方法。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在安装过程中出现Git相关的网络错误通常与仓库克隆问题或网络连接不稳定有关。以下是分步解决方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;升级Git和Pip&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 更新Git配置（针对大仓库）
git config --global http.postBuffer 524288000
git config --global core.compression 0
# 升级pip和工具链

 pip install --upgrade pip setuptools wheel
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;更换Git协议（二选一）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 尝试SSH协议（需提前配置SSH key）
git config --global url.&quot;git@github.com:&quot;.insteadOf &quot;https://github.com/&quot;

# 或强制使用HTTP/1.1
git config --global http.version HTTP/1.1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;手动克隆仓库（关键步骤）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 先单独克隆主仓库（替换为实际仓库URL）
git clone https://github.com/yourusername/llava-next.git
cd llava-next
# 初始化子模块（如果有）
git submodule update --init --recursive
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用镜像源安装&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在项目目录中运行（已手动克隆后）
pip install -e &quot;.[train]&quot; \
 -i https://pypi.tuna.tsinghua.edu.cn/simple \
 --trusted-host pypi.tuna.tsinghua.edu.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;若仍遇到包下载问题&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 对特定包使用镜像源
pip install torch torchvision -i https://mirrors.aliyun.com/pypi/simple/
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;其他注意事项：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;确保已安装构建依赖：&lt;code&gt;sudo apt-get install -y git python3-dev python3-venv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果使用代理，请配置git代理：&lt;code&gt;git config --global http.proxy your_proxy:port&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;尝试在网络状况较好的时段进行操作&lt;/li&gt;
&lt;li&gt;对于特别大的仓库，可添加&lt;code&gt;--depth 1&lt;/code&gt;参数进行浅克隆&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果问题依旧存在，请提供：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;完整的安装命令输出&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip -V&lt;/code&gt; 和 &lt;code&gt;git --version&lt;/code&gt; 的版本信息&lt;/li&gt;
&lt;li&gt;是否使用特殊网络环境（公司代理/VPN等）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样可以进一步诊断具体问题原因。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>写一个 hexo 插件</title><link>https://www.aaafishcat.top/posts/hexo-heimu-plugin</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/hexo-heimu-plugin</guid><description>介绍一下我写的一个简单hexo插件 hexo-tag-plugin-heimu。</description><pubDate>Sun, 09 Feb 2025 18:17:32 GMT</pubDate><content:encoded>&lt;h1&gt;黑幕，绝对有黑幕！&lt;/h1&gt;
&lt;p&gt;今天在尝试美化hexo博客的突然灵光一现，然后就把我之前因为每次都要写 &lt;code&gt;{ % raw % }&lt;/code&gt; 这样的麻烦的hexo外挂标签语法而不怎么用的黑幕功能做成了插件。&lt;/p&gt;
&lt;p&gt;好吧简单说就是把{% heimu 这个 标题在这 %}写成了一个插件。&lt;/p&gt;
&lt;p&gt;是不是很眼熟？{% heimux 像这样的事情…… 后面忘了总之加入绝地潜兵 %}很正常，因为在萌娘百科就有这样的效果。&lt;/p&gt;
&lt;h1&gt;好的，那么我怎么用呢？&lt;/h1&gt;
&lt;p&gt;你可以参照&lt;a href=&quot;https://github.com/FishCat233/hexo-tag-plugins-heimu&quot;&gt;FishCat233/hexo-tag-plugins-heimu: 适用于 Hexo 的黑幕标签插件&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;或者更加省流一点，在你的 hexo 博客目录执行这个：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install hexo-tag-plugins-heimu --save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后每当你想用使用黑幕的时候，&lt;code&gt;{%heimu 黑幕内容 标题%}&lt;/code&gt; 这样就可以变成 -&amp;gt; {%heimu 黑幕内容 标题%}，其中标题可以省略不写，默认的是「你知道的太多了」这个。（或许晚些时候我会写个读取配置的版本能够设置默认标题，但是现在！{%heimu 先鸽！%}）&lt;/p&gt;
&lt;h1&gt;应该不会有人在意的原理吧？&lt;/h1&gt;
&lt;p&gt;查文档呗，看看hexo怎么写插件。首先是hexo自带的功能&lt;a href=&quot;https://hexo.io/zh-cn/docs/tag-plugins&quot;&gt;标签插件（Tag Plugins）&lt;/a&gt;，也就是&lt;code&gt;{% %}&lt;/code&gt;这样的语法。&lt;/p&gt;
&lt;p&gt;然后参照&lt;a href=&quot;https://hexo.io/zh-cn/docs/plugins&quot;&gt;插件&lt;/a&gt;这章知道怎么写脚本。让插件注册一个&lt;a href=&quot;https://hexo.io/zh-cn/api/renderer&quot;&gt;渲染器&lt;/a&gt;来处理自定义的&lt;code&gt;{% heimu %}&lt;/code&gt;标签，配合&lt;a href=&quot;https://hexo.io/zh-cn/api/injector&quot;&gt;注入器（Injector）&lt;/a&gt;在网页&amp;lt;head&amp;gt;标签后面注入黑幕配套的css就可以达到这样的效果了。&lt;/p&gt;
&lt;p&gt;当然还加入了npm和cdn的要素，不过这都是后话了。&lt;/p&gt;
&lt;p&gt;源代码可以在github上面看。&lt;/p&gt;
&lt;h1&gt;实现这个的代价是？&lt;/h1&gt;
&lt;p&gt;&lt;s&gt;代价就是：累坏我了。&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;代价是不如之前通过修改主题注入css、{%raw%}直接写html那么灵活，因为hexo的标签插件内部不能混合markdown语法。&lt;/p&gt;
&lt;h1&gt;后续：更多style支持以及快捷划线&lt;/h1&gt;
&lt;p&gt;锵锵锵~&lt;/p&gt;
&lt;p&gt;1.0.2干了这个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;现在支持语法 &lt;code&gt;{% heimu 黑幕内容 [标题] [style] %}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;style就是css的style。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;此外还有新的标签 &lt;code&gt;{% heimux %}&lt;/code&gt;，语法同上，效果是黑幕带删除线 {% heimux 快速删除 %}&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><author>FishCat233</author></item><item><title>x264处理安卓手机视频时产生的视频旋转问题</title><link>https://www.aaafishcat.top/posts/debug-x264-process-with-rotate-meta-info</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/debug-x264-process-with-rotate-meta-info</guid><description>省流：用 ffmpeg -i video.mp4 output.mp4 处理一下就可以了</description><pubDate>Mon, 10 Feb 2025 18:23:36 GMT</pubDate><content:encoded>&lt;p&gt;你好&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;省流：用 ffmpeg -i video.mp4 output.mp4 处理一下就可以了&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;什么玩意？这就完了？&lt;/h1&gt;
&lt;p&gt;事情也不是很复杂：安卓拍摄的视频会附带带有rotation的Side data在视频的Meta data中——也就是也就是说安卓拍的视频可能自带了旋转信息。&lt;/p&gt;
&lt;p&gt;可以做个实验测试一下，使用 &lt;code&gt;ffmpeg -i video.mp4 -hide_banner&lt;/code&gt; 查看一个安卓手机拍摄的竖屏视频的信息。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &apos;video.mp4&apos;:
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2024-11-08T09:05:46.000000Z
    com.android.version: 13
    com.android.capture.fps: 60.000000
  Duration: 00:00:20.32, start: 0.000000, bitrate: 10410 kb/s
  Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709), 1920x1080, 10002 kb/s, 60.02 fps, 59.94 tbr, 90k tbn (default)
    Metadata:
      creation_time   : 2024-11-08T09:05:46.000000Z
      handler_name    : VideoHandle
      vendor_id       : [0][0][0][0]
    Side data:
      displaymatrix: rotation of -90.00 degrees
  Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default)
    Metadata:
      creation_time   : 2024-11-08T09:05:46.000000Z
      handler_name    : SoundHandle
      vendor_id       : [0][0][0][0]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;目光放到视频流信息这里，其中可以看见是视频流的信息，里面有视频分辨率和视频的旋转信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709), 1920x1080, 10002 kb/s, 60.02 fps, 59.94 tbr, 90k tbn (default)
    Metadata:
      creation_time   : 2024-11-08T09:05:46.000000Z
      handler_name    : VideoHandle
      vendor_id       : [0][0][0][0]
    Side data:
      displaymatrix: rotation of -90.00 degrees
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意看这个视频流的分辨率——&lt;strong&gt;1920x1080&lt;/strong&gt;？这不是横屏的分辨率吗，怎么回事呢？答案在底下的 &lt;code&gt;Side data&lt;/code&gt; 里面的 &lt;code&gt;displaymatrix: rotation of -90.00 degress&lt;/code&gt; 这里。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;——旋转 90 度！！！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在播放器读取到这样的 Side data 之后播放视频的时候就会自动旋转 90 度，变成&lt;strong&gt;1080x1920&lt;/strong&gt;——也就是播放时所看到的竖屏。&lt;/p&gt;
&lt;p&gt;原来如此原来如此。&lt;/p&gt;
&lt;h1&gt;原来什么啊？所以为什么x264处理视频会旋转呢？&lt;/h1&gt;
&lt;p&gt;因为x264 &lt;em&gt;疑似&lt;/em&gt; 直接丢了旋转的信息（做过实验但是我忘了结果，感兴趣可以自己试试）。而如果你使用 ffmpeg 就不会发生这样的事——ffmpeg会自动检测旋转信息然后在对视频处理的时候默默帮你旋转然后消去旋转信息。&lt;/p&gt;
&lt;p&gt;所以解决办法就有了，让ffmpeg先处理把视频的旋转信息消掉，然后再让x264处理就行了。&lt;/p&gt;
&lt;p&gt;虽然看起来有些笨，但是暂时是没想到别的简单的方法了。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>展示博客功能</title><link>https://www.aaafishcat.top/posts/showing-off-blog-features</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/showing-off-blog-features</guid><pubDate>Sun, 20 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;由于文章的 frontmatter 中没有 description 字段，因此使用第一段作为描述。&lt;/p&gt;
&lt;h2&gt;主题设置&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;为你的博客使用你最喜欢的编辑器主题！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;网站的主题来自 Expressive Code 中内置的 Shiki 主题。你可以在&lt;a href=&quot;https://expressive-code.com/guides/themes/#available-themes&quot;&gt;这里&lt;/a&gt;查看它们。一个网站可以有一个或多个主题，在 &lt;code&gt;src/site.config.ts&lt;/code&gt; 中定义。有三种主题模式可供选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;single&lt;/code&gt;：为网站选择一个主题。简单明了。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;light-dark-auto&lt;/code&gt;：为网站选择两个主题，分别用于浅色和深色模式。页眉将包含一个按钮，用于在浅色/深色/自动之间切换。例如，你可以选择 &lt;code&gt;github-dark&lt;/code&gt; 和 &lt;code&gt;github-light&lt;/code&gt;，默认设置为 &lt;code&gt;&quot;auto&quot;&lt;/code&gt;，用户的体验将立即匹配其操作系统主题。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt;：为网站选择两个或更多主题，并在页眉中包含一个按钮，用于在这些主题之间切换。你可以包含任意数量的 Expressive Code 中的 Shiki 主题。让用户找到他们最喜欢的主题！&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;当用户更改主题时，他们的偏好会存储在 &lt;code&gt;localStorage&lt;/code&gt; 中，以便在页面导航之间持久保存。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;代码块&lt;/h2&gt;
&lt;p&gt;让我们看看一些代码块样式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def hello_world():
    print(&quot;Hello, world!&quot;)

hello_world()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;def hello_world():
    print(&quot;Hello, world!&quot;)

hello_world()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;python hello.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有一些行内代码：&lt;code&gt;1 + 2 = 3&lt;/code&gt;。或者甚至是 &lt;code&gt;(= (+ 1 2) 3)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;有关文本换行、行高亮、差异对比等可用功能的更多信息，请参阅 &lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;Expressive Code 文档&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;基本 Markdown 元素&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;列表项 1&lt;/li&gt;
&lt;li&gt;列表项 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;粗体文本&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;斜体文本&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;删除线文本&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.example.com&quot;&gt;链接&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;生活中，就像艺术中一样，有些结局是苦乐参半的。尤其是当涉及到爱情时。有时命运将两个恋人撮合在一起，却又将他们撕裂。有时英雄终于做出了正确的选择，但时机却完全不对。而且，正如人们所说，时机就是一切。&lt;/p&gt;
&lt;p&gt;- 绯闻女孩&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;姓名&lt;/th&gt;
&lt;th&gt;年龄&lt;/th&gt;
&lt;th&gt;城市&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;爱丽丝&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;纽约&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;鲍勃&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;洛杉矶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查理&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;芝加哥&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;图片&lt;/h2&gt;
&lt;p&gt;图片可以在 URL 后包含标题字符串，渲染为带有 &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; 的 &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; 元素。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./PixelatedGreenTreeSide.png&quot; alt=&quot;像素艺术树&quot; title=&quot;像素艺术在没有适当 CSS 的情况下渲染效果不佳&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![像素艺术树](./PixelatedGreenTreeSide.png &apos;像素艺术在没有适当 CSS 的情况下渲染效果不佳&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我还添加了一个特殊的像素艺术标签，添加正确的 CSS 以正确渲染。只需在 alt 字符串的最末尾添加 &lt;code&gt;#pixelated&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./PixelatedGreenTreeSide.png&quot; alt=&quot;像素艺术树 #pixelated&quot; title=&quot;但在 alt 字符串末尾添加 #pixelated 可以修复这个问题&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![像素艺术树 #pixelated](./PixelatedGreenTreeSide.png &apos;但在 alt 字符串末尾添加 #pixelated 可以修复这个问题&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;提示框&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:::note
测试123
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
测试123
:::&lt;/p&gt;
&lt;p&gt;:::tip
测试123
:::&lt;/p&gt;
&lt;p&gt;:::important
测试123
:::&lt;/p&gt;
&lt;p&gt;:::caution
测试123
:::&lt;/p&gt;
&lt;p&gt;:::warning
测试123
:::&lt;/p&gt;
&lt;h2&gt;角色对话&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:::duck
**你知道吗？** 你可以使用 MultiTerm 轻松为你的博客创建自定义角色对话！
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::duck
&lt;strong&gt;你知道吗？&lt;/strong&gt; 你可以使用 MultiTerm 轻松为你的博客创建自定义角色对话！
:::&lt;/p&gt;
&lt;h3&gt;添加你自己的角色&lt;/h3&gt;
&lt;p&gt;要添加你自己的角色，首先将图片文件添加到克隆的 MultiTerm 仓库中的顶级 &lt;code&gt;/public&lt;/code&gt; 目录。Astro 无法自动优化来自 markdown 插件的图片资源，因此请确保将图片压缩到适合网页的大小（&amp;lt;100kb）。&lt;/p&gt;
&lt;p&gt;我推荐使用 Google 免费的 &lt;a href=&quot;https://squoosh.app&quot;&gt;Squoosh&lt;/a&gt; 网页应用来创建超小的 webp 文件。这里的角色已使用 Squoosh 调整为 300 像素宽，并以 75% 质量导出为 webp。&lt;/p&gt;
&lt;p&gt;添加图片后，使用新添加的图片文件更新 &lt;code&gt;site.config.ts&lt;/code&gt; 中的 &lt;code&gt;characters&lt;/code&gt; 选项，然后重新启动开发服务器。&lt;/p&gt;
&lt;h3&gt;角色对话&lt;/h3&gt;
&lt;p&gt;当连续出现多个角色对话时，对话图片和对话气泡的顺序会反转，使对话更具来回对话的外观。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::owl
这是一个很酷的功能！
:::

:::unicorn
我同意！
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::owl
这是一个很酷的功能！
:::&lt;/p&gt;
&lt;p&gt;:::unicorn
我同意！
:::&lt;/p&gt;
&lt;p&gt;你可以指定对齐方式（&lt;code&gt;left&lt;/code&gt; 或 &lt;code&gt;right&lt;/code&gt;）来覆盖默认的 &lt;code&gt;left, right, left, ...&lt;/code&gt; 顺序。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::unicorn{align=&quot;right&quot;}
在这里，右边！
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::unicorn{align=&quot;right&quot;}
在这里，右边！
:::&lt;/p&gt;
&lt;h2&gt;GitHub 卡片&lt;/h2&gt;
&lt;p&gt;GitHub 概览卡片深受 &lt;a href=&quot;https://github.com/chrismwilliams/astro-theme-cactus&quot;&gt;Astro Cactus&lt;/a&gt; 启发。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;stelcodes/multiterm-astro&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::github{repo=&quot;stelcodes/multiterm-astro&quot;}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{user=&quot;withastro&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::github{user=&quot;withastro&quot;}&lt;/p&gt;
&lt;h2&gt;Emoji :star_struck:&lt;/h2&gt;
&lt;p&gt;可以通过包含字面 emoji 字符或 GitHub 短代码在 markdown 中添加 emoji。你可以在&lt;a href=&quot;https://emojibase.dev/emojis?shortcodePresets=github&quot;&gt;这里&lt;/a&gt;浏览非官方数据库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;早上好！ :sleeping: :coffee: :pancakes:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;早上好！ :sleeping: :coffee: :pancakes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;所有 emoji（包括字面和短代码形式）都通过包装在 &lt;code&gt;span&lt;/code&gt; 标签中来提高可访问性，如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span role=&quot;img&quot; aria-label=&quot;coffee&quot;&amp;gt;☕️&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在撰写本文时，&lt;a href=&quot;https://emojipedia.org/emoji-16.0&quot;&gt;emoji v16&lt;/a&gt; 尚不支持。这些 emoji 可以字面包含，但它们没有短代码，也不会被包装。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;LaTeX/KaTeX 数学支持&lt;/h2&gt;
&lt;p&gt;你还可以通过 &lt;a href=&quot;https://github.com/remarkjs/remark-math&quot;&gt;remark-math 和 rehype-katex&lt;/a&gt; 显示行内数学公式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;让方程式变得漂亮！ $ \frac{a}{b} \cdot b = a $
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;让方程式变得漂亮！ $ \frac{a}{b} \cdot b = a $&lt;/p&gt;
&lt;p&gt;查看 &lt;a href=&quot;https://katex.org/docs/supported&quot;&gt;KaTeX 文档&lt;/a&gt;了解语法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$$
a + ar + ar^2 + ar^3 + \dots + ar^{n-1} = \displaystyle\sum_{k=0}^{n - 1}ar^k = a \bigg(\dfrac{1 - r^n}{1 -r}\bigg)
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;$$
a + ar + ar^2 + ar^3 + \dots + ar^{n-1} = \displaystyle\sum_{k=0}^{n - 1}ar^k = a \bigg(\dfrac{1 - r^n}{1 -r}\bigg)
$$&lt;/p&gt;
&lt;h2&gt;HTML 元素&lt;/h2&gt;
&lt;p&gt;&amp;lt;button&amp;gt;一个按钮&amp;lt;/button&amp;gt;&lt;/p&gt;
&lt;h3&gt;带输入框的字段集&lt;/h3&gt;
&lt;p&gt;&amp;lt;fieldset&amp;gt;
&amp;lt;input type=&quot;text&quot; placeholder=&quot;输入一些内容&quot;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;input type=&quot;number&quot; placeholder=&quot;输入数字&quot;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;input type=&quot;text&quot; value=&quot;输入值&quot;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;select&amp;gt;
&amp;lt;option value=&quot;1&quot;&amp;gt;选项 1&amp;lt;/option&amp;gt;
&amp;lt;option value=&quot;2&quot;&amp;gt;选项 2&amp;lt;/option&amp;gt;
&amp;lt;option value=&quot;3&quot;&amp;gt;选项 3&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;textarea placeholder=&quot;插入评论...&quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;label&amp;gt;&amp;lt;input type=&quot;checkbox&quot;&amp;gt; 我理解&amp;lt;br&amp;gt;&amp;lt;/label&amp;gt;
&amp;lt;button type=&quot;submi&quot;&amp;gt;提交&amp;lt;/button&amp;gt;
&amp;lt;/fieldset&amp;gt;&lt;/p&gt;
&lt;h3&gt;带标签的表单&lt;/h3&gt;
&lt;p&gt;&amp;lt;form&amp;gt;
&amp;lt;label&amp;gt;
&amp;lt;input type=&quot;radio&quot; name=&quot;fruit&quot; value=&quot;apple&quot;&amp;gt;
苹果
&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;label&amp;gt;
&amp;lt;input type=&quot;radio&quot; name=&quot;fruit&quot; value=&quot;banana&quot;&amp;gt;
香蕉
&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;label&amp;gt;
&amp;lt;input type=&quot;radio&quot; name=&quot;fruit&quot; value=&quot;orange&quot;&amp;gt;
橙子
&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;label&amp;gt;
&amp;lt;input type=&quot;radio&quot; name=&quot;fruit&quot; value=&quot;grape&quot;&amp;gt;
葡萄
&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;label&amp;gt;
&amp;lt;input type=&quot;checkbox&quot; name=&quot;terms&quot; value=&quot;agree&quot;&amp;gt;
我同意条款和条件
&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/p&gt;
</content:encoded><author>FishCat233</author></item><item><title>博客迁移到了新家</title><link>https://www.aaafishcat.top/posts/blog-new-home-to-multiterm</link><guid isPermaLink="true">https://www.aaafishcat.top/posts/blog-new-home-to-multiterm</guid><description>如题所示，在博客运行的第 1785 天，我把博客迁移到了基于 astro 框架的 multiterm 上.</description><pubDate>Mon, 04 May 2026 17:41:53 GMT</pubDate><content:encoded>&lt;p&gt;如题所示，在博客运行的第 1785 天，我把博客迁移到了基于 astro 框架的 multiterm 上.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;stelcodes/multiterm-astro&quot;}&lt;/p&gt;
&lt;h2&gt;事情起因&lt;/h2&gt;
&lt;p&gt;起因就是看到了其他人在用 multiterm 替代了 hexo，让我想起来我有一个很长时间没有更新的 hexo 博客。&lt;/p&gt;
&lt;p&gt;很长时间没有更新 hexo 的借口有很多，听我慢慢狡辩。一是因为主要在更新 &lt;a href=&quot;lib.aaafishcat.top&quot;&gt;图书馆&lt;/a&gt; 那边，二是因为现实中确实有实在太多事情要处理，包括我在其他平台和社群也有文章在写，加上博客这边好像也没什么人看，所以博客这边一直处于搁置状态。但还有其三，那就是 hexo 博客维护起来相当折磨。&lt;/p&gt;
&lt;p&gt;其实 hexo 博客维护起来折磨当然有一部分原因是我以前不会用 CI/CD 工具来省力，每次写完文章都要手动打指令在本地构建然后通过 Github Page 部署。现在看来，如果没有 Github Page 自动部署，技术力底下的我大概连博客都部署不起来。可以看见，在后来 Library 那边引入了 CI/CD 后，文章就库库冒出来一大堆，因为我只管写了，底下自动构建自动部署把障碍清理干净了。&lt;/p&gt;
&lt;p&gt;但是即便在今天，hexo 的开发体验让我觉得有点便秘。本地构建感觉有点慢；定制的时候要去主题文件翻天书的阴影；加上现在对各种现代技术的关注让我觉得——感觉不如试试 astro.&lt;/p&gt;
&lt;h2&gt;选择了 Astro&lt;/h2&gt;
&lt;p&gt;选择 astro 的一个很大原因是看到了他们官网上的介绍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Astro&lt;/strong&gt; is a JavaScript web framework optimized for building fast, content-driven websites.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Astro&lt;/strong&gt; 是一个专为构建快速、内容驱动型网站而优化的 JavaScript 网页框架。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;内容驱动！然后我就换成了基于 astro 的 multiterm——我当然没空手搓一个，虽然 astro 在直觉上让我觉得用起来会很方便。不过考虑一个喜欢的简单项目然后在其基础上定制更省事一点。&lt;/p&gt;
&lt;p&gt;去看看 &lt;a href=&quot;https://astro.build/&quot;&gt;astro 的官网&lt;/a&gt;，可以看见其支持相当多能让我心动的特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;集成兼容 React、Vue、Preact、Svelte、Solid.&lt;/li&gt;
&lt;li&gt;支持 Typescript 验证 Markdown mdx 的 Front matter&lt;/li&gt;
&lt;li&gt;默认按需加载 js&lt;/li&gt;
&lt;li&gt;内置页面过渡效果&lt;/li&gt;
&lt;li&gt;图片优化，比如自动 png 转 webp&lt;/li&gt;
&lt;li&gt;基于文件路由&lt;/li&gt;
&lt;li&gt;中间件支持&lt;/li&gt;
&lt;li&gt;部署适配器&lt;/li&gt;
&lt;li&gt;集成 AI MCP&lt;/li&gt;
&lt;li&gt;环境变量管理&lt;/li&gt;
&lt;li&gt;开发工具栏&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比起 hexo 这种专门的静态网站生成器，astro 作为一个带有现代特性的网页框架让我更为想要尝试，于是我花了一下午的时间了解了一下 multiterm，然后配好并进行了一些定制。&lt;/p&gt;
&lt;h2&gt;Multiterm 很棒&lt;/h2&gt;
&lt;p&gt;在我了解了 Multiterm 后（实际上只是看了那篇&lt;a href=&quot;showing-off-blog-features&quot;&gt;说明书&lt;/a&gt;），我发现它支持了不少方便的 md 扩展，而且语法也不算很难记，改起来更是看一眼大概能明白什么意思——这点很重要，除了 hexo，我也尝试过 hugo，但是 hugo 的模板语法实在是第一眼太抽象，而且还有不少限制，我花了不少时间搞明白怎么自己制作一个模板，结果还是有问题的。相比之下，astro 还是方便很多。&lt;/p&gt;
&lt;p&gt;而且 Multiterm 让我最喜欢的就是样式主题，这个主题很简洁漂亮，而且主页还集成了 github heatmap。&lt;/p&gt;
&lt;p&gt;不过 Multiterm 也不是什么都有，比如说国内平台相关的功能就没有：像是 footer 的知乎链接还是我进行定制做出来的功能。不过这些都是小问题，项目的代码还挺清晰的，至少我让 ai 改，我还能毫无压力地重新审查一遍，都不需要问 ai 哪个是什么意思。&lt;/p&gt;
&lt;p&gt;总得来说，我觉得 astro + multiterm 已经比之前 hexo + butterfly 或者 hugo + gitbook 的体验好很多了，非常适合个人博客尤其是我自己的博客。&lt;/p&gt;
&lt;h2&gt;重新思考博客&lt;/h2&gt;
&lt;p&gt;在工具更换的同时，我当然会下意识思考我是否陷入了换玩具的心理。但我没有回答，我觉得我确实会有「因为更现代更快而且玩起来很方便就想要试试」的心理。&lt;/p&gt;
&lt;p&gt;我重新思考我很长时间没有更新的博客，我想到了最近一直在维护社团知识库和个人数字花园的那些笔记，我想我一直以来对博客的理解可能有些问题。&lt;/p&gt;
&lt;p&gt;在早期，我看见很多技术博客他们会在上面更新技术，而我正在学习，所以我也同样想要将学习整理成笔记传上博客，但是后来我发现笔记这种东西如大雨中的水一样到处都是，全部上传博客只会让人看到一大堆有头没尾的碎片化信息，再后来我知道了数字花园这样的概念后，我相信 quartz + obsidian 搭建的数字花园才是那些笔记的去处，而博客则因为失去了笔记流而停滞。&lt;/p&gt;
&lt;p&gt;最近遇到了很多事情，我开始稍微留意了一下那些不止是技术类的个人公众号和博客，我突然意识到，也许博客相比数字花园，其内容更应该偏向记录、分享、表达而不是将知识捋顺成笔记讲给人，因为博客这种由 tag 和 series 形式组成的检索而不是文件树组织的文章天然就更偏向记录，使用博客的形式去记载各种零碎的笔记完全是折磨读者，因为笔记很短，而且不少还因为学得不深而不成体系地零零散散。&lt;/p&gt;
&lt;p&gt;总而言之，我觉得我现在得重新探索博客应该真正写点什么的问题。&lt;/p&gt;
&lt;p&gt;先祝贺博客的乔迁之喜吧。&lt;/p&gt;
</content:encoded><author>FishCat233</author></item></channel></rss>