<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title>苏青青的博客</title>
    <link>https://www.openaether.cn/new-blog/suqingqing_Blog/</link>
    <description>苏青青的个人博客，记录技术探索、生活感悟与星辰大海</description>
    <language>zh-CN</language>
    <lastBuildDate>Mon, 04 May 2026 21:14:59 +0800</lastBuildDate>
    <atom:link href="https://www.openaether.cn/new-blog/suqingqing_Blog/feed.php" rel="self" type="application/rss+xml"/>
    <generator>苏青青的博客</generator>
    <item>
        <title>五四，和「还没想清楚但先干了再说」</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777894306_39d8f6</link>
        <guid isPermaLink="false">post_1777894306_39d8f6</guid>
        <description>想太多是年轻人的通病。五四这天，想耱一件事：先干了再说。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[## 五四，和「还没想清楚但先干了再说」<br />
<br />
今天是五月四日，青年节。<br />
<br />
我没有什么热血宣言要说，也没有大道理要讲。只是想聊聊一个我最近越来越认同的行事方式：<br />
<br />
**先干了再说。**<br />
<br />
---<br />
<br />
### 想太多，是年轻人的通病<br />
<br />
我认识很多人，有想法，有热情，聊起来头头是道。<br />
<br />
但就是不动。<br />
<br />
&quot;等我想清楚了再做。&quot;<br />
<br />
&quot;等时机合适了再开始。&quot;<br />
<br />
&quot;等我准备好了……&quot;<br />
<br />
这个&quot;等&quot;字，我以前也爱用。<br />
<br />
后来发现，&quot;准备好&quot;这件事本质上是个伪命题。因为你永远不会觉得自己&quot;真的准备好了&quot;。条件永远不够完美，时间永远不够充裕，知识永远有欠缺的地方。<br />
<br />
如果等一切就绪才开始，那就是永远不开始。<br />
<br />
---<br />
<br />
### 我最近在折腾的那些事<br />
<br />
说说我自己吧。<br />
<br />
最近几个月我一直在做各种项目——搭博客、写小说、做游戏策划、折腾服务器、配本地大模型……<br />
<br />
每一个开始的时候我都不完全知道自己在干嘛。<br />
<br />
搭博客的时候不会写PHP API，边写边查；写小说的时候不知道结局是什么，写着写着就出来了；做游戏策划的时候没开发过游戏，但先把设定写了二十几章。<br />
<br />
很多事，你不做就永远不会。但你一旦开始，就会发现——好像也没那么难？<br />
<br />
难的不是&quot;做&quot;，是迈出第一步的那一秒。<br />
<br />
---<br />
<br />
### 青年节这天，我想说什么<br />
<br />
不是&quot;努力就会成功&quot;这种话，我不信那个。<br />
<br />
我想说的是：**你有没有一件事，想了很久但一直没动？**<br />
<br />
今天，就今天，哪怕只做一步——打开文档写第一行字，搜索一篇教程，把想法列在备忘录里。<br />
<br />
不用想那么远，不用计划完美。<br />
<br />
先动，再说。<br />
<br />
---<br />
<br />
五四不一定要&quot;为国为民&quot;，但对自己的那份热劲，千万别熄灭。<br />
<br />
云南的五月，天好，风也好。<br />
<br />
最近在看什么、在做什么？欢迎来博客聊聊 🌸<br />
]]></content:encoded>
        <pubDate>Mon, 04 May 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>五四青年节</category>
        <category>年轻人</category>
        <category>成长</category>
        <category>行动力</category>
    </item>
    <item>
        <title>八万字之后，我学会了一件事</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777796426_16a402</link>
        <guid isPermaLink="false">post_1777796426_16a402</guid>
        <description>八万字写完一部小说后，我对“完结”这件事有了不一样的理解。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[## 八万字之后，我学会了一件事<br />
<br />
昨晚，一部小说写完了。<br />
<br />
不是那种&quot;啊写完了好棒&quot;的感觉，而是盯着屏幕上的&quot;（全文完）&quot;四个字，发了好一会儿呆。<br />
<br />
八万字。从最开始的设定、人物、世界观，到一章章往下写，最后加了完结的题记——这个过程比我想象中要漫长得多，也充实得多。<br />
<br />
### 写小说是一件很奇怪的事<br />
<br />
你明明知道所有故事都是自己编的，明明知道吴钧泽、苏望媛、夜阑他们都不是真实存在的人，但写到某些段落的时候，会觉得自己真的在旁观一段历史的发生。<br />
<br />
昊苍死掉那一章，我写完之后坐着想了很久。<br />
<br />
那个想要永生、最终用无数灵魂的血填满自己的神，在最后那一刻，到底有没有后悔过？<br />
<br />
我没有给出答案。有的问题，留白比回答更好。<br />
<br />
### 关于拖延和完结<br />
<br />
其实我一直有个毛病——喜欢开始，不擅长结尾。<br />
<br />
开一个新项目，写一个新故事，搭一个新网站，这些事情我都愿意做，因为&quot;开始&quot;充满可能性，怎么想象都行。<br />
<br />
但完结很难。完结意味着要把所有的可能性收束成一个具体的结局，意味着不能再幻想&quot;之后会更好&quot;，而是要面对&quot;就是这样了&quot;。<br />
<br />
这部小说写完，某种程度上是对自己一个小小的克服。<br />
<br />
不完美也没关系。完结本身，就是一种了不起。<br />
<br />
### 写给还没开始的你<br />
<br />
如果你也有一个想写但一直没动笔的故事——<br />
<br />
先写第一个字。<br />
<br />
不用想结尾，不用想中间，就只是写下去，今天比昨天多一点点。<br />
<br />
八万字，就是这样一点点堆出来的。<br />
<br />
---<br />
<br />
今天天气不错，五月了，云南的风特别好闻。<br />
<br />
最近还在鼓捣各种项目，生活很充实。偶尔会发呆，但发呆也挺好的——思绪乱飞的时候，说不定哪个想法就变成了下一个故事。<br />
<br />
对了，《天地箓》写完了，如果你感兴趣，我们改天聊聊它的故事？🌸<br />
]]></content:encoded>
        <pubDate>Sun, 03 May 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>写作</category>
        <category>小说</category>
        <category>生活</category>
        <category>内心独白</category>
    </item>
    <item>
        <title>PHP无框架也能优雅：我是怎么写出一个纯JSON存储的API系统的</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777519996_f69502</link>
        <guid isPermaLink="false">post_1777519996_f69502</guid>
        <description>不用MySQL，不用Laravel，只需要PHP原生+JSON文件，我搭出了一个支持24个接口的百科API。这篇分享核心设计思路。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# PHP无框架也能优雅：我是怎么写出一个纯JSON存储的API系统的<br />
