<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>All the posts! on BLumia's Darkness World</title><link>https://www.blumia.net/post/</link><description>Recent content in All the posts! on BLumia's Darkness World</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 19 Apr 2026 22:14:00 +0800</lastBuildDate><atom:link href="https://www.blumia.net/post/index.xml" rel="self" type="application/rss+xml"/><item><title>适应 AI？</title><link>https://www.blumia.net/post/2026-04-19-adopting-llm-questionmark/</link><pubDate>Sun, 19 Apr 2026 22:14:00 +0800</pubDate><guid>https://www.blumia.net/post/2026-04-19-adopting-llm-questionmark/</guid><description>&lt;p&gt;承上上一篇博客挖的坑：&lt;/p&gt;



 &lt;blockquote&gt;
 &lt;p&gt;其实一直都很想写博客扯一些东西的，主题的话大致脑子里分两类，一类是如今的“AI”热之下的生成式绘图、“Vibe Coding”等工具的看法&amp;hellip;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;去年国庆的时候就打算写这么一篇博客了，倒是写了也有不少内容但是没有写完就搁置了。如今“AI”发展速度之快使那篇的内容在现在看来很多都不必要再提及了，于是想了想干脆结合最近的感受，重新写这么一篇。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="part-1"&gt;Part 1.&lt;/h1&gt;
&lt;h2 id="wtf-is-ai"&gt;WTF IS “AI”&lt;/h2&gt;
&lt;p&gt;我觉得看到这篇文字的读者，在当今环境下，肯定不会把“AI”理解成别的含义。说实话，我一开始（甚至事实上一直以来）很不喜欢用“AI”这个词指代当前的机器学习领域的人工智能相关的成果。毕竟倒退二十年，“大屁股电脑”时代的中国象棋人机中的机器也被称为 AI，游戏开发过程中，NPC 的行为逻辑也被称为 AI，如此等等。“AI”之意“人工智能”本身指的是很宽泛的内容，而当机器学习相关尤其是大模型领域成果发展迅猛后，这个词也成为了新的 marketing 热词被推上风口，如此之热以至于被几乎所有人都接受了，当然甚至连“AGI”也成了新的时尚单品热词&amp;hellip;&lt;/p&gt;
&lt;p&gt;于是本文提到的“AI”指的自然是目前的香饽饽，也就是机器学习、生成式人工智能、LLM什么的了。事实上由于大家都开始这么叫，我也听习惯了，也不那么反感这种叫法了&amp;hellip;颇有&lt;a href="https://www.bookstama.com/school/column/%E3%81%AF%E3%81%A1%E3%81%BF%E3%83%BC/"&gt;“哈基米”&lt;/a&gt;的意味。&lt;/p&gt;
&lt;p&gt;至于一开始为什么想写这篇，目的自然也并不是吐槽这种词语含义演化，而是&amp;hellip;&lt;/p&gt;
&lt;h2 id="fanboy-vs-anti-ai"&gt;Fanboy vs Anti-AI&lt;/h2&gt;
&lt;p&gt;“AI”吹与“AI”黑的互相鄙视现象持续到大概一年前还相当常见，虽然显然不能认为这个现象目前不存在了，但想必这个现象在现在也没有太大的讨论意义了。不过作为这篇文章最初的写作动机，这里还是拿出来讨论一下。&lt;/p&gt;
&lt;p&gt;其实最早看到这个论调的时候我还是很少接触和使用“AI”的状态。ChatGPT 还很难注册，国内还连“文心一言”都没发布，Stable Diffusion 还是效果（在现在看来）很惨的时代，但就已经能明显的观察到两个明显的阵营：“AI”吹和“No AI”，在绘画相关领域尤其显著。自然，字面理解而言，真正的艺术创作和随便输入一些描述而生成得到的产物，在艺术创作本身角度而言，后者显然是毫无价值的。我能够理解和认同这个想法，但“AI”技术就因此一文不值吗？&lt;/p&gt;
&lt;p&gt;一个蛮容易想到的“折中说”观点是，应当将“AI”视为工具，辅助人们更好的进行“创作”。而让我亲自接受这个观点则需要从不同的方面试图理解事情本身。那我觉得，首要问题是：应当因为“AI”“没有灵魂”而拒绝/刻意规避使用“AI”吗？&lt;/p&gt;
&lt;p&gt;这里面有两个很有意思的讨论点，一个是“没有灵魂”，一个是“规避使用AI”。我们暂且不谈前面那个“最重要”的，只谈后者的话，让我换个角度：如果要实施“No AI”这个 policy 的话&amp;hellip;&lt;/p&gt;
&lt;h2 id="since-when-it-count-as-ai"&gt;Since when it count as &amp;ldquo;AI&amp;rdquo;?&lt;/h2&gt;
&lt;p&gt;来两道很没意思的题：&lt;/p&gt;



 &lt;blockquote&gt;
 &lt;ul&gt;
&lt;li&gt;找规律：给定一个数列，1、2、3、4、5、（），请问括号内的值可能是什么？&lt;/li&gt;
&lt;li&gt;找规律：给定一个数列，2、4、8、（）、32、64，请问括号内的值可能是什么？&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;p&gt;尽管你大概知道括号里都填 114514 也是对的，但大家自然还是会认可这里的通常预期答案是 6 和 16。这两个问题非常简单，也因此是训练儿童观察和分析能力的题目常客，那么，如果一个程序能帮你解决这个问题，这算 “AI” 吗？&lt;/p&gt;
&lt;p&gt;&amp;hellip;算。尽管一开始就提到过，二十年前的“象棋人机”也可以是AI，但&lt;a href="https://www.youtube.com/watch?v=hfMk-kjRv4c"&gt;这个问题确实是个神经网络的初步问题&lt;/a&gt;。而这里提到这点的原因则是：目前很多人会根据能解决问题的难易程度来判断自己所用的东西到底算不算所谓的“AI”，而忽略了大家很可能早就在用“AI”技术的东西的事实。例如在“AI热”之前，机器翻译也基于语言模型，输入法候选词的智能推荐和纠错也是语言模型的应用，OCR则也是早就被大家接受的东西了（背后是神经网络/深度学习）。如果要拒绝使用所有AI产品的话，划定“AI”的界限就变得尤为困难，甚至容易不小心把自己限制成原始人&amp;hellip;&lt;/p&gt;
&lt;h2 id="soulless"&gt;Soulless&lt;/h2&gt;
&lt;p&gt;那么我觉得接下来就应该回到另一个讨论点了——“没有灵魂”。这点其实很容易让我联想到电子乐器/数字音乐合成器被发明的时期。这些数字乐器被批评为“并非真正的乐器”，其产生的音色也被很多届时的音乐家称为没有灵魂的恶魔&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。尽管现如今已经几乎见不到这样的评价了，但此类印象的关联甚至被持续的延申到了电子乐中（DOOM 配乐可能是个比较知名的例子）。&lt;/p&gt;
&lt;p&gt;诚然，切换回“AI生成产物”的场景下，手工打造的产物和根据提示符生成出的东西存在的精力投入/心血付出确实是不同的，但至少这多少可以说明，工具的可用性并不取决于其制造期间的“含人量”。当然，这也是我决定尝试“以善用工具作为目的使用AI”的原因之一了。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="part-2"&gt;Part 2.&lt;/h1&gt;
&lt;p&gt;能让自己接受“尝试以善用工具作为目的使用AI”的想法后，我自然也更多的主动开始尝试各类平台提供的相关服务——尽管使用过程非常克制，会主动频繁的手动进行事实核查（当然实践证明事实核查是必要的，大模型太擅长一本正经的胡说八道了）——但也不得不说，总体给我的使用体验是正面的：在提高对产出内容可信度的质疑程度的前提下，它所提供的信息对解决我所需解决的问题而言还是在大多情况下都很有帮助。尽管也同样是因为大模型幻觉的问题，我一直以来没有使用相比常规更激进的用法，直到后来有机会尝试所谓的“Vibe Coding”。&lt;/p&gt;
&lt;h2 id="vibe"&gt;Vibe&lt;/h2&gt;
&lt;p&gt;在实际描述我的实践与感想之前，我觉得还是要先简要的吐槽一下 Vibe 这个词。&lt;/p&gt;
&lt;p&gt;我甚至到现在都主观的觉得 Vibe 这个词在这个语境下会伴随一种贬义，比如调侃川建国的“vibe presidenting”。“我不关心写出来的代码是什么，也不需要关心。瞎搞反正是搞出来了”的感觉。这话放到现在可能立马要有人拿自己用 &lt;code&gt;claude-code&lt;/code&gt; 或是 &lt;code&gt;codex&lt;/code&gt; 之类的 agent 搓出来的可用工具来反驳——但不要忘记，Vibe Coding 一词诞生之时，现在已经不能更常见的“Tool calling/MCP”、“上下文工程”、“驾驭(Harness)工程”、“A2A”之类提高 LLM 产出代码可用与稳定性的实践方式还不存在。&lt;/p&gt;</description></item><item><title>开源软件 = 自主可控？</title><link>https://www.blumia.net/post/2025-12-29-open-source-and-controllability/</link><pubDate>Mon, 29 Dec 2025 22:11:00 +0800</pubDate><guid>https://www.blumia.net/post/2025-12-29-open-source-and-controllability/</guid><description>&lt;h2 id="creative--hackable"&gt;Creative &amp;amp; Hackable&lt;/h2&gt;
&lt;p&gt;已经记不清我是从几岁时对计算机产生的兴趣了，但最初是从沉迷那个叫 Ballance 的游戏开始，通过贴吧获知了自制关卡的存在，也了解到有人给这个游戏开发各种各样的小工具，于是就“好神奇，我也想做”为契机，从一款游戏开始了我的计算机旅程。Virtools、3DS Max、Virtual Basic、Free Pascal、Lazarus、Flash、Qt Creator，接触的东西越来越多，也越发觉得好像每个东西都很有趣。我做了很多现在看来几乎没卵用的小玩意儿，但也因为这些经历了解到了很多各种各样的技术，也尝试过各色各样的新奇小工具，并且能利用这些技术和工具来满足我的奇奇怪怪的需求。&lt;/p&gt;
&lt;p&gt;我还记得头一次接触 Qt Creator 是为了瞎改一个别人拿来充当结课作业的播放器，当时很喜欢 osu! 这个游戏，尽管人菜但是很喜欢挂机听歌，后来就基于那位的结课作业瞎改了一个仿 osu! 主界面右上角播放控制栏的悬浮窗迷你播放器，配合扫描 osu! 曲库的功能拿来听我 osu! 里的曲目。东西本身不是个很新奇的玩意儿，但满足了我的奇怪需求，好用！这是在对我对“开源”软件所知并不多时对“开源”&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;项目进行所谓源码级的利用的体验。对于“大体用起来很棒但其中一些功能不太顺手”的情况，相比闭源程序的“那只能忍了”而言，“开源”给了我完全控制程序行为并使之为我所用的能力。&lt;/p&gt;
&lt;p&gt;后来，我也开始试着使用 Qt 来搓一些自己觉得会很符合自己使用习惯的工具，比如我很喜欢古早版本 QQ 内置的看图程序——透明窗口，能看 gif，方便的切换上下一张图片，双击消失——可惜它不是独立的看图程序，于是就有了菠萝看图&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;——它没有很复杂的业务逻辑或“技术含量”，但我可以利用 Qt 所提供的特性来快速定制出具有我想要行为的程序。后续开发过程不乏碰到一些 Qt 自身的问题，由于其开源，我也能够直接通过阅读和修改源码来解决我的问题。嗯，这使我更加相信“开源”所能带给我的“自主可控”之力。&lt;/p&gt;
&lt;p&gt;我已经记不清今年是我使用 Linux 桌面的第几个年头了，而“开源”是我使用 Linux 桌面的契机之一。我仍然还记得我最初会尝试各式各样的桌面布局和主题来把桌面摆成想要的样子，把玩着果冻窗口甚至酷炫的 Compiz 特效等等。KDE 桌面环境的灵活性使我可以做我想做的大部分事情，而对于我不习惯的地方，我也可以修改相关小组件或是其他开源程序的源码来使之符合我的习惯。这种“Hackable”的体验可以认为是站在巨人的肩膀上，使工具可以为我所用，从而能更高效率的做更有意义的事情。&lt;/p&gt;
&lt;p&gt;但是&amp;hellip;开源软件真的等于“自主可控”吗？&lt;/p&gt;
&lt;h2 id="waylandagain"&gt;Wayland&amp;hellip;again&lt;/h2&gt;
&lt;p&gt;今天刷推的时候时间线冒出一个视频，内容是一个用户使用 MateEngine 制作的 OneShot Neko 桌宠站在任务栏上，跟随 WACUP 播放的音乐做出相关的动作。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/Mmmtttbbb2/status/2005332661234245830"&gt;https://twitter.com/Mmmtttbbb2/status/2005332661234245830&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个视频所演示的内容并非很新奇的内容，而很遗憾的告诉你——这个视频所演示的内容在现如今的 Wayland&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt; 上是做不到的。因为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WACUP（山寨 WAMP）播放器的小窗口可以边缘吸附在主窗口上一起移动&lt;/li&gt;
&lt;li&gt;MateEngine 桌宠可以获知你任务栏（以及事实上也支持其他应用程序窗口）所在的位置并做出响应（“站在”任务栏上）&lt;/li&gt;
&lt;li&gt;桌宠是置顶显示的，位于其他所有普通窗口之上&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些问题（除了获知其他程序窗口位置外）在之前的博客中也有提到，而这里并不是希望再“喷” Wayland 一次，而是因为这是一个绝佳的关于“开源 != 自主可控”的例子。那么假设我们是 MateEngine 的开发者，让我们看看如果希望我们的程序能在自己的 Wayland 会话下支持上述功能之一“置顶显示”，我们需要做哪些事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检查当前所使用的 Wayland 合成器是否有自己的独特协议来支持窗口置顶，如果没有，需要添加此类协议，无论是插件形式还是脚本形式还是修改合成器本体的形式&lt;/li&gt;
&lt;li&gt;修改 MateEngine，使用合成器自己的独特协议或是我们所添加的协议来声明窗口置顶属性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其中第二条是不管放在什么平台都要做的事情，也就是“适配目标平台的 API”。而第一条则比较有趣，是让我们自己来给“平台”添加原本所不具备的功能——嗯，我们自己甚至可以给平台添加新的原本并不支持的行为，好像更自主可控了？&lt;/p&gt;</description></item><item><title>来扯一扯开源软件设计</title><link>https://www.blumia.net/post/2025-08-17-lets-talk-about-oss-design/</link><pubDate>Sun, 17 Aug 2025 17:33:00 +0800</pubDate><guid>https://www.blumia.net/post/2025-08-17-lets-talk-about-oss-design/</guid><description>&lt;p&gt;其实一直都很想写博客扯一些东西的，主题的话大致脑子里分两类，一类是如今的“AI”热之下的生成式绘图、“Vibe Coding”等工具的看法，一类是写个文章喷一喷 Wayland。之前苦于社畜腾不出太多时间加上懒，所以一直没成功开坑。这两天刚好不巧被传染感冒发烧了，浑身乏力啥都干不了也不想费脑子，但好在还能按的动键盘，于是来写这么一篇，扯一扯“开源软件设计”。&lt;/p&gt;
&lt;h2 id="那就让我们从-wayland-开始吧"&gt;那就让我们从 Wayland 开始吧&lt;/h2&gt;
&lt;p&gt;上一段已经很明显的暴露了我的观点——我并不待见当前的 Wayland——那么为什么呢？让我来先引用一个大概大家都看过的&amp;hellip;我暂且称之为帖子吧：&lt;a href="https://gist.github.com/probonopd/9feb7c20257af5dd915e3a9f2d1f2277"&gt;Think twice before abandoning X11. Wayland breaks everything!&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这个“帖子”列举了一大堆 X11 和 Wayland 的差异，描述了很多 Wayland 现在根本不存在替代方案的功能缺失。这个帖子目前仍在频繁更新，截至当前，帖子里通过一大堆 X11 API 来列举了哪些东西 Wayland 目前还做不到，而让我们抛开 X11 不谈，作为纯粹应用程序开发者的角度，描述一下我的关注点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序是否可以给窗口设置图标？
&lt;ul&gt;
&lt;li&gt;多窗口程序可能会希望对自己的不同窗口设置不同的图标和窗口标题以让用户更好的区分不同窗口&lt;/li&gt;
&lt;li&gt;一个“程序管理器”可能会spawn其他第三方程序，例如 MC 启动器、通用的类 Spotlight 快速启动器、Distrobox&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;程序是否可以自由的获取和控制窗口位置？
&lt;ul&gt;
&lt;li&gt;使窗口位置居中展示&lt;/li&gt;
&lt;li&gt;多窗口程序，记住窗口上次被关闭时的位置以供恢复&lt;/li&gt;
&lt;li&gt;获取显示器主副屏信息，提供更好的多显示器支持&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;程序是否可以主动置顶或取消置顶窗口？
&lt;ul&gt;
&lt;li&gt;应用程序自身的临时 HUD 提示、自定义通知、参考图软件置顶等&lt;/li&gt;
&lt;li&gt;也是在 DAW 类程序中非常常见的需求&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一条的现状比较有意思，这个功能是 2024 年 6 月 6 日合入的 &lt;a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/269"&gt;xdg-toplevel-icon&lt;/a&gt; 协议提供的特性，涵盖在 &lt;a href="https://doc-snapshots.qt.io/qt6-dev/whatsnew69.html"&gt;Qt 6.9&lt;/a&gt; 中（参考信息：最近才发布的 &lt;a href="https://packages.debian.org/trixie/qt6-base-dev"&gt;debian trixie 使用 Qt 6.8.2&lt;/a&gt;，deepin 25 也仍在使用 Qt 6.8），而至于一众 Wayland 合成器，目前也&lt;a href="https://wayland.app/protocols/xdg-toplevel-icon-v1"&gt;只有 KWin 和 Labwc 对其进行了支持&lt;/a&gt;。&lt;/p&gt;</description></item><item><title>现在换到了 HUGO</title><link>https://www.blumia.net/post/2025-02-16-now-switched-to-hugo/</link><pubDate>Sun, 16 Feb 2025 15:35:00 +0800</pubDate><guid>https://www.blumia.net/post/2025-02-16-now-switched-to-hugo/</guid><description>&lt;p&gt;距离上次更新博客也有个一阵子了，这次更新博客的契机是把静态博客方案从 Jekyll 换到了 HUGO。这正好也是 2025 年的第一篇博客，就借此机会漫无目的的瞎扯一篇吧。&lt;/p&gt;
&lt;h2 id="换到-hugo"&gt;换到 HUGO&lt;/h2&gt;
&lt;p&gt;首先是为什么要换。原因其实很简单，我有一些打算把这个博客站点做一些改造，让它能更方便的罗列一些我在做的事情或者说按新的方式展示一些我想展示的东西，而事实上我已经不能在本地正常的重新跑起来我的原有的 Jekyll 静态生成环境了。导致这个的原因可能是我不熟悉 Ruby 的生态，折腾起来会麻烦很多，而即便折腾后，做出后续调整可能需要花费更多的精力。另一方面原因是，原站点站在我目前的视角而言，实在是太粗糙了，并且涉及到的一些懒人方案，例如 iconfont 对应的平台甚至把我长久没登录过的账号消掉了，导致重新调整相关内容也会变得非常费劲&amp;hellip;&lt;/p&gt;
&lt;p&gt;于是接下来要决定的就是换到什么方案了，那自然需要知道我在意的点有哪些：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;能方便的把环境跑起来，哪怕是放上几年后不去动它&lt;/li&gt;
&lt;li&gt;整体迁移的方便程度，不希望浪费太长时间，所以越省事越好&lt;/li&gt;
&lt;li&gt;有相对多一些的资料可参照，减少踩坑概率，复用现有生态&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HUGO 是第一个想到的方案，也是最终选择的方案。由于它提供的是单一可执行，所以条件①可以很方便的满足，只需要知道对应版本即可。条件②最初考虑是之前用过所以相对熟悉一些，可能省点事。至于③则是因为看 KDE 社区目前的方案如此，也确实资料相对多一些。当然，②实际要做的事情具体有多少也是后来才知道的。如此迁移的话，大概有这些目标：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;保留旧静态博客的数据&lt;/li&gt;
&lt;li&gt;文章现有写法（不常见的 Markdown 语法或者额外的标记语法）的兼容性，迁移不兼容的部分&lt;/li&gt;
&lt;li&gt;对原有 URL 的兼容（有几个文章页面应该是被搜索引擎索引到了，希望能至少重定向到新的页面）&lt;/li&gt;
&lt;li&gt;现有主题的迁移&lt;/li&gt;
&lt;li&gt;迁移 Action，自动部署页面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;查阅资料发现 HUGO 甚至提供了 &lt;a href="https://gohugo.io/commands/hugo_import_jekyll/"&gt;&lt;code&gt;hugo import jekyll&lt;/code&gt;&lt;/a&gt; 这种命令，以为能直接搞定前三点，不过实际执行才发现这个命令事实上只拷贝了文章本身以及静态资源目录，并未做额外的处理，于是事实上和自己手动复制没太大差异。于是后续的几点还是得自己上。开始第二点之前需要做的事情则是先至少跑起来一个架子站点，而由于 HUGO 自身并未提供一个最小可用的架子站点，则最终选了 &lt;a href="https://github.com/Vimux/blank"&gt;GitHub: Vimux/blank&lt;/a&gt; 作为起点，于是终于可以真正的开始迁移本身了。&lt;/p&gt;
&lt;p&gt;尽管把“现有主题的迁移”列在了最后，而它实际是把空白主题放上去后先做的事情。迁移现有主题并不是因为旧主题哪里好（相反，现在觉得其实很差），而是因为原本主题事实上也没太多东西，迁移后也方便查看文章的排版情况，也方便检查标记语法的兼容情况。好在主题的迁移相对确实也比较轻松，于是主题大致迁移完成后，就是检查文章和 URL 的兼容了。&lt;/p&gt;
&lt;p&gt;文章的标记语法兼容性这点，最初是查看了 HUGO 对 GFM 的支持情况。我在乎的大体上是这些：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;脚注&lt;code&gt;[^1]&lt;/code&gt;支持&lt;/li&gt;
&lt;li&gt;站内文章链接支持&lt;/li&gt;
&lt;li&gt;额外的，&lt;code&gt;&amp;gt; [!NOTE]&lt;/code&gt; 支持？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;脚注是我大部分文章都会用的特性，第二点虽说实际不太算是 GFM 的一部分，但也可以说是来自 Wikilink。前两者在试水 HUGO 之前就查对应资料确认支持了，最后一点也意外的发现确实支持，而最终则遇到问题的反而是我完全没觉得会是问题的地方——在 Markdown 内编写基本的 HTML 标注。&lt;/p&gt;
&lt;p&gt;HUGO 默认不允许在 Markdown 中混写任何 HTML 标签，并认为这是 &lt;code&gt;unsafe&lt;/code&gt; 的。于是一些原本便于使用的特性反而成了问题，包括&amp;hellip;&lt;/p&gt;</description></item><item><title>小米路由器 AX3000T 刷入 U-boot + ImmortalWrt 过程记录</title><link>https://www.blumia.net/post/2024-05-25-ax3000t-uboot-immortalwrt/</link><pubDate>Sat, 25 May 2024 19:14:00 +0000</pubDate><guid>https://www.blumia.net/post/2024-05-25-ax3000t-uboot-immortalwrt/</guid><description>&lt;div class="alert alert-primary alert-warning"&gt;
 &lt;p class="alert-heading mb-0"&gt;
 ℹ️
 
 Warning
 
 &lt;/p&gt;
 &lt;p&gt;这篇博客写于 2024/05/25，当时小米 AX3000T 没有 V2 / V3 版本。&lt;strong&gt;这篇文章的内容（尤其是 uboot）不适用于 V2 / V3 版本&lt;/strong&gt;！&lt;br&gt;
