<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>深鸣</name>
    <email>DeepChirp@outlook.com</email>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <icon>https://www.gravatar.com/avatar/7c23c8a210d463239e12b9f53d4c85db</icon>
  <id>https://blog.deepchirp.com/</id>
  <link href="https://blog.deepchirp.com/" rel="alternate"/>
  <link href="https://blog.deepchirp.com/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, 深鸣</rights>
  <subtitle>DeepChirp Blog</subtitle>
  <title>空鸣深语</title>
  <updated>2026-05-27T11:31:20.000Z</updated>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="友人帐" scheme="https://blog.deepchirp.com/tags/%E5%8F%8B%E4%BA%BA%E5%B8%90/"/>
    <category term="感想" scheme="https://blog.deepchirp.com/tags/%E6%84%9F%E6%83%B3/"/>
    <category term="游戏" scheme="https://blog.deepchirp.com/tags/%E6%B8%B8%E6%88%8F/"/>
    <category term="音乐" scheme="https://blog.deepchirp.com/tags/%E9%9F%B3%E4%B9%90/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://x.com/si1chan_">31chan</a>在<a href="https://x.com/si1chan_/status/2030663581277311386">X（前Twitter）上的推文</a>，版权归原作者所有。</p></div><div class="note warning flat"><p>本文是阶段性的个人总结，使用了较多音游术语，建议有一定基础的读者阅读。</p></div><p>上次写的<a href="/2025/11/27/My-Rhythm-Game-Journey/" title="我的音游心路历程">音游心路历程</a>意外地有不少人看，这回借近期达成的双星成就，专讲一讲<a href="https://arcaea.lowiro.com">《Arcaea》</a>。我自2025年3月摘星后，刚好用了一年时间取得双星，自觉各方面都进步了一点，但不多。下面以游玩经验为基础，分两章谈谈对部分谱面的评价分析，及整体性的思考与感想。</p><h2 id="b30分表评析及推荐">b30分表评析及推荐</h2><div class="note info flat"><p>主观意见如有不同，最终解释权归<strong>读者</strong>所有。</p></div><p>这部分简单评价、分析我双星分表中的30个谱面（见下图），并给想要冲击更高水平的玩家提供一个参考，其中「推荐程度」主要以双星吃分为评判标准。我将使用combo数和配置指代谱面段落，可能需要读者对10级以上谱面足够熟悉，亦可参考视频来源，如<a href="https://space.bilibili.com/441390256">雨笙Hikari</a>、<a href="https://space.bilibili.com/13099001/lists/790838">Adriunk</a>、<a href="https://space.bilibili.com/354869623">石原坂奈</a>等。</p><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/ptt12.50.avif" alt="双星b30分表"></p><h3 id="《Nightmare》ETR-10-8">《Nightmare》ETR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Nightmare.avif" alt="《Nightmare》ETR曲绘"></p><ul><li><p>整体评价：很多人觉得这玩意虚低。我刚打一两遍确实也这么觉得，EX好容易，「这是哪门子10.8？」但是想推高分就会发现，「这是哪门子10.8？」怀疑616是把10.6的前半段和11.0的后半段拼出来个10.8。</p></li><li><p>配置分析：如果想扛873combo开始的尾杀，那么它等效于285BPM的8分连打，这比《World Ender》BYD中标志性的280BPM的8分连打还快，虽然双手轮流扛三下，但没有休息段啊！如果想<a href="https://www.bilibili.com/video/BV1P7jmzNERS">拆尾杀</a>——这不是11那什么是11？我还不如扛呢。所以我认为尾杀不管是扛是拆，都起码有11的高度了。对于前半段，我认为配置其实不难，而且BPM不高、节奏也规整，但谱师在位移和运手上加难度，至于是不是「硬凑难度」见仁见智：基础好、打得来，可能觉得只有10级下位，打不来就可能觉得全程在打尾杀了。</p></li><li><p>推荐程度：2/5。个人差较大。建议不会打前半段就背一背。</p></li></ul><h3 id="《Ringed-Genesis》FTR-10-8">《Ringed Genesis》FTR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Ringed_Genesis.avif" alt="《Ringed Genesis》FTR曲绘"></p><ul><li><p>整体评价：砖魔王，从容的老资历谱面。我既非老资历，打得也不从容。</p></li><li><p>配置分析：全程都在考硬扛，包括双押三纵、交互接双押及各种单单双。这些不均衡的配置对发力协调要求很高；但只是吃分，而不追求PM/理论的话，难点就不突出了，以至于「不像个10.8」。个人难点在于结尾的三纵和连续12分硬扛，耐力实在不够，发力一错则全盘皆崩。<a href="https://www.bilibili.com/video/BV1VV411K7XC">零零五的拆法</a>对我稳定性的提高十分有帮助，不妨借鉴一部分。你问为什么要说「一部分」？因为小指/中指辅助拆三纵太特立独行了。</p></li><li><p>推荐程度：4/5。几乎在每个双星的必吃榜上，无需质疑。</p></li></ul><h3 id="《Climax》FTR-10-4">《Climax》FTR 10.4</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Climax.avif" alt="《Climax》FTR曲绘"></p><ul><li><p>整体评价：双星耐力与定位质检谱，且相对好读，具有较高练习价值。顺带一提，我认为《trappola bewitching》FTR算是摘星耐力与定位质检谱。</p></li><li><p>配置分析：开头建议从44combo起用单手扛，不追求全大P的前提下，我的抽奖成功率很高。333combo平行四边形交互的下位练习为《felys final remix》FTR。452combo波浪蛇按住中间放置即可，容易出错的反而是单手8分连打，注意应以上下位移为主，不能有多余的左右位移。</p></li><li><p>推荐程度：3/5。定数10.4使得吃分上限太低。</p></li></ul><h3 id="《多次元宇宙融合論》FTR-10-6">《多次元宇宙融合論》FTR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Extradimensional.avif" alt="《多次元宇宙融合論》FTR曲绘"></p><ul><li><p>整体评价：著名<a href="https://www.bilibili.com/video/BV1L6AyzyEYp">彩虹糖</a>，喂饱目押党。你说音押党？能音押这个的是哪路神仙？</p></li><li><p>配置分析：细节很多，取印象深刻的几个来讲：180和294combo的两处三连交互是同款引导，不要被骗手了。367combo的一连串8分，如果容易脑梗，试试单手扛。409、1014、1066combo的几组折线蛇极容易漏，既要划快还要划重，我反正是纯抽奖。537combo处红蛇特别容易接反，得背一下。1230和1242combo是两处出张16分切分，手感却很好。</p></li><li><p>推荐程度：2/5。在10.6里绝对不属于水的那一批，但好歹有容错率。</p></li></ul><h3 id="《Qovat》FTR-10-4">《Qovat》FTR 10.4</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Qovat.avif" alt="《Qovat》FTR曲绘"></p><ul><li><p>整体评价：这个才是双星节奏质检谱。具有较高练习价值。</p></li><li><p>配置分析：该谱以众多跳拍为特色，经常出现跳拍后接双押，在读谱和控手上有难度；排键算得上友好，当出现天—地跳拍时，可通过天键的影子读出节奏，只有1015（1051同）、1089（1125同）combo处的跳拍相对难读。638combo天键可右手出张。尾杀交互等效于183BPM的16分交互，不快，但位移较难，其中1271combo后的左手位移幅度应尽可能拉大。再看隔壁8周年曲《Placebo♥Battler》FTR，天—地跳拍清仓大甩卖，排键没什么规律，速度还更快，所以读谱困难得多。</p></li><li><p>推荐程度：3/5。同样是因为10.4的定数使得吃分上限过低。</p></li></ul><h3 id="《Twilight-Concerto》ETR-10-5">《Twilight Concerto》ETR 10.5</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Tasogare.avif" alt="《Twilight Concerto》ETR曲绘"></p><ul><li><p>整体评价：黄昏の协奏曲，爬梯の效率曲。兼具玩蛇和交互，感觉主要考察基本功。底力门槛效应明显，交互稳不住的话EX都难。</p></li><li><p>配置分析：124、131combo半高天键可打高些，防止吃音。381combo红蛇、385combo蓝蛇拐角处有判定点，需要先往外侧拉一段，不然必漏。679combo处4个天键的定位尤其难，需要左手先出张再拉回，702combo处镜像同理。本谱中的出张交互几乎都是「有引导但不多」，需要堆熟练度。</p></li><li><p>推荐程度：5/5。肯练就能吃的那种，但没有容错率，需要全谱都会打。</p></li></ul><h3 id="《Inverted-World》ETR-10-7">《Inverted World》ETR 10.7</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Inverted_World.avif" alt="《Inverted World》ETR曲绘"></p><ul><li><p>整体评价：反转世界，最水10.7竞争者。考察点几乎全在定位上了。</p></li><li><p>配置分析：350至551combo段，交互均为四颗键，熟悉引导规律即可。关于尾杀，主要说一下854combo处的交互，第一颗中间天键左手打，第二颗一轨地键右手打，在此瞬间形成反手交互，前后衔接配置的位移还不小，我觉得手感很差。</p></li><li><p>推荐程度：4/5。难点少，容错率不高。</p></li></ul><h3 id="《Dies-irae》ETR-10-6">《Dies irae》ETR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Diesirae.avif" alt="《Dies irae》ETR曲绘"></p><ul><li><p>整体评价：像《Purgatorium》BYD进化版。小六边形战士，底力、定位、节奏、读谱等等，什么都考一点。</p></li><li><p>配置分析：577combo天键排太挤了，建议右手辅助指接。626combo单单双觉得很突兀，老记不住。640combo交互位移规律很明显，可以按五连交互+三连交互为一组来读，1075combo处镜像同理。1135、1140、1145combo三处反手切分，很难看出节奏，简直反人类。</p></li><li><p>推荐程度：3/5。想推995万分以上比较难。</p></li></ul><h3 id="《Last-Celebration》FTR-10-4">《Last Celebration》FTR 10.4</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Last_Celebration.avif" alt="《Last Celebration》FTR曲绘"></p><ul><li><p>整体评价：双星爆发质检谱。也是知名水谱，因为休息段给得实在太多了。</p></li><li><p>配置分析：主体配置为238BPM下的带位移单双及交互，其中单双的下位（真下位吗）练习为256BPM的《Vicious Heroism》FTR。955combo处的多组三连交互，左右手轮流起手，手感意外地好。</p></li><li><p>推荐程度：3/5。另外提一下，如果是摘星吃分，它一定是5/5。</p></li></ul><h3 id="《Ego-Eimi》FTR-10-5">《Ego Eimi》FTR 10.5</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Ego_eimi.avif" alt="《Ego Eimi》FTR曲绘"></p><ul><li><p>整体评价：好听的，最水10.5竞争者。手感在神与粪之间反复横跳。</p></li><li><p>配置分析：为防止卡手，334combo天键建议右手中指接，966combo天键同理。650combo处交互转双押需要稳住节奏，可以试试双押刻意重敲，一旦不稳就会爆一串。763combo处双押转交互，排键上没有做明显区分，因此比较难读，算是个小雷点。777combo旋转双蛇要划慢，而794combo旋转双蛇要划快。843combo反手交互建议反接，因为后面又又又衔接双押，还不好读，全谱最大地雷来的。最后是987、1033combo两处12分转圈反手交互，我是纯正攻的，感觉手感不差，只是反手幅度要拉很大，尽力往两侧出张，位移规律可以参考《Fracture Ray》FTR中643combo反手双蛇转圈；不喜欢正攻的话，中间扛两颗来规避反手，像《Dantalion》FTR结尾那样。</p></li><li><p>推荐程度：4/5。上面看似列出了不少雷点，但糊一下大多就过去了，爆几个Far又何妨。</p></li></ul><h3 id="《Halcyon》FTR-10-5">《Halcyon》FTR 10.5</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Halcyon.avif" alt="《Halcyon》FTR曲绘"></p><ul><li><p>整体评价：翡翠鸡，在砍了0.2的定数之后，基本是个常规10.5了。</p></li><li><p>配置分析：先说那臭名昭著的下拉蛇，判定点全在小尾巴上，松早了直接死给你看。以前实在不会打，现在发现可以刻意地滞后音押，按和松都晚8分，当然调整延迟也行。再说179、909、1025、1091combo这一类双押接交互的写法，位移有点反引导的意思，我觉得比较烂，不背不行。不过全程打交还是很爽的，191BPM基本处于大众的舒适区间内。</p></li><li><p>推荐程度：3/5。</p></li></ul><h3 id="《REKKA-RESONANCE》FTR-10-7">《REKKA RESONANCE》FTR 10.7</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/REKKA_RESONANCE.avif" alt="《REKKA RESONANCE》FTR曲绘"></p><ul><li><p>整体评价：烈华/旺仔牛奶。全谱基本都是平A配置，以高速位移单双为主要难点。</p></li><li><p>配置分析：像233combo处的这类单双单，换手容易脑梗。802combo处短蛇加单点仍可视作单双，且这里的下拉蛇只有1物量，按一下头部就行。813与816combo的两个地键间隔4分，还有跨两轨的位移，是个人易爆点，1093与1096combo同理。1145至1162combo可能是全谱最难段，位移比较反直觉。虽然我打的时候没出现，但275combo可能有蹭键问题。</p></li><li><p>推荐程度：2/5。要看个人差，且不能用<a href="https://arcaea.fandom.com/wiki/Hikari_%26_Tairitsu_(Reunion)">光 &amp; 对立</a>换暗侧。</p></li></ul><h3 id="《Axium-Crisis》FTR-10-6">《Axium Crisis》FTR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Axium_Crisis.avif" alt="《Axium Crisis》FTR曲绘"></p><ul><li><p>整体评价：技巧谱？定位谱！对熟练度要求很高，必要时背谱。在不为人知的角落，病女：「什么叫我成了我前任守门员的现任守门员？」</p></li><li><p>配置分析：慢速段补拍音押更稳。建议46combo右手切。396至443combo五连交互起手依次为：右左左右、左右右左，考虑到BPM仅有170，这样的写法在可接受范围内，能靠临时反应读懂。539、554combo交互需要出张起手，且相对不好读。770至849combo慢速段，我设计了一点单手双押的手法来减少出张，但过率依然很低（616复杂配置能不能别写慢速）。888、929combo地键容易挡视野，划蛇手可抬高些。973combo处的这种蛇加单点配置，把位移写得很开，可酌情使用并指以降低定位难度；如果打到位了，会感觉像拉小提琴一样优雅，对门光光家的《Loveless Dress》FTR也有这特点。一定要保持优雅！</p></li><li><p>推荐程度：2/5。考点过于集中在定位上了，要推高分的话容错率低，还有随机手癖加成。</p></li></ul><h3 id="《MVURBD》FTR-10-6">《MVURBD》FTR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/MVURBD.avif" alt="《MVURBD》FTR曲绘"></p><ul><li><p>整体评价：曲名其实是「Move Your Body」简写，外号为少儿不宜的「紫色心情」。<a href="https://arcaea.fandom.com/wiki/Chart_Designers#Exschwasion">Exschwasion</a>风评极好的一张谱，个人手感中规中矩，虽然都会，可莫名其妙推不了分。</p></li><li><p>配置分析：<a href="https://www.bilibili.com/video/BV1gip4eCEk4">時雨伍的手法包裹</a>请查收，最建议学的是410combo双蛇规避反手及597combo单双当轴打。</p></li><li><p>推荐程度：3/5。另，摘星吃分5/5。</p></li></ul><h3 id="《Infinite-Strife-》BYD-10-9">《Infinite Strife,》BYD 10.9</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Infinite_Strife.avif" alt="《Infinite Strife,》BYD曲绘"></p><ul><li><p>整体评价：分表中唯一的BYD，感觉难度分布很平均，莫名其妙吃到了。因为实力不够，哪哪都爆，配置分析就不多写了。</p></li><li><p>配置分析：493至660combo段建议音押，音乐信号清晰，手会自己拆。750至768combo段自研小手法：一手天一手地，地面全部用左手双押拍，减少位移。</p></li><li><p>推荐程度：1/5。不少人觉得很难，看各自接受程度。</p></li></ul><h3 id="《Wish-Upon-a-Snow》FTR-10-5">《Wish Upon a Snow》FTR 10.5</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Wishuponasnow.avif" alt="《Wish Upon a Snow》FTR曲绘"></p><ul><li><p>整体评价：雪愿，<a href="https://arcaea.fandom.com/wiki/Chart_Designers#Exschwasion">絶滅</a>写的纯良谱。跟黄昏の协奏曲同一类别，但更考察底力，且节奏基本没有难度。个人认为这谱是病女Drop段的下位练习。</p></li><li><p>配置分析：大b弓蛇都是纸老虎，直线段定位准了就行。823、841combo处的侧面单双，如果容易脑梗，可以试试一手天一手地。</p></li><li><p>推荐程度：5/5。肯练就能吃的那种。</p></li></ul><h3 id="《Dantalion》FTR-10-8">《Dantalion》FTR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Dantalion.avif" alt="《Dantalion》FTR曲绘"></p><ul><li><p>整体评价：蛋挞林，真·黑魔王。</p></li><li><p>配置分析：讲几处细节吧：177combo此类波浪蛇按折线轨迹划，拐角处有判定点，所以不怕划过头就怕划不够。284combo双蛇转圈划快一些，之后往最远端用力出张，304combo同理。352combo处为天键3纵接双押，读谱比较难。像593、607combo处，写的其实都是225度反手，需要刻意旋转手腕、让开空间，后面出现了很多次。768连续双押段正攻不难，我用多指拍反而容易定位错。16分混24分就是纯粹的难，在黑魔王《Sheriruth》FTR中亦有记载（793combo）。尾杀位移太大了，手臂甩到起飞；甚至1355combo塞了个反手交互，不过一般都扛一下转正手打了。</p></li><li><p>推荐程度：2/5。难点处处有，或许它最合适的定数是10.85。</p></li></ul><h3 id="《Seclusion》FTR-10-6">《Seclusion》FTR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Seclusion.avif" alt="《Seclusion》FTR曲绘"></p><ul><li><p>整体评价：隐居，放在6.0大版本里，简直就是纯良谱。虽然低物量导致低容错率，但配置以一个个段落的形式组织起来，使得练习可以极具针对性，各个击破。</p></li><li><p>配置分析：219combo处强烈建议蛇尾不划、天键拿辅助指点一下，规避了出张且避免挡手，手感好不少，类似的反手蛇点配置均可考虑使用。455combo为常规单单双，而490combo在单单双前的衔接上更难一点。本谱的交互形式较为多样，排键有些反常规，但手感并不差（差的是单单双），需要堆熟练度；没有判定很严的蛇；定位要求略低于《Axium Crisis》FTR。</p></li><li><p>推荐程度：5/5。</p></li></ul><h3 id="《Lilly》ETR-10-8">《Lilly》ETR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Lilly.avif" alt="《Lilly》ETR曲绘"></p><ul><li><p>整体评价：新时代的大海（水完了），同曲包几个玩意里最眉清目秀的那个。<a href="https://www.bilibili.com/video/BV1LZbSzZEZm">其节奏</a>并非动次打次，有几处容易搞混。</p></li><li><p>配置分析：全谱279combo一类的天键4颗8分接交互，哪只手打8分都行，重点在于控手只打4颗。405、494combo处是多组三连交互而非匀速交互，需要打出间断感。454combo又见单双单，考验横向位移下的高速协调，手感略显奇怪。591combo有16分转12分交互。1195combo是个人耐力最不够的一集，每次到这才能感受到235BPM的力量。</p></li><li><p>推荐程度：5/5。</p></li></ul><h3 id="《AttraqtiA》FTR-10-6">《AttraqtiA》FTR 10.6</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/AttraqtiA.avif" alt="《AttraqtiA》FTR曲绘"></p><ul><li><p>整体评价：这玩意极为诡异，难与不难的跨度很大，我认为半步勾石境界。</p></li><li><p>配置分析：139至188combo这一大段是全谱最难段，先是天键起手三连交互，再是双押，最后是三组24分带位移爆发，强度堪比《Abstruse Dilemma》FTR爆发段，一共出现三次啊三次。像209combo的这种双押排键，写得像是为了位移而位移。811combo长交互后接双押，纯纯雷点。</p></li><li><p>推荐程度：2/5。1433物量中有不少送分段，因此容错率很高，分数往往比预想的多，但难点和雷点又非同小可。</p></li></ul><h3 id="《BUCHiGiRE-Berserker》FTR-10-8">《BUCHiGiRE Berserker》FTR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/BUCHiGiRE_Berserker.avif" alt="《BUCHiGiRE Berserker》FTR曲绘"></p><ul><li><p>整体评价：狂战士，以<a href="https://www.bilibili.com/video/BV1hV4y1e7fr">复杂节奏</a>著称，变速和爆发为主要难点。以目押党的角度来看，很多地方只需打个大概。</p></li><li><p>配置分析：783combo处24分加12分纵连可以当16分纵连糊。24分爆发都是短交互，抖一抖就过去了，下位练习为《Scarlet Lance》FTR。</p></li><li><p>推荐程度：4/5。推分难度曲线大约是先缓后陡，推高分毋庸置疑属于10+顶位水准，但仅吃分真不需要付出多少，我打了5次就抽奖到994万分。</p></li></ul><h3 id="《Abstruse-Dilemma》FTR-11-3">《Abstruse Dilemma》FTR 11.3</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Abstruse_dilemma.avif" alt="《Abstruse Dilemma》FTR曲绘"></p><ul><li><p>整体评价：写得极具设计感，特别是开头的交互。11.3里面只有这个我能嫖到分。</p></li><li><p>配置分析：单说那2112112（干什么！），其实等效于162BPM的16分单单双。看《Conflict》FTR中段的单单双比它还快，难吗？不难；所以它难吗？如难。我是双指正攻打的，准度还行。</p></li><li><p>推荐程度：3/5。看在上调定数的分上，或许很好吃，看各自情况。</p></li></ul><h3 id="《Divine-Light-of-Myriad》FTR-10-8">《Divine Light of Myriad》FTR 10.8</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Divine_Light_of_Myriad.avif" alt="《Divine Light of Myriad》FTR曲绘"></p><ul><li><p>整体评价：龟速神授説，我是抽奖吃到大分了，我也吃到大奋了。</p></li><li><p>配置分析：先说一说个人研究的手法：19combo红蓝蛇均为1物量，可以放置。93combo把单双全视作双押，单手拍掉。114combo一类的反手蛇如果用辅助指逃课，注意后续交互的手序会乱掉，对协调是个考验，因此我选择在759combo反手空间较大的几处正攻，手感依然挺烂。553combo两组单双用左手双押解成交互。下面是吐槽：慢速段完完全全的龟速，我祝谱师上大号也这速度。286combo轴交互写太简单了，你有《SOUNDWiTCH》FTR轴交互难吗？697combo交互出张起手，纯地雷。809、992combo的16分切分排键看似有位移规律，手感直接爆炸。</p></li><li><p>推荐程度：1/5。除非接受背谱抽奖或对上电波，不建议买这个。</p></li></ul><h3 id="《ouroboros-twin-stroke-of-the-end-》FTR-10-7">《ouroboros -twin stroke of the end-》FTR 10.7</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Ouroboros_-twin_stroke_of_the_end-.avif" alt="《ouroboros -twin stroke of the end-》FTR曲绘"></p><ul><li><p>整体评价：衔尾蛇，细节谱，最需要精确规划位移的一集。</p></li><li><p>配置分析：471combo的12123434交互老不会打。690combo天键总要有一只手连扛三下还带位移，需要提前想清楚。890combo处判定贼严，一定得先把蓝蛇转圈划完整，再去划红蛇。</p></li><li><p>推荐程度：3/5。推高分太难了。</p></li></ul><h3 id="《Fracture-Ray》FTR-11-1">《Fracture Ray》FTR 11.1</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Fracture_Ray.avif" alt="《Fracture Ray》FTR曲绘"></p><ul><li><p>整体评价：骨折光，早期节奏兼爆发魔王，如今在多次元面前不配上桌了。</p></li><li><p>配置分析：273、299combo单双运手比较难。627至796combo休息段要找到超180度反手的感觉，作为平板玩家感觉反手空间非常充足；而《Breach of Faith》BYD的102combo反手双蛇很挤/卡手，是超180度反手更难的写法。两个彩虹糖段纯粹的难，撑起11.1的排面。</p></li><li><p>推荐程度：3/5。难点过于难，容错率不高。</p></li></ul><h3 id="《KYOREN-ROMANCE》FTR-10-7">《KYOREN ROMANCE》FTR 10.7</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Kyoren.avif" alt="《KYOREN ROMANCE》FTR曲绘"></p><ul><li><p>整体评价：狂恋，又是最水10.7竞争者。它与绿魔王在一些配置上手感比较相似。</p></li><li><p>配置分析：165combo是32分交互，不过很简单，抖一下就完了。307combo直角蛇注意超180度反手，能识别出来基本就好过，判定不严。489combo此类单双，需要左右手轮流交换天地，按理说打出规律即可，但我容易在这脑梗。517combo反手双蛇手感上像划出「X」形剑气，而不能两手相对静止地划。862combo三押段看似送分，对定位要求还蛮高的，歪了可能吃音，手指应分得开一些。由于BPM为205，1044combo的8分直角蛇非常难，不仅位移大，还要到位快。</p></li><li><p>推荐程度：5/5。送分多，底力达标就能吃。</p></li></ul><h3 id="《Welcome-Queen-of-Fiction-》ETR-10-9">《Welcome, Queen of Fiction.》ETR 10.9</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Welcome.avif" alt="《Welcome, Queen of Fiction.》ETR曲绘"></p><ul><li><p>整体评价：虚构女王，双星达成谱。其实排键写得挺直白，但架不住<a href="https://www.bilibili.com/video/BV1oUYSzBEQf">疯狂的节奏和疯狂的变速</a>。</p></li><li><p>配置分析：572至662combo段，1物量短蛇可放置，明明很容易看懂，但手感就是很怪。832combo下拉蛇在视觉上可能影响对后续交互的手序判断。1212combo转圈交互个人最难段，约等效于230BPM的16分交互，我连《Désive》ETR交互都打不动，这带大位移的更加打不动。1298combo骤降速，让人立刻化身急急国王；此外全谱的变速节点都建议背。</p></li><li><p>推荐程度：4/5。还算好吃分，如果不怕被搞心态的话。</p></li></ul><h3 id="《Cyaegha》FTR-10-7">《Cyaegha》FTR 10.7</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Cyaegha.avif" alt="《Cyaegha》FTR曲绘"></p><ul><li><p>整体评价：绿魔王，最水10.7最有力竞争者，传说没降定数是因为游戏创始人<a href="https://arcaea.fandom.com/wiki/Credits">Guy</a>就会打这一个10+，可见其简单程度。不过没有掌握200BPM的底力之前建议不要越级。</p></li><li><p>配置分析：像99combo这样的二纵加Hold我都拆交互了，手感不错；扛也可以，控手要难一点。尤其注意195combo为单个地键，而前后配置均为双押，因此建议只盯单键来切换手感，后面类似的单双混合配置也是如此。692combo双蛇为225度反手，前面已经有反手蛇点引导了。1055combo有个略隐蔽的中间天键换手。1137至1206combo段纯溜冰，左右手轮流交换天地，但需注意1209combo是不符合此规律的衔接点。1246combo存在挡键现象，尽可能提高熟练度，别到结尾一下崩盘了（啊嗯，经验之谈……（╯‵□′）╯︵┴─┴）。</p></li><li><p>推荐程度：5/5。</p></li></ul><h3 id="《Misdeed-la-bonte-de-Dieu-et-l’origine-du-mal-》FTR-10-9">《Misdeed -la bonté de Dieu et l’origine du mal-》FTR 10.9</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Misdeed.avif" alt="《Misdeed -la bonté de Dieu et l'origine du mal-》FTR曲绘"></p><ul><li><p>整体评价：业善，邻居老爷爷级10.9：如果你听不懂节奏，那么老朽也略懂一些爆发。</p></li><li><p>配置分析：55combo每条蛇3个判定点，可能头判有些容易掉。424combo交互起手位移无引导，读谱有难度但不容易混淆。646combo处我选择硬扛，打成交互的话既太慢又难定位。1000combo拇指Hold交互难爆了，而且板子还有几率断触，已严肃滑跪。1153combo二纵可选择<a href="https://www.bilibili.com/video/BV1wX4y1v7Xs">出张拆掉</a>，硬扛影响打交手感。1301combo处M形交互节奏诡异。1457combo结尾碎蛇，不要放松，这里不是休息段！</p></li><li><p>推荐程度：3/5。个人差或许比虚构女王更明显，我猜的。</p></li></ul><h3 id="《Grievous-Lady》FTR-11-1">《Grievous Lady》FTR 11.1</h3><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/Grievous_Lady.avif" alt="《Grievous Lady》FTR曲绘"></p><ul><li><p>整体评价：病女，双星必吃榜，跟10.9里面的妖魔鬼怪一比，梦中情人白月光。奠定了全游戏的基础谱面风格，虽有几处小问题，总体上仍瑕不掩瑜。</p></li><li><p>配置分析：两个Drop键盘段没有想象中难，能把200BPM的带位移交互（如著名嫖分谱《Overwhelm》FTR）打明白就能推它了。362combo双蛇段需用力出张到最远。798combo双押可能有手序问题，我的打法是先跟随蛇的引导，再转至水平。961combo交互出张起手，我很讨厌这种无引导的雷人写法，进而设计了雷人手法：右手小拇指接前一组双押，则食指自然处于出张位置，避免反直觉位移。还要注意970combo为交互后紧邻的双押（看了别人的视频我才知道是要打的，还纳闷怎么老断连），最好按手序由右手拍掉。</p></li><li><p>推荐程度：5/5。另，摘星其实不推荐吃这个，各方面能力还是有欠缺，如果养成手癖得不偿失。</p></li></ul><h2 id="思考与感想">思考与感想</h2><p>这部分讲一讲游玩策略、评估分析、手癖等话题，相比于<a href="#b30%E5%88%86%E8%A1%A8%E8%AF%84%E6%9E%90%E5%8F%8A%E6%8E%A8%E8%8D%90">b30分表评析及推荐</a>有更大的泛用性，但建议仅作参考。</p><h3 id="关于游玩策略">关于游玩策略</h3><p>我采用的是略显极端的「打基础」策略，即把完全掌握/基本掌握的谱面作为主要游玩对象，偶尔游玩能够初步掌握的谱面或针对性学习分析，很少越级。对于掌握程度，我的一般标准是：</p><ul><li>完全掌握：997万分以上，没有不会的段落。</li><li>基本掌握：992万分以上，不会少数细节或个别段落。</li><li>初步掌握：985万分以上，不会多个段落。</li><li>需要学习：970万分以上，明显吃力。</li><li>越级：970万分以下。</li></ul><p>选取这种策略有两方面原因：自身方面，底力不突出、耐力稍弱，体力分配强依赖读谱，故基础稳定性对推分有显著作用。外界方面，因为谱面肯定有难度起伏，一首9+的最难段达到10级水平稀松平常（致敬传奇定数9.8），且谱面配置普遍有着<strong>上下位继承关系</strong>，例如转圈蛇半径越大越难划，掌握了下位配置就可以学习其上位配置。所以游戏本身支持「掌握」的继承；但会受到配置多样性的影响。</p><p>进而，我的练习生态大约是：在游玩次数上，完全掌握的谱面占20%，基本掌握的谱面占50%，初步掌握的谱面占20%，需要学习的谱面占10%。</p><h3 id="关于自我评估">关于自我评估</h3><p>在《Arcaea》定数愈显混乱的6.0大版本（参见<a href="https://www.bilibili.com/video/BV1wEahzWEAW">主观定数统计</a>，致敬传奇定数10.1），定数系统还能勉强发挥评估与反映作用——条件是必须有足够数量的已游玩谱面记录，从而利用大样本降低定数异常值带来的偏差（参见<a href="https://zh.wikipedia.org/wiki/%E5%A4%A7%E6%95%B0%E5%AE%9A%E5%88%99">大数定律</a>、<a href="https://zh.wikipedia.org/wiki/%E4%B8%AD%E5%BF%83%E6%9E%81%E9%99%90%E5%AE%9A%E7%90%86">中心极限定理</a>等），得到更准确的自我能力评估。</p><p>例如，当初我判断自己有能力摘星的评估依据为：已玩过80个9+谱面，其中游玩5次以上的有70个，包含15个997万分以上的，30个992万分以上的。通过参考他人<strong>正常</strong>的摘星b30结构，类似地假定：我的摘星分表里有11个9+谱面、天花板为ptt12.3，且9+的单曲ptt为11.65至11.85的等差数列。发现基本达成了9+的要求，那么说明：我应该尝试将舒适区从9+扩大到10级下位，且有基础冲击单曲ptt12.3了，这等效于冲击定数10.7的谱面992万分（见<a href="https://wiki.arcaea.cn/%E6%BD%9C%E5%8A%9B%E5%80%BC#%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95">ptt计算方法</a>），可以试试哪些10.7对得上口味。当b30既拥有稳健的地板，也拥有超常的天花板，那么摘星就触手可得了。</p><p>也就是说，单曲ptt的特定集合可以衡量对某一难度层级的掌握情况。集合越大，覆盖越全面，则掌握越稳固、能力越扎实。</p><h3 id="关于分表结构">关于分表结构</h3><p>那么，个人ptt呢？多个难度层级的掌握情况共同反映个人ptt，这就涉及到何为<strong>正常</strong>的b30分表结构：简单的分数高，难的分数低，<strong>且定数从低到高大致均匀分布</strong>。</p><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/b30_example.svg" alt="b30分表正常结构示例"></p><p>以上图为例，圆点表示各个单曲ptt，越靠近上方则单曲ptt越高；金字塔表示某难度层级的各分数段，越靠近上方越难达成；绿框表示b30分表组成。可见，9+的单曲ptt上限（即金字塔顶端）最低，10级下位居中，10级上位最高。同时，9+普遍打得最好（即圆点分布偏上），10级下位次之，10级上位最差。那么，在取单曲ptt最优规则下，只有绿框中的圆点能参与组成b30分表，这个结构是相对正常的。</p><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/b30_my_distribution.svg" alt="不同定数组的单曲ptt分布"></p><p>再来看一个真实的分表结构，即我的双星b30做成的散点图。各谱按定数分为三组（没什么依据，只为方便观察），分别是10.3 ~ 10.5、10.6 ~ 10.8、10.9 ~ 11.3。此图的分布与b30分表正常结构示例图非常相似，第一组分布集中，且上限最低；第二组分布较散，且上限居中；第三组分布最散，且上限最高。额外画出的三条均值线反映，定数高的组贡献更大，理所应当的，对吧。</p><h3 id="关于进步的判断">关于进步的判断</h3><p>一般地，读谱不严重影响发挥的条件下，算出个人ptt减去单曲ptt：</p><ul><li>&gt;0.2，则此次游玩处于舒适区，用于热身、巩固；</li><li>+0.2 ~ -0.1，则此次游玩处于进步区，可以此为突破口，分析和学习谱面；</li><li>&lt;-0.1，则此次游玩处于超常区，即发挥超常，但不代表普遍性的掌握。</li></ul><p>b30仅仅是游玩经历的冰山一角。从经验上讲，状态与发挥总是有波动，想达到进步区其实比较困难；如果发现近期1/4以上的游玩结果处于进步区，那么能力大概有突破了——发挥怎样，玩家自己最为清楚。</p><h3 id="关于手癖与学习">关于手癖与学习</h3><p>以新手的视角重新审视一下正在玩的这些东西——好快、好密、好乱、看不懂。对某一谱面信手拈来，真是很平常的事情吗？当然不是。进阶玩家早已习惯于按原速游玩谱面，大脑开启着自动模式阅读着它们，而前提是大量的练习。现在，把玩家同时进行的读谱和打谱类比一下：</p><blockquote><p>研表究明，汉字序顺并不定一影阅响读。事证实明了当你看这完句话之后才发字现都乱是的。</p></blockquote><p>虽然中文母语者能轻松读懂这句话，但是若要求浏览10秒就默写出来呢？这就非常困难。我们总是会受到词句正常顺序的影响。</p><p>每个人对谱面即「句子」的理解都不相同，而这游戏<strong>没有</strong>统一的「句子」标准。游戏中的谱面又是复杂且高速流过的，因此若按照直觉来读和打，出错的可能性极大，就像把「研表究明」错认为「研究表明」。老出同一个错，就可能形成<a href="https://www.taptap.cn/moment/15226287559805645">手癖</a>，即错误且难以改正的肌肉记忆。</p><p>所以，多试试放慢速度吧！谱面一点点看，反复琢磨，摸透位移，感受节奏。当谱师像诗人写诗一样字斟句酌，玩家何不能像读者一样咬文嚼字呢？可以借助视频资源或软件<a href="https://hyoromo.github.io/sound-game-training-android/zh/">《音乐游戏培训》</a>，动脑子的学习才是更高效率的。</p><p>话又说回来。谱师可不一定字斟句酌呢。比如<a href="https://arcaea.fandom.com/wiki/Chart_Designers#Luxance">Luxance</a>臭名昭著的几张谱，该骂还是要骂，拉成一坨了不下岗，还想让玩家琢磨，没门。</p><h3 id="关于放置">关于放置</h3><p>放置，指的是足够长的时间不游玩。放置可以解手癖（镜像是另一主要手段），也可能提高能力。实际应用时效果起伏、难以把控，因为除时间长短外没什么量化指标，也不容易提出合理的理论解释。</p><p><img src="/2026/05/27/Commemorating-Arcaea-ptt12-50/ptt_trend.avif" alt="ptt变化曲线"></p><p>上图是我自摘星到双星的ptt变化趋势。ptt约为12.2的几个月里，我很少打开《Arcaea》，甚至没怎么玩其他音游，但是发现各方面能力均有提升，我不明白。可能是身体得到了足够的休息、大脑得到了在潜意识中整合记忆的时间？这些难以量化，甚至难以意识到。所以，有时干脆不去想，做别的事情，比刻苦地搓玻璃屏幕强多了。</p><h3 id="结语">结语</h3><p>双星达成后，我有些摆烂，通常只在舒适区内推一推小歌PM：丢掉分数主义，享受音游本身。但就尽量多PM的目标而言，可能又算完美主义了，保持一点追求，也借此文表达出来。最后，欢迎留言讨论。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/05/27/Commemorating-Arcaea-ptt12-50/</id>
    <link href="https://blog.deepchirp.com/2026/05/27/Commemorating-Arcaea-ptt12-50/"/>
    <published>2026-05-27T09:04:55.000Z</published>
    <summary>本文以纪念《Arcaea》双星成就为契机，对部分谱面做了评析和推荐，并围绕不同话题叙述思考及感想。</summary>
    <title>《Arcaea》双星纪念</title>
    <updated>2026-05-27T11:31:20.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Linux" scheme="https://blog.deepchirp.com/tags/Linux/"/>
    <category term="KDE" scheme="https://blog.deepchirp.com/tags/KDE/"/>
    <category term="Plasma" scheme="https://blog.deepchirp.com/tags/Plasma/"/>
    <category term="时区" scheme="https://blog.deepchirp.com/tags/%E6%97%B6%E5%8C%BA/"/>
    <content>
      <![CDATA[<div class="note info flat"><p>封面图为KDE壁纸「Autumn 5.5」，原作者为<a href="mailto:rjquiralte@gmail.com">RJ Quiralta</a>，使用<a href="https://www.gnu.org/licenses/lgpl-3.0.html">LGPLv3</a>许可。</p></div><p>Windows、Android等系统均提供了自动设置时区的功能，对于跨国旅行的用户很有帮助。然而，截至6.6.4版本，KDE Plasma仍未在系统设置中提供自动设置时区的选项（参见功能请求<a href="https://bugs.kde.org/show_bug.cgi?id=443354">Bug 443354</a>）。不过，该功能实际<a href="https://invent.kde.org/plasma/plasma-workspace/-/commit/a9dcdd5e56a8a503a3b204d607fd6ed2e1d29c11">已被引入</a>。在该选项显示在系统设置之前，可以通过以下步骤启用该功能：</p><ol><li>搜索并打开「后台服务」<br><img src="/2026/05/03/KDE-Plasma-Automatic-Time-Zone/Screenshot_20260503_173634.avif" alt="搜索「后台服务」"></li><li>找到并勾选「基于位置的系统时区」<br><img src="/2026/05/03/KDE-Plasma-Automatic-Time-Zone/Screenshot_20260503_173855.avif" alt="启用「基于位置的系统时区」"></li></ol><p>除此之外，还可使用命令行的方式加载该模块。可参见《<a href="https://linuxjedi.co.uk/kde-plasma-automatic-time-zone/">KDE Plasma Automatic Time Zone</a>》。具体地，下列命令可以加载并启动该模块：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">qdbus org.kde.kded6 /kded setModuleAutoloading geotimezoned true</span><br><span class="line">qdbus org.kde.kded6 /kded loadModule geotimezoned</span><br></pre></td></tr></table></figure><p>根据代码，该模块会向<code>https://geoip.kde.org/v1/timezone</code>发送请求以获取时区信息。因此，若使用代理软件，需要令该域名直连，否则可能会获取到代理服务器所在的时区信息。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/05/03/KDE-Plasma-Automatic-Time-Zone/</id>
    <link href="https://blog.deepchirp.com/2026/05/03/KDE-Plasma-Automatic-Time-Zone/"/>
    <published>2026-05-03T12:40:23.000Z</published>
    <summary>KDE Plasma尚未在系统设置中提供自动设置时区的选项，但该功能已被引入。本文介绍了如何在「后台服务」中启用该功能。</summary>
    <title>KDE Plasma自动设置时区</title>
    <updated>2026-05-03T12:40:23.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="操作系统" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    <category term="Linux" scheme="https://blog.deepchirp.com/tags/Linux/"/>
    <category term="runc" scheme="https://blog.deepchirp.com/tags/runc/"/>
    <category term="容器" scheme="https://blog.deepchirp.com/tags/%E5%AE%B9%E5%99%A8/"/>
    <category term="OCI" scheme="https://blog.deepchirp.com/tags/OCI/"/>
    <content>
      <![CDATA[<!--markdownlint-disable MD046--><div class="note info flat"><p>封面图来自<a href="https://commons.wikimedia.org/wiki/File:Hong_Kong_Harbour_view_from_International_Commerce_Center_Building.jpg">维基共享资源</a>，原作者为<a href="https://commons.wikimedia.org/wiki/User:Wilfredor">Wilfredor</a>，使用<a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 1.0 通用公有领域贡献</a>许可。</p></div><div class="note info flat"><p>本文翻译自Antoine Cotten的《<a href="https://acotten.com/2023/08/17/oci-runtime-create-flow">OCI runtime: container creation flow</a>》，原文采用<a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0许可协议</a>发布，本文亦采用该许可协议发布。</p></div><p>最近，我一直在钻研<a href="https://opencontainers.org/posts/blog/2023-07-21-oci-runtime-spec-v1-1/">OCI运行时规范</a>，以及该规范采用Go语言编写的参考实现——<a href="https://github.com/opencontainers/runc"><code>runc</code></a>。早在Kubernetes问世之初，我便开始接触容器技术。然而，在开放容器计划（Open Container Initiative，OCI）持续推进的岁月里，Linux容器于底层运行时架构上的诸多标准化演进，却大多处于我的视线之外。</p><p>在我看来，这种「无感」恰恰证明了标准化处理得十分精妙，未对依赖容器技术的平台造成冲击。不过，此刻确实是我填补这块知识盲区的绝佳契机。</p><p>如果你还不熟悉容器管理器与容器运行时的职责分工，我强烈建议你阅读Ivan Velichko的《<a href="https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/">Journey From Containerization To Orchestration And Beyond</a>》。这篇文章清晰直观，附带了许多高质量的延伸资源，是探索这个无底洞的绝佳切入点。</p><h2 id="OCI运行时的操作">OCI运行时的操作</h2><p>若要符合OCI运行时规范，容器运行时则必须实现以下五个不言自明的操作：</p><ul><li>创建（Create）</li><li>启动（Start）</li><li>查询状态（State）</li><li>终止（Kill）</li><li>删除（Delete）</li></ul><p>这些操作均属抽象范畴，规范本身并未针对CLI运行时（如<code>runc</code>）强制规定具体的命令行API。尽管业界正积极探索如何界定<a href="https://github.com/opencontainers/runtime-tools/blob/v0.9.0/docs/command-line-interface.md">命令行界面</a>的合规标准，但这种极度的抽象性起初令我倍感困惑。</p><p>下面的示意图展现了容器的生命周期，包括先前提到的五个操作：</p><div class="mermaid-wrap"><pre class="mermaid-src" data-config="{}" hidden>    %%{init: { &#39;sequence&#39;: { &#39;mirrorActors&#39;: false } } }%%sequenceDiagram    participant runc    participant OS    runc-&gt;&gt;+OS: 创建（Create）    OS--&gt;&gt;-runc: 进程 ID    runc-&gt;&gt;OS: 保存状态（state.json）    Note right of OS: 已创建（created）    runc-&gt;&gt;+OS: 查询状态（State）    OS--&gt;&gt;-runc: 容器状态    runc-&gt;&gt;+OS: 启动（Start）    OS--&gt;&gt;-runc: 进程状态    Note right of OS: 运行中（running）    runc-&gt;&gt;OS: 终止（Kill）    Note right of OS: 已停止（stopped）    runc-&gt;&gt;OS: 删除（Delete）    Note right of OS: [已销毁]  </pre></div><p>在本文接下来的部分中，我将专注于创建（Create）和启动（Start）这两个阶段的具体细节。</p><h2 id="分步解析">分步解析</h2><p>正如上图所示，通过OCI运行时运行容器化进程分为两个步骤：创建（Create）、启动（Start）。对于习惯驾驭Docker等高层容器运行时的开发者而言，他们往往会将这些OCI操作与<code>docker container [create|start]</code>等命令混为一谈。这种看法很容易产生误导，因为两者尽管语义相似，但并不等同。要理解其中的原因，我们必须观察当这两个操作在Linux宿主机上执行时，操作系统进程究竟发生了什么。</p><p>下面所有的实验都是针对名为<code>mybundle</code>的<a href="https://github.com/opencontainers/runtime-spec/blob/v1.1.0/bundle.md">OCI bundle</a>进行的。它是从Docker Hub镜像<a href="https://hub.docker.com/_/nginx"><code>docker.io/library/nginx</code></a>生成的，其<code>rootfs</code>可以使用<code>crane</code>等OCI镜像处理工具导出。该bundle的目录结构如下所示，其中<code>config.json</code>是容器的<a href="https://github.com/opencontainers/runtime-spec/blob/v1.1.0/config.md">OCI运行时配置文件</a>，由<code>runc spec</code>或容器运行器/引擎生成。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">mybundle</span><br><span class="line">├── config.json</span><br><span class="line">└── rootfs</span><br><span class="line">    ├── bin</span><br><span class="line">    ├── dev</span><br><span class="line">    ├── docker-entrypoint.sh</span><br><span class="line">    ├── etc</span><br><span class="line">    ├── home</span><br><span class="line">    ├── lib</span><br><span class="line">    ├── ...</span><br><span class="line">    ├── usr</span><br><span class="line">    └── var</span><br></pre></td></tr></table></figure><p><code>runc</code>需要根目录，还需要与容器ID对应的子目录（<code>mycontainer</code>），后者用于存储各操作间的状态。此类目录树通常交由<code>containerd</code>等容器管理器代为维护，但本文的实验已剥离了这层上级管控。</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p /run/runc/mycontainer</span><br></pre></td></tr></table></figure><h3 id="创建（Create）">创建（Create）</h3><p>在我们的bundle上执行<code>runc create</code>命令：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">runc --root /run/runc \</span><br><span class="line">  create \</span><br><span class="line">  --bundle ~acotten/mybundle \</span><br><span class="line">  --pid-file ~acotten/init.pid \</span><br><span class="line">  mycontainer</span><br></pre></td></tr></table></figure><p>查询其状态：</p><figure class="highlight console"><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><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">runc --root /run/runc state mycontainer</span></span><br><span class="line">&#123;</span><br><span class="line">  &quot;ociVersion&quot;: &quot;1.1.0&quot;,</span><br><span class="line">  &quot;id&quot;: &quot;mycontainer&quot;,</span><br><span class="line">  &quot;pid&quot;: 19374,</span><br><span class="line">  &quot;status&quot;: &quot;created&quot;,</span><br><span class="line">  &quot;bundle&quot;: &quot;/home/acotten/mybundle&quot;,</span><br><span class="line">  &quot;rootfs&quot;: &quot;/home/acotten/mybundle/rootfs&quot;,</span><br><span class="line">  &quot;created&quot;: &quot;2023-08-17T19:10:49.347132023Z&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>值得玩味的一个细节是，尽管目前状态为<code>created</code>而非<code>running</code>，但容器状态中竟然已经包含了<strong>进程ID</strong>（<code>19374</code>）。这正是它与<code>docker container create</code>及其同类命令的首个主要区别——后者仅从指定镜像创建容器，而不会启动它。</p><p>现在我们来看看正在运行的进程。在基于Ubuntu的WSL实例中，进程树如下所示：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">ps axjf</span></span><br><span class="line"> PPID   PID  PGID   SID ... COMMAND</span><br><span class="line">    0     1     0     0 ... /init</span><br><span class="line">    1 18594 18594 18594 ...  \_ /init</span><br><span class="line">18594 18595 18595 18595 ...      \_ -zsh</span><br><span class="line">18594 19374 19374 19374 ...      \_ runc init</span><br></pre></td></tr></table></figure><p>从上面的输出可以看出第二个有趣但重要的细节：进程ID对应的是<code>runc init</code>，与我们的<code>nginx</code> bundle毫无关联。</p><h3 id="启动（Start）">启动（Start）</h3><p>当我们执行<code>runc start</code>时，来看看这个过程会如何进行：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">runc --root /run/runc start mycontainer</span><br></pre></td></tr></table></figure><p>刹那间，我们可以看见容器的入口点（entrypoint）命令正沿用<strong>相同的进程ID</strong>启动执行，但随即消失：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">ps axjf</span></span><br><span class="line"> PPID   PID  PGID   SID ... COMMAND</span><br><span class="line">    0     1     0     0 ... /init</span><br><span class="line">    1 18594 18594 18594 ...  \_ /init</span><br><span class="line">18594 18595 18595 18595 ...      \_ -zsh</span><br><span class="line">18594 19374 19374 19374 ...      \_ /bin/sh /docker-entrypoint.sh nginx -g daemon off</span><br></pre></td></tr></table></figure><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">ps axjf</span></span><br><span class="line"> PPID   PID  PGID   SID ... COMMAND</span><br><span class="line">    0     1     0     0 ... /init</span><br><span class="line">    1 18594 18594 18594 ...  \_ /init</span><br><span class="line">18594 18595 18595 18595 ...      \_ -zsh</span><br><span class="line">                                 #gone!</span><br></pre></td></tr></table></figure><p>再次查询其状态：</p><figure class="highlight console"><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><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">runc --root /run/runc state mycontainer</span></span><br><span class="line">&#123;</span><br><span class="line">  &quot;ociVersion&quot;: &quot;1.1.0&quot;,</span><br><span class="line">  &quot;id&quot;: &quot;mycontainer&quot;,</span><br><span class="line">  &quot;pid&quot;: 0,</span><br><span class="line">  &quot;status&quot;: &quot;stopped&quot;,</span><br><span class="line">  &quot;bundle&quot;: &quot;/home/acotten/mybundle&quot;,</span><br><span class="line">  &quot;rootfs&quot;: &quot;/home/acotten/mybundle/rootfs&quot;,</span><br><span class="line">  &quot;created&quot;: &quot;2023-08-17T19:10:49.347132023Z&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>容器正处于<code>stopped</code>状态，并且不再返回进程ID。</p><h3 id="运行（Run）">运行（Run）</h3><p>在进一步深入探究之前，我们先试着解释一下刚刚观察到的行为。为此，我们将使用<code>runc</code>的高层命令之一：<code>runc run</code>。该命令并不直接映射到此前列举的任何一种OCI运行时操作，但可以粗略地将其描述为<code>create</code>与<code>start</code>的结合，尽管存在一些细微差别。</p><p>首先，我们必须删除已停止的容器：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">runc --root /run/runc delete mycontainer</span><br></pre></td></tr></table></figure><p>然后就像先前调用<code>runc create</code>那样，执行<code>runc run</code>：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">runc --root /run/runc \</span><br><span class="line">  run \</span><br><span class="line">  --bundle ~acotten/mybundle \</span><br><span class="line">  --pid-file ~acotten/init.pid \</span><br><span class="line">  mycontainer</span><br></pre></td></tr></table></figure><p>这次，命令并没有立即退出，而是将容器init进程（<code>nginx</code>）的标准输出直接打印到了当前终端上：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">/docker-entrypoint.sh: Configuration complete; ready for start up</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: using the &quot;epoll&quot; event method</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: nginx/1.25.1</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1)</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: OS: Linux 5.15.90.1-microsoft-standard-WSL2</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:1024</span><br><span class="line">2023/08/17 19:12:34 [notice] 1#1: start worker processes</span><br></pre></td></tr></table></figure><p>让我们在另一个独立的终端窗口中检查容器的状态以及进程树：</p><figure class="highlight console"><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><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">runc --root /run/runc state mycontainer</span></span><br><span class="line">&#123;</span><br><span class="line">  &quot;ociVersion&quot;: &quot;1.1.0&quot;,</span><br><span class="line">  &quot;id&quot;: &quot;mycontainer&quot;,</span><br><span class="line">  &quot;pid&quot;: 24977,</span><br><span class="line">  &quot;status&quot;: &quot;running&quot;,</span><br><span class="line">  &quot;bundle&quot;: &quot;/home/acotten/mybundle&quot;,</span><br><span class="line">  &quot;rootfs&quot;: &quot;/home/acotten/mybundle/rootfs&quot;,</span><br><span class="line">  &quot;created&quot;: &quot;2023-08-17T19:12:34.054132023Z&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>runc state</code>报告的进程ID现在显示为<code>running</code>状态：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">ps axjf</span></span><br><span class="line"> PPID   PID  PGID   SID ... COMMAND</span><br><span class="line">    0     1     0     0 ... /init</span><br><span class="line">    1 20434 20434 20434 ...  \_ /init</span><br><span class="line">20434 20435 20435 20435 ...  \_ -zsh</span><br><span class="line">20435 24963 24963 20435 ...      \_ runc --root /run/runc run --bundle /home/ac...</span><br><span class="line">24965 24977 24977 24977 ...          \_ nginx: master process nginx -g daemon off</span><br><span class="line">24977 24998 24977 24977 ...              \_ nginx: worker process</span><br><span class="line">24977 24999 24977 24977 ...              \_ nginx: worker process</span><br><span class="line">24977 25000 24977 24977 ...              \_ nginx: worker process</span><br><span class="line">24977 25001 24977 24977 ...              \_ nginx: worker process</span><br></pre></td></tr></table></figure><p>相应的进程在进程树中清晰可见，根据容器配置，其运行命令正对应<code>nginx</code>主进程。</p><p>想必大家已经猜到了，我们在本实验中观察到的差异与标准I/O流（stdin、stdout、stderr）有关：</p><ul><li>使用<code>runc run</code>时，<code>runc</code>仍然是容器init进程（<code>nginx</code>）的父进程。由于<code>runc</code>是从shell中fork出来的，它继承了shell的I/O流（<a href="https://github.com/opencontainers/runc/blob/v1.1.9/docs/terminals.md#foreground">前台模式</a>）。</li><li>使用<code>runc start</code>时，容器的init进程已沦为孤儿进程，并被重新托管给层级最近的宿主机init进程。随后，由于该进程向已关闭的标准输出（stdout）写入失败导致退出，它立刻被新接管的父进程回收。</li></ul><p>倘若在整体架构中引入诸如<code>containerd</code>这类的容器管理器，系统便会在管理器与核心容器进程之间垫入一个「容器运行时shim（垫片）」进程，从而规避上述I/O断链的问题。同样，Ivan在《<a href="https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/">Journey From Containerization To Orchestration And Beyond</a>》中很好地阐述了运行时shim的作用，因此我不打算在此进一步展开讨论。</p><p>此外，解释该进程在分离模式下的退出原因不是我的关注重点。言归正传，让我们看看在创建OCI容器的这两个相独立的阶段（创建与启动）中，究竟发生了什么。</p><h2 id="多个初始化阶段">多个初始化阶段</h2><p>读者不禁会产生疑问：既然在技术维度上容器完全能够一步到位启动，那么这种分两阶段的启动流程有何意义？OCI运行时规范并未阐述如此设计的初衷，但我相信，通过与UNIX创建进程的一些API（<code>fork()</code>和<code>exec()</code>）相类比，可以很好地回答这个问题。</p><h3 id="插曲：UNIX进程">插曲：UNIX进程</h3><p>在UNIX系统中，运行与当前调用程序不同的程序需要两次系统调用：</p><ul><li><code>fork()</code>：创建一个与调用（父）进程（几乎）完全相同的副本</li><li><code>exec()</code>：在不创建新进程的情况下，将当前运行的程序替换为另一个程序</li></ul><p>这样一来，父进程便能在<code>fork()</code>和<code>exec()</code>之间执行一些代码。这种机制对于像UNIX shell这样的程序至关重要，因为它需要支持I/O流重定向和其他进程操作等功能。</p><p>例如，当执行shell命令<code>echo 'hi' &gt;out.txt</code>或<code>echo 'hi' | wc</code>时，shell会在底层执行以下操作：</p><ol><li>使用<code>fork()</code>创建一个子进程</li><li>关闭该子进程的标准输出，并获取应重定向到的目标文件描述符（在上述示例中分别为文件和管道）</li><li>将此文件描述符分配给该进程的标准输出</li><li>通过调用<code>exec()</code>运行<code>echo</code>命令</li></ol><p>这个机制非常强大，Remzi和Andrea Arpaci-Dusseau所写的（<strong>免费</strong>）著作《<a href="https://pages.cs.wisc.edu/~remzi/OSTEP/">Operating Systems: Three Easy Pieces</a>》中，第五章「Process API」对此做了简洁精辟的解释。</p><h3 id="OCI运行时初始化">OCI运行时初始化</h3><p>厘清这些基本概念后，我们现在就有了充足的背景知识，可以深入探究在OCI容器生命周期的创建（Create）与启动（Start）阶段之间，究竟发生了什么。</p><p>在本文的第一部分中，我们看到<code>runc create</code>最终产生了一个新进程，它并不是预期的容器应用程序，而是<code>runc</code>本身。深挖<a href="https://pkg.go.dev/github.com/opencontainers/runc@v1.1.9/libcontainer">libcontainer</a>底层的源码脉络不难发现，在这个被称为「bootstrap」（引导）的阶段中，系统会调用<code>/proc/self/exe init</code>命令（实质上是重新拉起<code>runc</code>二进制文件本身）来孵化出一个父进程。随后，该进程不仅会提前继承未来容器init进程（PID 1，即本文示例中的<code>nginx</code>）所需的Linux cgroup及命名空间上下文，还会从其源头父进程处接收待拉起容器的OCI运行时配置。此后，它将一直保持该状态，等待启动（Start）阶段的到来<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>。</p><p>从概念上讲，这与<code>fork() + exec()</code>语境下的<code>fork()</code>UNIX系统调用非常相似。</p><div class="mermaid-wrap"><pre class="mermaid-src" data-config="{}" hidden>    graph LR    subgraph host_ns [&quot;宿主机命名空间&quot;]        A[runc create]    end    subgraph container_cgroups [&quot;容器cgroup&quot;]        subgraph container_ns [&quot;容器命名空间&quot;]            B[runc init]        end    end    A -- &quot;fork, nsenter&quot; --&gt; B  </pre></div><p>在创建（Create）阶段结束时，<code>runc</code>会将状态写入到<code>state.json</code>文件中，其存放于由<code>--root</code>命令行参数指定的目录下。该文件包含了诸如引导进程的进程ID等信息。随后所有的<code>runc</code>命令都会读取此文件，将其作为唯一依据，并根据其init进程的状态来确定容器的当前状态。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/run/runc/mycontainer</span><br><span class="line">└── state.json</span><br></pre></td></tr></table></figure><p>前面我刻意省略了一个细节：同一目录下其实还创建了名为<code>exec.fifo</code>的命名管道（FIFO）。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/run/runc/mycontainer</span><br><span class="line">├── exec.fifo</span><br><span class="line">└── state.json</span><br></pre></td></tr></table></figure><p>正是这个命名管道，宿主机方能向引导进程传达启动容器的意图，并开启下一阶段：启动（Start）。该命名管道的写入端绑定至引导进程，而读取端则暂处于封闭状态。此时，引导进程会因尝试向<code>exec.fifo</code>执行写入调用而<a href="https://github.com/opencontainers/runc/blob/v1.1.9/libcontainer/standard_init_linux.go#L233-L244">陷入阻塞态</a>；直到外部执行<code>runc start</code>并<a href="https://github.com/opencontainers/runc/blob/v1.1.9/libcontainer/container_linux.go#L327-L329">从中读取数据</a>，扣下准许放行的「发令枪」后，阻塞方才解除。</p><p>在此阶段，调用者（例如<code>containerd</code>之类的容器管理器）在正式启动容器前，可以根据需要，执行任何其认为合适的额外步骤。在实际应用中，这通常意味着调用一系列<a href="https://www.cni.dev/">CNI</a>插件来配置容器的网络接口<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。待此类操作完成后，调用者便可发起启动（Start）阶段。</p><p>而在容器启动的第二阶段（亦即最终收尾阶段），底层实际发生的动作核心，不过是一次<a href="https://github.com/opencontainers/runc/blob/v1.1.9/libcontainer/standard_init_linux.go#L261"><code>exec()</code>系统调用</a>。而触发它的，正是前文提到的<code>exec.fifo</code>管道读取事件。由于引导进程在创建（Create）阶段就已经从父级<code>runc</code>进程接收了容器的运行时配置，因此无需再执行任何额外步骤。</p><div class="mermaid-wrap"><pre class="mermaid-src" data-config="{}" hidden>    %%{init: { &#39;sequence&#39;: { &#39;mirrorActors&#39;: false } } }%%sequenceDiagram    autonumber    box 进程    participant RS as runc start    participant RI as runc init    participant NX as nginx    end    box 文件    participant FF as fifo    end    RI-&gt;&gt;FF: 写入    activate FF    Note right of FF: 阻塞    FF--&gt;&gt;RS: 读取    deactivate FF    RI-&gt;&gt;NX: exec    RS-&gt;&gt;FF: 删除  </pre></div><p>最后，<code>exec.fifo</code>命名管道被删除。</p><h2 id="附录：引导进程全貌">附录：引导进程全貌</h2><p><code>initProcess</code>结构体的完整内容（为清晰起见，省略了一些无关属性）展示如下，以供参考：</p><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line">libcontainer.parentProcess(*libcontainer.initProcess) *&#123;</span><br><span class="line">    cmd: *os/exec.Cmd &#123;</span><br><span class="line">        Path: <span class="string">&quot;/proc/self/exe&quot;</span>,</span><br><span class="line">        Args: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">2</span>, <span class="built_in">cap</span>: <span class="number">2</span>, [</span><br><span class="line">            <span class="string">&quot;/usr/local/bin/runc&quot;</span>,</span><br><span class="line">            <span class="string">&quot;init&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        Env: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">7</span>, <span class="built_in">cap</span>: <span class="number">12</span>, [</span><br><span class="line">            <span class="string">&quot;GOMAXPROCS=&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_INITPIPE=3&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_STATEDIR=/run/runc/mycontainer&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_LOGPIPE=4&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_LOGLEVEL=4&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_FIFOFD=5&quot;</span>,</span><br><span class="line">            <span class="string">&quot;_LIBCONTAINER_INITTYPE=standard&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        Dir: <span class="string">&quot;/home/acotten/mybundle/rootfs&quot;</span>,</span><br><span class="line">        Stdin: io.Reader(*os.File) *&#123;</span><br><span class="line">            file: *(*os.file)(<span class="number">0xc000082060</span>),&#125;,</span><br><span class="line">        Stdout: io.Writer(*os.File) *&#123;</span><br><span class="line">            file: *(*os.file)(<span class="number">0xc0000820c0</span>),&#125;,</span><br><span class="line">        Stderr: io.Writer(*os.File) *&#123;</span><br><span class="line">            file: *(*os.file)(<span class="number">0xc000082120</span>),&#125;,</span><br><span class="line">        ExtraFiles: []*os.File <span class="built_in">len</span>: <span class="number">3</span>, <span class="built_in">cap</span>: <span class="number">4</span>, [</span><br><span class="line">            *(*os.File)(<span class="number">0xc000014bb8</span>),</span><br><span class="line">            *(*os.File)(<span class="number">0xc000014bc8</span>),</span><br><span class="line">            *(*os.File)(<span class="number">0xc000014be8</span>),</span><br><span class="line">        ],&#125;,</span><br><span class="line">    messageSockPair: libcontainer.filePair &#123;</span><br><span class="line">        parent: *(*os.File)(<span class="number">0xc000014bb0</span>),</span><br><span class="line">        child: *(*os.File)(<span class="number">0xc000014bb8</span>),&#125;,</span><br><span class="line">    logFilePair: libcontainer.filePair &#123;</span><br><span class="line">        parent: *(*os.File)(<span class="number">0xc000014bc0</span>),</span><br><span class="line">        child: *(*os.File)(<span class="number">0xc000014bc8</span>),&#125;,</span><br><span class="line">    config: *libcontainer.initConfig &#123;</span><br><span class="line">        Args: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">4</span>, <span class="built_in">cap</span>: <span class="number">4</span>, [</span><br><span class="line">            <span class="string">&quot;/docker-entrypoint.sh&quot;</span>,</span><br><span class="line">            <span class="string">&quot;nginx&quot;</span>,</span><br><span class="line">            <span class="string">&quot;-g&quot;</span>,</span><br><span class="line">            <span class="string">&quot;daemon off;&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        Env: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">4</span>, <span class="built_in">cap</span>: <span class="number">4</span>, [</span><br><span class="line">            <span class="string">&quot;PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&quot;</span>,</span><br><span class="line">            <span class="string">&quot;NGINX_VERSION=1.25.1&quot;</span>,</span><br><span class="line">            <span class="string">&quot;PKG_RELEASE=1&quot;</span>,</span><br><span class="line">            <span class="string">&quot;NJS_VERSION=0.7.12&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        Cwd: <span class="string">&quot;/&quot;</span>,</span><br><span class="line">        Capabilities: *(*<span class="string">&quot;libcontainer/configs.Capabilities&quot;</span>)(<span class="number">0xc0000bf200</span>),</span><br><span class="line">        User: <span class="string">&quot;0:0&quot;</span>,</span><br><span class="line">        AdditionalGroups: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">11</span>, <span class="built_in">cap</span>: <span class="number">16</span>, [</span><br><span class="line">            <span class="string">&quot;0&quot;</span>,<span class="string">&quot;1&quot;</span>,<span class="string">&quot;2&quot;</span>,<span class="string">&quot;3&quot;</span>,<span class="string">&quot;4&quot;</span>,<span class="string">&quot;6&quot;</span>,<span class="string">&quot;10&quot;</span>,<span class="string">&quot;11&quot;</span>,<span class="string">&quot;20&quot;</span>,<span class="string">&quot;26&quot;</span>,<span class="string">&quot;27&quot;</span>],</span><br><span class="line">        Config: *(*<span class="string">&quot;libcontainer/configs.Config&quot;</span>)(<span class="number">0xc0000e21e0</span>),</span><br><span class="line">        Networks: []*libcontainer.network <span class="built_in">len</span>: <span class="number">0</span>, <span class="built_in">cap</span>: <span class="number">0</span>, <span class="literal">nil</span>,</span><br><span class="line">        PassedFilesCount: <span class="number">0</span>,</span><br><span class="line">        ContainerId: <span class="string">&quot;mycontainer&quot;</span>,</span><br><span class="line">        Rlimits: []libcontainer/configs.Rlimit <span class="built_in">len</span>: <span class="number">1</span>, <span class="built_in">cap</span>: <span class="number">1</span>, [</span><br><span class="line">            (*<span class="string">&quot;libcontainer/configs.Rlimit&quot;</span>)(<span class="number">0xc00002d4d0</span>),</span><br><span class="line">        ],&#125;,</span><br><span class="line">    manager: libcontainer/cgroups.Manager(*libcontainer/cgroups/fs.manager) *&#123;</span><br><span class="line">        cgroups: *libcontainer/configs.Cgroup &#123;</span><br><span class="line">            Name: <span class="string">&quot;&quot;</span>,</span><br><span class="line">            Parent: <span class="string">&quot;&quot;</span>,</span><br><span class="line">            Path: <span class="string">&quot;/default/1b260428b931d1c22fa618e251c7da66f84d18fe66f2ee67d...+15 more&quot;</span>,</span><br><span class="line">            ScopePrefix: <span class="string">&quot;&quot;</span>,</span><br><span class="line">            Resources: *(*<span class="string">&quot;libcontainer/configs.Resources&quot;</span>)(<span class="number">0xc000002300</span>),</span><br><span class="line">            Rootless: <span class="literal">false</span>,</span><br><span class="line">            OwnerUID: *<span class="type">int</span> <span class="literal">nil</span>,&#125;,</span><br><span class="line">        paths: <span class="keyword">map</span>[<span class="type">string</span>]<span class="type">string</span> [</span><br><span class="line">            <span class="string">&quot;memory&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/memory/default/1b260428b931d1c22fa618e2...+40 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;net_cls&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/net_cls/default/1b260428b931d1c22fa618...+42 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;net_prio&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/net_prio/default/1b260428b931d1c22fa6...+44 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/unified/default/1b260428b931d1c22fa618e251c7d...+35 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;cpuset&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/cpuset/default/1b260428b931d1c22fa618e2...+40 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;rdma&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/rdma/default/1b260428b931d1c22fa618e251c7...+36 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;devices&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/devices/default/1b260428b931d1c22fa618...+42 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;cpu&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/cpu/default/1b260428b931d1c22fa618e251c7da...+34 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;perf_event&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/perf_event/default/1b260428b931d1c2...+48 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;misc&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/misc/default/1b260428b931d1c22fa618e251c7...+36 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;cpuacct&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/cpuacct/default/1b260428b931d1c22fa618...+42 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;pids&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/pids/default/1b260428b931d1c22fa618e251c7...+36 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;blkio&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/blkio/default/1b260428b931d1c22fa618e251...+38 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;hugetlb&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/hugetlb/default/1b260428b931d1c22fa618...+42 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;freezer&quot;</span>: <span class="string">&quot;/sys/fs/cgroup/freezer/default/1b260428b931d1c22fa618...+42 more&quot;</span>,</span><br><span class="line">        ],&#125;</span><br><span class="line">    container: *libcontainer.linuxContainer &#123;</span><br><span class="line">        id: <span class="string">&quot;mycontainer&quot;</span>,</span><br><span class="line">        root: <span class="string">&quot;/run/runc/mycontainer&quot;</span>,</span><br><span class="line">        config: *(*<span class="string">&quot;libcontainer/configs.Config&quot;</span>)(<span class="number">0xc0000e21e0</span>),</span><br><span class="line">        cgroupManager: libcontainer/cgroups.Manager(*libcontainer/cgroups/fs.manager) ...,</span><br><span class="line">        initPath: <span class="string">&quot;/proc/self/exe&quot;</span>,</span><br><span class="line">        initArgs: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">2</span>, <span class="built_in">cap</span>: <span class="number">2</span>, [</span><br><span class="line">            <span class="string">&quot;/usr/local/bin/runc&quot;</span>,</span><br><span class="line">            <span class="string">&quot;init&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        initProcess: libcontainer.parentProcess(*libcontainer.initProcess) ...,</span><br><span class="line">        initProcessStartTime: <span class="number">0</span>,</span><br><span class="line">        state: libcontainer.containerState(*libcontainer.stoppedState) ...,</span><br><span class="line">        created: (*time.Time)(<span class="number">0xc0001d42b0</span>),</span><br><span class="line">        fifo: *(*os.File)(<span class="number">0xc000014be8</span>),&#125;,</span><br><span class="line">    fds: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">0</span>, <span class="built_in">cap</span>: <span class="number">0</span>, <span class="literal">nil</span>,</span><br><span class="line">    process: *libcontainer.Process &#123;</span><br><span class="line">        Args: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">4</span>, <span class="built_in">cap</span>: <span class="number">4</span>, [</span><br><span class="line">            <span class="string">&quot;/docker-entrypoint.sh&quot;</span>,</span><br><span class="line">            <span class="string">&quot;nginx&quot;</span>,</span><br><span class="line">            <span class="string">&quot;-g&quot;</span>,</span><br><span class="line">            <span class="string">&quot;daemon off;&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        Env: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">4</span>, <span class="built_in">cap</span>: <span class="number">4</span>, [</span><br><span class="line">            <span class="string">&quot;PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bi...+1 more&quot;</span>,</span><br><span class="line">            <span class="string">&quot;NGINX_VERSION=1.25.1&quot;</span>,</span><br><span class="line">            <span class="string">&quot;PKG_RELEASE=1&quot;</span>,</span><br><span class="line">            <span class="string">&quot;NJS_VERSION=0.7.12&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">        User: <span class="string">&quot;0:0&quot;</span>,</span><br><span class="line">        AdditionalGroups: []<span class="type">string</span> <span class="built_in">len</span>: <span class="number">11</span>, <span class="built_in">cap</span>: <span class="number">16</span>, [</span><br><span class="line">            <span class="string">&quot;0&quot;</span>,<span class="string">&quot;1&quot;</span>,<span class="string">&quot;2&quot;</span>,<span class="string">&quot;3&quot;</span>,<span class="string">&quot;4&quot;</span>,<span class="string">&quot;6&quot;</span>,<span class="string">&quot;10&quot;</span>,<span class="string">&quot;11&quot;</span>,<span class="string">&quot;20&quot;</span>,<span class="string">&quot;26&quot;</span>,<span class="string">&quot;27&quot;</span>],</span><br><span class="line">        Cwd: <span class="string">&quot;/&quot;</span>,</span><br><span class="line">        Stdin: io.Reader(*os.File) ...,</span><br><span class="line">        Stdout: io.Writer(*os.File) ...,</span><br><span class="line">        Stderr: io.Writer(*os.File) ...,</span><br><span class="line">        ExtraFiles: []*os.File <span class="built_in">len</span>: <span class="number">0</span>, <span class="built_in">cap</span>: <span class="number">0</span>, <span class="literal">nil</span>,</span><br><span class="line">        Capabilities: *(*<span class="string">&quot;libcontainer/configs.Capabilities&quot;</span>)(<span class="number">0xc0000bf200</span>),</span><br><span class="line">        Rlimits: []libcontainer/configs.Rlimit <span class="built_in">len</span>: <span class="number">1</span>, <span class="built_in">cap</span>: <span class="number">1</span>, [</span><br><span class="line">            (*<span class="string">&quot;libcontainer/configs.Rlimit&quot;</span>)(<span class="number">0xc00002d4d0</span>),</span><br><span class="line">        ],</span><br><span class="line">        Init: <span class="literal">true</span>,</span><br><span class="line">        ops: libcontainer.processOperations <span class="literal">nil</span>,</span><br><span class="line">        LogLevel: <span class="string">&quot;4&quot;</span>,</span><br><span class="line">        SubCgroupPaths: <span class="keyword">map</span>[<span class="type">string</span>]<span class="type">string</span> <span class="literal">nil</span>,&#125;,</span><br><span class="line">    bootstrapData: io.Reader(*bytes.Reader) *&#123;</span><br><span class="line">        s: []<span class="type">uint8</span> <span class="built_in">len</span>: <span class="number">32</span>, <span class="built_in">cap</span>: <span class="number">32</span>, [</span><br><span class="line">            <span class="number">32</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">48</span>,<span class="number">242</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">8</span>,<span class="number">0</span>,<span class="number">145</span>,<span class="number">106</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">108</span>,<span class="number">8</span>,<span class="number">0</span>,<span class="number">151</span>,<span class="number">106</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],</span><br><span class="line">        i: <span class="number">0</span>,</span><br><span class="line">        prevRune: <span class="number">-1</span>,&#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>暂且略去那些繁复的深层嵌套细节，有几个关键字段值得我们重点关注：</p><ul><li><code>cmd</code>描述了引导（bootstrap）命令：<code>runc init</code>。<ul><li>用于向引导进程传达启动（Start）阶段开始信号的命名管道<code>exec.fifo</code>，其文件描述符在环境变量<code>_LIBCONTAINER_FIFOFD</code>中被引用。它引用了地址为<code>(*os.File)(0xc000014be8)</code>的<code>cmd.ExtraFiles</code>项，顺带一提，该项也同样被<code>container.fifo</code>引用。</li></ul></li><li>OCI运行时配置（<code>config.json</code>）的反序列化版本在<code>config</code>字段中可见：包含容器<code>cmd</code>、环境变量、工作目录等。<ul><li>实际上，该配置的很大一部分隐藏在<code>config.Config</code>与<code>config.Capabilities</code>字段之后，但在此处展开它们会给示例引入大量干扰，且这两者在OCI运行时规范中均有详细说明。</li><li>一旦引导进程启动，完整的容器配置便会通过一对UNIX域套接字<code>messageSockPair</code>，以JSON格式传递给引导进程。此数据至关重要，引导进程因此才得以在启动（Start）阶段利用预期的环境对容器命令调用<code>exec()</code>。</li></ul></li><li><code>container</code>和<code>process</code>两个字段，与<code>config</code>字段存在部分重叠。它们分别代表了容器的内部表示（由<code>runc</code>/<code>libcontainer</code>所见），以及专门针对容器init进程（即<code>nginx</code>）的表示。</li><li>分配给引导进程（进而分配给容器init进程）的cgroup在<code>manager</code>字段中可见：如<code>cpu</code>、<code>memory</code>、<code>blkio</code>等。</li></ul><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>实际上，<code>runc create</code>在bootstrap（引导）序列中会执行两次fork，从而允许第二个子进程在最终的Linux命名空间内启动，而第一个子进程随后则会退出。这一流程细节丰富，足以专门写一篇文章来探讨。 <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>CNI规范并不属于开放容器计划（OCI）。然而，它是云原生计算基金会（CNCF）生态系统中被广泛采用的标准，主要通过Kubernetes项目得以推广应用。 <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/04/20/OCI-Runtime-Container-Creation-Flow/</id>
    <link href="https://blog.deepchirp.com/2026/04/20/OCI-Runtime-Container-Creation-Flow/"/>
    <published>2026-04-20T13:30:51.000Z</published>
    <summary>本文探讨了OCI运行时规范及其参考实现runc，详细解析了容器化进程在创建与启动两阶段的底层工作流，揭示了bootstrap阶段及命名管道的通信机制。</summary>
    <title>OCI运行时：容器创建流程</title>
    <updated>2026-04-24T15:28:27.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="操作系统" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    <category term="Linux" scheme="https://blog.deepchirp.com/tags/Linux/"/>
    <category term="CVE" scheme="https://blog.deepchirp.com/tags/CVE/"/>
    <category term="Docker" scheme="https://blog.deepchirp.com/tags/Docker/"/>
    <category term="容器安全" scheme="https://blog.deepchirp.com/tags/%E5%AE%B9%E5%99%A8%E5%AE%89%E5%85%A8/"/>
    <category term="runc" scheme="https://blog.deepchirp.com/tags/runc/"/>
    <content>
      <![CDATA[<!-- markdownlint-disable no-hard-tabs --><div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/116713516">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/96112537">仓鼠_Cang</a>。</p></div><h2 id="背景">背景</h2><p>在先前的《<a href="/2026/04/04/CVE-2019-5736-Notes/" title="CVE-2019-5736浅析">CVE-2019-5736浅析</a>》中，我们探讨了旧版<code>runc</code>在处理宿主机与容器之间交互的缺陷。CVE-2024-21626也涉及到<code>runc</code>的处理逻辑问题。两者表现类似，但在安全模型上完全不同：前者属于「<a href="https://en.wikipedia.org/wiki/Confused_deputy_problem">混淆代理人问题</a>」（confused deputy problem），是<code>runc</code>被容器内的恶意逻辑欺骗，交出了控制权；而后者是「资源未回收」问题，<code>runc</code>在初始化隔离环境时，意外留下了可被容器内进程访问的文件描述符。</p><h3 id="runc的初始化流程"><code>runc</code>的初始化流程</h3><p>在使用高层运行时启动容器时，底层的<code>runc</code>分为两个阶段，类似于Unix的<code>fork()</code>与<code>exec()</code>：</p><ol><li><p><strong>创建阶段（<code>runc init</code>）</strong>：</p><p>宿主机调用<code>runc create</code>时，会fork出<code>runc init</code>子进程。该进程负责配置环境：通过C语言层面的<code>nsexec</code>进入各种Namespace，配置Cgroups资源限制，并调用<code>pivot_root</code>将文件系统根目录切换到容器镜像的rootfs中。</p><p>完成准备工作后，<code>runc init</code>会阻塞在名为<code>exec.fifo</code>的命名管道上，等待宿主机的进一步指令。</p></li><li><p><strong>启动阶段（<code>execve</code>）</strong>：</p><p>当宿主机调用<code>runc start</code>，即向<code>exec.fifo</code>写入数据后，<code>runc init</code>解除阻塞。它调用<code>execve</code>系统调用，将自己从内存中清空，替换为用户真正在容器里运行的程序。至此，容器才真正处于运行状态。</p></li></ol><p>（关于更多信息，可参见《<a href="https://acotten.com/2023/08/17/oci-runtime-create-flow">OCI runtime: container creation flow</a>》；本人亦翻译了该文章，参见《<a href="/2026/04/20/OCI-Runtime-Container-Creation-Flow/" title="OCI运行时：容器创建流程">OCI运行时：容器创建流程</a>》）</p><h3 id="O-CLOEXEC">O_CLOEXEC</h3><p>在Linux中，子进程会默认继承父进程的所有文件描述符。但为了防止敏感句柄在<code>execve</code>后泄露，在打开文件时，Linux提供了<a href="https://man.archlinux.org/man/open.2.en#O_CLOEXEC"><code>O_CLOEXEC</code></a>标志，这样可以为文件打上<code>close-on-exec</code>标记。当进程调用<code>execve</code>时，内核会自动关闭所有带有该标记的文件描述符。</p><h3 id="Magic-Link">Magic Link</h3><p>既然容器已经执行了<code>pivot_root</code>，为什么拿到句柄就能逃逸？这就涉及Linux中<code>/proc</code>伪文件系统的特性。</p><p>在Linux中，<code>/proc/self/fd/</code>目录下的数字并不是普通的符号链接，而是<a href="https://man.archlinux.org/man/core/man-pages/symlink.7.en#Magic_links">Magic Link</a>。普通的符号链接解析的是纯文本路径，而Magic Link在内核的虚拟文件系统层面直接绑定了底层的文件对象。</p><h2 id="攻击流程">攻击流程</h2><p>在<code>runc v1.0.0-rc93</code>版本中，为了防御由于挂载点导致的符号链接替换攻击，<code>runc</code>开始使用<a href="https://man.archlinux.org/man/openat2.2.en"><code>openat2</code></a>系统调用来处理cgroup路径。（参见<a href="https://github.com/opencontainers/runc/commit/6bda4600003e145f5aff4dd8d9d2d5866fc44ce9">Commit 6bda460</a>；关于更多背景信息，可参见《<a href="https://brauner.io/2023/02/28/mounting-into-mount-namespaces.html">Mounting into mount namespaces</a>》）</p><p>为此，<code>runc</code>进程会在早期打开宿主机<code>/sys/fs/cgroup</code>目录获取句柄，并将其传递给底层逻辑。</p><p>然而，虽然<code>runc</code>开发者在后续打开具体子文件时都严谨地加上了<code>O_CLOEXEC</code>标志，却唯独遗漏了根目录。这导致该文件描述符（通常为 FD 7）被意外保留。</p><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// libcontainer/cgroups/fscommon/open.go</span></span><br><span class="line"><span class="comment">// Under Apache-2.0 license</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">prepareOpenat2</span><span class="params">()</span></span> <span class="type">error</span> &#123;</span><br><span class="line">prepOnce.Do(<span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line"><span class="comment">// Missing unix.O_CLOEXEC flag when acquiring the cgroupfs root directory handle</span></span><br><span class="line">fd, err := unix.Openat2(<span class="number">-1</span>, cgroupfsDir, &amp;unix.OpenHow&#123;</span><br><span class="line">Flags: unix.O_DIRECTORY | unix.O_PATH&#125;)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="comment">/* ... [snip: error handling] ... */</span></span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* ... [snip: statfs and other checks] ... */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// The leaky fd (typically FD 7) is stored in a global variable</span></span><br><span class="line">cgroupFd = fd</span><br><span class="line"></span><br><span class="line"><span class="comment">/* ... */</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> prepErr</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">OpenFile</span><span class="params">(dir, file <span class="type">string</span>, flags <span class="type">int</span>)</span></span> (*os.File, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="comment">/* ... */</span></span><br><span class="line"><span class="keyword">if</span> prepareOpenat2() != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> openWithSecureJoin(dir, file, flags, mode)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">relname := reldir + <span class="string">&quot;/&quot;</span> + file</span><br><span class="line"><span class="comment">// When opening specific sub-files using cgroupFd, unix.O_CLOEXEC is strictly applied</span></span><br><span class="line">fd, err := unix.Openat2(cgroupFd, relname,</span><br><span class="line">&amp;unix.OpenHow&#123;</span><br><span class="line">Resolve: resolveFlags,</span><br><span class="line">Flags:   <span class="type">uint64</span>(flags) | unix.O_CLOEXEC,</span><br><span class="line">Mode:<span class="type">uint64</span>(mode),</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">/* ... */</span></span><br><span class="line"><span class="keyword">return</span> os.NewFile(<span class="type">uintptr</span>(fd), cgroupfsPrefix+relname), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>不过，<code>runc init</code>会在<code>execve</code>前将标准输入输出和显式传递文件之外的其余文件描述符统一标记为<code>O_CLOEXEC</code>。因此，容器最终进程通常无法获取这些泄露句柄。</p><p>因此，漏洞利用的核心并非调用<code>open(&quot;/proc/self/fd/7&quot;)</code>，而是在<code>runc init</code>调用<code>execve</code>之前，利用它手中的句柄来偷梁换柱。<a href="https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv">官方公告</a>中提到的几种攻击方式，本质上都是围绕这一思路展开的：</p><ol><li><p><strong>劫持工作目录</strong></p><p>在容器启动前，<code>runc init</code>会根据镜像或命令行配置，将当前工作目录切换到指定位置。据此，有如下两种方式：</p><ul><li>恶意镜像攻击（对应「Attack 1」）：攻击者在制作恶意镜像时，直接将<code>Dockerfile</code>中的<code>WORKDIR</code>设置为<code>/proc/self/fd/7/</code>。此外，该容器中启动的进程本身就是攻击者控制的脚本。因此可通过<code>../../../</code>路径回溯，随即越权读写宿主机的文件。</li><li>符号链接陷阱（对应「Attack 2」）：攻击者在已攻陷的容器内，将某个常用目录（如<code>/app</code>）替换为指向<code>/proc/self/fd/7/</code>的软链接，静待宿主机管理员执行<code>docker exec --workdir /app</code>。当<code>runc init</code>尝试切换工作目录时，由于它仍持有指向宿主机<code>/sys/fs/cgroup</code>的FD 7，内核会顺着Magic Link，将物理工作目录定位在宿主机的真实文件系统中。紧接着，<code>runc init</code>清理文件描述符，并调用<code>execve</code>。虽然FD 7随之关闭，但启动的新进程继承了该工作目录。尽管启动的进程本身可能并无恶意行为，然而攻击者可以通过遍历<code>/proc</code>目录发现该进程，并直接访问<code>/proc/&lt;该进程PID&gt;/cwd/../../../</code>，从而窃取或篡改宿主机文件。</li></ul></li><li><p><strong>劫持执行程序</strong></p><p>攻击者也可借此启动宿主机的二进制文件，从而达到篡改或是劫持的目的。</p><ol><li>攻击者将容器配置中需要执行的程序路径，篡改为类似<code>/proc/self/fd/7/../../../bin/bash</code>的形式。</li><li>当<code>runc init</code>准备执行<code>execve</code>后，它持有尚未被关闭的FD 7，让内核顺着Magic Link找到了宿主机物理硬盘上的<code>/bin/bash</code>，并将其加载执行。</li><li><code>execve</code>发生后，容器内执行的进程变成了宿主机的<code>bash</code>。</li></ol><p>根据触发方式的不同，这种攻击同样分为两个变种：</p><ul><li>恶意镜像触发（对应「Attack 3a」）：与Attack 1类似，恶意指令被硬编码在恶意镜像的启动配置中（例如<code>[&quot;/proc/self/fd/7/../../../bin/bash&quot;, &quot;-c&quot;, &quot;malicious_command&quot;]</code>）。当管理员运行<code>docker run</code>时，恶意指令便会被运行。</li><li>内部潜伏触发（对应「Attack 3b」）：与Attack 2类似，攻击者在已攻陷的容器内，将所有管理员可能调用的常规命令全部替换为指向<code>/proc/self/fd/7/../../../bin/bash</code>的恶意脚本。当管理员执行<code>docker exec</code>后，宿主机上的<code>/bin/bash</code>便会被加载执行。后续破坏过程与CVE-2019-5736如出一辙：攻击者只需在容器内部以写入模式（<code>O_WRONLY</code>）打开<code>/proc/&lt;bash PID&gt;/exe</code>，便能直接覆写宿主机的<code>/bin/bash</code>。</li></ul></li></ol><h3 id="复现">复现</h3><p>为了方便地复现漏洞，我直接使用了<code>docker build</code>命令。因为在处理<code>Dockerfile</code>的<code>RUN</code>指令时，Docker底层同样会调用<code>runc</code>启动临时容器，从而触发相同的逻辑。不过需要注意的是，此时泄露的句柄或有不同，在我电脑上仍为FD 7。</p><p>为了避免污染宿主机，我使用Vagrant搭建虚拟机环境，并采用Libvirt作为后端。我使用了Ubuntu 22.04（需要注意的是，<a href="https://www.phoronix.com/news/Linux-5.6-Adds-Openat2"><code>openat2</code>在Linux 5.6版本中被引入</a>，故不能使用早于该版本的内核）。不知何故，Metarget似乎无法正确配置环境。因此我直接安装了官方的Docker包，并手动将<code>runc</code>降级到1.1.11版本。</p><p>查看内核及<code>runc</code>版本：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">uname</span> -r</span></span><br><span class="line">5.15.0-91-generic</span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">runc --version</span></span><br><span class="line">runc version 1.1.11</span><br><span class="line">commit: v1.1.11-0-g4bccb38c</span><br><span class="line">spec: 1.0.2-dev</span><br><span class="line">go: go1.20.12</span><br><span class="line">libseccomp: 2.5.4</span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker info | grep runc</span></span><br><span class="line"> Runtimes: io.containerd.runc.v2 runc</span><br><span class="line"> Default Runtime: runc</span><br><span class="line"> runc version: v1.1.11-0-g4bccb38c</span><br></pre></td></tr></table></figure><p><img src="/2026/04/18/CVE-2024-21626-Notes/Screenshot_20260418_213829.avif" alt="环境信息"></p><p>查看<code>/tmp</code>目录，确保原先并没有相应文件。创建一个简单的<code>Dockerfile</code>，其中有向<code>tmp/tomorin_was_here</code>写入<code>MyGO!!!!!</code>的命令（注意这里多个<code>../</code>是为了确保能够回到根目录）：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /proc/self/fd/7</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">cd</span> ../../../../../../../../ &amp;&amp; \</span></span><br><span class="line"><span class="language-bash">    <span class="built_in">echo</span> <span class="string">&quot;MyGO!!!!!&quot;</span> &gt; tmp/tomorin_was_here</span></span><br></pre></td></tr></table></figure><p><img src="/2026/04/18/CVE-2024-21626-Notes/Screenshot_20260418_214310.avif" alt="tmp目录及Dockerfile"></p><p>随后构建镜像：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker build .</span></span><br><span class="line">[+] Building 21.3s (7/7) FINISHED                                                                              docker:default</span><br><span class="line"> =&gt; [internal] load build definition from Dockerfile                                                                     0.1s</span><br><span class="line"> ... (omitted routine image pull and setup output) ...</span><br><span class="line"> =&gt; [2/3] WORKDIR /proc/self/fd/7                                                                                        0.2s</span><br><span class="line"> =&gt; [3/3] RUN cd ../../../../../../../../ &amp;&amp;     echo &quot;MyGO!!!!!&quot; &gt; tmp/tomorin_was_here                                 1.1s</span><br><span class="line"> ... (omitted exporting and manifest output) ...</span><br></pre></td></tr></table></figure><p>再次查看<code>/tmp</code>目录，发现<code>tomorin_was_here</code>文件已被创建，并写入了预期内容：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> /tmp/tomorin_was_here</span></span><br><span class="line">MyGO!!!!!</span><br></pre></td></tr></table></figure><p><img src="/2026/04/18/CVE-2024-21626-Notes/Screenshot_20260418_214348.avif" alt="tmp目录被写入文件"></p><h2 id="修复与后续">修复与后续</h2><p><code>runc</code>于<a href="https://github.com/opencontainers/runc/commit/a9833ff391a71b30069a6c3f816db113379a4346">该commit</a>中修复了该漏洞。其修改包括四点：</p><ul><li>检查<code>getcwd</code>语义是否返回<code>ENOENT</code>（实现上使用<code>unix.Getwd</code>以及<code>linux.Getwd</code>，而非<code>os.Getwd</code>），以确认当前工作目录确实位于容器内部。</li><li>在<code>runc</code>执行<code>execve</code>之前，关闭所有<code>runc</code>内部的文件描述符。同时需要保证不会关闭Go运行时所需的关键内部文件描述符。</li><li>修复了特定文件描述符的泄漏问题，如为<code>/sys/fs/cgroup</code>设置<code>O_CLOEXEC</code>标志。</li><li>在执行<code>runc init</code>之前，将所有非标准I/O的文件描述符统一设置<code>O_CLOEXEC</code>标志。</li></ul><p>先前我对<code>docker run</code>运行镜像十分警惕，但认为<code>docker build</code>应该基本上没有危险。我想，我只是在本地编译一下代码，只要不运行，肯定不会有什么问题。然而分析、复现该漏洞后，我意识到构建过程同样需要警惕。安全防线必须从「运行期」向前推进到「构建期」。为此，可以采取无特权构建。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/04/18/CVE-2024-21626-Notes/</id>
    <link href="https://blog.deepchirp.com/2026/04/18/CVE-2024-21626-Notes/"/>
    <published>2026-04-18T14:48:28.000Z</published>
    <summary>本文从runc的初始化流程、O_CLOEXEC机制及Magic Link的特性切入，简单分析了CVE-2024-21626中的越权逻辑，并探讨了相应的攻击手法与构建期安全。</summary>
    <title>CVE-2024-21626浅析</title>
    <updated>2026-04-18T14:48:28.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="操作系统" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    <category term="C" scheme="https://blog.deepchirp.com/tags/C/"/>
    <category term="内核" scheme="https://blog.deepchirp.com/tags/%E5%86%85%E6%A0%B8/"/>
    <category term="Linux" scheme="https://blog.deepchirp.com/tags/Linux/"/>
    <category term="CVE" scheme="https://blog.deepchirp.com/tags/CVE/"/>
    <content>
      <![CDATA[<!-- markdownlint-disable no-hard-tabs --><div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/136181997">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/31434343">二狗子茶壶BRH</a>。</p></div><h2 id="背景">背景</h2><h3 id="页与页缓存">页与页缓存</h3><p><a href="https://en.wikipedia.org/wiki/Page_(computer_memory)">页</a>是操作系统管理内存的基本单位，也是CPU中MMU（内存管理单元）内存映射的最小单位，与Linux内存管理机制息息相关。与CPU处理速度相比，磁盘读写速度过慢，因此Linux内核引入了<a href="https://en.wikipedia.org/wiki/Page_cache">页缓存</a>机制。当进程尝试读取文件时，内核会将文件内容加载到内存的页缓存里。后续再次读取该文件时，内核会直接从页缓存中获取数据，而无需访问磁盘。另一方面，程序通过正常途径修改页缓存中的数据后，内核会将这些修改标记为「脏页」，并会适时将它们写回磁盘。</p><h3 id="管道">管道</h3><p><a href="https://www.linfo.org/pipe.html">管道</a>是一种重定向形式，能够将一个程序的输出发送给另一个程序作为输入，从而实现进程间通信。它以一对文件描述符的形式提供给进程，其中一个用于读取，另一个用于写入。向管道的一端写入数据，即可从另一端读取该数据。在内核实现中，这套文件描述符接口并不与真实的磁盘设备相关联，而是连接到了内核空间中专门维护的内存缓冲区。</p><p>对于Linux 5.8版本而言，管道是由内存页组成的环形缓冲区，内核主要通过<a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L34-L81"><code>pipe_inode_info</code>结构体</a>来管理管道。其使用循环数组的方式，定义了指向缓冲数组的指针<a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L76"><code>bufs</code></a>，并通过<a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L60-L61"><code>head</code>和<code>tail</code></a>索引。管道的环形缓冲区大小有限（<a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L5">PIPE_DEF_BUFFERS</a>定义了缓冲区大小），进程从管道读取数据后，消耗掉的槽位会被回收，供后续写入复用。</p><p>循环数组中的每个槽位为<a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L17-L32"><code>pipe_buffer</code>结构体</a>，存储相关元数据，包括标志位<code>flags</code>，以及直接指向物理内存页的指针<code>page</code>：</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/* SPDX-License-Identifier: GPL-2.0 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *struct pipe_buffer - a linux kernel pipe buffer</span></span><br><span class="line"><span class="comment"> *@page: the page containing the data for the pipe buffer</span></span><br><span class="line"><span class="comment"> *@offset: offset of data inside the @page</span></span><br><span class="line"><span class="comment"> *@len: length of data inside the @page</span></span><br><span class="line"><span class="comment"> *@ops: operations associated with this buffer. See @pipe_buf_operations.</span></span><br><span class="line"><span class="comment"> *@flags: pipe buffer flags. See above.</span></span><br><span class="line"><span class="comment"> *@private: private data owned by the ops.</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">pipe_buffer</span> &#123;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">page</span> *<span class="title">page</span>;</span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> offset, len;</span><br><span class="line"><span class="type">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">pipe_buf_operations</span> *<span class="title">ops</span>;</span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> flags;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">long</span> private;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><a href="https://elixir.bootlin.com/linux/v5.8/source/include/linux/pipe_fs_i.h#L11"><code>PIPE_BUF_FLAG_CAN_MERGE</code></a>亦为标志位之一。当进程调用<code>write()</code>向管道的某一全新槽位写入数据时，内核会分配一个匿名页（即不与磁盘文件关联的纯内存页），并为该槽位打上<code>PIPE_BUF_FLAG_CAN_MERGE</code>标志。随后继续执行写操作时，内核如果发现当前槽位带有此标志，且页面尚未写满，便不会再申请新页面，而是直接将新数据追加到当前页中。这样能够优化管道写入的过程，减少内存分配和管理的开销。</p><p>当往管道写入普通匿名页时，<code>buf-&gt;ops</code>会被赋值为指向<code>anon_pipe_buf_ops</code>；而当通过<code>splice()</code>传入页缓存时，<code>buf-&gt;ops</code>会被赋值为指向<code>page_cache_pipe_buf_ops</code>。这也是判断能否追加写入的依据之一。在5.8之前，内核即采用该依据（即<code>buf-&gt;ops == &amp;anon_pipe_buf_ops</code>），而非读取标志位。在<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f6dd975583bd8ce088400648fd9819e4691c8958">commit f6dd975583bd</a>后，判断逻辑改为现状。</p><h3 id="零拷贝与splice">零拷贝与<code>splice()</code></h3><p>一些进程间数据传输的方法（如从文件读出再写入管道）需要在用户空间与内核空间之间多次拷贝数据，开销较大。为了追求极致性能，Linux提供了<a href="https://man.archlinux.org/man/core/man-pages/splice.2.en"><code>splice()</code></a>系统调用以实现零拷贝。其可以直接在两个文件描述符之间移动数据，唯需其中某个传输端为管道。</p><p>当使用<code>splice()</code>将文件页缓存推入管道时，内核底层会分配一个<code>pipe_buffer</code>槽位，并将其<code>page</code>指针指向文件的页缓存。<a href="https://elixir.bootlin.com/linux/v5.8/source/lib/iov_iter.c#L368-L414"><code>copy_page_to_iter_pipe</code>函数</a>相关代码片段如下：</p><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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// SPDX-License-Identifier: GPL-2.0-only</span></span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">size_t</span> <span class="title function_">copy_page_to_iter_pipe</span><span class="params">(<span class="keyword">struct</span> page *page, <span class="type">size_t</span> offset, <span class="type">size_t</span> bytes,</span></span><br><span class="line"><span class="params"> <span class="keyword">struct</span> iov_iter *i)</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">pipe_inode_info</span> *<span class="title">pipe</span> =</span> i-&gt;pipe;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">pipe_buffer</span> *<span class="title">buf</span>;</span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> p_mask = pipe-&gt;ring_size - <span class="number">1</span>;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> i_head = i-&gt;head;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* ... [snip: validation and capacity checks] ... */</span></span><br><span class="line"></span><br><span class="line">buf = &amp;pipe-&gt;bufs[i_head &amp; p_mask];</span><br><span class="line"></span><br><span class="line"><span class="comment">/* ... [snip: page merging optimization and pipe_full check] ... */</span></span><br><span class="line"></span><br><span class="line">buf-&gt;ops = &amp;page_cache_pipe_buf_ops;</span><br><span class="line">get_page(page);</span><br><span class="line">buf-&gt;page = page;</span><br><span class="line">buf-&gt;offset = offset;</span><br><span class="line">buf-&gt;len = bytes;</span><br><span class="line"></span><br><span class="line">pipe-&gt;head = i_head + <span class="number">1</span>;</span><br><span class="line">i-&gt;iov_offset = offset + bytes;</span><br><span class="line">i-&gt;head = i_head;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* ... [snip: cleanup and return] ... */</span></span><br><span class="line"><span class="keyword">return</span> bytes;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="攻击流程">攻击流程</h2><p>攻击者首先填满并清空管道，使得管道环形缓冲区的每个槽位（<code>pipe_buffer</code>）都残留<code>PIPE_BUF_FLAG_CAN_MERGE</code>标志位。随后，攻击者调用<code>splice()</code>将目标可读文件的一段内容以零拷贝的方式切入管道。</p><p>此时漏洞被触发：内核在处理<code>splice()</code>时，相关函数并未清空新分配槽位的<code>flags</code>标志位，导致原先残留的<code>PIPE_BUF_FLAG_CAN_MERGE</code>被错误保留。受此标志位误导，当攻击者继续向管道写入数据时，内核不会分配新的匿名页，而是直接将数据追加到先前引用的文件页缓存中，从而篡改缓存内容。尽管磁盘上的文件内容往往不会改变（参见<a href="https://www.kernel.org/doc/Documentation/filesystems/Locking#:~:text=set_page_dirty()"><code>set_page_dirty()</code></a>），但内核会读取被篡改的页缓存内容，从而受到欺骗。</p><p>另一方面，该漏洞不仅能在攻击者无写入权限的情况下生效，甚至还可以篡改不可变文件、只读的Btrfs快照以及只读挂载点（如 CD-ROM）中的文件内容。这是因为页缓存始终是可写的，而在写入管道后，内核不会校验后端存储的文件系统权限。</p><p>不过，该漏洞也有一定局限性。首先，攻击者无法从页边界写入数据：若<code>splice()</code>中长度设为<code>0</code>以试图从偏移量<code>0</code>处开始追加，则该操作将被内核短路返回，导致映射失败；其次，攻击者无法跨越页边界连续写入：单个管道槽位的映射容量被严格限制在单一物理页之内，溢出的数据会被写入新申请的匿名页中；最后，攻击者无法突破文件大小的约束：内核并不会更新该文件Inode中的元数据，后续数据虽在页缓存里，但由于超出文件大小，读取时会被内核忽略。</p><h3 id="复现">复现</h3><p><a href="https://web.archive.org/web/20220318223923/http://packetstormsecurity.com/files/166229/Dirty-Pipe-Linux-Privilege-Escalation.html">该网站</a>提供了漏洞的PoC。其流程与上方描述一致，此处不再赘述。</p><p>为了避免污染宿主机，我使用Vagrant搭建虚拟机环境，并采用Libvirt作为后端。虚拟机中使用Metarget构建环境。对于该漏洞，使用Ubuntu 20.04可以搭建相关环境。部署完环境后，验证内核版本确实在受影响范围内：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">uname</span> -r</span></span><br><span class="line">5.8.0-23-generic</span><br></pre></td></tr></table></figure><p><img src="/2026/04/11/CVE-2022-0847-Notes/Screenshot_20260411_201916.avif" alt="靶机的内核版本"></p><p>为了直观地演示越权覆盖，我创建了由root拥有，且普通用户仅有读取权限、无写入权限的测试文件：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> sh -c <span class="string">&#x27;echo &quot;This file belongs to root, you cannot modify it.&quot; &gt; /tmp/target.txt&#x27;</span></span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> <span class="built_in">chmod</span> 644 /tmp/target.txt</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">ls</span> -l /tmp/target.txt</span></span><br><span class="line">-rw-r--r-- 1 root root 49 Apr 11 12:20 /tmp/target.txt</span><br></pre></td></tr></table></figure><p>此时，若尝试以普通用户（<code>vagrant</code>）的身份修改它，会被操作系统拒绝：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="string">&quot;test&quot;</span> &gt; /tmp/target.txt</span></span><br><span class="line">-bash: /tmp/target.txt: Permission denied</span><br></pre></td></tr></table></figure><p><img src="/2026/04/11/CVE-2022-0847-Notes/Screenshot_20260411_202023.avif" alt="尝试修改受保护的文件"></p><p>考虑到C标准库版本可能不一致的问题，我在靶机内部编译了PoC代码。该PoC的限制之一是不能从页边界写入，因此我设置偏移量为5（即「This 」之后），写入的Payload为<code>tomorin_was_here: MyGO!!!!!</code>：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">./shared_code/CVE-2022-0847/poc/exploit /tmp/target.txt 5 <span class="string">&#x27;tomorin_was_here: MyGO!!!!!&#x27;</span></span></span><br><span class="line">It worked!</span><br></pre></td></tr></table></figure><p>再次查看该文件的内容，会发现内容已经被篡改，原本受保护的内容被强行注入了「MyGO!!!!!」的印记：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> /tmp/target.txt</span></span><br><span class="line">This tomorin_was_here: MyGO!!!!!annot modify it.</span><br></pre></td></tr></table></figure><p><img src="/2026/04/11/CVE-2022-0847-Notes/Screenshot_20260411_202055.avif" alt="受保护的文件被篡改"></p><p>据此思路，只需将目标文件替换为系统的关键文件（如<code>/etc/passwd</code>），攻击者即可实现真正的提权攻击。</p><h2 id="修复与后续">修复与后续</h2><p>漏洞发现者Max Kellermann于<a href="https://lore.kernel.org/lkml/20220221100313.1504449-1-max.kellermann@ionos.com/">该patch</a>中修复了该漏洞，即在处理<code>splice()</code>的函数中，显式清空新分配槽位的<code>flags</code>标志位。</p><p><a href="https://dirtypipe.cm4all.com/">漏洞发现者的博文</a>也值得一读，他从发现服务器上的文件意外损坏开始，总结时间规律，编写测试程序锁定内核问题，最后阅读代码定位漏洞。这种排查思路对我颇具启发。</p><p>尽管排查过程如此硬核，但这个漏洞的根因极其低级：在复用<code>pipe_buffer</code>结构体时，开发者采用逐字段赋值的方式，却忘记重置<code>flags</code>字段，导致旧状态残留。因此我认为，在该情况下，采用结构体整体赋值（如<code>*buf = (struct pipe_buffer)&#123; ... &#125;</code>以触发隐式初始化，参见《<a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf">ISO/IEC 9899:2011 (C11)</a>》 § 6.7.9 Initialization, ¶ 21），抑或是在语言层面引入更严格的状态流转机制，即可避免此种问题发生。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/04/11/CVE-2022-0847-Notes/</id>
    <link href="https://blog.deepchirp.com/2026/04/11/CVE-2022-0847-Notes/"/>
    <published>2026-04-11T13:44:54.000Z</published>
    <summary>本文从Linux页缓存、管道缓冲及`splice()`零拷贝机制切入，简单分析了CVE-2022-0847（Dirty Pipe）本地提权漏洞的越权篡改逻辑。</summary>
    <title>CVE-2022-0847浅析</title>
    <updated>2026-04-11T13:44:54.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="操作系统" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    <category term="Linux" scheme="https://blog.deepchirp.com/tags/Linux/"/>
    <category term="CVE" scheme="https://blog.deepchirp.com/tags/CVE/"/>
    <category term="Docker" scheme="https://blog.deepchirp.com/tags/Docker/"/>
    <category term="容器安全" scheme="https://blog.deepchirp.com/tags/%E5%AE%B9%E5%99%A8%E5%AE%89%E5%85%A8/"/>
    <category term="runc" scheme="https://blog.deepchirp.com/tags/runc/"/>
    <content>
      <![CDATA[<!-- markdownlint-disable commands-show-output --><div class="note primary flat"><p>本文的封面图来源于<a href="https://x.com/bang_dream_gbp">bang_dream_gbp</a>在<a href="https://x.com/bang_dream_gbp/status/1702301623442403588">X（前Twitter）上的推文</a>，版权归原作者所有。</p></div><h2 id="背景">背景</h2><h3 id="容器架构">容器架构</h3><p>Docker等容器采用分层架构，大致可以分为三层：</p><ol><li><strong>dockerd（API层）</strong>：处理高层逻辑。负责镜像管理、网络分配及存储卷挂载。</li><li><strong>containerd（管理层）</strong>：容器生命周期守护进程。负责拉取镜像、利用OverlayFS准备根文件系统（rootfs），并调用底层的运行时。</li><li><strong>runc（执行层）</strong>：OCI标准运行时。它是宿主机上的一个轻量级二进制文件（<code>runc</code>，对于Docker而言为<code>docker-runc</code>），通过<code>clone</code>、<code>pivot_root</code>等系统调用配置Namespace、Cgroups等，创建隔离环境，并最终在隔离区内执行目标命令。<strong>每当执行<code>docker exec</code>时，宿主机会启动一个新的<code>runc</code>实例进入已有的隔离空间。</strong></li></ol><p>（关于更多内容，参见《<a href="https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/">Journey From Containerization To Orchestration And Beyond</a>》）</p><h3 id="ETXTBSY">ETXTBSY</h3><p>根据<a href="https://pubs.opengroup.org/onlinepubs/9799919799/">POSIX标准</a>（IEEE Std 1003.1）：</p><blockquote><p>[ETXTBSY]The file is a pure procedure (shared text) file that is being executed and <em>oflag</em> is O_WRONLY or O_RDWR.</p></blockquote><p>如果二进制文件正在被进程执行，那么无法以写入模式（<code>O_WRONLY</code>或<code>O_RDWR</code>）打开并修改它。 内核会直接抛出<code>ETXTBSY</code>错误。</p><p><code>runc</code>是沟通宿主机和容器的桥梁。当其进入容器命名空间执行指令时，<code>runc</code>本身会暴露在容器的视角中。但在正常逻辑中，内核的<code>ETXTBSY</code>机制会禁止任何进程修改正在运行的二进制镜像，这能够防止容器内进程对宿主机实体的反向篡改。</p><h2 id="攻击流程">攻击流程</h2><p>简而言之，旧版本的<code>runc</code>在容器内重新执行自身时，意外暴露了宿主机可执行文件在物理层面的写入路径。<a href="https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html">Dragon Sector</a>指出了该漏洞的攻击流程：</p><ol><li>攻击者在容器内，把某个常用命令（如<code>/bin/sh</code>）替换成符号链接，直接指向<code>/proc/self/exe</code>。</li><li>宿主机的管理员执行<code>docker exec -it &lt;Container ID&gt; /bin/sh</code>。宿主机上的<code>/usr/bin/runc</code>进程启动，配置好Namespace等隔离机制后，进入容器内部。</li><li><code>runc</code>执行容器中的<code>/bin/sh</code>，顺着软链接执行<code>/proc/self/exe</code>，即重新执行了自己一次。</li><li>此时<code>runc</code>已处于容器的文件系统中，因此会加载容器内部相应的动态链接库。而攻击者已将容器里相关的链接库替换，其带有恶意全局构造函数，会在<code>runc</code>的<code>main</code>函数之前运行。</li><li>恶意代码先以只读模式（<code>O_RDONLY</code>）打开<code>/proc/self/exe</code>，拿到其文件描述符后，启动另一个独立的恶意脚本，并向之传递文件描述符。</li><li>当原本的<code>runc</code>进程退出后，独立运行的恶意脚本可以以写入模式（<code>O_WRONLY</code>）重新打开它，并将之覆写为恶意程序。只要宿主机再调用<code>runc</code>，恶意代码就会在宿主机执行。</li></ol><p>他们还提到，也可以不采用替换动态链接库的方式。当<code>runc</code>调用<code>execve</code>系统调用，去执行<code>#!/proc/self/exe</code>时，其<code>dumpable</code>标志位被重置为<code>1</code>。这意味着其他进程可以读取该进程的信息。因此，攻击者可以在容器中执行恶意程序，判断<code>/proc/&lt;runc PID&gt;/exe</code>是否可访问；当其可访问时，可将之打开，拿到指向宿主机<code>/usr/bin/runc</code>的文件描述符，随后不断尝试写入。下面的复现流程即采用该方法。</p><h3 id="复现">复现</h3><p><a href="https://github.com/Frichetten/CVE-2019-5736-PoC">该仓库</a>提供了漏洞的PoC。其首先覆写了<code>/bin/sh</code>文件，然后不断查找<code>runc</code>对应的PID，最终尝试将恶意代码写入该文件。考虑到演示效果，若攻破宿主机，则会在<code>/tmp</code>中创建<code>tomorin_was_here</code>文件，并写入内容<code>MyGO!!!!!</code>。为避免链接库版本差异而带来的问题，我采用静态编译（即传入<code>CGO_ENABLED=0</code>）。</p><p>为了避免污染宿主机，我使用Vagrant搭建虚拟机环境，并采用Libvirt作为后端。虚拟机中使用Metarget构建环境。对于该漏洞，使用Ubuntu 18.04可以搭建相关环境。</p><p>首先创建后台运行的普通容器，名为victim：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker run -d --name victim ubuntu:18.04 <span class="built_in">sleep</span> infinity</span></span><br></pre></td></tr></table></figure><p>随后将生成的二进制文件复制到该容器中，并执行：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker <span class="built_in">cp</span> /home/vagrant/shared_code/CVE-2019-5736/poc/exploit victim:/exploit</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker <span class="built_in">exec</span> -it victim /bin/bash</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash"><span class="built_in">chmod</span> +x /exploit</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">./exploit</span></span><br></pre></td></tr></table></figure><p><img src="/2026/04/04/CVE-2019-5736-Notes/Screenshot_20260404_125456.avif" alt="创建被污染的容器"></p><p>该容器中的<code>/bin/sh</code>即被替换成了指向<code>/proc/self/exe</code>的软链接，该容器已被污染。</p><p>当管理员尝试打开该容器时：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">sudo</span> docker <span class="built_in">exec</span> -it victim /bin/sh</span></span><br></pre></td></tr></table></figure><p>可以看到容器中的恶意程序旋即打开了宿主机上的<code>/usr/bin/docker-runc</code>，并将其覆写为恶意程序。同时<code>containerd</code>可能是为了清理残留状态，再次调用了<code>runc</code>，恶意代码得以执行。因此可以观察到<code>/tmp/tomorin_was_here</code>文件被创建，并写入了<code>MyGO!!!!!</code>：</p><figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">ls</span> -l /tmp/tomorin_was_here</span></span><br><span class="line">-rw-r--r-- 1 root root 10 Apr  4 04:55 /tmp/tomorin_was_here</span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> /tmp/tomorin_was_here</span></span><br><span class="line">MyGO!!!!!</span><br></pre></td></tr></table></figure><p><img src="/2026/04/04/CVE-2019-5736-Notes/Screenshot_20260404_125832.avif" alt="访问容器后宿主机被攻破"></p><h2 id="修复与后续">修复与后续</h2><p><code>runc</code>于<a href="https://github.com/opencontainers/runc/commit/0a8e4117e7f715d5fbeef398405813ce8e88558b">该commit</a>中修复了该漏洞。其核心是通过<code>memfd_create</code>系统调用切断容器到物理文件的连接。</p><p>修复后的<code>runc</code>在进入容器前，会在内存中创建独立的匿名文件，将自身的二进制代码拷贝至此，并执行<a href="https://lwn.net/Articles/593918/">密封操作</a>。随后，程序转为执行该内存副本。即使容器内进程通过<code>/proc/self/exe</code>等方式获取到<code>fd</code>，也无法触及宿主机的<code>/usr/bin/runc</code>物理文件。此外，由于内存中的可执行文件被密封，因此也不会遭到修改。</p><p>LXC开发者Christian Brauner在其<a href="https://brauner.io/2019/02/12/privileged-containers.html">博文</a>中批评了包括Docker在内的特权容器，称这种容器内部的root（UID 0）等同于宿主机的root，因此是「不安全的组件」，无法实现所谓的「root安全性」（即即便容器里的用户获得了root权限，也无法对宿主机安全构成威胁）。因此，他极力倡导将非特权容器作为默认标准。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/04/04/CVE-2019-5736-Notes/</id>
    <link href="https://blog.deepchirp.com/2026/04/04/CVE-2019-5736-Notes/"/>
    <published>2026-04-04T06:18:21.000Z</published>
    <summary>本文从Docker容器架构及Linux的ETXTBSY机制切入，简单分析了CVE-2019-5736容器逃逸漏洞的触发逻辑，探讨了修复方案及特权容器的安全缺陷。</summary>
    <title>CVE-2019-5736浅析</title>
    <updated>2026-04-04T06:18:21.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E7%94%9F%E6%B4%BB/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/tags/%E7%94%9F%E6%B4%BB/"/>
    <category term="友人帐" scheme="https://blog.deepchirp.com/tags/%E5%8F%8B%E4%BA%BA%E5%B8%90/"/>
    <category term="寓言" scheme="https://blog.deepchirp.com/tags/%E5%AF%93%E8%A8%80/"/>
    <category term="随笔" scheme="https://blog.deepchirp.com/tags/%E9%9A%8F%E7%AC%94/"/>
    <content>
      <![CDATA[<div class="note info flat"><p>封面图来自<a href="https://commons.wikimedia.org/wiki/File%3AUnfinished_concrete_building_-_panoramio.jpg">维基共享资源</a>，原作者为<a href="https://web.archive.org/web/20161012115009/http://www.panoramio.com/user/2420637?with_photo_id=15723148">macrolepis</a>，使用<a href="https://creativecommons.org/licenses/by/3.0/">CC BY-SA 3.0</a>许可。</p></div><p>一群人想建一栋房子，他们是一个承包商、两个建筑师和三个工人。为什么要建呢？不是因为要住进去，而是为了参加「全镇建筑创新建造大赛」并拿个奖：要是拿到了，承包商能借此揽下更多建房项目，建筑师能借此接到更大的活，工人能借此证明有晋升建筑师的能力，当然大家也都有了自豪和吹嘘的资本。</p><p>万事开头难。承包商一人决定「咱们参加7层以下楼房分赛道！对手少、好拿奖！」但建筑师A专做地下室，这一看比的是楼房，肯定干不了，找他议论。承包商说，我知道你不能做，但是规则规定，必须有两个建筑师交叉验证计算，确保安全可靠，你就挂个名，拿了奖算你一份！建筑师A同意，搞自己的活路了。万幸，建筑师B是专做楼房的，尽管他刚学会。三个工人听不懂这些门道，被承包商雇了等着干活。</p><p>承包商手上的项目太多了，定下这事后，画了个可大可小的圈，表示楼房的建筑范围，便转头忙他的去了。这一忙就是半年，建筑师B不熟练，也不着急，慢慢画他的建筑设计图。倒是工人们不耐烦了，离初赛就剩三个月，什么时候开工？</p><p>万事推进难。建筑师B掐指一算，认真画完图是肯定来不及了。但还有一计，楼房搭个主体结构起来，使劲在外墙糊颜料，糊得花里胡哨，也算得创新嘛；现在的人都这样干，你们照葫芦画瓢。工人们面面相觑，「想不想当建筑师？」「想不想晋升？」「我们干。」</p><p>不久，主体结构勉强搭好了，但糊墙是个费劲的活：但凡颜料没干透时下个雨，得擦掉重画；但凡建筑师觉得颜料涂太多太重、外墙会塌，得擦掉另画；但凡路过的承包商指点江山，也得擦掉重画。真费劲，工人们想，但是最迟明年就得升职，不然非升即走，要下海喂鱼的哟！因此他们态度最积极。</p><p>到初赛那天，工人们选出代表上去给评委介绍，「本楼房的创新点是基于多元色彩一体化装裱技术在动态外立面的稳定长期外观修饰上取得进展，切实解决了城镇建筑群美学欣赏中突出点不显著问题……」有个评委先盯着代表看，又盯着外墙看——打了高分；有个评委提了改进意见，要拉高创新点和外墙图案的相关度——打了高分；有个评委低着头，一声没吭——打了低分。</p><p>工人们不服，为什么打低分？但他们不敢找评委议论，毕竟一身臭汗，凑近了就得挨骂。可能是那评委相较于纯黑的黑色更喜欢五彩斑斓的黑色吧，谁知道呢？不过好歹拿了四等奖，工人们不再计较了。建筑师B拿它练手，没什么好计较的。承包商另一个赛道的楼房项目拿了初赛一等奖，妥妥进决赛，懒得计较了。</p><p>万事收尾难。初赛后一个月，吹来一阵2.5级大风，楼房塌了；工人的工资也塌了，他们不敢计较。唯一计较的人是建筑师A，因为他一里开外的地下室被塌倒的楼房震垮了。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/03/28/A-Fable-Papering-the-House/</id>
    <link href="https://blog.deepchirp.com/2026/03/28/A-Fable-Papering-the-House/"/>
    <published>2026-03-28T04:13:43.000Z</published>
    <summary>本文是一则荒诞现实主义风格的寓言，以建楼房为隐喻，讽刺科研竞赛项目中包装粉饰的草台班子现象，从真实事件改编而来。</summary>
    <title>寓言：糊房子</title>
    <updated>2026-03-28T04:13:43.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E7%94%9F%E6%B4%BB/"/>
    <category term="北航" scheme="https://blog.deepchirp.com/tags/%E5%8C%97%E8%88%AA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/tags/%E7%94%9F%E6%B4%BB/"/>
    <category term="随笔" scheme="https://blog.deepchirp.com/tags/%E9%9A%8F%E7%AC%94/"/>
    <category term="日常" scheme="https://blog.deepchirp.com/tags/%E6%97%A5%E5%B8%B8/"/>
    <content>
      <![CDATA[<p>接近寒假时，我进了项目组；开学后顺理成章得到了新工位。本以为只是换了个地方，却发现生活发生了一系列意想不到的连锁反应。</p><h2 id="空间的扩容">空间的扩容</h2><p>先前大多时候我都在寝室里学习，偶尔去图书馆。虽然室友非常体谅人，每天晚上都是十二点不到就熄灯；然而，每个人作息习惯不同，白天的时间安排各异。例如，有位室友晚上会失眠，靠近中午才起床；还有的室友习惯睡午觉。写代码或钻研技术原本就需要高度专注，在寝室里为了顾及他人又要小心翼翼，这进一步加剧了心理内耗。此外，寝室空间狭小，根本没法放太多东西。从沙河搬到学院路之后，空间进一步遭到压缩。现状如此，我无力改变。</p><p>而当我搬到工位后，便不用担心这些问题了。一方面，工位的空间更大，甚至还配有独属的柜子，能够容纳更多的物品和设备；另一方面，这里大多数时候仅有我一人，偶尔还会有位师姐。我一直觉得，学校里很难找到真正的「独属自己的空间」，而工位从很大程度上弥补了这一遗憾。在这里，我终于可以毫无心理负担地敲击机械键盘。这种沉浸感是我在寝室、图书馆等公共空间里无法体会到的。硬件方面也有了提升。朋友<a href="https://tsxb.top/">tsxb</a>先前也在这里科研，他留给我的显示屏让我体会到双屏的显著优势：一块屏幕编写代码，一块屏幕查阅文档，不会因来回切换窗口而打断思维。并且，大屏看起来更加细腻、舒适。此外，这里的网络免费且稳定。这些都极大提升了我的学习效率和体验。</p><h2 id="节律的校准">节律的校准</h2><p>当习惯于每天前往工位时，我的生物钟也悄然发生了变化。先前在寝室时——尤其是从<a href="/2025/10/15/From-Diverging-Crossroads-to-Endless-Journey-Reflections-on-the-Shanghai-Concert/" title="从「分歧路口」到「前途漫漫」：上海站观后">上海演唱会</a>回来后，了解自己的困境却无力改变，从而沉入低谷的那段时间——我的作息极其紊乱：每天都心烦意乱，晚上到凌晨两三点才睡着，睡醒后就靠近中午了，自然是不会吃早饭的。那是一种对生活失去掌控的无力感。而现在，我的作息变得极为规律，每晚十点半左右便能抱着高松灯的棉花娃娃安然入睡，第二天早上七点自然醒来，甚至久违地有了去食堂吃一顿早饭的胃口与动力。现在的生物钟就像是稳定的底层系统，为我提供了踏实的支撑，能够全身心地投入到接下来的学习以及长线的考研备考之中。</p><p>而每天从寝室前往工位的五分钟路程，则像是这套底层系统的「启动仪式」。路途中，我会计划今天要做什么。到达工位后，我就能立刻进入状态，专注于学习之中。</p><p>除了宏观作息的规律，工位桌上的一些小物也在无形中重塑着我的微观节律。例如前不久<a href="/2026/03/09/Interweaving-Moment-and-Memory-Yokohama-Report-and-Pilgrimage/" title="「瞬间」交织「记忆」：横滨站观后与圣地巡礼">日本演唱会</a>附赠的马克杯特典，每当我看到它，不由得想到那段美好的经历，因此会倾向于用它喝水。先前在寝室时，我习惯用大水瓶装水，但会觉得自己喝不完，反而不太想喝水了。而马克杯的容量较小，我每隔一段时间便要起身去接水，这对我的身体更好，也给了大脑喘息的空间。</p><h2 id="内心的归属">内心的归属</h2><p>大二时，我跟着另一位导师打工赚钱。虽说有较为可观的报酬，让我有条件去追寻自己喜爱的事物；并且导师还常常称兄道弟，请我们吃了几次饭。但我总觉得像在公司打工，能力没得到什么提升，也没有找到自己的位置。后来导师因为资金不足而撤裁了一半人，其中就包括我。这一度让我陷入了自我怀疑与不服气的矛盾中。前段时间，我才辗转听闻自己被裁掉的原因是导师觉得我「不善于沟通」，并非技术不精。这种通过第三方传达的否定，让我产生了一种强烈的「被用作工具人」的无力感。</p><p>但目前的导师给了我完全不同的反馈。在上了他的「科研课堂」课程后，他仅仅是因为觉得我对Linux比较熟悉、有技术潜力，便邀请我加入项目组。这种对我能力的直接肯定，对我而言是极大的救赎。这就好像高松灯在因为不善言辞而深感自己与世界格格不入时，却有人翻开了她那本满是划痕的笔记本，没有嫌弃她的笨拙，而是发自内心地赞扬她的歌词。目前我还处在学习基础知识、尚未产出实际成果的阶段，导师却愿意分配一个工位。从某种意义上说，这张桌子超越了免费网络和双屏的价值，代表着不带功利性的信任与接纳。现在的我，终于找到了暂时的容身之地。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/03/23/After-Getting-a-Workspace-A-Restarted-Daily-Routine/</id>
    <link href="https://blog.deepchirp.com/2026/03/23/After-Getting-a-Workspace-A-Restarted-Daily-Routine/"/>
    <published>2026-03-23T07:27:46.000Z</published>
    <summary>本文记录了作者获得新工位后生活发生的一系列连锁反应：从物理空间的扩容到作息节律的校准，以及在这个专属的小小角落里，重新找回的内心归属与平静。</summary>
    <title>有了工位之后：重新运转的日常</title>
    <updated>2026-03-23T07:27:46.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E7%94%9F%E6%B4%BB/"/>
    <category term="旅行" scheme="https://blog.deepchirp.com/tags/%E6%97%85%E8%A1%8C/"/>
    <category term="BanG Dream!" scheme="https://blog.deepchirp.com/tags/BanG-Dream/"/>
    <category term="MyGO!!!!!" scheme="https://blog.deepchirp.com/tags/MyGO/"/>
    <category term="Ave Mujica" scheme="https://blog.deepchirp.com/tags/Ave-Mujica/"/>
    <category term="演唱会" scheme="https://blog.deepchirp.com/tags/%E6%BC%94%E5%94%B1%E4%BC%9A/"/>
    <category term="日本" scheme="https://blog.deepchirp.com/tags/%E6%97%A5%E6%9C%AC/"/>
    <category term="圣地巡礼" scheme="https://blog.deepchirp.com/tags/%E5%9C%A3%E5%9C%B0%E5%B7%A1%E7%A4%BC/"/>
    <content>
      <![CDATA[<div class="note info flat"><p>本文部分图片由「小哭败」和「m1saka」提供，亦采用<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>许可。在此表示感谢！</p></div><p>去年<a href="/2025/10/15/From-Diverging-Crossroads-to-Endless-Journey-Reflections-on-the-Shanghai-Concert/" title="从「分歧路口」到「前途漫漫」：上海站观后">前往MyGO!!!!!和Ave Mujica的上海演唱会</a>后，我便对现场演出念念不忘。原本满心期待着后续的国内巡演，但受近期大环境影响<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>，海外艺人来华的演出活动充满变数<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>：例如，同属《BanG Dream!》的乐队Roselia原定于上海的巡演遭取消<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>。悲观来看，上次的演出可能是她们乃至整个企划在中国大陆的最后一舞了，不免让人沮丧。</p><p>既然家门口的舞台暂时拉上了帷幕，那我也只能主动跨越山海，亲自前往日本赴约了。这次MyGO!!!!!和Ave Mujica的演唱会定于3月1日，名为「“moment / memory”」，是她们的第二场联合演唱会（鸡狗对邦）。有趣的是，虽然中国官方时常发布赴日旅游的警告<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>，但境外旅游险依然为日本提供全套保障；相比之下，某些免签的「友好邻邦」却静静地躺在保险公司的战乱免责条款里<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup><sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup>。比起宏大的政治叙事，我更相信保险公司精算师的风险评估。这次除了看MyGO!!!!!和Ave Mujica的演唱会外，我还想去圣地巡礼，实地感受屏幕里的风景。</p><p>上次一起去上海的邦友中，memory这次虽然与我们行程有别，但在订票等方面帮了不少忙：例如他推荐了南航的廉价机票，北京往返羽田仅需1700左右；真正与我一路同行的，是小哭败和m1saka。我们准备2月26日前往，3月3日返回。可惜机票数量有限，小哭败只能晚一天出发。虽然这次行程恰逢2月28日的《BanG Dream!》十周年演唱会，但票价被炒得太高，我们都没打算去看。出发前的一个月内，我们做足了各类功课，例如办理签证、预订住宿、准备银行卡、兑换日元等等。虽然过程繁琐，但想着出国计划越来越近，不免充满兴奋与期待。但对于旅行本身，我们确实没有做详尽的规划，只是大概敲定了去哪些地方。</p><h2 id="Day-0">Day 0</h2><p>飞机将近早上十点起飞。而m1saka住在沙河校区，距离机场有段距离；为了避免国际漫游相关问题，我将电话卡留给了同学，这意味着最好有人与我同行，防止失联。因此，我们决定提前一天在机场附近住宿，为第二天留足时间。酒店位置偏僻，但好在提供接机服务，价格也确实便宜。m1saka先从沙河赶到学院路与我汇合，随后一同前往机场。到了机场后，来接机的是酒店老板，他在省道上甚至开到了一百多码，颠得我有些头晕；后来又拐进了黑灯瞎火的乡间小路，更是让我心里发毛，m1saka也不禁看起导航。好在最后总算平安抵达。只是，真正让人难以入睡的，并不是这段提心吊胆的车程，而是「明天就要出发」这件事本身。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260226_211015.avif" alt="机场拍摄的爱灯"></p><p>酒店附近没什么饭店，m1saka没吃晚饭，只能买了泡面吃。我玩了一会儿《osu!》，他也玩不少音游：我们本就算是聊得来的同好，只是他这次论文截止日期就在眼前，只能偶尔看我玩。他一边改着论文，一边与我聊天，还顺带推荐了《超时空辉夜姬》，说希望这次也有机会巡礼。虽然先前在上海和观影会也见过面，但像这样长时间地待在同一个房间里聊天，还是头一次。等我们从学业、生活一路聊到杂七杂八的兴趣时，已是凌晨两点半了。m1saka带来的爱音娃娃一直放在旁边，实在是太可爱了，不免让我萌生出抱着睡觉的想法。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260226_213756.avif" alt="爱音和灯的棉花娃娃"></p><h2 id="Day-1">Day 1</h2><p>早上六点半起床后，外面竟下了雪，颇有《静降想》的意蕴；只是这样的天气，也难免让人担心航班会不会受影响。所幸一切都十分顺利，安检、边检都比想象中更快，没多久我们便到了登机口。登机时也碰到了邦友，冲我们会心一笑。飞机上闲来无事，我用地图记录飞行路线，顺便看了看海拔和速度。看着自己从韩国上空飞过，身处未曾到达之地，着实是一番新奇的体验。后来看了会儿邦邦的动画，但没一会儿便感到头晕，只好作罢。m1saka则一直在玩<a href="https://github.com/2394425147/astrodx">《AstroDX》</a>，即<a href="https://zh.wikipedia.org/wiki/Maimai">《舞萌》</a>移动端的模拟器，还邀请我体验一番。飞机上提供了餐食，虽然主食牛肉饭尚可接受，但有道配菜把虾、玉米、土豆混在一起，口感颇为古怪，那几只几乎没什么味道的虾成了我唯一还能接受的部分。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_110148.avif" alt="飞机上的餐食"></p><p>到达日本上空时，尽管我的座位并不靠窗，大半视野也被机翼遮挡，但透过舷窗缝隙，蔚蓝的海岸线依然颇为壮观，这也是我首次从高空俯瞰海洋。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_124618.avif" alt="飞机上拍摄的海洋"></p><p>飞行约三小时后，我们于当地时间下午两点多抵达羽田机场。出关的流程比预想中快，只需在机器上扫描护照，随后将护照交给工作人员，贴上入境章就搞定了，并没有想象中的询问环节。取行李的地方还有条狗，大概是检测有没有携带肉类的。旁边一位小女孩被吓到了，突然抓住我的腿；与此同时，狗趴在我的痛包上，也让我吓了一跳。在站内搞定西瓜卡和流量卡后，我们便坐电车前往民宿。民宿位于蒲田，离羽田机场不远，坐车大约十几分钟就到了。与国内不同，这里的酒店没有前台，像是自助一般，用密码打开储物柜便能拿到钥匙。房间较为狭小，也没有像样的窗户；但设施齐全，甚至还能洗衣做饭，价格也不算贵。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_160109.avif" alt="民宿内景"></p><p>放下行李休整片刻，我们便迫不及待地出门，目的地是下北泽，《孤独摇滚！》的取景地。为了省点钱，同时也为领略当地的风土人情，我们走路去蒲田站坐JR，而不是京急蒲田站。正如之前我在OpenStreetMap上看到的一般，日本的路网比中国大陆密集不少（虽然两地贡献者数量应该也有较大差异），几乎每隔几十米就有道路交汇。开车的人很有礼貌，基本上都会让行人先行。我感受到国内近年来在这点上也有进步。路上经过一座公园，里面有不少小孩在玩耍，欢声笑语中透着浓郁的生活气息。途中还去7-Eleven便利店买了水，商店竟然支持包括微信、支付宝在内的一二十种支付方式，多少让我感叹了一下它的「海纳百川」。</p><p>坐电车时，我们在涩谷站外换乘。m1saka提议，既然都来了，不如就在涩谷转一转，然后再去下北泽。出了车站，便是涩谷的十字路口，我先前一度以为这里是《MyGO!!!!!》动画中某张主视觉图的取景地。这里人多繁华，让我想起南京路步行街；然而，我感觉后者更像是商业街，而涩谷更像是商业圈。m1saka说这里有他收藏的周边店，所以我们便去看了看，但没有多少邦邦的周边，并且即使不含税，价格似乎也比国内更高。之后，我们逛了CD店和GiGO（看起来是抓娃娃的店，<s>绝对不是<a href="https://en.wikipedia.org/wiki/Garbage_in,_garbage_out">garbage in, garbage out</a></s>），就返回车站，前往下北泽了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_171344.avif","alt":"涩谷的十字路口","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_172622.avif","alt":"涩谷的建筑","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_180038.avif","alt":"涩谷的小巷","title":""}]</div>  </div><p>到了下北泽，已经接近六点半了。根据Gemini的推荐，我们去吃了广岛烧。店里有个大铁板，服务员会把在上面做好的菜推到顾客面前。我觉得海鲜的味道还不错，但是吃不惯蔬菜。m1saka说有个服务员长得像立石凛，尤其是瞪大眼睛的正脸简直如出一辙，不愧是女声优痴。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_202450.avif","alt":"下北泽站","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_184556.avif","alt":"下北泽的广岛烧","title":""}]</div>  </div><p>吃完后，我们找到附近的自动贩卖机，买了与邦邦联动的饮料。虽说是在日本买的红茶，但仍然由中国生产，有种出口转内销的意味。此外，售卖形式是我深恶痛绝的抽盲盒，不能自己指定角色，不过不买一罐也说不过去。最后抽中了弦卷心。虽然没抽到灯多少有点遗憾，但本来概率就不高，也只能认了。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_192503.avif" alt="弦卷心的饮料"></p><p>然后便去了《孤独摇滚！》的取景地。「STARRY」的创作原型「SHELTER」自然不必多说。可能是拍照的人太多，「SHELTER」门口的商店还贴上了「禁止在此处拍照」的告示。「SHELTER」的附近便是动画中出镜的自动贩卖机。接着寻到了五人拍摄合影的地点，并顺着街道一路漫步至动画取景的公园中。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_193621.avif","alt":"SHELTER","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_193924.avif","alt":"自动贩卖机","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_194844.avif","alt":"下北泽的街道","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_195903.avif","alt":"五人合影的地方","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260227_201415.avif","alt":"动画中出现的公园","title":""}]</div>  </div><p>逛完后时间已然不早，我们只好放弃巡礼《超时空辉夜姬》的计划，坐车回了民宿。在民宿附近，我们还在便利店里买了雪糕，入口即化、味道不错。回到房间后，m1saka继续对着论文死磕，足见研究生生活之不易。</p><h2 id="Day-2">Day 2</h2><p>今天早上九点多起来，m1saka仍苦于修改论文，于是我先行前往K-Arena横滨，看看邦邦十周年演唱会的盛况。在电车上没什么异样，但在横滨站下车后，周遭的「邦邦浓度」瞬间拉满，许多人都拿着邦邦的周边。即使我不清楚路线，并且身处地下而无法使用导航，但跟着人流走，还是顺利到了会场。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_114447.avif","alt":"K-Arena横滨的大门","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_114618.avif","alt":"LAYER和高松灯的宣传图","title":""}]</div>  </div><p>K-Arena横滨邻近海边，视野开阔，景致颇佳。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_144240.avif" alt="K-Arena横滨附近的风景"></p><p>会场门口能看到不少棉花娃娃和挂满徽章的痛包，算是活动的经典环节了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_114249.avif","alt":"摆娃娃的摊位","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_114540.avif","alt":"摆痛包的摊位","title":""}]</div>  </div><p>在会场外，我顺利从代购那里拿到了高松灯的法被——因为上次网络通贩时没有买到，而我迫切想要一件，于是就只能拜托其他人帮我买了。法被着实精美，背面的灯也很可爱。只是穿上后自己反而看不见，于是我后来和m1saka开玩笑说，不如把法被交换着穿，这样就能看到自己喜欢的角色了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_122745.avif","alt":"未拆封的法被","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_130209.avif","alt":"穿上的法被","title":""}]</div>  </div><p>m1saka修改完论文后也来了。演唱会的场贩及活动在另一处地方，一走过去，便看到了巨大的户山香澄。会场有卖棉花娃娃的，还有扮演成高松灯人偶的工作人员在互动。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_132541.avif","alt":"户山香澄的巨大雕塑","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_132557.avif","alt":"棉花娃娃","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_133655.avif","alt":"扮成高松灯的人偶","title":""}]</div>  </div><p>逛完活动现场后，我们领了整理券，希望等到演唱会开始入场后购买场贩。在此期间，我在旁边的便利店里买了个菓子，权当是午餐了。随后我们又回到K-Arena横滨，看了看入场时的情况，现场的人确实不少，十分热闹。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_142608.avif" alt="m1saka拍摄的爱音"></p><p>等到入场开始时，我们才回到场贩现场。m1saka说，我们的装扮显然像是来看邦邦的，却往反方向走，行为让人迷惑。不过，场贩里确实也没有人了。除了今明两天的演唱会周边外，还有不少先前没卖出去的东西。在这里，我还看到了许多MyGO!!!!!的法被。要是早知道如此，我就不会高价从别人那里买了；但是先前付出的溢价，也算是花钱买了安心吧。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_150716.avif" alt="MyGO!!!!!角色的法被"></p><p>正当我们选购周边时，小哭败也平安落地、到达酒店。酒店配有两把钥匙，其中一把是备用的，我和m1saka让小哭败用备用钥匙开门。我们都觉得两把钥匙的密码应该是一样的，也没有测试，但结果并不是。于是m1saka开始和酒店交涉。酒店电话不知何故，未能打通。所以只能在预订平台上找在线客服。客服的态度起初颇为死板，咬定除非万不得已，否则坚决不提供备用密码。后来在好说歹说下，客服最终还是提供了密码。</p><p>在等待小哭败时，我们在车站附近的商场里逛，碰到マルイシティ横浜关店。商场里人很多，想必是因为闭店促销吧。虽然没什么想买的，我们还是在几家周边店里转了转，算是打发时间。</p><p>小哭败收拾完行李后来到横滨，我们一起去了逗子，即《描绘未来》MV的取景地。下了电车后，我们选择骑车前往。这里能租到的是电动自行车，配有车灯等设备，起步时推背感十足，骑起来非常轻快。相应地，车费比国内贵了不少。但要命的是，日本是靠左通行的，而我潜意识里仍死守着靠右的习惯。在一条狭窄的道路上，我本能地靠右骑行，险些与迎面驶来的汽车撞上，惊魂未定之余，第一反应竟是疑惑对方为何逆行。幸亏对方很有礼貌，及时避让了我。</p><p>来到逗子海岸，邻近黄昏，沙滩上有不少人在玩耍，甚至还有烧烤。由于动画巡礼网站上标注的取景点有偏差，我们骑着车没找到点位，还车后在沙滩上绕了好一会儿才找到。看到了MV中类似于隧道的避难口后，m1saka还模仿MV中的情形，站在桥上扮演爱音拍照。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_180612.avif","alt":"逗子海岸","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_181743.avif","alt":"MV中的避难口","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_181948.avif","alt":"m1saka模仿MV的爱音","title":""}]</div>  </div><p>随后我们一路南下，到达叶山港。路上看到了被用作取景地的路口、叶山町的牌子，以及儿童游乐园。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_182446.avif","alt":"被用作取景地的路口","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_183437.avif","alt":"叶山町的牌子","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_184231.avif","alt":"儿童游乐园_1","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_184443.avif","alt":"儿童游乐园_2","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_184458.avif","alt":"儿童游乐园_3","title":""}]</div>  </div><p>然而，寻找防波堤时我们还是迷了路，怎么都找不到入口。后来根据小红书上其他人的分享，才找到对应的地方；然而，防波堤在晚上已经关闭了，因此我们只能在外面看看。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_190853.avif" alt="叶山港的防波堤门口"></p><p>随后我们骑车前往停车场、巴士站等地看了看，许多细节都能和MV中对应。由于我们还想赶去横滨参加off会，因此并没有去芝崎海岸、一色海岸、叶山公园之类的地方，刚好可以留作下次的巡礼了。另一方面，夜间巡礼的氛围多少有点「阴间」，真想拍得好看，还是得白天来。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_193602.avif","alt":"三角屋根停车场","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_194414.avif","alt":"真名濑巴士站","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_195101.avif","alt":"HAYAMA TOWN GUIDE","title":""}]</div>  </div><p>然后我们骑车回到了逗子站。一路上七拐八拐的，有的路还很窄，骑得我心里发虚。由于我对电动自行车的挡位不够熟悉，爬坡时因挡位不匹配突然发生跳齿，险些连人带车摔倒，着实惊出一身冷汗。</p><p>由于时间问题，我们并未前往K-Arena横滨与群友们拍合照，而是直接去了off会的地点。在等群友时，有两位日本人还用日文请求我给他们拍集体照，而不是m1saka或小哭败；对此，m1saka解释说我长得像是日本人，这个说法实在有些难绷。餐馆菜品的分量确实很大，根本吃不完。旁边也有几桌是邦友，我们的群主还前去「外交」，和他们聊了会儿天。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_223901.avif","alt":"比萨","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260228_223904.avif","alt":"烤肉","title":""}]</div>  </div><h2 id="Day-3">Day 3</h2><p>昨天场贩中，没有看到m1saka心心念念的衣服，所以我和m1saka决定今天早上再去排场贩，中午回酒店休息后，下午前往K-Arena横滨看演唱会。小哭败仍在睡觉，所以便没有喊他。虽然七点多就出发了，但到达场贩后发现已经有不少人在排队了，据称大约要等一个小时。而昨天memory给我发了照片，说秋叶原有高松灯的大棉花娃娃卖，价格比国内要便宜一些。先前在北京和七芬逛街时，我就对它念念不忘，于是我决定单独前往秋叶原将之拿下。</p><p>秋叶原确实非常繁华，人头攒动，街道两旁都是商店。但由于赶时间，所以我不能细细游览，最终只去了两家店：一家是Gamers，其中一层楼专门卖邦邦的周边；另一家是K-BOOKS，memory说那里有卖高松灯的棉花娃娃。Gamers里还有高松灯的塑像，和一款手办的外形一致，但不太符合我的审美，主要是身材比例略显奇怪。Gamers里倒是没什么想买的，随后我便前往K-BOOKS了。除了灯的棉花娃娃，还有爱音和祥子的。与店员交流时，我用了我的「散装英语」，最终还是达到了目的。价格固然不错，但有点遗憾的是，这并不是免税店，否则六百多就能拿下。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_112051.avif","alt":"秋叶原的街道","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_112430.avif","alt":"Gamers店内的高松灯塑像","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_114040.avif","alt":"K-BOOKS店内的棉花娃娃","title":""}]</div>  </div><p>坐车到了蒲田站，准备返回酒店时，m1saka说他的西瓜卡没钱了，而且也没有其他支付手段。因此我再次前往横滨，把纸币给了他。看来结伴出游还是有不少好处的，至少能够相互照应。m1saka看到灯的棉花娃娃后，觉得她的样子不太开心，尤其是与爱音相比较。但我觉得这样呆呆的表情也很可爱。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_141436.avif" alt="高松灯的棉花娃娃"></p><p>下午便是激动人心的演唱会了。我当时为了省钱买了一般席，其他人则冲了S席。世事难料，后来门票价格一路跳水；若把当初的预算放到现在，甚至都够买个位置稍偏的S席了。不过千金难买早知道。没遇上十周年那种一票难求的局面，已算万幸；至于花钱升舱，我也懒得折腾了，主要是先前的票难以卖出。特典是MyGO!!!!!和Ave Mujica的马克杯，黑底、白色人物，设计感十足。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_153742.avif" alt="高松灯的棉花娃娃于K-Arena横滨门口"></p><p>在K-Arena横滨，我们仨还与memory见了面。不过不知何故，他的朋友并不在现场。随后我们便入场。我的座位在LEVEL 5的第三排，虽然距离舞台有点远，但座位靠前，视野还是挺开阔的。演唱会的舞台设计相较于上海梅奔的四面台更为出色，至少视角是固定的。舞台设有一个大屏幕，两侧还有小屏幕。不过从我的视角来看，部分大屏幕被遮挡。我的旁边以日本人居多，但m1saka说前排的S席基本上都是中国人。大概也是因为难得来一次，很多中国人都更愿意买更好的座位。与国内不同，这里即使在开场前也不允许拍照，只能在演出结束后拍照。另一方面，这里也没有像上海一样发荧光棒。虽然我带了两根，但借给了小哭败一根，感觉一根打起来应该没有两根过瘾。此外，现场的声音效果实属震撼，当给贝斯试音时，我能明显感觉身体传来的震动，这是耳机无法带来的体验。</p><p>等到五点多，会场暗了下来，全场观众不禁欢呼。首先登场的是《BanG Dream!》的两支新乐队「millsage」和「一家Dumb Rock!」，这些都是《Our Notes》中公布的新团，但老实讲此前我并未过多关注。不过，两支乐队的风格都挺显著的：她们似乎都是摇滚风格，后者更偏向于爵士摇滚。另外值得一提的是，「一家Dumb Rock!」采用了双主唱的配置，还是挺新鲜的。除了主唱，两支乐队其他位置的正式成员均未公布，皆由临时的支援乐手代阵。说实话，作为未经预热的观众，初见她们时我确感陌生，但这并未妨碍歌曲带给我听觉冲击。</p><p>两支乐队各献唱一曲后便离场了，此时是五点二十多分。我先前注意到<a href="https://bang-dream.com/wordpress/wp-content/uploads/2026/02/17153810/57a82ceb-142893ad-0eb685cd-eacfb4c0.jpg">演唱会的主视觉图</a>中出现了「17:36」的字样，并了解到这是<a href="https://eco.mtk.nao.ac.jp/koyomi/dni/2026/s1503.html">当天横滨的日落时间</a>，但我没想到这也是Ave Mujica的登场时间。这种设计颇具巧思，恰与Ave Mujica的世界观相契合。不过间隔时间还是稍长了些，原本被暖起来的气氛也随之冷了下去。</p><p>Ave Mujica的登场极具压迫感。演出伊始，红色幕布低垂，聚光灯依次将成员的剪影投射其上。待全员集结，幕布骤然升起，真容方才显现。场馆外自然天光的彻底消亡，与场馆内人造聚光灯的骤然亮起，完成了一次完美的交接。她们的表演不必多说，放在整个企划里都绝对算得上最专业、也最稳定的那档。她们没有任何互动，十二首曲目如暴风骤雨般倾泻，最终以《Symbol I : 🜂》收尾。即使仅仅是站立打call，我都已感到体力的消耗，更遑论台上始终保持高强度演出的她们。虽然很累，但我也被演出所震撼，完全沉浸于其中。旁边的日本邦友则是戴着手环做着手势，并没有挥荧光棒，动作看起来十分专业。这次场贩的手环似乎还是场控的，可以自动切换颜色。</p><p>然而，相较于Ave Mujica那种严丝合缝的呈现，随后登场的MyGO!!!!!则不免让人揪心。昨天十周年的演唱会上，羊宫妃那的状态似乎不太对，不仅时常喝水，唱功感觉不及平时；而且诠释《影色舞》时，她也没有像往常那样跳舞。网上有人说，她貌似是生病了，喝的实际上是药；不过，我没有找到官方的相关说明。而在今天，羊宫妃那的状态仍旧不佳。我能明显听出她唱得很吃力，甚至有些歌词直接留白，这让我很难不心疼。现场的大屏幕上，《迷星叫》呈现出五彩交织的线条，《回层浮》中深海窒息般的泡泡冉冉升起，与她在舞台上几近声嘶力竭的挣扎形成了强烈的对照。就我个人的现场感受而言，这段演出只能勉强算作及格；但正因为她们并不完美，我反而更能沉浸其中。那种几乎带着裂痕硬撑到最后的感觉，不恰恰是对MyGO!!!!!「迷子」精神最生动的诠释吗？</p><p>MyGO!!!!!离场后，屏幕上便开始播放宣传图和视频：包括今晚发布新乐队以及MyGO!!!!!的新歌、《Our Notes》的PV（虽然中午就被官方偷跑了），以及明年1月全新TV动画的消息。紧接着，屏幕上出现了这次演唱会的logo，随即突然放了彩带，便宣告演唱会结束。这突如其来的收尾，着实让我错愕：既没有像样的MC，也没有现场互动，甚至没有安可环节；成员演出结束后匆匆离场，没有告别。回想起先前的访谈中，两队成员都被问到过「想翻唱对方哪首歌曲」<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup><sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup>，所以我还期望这次会有翻唱环节，现在看来是我的想象力太丰富了。总结来说，我确实略感失望，先不论MyGO!!!!!成员当时的身体状态，单就演出编排而言，也完全可以做得更好。即使是羊宫妃那因病无法继续演出，那最起码也不能删去谢幕环节，此外也可以让Ave Mujica来个安可或是MC。如今这样的编排，让我原本高涨的情绪一下子失去了落点。但换个角度想，这或许就是现场演出的魅力吧，你永远不知道等待你的是超常发挥的神级现场，还是充满遗憾的戛然而止。这次的不完美，反而让我对下次相遇产生了期待。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_193102.avif","alt":"离场时场内的情景","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_193901.avif","alt":"离场时场外的情景","title":""}]</div>  </div><p>与m1saka和memory会面后，我才意识到现场还有粉丝花篮，此前我只看到了其他公司送的花篮，觉得有些单调乏味。但离场时人流密集，不可能再去欣赏粉丝花篮了，只能借助他们拍摄的照片来感受。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_160738.avif","alt":"花篮_1","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_160849.avif","alt":"花篮_2","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_160919.avif","alt":"花篮_3","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_160929.avif","alt":"花篮_4","title":""}]</div>  </div><p>离场后，memory匆匆告别，我们决定去吃寿司郎。就在前不久，我和七芬在北京吃了滨寿司。m1saka说寿司郎比滨寿司更好吃。有点黑色幽默的是，恰巧也是这天，北京有顾客在寿司郎中吃出了疑似寄生虫卵的东西<sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup>。由于会场附近的店里人太多了，我们便步行到神奈川站附近的店。一路上我们都在讨论这次演唱会的感受，他们的看法也和我相仿，觉得这场演唱会的编排是大问题，不如上次上海的演唱会。我们在寿司郎大吃特吃，味道确实不错，但单盘的分量偏少。不过这样反而更容易控制食量，恰到好处的饱腹感让我感觉很舒服。他们觉得其中的鱼非常腥，但我却觉得还好，所以他们戏称我为「小猫」。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260301_220508.avif" alt="吃尽的餐盘"></p><h2 id="Day-4">Day 4</h2><p>今天是我们三人唯一可以一整天自由行动的日子。因此，我们决定去邦邦相关的地方巡礼，许多取景点都在新宿。然而，由于行程安排变更的缘故，我们的酒店少预订了一天，今晚还得另寻出路。所以，我们把行李放到了memory的住处，并在附近吃了午饭。在穿梭于居民区小巷的途中，我注意到一个挺有意思的现象：日本的街道基本上没有公共绿化，只能偶尔在私人院落中看到零星的绿植；同时，每栋房屋的设计都各具特色，相较之下，国内一些村镇的自建房，在观感上往往显得千篇一律。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_105442.avif","alt":"日本的街道","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_114157.avif","alt":"午饭的牛丼","title":""}]</div>  </div><p>随后乘上电车。路途中，小哭败甚至还在处理工作，出来旅游都没法彻底放松，多少有些无奈。到达<a href="https://zh.wikipedia.org/wiki/%E7%A5%9E%E6%A8%82%E5%9D%82%E7%AB%99">神乐坂站</a>后，我们径直前往商店街，其中有山吹面包店的原型。店主显然知道自己的店是动画取景地，店里摆放着不少邦邦的东西，店员还会不时拍摄我们带来的棉花娃娃；最神的还是「梅奔↔横K」的横幅，应该是中国人贴的。店内，我们还遇到了其他邦邦人，好像来自中科大。m1saka笑称，店老板大概只要看看客流情况，就能判断最近是不是又有邦邦的演唱会了。拍了几张照后，我们自然也是买了点面包。巧克力螺卖完了，我选的面包又干又咸，确实吃不习惯。店门口遇到了另一位邦友，带着乐奈，背着「何意味」的包，拖着行李箱，一看就知道是中国人。m1saka冲他打了招呼。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_135828.avif","alt":"マメココロ​@​江戸川​橋，据称可能是羽泽咖啡店的原型","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_140258.avif","alt":"サンエトワール地蔵通り店，为山吹面包店的原型","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_140343.avif","alt":"面包店内景","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_140735.avif","alt":"爱音和灯","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_140931.avif","alt":"香澄和灯","title":""}]</div>  </div><p>告别了满是同好气息的商店街，顺着导航的指引一路向前，江户川公园便映入眼帘。在这里，我们再次偶遇了刚刚打过招呼的邦友「阡鎏」，他自称目前在广州上班。和我们一样，他看的第一场演唱会也是上次上海的鸡狗对邦。江户川公园内还有早樱，虽然只有一棵，但也还算不错。打卡完江户川公园的滑梯与秋千，我们继续沿着神田川寻迹，向「流星堂」的原型——永青文库走去。在攀爬极其陡峭的胸突坂时，我们注意到栏杆上竟然还有残存的动画贴纸，仿佛是前人留下的巡礼路标。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_142433.avif","alt":"江户川公园的早樱","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_143504.avif","alt":"江户川公园的滑梯","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_144108.avif","alt":"江户川公园的秋千","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_144927.avif","alt":"胸突坂","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_145252.avif","alt":"胸突坂栏杆上的动画贴纸","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_145017.avif","alt":"神田川","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_145715.avif","alt":"永青文库","title":""}]</div>  </div><p>从胸突坂行至高处再折向西边，便是被视为羽丘女子学园原型的日本女子大学。或许是现实与动画视角的差异，建筑的外观并未给我带来太强烈的既视感。匆匆拍了几张照后，我们又转去寻找富士见坂——动画里爽世追着祥子跑过的那段坡道。阡鎏说他先前已然看过千登世桥、高松灯家等地，今天想去看看学习院大学，即被视作月之森女子学园原型之地；但这与我们的路线不符，并且时间也不允许。我们便分道扬镳了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_150321.avif","alt":"目白台三丁目","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_151442.avif","alt":"日本女子大学","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_152110.avif","alt":"富士见坂","title":""}]</div>  </div><p>顺着这片高低起伏的街区继续前行，便是のぞき坂，为《路人女主的养成方法》的取景地。小哭败希望去看一看，我和m1saka则在坡上等着。因为这个坡实在是太陡了，刚刚爬的胸突坂已然消耗了很多体力，我不想再体验一次。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_153100.avif" alt="のぞき坂"></p><p>距此不远是千登世小桥以及千登世桥。不过这里目前在施工，也没有绿植，和动画中的景象相去甚远。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_154707.avif","alt":"千登世小桥向南望去","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_154854.avif","alt":"灯于千登世小桥上","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_155354.avif","alt":"千登世桥向南望去","title":""}]</div>  </div><p>下了桥，没走多长时间便到达了千登世步道桥。但不知何故，天桥上的护栏被修得很高，以至于无法拍出动画中那种感觉了。m1saka见状打趣说，怕不是有哪位邦友在这儿拍照，不小心把棉花娃娃掉到了底下的车道上阻碍了交通，才逼得官方加高了护栏。</p><p>再向北走一小段，能看到据称是高松灯家原型的高楼，不过与动画中紧挨着步道的设定略有出入。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_160034.avif","alt":"千登世步道桥","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_160143.avif","alt":"千登世步道桥向北望去","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_160511.avif","alt":"疑似高松灯家的原型","title":""}]</div>  </div><p>沿着灯的日常轨迹继续寻觅，我们来到了鬼子母神前停留场——即动画中爽世无视灯那一幕发生的地方。途经的鬼子母神堂虽然并未引起我们太多兴趣，但也算顺手补全了这片区域的巡礼拼图。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_161018.avif","alt":"鬼子母神堂","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_161734.avif","alt":"鬼子母神前停留场","title":""}]</div>  </div><p>顺着铁路线向北行进，便到达了南池袋第二公园。动画的ED部分中，这里的滑梯和沙坑均有出镜。在这种「景区」中，自然是能遇到同好的。有个邦友还为爱音戴上了假面，让人忍俊不禁。沙坑里确实也有动画中的那些玩具，让我有些惊讶。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_162716.avif","alt":"南池袋第二公园的滑梯","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_164053.avif","alt":"南池袋第二公园的沙坑","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_163606.avif","alt":"戴上假面的爱音","title":""}]</div>  </div><p>遇到的几位同好与我们方向不同，告别后我们继续前行，抵达了东池袋的Sunshine City。这里还有动画中出现的水族馆，甚至还有企鹅，但m1saka表示他已经去过了，所以还是没有购票入内。随后m1saka和小哭败去上厕所，让我一个人坐在台阶上<s>cos灯</s>。有趣的是，几位台湾同好凑上来跟我搭话，由于我起初没听清他们在说什么，竟被对方误以为听不懂中文。接着他们便切换成英语，小心翼翼地试探我是Japanese还是Korean。当我用英语利落地回复「Chinese」时，他们脸上写满了不可思议。解开误会后，他们还凑过来撸了撸我手里可爱的灯娃。m1saka和小哭败听闻这件事后，在一旁狂笑，直呼这又一次印证了我「长得像日本人」的设定。在这座台阶上，我们不仅捕捉到了爱音和灯的野生coser，临走时还在角落里发现了一只被人遗忘的灯宝——<s>竟然还真有人敢在现实里无视灯</s>。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_170928.avif","alt":"Sunshine City的台阶","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_171450.avif","alt":"Sunshine City的台阶（侧面）","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_170724.avif","alt":"爱音和灯的角色扮演者","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_172036.avif","alt":"Sunshine City处的爱灯玩偶","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_172244.avif","alt":"被遗忘的灯","title":""}]</div>  </div><p>Sunshine City一旁即为东池袋中央公园，这是动画中爱音逃走后，被灯拉回之地。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_172718.avif","alt":"东池袋中央公园","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_172920.avif","alt":"东池袋中央公园的爱灯","title":""}]</div>  </div><p>离开公园后，我们沿着Sunshine60通一路前行，整体观感有些像国内的商业街。沿途终于见到了被视作live house「RiNG」原型的Mixalive TOKYO，可惜它早已停业。钻进一旁的GiGO游戏厅转了转，机台里躺着MyGO!!!!!的景品娃娃，但碍于对抓娃娃机提不起兴趣便没有尝试。退出来后，我们又在动画中出镜过的「カラオケ館」（KTV）门口打卡留念。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_173730.avif","alt":"Sunshine60通","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_174007.avif","alt":"Mixalive TOKYO","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_174430.avif","alt":"GiGO中MyGO!!!!!的娃娃机","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_180327.avif","alt":"カラオケ館","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_181523.avif","alt":"池袋站门口","title":""}]</div>  </div><p>结束了池袋街头的暴走，我们乘车赶往飞鸟山公园。抵达时夜幕降临，幽暗的灯光完美复刻了动画情景。作为重量级「景点」，公园里自然少不了前来朝圣的邦友，甚至还有人兴奋地练习甩手。我们又遇到了先前于Sunshine City碰到的台湾人，他们也认出了我。m1saka还笑着担保说，我确实是中国人。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_190039.avif","alt":"飞鸟山公园_1","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_190707.avif","alt":"飞鸟山公园_2","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_191830.avif","alt":"飞鸟山公园的儿童城堡","title":""}]</div>  </div><p>夜间巡礼的最后一站，我们杀回了涩谷，参观《BanG Dream!》画师信泽收的个人画展。受限于场地，展览内容并不算丰富，还是以角色插画为主。在场贩区，高松灯的立牌着实让我心动，但由于我们事前没有领到整理券，只能无奈作罢，也算是个小小的遗憾。此外，m1saka发现WEGO中也有MyGO!!!!!联动的衣服，想去购买，但店面已然打烊，所以只能放弃了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_201746.avif","alt":"信泽收展上的绘画","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_201901.avif","alt":"信泽收展的高松灯","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_201942.avif","alt":"信泽收展的千早爱音","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_202501.avif","alt":"信泽收展的场贩","title":""}]</div>  </div><p>走出画展，饥肠辘辘的我们急需解决晚饭。循着网上的高分评价，我们在附近找到了一家主打肉类的自助餐厅。刚坐下来，旁边的人就看着我们笑，不用想就知道肯定是邦友。我觉得肉味道不错，非常新鲜，尤其是蘸着生鸡蛋吃，别有一番风味。但我打蛋的技术很差，两次都把鸡蛋壳混了进去。餐馆的价格不菲，每个人花了三百多。不过m1saka说，既然都已经出来旅游了，就没必要在意这点花销。话虽如此，我还是得考虑之后可能还有赴日计划，毕竟消费也得讲究「可持续发展」🐶。</p><p><img src="https://image.deepchirp.com/blog/2026/03/09/IMG_20260302_214844.avif" alt="自助餐厅的肉"></p><p>吃饱喝足后，今晚可能流落街头的危机被提上日程。虽然去KTV凑合一晚也不是不行，但即使用学生证打折后，价格也不算美丽。幸运的是，小哭败找到了位于横滨的廉价酒店，一晚仅需两百多。搞定落脚点后，小哭败提议去药妆店买点东西带回去。就在他们在商场里扫货时，我自己的服务器又出了问题——SSL证书竟然过期了。虽然之前配好了自动续期的<code>timer</code>，却因未能继承环境变量导致配置读取失败。手机上排查问题堪称折磨，尤其是在网页版的VNC中，连特殊按键都传不进去，这意味着包括<code>nano</code>在内的交互式编辑器无法使用。面对琳琅满目的商品，我瞬间兴致全无，只能如游魂般默默跟着他们，满脑子都在疯狂排查环境配置。好在一番折腾后终于化险为夷。警报解除后，我才安心坐上前往横滨的电车。只不过，经过刚才那场极限的移动端运维，我的精力已被彻底榨干，困乏交加，几近断片。</p><p>神奇的是，抵达酒店后，我竟又满血复活了。m1saka和小哭败还打趣说，就知道我会这样。m1saka终于搞定了自己的论文，准备投稿了。毕竟是旅行的最后一晚，我们一直聊天。直到凌晨三点半，在m1saka的最后通牒下，我们才不情不愿地睡去。</p><h2 id="Day-5">Day 5</h2><p>今天下午便要回国，而且为保险起见，还得提前几个小时到达机场，留给我们的时间并不多。上午，memory将我们的行李都留在了酒店，并且计划和朋友一起前往川崎，简单看看《少女乐队的呐喊》的取景地。我们一拍即合，决定与他们同行。</p><p>我们首先去了动画中的吉野家。经过装修，店面已经焕然一新，不论是外观还是内部结构，和动画中的样子都已经完全不同了。不过，店内还保留着相关元素。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260303_110343.avif","alt":"吉野家","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260303_112335.avif","alt":"吉野家内部","title":""}]</div>  </div><p>吃完饭后，我们又赶往川崎站东口，这是动画里桃香和仁菜首次见面的地方。此外，我们还途经了她们某次演出时所在的露天舞台。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260303_114622.avif","alt":"露天舞台","title":""},{"url":"https://image.deepchirp.com/blog/2026/03/09/IMG_20260303_115900.avif","alt":"川崎站东口","title":""}]</div>  </div><p>由于时间有限，并且《少女乐队的呐喊》也不是我们的重点，所以我们返回memory的住处，拿上行李后便前往机场、登上飞机。回国的飞机上倒没有多少中国人，可能是因为邦友大多选择前两天就回国了吧。过海关时，memory买的小日向美香的写真集还被查了一通。刚下飞机时，还遵循着日本的习惯，例如电梯靠左站着，让人哭笑不得。随后坐上熟悉的地铁，回到了学校。</p><hr><p>我和memory坐在大运村的凳子上，等着小哭败整理东西。我不禁思考起这次跨国之旅，它并不完美，甚至可以说是充满了遗憾：混乱且匆忙的行程安排、圣地巡礼中找错点位的迷路、MyGO!!!!!状态不佳的演出、没有安可与MC的突兀收场、药妆店里维修服务器的狼狈……但当我回味时，最先想起的还是这些略显粗糙的真实片段。此外，穿梭于陌生的国度，见识到诸如日本复杂的电车系统等等风土人情，这样新奇的体验更难以遗忘。无论是遗憾也好、美好也罢，这些不可复制的「瞬间」交织在一起，才构成了这次旅行的独特「记忆」。而这些不完美，恰恰引发了我对下次「可能完美」的期待。</p><p>而在这趟旅途中，比这些记忆更珍贵的，或许是我心态上的「脱敏」。</p><p>memory谈到自己的学习，坦言称自己仍在迷茫之中。是啊，去年身处「分歧路口，前途漫漫」的演唱会现场时，我同样也深陷迷茫。在成长过程中，我似乎也不知不觉地接受了<a href="https://www.zhihu.com/question/622014984/answer/1914303273776691029">「一步也不能错」</a>的想法；一旦现实稍有偏差，便会不自觉地产生焦虑。大一上学期的数学分析，我考了80分左右。这个成绩虽然并不难看，但跟周围人相比却远远不够。随后我就一直惶恐不安，担心自己不能保研、不能推优，总想着要是当时分数考得高一点就好了。很长一段时间里，我都把大量精力用在诸如此类的内耗上，总觉得自己再怎么努力也于事无补。而这次在异国他乡中，m1saka的那份豁达深深感染了我——他一边在截稿日前死磕论文，一边毫无芥蒂地和我们巡礼、打趣。他甚至开玩笑说，我之所以迷茫，纯粹是因为「游戏打少了」。</p><p>这几天跳出了原本的社会关系网，再回看这场不尽人意的演唱会，我突然感受到：每个人、每件事都会存在「不完美」和「遗憾」。那些过去我以为无法挽回的偏差，其实并不会真的把人生彻底毁掉。当我接受这一点后，心头上的许多重担也就自然消解了。先前绩点未能达到预期的事实已经翻篇，与其盯着一张成绩单上的排名内耗，不如沉下心来提升自己的能力。如今，我已经下定决心考研并为此努力；更重要的是，我对未来的大致方向，乃至希望跟随的导师，都有了相对明确的判断。从上海的「分歧路口」走到横滨的这场「瞬间与记忆」，我终于找回了继续往前走的节奏。</p><p>除了缓解对未来的焦虑，这趟旅行也让我放下了人际交往中那层「伪装」。学校目前的制度，让人难以有独属自己的空间。即使在寝室也要考虑室友们的感受，只有他们放假回家的时候，我才能稍微放松一点；更别提在公共场合了。邦邦群友偶尔组织的线下活动，反而成了我的避难所。所以在学校的多数时候，我都会下意识地把更真实的一面收起来，就像是Ave Mujica戴上假面那般。但在这次旅行里，出于对同伴的信任，我才能卸下那种防备。有时我会因为心里高兴、感到安心，忍不住看着m1saka傻笑。他吐槽我这样「有点奇怪」，但还是接受了我的这份随性和笨拙。或许真正舒服的人际关系就是这样——可以做回真实的自己，而不用刻意维持「人设」。这种轻松的感受，或许比游玩本身更弥足珍贵。</p><p>那晚恰逢月食，天上的月亮并不完整。我反而觉得，正因为它有缺口，才更让人印象深刻。横滨港畔没能听到的安可与告别，大抵也是如此。它们并未随着突如其来的彩带一起坠落，而是化作了下次再见的理由。今年7月，MyGO!!!!!将于横滨举办演唱会。想到这里，我也开始期待与她们的下一次相遇。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>呂嘉鴻. <a href="https://www.bbc.com/zhongwen/articles/cp85eg85zzgo/trad">「台灣有事，就是日本有事」？高市早苗發言引發中日外交風波，北京將如何反制</a> [EB/OL]. BBC中文, (2025-11-14)[2026-03-09]. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>新明日报. <a href="https://www.zaobao.com.sg/entertainment/story20251211-7949526">宫崎骏也遇限日令 吉卜力展延期</a> [EB/OL]. 联合早报, (2025-12-11)[2026-03-09]. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>オリコンニュース. <a href="https://www.oricon.co.jp/news/2425784/full/">『バンドリ!』Roselia、上海公演は開催中止 予定日に大阪公演追加でYouTube・bilibiliにて冒頭の一部無料生配信</a> [EB/OL]. ORICON NEWS, (2025-12-18)[2026-03-09]. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>新华社. <a href="https://www.news.cn/world/20251114/34e60277a1604e1fa57964d834d42914/c.html">外交部和中国驻日本使领馆郑重提醒中国公民近期避免前往日本</a> [EB/OL]. 新华网, (2025-11-14)[2026-03-09]. <a href="#fnref4" class="footnote-backref">↩︎</a></p></li><li id="fn5" class="footnote-item"><p>新华社. <a href="https://www.news.cn/20251201/08f30fa06c714e6798f598ac2ed891c1/c.html">普京签署中国公民临时入境俄罗斯法令</a> [EB/OL]. 新华网, (2025-12-01)[2026-03-09]. <a href="#fnref5" class="footnote-backref">↩︎</a></p></li><li id="fn6" class="footnote-item"><p>涂颖浩. <a href="https://www.nbd.com.cn/articles/2024-04-17/3334080.html">一男子珠峰地区登山死亡，保险公司称产品保障区域不包含尼泊尔，购买境外旅游险要注意什么？</a> [EB/OL]. 每日经济新闻, (2024-04-17)[2026-03-09]. <a href="#fnref6" class="footnote-backref">↩︎</a></p></li><li id="fn7" class="footnote-item"><p>一条皓太. <a href="https://www.billboard-japan.com/special/detail/4807">＜インタビュー＞バンドのフロントマンは“神”であるべき？――MyGO!!!!!の“結束”を刻んだ6thシングル『聿日箋秋』</a> [EB/OL]. Billboard JAPAN, (2025-04-23)[2026-03-09]. <a href="#fnref7" class="footnote-backref">↩︎</a></p></li><li id="fn8" class="footnote-item"><p>一条皓太. <a href="https://www.billboard-japan.com/special/detail/4816">＜インタビュー＞傷すら絆に変えるのがAve Mujicaである――確かな“前進”を刻んだ1stアルバム『Completeness』</a> [EB/OL]. Billboard JAPAN, (2025-04-23)[2026-03-09]. <a href="#fnref8" class="footnote-backref">↩︎</a></p></li><li id="fn9" class="footnote-item"><p>中央社. <a href="https://udn.com/news/story/7333/9364030">北京壽司郎爆食安風波遭調查 日本母公司股價重挫</a> [EB/OL]. 聯合新聞網, (2026-03-06)[2026-03-09]. <a href="#fnref9" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2026/03/09/Interweaving-Moment-and-Memory-Yokohama-Report-and-Pilgrimage/</id>
    <link href="https://blog.deepchirp.com/2026/03/09/Interweaving-Moment-and-Memory-Yokohama-Report-and-Pilgrimage/"/>
    <published>2026-03-09T04:33:59.000Z</published>
    <summary>本文记录了作者参加MyGO!!!!!和Ave Mujica的「“moment / memory”」横滨演唱会的经历，并分享了圣地巡礼的见闻。</summary>
    <title>「瞬间」交织「记忆」：横滨站观后与圣地巡礼</title>
    <updated>2026-03-09T13:52:52.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="友人帐" scheme="https://blog.deepchirp.com/tags/%E5%8F%8B%E4%BA%BA%E5%B8%90/"/>
    <category term="感想" scheme="https://blog.deepchirp.com/tags/%E6%84%9F%E6%83%B3/"/>
    <category term="游戏" scheme="https://blog.deepchirp.com/tags/%E6%B8%B8%E6%88%8F/"/>
    <category term="音乐" scheme="https://blog.deepchirp.com/tags/%E9%9F%B3%E4%B9%90/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图取自《Arcaea》游戏内插图，从<a href="https://arcwiki.mcd.blue/File:Story_Last2_epilogue_cg.jpg">Arcaea中文维基</a>获取。</p></div><div class="note info flat"><p>本文的《Phigros》谱面演示均使用PhiEdit @cmdysj制作。</p></div><p>笔者主要游玩移动端音游。若有批评或建议，敬请在评论区指出。</p><h2 id="第一章：初识">第一章：初识</h2><p>小学时期，我经常会拿父母的手机玩游戏，因为什么也不懂，所以就在应用商店里随意下载感兴趣的小游戏，其中之一就是<a href="https://zh.wikipedia.org/wiki/%E5%88%AB%E8%B8%A9%E7%99%BD%E5%9D%97%E5%84%BF">《别踩白块儿》</a>。它的谱面（可见下方《钢琴块2》游玩界面图，与此类似）是传统固定轨道下落式，需要玩家在音符下落到屏幕底部之前正确击打，无判定线，若有错误或遗漏则游戏结束，即强制全部连击。那时触摸屏手机刚刚兴起，屏幕尺寸较小，我出于一种奇怪心理，坚持手持手机、只用右手大拇指击打音符，左手则完全不用。可能是因为右手大拇指努努力就能刚好够到最左边吧。我对于挑战新的极限分数（换种说法就是自虐）很有热情，继承了一点外公的逞强与倔强心态，对这种新颖的游戏类型上了瘾。在街上走路时我甚至都会抓住闲暇时间开一把，估计挨过不少骂，但我不会记这种没趣的事。玩了几个月后，右手大拇指的灵活度明显得到提升，而左手始终废柴，为以后的音游之路埋下了巨坑。《别踩白块儿》的游戏模式不多，曲目仅作为背景音乐、与玩家操作无关联，我极为小学生地对其他游戏移情别恋了，比如「火柴人」系列。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/ptiles-ui.avif" alt="《钢琴块2》游玩界面"></p><p>约一年后，《别踩白块儿2》，亦即<a href="https://zh.moegirl.org.cn/%E9%92%A2%E7%90%B4%E5%9D%972">《钢琴块2》</a>发布。</p><p>它的主要玩法不变，但加入了几种新音符，曲库极大丰富，成长机制引诱玩家不停去肝、解锁新歌。我仍然坚持「手持手机、右手大拇指游玩」的方式——直到某次旅游，住进一个类似民宿的大院子，旁观一对二三十岁的情侣（也可能是夫妻）推分数：他们把平板放在腿上，用双手食指打歌，完全投入到游戏中，其交流透露出极度的强者自信，根本不瞅作为小屁孩的我。嗯，没有吃狗粮的感觉，我只对他们的强者分数感兴趣。手持、右手大拇指游玩的方式，许久以来首次受到我的强烈怀疑：按这路子真能打好音游么？双拳难敌四手，毋庸置疑。立刻开始改革。</p><p>由于先前方式的惯性，我采取了比较缓和的尝试，即把音符下落四轨道中的右边三轨交给右手，最左边一轨交给左手。左手若要处理两条轨道，在高速击打时就不够灵活准确，总拖右手后腿，因此「右3左1」是当时冲击高分的最优解。适应后，我的整体分数有起色，左手也得到基本锻炼，但仍比不上右手的能力。</p><p>进一步改革的结果是「右2.5左1.5」:右手全权掌管右边二轨，左手全权掌管最左边一轨，剩余一轨由左手和右手共同击打，哪边压力小就由哪边打，莫名锻炼了协调能力。不过，「手持手机」到底有没有问题，暂且没有引起我的思考。</p><hr><p>对小学生而言比较神奇的事情是，我能持续地玩《钢琴块2》一年以上，不少歌曲能打到一两千分，对手速自信叉腰（手速只是笼统的说法，将在第三章说明）。在乐高兴趣班里，有位老师（英文名艾伦）知道我玩《钢琴块2》后，主动带我入<a href="https://zh.moegirl.org.cn/%E8%8A%82%E5%A5%8F%E5%A4%A7%E5%B8%88">《节奏大师》</a>的坑。它的谱面也是传统固定轨道下落式，有一根固定判定线，具有4k、5k、6k三种模式（k即轨道），特殊音符种类有滑键、可变轨长键，采取血条制，即漏击过多才会使游玩失败。</p><p>大概是因为我多少散发出一点（坐井观天的）强者气势，他十分乐意让我吃瘪，拿出手机让我尝试：选了4k模式下的《野蜂飞舞》，先体贴地给我开「简单」和「普通」难度以熟悉音符种类，此时「普通」难度已经使我略感到不对劲了；到了「困难」难度，虽然手指飞舞，但是我仍是飞（废）舞（物），血条撑不过十五秒。震惊，所以再试几次，还是如此，终于震惊：我拼尽全力练习两年半，终究还是无法战胜你吗，哈基米（此处以はちみつ的原意「蜂蜜」代指《野蜂飞舞》），你这家伙！之后，则是我单方面被其他难谱折磨的酸爽时间。艾伦老师由于愿意跟我玩，水平又确实高于我一截，从而被我当成好朋友兼短期偶像了。</p><p>这样，我被《节奏大师》折服，也不忘精进《钢琴块2》，整个暑假几乎就在一个人窝在沙发里愉快打歌中度过。我主要在玩《节奏大师》的闯关模式，没过两三个月就攻破到约莫四百关，和艾伦老师旗鼓相当了。至于9级、10级（当时最高10级）的谱面，我只作为远期目标，偶尔碰一碰。（偶尔越级是好文明！）而且也感觉到9级、10级谱面内部亦有差距，某些9级和9级之间的差距比晚期智人与草履虫之间的差距都大，官方定级或定数不能说明一切，有时甚至指鹿为马。</p><p>艾伦老师在兴趣班的工作不算忙，但他大概有别的事要忙，或者只是不想玩音游，小学毕业以后，我的闯关模式记录遥遥领先于他，但始终见不到他的记录更上一层。</p><p>值得一提的是，当时《节奏大师》最难曲似乎是《卡农-摇滚版》（曲目列表见<a href="https://zh.moegirl.org.cn/%E8%8A%82%E5%A5%8F%E5%A4%A7%E5%B8%88/%E6%9B%B2%E7%9B%AE%E5%88%97%E8%A1%A8">此处</a>），凭我的水平始终无法尝试。而在<a href="https://zh.wikipedia.org/wiki/%E5%86%85%E6%B6%B5%E6%AE%B5%E5%AD%90">内涵段子</a>上偶然看到自制谱<a href="https://www.bilibili.com/video/BV1f4411v7z8/">《霍元甲》全连手元</a>（原视频已找不到，这里的链接似乎是同一个玩家后来重新录制的，以「手持手机，拇指为主，食指为辅」方式游玩）后，我对音游上限，以及手持游玩上限的认知，又被刷新了。这也使我在初步察觉到「手持手机，拇指游玩」限制的时候，继续坚持走这条路，而不是立刻更改为「平放手机，食指和中指游玩」等主流方式。从现在的经历来看，尽管这种坚持让我长久陷入瓶颈期，但它仍值得尊重，特别是在我年纪尚小的情况下。条条大路通罗马——百花齐放、百家争鸣所体现的，是人的生命力和创造性。</p><hr><p>初中时期，我认为是移动端游戏最繁荣的时候，音游玩得相对少些。某次校级运动会，班上以仅拍照为条件，允许带手机，但「不准打游戏」在我们听来即「不准被发现打游戏」。除了想方设法和同学们一起躲着藏着玩手机，我还带着一点拿音游装逼的私心。然而机会不多，只是在几个好友围观下开了两局《野蜂飞舞》困难难度而已，发挥很一般，勉强通过，没让血条掉干净；《钢琴块2》大概也有玩，以及给同学们玩。不过目的倒是达到了：塑造「打音游很厉害」的形象。我在炫耀和吹嘘上的克制似乎还给人「深藏不露」的感觉，大成功。</p><p>寒暑假回了乡下老家，和表姐、表弟一块玩，那几个少儿动画电视频道看腻之后，我经常不合群地打音游。「修行不能断」呢。他们是会看我玩音游，却对上手自己玩兴趣缺缺，我也没有什么口才来作推荐。所以我是一个失败的传道士。</p><p>自此以后，音游不过是「零食」罢了。直到2021年暑假，有件事彻底使我改观，将音游作为「正餐」，并对其本身进行思考。</p><h2 id="第二章：重拾">第二章：重拾</h2><p>其实，先是深鸣受到了惨无人道的虐待。他先前仅接触过《钢琴块2》。在高中暑假时，他去了叶子（是我们共同的初中同学）家里玩，在没有游玩新手教程，也没有任何心理准备的情况下，直接<s>被逼着</s>玩了《Phigros》，挑战了Insane 15级难度（当时最高16级）的<a href="https://phigros.fandom.com/wiki/GOODFORTUNE">《GOODFORTUNE》</a>（俗称《良幸》）。当时他谱面都看不懂，还是叶子在旁边实时教导。这就像「新兵拿着弹弓朝碉堡射出啤酒瓶」一样荒诞，最后打出来的分数嘛，当然是惨不忍睹。</p><p>深鸣随后迫不及待地向我推荐《Phigros》，并且转达叶子的想法，教唆我首先去打Insane 15级难度的<a href="https://phigros.fandom.com/wiki/Better_Graphic_Animation">《Better Graphic Animation》</a>。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/phi-bga-art.avif" alt="《Better Graphic Animation》俗称《小电脑》，上图为曲绘"></p><p>比起深鸣，至少我规规矩矩地过完了新手教程，是「新兵端着步枪朝碉堡射击」的程度了。我原本盲目自信地以为音游之间大同小异，既然玩了《钢琴块2》和《节奏大师》好几年，玩《Phigros》当然也不成问题。事实上，所谓「创」新音游狠狠创死了我。当时立刻向深鸣吐槽：「这个歌怎么这么坑？？」「不知道判定真的不会打啊！」</p><p>不懂判定机制，那就多打几遍。后来深鸣被我试图拿各类音游「创」新谱面加以谋害时，发扬生物本能趋利避害，可喜可贺；与他反应不同的是，我喜欢作死，直到手指的力气被榨干、小臂发烫。面对Insane难度《Better Graphic Animation》的标志性120连击长纵连，我选择拿单拇指硬扛。扛不动的。为此，我无师自通了Vibro（<a href="https://www.bilibili.com/video/BV1hV411g7Lp">教学视频</a>），简而言之就是抽搐，进化出人体筋膜枪。物理和心理上的双重震撼.jpg。</p><p>初中打音游的无心之举，实际上竟然「传道」成功了，挺开心的。叶子「闷声发大财」（出自卢本伟），在音游水平上远超疏于练习的我；加上《Phigros》确实很有意思，谱面表现手法几乎无上限，重新点燃了我对音游的热情，当然也包括深鸣的热情。</p><hr><p>玩了挺久《Phigros》后，对机制和谱面都很熟悉了，即使<a href="https://phigros.fandom.com/wiki/Game_Mechanics#Judgement">《Phigros》判定宽松</a>，但是准度仍偏低、拿不到高分。我发现了两个主要问题：</p><ol><li>由于流速不能调整，用手机游玩时，谱面会很「挤」。而平板屏幕更大、音符排列更宽，因此谱面更好读。</li><li>改革后遗症：谱面总体上是左右均衡的，现行的「右2.5左1.5」分配方式导致左手经常拖后腿。</li></ol><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-dens-phone.avif" alt="手机读谱示意"></p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-dens-pad.avif" alt="平板读谱示意"></p><p>对策是：</p><!-- markdownlint-disable-next-line MD051 --><ol><li>为了即时读谱能力与<strong>谱面分析能力</strong>（见<a href="#%E9%99%84%E7%AB%A0%EF%BC%9A%E8%B0%B1%E9%9D%A2%E5%88%86%E6%9E%90%E6%A6%82%E8%AE%BA">谱面分析概论</a>）的锻炼，放弃用手机游玩，改用平板。</li><li>个人实践告诉我「平板不便于用拇指游玩」（注：此看法是片面的，如高水平板拇玩家<a href="https://space.bilibili.com/432472992">Nitrogen冰氮</a>），于是另起炉灶，从拇指改为食指击打的主流方式。</li></ol><p>直至今日，我使用的都是「桌上放置平板，食指为主」的游玩方式。适应期比较痛苦，因为食指以前没怎么锻炼过。不过，更彻底的改革带来了更深入的理解和堪称丰硕的成绩，使我略微超越了叶子。</p><p>我对《钢琴块2》里的钢琴曲（如<a href="https://www.youtube.com/watch?v=ZHCjU_rcQno">《卡农》</a>）、《节奏大师》里的流行歌曲（如<a href="https://www.youtube.com/watch?v=OWjOW57KWBE">《PLEASE》</a>）不算很感兴趣，但是被《Phigros》中的电子音乐打动了。相当一部分乐曲曲风前卫、质量上乘，典型有<a href="https://www.bilibili.com/video/BV14Y411h7XB/">《Credits》</a>、<a href="https://www.bilibili.com/video/BV1Ex411m7R6/">《Aleph-0》</a>；曲库足够多样化，例如旋律经典的<a href="https://www.bilibili.com/video/BV1Xt411W73g/">《Aphasia》</a>、<a href="https://www.bilibili.com/video/BV1C44y1r7KH/">《Reimei》</a>。还了解了乐曲及谱面比赛BOF（全称THE BMS OF FIGHTERS，<a href="https://www.bmsoffighters.net/">此处</a>为官网），《Phigros》收录了其中一些乐曲，可以找排名靠前的听一听。</p><h2 id="第三章：求索">第三章：求索</h2><p>疫情期间，我和深鸣在家待着上网课。网课≈闲来无事，故找来<a href="https://indienova.com/corp/adofai">《冰与火之舞》网页试玩版</a>消遣。<a href="https://zh.moegirl.org.cn/%E5%86%B0%E4%B8%8E%E7%81%AB%E4%B9%8B%E8%88%9E">它的玩法</a>最大特色是，节奏依靠旋转角度来表现，而非传统的下落距离；伪1k的谱面实际上通常要求多指（使用大于2个手指）游玩，手法设计有极大空间。之后购入PC端正版，虽然有人性化的可调速「练习模式」，但因为多指能力疲弱、难以适应而逐渐弃坑。</p><p>我同时期接触了<a href="https://musedash.peropero.net/">《喵斯快跑》</a>（PC端），<a href="https://zh.moegirl.org.cn/Muse_Dash">其玩法</a>特色在于结合了跑酷和音游，视觉效果极佳，且2k侧落式谱面易上手。由于笔记本电脑的薄膜键盘手感不佳，所以玩得不多。</p><p>大学入学自我介绍时，我表明自己有在玩音游，没说具体是哪些，因为心里想着应该更包容开放，并借此和新同学打好关系。一位同学问道「玩不玩烤」，而我并不懂「烤」其实是<a href="https://www.tw-pjsekai.com/">《世界计划 彩色舞台 feat. 初音未来》</a>的简称，就问「烤是什么」，瞬间冷场。他回复说「啤酒烧烤」，我回不上话，一度极为尴尬。自诩多年音游玩家，却对涉足范围以外的音游孤陋寡闻，似乎又成了坐井观天的所谓强者，又无法为「开放」和「求新」付诸行动，这种打击实在破防，后来特别去留意常见的音游。</p><ul><li>英文全称：Project Sekai Colorful Stage! feat. Hatsune Miku</li><li>英文缩写：PJSK</li><li>中文拼音：啤酒烧烤</li><li>取末尾字：烤</li></ul><p>我暂时将音游游玩能力大致划分为如下结构，笼统说法「手速」包含耐力和爆发力。进入大学后，自觉在《Phigros》上精进了大部分能力，直至耐力、爆发力、协调不足使我又一次陷入瓶颈期。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-ability-map.svg" alt="音游游玩能力结构"></p><p>这一次有些触摸到肌肉上限了，常态化的原地打转使人沮丧。原本想着转移赛道，去玩以硬核著称的<a href="https://arcaea.lowiro.com/zh">《Arcaea》</a>，但是刚好碰上<a href="https://zh.moegirl.org.cn/Paradigm:_Reboot">《范式：起源》</a>国服发布（国产音游要起飞了吗！），觉得是同一类型，就先尝试了《范式：起源》。它的特色是立体读谱，音符从四面及中央下落，位移要求中等，颇有缝合怪的味道；与地狱读谱难度互补的是，音符种类相当简单。</p><p>2024年我正式入坑《Arcaea》，它与后辈《范式：起源》相比，对位移和反手（即左手在右，右手在左）的要求极高，且<a href="https://zh.moegirl.org.cn/Arcaea#.E9.9F.B3.E7.AC.A6.E7.B1.BB.E5.9E.8B">音弧</a>（俗称蛇）不能换手。和深鸣联机游玩时，曾被家人调侃「你俩在打同一个游戏吧？动作跟复制似的」；还有补刀「手在那点点点，不知道有什么好玩的」，由于频繁听到这种话，已经免疫了。</p><p>虽然深鸣比我更早开始玩《Arcaea》，但在他转战<a href="https://zh.wikipedia.org/wiki/BanG_Dream!_%E5%B0%91%E5%A5%B3%E6%A8%82%E5%9C%98%E6%B4%BE%E5%B0%8D">《BanG Dream! 少女乐团派对！》</a>后，逐渐冷落了《Arcaea》。我觉得《BanG Dream! 少女乐团派对！》优点在于养成（深鸣：<a href="https://zh.moegirl.org.cn/%E9%AB%98%E6%9D%BE%E7%81%AF">Tomorin</a> saikō!）、曲库优良，而核心玩法其实等效于双指击打无轨下落式谱面，没有太多创新性，加上难以适应眼花缭乱的背景演出与长条尾判，所以没有多少兴趣。</p><p>我也尝试过创新性较强的<a href="https://c2.dragonest.com/">《Cytus II》</a>，但在上手阶段里难以适应它的即时读谱。</p><p>以往总是使用双指打歌，迫不得已时才用多指（食指以外的任何手指）辅助。有一点锻炼多指的想法，然而动力不足，偶尔玩一玩定轨5k游戏<a href="https://zh.moegirl.org.cn/KALPA">《KALPA》</a>。如果需要，普遍推荐的是：移动端，<a href="https://m.mugzone.net/">《Malody》</a>（传统4k等）、<a href="https://zh.moegirl.org.cn/Dynamix">《Dynamix》</a>（无轨，三面下落）、<a href="https://zh.moegirl.org.cn/TAKUMI3">《TAKUMI³》</a>（无轨，传统下落）；PC端，<a href="https://osu.ppy.sh/">《Osu!》</a>（多种定轨等）。</p><hr><p>本章没有太多心理鲜明的经历可写，更多的是具体游玩过程中的挣扎，我认为其中有价值的是对音游本身的思考。下面根据个人感受，对部分音游进行对比，更深入地说明各自特点。</p><ul><li><p>《KALPA》：</p><p>最为常规的5k定轨下落式游戏，音符只有单键和不变轨的长条。学习成本极低，拿来练习多指协调能力非常合适。此外，这样大道至简的路径选择反而更能凸显谱师的创作功底。</p></li><li><p>《钢琴块2》：</p><ol><li>虽然没有固定判定线，但是实际游玩时不可能一会儿打屏幕上部、一会儿打屏幕下部，所以玩家需要想象一个判定线以作参考。这种设计与可调整位置的判定线无异。</li><li>谱面流速逐渐加快，不可调整，使得高刷新率屏幕成为刚需。当分数越来越高，音符在屏幕中存留时间越短，人的反应时间越短，即时读谱要求越高，击打容错空间越小。</li><li>谱面是随机产生的，无法背谱，只能依靠即时读谱来游玩。</li><li>紧邻的两个音符不会出现在同一轨道（部分模式除外），故很多配置是楼梯及其变式。</li></ol><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-stair.avif" alt="楼梯"></p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-stair-var.avif" alt="楼梯变式"></p></li><li><p>《节奏大师》：</p><ol><li>谱面下落不符合透视原理，「前快后慢」，《世界计划 彩色舞台 feat. 初音未来》也是如此，视觉效果比较奇怪，但适应之后还行。</li><li>滑键和可变轨长条的存在使难度上限极高，甚至可以制造反手配置，使玩家万万不能把谱面当作常规定轨来打。</li><li>因为腾讯出品，充值系统是不得不品尝的一环。若想提高成绩，除了锻炼硬实力，也可以购买道具和功能强大的角色，可能让人产生不良路径依赖，因此不算硬核类型。</li><li>2021年旧版停服，2023年新版回归，不仅「效率奇高」，界面也一如既往地丑。</li></ol></li><li><p>《Phigros》：</p><ol><li>几乎达到了平面音游的自由度上限，堪称音游界的<a href="https://zh.moegirl.org.cn/%E6%88%91%E7%9A%84%E4%B8%96%E7%95%8C(%E6%B8%B8%E6%88%8F)">《Minecraft》</a>。高自由度的原因有：1. 判定线和音符在时空上均可任意调整；2. 判定线数量很多；3. 音符的判定取决于与判定线/音符重合的瞬间。因此，通过组织多个判定线/音符，就能实现多样化的谱面形式，典例见2024年愚人节谱面<a href="https://www.bilibili.com/video/BV14m411z7Vr/">《Retribution ~ Cycle of Redemption ~》</a>；只要不出现应该判定的重合，那么点与线的「表演」将大放异彩，顺带起引导和提示作用。</li><li>游玩过程中，需要注意区分哪些是需要击打的部分、哪些是纯粹表演的部分。阅览谱面不仅是在理解配置，也是在欣赏艺术。同样地，这种高自由度对谱师发挥提出更严苛的要求：尽量把音乐、配置、表演适当地结合起来，达到「和谐」的境界。而且我认为表演的重要性次于配置，毕竟谱面是拿来玩的而不是看的，除非是观赏谱。</li><li>游戏内的<a href="https://zh.moegirl.org.cn/Phigros#Tips">Tips</a>很有趣，如「阿鸠你又在反复看Tips了哦」。</li></ol></li><li><p>《冰与火之舞》：</p><ol><li>如果有一个谱面是1k下落式的，这将是地狱：<br><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-angle-1k.avif" alt="1k下落式谱面示意"><br>对此，《冰与火之舞》的底层设计思路让我想到平面直角坐标系和极坐标系：把距离，转换成角度！如此一来，一条1k谱面将在平面内蜿蜒展开，可读性大大增强，但读谱难度依然较高。<br><img src="/2025/11/27/My-Rhythm-Game-Journey/adofai-angle-path.avif" alt="冰与火之舞谱面"></li><li>前面提到「伪1k」，为什么呢？要想让谱面难度够高，则音符密度要够高，高到一定程度时，单个手指就无法承受了。事实上，它的大多数谱面设计根本不以单指游玩为前提，只是将1k作为表现形式，实操到底按什么方式（例如定轨4k）由玩家自主决定。这样，玩家就有了完全的实操手法设计自由，游戏为这种自由弥补了人性化的工具，即可调速的「<a href="https://zh.moegirl.org.cn/%E5%86%B0%E4%B8%8E%E7%81%AB%E4%B9%8B%E8%88%9E#.E7.BB.83.E4.B9.A0.E6.A8.A1.E5.BC.8F">练习模式</a>」。</li></ol></li><li><p>《Arcaea》：</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/arc-chart-3d.avif" alt="《Arcaea》谱面演示"></p><ol><li>立体音游代表作，移动端难度上限数一数二，且十分难上手，判定严格。</li><li>绝大多数谱面仅需要且建议用双指游玩，借助音弧等特殊机制，位移和引导有更大发挥空间，笔走龙蛇、起承转合堪称双指玩法最高的浪漫；同时因为谱面设计感很强，仅靠即时读谱很难理解，故谱面分析能力必不可少，Ranker（冲榜玩家）们<a href="https://www.bilibili.com/video/BV1t3UDYEEMu/">被初见杀的场面</a>喜闻乐见。</li><li>一众谱师在创新上不遗余力，对某些配置，玩家们的态度常常先是「菜菜，捞捞」、后是「儿简送，不教」。见证音游的难度膨胀吧。</li></ol></li><li><p>《范式：起源》：</p><ol><li>和老前辈《Arcaea》比较相似，但是长条不锁手，对反手无硬性要求，位移要求更低。从这点来说，堆难度上限几乎只能依赖单键排布。</li><li>「大逼圈」配置（即单指画圆）出现较频繁，因此也被称为移动端的<a href="https://maimai.sega.com/">《舞萌》</a>。</li></ol></li><li><p>《Cytus II》：</p><p>反转了下落式音游的传统，音符将在固定位置浮现，而判定线上下往复移动，实现「动静互换」，有趣的底层思路。</p></li></ul><h2 id="总结">总结</h2><p>一般情况下平板比手机更好读谱，而影响发挥的外在因素不止设备本身，还有坐姿、设备放腿上或桌上、桌/椅高度、屏幕保护膜种类、指甲长度、指套/手套等等，甚至指腹抹点鼻子上的油作润滑，都可能有显著效果。这些因素没有谁好谁坏的定论，多多尝试，找到适合自己的方式就好。</p><p>音游的本质，我想，是以游戏为形式，对音乐进行抽象和重构。在作为游戏这方面，音游要求玩家尽可能精准地「复刻游玩」，这听起来不浪漫，甚至有些冷酷；而在抽象和重构音乐这方面，音游是浪漫的：不仅涉及时间艺术，还涉及空间艺术，或许是游戏最为艺术的种类之一，而且玩家在这两方面均有一定自主发挥空间。所以，不管有什么干扰和困难，享受音乐、享受游戏都可以是十足浪漫和快乐的。</p><p>目前我取得的主要成就是《Phigros》rks 15.50+以及《Arcaea》ptt 12.00+。玩了各类音游逾10年，热情有起有伏。以后若没有变故，大概会一直玩下去，逐步见证音游的进步与自身的成长。</p><p>如果想要入坑移动端音游，建议从玩法传统、容易上手、曲库丰富且质量高的音游开始，例如《Cytus II》，但是最好的动力仍是能够一起玩的朋友。</p><h2 id="附章：谱面分析概论">附章：谱面分析概论</h2><div class="note warning flat"><p>本章使用了较多音游术语，建议有一定基础的读者阅读。</p></div><h3 id="概述">概述</h3><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-ability-map.svg" alt="音游游玩能力结构"></p><p>即时读谱，指的是：只依靠当场反应来理解谱面。这种方式最为常见，然而有几个缺陷：</p><ul><li>很难透彻理解复杂度高/创新性强的配置</li><li>极慢流速下信息过载，极快流速下无法反应，流速变化时判断失准</li><li>易产生手癖（即认知正确，但肌肉记忆错误）</li></ul><p>所以，就需要「马后炮」式的谱面分析来厘清节奏、理解配置、抓准细节，进一步地为手法设计提供依据，在应对难谱时尤为重要。谱面分析可以通过游戏内播放谱面且只观察（有些游戏做不到）、录屏慢放（推荐软件<a href="https://hyoromo.github.io/sound-game-training-android/zh/">《音乐游戏培训》</a>）、参考网络视频（如<a href="https://www.bilibili.com/video/BV1wZ421J7N4/">谱面确认</a>）等形式来进行。</p><p>谱面分析为实操服务，所以有时间和空间两个层面。</p><h3 id="时间层面">时间层面</h3><h4 id="延迟对准">延迟对准</h4><p>包括游戏设置中的内容和游玩段落时首个音符的对准。关于后者，谱面分析可为谱面休息段提供补拍依据，减少目押重新对准而造成的失误。</p><h4 id="节奏复现">节奏复现</h4><p>节奏复现中的节奏，指的是击打谱面而非音乐本身的节奏，且与各手指的击打分配有关。（例如，交互配置一般拆解为双指交替击打，而不是单指硬扛。）为得到更有实操指导价值的节奏，有三个步骤：</p><ol><li><p>厘清采音节奏。若有现成资源，如节奏解析（参见<a href="https://www.bilibili.com/video/BV1wU4y1B79P/">8岁时光对节奏解析的说明</a>），当然尽可能利用；若没有，可以目测节奏或借助节拍器等工具。一般来说，谱面中的小部分非常规节奏（参见<a href="https://www.bilibili.com/video/BV1zAP2ewEgq/">节奏普及向视频</a>）才容易导致失误，游玩时留意出错片段，不需要全程确认。最后，建议整理为1k节奏解析形式的采音节奏谱，这样最为直观。</p></li><li><p>节奏改良（选用）。对于判定宽松的部分音符，如<a href="https://arcaea.lowiro.com/zh">《Arcaea》</a>的Hold、<a href="https://phigros.fandom.com/wiki/Phigros_Wiki">《Phigros》</a>常规模式下的所有音符，可以在不影响/轻微影响判定的前提下，人为增/删/更改它们的节奏，以得到相对简单、不易失误的节奏。理论上虽然这么说，实操中往往需要奇思妙想，结合采音与排键来设计更优手法。下面是一个补拍示例，即右手多打一颗交互并顺势右划接住黄键，不会影响判定，且恰好使得双手复位。</p></li></ol>  <div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-rhythm-before.avif","alt":"原始谱面","title":""},{"url":"gen-rhythm-after.avif","alt":"实际击打，红色箭头表示右手位移","title":""}]</div>  </div><ol start="3"><li>复现，即想象或敲击改良的节奏。在谱面中实践时，可以先在游戏内播放谱面，且只击打需要练习的片段，观察其余部分；逐步延长击打的部分、缩减观察的部分，锻炼片段前后的衔接，最终正常游玩全谱面。</li></ol><hr><p>要分析具体配置并分配各手指的任务，必定涉及空间层面的排键。在此，我们关注难点主要在节奏而非排布的配置，下面简单列举几种情形。</p><ul><li><p>难点在于击打「空闲」：</p><p>这听上去似乎不成立：手指都处于空闲状态了，还有什么难的呢？实际上「空闲」难在「不规律」，把常规配置中的某个音符舍弃，造成规律中断，则可能形成易失误的新配置。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-gap-3-1-7.avif","alt":"3+1+7纵连","title":""},{"url":"gen-gap-3-1-7-skip.avif","alt":"3+1+7纵连拆解示例，黄键处表示跳过击打","title":""}]</div>  </div><p>这个纵连如果拆解为右手起手的不规律交互，则需要左手刻意跳过两次击打，实操中容易出现「打多了」。左手起手同理。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-gap-1-2.avif","alt":"缺位的连续单双","title":""},{"url":"gen-gap-1-2-skip.avif","alt":"补全的连续单双，黄键处表示跳过击打","title":""}]</div>  </div><p>同样地，若连续单双配置中舍去一个单键，左手容易按照先前规律多打，造成缺位处的后一个单键过早判定。双押夹三角夹双押已经<a href="https://www.bilibili.com/video/BV1JS4y197NY/">作为协调性配置出现过</a>，俗称夹心饼干。</p></li><li><p>难点在于击打变速：</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-poly-8-12-24-16.avif" alt="8分转12分转24分转16分交互"></p><p>如节奏快速变化的组合交互，判定不十分严格的情况下，大致判断出「前半段慢、后半段快」即可通过。</p></li><li><p>难点在于重音强调：</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-jack-7chain.avif","alt":"7连+双押纵连","title":""},{"url":"gen-jack-7chain-lh.avif","alt":"单手双押解法","title":""},{"url":"gen-jack-7chain-mf.avif","alt":"多指辅助解法","title":""},{"url":"gen-jack-7chain-burst.avif","alt":"爆发硬扛解法","title":""}]</div>  </div><p>一般地，为强调结尾重音，才会写出结尾为双押的16分纵连。假设右手起手，有这么三种解法：双押由手序对应的左手拍掉；右手以多指轮指方法解；右手最后一颗8分交互转16分硬扛。前两种解法一般更好。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-single-single-double.avif" alt="单单双两组"></p><p>把这种纵连缩短长度，即仅减少打均匀交互的时长，便能得到臭名昭著的单单双配置，其解法除上述三种以外，还可以一手硬扛「单单」、一手拍掉双押。同类型的还有单单单双配置、开头与结尾均为双押的纵连等。</p></li><li><p>难点在于读谱上的节奏混淆：</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-cross-wide.avif","alt":"排键极宽的三连交互","title":""},{"url":"gen-cross-normal.avif","alt":"排键正常的三连交互","title":""}]</div>  </div><p>看到排键极宽的三连交互，你的第一反应是？因为距离过远，不容易看出左边和右边的蓝键谁在前、谁在后，甚至可能打成双押加单点。如果排键正常，就容易看出这是一个左手起手的交互，中央蓝键应由左手击打了。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-hold-8th.avif" alt="5k长条海"></p><p>长条海的击打节奏实际上为均匀8分，但是容易出现读谱困难，原因是长条的头部与尾部比较相似，易把尾部当作头部打击而造成节奏错误。所以读谱应以空缺处为重点，读懂空缺处的节奏为均匀8分，则长条也具有相同排布。</p></li></ul><h3 id="空间层面">空间层面</h3><p>如果节奏确定了，怎么利用空间排布把谱面写得更易/难？在此，我们关注难点主要在排布而非节奏的配置，下面亦简单列举几个情形。</p><ul><li><p>一段交互有多少种写法？</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-cross12-base.avif" alt="初始交互"></p><p>这是初始状态的12连交互，左手起手。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-cross12-4k-move.avif","alt":"四键一组，常规位移交互","title":""},{"url":"gen-cross12-4k-stack.avif","alt":"四键一组，常规叠键交互，红色箭头表示左手位移","title":""},{"url":"gen-cross12-4k-stack121.avif","alt":"四键一组，1+2+1叠键交互，红色箭头表示左手位移","title":""}]</div>  </div><p>若以四个键为一组，通过位移可产生常规位移交互和叠键交互，每组的起手都相同。即使叠键交互与常规位移交互的位移幅度相同，叠键交互也更难，原因是读谱困难以及可能产生撞手。其中1+2+1叠键交互被戏称为「The shit from Arcaea」。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-cross12-3k-small.avif","alt":"三键一组，小位移交互","title":""},{"url":"gen-cross12-3k-large.avif","alt":"三键一组，大位移交互，红色箭头表示左手位移","title":""}]</div>  </div><p>以三个键为一组的情况也很常见，每打完一组，起手都要改变。</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-cross12-to-jack.avif" alt="交互变纵连，红色箭头表示左手位移"><br>交互向中间靠拢，逐渐变为纵连。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-cross12-axis-x.avif","alt":"X形轴交互，黄色箭头表示右手位移","title":""},{"url":"gen-cross12-axis-8.avif","alt":"8形轴交互，黄色箭头表示右手位移","title":""}]</div>  </div><p>以「一静一动」为思路，可得到轴交互：以左手为轴（静止或位移很小），右手击打时需要持续位移。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"gen-cross12-guide-step.avif","alt":"位移逐渐增大的引导交互，红色箭头表示左手位移","title":""},{"url":"gen-cross12-guide-3-1.avif","alt":"3+1纵连，红色箭头表示左手位移","title":""},{"url":"gen-cross12-guide-stair.avif","alt":"向楼梯引导的交互，红色箭头表示左手位移","title":""}]</div>  </div><p>制造位移规律，则可以得到引导交互。3+1纵连可视作引导较弱的交互来击打。向楼梯引导的交互比较少见，但它启示我们：楼梯也可当作交互来打，只是一般情况不这么打。</p><p>交互是音游中最多变的配置之一，至今仍具有相当大的空间排布潜力，这一点在立体音游中体现更明显。想打好交互，空间上要看准起手、发现位移规律，时间上则要稳住节奏。</p></li><li><p>连续三连交互：</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-cross-triplet-xhand.avif" alt="连续三连交互较难写法"><br>这是三组16分3连交互，每组间隔8分。若用双指击打，这种写法的难点在于：每打一组交互，起手都要改变，但是起手位置是反直觉的。1号蓝键右手起手，位置在右边，符合直觉；2号蓝键左手起手，位置却在右边，需要左手伸过去「够」、右手让出空间，不符合直觉；3号蓝键右手起手，位置却在左边，同样需要伸过去「够」，不符合直觉。如果多指协调能力好，可以看作定轨4k解。</p></li><li><p>连续单双：</p><p><img src="/2025/11/27/My-Rhythm-Game-Journey/gen-double-single-offset.avif" alt="连续单双较难写法，红色箭头表示左手位移，黄色箭头表示右手位移"><br>这是三组8分单双，与上面类似，若用双指击打，图中标出箭头的蓝键击打是反直觉的。如果多指协调能力好，亦可以看作定轨4k解。</p></li></ul><h3 id="小结">小结</h3><p>谱面分析的步骤大致为：判断具体配置的难点主要在节奏还是排布。若在节奏，则要厘清并改良节奏；若在排布，则要分析位移，挖掘规律。最后列举可能的、合理的解法，根据个人情况选择最适合的解法，比如爆发力强就硬扛，协调能力好就使用辅助指。</p><p>其实谱面分析的主要作用仍是「看懂谱面」。对于大多数配置，能看懂就等同于知道最优解法；对于少数配置，没有哪种解法具有绝对优势，这就需要权衡，或者设计专属于你的全新手法。</p><p>特别补充一点：笔者认为前面给出的音游游玩能力结构仅可作为参考，不能孤立地把问题归为某一个能力的不足：定位不准不一定是因为位移能力差，也可能是因为前面消耗了太多体力，即耐力不足。应该认识到各种能力之间互相关联，找到问题的主要方面，全面地分析并针对性地解决。</p><h3 id="补充资源">补充资源</h3><p>更详细的解说可见<a href="https://www.bilibili.com/video/BV1mAaKz4E3p">《音游学院派》系列</a>、<a href="https://www.bilibili.com/video/BV1bDQUY9E3H/">FLAME剑帝的三种发力方式</a>、<a href="https://www.bilibili.com/video/BV1TcfkYJEi6">Lusaslan的相对位移法</a>等。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/11/27/My-Rhythm-Game-Journey/</id>
    <link href="https://blog.deepchirp.com/2025/11/27/My-Rhythm-Game-Journey/"/>
    <published>2025-11-27T08:44:48.000Z</published>
    <summary>本文分享了作者多年游玩移动端音乐游戏的经历与思考，涵盖了从初识音游到深入求索的心路历程，最后提到了对谱面分析的理解。</summary>
    <title>我的音游心路历程</title>
    <updated>2025-11-27T08:44:48.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="教程" scheme="https://blog.deepchirp.com/tags/%E6%95%99%E7%A8%8B/"/>
    <category term="NetworkManager" scheme="https://blog.deepchirp.com/tags/NetworkManager/"/>
    <category term="TUN" scheme="https://blog.deepchirp.com/tags/TUN/"/>
    <category term="sing-box" scheme="https://blog.deepchirp.com/tags/sing-box/"/>
    <category term="网络" scheme="https://blog.deepchirp.com/tags/%E7%BD%91%E7%BB%9C/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/122310725">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/31434343">二狗子茶壶BRH</a>。</p></div><div class="note info flat"><p>对于<code>sing-box</code>用户，更新至1.13.3及更高版本后应当不会出现该问题。详见<a href="https://github.com/SagerNet/sing-tun/commit/caaf8469e09e309557b217c8997e0bfc55ebad91">该commit</a>。</p></div><p>不知从何时开始，当启用代理软件并使用TUN虚拟网卡时，<a href="https://networkmanager.dev/"><code>NetworkManager</code></a>会错误地提示「网络连接受限」，但事实上网络能够正常使用。这不仅会让人困惑，还会影响到依赖网络状态通知的应用（例如<a href="https://wiki.archlinuxcn.org/wiki/NetworkManager#%E4%BD%BF%E7%94%A8_NetworkManager_%E8%B0%83%E5%BA%A6%E7%BD%91%E7%BB%9C%E6%9C%8D%E5%8A%A1">调度网络服务</a>）。</p><h2 id="解决方法">解决方法</h2><p>将检查连通性的服务器绕过TUN网卡即可（例如，<a href="https://github.com/v2fly/domain-list-community"><code>domain-list-community</code></a>提供了<a href="https://github.com/v2fly/domain-list-community/blob/master/data/connectivity-check"><code>connectivity-check</code>列表</a>，包含了相关域名）。1.13.0及之后版本的<code>sing-box</code>支持<a href="https://sing-box.sagernet.org/zh/configuration/route/rule_action/#bypass"><code>bypass</code>路由动作</a>，将相关域名应用<code>bypass</code>动作规则即可。需要确保域名解析出的结果为真实IP而非<a href="https://sing-box.sagernet.org/zh/configuration/dns/server/fakeip/">FakeIP</a><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>，且DNS中启用了<a href="https://sing-box.sagernet.org/zh/configuration/dns/#reverse_mapping"><code>reverse_mapping</code></a>，同时该规则需在<a href="https://sing-box.sagernet.org/zh/configuration/route/rule_action/#sniff"><code>sniff</code>路由动作</a>之前。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;rule_set&quot;: &quot;geosite-connectivity-check&quot;,</span><br><span class="line">  &quot;action&quot;: &quot;bypass&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>若使用较旧版本的<code>sing-box</code>，或是其他代理软件，则可将相应的IP地址绕过TUN网卡。<code>sing-box</code>中可使用<a href="https://sing-box.sagernet.org/zh/configuration/inbound/tun/#route_exclude_address"><code>route_exclude_address</code></a>或<a href="https://sing-box.sagernet.org/zh/configuration/inbound/tun/#route_exclude_address_set"><code>route_exclude_address_set</code></a>。以<code>Arch Linux</code>为例，其所使用的默认服务器为<code>ping.archlinux.org</code>，IP地址为<code>95.216.195.133</code>和<code>2a01:4f9:c010:2636::1</code>。其他发行版可能需要根据实际情况调整。对于<code>sing-box</code>配置文件：</p><p>在入站的<code>tun</code>网卡配置中加入：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&quot;route_exclude_address_set&quot;: [&quot;arch-linux-ping&quot;]</span><br></pre></td></tr></table></figure><p>同时添加对应的规则集：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;tag&quot;: &quot;arch-linux-ping&quot;,</span><br><span class="line">  &quot;rules&quot;: [</span><br><span class="line">    &#123;</span><br><span class="line">      &quot;ip_cidr&quot;: [</span><br><span class="line">        &quot;95.216.195.133/32&quot;,</span><br><span class="line">        &quot;2a01:4f9:c010:2636::1/128&quot;</span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="探究过程">探究过程</h2><p>在<code>Arch Linux</code>上，与网络连通性相关的配置文件位于<code>/usr/lib/NetworkManager/conf.d/20-connectivity.conf</code>，其中指定了<code>uri</code>为<code>http://ping.archlinux.org/nm-check.txt</code>。根据<code>NetworkManager</code>的文档，程序会使用<code>SO_BINDDEVICE</code>检查网络是否通畅<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。源代码中，其<code>nm-connectivity.c</code>中调用<code>libcurl</code>相关函数，使用<code>curl_easy_setopt(ehandle, CURLOPT_INTERFACE, cb_data-&gt;ifspec)</code>绑定网络接口，随后检查是否能收到响应<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>。而<code>libcurl</code>会调用<code>setsockopt</code>，以实现绑定<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>。使用<code>strace</code>跟踪系统调用时，发现其调用了<code>setsockopt</code>，和先前分析一致：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">821   setsockopt(30, SOL_SOCKET, SO_BINDTODEVICE, &quot;enp55s0\0&quot;, 8) = 0</span><br><span class="line">821   setsockopt(24, SOL_SOCKET, SO_BINDTODEVICE, &quot;wlan0\0&quot;, 6) = 0</span><br><span class="line">821   setsockopt(32, SOL_SOCKET, SO_BINDTODEVICE, &quot;sing-box\0&quot;, 9) = 0</span><br></pre></td></tr></table></figure><p>依此，我编写了一个类似的测试程序：</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;curl/curl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    CURL *curl;</span><br><span class="line">    CURLcode res;</span><br><span class="line"></span><br><span class="line">    curl_global_init(CURL_GLOBAL_DEFAULT);</span><br><span class="line">    curl = curl_easy_init();</span><br><span class="line">    <span class="keyword">if</span> (curl)</span><br><span class="line">    &#123;</span><br><span class="line">        curl_easy_setopt(curl, CURLOPT_URL, <span class="string">&quot;https://deepchirp.com/&quot;</span>);</span><br><span class="line">        curl_easy_setopt(curl, CURLOPT_INTERFACE, <span class="string">&quot;wlan0&quot;</span>);</span><br><span class="line">        curl_easy_setopt(curl, CURLOPT_TIMEOUT, <span class="number">5L</span>);</span><br><span class="line"></span><br><span class="line">        res = curl_easy_perform(curl);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (res != CURLE_OK)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;curl_easy_perform() failed: %s\n&quot;</span>,</span><br><span class="line">                    curl_easy_strerror(res));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="type">char</span> *local_ip;</span><br><span class="line">            <span class="type">long</span> local_port;</span><br><span class="line">            curl_easy_getinfo(curl, CURLINFO_LOCAL_IP, &amp;local_ip);</span><br><span class="line">            curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT, &amp;local_port);</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;Local bind: %s:%ld\n&quot;</span>, local_ip, local_port);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        curl_easy_cleanup(curl);</span><br><span class="line">    &#125;</span><br><span class="line">    curl_global_cleanup();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>使用<code>tcpdump</code>监听网卡流量时，我发现TUN接口<code>sing-box</code>上存在与<code>deepchirp.com</code>相关的多路流量，但物理网卡<code>wlan0</code>上似乎并无相关流量；另一方面，查阅<code>sing-box</code>本身的日志，发现其本身似乎并未收到连接。而在关闭<code>sing-box</code>后，<code>wlan0</code>上则能捕获到相关流量。由此可见，<code>sing-box</code>会将流量劫持到其TUN网卡上，导致绑定物理网卡的<code>setsockopt</code>调用失效，从而使<code>NetworkManager</code>误判网络状态。</p><p>因此，只需将检查连通性的相关流量绕过TUN网卡即可。拜<code>sing-box</code>于1.13版本中更新的<code>bypass</code>路由动作所赐，只需将相关域名绕过TUN网卡即可。但在最初撰写此文时，<code>sing-box</code>并未提供<code>bypass</code>路由动作。我一开始考虑使用策略路由，为<code>ping.archlinux.org</code>的流量打上路由标记（使用<a href="https://sing-box.sagernet.org/zh/configuration/route/#default_mark">default_mark</a>即可），并使用<code>nftables</code>及<code>ip rule</code>将其路由到物理网卡，但感觉不够优雅：因为当<code>sing-box</code>退出后，相关的路由规则无用但仍存在。后来发现，<code>ping.archlinux.org</code>的IP地址似乎并不常变动——至少2022年8月的IP地址即与今相同<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>——因此选择直接将其IP地址绕过TUN网卡。不过，其他发行版的连通性检查服务器地址可能不同，IP地址若时常变动，可能还是使用策略路由更加方便。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>对<a href="https://github.com/v2fly/domain-list-community/blob/master/data/geolocation-!cn"><code>geolocation-!cn</code></a>使用FakeIP应该是常见做法；但其包含了<a href="https://github.com/v2fly/domain-list-community/blob/master/data/category-dev"><code>category-dev</code></a>，而后者又涵盖<a href="https://github.com/v2fly/domain-list-community/blob/master/data/archlinux"><code>archlinux</code></a>，包括了<code>archlinux.org</code>。在这种情况下，需要令<code>connectivity-check</code>中的域名解析出真实IP。 <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>NetworkManager. <a href="https://networkmanager.dev/docs/api/latest/NetworkManager.conf.html">NetworkManager.conf — NetworkManager configuration file</a> [EB/OL]. (n.d.)[2025-10-20]. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>NetworkManager. <a href="https://gitlab.apertis.org/pkg/network-manager/-/blob/apertis/v2026pre/src/core/nm-connectivity.c">src/core/nm-connectivity.c — apertis/v2026pre, pkg/network-manager (GitLab)</a> [EB/OL]. (n.d.)[2025-10-20]. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>Android Open Source Project. <a href="https://android.googlesource.com/platform/external/curl/+/refs/heads/main/lib/connect.c">lib/connect.c — platform/external/curl (main)</a> [EB/OL]. (n.d.)[2025-10-20]. <a href="#fnref4" class="footnote-backref">↩︎</a></p></li><li id="fn5" class="footnote-item"><p>Andreiva. <a href="https://bbs.archlinux.org/viewtopic.php?id=279074">[SOLVED] Arch makes many reverse dns lookups for redirect.archlinux.org</a> [EB/OL]. Arch Linux Forums, (2022-08-22)[2025-10-20]. <a href="#fnref5" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/10/20/Correcting-NetworkManager-Status-Under-TUN/</id>
    <link href="https://blog.deepchirp.com/2025/10/20/Correcting-NetworkManager-Status-Under-TUN/"/>
    <published>2025-10-20T13:34:57.000Z</published>
    <summary>Linux使用TUN虚拟网卡（如代理软件）时，NetworkManager可能错误提示「网络连接受限」。令相关流量绕过TUN即可修正该问题。</summary>
    <title>修正TUN下NetworkManager的网络状态</title>
    <updated>2026-03-12T05:55:43.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E7%94%9F%E6%B4%BB/"/>
    <category term="旅行" scheme="https://blog.deepchirp.com/tags/%E6%97%85%E8%A1%8C/"/>
    <category term="BanG Dream!" scheme="https://blog.deepchirp.com/tags/BanG-Dream/"/>
    <category term="MyGO!!!!!" scheme="https://blog.deepchirp.com/tags/MyGO/"/>
    <category term="Ave Mujica" scheme="https://blog.deepchirp.com/tags/Ave-Mujica/"/>
    <category term="演唱会" scheme="https://blog.deepchirp.com/tags/%E6%BC%94%E5%94%B1%E4%BC%9A/"/>
    <category term="上海" scheme="https://blog.deepchirp.com/tags/%E4%B8%8A%E6%B5%B7/"/>
    <content>
      <![CDATA[<div class="note info flat"><p>本文部分图片由「小哭败」和「三三_Official」提供，亦采用<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>许可。在此表示感谢！</p></div><p>自从今年过年时看了《BanG Dream! It’s MyGO!!!!!》后，我便<a href="/2025/02/01/BanG-Dream-It-s-MyGO/" title="《BanG Dream! It&#39;s MyGO!!!!!》短评">被其中的角色深深吸引</a>，尤其是高松灯——<a href="/2025/07/04/Gazing-Through-Mirrors-Tracing-the-Diagnostic-Path-of-Aspergers-Syndrome/" title="窥探镜中的自己：阿斯伯格综合征的诊断轨迹">毕竟我能与之深刻共鸣</a>。而《BanG Dream!》是2.5次元偶像企划，将线下和线上活动结合，所以我自然也会关注真人声优。今年9月份开学时，我就了解到MyGO!!!!!和Ave Mujica翌月将在上海举办联合公演，名为「分歧路口，前途漫漫」。小哭败是我给导师打工时认识的，他也很喜欢邦邦，所以我们决定一起去。</p><p>七芬有看邦邦演唱会的经验。他建议我们找代抢，因为票很难买到。在综合考虑下，我们选择了880价位的票。第一次开票时没有抢到，当时我们还自己手抢，感觉几秒就没了。幸亏第二次开票时，代抢抢到了第二天的票。然后便是买车票、订酒店之类，我们选择坐T109的硬座去上海；原本打算坐普速火车回来，但似乎赶不上，最后还是选择了飞机。</p><p>由于没有经验，我还不知道贩卖周边的快闪店需要预约，所以错失了机会，只能找群友杕杜代买。小哭败则是搞忘记了，在寻求帮助时，遇到了memory，他不仅答应帮忙购买，还说要和我们一起去火车站。同行的还有m1saka、杕杜。他们坐的也都是T109，不过是硬卧。</p><h2 id="Day-0">Day 0</h2><p>我们在10月10日出发。北京这几天雨下得挺大，上完课后，我便匆匆去吃饭，赶往地铁站，穿着类似羊宫妃那的蓝白外套、带着痛包。本来想把灯的玩偶带着的，但有点占地方，还是放弃了；后来有些后悔，因为不少人都带着，挺有纪念意义。到了地铁站，memory看到我，笑称「go批真好认」。路上就是聊天，memory还发了自己印的物料。</p><p>今天恰好还是我写的《<a href="/2025/06/03/Crafting-the-%22BanG-Dream-Girls-Band-Party%22-Entry-on-Wikipedia/" title="从初级到典范：《少女乐团派对》维基百科条目炼成记">从初级到典范：〈少女乐团派对〉维基百科条目炼成记</a>》在维基百科电子游戏专题发布的日子，感觉挺巧的。<a href="https://zh.wikipedia.org/wiki/User:Olaf8940">英國皇家歐拉夫王子</a>看了文章后称：「阁下在电子游戏简讯所撰写的专题，让小弟受益良多，感谢您的贡献，是真mygo厨」。感觉能够帮助到其他人，就是最大的快乐。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251010_192856.avif","alt":"夜晚的北京站","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251010_194358.avif","alt":"车站站台","title":""}]</div>  </div><p>上了火车，我和小哭败便与其他人分道扬镳了。我们坐下之后，周围几个人就开始笑，因为大家都是去看邦邦的。后面经过奔走相告，人越来越多，甚至还建了个群，有几十个人。我们一起聊了会儿天，随后我开始打起邦邦手游。后来经过号召，我们尝试去餐车，但是中间有道门被封住了。于是在天津西，我们迅速下车跑了过去。餐车是40块钱一位，算是夜宵，可以从晚上十点待到第二天六点。这里的环境比硬座要好不少。本来想和memory他们一起的，但是硬卧的火车餐似乎和硬座是隔开的，故作罢。火车餐的品质……真的是一言难尽。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251010_222236.avif" alt="火车餐"></p><p>工作人员还问我们是不是去看谁的演唱会，有人回答说是动画小人，笑。随后，我们打起了邦邦联机。车上的网络并不好，总是掉线，大概每打一把就会掉一次。不过我手感不错，把《Paradisus-Paradoxum》的28级全连了，先前总漏一两个。打了大概一两个小时，便休息了。</p><p>凌晨还因其他人吵架而醒。一个退伍军人非要坐在餐车的座位上，后厨的工作人员不让他坐，所以双方开始吵架。乘客非说自己作为退伍军人，必须要得到照顾，坚持不离开。但那个后厨也声称自己是退伍军人。不知道后来是怎么解决的。</p><h2 id="Day-1">Day 1</h2><p>早上六点不到，工作人员就让我们回到原来的座位。车厢人非常多，似乎还有不少是无座。然后我又稍微睡了一会儿。十一点多，终于到了上海。我们去看邦的还拍了张合照。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_111638.avif" alt="合影"></p><p>随后，我们几个人再次会合。除了杕杜，我们都住在塘桥，所以一起坐地铁过去，但他实际上也顺路。地铁到站后，还碰到一扇站台门没开，等了十几秒一直这样，只能从其他门出去。暑假来上海的时候，也碰到这种事情。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_115406.avif" alt="关闭的站台门"></p><p>在酒店把东西收拾好之后，我们在附近的塘桥人家吃了午饭。这里的菜量挺大，味道也还行，不过看起来并不是正宗的上海菜。memory两天都有票，所以吃完后先回酒店休息了。我们三个都是第二天的票，状态还不错，没必要休息。memory是博士，小哭败在读研，他们聊了不少学业上的事情，还给我提了不少建议。</p><p>此后，我们去了梅赛德斯-奔驰文化中心。浦东100路发车间隔三四十分钟，恰巧赶上了。下车后，刚好是鸡狗对邦手游卡池的开放时间，于是我和小哭败便开始抽卡。我抽了40发，其中一次十连双黄，但没有抽到灯的。在门口，我们还看到了祥子的痛车，感觉很帅气。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_150510.avif","alt":"梅赛德斯-奔驰文化中心","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_150656.avif","alt":"祥子的痛车","title":""}]</div>  </div><p>m1saka领完荧光棒后，我们就去了世博源。门口还有所谓的工作人员，说可以免费打印纸质票；不过后来听别人说这是假的，不知道具体是什么套路，可能是骗取个人信息？世博源的人挺多。我们先是在楼上逛。花篮的队都排满了，还限制人流，所以就没看。此外，这里还有不少cosplayer。不过我非常社恐，所以不敢上前搭话。其他两个同学倒是很活跃，和cosplayer交流又合影。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_154719.avif" alt="长崎爽世的角色扮演者"></p><p>闲逛时，突然有一群人围起来，有人还拉着横幅，说什么牛子豪之类的。我们也过去看了一下，但我并不了解，似乎是因为他喷了羊宫妃那？横幅上印了真人大头照，感觉不太好，往严重了说可能有法律风险。之后我们在楼下逛。快闪店说四点对没有预约的人开放，所以我就排着很长的队等。不过，m1saka和小哭败都说快闪店里已经没有东西了，所以我就没进去。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_155925.avif" alt="快闪店排队"></p><p>后来memory也从宾馆赶来了。一路上，我们收到了许多其他人发的物料。对我这种社恐而言，感觉平时没有什么人关注我，但在这种场合下，很多人会主动来找我，因此十分开心。小哭败还建议我下次cos灯，说这样会有不少人找我拍照。虽然也不是不可以，但我总怀疑自己的身材和颜值真的能撑住吗？逛累了，我们在电玩城坐了一会儿，m1saka帮我在邦邦手游里打歌，拿到了「顶点」称号。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_173235.avif" alt="世博源的玩偶"></p><p>六点多，我们就动身去会场了。memory进去后，我们就在外面等。这里隔音效果太好了，外面一点声音都听不到。去年暑假Roselia在上海静安体育中心的演唱会，我是隔着马路都能听到声音。我们进了建筑，先是在六楼转，看有没有什么地方能听到声音，但以失败告终。后来发现一楼的楼梯旁边能勉强听到一点声音，还有不少人在那里听。唱《春日影》的时候，不知道工作人员把什么门打开了，声音一下子清晰了不少，但只持续了几秒钟。我感觉这样听太受罪了，所以就在楼里逛。后来看到门口放着网关、交换机之类的，便凑近看了一会儿。几台交换机和网关就放在门口旁的柜子里，旁边还贴着一个二维码，扫出来是一串数字和字母，感觉不甚安全。但随即遭到了工作人员的质问，我只能悻悻离开。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_180157.avif","alt":"夜晚的梅赛德斯-奔驰文化中心","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_200949.avif","alt":"门口的网关和交换机","title":""}]</div>  </div><p>过了一会儿，我们三个去看了花篮。这时人不多，但光照比不上白天。我记得北航在先前某些演唱会上有过花篮，不知道为什么这次没有。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_203101.avif","alt":"花篮 1","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_203246.avif","alt":"花篮 2","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_203354.avif","alt":"花篮 3","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_203752.avif","alt":"花篮 4","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_203811.avif","alt":"花篮 5","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251011_204109.avif","alt":"花篮 6","title":""}]</div>  </div><p>最后，我们去了线下聚会，和北航的一些同学一起吃饭。有个同学lxh还骑车、坐轮渡到饭店，确实有点神，堪称铁人三项了。他们还模仿舞台现场，让饭桌的转盘转圈，感觉挺有趣的。</p><div class="video-container"><iframe src="https://www.youtube.com/embed/QCpMoMfohJA" frameborder="0" loading="lazy" allowfullscreen></iframe></div><p>有人领到了纪念币，感觉造型还可以，并且含有0.1g的金。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_000401.avif" alt="纪念币"></p><p>杕杜在群里开了视频，让我们给群友做自我介绍。不过，他认识七芬，<a href="/2025/06/30/My-First-Live-House-Experience-Between-Pulse-and-Solitude/" title="首次踏入live house：躁动氛围与孤独心声">上次live house似乎也是一起去的</a>，所以也认识我，就直接帮我介绍了。吃饭的时候，我还是很社恐，只讲了一两句话。毕竟和群友们暂时还不太熟悉。不过，听他们聊天，挺热闹，我感觉也还不错。据群友说，有人穿着《少女乐队的呐喊》的「不登校」衣服，就被辅导员还是老师讲了一顿。此外，还提到了「清华拳」事件的另一个版本。</p><p>吃完饭后，便打车回到了酒店。</p><h2 id="Day-2">Day 2</h2><p>今天早上，小哭败的导师还要开组会。杕杜说已经帮我买好了东西，我们两人便出发了。我则等待memory买东西，拿到为我代购的周边。一开始把目的地选错成「世博园A片区」，结果距离世博源还有段距离。领到了杕杜代买的周边，看了实物后，我感觉冰箱贴和手环也挺不错，于是又让memory帮我买。我随即换上了新T恤，虽然觉得不及前几次演唱会的好看，但也还可以。然后，我和小哭败又逛了逛，在《黑白双翼》的店里领了免费的卡组。</p><p>小哭败在上海还有同学，中午相约一起吃饭，于是我们便分开了。快闪店还有活动，说下载反诈软件并且注册，就能领这次演唱会的海报。我有点心动，问了问工作人员，但只有预约的人才能领，我没有资格。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_115536.avif","alt":"快闪店的MyGO!!!!!","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_115554.avif","alt":"快闪店的Ave Mujica","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_121119.avif","alt":"快闪店的MyGO!!!!! 2","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_120539.avif","alt":"快闪店推广反诈软件","title":""}]</div>  </div><p>拿到周边之后，应m1saka的邀请，我去了南京路的百联。memory因为早上已经去过了，所以不准备去。小哭败说他的同学来得比较晚，所以暂时也在那里。我们在百联逛了一会儿谷子店，我甚至感觉有些祛魅了。路上还看到了《明日方舟》和大白兔的联动。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_140725.avif" alt="《明日方舟》和大白兔联动"></p><p>随后，小哭败和他同学一起，我则和m1saka一起去吃午饭。他发现附近一家店有<a href="https://x.com/kohinatamika/status/1976638653628879201">蜜柑同款小笼包</a>，于是便在那里吃了。吃完后，我还在旁边的店里点了抹茶芭菲。等的时间挺长，但味道确实不错。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_144148.avif","alt":"小笼包","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_150630.avif","alt":"抹茶芭菲","title":""}]</div>  </div><p>吃完后，我们又赶回了世博源。m1saka也想去领卡牌，不过卡组已经没有了，只剩下单张牌。在店里，还看到了巨型高松灯。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_163741.avif" alt="高松灯及其玩偶"></p><p>接着是前往会场。据说昨天去得晚了，领不到应援棒，所以今天就提前一点。路上还看到有人用玩具车装玩偶，感觉有点神人。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_163928.avif","alt":"玩具车 1","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_164108.avif","alt":"玩具车 2","title":""}]</div>  </div><div class="video-container"><iframe src="https://www.youtube.com/embed/6KxMeOVuGbQ" frameborder="0" loading="lazy" allowfullscreen></iframe></div><p>m1saka也把自己的爱音玩偶摆在了车上。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_164812.avif" alt="车上的爱音"></p><p>会场的安检严格程度似乎有很大差异。我只带了个包，安检人员看了两秒，扒拉了一下，就让我进去了。我甚至感觉相机都能带进去。然而网上看到，有人穿着法批，被认为是和服，要求脱掉。后来发了一根应援棒，没有场控，还是24色，只有一个按钮。这意味着如果不小心切换了颜色，得再连续按下23次才能回到原来的颜色，感觉设计得不人性化。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_165946.avif" alt="入场"></p><p>我们的座位在北边，很靠近中间。感觉位置还不错，视野清晰，大屏幕也很清楚，前面没有人挡住视线。我的左边是一位女邦友，右边是小哭败。staff就站在我们前面，举着牌子，要求我们演出开始后不能拍照和录像。坐在后面的人还给我们发了物料，是像素风格的角色，我顺手拿了个灯的。舞台上有三组架子鼓，可能是除了sumimi之外，其他每支乐队都有自己专属的吧。演出开始前，工作人员念了两次观众须知，结果说「不能在头顶旋转应援棒」、「不能把玩偶高举超过胸部」之类的事项时，不少人跟着做，从某种意义上说，像是任务列表一样。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_171830.avif" alt="禁止盗摄的标志"></p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_171549.avif","alt":"舞台","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_175327.avif","alt":"现场","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_175312.avif","alt":"灯的痛包","title":""}]</div>  </div><p>节目单大致和<a href="https://zh.moegirl.org.cn/%E5%88%86%E6%AD%A7%E8%B7%AF%E5%8F%A3%EF%BC%8C%E5%89%8D%E9%80%94%E6%BC%AB%E6%BC%AB#DAY2_:_Geosmin">日本公演时</a>的相同。当灯光暗下，sumimi上场后，全场便沸腾了，我们也纷纷站起来。最开始是经典的《Here, the world!》，后来的《Sweet Escape》我好像没听过。舞台一直在转，一开始还对着我们。但距离确实有点远，只能看到大概的轮廓，所以还是看大屏幕更清楚一些。sumimi的舞台表现力确实不错，感觉她们很享受在舞台上的感觉。观众的氛围也很好，大家非常热情。我虽然不怎么会打call，但模仿着大家的动作，很能沉浸其中。经过报幕后，便是Ave Mujica的表演。</p><p>当MyGO!!!!!上场时，我心头为之一振。先前只能透过电脑屏幕看到的场面，如今却真实地展现在眼前，感觉非常震撼。灯的声音很有感染力，旁边的人也跟着应援、欢呼，在这种氛围之下，我真的难以抑制住自己的情绪。尤其是大屏幕上同时出现五个人的合影之时。然而，感觉可能是设备的问题，灯的声音有些小，和声也不是很清晰。在唱《碧天伴走》之时，羊的声音还断了。不过看大屏幕，她仍然在唱，并不是忘词。</p><p>随后播放了《Ave Mujica》CRYCHIC成员和解的情节，播放千早爱音在手机中的语音时，我感觉耳朵都要炸了，不知道是不是有意为之。《春日影》又是万人大合唱，不过我不知道具体的发音，所以只能跟着哼一哼。虽然有些人批评中国观众的合唱，但我不这么觉得。我感觉现场能听到其他人的合唱，而且不至于盖住主唱的声音，氛围挺好的。</p><p>之后，Ave Mujica和MyGO!!!!!各演奏了几首歌，歌曲就都唱完了。比较遗憾，《焚音打》的第一段副歌中，灯唱漏了一句词。可能是我对这首歌的期望太高了，无论是设备问题还是她本身的失误，感觉这首歌的表现只算差强人意。炸金花的场面，也让我颇为震撼与感动。最后是<a href="https://zh.wikipedia.org/wiki/MC_(%E9%9F%B3%E6%A8%82)">MC</a>环节，声优们逐个介绍自己、谈感受，还说了几句中文，感觉很可爱。不过有点抽象的是，大屏幕上一直都是禁止拍照录像的提醒，而不是转播画面，更没有实时转译字幕。对我来说距离太远、很难看清，同时也听不懂日语，体验不是很友好。另一方面，演出时各个乐队一直在唱歌，基本没有互动环节。此外，Day2的演唱会比Day1少了些流程，例如没有Ave Mujica的小剧场环节。</p><p>快乐的时光总是过得飞快，两个小时的演出很快就结束了。然后我和小哭败便去了第二天的线下聚会。由于要过江，没法骑车；考虑到地铁站的人很多，于是我们选择坐公交。另外几个人则是租了车，自己开车过去。会上交谈甚欢，我稍微放开了一些，交流了不少。吃饭时收到短信，飞机延误了一个小时，七点多才起飞。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_215057.avif" alt="线下聚会"></p><h2 id="Day-3">Day 3</h2><p>吃完饭后，就得考虑怎么回北京了。晚上好像没什么公交了，也没有订住宿的地方，而且时间很多，所以我和小哭败决定直接骑车去浦东机场。不过，共享单车在机场那边不能停，于是我在地图上找到了离机场最近的停放点——朝海村。我们先让メコン开车把我们送到了塘桥，然后开始骑车。</p><p>路上听歌的同时，我和小哭败还一直在聊天，聊演唱会、聊动漫、聊学校、聊生活。小哭败有点太嗨了，一度边骑车边打call。我们总共骑了四十多公里，花了四个小时，靠近四点时到达目的地。感觉这里前不着村、后不着店，尽管这在机场附近，时常还能看到起飞的飞机。但是由于在南边，没办法走路或者骑车过去，于是我们便打车。一开始用高德地图打车，等半天都不行；后来换成了滴滴，立即就打上了。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251012_234123.avif","alt":"塘桥","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_011200.avif","alt":"华夏中路","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_015149.avif","alt":"浦东运河","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_030936.avif","alt":"川南奉公路","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_032124.avif","alt":"盐朝公路","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_034435.avif","alt":"祝桥镇","title":""}]</div>  </div><p><img src="https://image.deepchirp.com/blog/2025/10/15/Screenshot_2025-10-15-14-37-56-992_net.osmand.plus.avif" alt="路线"></p><p>到了机场后，经过值机、安检，就到专门过夜的地方睡觉了。五点多开始睡，但六点被电话吵醒了。发现是高德打车没有取消，所以司机在找我们。但我清楚地记得，当时确实取消了订单，还有文字提示，可能是高德那边的bug吧。后来就睡不着了，于是开始刷手机。七点多小哭败醒了，我们去坐摆渡车，有人主动找我聊天，觉得我的痛包很好看，还拍了照片。随后便是登机。飞机还有早餐，感觉比火车餐好一些。</p><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_071907.avif","alt":"登机","title":""},{"url":"https://image.deepchirp.com/blog/2025/10/15/IMG_20251013_084621.avif","alt":"早餐","title":""}]</div>  </div><h2 id="感受">感受</h2><p>这几天确实非常愉快。对我而言，与演唱会相比，和同学一起出去更加弥足珍贵。作为社恐，我在学校几乎不参加活动，也很少与其他人交流——尤其是讨论自己喜欢的东西。例如，我们五人乘地铁前往火车站时和メコン开车时，大家都聊了聊如何接触的邦邦，不免让人热泪盈眶。虽然我也在维基百科上认识了一些热爱ACG的人，但那毕竟是线上，和线下真实见面的感觉还是有所区别。而北航的群友们以及现场素不相识的陌生人，对我都非常好。虽然，有许多「黑话」我听不懂（例如喜欢喊对方为「老师」或者「妈咪」），但这并不影响流露出的热情与善意。这次收到了不少物料，下次我其实也想制作一些。此外，大学很少有私人空间，这意味着我很难找到可以放松的环境，多数时候还是只能「伪装」自己。学校理应是个自由的环境，能够让每个人都展现出自己的个性。然而，北航前不久即<a href="https://mp.weixin.qq.com/s/7lzj7hnvnK3eGKfF7nHb7w">制裁了ACG飞梦社团</a>（<a href="https://web.archive.org/web/20251011075712/https://mp.weixin.qq.com/s/7lzj7hnvnK3eGKfF7nHb7w">网页存档</a>），虽然后来又声称是「传达过程中出现失误」，但不免让人心存疑虑：在学校究竟是否可以展现出自己真实的一面？而在上海，我能无拘无束地背着痛包、穿着MyGO!!!!!的衣服，不必在意他人的眼光，尽情地享受这一切。我觉得，这才能尽情地展现自我，才算是真正的自由。虽然事后听说，演唱会过程中有一些离谱的事情发生，但我觉得总体上还是可以接受的，不能因为少部分人或事，就否定整个群体。</p><p><img src="https://image.deepchirp.com/blog/2025/10/15/IMG_20251015_194440.avif" alt="收到的物料及购买的周边"></p><p>另一方面，这样出去玩真的可以抛却烦恼。在学校，总会有各种各样的事情缠绕着我。大多数时间，我都在处理学业上的事情，但实际上也不知道有什么作用。有时真的觉得，上几天学，学到的东西还不如往开源社区提个PR多。许多重要的东西，像是git、Docker之类，我似乎都是自学的，学校最多就是顺带提及。每天想着这些事情，不免会让人焦虑。而在上海的这几天，我暂时抛下学业相关的事情，真的轻松了不少。看到自己喜欢的声优，有什么理由不开心呢？在学校里出现的种种莫名其妙的症状，也都烟消云散了。这几天睡眠质量不佳，但状态却意外地好。或许，这就是所谓的「逃避」吧。但我觉得，偶尔逃避一下，也未尝不可。</p><p>邦邦着实改变了我的人生轨迹。一开始，我只是在七芬的推荐下接触了邦邦音游，感觉曲库很大，手感也不错，便开始玩了起来。说实话，我最开始只是把它当作普通的音游来玩，里面的剧情都没有看。而在今年过年时，注意到<a href="https://vcb-s.com/">VCB-Studio</a>压制了《BanG Dream! It’s MyGO!!!!!》，便去看了动画。当我看到高松灯整理黑板上的磁石时，我突然感觉，这个角色似乎和我有些相似。随后天文社中的爱灯互动，更是让我感同身受。<a href="https://zh.wikipedia.org/wiki/User:Peacearth">Peacearth</a>在看了我先前的博文后也提到：「能和灯深度共鸣的人，或许做这个测验（注：指<a href="https://www.rdos.net/china/">Aspie Quiz</a>）的分数都难免会很高XD……都没能成为人类了要怎么不影响生活」。评论员们提到，孤独症是灯的一大特征<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。我先前怀疑自己可能有阿斯伯格综合征，受到灯的鼓舞后，我才下定决心前去确诊。确诊后，我的心态确实改变了许多。</p><p>不过，灯毕竟是个虚拟角色，她也在乐队中找到了自己的位置。但对我而言，目前确实正站在「分歧路口」上。之后究竟要怎么做呢？目前在学院的GPA排名大约在30%，但保研显然是不可能了。在上海和学长们交流后，我还是更加坚定了考研的想法。毕竟，读研可以晚一点就业，还能有更多时间思考未来的方向。虽然也想过直接工作，但仍感准备不足。「前途漫漫」，唯有努力前行。</p><h3 id="盗摄">盗摄</h3><p>关于盗摄，我感觉有点把版权扩大化解释了。<a href="https://commons.wikimedia.org/wiki/Commons:Copyright_rules_by_subject_matter/zh#%E8%A1%A8%E6%BC%94%E6%B4%BB%E5%8B%95%E7%85%A7%E7%89%87">维基共享资源</a>上称：「您在音乐会上自己拍摄的照片被认为是可以接受的。我们认为这些照片不属于表演艺术家的<a href="https://zh.wikipedia.org/wiki/%E9%82%BB%E6%8E%A5%E6%9D%83">相关（相邻）权利</a>[……]。尽管如此：理想情况下，您应该能够出示表演者的明确许可才能拍摄和发布照片。谨防展示艺术舞台设计的音乐会照片：此类照片『不好』，因为它们可能侵犯了舞台设计师的版权。不过，表演艺术家的特写应该没问题。另一方面，您应该知道，在此处上传音乐会照片可能会违反您在购买门票时或作为入场条件所同意的条款。」此外，「<a href="https://commons.wikimedia.org/wiki/Commons:Copyright_rules_by_subject_matter/zh#%E5%8D%9A%E7%89%A9%E9%A4%A8%E5%8F%8A%E5%85%B6%E5%85%A7%E9%83%A8%E7%85%A7%E7%89%87">博物馆及其内部照片</a>」一章也提到了类似的思想：「如果博物馆的内部规则禁止摄影，违反该规则是摄影师和博物馆之间的问题，但不会影响图像的版权状态。如果博物馆的内部规则是一份有效的合同，它只会约束合同的双方：摄影师和博物馆。维基共享资源和所有其他第三方不受此类合同的约束。」</p><p>据此，如果有人拍了演员的图片，确实可以上传，在维基百科里使用。例如，维基百科上的「<a href="https://zh.wikipedia.org/wiki/%E9%99%B3%E8%95%BE%E6%BC%94%E5%94%B1%E6%9C%832024%E3%80%8A%E5%BF%B5%E3%80%8B">陈蕾演唱会2024《念》</a>」条目，就大量使用了现场照片，展现演唱会整体氛围和演出者。我觉得一律禁止拍摄似乎太过苛刻，用手机拍几张照片还是可以接受的；但是，用专业摄影设备，或是拍较长时间的视频应该是不合适的。另一方面，自己拍摄的品质显然不及官方，不会与之产生竞争关系。日本版权管理比较严格，例如日语维基百科甚至不允许「合理使用」的图片。我认为美国的「合理使用」制度比日本的列举式例外更灵活、更贴合现代互联网环境。日本的版权管理制度较为僵化且不利于二次创作、知识传播。从某种意义上说，这也是我喜爱开源社区的原因。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Farris C, Eisenbeis R, Dupree N, Silverman R, Beckett J. <a href="https://www.animenewsnetwork.com/preview-guide/2023/summer/bang-dream-its-mygo/.199235">The Summer 2023 Anime Preview Guide: BanG Dream! It’s MyGo!!!!!</a> [EB/OL]. Anime News Network, (2023-07-01)[2025-07-02]. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>MrAJCosplay, Moore C, Jones S. <a href="https://www.animenewsnetwork.com/feature/2023-12-30/the-best-anime-of-2023-mrajcosplay-caitlin-moore-steve-jones-the-best-songs-of-2023/.205681">The Best Anime of 2023 – MrAJCosplay, Caitlin Moore, Steve Jones + The Best Songs of 2023</a> [EB/OL]. Anime News Network, (2023-12-30)[2025-07-02]. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/10/15/From-Diverging-Crossroads-to-Endless-Journey-Reflections-on-the-Shanghai-Concert/</id>
    <link href="https://blog.deepchirp.com/2025/10/15/From-Diverging-Crossroads-to-Endless-Journey-Reflections-on-the-Shanghai-Concert/"/>
    <published>2025-10-15T09:55:41.000Z</published>
    <summary>本文记录了作者参加MyGO!!!!!和Ave Mujica的「分歧路口，前途漫漫」上海演唱会（鸡狗对邦）的经历，提到群体归属、自由等感受。</summary>
    <title>从「分歧路口」到「前途漫漫」：上海站观后</title>
    <updated>2025-10-15T11:54:43.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="评价" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E8%AF%84%E4%BB%B7/"/>
    <category term="动漫" scheme="https://blog.deepchirp.com/tags/%E5%8A%A8%E6%BC%AB/"/>
    <category term="东映动画" scheme="https://blog.deepchirp.com/tags/%E4%B8%9C%E6%98%A0%E5%8A%A8%E7%94%BB/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文封面图取自《少女乐队的呐喊》第13集，版权归制作方所有。</p></div><p>前几天我把《少女乐队的呐喊》看完了，回味无穷。毕竟我已经看了《孤独摇滚！》、《BanG Dream! It’s MyGO!!!!!》两部少女乐队动画，自然也会想看这部作品。此外，我在Spotify上听歌时，就时常会听到相关曲目，很符合我的胃口。事实上，这几部作品虽同是少女乐队题材，但叙事语气、情绪浓度差别很大。</p><p>写这篇文章前，我在维基百科上把<a href="https://zh.wikipedia.org/wiki/%E5%B0%91%E5%A5%B3%E6%A8%82%E5%9C%98_%E5%90%B6%E5%96%8A%E5%90%A7#%E5%90%84%E8%AF%9D%E5%88%97%E8%A1%A8">各集剧情</a>写完了，也是为了更好地理解这部作品。主角井芹仁菜在老家因帮助受到欺凌的同学，反而使自身遭到欺凌，身为教育家的父亲也不站在她这边。仁菜靠着乐队的歌曲，才逐渐走出阴影。但她仍无法压抑情绪，最终选择辍学，独自前往东京谋生。到达后，她一开始打算继续学习，但遇见了自己向往的偶像，转而走上音乐道路，组建了乐队「无刺有刺」。此外，她还意外发现当下热度较高的乐队「钻石星尘」主唱是她的高中旧友雏，但雏在面对欺凌现象时并不站在她这边，而是选择了沉默。在种种因素下，仁菜不愿输给「钻石星尘」，决定与之一决高下。</p><h2 id="感想">感想</h2><blockquote><p>教育はそうやって僕の人格をずっと認めやしないよ（看吧，教育永远不会认同我的品格）</p><p>正解の無い問題を僕に押し付けて（强迫我解出没有正确答案的问题）</p><p>「何もかもが分からない」そう、僕は一人叫んでいる（「我什么都不懂」 孤身一人的我如此大喊）</p><footer><strong>无刺有刺</strong><cite>《互相伤害 痛苦交加》</cite></footer></blockquote><p>我认为这部动画的主题之一，就是探讨何为正确。例如，「钻石星尘」和「无刺有刺」两支乐队，都面临着「个性」与商业化之间的矛盾。桃香正是因为不愿失去个性，才选择退出偶像乐队「钻石星尘」；她看到仁菜能够坚持自我，才主动邀约共建乐队。但「钻石星尘」确实取得了商业成功，其影响力远胜于「无刺有刺」。那么究竟哪条道路是正确的？这没有定论。</p><p>当初面对校园欺凌之时，仁菜选择挺身而出，但她的朋友雏并不支持她。雏认为这会让仁菜成为「下一个目标」，劝她别多管闲事。结果一语成谶。现实中何尝不是如此呢？俗话说「枪打出头鸟」，在面对不公时，选择沉默往往是最安全的做法，我不仅理解，甚至在多数情况下也会这么做。但是，也会有一小撮人选择挺身而出，哪怕惹上麻烦也在所不惜。「为众人抱薪者，不可使其冻毙于风雪」，我会坚定地选择支持他们。仁菜就是这样的「抱薪者」，理应得到家人的支持，但她的父亲作为教育家，却希望仁菜认错，换取大学保送机会以息事宁人。仁菜并不服气，始终认为自己是正确的，后续离开家乡、组建乐队等一系列行为，都是她坚持自我、证明自己的过程。另一方面，雏在仁菜受到欺凌后，还声称「都是仁菜的错」，从某种程度上也算是间接的欺凌者；而作为「钻石星尘」的新主唱，她在会上演唱象征着反欺凌的《空の箱》，这又是何等的讽刺。</p><p>作品里反复出现「没有标准答案的难题」，这让我很自然地联想到中国大陆的应试教育。标准化考试为了效率和可比性，总是要求「唯一正确」，而且更看重「别答错」而不是「能讲清楚」。在这样的环境下，出错的代价很高，名额又有限，于是大多数人选择沉默，即更安全的策略。仁菜选择站出来，结果付出了代价，但她至少守住了自我；雏选择沉默，从风险角度看确实更聪明。其实应试教育本身不一定是坏事，它也带来秩序和某种公平的机会。但当「唯一答案」变成价值判断的唯一尺度时，问题就出现了。就像《空の箱》里唱的那样，在没有标准答案的议题上，我们更该追问的，也许不是「谁对谁错」，而是「能不能找到一个可以自我说服、能和别人共存的答案」。我们初中的语文老师就很看重这一点，希望我们有自己的思想，而不被标准答案束缚。并且事实上，他也是这么做的。初中有篇课文《事物的正确答案不止一个》，就被他大加赞许。来到大学后，我本以为可以自由地探索知识，但事实上还是换了皮的应试教育，只不过不强制。成绩和绩点似乎仍是评价、评优的唯一标准。</p><p>证明自己「没有错」的过程或许并不美好，却很真实。因此，第10集让我格外动容。这一集中，仁菜经过他人的劝说，选择回到老家，试图与父亲和解。父亲一开始还说「你知道妈妈多难过吗」，即便作为旁观者，听到这句话也让我愤怒，感觉像是用亲情来绑架仁菜。不过后来，父亲意识到了自己的错误，选择带着仁菜与学校谈判，并且坚定地站在她这边。后来，她在房间和姐姐独处时提到，当时她都萌生了自杀念头，但是「钻石星尘」的歌拯救了她。在乐队中，仁菜通过歌唱来呐喊，「不管悲伤、喜悦、还是愤怒，全部投入歌中」。我上高中时，面对压抑且紧张的学习生活时，也常常觉得喘不过气来。虽然我当时不像仁菜那样有轻生的想法，但也意识到了音乐的力量：我感觉最轻松的时刻，就是晚上躺在床上听歌，一天的烦恼都融化在动听的音乐之中。她的姐姐还透露，在她离家后，父亲为她付出了很多。仁菜意识到，父亲其实是爱她的，只是方式不对。第二天，父亲认为「钻石星尘」的那首歌很好，并且支持仁菜的决定，父女俩终于和解。父亲从压制者到支持者的转变，我认为是全剧最动人的高潮。</p><p>乐队的曲目也很有感染力。与《孤独摇滚！》的「孤独」、《BanG Dream! It’s MyGO!!!!!》的「迷茫」不同，我认为本作的音乐多带有叛逆风格，流露出对主流文化的批判。正如剧中所说，「不管悲伤、喜悦、还是愤怒，全部投入歌中」。《<a href="https://www.youtube.com/watch?v=p2augTPjtYM&amp;">互相伤害 痛苦交加</a>》便是说要追求个性，不要为别人而活；《<a href="https://www.youtube.com/watch?v=MSmfAa_oSqE">熙熙攘攘、我们的城市</a>》则是在破败与绝望中继续坚持，虽然看不见希望，但只要还有「未完成的心跳」，就要去伸手、去触碰、去照亮黑暗；《<a href="https://www.youtube.com/watch?v=gpCHjSaetds">空の箱</a>》也表达了对所谓「正确答案」的质疑，以及对自我存在的执着。除了这种比较「燃」的作品，还有细腻的情歌，例如《<a href="https://www.youtube.com/watch?v=8SRJnOFicAM">蝶に結いた赤い糸</a>》就让我感到很「甜」。片尾曲《<a href="https://www.youtube.com/watch?v=dJottC7FmYc">正因为是无法成为他人的我</a>》感觉节奏起先很舒缓，后来迸发出了「即使无法成为其他人，也要相信自己」的强烈信念，放在结尾让人意犹未尽。</p><h2 id="吐槽">吐槽</h2><p>尽管我很喜欢这部作品，不过感觉剧情上还是有些瑕疵。例如，第一集结尾处，仁菜抱着吉他在雨中寻找桃香，虽然能理解拿着吉他是为了引出最后的歌唱情节，但我为淋雨的吉他感到十分担忧；在其歌唱部分，我不仅觉得电吉他在雨中插电演奏很危险，而且似乎凭空冒出了贝斯声？不过，这段剧情的情感渲染比较到位，《空の箱》也很好听。此外，末尾两集感觉节奏有些急促，尤其是最后一集，有种戛然而止的感觉。制作人平山理志也说，实际上没有为之后的剧情做打算。live部分也被压缩得太短了，感觉效果甚至不如11集。虽然《Ave Mujica》饱受批评，但它最后一集都在开演唱会，看起来还是挺爽的。我觉得把OP或是ED去掉，让live更长一些会好些。</p><p>动画全部使用3DCG技术<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>，还采用了动作捕捉技术<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。我一开始看不习惯，可能先前看的多是2D动画，但后来慢慢也能接受了。酒井和男也坦言，这种作画方式会有「怪异感」<sup class="footnote-ref"><a href="#fn2" id="fnref2:1">[2:1]</a></sup>。《It’s MyGO!!!!!》虽然也采用了3D，但在此基础上又补充了手绘，我并没有感到违和<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>。此外，不知道为什么，总觉得动画中live的临场感有所欠缺，尤其是在声音方面，和听专辑的体验大差不差。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>東響希. <a href="https://0115765.com/archives/86941">ガルクラ総研③：立ち塞がるハードルにどう挑んだ？監督と制作Pに訊く「ガールズバンドクライ」アニメ制作秘話</a> [EB/OL]. オタク総研, (2024-08-25)[2025-10-07]. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>前田久. <a href="https://febri.jp/topics/girls-band-cry_int_02_03/">シリーズディレクター・酒井和男が振り返る『ガールズバンドクライ』の画づくり③</a> [EB/OL]. Febri, (2024-10-02)[2025-10-07]. <a href="#fnref2" class="footnote-backref">↩︎</a> <a href="#fnref2:1" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>杉本穂高. <a href="https://realsound.jp/movie/2024/10/post-1814313.htm">サンジゲン 松浦裕暁が語る、CGアニメの現在地 『MyGO!!!!!』の“ハイブリッド”な魅力</a> [EB/OL]. リアルサウンド 映画部, (2024-10-19)[2025-10-07]. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/10/07/Girls-Band-Cry/</id>
    <link href="https://blog.deepchirp.com/2025/10/07/Girls-Band-Cry/"/>
    <published>2025-10-07T14:23:22.000Z</published>
    <summary>本文结合剧情与音乐，探讨《少女乐队的呐喊》中校园欺凌、亲子矛盾、个性与商业化的抉择等情节，分享了作者的共鸣、思考、吐槽。</summary>
    <title>《少女乐队的呐喊》短评</title>
    <updated>2025-10-07T14:23:22.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Android" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/Android/"/>
    <category term="教程" scheme="https://blog.deepchirp.com/tags/%E6%95%99%E7%A8%8B/"/>
    <category term="小米" scheme="https://blog.deepchirp.com/tags/%E5%B0%8F%E7%B1%B3/"/>
    <category term="单页应用" scheme="https://blog.deepchirp.com/tags/%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8/"/>
    <category term="前端路由" scheme="https://blog.deepchirp.com/tags/%E5%89%8D%E7%AB%AF%E8%B7%AF%E7%94%B1/"/>
    <category term="调试" scheme="https://blog.deepchirp.com/tags/%E8%B0%83%E8%AF%95/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/112629872">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/40037792">潘潘没有Hp</a>。</p></div><div class="note danger flat"><p>根据网友反馈，在获取学校列表时会发生错误。经测试，对应的API直接返回405错误，故此方法可能已失效。</p></div><div class="note info flat"><p>本文方法与<a href="https://web.vip.miui.com/page/info/mio/mio/detail?postId=51260514">小米社区上的教程</a>所描述的操作一致，原文由<a href="https://web.vip.miui.com/page/info/mio/mio/homePage?uid=2182856887">靠墙的钴-60</a>撰写。本文加入了自行探究的过程。</p></div><h2 id="方法">方法</h2><ol><li>在「小爱课程表」下方的导航栏中点击最右边的头像，进入设置。然后滑动至最下方，连续点击5次空白处，即图中的红框位置，进入Debug页面。</li><li>下滑，启用「vConsole」选项，然后点击右下角绿色的按钮。</li><li>在下方红框所示的command中输入<code>window.location.hash='/import'</code>，并按右侧的「OK」。</li><li>这时页面会跳转到「教务导入」界面，可点击下方的「Hide」隐藏vConsole界面。</li><li>若要隐藏右下角的「vConsole」按钮，可以重新按照第1步进入Debug页面，随后禁用vConsole选项。</li></ol><div class="gallery-container" data-type="data" data-button="" data-limit="10" data-first="10">    <div class="gallery-items">[{"url":"Screenshot_2025-09-07-22-44-17-817_com.miui.voiceassist.avif","alt":"连续点击5次红框所示的空白处","title":""},{"url":"Screenshot_2025-09-07-22-45-01-116_com.miui.voiceassist.avif","alt":"打开vConsole并点击绿色按钮","title":""},{"url":"Screenshot_2025-09-07-22-46-10-178_com.miui.voiceassist.avif","alt":"输入相关命令并按「OK」","title":""},{"url":"Screenshot_2025-09-07-22-46-29-173_com.miui.voiceassist.avif","alt":"点击「Hide」隐藏vConsole界面","title":""},{"url":"Screenshot_2025-09-07-22-46-39-788_com.miui.voiceassist.avif","alt":"进入「教务导入」页面","title":""}]</div>  </div><h2 id="探究">探究</h2><p>明天就要开学了。小米「超级小爱」中的「小爱课程表」很实用，不仅比学校的课程表更直观，还会在上课前提醒。不过，今天准备导入课程表时，发现「教务系统导入」功能被关闭，说是产品技术方案调整，建议使用拍照导入。据<a href="https://web.vip.miui.com/page/info/mio/mio/detail?postId=49251538">小米社区一篇贴文所述</a>，这个功能在今年4月份就已经下线了。这个功能挺好的，我不能理解为何要下线。可能是因为获取了第三方网站的数据？然而，作为替代方案的拍照导入却不尽人意，我尝试了几次，都是识别失败。</p><p><img src="/2025/09/07/Restore-the-Academic-Import-Feature-in-XiaoAi-Schedule/Screenshot_2025-09-07-22-56-54-694_com.miui.voiceassist.avif" alt="提示功能即将下线"></p><p>说实话，我一开始并没有什么思路。不过考虑到，课程表只能在线使用，并且在「超级小爱」中似乎并未找到相关活动，因此我觉得这个功能是<a href="https://zh.wikipedia.org/wiki/%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8">单页应用</a>。我还推测，教务导入只是禁用了入口，相关页面应该仍可打开，应该没有做其他校验。我先是尝试用Chromium对应用的WebView做<a href="https://developer.chrome.com/docs/devtools/remote-debugging/webviews">远程调试</a>，但并未找到相关进程，可能是生产版未<a href="https://developer.android.com/reference/android/webkit/WebView#setWebContentsDebuggingEnabled(boolean)">启用相关配置</a>。随后我便使用<code>apktool</code>静态解包，并在其中搜索关键词「课程表」，于<code>h5_pad_config.json</code>文件中发现了这样的配置：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/h5/precache/ai-schedule/&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;des&quot;</span><span class="punctuation">:</span> <span class="string">&quot;课程表&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure><p>我猜这里的<code>path</code>应该是网页路径的一部分，但需要找到完整路径。随后查找<code>ai-schedule</code>，发现设置界面所对应的页面为<a href="https://i.xiaomixiaoai.com/h5/precache/ai-schedule/#/setting">https://i.xiaomixiaoai.com/h5/precache/ai-schedule/#/setting</a>。「教务导入」与「设置课程背景」应该类似，都是打开了新界面，而后者能正常使用；点击时，路由会更改为<code>/choose-bg</code>。我想，「教务导入」应该也是一个新的路由，只要找到就万事大吉。因此，我在浏览器的调试器中搜索<code>/choose-bg</code>，发现以<code>umi</code>开头的某一js脚本中写了按钮与路由的映射关系。虽然没能直接找到路由，但我观察到「通过分享导入课表」的按钮路由为<code>/import</code>，此外还有一些路由是以<code>import_</code>开头。我想「教务导入」的路由多少会与<code>import</code>相关，便开始尝试。第一次即尝试了<code>/import</code>，运气很好，直接进入了「教务导入」页面。</p><p>下一个关键的问题是，如何在「超级小爱」中打开这个页面呢？我想，应用中应该有类似于浏览器Console的东西。在小米社区搜索时，发现<a href="https://web.vip.miui.com/page/info/mio/mio/detail?postId=51439309">小爱课程表中可以使用vConsole</a>，而相关推荐中即有<a href="https://web.vip.miui.com/page/info/mio/mio/homePage?uid=2182856887">靠墙的钴-60</a>所提到的操作方法，与我的想法不谋而合。按其方法操作，能够打开「教务导入」页面。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/09/07/Restore-the-Academic-Import-Feature-in-XiaoAi-Schedule/</id>
    <link href="https://blog.deepchirp.com/2025/09/07/Restore-the-Academic-Import-Feature-in-XiaoAi-Schedule/"/>
    <published>2025-09-07T15:55:01.000Z</published>
    <summary>小米「超级小爱」的课程表中，「教务系统导入」功能已然下线。本文将介绍如何通过调试手段打开该功能，同时也分享了探究过程。</summary>
    <title>恢复小爱课程表的「教务导入」</title>
    <updated>2025-12-26T12:26:22.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="北航" scheme="https://blog.deepchirp.com/tags/%E5%8C%97%E8%88%AA/"/>
    <category term="编程" scheme="https://blog.deepchirp.com/tags/%E7%BC%96%E7%A8%8B/"/>
    <category term="设计模式" scheme="https://blog.deepchirp.com/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
    <category term="Rust" scheme="https://blog.deepchirp.com/tags/Rust/"/>
    <category term="软件工程" scheme="https://blog.deepchirp.com/tags/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/"/>
    <content>
      <![CDATA[<div class="note info flat"><p>相关代码已上传至GitHub，地址：<a href="https://github.com/saitewasreset/BUAA-SE-2025-Project-Group4-SwiftJourney">https://github.com/saitewasreset/BUAA-SE-2025-Project-Group4-SwiftJourney</a>。</p></div><h2 id="开发">开发</h2><p>上学期的「软件工程基础」，要求我们以小组为单位，完成给定的项目。由于是自由组队，我们几个认识的自然组成了一组，分到了「风行旅途」的开发任务。这是在线火车购票旅游系统，用于线上的火车购票、酒店预订、火车订餐，类似于12306（具体需求<a href="Requirements.pdf">见此</a>）。我们给其的英文名为「SwiftJourney」，因为「Swift」有「迅捷」之意。</p><p>项目初期，我们先确定了技术栈。我和<a href="https://github.com/saitewasreset">saite</a>负责后端，而前端由其他三位组员负责。他们自然选择了Vue，因为先前有过相关的开发经验。我们选择了Rust，因为saite对Rust比较熟悉，我在先前的寒假中也学习了一些。Rust的性能和安全性都很出色，比较适合我们的项目，也贴合了「Swift」（迅捷）的特点；不过它的学习曲线确实很陡峭<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。</p><p>先前的面向对象课程中，大作业是组队开发Java项目，我们选择<a href="https://github.com/Lancezer/BidTurmoil">复刻游戏《竞宝风云》</a>（出自综艺节目《魔方新世界》）。不过，当时任务分配不甚均衡，且学期中还有其他事务，因此只能在最后几天连夜赶工，在最终展示时还出现了bug，不甚顺遂。汲取了先前的教训，这次我们一开始就制订了团队成员准则、分配了任务，还确定了每周进度目标。由于平时课程中就使用华为云的CodeArts，我们也就自然沿用了这个系统，管理项目并分配工作项。不过，我认为这个系统太过复杂了，每个用户有多种不同类别的ID，在不同操作中需要使用的ID类型都不同，且缺少明确指引，把其他人拉进项目也是难上加难，花了几十分钟才搞定。有次课下实践是使用CodeArts，不少同学也如此抱怨。</p><p>其实我对架构之类的宏观设计理解很差，只能依靠其他人，<a href="/2025/07/04/Gazing-Through-Mirrors-Tracing-the-Diagnostic-Path-of-Aspergers-Syndrome/" title="窥探镜中的自己：阿斯伯格综合征的诊断轨迹">这可能是因为我过于专注细节的缘故</a>。在saite的推荐之下，后端采用了<a href="https://zh.wikipedia.org/wiki/%E9%A0%98%E5%9F%9F%E9%A9%85%E5%8B%95%E8%A8%AD%E8%A8%88">领域驱动设计</a>，以期更好地应对复杂业务逻辑，同时也是方便后续改造。不过其实我们都没接触过，只能根据网上的资料摸索。最开始，我根本不知道应该从何入手，后来在saite的指导之下，我才有了些许头绪。</p><p>saite后来如此总结道：</p><blockquote><p>实际上，我在设计时根本不清楚软件工程的基本流程（当时「软件工程基础」课程才刚开始，还未完成对需求分析、概要设计、详细设计等内容的介绍），甚至并不清楚在着手写代码前总体设计的重要性。在看了「领域驱动设计」的大致概念与几篇教程后便直接开始创建数据库、编写代码（虽然同一学期还安排了「数据管理技术」课程，但当时的课程进度并未介绍到数据库设计理论相关内容，在设计项目数据库时，我甚至并不知道3NF等范式）。课程结束之后回顾，才发现我忽略了战略（Strategy）层面设计，例如划分限界上下文、统一语言（Ubiquitous Language）制定等，而只注意了战术（Tactical）上的设计模式<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>，导致一些问题，例如Entity设计不合理（特别是关于火车订票的相关实体）、Domain Service间耦合程度太高、Application Service的拆分并未明确对应用例。虽然存在上述诸多问题，但由于「软件工程基础」课程只要求实现单体应用，服务、数据库表之间关联程度较大也不太影响结果。而在之后的「软件工程基础实践」（小学期）中，要求编写单元测试、拆分微服务（独立数据库），相关问题才完全暴露出来。</p></blockquote><div class="mermaid-wrap"><pre class="mermaid-src" data-config="{}" hidden>    flowchart TD  USER[用户&#x2F;客户端]  subgraph Interface[&quot;Interface｜统一入口&quot;]    direction LR    API[写操作API]    QRY_API[读操作API]  end  USER --&gt; API  USER --&gt; QRY_API  subgraph main[&quot;核心流程&quot;]    direction LR    subgraph WriteModel[&quot;写模型（命令侧）&quot;]      APP[应用服务] --&gt; AGG[聚合&#x2F;实体&#x2F;值对象]      APP -- 依赖 --&gt; REPO_PORT[仓储端口]      APP -- 依赖 --&gt; EXT_PORT[外部服务端口]      AGG -- 产生 --&gt; EV[领域事件]      subgraph Infra[&quot;Infrastructure｜技术实现&quot;]        REPO_IMPL[(仓储实现)]        EXT_ADAPTER[[外部适配器]]        ACL_IMPL[&#x2F;防腐层&#x2F;]        BUS[(消息总线)]      end      EV --&gt; BUS      REPO_PORT -.-&gt; REPO_IMPL      EXT_PORT -.-&gt; EXT_ADAPTER    end    subgraph ReadModel[&quot;读模型与外部依赖&quot;]      PRJ[(投影／读模型)]      style PRJ fill:#E3F2FD,stroke:#90CAF9,stroke-width:2px      DB[(数据存储)]      OTHER_CTX[[其他上下文OHS]]    end  end  API --&gt; APP  QRY_API --&gt; PRJ  REPO_IMPL --&gt; DB  BUS -- 订阅 --&gt; PRJ  APP --&gt; ACL_IMPL --&gt; OTHER_CTX  </pre></div><p>对我而言，另一个困难之处是对Rust并不十分熟悉。我只是把《<a href="https://course.rs/">Rust语言圣经</a>》中的基础部分学习完了，而且也不敢说非常扎实。写项目时，我最头疼的就是类型转换。例如错误类型就有<code>ServiceError</code>、<code>RepositoryError</code>、<code>GeneralError</code>，使用到了<a href="https://crates.io/crates/anyhow"><code>anyhow</code></a>、<a href="https://crates.io/crates/tracing"><code>tracing</code></a>等库。虽然现在来看也没有什么，但当时我对特征对象也比较陌生，看代码就如同看天书一般，复制粘贴的其他文件代码也往往无法直接使用。此外，可能由于项目过于复杂，又或是Rust的相关资料比较少，AI也无法提供太多帮助。还有一处麻烦的地方是，如果需要更改某个服务所需的外部依赖，那就需要修改对应的泛型参数列表，散布多处，十分繁琐。尽管如此，我觉得Rust的报错信息相对清晰，能够帮助我定位问题。</p><p>在开发过程中，还遇到了烦心事。我负责收集、生成数据，包括车站、车次等。由于车次采用了真实数据，在生成火车餐时，产出的json文件大小接近1GB，然后使用Git LFS将其上传到仓库中。后来在saite的建议之下，还是采用了压缩包的方式。然而，原先的json文件始终占用着存储空间，即使我使用了强制推送，确保没有任何commit中有对该文件的引用，可仓库的体积仍然没有改变。而免费版的仓库只有1GB存储空间——过了几天，代码完全提交不上去了。当时查阅了华为云的文档，没有看到相关信息；联系客服并等待数小时后，也被告知无法删除。与之形成对比的是，<a href="https://docs.github.com/zh/repositories/working-with-files/managing-large-files/removing-files-from-git-large-file-storage">GitHub的文档</a>中就提到，可以联系支持人员删除Git LFS对象。当时担心工作项等丢失，于是选择充钱升级华为云仓库。此外，开发期间还遇到<a href="https://blocksandfiles.com/2025/06/19/minio-removes-management-features-from-basic-community-edition-object-storage-code/">MinIO社区版的Console去除了多数管理、配置功能</a>，因此我们一怒之下使用脚本自动化配置。</p><p>虽然最终并没有完全实现所有功能，但总体来说也还不错。后端在期末周之前就写完了，并且也没太多致命错误。中转、换乘查询的算法是由AI写的，速度很快，即便使用了中国大陆的真实数据，也能在一秒内给出结果。前端人员在学期中有些忙碌，不过紧赶慢赶，最终也是写完了。展示时，老师和助教都肯定了我们的项目。老师还惊异于我们的技术选型，尤其是为什么要用Rust，而不是常用的Java等。我当时直接引用「软件工程基础」课程PPT中的回答，「作为学生，应当积极尝试新兴技术」，老师对这个回答非常满意🐶。</p><p><img src="/2025/09/06/Beihang-Software-Engineering-Notes-Building-SwiftJourney-with-Rust/ticket_search.avif" alt="查询车票界面"></p><div class="video-container"><iframe src="https://www.youtube.com/embed/DTRi1QXv19w" frameborder="0" loading="lazy" allowfullscreen></iframe></div><h2 id="改造">改造</h2><p>软件学院在暑假末会开设「软件工程基础实践」课程（俗称「小学期」），要求在先前项目的基础上做改造。这应该也是学院的特色吧。这次主要的要求是将后端拆分为微服务，为后端写单元测试，并且要部署CI/CD流水线，执行集成测试、压力测试。其实我猜课程团队是希望前端成员负责流水线，但对我们来说，项目本身就使用了Docker，改造成k8s部署也并不复杂，<s>使用AI可很快完成</s>。所以对于后端的压力还是更大些。也因此，另一位刚学会Hello World的组员加入后端团队，负责写单元测试。他一直抱怨我们先前写的代码是「屎山」，还吐槽测试样例的mock很复杂。我前几天学习了如何写测试，但后来发现AI生成得非常好，根本就不需要改动代码。单从项目的角度来说，算是白费了力气。</p><p>然而，由于saite个人的身体原因，他在课程初期无法投入过多精力，导致后端进展受阻，尤其是拆分微服务。如前所述，我拙于宏观把控，只能等待他制订拆分方案。而前端虽相对轻松，但缺乏后端经验，也是心有余而力不足。至结束期限前几天，我们才制定出了明确的拆分方案，开始拆分。我们计划拆出7个微服务，如图所示：</p><!-- markdownlint-disable no-inline-html --><div class="mermaid-wrap"><pre class="mermaid-src" data-config="{}" hidden>    flowchart LR  Client([&quot;外部客户端／前端&quot;]):::client  UserSvc[&quot;User (Err:90xxx)&lt;br&#x2F;&gt;• 注册、登录、登出&lt;br&#x2F;&gt;• 会话与口令校验&lt;br&#x2F;&gt;• 用户、个人信息&quot;]:::svc  GeoSvc[&quot;Geo (Err:91xxx)&lt;br&#x2F;&gt;• 城市、车站查询&lt;br&#x2F;&gt;• 城市、站点映射维护&quot;]:::svc  TrainSvc[&quot;Train (Err:92xxx)&lt;br&#x2F;&gt;• 直达、换乘查询&lt;br&#x2F;&gt;• 车次、时刻、席位校验&lt;br&#x2F;&gt;• 列车类型配置&quot;]:::svc  HotelSvc[&quot;Hotel (Err:93xxx)&lt;br&#x2F;&gt;• 酒店搜索、评分&lt;br&#x2F;&gt;• 预订、占房&quot;]:::svc  DishSvc[&quot;Dish (Err:94xxx)&lt;br&#x2F;&gt;• 车上、外卖餐查询&lt;br&#x2F;&gt;• 库存管理&lt;br&#x2F;&gt;• 与车次联动校验&quot;]:::svc  OrderSvc[&quot;Order (Err:95xxx)&lt;br&#x2F;&gt;• 下单、支付、退款&lt;br&#x2F;&gt;• 订单聚合、状态机&quot;]:::svc  ObjStore[&quot;ObjectStorage (Err:96xxx)&lt;br&#x2F;&gt;• put&#x2F;get&#x2F;delete对象存取&lt;br&#x2F;&gt;• 数据装载辅助&quot;]:::svc  Client --&gt; UserSvc  Client --&gt; GeoSvc  Client --&gt; TrainSvc  Client --&gt; HotelSvc  Client --&gt; DishSvc  Client --&gt; OrderSvc  TrainSvc -. 数据装载 .-&gt; ObjStore  HotelSvc -. 数据装载 .-&gt; ObjStore  </pre></div><!-- markdownlint-enable no-inline-html --><p>从理论上来说，微服务的好处是可独立部署、降低耦合<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>。但由于已有的架构问题，按照我们的方法拆分微服务，基本就是将可在内存中完成的跨Service调用，改为使用HTTP在微服务之间完成。这不仅没什么好处，还降低了系统的整体性能，只是为了满足课程要求，是典型的「分布式单体」反模式。拆分过程可以说是苦力活，但AI并不能帮上忙：尽管有详尽的拆分方案文档，可它总是乱写一气。在展示的前一天，我们才勉强拆分完，随即发现系统有诸多bug。虽然一直修到晚上，但还是存在问题。直到展示结束后，才基本把问题处理完。</p><p>不过展示时，老师和助教都认为我们的项目挺不错。老师最后还问我们：「如果再让你们重新写一遍项目，你们还会选Rust吗？」我们都只是在笑，根本无法回答这个问题。虽然有队友开玩笑称，如果当初选择Python或是Java，就不会有这么多问题。不过saite觉得，架构设计的错误以及人员分工的不合理，才是问题的主要原因，而不是Rust。虽然从某种意义上讲，选择Rust也是导致人员分工不合理的原因之一。对我而言，如果选用其他简单的语言，确实能快速完成课程任务，但用Rust写这个项目，确实收获了许多。</p><div class="video-container"><iframe src="https://www.youtube.com/embed/KKr-u9W9wNk" frameborder="0" loading="lazy" allowfullscreen></iframe></div><p>saite还吐槽了此类团队作业。虽然明面上都有权重分配，但事实上也没什么作用，除非是一点都不做，否则权重基本上都是1。他还称，从之前的团队分工中的问题中得到的经验，在面临新的问题时总显得无用，最后回顾，还是每次都觉得犯了一堆错误（或许，这就是学习吧）。他还认为，在团队项目中，最好不要产生「有靠山」的感觉，这样会产生懈怠。据说这学期的「软件系统分析与设计」会有十余人的团队作业，真是令人头大。「人类在神圣的沉默当中学会历史」，项目结束后，我们很少再激烈地讨论当初的选择；而团队合作的种种教训，都已内化为我们无声的经验。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Blanco-Cuaresma S, Bolmont E. What can the programming language Rust do for astrophysics [J/OL]. Proceedings of the International Astronomical Union, 2017, 12(S325): 341–344. DOI: <a href="https://doi.org/10.1017/S1743921316013168">10.1017/S1743921316013168</a>. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>Perkel J M. Why scientists are turning to Rust [J/OL]. Nature, 2020, 588(7836): 185–186. DOI: <a href="https://doi.org/10.1038/d41586-020-03382-2">10.1038/d41586-020-03382-2</a>. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>Evans E. Domain-Driven Design: Tackling Complexity in the Heart of Software [M]. Upper Saddle River: Addison-Wesley, 2003. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>Newman S. Building Microservices: Designing Fine-Grained Systems [M]. 2nd ed. Sebastopol: O’Reilly Media, 2021. <a href="#fnref4" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/09/06/Beihang-Software-Engineering-Notes-Building-SwiftJourney-with-Rust/</id>
    <link href="https://blog.deepchirp.com/2025/09/06/Beihang-Software-Engineering-Notes-Building-SwiftJourney-with-Rust/"/>
    <published>2025-09-06T12:42:10.000Z</published>
    <summary>本文讲述了作者在北航的软件工程课程和「小学期」中，用Rust开发线上铁路购票系统的经历，并记录了架构失误、团队协作等体会。</summary>
    <title>北航软件工程小记：用Rust开发「风行旅途」</title>
    <updated>2025-09-10T02:12:35.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="个人" scheme="https://blog.deepchirp.com/tags/%E4%B8%AA%E4%BA%BA/"/>
    <category term="博客" scheme="https://blog.deepchirp.com/tags/%E5%8D%9A%E5%AE%A2/"/>
    <category term="写作" scheme="https://blog.deepchirp.com/tags/%E5%86%99%E4%BD%9C/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/101462757">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/420509">necömi</a>。</p></div><p>写作是不断做选择的过程：要不要在中西文间加空格？是用直角引号还是弯引号？这些看似细节的决定，能够塑造文章的整体风格。如同公司制订统一的代码风格一般，维基百科有一整套格式手册来保证一致性。相比之下，个人博客更自由，但自由不代表随意。为了阐述我的语言风格、避免排版混乱，我希望制定一份属于本站的风格手册。</p><h2 id="标点">标点</h2><p>首先需要做到正确输入标点（可见<a href="https://sspai.com/post/45516">少数派的一篇文章</a>，提到了常被误输入的符号）。关于标点符号的用法，我参考了《<a href="http://www.moe.gov.cn/ewebeditor/uploadfile/2015/01/13/20150113091548267.pdf">标点符号用法（GB/T 15834—2011）</a>》，但有些地方不同：</p><ul><li><p><strong>标有引号或书名号的并列成分之间使用顿号</strong><br>国标的4.5.3.5称：「标有引号的并列成分之间、标有书名号的并列成分之间通常不用顿号。若有其他成分插在并列的引号之间或并列的书名号之间（如引语或书名号之后还有括注），宜用顿号。」教育部语言文字信息管理司如此解释：</p><blockquote><p>首先从表达功能上看，并列的引号之间无论实际上有没有停顿，不使用顿号都不会造成理解上的困难；其次，当所引内容比较多或者所引内容本身已经带有标点符号时，如果并列的引号之间再使用顿号，不仅形式上不美观，也降低了符号的表达效率。而且从编辑出版的技术处理角度看，各个出版社也多采用并列的引号之间不使用顿号的处理方式。如《出版校对培训教程》中就指出：「因为引号在视觉上有分隔作用，可以避免『满纸黑瓜子（顿号）』。」另外，从经济美观的角度出发，在同时引用大量同类并列成分、而并列成分本身又比较简单的情况下，可以将多个并列成分放在一组引号之内。这时，由于没有了引号的间隔作用，并列成分之间应使用顿号隔开。有时会出现别的成分插在并列的引号之间（如引语之后有括注时），这时为了避免理解的困难，需要使用顿号。</p><footer><strong>教育部语言文字信息管理司</strong><cite>《〈标点符号用法〉解读》，第60—61页</cite></footer></blockquote><p>事实上，仍有知名出版物并未遵循此规定，例如《现代汉语词典》（第七版）的【四书】词条：「指《大学》、《中庸》、《论语》、《孟子》四种书。是儒家的主要经典。」（<a href="https://archive.org/details/modern-chinese-dictionary_7th-edition/page/4240/mode/2up">第1241页</a>）《<a href="https://www.gov.cn/xinwen/2020-06/01/content_5516649.htm">民法典</a>》也有：「本法自2021年1月1日起施行。《中华人民共和国婚姻法》、《中华人民共和国继承法》、《中华人民共和国民法通则》、《中华人民共和国收养法》、《中华人民共和国担保法》、《中华人民共和国合同法》、《中华人民共和国物权法》、《中华人民共和国侵权责任法》、《中华人民共和国民法总则》同时废止。」（第一千二百六十条）个人认为，引号和书名号在此处为标号，而顿号为点号，不能因标号能够标示清楚，就忽略顿号的使用。此外，有不少人喜欢在最后两个并列成分间使用「和」，在这种情况下，略去顿号更显奇怪。如：</p><blockquote><p>《红楼梦》《三国演义》《西游记》和《水浒传》是我国长篇小说的四大名著。</p></blockquote><p>一眼看过去，可能会以为前三项与最后一项分属不同类别。综上所述，本人在此种情况下会使用顿号。而唯一的问题可能就是没有标点挤压，略显拖沓。</p><p>不过，<a href="https://zh.wikipedia.org/wiki/User:%E8%87%AA%E7%94%B1%E9%9B%A8%E6%97%A5">自由雨日</a>称，按照国标可以表示更小的停顿层次，也有一定道理。如：</p><blockquote><p>最喜欢的作品：Rachmaninoff（拉赫玛尼诺夫）《c小调第二钢琴协奏曲》《d小调第三钢琴协奏曲》、Chopin（肖邦）《e小调第一钢琴协奏曲》。</p></blockquote><p>而我在这种情况下选择使用逗号表示不同作家间的分割，若有更大的层次则直接使用分号：</p><blockquote><p>最喜欢的作品：Rachmaninoff（拉赫玛尼诺夫）《c小调第二钢琴协奏曲》、《d小调第三钢琴协奏曲》，Chopin（肖邦）《e小调第一钢琴协奏曲》。</p></blockquote><p>延伸阅读：</p><ul><li>张国功. 标有引号的并列成分之间顿号使用规范商榷 [J/OL]. 现代语文, 2023(9): 78–83. CNKI <a href="https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFN&amp;filename=YWLY202309012">YWLY202309012</a>.</li><li>犊犊. <a href="https://www.jlao.net/translation/10516/">救救顿号！——与《标点符号用法》商榷</a> [EB/OL]. 犊犊的小棚棚, (2021-10-12)[2025-08-31].</li></ul></li><li><p><strong>使用直角引号代替弯引号</strong><br>其实国标要求使用横排时使用弯引号（<code>“”‘’</code>），但个人倾向于直角引号（<code>「」『』</code>）。试举一例：</p><blockquote><p>「老师，『有条不紊』的『紊』是什么意思？」</p><p>“老师，‘有条不紊’的‘紊’是什么意思？”</p></blockquote><p>个人感觉使用直角引号的上引号和下引号易于辨识，弯引号则在部分字体中不容易辨别，例如BBC中文使用直角引号，所以很容易发现其<a href="https://www.bbc.com/zhongwen/trad/chinese-news-58945507">文章中的引号错误</a>；直角引号在中文排版里看起来也更为协调，显示宽度与其他中文标点一致，弯引号则可能为半宽。</p><p>此外，<a href="https://manual.sspai.com/rules/style/">少数派</a>、<a href="https://blog.taptap.dev/pages/chinese-copywriting-guide">TapTap</a>等平台均建议使用直角引号。台港澳地区的标准亦采用直角引号。</p></li><li><p><strong>使用书名号包裹英文书刊</strong><br>虽然根据《<a href="http://sxqx.alljournal.cn/uploadfile/sxqx/20190304/CY%20T154%E2%80%942017%20%E4%B8%AD%E6%96%87%E5%87%BA%E7%89%88%E7%89%A9%E5%A4%B9%E7%94%A8%E8%8B%B1%E6%96%87%E7%9A%84%E7%BC%96%E8%BE%91%E6%A0%87%E5%87%86.pdf">中文出版物夹用英文的编辑规范（CY/T 154-2017）</a>》，「中文句子内夹有英文书籍名、报刊名时，不应借用中文书名号，应以英文斜体表示」。不过，我没有看到为何要如此规范，一篇论文仅提到这「与标准的要求是相违背的」<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>，给出了错误范例：</p><blockquote><p>研究前期，团队主要查阅了《中国竹类图志》、《Illustrated Flora of Bambusoideae in China》、《竹类植物资源与利用》等书籍。</p></blockquote><p>并指出正确用法为：</p><blockquote><p>研究前期，团队主要查阅了《中国竹类图志》《竹类植物资源与利用》 、<em>Illustrated Flora of Bambusoideae in China</em>等书籍。</p></blockquote><p>但我个人感觉这样显得更加奇怪，原文三本书并列，一目了然，改后却不易看出。另一点让我感到疑惑的是，在中文语境下标示英语作品名，为什么要用英文特有的形式呢？如果按此标准，《挪威的森林》是否要表示为日语『ノルウェイの森』，《钢铁是怎样炼成的》是否要表示为俄语«Как закалялась сталь»？相反，如果都使用中文书名号，我认为更加统一。</p></li></ul><h2 id="排版">排版</h2><p>我不使用人工空格来「排版」。一些排版指南要求在中英文间、链接前后添加空格以改善排版（例如《<a href="https://github.com/sparanoid/chinese-copywriting-guidelines">中文文案排版指北</a>》），有些论文也认为空格是辅助排版的元素<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。但我认为内容与表现应该是分离的，应该由排版引擎处理此类排版问题。例如，Chrome就尝试<a href="https://developer.chrome.com/blog/css-i18n-features">通过CSS属性来处理混排时的间距调整</a>。如果人工处理，不仅会增加写作负担，而且当相关引擎成熟后又得重新调整。</p><p>先前我尝试过使用<a href="https://github.com/next-theme/hexo-pangu/tree/main"><code>hexo-pangu</code></a>处理排版问题，但效果不佳（例如还会把半角符号修改为全角），遂放弃。<a href="https://github.com/sivan/heti">赫蹏</a>的样式看起来还不错，不过恐怕会与本博客的主题排版相冲突。我想还是交由主题本身或是浏览器来处理吧。</p><h2 id="用语">用语</h2><ul><li><strong>避免翻译腔</strong>：翻译腔的表现形式是文章生硬、不协调<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>。虽然许多文章并非翻译而来，但仍会受西方语言的影响，产生西化问题<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>。维基百科上的<a href="https://zh.wikipedia.org/wiki/Wikipedia:%E7%BF%BB%E8%AF%91%E8%85%94">相关页面</a>写得就挺好，列举了相关表现形式及修改方法。较为典型的包括：使用「进行」将动词变成抽象名词、仅强调种类时使用数量词（如「大众桑塔纳是一款由大众汽车公司生产的三厢轿车」，大众汽车显然不会只生产一款汽车，故该句无需使用「一款」）、照抄外文的「优雅」说法（如「作出了巨大的贡献」，可直接改为「贡献巨大」）。</li><li><strong>观点使用「认为」、「觉得」等词</strong>：一篇好文章应该清楚地将事实与观点区分开，故我会使用「认为」、「觉得」等词表明观点。</li><li><strong>不使用模棱两可的词语</strong>：如《现代汉语词典》（第七版）中对「空穴来风」的定义为：「有了洞穴才有风进来（语出宋玉《风赋》）。比喻消息和传说不是完全没有原因的，现多用来指消息和传说毫无根据。」（<a href="https://archive.org/details/modern-chinese-dictionary_7th-edition/page/746/mode/2up">第746页</a>）同一个词却可以指两种完全相反的意思，因此我不会使用它。</li><li><strong>用语尽量直白</strong>：如同维基百科的<a href="https://zh.wikipedia.org/wiki/Wikipedia:%E7%9B%B4%E8%A8%80%E4%B8%8D%E8%AE%B3">一篇论述</a>所说的那般，「铲子」不叫「手持式地貌修改专用装置」，也不叫「单兵战术人力壕沟挖掘机」。我认为在不损失准确度的前提下，应该尽量使用简单明了的表达方式，以免加重读者的心智负担。</li></ul><h2 id="引用">引用</h2><p>或许是受到维基百科的影响，我倾向于引用其他来源，佐证我文中提到的事实及观点。毕竟我不是专家，只能使用「引用论证」来支持我的观点。链接可以提供进一步的背景、关键来源材料、实用信息及评论<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>，我认为也算是一种引用。这能够提高透明度<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup>与网页可见度<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup>，颇有益处。不过就我的观察而言，中国的新闻机构似乎不喜欢使用外部链接。</p><p>对于可以在内文使用超链接的引用，我会直接链接到对应页面。对于脚注方式的引用，则基本采用《<a href="https://journal.ustc.edu.cn/uploadfile/yjsjy/20161108/GB%20T%207714-2015%E4%BF%A1%E6%81%AF%E4%B8%8E%E6%96%87%E7%8C%AE-%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%E8%91%97%E5%BD%95%E8%A7%84%E5%88%99.pdf">文后参考文献著录规则（GB/T 7714—2015）</a>》。但考虑到网页可使用超链接，且url基本不会带来额外信息，故会将标题改为链接形式。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>孙晓芳, 侯春晓, 高峻. 中文科技期刊不规范夹用英文的常见问题及其修改建议 [J/OL]. 编辑学报, 2023, 35(S1): 51–55. CNKI <a href="https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&amp;filename=BJXB2023S1013">BJXB2023S1013</a>. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>魏英杰, 张宁．CY/T 154—2017在科技著作出版中的实践与探索 [J/OL]. 出版科学, 2018, 26(5): 31–33. DOI: <a href="https://doi.org/10.13363/j.publishingjournal.2018.05.053">10.13363/j.publishingjournal.2018.05.053</a>. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>冯彤. “翻译腔”例析 [J/OL]. 中南大学学报(社会科学版), 2003, 9(4): 556–560. CNKI <a href="https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFQ&amp;filename=ZLXS200304029">ZLXS200304029</a>. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>钱寿初. 中文科技语言文字的西化问题 [J/OL]. 编辑学报, 1996(04): 218–222. DOI: <a href="https://doi.org/10.16811/j.cnki.1001-4314.1996.04.075">10.16811/j.cnki.1001-4314.1996.04.075</a>. <a href="#fnref4" class="footnote-backref">↩︎</a></p></li><li id="fn5" class="footnote-item"><p>BBC. <a href="https://downloads.bbc.co.uk/guidelines/editorialguidelines/pdfs/links-and-feeds.pdf">Links and Feeds: Editorial Policy Guidance Note</a> [EB/OL]. (2010-10)[2025-09-01]. <a href="#fnref5" class="footnote-backref">↩︎</a></p></li><li id="fn6" class="footnote-item"><p>De Maeyer J. The journalistic hyperlink: Prescriptive discourses about linking in online news [J/OL]. Journalism Practice, 2012, 6(5–6): 692–701. DOI: <a href="https://doi.org/10.1080/17512786.2012.667273">10.1080/17512786.2012.667273</a>. <a href="#fnref6" class="footnote-backref">↩︎</a></p></li><li id="fn7" class="footnote-item"><p>Baggio R, Antonioli Corigliano M. On the Importance of Hyperlinks: A Network Science Approach [C/OL] // Buhalis D, Höpken W, Gretzel U, eds. <em>Information and Communication Technologies in Tourism 2009</em>. Vienna: Springer, 2009: 309–318. DOI: <a href="https://doi.org/10.1007/978-3-211-93971-0_26">10.1007/978-3-211-93971-0_26</a>. <a href="#fnref7" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/09/01/Writing-Is-Choosing-My-Words-and-Layout/</id>
    <link href="https://blog.deepchirp.com/2025/09/01/Writing-Is-Choosing-My-Words-and-Layout/"/>
    <published>2025-09-01T08:14:36.000Z</published>
    <summary>本文描述了作者的写作风格与版面选择，旨在通过制定风格手册，以提升文章质量与一致性，涵盖标点、排版、用语、引用等方面。</summary>
    <title>写作即取舍：我的文字与版面</title>
    <updated>2025-09-05T12:24:57.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="评价" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E8%AF%84%E4%BB%B7/"/>
    <category term="读书" scheme="https://blog.deepchirp.com/tags/%E8%AF%BB%E4%B9%A6/"/>
    <category term="心理学" scheme="https://blog.deepchirp.com/tags/%E5%BF%83%E7%90%86%E5%AD%A6/"/>
    <category term="科学" scheme="https://blog.deepchirp.com/tags/%E7%A7%91%E5%AD%A6/"/>
    <category term="友情" scheme="https://blog.deepchirp.com/tags/%E5%8F%8B%E6%83%85/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/93074623">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/19389056">XilmO@夕末</a>。</p></div><p>前段时间，<a href="https://zh.wikipedia.org/wiki/User:%E8%87%AA%E7%94%B1%E9%9B%A8%E6%97%A5">自由雨日</a>给我推荐了《进化心理学：心理的新科学》这本书。我刚好对心理学有些兴趣，于是便抽空阅读了一下。目前中文最新版是第4版，英文则是第7版，后者更新了不少内容。不过，我还是更喜欢读翻译版，因为有母语优势；同时，心理学应该有许多专业术语，我担心读英文版会受挫。</p><h2 id="第一编-进化心理学的理论基础">第一编 进化心理学的理论基础</h2><p>《导致进化心理学出现的科学运动》中，作者首先介绍了一些基本理论，包括达尔文的自然选择和性选择理论（包含同性竞争和异性选择）、哈密尔顿的广义适合度理论（即从基因的相似度看待选择过程）等。随后澄清了一些常见误解，例如认为自然选择就是「遗传决定论」。显然，人的行为不仅受到基因的影响，还有环境的塑造。最后则介绍了人类进化史及心理学领域的里程碑。</p><p>我个人感觉，这部分内容和高中生物知识十分相似。广义适合度理论从基因这一微观视角解释选择过程，强调基因的重要性，虽然原理很容易想到，但我还是认为这种观点很有趣。文中在讲述「组合爆炸」时，也提及人的心理一定是特殊的：</p><blockquote><p>当人或计算机在解决具体的任务时，一定要有特殊的程序将反应的可能性限定在非常有限的范围内。如果没有这样的特殊程序，哪怕是最简单的任务，人和计算机都不可能完成它。</p></blockquote><p>换言之，人的心理只有被特殊设计过，才能在复杂的环境中生存下来。日常生活中处理琐事时，我们往往会依靠直觉，而不需要多少分析和思考。这种直觉所依赖的，我想应该就是进化过程中形成的心理机制。</p><p>第二章《作为新科学的进化心理学》，主要介绍了进化产物及原理、研究方法。进化的主要产物是适应器，即具有遗传性的可稳定表现的特征（如脐带）。其还可能有副产物（如肚脐）和噪音（如肚脐的特殊形状）。</p><h2 id="第二编-生存问题">第二编 生存问题</h2><p>文中首先提到了觅食。作者提到，妊娠病可能是一种适应器，用以防止孕妇摄入毒素，危害胎儿。作者还写道，人们之所以喜欢香料，是因为其抗菌作用。此外，关于饮酒的观点很有趣，作者称，水果成熟后会散发出乙醇香味，而酒的主要成分为乙醇，因此人们会对酒产生兴趣。</p><blockquote><p>根据食果产物假说（frugivory by-product hypothesis），人类对酒的迷恋本身并不是一种适应器，而是喜欢成熟的果实这一适应行为的副产物（Dudley, 2002; Singh, 1985）。[……]所有的人类都已经进化了喜欢成熟水果的食物偏好机制，但是这些机制和我们现在的高酒精含量的酒类相遇时却出现了问题。事实上，现代社会中的酗酒行为很有可能是因为过度沉溺于食果机制而导致的适应不良。因此，当你下次喝酒的时候，你也许会想到你的灵长目祖先们也开过聚会——围坐在一棵果树下吃着甘美的熟果。</p></blockquote><p>我不怎么吃水果，闻到酒味也会不舒服。不过，我的父亲喜欢喝酒，但他并不喜欢吃水果。或许是因为水果里的乙醇含量太少了，「由奢入俭难」？</p><p>其次涉及到了住所。作者提到「热带大草原假说」，即不同文化的人都喜欢大草原般的环境，因为这种环境较为开阔，同时也能提供一定的遮蔽。周围环境也会影响到我们的情绪：</p><blockquote><p>有研究表明，在病房里面放些花儿，可以提高病人的康复速度，还能带给病人一种非常积极的心理状态（Watson &amp; Burlingame, 1960）。</p><p>当我们生病住院时，如果能够看到窗外的树木，我们也会康复得更快（Ulrich, 1984）。</p></blockquote><p>我先前觉得送花只是表达自己的心意，并没有其他作用，但现在有所改观。同时，这也让我想起欧·亨利的《<a href="https://zh.wikipedia.org/wiki/%E6%9C%80%E5%90%8E%E4%B8%80%E7%89%87%E5%B8%B8%E6%98%A5%E8%97%A4%E5%8F%B6">最后一片叶子</a>》：一位老画家为鼓励病患乔安，在狂风暴雨的夜晚画下常青藤叶；患者受到叶子的鼓励，最终战胜病魔，但画家因感染肺炎而死。现在看来，这确实是有科学依据的。</p><p>接着还提到了人面临危险时的情绪反应，包括害怕、焦虑、恐惧等，这些情绪都是为了让我们避开危险。文中还提到了「高度错觉」，即在相同距离的前提下，从上往下看时会认为比从下往上看更高。这也让我想起了主观与客观之间的联系。虽然俗话说「眼见为实」，但我认为主观并不一定要完全反映客观事实，而应对主体本身有益。例如，蜜蜂的视觉感知范围包括人眼看不到的紫外光，这帮助它们更好地识别花朵的模式<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。人类看不见许多其他频率的光，看似是劣势与缺陷，但这是不是为了获取最有用的信息，避免信息过载，实则是一种优势呢<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup><sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup><sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>？</p><p><img src="/2025/08/27/Evolutionary-Psychology-The-New-Science-of-Psychology/EM_spectrum.svg" alt="人类的可见光谱只占宽广的电磁波谱的一小部分，但能看到得越多，就意味着越好吗？（取自维基共享资源，原作者为Ufoismey3k，采用CC BY-SA 4.0协议）"></p><p><img src="/2025/08/27/Evolutionary-Psychology-The-New-Science-of-Psychology/Checker_shadow_illusion.svg" alt="棋盘阴影错觉，人眼看来正方形A较B颜色更深，实则两者相同；虽与事实不符，但人眼能将光线信息转换成有意义的信号，表明了人类视觉系统之优越性（取自维基共享资源，原作者为Edward H. Adelson、Pbroks13，采用CC BY-SA 4.0协议）"></p><p>这章最后，作者讨论了人类的死亡问题，还特别提及了为何男性的平均寿命较女性短：</p><blockquote><p>有利于在求偶竞争中获得成功的基因将会被选择出来，这种作用在男性身上更为强烈，同时以年老时的生存为代价。这种对生命早期利益的强烈选择，产生了能导致人们死得更早的多效性基因。正如一位研究者所言，「男性的死亡率总是比女性高，因为他们早期已经享用了更多潜在的繁殖机会，而且，进化过程已经塑造出了这样的特质，它们既与积极的高繁殖成功率相连，又不得不付出早逝的代价」（Trivers, 1985, p.314）。</p></blockquote><p>其中关于人们为何要自杀的观点也很有意思。他提到，如果一个人认为自己传播基因（即文中所述的「实现广义适合度的能力」）的希望渺茫，那么自杀的概率会提高，通过让出资源提高亲属传递基因的可能性。</p><h2 id="第三编-性行为和择偶行为的挑战">第三编 性行为和择偶行为的挑战</h2><p>除生存外，人们面临的另一大挑战便是择偶。第4章《女性的长期择偶策略》主要描述了女性如何选择男性配偶，考虑的因素包括获取资源的潜力、对于女性的承诺、社会地位等，择偶标准也显然与女性自身的背景相关联。让我感到惊讶的是，女性看重面孔和身体的对称性，据研究这关乎男性是否健康。</p><blockquote><p>第一，面孔对称的人在生理测验、心理测验以及情绪健康测验上都取得了较高的分数（Shackelforl &amp; Larsen, 1997）。第二，不管是男性还是女性，面孔对称性和身体吸引力的评分之间存在正相关。第三，女性通常认为面孔对称性更好的男人看起来更加性感[……]</p></blockquote><p>第5章《男性的长期择偶策略》则从另一角度出发。男性对配偶年龄的偏好很有意思，青春期时的男生会选择年龄稍长的女生，但成年后的男性会青睐更年轻的女性。进化心理学称，这意味着男性看重对方的生育能力，而对应年龄的配偶拥有更强的生育力。不过，年长男性因多种原因，而不选择处于最佳生育年龄的异性，这可能是因为男性退而求其次，或是年龄差太大会导致难以相处，抑或是现代婚姻改变了男性的偏好。</p><p>此外，女性的外貌和行为往往反映了繁殖价值，这也会影响男性的评价。就外貌而言，显而易见，发长、腿长、体脂等均有影响，但是这种审美标准天生即有之，而非后天培养习得。与我的直觉相左，面孔平均化更具吸引力，这可能是因为人们偏爱易于加工的事物，或是意味着某种表现型优势。之后，还具体介绍了男性的择偶偏好如何影响他们的择偶行为，例如在与漂亮女性对话时，会刻意压低嗓音。</p><p>第6章《短期的性关系策略》则提到了两性的短期择偶。男性比女性更倾向于短期择偶，这是因为男性付出代价小，且能有更多后代。本章开头的实验便体现出了两性间的差异：</p><blockquote><p>假如在大学校园里，一位迷人的异性走过来跟你说：「你好，我最近一直在注意你，我觉得你很有魅力。你愿意和我做爱吗？」碰到这样的情形，你会作何反应？如果你和其他女性一样，你会毫不犹豫地拒绝。事实上，在一项研究中，100%的女性都这样作答。这样的请求可能让你觉得被冒犯、被羞辱或者不知所措。但是，假如你和研究中的男性被试一样，便会觉得走了桃花运：75%的男性接受了请求（Clarke &amp; Hatfield, 1989）。而且对男性而言，遇到这种请求也算是莫大的荣幸。</p></blockquote><p>为了尽可能多地获取性行为机会，男性会降低标准。「零点现象」佐证了这一点，即在单身酒吧中，越接近晚上12点，男性对女性的魅力评价越高，这表示男性会逐渐降低标准。书中提到性幻想时称，对男性而言，「性就是单纯的欲望和生理满足」，而女性会注重对象的个性和情绪特征。此外，男性更可能会红杏出墙。</p><p>而从数学的角度看，男性和女性参与短期择偶行为的数量应该是相等的。书中提及，女性可以获得5种收益：资源、基因、更换配偶、获取择偶技巧、操纵配偶。</p><h2 id="第四编-亲代抚育和亲属关系的挑战">第四编 亲代抚育和亲属关系的挑战</h2><p>解决生存和择偶、繁殖问题后，人们面临的下一挑战便是如何抚养后代。实际上，自然界中有许多物种并不抚养后代，因为付出的成本不及生出更多后代的收益。第7章《亲代抚育问题》中，作者首先讨论了为何母亲在养育后代中投入更多，原因包括父子关系的确定性普遍较母子关系低，以及雄性更害怕错失择偶机会。作者提到，「男性倾向于为择偶活动投资，而女性倾向于为抚育子女投资」。同时，书中也探究了父母为后代的投入会受哪些因素影响，包括遗传相关度、子女运用亲代投资的能力等。其中有个发现很有趣，即母亲多数情况下都会说孩子长得像父亲，在我家中亦是如此，母亲还说我和父亲是「从一个模子里刻出来的」。但实际上，新生儿与母亲的相似度更高。研究提出，这可能是母亲希望让父亲感知到自己的父亲身份，从而鼓励他对子女的投资。</p><p>根据进化理论，父母和子女间必然存在冲突：</p><blockquote><p>在有性繁殖的物种（比如人类）中，父母和后代有50%的遗传相关度。[……]但这也意味着，父母和子女之间有50%的基因差异。因此，对父母和子女而言，双方心目中的理想行为很难达成一致（Trivers, 1974）。具体而言，父母和子女将在如何分配父母的资源上产生分歧，这导致的典型结果就是，子女想得到的资源会超出父母愿意提供的资源量。</p></blockquote><p>此外，子宫中也会产生母婴冲突。其最早表现为胎儿是否会自发性流产，母亲的适应器会让不良胚胎流产，从而尽早停止投资的损失；而在受精卵着床成功后，母亲和孩子还会发生食物供给的冲突。</p><p>下一章是《亲属关系问题》。文中首先提到了<a href="https://zh.wikipedia.org/wiki/%E5%93%88%E5%AF%86%E5%B0%94%E9%A1%BF%E8%A7%84%E5%88%99">哈密尔顿规则</a>，揭示了利他行为的进化基础。虽然利他行为可能会对利他者本身不利，但通过帮助亲属，会使得与自己相似的基因得以保留和传递。随后讨论了亲属关系的话题，主要是如何相互帮助、投资。不过，我的亲戚离我们家都有一段距离，每年只探访几次，存在感并不强。但在乡村更容易形成宗族社会般的形式，人们集体生存。最后探讨了家庭的进化过程，也提到了家庭存在阴暗面，包括同胞冲突、亲子冲突、父母冲突。</p><h2 id="第五编-群居问题">第五编 群居问题</h2><p>顾名思义，此编主要讨论群居生活，共包括4章内容。</p><blockquote><p>我们常说自然选择是自私的，是因为它是一个反馈的过程。如果它青睐某个生物体，这一个体所拥有的设计特征肯定比群体中的其他个体更具繁殖优势。但是，为朋友作出牺牲的人难免要付出代价，而朋友却会从中受益。所以我们不禁会问，这样的友谊和利他行为是如何得以进化的呢？</p></blockquote><p>本编首章《合作联盟》讲述了朋友间的利他行为。互惠式利他主义称，利他者能够在将来的某个时刻从受惠者那里获得回馈，从而实现双赢。但最重要的问题是，如何识别欺骗问题。随后提到了经典的「<a href="https://zh.wikipedia.org/wiki/%E5%9B%9A%E5%BE%92%E5%9B%B0%E5%A2%83">囚徒困境</a>」，指出在「重复的囚徒困境」中，玩家的最佳选择应该是以牙还牙。「首先，以你希望对方对待你的方式去对待他，然后以他实际对待你的方式去对待他」。文章还提到，人们对识别欺骗者有着特殊的能力。其基础之一是辨认不同个体的能力，「能够认出已经34年未曾见面的故人，正确辨认率超过90%」。不过这对我来说不太可能，因为我确实脸盲，过几个月可能就认不出来了。</p><p>我现在也在采用「以牙还牙」的策略，以及时止损。原先，家长总是让我尽可能和所有人都打好关系。但我在交朋友的过程中发现，许多友谊确实没有必要维持。例如初中时，我帮了一个同学不少忙，他重装系统出了问题，再一次让我帮他解决，当时忙碌的我第二天才看到并回复，却发现自己惨遭删除。我提供的许多帮助并未得到任何回报，甚至连一句感谢都没有，我一度开始怀疑帮助别人的价值何在。后来，我逐渐变得「冷漠」，并且意识到要将精力放在值得的人身上。如果对方三番两次都不回报我的付出，我便会选择断绝关系。大学时，就有一些同学经常问我问题，当我没有感受到回报后，便主动淡了联系，甚至直接将之联系方式删除。随后也发现，其实自己在对方的朋友圈中并不重要，甚至只算工具人。<a href="https://blog.rxliuli.com/p/ba7f17b8f76347c08ae8a49893869942/">rxliuli在其博客中也提到</a>，「帮助别人似乎开始变成了一件吃力不讨好的事情」，我感同身受。</p><blockquote><p>在这些交换活动中，交换双方根本谈不上朋友关系。实际上，如果你总是希望朋友对你提供的帮助马上给予相似的回馈，那说明你们的友谊非常脆弱，因为你们还缺乏真正的信任（Tooby &amp; Cosmides, 1996）。</p></blockquote><p>我初中时确实和其他人有过这种脆弱的友谊。当时学校门口有卖烤肠的商店，我和一位同学轮流请对方吃烤肠。但当一方忘记带钱时，另一方在第二天也不会请客。其实我觉得和他不算是朋友，虽然当时学习成绩相仿，可以进一步加深友谊，但我确实不屑于他的品格。碍于情面，我还是选择了维持这种表面的友谊。初中毕业之后，他旋即断绝了与我们之间的联系。</p><blockquote><p>当你春风得意的时候，交朋友并不是什么难事。但是，只有当你身处困境的时候，你才会发现哪些人才是真正的朋友。[……]真正的朋友之间完全是另一种期望和感受。和朋友在一起时，我们会感到非常愉快。当朋友获得成功时，我们不是感到妒忌，而是由衷地替他高兴。我们和朋友拥有相同的价值观和世界观，这种志同道合让我们体会到深深的满足感。当朋友急需帮助时，我们会毫不犹豫地伸出援助之手，不会在意我们的付出能否马上得到回报。</p></blockquote><p>其实我很庆幸交到了真正的朋友，并且还时常有联系。不过到了大学，社交大幅减少了，我到现在也没找到那般亲近的朋友。或许是因为大家都忙于学业和生活，没时间维系友谊吧。虽然线下社交还是有些障碍，不过我觉得在维基百科认识的几位编者都很不错。</p><blockquote><p>图比和科斯米德斯（Tooby &amp; Cosmides, 1996）认为，合作行为和利他行为还有（其他）潜在的进化途径，那就是友谊。他们提到了人们的直觉反应：当许多人听说人类的友谊只是基于纯粹的互惠互利时，他们变得非常生气。人们经常说，当他们为朋友提供帮助时，他们感到由衷的快乐，根本不会计较将来能否得到回报。</p></blockquote><p>我确实一度以为朋友之间只是交换信息、互通有无。但在和真正的朋友相处后，我意识到不仅仅是这样。我觉得待在一起，就会感到很放松。</p><blockquote><p>友谊在很多维度上都存在差异，其中一个维度就是性别。友谊可以发生在同性之间，也可以发生在异性之间。这两种不同形式的友谊所带来的收益和代价，可能存在天壤之别。比如，同性之间的友谊往往会产生同性竞争，但异性之间却不会。而且，异性朋友拥有一种同性朋友所不具备的好处，那就是异性朋友有可能成为你的配偶。</p></blockquote><p>这让我想起初中时与异性交往的糟糕经历。疫情期间，我和一位女生经常聊天，她会及时回应，还会倾诉她的烦恼。我觉得和她聊天很有意思，于是对她说我喜欢她之类的话，但只是想表达好感，并不想发展成恋爱关系。随后她还给出了种种承诺，但最终无一兑现。现在回想，我们事实上并没有什么友谊，她纯粹就是把我当作工具人使用。这段经历也让我产生了社交焦虑。高中时，一位女生主动找我吃饭，高考结束后约我一起玩，密室逃脱时挽着我的手，大学时还打电话和我聊天。虽然我感觉和她的关系有些微妙，但我担心是自己想多了，怕重蹈覆辙，于是也没说什么。最终她在大学找到了男朋友，我感觉挺不错的。</p><p>下一章名为《攻击与战争》。雌性在亲代投资上付出更多，故雄性的繁殖上限大于雌性。正是因为这种「一雄多雌」的现象，部分雄性所获得的繁殖资源高于均值，因此雄性之间的竞争更加残酷，也更具攻击性。女性间虽不太会有武力上的攻击，但也会出现言语攻击，且多是诋毁外貌，或宣称对手水性杨花。男性是战争的主要参与者，还为此进化出了专门的心理机制。这也是为了获取更多的性交机会。</p><p>两性之间会因为进化利益不同而产生冲突。《两性冲突》阐述了具体原因，比如男性常会认为女性对自己有兴趣，实则不然。书中提到这是一种认知偏差，并将其与烟雾报警器做类比，称烟雾报警器偏向于误报而非漏报，因为漏报比误报的代价大得多。两性间的冲突包括身体接触的冲突以及性嫉妒。本章结尾处，作者还谈论了男权制度：</p><blockquote><p>在女权主义作家笔下，男性有时被描绘成这个样子：他们联合起来压制女性，实现共同的目标（Dworkin, 1987; Faludi, 1991）。但是，进化心理学的分析表明上述说法是错误的，因为男人和女人的竞争对手主要还是同性。[……]同时，我们必须认识到，男性和女性也都从异性的择偶策略中获益。[……]出于利益的考虑，每个人都会和两种性别中的某些成员结成联盟或者发生冲突。</p></blockquote><p>本编最后一章是《地位、声望和社会等级》，主要探讨了社会地位和支配行为的进化心理。文中认为，自尊是跟踪社会地位的机制，既可以促使主体改善人际关系，又可以激发获得尊重的行为。</p><h2 id="第六编-一门整合的心理科学">第六编 一门整合的心理科学</h2><p>这一编主要讲述了如何从进化的角度评述心理学的各个领域。作者认为，目前心理学各个领域的划分有着很强的人为性，而进化视角可以将这些领域整合起来。</p><h2 id="总结">总结</h2><p>总的来说，这本书质量相当不错，毕竟是商务印书馆背书。这本书算是极致的文献综述（自由雨日也提到了这一点），后面列出的参考文献足足有三十多页。我发现我所读的国外大学级别的书籍，似乎都很爱使用参考文献；而国内教材则不然。从生物进化的角度来解释心理学，我认为是自然而然的。同时书中对部分问题的讨论，解释了部分长期萦绕在我心头的谜题。最后，我希望了解心理学，是为了更清楚地了解自己和他人。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Hempel de Ibarra N, Vorobyev M, Menzel R. Mechanisms, functions and ecology of colour vision in the honeybee [J/OL]. J Comp Physiol A Neuroethol Sens Neural Behav Physiol, 2014, 200(6): 411–433. DOI: <a href="https://doi.org/10.1007/s00359-014-0915-1">10.1007/s00359-014-0915-1</a>. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>Hempel de Ibarra N, Holtze S, Bäucker C, Sprau P, Vorobyev M. The role of colour patterns for the recognition of flowers by bees [J/OL]. Philos Trans R Soc Lond B Biol Sci, 2022, 377(1862): 20210284. DOI: <a href="https://doi.org/10.1098/rstb.2021.0284">10.1098/rstb.2021.0284</a>. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>Barlow H B. Possible principles underlying the transformations of sensory messages [M/OL]. In: Rosenblith W A (ed.). Sensory Communication. Cambridge, MA: MIT Press, 1961: 217–234. Available: <a href="https://www.cnbc.cmu.edu/~tai/microns_papers/Barlow-SensoryCommunication-1961.pdf">https://www.cnbc.cmu.edu/~tai/microns_papers/Barlow-SensoryCommunication-1961.pdf</a>. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>Niven J E, Laughlin S B. Energy limitation as a selective pressure on the evolution of sensory systems [J/OL]. Journal of Experimental Biology, 2008, 211(11): 1792–1804. DOI: <a href="https://doi.org/10.1242/jeb.017574">10.1242/jeb.017574</a>. <a href="#fnref4" class="footnote-backref">↩︎</a></p></li><li id="fn5" class="footnote-item"><p>MacFarlane E R, Patel S, Nayak R, et al. UV light and the ocular lens: a review of exposure models, risk factors and protective mechanisms [J/OL]. Frontiers in Ophthalmology, 2024, 4: 1414483. DOI: <a href="https://doi.org/10.3389/fopht.2024.1414483">10.3389/fopht.2024.1414483</a>. <a href="#fnref5" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/08/27/Evolutionary-Psychology-The-New-Science-of-Psychology/</id>
    <link href="https://blog.deepchirp.com/2025/08/27/Evolutionary-Psychology-The-New-Science-of-Psychology/"/>
    <published>2025-08-27T13:21:58.000Z</published>
    <summary>本文是关于《进化心理学：心理的新科学》的阅读心得，涵盖生存、择偶、亲代抚育、群居、友谊等主题，并结合亲身经历展开思考。</summary>
    <title>读书：《进化心理学：心理的新科学》</title>
    <updated>2025-08-27T13:21:58.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Android" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/Android/"/>
    <category term="Android" scheme="https://blog.deepchirp.com/tags/Android/"/>
    <category term="root" scheme="https://blog.deepchirp.com/tags/root/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/66987311">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/418969">TID</a>。</p></div><p>我的第一台手机是三星的G5109，搭载Android 4.4.4系统，存储空间仅有16GB。这台机器从电信渠道购入，每次恢复出厂设置都会自动安装一批运营商相关应用。这些软件预先存储在手机上的<code>system</code>分区中，既占空间也难以移除干净。因此我想着把手机root，从根源上删除那些安装包。当时root手机很简单：要么使用一键root工具，要么刷入第三方Recovery并用SuperSU管理授权。同时，由于机器性能孱弱，我还用MyAndroidTools（俗称「写轮眼」）禁用QQ、微信的部分组件，以减少资源占用。</p><p>如今硬件性能和系统功能都显著提升，root看起来不再「刚需」。以我现在的主力机Redmi K60 Pro为例，使用首年即使并未root，也感觉够用了；但随后还是选择了root——为了更多的可能、更好的体验。</p><h2 id="好处">好处</h2><h3 id="保护隐私">保护隐私</h3><p>我之所以root，主要还是出于隐私考虑。国内许多软件并不安分，会在公共存储写入可跨应用读取的持久标记，形成跨应用的跟踪面。如果不root，确实对它们束手无策。Google虽也意识到了这个问题，<a href="https://sspai.com/post/61168">例如在Android 10引入了分区存储特性，并在后续版本中持续收紧</a>，但时至今日尚未完全解决。而在root后，通过<a href="https://sr.rikka.app/">存储空间隔离</a>之类的软件，可以将不同软件的数据隔离开来，防范不同应用间的跟踪数据共享。此外，<a href="https://github.com/lihenggui/blocker">Blocker</a>和<a href="https://github.com/MuntashirAkon/AppManager">App Manager</a>等软件能够禁用一些应用组件，包括跟踪器、广告等。</p><p>另一方面，国产系统本身也存在隐私问题，<a href="https://www.theregister.com/2021/10/13/android_os_vendor_variants_transmit/">一些国产Android系统会将用户数据上传至云端</a>。在小米手机上，可以使用<a href="https://github.com/ReChronoRain/HyperCeiler">HyperCeiler</a>等软件，禁止系统上传已安装应用列表等。</p><h3 id="扩展功能">扩展功能</h3><p>小米系统的某些功能仅部分机型可用。其中一些情况是硬件所致，例如AI能力需NPU支持；而另一些情况则是软件限制，如<a href="https://www.nextpit.com/how-tos/how-to-activate-super-wallpapers-miui-hyperos">超级壁纸仅在部分机型上可用</a>。对于后者，可以在root之后解除相关限制，例如晕车缓解、录像时使用4K 60fps等功能。此外，官方系统并未提供部分功能，例如原先系统中不支持调节手电筒亮度，只能依靠其他模块完成。</p><p>还有一些有趣的实验性功能显然不会在普通系统中提供。比如，<a href="https://github.com/chenxiaolong/MSD">MSD</a>可以将手机模拟为大容量存储设备：例如能将ISO文件模拟为光驱，让电脑从中启动。</p><h3 id="其他方面">其他方面</h3><p>root后还能完成其他一些操作。我的电脑与手机均使用了<a href="https://rime.im/">RIME输入法引擎</a>，root后使用<a href="https://syncthing.net/">Syncthing</a>，可以实现多端数据同步（因为Syncthing需要读写其他应用的数据文件，而不root则做不到这一点）。<a href="https://adguard.com/">AdGuard</a>在root后才能将根证书安装到系统分区中，从而实现HTTPS过滤，还可自动配置网络，无需占用VPN槽位。<a href="https://f-droid.org/">F-Droid</a>需要向系统分区中安装<a href="https://f-droid.org/packages/org.fdroid.fdroid.privileged/">特权扩展</a>，以实现自动更新等功能。先前的博文中也提到，root后<a href="/2024/09/26/About-Google-Play-Store-Self-Update/" title="关于Google Play检查本体更新问题">可以解除Google Play商店的自我更新限制</a>，还可<a href="/2025/07/25/How-to-Enable-WeChat-FCM-Push-Notifications/" title="告别常驻进程：如何让微信使用FCM推送">维持微信正常的FCM推送</a>。</p><p>调整调度也是津津乐道的话题。例如<a href="http://vtools.omarea.com/">Scene</a>可以检测、调节手机性能，而<a href="https://github.com/nakixii/Magisk_AsoulOpt">AsoulOpt</a>模块可以优化游戏的线程调度，进而改善性能。我虽然使用了这些软件，但基本不会在手机上打游戏，所以不清楚效果几何。</p><p>除此之外，还有强大的<a href="https://lsposed.org/">LSPosed</a>框架，可以在不修改应用本身的情况下控制其行为。先前提到的HyperCeiler即依赖于此。利用这个框架，<a href="https://tornaco.github.io/Thanox-Docs/">Thanox</a>可以控制各应用的自启动、关联启动等，还可避免应用被系统杀死；<a href="https://github.com/cinit/QAuxiliary">QAuxiliary</a>、<a href="https://github.com/shatyuka/Zhiliao">知了</a>、<a href="https://github.com/cledwynl/mbga">mbga</a>等模块则让相应软件更加好用；<a href="https://github.com/KitsunePie/AppErrorsTracking">异常跟踪</a>则可以完整显示应用崩溃后的错误日志。</p><h2 id="坏处与局限">坏处与局限</h2><p>首先，手机root需要先解锁Bootloader，而<a href="https://github.com/KHwang9883/MobileModels/blob/master/misc/bootloader-kernel-source.md">不少国内的手机厂商都在逐步限制Bootloader的解锁</a>。先前小米的解锁政策十分宽松，但现在<a href="https://www.landiannews.com/archives/100967.html">甚至还需要答题才能获取资格</a>。幸亏我的手机型号较旧，能<a href="https://github.com/MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass">通过其他方法绕过</a>。而就在前几天，<a href="https://www.landiannews.com/archives/110212.html">一加的解锁也变成了人工审核</a>，将来是什么情况，暂时无法预料。与手机厂商的限制相比，解锁需要清空手机数据，这就不算什么了。</p><p>其次，root后还需要考虑隐藏root的问题，这不是一劳永逸的。其实以前我也考虑过，隐藏root是不是不道德：因为root之后，即可控制软件的运行过程，而这可能是软件开发者不愿看到的。但我发现，在仅root的情况下，QQ就会把我的账号冻结，于是打消了这一顾虑，否则根本无法正常使用软件。为此，得安装<a href="https://github.com/pumPCin/HMAL">隐藏应用列表</a>之类的软件，防止不安分的软件获取已安装的应用信息（直接不授予「获取应用列表」的权限不一定可行，因为某些应用会绕过相应机制）。然后，若要通过谷歌验证，则需要使用<a href="https://github.com/KOWX712/PlayIntegrityFix">Play Integrity Fix</a>以及<a href="https://github.com/5ec1cff/TrickyStore">Tricky Store</a>，由于谷歌经常吊销泄露的证书和密钥，所以也需要时常更新这两个模块的数据。此外，可能还需要使用Treat Wheel、<a href="https://github.com/MhmRdd/NoHello">NoHello</a>之类的模块隐藏root状态。尽管如此，QQ最新版的root检测还是非常厉害，为了账号不被封禁，我不得不使用旧版。</p><p>最后，还是老生常谈的安全问题。root本身并没有安全隐患，但解锁Bootloader会让安全性有所降低，让不信任的软件以root权限运行也会让设备面临风险。我认为只要不乱授予应用root权限、不随意安装模块，选用开源、可信赖的软件，那基本上就没什么问题。</p><h2 id="总结">总结</h2><p>其实，root的性价比似乎没有想象中的那么高，因为投入远多于收益。有许多操作并不需要root就可以实现，例如：卸载系统应用可以<a href="https://developer.android.com/tools/adb#pm">通过adb实现</a>；<a href="https://shizuku.rikka.app/">Shizuku</a>也可以在免root的情况下，<a href="https://sspai.com/post/73294">实现停用应用、批量安装应用等操作</a>。而我选择root，可能是心里的完美主义在作祟，想让手机成为我希望的样子。</p><p>我之后仍然会选择root，但对国内手机厂商的限制政策感到无奈。我认为既然用户购买了设备，那么就应该拥有高度的自由度和控制权。目前更像是只有使用权，而没有拥有权。同时，我也对QQ检测到root就封号感到不解，如果真的不想让用户root，那就检测到root后，直接禁止软件运行就足够了；诸如广告群发等违规行为，可以直接在服务端检测。我能理解root常与灰产、黑产相关联，但这样一刀切的方式，在我看来就是「懒政」的体现。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/08/19/Rooting-Continues-yet-Reality-Tightens/</id>
    <link href="https://blog.deepchirp.com/2025/08/19/Rooting-Continues-yet-Reality-Tightens/"/>
    <published>2025-08-19T08:30:29.000Z</published>
    <summary>本文介绍了root后带来的好处，包括保护隐私、扩展功能等，同时也探讨了root的坏处与局限，最后虽认为其性价比不高，但仍会继续。</summary>
    <title>root仍在路上，现实却愈发收紧</title>
    <updated>2025-08-19T12:56:29.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="个人" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/categories/%E4%B8%AA%E4%BA%BA/%E7%94%9F%E6%B4%BB/"/>
    <category term="决策" scheme="https://blog.deepchirp.com/tags/%E5%86%B3%E7%AD%96/"/>
    <category term="未知" scheme="https://blog.deepchirp.com/tags/%E6%9C%AA%E7%9F%A5/"/>
    <category term="生活" scheme="https://blog.deepchirp.com/tags/%E7%94%9F%E6%B4%BB/"/>
    <category term="友人帐" scheme="https://blog.deepchirp.com/tags/%E5%8F%8B%E4%BA%BA%E5%B8%90/"/>
    <content>
      <![CDATA[<div class="note primary flat"><p>本文的封面图来源于<a href="https://www.pixiv.net/artworks/115293810">Pixiv</a>，原作者是<a href="https://www.pixiv.net/users/6681779">黄瓜</a>。</p></div><h2 id="引言">引言</h2><blockquote><p><a href="https://zh.moegirl.org.cn/MyGO!!!!!">MyGO!!!!!</a> or <a href="https://zh.moegirl.org.cn/CRYCHIC">CRYCHIC</a>?</p><p><a href="https://en.wikipedia.org/wiki/To_be,_or_not_to_be">生存还是毁灭？</a></p></blockquote><p>我和深鸣想点个外卖一块吃，</p><ul><li>选谁来决定？</li><li>选哪个平台？</li><li>选哪家餐厅？</li><li>选哪种食物？</li><li>选哪杯饮料？</li></ul><p>一系列问题虽微不足道却环环相扣，有太大选择空间、太多未知信息，所以极易让人脑袋过载，抛出世纪难题：「吃啥？」</p><p>分析一下它为什么如此难以回答，要点在于：决策本身极复杂，而我们懒得搞「吃饭学术研究」，想在几分钟内给出答案。</p><p>有什么方法能永久治好选择困难症吗？我觉得没有。如果不愿「搞研究」而使用简化决策方法，一定不够通用，并且有其缺陷。下面我将试着叙述一种足够简单的决策思路，但是仍需注意适用范围。</p><h2 id="使大脑重新运转">使大脑重新运转</h2><p><strong>从已知出发，不要从未知出发。</strong></p><p>整理一下你的处境，确认：你有没有忽略某些重要的需求？比如：</p><ul><li>是不是很饿（这不是废话，深鸣曾感觉坐着很饱，但是站起来后很饿，玄学）、饭后需不需要赶去工作——如果是，优先考虑「距离近」、「配送快」因素；</li><li>是否想吃米饭类、是否想要清淡口味——如果是，利用平台的分类与筛选功能缩小范围。</li><li>是否感觉「总是那几样，吃腻了」——如果是，试试扩大食谱范围。（有文献指出人类对陌生食物天生抱有厌恶感<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>，这可以指导我们多去吃熟悉的食物。又，食谱范围过窄与营养不均衡密切相关<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>，则我们应该适当地尝试新食物）</li></ul><h2 id="基本目标">基本目标</h2><p>我发现选择困难时，自己往往没有什么迫切需求，觉得「都行，随便」或者「这个想尝尝，那个也想尝尝」。</p><p>耗费两个小时来选择，不行；吃了要是过敏或拉肚子，不行；买了太多而浪费，不行；一口都咽不下去，当然也不行。使用扔骰子、扔硬币等替代方法，不仅有限制，本质上无益于决策，还要确定谁对应谁，可能导致进一步的选择困难。由此，基本目标有：</p><ol><li>最好五分钟内解决难题</li><li>避免过敏、不卫生、浪费、无法咽下等情况</li><li>从正面突破，使决策更有效</li></ol><h2 id="基本策略1：觉察你的心情">基本策略1：觉察你的心情</h2><p>该策略对应目标1：节约时间。</p><p>觉察自己的心情——不要因眼花缭乱，而忽视心情。我们不知道一样食物在送达之前味道究竟怎样，所以别考虑未知的信息。短时间内浏览几十个选项比只看少数几个选项更难作出抉择<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>，所以遮住一半屏幕并慢慢翻阅，只注视两三家餐厅，看看其类别和评价，你讨厌它吗？对于不讨厌的那一家，点进去，依然遮住一半屏幕并慢慢翻阅，只注视三四种食物，看看其食材和风味，你讨厌它吗？如果不讨厌，立刻选上。同时，考虑你的食量，别浪费，则一个点餐方案很快就能完成。</p><p>以「讨厌」程度为阈值是为了提高效率，即快速找到一个平庸的选项。若有闲暇，可提高标准、以「喜欢」程度为阈值，即更耗时地找到一个较优的、满意的选项，注意只是较优而不是最优，得避免完美主义心态。<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup></p><h2 id="基本策略2：预测你能否接受">基本策略2：预测你能否接受</h2><p>该策略对应目标2：避免极差选项。</p><p>我们经常会遇到「信息偏差」问题。一部分是外部引起的：商家放出的照片其实是「照骗」；尽管好评如潮，但可能是水军作祟，吃起来很一般。对这些问题，用户没有针对性办法，只能尽量督促平台纠正。另一部分是内部引起的：信息本身没有失真，但我们预估错误，或只是偏好与众人不同等等，最终导致失望。</p><p>假想我们直接选择由策略1得到的方案，把主要预期降低一档以留出风险缓冲空间，例如实际食物比图片看起来难吃些、配送时间比平台计算略慢些，你会不会口吐芬芳？会不会耽误工作？如果不会，直接下单。</p><p>自己过去的经验是最真实可靠的，再次选择常吃的食品没有什么风险，还可以借鉴身边人的经验。到了想尝试新食物的时候，可再上一层保险——存一些零食、快餐之类备用。</p><h2 id="基本策略3：「暂时」忽略别人">基本策略3：「暂时」忽略别人</h2><p>上面两个策略适用于自身，该策略进一步地适用于多人场景。</p><p>一起点外卖的实质是：找到「吃饭公约数」，则决策倾向是保守的。谁来主导点餐过程不重要，吃饭才重要，那么你来主导就好。首先<a href="https://zh.moegirl.org.cn/%E6%88%91%E4%BB%80%E4%B9%88%E9%83%BD%E6%84%BF%E6%84%8F%E5%81%9A">「满脑子只想着自己」</a>，暂时地忽略他人，使用策略1和2，相对保守地给出你的点餐方案；然后抛弃「暂时」，听听别人对此具体方案的意见，若比较满意，缝缝补补即可；若不满意，便从头再来，或让别人来主导。这个策略只是给出一个起点，后续仍需友善讨论与协商，并非真正提倡「自私」。</p><h2 id="总结">总结</h2><p>选择困难症的病根是信息过载和信息偏差。从已知信息出发，尽可能缩小考虑范围，并减少信息量；信息偏差问题难以解决，因此可以多依靠过去的经验。</p><p>应对点外卖的4个步骤：整理处境，觉察心情，规避风险，主导决策。</p><p>更广泛地说，我们只能在点外卖、买衣服、看电影等小事上用以上简化策略应对选择困难症；对于有意义的大事，包括远途旅游、买房子、填志愿等，就应该采取「学术研究」的态度慎重考虑了。</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Birch LL. Development of food preferences [J/OL]. Annual Review of Nutrition, 1999, 19: 41-62. DOI: <a href="https://doi.org/10.1146/annurev.nutr.19.1.41">10.1146/annurev.nutr.19.1.41</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>Arimond M, Wiesmann D, Becquey E, et al. Simple food group diversity indicators predict micronutrient adequacy of the diet of women of reproductive age in five resource-poor settings [J/OL]. The Journal of Nutrition, 2010, 140(11): 2059S-2069S. DOI: <a href="https://doi.org/10.3945/jn.110.123414">10.3945/jn.110.123414</a> <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>Haynes G A. Testing the boundaries of the choice overload phenomenon: The effect of number of options and time pressure on decision difficulty and satisfaction [J/OL]. Psychology &amp; Marketing, 2009, 26(3): 204-212. DOI: <a href="https://doi.org/10.1002/mar.20269">10.1002/mar.20269</a> <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>Simon H. A. A Behavioral Model of Rational Choice [J/OL]. The Quarterly Journal of Economics, 1955, 69(1): 99–118. DOI: <a href="https://doi.org/10.2307/1884852">10.2307/1884852</a> <a href="#fnref4" class="footnote-backref">↩︎</a></p></li></ol></section>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/08/15/A-Brief-Discussion-on-Decision-Paralysis-Taking-Food-Delivery-as-an-Example/</id>
    <link href="https://blog.deepchirp.com/2025/08/15/A-Brief-Discussion-on-Decision-Paralysis-Taking-Food-Delivery-as-an-Example/"/>
    <published>2025-08-15T10:15:48.000Z</published>
    <summary>本文从点外卖的场景切入，分析选择困难症背后的信息过载和信息偏差问题，并给出节省时间、规避风险和多人场景下的实用策略。</summary>
    <title>浅谈选择困难症——以点外卖为例</title>
    <updated>2025-09-09T07:52:48.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>深鸣</name>
      <email>DeepChirp@outlook.com</email>
    </author>
    <category term="技术" scheme="https://blog.deepchirp.com/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="博客" scheme="https://blog.deepchirp.com/tags/%E5%8D%9A%E5%AE%A2/"/>
    <category term="必应" scheme="https://blog.deepchirp.com/tags/%E5%BF%85%E5%BA%94/"/>
    <category term="索引" scheme="https://blog.deepchirp.com/tags/%E7%B4%A2%E5%BC%95/"/>
    <category term="搜索引擎" scheme="https://blog.deepchirp.com/tags/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/"/>
    <content>
      <![CDATA[<p>去年10月底，我把博客的主题由<a href="https://github.com/fluid-dev/hexo-theme-fluid"><code>fluid</code></a>改成了<a href="https://github.com/jerryc127/hexo-theme-butterfly"><code>butterfly</code></a>。在原先的主题中，我没有配置<a href="https://en.wikipedia.org/wiki/Canonical_link_element"><code>canonical</code>选项</a>，即所谓的<a href="https://developers.google.com/search/blog/2009/02/specify-your-canonical">规范网址</a>——搜索引擎认定的链接范式；而新主题会根据hexo配置文件自动生成<code>canonical</code>。我并未将<code>pretty_urls</code>中的<code>trailing_index</code>与<code>trailing_html</code>设置为<code>false</code>，导致规范网址带有<code>index.html</code>后缀。但不知何故，此规范网址也会自动重定向至没有<code>index.html</code>后缀的链接。这导致Google和Bing对网站的索引逐渐消失，而我几天后才发现并修正，已然于事无补。</p><p>之后，我的网站的反向链接逐渐增多，尤其是将本站提交至<a href="https://v2ex.com/">V2EX</a>的<a href="https://v2ex.com/xna">VXNA节点</a>后，Google的索引逐渐恢复，但Bing的索引却迟迟未见起色。虽然在Bing Webmaster Tools的「搜索性能」中，显示索引页面数在不断增加，但使用<code>site</code>运算符搜索时，却显示没有结果。</p><p><img src="/2025/08/12/Notes-on-Losing-and-Regaining-Bing-Indexing/noindex.avif" alt="搜索时显示「没有与此相关的结果」"></p><p>在网上搜寻一番后，发现此种情况似乎不在少数。根据<a href="https://www.52txr.cn/2022/WhyBing.html">陶小桃</a>和<a href="https://www.zctou.com/2156.html">zcTou</a>等人的博客文章，这可能是站点进入了必应的黑名单之中，需要向官方反馈，提请人工审查。根据教程，我提交了「我的网站不在索引中」的问题。等待几天后，收到了如此回信：</p><blockquote><p>After further review, it appears that your site did not meet the standards set by Bing the last time it was crawled.</p></blockquote><p>其实我看到这个回复后有些失望。首先，必应官方只是说不符合质量标准，但又不具体指出，让我不知道从何做起。照理说，我的网站应该不是<a href="https://zh.wikipedia.org/wiki/%E5%85%A7%E5%AE%B9%E8%BE%B2%E5%A0%B4">内容农场</a>，先前也曾被必应收录过，质量上应该没有问题。其次，发件人为<a href="mailto:bingwb@microsoft.com">bingwb@microsoft.com</a>，当我希望进一步了解原因时，却发现该邮箱无法回复。更令人气愤的是，收到这封邮件后，我的索引页面数逐渐下降，最终只剩下个位数；每天可提交的URL数也从100变成了10。我甚至怀疑，一开始只是索引问题，在我反馈后，他们又将我的网站添加到了黑名单中。之后我多次联系必应官方，但收到的多封回复均为模板化的「未满足质量标准」。期间，我还找到了<a href="https://www.simoncox.com/post/2025-04-07-recovery-from-a-bing-de-indexing/">Simon Cox写的一篇博文</a>，步骤很详尽，我依照此文尝试，却不起作用，但读者不妨自查一番。</p><p>直到前几天，我突发奇想，反馈问题时选择了其他类别（错误的搜索结果—Issue with Favicon），发现负责的团队有所变化，发信人变成了<a href="mailto:bwtsupport@microsoft.com">bwtsupport@microsoft.com</a>。先前的工单编号都是以<code>REQ</code>开头，而这次则是以<code>UCM</code>开头。并且，他们的回复不再完全模板化，同时也可以直接回复邮件。他们提到，将问题上报至更高级别的团队后，确认我的网站违反了网站站长指南。当我询问违反了哪些具体规则时，他们也不清楚，但提及编制索引是由Bingbot爬虫自动完成的，他们无法控制这一流程。然而，在收信后一两天，网站的URL可提交数又上升至100。又过了几天，索引页面数也开始逐渐恢复，通过搜索引擎也能直接搜索到网站。</p><p>总之，搜索引擎的收录是个黑盒。虽然不能完全确定两者之间的关联，不过我猜，在把问题提交给后一个团队时，他们虽然认为我的网站不够格，但也不至于进入黑名单，故将其移出。而我的网站有一定的反向链接，因此爬虫很快就重新索引了。如果读者也受类似问题的困扰，不妨在向官方寻求支持时，尝试使用其他反馈类别，将问题提交给看起来就更负责的团队。</p>]]>
    </content>
    <id>https://blog.deepchirp.com/2025/08/12/Notes-on-Losing-and-Regaining-Bing-Indexing/</id>
    <link href="https://blog.deepchirp.com/2025/08/12/Notes-on-Losing-and-Regaining-Bing-Indexing/"/>
    <published>2025-08-12T15:47:05.000Z</published>
    <summary>本文记录了作者博客因配置失误导致必应的索引丢失，后联系必应官方，通过选择其他类别的反馈，得以恢复索引、重新收录网站。</summary>
    <title>必应索引失而复得小记</title>
    <updated>2025-08-12T15:47:05.000Z</updated>
  </entry>
</feed>