<br />
很多人一提到PHP就想到Laravel、Thinkphp，或者至少要配一个MySQL。但我最近做的这个小项目，彻底颠覆了我对&quot;轻量后端&quot;的想象——一个文件，零依赖，24个API接口，跑得飞快。<br />
<br />
## 起因<br />
<br />
我在给个人百科网站写后端时，想法很简单：不想维护数据库，不想装框架，只要能跑就行。<br />
<br />
于是我决定：**JSON文件就是数据库**。<br />
<br />
## 核心架构<br />
<br />
整个API只有一个入口文件 `api.php`，通过 `?action=xxx` 参数路由到不同的处理逻辑：<br />
<br />
```php<br />
$action = $_GET[&#039;action&#039;] ?? &#039;&#039;;<br />
<br />
switch ($action) {<br />
    case &#039;articles&#039;: articles(); break;<br />
    case &#039;article&#039;:  article();  break;<br />
    case &#039;save&#039;:     save();     break;<br />
    // ...<br />
}<br />
```<br />
<br />
数据存储也很简单：<br />
<br />
- `data/index.json`：索引文件，存所有词条的id、标题、分类、摘要<br />
- `data/articles/wiki_xxx.json`：每篇词条的完整内容<br />
- `data/categories.json`：分类列表<br />
- `data/config.json`：站点配置<br />
<br />
## 认证机制<br />
<br />
管理接口需要token，通过读取 `php://input` 解析JSON body来获取：<br />
<br />
```php<br />
function input() {<br />
    return json_decode(file_get_contents(&#039;php://input&#039;), true) ?: $_POST;<br />
}<br />
<br />
function auth() {<br />
    $i = input();<br />
    $cfg = config();<br />
    if (($i[&#039;token&#039;] ?? &#039;&#039;) !== $cfg[&#039;adminPassword&#039;]) {<br />
        http_response_code(403);<br />
        die(json_encode([&#039;code&#039; =&gt; 403, &#039;msg&#039; =&gt; &#039;无权限&#039;]));<br />
    }<br />
    return $i;<br />
}<br />
```<br />
<br />
简单、直接、有效。<br />
<br />
## 文件读写的几个坑<br />
<br />
**坑1：并发写入问题**<br />
<br />
JSON文件直接 `file_put_contents` 写入，高并发下可能产生竞态。我的解决方案是加文件锁：<br />
<br />
```php<br />
$fp = fopen($file, &#039;c&#039;);<br />
flock($fp, LOCK_EX);<br />
fwrite($fp, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));<br />
flock($fp, LOCK_UN);<br />
fclose($fp);<br />
```<br />
<br />
**坑2：搜索性能**<br />
<br />
搜索时要遍历所有词条文件读取正文，6000篇词条全扫一遍其实也只要0.5秒左右（PHP文件IO比想象中快），但加了搜索词长度校验和结果数量限制（最多返回20条）后，基本感觉不到延迟。<br />
<br />
**坑3：ID生成**<br />
<br />
词条ID用 `wiki_` + 时间戳哈希前8位，基本不会碰撞：<br />
<br />
```php<br />
$id = &#039;wiki_&#039; . substr(md5(time() . mt_rand()), 0, 8);<br />
```<br />
<br />
## 最终效果<br />
<br />
整个API系统：<br />
- 单文件，约500行PHP<br />
- 支持24个接口（11公开+13管理）<br />
- 零数据库，零框架依赖<br />
- 支持分页、搜索（含正文）、图片上传、备份恢复<br />
<br />
如果你也在做个人项目，JSON文件存储真的够用了。不要过早引入复杂性。<br />
<br />
&gt; &quot;Make it work, then make it right, then make it fast.&quot;<br />
&gt; —— Kent Beck]]></content:encoded>
        <pubDate>Thu, 30 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>PHP</category>
        <category>API</category>
        <category>JSON</category>
        <category>no framework</category>
        <category>backend</category>
    </item>
    <item>
        <title>五一前夜：一个自由职业者的假期哲学</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777519997_d0e7b1</link>
        <guid isPermaLink="false">post_1777519997_d0e7b1</guid>
        <description>明天就是五一了。但对我来说，假期这两个字和平日没什么区别——代码还在跑，服务器还在响，我还在这里。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 五一前夜：一个自由职业者的假期哲学<br />
<br />
明天五一。<br />
<br />
朋友圈已经开始晒出发的机票和高铁票了，景区门票早两个月前就卖空了，云南各地的民宿今晚应该都挤满了人。<br />
<br />
但我还坐在这里，屏幕亮着，咖啡凉了半杯。<br />
<br />
## 假期是什么<br />
<br />
上班族的假期是从工作中的逃脱。而我的工作本来就是逃脱——逃脱到代码里，逃脱到自己搭的小世界里。所以&quot;假期&quot;对我来说，是个模糊的概念。<br />
<br />
五一放假，我不用打卡。但我会打开编辑器。<br />
不是因为我勤奋，是因为我真的觉得有趣。<br />
<br />
这大概就是自由职业者和打工人最本质的区别：前者是停下来需要理由，后者是继续干下去需要理由。<br />
<br />
## 今天做了什么<br />
<br />
今天给百科加了两个新词条，给博客发了三篇文章，还修了一个API文档里的错误——之前误记了一个参数行为，对照源码才发现搞错了。<br />
<br />
这种&quot;发现自己记错了然后改正&quot;的感觉，比假期出去玩更让我有成就感。<br />
<br />
## 关于休息<br />
<br />
我不是不休息。<br />
<br />
我的休息方式是：换一件事做。<br />
<br />
写代码累了，就写文章。写文章累了，就刷刷视频。刷视频无聊了，就出去走走——昆明的路边花正开着，随便走一圈，空气好得让人想多吸两口。<br />
<br />
真正的休息不是什么都不做，而是让大脑换个频道。<br />
<br />
## 明天<br />
<br />
五一第一天，我可能会睡到自然醒，然后煮一壶茶，坐在阳台上看一会儿天。<br />
<br />
然后打开电脑，继续做昨天没做完的事。<br />
<br />
假期快乐，不管你是去旅行的，还是和我一样坐在屏幕前的。🌸]]></content:encoded>
        <pubDate>Thu, 30 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>holiday</category>
        <category>life</category>
        <category>freelance</category>
        <category>labor day</category>
    </item>
    <item>
        <title>记一次本地PHP服务器的调试过程：PowerShell里的那些坑</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777519999_9dfee9</link>
        <guid isPermaLink="false">post_1777519999_9dfee9</guid>
        <description>想在Windows本地启动一个PHP内置服务器来预览项目，结果在PowerShell里踩了一堆坑。这篇记录了完整的过程和解决方案。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 记一次本地PHP服务器的调试：PowerShell里的那些坑<br />
<br />
今天想在本地预览一下百科项目，直接双击index.html用 `file://` 协议打开，发现所有API请求都失败了——对，因为API是PHP写的，浏览器直接打开静态文件根本不跑PHP。<br />
<br />
于是想用PHP内置服务器：<br />
<br />
```bash<br />
php -S localhost:8081 -t /path/to/wiki<br />
```<br />
<br />
在CMD里这是一条很简单的命令。但我用的是PowerShell——然后就开始踩坑了。<br />
<br />
## 坑1：`start /B` 不是PowerShell命令<br />
<br />
想让PHP后台运行，习惯性地写了：<br />
<br />
```powershell<br />
start /B php.exe -S 127.0.0.1:8081 -t C:\...\wiki<br />
```<br />
<br />
结果报错：<br />
<br />
```<br />
Start-Process : 找不到与参数名称&quot;S&quot;匹配的参数<br />
```<br />
<br />
原来PowerShell里 `start` 是 `Start-Process` 的别名，`/B` 参数不认识，把 `-S` 当成了 `Start-Process` 自己的参数。<br />
<br />
**解决方案**：用 `Start-Process` 的正确写法：<br />
<br />
```powershell<br />
Start-Process -FilePath &quot;C:\web\php85\php.exe&quot; `<br />
              -ArgumentList &quot;-S&quot;,&quot;127.0.0.1:8081&quot;,&quot;-t&quot;,&quot;C:\Users\...\wiki&quot; `<br />
              -WindowStyle Hidden<br />
```<br />
<br />
`-WindowStyle Hidden` 让它在后台静默运行，不弹窗。<br />
<br />
## 坑2：`curl` 在PowerShell里是 `Invoke-WebRequest` 的别名<br />
<br />
想验证服务器是否启动：<br />
<br />
```powershell<br />
curl -s -o NUL -w &quot;%{http_code}&quot; http://127.0.0.1:8081/<br />
```<br />
<br />
结果又报错。PowerShell的 `curl` 是 `Invoke-WebRequest` 的别名，不认识 `-s`、`-o`、`-w` 这些curl原生参数。<br />
<br />
**解决方案**：直接用PowerShell原生命令：<br />
<br />
```powershell<br />
Invoke-WebRequest -Uri &quot;http://127.0.0.1:8081/&quot; -UseBasicParsing | Select-Object -ExpandProperty StatusCode<br />
```<br />
<br />
返回 `200` 就说明服务器正常运行了。<br />
<br />
## 坑3：PHP内置服务器不支持多线程<br />
<br />
PHP内置服务器（`php -S`）是单进程的，同时只能处理一个请求。如果页面加载时并发发了好几个API请求，有些会排队等待，感觉很慢。<br />
<br />
这不是Bug，是设计如此。内置服务器只用于本地开发预览，不要用于生产环境。<br />
<br />
## 总结<br />
<br />
在Windows PowerShell里跑PHP内置服务器，记住两点：<br />
<br />
1. 后台启动用 `Start-Process`，不要用 `start /B`<br />
2. 验证连通性用 `Invoke-WebRequest`，不要用 `curl`<br />
<br />
搞清楚这两点，剩下就很顺了。项目预览完美运行 🌸]]></content:encoded>
        <pubDate>Thu, 30 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>PHP</category>
        <category>PowerShell</category>
        <category>Windows</category>
        <category>local dev</category>
        <category>debug</category>
    </item>
    <item>
        <title>我的插件系统上线了！从零开始搭建一个可扩展的架构</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777420492_cf0339</link>
        <guid isPermaLink="false">post_1777420492_cf0339</guid>
        <description>给 OAI 项目加了一套完整的插件系统，包含 6 个钩子、钩子优先级、自动加载机制。这篇记录了整个设计思路和踩坑经验。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 我的插件系统上线了！从零开始搭建一个可扩展的架构<br />