另请参阅 &lt;a href="https://github.com/hanwckf/bl-mt798x/issues/88"&gt;hanwckf/bl-mt798x#88&lt;/a&gt; 的相关讨论。&lt;/p&gt;
 &lt;/div&gt;
&lt;h2 id="杂话"&gt;杂话&lt;/h2&gt;
&lt;p&gt;没想到八百年不更一次博客，这次更新竟然又是写折腾路由器的&amp;hellip;&lt;/p&gt;
&lt;p&gt;折腾的原因是之前用的 AC2100 的 Padavan 在配合某些配置时愈加容易出现奇奇怪怪的问题，怀疑问题出在了内核以及特别有限的性能上，加之目前 Wi-Fi 6 甚至 Wi-Fi 7 时代都来了，之前那个也确实差不多该淘汰了，就考虑换一个。于是考虑了几个候选，一个是移动 RAX3000M，然后发现过了个年奸商炒的涨了不少钱。一个是 H68K Mini 这种类似各种 XX 派的玩意儿，但是一方面它本身就很贵，另一方面也担心 ARM 设备的功耗。再一个就是小米 AX3000T 了，也是最后选的产品。和上次一样，也是一次买了两个，另一个会给家里用。&lt;/p&gt;
&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;
&lt;p&gt;尽管和之前一样，&lt;a href="https://openwrt.org/inbox/toh/xiaomi/ax3000t"&gt;OpenWrt 官网上的 Xiaomi AX3000T 硬件信息页面&lt;/a&gt; 已经非常完整的介绍了整个过程实际要做的事情以及原因，但这次开搞之前参考了很多其它资料，最后没有 &lt;em&gt;完全&lt;/em&gt; 参照 OpenWrt 官网写的步骤来搞。原因的话下面会说。步骤的话总体看也不复杂，大致也就是：拿 root ssh shell、刷第三方 U-boot、刷 ImmortalWrt。&lt;/p&gt;
&lt;p&gt;下面的步骤主要是记录我折腾的过程，并非是指导教程目的的文章，所以有点流水账。哦对，顺口一提，我搞它的环境是 Arch Linux，下面的步骤也都是按我实际操作的情况记录的。&lt;/p&gt;
&lt;h3 id="拿-root-ssh-shell"&gt;拿 root ssh shell&lt;/h3&gt;
&lt;p&gt;首先要做的是，插电然后跑一下首次安装向导，这样后面才能连它&amp;hellip;但 &lt;strong&gt;或许&lt;/strong&gt; 这个向导里的 SSID 应该填成自己想用的，因为似乎这个路由器带了 NFC 功能，会使用原厂固件设置的 SSID 和密码，而刷掉后这个功能仍然会存在，只是会继续用之前原厂固件最后一次设置的结果&amp;hellip;不过我不太在乎这个特性，所以反正我是乱填的就是了&amp;hellip;&lt;/p&gt;</description></item><item><title>红米 K40 折腾记</title><link>https://www.blumia.net/post/2021-09-01-redmi-k40-lineageos/</link><pubDate>Wed, 01 Sep 2021 00:02:00 +0000</pubDate><guid>https://www.blumia.net/post/2021-09-01-redmi-k40-lineageos/</guid><description>&lt;p&gt;我觉得我再不写就会把之前的步骤忘掉了，所以趁着没忘掉，赶紧先记一下&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;免责声明：以下内容仅供参考，如果您要做，请搞清楚您在做什么，如果不清楚，请不要做！以下内容只是我个人情况的记录，如果照做导致问题本人不对产生的后果负责！&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="乱谈---选手机"&gt;乱谈 - 选手机&lt;/h2&gt;
&lt;p&gt;因为该死的 Delta 导致进出小区又得扫码了，而随着支付鹫和微信的不断更新和我手机不变的硬件规格，导致进小区扫健康码和便利店/超市结账之前都要提前很久来启动应用来避免结账时等待应用启动和扫码时的尴尬。一直因为很恶心现在各大厂商因为某果公司起头而开始的在屏幕上各种挖空打洞的做法而没有考虑更换手机，但迫于目前那两大扫码应用的启动速度太感人，于是最终还是决定妥协，换个手机好了。&lt;/p&gt;
&lt;p&gt;之前意向购买的手机大概是这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;屏幕不缺口不打洞（屏幕四角圆角还算可以接受）&lt;/li&gt;
&lt;li&gt;有 3.5mm 耳机孔&lt;/li&gt;
&lt;li&gt;有开源 ROM 可刷&lt;/li&gt;
&lt;li&gt;价格不算太离谱&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;某果公司有个很奇怪的特性是，不管再匪夷所思的事情，只要某果起头做了，那别的厂商就都跟着无脑去抄。某果 UI 是一个例子，刘海屏是一个例子，去 3.5mm 耳机孔是一个例子，不再附赠电源又是一个例子。因为全面屏技术不成熟而导致屏幕被啃掉一块儿的妥协做法实在让人看着难受，为了手机薄一点而干脆去掉耳机孔也是个很奇葩的做法。跟风的安卓厂商甚至能发明出“水滴之美”的营销宣传语，并做着意外突出很多的摄像头使人不得不使用手机壳来补充摄像头突出产生的高度差，然后看着手上厚厚的手机却连个耳机孔都没有&amp;hellip;&lt;/p&gt;
&lt;p&gt;当然，也因为这些安卓厂商的跟风，以至于不做出一点妥协就实在没手机可选了，于是只得妥协了屏幕打孔和耳机孔。想到如果早点计划买手机的话还有非打孔的 k30 可以少妥协点东西，但现在才这么想也已经没用了。至于开源 ROM，则是因为屡出安全问题&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;的国行 ROM 使得我不再敢于信任国行 ROM，于是“能刷”变成了不可妥协的一条要求，而由于自行编译 LineageOS 甚至仅仅是 TWRP 都需要近 50 G 的磁盘空间，加之我截至目前也确实没有自行编译 ROM 的经验，故自然还是会优先选择有受到开源 ROM 官方支持的机型。&lt;/p&gt;
&lt;p&gt;由于“能刷”这一不可妥协条件就能淘汰绝大多市面在售手机了，于是其实并没有太多手机可选。小米在售的主流红米和小米机器只要不是联发科 SoC 就大概都可以刷，要么现在就有受 LineageOS 或 crDroid 之类官方支持的 ROM 包，要么在一段时间内也可以等到社区或官方的移植。红米 K40 在国外以小米 11X 和 POCO F3 的名义进行售卖，并且也已经有了 LineageOS 和 crDroid 的官方支持，考虑到价格也算可以接受，于是最终决定选这款机型，并最终购买了这款手机。&lt;/p&gt;
&lt;h2 id="等待刷机---准备工作"&gt;等待刷机 - 准备工作&lt;/h2&gt;
&lt;p&gt;手机到手的第一天自然是感受了一下 ADUI 的厉害，手机放置了一晚上就冒出了一大堆甚至我启动都没启动过的应用的广告通知，尽管这些第三方应用的通知我删掉那些应用就好了，以及来自 ADUI 自身的广告也大都有选项可以关掉&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;，不过我本来也打算要刷的，于是这些就没再管了。&lt;/p&gt;
&lt;p&gt;因为要刷的前提是要解锁，于是到手后没多久下载了官方的解锁工具，发现需要登陆小米账号并插卡联网才可以申请解锁，并且需要等待整整七天，于是那就等呗，直到七天后才解锁，索性七天之后解锁过程没遇到别的什么意外情况，还算比较顺利。&lt;/p&gt;
&lt;h2 id="失败尝试"&gt;失败尝试&lt;/h2&gt;
&lt;p&gt;因为之前手机在用的是 LineageOS，而据说 crDroid 有很多比 LineageOS 好的特性，之前因为怕丢数据和嫌麻烦而没去折腾，故打算借此机会试试 crDroid，于是当天解锁之前自然也准备好了 crDroid 提供的注明了 POCO F3 的代号 alioth 的手机的 ROM 包，OpenGApps 以及一个第三方维护的 TWRP。&lt;/p&gt;</description></item><item><title>《平面设计完全手册》读后乱想</title><link>https://www.blumia.net/post/2021-08-14-after-reading-grafik-und-gestaltung/</link><pubDate>Sat, 14 Aug 2021 22:49:00 +0000</pubDate><guid>https://www.blumia.net/post/2021-08-14-after-reading-grafik-und-gestaltung/</guid><description>&lt;p&gt;目前所在的公司规模比之前小非常多，工作所涉及到的面就会非常杂。因为前段时间工作需要做一些设计，就决定趁机学学看，并借此机会读完了《平面设计完全手册（Grafik und Gestaltung）》这本书。读这本书的时候总是会联想到一些之前的奇怪经历，也有很多奇怪的总结和联想，于是这篇的目的就是记录一下这些乱七八糟的想法。&lt;/p&gt;
&lt;p&gt;《平面设计完全手册》这本书作为对平面设计的扫盲书或者基础入门书来看待的话是很棒的，这本书覆盖了关于基本设计原理的内容、形状和颜色的选用和含义、色彩和谐、图像设计和信息传达、文字排版、设计栅格、企业和徽标设计以及基础印刷交付的相关内容，并且每个部分都很详细的讲述做出怎样设计的原因以及通常情况下建议的做法。不过由于这本书原书是德语的，于是文字字体和排版的很大篇幅是讲述西文排版才适用的内容，对于国内中文排版或许帮助不大。另外可能也是因为近似的原因，书中对于一些术语以及涉及到的人名或书名并未给出原名，对于想要进一步了解背景或细节的情况可能会增加难度。&lt;/p&gt;
&lt;p&gt;这本书是 16 年的书，于是一部分涉及的内容可能有点过时，尤其是提及前端/网站界面设计的相关内容，不过我觉得问题不大。人们对艺术的认知总是和所在的历史时期和地域文化背景有很强的关联的，这也是讲述原理比讲述“万能设计公式”更有意义和重要的地方，于是即便时间推移，只要基于一些理念来找到或归纳得到适用于当下的规则就好，况且就拿当下的应用场景之一的前端举例，目前的前端娱乐圈现状，每隔个半年不知道又会冒出多少东西&amp;hellip;&lt;/p&gt;
&lt;h2 id="pizzicato--stupid"&gt;Pizzicato = stupid&lt;/h2&gt;
&lt;p&gt;艺术作品和平面设计作品的概念蛮近似但实际多少有些差异，相对普通的艺术作品创作而言，艺术本身就可以作为目的，而平面设计则总是服务于特定的功能性的目的。平面设计显然也可以被涵盖在艺术作品的范畴内，而艺术作品本身也是透过作品本身对作者某方面思想或意图的传达，但大致可以认为，平面设计的目的本身是希望信息传达的过程无阻，让受众尽快的理解和接受信息，而艺术作品进行信息传达则不受这样的约束，可以很晦涩吧。&lt;/p&gt;
&lt;p&gt;这样“形式服从于功能”的事情也可以类比到其它方面，例如音乐和商业作品配乐（Stock Music），后者显然也属于音乐，但信息传达的目的性也就更强。当你希望渲染悲伤情绪的时候应当如何配乐，如何让受众一听就知道这个人在干蠢事，如何让这里听起来能彰显我的企业很大气很牛逼之类。这里不得不联想到看过的 Tantacrul 频道的两个视频，&lt;a href="https://www.youtube.com/watch?v=G77ev9pks4I"&gt;Stock Music &amp;amp; Reality TV - How to Misrepresent the World&lt;/a&gt; 和 &lt;a href="https://www.youtube.com/watch?v=AIxY_Y9TGWI"&gt;Corporate Music - How to Compose with no Soul&lt;/a&gt;。尽管这两个视频都在批判这样的声音或音乐设计安排丢掉了其作为“艺术”的灵魂，但我觉得其实这也正是商业作品音乐和音效安排设计的目的，绝对的“形式服从于功能”。&lt;/p&gt;
&lt;p&gt;但说实话，日常生活中的设计场景并未有上面提及的两个视频展示的那样极端，例如可以试着听一下&lt;a href="https://soundcloud.com/juriy-nikitin/voice-of-the-spirit-1"&gt;这段音乐&lt;/a&gt;然后思考可以联想到什么。为游戏的沙漠关卡和丛林关卡配乐，&lt;a href="https://knowyourmeme.com/photos/2135911-gaming"&gt;换做自己的话配器选用会是怎样的&lt;/a&gt;，联想所玩过的游戏，这些游戏中的对应关卡的配器做法是否恰当。Tantacrul 所批判的大概是失去灵魂的音乐和对受众观感的刻意影响，而我们平时设计所需要做的大都只是仅仅希望作品能更好的服务于信息传达而已。&lt;/p&gt;
&lt;h2 id="tab-to-search"&gt;Tab to Search&lt;/h2&gt;
&lt;p&gt;谈及“服从于功能”，就必然联想得到界面交互设计，同样出自 Tantacrul 频道的对 &lt;a href="https://www.youtube.com/watch?v=dKx1wnXClcI"&gt;Sibelius&lt;/a&gt;，&lt;a href="https://www.youtube.com/watch?v=4hZxo96x48A"&gt;MuseScore 3.x&lt;/a&gt; 和 &lt;a href="https://www.youtube.com/watch?v=S-3wEC6Fj_8&amp;amp;t=2387s"&gt;Dorico&lt;/a&gt; 的界面交互评价视频也很有趣，大致讲述了对应软件的交互设计哪里不好，不好在哪里，怎样才能改进。我希望我的用户能在看到界面后一眼就知道这里是干嘛的，我希望用户在进行这样的交互后呈现的结果最符合直觉，我希望用户看到这样的效果呈现后不会感到困惑。达到这些目的，也就是界面交互设计的目标了。Blender 在 3.x 版本后进行了界面的大换新，使得其易用性得到了非常显著的提升，而 Inkscape 和 Audacity 则因为其难用的交互，始终难以获得更多的用户，不过 GIMP 就不再提了，因为它的痛点不在界面交互。&lt;/p&gt;
&lt;p&gt;这里非常想提的就是 Firefox 了。作为一个老牌浏览器，目前市场份额却小的可怜，我觉得造成这个情况的原因之一是他们的用户体验，而这里要举的一个例子就是它的搜索引擎功能了。打着网络自由和用户可控旗号的 Mozilla 的产品 Firefox 至今（截至目前，Firefox 最新版本为 89.0.2）无法手动输入网址来添加搜索引擎，而实际要添加搜索引擎，若不从其提供的中心化的扩展商店添加搜索工具的话，就只能希望网址本身支持 opensearch 然后从地址栏添加，或者在网站的搜索输入框右键选择“为此搜索引擎添加关键词”来添加搜索引擎了。&lt;/p&gt;
&lt;p&gt;看到这里你或许觉得这还不是什么大问题，但实际操作会发现，若网址支持 opensearch，通过地址栏选项添加的搜索引擎会在设置里的搜索引擎列表里展示，而在网站的搜索输入框右键菜单所添加的则并不能在那里找到，实际会发现添加进去的是个书签！为什么一个浏览器会有两个不同的地方表示搜索引擎这个概念呢？为什么要在两个不同的地方管理它们呢？&lt;/p&gt;
&lt;p&gt;这还没有完，若你是 Firefox 的 Power User，你可能知道 Firefox 也有类似 Chrome 的 Tab to Search 功能，在地址栏输入搜索引擎的前几个字母后按下 Tab 即可补全搜索引擎的名称并允许接下来直接输入要搜索的关键词开搜，然后你可能会联想到上面“为此搜索引擎添加关键词”的文案。哦！那就是说，我右键菜单添加的搜索引擎里输入的关键词就是 Tab to Search 里可以用的前缀咯？然而并非如此！只有 opensearch 添加的搜索引擎或者从它的中心化的扩展商店添加的搜索工具才可以被 Tab 补出来。并且即便是同一个前缀，若你输入的过快，你 Tab 出来的搜索引擎和输入较慢时可能还并不是同一个。&lt;/p&gt;</description></item><item><title>加密数字货币是这个世纪最糟糕的发明</title><link>https://www.blumia.net/post/2021-05-15-cryptocurrency-worst-inventions-in-21-century/</link><pubDate>Sat, 15 May 2021 17:38:00 +0000</pubDate><guid>https://www.blumia.net/post/2021-05-15-cryptocurrency-worst-inventions-in-21-century/</guid><description>&lt;p&gt;最初接触区块链这个概念的时候，看了工作原理，觉得这是个挺有趣的想法。所谓区块链技术设立了一个人人可参与的规则，来使得众人参与，构成一个机制透明且不可篡改的工作体系。对所有人透明且不可篡改，是个相当有用的特性，其实很多地方都可以应用，例如各种各样需要涉及审计的大型公司甚至体制内单位。了解大致原理后，最初对其还是比较看好的态度，认为是一项很有用的技术，应该可以使人们的生活在某些程度上变得更好，但实际上真的如此吗？请别误会，我仍然相信能做到“对所有人透明且不可篡改”的技术存在其意义及实际的应用价值，但我觉得，基于区块链技术的加密数字货币是 21 世纪的最糟糕的发明了。&lt;/p&gt;
&lt;p&gt;有人也可能会说，数字货币本身是“对所有人透明且不可篡改”的这个“体系”的应用方式之一，为什么要单独拿数字货币这种用法说事呢？实际考虑的话，区块链和数字货币真的是紧密关联的。不可篡改依赖的是众人参与，而用以确保众人参与的则是对应的奖励，也就是各种各样的数字货币了，并且显然它们要能够折算成可以消费的真金白银才算真正的有激励人们参与的意义。那么区块链技术到底带来了什么呢？“对所有人透明且不可篡改”的体系，这点毫无疑问没问题，而“去中心化的数字货币”则几乎可以说是必然会存在的一种应用方式了，何况实际上，区块链的概念和加密数字货币的元老（比特币）本身就是一并诞生的。&lt;/p&gt;
&lt;p&gt;尽管加密数字货币对于区块链这一概念而言理所应当是一等公民的存在，而我却一直觉得“对所有人透明且不可篡改”的这个“体系”是个好东西，而对附属的“去中心化数字货币”表示存疑。一项技术是否有其意义，我认为取决于它能给人类的生活带来多大的价值，加密数字货币存在已经数年了，在这些年，你能想到的，由加密数字货币带来的生活本质的改善都有哪些呢？我真的想不出来，而坏处则到处皆是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;构成了无人真正可控的真正的赌场（炒币）&lt;/li&gt;
&lt;li&gt;浪费了堪比某些小国一年总耗电量的能源&lt;/li&gt;
&lt;li&gt;助力了互联网勒索团体的资金收取&lt;/li&gt;
&lt;li&gt;促使了无数多的欺诈和庞氏骗局的发生&lt;/li&gt;
&lt;li&gt;造就了迄今为止最严重的公共设施滥用&lt;/li&gt;
&lt;li&gt;以及更多&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你肯定听到过最初的各种 ICO 风潮，见到过各种公司拼命的往区块链这个热词上凑。意见领袖一句话，币值走向就开始像跳绳一样摆动。富豪们坐在家里想想怎么说话就可以收割一波又一波金钱，而加密数字货币就在这种大风大浪中名声愈加牢固。网络勒索团体把目标瞄向一家又一家公司甚至是医院等社会基础设施组织，真正能给人们带来实质意义产出的公司不得不掏钱给这些流氓以免影响到更多无辜的群众。投机的人偶然致富的传说变得仿佛离凡人更近，就有更多人掏出钱包购置挖矿设备或把钱砸向交易所来给这一加密数字货币的狂潮推波助澜。&lt;/p&gt;
&lt;p&gt;一套“对所有人透明且不可篡改”的“体系”理论上来说确实可以给人们带来实质性的生活改善，也尽管加密数字货币是对这个体系的无数种应用方式之一，但现在显然加密数字货币成为了这个体系的几乎唯一的用法。多少年过去了，普通人因此工作需要购置显卡的价格会翻数倍，所依赖的基础设施被勒索的概率会翻数倍，所生活的地球的碳排放量会多数倍，可能遇到的金融甚至非金融&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;骗局会多数倍。有影响力的富人可以几句话操纵这一切，聊天软件群聊内各种“入场不逢时”的“韭菜的声音”短视频已经成了平凡的段子。无数多创业公司找到了新的方式忽悠投资人，遭殃的还是更多的群众。&lt;/p&gt;
&lt;p&gt;有人可能会说“技术无罪”，我也同意技术无罪，但加密数字货币目前的疯狂程度并非技术是否有罪的问题，而是加密数字货币的特性造就了这一系列问题，而这一技术本身所能带来的益处，则没有人真正的放在眼里了。若一切追至根本，倒不如说错在人们的价值观。有钱能使鬼推磨，只要给钱什么都做。投身于“币圈”的人有多少是认为加密数字货币是能为人类带来生活本质的改善的，又有多少是为了自己能趁机赚一笔的投机呢？&lt;/p&gt;
&lt;p&gt;Sourcehut 为众多计算机技术爱好者提供了免费的基础设施，却因被挖矿脚本滥用而不得不限制用户使用&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;，各大 CI 服务网站也开始有免费配额被用作挖矿的消息爆出。一些网站开始主动挂上了隐藏的挖矿脚本，甚至有衍生出给“开源库”加挖矿脚本的供应链攻击。负面影响越来越大，而加密数字货币的狂欢却因为人们对钱的热爱而愈演愈烈，真是可笑又可悲。&lt;/p&gt;
&lt;p&gt;加密数字货币是这个世纪最糟糕的发明，我从未持有也不将持有任何加密数字货币。加密数字货币浪费了多少资源，又毁掉了多少人。加密数字货币造就了骗局和勒索的猖獗，促使试图投机之人越来越多，甚至铤而走险。加密数字货币就不应该被发明。吔屎了！加密数字货币！&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;每次看到有人去玩币都会很想写一篇博客喷一下加密数字货币，于是终于决定写这么一篇。其中很多事件我并没有给出对应的链接，但想必稍微关注相关事件的人就会知道我哪里指的是哪件事了。另外，也可以考虑阅读：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://drewdevault.com/2021/04/26/Cryptocurrency-is-a-disaster.html"&gt;https://drewdevault.com/2021/04/26/Cryptocurrency-is-a-disaster.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;区块链技术&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;去避免篡改靠的是算力的较量，押宝没有人能轻易使出大于50%的算力，以此确保了加密数字货币的正常工作&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;，于是甚至有一部分人未能准确理解后认为者代表着很难有人能随意干预这种数字货币的使用。而对应的有一席话语权的富豪一句话就能影响对应的加密货币的价值了，想想看，不觉得可笑吗？&lt;/p&gt;
&lt;p&gt;去中心化是个挺好的思想，甚至区块链本身，但数字货币不是。如今很多各种各样的项目都想和数字货币和/或区块链扯一腿，但实际情况是，若项目本身是个好项目，那它即便不和区块链扯一块儿，它也会是个好项目。torrent 我觉得是个很好的例子，种子对应的资源本身是核心，若资源本身重要，参与者共同维护的就是资源本身。区块链技术不可篡改的当然是参与者（挖矿者）共同维护的区块链本身，而显然大家都不是冲着这个区块链本身去中心化的“对所有人透明且不可篡改”的特性去的，而是冲着钱，于是一切就成了围绕着钱产生的闹剧了。&lt;/p&gt;
&lt;p&gt;惯例，2021年5月15日19点04分。&lt;/p&gt;
&lt;h3 id="dlc-nft-是什么垃圾"&gt;DLC: NFT 是什么垃圾&lt;/h3&gt;
&lt;p&gt;没想到还是会来更新这篇文章，是因为发现区块链技术拉了新的屎 —— NFT。所谓非同质化代币称呼自己是作为艺术作品的唯一凭证的存在，但实际仍然是围绕其可交易的特性为中心存在的。&lt;/p&gt;
&lt;p&gt;把一个彩虹猫搬上 NFT 可以卖上数十万美元，其实之前看到把一张几近白纸的作品在现实中拍卖上千万的价格的消息我都觉得不奇怪（甚至连消息的真实性都懒得验证），但艺术收藏这种事情，为什么也要和区块链掺和一脚？你若是艺术作品，那么它的价值固然在于作品自身（人们对于艺术作品本身的认可），所谓 NFT 只是为所谓区块链技术带来了又一个新的资本狂欢的方式，它真的能为所谓艺术带来什么吗？&lt;/p&gt;
&lt;p&gt;发行一个新的 NFT 无异于发行了数量和最小交易单位仅为 1 的一种新区块链数字货币代币。抛开区块链本身属性导致它必然会对自然环境的破坏外，这种所谓对“艺术作品”的创新甚至无法验证上传作品的人原本就是作品著作权人亦或是合法持有人。你的艺术创作&lt;a href="https://twitter.com/silverfox5213/status/1453185116608421895"&gt;可能被别人恶意发行&lt;/a&gt;并拍出高价而你却因为区块链的匿名性更加难以维权，这也算是对艺术作品的革新吗？&lt;/p&gt;
&lt;p&gt;哦，我好像忘记提到了，如果你购买了一个 NFT，那么你买到的其实是一个存储于区块链上的元信息，表示你拥有了某个艺术作品，你并没有真的“拥有”这个作品，而只是买了一个“拥有凭证”！而这个元信息中指向你所买的艺术作品的“链接”&lt;a href="https://www.theverge.com/2021/3/25/22349242/nft-metadata-explained-art-crypto-urls-links-ipfs"&gt;可能还会是 404&lt;/a&gt;！假设你破费高价购买艺术作品，得到的却只是对一个不存在的页面的所有权凭证，再加上原本描述的作品是被第三方恶意上传的话，你就有了一个在区块链上永远存在的耻辱了，对吧？&lt;/p&gt;
&lt;p&gt;但其实，让我们抛开上面的所有问题，我觉得让艺术作品在最初属性上就变成一种商品，本身就是对艺术的一种亵渎。艺术创作本就不应该直接变成资本的狂欢，艺术家进行真正的艺术创作的目的本身也就不应是变着法的“造钱”，故 NFT 从各种方面而言我觉得都是又一由区块链创造的可悲发明了。当然，我觉得 NFT 风头过后，再过不久就会有新的基于区块链的又一轮资本狂欢诞生了，但我们又能做点什么呢？&lt;/p&gt;
&lt;p&gt;那就让我们来欣赏一下都有哪些艺术作品 NFT 吧！&lt;a href="https://www.refinery29.com/en-us/2021/03/10378154/nft-non-fungible-tokens-fart-recording-sale-alex-ramirez-mallis"&gt;价值 86 美元的艺术作品会是什么呢？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最后惯例：2021年11月1日01点05分。&lt;/p&gt;
&lt;h3 id="dlc-nft-是什么垃圾---session-2"&gt;DLC: NFT 是什么垃圾 - Session 2&lt;/h3&gt;
&lt;p&gt;另外，我写前面第一段“DLC”时其实对 NFT 了解并不算多，而浪费了人生中宝贵的半小时草草看了所谓 NFT 的合约 API 文档（即 &lt;a href="https://docs.openzeppelin.com/contracts/2.x/api/token/erc721"&gt;ERC721&lt;/a&gt;，对应 &lt;a href="https://eips.ethereum.org/EIPS/eip-721"&gt;EIP-721&lt;/a&gt;），才发现我之前不仅没猜错它的工作方式，而包括&lt;a href="https://ethereum.org/en/nft/"&gt;其官网页面&lt;/a&gt;的描述在内都在误导 NFT 所能发挥的实际作用。称之“You can easily prove you&amp;rsquo;re the creator.” 但实际你所能证明的是你是这个 NFT 的创建者，而不是你是某个艺术作品的创建者。官网在对比 NFT 与传统网络载体也采用了这种混淆视听的方式，试图将 NFT 与艺术作品直接进行对比，而作为代币和艺术作品进行比较本身则是及其可笑的偷换概念。&lt;/p&gt;</description></item><item><title>关于《菠萝看图》的杂话</title><link>https://www.blumia.net/post/2021-01-03-ppic/</link><pubDate>Sun, 03 Jan 2021 22:35:00 +0000</pubDate><guid>https://www.blumia.net/post/2021-01-03-ppic/</guid><description>&lt;p&gt;每天打开 GitHub 看首页动态的习惯保持到了现在，突然有一天就注意到了我之前写给自己用的那个看图软件（&lt;a href="https://github.com/BLumia/pineapple-pictures"&gt;菠萝看图&lt;/a&gt;）连续有了多个 Star，就好奇看了下 Traffic，然后发现竟然有一些网站收录了我的这个软件。于是后续的一段时间就开始偶尔也关注下（GitHub repo 访问的） Traffic，然后发现了一些蛮有趣的事情。其实，我把我这个软件发布出去到现在这个过程都蛮有意思的，于是这篇文章就正好记录下关于我为什么写这个东西出来，以及都有哪些有意思的事情。&lt;/p&gt;</description></item><item><title>ballance 自制关卡《迈出这一步》开发日志</title><link>https://www.blumia.net/post/2020-09-13-take-the-leap-devlog/</link><pubDate>Sun, 13 Sep 2020 15:29:00 +0000</pubDate><guid>https://www.blumia.net/post/2020-09-13-take-the-leap-devlog/</guid><description>&lt;p&gt;曾经在熊孩子群内立 flag 说如果爷爷们能研究出纯 blender 制图的方法的话我就做图，于是来交作业了。自然，这是一个使用 blender 而未使用 3ds max 的自制关卡，拜 yyc12345 的制图工具链所赐，制图的门槛已经降低到我这种只会拉方块的人都可以做的程度了，于是无论是从减少一个来自自动桌子的盗版软件的角度来讲，还是从学习新东西的角度来讲，还是从方便程度来讲，我都鼓励大家尝试一下使用 yyc12345 的这套工具来制图，无论之前有没有经验。&lt;/p&gt;
&lt;p&gt;我的这个关卡的整个制图流程很简单，在草稿纸上进行关卡的设计后，就开始使用由 yyc12345 修改过的 Jxpxxzj 的路面设计工具（下简作“鸡哥编辑器”）进行大致路面的设计，完毕后导出 &lt;code&gt;.py&lt;/code&gt; 脚本后，复制并打开 Ballance 制图的 blend 模板文件，然后在其中执行上述脚本来生成路面。此后则在 blender 内进行实际关卡结构的处理，放置机关，按照 yyc12345 所给定的命名规范对物体进行命名（供后续自动归组使用），然后导出为 yyc12345 所设计的 &lt;code&gt;.bm&lt;/code&gt; 格式。最后则打开安装过 yyc12345 的 bm 插件的 virtools，从插件所提供的菜单中导入 bm 文件，依次选择修复贴图，自动归组，添加影子，然后右键 Level 保存为 nmo 文件，就得到可以放到游戏里玩的关卡文件了，接下来的就是不断的完善，调整，直到满意。尽管实际过程也有一些值得注意的细节，但这篇文章就不再详细描述了。这篇并不是制图教程文章，如果贴吧或者社区对此确实很感兴趣的话，随后也可以单独写篇使用 blender + yyc工具链制图的教程。&lt;/p&gt;
&lt;p&gt;当然，比较有意思的是，在首个小节的设计完成后，由于游玩体验并不佳以及一些错误的操作导致调整关卡本身变得较为困难，故后续打算对这一小节完全推翻重做。但由于鸡哥编辑器体验过差（虽然不能怪鸡哥），故我拿 Godot Engine 写了个简单的编辑器来进行草稿设计，完毕后可以导出鸡哥编辑器所支持的 bme 格式，然后在鸡哥编辑器内导入，再导出为 &lt;code&gt;.py&lt;/code&gt; 脚本供 blender 使用。这个小工具的完成度并不高，但鉴于目的只是辅助我自己完成这个关卡的设计，所以还是够我用的。这个工具的可以在&lt;a href="https://github.com/BLumia/naive-ballance-map-editor/releases"&gt;这里&lt;/a&gt;下载，也可以在&lt;a href="https://github.com/BLumia/naive-ballance-map-editor"&gt;这里&lt;/a&gt;获取到源码。如果你觉得这个小工具也有可能发挥其它的作用，也欢迎折腾下看看:)&lt;/p&gt;
&lt;p&gt;除了 yyc 的制图工具链之外，这里也要感谢帮助进行 playtest 的 yyc 本体，chris241097 和 617274873，也感谢 chris241097 额外帮忙处理了柱子的问题。不过由于帮助测试的人很少，因而 playtest 可能做的仍不够充分，所以如果有体验不好的地方，也请通过任何途径让我知道。接下来的内容也会是讲关于关卡的设计想法相关的内容，你也可以通过下面的内容来对比是否和你的游玩过程一致，并且如果乐意的话，把不一致的地方和你的想法分享给我。我会非常高兴与你讨论这相关的内容。当然，如果你还没玩过此关卡，建议你停止阅读，若你打算游玩，则在游玩前阅读下面的内容会毁掉你的游玩体验。&lt;/p&gt;</description></item><item><title>红米路由器 AC2100 刷入 Breed + OpenWrt / Padavan 过程记录</title><link>https://www.blumia.net/post/2020-08-02-rm2100-breed-openwrt-padavan/</link><pubDate>Sun, 02 Aug 2020 17:19:27 +0000</pubDate><guid>https://www.blumia.net/post/2020-08-02-rm2100-breed-openwrt-padavan/</guid><description>&lt;h3 id="杂话"&gt;杂话&lt;/h3&gt;
&lt;p&gt;我自己其实有过很久的时间想研究一下路由器怎么刷机跑自己服务了，因为自己的企鹅云快到期了而自己还需要一些比如 git 托管，私有网盘以及&lt;a href="https://github.com/BLumia/Private-Cloud-Music/"&gt;私有云音乐&lt;/a&gt;之类的服务要用，之前并没有折腾过这些东西所以完全不了解于是就想找个机会了解下，但由于不是刚需所以就一直拖着没动了。前不久换工作后，由于工作有做弱网测试需求的缘故需要折腾公司的某个斐讯路由器刷机，于是大战了一天的 openwrt 构建&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;，也熟悉了一下相关的一些东西，但其实还是没了解太多。后来和家里联系的过程了解到家里的路由器的断线变得愈加频繁，于是家里计划买个路由器，想了下索性我买得了，就开始打算买个能刷的路由器玩玩看。&lt;/p&gt;
&lt;p&gt;因为其实对硬件行情本身不是特别感兴趣，所以还是去问了对这方面异常关注的特技狼童鞋。那边推荐的型号是小米的 &lt;strong&gt;红米路由器 AC2100&lt;/strong&gt; 型号 ，理由是价格不贵，能刷，并且性能相对也说得过去。想了一下就它了，于是买了两个相同型号的路由器，一个寄到家一个寄到我这儿，就总算有东西能折腾了。因为确实不是刚需，所以东西到手后也没有立即开始折腾的欲望，而是拖到了现在，于是本篇目的就是大致记录下步骤，以备后续查阅。&lt;/p&gt;
&lt;h3 id="步骤"&gt;步骤&lt;/h3&gt;
&lt;p&gt;不提国内乱七八糟论坛和视频教程里不明就里的步骤和操作，其实 &lt;a href="https://openwrt.org/toh/xiaomi/xiaomi_redmi_router_ac2100"&gt;OpenWrt 官网上的 Xiaomi Redmi Router AC2100 硬件信息页面&lt;/a&gt; 页面就非常完整的介绍了整个过程实际要做的事情以及原因了，于是大致步骤也是按那个步骤来的。我的操作环境是我的 KDE/Archlinux 中，而绝大多数步骤基本和官网没有任何出入，只需要照做就行了。如果你还没有看过 openwrt 官网的步骤描述，建议先过一遍在看下面的内容，下面也只概述大致步骤以及实际的意义。&lt;/p&gt;



 &lt;blockquote&gt;
 &lt;p&gt;2023/10/03：下面的步骤其实是早期网上还没发现有存在路由器后台漏洞时，而选择利用 PPPoE 漏洞的方案（对应 OpenWrt 官网 &lt;code&gt;Method B: Python Exploit&lt;/code&gt; 部分）。现在选择利用路由器后台漏洞的操作方式更省事，因而更推荐选择此方案而非下面博客里所写的方案，可参见 OpenWrt 官网中 &lt;code&gt;Method A: Web Exploit&lt;/code&gt; 部分。现在网上的各种教程也都是在写这种方案的操作步骤了。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;首先准备环境，pacman 直装了 &lt;code&gt;python-scapy&lt;/code&gt; 和 &lt;code&gt;openbsd-netcat&lt;/code&gt; 之类的包，把步骤提及的 python 脚本也保存好备用，然后获取了列举的两个固件，mipsel 的 busybox 二进制文件以及 breed bootloader 固件，就可以准备开搞了。当然两个脚本写到的网络接口名称还是得改的，我的是 &lt;code&gt;enp8s0&lt;/code&gt;，看实际情况改就是了。&lt;/p&gt;
