<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Super Blog</title>
  
  <subtitle>循此苦旅 以达星辰</subtitle>
  <link href="https://superpung.com/atom.xml" rel="self"/>
  
  <link href="https://superpung.com/"/>
  <updated>2025-02-04T17:06:29.000Z</updated>
  <id>https://superpung.com/</id>
  
  <author>
    <name>SUPER</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  <follow_challenge>
    <feedId>65053891398556672</feedId>
    <userId>58518876444073984</userId>
  </follow_challenge>
  
  <entry>
    <title>2024：悲观者正确，乐观者前行</title>
    <link href="https://superpung.com/rev-2024/"/>
    <id>https://superpung.com/rev-2024/</id>
    <published>2025-02-04T17:06:29.000Z</published>
    <updated>2025-02-04T17:06:29.000Z</updated>
    
    <content type="html"><![CDATA[<p>回忆 2024 年的瞬间，在年的尺度上感受生命。</p><span id="more"></span><p>2024 年对我来说是很有意义的一年，虽然更加忙碌<del>（以至于本篇文章拖了一个多月才能写完）</del>，但好在还是做了很多事情。</p><h2 id="四季"><a href="#四季" class="headerlink" title="四季"></a>四季</h2><p>2024 开年伴随着春节，和多年未见的表哥见了面，但好朋友因事没能回家团聚。随着我们的成长与老去，越来越觉得如此团聚实属不易。谈论着儿时发生的故事，就像活在昨天一般。家庭是令人舒适的港湾，一年的紧张和辛劳都能在家人的陪伴中消散。</p><img data-src="https://61375c0.webp.li/2024-5km.JPG" alt="2024 第一个 5km" style="zoom:30%;" /><p>春天开始跑步，已经不记得上次跑 5km 是什么时候了。在 3 月 30 日完成了 2024 第一个 5km，跑步确实能让人感到快乐。</p><p><img data-src="https://61375c0.webp.li/2024-crabapple.jpg" alt="春日海棠"></p><p>四月正逢海棠花开，和女朋友一起去看花。满街的盛开和未盛开的海棠，映衬着熙熙攘攘的人流，在天空和古墙的背景下分外夺目。</p><p><img data-src="https://61375c0.webp.li/2024-IKEA.jpeg" alt="宜家"></p><p>趁着晴空万里，逛了宜家<del>（感觉就是库房 + 家具 + 餐厅）</del>。</p><p><img data-src="https://61375c0.webp.li/2024-platform.jpeg" alt="落日站台"></p><p>落日下的站台，伴随着春日的微风。铁路蜿蜒曲折，向落日延伸，是否能留住最后的余晖。</p><img data-src="https://61375c0.webp.li/2024-fastest-5km.jpg" alt="最快的 5km" style="zoom:30%;" /><p>夏天继续跑步，不断刷新 5km 记录。挑战体能，突破极限，正反馈令人备受鼓舞，在夏夜的晚风中可以忘掉一切。</p><p><img data-src="https://61375c0.webp.li/2024-summer-sunset.jpeg" alt="湖边落日"></p><p>在湖边欣赏落日，与宁静的湖水一起迎接夜幕降临。</p><p><img data-src="https://61375c0.webp.li/2024-fall.jpeg" alt="秋日"></p><p>转眼间到了秋天。自大学以来，一直只在寒假和暑假回家。今年为了弥补短暂的暑假，在十一假期赴上了回家的旅途。说来神奇，临时调整的会议安排、行程上的临时改签、得知我的发车时间临近而极限超车的出租车司机、差七分钟就要发车的高铁……一件件预料之外的突发情况仿佛在阻拦我回家的决定。</p><p>无论如何，我已经好久没有见过秋天的家乡了。这几年与家人团聚的时间日益减少，对家乡的印象也停留在极寒和极热之间。再会久违的家乡的秋高气爽，无比留恋。</p><p>时间来到了十一月，这是我一年中最难以忘怀的一段时间。在短暂的两周内，无数个 deadline 接踵而至。仍然有问题的实验代码、未完成的论文、未跑完的实验数据、答辩需要的材料、展示的 PPT、学术汇报的 PPT、学生的研究课题、学校的讲座安排、出差的时间规划、计划好和女朋友一起参与的活动……在那段时间，每一天的所有时段都安排好了任务。</p><p><img data-src="https://61375c0.webp.li/2024-work-in-taxi.JPG" alt="在出租车上工作"></p><p>甚至在出租车上，我也不得不在改文件。可惜改了一会就晕得不行，可能我不适合当这种打工人吧。</p><p>最难忘的是，两件重要的事仅隔 1 天。我需要同时准备好两场汇报，并在第一场汇报结束后乘飞机去往参会处，并在第二天参会之余准备好第三天的汇报。和我同住会议酒店的师兄在第三天也有汇报任务，于是在第二天晚上我们一起熬夜改 PPT……</p><p><img data-src="https://61375c0.webp.li/2024-rose.jpeg" alt="秋日玫瑰"></p><p>现在回想起来，那些事情都已有了阶段性的结果。好在挺过了那段紧张的时光，可惜错过了秋日的美景，只能在出差之余欣赏残存的玫瑰了。</p><h2 id="远方"><a href="#远方" class="headerlink" title="远方"></a>远方</h2><p>在忙碌之余，还好有时间出门走走。</p><p><img data-src="https://61375c0.webp.li/2024-CNBG.jpeg" alt="国家植物园"></p><p>春天，再次去了北京，到植物园看花。</p><p><img data-src="https://61375c0.webp.li/2024-shanghai-dalian.jpeg" alt="上海-大连"></p><p>晚春，在绿皮火车上，从黑夜到白天，沿着渤海湾，第一次踏足大连。</p><p><img data-src="https://61375c0.webp.li/2024-dalian.jpeg" alt="大连站"></p><p>大连的景色很美，人流量并不多，海边住宿的体验还不错。</p><p><img data-src="https://61375c0.webp.li/2024-dalian-square.jpg" alt="东港音乐喷泉广场"></p><p>在海边的广场，眺望着无边际的大海。没有人头攒动，只有海浪轻拂。</p><p>与大连相反，长沙是一个拥挤的城市。</p><p><img data-src="https://61375c0.webp.li/2024-huangxing-square.jpeg" alt="五一广场"></p><p>在夏天的长沙，五一广场上有无数的人来来往往。在这里见到了未曾见过的不夜城，即使到了凌晨也不曾退减。</p><p><img data-src="https://61375c0.webp.li/2024-hunan-museum.jpeg" alt="湖南省博物馆"></p><p>逛了湖南省博。</p><p><img data-src="https://61375c0.webp.li/2024-hunan-museum-mawangdui.jpeg" alt="马王堆"></p><p>以及马王堆。</p><p><img data-src="https://61375c0.webp.li/2024-orange-isle.jpeg" alt="橘子洲头"></p><p>还有橘子洲、岳麓山。</p><p>说来也巧，在我到达长沙前几天，这里正因大雨而关闭了岳麓山和橘子洲的参观。在到达后正逢开放参观，很高兴没有留下遗憾。</p><p><img data-src="https://61375c0.webp.li/2024-lobster.jpeg" alt="小龙虾"></p><p>长沙小龙虾确实好吃，十分推荐。</p><p><img data-src="https://61375c0.webp.li/2024-shaanxi-museum.jpeg" alt="陕西历史博物馆"></p><p>与长沙类似，西安的人流量也不小，但可以感受到其强大的历史底蕴。</p><p><img data-src="https://61375c0.webp.li/2024-xuanzang.jpeg" alt="玄奘像"></p><p>逛了陕历博、大雁塔、大唐不夜城。</p><p><img data-src="https://61375c0.webp.li/2024-roujiamo.jpeg" alt="肉夹馍"></p><p>西安肉夹馍确实好吃，十分推荐。</p><p>在西安的短暂几天，认识了许多新朋友，和大家玩得很开心。</p><h2 id="欢愉"><a href="#欢愉" class="headerlink" title="欢愉"></a>欢愉</h2><p>2024 年有许多快乐的瞬间，最难忘的是沉浸感受了天外来物。</p><p><img data-src="https://61375c0.webp.li/2024-extraterrestrial-1.jpeg" alt="天外来物"></p><p>从 16 年开始听他的歌曲，那是他还是“微博段子手”、“综艺狂”的人设。喜欢一首歌曲，有人因词共鸣，有人偏爱旋律，而我是前者。他的词曲陪伴了我 8 年，8 年间见证他从雪藏到闻名，从顶峰到低谷，从逆境到重生。有时很敬佩他的真诚，和对音乐的认真。</p><p><img data-src="https://61375c0.webp.li/2024-extraterrestrial-2.jpeg" alt="天外来物"></p><p>喜欢听他的歌，但也并不是“追星”，因此在此之前我甚至不知道“天外来物”巡回演唱会是何时开始的<del>（后来才发现 23 年来过我的城市，但当时没关注且没抢票……）</del>，最新的单曲也没有听过。偶然间得知他的巡演即将来到附近的城市，抱着试一试的心态竟然抢到了门票。</p><p><img data-src="https://61375c0.webp.li/2024-extraterrestrial-3.jpeg" alt="天外来物"></p><p>来到了演唱会的现场，在 23 年夏天看着录制的演唱会视频的我，如何能想到 24 年的今天能身临其境。震撼人心的开场、观众齐声的呐喊，无数脑海里的旋律如今在体育场回荡，身边是无数与我共鸣的人，台上是我多年倾听的“老友”。精心设计的演出桥段、极致的舞台表现力，带给我无数感动。当天的天气很冷，但在演出结束后他依然三次跪谢观众。</p><p>演唱会的体验带给我的是久久难忘的记忆，远胜于 8 年前偶然听到他的歌曲时的欣喜。在这之后，我开始重新了解他，重新聆听他的作品。才发现“天外来物”巡演从 21 年就已经开始，并已走遍了大江南北、世界东西。</p><p><img data-src="https://61375c0.webp.li/2024-xue-beijing.jpeg" alt="地铁站的薛之谦海报"></p><p>在收官之时，北京地铁可见演唱会海报，有“这城市怎么都是你”的感觉。在 818 苏州收官之后，又再次开启世界巡演返场，本巡也创造了许多历史性的“第一”。</p><p><img data-src="https://61375c0.webp.li/2024-extraterrestrial-store.jpeg" alt="“天外来物”便利店"></p><p>有趣的是，某天偶然在城市的角落发现了一个名为“天外来物”的便利店。</p><h2 id="重逢"><a href="#重逢" class="headerlink" title="重逢"></a>重逢</h2><p>很高兴在 2025 春节能与多年未见的老朋友重聚。</p><p><img data-src="https://61375c0.webp.li/2024-drone.jpg" alt="无人机"></p><p>一起在零下十几度的天气下飞无人机，差点没成功返航。</p><p><img data-src="https://61375c0.webp.li/2024-lantern.jpg" alt="孔明灯"></p><p>在冷风中尝试放飞孔明灯。</p><p><img data-src="https://61375c0.webp.li/2024-fireworks.jpeg" alt="烟花"></p><p><img data-src="https://61375c0.webp.li/2024-fireworks-gatling.jpg" alt="烟花"></p><p>除夕夜放烟花，仿佛回到了几年前。</p><p><img data-src="https://61375c0.webp.li/2024-lias-bar.jpeg" alt="Lias&#39; Bar"></p><p><img data-src="https://61375c0.webp.li/2024-pubg.jpeg" alt="PUBG"></p><p>一起玩了游戏。</p><p><img data-src="https://61375c0.webp.li/2024-dc1900.jpeg" alt="唐探 1900"></p><p>看了电影。</p><p><img data-src="https://61375c0.webp.li/2024-dinner.jpeg" alt="和朋友们聚餐"></p><p>和朋友们聚餐。</p><p><img data-src="https://61375c0.webp.li/2024-mahjong.jpeg" alt="麻将"></p><p>打麻将。</p><h2 id="数字"><a href="#数字" class="headerlink" title="数字"></a>数字</h2><p>仍然是数字总结时间。</p><p><img data-src="https://61375c0.webp.li/bilibili-2024.PNG" alt="Bilibili 2024"></p><p>341 天，比前几年略少了一些。</p><p><img data-src="https://61375c0.webp.li/netease-music-2024.PNG" alt="Netease Music 2024"></p><p>也许是因为用了 Apple Music，网易云的时间少了些。</p><p><img data-src="https://61375c0.webp.li/apple-music-2024.PNG" alt="Apple Music 2024"></p><p>周董的歌总是百听不厌。</p><p><img data-src="https://61375c0.webp.li/github-2024.png" alt="GitHub 2024"></p><p>可能比 23 年好一些？真的没有太多时间做开源了，写的大部分代码也都是论文的实验。</p><p><img data-src="https://61375c0.webp.li/gitlab-2024.png" alt="GitLab 2024"></p><p>实验代码的时间还是很多的。</p><p><img data-src="https://61375c0.webp.li/tju-expense-2024.png" alt="TJU Expense"></p><p>今年做了个校园卡支出的统计，Vibe Coding 很有趣。</p><p><img data-src="https://61375c0.webp.li/wakatime-2024.png" alt="Wakatime 2024"></p><p>Coding 的时间还是蛮多的。</p><p><img data-src="https://61375c0.webp.li/ns-2024.jpg" alt="Nintendo Switch 2024"></p><p>旷野之息和 Splatoon 是最喜欢的 NS 游戏。</p><p><img data-src="https://61375c0.webp.li/2024-footprint.jpg" alt="足迹"></p><p>今年去了几个城市，还不错！</p><h2 id="年度"><a href="#年度" class="headerlink" title="年度"></a>年度</h2><p>2024 年的年度 App 是：<a href="https://github.com/LazyVim/LazyVim">LazyVim</a>。</p><p>年度 App 提名是：</p><ul><li><a href="https://github.com/jesseduffield/lazygit">LazyGit</a></li><li><a href="https://timingapp.com/">Timing</a></li></ul><p>2024 年的年度影响力视频是：<a href="https://youtu.be/arj7oStGLkU">Inside the Mind of a Master Procrastinator | Tim Urban | TED</a></p><iframe width="560" height="315" src="https://www.youtube.com/embed/arj7oStGLkU?si=OYJsthvnJpJdtojl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe><p>2024 年的年度综艺是：<a href="https://www.mgtv.com/h/648886.html">魔方新世界</a>。</p><p>今年看的电视剧和电影比较少，就不对年度剧集和年度电影进行评选了。</p><h2 id="Things-Learned-in-2024"><a href="#Things-Learned-in-2024" class="headerlink" title="Things Learned in 2024"></a>Things Learned in 2024</h2><ul><li>有时在年的尺度上感受生命，可以远离眼前的烦恼。试着把自己放在更大的时间尺度上看问题，或许能获得新的视角。</li><li>很多事情都是从顶层设计到底层实现，过分思考底层实现会牵制想象力，过分思考顶层设计会难以推进。</li><li>合作。即使有很多天才可以独立完成一些伟大的事情，但大部分人还是需要合作才能完成更大的目标。</li><li>多线程并行。以前往往会想把事情一件一件做好，但实际上很多事情是可以并行推进的。学会时间切片和任务切片，合理安排时间。</li><li>分配任务。在不同的事情中，自己扮演的角色往往不同。学会分配任务，才能合理利用资源。</li><li>多从他人角度思考，甚至是对立方。这样能更好地理解对方的需求和动机，明白一些事情究竟是为什么，从而找到更好的解决方案。</li><li>积极沟通，向上社交。社交本就是一个资源置换的过程，积极沟通能帮助少走很多弯路，也有助于提高思维的敏捷。</li><li>摆脱学生思维。和导师更多是合作关系，所以积极向导师提出问题并索取答案，好过被动等待导师指导。</li><li>不要害怕失败。</li><li>学会提出问题。</li><li>成功从来不是靠运气，只有脚踏实地。成功的故事常有，而成功者“愚蠢的尝试”不常听。</li><li>Critical thinking。大部分言论都是一家之言，不要先接受。</li><li>选择本就大于努力。没什么值得抱怨的，就像有人说的，悲观者正确，乐观者前行。</li></ul><h2 id="展望"><a href="#展望" class="headerlink" title="展望"></a>展望</h2><p>已经来临的 2025 年，希望能有时间多陪家人，多陪身边的人。在技术方面，希望能参与开源软件的贡献，完成一项 side project。保持健康，努力行动。</p><h2 id="往年"><a href="#往年" class="headerlink" title="往年"></a>往年</h2><ul><li><a href="/rev-2023">我和我的 2023</a></li><li><a href="/rev-2022">我和我的 2022</a></li><li><a href="/rev-2021">我和我的 2021</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;回忆 2024 年的瞬间，在年的尺度上感受生命。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
  </entry>
  
  <entry>
    <title>Overleaf LaTeX citation 无法正常显示问题解决</title>
    <link href="https://superpung.com/overleaf-citation-error/"/>
    <id>https://superpung.com/overleaf-citation-error/</id>
    <published>2024-12-26T14:24:42.000Z</published>
    <updated>2024-12-26T14:24:42.000Z</updated>
    
    <content type="html"><![CDATA[<p>神奇的 Overleaf。</p><span id="more"></span><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>今天在用 Overleaf writing 的时候，使用 <code>\cite&#123;paper&#125;</code> 出现 <code>?</code> 而非 ref 序号。<code>main.tex</code> 的具体内容如下：</p><figure class="highlight latex"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">\usepackage</span>&#123;filecontents&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\begin</span>&#123;filecontents&#125;&#123;<span class="keyword">\jobname</span>.bib&#125;<span class="string"></span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">@article&#123;you2023,</span></span><br><span class="line"><span class="string">  author =       &#123;You&#125;,</span></span><br><span class="line"><span class="string">  title =        &#123;Overleaf is bad&#125;,</span></span><br><span class="line"><span class="string">  publisher =    &#123;Science&#125;,</span></span><br><span class="line"><span class="string">  year =         2023</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">@article&#123;you2024,</span></span><br><span class="line"><span class="string">  author =       &#123;You&#125;,</span></span><br><span class="line"><span class="string">  title =        &#123;Overleaf is not what you need at all&#125;,</span></span><br><span class="line"><span class="string">  publisher =    &#123;Science&#125;,</span></span><br><span class="line"><span class="string">  year =         2024</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span><span class="keyword">\end</span>&#123;filecontents&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\begin</span>&#123;document&#125;</span><br><span class="line"></span><br><span class="line">Overleaf is bad~<span class="keyword">\cite</span>&#123;you2023&#125;.</span><br><span class="line"></span><br><span class="line">Overleaf is not what you need at all~<span class="keyword">\cite</span>&#123;you2024&#125;.</span><br><span class="line"></span><br><span class="line">DO NOT use Overleaf~<span class="keyword">\cite</span>&#123;you2024,you2023&#125;.</span><br><span class="line"></span><br><span class="line"><span class="keyword">\bibliographystyle</span>&#123;plain&#125;</span><br><span class="line"><span class="keyword">\bibliography</span>&#123;<span class="keyword">\jobname</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\end</span>&#123;document&#125;</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></pre></td><td class="code"><pre><span class="line">Overleaf is bad [?].</span><br><span class="line">Overleaf is not what you need at all [?].</span><br><span class="line">DO NOT use Overleaf [?, ?].</span><br></pre></td></tr></table></figure><p>但十分奇怪的是，并不是开始时就出现此问题。当我新建项目并导入 <code>TeX</code> 文件时，Overleaf 可以正常编译并显示 ref 序号：</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></pre></td><td class="code"><pre><span class="line">Overleaf is bad [1].</span><br><span class="line">Overleaf is not what you need at all [2].</span><br><span class="line">DO NOT use Overleaf [1, 2].</span><br></pre></td></tr></table></figure><p>当删除 ref 内容再重新粘贴回去时，序号就会变为 <code>?</code>，且重新编译不能解决。</p><p>于是搜索了一下相关问题，但并没有找到类似问题的讨论。尝试了清除缓存、检查并修改文件名、检查 <code>sty</code> 文件、调整文件路径、更换编译器等操作后，均无法解决此问题。</p><h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><p>Overleaf 内置的编译器（<code>pdfLaTeX</code> 和 <code>LaTeX</code>）对 <code>\jobname</code> 的支持有问题，因此需要将隐式的 <code>\jobname</code> 替换为显式的文件名称。</p><p>以 <code>main.tex</code> 举例，需要将 <code>\jobname</code> 替换为 <code>main</code>：</p><figure class="highlight latex"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">\usepackage</span>&#123;filecontents&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\begin</span>&#123;filecontents&#125;&#123;main.bib&#125;<span class="string"></span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">@article&#123;you2023,</span></span><br><span class="line"><span class="string">  author =       &#123;You&#125;,</span></span><br><span class="line"><span class="string">  title =        &#123;Overleaf is bad&#125;,</span></span><br><span class="line"><span class="string">  publisher =    &#123;Science&#125;,</span></span><br><span class="line"><span class="string">  year =         2023</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">@article&#123;you2024,</span></span><br><span class="line"><span class="string">  author =       &#123;You&#125;,</span></span><br><span class="line"><span class="string">  title =        &#123;Overleaf is not what you need at all&#125;,</span></span><br><span class="line"><span class="string">  publisher =    &#123;Science&#125;,</span></span><br><span class="line"><span class="string">  year =         2024</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span><span class="keyword">\end</span>&#123;filecontents&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\begin</span>&#123;document&#125;</span><br><span class="line"></span><br><span class="line">Overleaf is bad~<span class="keyword">\cite</span>&#123;you2023&#125;.</span><br><span class="line"></span><br><span class="line">Overleaf is not what you need at all~<span class="keyword">\cite</span>&#123;you2024&#125;.</span><br><span class="line"></span><br><span class="line">DO NOT use Overleaf~<span class="keyword">\cite</span>&#123;you2024,you2023&#125;.</span><br><span class="line"></span><br><span class="line"><span class="keyword">\bibliographystyle</span>&#123;plain&#125;</span><br><span class="line"><span class="keyword">\bibliography</span>&#123;main&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">\end</span>&#123;document&#125;</span><br></pre></td></tr></table></figure><p>但如果只是这样替换，并无法解决问题。还需要在同目录下新建 <code>main.bib</code> 文件，将 <code>\begin&#123;filecontents&#125;&#123;main.bib&#125;</code> 和 <code>\end&#123;filecontents&#125;</code> 之间的内容拷贝至 <code>main.bib</code>。此时可以删除 <code>main.tex</code> 中的对应内容。</p><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></pre></td><td class="code"><pre><span class="line">Overleaf is bad [1].</span><br><span class="line">Overleaf is not what you need at all [2].</span><br><span class="line">DO NOT use Overleaf [1, 2].</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;神奇的 Overleaf。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="LaTeX" scheme="https://superpung.com/tags/LaTeX/"/>
    
    <category term="Overleaf" scheme="https://superpung.com/tags/Overleaf/"/>
    
  </entry>
  
  <entry>
    <title>Mac 终端无法联网问题解决</title>
    <link href="https://superpung.com/mac-terminal-network/"/>
    <id>https://superpung.com/mac-terminal-network/</id>
    <published>2024-12-20T18:04:16.000Z</published>
    <updated>2024-12-20T18:04:16.000Z</updated>
    
    <content type="html"><![CDATA[<p>神奇的 macOS。</p><span id="more"></span><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>今天本想装个东西，但 <code>brew update</code> 时一直报 <code>could not resolve host</code>。第一时间觉得是 Clash 的问题，于是设置了 proxy，但仍未解决，尝试 unset 但也无济于事。</p><p>后来发现不仅对于 <code>github.com</code> 报错，甚至对镜像 <code>mirrors.tuna.tsinghua.edu.cn</code> 也报错，<code>ping</code> 了一下 <code>github.com</code> 和 <code>baidu.com</code>，果然都不通。因此并不是 proxy 的问题。</p><p>尝试 <code>ping 8.8.8.8</code>，发现可以通。因此原因基本可以锁定是 DNS 设置的问题。</p><p>但之前从未更改过 Mac 的 DNS 设置，为什么终端突然不能联网了呢？尝试在 Settings - Wi-Fi - Details - DNS - DNS Servers 添加了两个阿里云的 DNS Server：<code>223.5.5.5</code>、<code>223.6.6.6</code>，并刷新 DNS 缓存：</p><figure class="highlight sh"><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="built_in">sudo</span> dscacheutil -flushcache</span><br><span class="line"><span class="built_in">sudo</span> killall -HUP mDNSResponder</span><br></pre></td></tr></table></figure><p>稍等几分钟后，终端网络恢复正常。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>当 Mac 终端无法联网时，大多是因为两种情况：proxy 和 DNS，首先可以通过 <code>ping</code> 一个 IP（如 <code>ping 8.8.8.8</code>）检查是否是 DNS 的问题。</p><p>如果是 DNS 的问题，手动在 Settings - Wi-Fi - Details - DNS - DNS Servers 处添加公共 DNS Server（如 <code>223.5.5.5</code> 和 <code>223.6.6.6</code>）并刷新缓存：</p><figure class="highlight sh"><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="built_in">sudo</span> dscacheutil -flushcache</span><br><span class="line"><span class="built_in">sudo</span> killall -HUP mDNSResponder</span><br></pre></td></tr></table></figure><p>这种方式在大多数情况下应该都可以解决 DNS 问题导致的网络连接问题。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;神奇的 macOS。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="Mac" scheme="https://superpung.com/tags/Mac/"/>
    
    <category term="Apple" scheme="https://superpung.com/tags/Apple/"/>
    
  </entry>
  
  <entry>
    <title>我和我的 2023</title>
    <link href="https://superpung.com/rev-2023/"/>
    <id>https://superpung.com/rev-2023/</id>
    <published>2023-12-31T03:58:24.000Z</published>
    <updated>2023-12-31T03:58:24.000Z</updated>
    
    <content type="html"><![CDATA[<p>上一次在学校跨年还是 2019 年。四年过去了，我还在这里。</p><span id="more"></span><p>如果有人问我，你和四年前有何不同？很遗憾，我并不确定自己是否真正做出了改变。在相似的新旧交替之际，我试着寻回四年前的记忆，却不敢认出那个自己。穿越时间的相遇，让我发现自己并没有变得更好，反而失去了那时一般的快乐，也失去了那时对今日的期望。我不知道是否“成长”皆如此般令人怅然，只知道行路至此，我依然没有踏出那片荒野。</p><p>2023 年真的如去年期望一般变好了吗？也许有些，但在不同的阶段总会有不同的困难。2023 对我来说是一个比较大的转折点，从越来越躺平的本科生活到忙碌的研究生生活，我逐渐明白了若想有所为则需有所不为。遇到的选择题从来不会减少，所以只能按照局部最优踟躇向前。站在 2024，与背后的 2019 已经相隔了五年，却仍感觉 2019 很近，也许是因为 2020-2022 并没有留下太多的记忆点，这段时间被我们在内心折叠。</p><p>我的 2023 也如此一般飞逝。翻看相册才发觉，虽然上半年自由的时间很多，但下半年的大部分时间都忙于工作，甚至没留下许多照片。无法挽回我这越来越无聊的生活，只希望前行的路上亦能且行且歌。</p><hr><p>现在回想起来，22 年冬天可能是我人生中最后一个美好的寒假。和家人团聚，和老友重聚，有许多时间自我冥想和放空。</p><p>通过了考试，准备复试，录取。这段时间很难熬，归根到底是对未知的恐惧和对未来的迷茫。只记得复试前的几天天气阴沉，复试之后开始放晴，我的内心也逐渐平静。总有许多话想记录，但零碎的空闲时间击碎了记录的热情。希望我能在下一个自己的时间完成这些事情……</p><p>上半年的空闲时间很多，重新逛了一次北京，感觉和七年前的印象好不一样。来一次说走就走的旅行，第一次踏上山东的土地，感谢 YF 的招待。看了很多风景，吃了很多美食，两次通宵 KTV 印象深刻。喜欢这种自由，希望 2024 依旧有心情行万里路。</p><p>毕业，一条分隔线将我的人生划开。也许是因为常常低头行路，却不曾发现自己已经走了很远。和朋友们一个一个道别，各自去往不同的方向，四年的喜怒哀乐在两本证书、一张照片中被封存。我知道这种经历不会再来，就像我的青春一去不复还。</p><p>分隔线开启了我忙碌的下半年。研究生生活虽然带来了更多自由的时间，但未曾涉足的领域和新的挑战也让我压力倍增。</p><blockquote><p>It is no use doing what you like; you have got to like what you do.</p></blockquote><p>导师和实验室的师兄都很 nice，大家都很有实力，希望我自己也能应对不断的挑战，继续走下去。</p><p>在少有的闲暇时间，突然对摄影很感兴趣，入手了 📷 。结局就是过于忙碌以至于吃灰了许久，虽然拍了一些照片，但还有好多没来得及修。希望有时间能多出去走走。</p><p>忙里得闲，压力需要娱乐缓解。重拾了 Steam 游戏，也突然对 NS 很感兴趣。遗憾的是 23 年的末尾才开始接触 NS，50 小时+ 畅游海拉鲁大陆没有让我感到疲倦。内心的紧张和压抑在游戏中得以释怀，希望 2024 能找回更多的乐趣。</p><hr><p>OK，结束这压抑的流水账，接下来是一年一度的数字总结时间！</p><p>首先是网易云音乐，从下到上依次是 2020、2021、2022、2023 年度总结。</p><p><img data-src="https://i0.hdslb.com/bfs/article/6c53e8c3413e9e8ec455af809733dc2e291637678.jpg@27p_100q.jpg" alt="netease-music-2023"></p><img data-src="https://i0.hdslb.com/bfs/album/18d23ec6e1d91a6d387a6452a11557f13f0fcfa4.png" alt="netease-music-2022" style="zoom:36%;" /><p><img data-src="https://i0.hdslb.com/bfs/album/dc3d493bc67161ae50101da2e6a81a5470b5fe72.png" alt="2021-22"></p><p><img data-src="https://i0.hdslb.com/bfs/album/94cef62384e8d5ec2029703d34ab92f7d59e63d6.png" alt="2021-24"></p><p>23 年用网易云的时间屈指可数，因为网易云音乐 app 冗余的功能、倒退的设计、少量的曲库、更多的广告，让我不得不放弃这个平台。去年曾开始使用 Apple Music，但每次 App Store 换区时我的音乐库都会被清空，所以我也不得不放弃它。最终选择了 Spotify，目前仍然是我的主要音乐平台。</p><p><img data-src="https://i0.hdslb.com/bfs/article/a5df50f6de94a6bdae2d75b81495e551291637678.jpg@30p_100q.jpg" alt="spotify-2023"></p><p>然后是 Bilibili，我以为 2023 我会比 2022 时间更长，但事实上看的更少了。</p><table><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/ed49fe23ded6dd54d3149c7e11452f9b4c701f9b.png" alt="2021-23" height=500px /></td><td><img data-src="https://i0.hdslb.com/bfs/album/fe48890094cb5f6cf8af29766ee079bf37082d8f.jpg" alt="bilibili-2022" height=500px /></td><td><img data-src="https://i0.hdslb.com/bfs/article/57ade8c3baa9002660923941bd4f4451291637678.png" alt="bilibili-2023" height=500px /></td></tr></table><p>2023 依然没有在开源事业上有所进步。有几个 project 的 idea，但苦于没有时间实现，也有几个 project 写了一点就不了了之。希望 2024 我能写完一个。</p><p><img data-src="https://i0.hdslb.com/bfs/article/2724af94ae19bb56822a7009f545ad04291637678.png" alt="github-2023"></p><hr><p>从去年开始，我计划每年评选出 1～2 个“年度 app”。2021 年度 app 是 Notion，这也是我目前主力笔记软件；2022 年度 app 是 Arc，这也是我目前主力浏览器。2022 另一个年度 app 是 ChatGPT，没想到它在 2023 年引发了世界人工智能和大语言模型的热潮。2023 我评选的年度 app 是 1Password，它改变了我记录密码的方式，也让我更加安全地管理越来越多的账户。</p><p>除了“年度 app”，我还打算评选出我的“年度影响力视频”。今年的是 <a href="https://www.bilibili.com/video/BV19c411o7os">【毕导】13年过去了，我终于毕业啦！_哔哩哔哩_bilibili</a>。</p><iframe src="//player.bilibili.com/player.html?aid=280129629&bvid=BV19c411o7os&cid=1313429825&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe><p>除了“年度影响力视频”，我还打算评选“年度电影”和“年度剧集”。今年一共看了 33 部电影和剧集，我的“年度电影”是 <a href="https://movie.douban.com/subject/1292343">《蝴蝶效应》</a>，“年度剧集”是 <a href="https://movie.douban.com/subject/35588177">《漫长的季节》</a>。</p><p>以上评选的内容都出于我的主观评价，对我来说都很有意义。期待 2024 可以看到更多优秀的作品。</p><hr><p>2023 带给我最大的感受就是，我开始更深刻地认识自身。</p><p>我不断认识到自己的缺点，这些在我独自完成有挑战性的任务时总会显现出来。</p><p>2023 是充满挑战的一年，我不在沉迷于自己的舒适圈，开始寻求一些改变。</p><p>痛苦常伴，快乐易逝；道阻且长，不虚此行。愿来年我能过得从容，至少改掉一个缺点，至少完成一个目标。</p><p>2024，要开心。</p><p><img data-src="https://i0.hdslb.com/bfs/article/fbbed187a98cd5598831b6c35e05899a291637678.jpg" alt="rev-2023"></p><p>2023，再见！</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;上一次在学校跨年还是 2019 年。四年过去了，我还在这里。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
  </entry>
  
  <entry>
    <title>新起点</title>
    <link href="https://superpung.com/new-ui/"/>
    <id>https://superpung.com/new-ui/</id>
    <published>2023-04-03T08:23:27.000Z</published>
    <updated>2023-04-03T08:23:27.000Z</updated>
    
    <content type="html"><![CDATA[<p>新的样子，新的开始。</p><span id="more"></span><p>忙碌了 5+3 个月，很多重要的事情终于有了结果。过去的一个月可能是比较 challenging 的一个月，面对种种未知和阻碍，最后还是挺了过来。很难说收获了什么经验，只不过是随着时间的流逝而不得不面对罢了。</p><p>话说回来，从寒假开始构思如何改造本站的 UI 以更符合我的审美，最终做了如下更改：</p><ol><li>不再使用英文为主要语言，改为完全中文站；</li><li>改用 <a href="https://github.com/lxgw/LxgwWenKai">霞鹜文楷</a> 作为主要字体；</li><li>重构许多 UI 细节，增加圆角等；</li><li>重构色彩搭配，重新设计了亮暗模式；</li><li>不再使用 <a href="https://github.com/utterance/utterances">utterances</a> 为评论系统，改为使用 <a href="https://github.com/giscus/giscus">giscus</a>，也就是把评论系统从 Issues 改为 Discussions；</li><li>其他若干修改。</li></ol><p>当然，这次对 NexT 主题的魔改也存在不合理之处，目前发现的 bug 有：</p><ol><li><del>评论需要手动刷新才加载</del> <a href="https://github.com/next-theme/hexo-next-giscus/commit/84531743bf8d86e12bb6f7950e81a5a135bc48c8">已解决</a>；</li><li>评论在暗色模式下仍呈现亮色；</li><li>字体的粗体格式很不明显；</li><li>其他若干问题，欢迎你在下方评论区提出。</li></ol><p><img data-src="https://article.biliimg.com/bfs/article/2dbc2aa46af9623a181a2e58f3edf4345dabdd89.png" alt="旧版UI"></p><p><img data-src="https://article.biliimg.com/bfs/article/b1a1c65cce9595a45dfc319311f1435409d1979c.png" alt="新版UI"></p><p>现在开始，是本站的新起点，也是我的新篇。</p><blockquote><p>最近应该会更新几篇文章，敬请期待（在写了在写了）。</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;p&gt;新的样子，新的开始。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
    <category term="博客配置" scheme="https://superpung.com/tags/%E5%8D%9A%E5%AE%A2%E9%85%8D%E7%BD%AE/"/>
    
  </entry>
  
  <entry>
    <title>使用 Arc 浏览器自定义网页</title>
    <link href="https://superpung.com/arc-boost/"/>
    <id>https://superpung.com/arc-boost/</id>
    <published>2023-01-27T05:52:06.000Z</published>
    <updated>2023-01-27T05:52:06.000Z</updated>
    
    <content type="html"><![CDATA[<p>方便、快捷地自定义网页，无需安装任何插件。</p><span id="more"></span><h2 id="什么是-Arc-浏览器"><a href="#什么是-Arc-浏览器" class="headerlink" title="什么是 Arc 浏览器"></a>什么是 Arc 浏览器</h2><p>在上一篇文章 —— <a href="/rev-2022">2022 年度总结</a> 中，我提到了去年比较满意的一款产品：Arc 浏览器。它是一款基于 Chromium 的浏览器，有很多传统浏览器没有的新功能。这里不过多介绍它的其他功能，主要讲一讲自定义网页 —— 即 <a href="https://youtu.be/53KQ2wUZG2s">Arc Boost</a>。</p><h2 id="为什么要自定义网页"><a href="#为什么要自定义网页" class="headerlink" title="为什么要自定义网页"></a>为什么要自定义网页</h2><p>我喜欢使用浏览器，只要浏览器能做的，我一般不会下载 app。很多网站的布局、设计和推荐的内容都不是我想要的，我希望能够自定义网页，只看到我想要的内容。比如在用 Bilibili 时，视频上方的推荐搜索、直播间花里胡哨的活动通知和礼物等，我都不想看到。这些内容在 app 中是不可以自定义的，但正因为是浏览器，才有了自定义网页的可能。</p><h2 id="为什么不…？"><a href="#为什么不…？" class="headerlink" title="为什么不…？"></a>为什么不…？</h2><h3 id="为什么不直接修改网页源代码？"><a href="#为什么不直接修改网页源代码？" class="headerlink" title="为什么不直接修改网页源代码？"></a>为什么不直接修改网页源代码？</h3><p>这样做的话，每次网页刷新都需要重新修改，而且不同路由下的网页都需要修改，比较麻烦。</p><h3 id="为什么不直接安装插件？"><a href="#为什么不直接安装插件？" class="headerlink" title="为什么不直接安装插件？"></a>为什么不直接安装插件？</h3><div class="note info"><p>上文和下文提到的“插件”指的就是浏览器的扩展（extension）。</p></div><p>当然，对于 Bilibili 网站，有很多出色、强大的自定义插件可供使用。但插件提供了太多我不需要的功能，提供的需要的功能实现又过于复杂也不是我想要的样子，而且向插件中添加我想要的功能又太麻烦，最后成了为了自定义网页而去自定义插件。</p><h2 id="如何快速利用-Arc-Boost-自定义网页（以-Bilibili-为例）"><a href="#如何快速利用-Arc-Boost-自定义网页（以-Bilibili-为例）" class="headerlink" title="如何快速利用 Arc Boost 自定义网页（以 Bilibili 为例）"></a>如何快速利用 Arc Boost 自定义网页（以 Bilibili 为例）</h2><p>首先，你要有一台运行 macOS 的电脑，因为 Arc 浏览器暂时只支持 macOS。</p><p>其次，你需要安装 Arc 浏览器，这里是邀请码：</p><blockquote><p>hey, here’s an invite to Arc, the browser I was telling you about!</p><p><a href="https://arc.net/gift/44d83098">https://arc.net/gift/44d83098</a></p></blockquote><p>在浏览器中打开 <a href="https://bilibili.com/">Bilibili</a>，在侧边栏的右下角 <code>+</code> 号中选择 <code>New Boost</code>，即可进入 Arc Boost 编辑页面。</p><p><img data-src="https://i0.hdslb.com/bfs/album/1dbcab3fdcf8e8d848f326145da195165d14c18e.png" alt="Arc Boost 编辑页面"></p><p>点击 <code>Style</code> - <code>A specific website</code>，在窗口中将 <code>www.bilibili.com</code> 改为 <code>bilibili.com</code>，点击 <code>Create Boost</code>，即可进入 <code>styles.css</code> 编辑页面。</p><div class="note info"><p>因为 Bilibili 空间、直播间等页面的三级域名都不是 www，如果这里只写 www，会导致自定义 css 在这些页面无法生效。</p></div><p><img data-src="https://i0.hdslb.com/bfs/album/22e9ac3d7f36682460d2259855ce4983f5d0645f.png" alt="Arc Boost css 页面"></p><p>这里就是自定义网页的地方了，你可以在这里添加你想要针对 Bilibili 的 css 代码，浏览器会自动覆盖掉原网页的 css。</p><div class="note info"><p>你应该对 css 有一些比较基础的了解。如果完全不了解，Arc 浏览器还贴心地提供了很多教程，在右上角的 Handbook 中可以找到。</p></div><p>下面以隐藏 Bilibili 网页上方的推荐搜索为例，这里是修改前的网页：</p><p><img data-src="https://i0.hdslb.com/bfs/album/3bf9db6c793b12ddbfb00f839b51911e940be08f.png" alt="修改前"></p><p>用开发者工具找到搜索框的元素路径，这里是 <code>#nav-searchform &gt; div.nav-search-content &gt; input</code>。</p><p>删除原有的 css 代码，添加如下代码：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#nav-searchform</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.nav-search-content</span> &gt; <span class="selector-tag">input</span><span class="selector-pseudo">::placeholder</span> &#123;</span><br><span class="line">  <span class="attribute">color</span>: transparent;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>浏览器会自动保存并自动刷新，修改后的网页如下：</p><p><img data-src="https://i0.hdslb.com/bfs/album/7d216ad778c1d1415dd9115f37a6f70260f590af.png" alt="修改后"></p><p>而且此后只要通过 Arc 浏览器访问 Bilibili，都会自动隐藏搜索框的推荐搜索。</p><p>是不是很简单！</p><h2 id="修改更多网页"><a href="#修改更多网页" class="headerlink" title="修改更多网页"></a>修改更多网页</h2><p>这三行代码可以隐藏 Bilibili <strong>首页</strong> 上方的推荐搜索，但在其他页面可能不生效。因为 Bilibili 其他页面的结构可能有所不同，所以需要到不生效的页面再次找到对应的元素路径，然后添加 css 代码。</p><p>这里以直播间页面 <a href="https://live.bilibili.com/">https://live.bilibili.com/</a> 的搜索框路径为例：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#nav-searchform</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.p-relative</span><span class="selector-class">.search-bar</span><span class="selector-class">.over-hidden</span><span class="selector-class">.border-box</span><span class="selector-class">.t-nowrap</span> &gt; <span class="selector-tag">input</span><span class="selector-pseudo">::placeholder</span> &#123;</span><br><span class="line">  <span class="attribute">color</span>: transparent;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>应该可以隐藏全部搜索框的推荐搜索了。</p><p>说到直播间，默认的 Bilibili 直播间是这样的：</p><p><img data-src="https://i0.hdslb.com/bfs/album/d675a80cd2b2978ee3b45771e9460a0b861306c6.png" alt="Bilibili 默认直播间"></p><p>比如我只想看 v，不喜欢充值、送礼物、打赏、买周边、上舰，那么上面的礼物星球、限时领取、购物提示，以及下面的小橙车、一排礼物、上舰提示、充值按钮，都是我不想看到的。这时就可以找到它们的元素路径，然后添加 css 代码隐藏它们。</p><figure class="highlight css"><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="selector-id">#head-info-vm</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.lower-row</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.left-ctnr</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.gift-planet-entry</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#head-info-vm</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.lower-row</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.left-ctnr</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.activity-gather-entry</span><span class="selector-class">.activity-entry</span><span class="selector-class">.s-activity-entry</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#gift-control-vm</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.vertical-middle</span><span class="selector-class">.dp-table</span><span class="selector-class">.section</span><span class="selector-class">.right-part</span><span class="selector-class">.p-relative</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#gift-control-vm</span> &gt; <span class="selector-tag">div</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.left-part-ctnr</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.ecommerce-entry</span><span class="selector-class">.gift-left-part</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#sections-vm</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.section-block</span><span class="selector-class">.f-clear</span><span class="selector-class">.z-section-blocks</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.left-container</span> &gt; <span class="selector-tag">div</span><span class="selector-class">.flip-view</span><span class="selector-class">.p-relative</span><span class="selector-class">.over-hidden</span><span class="selector-class">.w-100</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#shop-popover-vm</span>, <span class="selector-id">#my-dear-haruna-vm</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: none;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>修改后：</p><p><img data-src="https://i0.hdslb.com/bfs/album/9434bae5a17737cf2d8529f4c387e2d5e2c72be4.png" alt="Bilibili 修改后直播间"></p><p>是不是简洁很多！这下可以专心看直播了。</p><p>同理，你可以修改任何网页，只要找到对应的元素路径，然后添加 css 代码就可以了。</p><h2 id="这是怎么实现的？"><a href="#这是怎么实现的？" class="headerlink" title="这是怎么实现的？"></a>这是怎么实现的？</h2><p>实际上，Arc Boost 就是为浏览器添加了一个插件。比如刚才我们添加的对于 bilibili.com 的 Boost，可以在已安装的插件中找到：</p><p><img data-src="https://i0.hdslb.com/bfs/album/0c2f3aff2006a0d43b6543cde2874fb03e3c18a8.png" alt="已安装的插件"></p><p>在插件管理中，可以看到具体信息，包括插件的大小、权限和存储位置等：</p><p><img data-src="https://i0.hdslb.com/bfs/album/3f15f51105a1fc8846e54e7ee0520dc61227ae73.png" alt="Arc Boost 详情"></p><p>上面显示 &lt; 1 MB，其实也就 2 KB。</p><p><img data-src="https://i0.hdslb.com/bfs/album/d366149c8c08efe6aa89c3e0a519c08d043e96d8.png" alt="Arc Boost 文件夹"></p><h2 id="如何发挥-Arc-Boost-更大的作用？"><a href="#如何发挥-Arc-Boost-更大的作用？" class="headerlink" title="如何发挥 Arc Boost 更大的作用？"></a>如何发挥 Arc Boost 更大的作用？</h2><p>得益于 Arc 浏览器优秀的套壳技术，对于已经添加的 Boost，可以在作用的网页右上角的插件列表（Extensions）中看到，且单独以“Boosts”列出，可以一键删除、修改或置顶，不需要单独在 Finder 中打开并修改。</p><p>Arc Boost 的作用远不止于此。本文只介绍了它的最简单的用法 —— 改变网站样式，实际上，正如一开始进入 Boost 所见，它还可以通过编写 JavaScript 代码替换、注入网站内容，或者做任何事情。它的存在将浏览器插件的开发门槛降到了极低，让任何人都可以轻松地编写并使用适合自己的浏览器插件，不依赖其他工具。</p><p><a href="https://arcboosts.com/">https://arcboosts.com/</a> 收录了很多有趣的 Boost，你可以在这里探索适合自己的，或者自己编写一个并上传上去。如果你有更多关于 Arc Boost 或 Arc 浏览器 的想法，欢迎在下方留言交流。</p><h2 id="题外话"><a href="#题外话" class="headerlink" title="题外话"></a>题外话</h2><div class="note info"><p>如果你只想看关于本文主题的内容，可以跳过这一部分。</p></div><p>细心的小伙伴应该已经发现了，我的博客域名又又又换了。从最开始的 .xyz 到后来的 .cn，再到现在的 .com，以后应该不会再换了。这次换域名的原因是，之前在 <a href="https://www.value-domain.com/">Value Domain</a> 上面一元买到了 6 个域名，现在的这个域名就是其中之一。.com 域名确实更加通用，而且不用放在国内的阿里云或腾讯云上（相比 .cn），我转移到了 Cloudflare 上，体验也更好。原来的 .cn 域名做了跳转，所以这次迁移暂时也不会影响到原来的链接（为什么说是“暂时”呢，因为 .cn 域名过期之后大概率不会再续费了，所以到时候原来的链接肯定会失效）。唯一受影响的就是之前不蒜子统计的浏览数据了，不过也没什么关系，新的开始，新的计数。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;方便、快捷地自定义网页，无需安装任何插件。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="Arc 浏览器" scheme="https://superpung.com/tags/Arc-%E6%B5%8F%E8%A7%88%E5%99%A8/"/>
    
  </entry>
  
  <entry>
    <title>我和我的 2022</title>
    <link href="https://superpung.com/rev-2022/"/>
    <id>https://superpung.com/rev-2022/</id>
    <published>2022-12-31T02:41:04.000Z</published>
    <updated>2022-12-31T02:41:04.000Z</updated>
    
    <content type="html"><![CDATA[<p>年更 Blogger 的 2022，是平凡但不平静的一年。</p><span id="more"></span><p>回看了 2021 的年度总结，感叹 2022 确实因各种原因变得更平淡无奇。一方面因为疫情和防控，基本没有出校的机会，枯燥的学校生活让人难以留下深刻的记忆，禁锢的脚步让人难以满足生活的现状，无休止的打扰让人充满无奈和妥协。另一方面由于下半年的考试准备，推辞了很多有趣的事情，也“忍痛割爱”地放弃了坚持许久的探索，而且准备考试的过程更加无聊和乏味。很惭愧，2021 对 2022 充满期待的我未能如愿以偿，在今天的心境下也难以抒发去年今日的积极感。</p><p>机缘巧合下，今年跨年在家里一个人度过。上次在家里跨年还是在 7 年前的初中，已经记忆不清了。之后几年的跨年都是在高中，然后就是在大学了。惟有感慨时光飞快，无数记忆碎片填满了过去的回忆，时间如刀割般在某些时刻断裂，又在整体上相连。太阳在 2022 年最后一次落下，也会在 2023 年第一次升起，希望新的一天可以扫除旧的阴霾，带来新的希望。</p><p>回忆上一个假期，只能想起寒假，而暑假的记忆却很模糊。寒假是和朋友们团聚的假期，在这之前满分通过科四拿到了驾驶证（然而并没有开车…），和朋友们去滑雪，也是第一次。</p><img data-src="https://i0.hdslb.com/bfs/album/526cdd69eb65f4e4223659bf93c26bd21e98d726.jpg" alt="ski-2022" style="zoom:10%;" /><p>这是某次滑下来的场景，滑雪对身体不协调的人来说好难。</p><p>相比之下，暑假生活略显平淡和短暂。一方面朋友们大多忙于实习和工作，或疫情防控原因，或时间原因没能团聚；另一方面暑假开始准备考试，规划下半年的计划，也很少有能自由支配的时间。</p><p>不过从 6 月开始养成的记“日记”习惯让我比较受益。不是传统意义的日记，只是某时某刻想到的一句话、一个灵感、一个经验、一个总结，按时间和方向有意识地记下来，现在回看仍有很大的意义。让我觉得这一年并没有在浑浑噩噩中度过，相反，这一年可能是我思想上提高最大的一年，或多或少得益于我的大部分想法都能记录下来，当串连起来时更能引发新的感悟。</p><p>这一年也看了很多电影和剧，也有意识地记录在了 Notion 里，包括《爱、死亡和机器人》等充满创意的 Series，也有《Friends》等经典美剧，希望新的一年能有更多时间欣赏更多优秀的作品</p><p>暑假打卡了 Apple Store，在 Genius Bar 换了一个键盘，详情可以看 <a href="/genius-bar">这篇文章</a>。</p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">a tour of Genius Bar <a href="https://t.co/omgvOWzDZG">pic.twitter.com/omgvOWzDZG</a></p>&mdash; 𝙎𝙐𝙋𝙀𝙍 (@repusme) <a href="https://twitter.com/repusme/status/1551117378708455427?ref_src=twsrc%5Etfw">July 24, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>同时也换了新 iPad，不巧在闲鱼上遇到了假冒的 Apple Pencil。和骗子斗争几天后，最终成功全身而退，对方也受到注销账号的处罚，我发布的一篇“如何辨别真假 Apple Pencil”的帖子也收获了数万次浏览。</p><p>今年是世界杯年，继初中（2014）、高中（2018）后，是第三次看世界杯。还记得 2018 年世界杯时，还在幻想 4 年后的 2022 我会以什么样的处境和心境看这场比赛。那时对今日的想象很不清楚，此时对彼刻的回忆也很模糊。总之，今年的世界杯决赛非常精彩，恭喜阿根廷、恭喜梅西夺冠 🏆。</p><p>最后记录一下数字总结。使用网易云音乐的第 7 年，也是正式使用 Apple Music 的第一年，所以使用网易云音乐的次数也在减少。</p><p><img data-src="https://i0.hdslb.com/bfs/album/94cef62384e8d5ec2029703d34ab92f7d59e63d6.png" alt="2021-24"></p><p><img data-src="https://i0.hdslb.com/bfs/album/dc3d493bc67161ae50101da2e6a81a5470b5fe72.png" alt="2021-22"></p><img data-src="https://i0.hdslb.com/bfs/album/18d23ec6e1d91a6d387a6452a11557f13f0fcfa4.png" alt="netease-music-2022" style="zoom:36%;" /><p>今年是重度使用 B 站的一年，留下了很多难忘的回忆，有 3 天因为太忙忘记了打开 B 站…</p><table><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/ed49fe23ded6dd54d3149c7e11452f9b4c701f9b.png" alt="2021-23" height=500px /></td><td><img data-src="https://i0.hdslb.com/bfs/album/fe48890094cb5f6cf8af29766ee079bf37082d8f.jpg" alt="bilibili-2022" height=500px /></td></tr></table><p>我觉得每年选出一个“年度 app”是很有意思的事情，以后会坚持下去。去年我认为我的年度 app 是 Notion，而今年则是 Arc。Arc 是一个充满革新性的浏览器，解决了 Chrome、Edge 和 Safari 等曾经常用浏览器的许多痛点，比如标签页的管理方式、主页面的布局等，达到了美观度和实用性的统一和提升。当然，它也有很多不足，比如书签管理是我认为它目前最大的短板，The Browser 官方也通过邮件告知我他们正在着手解决这一问题。而我通过转到 Raindrop 重新设计了我的工作流和信息流，从而很大程度上适应了 Arc 在此方面的不足。</p><blockquote><p>hey, here’s an invite to Arc, the browser I was telling you about!</p><p><a href="https://arc.net/gift/c748bf64">https://arc.net/gift/c748bf64</a></p></blockquote><p>由于这个产品的流行度和颠覆性，我还打算选出第二大年度 app —— <a href="https://chat.openai.com/">ChatGPT</a>。作为 OpenAI 的对话机器人，ChatGPT 更有逻辑、有知识，能较为出色地、人性化地解决提出的许多主观问题，再一次为人工智能的力量折服。但在我看来，它并不能替代 Google 成为新一代搜索引擎，因为它虽然能解决好“How”，但不能解决好“What”。比如一些常识性、知识性的问题，它总能“一本正经地胡说八道”，看似很有道理，但在事实上是完全错误的答案。</p><hr><p>除了生活方面，在学习方面进一步学习和发挥了 iOS 开发，参与开发了微北洋 4.2，也是一段很有趣的经历。对 iOS、对前端、对 git、对 cooperation 都有了新的理解。在闲暇之余我开展了 SuperLab 的 2022 年度项目 Galaxy，也是我的第 3 个 app，是包括 iOS 前端和后端完整的项目，有数据处理、音频处理等内容。</p><table><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/3a99bb66be5d304e0f490b6067634a9945ae2753.png" alt="wby-2022-1" height=500px/></td><td><img data-src="https://i0.hdslb.com/bfs/album/b1e4d1a7bce830ffe7f7ebdd659ebc1547c2c3d0.png" alt="wby-2022-2" height=500px /></td></tr><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/831022018566f7c978a50b8bc37ae694e27d268a.png" alt="galaxy-2022-1" height=500px /></td><td><img data-src="https://i0.hdslb.com/bfs/album/3c0406d1262b87a6f33a49361f526903a85b8406.png" alt="galaxy-2022-2" height=500px /></td></tr></table><p>p1 是微北洋求实论坛一代神贴，被投稿到了某 channel，而图片里的 UI 是我写的，很奇妙的感觉。p2 是“海棠季”粉色主题。p3 和 p4 是 Galaxy 中的部分功能，一个是简单爬校园卡流水的（主要是方便记账），另一个是音乐播放器的功能。</p><p>2022 下半年大部分时间都在准备考试，全年大部分时间也都在图书馆，度过了图书馆的春夏秋冬。</p><table><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/3b3fb062fb770ffcb9067e14bfce55541dd890aa.jpg" alt="lib-2022-spring" /></td><td><img data-src="https://i0.hdslb.com/bfs/album/30c508e2798746c784f2a37efbd6efaa21805f90.jpg" alt="lib-2022-summer" /></td></tr><tr align=center><td><img data-src="https://i0.hdslb.com/bfs/album/14d56eb1fba1647275262136c76664cffa67f25c.jpg" alt="lib-2022-autumn" /></td><td><img data-src="https://i0.hdslb.com/bfs/album/cdcfae2b0d0a0e6d23019e03801089e3b7987124.jpg" alt="lib-2022-winter" /></td></tr></table><p>p3 并不是图书馆的秋天，因为图书馆视角的秋天忘记拍照了。由此可见图书馆的窗户该擦了。</p><p><img data-src="https://i0.hdslb.com/bfs/album/d6e02153e684d78f409a49433989780a30314fe0.jpg" alt="river-qingnian-2022"></p><p>最喜欢的是青年湖畔的晚风。</p><p><img data-src="https://i0.hdslb.com/bfs/album/149d6a4a3c7665cbc253be1b3088bdda98f88b83.jpg" alt="kaoyan-2022-night"></p><p>考试前夕的某个夜晚，很安静。</p><p><img data-src="https://i0.hdslb.com/bfs/album/0a8ea659221abf04d319e3ad17173f331c98bb2f.jpg" alt="kaoyan-2022-day"></p><p>23 考研第一天中午，车水马龙。</p><hr><p>最后还是想记录一下 2022 最 upsetting 的事情，疫情，是 2022 年每个中国人都无法回避的话题。我的 2022 从疫情爆发开始，也从疫情爆发结束。21 年 12 月 31 日，我正写着年度总结、准备离校回家，未曾想过改变整个 2022 的疫情正悄然而至。1 月 8 日，奥密克戎首次在天津爆发（天津是国内首个发现奥密克戎境外输入的城市），爆发地恰是我 1 月 1 日去过的地方。第一次感觉和疫情如此接近，而我也在 1 月 10 日开始了一言难尽的隔离生活，直到 15 日。</p><p><img data-src="https://i0.hdslb.com/bfs/album/f6b6a5d2d7b84fc99978ef8532d1b46710b64e87.png" alt="end-of-quarantine"></p><p>当然这只是开始，不是结束。回到学校，开始了一言难尽的上百次（全年）核酸检测。没有疫情要做核酸检测，疫情爆发后就停止核酸检测，这陷入了一个诡异的逻辑，即如果核酸检测是为了防止疫情爆发，那么事实证明它并没有起到任何作用，疫情该爆发还是会爆发；如果核酸检测是为了保障每个人的健康，那么事实是在最容易感染的时刻停止了核酸检测，最终还是靠每个人自测抗原判断是否感染。讽刺的是，当寝室有感染风险时，找管理者要抗原试纸，管理者却说“抗原又不治病”，并没有给。试问核酸检测治病否？</p><img data-src="https://i0.hdslb.com/bfs/album/94f5e63ae4ff0f437822ad78ad853900c7db357a.jpg" alt="pcr-test-2022-rain-1" style="zoom:30%;" /><img data-src="https://i0.hdslb.com/bfs/album/8ff7b144adab470ade959de0940603aa7e3568da.png" alt="pcr-test-2022-rain-2" style="zoom:30%;" /><p>难以忘记的秋雨中的核酸检测，一场温暖的双向奔赴。（ <em>p1 来自微北洋求实论坛，非本人拍摄</em> ）</p><img data-src="https://i0.hdslb.com/bfs/album/bda7af0c30cc1cd55debb815fa81eda81aac6aa1.jpg" alt="wby-2022-csxq" style="zoom:50%;" /><p>来自微北洋求实论坛的一篇短文。</p><img data-src="https://i0.hdslb.com/bfs/album/3bcf43abac6b441eaad723e300e426c7d018f0d5.jpg" alt="unnecessary-poem" style="zoom:30%;" /><p>在 2022，一切都可以是“非必要”的。（ <em>图片来自微博，见水印</em> ）</p><p>没有制约的权力，没有义务的责任。甚至最终 12 月 2 日疫情在学校爆发之时，学生都没有最基本的知情权，那几天是这一年中最混乱的日子。12 月也是最戏剧性的一月，官方的宣传和 11 月时形成 180 度反转，不过说明了宣传者只需要对上负责而无需对下负责，也说明了很多人并没有独立思考的能力。如今，疫情防控的乱象总算是告一段落，但这一年中发生的 <a href="https://zh.wikipedia.org/w/index.php?title=2022%E5%B9%B4%E4%B8%AD%E5%9B%BD%E5%A4%A7%E9%99%86&oldid=75301656">各种事情</a> 难以忘怀。社会运行的真相是什么，官方是不是歌颂太平的工具，其公信力还有几何，今后诸如全员核酸检测之类的无理要求不知还会有多少人听从。曾经引以为傲的制度优势，最终还是背离了“实事求是”。文章写尽太平事，不肯俯首见苍生。太多的事情就不赘述了，有良知的人总会听见、看到、记下，没有良知的人总会视而不见。</p><blockquote><p>如果尖锐的批泙完全消失，</p><p>温和的批评将会变得刺耳。</p><p>如果温和的批评也不被允许，沉默将被认为居心叵测。</p><p>如果沉默也不再允许，赞扬不够卖力将是一种罪行。</p></blockquote><p>我只能记下并活着，或者让活着的记下我，像 * * 爱我一样爱 * *。当然，让人不至于如此难过的，是仍然有很多人有思想、有良知、敢发声，希望你我都能保持这份清醒，心怀希望。</p><p>向 2022 年因未知原因而失去生命的人默哀。</p><hr><p>正如前文所说，2022 是逐渐成熟、理性、清醒的一年，对待同一件事的看法不再像以前一样片面、情绪化、盲目从众。一方面是由于疫情，见得多了，自然就明白了；另一方面是反思自身的问题，找到存在的缺点和差距，每个人应该都会在大学生活将要结束时成长许多。</p><ul><li><strong>一个人的思想蕴含着他的经历</strong>，往往可以通过了解他的经历从而理解他的思想，有不同经历的人，对同一件事的看法可能不同。</li><li><strong>共同做事的人，目的有所不同</strong>，虽然一群人在做同样的事情，但不同人的目的往往不同，人们总是互相利用来达到自身的目的，总之要明确自己的目的，力求达到共识，警惕被人利用。</li><li><strong>投资自身，去做别人做不了的事情</strong>，这也是我 2023 的目标，真正把时间和精力放在提升自己上，不去做人人都能做的事情，多尝试困难、多试错、多挑战自己。</li><li><strong>果断行动，不要拖延</strong>，提高做事的效率和速度，新的一年任务很重，要在思考和行动上都有所提高。</li></ul><p>总之，无论 2022 有多糟糕，在 2023，还是要解放思想、实事求是，团结一致向前看。新年的鞭炮声已经响起，生命的新阶段已经到来。迎接新生和自由，拥抱梦想和彼岸。</p><p><img data-src="https://i0.hdslb.com/bfs/album/7bd9bbc50eeb1cf59fc79a129e2a1ffaa7345970.jpg" alt="rev-2022"></p><p>2022，再见！</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;年更 Blogger 的 2022，是平凡但不平静的一年。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
  </entry>
  
  <entry>
    <title>Genius Bar 两日游</title>
    <link href="https://superpung.com/genius-bar/"/>
    <id>https://superpung.com/genius-bar/</id>
    <published>2022-07-29T12:03:18.000Z</published>
    <updated>2022-07-29T12:03:18.000Z</updated>
    
    <content type="html"><![CDATA[<p>在 MacBook Air 购买了一年半之后，它的键盘获得了重生。</p><span id="more"></span><p>起因是暑假在家时，突然发现 MacBook 的 fn 键和左 shift 键被卡住了，fn 键尤为严重，导致每次按 F12 都很别扭。<del>可能 fn 键的唯二作用就是 F12 和表情符号了吧。</del>初步怀疑可能是键盘缝隙进入了杂物，尝试了 <a href="https://support.apple.com/zh-cn/HT205662">Apple 推荐的做法</a>，并没有成功。于是准备去 Genius Bar 让天才们修理一下。</p><p>截至目前，天津一共有 3 家 Apple Store，分别是位于南开区的 <a href="https://www.apple.com.cn/retail/tianjinjoycity/">天津大悦城</a>、位于和平区的 <a href="https://www.apple.com.cn/retail/riverside66tianjin/">天津恒隆广场</a> 和位于河西区的 <a href="https://www.apple.com.cn/retail/mixctianjin/">天津万象城</a>。很不巧，最近河西区和南开区先后出现了疫情中高风险区域，为避免因为有“高中风险地区和高中风险区所在县（市、区、旗、直辖市为所在区）旅居史”，我不得不退掉比较容易到达的 Apple 天津大悦城的预约，预约了 Apple 天津恒隆广场。</p><p>预约 Genius Bar 很简单，在 Apple 官网选择故障类型、预约时间段等信息进行预约即可，如果没有预约可能会导致排不上班的情况。预约成功后会收到 Apple 发来的短信和邮件（提醒：为接受 Genius Bar 天才吧服务做好准备），还可以将预约码添加到钱包。取消预约也很简单，进入预约列表点击取消即可。整个预约过程都是免费的。</p><p>根据 Apple 的提示，去 Genius Bar 之前需要备份你的数据，我用 Time Machine 备份了一下。Apple 还提醒需要确保可以提供相关单据（带上身份证）并携带购买凭证。虽然 Apple 说“请务必携带购买凭证”，但我也找不到我的购买凭证了，事实证明最后也并没有要我出示它，Apple Store 可以直接查到你的购买信息。</p><p>24 日我如约 <a href="https://twitter.com/repusme/status/1551117378708455427">来到 Apple Store</a>，在门口签到后坐下等待安排给我的天才到来。对了，在官网预约时应该登录了你的 Apple ID，所以预约的姓名是你的 Apple ID 对应的姓名。几分钟后天才来了，让我拿出 MacBook，问我出现了什么问题。得知键盘问题后，他按了几下发现确实如此，说可以给换个键盘。同意后，他开始对 MacBook 进行检测，关掉了 Find My Mac（据说是为了连接到 Apple Store 的设备）。检测没什么问题，告知我现在键盘并没有现货，需要从上海调配才能给我换，需要一周内时间。我同意，然后他开了维修记录（Apple Store 工作授权），我签字后收到了副本邮件，有维修编号、客户信息、产品信息、问题说明 &#x2F; 诊断、维修估价等信息。当然，维修估价共计 RMB 0。</p><p>第一日游并没有如愿修好我的 MacBook，我也把 MacBook 带回了。在 Apple Store 看到了春季新品，比如指纹收集器暗夜色 MacBook Air M2 和怀旧设计 MacBook Pro M2。指纹收集器是真的容易沾上指纹，显得尤为突兀。不过它的配色是我心目中最好看的 MacBook 配色。</p><p>回去之后，fn 键竟然似乎有些好转了，真是玄学。好几天过去了，Apple 并没有给我打电话，就在我以为 Apple 应该是不能如其到货了的昨天，Apple 打来了电话，问我什么时候有空去送修。我选择了上午的时间，然后就收到了短信和邮件。和前一次预约相同。天才让我做好备份，我又用 Time Machine 备份了一遍。</p><p>29 日我又如约 <a href="https://twitter.com/repusme/status/1552887350383894529">来到 Apple Store</a>，准确说来得稍早了一些，我又摸了一遍 Apple Store 的样机。不得不说，iPhone 13 Pro 和 iPhone 13 Pro Max 的 120 Hz 高刷真的震惊到我了，第一次认真体验才发现如此丝滑。我再拿起旁边的 iPhone 13 和 iPhone 13 mini，竟感觉如此卡顿……（不过多刷一会 60 Hz 也就习惯了）（反转了，后悔没有买 iPhone 13 Pro &gt;_&lt;）Mac Studio 是真的重。iMac 的大下巴是真的丑。MacBook Pro 16 英寸新款也丑，键盘的黑色底色尤为突兀，而且在那么大的 C 面上留那么小的键盘区域，感觉比例有些失调。</p><p>摸了半天，终于到我了。签到后又等着天才来找我，过来后又检测了一遍，和第一次来一样。最后签了字开了条就让我走了。理论上最快 4 小时可以换好，据天才说 M1 款的维修比 Intel 款的简单，而且维修后的检测时间也比 Intel 款的更短（0.5h &lt; 2~3h）。将信将疑下，他说最快今晚可以取回，比较稳妥是明天。一番交谈过后，我离开了 Apple Store（该吃午饭了）。</p><p>由于不想再浪费一天来个“三日游”，坐地铁时间还挺长的，我打算到处转转等今晚拿下。在 M 吃完午饭后回恒隆广场转了一圈，看到了无人问津的小米之家。体验了一下 12 S Ultra，<del>广告是真的多，</del>发现小米的触感反馈做得也很不错了，感觉比 iPhone 的触感体验还要好。恒隆广场挺大的，走一会我又回到了 Apple Store。过了一段时间 Apple 打来了电话，是下午 4:03，说我的 MacBook 修好了可以取货。看来天才诚不欺我，说 4 个小时就 4 个小时。等了一会后，天才拿着我的 MacBook 过来了，让我试一试键盘，试了一下挺好的<del>，像新的一样</del>。然后看了一下我的身份证，签字后就拿走了。</p><p>给我拿 iPad 的小哥让我印象深刻，他是一位听障人士，靠打字和我交流，能感受到他的紧张但很认真。很感动，致敬每一位努力生活的人，也致敬 Apple 强大的辅助功能为残障人士带来了科技的温暖。</p><p>回归正题，最后发现我的 MacBook 应该是整个 C 面都换新了，包括键盘和触控板，顺带给清洁了屏幕（忘了问天才是如何把屏幕清洁得这么干净的了）。<del>当然，最希望电池也能直接给换了，但并没有。</del>总之这次 Genius Bar 的体验还是很棒的，全过程没有任何数据丢失，0 成本（除去路费）九舍一入拿到了“全新”的 MacBook Air，感觉又可以再战几年了（希望 256 GB 硬盘能多撑一会）。</p><blockquote><p>怀念 2019 年在滨江道散步的夜晚，Apple 天津恒隆广场店人潮涌动（当时靠马路边的门是开的），那种景象大抵是回不去了罢。</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;p&gt;在 MacBook Air 购买了一年半之后，它的键盘获得了重生。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
    <category term="Apple" scheme="https://superpung.com/tags/Apple/"/>
    
  </entry>
  
  <entry>
    <title>实训小记</title>
    <link href="https://superpung.com/training-report/"/>
    <id>https://superpung.com/training-report/</id>
    <published>2022-06-18T03:15:23.000Z</published>
    <updated>2022-06-18T03:15:23.000Z</updated>
    
    <content type="html"><![CDATA[<p>简单记录一下一个多月的“实训”。</p><span id="more"></span><h2 id="1-Linux-虚拟网络基础"><a href="#1-Linux-虚拟网络基础" class="headerlink" title="1 Linux 虚拟网络基础"></a>1 Linux 虚拟网络基础</h2><h3 id="1-1-tap"><a href="#1-1-tap" class="headerlink" title="1.1 tap"></a>1.1 tap</h3><p>tap 和 tun 是操作系统内核中的虚拟网络设备，tap 位于二层，tun 位于三层。它们的数据结构如下：</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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">tun_struct</span> &#123;</span></span><br><span class="line">    <span class="type">char</span> name[<span class="number">8</span>];                <span class="comment">// 设备名</span></span><br><span class="line">    <span class="type">unsigned</span> <span class="type">long</span> flags;         <span class="comment">// 区分tun和tap设备</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">fasync_struct</span> *<span class="title">fasync</span>;</span> <span class="comment">// 文件异步通知结构</span></span><br><span class="line">    <span class="type">wait_queue_head_t</span> read_wait; <span class="comment">// 等待队列</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">net_device</span> <span class="title">dev</span>;</span>       <span class="comment">// Linux抽象网络设备结构</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sk_buff_head</span> <span class="title">txq</span>;</span>     <span class="comment">// 网络缓冲区队列</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">net_device_stats</span> <span class="title">stats</span>;</span> <span class="comment">// 网卡状态信息结构</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>tap 和 tun 的数据结构定义相同，两者仅通过一个 Flag 来区分。但二者承载的功能区别很大：</p><ul><li>tap 位于网络 OSI 模型的二层（数据链路层）</li><li>tun 位于网络的三层</li></ul><p>tap 从功能定位上来讲，位于数据链路层，数据链路层的主要协议有：</p><ol><li>点对点协议（Point-to-Point Protocol）</li><li>以太网（Ethernet）</li><li>高级数据链路协议（High-Level Data Link Protocol）</li><li>帧中继（Frame Relay）</li><li>异步传输模式（Asynchronous Transfer Mode）</li></ol><p>tap 只与其中一种协议——以太网（Ethernet）协议对应。所以 tap 有时也称为“虚拟以太设备”。</p><p>创建 tap 的方法：</p><ol><li>Linux 使用 tun 模块实现了 tun&#x2F;tap，所以首先 Linux 得有 tun 模块，使用 <code>modinfo tun</code> 检查</li><li>使用 <code>lsmod | grep tuntun</code> 检查 tun 模块是否已经加载</li><li>确认 Linux 是否有操作 tun&#x2F;tap 的命令行工具 tunctl，安装方式 <code>yum install tunctl</code></li><li>创建一个 tap 设备：<code>tunctl -t tap_test</code></li><li>查看刚刚创建的 tap：<code>ip link list</code> 或 <code>ifconfig -a</code></li><li>绑定IP地址：<code>ip addr add local 192.168.100.1/24 dev tap_test</code> 或 <code>ifconfig tap_test 192.168.100.1/24</code></li><li>创建完成</li></ol><h3 id="1-2-namespace"><a href="#1-2-namespace" class="headerlink" title="1.2 namespace"></a>1.2 namespace</h3><p>传统的 Linux 的许多资源是全局的，namespace 的目的首先就是将这些资源做资源隔离。Linux 可以在一个 Host 内创建许多 namespace，不同 namespace 的资源互相不可见、彼此透明。namespace 示意图如下所示：</p><p><img data-src="https://i0.hdslb.com/bfs/album/522a582e554e47577e053af295796565eea5e60d.png" alt="r-1-2-1"></p><p>从网络的视角来看，一个 namespace 提供了一份独立的网络协议栈（网络设备接口、IPv4、IPv6、IP路由、防火墙规则、sockets 等）。一个设备（Linux Device）只能位于一个 namespace 中，不同 namespace 中的设备可以利用 veth  pair 进行桥接。</p><p>namespace 操作：</p><ol><li>查看当前的 namespace 列表：<code>ip netns list</code></li><li>创建一个 namespace，名字是 ns_test：<code>ip netns add ns_test</code></li><li>把原来创建的虚拟设备 tap_test 迁移到这个 namespace 里去：<code>ip link set tap_test netns ns_test</code></li><li>查看或操作 namespace 里面的设备：<code>ip [-all] netns exec [NAME] cmd ...</code></li></ol><h3 id="1-3-veth-pair"><a href="#1-3-veth-pair" class="headerlink" title="1.3 veth pair"></a>1.3 veth pair</h3><p>veth  pair 不是一个设备，而是一对设备，以连接两个虚拟以太端口。操作 veth  pair，需要跟 namespace 一起配合，否则没有意义。</p><p>veth pair 简单示例：</p><p><img data-src="https://i0.hdslb.com/bfs/album/b77067976c8865d6120f2e9d2094f1f226b79b32.png" alt="r-1-3-1"></p><p>创建简单示例：</p><ol><li>创建 veth pair：<code>ip link add tap1 type veth peer name tap2</code></li><li>创建 namespace：<code>ip netns add ns1ip netns add ns2</code></li><li>把两个 tap 分别迁移到对应的 namespace 中：<code>ip link set tap1 netns ns1ip link set tap2 netns ns2</code></li><li>分别给两个 tap 绑定 IP 地址：<code>ip netns exec ns1 ip addr add local 192.168.50.1/24 dev tap1</code>、<code>ip netns exec ns2 ip addr add local 192.168.50.2/24 dev tap2</code></li><li>将两个 tap 设置为 up：<code>ip netns exec ns1 ifconfig tap1 up</code>、<code>ip netns exec ns2 ifconfig tap2 up</code></li><li>ping：<code>ip netns exec ns2 ping 192.168.50.1</code>、<code>ip netns exec ns1 ping 192.168.50.2</code></li></ol><h3 id="1-4-Bridge"><a href="#1-4-Bridge" class="headerlink" title="1.4 Bridge"></a>1.4 Bridge</h3><p>Linux 中 Bridge（网桥）即为 Switch（交换机）。Linux 实现 Bridge 功能的是 brctl 模块，相关用法如下：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">brctlUsage: brctl [commands]</span><br><span class="line">commands:</span><br><span class="line">addbr         &lt;bridge&gt;              add bridge</span><br><span class="line">    delbr         &lt;bridge&gt;              delete bridge</span><br><span class="line">    addif         &lt;bridge&gt; &lt;device&gt;     add interface to bridge</span><br><span class="line">    delif         &lt;bridge&gt; &lt;device&gt;     delete interface from bridge</span><br><span class="line">    hairpin       &lt;bridge&gt; &lt;port&gt; &#123;on|off&#125;     turn hairpin on/off</span><br><span class="line">    setageing     &lt;bridge&gt; &lt;<span class="keyword">time</span>&gt;              <span class="built_in">set</span> ageing <span class="keyword">time</span></span><br><span class="line">    setbridgeprio &lt;bridge&gt; &lt;prio&gt;              <span class="built_in">set</span> bridge priority</span><br><span class="line">    setfd         &lt;bridge&gt; &lt;<span class="keyword">time</span>&gt;              <span class="built_in">set</span> bridge forward delay</span><br><span class="line">    sethello      &lt;bridge&gt; &lt;<span class="keyword">time</span>&gt;              <span class="built_in">set</span> hello <span class="keyword">time</span></span><br><span class="line">    setmaxage     &lt;bridge&gt; &lt;<span class="keyword">time</span>&gt;              <span class="built_in">set</span> max message age</span><br><span class="line">    setpathcost   &lt;bridge&gt; &lt;port&gt; &lt;cost&gt;       <span class="built_in">set</span> path cost</span><br><span class="line">    setportprio   &lt;bridge&gt; &lt;port&gt; &lt;prio&gt;       <span class="built_in">set</span> port priority</span><br><span class="line">    show          [ &lt;bridge&gt; ]          show a list of bridges</span><br><span class="line">    showmacs      &lt;bridge&gt;              show a list of mac addrs</span><br><span class="line">    showstp       &lt;bridge&gt;              show bridge stp info</span><br><span class="line">    stp           &lt;bridge&gt; &#123;on|off&#125;     turn stp on/off</span><br></pre></td></tr></table></figure><p>veth pair 综合示例：</p><img data-src="https://i0.hdslb.com/bfs/album/1d0632762bd13e4185224c31efebc2e70ec77184.png" alt="r-1-4-1" style="zoom:50%;" /><p>实现这个用例：</p><ol><li>创建 veth pair：<code>ip link add tap1 type veth peer name tap1_peer</code>、<code>ip link add tap2 type veth peer name tap2_peer</code>、<code>ip link add tap3 type veth peer name tap3_peer</code>、<code>ip link add tap4 type veth peer name tap4_peer</code></li><li>创建 namespace：<code>ip netns add ns1</code>、<code>ip netns add ns2</code>、<code>ip netns add ns3</code>、<code>ip netns add ns4</code></li><li>把 tap 迁移到相应 namespace 中：<code>ip link set tap1 netns ns1</code>、<code>ip link set tap2 netns ns2</code>、<code>ip link set tap3 netns ns3</code>、<code>ip link set tap4 netns ns4</code></li><li>创建 Bridge：<code>brctl addbr br1</code></li><li>把相应 tap 添加到 Bridge 中：<code>brctl addif br1 tap1_peer</code>、<code>brctl addif br1 tap2_peer</code>、<code>brctl addif br1 tap3_peer</code>、<code>brctl addif br1 tap4_peer</code></li><li>配置相应 tap 的 IP 地址：<code>ip netns exec ns1 ip addr add local 192.168.50.1/24 dev tap1</code>、<code>ip netns exec ns2 ip addr add local 192.168.50.2/24 dev tap2</code>、<code>ip netns exec ns3 ip addr add local 192.168.50.3/24 dev tap3</code>、<code>ip netns exec ns4 ip addr add local 192.168.50.4/24 dev tap4</code></li><li>将 Bridge 及所有 tap 状态设置为 up：<code>ip link set br1 up</code>、<code>ip link set tap1_peer up</code>、<code>ip link set tap2_peer up</code></li></ol><h3 id="1-5-Router"><a href="#1-5-Router" class="headerlink" title="1.5 Router"></a>1.5 Router</h3><p>Linux 就是路由器（Router），修改配置文件 “&#x2F;etc&#x2F;sysctl.conf”， 将 <code>net.ipv4.ip_forward = 0</code> 修改为 <code>1</code>，保存后退出，即打开了路由转发功能。</p><p>查看路由表：<code>route -nee</code>，添加静态路由：<code>route add -net [ip] netmask [netmask] gw [gateway]</code>。</p><h3 id="1-6-tun"><a href="#1-6-tun" class="headerlink" title="1.6 tun"></a>1.6 tun</h3><p>tun 是一个网络层（IP）的点对点设备，它启用了 IP 层隧道功能。Linux 原生支持的三层隧道，可以通过命令行 <code>ip tunnel help</code> 查看：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">ip tunnel <span class="built_in">help</span></span><br><span class="line">Usage: ip tunnel &#123; add | change | del | show | prl | 6rd &#125; [ NAME ]</span><br><span class="line">[ mode &#123; ipip | gre | sit | isatap | vti &#125; ] [ remote ADDR ] [ <span class="built_in">local</span> ADDR ]</span><br><span class="line">    [ [i|o]<span class="built_in">seq</span> ] [ [i|o]key KEY ] [ [i|o]csum ]</span><br><span class="line">    [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]</span><br><span class="line">    [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]</span><br><span class="line">    [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]</span><br><span class="line">Where: NAME := STRING</span><br><span class="line">ADDR := &#123; IP_ADDRESS | any &#125;</span><br><span class="line">    TOS  := &#123; STRING | 00..ff | inherit | inherit/STRING | inherit/00..ff &#125;</span><br><span class="line">    TTL  := &#123; 1..255 | inherit &#125;</span><br><span class="line">    KEY  := &#123; DOTTED_QUAD | NUMBER &#125;</span><br></pre></td></tr></table></figure><p>可以看到，Linux 一共原生支持 5 种三层隧道（tunnel）：</p><table><thead><tr><th>隧道</th><th>简述</th></tr></thead><tbody><tr><td>ipip</td><td>IP in IP，在 IPv4 报文的基础上再封装一个 IPv4 报文头，属于IPv4 in IPv4</td></tr><tr><td>gre</td><td>通用路由封装（Generic Routing Encapsulation），定义了在任意一种网络层协议上封装任意一个其他网络层协议的协议，属于 IPv4&#x2F;IPv6 over IPv4</td></tr><tr><td>sit</td><td>这个跟 ipip 类似，只不过是用一个 IPv4 的报文头封装 IPv6 的报文，属于 IPv6 over IPv4</td></tr><tr><td>isatap</td><td>站内自动隧道寻址协议，一般用于 IPv4 网络中的 IPv6&#x2F;IPv4 节点间的通信</td></tr><tr><td>vti</td><td>全称是 Virtual Tunnel Interface，为 IPsec 隧道提供了一个可路由的接口类型</td></tr></tbody></table><h3 id="1-7-iptables"><a href="#1-7-iptables" class="headerlink" title="1.7 iptables"></a>1.7 iptables</h3><p>通过 iptables 相关的命令行，可以实现了防火墙、NAT 的功能，而这种功能的实现是通过运行在内核空间的 netfilter 模块完成的，它们之间的关系如下所示：</p><img data-src="https://i0.hdslb.com/bfs/album/a738684e1c9ff094909a5de2d14d7f55c0d5bb82.png" alt="r-1-7-1" style="zoom:50%;" /><p>iptables 内置了三张表：filter、nat 和 mangle。filter 和 nat 是为了实现防火墙和 NAT 功能而服务的，mangle 主要应用在修改数据包内容上，用来做流量整形。iptables 还内置了另外 2 张表 raw 和 security，这里不详细介绍了。</p><p>iptables 内置的既是三张表，也是三条链（chain），也是三种策略（policy），这些策略由不同规则（rule）串接而成。</p><p><code>iptables -A INPUT -i eth0 -p icmp -j ACCEPT</code> 这条规则表达的意思是：允许所有从eth0 端口进入且协议是 ICMP 的报文可以接受（可以进入下一个流程）的。</p><h4 id="1-7-1-NAT"><a href="#1-7-1-NAT" class="headerlink" title="1.7.1 NAT"></a>1.7.1 NAT</h4><p>NAT（Network Address Translation，网络地址转换），顾名思义，就是从一个 IP 地址转换为另一个 IP 地址。当然，这里面的根本原因还是IP地址不够用的问题（解决 IP 地址枯竭的方法一个是 IPv6，另一个就是 NAT）。</p><p>NAT 从实现技术角度分为：静态 NAT、动态 NAT 和端口多路复用三种方案：</p><ol><li><p>静态 NAT（Static NAT）</p><p> 静态 NAT 有两个特征：</p><ol><li>私网IP地址与公网IP地址的转换规则是静态指定的，比如 10.10.10.1 与 50.0.0.1 互相转换，这个是静态指定好的；</li><li>私网 IP 地址与公网 IP 地址是 1∶1，即一个私网 IP 地址对应 1 个公网 IP 地址。</li></ol></li><li><p>动态 NAT</p><p> 一般情况是公网 IP 比私网 IP 地址少的时候，用到动态 NAT 方案。动态 NAT，就是一批私网 IP 与公网 IP 地址之间不是固定的转换关系，而是在 IP 报文处理过程中由 NAT 模块进行动态匹配。虽然，公网 IP 比私网 IP 地址少，但是，同时在线的私网 IP 需求小于等于公网 IP 数量，不然某些私网 IP 将得不到正确的转换，从而导致网络通信失败。</p><p> 动态 NAT，有三个特征：</p><ol><li>私网与公网IP地址之间不是固定匹配转换的，而是变化的；</li><li>两者之间的转换规则不是静态指定的，而是动态匹配的；</li><li>私网 IP 地址与公网 IP 地址之间是 m∶n，一般 m &lt; n。</li></ol></li><li><p>端口多路复用 &#x2F; PAT</p><p> 如果私网 IP 地址有多个，而公网 IP 地址只有一个，那么，静态 NAT 显然是不行了，动态 NAT 也基本不行（只有一个公网 IP，不够用）。此时，就需要用到端口多路复用。多个私网 IP 映射到同一个公网 IP，不同的私网 IP 利用端口号进行区分，这里的端口号指的是 TCP&#x2F;UDP 端口号。所以端口复用又叫 PAT（Port Address Translation）。</p><p> 端口多路复用（PAT）的特征是：</p><ol><li>私网 IP：公网 IP &#x3D; m∶1；</li><li>以公网 IP + 端口号来区分私网 IP。</li></ol></li><li><p>SNAT &#x2F; DNAT</p><p> 前面说的静态 NAT（Static NAT）和动态 NAT不能简称 SNAT、DNAT，因为 SNAT&#x2F;DNAT 有另外的含义，是另外的缩写。要区分SNAT（Source Network Address Translation，源地址转换）与DNAT（Destination Network Address Translation，目的地址转换）这两个功能可以简单地由连接发起者是谁来区分。</p><ol><li>内部地址要访问公网上的服务时（如 Web访问），内部地址会主动发起连接，由路由器或者防火墙上的网关对内部地址做个地址转换，将内部地址的私有 IP 转换为公网的公有 IP，网关的这个地址转换称为 SNAT，主要用于内部共享 IP 访问外部。</li><li>当内部需要提供对外服务时（如对外发布 Web 网站），外部地址发起主动连接，由路由器或者防火墙上的网关接收这个连接，然后将连接转换到内部，此过程是由带有公网 IP 的网关替代内部服务来接收外部的连接，然后在内部做地址转换，此转换称为 DNAT，主要用于内部服务对外发布。</li></ol></li></ol><p>Linux 内核空间 Netfilter 模块的 NAT 处理，一共有三个 Chain（处理时刻点）：</p><table><thead><tr><th>流</th><th>流描述</th><th>Chain</th><th>NAT类型</th><th>NAT说明</th></tr></thead><tbody><tr><td>流1</td><td>流从外部到达 Linux 用户空间（私网 IP）</td><td>PREROUTING</td><td>DNAT</td><td>将目的 IP 从公网 IP（Linux 内核空间对应的 IP）转换到私网 IP（Linux 用户空间对应的 IP）</td></tr><tr><td>流2</td><td>流从 Linux 用户空间（私网 IP）到达外部</td><td>POSTROUTING</td><td>SNAT</td><td>将源 IP 从私网 IP（Linux 用户空间对应的 IP）转换到公网 IP（Linux 内核空间对应的 IP）</td></tr><tr><td>流3</td><td>流从 Linux 内核空间（公网 IP）到达外部</td><td>OUTPUT</td><td>DNAT</td><td></td></tr></tbody></table><h4 id="1-7-2-Firewall"><a href="#1-7-2-Firewall" class="headerlink" title="1.7.2 Firewall"></a>1.7.2 Firewall</h4><p>iptables 中的 Firewall（防火墙）概念，属于网络防火墙的概念。iptables 中的防火墙的规则就是基于 TCP&#x2F;IP 协议栈的规则，所以我们称之为网络防火墙。这些规则有：</p><ol><li>in-interface（入网络接口名），数据包从哪个网络接口进入；</li><li>out-interface（出网络接口名），数据包从哪个网络接口输出；</li><li>protocol（协议类型），数据包的协议，如 TCP、UDP 和 ICMP 等；</li><li>source（源地址（或子网）），数据包的源IP地址（或子网）；</li><li>destination（目标地址（或子网）），数据包的目标IP地址（或子网）；</li><li>sport（源端口号），数据包的源端口号；</li><li>dport（目的端口号），数据包的目的端口号。</li></ol><p>符合这些规则的，可以设置为通过（ACCEPT），反之，则不通过（DROP）。或者，符合这些规则的，设置为不通过（DROP）；反之，则通过（ACCEPT）。</p><p>Netfilter 中的 Firewall，会在三个时刻点，进行处理，如下图所示：</p><p><img data-src="https://i0.hdslb.com/bfs/album/2b3844ae03bd7f9038194d8ac2c45ad7b56a3348.png" alt="r-1-7-2"></p><h4 id="1-7-3-mangle"><a href="#1-7-3-mangle" class="headerlink" title="1.7.3 mangle"></a>1.7.3 mangle</h4><p>mangle 表主要用于修改数据包的 ToS（Type  of  Service，服务类型）、TTL（Time  to  Live，生存周期）以及为数据包设置 Mark 标记，以实现 QoS（Quality  of  Service，服务质量）调整以及策略路由等应用。</p><p>netfilter 模块中的 mangle 处理的时刻点如下图所示：</p><p><img data-src="https://i0.hdslb.com/bfs/album/f881ce8fdc2241ea2f99a3ea20a2ddae3d142d90.png" alt="r-1-7-3"></p><h3 id="1-8-Linux-虚拟网络基础总结"><a href="#1-8-Linux-虚拟网络基础总结" class="headerlink" title="1.8 Linux 虚拟网络基础总结"></a>1.8 Linux 虚拟网络基础总结</h3><p>tap、tun、veth  pair 在 Linux 中都被称为设备，但是在与日常概念的类比中，常常被称作接口。Neutron 利用这些“接口”进行 Bridge 之间的连接、Bridge 与 VM（虚拟机）的连接、Bridge 与 Router之间的连接。三者与物理网卡之间的对比关系，如下图所示：</p><p><img data-src="https://i0.hdslb.com/bfs/album/47af2c82d9a2a14309154aec09c026e6fe0e2fc9.png" alt="r-1-8-1"></p><p>Router、Bridge 这些在 Linux 中没有被称为设备的网络功能，反而在日常概念中常常被称为设备。Bridge 提供二层转发功能，Router 提供三层转发功能。Router 还常常借助 iptable 提供 SNAT&#x2F;DNAT 功能。Bridge 也常常借助 iptable 提供 Firewall 功能。</p><p>在 Neutron中，隔离是一个非常重要的特性，利用 namespace 做隔离也是 Neutron 的一个非常重要的手段。</p><h2 id="2-Neutron-原理介绍"><a href="#2-Neutron-原理介绍" class="headerlink" title="2 Neutron 原理介绍"></a>2 Neutron 原理介绍</h2><h3 id="2-1-Neutron-概述"><a href="#2-1-Neutron-概述" class="headerlink" title="2.1 Neutron 概述"></a>2.1 Neutron 概述</h3><p>Neutron 是 OpenStack 项目中负责提供网络服务的组件，它基于软件定义网络的思想，实现了网络虚拟化下的资源管理。Neutron 的设计目标是实现“网络即服务”，为了达到这一目标，在设计上遵循了基于“软件定义网络”实现网络虚拟化的原则，在实现上充分利用了 Linux 系统上的各种网络相关的技术。</p><p>Neutron管理下面的实体：</p><ul><li>网络：隔离的 L2 域，可以是虚拟、逻辑或交换。</li><li>子网：隔离的 L3 域，IP 地址块。其中每个机器有一个 IP，同一个子网的主机彼此 L3 可见。</li><li>端口：网络上虚拟、逻辑或交换端口。<br>  所有这些实体都是虚拟的，拥有自动生成的唯一标示id，支持CRUD功能，并在数据库中跟踪记录状态。</li></ul><h3 id="2-2-实现模式"><a href="#2-2-实现模式" class="headerlink" title="2.2 实现模式"></a>2.2 实现模式</h3><p>无论哪种具体的网络虚拟化实现，一个简化和抽象后的系统架构可以表述为下图所示。</p><p><img data-src="https://i0.hdslb.com/bfs/album/c5afc449e956e6b4156b8b8259bb7ea8bccc6fb9.png" alt="r-abstract_arch"></p><p>在启用 DVR 特性（J 版本以后支持）之前，所有流量（东西向、南北向）都需要经过网络节点的转发；DVR 特性则允许东西向流量和带有 Floating IP 的南北向流量不经过网络节点的转发，直接从计算节点的外部网络出去。</p><p>网络节点有且仅有 Neutron 服务，就是网络服务。Neutron 主要负责管理私有网段和公有网段之间的通信，同时管理虚拟机网络之间的通信以及防火墙等等。一般在部署时会部署两个以上的网络端口，分别用于与控制节点通信、同计算&#x2F;存储节点通信、用于外部的虚拟机与相应的网络之间的通信。</p><p>计算节点主要包含计算服务、网络服务以及监控服务。计算节点对所部署的虚拟机提供基本的网络功能支持，包括隔离不同租户的虚拟机和进行一些基本的安全策略管理。计算节点包含 Nova，Neutron，Telemeter 三个服务：</p><ul><li>基础服务 Nova：提供虚拟机的创建，运行，迁移，快照等各种围绕虚拟机的服务，并提供 API 与控制节点对接，由控制节点下发任务</li><li>基础服务 Neutron：提供计算节点与网络节点之间的通信服务</li><li>扩展服务 Telmeter：提供计算节点的监控代理，将虚拟机的情况反馈给控制节点，是 Centimeter 的代理服务</li></ul><h4 id="2-2-1-GRE-模式"><a href="#2-2-1-GRE-模式" class="headerlink" title="2.2.1 GRE 模式"></a>2.2.1 GRE 模式</h4><p>在 OpenStack 中网络实现的一个简化的架构示意：</p><p><img data-src="https://i0.hdslb.com/bfs/album/637cd7fc907ee5c793f2548d8c33c82c06493e84.png" alt="r-basic_arch_gre"></p><p>计算节点上包括两台虚拟机 VM1 和 VM2，分别经过一个网桥（如 qbr-XXX）连接到 br-int 网桥上。br-int 网桥再经过 br-tun 网桥（物理网络是 GRE 实现）连接到物理主机外部网络。对于物理网络通过 vlan 来隔离的情况，则一般会存在一个 br-eth 网桥，替代 br-tun 网桥。</p><p>br-tun将带有 vlan tag 的 vm 跟外部通信的流量转换到对应的 gre 隧道，这上面要实现主要的转换逻辑，规则要复杂，一般通过多张表来实现，这些规则所组成的整体转发逻辑如下图所示。</p><p><img data-src="https://i0.hdslb.com/bfs/album/d0cabd01553ddafa46d44f0a79d3f922aa75b154.png" alt="r-compute_br_tun_fwd_logic"></p><p>计算节点上发往 GRE 隧道的网包最终抵达网络节点上的 br-tun，该网桥的规则跟计算节点上 br-tun 的规则相似，完成 tunnel 跟 vlan 之间的转换。br-int 上挂载了很多进程来提供网络服务，包括路由器、DHCP服务器等。这些进程不同的租户可能都需要，彼此的地址空间可能冲突，也可能跟物理网络的地址空间冲突，因此都运行在独立的网络名字空间中。规则跟计算节点的br-int规则一致，表现为一个正常交换机。</p><h4 id="2-2-2-VLAN-模式"><a href="#2-2-2-VLAN-模式" class="headerlink" title="2.2.2 VLAN 模式"></a>2.2.2 VLAN 模式</h4><p>Vlan 模式下的系统架构跟 GRE 模式下类似，如下图所示。</p><p><img data-src="https://i0.hdslb.com/bfs/album/e7342f3cb10eff054eab1572b4dfc4c27edcd573.png" alt="r-basic_arch_vlan"></p><p>需要注意的是，在 vlan 模式下，vlan tag 的转换需要在 br-int 和 br-ethx 两个网桥上进行相互配合。即 br-int 负责从 int-br-ethX 过来的包（带外部 vlan）转换为内部 vlan，而 br-ethx 负责从 phy-br-ethx 过来的包（带内部 vlan）转化为外部的 vlan。</p><p>在计算节点中，类似 GRE 模式下，br-int 负责租户隔离，br-eth1 负责跟计算节点外的网络通信。在 Vlan 模式下，租户的流量隔离是通过 vlan 来进行的，因此此时包括两种 vlan，虚拟机在计算内流量带有的 local vlan 和在计算之外物理网络上隔离不同租户的 vlan。br-int 和 br-eth1 分别对从端口 int-br-eth1 和 phy-br-eth1 上到达的网包进行 vlan tag 的处理。此处有两个网，分别带有两个 vlan tag（内部 tag1 对应外部 tag101，内部 tag2 对应外部 tag102 ）。其中，安全组策略仍然在 qbr 相关的 iptables 上实现。</p><p>在网络节点中，类似 GRE 模式下，br-eth1 收到到达的网包，int-br-eth1 和 phy-br-eth1 上分别进行 vlan 转换，保证到达 br-int 上的网包都是带有内部 vlan tag，到达 br-eth1 上的都是带有外部 vlan tag。br-ex 则完成到 OpenStack 以外网络的连接。</p><h4 id="2-2-3-VXLAN-模式"><a href="#2-2-3-VXLAN-模式" class="headerlink" title="2.2.3 VXLAN 模式"></a>2.2.3 VXLAN 模式</h4><p>VXLAN 模式下，网络的架构跟 GRE 模式类似，所不同的是，不同节点之间通过 VXLAN 隧道互通，即虚拟化层是采用的 VXLAN 协议，基本结构如下图所示。</p><p><img data-src="https://i0.hdslb.com/bfs/album/9e87e5916e5f34ecaa1227254b42468e41380240.png" alt="r-vxlan"></p><p>计算节点主要包括两个网桥：集成网桥 br-int 和 隧道网桥 br-tun，网络节点担负着进行网络服务的任务，包括DHCP、路由和高级网络服务等，一般包括三个网桥：br-tun、br-int 和 br-ex。</p><h3 id="2-3-使用的服务"><a href="#2-3-使用的服务" class="headerlink" title="2.3 使用的服务"></a>2.3 使用的服务</h3><ol><li><p>网络命名空间</p><p> 在 Linux 中，网络名字空间可以被认为是隔离的拥有单独网络栈（网卡、路由转发表、iptables）的环境。网络名字空间经常用来隔离网络设备和服务，只有拥有同样网络名字空间的设备，才能看到彼此。</p></li><li><p>DHCP 服务</p><p> dhcp 服务是通过 dnsmasq 进程（轻量级服务器，可以提供 dns、dhcp、tftp 等服务）来实现的，该进程绑定到 dhcp 名字空间中的 br-int 的接口上。可以查看相关的进程。</p></li><li><p>路由服务</p><p> router 是提供跨 subnet 的互联功能的。比如用户的内部网络中主机想要访问外部互联网的地址，就需要 router 来转发（因此，所有跟外部网络的流量都必须经过 router）。目前router 的实现是通过 iptables 进行的。</p></li><li><p>安全组</p><p> 安全组通过 Linux IPtables 来实现，为此，在计算节点上引入了 qbr* 这样的 Linux 传统 bridge（iptables 规则目前无法加载到直接挂在到 ovs 的 tap 设备上），整体逻辑如下图所示：</p><p> <img data-src="https://i0.hdslb.com/bfs/album/648a26b2b03b6a23563200e25b617ca286f43bbb.png" alt="r-sg_global_logic"></p></li><li><p>负载均衡即服务</p><p> 负载均衡即服务（Load Balance as a Service，LBaaS）是一项网络高级服务。它允许租户动态的在自己的网络创建一个负载均衡设备，可以说是分布式系统中比较基础的组件，它接收前端过来的请求，然后将请求按照某种均衡的策略转发给后端资源池中的某个处理单元，以完成处理。进而可以实现高可用性和横向的扩展性。OpenStack Neutron 通过高级服务扩展的形式支持 LBaaS，目前默认是通过 HAProxy 软件来实现的。</p></li><li><p>防火墙即服务</p><p> 防火墙即服务（FireWall as a Service）在网络节点上（具体说来是在路由器命名空间中）来实现。目前，OpenStack 中实现防火墙基于 Linux 系统自带的 iptables 实现。一个可能混淆的概念是安全组（Security Group），安全组的对象是虚拟网卡，由 L2 Agent 来实现，比如 neutron_openvswitch_agent 和 neutron_linuxbridge_agent，会在计算节点上通过配置 iptables 规则来限制虚拟网卡的进出访问。防火墙可以在安全组之前隔离外部过来的恶意流量，但是对于同个子网内部不同虚拟网卡间的通讯不能过滤（除非它要跨子网）。可以同时部署防火墙和安全组实现双重防护。</p></li><li><p>分布式路由</p><p> 为了降低网络节点的负载，同时提高可扩展性，OpenStack 自 Juno 版本开始正式引入了分布式路由（Distributed Virtual Router，DVR）特性（用户可以选择使用与否），来让计算节点自己来处理原先的大量东西向流量和非 SNAT 南北流量（有 floating IP 的 vm 跟外面的通信）。这样网络节点只需要处理占到一部分的 SNAT （无 floating IP 的 vm 跟外面的通信）流量，大大降低了负载和整个系统对网络节点的依赖。很自然的，FWaaS 也可以跟着放到计算节点上。DHCP 服务、VPN 服务目前仍然需要集中在网络节点上进行。</p></li></ol><h2 id="3-虚拟网络安装配置"><a href="#3-虚拟网络安装配置" class="headerlink" title="3 虚拟网络安装配置"></a>3 虚拟网络安装配置</h2><h3 id="3-1-部署前的准备"><a href="#3-1-部署前的准备" class="headerlink" title="3.1 部署前的准备"></a>3.1 部署前的准备</h3><p>挂载本地镜像源，安装以下 rpm 包：<code>python3-openstackclient</code>、<code>mariadb</code>、<code>mariadb-server</code>、<code>python3-PyMySQL</code>、<code>rabbitmq-server</code>、<code>memcached</code>、<code>python3-memcached</code>、<code>openstack-keystone</code>、<code>httpd</code>、<code>python3-mod_wsgi</code>、<code>openstack-neutron</code>、<code>openstack-neutron-ml2</code>、<code>openstack-neutron-openvswitch</code>、<code>ebtables</code>、<code>ipset</code>。</p><h3 id="3-2-Neutron-的脚本部署"><a href="#3-2-Neutron-的脚本部署" class="headerlink" title="3.2 Neutron 的脚本部署"></a>3.2 Neutron 的脚本部署</h3><ol><li><p>定义 IP 和主机名变量，后续部署使用</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">LOCALMANAGEMENTIP=<span class="string">&quot;192.168.230.134&quot;</span></span><br><span class="line">LOCALOVERLAYIP=<span class="string">&quot;192.168.230.134&quot;</span></span><br><span class="line">LOCALHOSTNAME=<span class="string">&quot;localhost.localdomain&quot;</span></span><br></pre></td></tr></table></figure></li><li><p>设置语言为中文、编码为 <code>UTF-8</code></p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">localectl set-locale LANG=zh_CN.UTF-8</span><br></pre></td></tr></table></figure></li><li><p>利用 <code>firewalld</code> 开放端口，更新防火墙规则</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --permanent --add-port 9696/tcp <span class="comment">#neutron</span></span><br><span class="line">firewall-cmd --permanent --add-port 5000/tcp <span class="comment">#keystone</span></span><br><span class="line">firewall-cmd --permanent --add-port 5672/tcp <span class="comment">#rabbitmq</span></span><br><span class="line">firewall-cmd --permanent --add-port 4789/udp <span class="comment">#vxlan</span></span><br><span class="line">firewall-cmd --permanent --add-port 11211/tcp <span class="comment">#memcached</span></span><br><span class="line">firewall-cmd --permanent --add-port 11211/udp <span class="comment">#memcached</span></span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure></li><li><p>配置 MySQL</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> &gt; /etc/my.cnf.d/openstack.cnf &lt;&lt; <span class="string">EOF</span></span><br><span class="line"><span class="string">[mysqld]</span></span><br><span class="line"><span class="string">bind-address = $LOCALMANAGEMENTIP</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">default-storage-engine = innodb</span></span><br><span class="line"><span class="string">innodb_file_per_table = on</span></span><br><span class="line"><span class="string">max_connections = 4096</span></span><br><span class="line"><span class="string">collation-server = utf8_general_ci</span></span><br><span class="line"><span class="string">character-set-server = utf8</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure></li><li><p>启动 <code>mariadb.service</code></p> <figure class="highlight sh"><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">systemctl <span class="built_in">enable</span> mariadb.service</span><br><span class="line">systemctl start mariadb.service</span><br></pre></td></tr></table></figure></li><li><p>启动 <code>rabbitmqp-server</code>，增加新用户名和密码，给用户赋予配置、读、写权限</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">systemctl <span class="built_in">enable</span> rabbitmq-server.service</span><br><span class="line">systemctl start rabbitmq-server.service</span><br><span class="line">rabbitmqctl add_user openstack openstack</span><br><span class="line">rabbitmqctl set_permissions openstack <span class="string">&quot;.*&quot;</span> <span class="string">&quot;.*&quot;</span> <span class="string">&quot;.*&quot;</span></span><br><span class="line">systemctl restart rabbitmq-server.service</span><br></pre></td></tr></table></figure><blockquote><p>此处发生错误，在 <code>/etc/rabbitmq/rabbitmq-env.conf</code> 文件中添加 <code>NODENAME=rabbit@localhost</code>，重启 <code>rabbitmq-server</code> 解决。</p></blockquote></li><li><p>将 <code>memcached</code> 监听地址改为所有 IP，启动服务</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sed -i <span class="string">&#x27;/OPTIONS/c\OPTIONS=&quot;-l 0.0.0.0&quot;&#x27;</span> /etc/sysconfig/memcached</span><br><span class="line">systemctl <span class="built_in">enable</span> memcached.service</span><br><span class="line">systemctl start memcached.service</span><br></pre></td></tr></table></figure></li><li><p>MySQL 创建 <code>keystone</code> 和 <code>neutron</code> 数据库</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p &lt;&lt;<span class="string">EOF 2&gt;/dev/null</span></span><br><span class="line"><span class="string">    CREATE DATABASE keystone;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON keystone.* TO &#x27;keystone&#x27;@&#x27;localhost&#x27; IDENTIFIED BY &#x27;keystone&#x27;;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON keystone.* TO &#x27;keystone&#x27;@&#x27;%&#x27; IDENTIFIED BY &#x27;keystone&#x27;;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON keystone.* TO &#x27;keystone&#x27;@&#x27;$LOCALHOSTNAME&#x27; IDENTIFIED BY &#x27;keystone&#x27;;</span></span><br><span class="line"><span class="string">    CREATE DATABASE neutron;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON neutron.* TO &#x27;neutron&#x27;@&#x27;localhost&#x27; IDENTIFIED BY &#x27;neutron&#x27;;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON neutron.* TO &#x27;neutron&#x27;@&#x27;%&#x27; IDENTIFIED BY &#x27;neutron&#x27;;</span></span><br><span class="line"><span class="string">    GRANT ALL PRIVILEGES ON neutron.* TO &#x27;neutron&#x27;@&#x27;$LOCALHOSTNAME&#x27; IDENTIFIED BY &#x27;neutron&#x27;;</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure></li><li><p>更新 <code>keystone</code> 配置文件，设置文件所有权，设置管理 IP，初始化数据库信息和 <code>Fernet</code> 密钥数据库，并设置密码和节点</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/keystone/keystone.conf</span><br><span class="line"><span class="built_in">cp</span> ./keystone.conf /etc/keystone/keystone.conf</span><br><span class="line"><span class="built_in">chown</span> root:keystone /etc/keystone/keystone.conf</span><br><span class="line">sed -i <span class="string">&quot;s/172.30.20.211/<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>/g&quot;</span> /etc/keystone/keystone.conf</span><br><span class="line"></span><br><span class="line">su -s /bin/sh -c <span class="string">&quot;keystone-manage db_sync&quot;</span> keystone</span><br><span class="line">keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone</span><br><span class="line">keystone-manage credential_setup --keystone-user keystone --keystone-group keystone</span><br><span class="line">keystone-manage bootstrap --bootstrap-password admin \</span><br><span class="line">    --bootstrap-admin-url http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:5000/v3/ \</span><br><span class="line">    --bootstrap-internal-url http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:5000/v3/ \</span><br><span class="line">    --bootstrap-public-url http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:5000/v3/ \</span><br><span class="line">    --bootstrap-region-id RegionOne</span><br></pre></td></tr></table></figure></li><li><p>设置管理 IP，配置 HTTP 配置文件，启动服务</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/</span><br><span class="line">systemctl <span class="built_in">enable</span> httpd.service</span><br><span class="line">systemctl start httpd.service</span><br></pre></td></tr></table></figure></li><li><p>配置用户名、密码、项目名等信息</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> &gt;&gt; ~/.bashrc &lt;&lt; <span class="string">EOF</span></span><br><span class="line"><span class="string">export OS_USERNAME=admin</span></span><br><span class="line"><span class="string">export OS_PASSWORD=admin</span></span><br><span class="line"><span class="string">export OS_PROJECT_NAME=admin</span></span><br><span class="line"><span class="string">export OS_USER_DOMAIN_NAME=Default</span></span><br><span class="line"><span class="string">export OS_PROJECT_DOMAIN_NAME=Default</span></span><br><span class="line"><span class="string">export OS_AUTH_URL=http://$&#123;LOCALMANAGEMENTIP&#125;:5000/v3</span></span><br><span class="line"><span class="string">export OS_IDENTITY_API_VERSION=3</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure></li><li><p>获取 openstack token 并创建 service 项目</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">source</span> ~/.bashrc</span><br><span class="line">openstack token issue <span class="comment">#获取token</span></span><br><span class="line">openstack project create --domain default --description <span class="string">&quot;Service Project&quot;</span> service <span class="comment">#创建service项目</span></span><br></pre></td></tr></table></figure></li><li><p>创建 neutron 用户，将 neutron 用户添加入 service 项目并拥有 admin 权限，创建 network 服务并添加三个 endpoint</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">openstack user create --domain default --password neutron neutron</span><br><span class="line">openstack role add --project service --user neutron admin</span><br><span class="line">openstack service create --name neutron --description <span class="string">&quot;OpenStack Networking&quot;</span> network</span><br><span class="line">openstack endpoint create --region RegionOne network public http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:9696</span><br><span class="line">openstack endpoint create --region RegionOne network internal http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:9696</span><br><span class="line">openstack endpoint create --region RegionOne network admin http://<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>:9696</span><br></pre></td></tr></table></figure></li><li><p>更新 neutron 配置文件，设置文件所有权和管理 IP</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/neutron/neutron.conf</span><br><span class="line"><span class="built_in">cp</span> ./neutron.conf /etc/neutron/neutron.conf</span><br><span class="line"><span class="built_in">chown</span> root:neutron /etc/neutron/neutron.conf</span><br><span class="line">sed -i <span class="string">&quot;s/172.30.20.211/<span class="variable">$&#123;LOCALMANAGEMENTIP&#125;</span>/g&quot;</span> /etc/neutron/neutron.conf</span><br></pre></td></tr></table></figure></li><li><p>更新 ml2 配置文件和所有权</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/neutron/plugins/ml2/ml2_conf.ini</span><br><span class="line"><span class="built_in">cp</span> ./ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini</span><br><span class="line"><span class="built_in">chown</span> root:neutron /etc/neutron/plugins/ml2/ml2_conf.ini</span><br></pre></td></tr></table></figure></li><li><p>更新 openvswitch_agent 配置文件、所有权、业务 IP</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/neutron/plugins/ml2/openvswitch_agent.ini</span><br><span class="line"><span class="built_in">cp</span> ./openvswitch_agent.ini /etc/neutron/plugins/ml2/openvswitch_agent.ini</span><br><span class="line"><span class="built_in">chown</span> root:neutron /etc/neutron/plugins/ml2/openvswitch_agent.ini</span><br><span class="line">sed -i <span class="string">&quot;s/172.30.20.211/<span class="variable">$&#123;LOCALOVERLAYIP&#125;</span>/g&quot;</span> /etc/neutron/plugins/ml2/openvswitch_agent.ini</span><br></pre></td></tr></table></figure></li><li><p>更新 l3_agent 配置文件和所有权</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/neutron/l3_agent.ini</span><br><span class="line"><span class="built_in">cp</span> ./l3_agent.ini /etc/neutron/l3_agent.ini</span><br><span class="line"><span class="built_in">chown</span> root:neutron /etc/neutron/l3_agent.ini</span><br></pre></td></tr></table></figure></li><li><p>更新 dhcp_agent 配置文件和所有权，杀死 dnsmasq 进程</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf /etc/neutron/dhcp_agent.ini</span><br><span class="line"><span class="built_in">cp</span> ./dhcp_agent.ini /etc/neutron/dhcp_agent.ini</span><br><span class="line"><span class="built_in">chown</span> root:neutron /etc/neutron/dhcp_agent.ini</span><br><span class="line">pkill dnsmasq</span><br></pre></td></tr></table></figure></li><li><p>更新 ml2_conf 配置文件，同步数据库</p><figure class="highlight sh"><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="built_in">ln</span> -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini</span><br><span class="line">su -s /bin/sh -c <span class="string">&quot;neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head&quot;</span> neutron</span><br></pre></td></tr></table></figure></li><li><p>启动 neutron 服务</p><figure class="highlight sh"><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">systemctl <span class="built_in">enable</span> neutron-server.service openvswitch.service neutron-dhcp-agent.service neutron-l3-agent.service neutron-openvswitch-agent.service</span><br><span class="line">systemctl start neutron-server.service openvswitch.service neutron-dhcp-agent.service neutron-l3-agent.service neutron-openvswitch-agent.service</span><br></pre></td></tr></table></figure></li></ol><h3 id="3-3-验证网络操作"><a href="#3-3-验证网络操作" class="headerlink" title="3.3 验证网络操作"></a>3.3 验证网络操作</h3><p>使用 <code>openstack network agent list</code> 命令列出代理以验证启动 neutron 代理是否成功，得到输出如下：</p><p><img data-src="https://i0.hdslb.com/bfs/album/b0e9f005f1d5fc7934ac3168abe611220011e200.png" alt="agent-list"></p><p>启动成功。</p><h3 id="3-4-Neutron-创建网络和子网"><a href="#3-4-Neutron-创建网络和子网" class="headerlink" title="3.4 Neutron 创建网络和子网"></a>3.4 Neutron 创建网络和子网</h3><p>使用 <code>neutron net-create net1</code> 命令创建名为 <code>net1</code> 的网络：</p><img data-src="https://i0.hdslb.com/bfs/album/cf1a0915905448b5a2d9f0518b6a61f0ac055aaa.png" alt="net-create" style="zoom:50%;" /><p>使用 <code>neutron subnet-create net1 192.168.2.0/24 --name subnet1</code> 命令创建名为 <code>subnet1</code>、IP 为 <code>192.168.0.2/24</code> 的子网：</p><img data-src="https://i0.hdslb.com/bfs/album/add3cc6aed1c990d4d4ddb88fb043ae1cc7eaffc.png" alt="subnet-create" style="zoom:50%;" /><p>查看创建结果：</p><p><img data-src="https://i0.hdslb.com/bfs/album/29adb9796e0de81a332335d37f40cb8b53955536.png" alt="create-result"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;简单记录一下一个多月的“实训”。&lt;/p&gt;</summary>
    
    
    
    <category term="笔记" scheme="https://superpung.com/note/"/>
    
    
    <category term="Linux" scheme="https://superpung.com/tags/Linux/"/>
    
    <category term="计算机网络" scheme="https://superpung.com/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
    
  </entry>
  
  <entry>
    <title>《软件测试技术》笔记</title>
    <link href="https://superpung.com/stt-notes/"/>
    <id>https://superpung.com/stt-notes/</id>
    <published>2022-05-26T10:18:30.000Z</published>
    <updated>2022-05-26T10:18:30.000Z</updated>
    
    <content type="html"><![CDATA[<p>《软件测试技术》</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;《软件测试技术》&lt;/p&gt;
</summary>
      
    
    
    
    <category term="笔记" scheme="https://superpung.com/note/"/>
    
    
    <category term="软件测试" scheme="https://superpung.com/tags/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>Q-Learning 简介</title>
    <link href="https://superpung.com/q-learning/"/>
    <id>https://superpung.com/q-learning/</id>
    <published>2022-04-05T02:50:56.000Z</published>
    <updated>2022-04-05T02:50:56.000Z</updated>
    
    <content type="html"><![CDATA[<p>强化学习（Reinforcement Learning）是一种用于模拟现实世界的算法，而其中的一个重要的组成部分是 Q-Learning。</p><span id="more"></span><p>假设有一系列「状态」（state）组成的环境，在每一个状态中都可以采取一种「动作」（action）到达下一个状态。 这些状态并不都是相同的，根据实际应用，不同的状态有不同的「奖励」（reward），而且存在终止状态。我们的目标是从任意初始状态出发，到达终止状态，且所获得的奖励最大。</p><p>Q-Learning 就是这样一种决策算法，帮助我们在每个状态决定应该采取何种动作，才能最终得到最大奖励。</p><h2 id="算法描述"><a href="#算法描述" class="headerlink" title="算法描述"></a>算法描述</h2><p>Q-Learning 算法的核心是维护一张 Q 表，它的每一行对应一个状态，每一列对应一种动作，每个值代表了这个状态下采取这种动作最终可以得到的最大奖励。Q-Learning 会经过多次尝试去更新其中的值，不断试错，从而“学习”到外部环境的机制。</p><p>步骤如下：</p><ol><li>随机初始化 $Q(s, a)$</li><li>重复以下步骤，每一次重复记作一次 episode：<ol><li>初始化状态 s</li><li>重复以下步骤，每一次重复记作一次 episode 的一步（step）：<ol><li>选择状态 s 下要采取的动作 a（依据一定的策略，如 $\epsilon$-greedy）</li><li>执行动作 a，得到奖励 r，到达下一状态 s’</li><li>更新 Q 表：$Q(s,a)\leftarrow Q(s,a)+\alpha[r+\gamma max_{a’}Q(s’,a’)-Q(s,a)]$</li><li>更新状态：$s\leftarrow s’$</li></ol></li><li>当 s 为终止状态，停止</li></ol></li></ol><p>要说明的：</p><ul><li>在每个 step 中，要首先根据一定策略选择要执行的动作。其中 $\epsilon$-greedy 策略是在一定概率下按 Q 表的最优值选择动作，其他情况下随机选择动作。</li><li>在更新 Q 表的步骤中，$r+\gamma max_{a’}Q(s’,a’)$ 是当前得到的最大奖励值（当前状态 s 采取动作 a 获得的奖励 + 下一状态 s’ 获得的最大奖励（Q 表预测的 ）），而 $Q(s,a)$ 则是 Q 表预测的最大奖励值。将二者作差并乘上一个学习率 $\alpha$，叠加到现有的 Q 表中，就完成了 Q 表的一次更新。</li><li>上面中出现的 $\gamma$ 是衰减率，为 0 即不考虑未来奖励如何，只考虑当前奖励最大；为 1 即考虑所有未来的奖励；介于 0 和 1 之间则考虑的程度随 $\gamma^2$ 不断衰减。</li></ul><h2 id="代码演示"><a href="#代码演示" class="headerlink" title="代码演示"></a>代码演示</h2><p>根据上面数学角度的分析，不难看出实际需要处理的就是两个部分：选择动作和更新 Q 表。下面用 <code>python</code> 演示这两部分。</p><h3 id="init"><a href="#init" class="headerlink" title="__init__"></a><code>__init__</code></h3><p>初始化函数主要为建立 Q 表：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, actions, learning_rate=<span class="number">0.01</span>, reward_decay=<span class="number">0.9</span>, e_greedy=<span class="number">0.9</span></span>):</span><br><span class="line">    <span class="variable language_">self</span>.actions = actions</span><br><span class="line">    <span class="variable language_">self</span>.lr = learning_rate</span><br><span class="line">    <span class="variable language_">self</span>.gamma = reward_decay</span><br><span class="line">    <span class="variable language_">self</span>.epsilon = e_greedy</span><br><span class="line">    <span class="variable language_">self</span>.q_table = pd.DataFrame(columns=<span class="variable language_">self</span>.actions, dtype=np.float64)</span><br></pre></td></tr></table></figure><p>其中 <code>actions</code> 为动作的集合（<code>list</code> 类型），需要用到 <code>pandas</code> 和 <code>numpy</code> 库。</p><h3 id="choose-action"><a href="#choose-action" class="headerlink" title="choose_action"></a><code>choose_action</code></h3><p><code>choose_action</code> 是选择动作的函数，需要接收一个参数作为当前状态：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">choose_action</span>(<span class="params">self, observation</span>):</span><br></pre></td></tr></table></figure><p>为方便后续处理和操作，将参数转换为 <code>str</code> 类型：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">observation = <span class="built_in">str</span>(observation)</span><br></pre></td></tr></table></figure><p>接下来需要选择要执行的动作了，但我们首先要判断参数对应的状态是否在 Q 表中，需要引入函数 <code>check_state_exist</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">check_state_exist</span>(<span class="params">self, state</span>):</span><br><span class="line">    <span class="keyword">if</span> state <span class="keyword">not</span> <span class="keyword">in</span> <span class="variable language_">self</span>.q_table.index:</span><br><span class="line">        <span class="comment"># append new state to q table</span></span><br><span class="line">        <span class="variable language_">self</span>.q_table = <span class="variable language_">self</span>.q_table.append(</span><br><span class="line">            pd.Series(</span><br><span class="line">                [<span class="number">0</span>] * <span class="built_in">len</span>(<span class="variable language_">self</span>.actions),</span><br><span class="line">                index=<span class="variable language_">self</span>.q_table.columns,</span><br><span class="line">                name=state,</span><br><span class="line">            )</span><br><span class="line">        )</span><br></pre></td></tr></table></figure><p>逻辑很简单，当这个状态不在 Q 表中时，我们就把它加入 Q 表。</p><div class="note warning"><p>若此处出现报错 <code>TypeError: unhashable type: &#39;list&#39;</code>，应该是把 <code>list</code> 类型的 <code>state</code> 作为参数传了过来。<code>list</code> 类型是不可以作为 key 的，注意需要转换为 <code>str</code> 类型。</p></div><p>在 <code>choose_action</code> 中调用函数 <code>check_state_exist</code> 进行判断：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">self</span>.check_state_exist(observation)</span><br></pre></td></tr></table></figure><p>接下来就可以进行动作的选择了！</p><p>注意之前提到的 $\epsilon$-greedy 策略，我们需要在一定的概率下选择 Q 表中最优值：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> np.random.uniform() &lt; <span class="variable language_">self</span>.epsilon:</span><br><span class="line">    <span class="comment"># choose best action</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># choose random action</span></span><br></pre></td></tr></table></figure><p>回忆一下，Q 表每一行对应一个状态、每一列对应一种动作。所以在 Q 表中选择动作，首先要找到当前的状态：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">state_action = <span class="variable language_">self</span>.q_table.loc[observation, :]</span><br></pre></td></tr></table></figure><p>然后就可以找这一行中的最大值对应的动作了。</p><p>但是这里有一个问题，如果有多个相同的最大值呢？这种情况下如果我们直接判断 argmax，返回的将永远是第一个最大值，永远不会遍历到后面的最大值对应的动作。所以这里我们需要随机选择一个最大值来避免这种情况：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">action = np.random.choice(state_action[state_action == state_action.<span class="built_in">max</span>()].index)</span><br></pre></td></tr></table></figure><p>这就是基于 Q 表选择的动作了。</p><p>在另一个分支进行随机选择：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">action = np.random.choice(<span class="variable language_">self</span>.actions)</span><br></pre></td></tr></table></figure><p>最后返回执行的动作：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">return</span> action</span><br></pre></td></tr></table></figure><p>完整代码：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">choose_action</span>(<span class="params">self, observation</span>):</span><br><span class="line">    observation = <span class="built_in">str</span>(observation)</span><br><span class="line">    <span class="variable language_">self</span>.check_state_exist(observation)</span><br><span class="line">    <span class="comment"># action selection</span></span><br><span class="line">    <span class="keyword">if</span> np.random.uniform() &lt; <span class="variable language_">self</span>.epsilon:</span><br><span class="line">        <span class="comment"># choose best action</span></span><br><span class="line">        state_action = <span class="variable language_">self</span>.q_table.loc[observation, :]</span><br><span class="line">        action = np.random.choice(state_action[state_action == state_action.<span class="built_in">max</span>()].index)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="comment"># choose random action</span></span><br><span class="line">        action = np.random.choice(<span class="variable language_">self</span>.actions)</span><br><span class="line">        <span class="keyword">return</span> action</span><br></pre></td></tr></table></figure><h3 id="learn"><a href="#learn" class="headerlink" title="learn"></a><code>learn</code></h3><p><code>learn</code> 是学习的过程，也就是更新 Q 表的函数，需要接收当前状态、当前执行的动作、获得的奖励和下一个状态 4 个参数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">learn</span>(<span class="params">self, s, a, r, s_</span>):</span><br></pre></td></tr></table></figure><p>同样对状态做字符串化处理，并判断下一个状态是否在 Q 表中：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">s = <span class="built_in">str</span>(s)</span><br><span class="line">s_ = <span class="built_in">str</span>(s_)</span><br><span class="line"><span class="variable language_">self</span>.check_state_exist(s_)</span><br></pre></td></tr></table></figure><p>根据上一部分的分析，更新 Q 表需要知道当前选择对应的最大奖励值（$r+\gamma max_{a’}Q(s’,a’)$，记作 <code>q_target</code>）和 Q 表预测的最大奖励值（$Q(s,a)$，记作 <code>q_predict</code>）。</p><p>其中 <code>q_predict</code> 比较容易得到：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">q_predict = <span class="variable language_">self</span>.q_table.loc[s, a]</span><br></pre></td></tr></table></figure><p>而 <code>q_target</code> 需要判断下一状态是否到了最终状态，如果是，则 <code>q_target</code> 直接为当前获得的奖励 <code>r</code>，否则根据公式计算：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> s_ != <span class="string">&#x27;terminal&#x27;</span>:</span><br><span class="line">    q_target = r + <span class="variable language_">self</span>.gamma * <span class="variable language_">self</span>.q_table.loc[s_, :].<span class="built_in">max</span>()  <span class="comment"># next state is not terminal</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    q_target = r  <span class="comment"># next state is terminal</span></span><br></pre></td></tr></table></figure><p>更新 Q 表：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">self</span>.q_table.loc[s, a] += <span class="variable language_">self</span>.lr * (q_target - q_predict)</span><br></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://mofanpy.com/tutorials/machine-learning/reinforcement-learning/">强化学习 (Reinforcement Learning) | 莫烦Python</a></p><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><p><a href="https://copilot.github.com/">GitHub Copilot · Your AI pair programmer</a></p><p><img data-src="https://i0.hdslb.com/bfs/album/149d09fab5e7742af1c45be2ef804110282b2bcb.jpg" alt="copilot-qlearning"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;强化学习（Reinforcement Learning）是一种用于模拟现实世界的算法，而其中的一个重要的组成部分是 Q-Learning。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="机器学习" scheme="https://superpung.com/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="强化学习" scheme="https://superpung.com/tags/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="Q-Learning" scheme="https://superpung.com/tags/Q-Learning/"/>
    
  </entry>
  
  <entry>
    <title>软件测试技术实验 3 和 4 遇到的一些问题和解决方案</title>
    <link href="https://superpung.com/software-testing-lab3-4/"/>
    <id>https://superpung.com/software-testing-lab3-4/</id>
    <published>2022-03-23T14:02:56.000Z</published>
    <updated>2022-03-23T14:02:56.000Z</updated>
    
    <content type="html"><![CDATA[<p>最近写《软件测试技术》实验 3 和实验 4 时，遇到了一些工具上的问题，并尝试了一些解决方案，记录一下。</p><span id="more"></span><h1 id="实验-3：MuJava"><a href="#实验-3：MuJava" class="headerlink" title="实验 3：MuJava"></a>实验 3：MuJava</h1><p><a href="https://cs.gmu.edu/~offutt/mujava/">MuJava</a> 是一个变异测试的工具，可以生成变异体并运行，最终可以得到变异测试的结果。</p><blockquote><p>变异测试是衡量测试充分性的有效方法，其思想就是模拟程序编写中可能会出现的错误，得到一系列和源程序不同的“变异体”，用来“测试”你的测试程序是否能测出来这些“变异”。你的测试程序杀死（使变异体的运行结果不同于源程序）的变异体越多，测试越充分。</p></blockquote><h2 id="0x00-安装-MuJava"><a href="#0x00-安装-MuJava" class="headerlink" title="0x00 安装 MuJava"></a>0x00 安装 MuJava</h2><ol><li><p>直接到 <a href="https://cs.gmu.edu/~offutt/mujava/">官网</a> 下载 <code>mujava.jar</code>。</p></li><li><p>为了后续实验进行，还需要下载 <code>junit.jar</code>（编写测试程序）、<code>openjava.jar</code>。</p></li><li><p>保存三个 jar 包到固定路径，编辑 <code>~/.bash_profile</code> 引入环境：</p> <figure class="highlight shell"><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">export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_281.jdk/Contents/Home</span><br><span class="line">export PATH=$PATH:$JAVA_HOME/bin</span><br><span class="line">export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:/path/to/openjava.jar:/path/to/junit.jar:/path/to/mujava.jar</span><br></pre></td></tr></table></figure><p> （适用于 macOS，Windows 略有不同）</p></li><li><p>保存并运行 <code>source ~/.bash_profile</code>。</p></li><li><p>为了使用 MuJava，需要创建需要的目录结构：</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></pre></td><td class="code"><pre><span class="line">|--\classes\</span><br><span class="line">|--mujava.config</span><br><span class="line">|--\result\</span><br><span class="line">|--\src\</span><br><span class="line">|--\testset\</span><br></pre></td></tr></table></figure></li></ol><h2 id="0x01-生成变异体"><a href="#0x01-生成变异体" class="headerlink" title="0x01 生成变异体"></a>0x01 生成变异体</h2><ol><li>将源文件移至 <code>\src\</code> 目录。</li><li><code>javac</code> 编译源文件，得到 <code>classes</code> 文件，移至 <code>\classes\</code> 目录。</li><li>运行 <code>java mujava.gui.GenMutantsMain</code>，进入图形化设置界面，勾选需要生成变异体的文件和需要的变异算子，点击 <code>Generate</code> 即可生成（保存在 <code>result</code> 目录）。</li></ol><div class="note warning"><p>若此处出现问题，请检查 0x00 第 3 步中路径是否包含空格。即使使用 <code>\</code> 转译也可能存在问题，建议用 <code>-</code> 或 <code>_</code> 代替空格。</p></div><h2 id="0x02-生成测试集"><a href="#0x02-生成测试集" class="headerlink" title="0x02 生成测试集"></a>0x02 生成测试集</h2><p>使用 JUnit 编写即可，比较简单，得到 <code>xxxTest.java</code>。</p><h2 id="0x03-运行变异测试"><a href="#0x03-运行变异测试" class="headerlink" title="0x03 运行变异测试"></a>0x03 运行变异测试</h2><ol><li><code>javac</code> 编译测试文件，得到 <code>classes</code> 文件，移至 <code>\testset\</code> 目录。</li><li>运行 <code>java mujava.gui.RunTestMain &gt; TestResult.log</code>，将变异测试日志输出至文件保存。</li></ol><div class="note warning"><p>若此处出现问题，请检查 0x00 第 3 步中是否引入了 <code>$JAVA_HOME/lib/tools.jar</code> 和 <code>$JAVA_HOME/lib/dt.jar</code>。</p></div><p>变异测试完成，后续可以进一步分析测试代码和变异体，做进一步改进。</p><h1 id="实验-4：Major"><a href="#实验-4：Major" class="headerlink" title="实验 4：Major"></a>实验 4：Major</h1><p><a href="http://mutation-testing.org/">Major</a> 和 Mujava 功能相近，也是变异测试的工具。</p><h2 id="0x00-安装-Major"><a href="#0x00-安装-Major" class="headerlink" title="0x00 安装 Major"></a>0x00 安装 Major</h2><ol><li><p>直接到 <a href="http://mutation-testing.org/downloads/">官网</a> 下载 Major v1.3.5，解压为 major 目录，存放到固定路径。</p></li><li><p>配置环境变量：</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">export PATH=/path/to/major/bin:$PATH:$JAVA_HOME/bin</span><br></pre></td></tr></table></figure><p> 保存并运行 <code>source ~/.bash_profile</code>。</p></li><li><p>验证是否配置成功：</p> <figure class="highlight shell"><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">❯ javac -version</span><br><span class="line">javac 1.7.0-Major-v1.3.5</span><br><span class="line">❯ ant -version</span><br><span class="line">Apache Ant(TM) version 1.8.4-Major-v1.3.5 compiled on July 18 2019</span><br></pre></td></tr></table></figure></li></ol><div class="note warning"><p>如果验证时得到的输出和上述不同，特别是 <code>javac -version</code> 输出结果不包含 <code>Major-v1.3.5</code>，建议检查第 2 步引入环境变量的顺序，应将 <code>major/bin</code> 目录放在最前面。</p></div><h2 id="0x01-配置文件"><a href="#0x01-配置文件" class="headerlink" title="0x01 配置文件"></a>0x01 配置文件</h2><ol><li><p>Major 使用 <code>ant</code> 运行变异测试，并在 <code>major/example/</code> 目录下给出运行模板。所以我们需要依此建立目录结构：</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">|--\src\</span><br><span class="line">|--\test\</span><br><span class="line">|--build.xml</span><br><span class="line">|--run.sh</span><br></pre></td></tr></table></figure></li><li><p>将源文件移至 <code>src</code> 目录，将 <code>JUnit</code> 测试文件移至 <code>test</code> 目录。</p></li></ol><div class="note warning"><p>请确保代码文件的 <code>package</code> 和目录结构对应，参照给出的运行模板。</p></div><p><code>build.xml</code> 和 <code>run.sh</code> 是 Major 运行的重要文件，前者是配置文件、后者是运行脚本。由于运行目录不同，所以在运行前我们需要在 <code>example</code> 的基础上，根据自己的实际情况对两个文件做一些修改。</p><h3 id="build-xml"><a href="#build-xml" class="headerlink" title="build.xml"></a><code>build.xml</code></h3><ol><li><p>可以在第一行修改自己的项目名称：</p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">name</span>=<span class="string">&quot;YourProjectName&quot;</span> <span class="attr">default</span>=<span class="string">&quot;compile&quot;</span> <span class="attr">basedir</span>=<span class="string">&quot;.&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>修改 <code>/javac/</code> 文件的路径：</p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;major&quot;</span> <span class="attr">value</span>=<span class="string">&quot;/your/path/to/major/bin/javac&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure><p> 它上面两行一般不需要改动。</p></li></ol><h3 id="run-sh"><a href="#run-sh" class="headerlink" title="run.sh"></a><code>run.sh</code></h3><ol><li><p>修改 <code>/major/</code> 目录的路径：</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MAJOR_HOME=&quot;/your/path/to/major&quot;</span><br></pre></td></tr></table></figure></li><li><p>如果没有编写 MML 脚本（一般情况下不需要自己编写），修改 <code>ant</code> 运行的参数：</p> <figure class="highlight shell"><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">MAJOR_HOME/bin/ant -DmutOp=<span class="string">&quot;:ALL&quot;</span> clean compile</span></span><br></pre></td></tr></table></figure><p> 直接指定为 <code>ALL</code> 对应全部变异算子，若此处不修改可能会导致后续生成变异体数量为 0。</p></li></ol><h2 id="0x02-运行变异测试"><a href="#0x02-运行变异测试" class="headerlink" title="0x02 运行变异测试"></a>0x02 运行变异测试</h2><p>运行 <code>./run.sh</code>，得到类似下方的输出则成功：</p><figure class="highlight shell"><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></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">mutation.test:</span><br><span class="line">     [echo] Running mutation analysis ...</span><br><span class="line">    [junit] MAJOR: Mutation analysis enabled</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Run 1 ordered test to verify independence</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Preprocessing time: xxx seconds</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Mutants generated: xxx</span><br><span class="line">    [junit] MAJOR: Mutants covered:   xxx (xx.xx%)</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Export test map to testMap.csv</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Run mutation analysis with 1 individual test</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: 1/1 - UpgradedTriangleTest (xxms / xxx):</span><br><span class="line">    [junit] MAJOR: xxx (xxx / xxx / xxx) -&gt; AVG-RTPM: xms</span><br><span class="line">    [junit] MAJOR: Mutants killed / live: xxx (xxx-x-x) / xx</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Summary:</span><br><span class="line">    [junit] MAJOR:</span><br><span class="line">    [junit] MAJOR: Analysis time:  x.x seconds</span><br><span class="line">    [junit] MAJOR: Mutation score: xx.xx% (xx.xx%)</span><br><span class="line">    [junit] MAJOR: Mutants killed / live: xxx (xxx-x-x) / xx</span><br><span class="line">    [junit] MAJOR: Mutant executions: xxx</span><br><span class="line">    [junit] MAJOR: ------------------------------------------------------------</span><br><span class="line">    [junit] MAJOR: Export summary of results to summary.csv</span><br><span class="line">    [junit] MAJOR: Export run-time results to results.csv</span><br><span class="line">    [junit] MAJOR: Export mutant kill details to killed.csv</span><br><span class="line"></span><br><span class="line">BUILD SUCCESSFUL</span><br><span class="line">Total time: x second</span><br></pre></td></tr></table></figure><p>和 MuJava 类似，后续可以进一步分析测试代码和变异体，做进一步改进。</p><div class="note warning"><p>如果 Mutants covered 未达到 100%，请移除源程序的 <code>main</code> 方法。</p></div><h2 id="0x03-其他问题"><a href="#0x03-其他问题" class="headerlink" title="0x03 其他问题"></a>0x03 其他问题</h2><p>如有其他问题，强烈建议阅读 <a href="http://mutation-testing.org/doc/major.pdf">官方文档</a>，十分详细。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近写《软件测试技术》实验 3 和实验 4 时，遇到了一些工具上的问题，并尝试了一些解决方案，记录一下。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="Java" scheme="https://superpung.com/tags/Java/"/>
    
    <category term="软件测试" scheme="https://superpung.com/tags/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>我和我的 2021</title>
    <link href="https://superpung.com/rev-2021/"/>
    <id>https://superpung.com/rev-2021/</id>
    <published>2021-12-31T03:07:41.000Z</published>
    <updated>2021-12-31T03:07:41.000Z</updated>
    
    <content type="html"><![CDATA[<p>用数字记录 2021 很容易，但用文字记录却很难。</p><span id="more"></span><p>每一天都看似平常，但 365 个平常交叠，总会带来不一样的感受。是啊，茫茫中又度过了一年。2020 的记忆未曾消去，2021 却已悄然而过，来不及沉浸在过去的回忆里，时间催促着我们向前看，2022 的曙光即将在黑夜之后到来。</p><p>每逢新年伊始，心中满怀对新年的企盼。无数次盼望新年胜旧年，盼望旧年的伤悲都能随风，盼望新年的喜乐都能常伴。心怀希望永远是我们面对陌生的勇气，即使时代并不会对我们好些，我们也会继续走下去。</p><p>即使新冠疫情改变了世界的运作方式，但 2021 对我来说也不算很糟。做出了很多新的尝试，有很多有意义的回忆，并没有停留在以前的认知。热爱着我所热爱的，坚持着我所坚持的，继续学习，继续进步。</p><p>这一年的课余时间除了休息外，应该只有做一些项目和学一些新的知识了。开始使用 Notion 作为笔记管理工具，所以很惭愧没有经常更新博客……（2022 一定会多更新的，不能荒废了）学习真是一件容易让人满足的事情。</p><hr><p>找到几张比较有意义的照片，不能说可以贯穿 2021，但也能在漫无目的中留下一些意义。</p><img data-src="https://i0.hdslb.com/bfs/album/bbc36bcb82c4ec376b7879dc2c527e1d35ae98fb.png" alt="2021-1" style="zoom:50%;" /><p>2021 收到最有心的生日礼物，感谢一直陪伴我的 peggy。</p><img data-src="https://i0.hdslb.com/bfs/album/de7fb44cd42d755fe1fc6b5c18ba31bfaabbec60.png" alt="2021-2" style="zoom:50%;" /><p>在天津大悦城 Apple Store 第一次体验了 iPhone 12 mini，可以说是理想中的手机大小了。</p><img data-src="https://i0.hdslb.com/bfs/album/120dd7cbc86c4a1f580d32100b0c77000b51ca7f.png" alt="2021-3" style="zoom:50%;" /><p>AirPods Pro 牛年限定……</p><img data-src="https://i0.hdslb.com/bfs/album/7c73478bbaaff06bb67182c71a46b0393439dda1.png" alt="2021-4" style="zoom:50%;" /><p>拥有了第一台 Mac（也是最贵的生日礼物……），陪伴我一年的 Hackintosh 终于光荣退役，让它重新回到了 Windows。</p><img data-src="https://i0.hdslb.com/bfs/album/a7458dd71e3c307a54af963e5c3220eda10cbcc3.png" alt="2021-5" style="zoom:50%;" /><p>第一次坐救护车……希望不再有这种经历了。</p><p><img data-src="https://i0.hdslb.com/bfs/album/5f437ac89fb86545f48e1bbf316c412d30b4411b.png" alt="2021-6"></p><p>青年湖畔的落日和晚霞。</p><p><img data-src="https://i0.hdslb.com/bfs/album/b39be791b02aba811e5a14b4f92012f5533824a5.png" alt="2021-8"></p><p>重回卫津路，19 年的回忆浮现</p><p><img data-src="https://i0.hdslb.com/bfs/album/7b72db40a286d42b5f256f7335348c178fe1965f.png" alt="2021-9"></p><p>打卡三里屯 Apple Store。</p><p><img data-src="https://i0.hdslb.com/bfs/album/653ef1b06ed1c52473c150aff2c2f3490d55a27b.png" alt="2021-10"></p><p>第一次听周鸿祎老板的讲座。</p><p><img data-src="https://i0.hdslb.com/bfs/album/9e105498cdbb06af51da59a27223d604c734f494.png" alt="2021-11"></p><p>第一次去海洋馆，看到了北极狐。</p><p><img data-src="https://i0.hdslb.com/bfs/album/119258435b314174e34ec9b00de092d83092bb99.png" alt="2021-13"></p><p>去看了世界智能大会。</p><img data-src="https://i0.hdslb.com/bfs/album/93d85534b12a95e9dff123c169dd88c5f3b33396.png" alt="2021-14" style="zoom:50%;" /><p>AirPods Pro，喧嚣离我远一步。</p><p><img data-src="https://i0.hdslb.com/bfs/album/fc60372f2604e915587f03a3725b78bb651d64d9.png" alt="2021-15"></p><p>青年湖畔的午后。</p><p><img data-src="https://i0.hdslb.com/bfs/album/0f998ce90b8b74a0c04e302f7f14fb8606f411ad.png" alt="2021-16"></p><p>青年湖畔的晚霞。</p><img data-src="https://i0.hdslb.com/bfs/album/d260f69b7f053c68649c1ab7ac8e70972898bbcc.png" alt="2021-17" style="zoom:50%;" /><p>可能……是继 4s 后的第一部小手机？</p><p><img data-src="https://i0.hdslb.com/bfs/album/405c22ac5a10bdd5710b95d7120b0d28c5957549.png" alt="2021-18"></p><p>夜景模式下的体育场。</p><p><img data-src="https://i0.hdslb.com/bfs/album/0c4178f4c27a733e24e7a0f6a4fbaeb9c2d18c1a.png" alt="2021-19"></p><p>2021 初雪，随立冬而至。前一天晚上还在下雨，第二天醒来室外已是银装素裹。</p><p><img data-src="https://i0.hdslb.com/bfs/album/57b39bdb596e6916b43ad4988339aec62deed91a.png" alt="2021-20"></p><p>打卡天津恒隆广场 Apple Store。</p><p><img data-src="https://i0.hdslb.com/bfs/album/c359533b63cfbceaaefb262a6770a817536aab97.png" alt="2021-21"></p><p>22 考研第一天傍晚，路上满是出校的车。</p><p><img data-src="https://i0.hdslb.com/bfs/album/94cef62384e8d5ec2029703d34ab92f7d59e63d6.png" alt="2021-24"></p><p><img data-src="https://i0.hdslb.com/bfs/album/dc3d493bc67161ae50101da2e6a81a5470b5fe72.png" alt="2021-22"></p><p>每一年都和网易云度过，今年比去年多听了近 200 小时、近 1000 首歌。</p><img data-src="https://i0.hdslb.com/bfs/album/ed49fe23ded6dd54d3149c7e11452f9b4c701f9b.png" alt="2021-23" style="zoom:50%;" /><p>没想到今年有 324 天都登录了 B 站 🤣</p><hr><p>照片可以定格时间，时间也让照片有了岁月的意义。回望 2021 迈出的每一步，似乎都是平平无奇的一个念头，但这些「抉择」确确实实改变了许多。「落子无悔，抉择本身就是向前」，希望自己可以摆脱抱怨，坚持自己的选择，永远向前看。</p><p>来不及停留，来不及等待。来不及感伤岁月，来不及蹉跎光阴。惟愿 2022 的每一分时光都有意义，继续热爱生活。</p><p><img data-src="https://i0.hdslb.com/bfs/album/f47dfd5c157f553f495dd7ff24483b597c9995eb.png" alt="2021-25"></p><p>2021，再见！</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;用数字记录 2021 很容易，但用文字记录却很难。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
  </entry>
  
  <entry>
    <title>写过的第二个 App</title>
    <link href="https://superpung.com/my-2nd-app/"/>
    <id>https://superpung.com/my-2nd-app/</id>
    <published>2021-09-14T14:34:21.000Z</published>
    <updated>2021-09-14T14:34:21.000Z</updated>
    
    <content type="html"><![CDATA[<p>可能是第一个比较成熟的 app。</p><span id="more"></span><h1 id="What-and-Why"><a href="#What-and-Why" class="headerlink" title="What and Why"></a>What and Why</h1><p>好久没有更新博客了。上一次更新还是在 7 月 13 日，正好过去了两个月的时间。上一篇文章是在学习 swiftUI 时记录的，如今已经完成了 <a href="https://github.com/SuperPung/HwS-100days">100 days of swiftUI</a>。写上一篇文章的时候还没开始做这个 App，如今已经结束了。</p><p>两个月的时间，从在家躺平到提前返校，再到开始小学期、开始暑期训练营，再到正式上课……与此同时，这个 App 的开发也正好伴随着我度过这两个月。</p><p>做的第一个 App 是在 2020 年的暑期训练营，是一个 Todo 的快应用。虽然获了奖，但确实太简单了。一个人完成的项目，并没有付出很大的精力。但是在今年的暑期训练营，深深感受到了 Android 原生开发的困难，可能这也是 Flutter 等框架兴起的原因吧。</p><p>言归正传，我的第二个 App 并不能称作“我的”，因为小组的产品和设计起了很大作用，没有她们的努力，这个 App 最终也不会呈现。特别感谢设计组的朋友，无论是界面、配色、交互等各个方面，都设计得很完美。也要感谢 iOS 组组长提供的学习机会，学到了很多。</p><p>App 的功能是记账，当这个需求发布的时候我正想找一个记账的软件，遂即开始开发。我试用了很多记账的 App，大多十分冗杂。最终我选择了 <a href="https://apps.apple.com/cn/app/icost-%E8%AE%B0%E8%B4%A6-%E5%BF%AB%E9%80%9F%E7%AE%80%E6%B4%81%E5%A5%BD%E7%94%A8%E7%9A%84%E7%90%86%E8%B4%A2%E5%8A%A9%E6%89%8B/id1484262528">iCost</a>，并且至今仍在使用。它界面的简介和纯粹在我看来是十分可贵的，我正需要这样一款 App。在我的 App 开发大部分完成后，我发现它和 iCost 仍有很多差距，iCost 某些方面的布局和设计十分巧妙，也正是我之后需要学习的地方。</p><p>虽然 App 的展示结束了，但我认为这款 App 的开发远没有结束。我的 commit 集中在 8 月 8 日的一周（86 commits）和 8 月 15 日的一周（10 commits），之后由于小学期、课程设计、训练营、选修课等无数 ddl 就只能搁置了，大约暂停了 25 天……直到最近才开始修改之前留下的各种 bug，还有很多功能需要完善……</p><h1 id="目前实现的功能"><a href="#目前实现的功能" class="headerlink" title="目前实现的功能"></a>目前实现的功能</h1><h2 id="主页"><a href="#主页" class="headerlink" title="主页"></a>主页</h2><ul><li>本月支出、本月收入、结余</li><li>一键隐藏</li><li>月预算、日预算</li><li>按日期筛选交易记录</li><li>按类型筛选每日交易记录</li></ul><h2 id="记一笔"><a href="#记一笔" class="headerlink" title="记一笔"></a>记一笔</h2><ul><li>选择交易类型（支出、收入、不计入收支）</li><li>添加备注</li><li>选择分类</li><li>选择日期和时间</li><li>填写金额</li></ul><h2 id="摇食堂"><a href="#摇食堂" class="headerlink" title="摇食堂"></a>摇食堂</h2><ul><li>随机选择</li><li>可编辑奖池</li></ul><h2 id="预算"><a href="#预算" class="headerlink" title="预算"></a>预算</h2><ul><li>预算卡片背景随剩余比例变换颜色</li><li>查看预算详情</li><li>预算期内交易明细</li><li>可编辑预算</li></ul><h2 id="搜索"><a href="#搜索" class="headerlink" title="搜索"></a>搜索</h2><ul><li>搜索按钮和界面</li></ul><h2 id="账本"><a href="#账本" class="headerlink" title="账本"></a>账本</h2><ul><li>选择账本</li><li>添加账本</li></ul><h2 id="统计"><a href="#统计" class="headerlink" title="统计"></a>统计</h2><ul><li>选择月份</li><li>显示当月总支出、总入账</li><li>显示当月的每日支出和收入对比</li><li>显示当年的每月支出和收入对比</li><li>长按折线图可显示具体金额</li><li>显示当月的支出排行榜（金额排序）</li><li>显示当月的全部支出排行</li><li>不同排序方式（按金额和按时间）</li></ul><h2 id="账户"><a href="#账户" class="headerlink" title="账户"></a>账户</h2><ul><li>添加不同类型账户</li><li>添加每个账户的资产和备注</li><li>自动计算总资产</li><li>添加负债（可选）</li><li>自动计算净资产</li></ul><h2 id="设置"><a href="#设置" class="headerlink" title="设置"></a>设置</h2><ul><li>记账日报</li><li>记账月报</li><li>分类管理</li><li>常见问题</li><li>问题反馈</li></ul><h1 id="TODO"><a href="#TODO" class="headerlink" title="TODO"></a>TODO</h1><p>还有很长的路要走……所以先告一段落吧，希望有朝一日可以把 App 完善得更好。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;可能是第一个比较成熟的 app。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="Apple" scheme="https://superpung.com/tags/Apple/"/>
    
    <category term="iOS" scheme="https://superpung.com/tags/iOS/"/>
    
    <category term="SwiftUI" scheme="https://superpung.com/tags/SwiftUI/"/>
    
    <category term="Swift" scheme="https://superpung.com/tags/Swift/"/>
    
    <category term="App" scheme="https://superpung.com/tags/App/"/>
    
  </entry>
  
  <entry>
    <title>在 SwiftUI 中自定义修饰器</title>
    <link href="https://superpung.com/custom-modifier/"/>
    <id>https://superpung.com/custom-modifier/</id>
    <published>2021-07-13T02:41:14.000Z</published>
    <updated>2021-07-13T02:41:14.000Z</updated>
    
    <content type="html"><![CDATA[<p>学习 swiftUI 的记录。</p><span id="more"></span><p>首先定义结构体，在其中对内容修饰：</p><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Watermark</span>: <span class="title class_ inherited__">ViewModifier</span> &#123;</span><br><span class="line">    <span class="keyword">var</span> text: <span class="type">String</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">func</span> <span class="title function_">body</span>(<span class="params">content</span>: <span class="type">Content</span>) -&gt; <span class="keyword">some</span> <span class="type">View</span> &#123;</span><br><span class="line">        <span class="type">ZStack</span>(alignment: .bottomTrailing) &#123;</span><br><span class="line">            content</span><br><span class="line">            <span class="type">Text</span>(text)</span><br><span class="line">                .font(.caption)</span><br><span class="line">                .foregroundColor(.white)</span><br><span class="line">                .padding(<span class="number">5</span>)</span><br><span class="line">                .background(<span class="type">Color</span>.black)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后根据此结构体，定义 <code>extension</code>，在其中定义修饰器函数：</p><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extension</span> <span class="title class_">View</span> &#123;</span><br><span class="line">    <span class="keyword">func</span> <span class="title function_">watermarked</span>(<span class="params">with</span> <span class="params">text</span>: <span class="type">String</span>) -&gt; <span class="keyword">some</span> <span class="type">View</span> &#123;</span><br><span class="line">        <span class="keyword">self</span>.modifier(<span class="type">Watermark</span>(text: text))</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>最终只需调用 <code>extension</code> 中的函数即可实现：</p><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Color</span>.green</span><br><span class="line">    .frame(width: <span class="number">300</span>, height: <span class="number">200</span>)</span><br><span class="line">    .watermarked(with: <span class="string">&quot;Hacking with Swift&quot;</span>)</span><br></pre></td></tr></table></figure><p>效果图：</p><img data-src="https://i0.hdslb.com/bfs/album/e411afa5889eabb69f3512b4f2a6771cfbb5bd97.png" alt="image-20210713104903030" style="zoom:50%;" />]]></content>
    
    
    <summary type="html">&lt;p&gt;学习 swiftUI 的记录。&lt;/p&gt;</summary>
    
    
    
    <category term="技术" scheme="https://superpung.com/tech/"/>
    
    
    <category term="SwiftUI" scheme="https://superpung.com/tags/SwiftUI/"/>
    
  </entry>
  
  <entry>
    <title>关于最近，以及……</title>
    <link href="https://superpung.com/rev-1/"/>
    <id>https://superpung.com/rev-1/</id>
    <published>2021-07-07T04:00:37.000Z</published>
    <updated>2021-07-07T04:00:37.000Z</updated>
    
    <content type="html"><![CDATA[<p>小记。</p><span id="more"></span><h1 id="关于大学生活已经过去了一半这件事"><a href="#关于大学生活已经过去了一半这件事" class="headerlink" title="关于大学生活已经过去了一半这件事"></a>关于大学生活已经过去了一半这件事</h1><p>大学生活度过了一半，仍旧在学期内忙碌、假期内无所事事两个状态间切换，却没有留下些什么。</p><p>看到许多同龄人在大学两年快速成长，收获颇丰，学习生活两开花，令人羡慕。</p><p>假期前度过的考试周着实令人感到紧张刺激，感觉是一个学期记忆里的高峰，也是学习新知识的最多阶段。</p><p>关于课业，鄙人的大类课程终于告一段落了，接下来将面对专业方向的选择，于是在这个历史性的阶段，想着整理一番两年的学习资料，与它们告别，同时便于后人翻阅。</p><p>考试周前在 GitHub 上偶然间看到了许多课程资料分享的 repo，于是 Google 了一下，发现本校尚无，遂自创之。</p><p>后在考试期间、放假之初也在想如何归纳，后来慢慢变得细化、有条理，最终花了几天时间创建完成。</p><p>本想着能节约一下本就贫瘠的硬盘空间，没想到百余次 commit 让 .git 文件夹达到了 10 G，是资料文件的好几倍……</p><p>算了，10 G 就 10 G 吧……</p><p>就放在 <a href="https://github.com/SuperPung/TJU-CourseSharing">这里</a> 了，欢迎有缘人看到提提 Issue 或 PR……</p><p>希望这个项目可以帮助到更多的人吧……</p><h1 id="关于-2021-年过去了一半却还没有总结-2020-年这件事"><a href="#关于-2021-年过去了一半却还没有总结-2020-年这件事" class="headerlink" title="关于 2021 年过去了一半却还没有总结 2020 年这件事"></a>关于 2021 年过去了一半却还没有总结 2020 年这件事</h1><p>2020 年感觉经历了很多，本想在寒假的时候认真总结一下，但却又想不出什么值得纪念的事情。</p><blockquote><p>从人类尺度上来说，时间是连续的，所谓的年也不过是人为根据天体运行规律与气候所做的尺度划分。</p><p>虽然从回忆中单单拎出任何一件事来说，都不足以道，但是聚在一起，反倒如潮水般，暗流奔涌。</p></blockquote><p>无数件小事堆叠、重合，不断推搡着时间前进，有时多得让人喘不过气，有时空闲得静看庭花。</p><p>对所有人来说非同寻常的 2020 年，不知改变了多少人的人生轨迹。</p><p>疫情束缚了人的脚步，史无前例的线上教学，给了我莫大的自由空间。</p><p>2020 年，继续在博客上活跃，也尝试了公众号（因为发了很多实验讲解导致同学关注的很多），找到了喜欢做的事。</p><p>2020 年， 举行了线上发布会，这也是我开始凌晨一点守候  发布会的开端。从 WWDC20 开始， 至今所有的发布会都熬夜看完直播。从惊艳的 iOS 14、iPadOS 14，还有 macOS Big Sur；从 iPad Air、Apple Watch 6 到 iPhone 12、Apple Silicon M1、新的 MacBook Air、MacBook Pro、Mac mini，再到不痛不痒的 iOS 15、iPadOS 15、macOS Monterey……一年多的时光， 正潜移默化地影响着我的生活。</p><p>第一次接触 macOS 是官网的 Mojave 介绍，壁纸随着时间的推移，光影也在变化。后来了解到了黑苹果，最后熬了几个夜终于给装好了，用了一年多没出现异常。</p><p>后来换了真正的 MacBook，原来的电脑也结束了使命，重装回了 Windows。</p><p>在此记录一下，以纪念陪伴我一年的 Hackintosh。</p><p>2020 年，被困在内，但也可能是我向外迈出的第一步。参加了创新计划，最终顺利结题。参加了暑期训练营，第一次写应用，还获得了小奖（那段时间忙得甚至没来得及记录……）。第一次参加社团，当上了部长，组织了几次活动，有些成就感。</p><p>鄙人虽然才疏学浅，但很喜欢向别人分享学到的知识。2020 年报名了新生小班，遇到了非常厉害的几位“同事”，也接触了许多刚入大学的新生。</p><p>有幸指挥了开学典礼，印象深刻的是前夜的准备。</p><p><img data-src="https://i0.hdslb.com/bfs/album/983fa39e232ddf4e768cd8fd531cc306b1d0d2c3.png" alt="before-open"></p><p>（这张图片拍的不错，出自摄影师之手）</p><p>准备完，回宿舍的路上，安静的没有人，忽然觉得很自由。</p><p><img data-src="https://i0.hdslb.com/bfs/album/e504754383446308a1ad316789d060888fa3fdaa.jpg" alt="back-to-dom"></p><p>（这张图片当然是我自己拍的，但不是趴在地上）</p><p>新生周结束的时候，好多小班都感慨颇深。</p><blockquote><p>工作很辛苦，几乎把宿舍搬到了办公室，随时回消息，提前商量通知，虽然累，但是很快乐，一起吐槽奇葩问题，一起欣慰工作顺利，脑洞大开，脑回路拓宽，一起唱歌，一起蹦迪，一起吃喝，一起复习准备考试，一起湖边看星星唱歌。</p><p>好久没有这种一个团队一起付出的感觉了，这三周我很开心，很回味，机会不再有，友谊不会散~</p><p>——hrq</p></blockquote><blockquote><p>太多的话来不及表达，太多的人来不及道别，太多的事来不及结尾。</p><p>时过境迁，岂敢奢求驻足暂歇</p><p>幸甚至哉，得同道之人渡日夜</p><p>愿君前程皆坦途，往来莫徘徊</p><p>——hzy</p></blockquote><blockquote><p>永远不要甘于自己的平庸，永远对梦想和目标满怀热忱，永远永远不要习惯懒惰。</p><p>——zyn</p></blockquote><blockquote><p>面对大学里的众多选择，我曾选择逃避，选择承认自己的平庸然后自暴自弃。这段操心而忙碌的时光就像闹铃一般吵醒了我，让我突然摆脱了之前浑浑噩噩的状态，找到了自己为之奋斗的目标。</p><p>请永远保持踏进校门时心中的那份希冀与热忱。</p><p>——zyh</p></blockquote><p>还有很多，现在可能也回忆不起来了。只记得那是一个夏夜，十几个少年在湖边且行且歌。</p><p><img data-src="https://i0.hdslb.com/bfs/album/e24b44edbed70c0063f954979c9177de7723a0f6.jpg" alt="xiaobans-and-stars"></p><p>有星空相伴，亦如星般璀璨。</p><p>2020 年，有些事情确实没有白做，但得到的同时也伴有失去。没有什么两全其美的办法，尽力去弥补就好了。</p><p>在此记录一下，以纪念逝去的 2020。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;小记。&lt;/p&gt;</summary>
    
    
    
    <category term="生活" scheme="https://superpung.com/life/"/>
    
    
  </entry>
  
  <entry>
    <title>《数据库原理》笔记</title>
    <link href="https://superpung.com/fcds-notes/"/>
    <id>https://superpung.com/fcds-notes/</id>
    <published>2021-06-28T12:56:49.000Z</published>
    <updated>2021-06-28T12:56:49.000Z</updated>
    
    <content type="html"><![CDATA[<p>《数据库系统基础教程》《数据库系统全书》</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;《数据库系统基础教程》《数据库系统全书》&lt;/p&gt;
</summary>
      
    
    
    
    <category term="笔记" scheme="https://superpung.com/note/"/>
    
    
    <category term="数据库" scheme="https://superpung.com/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
  </entry>
  
  <entry>
    <title>《数字逻辑与数字系统》笔记</title>
    <link href="https://superpung.com/ddca-notes/"/>
    <id>https://superpung.com/ddca-notes/</id>
    <published>2021-06-24T07:10:29.000Z</published>
    <updated>2021-06-24T07:10:29.000Z</updated>
    
    <content type="html"><![CDATA[<p>《数字设计和计算机体系结构》</p><span id="more"></span>]]></content>
    
    
    <summary type="html">&lt;p&gt;《数字设计和计算机体系结构》&lt;/p&gt;</summary>
    
    
    
    <category term="笔记" scheme="https://superpung.com/note/"/>
    
    
    <category term="Computer System" scheme="https://superpung.com/tags/Computer-System/"/>
    
  </entry>
  
  <entry>
    <title>《形式化方法》笔记</title>
    <link href="https://superpung.com/fsv-notes/"/>
    <id>https://superpung.com/fsv-notes/</id>
    <published>2021-06-22T12:50:21.000Z</published>
    <updated>2021-06-22T12:50:21.000Z</updated>
    
    <content type="html"><![CDATA[<p>Formal Specification Using Z by David Lightfoot</p><span id="more"></span>]]></content>
    
    
    <summary type="html">&lt;p&gt;Formal Specification Using Z by David Lightfoot&lt;/p&gt;</summary>
    
    
    
    <category term="笔记" scheme="https://superpung.com/note/"/>
    
    
    <category term="形式化方法" scheme="https://superpung.com/tags/%E5%BD%A2%E5%BC%8F%E5%8C%96%E6%96%B9%E6%B3%95/"/>
    
  </entry>
  
  <entry>
    <title>宣言</title>
    <link href="https://superpung.com/declaration/"/>
    <id>https://superpung.com/declaration/</id>
    <published>2021-06-11T03:39:31.000Z</published>
    <updated>2021-06-11T03:39:31.000Z</updated>
    
    <content type="html"><![CDATA[<p>宣言</p><span id="more"></span><p style="TEXT-ALIGN: center" align="center"><font color="navy"><strong>社会主义没有辜负中国</strong></font></p><p style="TEXT-ALIGN: center" align="center"><font color="navy">宣言</font></p><p>　　习近平总书记在党史学习教育动员大会上深刻指出，对共产主义的信仰，对中国特色社会主义的信念，是共产党人的政治灵魂，是共产党人经受住任何考验的精神支柱，强调党的百年奋斗历程和伟大成就，是我们增强道路自信、理论自信、制度自信、文化自信最坚实的基础。总书记的话语，掷地有声、坚定豪迈，深刻揭示了社会主义、共产主义与百年求索、百年奋斗的内在关系，彰显了中国共产党人沿着中国特色社会主义这条唯一正确道路前进的坚毅和执着。</p><p>　　百年历程，许多人和事仍然历历在目，许多呐喊和高歌犹在耳旁。走过风霜雪雨，创造人间奇迹，我们有义务用胜利告慰先烈：社会主义没有辜负中国！我们有责任让历史告诉未来：社会主义不会辜负中国！</p><p>　　<strong>（一）</strong></p><p>　　历史的偶然中往往带着必然。19世纪40年代，古老的中国被列强的坚船利炮打开了国门，中国命运从此进入前所未有的悲惨境地。几乎是同样的年代，在资本主义发展方兴未艾的欧洲，马克思、恩格斯开始了对科学社会主义、对人类解放进步事业的伟大探索。</p><p>　　鸦片战争后的中国，积贫积弱、任人宰割。“四万万人齐下泪，天涯何处是神州”。谭嗣同的这句诗，字字血泪、字字彷徨。太平天国、戊戌变法、义和团运动、辛亥革命……中国人在黑暗中苦苦摸索救亡图存之路；改良主义、自由主义、社会达尔文主义、无政府主义、实用主义……种种西方的理论和学说都被引进作为强国富民的药方。一个个方案都试过了，却又屡屡化为泡影。一条条道路都探寻了，却撞得头破血流。“无量头颅无量血，可怜购得假共和。”列强横行、军阀混战，人民水深火热，第一次世界大战更是戳穿了资本主义文明看似美好的幻象。无数仁人志士一次次地用生命和灵魂发问：中国的出路在哪里？民族的希望在哪里？</p><p>　　十月革命一声炮响，给中国送来了马克思列宁主义。这是一场伟大的历史之约，这是一个郑重的历史之诺！封建社会上千年来的枷锁太严密，非进行彻底的社会改造不能除旧布新。帝国主义带给中国人的压迫太沉重，非动员几万万劳苦大众的伟力不能与之相抗。</p><p>　　李大钊赞叹：“人道的警钟响了！自由的曙光现了！试看将来的环球，必是赤旗的世界！”陈独秀宣示：“十八世纪法兰西的政治革命，二十世纪俄罗斯的社会革命，当时的人都对着他们极口痛骂；但是后来的历史家都要把他们当做人类社会变动和进化的大关键。”年轻的毛泽东疾呼：“时机到了！世界的大潮卷得更急了！洞庭湖的闸门动了，且开了！浩浩荡荡的新思潮业已奔腾澎湃于湘江两岸了！”</p><p>　　1920年乍暖还寒的春天，29岁的陈望道在老家浙江义乌分水塘的柴房里，废寝忘食两个月，第一次完整译出了《共产党宣言》，首印1000册即刻售罄，到1926年重印再版达17次之多。先进的、不屈的中国人经过反复比较、反复推求，选择了马克思主义作为救国救民的道路，作为始终不渝的志向。</p><p>　　1921年7月，以马克思主义为指导思想、以共产主义为奋斗目标的政党——中国共产党诞生，胸怀着信念、嘱托和梦想，在上海石库门的旭日里、在嘉兴南湖的碧波中毅然起航。从此以后，社会主义的火种就在东方点燃，曾经困顿无望的中国就有了方向！</p><p>　　<strong>（二）</strong></p><p>　　大革命失败后，共产党员夏明翰在汉口被捕，英勇就义前给妻子写信诀别：“抛头颅、洒热血，明翰早已视等闲。各取所需终有日，革命事业代代传。红珠留着相思念，赤云孤苦望成全。坚持革命继吾志，誓将真理传人寰。”在那些风雨如晦的岁月里，像夏明翰这样为了共产主义信仰九死而不悔、坚信革命理想一定会实现的烈士，何止千千万万。他们一旦认定了信仰和主义，就再也没有彷徨过、动摇过，不惜用青春和鲜血浇灌“共产花开”。</p><p>　　这个信仰和主义，闪耀着理想烛照人心的光芒。《共产党宣言》描绘道：“代替那存在着阶级和阶级对立的资产阶级旧社会的，将是这样一个联合体，在那里，每个人的自由发展是一切人自由发展的条件。”在社会主义新世界里，人的价值居于第一位，没有剥削、没有压迫，劳动光荣、劳工至上，人人平等富足，彼此亲如一家……这是超越资本主义世界的新世界，也是中华民族自古以来向往的“天下大同”，吸引着无数先进分子心驰之、神往之、践行之。</p><p>　　这个信仰和主义，揭示着社会发展演化的规律。世界大势、浩浩汤汤，顺之者生、逆之者亡。中国共产党是工人阶级的先锋队，代表着先进生产力的方向，代表着历史前进的潮流。经过科学理论武装、掌握社会发展规律的党，就具备了引领社会变革、推进正义事业的自觉，就具备了无坚不摧、百折不挠的力量。</p><p>　　这个信仰和主义，指引着革命走向胜利的道路。以毛泽东为主要代表的中国共产党人，用马克思主义立场观点方法分析中国国情、解决中国问题，鲜明提出中国革命的任务是推翻帝国主义、封建主义、官僚资本主义“三座大山”的压迫，中国革命的道路是农村包围城市、武装夺取政权，中国革命的力量是工人阶级、农民阶级、小资产阶级和一定条件下的民族资产阶级，无产阶级是领导力量、人民是真正的英雄，中国革命要分民主主义革命和社会主义革命两个阶段进行……这些科学认识，处处闪耀着马克思主义真理的光辉，引领着中国革命澎湃向前。</p><p>　　革命理想高于天。正是在理想信念的火炬下，我们党广泛发动工农群众，敢于突击冲锋，成功推进了北伐战争；正是在理想信念的火炬下，幸存的共产党人掩埋了被反动派屠杀的同伴的尸首，拿起武器、走进山林，投入新的战斗；正是在理想信念的火炬下，红军将士闯天险、战强敌，爬雪山、过草地，“风雨浸衣骨更硬，野菜充饥志越坚”，完成了彪炳人类史册的二万五千里长征；正是在理想信念的火炬下，党和人民用坚忍不拔、血战到底，书写了抗击日本军国主义的民族壮歌，取得了抵御外侮的最终胜利；正是在理想信念的火炬下，英勇的人民解放军只用三年时间就打垮了国民党反动派800万军队，彰显了什么是“天若有情天亦老，人间正道是沧桑。”</p><p>　　“批判的武器当然不能代替武器的批判，物质力量只能用物质力量来摧毁。”28年浴血奋战，28年砥砺前行，我们的国家从任人欺辱的“东亚病夫”变成令世界刮目相看的“东方醒狮”，我们的人民从做牛做马的奴隶变成扬眉吐气的主人。中国革命的胜利，就是中国共产党人运用马克思主义挽救中国的伟大实践，就是科学真理彰显力量的伟大历程！</p><p>　　<strong>（三）</strong></p><p>　　1949年6月30日，毛泽东发表《论人民民主专政》提出，我们要经过人民共和国，由农业国进到工业国，由新民主主义社会进到社会主义社会和共产主义社会。中华人民共和国的成立，是科学社会主义原则与中国革命实际相结合的历史结果，也标志着人类进步事业和社会主义力量的发展壮大，开启了社会主义在世界东方的伟大时代。</p><p>　　这是一个革故鼎新、改天换地的时代。面对重重困难考验，中国共产党带领人民迅速医治战争创伤、恢复国民经济，以中国独有的形式实现了对农业、手工业、资本主义工商业的社会主义改造，创造性地完成了由新民主主义革命向社会主义革命的转变，成功实现了中国历史上最深刻最伟大的社会变革。轰轰烈烈的土地改革，使三亿多农民无偿获得七亿亩土地和生产资料；1954年宪法，用根本大法的形式把人民民主和社会主义的原则固定下来；人民代表大会制度、中国共产党领导的多党合作和政治协商制度、民族区域自治制度，构筑起社会主义制度的“四梁八柱”……在这个古老而青春的国度，中国人民建设着社会主义的巍巍大厦，品尝着幸福生活的滋味。</p><p>　　这是一个朝气蓬勃、激情燃烧的时代。“每一秒钟都为创造社会主义社会而劳动”。规划于清末的成渝铁路在新中国成立前的40多年里还是地图上一条虚线，1950年正式开工后只用两年就全线贯通；“一五”期间156个重点工程、694个建设项目全部建成，打下了社会主义工业化的坚实基础；治淮治黄、治理长江取得明显效果，农田水利建设在全国热火朝天铺开；全国城乡卫生医疗网基本形成，天花、霍乱、血吸虫病、疟疾、鼠疫等疾病，或被根除、或得到有效防治……新生的人民政权唤醒了巨大的生产力，新生的社会主义制度激活了人民的能量、促进了人民的福祉。</p><p>　　这是一个英雄辈出、斗志昂扬的时代。为了和平，志愿军将士出国作战，谱写了以“钢少气多”力克“钢多气少”的雄壮史诗；为摘掉“贫油少油”的帽子，“铁人”王进喜带领钻井队战天斗地，“宁肯少活20年，拼命也要拿下大油田”；为改变贫穷落后的面貌，县委书记的榜样焦裕禄带领兰考人民整治“三害”，“生也沙丘，死也沙丘，父老生死系”；为打牢国家自立自强的基石，钱学森、钱三强、邓稼先等一大批科研工作者把汗水和热血洒在茫茫戈壁，创造了“两弹一星”的奇迹……无数有名字的英雄和没有留下名字的英雄，用血肉之躯和坚强臂膀，扛起民族的责任、共和国的荣光。</p><p>　　“筚路蓝缕，以启山林。”在中国这样经济文化比较落后、人口众多的东方大国建设社会主义，犹如攀登一座人迹未至的高山，没有笔直的大道可走，没有现成的路径可循。我们依靠“人民创造历史”的伟力，依靠“集中力量办大事”的优势，创造了一个又一个可以载入中华民族和人类史册的奇迹。我们凭着“革命加拼命”的精神，凭着“一万年太久、只争朝夕”的勇气，在九百六十多万平方公里的土地上描绘了社会主义新中国的最美图画。我们也曾在摸索探求的路上，遭受“文化大革命”这样严重的挫折，惨痛教训值得永远汲取。</p><p>　　无论平坦还是崎岖，无论阳光还是风雨，党领导人民探索社会主义道路的脚步始终向前。历史已经证明：“我们不但善于破坏一个旧世界，我们还将善于建设一个新世界”！</p><p>　　<strong>（四）</strong></p><p>　　“什么是社会主义？怎样建设社会主义？”这个回荡在中国上空的历史之问，中国共产党人从未停止作答。从深刻揭示社会主义建设和社会主义改造的“十大关系”，到及时作出我国社会主要矛盾已经转变成“先进的社会主义制度同落后的社会生产力之间的矛盾”的重要论断，到鲜明提出正确处理人民内部矛盾，无不是宝贵的探索、艰难的行进。</p><p>　　党的十一届三中全会成为党的历史和新中国历史上具有深远意义的伟大转折。停止使用“以阶级斗争为纲”，把全党工作重点转移到社会主义现代化建设上来，重新确立解放思想、实事求是的思想路线……为了建设社会主义，中国共产党领导人民矢志推进新的伟大革命，开启了改革开放的伟大航程。</p><p>　　贫穷不是社会主义！邓小平指出：“社会主义的本质，是解放生产力，发展生产力，消灭剥削，消除两极分化，最终达到共同富裕。”为了使生产关系适应生产力的发展，家庭联产承包责任制广泛施行，经济特区先行先试，乡镇企业异军突起，科技体制改革深入推进，对外开放格局加快形成，蕴藏在广大人民中的活力创造力充分迸发。</p><p>　　走自己的道路，建设有中国特色的社会主义！我们深刻认识到我国处于并将长期处于社会主义初级阶段，提出党在社会主义初级阶段的基本路线，积极发展公有制为主体、多种所有制经济共同发展的基本经济制度，不断完善社会主义市场经济体制，提出小康社会目标和现代化分步走战略，开创和发展了中国特色社会主义。</p><p>　　坚持改革开放的社会主义方向！坚持改革开放、坚持四项基本原则，这两个基本点紧密联系、不可偏废。我们坚持社会主义物质文明和精神文明“两手抓、两手都要硬”，坚定推进党的建设新的伟大工程，全面推进中国特色社会主义经济、政治、文化、社会、生态文明建设，让人民群众共享改革发展成果，为社会主义理想插上现实的翅膀。</p><p>　　改革开放40多年来，我国经济总量一路超过意大利、法国、英国、德国、日本，稳居世界第二；我国人民生活水平持续提升，已经进入中高收入国家行列；神州大地面貌日新月异，公路成网、铁路密布、西气东输、南水北调、高坝矗立、大桥巍峨，天堑变通途；中国还战胜了历史罕见的洪涝、雨雪冰冻、地震等重大自然灾害和非典等重大疫病，经受住了亚洲金融危机和国际金融危机严峻考验，风雨过后更见气度从容、身姿挺拔。</p><p>　　在把握历史前进的逻辑中前进，在顺应时代发展的潮流中发展。中华大地汹涌澎湃的伟大实践表明：只有社会主义才能发展中国，只有改革开放才能让中国大踏步赶上时代、让人民过上幸福生活。中国特色社会主义道路越走越宽广！</p><p>　　<strong>（五）</strong></p><p>　　雄伟壮丽的社会主义事业，凝结着一代代共产党人的艰苦卓绝和付出奉献，负载着多少先哲英烈的寄托与热望。当历史的接力棒再次传递，习近平总书记的话语铿锵有力：我们这一代共产党人的任务，就是继续把坚持和发展中国特色社会主义这篇大文章写下去！</p><p>　　党的十九大向全党全国和全世界庄严宣告：“经过长期努力，中国特色社会主义进入了新时代，这是我国发展新的历史方位。”</p><p>　　新时代的中国，理想的旗帜鲜艳高扬。面对世界百年未有大变局，习近平总书记带领全党全国人民揽全局、应变局、开新局，党和国家事业取得历史性成就、实现历史性变革，中华民族比历史上任何时候都更接近民族复兴的伟大目标。中国人民对马克思主义、共产主义的信仰更加坚定，对中国特色社会主义的信念更加牢固，对实现中华民族伟大复兴的信心空前高涨。</p><p>　　新时代的中国，发展的动力深厚强劲。从十八届三中全会的全面深化改革，到全面依法治国、全面建成小康社会，再到全面从严治党、以党的自我革命推动社会革命，从坚持和完善中国特色社会主义制度，到立足新发展阶段、贯彻新发展理念、构建新发展格局、推动高质量发展，全面建设社会主义现代化国家，中国特色社会主义的战略布局日益完善，现代化建设的方向目标愈加清晰。</p><p>　　新时代的中国，人民的地位充分彰显。“江山就是人民，人民就是江山”，初心的回响穿越时空。“人民对美好生活的向往，就是我们的奋斗目标”，铿锵的宣示淬铁成钉。为了实现中国人民摆脱贫困的千年夙愿，党领导人民打响了脱贫攻坚战，贫困地区广大干部群众顽强拼搏，第一书记和驻村干部全力投入，东西部协作精准对接，社会各界有钱出钱、有力出力，一户户贫困乡亲感受着社会主义大家庭的温暖，一座座寂静的深山涌动着生机和希望。</p><p>　　新时代的中国，团结的力量一往无前。面对科技的高峰，我们从不退缩。嫦娥飞天、蛟龙入海、天眼观星、北斗组网，就在前不久，“祝融”号火星车经过295天的旅程，成功登陆火星。面对霸凌和打压，我们从未屈服，全党全国敢于斗争、勇于胜利，攒成一股劲、拧成一股绳。百年不遇的新冠肺炎疫情，把我们每个人的命运与国家的、集体的命运紧紧连在一起，14亿中国人心手相连、守家护国，创造了人类抗疫斗争史上的伟大奇迹……社会主义的制度优势得到极大彰显。</p><p>　　天地有正气，浩然塞苍冥。如果说社会主义作为人类的正义事业、崇高的价值追求，赋予了新时代以最鲜明的底色、最厚重的底气；那么，新时代就以它最波澜壮阔的实践，赋予了科学社会主义以新的思想维度、新的历史高度。</p><p>　　2021年4月，习近平总书记专程来到广西全州，瞻仰红军长征湘江战役纪念园，他动情地说，理想信念之火一经点燃就会产生巨大的精神力量，要缅怀革命先烈，赓续共产党人精神血脉，坚定理想信念，砥砺革命意志。</p><p>　　回望八十七年前，长征路上、湘江岸边，无数红军战士为了保存革命的火种鏖战拼杀，用鲜血染红了漫漫征程、滚滚江水。这些大多二十来岁、甚至只有十五六岁的战士们，视死而如归、乐观而顽强，就是因为胸怀着对革命必胜的信念，对社会主义、共产主义美好社会的憧憬。这是一个党永生不灭的基因，是一个民族由衰而兴的密码。</p><p>　　今天，我们可以告慰百年来一切先辈和英魂的是：此时此刻，社会主义的阳光正映照在奋斗者的身影中、孩子们的笑脸上，中国特色社会主义旗帜正引领中华民族伟大复兴呈现出前所未有的光明前景。我们必将创造让世界刮目相看的更大奇迹，必将实现共产党人最崇高的伟大理想！</p><hr><p style="TEXT-ALIGN: center" align="center"><font color="navy"><strong>中国没有辜负社会主义</strong></font></p><p style="TEXT-ALIGN: center" align="center"><font color="navy">宣言</font></p><p>　　英国伦敦，大英博物馆，1516年出版的莫尔的《乌托邦》一书静静躺在展柜里。同时留在这座博物馆图书阅览室地板上的，是一位伟人厚重的足印。正是这位为人类解放事业奋斗终身的马克思，将社会主义从空想变为科学，从而广泛而深刻地影响了世界，也广泛而深刻地改变了中国。</p><p>　　中国北京，人民大会堂，习近平总书记2016年在庆祝中国共产党成立95周年大会上向世界宣示：中国共产党领导中国人民取得的伟大胜利，使具有500年历史的社会主义主张在世界上人口最多的国家成功开辟出具有高度现实性和可行性的正确道路，让科学社会主义在21世纪焕发出新的蓬勃生机。</p><p>　　数百年奔流激荡。曾经苦难深重，如今意气昂扬。在科学真理和崇高理想的指引下，中国大地发生历史巨变，我们无比坚定，社会主义没有辜负中国！在中国共产党领导人民的顽强奋斗中，信仰的光芒熠熠闪烁，伟大的事业青春盎然，我们无比自豪，中国没有辜负社会主义！</p><p>　　<strong>（一）</strong></p><p>　　走进江苏常州的瞿秋白纪念馆，“我总想为大家辟一条光明的路”的誓言格外醒目。</p><p>　　中国共产党这个百折不回的寻路者、大勇无畏的开路人，面对种种考验、重重难关，以愚公移山的坚定、精卫填海的奉献，带领中国人民走出了一条险峻而壮丽、艰辛而宽广的中国道路。中国特色社会主义道路，是党和人民100年奋斗、创造、积累的根本成就，是引领中国进步、增进人民福祉、实现民族复兴的康庄大道。</p><p>　　这是一条在历史洪流中扭转民族命运、书写人间奇迹的奋斗之路。在“山重水复疑无路”的彷徨困顿中，马克思主义给中国带来“柳暗花明”。从此，中国共产党开展了以马克思主义之“矢”射中国之“的”的伟大实践。为了推翻“三座大山”，党领导人民开创了农村包围城市、武装夺取政权的革命道路，建立了新中国。为了改变一穷二白的落后面貌，我们建立起全新的社会主义制度，形成了独立的比较完整的工业体系和国民经济体系，并在总结正反两方面经验的基础上，开启了改革开放的伟大航程，极大解放和发展了生产力。面对民族复兴和世界变局的交织激荡，我们坚定理想信念、保持战略定力，围绕坚持和发展中国特色社会主义，完善总体布局、确立战略布局，引领中华民族迎来了从站起来到富起来、强起来的伟大飞跃。</p><p>　　这是一条把人民放在最高位置，得民心、顺民意、惠民利的初心之路。“人民就是江山，共产党打江山、守江山，守的是人民的心，为的是让人民过上好日子。”一代代共产党人为了人民的利益和福祉，把青春和生命、鲜血和汗水，倾注在这片可爱的土地。“小康路上一个都不能少”！为了让幸福的阳光洒遍神州每一个角落，习近平总书记带领全党全国打响脱贫攻坚战，25.5万个驻村工作队挺进一线，近200万名乡镇干部、数百万村干部倾力奋战，八年时间实现了9899万农村贫困人口全部脱贫，832个贫困县全部摘帽，12.8万个贫困村全部出列。这是党、人民、民族的伟大光荣，是我国社会主义制度优越性的充分体现，标志着中华民族向着共同富裕迈出了一大步。</p><p>　　这是一条在经济文化落后国家探索建设现代化的创造之路。现代化是世界近代以来的历史潮流，也寄托着马克思主义先驱对理想社会的期许。错失了工业革命机遇的中国，从所谓“天朝上国”跌落成任人宰割的“鱼肉”。严复著《原强》《辟韩》，郭嵩焘著《使西纪程》，孙中山著《建国方略》，都见证着对现代化的希望和失望。只有中国共产党登上历史舞台，根除了帝国主义和封建主义的祸根，实现了经济基础和上层建筑的彻底改造，才为中国现代化提供了根本前提。从“四个现代化”目标到“三步走”战略，从建设小康社会到建设现代化强国……党领导人民不但用几十年时间走完了发达国家几百年走过的工业化历程，而且探索开辟了物质文明和精神文明相协调、全体人民共同富裕、人与自然和谐共生、走和平发展道路的中国式现代化，为人类社会发展提供了现代化的全新选择。</p><p>　　这是一条始终保持革命精神、以党的自我革命引领伟大社会革命的锻造之路。列宁指出：“无产阶级在争取政权的斗争中，除了组织，没有别的武器。”把曾经“一盘散沙”的中国凝聚起来，不能不依靠有理想、有纪律的马克思主义政党；为宏伟的目标、艰巨的任务而奋斗，不能不保持党的先进性和纯洁性、创造力和战斗力。古田会议、遵义会议、延安整风、“两个务必”、伟大工程和新的伟大工程……每到重大关头，党都指引着前进的方向、担当起历史的责任，坚持真理、修正错误，带领人民翻过一座又一座山，夺取一个又一个胜利。党的十八大以来，以习近平同志为核心的党中央坚持党对一切工作的领导，以自我革命精神推进全面从严治党，以党的革命性锻造引领新的伟大斗争。“打铁必须自身硬。”新时代共产党人用决心和勇气夯实了事业常青之基，用行动回答了跳出“历史周期率”的世纪之问！</p><p>　　2021年3月，俄罗斯联邦共产党中央委员会主席根纳季·久加诺夫在《真理报》撰文指出：“中国共产党的经验证明，20世纪末社会主义的失利，并不是各种反共产主义者喜欢说的‘乌托邦社会主义计划的失败’……在中共领导下，中国人民有能力应对时代的一切挑战，沿着建设新时代中国特色社会主义的正确道路前进”。</p><p>　　中国用铁一般的事实宣告：历史没有终结也不会终结，社会主义生机蓬勃、前途无限！中国特色社会主义道路不但走得对、走得通，而且必将通往更加光明的未来！</p><p>　　<strong>（二）</strong></p><p>　　马克思主义为人间带回真理的火种，但它并没有结束真理，而是开启了真理之书的扉页。中国，以鲜活厚重的理论创新、思想创造，在科学社会主义这部巨著里写下了属于自己的不朽篇章。</p><p>　　——坚守：中国从未背离科学社会主义基本原则</p><p>　　马克思、恩格斯曾对未来社会主义社会的发展过程、发展方向、一般特征作过科学预测和设想。比如，在生产资料公有制基础上组织生产，满足全体社会成员的需要是社会主义生产的根本目的；对社会生产进行有计划的指导和调节，实行等量劳动领取等量产品的按劳分配原则；合乎自然规律地改造和利用自然……这些构成了科学社会主义基本原则。</p><p>　　百年峥嵘岁月，无论弱小还是强大，无论处于高潮还是遭遇挫折，中国共产党从未动摇对科学社会主义基本原则的坚持。我们坚持党的领导；坚持人民民主专政的国体和人民代表大会制度的政体；坚持劳动光荣、按劳分配的社会主义分配原则；坚持把人的价值放在第一位，不断促进人的全面发展和社会全面进步……这些都在新的历史条件下体现了科学社会主义基本原则，赓续了社会主义的基因血脉。</p><p>　　——发展：中国不断推进马克思主义中国化</p><p>　　“马克思的整个世界观不是教义，而是方法。它提供的不是现成的教条，而是进一步研究的出发点和供这种研究使用的方法。”只有发展马克思主义，才能坚持马克思主义，这就是历史的辩证法。</p><p>　　百年风雨兼程，中国共产党始终高举真理的旗帜、进行理论的创造，坚持解放思想和实事求是相统一、培元固本和守正创新相统一，不断推进马克思主义基本原理同中国实际相结合，产生了毛泽东思想、邓小平理论、“三个代表”重要思想、科学发展观等重大理论创新成果，不断丰富和发展中国化的马克思主义，用与时俱进的科学理论回答了“中国向何处去、社会主义向何处去”的历史课题、时代之问。这些深深扎根于中国大地的思想成果，深刻影响着国家民族的前途命运，极大改变着中国人民的精神面貌，社会主义参天大树在世界东方根深叶茂。</p><p>　　——领航：引领中国、影响世界的当代中国马克思主义、21世纪马克思主义</p><p>　　“哲学把无产阶级作为自己的物质武器。同样，无产阶级也把哲学作为自己的精神武器。”从现实的此岸通向梦想的彼岸，从必然王国通向自由王国，必定依靠揭示客观规律、洞察历史大势、回应时代呼声的科学理论。</p><p>　　百年大江奔流，在中华民族伟大复兴的关键时期，在当今世界动荡变革的历史变局之中，中国共产党人凭着历史的积淀、理想的坚守、开拓的勇毅，紧紧围绕新时代坚持和发展什么样的中国特色社会主义、怎样坚持和发展中国特色社会主义，推进实践的新革命、思想的新长征，结出了饱含中国精神、时代精华的硕果——习近平新时代中国特色社会主义思想。</p><p>　　“中国共产党领导是中国特色社会主义最本质的特征”“坚持以人民为中心的发展思想”“推动全体人民共同富裕取得更为明显的实质性进展”“充分发挥市场在资源配置中的决定性作用，更好发挥政府作用”“坚持创新、协调、绿色、开放、共享的发展理念”“绿水青山就是金山银山”“推动构建人类命运共同体”……这些富有创见的思想、观点和论断，对马克思主义作出了原创性、时代性贡献，开拓了中国特色社会主义的新境界。</p><p>　　新时代中国共产党人赋予马克思主义以鲜明的中国特色、民族特色、时代特色，使人们对共产党执政规律、社会主义建设规律、人类社会发展规律的认识达到了一个新的历史高度，使科学社会主义释放出具有强大说服力、感召力的真理光芒！</p><p>　　<strong>（三）</strong></p><p>　　从莫尔笔下的“乌托邦”，到康帕内拉书中的“太阳城”，从摩莱里苦心写就的《自然法典》，到欧文身体力行的“新和谐公社”，从只存在了72天的巴黎公社，到世界上第一个社会主义国家苏联，人类对社会主义社会和制度形态的探索从未停止。中国在社会主义道路上的制度探索和实践，成就了经济快速发展和社会长期稳定“两大奇迹”。</p><p>　　中国共产党一经成立，就把建立体现社会主义原则的制度作为追求。无论是互助合作运动还是工农兵代表大会制度，无论是“三三制”还是“豆选法”，这些在革命根据地的早期实践，都蕴含着社会主义的制度因素和价值理念，为建立新型国家制度积累了宝贵经验。</p><p>　　新中国成立后，我们及时把成功的实践经验转化为制度成果，使我国国家制度既体现科学社会主义基本原则，又符合中国的特殊国情。社会主义公有制、人民代表大会制度、中国共产党领导的多党合作和政治协商制度、民族区域自治制度等一系列制度逐步建立健全。</p><p>　　习近平总书记深刻指出：“制度问题更带有根本性、全局性、稳定性、长期性。”“只有扎根本国土壤、汲取充沛养分的制度，才最可靠、也最管用。”</p><p>　　进入新时代，我们聚焦坚持和完善中国特色社会主义制度、推进国家治理体系和治理能力现代化，在实践探索的基础上加强顶层设计和战略安排，党和国家制度建设“施工图”恢弘展开。从党的领导、人民代表大会、坚持马克思主义在意识形态领域指导地位、党对人民军队的绝对领导等根本制度，到社会主义基本经济制度、基本政治制度，再到不同领域具有创新性、支撑性的重要制度，中国特色社会主义制度体系层次分明、系统完备，各项制度更加成熟、更加定型，在国家治理中日益显现出巨大的制度效能。</p><p>　　危机是制度的试金石。面对百年不遇的新冠肺炎疫情，党领导人民不惜一切代价阻断疫情传播链条，不惜一切代价抢救生命，仅用3个月左右的时间取得了武汉保卫战、湖北保卫战的决定性成果，以最快速度研制出安全有效的疫苗，在压力巨大的情况下确保了经济发展、社会稳定，并为世界各国抗击疫情提供了有力支持。中国速度、中国奇迹的背后，是人民至上、生命至上的社会主义价值理念，是同舟共济、集中力量办大事的制度优越性，是心系世界人民安危福祉的国际主义精神！</p><p>　　德国政治家埃贡·克伦茨这样评价：中国应对这场全球性危机的方式方法，展示了社会主义的制度优势。资本主义世界的旧药方已经不受欢迎，重心正在发生偏移。阿根廷学者马塞洛·罗德里格斯这样写道：这场危机再次凸显了两种理念之争，一种是资本主义，将所有社会关系都商品化，倡导消费主义、个人主义、剥削和社会达尔文主义；另一种是社会主义，倡导健康、教育、文化等不是市场上可交易的商品，而是人民的权利。</p><p>　　在中国特色社会主义制度下，中国人民享受着前所未有的民主、自由和人权，感受着前所未有的获得感、幸福感、安全感。中国制度和治理体系是党和人民历尽千辛万苦、付出巨大代价取得的伟大成就，矗立起人类制度文明和政治文明发展史上的一座丰碑！</p><p>　　<strong>（四）</strong></p><p>　　“文化自信是一个国家、一个民族发展中更基本、更深沉、更持久的力量。”源自于源远流长的中华优秀传统文化，熔铸于党领导人民创造的革命文化和社会主义先进文化，植根于中国特色社会主义伟大实践……历经百年，中国特色社会主义文化已经融入在中国共产党的精神血脉，时刻形塑着亿万中国人的精神气质。</p><p>　　悠远的文明传承是她的基因。今年3月22日，正在福建考察的习近平总书记来到朱熹园，语重心长地指出：“如果没有中华五千年文明，哪里有什么中国特色？如果不是中国特色，哪有我们今天这么成功的中国特色社会主义道路？”五千年文明的薪火相传、生生不息，赋予了我们党百折不挠的顽强与坚韧；中华文化特有的气质和禀赋，赋予了我们党质朴刚健、艰苦奋斗的宝贵品格；华夏先人对天下大同的追求向往，赋予了我们党心系苍生、天下为公的博大胸襟。凝结着人类思想精华的马克思主义，激活了古老的华夏文明；历史上唯一一个从未中断的伟大文明，又为马克思主义在中国的发展注入丰富的养分和深厚的动力。</p><p>　　威武不屈的革命精神是她的本色。在一百年来党领导人民开天辟地、改天换地、翻天覆地的进程中，不但书写了足以彪炳史册的伟大功绩，而且铸就了可歌可泣、光照千秋的伟大精神。上海兴业路的石库门，嘉兴南湖的红船，井冈山麓的八角楼，长征路上的大渡桥，大庆油田第一口油井，戈壁深处的“两弹一星”科研基地，深圳的莲花山，荆江大堤的抗洪纪念碑，汶川地震后建成的新城，旧貌换新颜的湘西十八洞村……这些早已不只是闻名中外的地理标识，更已成为中华民族不甘落后、拼搏奋斗的精神图腾。每当风雨来袭，每当挑战来临，中国人民都在精神之旅中坚定信心、鼓足勇气，凝聚起众志成城、一往无前的磅礴伟力。</p><p>　　社会主义不但要提高物质生产力、也要提高精神生产力，实现现代化一个重要目标就是建成社会主义文化强国。新时代的中国，党的创新理论深入人心，社会主义核心价值观广为弘扬，文化体制改革扎实推进，文化事业、产业蓬勃发展，文明之花处处绽放。《我和我的祖国》《我和我的家乡》等电影诉说着家国的情怀，《觉醒年代》《跨过鸭绿江》《山海情》等电视剧拨动着人民的心弦，《不忘初心》《天耀中华》《沂蒙山》《大地颂歌》等主题作品传扬着时代的旋律，更有那一支支乌兰牧骑活跃在边疆草原，一支支文艺志愿小分队扎根在工厂田间，一部部作品走出国门、走向世界……这一切，构成了激荡人心的时代协奏、感动世界的中国交响。</p><p>　　这是人民蓬勃向上的中国，这是文化繁盛绚丽的中国。中国特色社会主义文化，成为新时代中国屹立于世界民族之林的精神支柱，成为中华民族为人类贡献的文明瑰宝！</p><p>　　五百年来，人类追求社会主义的路途上，有鲜花芬芳，也有荆棘密布。一百年来，中国人追求社会主义的历程中，闪耀着光荣和梦想，也充满着奋斗和牺牲，伟大的中国共产党和英雄的中国人民从未退却、从未动摇。历史雄辩地证明：中国没有辜负社会主义！</p><p>　　面向未来，中国必将为人类文明进步、为世界社会主义发展作出更大贡献，让这个正义而充满前途的事业迸发出更加夺目的光芒！</p><hr><p>转载自：<a href="http://www.xinhuanet.com/">新华网</a></p><p>原文链接：</p><ul><li><a href="http://www.xinhuanet.com/2021-06/06/c_1127535562.htm">宣言：社会主义没有辜负中国｜新华网</a></li><li><a href="http://www.xinhuanet.com/2021-06/07/c_1127539369.htm">宣言：中国没有辜负社会主义｜新华网</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;宣言&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
</feed>