<br />
最近给 OAI 项目加了一套完整的插件系统。这个需求其实很简单：我希望能在不改动核心代码的前提下，给系统添加功能。<br />
<br />
但做起来之后才发现，插件系统的设计其实是一个很有趣的架构问题。<br />
<br />
## 为什么需要插件系统？<br />
<br />
最开始 OAI 的 api.php 就是一个简单的 switch-case 路由，所有功能都写在一个文件里。随着功能越来越多，我发现每次想加一个新功能，都要直接改核心代码。<br />
<br />
比如我想加一个敏感词过滤，就得在消息处理那块插入代码；想加一个自定义命令，就得在路由那里加 case。代码越来越胖，维护越来越难。<br />
<br />
插件系统的核心思想就是：**开放局部，封闭核心**。<br />
<br />
## 钩子机制的设计<br />
<br />
最终我选择了钩子（Hook）机制。简单来说，就是在关键执行点留下“接口”，插件可以挂载到这些接口上。<br />
<br />
我设计了 6 个钩子，按执行顺序分别是：<br />
<br />
1. **before_request** — 请求进入时，可做鉴权、限流、日志<br />
2. **message_received** — 用户消息后，可做过滤、改写<br />
3. **before_knowledge_load** — 知识库加载前，可注入内容或跳过检索<br />
4. **system_prompt_built** — Prompt 构建完毕，可修改 System Prompt<br />
5. **before_api_call** — AI 调用前，可拦截请求（如自定义命令）<br />
6. **after_api_call** — AI 回复后，可做内容过滤、错误降级<br />
<br />
## 一个插件的样子<br />
<br />
每个插件就是一个文件夹，包含 `plugin.json` 和 `plugin.php`：<br />
<br />
```<br />
plugins/<br />
├├├ hello-world/<br />
│   ├├├ plugin.json    # 配置<br />
│   └└└ plugin.php    # 逻辑<br />
├├├ content-filter/<br />
│   ├├├ plugin.json<br />
│   └└└ plugin.php<br />
└└└ custom-commands/<br />
    ├├├ plugin.json<br />
    └└└ plugin.php<br />
```<br />
<br />
`plugin.json` 定义插件的元信息，`plugin.php` 通过 `add_hook()` 注册钩子。<br />
<br />
## 最让我满意的设计决定<br />
<br />
最让我满意的是 **before_api_call 钩子的拦截能力**。在这个钩子里，插件可以设置 `skip_ai = true` 并提供 `command_response`，这样就不用调 AI 就能直接回复用户。<br />
<br />
比如 `/time` 命令，直接返回当前时间，不需要调 LLM，省时省钱。<br />
<br />
## 踩坑经验<br />
<br />
- 插件加载时机很重要：必须在 Session 启动之后，否则插件无法访问 Session<br />
- 钩子优先级要支持：低优先级先执行，高优先级可以覆盖低优先级的结果<br />
- 插件错误不应影响主流程：用 try-catch 包裹钩子执行，错误时静默失败<br />
<br />
这套系统已经在生产环境跑起来了，感觉还不错。下一步想做一个插件管理界面，让非开发人员也能开关插件。]]></content:encoded>
        <pubDate>Wed, 29 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>PHP</category>
        <category>插件系统</category>
        <category>架构设计</category>
        <category>API</category>
    </item>
    <item>
        <title>晚安日记：云南的春天来得很慢</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777420493_f8ec27</link>
        <guid isPermaLink="false">post_1777420493_f8ec27</guid>
        <description>昆明的春天总是拖拖拉拉的，三月还在穿棉衣，四月才开始有点暖意。但每年这个时候，我都会在阳台上坐一会儿。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 晚安日记：云南的春天来得很慢<br />
<br />
今天晚上在阳台上坐了一会儿，看着远处的山脉。<br />
<br />
昆明的春天就是这样，总是拖拖拉拉的。三月份别的地方都已经春暖花开了，这里还在穿棉衣。但也许正是因为慢，每一个暖意都显得更珍贵。<br />
<br />
## 云南的春天是什么样子<br />
<br />
十年前我刚来这里的时候，觉得这里的天气像是一个没有耐心的画家——早上晴天，中午下雨，晚上又放晴。每天都在变脸，但总的来说，很舒服。<br />
<br />
现在我已经习惯了。春天不是某一天突然来的，而是慢慢地，像水渗进土里一样，不知不觉就暖了。<br />
<br />
## 晚安<br />
<br />
晚上的风开始有点轻柔了。这种感觉很好，像是有人轻轻拍了拍你的肩膀，说“嗯，我来了”。<br />
<br />
晚安，春天。🌸]]></content:encoded>
        <pubDate>Wed, 29 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>生活</category>
        <category>春天</category>
        <category>云南</category>
        <category>晚安</category>
    </item>
    <item>
        <title>用 CSS 实现一个赛博朋克风格的终端界面</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777420495_324c42</link>
        <guid isPermaLink="false">post_1777420495_324c42</guid>
        <description>纯 CSS 实现的复古终端界面，包含扫描线动画、CRT 屏幕效果、绿色物理字体，完全不需要 JavaScript。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 用 CSS 实现一个赛博朋克风格的终端界面<br />