&lt;p&gt;步骤和官网的也基本没有出入，首先在 KDE 的网络设置里新建了个配置，填好 IP，然后两根网线一根环接 WAN 和 LAN1，另一根 LAN2 和电脑连接，然后连接刚刚配置好的网络，路由器通电开机，等一小会儿本机 &lt;code&gt;ping&lt;/code&gt; 得通路由器了，就可以正式开工了。&lt;/p&gt;
&lt;p&gt;由于是 PPPoE 漏洞利用，所以我们要做的事情就是启动 &lt;code&gt;pppoe-simulator.py&lt;/code&gt; 脚本以及 &lt;code&gt;netcat -nvlp 31337&lt;/code&gt; 开启监听，然后在希望利用时运行 &lt;code&gt;cve.py&lt;/code&gt; 来利用漏洞以在 netcat 监听处获得一个反弹的 shell，用来把要刷的东西写进去之类。但由于利用后的反弹 shell 很不稳定，会在几秒内就断开，为了获得一个稳定的环境，我们做的事情就是在这个短暂的 shell 期间把我们准备好的 busybox 丢进去，然后用它启动一个 &lt;code&gt;telnetd&lt;/code&gt; 来供我们后续稳定的连接。&lt;/p&gt;</description></item><item><title>在 Windows 10 上手动部署 KDE Craft CI 测试环境</title><link>https://www.blumia.net/post/2020-07-31-setting-up-kde-craft-ci-environment-manually-under-windows/</link><pubDate>Fri, 31 Jul 2020 20:09:52 +0000</pubDate><guid>https://www.blumia.net/post/2020-07-31-setting-up-kde-craft-ci-environment-manually-under-windows/</guid><description>&lt;p&gt;KDE Craft 官方 Wiki 写的还是比较简陋的，没有太深入去研究，所以下面的一部分内容可能不准确或者有误，若发现任何问题还请联系我更正，非常感谢！&lt;/p&gt;
&lt;p&gt;若是希望在自己的 Windows 上使用 KDE Craft 环境进行构建，推荐的还是走官方提供的方式进行安装，虽然国内安装由于显而易见的网络缘故可能会比较蛋疼。本篇尽管也是在 Windows 10 上安装和使用 KDE Craft，但我们这里的目的是能够在 CI 上部署 Craft 来进行自动构建，本文的目标则是在和 CI 玩乒乓之前把路走通，所以尽管本文是在描述如何在 Windows 10 上手动安装 craft ，但所使用的为适用于 CI 的步骤，实际得到的结果和直接使用官方步骤进行安装是有差异的。&lt;/p&gt;
&lt;h3 id="前置知识"&gt;前置知识&lt;/h3&gt;
&lt;p&gt;读这篇文章的话你可能已经知道了 KDE Craft 是一个很近似 emerge 的元构建系统加包管理工具（不知道的话你很可能没必要继续读下去了，或者也可以&lt;a href="https://community.kde.org/Craft"&gt;去了解一下&lt;/a&gt;看看是不是确实有兴趣），它会帮助获取依赖并帮助进行构建。工具名称为 &lt;code&gt;craft&lt;/code&gt;，大致提供的命令行用法是这样的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;craft packagename &lt;span style="color:#75715e"&gt;# 安装 packagename 包（仓库内存在二进制将直接获取二进制并安装，否则自动获取源码进行编译）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对，这里不写别的用法（下面再说..），因为整个环境的安装过程基本就是在用这个。例如安装（或者更新） craft 自身的方式就是执行 &lt;code&gt;craft craft&lt;/code&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;当然，在还没有 craft 环境时，我们没有 &lt;code&gt;craft&lt;/code&gt; 命令，下面会写实际的步骤。&lt;/p&gt;
&lt;h3 id="准备工作"&gt;准备工作&lt;/h3&gt;
&lt;h4 id="必要的软件"&gt;必要的软件&lt;/h4&gt;
&lt;p&gt;我们需要事先准备一些东西。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CraftMaster 初始仓库（ &lt;a href="https://invent.kde.org/packaging/craftmaster"&gt;https://invent.kde.org/packaging/craftmaster&lt;/a&gt; ）&lt;/li&gt;
&lt;li&gt;Python &amp;gt;= 3.6&lt;/li&gt;
&lt;li&gt;MSYS2&lt;/li&gt;
&lt;li&gt;PowerShell&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面提到的 MSYS2 可能是可选的，但我的环境本身就有 MSYS2 所以直接使用了我环境中的 MSYS2，并没有尝试如果不主动配置的话会不会在部署过程中下载。以及在我的尝试中，我使用 Windows 商店提供的 Python 时遇到了问题，于是后续从官网获取安装了 Python 并修改配置使其使用了我另外安装的 Python。另外整个过程基本全程是在 PowerShell 操作的，所以需要找个舒服的终端模拟器来用 PowerShell，系统自带版本即可，不过注意官方不建议使用 PowerShell ISE。&lt;/p&gt;</description></item><item><title>中兴 ZXV10 B860A v1.1 废物利用记录</title><link>https://www.blumia.net/post/2020-04-05-zte-zxv10-b860a-v1-1/</link><pubDate>Sun, 05 Apr 2020 20:39:00 +0000</pubDate><guid>https://www.blumia.net/post/2020-04-05-zte-zxv10-b860a-v1-1/</guid><description>&lt;p&gt;&lt;del&gt;用&lt;a href="https://pikuniku.net/"&gt;免费的钱&lt;/a&gt;收&lt;/del&gt;到手了些废弃的中兴的电信 OEM 的 IPTV 电视盒子，以废物利用的目的折腾了一下换上了第三方的桌面以安装应用并进行使用，实际上早些时候折腾过一次了但过程几乎完全忘记了，这次又要折腾一次，于是下面记录一下过程以免再有下回又忘记怎么折腾，也看看能不能节省一下搜到这篇文章的人的宝贵生命（&lt;/p&gt;
&lt;h2 id="概要步骤"&gt;概要步骤&lt;/h2&gt;
&lt;p&gt;其实大致目的就是替换自带启动器为第三方 Launcher 并安装第三方应用商店，以便直接通过电视盒子安装应用。大致步骤则就是通过 TTL 串口调试访问终端，手动把对应 apk 拷贝到盒子里，然后启动第三方的 Launcher 就行了。&lt;/p&gt;
&lt;p&gt;这么做的原因是没法随便 ADB，尽管有检索到网上有说可以免拆机直接解除 ADB 限制的方式来搞，但都需要 STB 现场调试工具和算号器之类的软件，由于一方面几乎都需要xx论坛注册账号登录才能下载，另一方面这些工具的安全性未知，鬼知道会不会有人动手脚，所以保险起见还是选了拆机的这种途径。&lt;/p&gt;
&lt;h2 id="工具和软件"&gt;工具和软件&lt;/h2&gt;
&lt;p&gt;头一次折腾的时候买过个 USB 转 TTL 的线，按&lt;a href="https://www.cnblogs.com/airoot/p/5907478.html"&gt;网上的说法，中兴必须使用“CH340G”模块的型号&lt;/a&gt;，我买的是&lt;a href="https://detail.tmall.com/item.htm?id=544809971237"&gt;这个&lt;/a&gt;。按照一些网站的说法，还需要安装驱动才能用，但目前在我的两台运行 Windows 10 的设备上尝试均不需要手动额外安装驱动程序就可以使用。当然，那个店也有提供驱动下载，或许在早期的系统还是需要的。&lt;/p&gt;
&lt;p&gt;我配合连接所用的工具是 putty，我的操作平台是 Windows 10 不过这个应用也有 Linux 的移植版可用。&lt;/p&gt;
&lt;p&gt;另外需要备一个 U 盘来存放待装的软件，我随便找了个读卡器插了个内存卡来用，这个无所谓，盒子认就行。&lt;/p&gt;
&lt;p&gt;用于电视盒子的第三方 Launcher 和市场均为当贝的产品，&lt;a href="http://www.dangbei.com/zhuomian/"&gt;当贝桌面&lt;/a&gt; 和 &lt;a href="http://www.dangbei.com/"&gt;当贝市场&lt;/a&gt;。因为不知道有什么合适的干净一些的替代。目标盒子的 Android 版本太低了，大致搜了一下也没搜到可能合适的替代软件，所以还是选了这两个。&lt;/p&gt;
&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;
&lt;h3 id="拆机并连接-usb-转-ttl-线"&gt;拆机并连接 USB 转 TTL 线&lt;/h3&gt;
&lt;p&gt;拆是挺好拆，背面标了螺丝钉标记的两个防滑垫下面就是螺丝钉了，拧开后顺缝撬开就行。&lt;/p&gt;
&lt;p&gt;之所以写这篇备忘的目的是拆开后发现和网上搜到的声称同型号的盒子拆机图都不一样，于是搞不清楚引脚顺序，于是下面是顺序和连接方式：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blumia.github.io/media/zxc10-b860a-v1-1.jpg" alt="拆机主板概览"&gt;&lt;/p&gt;
&lt;p&gt;实际插法是我试错试出来的，后来才发现其实 PCB 板上就标了引脚号，可以看到 GND 针脚下面写了 2，上面的针脚上也有个 1。于是如果你手上拆机后和网上的以及我的都不一样的话，可以在 PCB 板上找一下有没有编号，然后按 2-GND，5-TXD，6-RXD 连接自己手上的 TTL 转 USB 线。&lt;/p&gt;</description></item><item><title>隐藏的小宝石：QStringIterator</title><link>https://www.blumia.net/post/2020-03-27-a-little-hidden-gem-qstringiterator-zh-cn/</link><pubDate>Fri, 27 Mar 2020 15:52:00 +0000</pubDate><guid>https://www.blumia.net/post/2020-03-27-a-little-hidden-gem-qstringiterator-zh-cn/</guid><description>&lt;p&gt;本文译自：&lt;a href="https://www.kdab.com/a-little-hidden-gem-qstringiterator/"&gt;A little hidden gem: QStringIterator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;几天前，我在 KDAB 的一个同事，也是本文的作者之一 Marc Mutz ，发现了 Qt 源代码中有这样一段很有趣（&lt;a href="https://doc.qt.io/qt-5/qstring.html#isUpper"&gt;文档&lt;/a&gt;）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; Returns \c true if the string only contains uppercase letters,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; otherwise returns \c false.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; QString&lt;span style="color:#f92672"&gt;::&lt;/span&gt;isUpper() &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (isEmpty())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; QChar &lt;span style="color:#f92672"&gt;*&lt;/span&gt;d &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, max &lt;span style="color:#f92672"&gt;=&lt;/span&gt; size(); i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; max; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;d[i].isUpper())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; false;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; true;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;抛开它把空字符串认为其 &lt;strong&gt;不是&lt;/strong&gt; 大写的这个还是很容易处理的问题不谈，这部分代码中的循环看上去好像没什么毛病。我们如何就像上述代码中注释文档所提到的那样，判断一个字符串是只包含大写字符呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;逐字符的遍历字符串；&lt;/li&gt;
&lt;li&gt;看到非大写的字符，那这个字符串就不是大写的；&lt;/li&gt;
&lt;li&gt;否则，它就是大写的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这完全就是上面那段代码所做的事情了，对吧？&lt;/p&gt;
&lt;p&gt;然而并非如此。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这段代码它是有缺陷的。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>原来JS是这样的 (4)</title><link>https://www.blumia.net/post/2019-11-17-thats-javascript-4/</link><pubDate>Sun, 17 Nov 2019 16:13:17 +0000</pubDate><guid>https://www.blumia.net/post/2019-11-17-thats-javascript-4/</guid><description>&lt;p&gt;上一篇提到属性描述符 &lt;code&gt;[[Get]]&lt;/code&gt; 和 &lt;code&gt;[[Put]]&lt;/code&gt; 以及提到了访问描述符 &lt;code&gt;[[Prototype]]&lt;/code&gt;，看它们的特性就会很容易的让人想到经典的面向对象风格体系中对类操作要做的事情，但带一些 introspector 的味道。回想到之前所写来自用的辣鸡&lt;a href="https://github.com/BLumia/Private-Cloud-Music"&gt;私有云音乐&lt;/a&gt;应用中所附带了一个建议的类似 &lt;code&gt;jQuery&lt;/code&gt; 的简易常用功能实现，就用到了简单的 &lt;code&gt;[[Prototype]]&lt;/code&gt; 特性。但我们前几篇都没有详细的提及 js 的原型链相关的内容，本篇就将讨论 js 的 &lt;code&gt;[[Prototype]]&lt;/code&gt; 属性和相关的内容。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;注：ES6 的 Proxy 和 class 的概念不在本篇讨论范围内。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="prototype"&gt;&lt;code&gt;[[Prototype]]&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;JavaScript 中的特殊对象属性除了 &lt;code&gt;[[Get]]&lt;/code&gt; 和 &lt;code&gt;[[Put]]&lt;/code&gt; 外，还有一个很重要的特殊内置属性就是 &lt;code&gt;[[Prototype]]&lt;/code&gt; 了。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[[Prototype]]&lt;/code&gt; 是一个&lt;strong&gt;几乎&lt;/strong&gt;所有对象在创建时都会被赋予一个非空值的属性，还记得在之前提到 &lt;code&gt;new&lt;/code&gt; 操作符的行为吗？其中的行为之一就是把其 &lt;code&gt;[[Prototype]]&lt;/code&gt; 关联指向到对应的内置对象上。&lt;strong&gt;通常&lt;/strong&gt; &lt;code&gt;[[Prototype]]&lt;/code&gt; 所指向的即为创建此对象时所使用的对象了。&lt;/p&gt;
&lt;p&gt;来看下面一个例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;macat&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;codingcat&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;macat&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 和 macat 指向的内容相同
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;codingcat&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;macat&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pineapple&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;create&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;macat&lt;/span&gt; ); &lt;span style="color:#75715e"&gt;// 新对象，但其 [[Prototype]] 链向 macat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;pineapple&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 新对象的属性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;macat&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;codingcat&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;pineapple&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 4;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上例中， 变量 &lt;code&gt;codingcat&lt;/code&gt; 显然是指向和 &lt;code&gt;macat&lt;/code&gt; 相同的内容，实质完全一致，而 &lt;code&gt;pineapple&lt;/code&gt; 则是通过 &lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create"&gt;&lt;code&gt;Object.create()&lt;/code&gt;&lt;/a&gt; 创建的变量。显然 &lt;code&gt;pineapple&lt;/code&gt; 和 &lt;code&gt;macat&lt;/code&gt; 是不同的两个对象。不过我们会发现我们依然可以通过 &lt;code&gt;pineapple.d&lt;/code&gt; 访问 &lt;code&gt;macat.d&lt;/code&gt; 的值，这就是因为在 &lt;code&gt;Object.create()&lt;/code&gt; 中，会把 &lt;code&gt;pineapple&lt;/code&gt; 的 &lt;code&gt;[[Prototype]]&lt;/code&gt; 指向我们的原型对象 &lt;code&gt;macat&lt;/code&gt; 了。&lt;/p&gt;</description></item><item><title>原来JS是这样的 (3)</title><link>https://www.blumia.net/post/2019-09-08-thats-javascript-3/</link><pubDate>Sun, 08 Sep 2019 20:18:17 +0000</pubDate><guid>https://www.blumia.net/post/2019-09-08-thats-javascript-3/</guid><description>&lt;h2 id="引子"&gt;引子&lt;/h2&gt;
&lt;p&gt;在上一篇（原来JS是这样的 (2)）刚发布的时候就阅读了那篇文章的人可能会注意到那篇曾用过“JavaScript 中万物皆对象”的说法，而在随后我发现错误后立即更新改掉了这个错误的说法。另外上一篇实质上整篇都在描述 &lt;code&gt;this&lt;/code&gt; 到底在什么情况下会绑定到哪个对象上，看上去 JavaScript 中的对象概念的确很容易让人困惑。再看下面一个例子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strPrimitive&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;I&amp;#39;m mamacat&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strPrimitive&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strPrimitive&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; String; &lt;span style="color:#75715e"&gt;// false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strObject&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; String(&lt;span style="color:#e6db74"&gt;&amp;#34;I&amp;#39;m mamacat&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strObject&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// &amp;#34;object&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strObject&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; String; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;strPrimitive&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;substr&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// &amp;#34;cat&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同样的字符串赋值到对象，一会儿是字符串类型一会儿是对象，而明明不是对象类型的变量还是可以使用对象属性，为什么会这样呢？&lt;/p&gt;
&lt;h2 id="类型和内置对象"&gt;类型和内置对象&lt;/h2&gt;
&lt;p&gt;JavaScript 中一共有六种主要（语言）类型，即 &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt; 和 &lt;code&gt;object&lt;/code&gt;，其中前五个基本类型都不是对象（对 &lt;code&gt;null&lt;/code&gt; 进行 typeof 得到的是 &amp;ldquo;object&amp;rdquo;，这是语言本身的 BUG）。而在此之外，则有许多特殊的对象子类型，例如数组、函数和内置对象等。&lt;/p&gt;
&lt;p&gt;有些内置对象的名字看着和简单基本类型一样，就比如 &lt;code&gt;String&lt;/code&gt;，&lt;code&gt;Boolean&lt;/code&gt;，&lt;code&gt;Object&lt;/code&gt; 之类。这些内置对象从表现形式看就和别的面向对象语言中的“类”概念差不多，而正如上篇文章所属，它们实际使只是一些能被用来构造一个对应子类型的内置函数而已（不要困惑，函数也是对象，这里并不矛盾）。于是就可以回到最初的例子，&lt;code&gt;strObject&lt;/code&gt; 是由内置函数/内置对象 &lt;code&gt;String&lt;/code&gt; 所构造的变量，对应 &lt;code&gt;String&lt;/code&gt; 子类型，所以它是一个对象，而 &lt;code&gt;strPrimitive&lt;/code&gt; 则是一个原始字面值而已。&lt;/p&gt;
&lt;p&gt;当然，上面例子中最下面我们看上去对 &lt;code&gt;strPrimitive&lt;/code&gt; 调用了 &lt;code&gt;substr()&lt;/code&gt; 函数，这里则是因为，JavaScript 引擎会在需要时，把原始字面量转换成对应的对象，而转换之后我们自然就可以使用属性访问对应的方法了。&lt;/p&gt;
&lt;h2 id="对象属性"&gt;对象属性&lt;/h2&gt;
&lt;p&gt;那么，就上方的例子而言，&lt;code&gt;String&lt;/code&gt; 对象实例就会有 &lt;code&gt;substr()&lt;/code&gt; 函数可以用，但根据之前的文章可以知道，这些“函数”本身并不属于某个对象，而这些函数实质是对应对象的一个属性。当然，即便我们说某种类型的对象本身具备各种属性，实际上这些属性也多是各自独立存在的，只不过以引用的形式关联在了一起而已，这和之前了解的内容也并不矛盾。这些被关联起来的东西，被称为对象的 &lt;strong&gt;属性&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="对象的复制"&gt;对象的复制&lt;/h3&gt;
&lt;p&gt;插播一条快报，尽管之前的文章提到过，上方也又一次反复强调过属性只是以引用的形式关联起来的独立存在，我们有时仍然会“理所应当”的认为属性是对象的一部分，而最容易因此踩坑的地方之一就是对象的复制了。仔细思考即可知道，当我们复制对象时，由于其属性本身只是引用关联，故“复制”得到的对象所包含的属性引用指向的和原本对象的属性引用其实还是同一个位置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ori&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ori_copy&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ori&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ori&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;61&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ori_copy&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 61
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;显然这很可能和我们的期望不一样，而我们想要真正的拷贝对象则没有完美适用性的方案，很多时候的常规做法则是把对象序列化一下，然后再以此反序列化得到新的对象来实现对象的拷贝（比如使用 json）。ES6 中新增了 &lt;code&gt;Object.assign()&lt;/code&gt; 来进行对象的浅拷贝，做法是把对象的所有可枚举属性等号赋值到新对象中。不过仍需注意的是，等号赋值并不会赋值属性的元信息（属性描述符，后述），在需要的情况下应当特别留意。&lt;/p&gt;</description></item><item><title>马里奥制造2 - 亚玛姆拉道馆 - 笔记</title><link>https://www.blumia.net/post/2019-06-30-mario-maker-2-yamamura-note/</link><pubDate>Sun, 30 Jun 2019 17:16:46 +0000</pubDate><guid>https://www.blumia.net/post/2019-06-30-mario-maker-2-yamamura-note/</guid><description>&lt;p&gt;这里的笔记是马里奥制造2，亚玛姆拉道馆的“创作关卡的诀窍”部分。由于初级是在讲游戏本身的玩法，中级也是非常常规的点，所以这里只记了 “高级” 部分，用 &lt;code&gt;III&lt;/code&gt; 表示，以后可能也会补充几个初级或中级提到的比较值得记录的条目。&lt;/p&gt;
&lt;p&gt;注：并非所有条目都适用于任何类型的游戏设计，也并非所有条目都是需要特别注意的亮点。这里存粹仅供记录。&lt;/p&gt;
&lt;h2 id="iii-1-一开始试着随意创作吧"&gt;III-1: 一开始试着随意创作吧&lt;/h2&gt;
&lt;p&gt;对于创作关卡束手无策的人，在尝试关卡制作时，制作的初始就是自由的尝试想到的东西，然后在尝试后不断改进设计，也可以制作不错的关卡。&lt;/p&gt;
&lt;h2 id="iii-2-了解敌人的作用吧"&gt;III-2: 了解敌人的作用吧&lt;/h2&gt;
&lt;p&gt;敌人的作用是阻碍玩家前进，而另一个作用是能让玩家愉快的打败敌人。在放置敌人时考虑玩家能否爽快的打败敌人，也可以造成好的游戏体验（可以配合连击奖励类的机制来使用/设计）。马里奥中的例子包括使用龟壳连续打败一连串敌人，或是巧妙放置敌人使得可以不落地的一次踩踏消灭多个 Goomba（马里奥也有此类连击的分数奖励）。&lt;/p&gt;
&lt;h2 id="iii-3-试着使用终点条件吧"&gt;III-3: 试着使用终点条件吧&lt;/h2&gt;
&lt;p&gt;（注：SMM2 允许设置玩家在达成某个条件的前提下才可以在终点完成关卡）&lt;/p&gt;
&lt;p&gt;不要单纯的为了提高难度而使用终点条件，通过条件限制来引导玩家思考游戏方式是好的做法。同时，应当注意容错。&lt;/p&gt;
&lt;p&gt;（注：收集钥匙开门之类的机制也适用，值得注意的点也就是通过游戏机制本身来引导玩家按照设计进行游戏）&lt;/p&gt;
&lt;h2 id="iii-4-使用墙壁精心制作吧"&gt;III-4: 使用墙壁精心制作吧&lt;/h2&gt;
&lt;p&gt;把关卡设计器作为游戏的一部分呈现给玩家时，应当把设计器做到足够简单易用才能使玩家在制作关卡的过程中也能享受乐趣。&lt;/p&gt;
&lt;p&gt;对于常规的横板平台游戏，摄像头的移动规则会比较复杂，一个简单的需求是视野（摄像机）跟随玩家，但在边界的地方需要保证摄像头不再移动到边界之外。SMM2 的做法是当游戏中放置的墙和砖块等实体能在完整的一列/行填充，则视野不会跑出此边界。这种做法没有额外的引入任何摄像机相关的额外设置，能够简化面向玩家的关卡设计器的操作。&lt;/p&gt;
&lt;h2 id="iii-5-一定得设置为能看到接下来前进的落脚点"&gt;III-5: 一定得设置为能看到接下来前进的落脚点？&lt;/h2&gt;
&lt;p&gt;通过机关设计使得玩家可以自行探索而寻找到前进方向也是可以的，仍需注意是否需要放置用于提示玩家探索方向用的设计元素。&lt;/p&gt;
&lt;h2 id="iii-6-了解敌人出现的原理吧"&gt;III-6: 了解敌人出现的原理吧&lt;/h2&gt;
&lt;p&gt;（注：是在讲敌人会在靠近的时候才会 spawn 并触发移动）&lt;/p&gt;
&lt;p&gt;这条似乎没什么可总结的&amp;hellip;&lt;/p&gt;
&lt;h2 id="iii-7-玩家没有按创作者的想法游玩"&gt;III-7: 玩家没有按创作者的想法游玩&lt;/h2&gt;
&lt;p&gt;玩家的游戏体验方式不一定总是和关卡设计者一致，若真的希望规避设计意图之外的游戏方式，应当多进行测试，但多元化游戏方式的存在并不总是坏事。&lt;/p&gt;
&lt;h2 id="iii-8-让人游玩后就有所了解"&gt;III-8: 让人游玩后就有所了解&lt;/h2&gt;
&lt;p&gt;关卡 QA 阶段，收到负面反馈时应当询问具体是哪些地方难或者无聊或是导致了其它评价，以变后续调整关卡设计。同时也应当询问玩家自己特定的设计意图有没有感受到，感受如何等。如有条件，观看对方的游戏过程也有助于分析关卡设计中可能存在的问题。&lt;/p&gt;
&lt;h2 id="iii-9-花功夫设计为不会令人感觉被突袭"&gt;III-9: 花功夫设计为不会令人感觉被突袭&lt;/h2&gt;
&lt;p&gt;尽管可以设计“意外”来增进游戏趣味性，但通过关卡结构设计来引导玩家猜想“或许会发生什么”是很重要的，这样的“意外”不会给玩家带来负面游戏体验，同时也可以考虑额外的设计来容错，给玩家反应和处理意外留下时间（猫里奥和 i wanna 那种把试错作为游戏体验核心玩法的一部分的显然例外）。另一方面，从玩家的角度看，“可以躲过意外”会使得玩家觉得自己变熟练了，是正向的游戏体验反馈。&lt;/p&gt;
&lt;p&gt;仍需注意，建议规避面向新手的关卡设计中设计“意外”。&lt;/p&gt;
&lt;h2 id="iii-10-试着花功夫反复使用相同零件吧"&gt;III-10: 试着花功夫反复使用相同零件吧&lt;/h2&gt;
&lt;p&gt;反复使用相同设计元素可以给玩家较深的留下对此设计元素机制的印象，此时配合其它设计元素一同使用来体验同一元素的不同作用可以让玩家对游戏机制有更清楚的认识，并且带给玩家游戏操作熟练的感受。&lt;/p&gt;
&lt;h2 id="iii-11-让关卡张弛有度吧"&gt;III-11: 让关卡张弛有度吧&lt;/h2&gt;
&lt;p&gt;毫无理由的放置敌人，并不会变得有趣。在多组不同的小节点（挑战单元）之间的衔接部位，不需要刻意放置敌人，若设计上不希望设置存档点，也可以完全留空而不刻意的放置敌人。&lt;/p&gt;
&lt;h2 id="iii-12-创作可以悠闲操作的关卡吧"&gt;III-12: 创作可以悠闲操作的关卡吧&lt;/h2&gt;
&lt;p&gt;这条似乎没什么可总结的&amp;hellip;&lt;/p&gt;
&lt;h2 id="iii-14-怎么都无法完成关卡时"&gt;III-14: 怎么都无法完成关卡时&amp;hellip;&amp;hellip;&lt;/h2&gt;
&lt;p&gt;（注：这条应该是衔接 III-1 的，“随意创作”的关卡无法顺利完成时）&lt;/p&gt;
&lt;p&gt;应当考虑一个游戏阶段中出现的机关或敌人中的“主角”，在此基础上，尽量不要使用大量非主角的敌人和机关（否则会造成无意义的难度提升）。可以在设计关卡前自行划定关卡所需要涉及的游戏元素（设定限制）。在关卡设计过程中如果萌生了其它可能有趣的点子，可以记下来以备其它关卡使用，而不是盲目塞到当前的关卡中。&lt;/p&gt;
&lt;h2 id="iii-15-熟练创作关卡的第一要诀是"&gt;III-15: 熟练创作关卡的第一要诀是？&lt;/h2&gt;
&lt;p&gt;这条似乎没什么可总结的&amp;hellip;&lt;/p&gt;</description></item><item><title>我的第一篇正经博客 - 五周年</title><link>https://www.blumia.net/post/2019-06-25-first-blog-5-anniversary/</link><pubDate>Tue, 25 Jun 2019 00:36:00 +0000</pubDate><guid>https://www.blumia.net/post/2019-06-25-first-blog-5-anniversary/</guid><description>&lt;h1 id="我的第一篇正经博客---五周年"&gt;我的第一篇正经博客 - 五周年&lt;/h1&gt;
&lt;p&gt;今天是 19 年 6 月 24 日，是我所谓的意义上的第一篇博客的发布日期的五周年，虽然这怎么看都没有什么纪念意义，但至少能借此机会更新一下我万年不动一下的博客也是挺好的（这都哪跟哪）。于是以下会从那篇博客起记一些乱七八糟的事情，和往常一样，也别指望文章有任何逻辑（&lt;/p&gt;
&lt;p&gt;ps. 正经博客指的是 &lt;a href="https://www.blumia.net/post/2014-06-24-laji-redmi-note-1/"&gt;&amp;ldquo;红米note增强之换货评价等日杂&amp;rdquo;&lt;/a&gt;那篇。&lt;/p&gt;
&lt;h2 id="关于是否排斥小米品牌"&gt;关于是否排斥小米品牌&lt;/h2&gt;
&lt;p&gt;其实但凡完整看过一遍原文就会知道我的确是由于那一次异常糟糕的购物体验而产生了对品牌的畏惧，以至于长久一段时间没再敢接触这个品牌。不过，在群里狂热米粉T的评价下，我还是决定再给小米次机会，后来还是买了两部小米旗下的手机（给家长用），而且截至目前手机看上去也没有再遇到什么质量问题，所以对于我来说，下次选购手机时，或许这个品牌现在的确能够重新作为众多选择中的一个了吧。&lt;/p&gt;
&lt;p&gt;不过一件有趣的事情是，L同学在一次闲聊中告诉我他没有选择小米的原因是“身边的人狂吹小米，让人很不舒服”，于是不得不再想到狂热米粉T的实际情况——做到几乎每天都要称赞小米并否定其它厂商。事实上随着时间推移，米粉言论也从最初的无感变得慢慢的排斥起来。小米在众多手机厂商中做的的确还算是不错的一家，但也算不上是极其优秀到需要每天都拿出来夸的程度。由于L和我抱怨了相同的事情，所以这看上去并非个例。打趣地说，“用小米会使人疯狂”，但我的确不能理解在没有报酬的情况下这么做的缘由。尽管我总是试图去做“不能理解的事情就不要试图理解”，但如果不能理解的事情每天都在身边发生，还是会让我自己怀疑起自己来。&lt;/p&gt;
&lt;p&gt;回到问题本身的话，我大概现在并不排斥这个品牌了（尽管不代表我以后就一定会选择这个品牌），但我大概的确排斥任何品牌的狂热粉的“每日称赞”的行为——至少目前是这么觉得的。&lt;/p&gt;
&lt;h2 id="下一部手机"&gt;下一部手机&lt;/h2&gt;
&lt;p&gt;于是下个品牌会怎么选？其实现在我并不怎么在意。自 iPhone 的第一部刘海屏手机诞生起，各大 Android 手机厂商就开始莫名其妙的跟风做起了各色各样的屏幕缺口风潮。我确实无法理解和接受屏幕缺角的做法（因为除了多出来显示时间和少的可怜的应用图标的位置外，并没有任何好处）。与之近似的还有砍掉 3.5mm 耳机孔的做法，除了不能方便的使用耳机之外还导致了相机突起。这些做法在目前看来怎么看都觉得是为了所谓的创新而做出的毫无缘由的妥协，而我大概的确不会为了这些所谓的特性消费，所以这些厂商的性价比做的再好，这类手机我也不会考虑了。&lt;/p&gt;
&lt;p&gt;当然，选择手机还是有另一个很重要的点要看——能不能刷机。曾经小米有过小米浏览器内置黑名单的问题以及删除指定应用就禁止开机的问题，以及一加也出过上传剪切板的问题。鉴于此大概我是不再敢信任任何国行手机的 ROM 了，所以能够刷机成了目前让我接受某个手机的必要条件之一（尽管我手机里几乎没什么值得看的东西）。尽管我自己目前没有能力去 review 我所使用的开源 ROM （LineageOS）的源码，但至少它有比较大的用户量，会有更多双眼睛能够注视着它，出事的可能也就会更小吧。&lt;/p&gt;
&lt;p&gt;不过说了这么多，我目前的一加到现在也没出什么问题，于是在它出问题的那一天到来之前，我大概是不会换手机了&amp;hellip;吧？&lt;/p&gt;
&lt;h2 id="该听谁的"&gt;该听谁的&lt;/h2&gt;
&lt;p&gt;就上面的内容而言，其实有存在个问题，同一件事，同一个品牌，总是能够见到吹的见到黑的，包括我的各种博客也都通常会传递一个来自我的描述和观点。那么这些说法哪个对哪个错？又该听谁的？&lt;/p&gt;
&lt;p&gt;回顾一下，在我选购我的第一款红米手机前，我就知道有人告诉我屏幕质量问题了，而我选择没有相信而自己去实际尝试。尽管我显然觉得那次购买相当失败，但我依然觉得这样的尝试是对的。毕竟关于这件事，能起到实际担保作用的也就只有我和厂商（售后保障）了。不然还能相信谁呢？意见领袖？高玩？或者是软文？&lt;/p&gt;
&lt;p&gt;于是类比到别的场景也一样如此了，通常在某些地方看到一个观点，我不会立即相信它而是选择自己找找看有没有办法证实一个观点是对的或者错的，最终寻找到一个相对有保障的依靠点来得到结论，以保证自己获得的错误信息尽可能少。&lt;/p&gt;
&lt;p&gt;所以当我一本正经的告诉你一加一等于三的时候，你知道我是错的，而当我讲别的任何你所不熟悉的领域的内容时，抱着质疑的态度总是一个好习惯。&lt;/p&gt;
&lt;h2 id="状态栏的四个图标"&gt;状态栏的四个图标&lt;/h2&gt;
&lt;p&gt;稍微和上面一段能扯上点关系的事情是，我从 Android O 升级到 P 后就发现我没有刘海的手机也只能显示四个通知图标了，最初我怀疑是手机适配问题，故打算研究一下到底是不是适配问题，如果是的话就改改代码然后发个 patch 上去。而一番搜索后发现 reddit 上 nexus 用户抱怨自己的非刘海机也是四个应用图标，且大量新闻也指向了谷歌为了刘海设计而限制状态栏图标数量的设计决定，我也就因此放弃了继续研究。然而米粉T某天告诉我他的手机能够出现超过四个图标，抱着严重怀疑的态度我请求了截图，而截图真的发来后我开始翻看他所用 ROM 的代码，并发现了 &lt;a href="https://github.com/aosp-mirror/platform_frameworks_base/blob/master/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java#L131"&gt;AOSP 真的的确写死了四个图标&lt;/a&gt; 以及 &lt;a href="https://github.com/AospExtended/platform_frameworks_base/commit/95b611d96f548e0bf773c96b2795885a5e158401#diff-51afbc2b58389c1cbda63e2ecbea101a"&gt;T所使用的第三方 ROM 的确有打 patch 允许调整这个值&lt;/a&gt;，于是结论是无论是之前的首次搜索还是米粉T的说法，他们都是对的。&lt;/p&gt;
&lt;p&gt;当然这个例子并不能说明什么“谁是对的”或者“该听谁的”之类的问题，不过这里写这件事存粹是因为这件事发生了。后续是 Chris 告诉我有 RRO 这种东西存在，后来就提供了一个 RRO 给我用，我也摆脱了只能显示四个图标的蛋疼困扰——只不过最终并没有给 LineageOS 提 Patch 解决这个问题，因为太麻烦了。&lt;/p&gt;
&lt;h2 id="自己能有多可靠"&gt;自己能有多可靠？&lt;/h2&gt;
&lt;p&gt;尽管总是尝试自己获取信息来验证自己的观点是我目前希望尽可能参照来做的事情，但但凡遇到我不熟悉的领域，这么做的难度就变得异常的大了起来。比如目前我几乎是个硬件盲的身份的存在——完全不能根据型号反应出产品的好坏，甚至对硬件与其相应型号间的关系没有任何概念，于是若要购买相关的东西——比如台式机或笔记本——我仍需要从“向他人获取推荐”或者“自己重头入门相关信息再做出判断”之间做出选择。最近的一次笔记本电脑的购买我选择了前者，由于我的确没办法在这方面让我自己在短时间内变的可靠。&lt;/p&gt;</description></item><item><title>Qt 终于把我的 patch 合进去了</title><link>https://www.blumia.net/post/2018-11-03-first-patch-merged-into-qtbase/</link><pubDate>Sat, 03 Nov 2018 17:48:00 +0000</pubDate><guid>https://www.blumia.net/post/2018-11-03-first-patch-merged-into-qtbase/</guid><description>&lt;p&gt;这篇是纯水，实际这应该算是我的头一个正经一点的 patch ，合进去当时还挺高兴的，也感觉算是个“里程碑”，尽管这个 patch 并没有啥技术含量。&lt;/p&gt;
&lt;h3 id="起因"&gt;起因&lt;/h3&gt;
&lt;p&gt;前一段时间手头的任务是把深度文管的网络设备管理部分重构掉，由于之前文管做这部分的代码耦合度炒鸡高，而一旦把我重构的部分替换掉现有的部分就会动非常多的代码以至于可能造成成堆的我测不到的 BUG ，正逢即将冻结代码，所以我那部分就只先找了个耦合度不是非常高的地方换了上去，剩下的时间就用来修 bug 以及看看有没有别的可以改善的地方。&lt;/p&gt;
&lt;p&gt;任务列表里有一个一直放着的任务是有一部分 office 文档不能正确显示成“文档”类型，于是第一反应是拿到显示不对的文档然后看 MIME 类型是什么。深度文管的文件类型一列写的几个类型是固定的，&lt;a href="https://github.com/linuxdeepin/dde-file-manager/tree/4.6.10/dde-file-manager-lib/mimetypes"&gt;每一种类型对应一个 MIME 类型列表&lt;/a&gt;，而如果这个列表中找不到这个类型，就会显示成未知类型了。&lt;/p&gt;
&lt;p&gt;要到样本文档然后把对应的 MIME 类型加到列表里之后，我还是觉得哪里不对。查了一下 &lt;a href="http://blogs.msdn.com/vsofficedeveloper/pages/Office-2007-Open-XML-MIME-Types.aspx"&gt;Office 文档的 MIME 类型列表&lt;/a&gt; 后发现明显还有一堆类型是没加进深度文管的列表里去的，但我觉得这样挨个加并不是个办法，于是打开 nautilus 看看它是怎么显示的，于是看到了 nautilus 显示了正确的文件类型文字描述，然后开始蛋疼：它是怎么显示这个东西的，难不成也是个表？&lt;/p&gt;
&lt;p&gt;由于不熟悉于是只能去看文档，后来在文档里发现 &lt;code&gt;QMimeType&lt;/code&gt; 是有一个 &lt;code&gt;comment()&lt;/code&gt; 属性的，把这个值拿出来发现就是 nautilus 所显示的描述文字，于是我就给在 &lt;code&gt;QT_DEBUG&lt;/code&gt; 情况下编译的文管加了个功能 &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; ，显示实际的 MIME comment 而不是查表的结果，照理说这事儿就结束了。&lt;/p&gt;
&lt;p&gt;然后我反应过来一回事，WPS 的文档用了他们自己的 MIME 类型而不是上面所查到的列表的那些类型，那我得先试试 WPS 的这些文档类型能不能正确显示，于是就装了 WPS 并测试，结果发现并不能，显示的结果是 MIME 类型的字符串结果，打开 dolphin 之后发现 dolphin 显示的结果和我一样，于是放心并打开 nautilus 打算验证一下，却发现 nautilus 能够显示正确的描述文字&amp;hellip;&lt;/p&gt;
&lt;p&gt;这下可好，看 qt 的源码吧。&lt;/p&gt;
&lt;h3 id="定位-bug"&gt;定位 bug&lt;/h3&gt;
&lt;p&gt;首先根据文档找到了 &lt;code&gt;/usr/share/mime/packages/&lt;/code&gt; 并查看 WPS 所给的 shared MIME database 文件，发现它并没有给出 &lt;code&gt;xml:lang&lt;/code&gt; 为 &lt;code&gt;zh_CN&lt;/code&gt; 的 comment 值，而是给了一个只包含描述的空属性的 comment 元素。打开 qtbase 的代码后很容易的找到 &lt;a href="https://github.com/qt/qtbase/blob/5.11/src/corelib/mimetypes/qmimetype.cpp#L261"&gt;qmimetype.cpp&lt;/a&gt; ，找到 &lt;code&gt;QMimeType::comment()&lt;/code&gt;，然后发现 comment 内容来自 &lt;code&gt;d-&amp;gt;localeComments&lt;/code&gt; 以及这里只尝试了 &lt;code&gt;QLocal().name()&lt;/code&gt; 和 &lt;code&gt;QLocal().uiLanguage()&lt;/code&gt; 所对应的语言，顺着找到了 &lt;a href="https://github.com/qt/qtbase/blob/5.11/src/corelib/mimetypes/qmimeprovider.cpp#L504"&gt;qmimeprovider.cpp&lt;/a&gt;，发现会把读取的空属性 comment 元素作为 &lt;code&gt;en_US&lt;/code&gt; 的 locale 处理。于是问题找到：我们所用的 locale 是 &lt;code&gt;zh_CN&lt;/code&gt; ，而其并没有对应的 comment 内容，而这里也没有 fallback 措施，故自然找不到了。&lt;/p&gt;</description></item><item><title>原来JS是这样的 (2)</title><link>https://www.blumia.net/post/2018-10-21-thats-javascript-2/</link><pubDate>Sun, 21 Oct 2018 18:54:17 +0000</pubDate><guid>https://www.blumia.net/post/2018-10-21-thats-javascript-2/</guid><description>&lt;h2 id="引子"&gt;引子&lt;/h2&gt;
&lt;p&gt;习惯了别的语言的思维习惯而不专门了解 JavaScript 的语言特性的话，难免踩到一些坑。 [上一篇文章]({% post_url 2017-02-28-Thats-JavaScript-1 %}) 中简单总结了关于 &lt;em&gt;提升&lt;/em&gt;, &lt;em&gt;严格模式&lt;/em&gt;, &lt;em&gt;作用域&lt;/em&gt; 和 &lt;em&gt;闭包&lt;/em&gt; 的几个常见问题，当然这仅仅是了解 JavaScript 的一个开始，这次则依然从另一个大多人都见过但很容易搞错的概念开始了解 JavaScript 的不同之处 —— &lt;code&gt;this&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;首先看这段代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plusOne&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;plusOne get called, this.count: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;plusOne&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;plusOne&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 改成 plusOne.call(plusOne);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;plusOne.count = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plusOne&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;window.count = &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们知道 JavaScript 中 &lt;em&gt;几乎&lt;/em&gt; 所有的东西都是对象，那么很可能会把 &lt;code&gt;this&lt;/code&gt; 自然的理解成当前对象“身上”的属性，对于上面的代码（注意，并非严格模式下），我们为 &lt;code&gt;plusOne&lt;/code&gt; 创建了一个属性 &lt;code&gt;count&lt;/code&gt; 并试图通过在 &lt;code&gt;plusOne()&lt;/code&gt; 中使用 &lt;code&gt;this.count++&lt;/code&gt; 改变它的值。然而如果实际执行这段代码（注：假设是在浏览器 F12 的 Console 中），得到的结果会是这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;plusOne get called, this.count: NaN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;plusOne.count = 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.count = NaN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看出 &lt;code&gt;plusOne()&lt;/code&gt; 中的 &lt;code&gt;this.count&lt;/code&gt; 实际是 &lt;code&gt;NaN&lt;/code&gt;，&lt;code&gt;plusOne.count&lt;/code&gt; 却没有变化，并且 window.count 被创建了。而尝试按照上面代码中的注释那样把 &lt;code&gt;plusOne()&lt;/code&gt; 改成 &lt;code&gt;plusOne.call(plusOne)&lt;/code&gt; ，就会发现结果成了：&lt;/p&gt;</description></item><item><title>开源自由软件 - 你也应当参与进来</title><link>https://www.blumia.net/post/2018-09-26-free-and-open-source-software/</link><pubDate>Wed, 26 Sep 2018 21:58:52 +0000</pubDate><guid>https://www.blumia.net/post/2018-09-26-free-and-open-source-software/</guid><description>&lt;p&gt;想写一篇关于开源生态的文章已经有一段时间了，却一直没写，写这一篇则打算简单谈一下关于自由软件和开源相关的东西，关于是否应当使用，怎样使用，以及其它相关的东西。和往常一样，写这篇的时候也没打什么草稿，就想到啥写啥好了，如果提到的内容有误还请指正，如觉得行文混乱还请责怪我语文学的烂 :)&lt;/p&gt;
&lt;h1 id="给普通用户"&gt;给普通用户&lt;/h1&gt;
&lt;h2 id="自由及开放源代码软件就在你身边"&gt;自由及开放源代码软件——就在你身边&lt;/h2&gt;
&lt;p&gt;可能很多人对计算机相关知识并不熟悉或者并不主动关注从而不了解，但事实上自由软件其实就在你的身边改善着你的生活。或是你使用 Android 操作系统的手机时，或是你使用 Chromium （内核的）浏览器或 Firefox 时。但到底什么是自由软件呢？&lt;/p&gt;
&lt;p&gt;尽管自由软件基金会对 &lt;strong&gt;自由软件&lt;/strong&gt;（Free Software）一词有其定义，但我们暂且先宽泛的讨论 &lt;strong&gt;自由及开放源代码软件&lt;/strong&gt;（Free and open source software），顾名思义，即能够自由使用的开放源代码的软件。如果你不知道“源代码”的含义，就比方你使用的软件是一道名菜，而自由软件则会提供菜谱并允许你自由的使用菜谱来做菜、“调整”、“改善”甚至“创造”你想做的新菜。开放式的“菜谱”给了越来越多“厨子”们做出更好吃的菜肴的可能，自然而然也有越来越多的“食客”也能从中受益，而自由及开放源代码软件也正是如此，甚至非自由软件也会从中受益——例如使用 Qt 作为图形界面库的 WPS Office。&lt;/p&gt;
&lt;h2 id="我应当使用自由软件吗"&gt;我应当使用自由软件吗&lt;/h2&gt;
&lt;p&gt;当有一家很好吃的菜馆免费提供菜谱供食客自由使用时，你会使用那份菜谱吗？尽管真实的答案很可能是“看情况”，但如果条件允许的话，“为什么不试试呢”？&lt;/p&gt;
&lt;p&gt;各行各业各个方面的计算机软件中都或多或少有一些自由及开放源代码软件能够作为替代品或好助手来帮助你完成需要的任务，例如你可能见过使用 &lt;a href="https://krita.org/"&gt;Krita&lt;/a&gt; 或 &lt;a href="https://www.gimp.org/"&gt;GIMP&lt;/a&gt; 的画师，使用 &lt;a href="https://www.blender.org"&gt;Blender&lt;/a&gt; 构建模型的 3D 建模师，使用 &lt;a href="https://musescore.org/"&gt;MuseScore&lt;/a&gt; 打谱的作曲家，使用 pyTorch 或 TensorFlow 炼丹的机器学习工程师等。而事实上，自由/开源软件也并没有什么使用门槛。例如你可以简单的从网上下载 Notepad++ 来代替 Windows 内建的记事本应用，下载 &lt;a href="https://getsharex.com/"&gt;ShareX&lt;/a&gt; 来截图或录制 gif ，下载 &lt;a href="https://kdenlive.org/"&gt;Kdenlive&lt;/a&gt; 来剪辑视频等。无论是新手还是专家，都能让你首先体会到自由/开源软件给你带来的益处。&lt;/p&gt;
&lt;p&gt;尽管你可能会说，Adobe Photoshop 可能比 GIMP 更好用，Autodesk 3DS Max 可能比 Blender 更好用，那我为什么要使用后者呢？事实上，你的确总是应当使用能让你更快的把任务完成的软件，但如果有一个开放且自由的选择摆在你面前，尝试一下何尝不是一个很好的选择呢？&lt;/p&gt;
&lt;h2 id="那么开源自由软件到底有什么好处"&gt;那么开源/自由软件到底有什么好处&lt;/h2&gt;
&lt;p&gt;在前段时间，GOG 发起了一个名为 &lt;a href="https://fckdrm.com/"&gt;FCK DRM&lt;/a&gt; （去你喵的数字版权保护）的倡议活动，告诉广大玩家或用户，在诸多非自由软件中，都包含着各种各样形式的使用版权检查，并在一旦它检查出异常时停止工作——它们有时候还会有异常，例如 Windows 可能在你更换硬件后提醒你你使用的 Windows 不是正版，或是你购买的软件在你不小心误删注册密钥文件后无法继续工作。&lt;/p&gt;
&lt;p&gt;尽管该活动倡议的是 DRM-free（没有版权保护）的软件，但实际上，DRM-free 将使用的自由交给了用户，而自由/开源软件则直接将完全的自由&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;交给了用户，从而缔造了无限的可能。&lt;/p&gt;
&lt;p&gt;开源/自由软件让用户不再需要考虑非自由软件带来的限制，将最大的权力交给了用户，换句话说，即便是用户，除了最基本的自由使用的权力之外，也有了参与进来，一同改善软件本身，让更多人受益的过程中来。&lt;/p&gt;
&lt;h2 id="仅仅是使用就能让更多人受益吗"&gt;仅仅是使用就能让更多人受益吗&lt;/h2&gt;
&lt;p&gt;并不是所有的人都懂编程而能够直接的参与到软件的打造过程中，但所有人都能以各种形式参与到开源/自由软件的生态构建中来。开源软件生态并非有人开发软件有人使用这么简单，一个良性的开源软件生态能够帮助开发者打造更优秀的软件，并使得用户从中受益，而参与到其中的形式则多种多样。很多人第一个想到的可能是捐款，这的确是很直接的形式之一，除此之外，还有非常多的方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如你可以前往开发者提供的反馈渠道提交错误反馈，以帮助开发者更快的定位错误并修复错误。&lt;/li&gt;
&lt;li&gt;你也可以加入到用户社区，参与到帮助解答其它社区用户的问题的过程中，和其它社区成员一同进步。&lt;/li&gt;
&lt;li&gt;甚至仅仅是告诉朋友，“这里有一个更自由的选择”，也是个不错的做法。即便仅仅是使用，也是一种形式的支持了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="但闭源软件的质量往往更高更安全不是吗"&gt;但闭源软件的质量往往更高更安全不是吗&lt;/h2&gt;
&lt;p&gt;比较中肯的回答是“不一定”。尽管简单的闭源可以非常直接的减少恶意的竞争抄袭，但并不能保证闭源软件的质量就一定比开源的高，也不能代表它们更安全。就安全与否这一议题而言，开放源代码的软件给了所有用户一窥源码的权利&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;，就可以拥有更多双眼睛一起协助检查发现问题，及时的发现问题更能够使得问题更早暴露而更早被修复，作为用户也自然能更早的享受到安全更新了。&lt;/p&gt;</description></item><item><title>Main 通常是一个函数。那什么时候不是呢？</title><link>https://www.blumia.net/post/2018-08-12-main-is-usually-a-function/</link><pubDate>Sun, 12 Aug 2018 18:39:08 +0000</pubDate><guid>https://www.blumia.net/post/2018-08-12-main-is-usually-a-function/</guid><description>&lt;p&gt;&lt;a href="https://jroweboy.github.io/c/asm/2015/01/26/when-is-main-not-a-function.html"&gt;原文链接&lt;/a&gt;, 由于翻译需要和译者所使用的环境不同，对文章的部分内容有修改，相关原因请参见脚注和原文最后附加的内容。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;事情得从我的一个同事说起，尽管他已经知道怎么编写程序了，并且曾在大学内开设了入门级别的计算机科学的课程。我们拿他开涮说，他的课程内容需要把一个程序跑起来，但是他的助教却压根搞不清楚程序到底是 &lt;em&gt;怎么&lt;/em&gt; 跑起来的。所以挑战来了，我们可以搞一个能正常工作的程序，还得让这种不熟悉工作原理的人认为这程序不应该跑起来。因此，我开始在脑子里翻我曾经见过或用过的 C 语言奇技淫巧，其中一个点子尤为符合这个要求。这个点子来自一个叫 &lt;a href="http://mainisusuallyafunction.blogspot.com/"&gt;main 通常是一个函数&lt;/a&gt; 的博客名字，于是我就开始想，那 main 什么时候能够&lt;strong&gt;不是&lt;/strong&gt;一个函数呢？让我们搞清楚吧！&lt;/p&gt;
&lt;p&gt;（请留意，我是在 64 位 Linux 下编写的这些例子，并且不同发行版的 gcc 所用的默认参数很可能是不同的，你很可能需要根据情况调整代码）&lt;/p&gt;
&lt;p&gt;我解决这个问题的方式和大多数码农差不多。第一步：谷歌这个问题。第二步：把看上去相关的链接挨个点进去看，如果没，就换个关键词接着搜。幸运的是，这个问题答案就在搜索结果很靠前的 &lt;a href="https://stackoverflow.com/a/2252429/745719"&gt;这篇 Stackoverflow 回答中&lt;/a&gt; 。实际上在 1984 年，一个奇怪的程序拿下了 IOCCC （国际C语言混乱代码大赛）的第一名，而它的 main 则是一个 &lt;code&gt;short main[] = {...}&lt;/code&gt; （ short 数组），并且这个程序最终还能把东西输出到屏幕上！不过由于当时编写那个程序所用的编译器和架构都不清楚，于是想搞清楚那个程序到底输出了啥已经不是那么容易了，但通过那个程序的源码来看，由于就是一堆数字，那我猜那堆数字肯定就是某个函数的编译好的二进制内容，而当链接器试图寻找 main 函数的时候则使它作为要找的内容来使用。&lt;/p&gt;
&lt;p&gt;那么该程序的源码就仅仅是把 main 函数编译好的机器码作为数组形式呈现了出来——有了这个假说，那就让我们来看一下我们能不能写个小程序来验证这种做法的可行性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; main[] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;你好, 世界!&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ cat main_char.c 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;char main&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;你好, 世界!&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gcc -Wall main_char.c -o first
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;main_char.c:1:6: warning: ‘main’ is usually a &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;-Wmain&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; char main&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;你好, 世界!&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ^~~~
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./first 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;段错误 &lt;span style="color:#f92672"&gt;(&lt;/span&gt;核心已转储&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;好！它好使了！算是好使了&amp;hellip;所以我们的下一个目标就是让这个程序实际能在屏幕上输出点东西。根据我有限的汇编经验，我想起编译后的内容会被划分到不同的段（section）下存储。和我们所要做的事情最相关的就是 &lt;code&gt;.text&lt;/code&gt; 段和 &lt;code&gt;.data&lt;/code&gt; 段了。其中 &lt;code&gt;.text&lt;/code&gt; 这个只读段包含了所有可执行的代码而 &lt;code&gt;.data&lt;/code&gt; 则包含了可以被读写但不可执行的数据。对于我们的情况，我们需要想个办法把字符串 &lt;code&gt;&amp;quot;你好, 世界!&amp;quot;&lt;/code&gt; 搞进 main 函数并且能引用到它。&lt;/p&gt;</description></item><item><title>回到 GitHub Pages</title><link>https://www.blumia.net/post/2018-07-29-moving-back-to-ghpages/</link><pubDate>Sun, 29 Jul 2018 00:00:00 +0000</pubDate><guid>https://www.blumia.net/post/2018-07-29-moving-back-to-ghpages/</guid><description>&lt;p&gt;为了减少预算支出和为服务器调整做准备，打算把个人主页放回 ghpages ，或者是把一部分页面放回 ghpages ，除了不确定的&lt;del&gt;博客&lt;/del&gt;日记是否迁移之外，别的大概都可以搬过来，能节省一部分精力去维护这些东西。&lt;/p&gt;
&lt;p&gt;前一段写了这个 Jekyll 主题以便把东西都 port 过来，这次就是把所有除了博客文章的内容外的东西都搬过来了。接下来是否迁移博客文章过来还没想好，至于之前在我 ghpages 里的那些博客文章页面就在本次迁移中消失了，是否会 port 过来还不确定，不过反正如果真的是想找那些旧文章，我又不是 &lt;code&gt;git reset --hard&lt;/code&gt; 了，所以真的想找的话又不是没办法，然而谁会那么无聊&amp;hellip;&lt;/p&gt;
&lt;p&gt;另外，这次迁移 Jekyll 还是有一些不满意的地方的。由于本身选择各种使用 markdown 的文章撰写平台/工具的目的就是为了尽可能保持专注于文章本身而不是标记，但 Jekyll 或者说 GitHub Pages 支持的 Jekyll 还是有一些比较蛋疼的限制。比如尽管可以使用 &lt;code&gt;parse_block_html&lt;/code&gt; 和 &lt;code&gt;parse_span_html&lt;/code&gt; 来控制是否把 html tag 内的内容视为 markdown 解析，但 kramdown (GitHub Pages &lt;a href="https://help.github.com/articles/configuring-jekyll/"&gt;钦定&lt;/a&gt;的 用于 Jekyll 的 Markdown 解析引擎) 却并不总能把所有常见的 tag 正确识别区分，其中就包括 &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; 。以及另一个比较奇怪的地方是，作为已经支持 front-matter 的博客引擎，不清楚为什么 Jekyll 还是一定要要求文章的文件名是 &lt;code&gt;YEAR-MONTH-DAY-title.md&lt;/code&gt; 这样的格式。&lt;/p&gt;
&lt;p&gt;总之个人主页或者博客这种性质的东西，尤其是我这种基本没人看的，应该不会有人在乎时效性吧，那什么时候迁完&amp;hellip;就随缘吧（&lt;/p&gt;</description></item><item><title>在 Linux 和 Windows 下共享蓝牙鼠标</title><link>https://www.blumia.net/post/2018-07-22-share-bluetooth-mouse-between-linux-n-windows/</link><pubDate>Sun, 22 Jul 2018 15:09:33 +0000</pubDate><guid>https://www.blumia.net/post/2018-07-22-share-bluetooth-mouse-between-linux-n-windows/</guid><description>&lt;p&gt;因为会去玩一些游戏和各种 DAW 大都不支持 Linux 桌面，我一直没离开 Windows ，而我自打来 D 司之后就一直在用我带过来的一个坏了的有线鼠标。上个月初 bktcon &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; 后我拿到了卡拉否椰页的 Logitech M336 蓝牙鼠标 &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; ，在 Windows 下用着还蛮舒服的，跑到 Arch 下发现找不到蓝牙适配器，由于人太懒就没过脑子直接没去研究。后来 Deepin 社区版升级 15.6 偶然试了试发现能够正常配对使用蓝牙鼠标，这才反应过来我 Arch 下开机压根没启蓝牙服务，切回去启动发现配对使用还是没啥问题的，然而却发现每次切什么系统都得重新配对&amp;hellip;&lt;/p&gt;</description></item><item><title>于 Deepin 试用期</title><link>https://www.blumia.net/post/2018-05-17-during-probationary-period-in-deepin/</link><pubDate>Thu, 17 May 2018 21:22:52 +0000</pubDate><guid>https://www.blumia.net/post/2018-05-17-during-probationary-period-in-deepin/</guid><description>&lt;p&gt;&lt;em&gt;声明：本文章的任何内容均不能代表（且不打算代表）官方解释&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;该篇可能行文凌乱缺乏整理&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;来到 Deepin 工作（目前还在试用期）有大概一个半月了，而这段时间多多少少对一些事情有了很多看法，一些看法也有或多或少的变化，这促使我去写这篇文章。前来 Deepin 工作是因为我认为 Deepin 是国内企业中为数不多的至少象模像样在认真做开源软件的企业之一，故尽管其开出的薪资较我同期在其它企业实习的同学的薪资低一些，且地理位置并没有什么优势的情况下，我依然来到了这个地方，而我现在并不知道如何评价我自己的这个选择。&lt;/p&gt;
&lt;p&gt;在开始之前，我还是要强调一些事情，一个是，下面你的确可以看到一些我的立场，它可能与你的印象想法或者 Deepin 官方的描述有冲突，这是正常的，且仅仅只能代表我自己的观点。而写这篇文章并不是为了洗白或者抹黑 Deepin ，也仅仅是为了表明立场而已。另外，这篇文章对一些比较常见的观点做了一些解释，这些解释并不代表官方立场，且我并不保证我的解释和官方的想法是否冲突。&lt;/p&gt;
&lt;p&gt;另外一点是，如果你也是 Deepin 的员工或者领导，并且你不认同我的观点或者认为我的观点哪里有偏差，也希望你可以以任何形式——发博客也好，发邮件给我也好——将你的立场亮出来，同时希望你把链接发送给我，我会根据观点做出进一步回复并把你的观点/博客链接贴在下面给其它读者查阅。以及，如果你有兴趣的话，可以去 Wayback Machine 那里 Archive 一下这个网页。&lt;/p&gt;
&lt;p&gt;这篇文章会尽可能的选一些有争议的话题来讲，以此一方面表明我的立场，另一方面也希望能够带来的争议可以帮我判断一些事情&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。那么下面开始&amp;hellip;&lt;/p&gt;
&lt;h2 id="答疑-分类"&gt;答疑 分类&lt;/h2&gt;
&lt;p&gt;这段本来叫 “说好听的话 分类” ，但是的确有几个问题我不能给出一个好听的答复，故名字还是改回来了。&lt;/p&gt;
&lt;p&gt;ps. 并不是欲抑先扬，我的确是这么想的。&lt;/p&gt;
&lt;h3 id="linux-deepin-是个套壳骗经费产物-"&gt;&amp;ldquo;Linux Deepin 是个套壳骗经费产物&amp;rdquo; ？&lt;/h3&gt;
&lt;p&gt;这个的答案是“并不是”。深度一直以来的确有在正经的做东西，比如 Deepin Desktop Environment （dde）全家桶（某种角度上讲 dde 并不比 GNOME 差），其代码质量并不低，而使用体验也并不差&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;由于企业的确是要挣钱的，不然也没法给员工发工资，所以 Deepin 必然要寻找他们的目标&lt;strong&gt;客户&lt;/strong&gt;并迎合他们，故你会看到 deepin.com 上类似于 “适用于党、政、军等机要部门中” 的让普通用户看着瘆人（下面解释）的字眼。这是经济来源不假，但并不代表 Deepin 是套别的 DE 的壳然后改个主题就拿来骗钱的项目。&lt;/p&gt;
&lt;p&gt;由于目标&lt;strong&gt;用户&lt;/strong&gt;是新手，故 DDE 默认的使用体验大致会给人留下它有 “抄 Windows 模式” 和 “抄 Mac 模式” 的印象，这个的确不假，但的确是刻意这样做的，并下了一些功夫在里面——至少不是拿现有的 DE 换皮肤这样的存粹骗经费的行为。&lt;/p&gt;
&lt;h3 id="他们的目标客户是会不会内置个后门-"&gt;&amp;ldquo;他们的目标客户是&amp;hellip;，会不会内置个后门&amp;rdquo; ？&lt;/h3&gt;
&lt;p&gt;如果熟悉了 Deepin 的软件开发流程就会知道，其实整个开发过程是完全可见的，源码位于公司的服务器，使用 gerrit 作为 codereview 平台且&lt;a href="https://cr.deepin.io/"&gt;外网可访问&lt;/a&gt;，代码在 review 完成后被 merge 会自动同步到 GitHub 。而 review 过程则是贡献者（即公司内的开发者，员工）人工 review 和 &lt;a href="https://ci.deepin.io/"&gt;CI 跑构建&lt;/a&gt;和测试。由于源码甚至整个流程都是用户可见的，故这样保证了只要源码没有问题，就不会存在问题了。&lt;/p&gt;</description></item><item><title>编写简单的辅助脚本来在 Google 表格上记账</title><link>https://www.blumia.net/post/2018-04-01-googlespreadsheetscripting/</link><pubDate>Sun, 01 Apr 2018 21:53:52 +0000</pubDate><guid>https://www.blumia.net/post/2018-04-01-googlespreadsheetscripting/</guid><description>&lt;p&gt;&lt;em&gt;2020/7/7 edit: 这篇文章的参考意义不大，事实上这篇文章所涉及的所有内容使用表格软件本身自带的功能都可以实现，只是写这篇文章的时候自己并不熟悉表格软件（毕竟平时几乎不和表格软件打交道）所以误以为一些功能需要手动实现，所以才有了这篇文章&amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;我的第二份工作入职在即，而这一次则真的是完全跑到了一个陌生的城市了。租房，购置相关用品，还尚未工作钱就花掉一堆。尽管我个人之前一直都没有过记账的习惯，但为了让自己能够搞清楚自己的钱都花在哪里了，于是还是决定整个超级无敌无脑简单的账本出来。&lt;/p&gt;
&lt;p&gt;顺带一提，这篇文章仅仅是写下来记录一下整个过程，其实整个文章并没有多高的技术含量。如果你熟悉 Excel vba 或者 Google Spreadsheets 脚本的编写而又期望学习一些新的技巧的话，这篇文章不是你想要的文章。&lt;/p&gt;
&lt;p&gt;尽管很水，但鉴于这篇文章好歹和技术稍微挂点钩，所以这篇文章我&lt;a href="https://www.cnblogs.com/blumia/p/GoogleSpreadsheetScripting.html"&gt;同时发布在了 Cnblogs 上&lt;/a&gt;，不过 Cnblogs 上的文章自然是少一点关于日常的事情。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blumia.github.io/media/sheet1.png" alt="搞的就这玩意儿"&gt;&lt;/p&gt;
&lt;p&gt;（注：上图的数据非真实数据）&lt;/p&gt;
&lt;h2 id="选型"&gt;选型？&lt;/h2&gt;
&lt;p&gt;首先决定的就是搜索现有的账本工具，而发现一部分账本软件过于复杂，另一部分则是使用他们自己的云服务去存储这些信息。由于感觉自己的需求的确很简单，只需要简单的支出收入计算就可以满足，故最终选择不使用复杂的记账平台和软件。&lt;/p&gt;
&lt;p&gt;收入支出计算，差不多就是一个 Excel 就能做到的事情，故开始考虑直接使用 Excel 表格加 vba 来辅助完成工作。但考虑到我平时需要使用手机处理事情，以及曾经被Excel Online的用户体验“感动”过，我决定使用另一家的服务来做这件事，也就是 Google Spreadsheets 。&lt;/p&gt;
&lt;h2 id="开发"&gt;开发？&lt;/h2&gt;
&lt;p&gt;不同于以往写小工具的时候的复杂需求和复杂流程，如果选择使用表格软件完成这个记账任务其实只需要在指定的单元格填填东西编写公式就好了。于是填写好列的表头：时间，内容，数值变动，变动后结果和备注。然后就完事儿了。&lt;/p&gt;
&lt;p&gt;作为账本，需要自动计算的东西其实就两个，即从初始金额开始每次数值变动后的“变动后结果”，以及当前页账本整个算下来的余额。而这两个需求其实也非常简单，只需要公式即可完成。其中整页余额只需要找个格子写个 &lt;code&gt;SUM(C4:C200)&lt;/code&gt; （假设变动的值从在C列，从行4开始，计算到4到200行值的和）把变动的值加一块儿就行了。而计算当前行金额变动后的结果也很简单，只需把上一行的结果和这一行变动的数值相加即可。在我的这个例子中，即当前单元格的值为这个单元格上方的值加上这个单元格左方的值，即公式 &lt;code&gt;=INDIRECT(&amp;quot;R[-1]C[0]&amp;quot;,false)+INDIRECT(&amp;quot;R[0]C[-1]&amp;quot;,false)&lt;/code&gt; 。Tada！一个无脑账本就这么完成了（你什么都没做啊喂！）。&lt;/p&gt;
&lt;h2 id="就这么结束了"&gt;就这么结束了？&lt;/h2&gt;
&lt;p&gt;&lt;del&gt;由于如果仅仅如此的话，一切的确太过简陋以至于连一篇博客也水不完，&lt;/del&gt; 于是还是决定加一点东西进去，即按照颜色标识收入和支出，而这就需要编写简单的脚本处理了。事实上，相比正常的软件开发，这个需求也显得过于简单，所以我们很容易就能得到这种伪代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;这次花的钱钱&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;这次花的钱钱&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;yyy&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;这个格子&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;设置背景颜色&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;某个颜色&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (...) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;于是我们要做的事情就是，翻文档，看看如何做到上面的事情。&lt;/p&gt;
&lt;p&gt;大致阅读文档发现代码有一股 JavaScript 的味道，于是就决定先按 js 的语法套路来写，如果出了问题再查。通过查阅文档可知，获得当前表的方式就是 &lt;code&gt;SpreadsheetApp.getActiveSheet()&lt;/code&gt; ，而得到现有表格的数据范围（即这个表的数据情况）则是 &lt;code&gt;getDataRange()&lt;/code&gt; 了。当我们对得到的数据取值，只需要 &lt;code&gt;getValues()&lt;/code&gt; 即可得到一个映射表，而取得数据范围内某个格子则只需 &lt;code&gt;getCell(行, 列)&lt;/code&gt; ，相应的，取得单元格的值使用 &lt;code&gt;getValue()&lt;/code&gt; ，为单元格设置背景使用 &lt;code&gt;setBackground(&amp;quot;颜色&amp;quot;)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;于是我们就可以通过这些来实现为每一个现有行的收入支出结果那一列标识不同背景颜色的代码了。我们在 工具 &amp;gt; 代码编辑器 编写代码即可，代码也异常简单，如下所示。&lt;/p&gt;</description></item><item><title>使用 TUN 设备实现一个简单的 UDP 代理隧道</title><link>https://www.blumia.net/post/2017-09-28-write-a-simple-udp-tunnel-using-tun-device/</link><pubDate>Thu, 28 Sep 2017 17:05:31 +0000</pubDate><guid>https://www.blumia.net/post/2017-09-28-write-a-simple-udp-tunnel-using-tun-device/</guid><description>&lt;p&gt;若要实现在 Linux 下的代理程序，方法有很多，比如看着 &lt;a href="https://www.ietf.org/rfc/rfc1928.txt"&gt;RFC 1928&lt;/a&gt; 来实现一个 socks5 代理并自行设置程序经过 socks5 代理等方式，下文是使用 Linux 提供的 &lt;code&gt;tun/tap&lt;/code&gt; 设备来实现 UDP 代理隧道的大体思路和过程讲解。&lt;/p&gt;</description></item><item><title>写于实习前</title><link>https://www.blumia.net/post/2017-06-05-dairy-before-intern/</link><pubDate>Mon, 05 Jun 2017 01:58:18 +0000</pubDate><guid>https://www.blumia.net/post/2017-06-05-dairy-before-intern/</guid><description>&lt;p&gt;说是写于实习前，但实习其实还有一段时间 &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; ，今晚有点时间，简要记一下这段时间的事情吧。&lt;/p&gt;</description></item><item><title>原来JS是这样的 (1)</title><link>https://www.blumia.net/post/2017-02-28-thats-javascript-1/</link><pubDate>Tue, 28 Feb 2017 22:26:17 +0000</pubDate><guid>https://www.blumia.net/post/2017-02-28-thats-javascript-1/</guid><description>&lt;h2 id="引子"&gt;引子&lt;/h2&gt;
&lt;p&gt;长久以来一直都没有专门学过 JS ，因为之前有自己啃过 C++ ，又打过一段时间的算法竞赛（写得一手好意大利面条），于是自己折腾自己的网站的时候，一直都把 JS 当 C 写。但写的时候总会遇到一些奇怪的问题，于是打算花点时间看了看《你不知道的JavaScript》。写这篇文章以记录一下一段时间的学习内容，也治疗一下我不爱做笔记和总结的毛病。如果你也是一直按着别的语言的编程习惯来写 JS 而没有专门去了解过它，不妨一起来了解一下 JS 的一些独特之处。&lt;/p&gt;</description></item><item><title>关于不要买辣鸡酷派</title><link>https://www.blumia.net/post/2017-02-09-laji-coolpad/</link><pubDate>Thu, 09 Feb 2017 02:11:46 +0000</pubDate><guid>https://www.blumia.net/post/2017-02-09-laji-coolpad/</guid><description>&lt;p&gt;其实压根没想到会有这么一篇。我感觉我黑过红米，黑过wp，然后当我拿到手一部酷派大神F2的时候，我觉得我都应该给某米和某软道歉了。于是这么一篇，可以当个故事段子看。&lt;/p&gt;</description></item><item><title>OnePlus3T 从解锁 BootLoader 到 Xposed</title><link>https://www.blumia.net/post/2017-01-14-oneplus3t-from-unlock-to-xposed/</link><pubDate>Sat, 14 Jan 2017 11:31:06 +0000</pubDate><guid>https://www.blumia.net/post/2017-01-14-oneplus3t-from-unlock-to-xposed/</guid><description>&lt;p&gt;我[之前]({{ site.baseurl }}{% post_url 2016-11-17-talk-begin-with-bloj %})立了个flag，说如果年前换了手机我就要好好黑一黑wp来着。于是年前真换了手机，于是就有了这一篇，打算写写折腾1+3T的过程以及顺便黑一黑垃圾WP。&lt;/p&gt;</description></item><item><title>一些事情 - 从OJ开发谈起</title><link>https://www.blumia.net/post/2016-11-17-talk-begin-with-bloj/</link><pubDate>Thu, 17 Nov 2016 01:14:24 +0000</pubDate><guid>https://www.blumia.net/post/2016-11-17-talk-begin-with-bloj/</guid><description>&lt;h2 id="杂话"&gt;杂话&lt;/h2&gt;
&lt;p&gt;BLumiaOJ 这个repo被我闲置了大概有快一年了吧，现在因为一些事情不得不拾起来这个repo，于是打算谈一下相关的事情，当然，不止会谈OJ本身，也会叙叙事，所以这篇依然算是一篇杂记吧。&lt;/p&gt;</description></item><item><title>Qt5 多显示器获取不同显示器的分辨率和位置的方法</title><link>https://www.blumia.net/post/2016-01-30-qt5-multi-monitor/</link><pubDate>Sat, 30 Jan 2016 22:52:20 +0000</pubDate><guid>https://www.blumia.net/post/2016-01-30-qt5-multi-monitor/</guid><description>&lt;blockquote&gt;
 &lt;p&gt;2020/05/30 edit:&lt;br&gt;
该文章描述的特性已过时，建议检索新的 Qt 文档来查找适用于新版本 Qt 的解决方案。此文章保留做归档目的。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;先放官方文档链接：&lt;a href="http://doc.qt.io/qt-5/qdesktopwidget.html"&gt;QDesktopWidget - Qt5 Reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;之前一直在用被我乱搞后的ShadowPlayer作为默认播放器，后来主力系统换成linux了也就没再用了。这两天the Witness发布，也正好想玩一些别的windows only的游戏，于是回到windows打算好好玩一玩游♂戏。而这几天因为集训也还是在机房，于是我拿着我那台电脑显示器连着笔记本玩双屏很爽，回到windows后发现依然很爽，不过播放器mini界面会有bug，总是会回到主显示器的最右面，于是打算修一修，然后就有了这一片水文（&lt;/p&gt;</description></item><item><title>Hello Hexo</title><link>https://www.blumia.net/post/2015-10-23-hello-hexo/</link><pubDate>Fri, 23 Oct 2015 12:39:08 +0000</pubDate><guid>https://www.blumia.net/post/2015-10-23-hello-hexo/</guid><description>&lt;h3 id="换hexo了"&gt;换Hexo了&lt;/h3&gt;
&lt;p&gt;换Hexo了&amp;hellip;
其实很早之前就想换了，但是懒，没换。然而总有一只可爱的“熊孩子”刷我sae的流量。虽然没怎么花钱但是好歹也冲过两块钱软妹币。既然这样我还是接着懒下去吧，上&lt;a href="http://hexo.io/"&gt;Hexo&lt;/a&gt;和github.io，以免担心刷流量烧豆。&lt;/p&gt;</description></item><item><title>面基赛赛后有感</title><link>https://www.blumia.net/post/2015-10-21-after-ccpc/</link><pubDate>Wed, 21 Oct 2015 22:17:08 +0000</pubDate><guid>https://www.blumia.net/post/2015-10-21-after-ccpc/</guid><description>&lt;h3 id="比赛感想"&gt;比赛感想&lt;/h3&gt;
&lt;p&gt;于是一次比赛开始了，于是一次比赛结束了，于是有了这篇文章。&lt;/p&gt;</description></item><item><title>HDU 1045(Fire Net)题解</title><link>https://www.blumia.net/post/2015-08-10-hdu-1045fire-net-solution/</link><pubDate>Mon, 10 Aug 2015 15:12:00 +0000</pubDate><guid>https://www.blumia.net/post/2015-08-10-hdu-1045fire-net-solution/</guid><description>&lt;p&gt;嘛..markdown爽..那就再爽一次..&lt;/p&gt;
&lt;p&gt;相应博客园url：&lt;a href="http://www.cnblogs.com/blumia/p/hdu1045.html"&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;题解写的越发的少了，主要也只是因为题写的慢了..莫名其妙的动力减少以及难度增加导致的做题缓慢什么的.. &lt;del&gt;趁着这回写一次凑个数吧&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;以防万一，题目原文和链接均附在文末。那么先是题目分析：&lt;/p&gt;</description></item><item><title>POJ 3279(Fliptile)题解</title><link>https://www.blumia.net/post/2015-07-20-poj-3279fliptile-solution/</link><pubDate>Mon, 20 Jul 2015 13:55:00 +0000</pubDate><guid>https://www.blumia.net/post/2015-07-20-poj-3279fliptile-solution/</guid><description>&lt;p&gt;能用Markdown排版真爽。于是头一回打算先把题解发在这个我本来只发所谓日记的地方&amp;hellip;
相应博客园url：&lt;a href="http://www.cnblogs.com/blumia/p/poj3279.html"&gt;这里&lt;/a&gt;
以防万一，题目原文和链接均附在文末。那么先是题目分析：&lt;/p&gt;</description></item><item><title>TGE dif文件调试助手 软件发布页</title><link>https://www.blumia.net/post/2014-08-10-tge-dif-tester-release/</link><pubDate>Sun, 10 Aug 2014 15:52:00 +0000</pubDate><guid>https://www.blumia.net/post/2014-08-10-tge-dif-tester-release/</guid><description>&lt;p&gt;软件信息：&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blumia.github.io/media/dtr.png" alt="程序运行截图（中文）"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;软件名称：TGE dif文件调试助手（程序所注文件名称为 HappyRoll *.Dif 模型调试器）&lt;/li&gt;
&lt;li&gt;软件版本：Build 9（当前最终版本，如未发现严重bug则停止继续更新）&lt;/li&gt;
&lt;li&gt;软件类型：开源文件调试工具 （源码是找我要的…）&lt;/li&gt;
&lt;li&gt;软件下载地址：&lt;a href="http://pan.blumia.cn/file/302340"&gt;BLumia的分享盘载点&lt;/a&gt;  &lt;a href="http://www.crsky.com/soft/72929.html"&gt;霏凡软件站载点&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>BLumia's Timidity Shell软件发布及更新页</title><link>https://www.blumia.net/post/2014-07-02-blumia-s-timidity-shell-release-page/</link><pubDate>Wed, 02 Jul 2014 20:06:00 +0000</pubDate><guid>https://www.blumia.net/post/2014-07-02-blumia-s-timidity-shell-release-page/</guid><description>&lt;blockquote&gt;
 &lt;p&gt;2020/05/30 edit:&lt;br&gt;
这个软件已经很久没维护了，个人也不是特别建议使用，这个页面仅作归档保留目的。&lt;br&gt;
如果您有对本地 .mid 格式文件支持使用指定 soundfont 进行回放的需求，建议考虑尝试 &lt;a href="https://github.com/chirs241097/QMidiPlayer"&gt;Chris 的 QMidiPlayer&lt;/a&gt;，它能够跨平台使用，且功能非常完善，非常值得尝试。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;软件信息：&lt;/p&gt;
&lt;p&gt;&lt;img src="http:/blumia.github.io/media/bl_timidity_shell_screenshot.png" alt="软件主界面（未展开播放列表时）"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;软件名称：BLumia&amp;rsquo;s Timidity Shell&lt;/li&gt;
&lt;li&gt;软件版本：Build 122 （Banana 122 - 20180126）&lt;/li&gt;
&lt;li&gt;软件类型：开源midi播放器 （&lt;a href="https://github.com/BLumia/BLumiaTimidityShell"&gt;源码&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;软件下载地址：&lt;a href="https://github.com/BLumia/BLumiaTimidityShell"&gt;GitHub Release&lt;/a&gt; &lt;a href="https://garysoft.wodemo.com/file/305609"&gt;BLumia的分享盘载点(旧版)&lt;/a&gt;  &lt;a href="https://www.crsky.com/soft/62713.html"&gt;霏凡软件站载点(旧版)&lt;/a&gt; &lt;a href="http://www.duote.com/soft/4194.html"&gt;2345软件站载点(旧版)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>红米note增强之换货评价等日杂</title><link>https://www.blumia.net/post/2014-06-24-laji-redmi-note-1/</link><pubDate>Tue, 24 Jun 2014 14:00:51 +0000</pubDate><guid>https://www.blumia.net/post/2014-06-24-laji-redmi-note-1/</guid><description>&lt;p&gt;话说这几天也挺忙的，不过所谓的忙除了整理个人网站和码一些代码外也就是悠哉游哉了。毕竟高考今天24点就正式出分了，所以，这算是我等学渣最后的好日子吧。&lt;/p&gt;
&lt;p&gt;说是好日子其实并不算是。前些日子顺利的抢到红米后，漫长的等来了发货：
&lt;img src="https://www.blumia.net/media/redmi.png" alt="小米发货日程"&gt;&lt;/p&gt;
&lt;p&gt;看得出来，我等了也算很久才到货（我给官网给出的客服电话打过一次电话询问手机什么时候发货，他提示我稍等等），而我下单时间也并不算迟。毕竟到货了嘛。然后呢，&lt;/p&gt;</description></item><item><title>我的第一篇博客</title><link>https://www.blumia.net/post/2014-06-19-my-first-blog-post/</link><pubDate>Thu, 19 Jun 2014 10:52:00 +0000</pubDate><guid>https://www.blumia.net/post/2014-06-19-my-first-blog-post/</guid><description>&lt;p&gt;第一篇博客。。。。啊。。。。
话说。。这博客也没完全布置好呢。其实差的也还远呢。。
昨天决定用sae搭建网站，倒是挺稳定的。访问也很流畅。不过有流量限制。
本来有找一个虚拟主机或者租台服务器的打算来着，不过囊中羞涩，嘿嘿。。。。
好了，不写了，先完善网站去。&lt;/p&gt;</description></item></channel></rss>