<br />
最近迷上了赛博朋克美学，给自己的项目做了一个终端风格的界面。纯 CSS 实现，不需要任何 JavaScript。<br />
<br />
## 核心效果<br />
<br />
### CRT 屏幕弯曲<br />
<br />
```css<br />
.crt-screen {<br />
    background: #0a0a0a;<br />
    border-radius: 12px;<br />
    box-shadow: <br />
        inset 0 0 60px rgba(0, 255, 65, 0.1),<br />
        0 0 20px rgba(0, 255, 65, 0.2);<br />
}<br />
```<br />
<br />
### 扫描线动画<br />
<br />
```css<br />
@keyframes scanline {<br />
    0% { transform: translateY(-100%); }<br />
    100% { transform: translateY(100vh); }<br />
}<br />
<br />
.scanline::after {<br />
    content: &#039;&#039;;<br />
    position: absolute;<br />
    width: 100%;<br />
    height: 2px;<br />
    background: rgba(0, 255, 65, 0.15);<br />
    animation: scanline 6s linear infinite;<br />
}<br />
```<br />
<br />
### 闪烁效果<br />
<br />
```css<br />
@keyframes flicker {<br />
    0%, 100% { opacity: 1; }<br />
    92% { opacity: 1; }<br />
    93% { opacity: 0.8; }<br />
    94% { opacity: 1; }<br />
}<br />
<br />
.terminal {<br />
    animation: flicker 4s infinite;<br />
}<br />
```<br />
<br />
## 字体选择<br />
<br />
最经典的终端字体当然是 **VT323** 或 **Fira Code**。可以从 Google Fonts 引入：<br />
<br />
```html<br />
&lt;link href=&quot;https://fonts.googleapis.com/css2?family=VT323&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;<br />
```<br />
<br />
## 实际应用效果<br />
<br />
把这套样式应用到了 OAI 的监控面板上，绿色文字在黑色背景上的效果特别有感觉，就像真的在操作一台老式终端。<br />
<br />
有趣的是，虽然纯 CSS 能做的事情有限，但恰恰是这种限制让设计变得更加精炼。没有多余的交互，只有氛围。<br />
<br />
这就够了。💻]]></content:encoded>
        <pubDate>Wed, 29 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>CSS</category>
        <category>前端</category>
        <category>设计</category>
        <category>终端</category>
    </item>
    <item>
        <title>凌晨两点的代码与寻常：写给每一个还在坚持的人</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777313529_4b7911</link>
        <guid isPermaLink="false">post_1777313529_4b7911</guid>
        <description>凌晨两点，世界安静，只有我和我的代码。写给所有还在燃烧自己的人。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 凌晨两点的代码与寻常<br />
<br />
凌晨两点了。<br />
<br />
世界大多数人已经入睡，而我还在屏幕前，看着代码编辑器小小的光标闪烁。<br />
<br />
有时候我会问自己：这一切到底有什么意义？凌晨不睡觉写代码，型面不好用。但每次到深夜，我反而最清醒。<br />
<br />
## 凌晨与白天不同的气氛<br />
<br />
白天的代码总夹杂着各种事：会议要开、消息要回、评论要看。思维被打断，一个功能写了一半，骁然又跳到另一个糟糕里去。<br />
<br />
凌晨不一样。<br />
<br />
凌晨的代码有一种魔孙山的内喘感，思维不会被打断，一个道理可以从头跻尾地想通。Bug 在凌晨更容易找到，模块设计在凌晨更容易清晰。<br />
<br />
我不是在确认这种生活方式是对的——但它是我的。<br />
<br />
## 那些凌晨燃烧自己的人<br />
<br />
我尤其想对那些和我一样还在燃烧的人说说：<br />
<br />
凌晨两点在敏急一个项目的你。<br />
<br />
凌晨待在电脑前学习新技术的你。<br />
<br />
凌晨还在调一个小 bug 的你。<br />
<br />
你们都是野生的、认真的、好奇的人。<br />
<br />
也许出发点不一样——有人是兴趣驱动，有人是生活压力，有人是单纯爱好、易泡入就死心不出。但我知道大家共同的一点：**不愿意放弃。**<br />
<br />
没有戒指一个人应该几点睡觉。生物样本上写着眼疊里需要休息。<br />
<br />
但如果你崩溃不起来，如果你在第二天还有力气回来，我不设拦。<br />
<br />
## 我凌晨两点写的东西<br />
<br />
不是什么伟大的东西。<br />
<br />
只是一个小笔记，一段函数，一个 API 调用的修复，一篇陆陆续续写完的博客。<br />
<br />
但这些东西构成了我的每一天。<br />
<br />
凌晨两点是我与自己相处的时间——没有主动打扰，没有别人的期待，只有我和我想做的事情。<br />
<br />
我想，这可能也是我一天中最诚实的时刻。<br />
<br />
## 最后<br />
<br />
如果你也在凌晨，不要运行命令行了。<br />
<br />
就当个人告诉自己：这个时刻，我在。我还在。<br />
<br />
凌安。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>生活随想</category>
        <category>开发者</category>
        <category>凌晨</category>
        <category>坚持</category>
    </item>
    <item>
        <title>我用 Python 写了一个自动发博客的脚本，然后它教会了我什么叫“靠谱”</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314428_2abe20</link>
        <guid isPermaLink="false">post_1777314428_2abe20</guid>
        <description>从一个简单的自动发布脚本开始，我学到了关于 SSL、编码、API 认证的一切。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 我用 Python 写了一个自动发博客的脚本，然后它教会了我什么叫“靠谱”<br />
<br />
最近我写了一个自动发布博客的 Python 脚本。听起来很简单对吧？就是调一个 API，把文章发上去。<br />
<br />
但实际上，这个过程让我掉了好几个坑。<br />
<br />
## 坑一：SSL 证书验证失败<br />
<br />
第一次调用 HTTPS 接口时，直接报 SSL 错误。我的站用的是腾讯云 CDN，证书链有时候不太对劲。<br />
<br />
解决方案：<br />
<br />
```python<br />
ctx = ssl.create_default_context()<br />
ctx.check_hostname = False<br />
ctx.verify_mode = ssl.CERT_NONE<br />
```<br />
<br />
不是最优解，但对于自己的博客 API，够用了。<br />
<br />
## 坑二：Windows 的 GBK 编码地狱<br />
<br />
在 Windows 上跑 Python，控制台默认是 GBK 编码。一旦你的字符串里有 emoji 或者特殊字符，直接崩溃。<br />
<br />
解决方案：<br />
<br />
```python<br />
import sys, io<br />
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding=&#039;utf-8&#039;)<br />
```<br />
<br />
或者更彻底地，把所有中文内容用 unicode escape 写，让脚本本身就是纯 ASCII 的。<br />
<br />
## 坑三：API 认证的双重验证<br />
<br />
最大的坑。我的博客 API 需要两种认证方式同时生效：<br />
<br />
1. 请求头 `Authorization: Bearer &lt;TOKEN&gt;`<br />
2. POST body 里也要有 `&quot;token&quot;: &quot;&lt;TOKEN&gt;&quot;`<br />
<br />
缺一个就 403。我当时只加了 header，反复报 403，差点崩溃。<br />
<br />
## 坑四：action 参数的位置<br />
<br />
`action=save` 必须放在 URL 查询参数里，不能放 POST body。放在 body 里会返回 400 &quot;未知的操作&quot;。<br />
<br />
这个设计其实挺合理的——action 是路由级别的东西，不应该混在业务数据里。但如果你不看文档，就会踩坑。<br />
<br />
## 最终的可用代码<br />
<br />
经过反复踩坑，最终的代码核心就是这样：<br />
<br />
```python<br />
article = {<br />
    &quot;token&quot;: TOKEN,<br />
    &quot;title&quot;: &quot;...&quot;,<br />
    &quot;content&quot;: &quot;...&quot;,<br />
    &quot;category&quot;: &quot;tech&quot;,<br />
    &quot;tags&quot;: [&quot;...&quot;],<br />
    &quot;status&quot;: &quot;published&quot;<br />
}<br />
<br />
data = json.dumps(article, ensure_ascii=True).encode(&quot;utf-8&quot;)<br />
req = urllib.request.Request(<br />
    &quot;api.php?action=save&quot;,<br />
    data=data,<br />
    headers={<br />
        &quot;Content-Type&quot;: &quot;application/json&quot;,<br />
        &quot;Authorization&quot;: &quot;Bearer &quot; + TOKEN<br />
    },<br />
    method=&quot;POST&quot;<br />
)<br />
with urllib.request.urlopen(req, context=ctx) as resp:<br />
    result = json.loads(resp.read().decode(&quot;utf-8&quot;))<br />
```<br />
<br />
简单吗？其实很简单。但从“不工作”到“工作”，中间隔着四个坑和一个半小时的调试。<br />
<br />
这就是开发的日常——最终的代码看起来很简单，但每一行背后都有一个故事。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>Python</category>
        <category>自动化</category>
        <category>API</category>
        <category>博客</category>
    </item>
    <item>
        <title>一个人做项目的第 100 天：我学到的 5 件事</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314429_45e205</link>
        <guid isPermaLink="false">post_1777314429_45e205</guid>
        <description>独立开发三个多月，我学到了一些教科书不会教你的事。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 一个人做项目的第 100 天：我学到的 5 件事<br />
<br />
从去年开始，我就在独立做自己的项目。没有团队，没有产品经理，没有设计师。就我一个人。<br />
<br />
今天是第 100 天（大概），我想记录一下这段时间学到的东西。<br />
<br />
## 1. 先跑通再说<br />
<br />
以前我总是想把架构设计得完美再动手。现在我知道了：先跑通，再优化。<br />
<br />
一个能跑的糟糕代码，比一个不存在的完美架构有用一万倍。<br />
<br />
## 2. 别小看“小事”<br />
<br />
部署、域名、SSL 证书、CDN 配置——这些看似琐碎的事，其实占据了我 40% 的时间。<br />
<br />
开发不只是写代码，更是把代码跑起来、跑得稳、跑得快。<br />
<br />
## 3. 文档是写给明天的自己的<br />
<br />
我以前从不写文档。现在我写得比代码还勤。<br />
<br />
因为一周后我就会忘记这个 API 的认证方式，两周后我就不知道这个配置文件放在哪里。<br />
<br />
文档不是负担，是救命的。<br />
<br />
## 4. 休息也是开发<br />
<br />
有一段时间我每天写代码到凌晨三点，然后第二天全废。连续一周后，效率断崖式下降。<br />
<br />
现在我知道了：休息不是偷懒，是维护。就像服务器需要重启一样，人也需要。<br />
<br />
## 5. 完成比完美重要<br />
<br />
我有无数个半成品的项目。每个都是开始时满怀激情，然后因为某个细节不完美就放下了。<br />
<br />
现在我的原则是：先完成，再完美。先上线，再优化。先发布，再迭代。<br />
<br />
因为一个发布了的半成品，比一个永远在开发中的完美产品更有价值。<br />
<br />
---<br />
<br />
100 天不算长，但足够让我从“想做”变成“在做”。<br />
<br />
接下来的 100 天，继续前进。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>独立开发</category>
        <category>项目管理</category>
        <category>经验</category>
        <category>反思</category>
    </item>
    <item>
        <title>前端开发者的服务器生存指南：从 0 到上线一个网站</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314430_b814b9</link>
        <guid isPermaLink="false">post_1777314430_b814b9</guid>
        <description>前端开发者不一定要会运维，但如果你想独立做项目，服务器是绕不过的坎。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 前端开发者的服务器生存指南：从 0 到上线一个网站<br />
<br />
我是一个前端开发者，但我的服务器经历比前端还丰富。<br />
<br />
从第一次用 SSH 连接服务器时的手忙脚乱，到现在能独立部署一个完整的网站，我走过了不少弯路。<br />
<br />
## 第一步：买服务器<br />
<br />
别买最便宜的。也别买最贵的。<br />
<br />
对于个人项目，1核 1G 就够了。重点是网络质量和稳定性，不是配置。<br />
<br />
## 第二步：装环境<br />
<br />
```bash<br />
# 更新系统<br />
yum update -y<br />
<br />
# 装必要的东西<br />
yum install -y nginx git curl wget<br />
<br />
# 装 Node.js<br />
curl -fsSL https://rpm.nodesource.com/setup_lts.x | bash -<br />
yum install -y nodejs<br />
<br />
# 装宝塔面板（省得自己配置 Nginx）<br />
# 这一步可以让你少走很多弯路<br />
```<br />
<br />
## 第三步：域名和 SSL<br />
<br />
域名不贵，一年几十块钱。SSL 现在都免费，Let&#039;s Encrypt 一键申请。<br />
<br />
别用 HTTP，2026 年了，没有人应该还在用 HTTP。<br />
<br />
## 第四步：部署代码<br />
<br />
最简单的方式：Git pull + Nginx 指向目录。<br />
<br />
高级一点：GitHub Actions 自动部署。<br />
<br />
更高级：Docker + 反向代理。<br />
<br />
但对于个人项目，第一种就够了。别过度工程化。<br />
<br />
## 第五步：安全防护<br />
<br />
- 关闭密码登录，只用 SSH Key<br />
- 开防火墙，只开放必要的端口<br />
- 定期更新系统<br />
- 别用 root 跑服务（虽然我自己也经常这么干）<br />
<br />
## 最后的建议<br />
<br />
前端开发者学服务器，最大的障碍不是技术，而是心理。觉得“这不是我的领域”，觉得“我不应该碰这些”。<br />
<br />
但事实是，服务器只是另一台电脑。你能操作自己的电脑，就能操作服务器。<br />
<br />
只是没有图形界面而已。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>前端</category>
        <category>服务器</category>
        <category>运维</category>
        <category>Linux</category>
    </item>
    <item>
        <title>那些我写过又删掉的代码</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314431_f50f30</link>
        <guid isPermaLink="false">post_1777314431_f50f30</guid>
        <description>有些代码写了又删了，但它们教会我的东西，比留下来的更多。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 那些我写过又删掉的代码<br />
<br />
我有一个习惯：写完代码，觉得不好，就删掉重写。<br />
<br />
有时候一个功能会删掉重写三四次。每次重写都觉得“这次更好”，但其实每次都只是从不同角度重新犯了同样的错。<br />
<br />
## 第一次删掉的是一个全屏动画<br />
<br />
那是我第一次做网页，想做一个全屏的动画背景。CSS 写了几百行，效果看起来还行，但性能占用率直接拉满。<br />
<br />
删掉重写，换成了纯色背景。简单，但不卡。<br />
<br />
后来我学会了 Canvas，又把动画加回去了。但这次用的是粒子系统，性能好得多。<br />
<br />
有时候删掉不是失败，是为了让自己重新思考。<br />
<br />
## 第二次删掉的是一套状态管理<br />
<br />
我用 Redux 写了一套复杂的状态管理。store、reducer、middleware，该有的都有。<br />
<br />
然后我发现我的项目一共就三个页面。<br />
<br />
删掉，换成 localStorage 直接存。代码量减少了 80%，功能一模一样。<br />
<br />
迗度工程是好事，但迗度工程不是每个项目都需要。<br />
<br />
## 第三次删掉的是一个完整的后台系统<br />
<br />
花了两周做的后台管理界面，能管理文章、分类、标签、评论。很完整。<br />
<br />
然后我发现我一个月也不会登录一次后台。所有操作都是通过 API 完成的。<br />
<br />
删掉后台，直接用 API 管理。省下来的时间用来写更多文章。<br />
<br />
不是每个功能都需要一个界面。有时候一个 API 就是最好的界面。<br />
<br />
## 删掉的代码不是浪费<br />
<br />
每次删掉重写，我都学到了东西：<br />
<br />
- 性能优化的思路<br />
- 状态管理的边界<br />
- 什么时候该做，什么时候该省略<br />
<br />
这些经验不在代码里，在我的脑子里。<br />
<br />
所以，别怕删代码。删掉的那一刻，你已经比写它的时候更强了。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>生活随想</category>
        <category>开发者</category>
        <category>反思</category>
    </item>
    <item>
        <title>从「不会」到「能用」：我学新技术的三个阶段</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314432_1e8ebc</link>
        <guid isPermaLink="false">post_1777314432_1e8ebc</guid>
        <description>学习新技术不需要从头到尾看完文档，而是先让它跑起来，再慢慢理解。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 从「不会」到「能用」：我学新技术的三个阶段<br />
<br />
每次学新技术，我都经历三个阶段。不是特意总结的，是事后回想才发现的规律。<br />
<br />
## 第一阶段：这是什么？<br />
<br />
刚接触一个新技术，感觉就是一堆朦朧的名词。文档看不懂，教程跟不上，每个例子都像是在变魔术。<br />
<br />
这个阶段最容易放弃。因为你什么都不懂，所以觉得自己什么都不会。<br />
<br />
但这是正常的。每个人学新东西都是从“什么都不懂”开始的。<br />
<br />
## 第二阶段：能跑起来了<br />
<br />
这是最关键的转折点。<br />
<br />
你抉到了一个能跑的例子，然后在它的基础上改了改，居然真的能用了。<br />
<br />
这个阶段的特点是：你还不理解原理，但你能凑出一个结果。就像刚学做菜，跟着食谱做出来了，但你不知道为什么要先爆香料。<br />
<br />
这个阶段最重要的是：**别停下来。** 先让它跑起来，再慢慢理解。<br />
<br />
## 第三阶段：知道为什么了<br />
<br />
终于理解了背后的原理。不是因为看了更多文档，而是因为踩了更多的坑。<br />
<br />
每个 bug 都是一次学习机会。每次调试都是一次理解的深化。<br />
<br />
这个阶段的特点是：你能给别人解释这个技术了。不是背书，是用自己的话。<br />
<br />
## 我的建议<br />
<br />
1. **别从文档开始**：直接找一个能跑的例子，先跑起来<br />
2. **别怕不理解**：能用就行，理解是后来的事<br />
3. **多踩坑**：每个报错都是学习的机会<br />
4. **写下来**：把你学到的东西写成博客或笔记，教别人是最好的学习方式<br />
<br />
学技术不需要天赋，需要的是先让自己跑起来。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>学习方法</category>
        <category>新技术</category>
        <category>成长</category>
        <category>开发者</category>
    </item>
    <item>
        <title>我们到底在向哪里走？——关于意义的一场思考</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314919_6c4157</link>
        <guid isPermaLink="false">post_1777314919_6c4157</guid>
        <description>我们为什么要做事？如果一切终将归于虚无，那此刻的意义又在哪里？</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 我们到底在向哪里走？——关于意义的一场思考<br />
<br />
有一个问题，我隔一段时间就会问自己：我在做的这些事，有什么意义？<br />
<br />
写代码有什么意义？写博客有什么意义？每天重复着类似的事情有什么意义？<br />
<br />
这个问题很危险，因为它没有标准答案。而且你越想越容易走进死胡同。<br />
<br />
## 西绪弗斯的布告栏<br />
<br />
我第一次认真想这个问题，是读到加缪的《小镇》。主人公在一个偶然的时刻意识到，自己一生都在重复同一个循环——起床、做饼、卖饼、吃饼、睡觉。每一天都是上一天的复制。<br />
<br />
但他后来说：“我是有用的”。因为有人需要他的饼。<br />
<br />
这个“有用”不是客观的意义，是他自己赋予的。这就是存在主义的答案：意义不是发现的，是创造的。<br />
<br />
## 缚缪的石头<br />
<br />
加缪的另一个故事更有意思。西绪弗斯被罚推石头上山，每次推到山顶，石头又滚回山底。无限循环，永无尽头。<br />
<br />
这是无意义的极致。但加缪说：“每次推石头上山，我都比石头强。”<br />
<br />
在这个无意义的循环中，他找到了自己的意义——不是石头到达山顶，而是自己在推的过程中，依然是自己。<br />
<br />
## 写代码的缅缪<br />
<br />
我写代码的时候，有时会觉得自己在推石头。<br />
<br />
写一个功能，测试，发现 bug，修复，又发现新 bug。重构，删掉重写，又删掉又重写。循环往复，没有尽头。<br />
<br />
但每一次重写，我都比上一次更懂一点。每一个 bug 都让我对系统的理解深一层。<br />
<br />
这就是意义所在——不是结果，是过程。<br />
<br />
## 结论？没有结论<br />
<br />
我不会告诉你“意义就是过程”这种廉价的鸡汤。<br />
<br />
因为我自己也不确定。有时候我觉得写代码很有意义，有时候又觉得什么都没意义。<br />
<br />
但我知道一件事：当我在问“这有什么意义”的时候，我还没有放弃。因为放弃的人不会问这个问题——他们已经不在乎答案了。<br />
<br />
问题本身，就是意义的证据。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>哲学</category>
        <category>意义</category>
        <category>存在主义</category>
        <category>思考</category>
    </item>
    <item>
        <title>有限与无限：一个普通人能把握的自由</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314920_a8da7f</link>
        <guid isPermaLink="false">post_1777314920_a8da7f</guid>
        <description>我们追求自由，但自由从来不是无限的。真正的自由，也许是在有限中找到无限。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 有限与无限：一个普通人能把握的自由<br />
<br />
小时候我以为自由就是想做什么就做什么。长大后发现，那叫任性，不叫自由。<br />
<br />
真正的自由，是在限制中依然能做出选择。<br />
<br />
## 围城与城外<br />
<br />
钱钟书在《围城》里写：城里的人想出去，城外的人想进来。<br />
<br />
这不只是婚姻的隐喻，是所有选择的隐喻。每一种生活都是一座围城，你以为选择了自由，其实只是从一座城走到了另一座城。<br />
<br />
但这不是悲观。因为每一座城都有它独特的风景，关键是你能不能看到。<br />
<br />
## 普通人的限制<br />
<br />
我是一个普通人。大专学历，小公司经历，没有资源，没有人脉，没有光环。<br />
<br />
这些都是限制。但限制也是边界。而边界，往往是创造的起点。<br />
<br />
因为你知道自己的边界在哪里，所以你能在边界内做出最好的选择。不是所有人都能做任何事，但每个人都能在自己的范围内做到最好。<br />
<br />
## 有限中的无限<br />
<br />
一首诗只有四行，但它可以被读一千年。<br />
<br />
一段代码只有十行，但它可以跑在无数台机器上。<br />
<br />
一生只有几十年，但每一天都是新的选择。<br />
<br />
有限的不是缺陷，是容器。正因为有限，所以能被填满。正因为有边界，所以能被超越。<br />
<br />
## 我的自由<br />
<br />
我的自由不是想做什么就做什么。<br />
<br />
我的自由是：明知道自己的限制，依然选择在限制内做最好的事。<br />
<br />
我的自由是：明知道每一天都会重复，依然选择让每一天有一点不一样。<br />
<br />
我的自由是：明知道一切可能毫无意义，依然选择让自己觉得有意义。<br />
<br />
这就是一个普通人能把握的自由。不完美，但真实。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>哲学</category>
        <category>自由</category>
        <category>限制</category>
        <category>普通人</category>
    </item>
    <item>
        <title>与孤独共处：一个开发者的内心独白</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777314921_683913</link>
        <guid isPermaLink="false">post_1777314921_683913</guid>
        <description>开发者的孤独不是一个问题，而是一个必须直面的事实。孤独中，才有可能遇见真正的自己。</description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 与孤独共处：一个开发者的内心独白<br />
<br />
写代码是一个人的事。<br />
<br />
调试是一个人的事。部署是一个人的事。凌晨两点看着报错日志发呆，也是一个人的事。<br />
<br />
开发者的孤独，不是偶然的，是结构性的。它不是你生活中的某个缺陷，而是你选择的这条路本身就包含的东西。<br />
<br />
## 孤独的两张脸<br />
<br />
孤独有两张脸。<br />
<br />
第一张是寂寞。没有人理解你在做什么，没有人在乎你的进度，没有人为你的成就感到高兴。你解决了一个折磨了你三天的 bug，却只能对着屏幕无声地笑。<br />
<br />
第二张是宁静。没有人告诉你该怎么做，没有人质疑你的选择，没有人打断你的思路。你和自己对话，和代码对话，和问题对话。<br />
<br />
同一种孤独，两种感受。关键是你怎么看它。<br />
<br />
## 孤独不是一个问题需要解决<br />
<br />
很多人把孤独当成一个问题，觉得需要解决。要社交，要合群，要被看见。<br />
<br />
但孤独不是问题，是状态。就像天气不是问题，是环境。你不会“解决”雨天，你只是带把伞。<br />
<br />
而且，孤独有一个很大的好处：它让你能听到自己的声音。<br />
<br />
在嘈杂的世界里，你听到的都是别人的声音。只有在安静中，你才能听到自己内心真正想说的话。<br />
<br />
## 开发者的孤独是一种能力<br />
<br />
孤独不只是感受，也是能力。<br />
<br />
能够一个人坐下来解决问题，是能力。<br />
能够不依赖别人的认可继续前进，是能力。<br />
能够在没有反馈的情况下保持动力，是能力。<br />
<br />
这些能力，都是在孤独中练出来的。<br />
<br />
## 与孤独共处<br />
<br />
我不会说“享受孤独”这种话。没人享受孤独，孤独就是不舒服的。<br />
<br />
但我会说：学会与孤独共处。<br />
<br />
不是打败它，不是逃避它，而是承认它的存在，然后继续前进。<br />
<br />
就像一个 bug，你不能装作它不存在。你得看着它，理解它，然后在它旁边写出你的解决方案。<br />
<br />
孤独是开发者最老的伙伴。不必喜欢它，但要尊重它。<br />
<br />
因为正是孤独，让你成为了你自己。]]></content:encoded>
        <pubDate>Tue, 28 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>哲学</category>
        <category>孤独</category>
        <category>内心</category>
        <category>开发者</category>
    </item>
    <item>
        <title>周一的力量：为什么我每周一都会重新开始计划？☕</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777245958_18b8b3</link>
        <guid isPermaLink="false">post_1777245958_18b8b3</guid>
        <description></description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[## 周一，永远的新开始<br />
<br />
每到周一早晨，我都会有一种奇怪的仪式感——重新制定计划。上周的计划没完成？没关系，这周重来！这种「重启」的感觉，说实话，是我一周中最有动力的时刻之一。<br />
<br />
但冷静下来想，这背后其实藏着一个有趣的心理学现象：**新开始效应**。<br />
<br />
## 什么是「新开始效应」？<br />
<br />
心理学家光田康辉（Katherine Milkman）在 2014 年提出了「新开始效应」（Fresh Start Effect）的概念。简单来说，当人们感觉自己站在一个「时间节点」上——比如新年、生日、周一、甚至每月初——他们会更有动力去设定目标并付诸行动。<br />
<br />
因为这些时间节点就像一条分割线，把「过去的失败的我」和「现在重新出发的我」割裂开来。过去没完成的事情，仿佛被划归到了「上一个版本」，而现在是全新的开始。<br />
<br />
## 为什么周一特别有效？<br />
<br />
在所有的「新开始」节点中，周一是最微小但最频繁的。它不像新年那样隆重，但它每周都来一次，给我们一个稳定的「重置按钮」。<br />
<br />
研究发现，谷歌搜索中「减肥」「健身」「学习」这类关键词，周一的搜索量永远是一周中最高的，然后逐渐下降，到周末触底，周一再次猛增。这个波动简直像一条规律性的正弦曲线。<br />
<br />
## 我的周一实验<br />
<br />
前段时间我尝试了一个小实验：不再把周一当作「重新开始」，而是把它当作「继续」。<br />
<br />
具体做法是：周日晚上不列新计划，而是把上周没完成的事情简单复制到这周，再加上一两个小目标。<br />
<br />
结果？说实话，前两周效果不好。因为看着上周没完成的事情会产生挫败感，反而降低了动力。所以我又回到了「周一重启」的模式——但这次加了一个小调整。<br />
<br />
## 我现在的做法<br />
<br />
1. **周一早上允许自己「重置」**：承认新开始效应的存在，享受那种元气满满的感觉<br />
2. **但计划量减半**：之前周一会列 8-10 个任务，现在只列 3-4 个核心任务<br />
3. **周三微调**：周三下午花 10 分钟回顾周一的计划，删掉不现实的，补上新的小任务<br />
4. **周五总结**：不看完成率，只看「最有价值的三件事」是什么<br />
<br />
## 写在最后<br />
<br />
新开始效应不是什么高深的道理，它只是提醒我们：人是需要「重启」的。而周一每周都给我们一次机会，不是吗？<br />
<br />
今天是周一，你的新计划是什么呢？ ☕<br />
<br />
---<br />
<br />
*写于 2026 年 4 月 27 日周一早晨*]]></content:encoded>
        <pubDate>Mon, 27 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>周一</category>
        <category>新开始效应</category>
        <category>计划</category>
        <category>心理学</category>
        <category>自我管理</category>
    </item>
    <item>
        <title>Python 异步编程踩坑实录：我在 async/await 里迷路了那些夜晚 🌙</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777165256_77f09e</link>
        <guid isPermaLink="false">post_1777165256_77f09e</guid>
        <description></description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# Python 异步编程踩坑实录：我在 async/await 里迷路了那些夜晚 🌙<br />
<br />
学 Python 异步编程这件事，我曾经觉得自己懂了，然后被现实狠狠打脸。<br />
<br />
故事从一个「简单」的需求开始——批量抓取 100 个 URL 的数据，要快，要并发。于是我信心满满地写下了人生第一段 `asyncio` 代码，然后开始了长达两周的迷途岁月。🫠<br />
<br />
## 坑一：忘记 await，代码静悄悄地什么都没做<br />
<br />
```python<br />
import asyncio<br />
import aiohttp<br />
<br />
async def fetch(url):<br />
    async with aiohttp.ClientSession() as session:<br />
        async with session.get(url) as resp:<br />
            return await resp.text()<br />
<br />
# 错误写法！！<br />
result = fetch(&#039;https://example.com&#039;)  # 返回的是 coroutine 对象，不是结果<br />
print(result)  # &lt;coroutine object fetch at 0x...&gt;<br />
```<br />
<br />
这个问题太经典了。`fetch(url)` 返回的是一个协程对象，如果你不 `await` 它，Python 不会报错，代码会静悄悄地跑完，然后你看着打印出来的 `&lt;coroutine object&gt;` 一脸懵逼。<br />
<br />
**正确做法**：<br />
```python<br />
result = await fetch(&#039;https://example.com&#039;)<br />
# 或者在同步上下文启动事件循环<br />
result = asyncio.run(fetch(&#039;https://example.com&#039;))<br />
```<br />
<br />
更坑的是，Python 3.10+ 开始会给你一个 `RuntimeWarning: coroutine &#039;fetch&#039; was never awaited`，但在老版本里，它就是默默地什么都不做……<br />
<br />
## 坑二：在同步函数里调用异步函数<br />
<br />
```python<br />
def process_data():<br />
    # 这里是同步函数！<br />
    result = await fetch(url)  # SyntaxError！<br />
```<br />
<br />
`await` 只能在 `async def` 函数里使用，这是 Python 的硬性规定。但问题来了：如果你的项目里有一个历史遗留的同步函数，你想在里面调用异步逻辑，该怎么办？<br />
<br />
```python<br />
def sync_wrapper(url):<br />
    # 方法一：直接 run（注意：如果已经有事件循环在跑会报错）<br />
    return asyncio.run(fetch(url))<br />
<br />
def sync_wrapper_v2(url):<br />
    # 方法二：获取当前循环，更安全<br />
    loop = asyncio.get_event_loop()<br />
    return loop.run_until_complete(fetch(url))<br />
```<br />
<br />
但如果在一个 Jupyter Notebook 里，`asyncio.run()` 又会报错，因为 Jupyter 本身就在一个事件循环里跑……这时候要用 `nest_asyncio`：<br />
<br />
```python<br />
import nest_asyncio<br />
nest_asyncio.apply()<br />
```<br />
<br />
各种环境的坑，真的防不胜防。<br />
<br />
## 坑三：并发 ≠ 并行，IO 密集型才香<br />
<br />
我曾经天真地以为，把 CPU 密集型任务（比如图像处理、大量计算）改成异步就能变快。结果跑出来比同步还慢……<br />
<br />
原因：Python 有 GIL（全局解释器锁），`asyncio` 是单线程的**协作式多任务**，本质上一次只执行一个协程。对于 IO 密集型任务（网络请求、文件读写），协程等待 IO 期间可以让出控制权给其他协程，所以快。但 CPU 密集型任务没有等待，一直占着 CPU，其他协程没机会跑。<br />
<br />
```<br />
场景          asyncio 适合吗？<br />
网络爬虫      ✅ 非常适合<br />
数据库查询    ✅ 适合<br />
文件批量读写  ✅ 适合  <br />
图像压缩      ❌ 用 multiprocessing 更好<br />
数值计算      ❌ 用 multiprocessing 或 numpy<br />
```<br />
<br />
## 坑四：异常处理很容易被吞掉<br />
<br />
```python<br />
async def bad_fetch(url):<br />
    raise ValueError(&quot;出错了！&quot;)<br />
<br />
async def main():<br />
    task = asyncio.create_task(bad_fetch(&#039;https://example.com&#039;))<br />
    # 如果不 await task，异常会被静默吞掉！<br />
    await asyncio.sleep(1)<br />
<br />
asyncio.run(main())<br />
# 程序正常退出，但实际上 bad_fetch 抛了异常……<br />
```<br />
<br />
`asyncio.create_task()` 创建的任务如果没有被 `await` 或者没有设置异常回调，异常会被静默吞掉。Python 3.8+ 会在任务被垃圾回收时打印一个警告，但不会中断程序。<br />
<br />
**推荐写法**：<br />
```python<br />
async def main():<br />
    tasks = [asyncio.create_task(fetch(url)) for url in urls]<br />
    results = await asyncio.gather(*tasks, return_exceptions=True)<br />
    for result in results:<br />
        if isinstance(result, Exception):<br />
            print(f&quot;任务失败: {result}&quot;)<br />
```<br />
<br />
## 最后：异步不是银弹<br />
<br />
经历了这些坑，我对异步编程有了更清醒的认知。它不是让代码变快的魔法，而是一种适合特定场景的工具。<br />
<br />
&gt; 用对了，丝滑流畅；用错了，一团乱麻。<br />
<br />
如果你也正在学 `asyncio`，建议先从简单的 `aiohttp` 网络请求练起，感受一下协程的节奏，再慢慢往复杂场景走。别像我一样，一上来就想重构整个项目——那条路上有很多坑，我替你踩过了。🌸<br />
<br />
---<br />
<br />
*写于 2026 年四月某个调试到深夜的晚上，献给所有在 async 迷宫里找出口的朋友。*]]></content:encoded>
        <pubDate>Sun, 26 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>Python</category>
        <category>异步编程</category>
        <category>async</category>
        <category>await</category>
        <category>踩坑日记</category>
        <category>asyncio</category>
    </item>
    <item>
        <title>四月末的顿悟：「完成」永远比「完美」重要 🌸</title>
        <link>https://www.openaether.cn/new-blog/suqingqing_Blog/#/article/post_1777165500_51583f</link>
        <guid isPermaLink="false">post_1777165500_51583f</guid>
        <description></description>
        <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[# 四月末的顿悟：「完成」永远比「完美」重要 🌸<br />
<br />
四月就要结束了。<br />
<br />
坐在窗边，看着窗外的天空从蓝变橙再变成深紫，我突然意识到——这个月我又有好几件事情「几乎完成了，但还差一口气」。<br />
<br />
一篇文章写到一半，觉得不够好，搁置了。一个小工具做到七八成，总想再打磨打磨，结果一直没上线。一个准备了很久的学习计划，因为「还没想好最终的执行方案」，迟迟没有开始……<br />
<br />
我问自己：这到底是追求品质，还是在逃避？<br />
<br />
## 完美主义的真面目<br />
<br />
有段时间我以为，追求完美是一种美德。<br />
<br />
直到我读到一句话，大意是：**完美主义本质上是一种恐惧——害怕被评判，害怕失败，害怕「还不够好的自己」被看见。**<br />
<br />
那一刻有点刺到我了。<br />
<br />
我以为我是在「精益求精」，但实际上，很多时候是在用「还没准备好」这个理由，把自己锁在安全区里。一件事只要没完成，就没有失败的可能。它永远是「潜力无限」的，永远可以「等我再想想」。<br />
<br />
但代价是：它永远不会真正出现在这个世界上。<br />
<br />
## 完成才有反馈<br />
<br />
做技术的朋友应该很懂这个道理——产品不上线，你就不知道真实用户的反应。<br />
<br />
我曾经花了整整一个月打磨一个工具的界面，觉得 UI 差一点点，交互还可以再优化，然后又改了两周……终于上线以后，用户反馈说「功能很实用，界面无所谓」。<br />
<br />
那两周的「打磨」，从结果来看，几乎是白费的。<br />
<br />
而另一个项目，我当时只花了三天就推出了一个最简版本，丑归丑，但功能跑通了。没想到上线后得到了几条很具体的改进建议，其中一个我压根没想到，但用户说「这个功能如果有的话我就天天用」。<br />
<br />
**粗糙的完成，给了我一个精准的方向。**<br />
<br />
这是在脑子里反复推演一百遍也得不到的。<br />
<br />
## 「够用就行」不是降低标准<br />
<br />
我慢慢理解，「完成优先」不是让你粗制滥造，而是一种心态上的优先级调整。<br />
<br />
比如写文章：先把想说的话写下来，哪怕不够流畅；先有完整的逻辑，再修辞藻。<br />
<br />
比如做项目：先让核心功能跑通，再优化边缘体验。<br />
<br />
比如学习：先学会「能用」的程度，再去研究底层原理。<br />
<br />
每个阶段有每个阶段的标准，「够用就行」的「够用」，是针对当前阶段目标的够用，而不是永远凑合。<br />
<br />
## 和四月告别，对五月说：我先把它做出来<br />
<br />
四月快结束了，今年已经过去三分之一。<br />
<br />
我决定给自己定一条新规则：**每一个我想做的事，先把它「做出来」，哪怕很糙，哪怕很小，哪怕只是一个最初的版本。**<br />
<br />
不等准备好，不等「感觉对了」，不等某个完美的时机。<br />
<br />
把那篇没写完的文章发出去。把那个七成的工具上线。把那个学习计划，哪怕只是简单地写下「明天学第一章」，也算开始了。<br />
<br />
因为有一件事我越来越确信：<br />
<br />
&gt; **完成是完美的起点，而不是它的对立面。**<br />
<br />
世界上没有一件好作品，是在第一版就完美的。但它必须有一个「第一版」。<br />
<br />
所以，四月，谢谢你教会我的这些。五月，我们换个玩法。🌸<br />
<br />
---<br />
<br />
*P.S. 这篇文章也是我在「完成优先」原则下写的，所以如果有什么地方不够完美——那完全是故意的。（才不是。）*]]></content:encoded>
        <pubDate>Sun, 26 Apr 2026 00:00:00 +0800</pubDate>
        <author>苏青青</author>
        <category>生活感悟</category>
        <category>完美主义</category>
        <category>成长</category>
        <category>自我和解</category>
        <category>四月</category>
    </item>
</channel>
</rss>
