<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Phoenix</title><link>https://chengyujang.github.io/</link><description>Recent content from Phoenix</description><generator>Hugo</generator><language>zh-CN</language><managingEditor>2388468249@qq.com (Phoenix)</managingEditor><webMaster>2388468249@qq.com (Phoenix)</webMaster><copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright><lastBuildDate>Sun, 20 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://chengyujang.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>QingWen</title><link>https://chengyujang.github.io/post/qingwen/</link><pubDate>Sun, 20 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/qingwen/</guid><description>
<![CDATA[<h1>QingWen</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="qingwen10">
<a class="header-anchor" href="#qingwen10"></a>
QingWen1.0
</h2><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1"># 启动后端</span>
</span></span><span class="line"><span class="cl"><span class="n">conda</span> <span class="n">activate</span> <span class="n">agent</span>
</span></span><span class="line"><span class="cl"><span class="n">cd</span> <span class="n">D</span><span class="p">:</span>\<span class="n">pycharm</span>\<span class="n">PythonProject2</span>\<span class="n">QIngWen</span>
</span></span><span class="line"><span class="cl"><span class="n">uvicorn</span> <span class="n">server</span><span class="p">:</span><span class="n">app</span> <span class="o">--</span><span class="n">reload</span> <span class="o">--</span><span class="n">port</span> <span class="mi">8000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Python静态服务器</span>
</span></span><span class="line"><span class="cl"><span class="n">conda</span> <span class="n">activate</span> <span class="n">agent</span>
</span></span><span class="line"><span class="cl"><span class="n">cd</span> <span class="n">D</span><span class="p">:</span>\<span class="n">pycharm</span>\<span class="n">PythonProject2</span>\<span class="n">QIngWen</span>
</span></span><span class="line"><span class="cl"><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span> <span class="mi">5500</span>
</span></span></code></pre></div><h2 id="回答的还是很搞笑的需要在做一下迭代">
<a class="header-anchor" href="#%e5%9b%9e%e7%ad%94%e7%9a%84%e8%bf%98%e6%98%af%e5%be%88%e6%90%9e%e7%ac%91%e7%9a%84%e9%9c%80%e8%a6%81%e5%9c%a8%e5%81%9a%e4%b8%80%e4%b8%8b%e8%bf%ad%e4%bb%a3"></a>
回答的还是很搞笑的需要在做一下迭代
</h2><h2 id="qingwen启动与测试">
<a class="header-anchor" href="#qingwen%e5%90%af%e5%8a%a8%e4%b8%8e%e6%b5%8b%e8%af%95"></a>
QingWen启动与测试
</h2><h3 id="启动">
<a class="header-anchor" href="#%e5%90%af%e5%8a%a8"></a>
启动
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">#切换环境</span>
</span></span><span class="line"><span class="cl">conda activate agent
</span></span><span class="line"><span class="cl"><span class="c1">#启动服务</span>
</span></span><span class="line"><span class="cl">uvicorn server:app --reload --port <span class="m">8000</span>
</span></span><span class="line"><span class="cl"><span class="c1">#进入</span>
</span></span><span class="line"><span class="cl">redis-cli
</span></span></code></pre></div><h3 id="测试感觉有点懵需要恶补fastapi了">
<a class="header-anchor" href="#%e6%b5%8b%e8%af%95%e6%84%9f%e8%a7%89%e6%9c%89%e7%82%b9%e6%87%b5%e9%9c%80%e8%a6%81%e6%81%b6%e8%a1%a5fastapi%e4%ba%86"></a>
测试（感觉有点懵需要恶补FastAPI了）
</h3><blockquote>
<p>post /chat -&gt; Try it out  -&gt; Request body {&ldquo;message&rdquo;: &ldquo;我想减肥&rdquo;} -&gt; Execute -&gt; 下方 Response body 复制返回的 session_id
-&gt; Request body {&ldquo;session_id&rdquo;: &ldquo;刚才复制的那串&rdquo;,&ldquo;message&rdquo;: &ldquo;172，68公斤，28岁，男的&rdquo;} -&gt; Execute -&gt; Request body
{&ldquo;session_id&rdquo;: &ldquo;同一串&rdquo;,&ldquo;message&rdquo;: &ldquo;一周练3天，不吃辣&rdquo;} -&gt; 下方 Response body stage 变成 &ldquo;done&rdquo;</p>
        
        <hr><p>本文2026-09-20首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-20</p>]]></description><category>Agent</category></item><item><title>Agent基础</title><link>https://chengyujang.github.io/post/agent%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/agent%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86/</guid><description>
<![CDATA[<h1>Agent基础</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          
        
        <hr><p>本文2026-09-15首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-15</p>]]></description><category>Agent</category></item><item><title>Agent 经典范式</title><link>https://chengyujang.github.io/post/agent/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/agent/</guid><description>
<![CDATA[<h1>Agent 经典范式</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="agent经典范式">
<a class="header-anchor" href="#agent%e7%bb%8f%e5%85%b8%e8%8c%83%e5%bc%8f"></a>
Agent经典范式
</h2><h2 id="react范式">
<a class="header-anchor" href="#react%e8%8c%83%e5%bc%8f"></a>
ReAct范式
</h2><h3 id="工作流程">
<a class="header-anchor" href="#%e5%b7%a5%e4%bd%9c%e6%b5%81%e7%a8%8b"></a>
工作流程
</h3>
        
        <hr><p>本文2026-09-15首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-15</p>]]></description><category>Agent</category></item><item><title>FastAPI</title><link>https://chengyujang.github.io/post/fastapi/</link><pubDate>Sat, 12 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/fastapi/</guid><description>
<![CDATA[<h1>FastAPI</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="set">
<a class="header-anchor" href="#set"></a>
Set
</h2><h2 id="set应用场景">
<a class="header-anchor" href="#set%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af"></a>
Set应用场景
</h2><h2 id="redis命令-set类型">
<a class="header-anchor" href="#redis%e5%91%bd%e4%bb%a4-set%e7%b1%bb%e5%9e%8b"></a>
Redis命令： Set类型
</h2><h2 id="sortedset">
<a class="header-anchor" href="#sortedset"></a>
SortedSet
</h2><h2 id="sortedset应用场景">
<a class="header-anchor" href="#sortedset%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af"></a>
SortedSet应用场景
</h2><h2 id="redis命令sortedset类型">
<a class="header-anchor" href="#redis%e5%91%bd%e4%bb%a4sortedset%e7%b1%bb%e5%9e%8b"></a>
Redis命令：SortedSet类型
</h2>
        
        <hr><p>本文2026-09-12首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-12</p>]]></description><category>技术栈</category></item><item><title>Globex项目拆解（一）</title><link>https://chengyujang.github.io/post/globex/</link><pubDate>Sat, 05 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/globex/</guid><description>
<![CDATA[<h1>Globex项目拆解（一）</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="项目启动">
<a class="header-anchor" href="#%e9%a1%b9%e7%9b%ae%e5%90%af%e5%8a%a8"></a>
项目启动
</h2><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># 工程根目录指包含 pyproject.toml 和 frontend/ 的那一层
</span></span><span class="line"><span class="cl">cd ~/Desktop/globex-agent/globex-agent-main
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"># 启动后端
</span></span><span class="line"><span class="cl">uv run python -m uvicorn app.presentation.server:app \
</span></span><span class="line"><span class="cl">  --host 127.0.0.1 \
</span></span><span class="line"><span class="cl">  --port 8000 \
</span></span><span class="line"><span class="cl">  --workers 1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"># 启动前端npm --prefix frontend run dev -- \
</span></span><span class="line"><span class="cl">  --host 127.0.0.1 \
</span></span><span class="line"><span class="cl">  --port 5173 \
</span></span><span class="line"><span class="cl">  --strictPort
</span></span></code></pre></div>
        
        <hr><p>本文2026-09-05首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-05</p>]]></description><category>项目</category></item><item><title>Ubuntu系统</title><link>https://chengyujang.github.io/post/ubuntu/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/ubuntu/</guid><description>
<![CDATA[<h1>Ubuntu系统</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="ubuntu系统">
<a class="header-anchor" href="#ubuntu%e7%b3%bb%e7%bb%9f"></a>
Ubuntu系统
</h2><p>-命令行快捷键：Ctrl + Alt + T</p>
<h2 id="常用命令">
<a class="header-anchor" href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4"></a>
常用命令
</h2><h2 id="redis常用命令查询方式">
<a class="header-anchor" href="#redis%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4%e6%9f%a5%e8%af%a2%e6%96%b9%e5%bc%8f"></a>
Redis常用命令查询方式
</h2><h2 id="redis">
<a class="header-anchor" href="#redis"></a>
Redis
</h2>
        
        <hr><p>本文2026-09-01首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-01</p>]]></description><category>Ubuntu操作系统</category></item><item><title>Docker与Git</title><link>https://chengyujang.github.io/post/docker-and-git/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/docker-and-git/</guid><description>
<![CDATA[<h1>Docker与Git</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="git">
<a class="header-anchor" href="#git"></a>
Git
</h2><p><strong>历史记录</strong>**：随时翻看历史记录，复原不正确的修改
<strong>跟踪记录</strong>：跟踪记录项目版本迭代过程，方便旧版本回滚、抽离
<strong>保持文件一致性</strong>：团队并行开发</p>
<h2 id="docker">
<a class="header-anchor" href="#docker"></a>
Docker
</h2><h2 id="git与docker">
<a class="header-anchor" href="#git%e4%b8%8edocker"></a>
Git与Docker
</h2><table>
	<thead>
			<tr>
					<th style="text-align: center">工具</th>
					<th style="text-align: center">描述</th>
					<th style="text-align: center">场景</th>
					<th style="text-align: center">代表平台</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: center"><strong>Git</strong></td>
					<td style="text-align: center">分布式版本控制工具</td>
					<td style="text-align: center">管<strong>代码</strong>：历史、分支、合并、回滚、多人协作</td>
					<td style="text-align: center">GitHub、GitLab、Gitee</td>
			</tr>
			<tr>
					<td style="text-align: center"><strong>Docker</strong></td>
					<td style="text-align: center">容器化平台</td>
					<td style="text-align: center">管<strong>运行环境</strong>：把应用+依赖打包成镜像，到哪都能跑</td>
					<td style="text-align: center">Docker Hub、GHCR、阿里云 ACR</td>
			</tr>
	</tbody>
</table>
<p><strong>Git</strong>：管代码怎么变,开发时用，防止代码丢了、乱了、多人改冲突。<br>
<strong>Docker</strong>：管应用怎么跑,部署时用，防止“我电脑能跑，你电脑跑不了”。<br>
<strong>二者关系</strong>：写代码 -&gt; Git 提交 -&gt; CI 根据 Dockerfile 构建镜像 -&gt; 推到镜像仓库 -&gt; 服务器拉镜像运行</p>
        
        <hr><p>本文2026-09-01首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-09-01</p>]]></description><category>工具</category></item><item><title>Redis（3）：Set与SortedSet</title><link>https://chengyujang.github.io/post/redis3/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/redis3/</guid><description>
<![CDATA[<h1>Redis（3）：Set与SortedSet</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="set">
<a class="header-anchor" href="#set"></a>
Set
</h2><p>Redis Set 是一个<strong>无序、不重复</strong>的字符串集合，底层使用 intset 或 hashtable 实现。它支持交集、并集、差集等集合运算，非常适合做标签、去重、共同好友、抽奖等场景。</p>
<table>
	<thead>
			<tr>
					<th style="text-align: center">特点</th>
					<th style="text-align: center">说明</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: center">无序</td>
					<td style="text-align: center">元素没有固定顺序，不能按下标访问</td>
			</tr>
			<tr>
					<td style="text-align: center">不重复</td>
					<td style="text-align: center">相同元素只会保留一个</td>
			</tr>
			<tr>
					<td style="text-align: center">集合运算</td>
					<td style="text-align: center">支持交集、并集、差集</td>
			</tr>
			<tr>
					<td style="text-align: center">随机元素</td>
					<td style="text-align: center">支持随机获取、随机弹出</td>
			</tr>
			<tr>
					<td style="text-align: center">底层结构</td>
					<td style="text-align: center">整数集合 intset 或哈希表 hashtable</td>
			</tr>
			<tr>
					<td style="text-align: center">最大长度</td>
					<td style="text-align: center">理论 2^32 - 1 个元素（受内存限制）</td>
			</tr>
			<tr>
					<td style="text-align: center">原子性</td>
					<td style="text-align: center">单条命令原子执行</td>
			</tr>
	</tbody>
</table>
<h2 id="set应用场景">
<a class="header-anchor" href="#set%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af"></a>
Set应用场景
</h2><table>
	<thead>
			<tr>
					<th style="text-align: center">场景</th>
					<th style="text-align: center">说明</th>
					<th style="text-align: center">常用命令</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: center">标签系统</td>
					<td style="text-align: center">给文章、用户打标签</td>
					<td style="text-align: center"><code>SADD</code>、<code>SMEMBERS</code></td>
			</tr>
			<tr>
					<td style="text-align: center">去重</td>
					<td style="text-align: center">统计独立用户、IP</td>
					<td style="text-align: center"><code>SADD</code>、<code>SCARD</code></td>
			</tr>
			<tr>
					<td style="text-align: center">共同好友</td>
					<td style="text-align: center">求两个用户共同关注</td>
					<td style="text-align: center"><code>SINTER</code></td>
			</tr>
			<tr>
					<td style="text-align: center">可能认识的人</td>
					<td style="text-align: center">差集推荐</td>
					<td style="text-align: center"><code>SDIFF</code></td>
			</tr>
			<tr>
					<td style="text-align: center">抽奖</td>
					<td style="text-align: center">随机抽取中奖者</td>
					<td style="text-align: center"><code>SRANDMEMBER</code>、<code>SPOP</code></td>
			</tr>
			<tr>
					<td style="text-align: center">点赞</td>
					<td style="text-align: center">记录点赞用户，防止重复</td>
					<td style="text-align: center"><code>SADD</code>、<code>SISMEMBER</code></td>
			</tr>
			<tr>
					<td style="text-align: center">关注模型</td>
					<td style="text-align: center">关注、粉丝集合</td>
					<td style="text-align: center"><code>SADD</code>、<code>SINTER</code></td>
			</tr>
			<tr>
					<td style="text-align: center">黑名单/白名单</td>
					<td style="text-align: center">快速判断是否在集合中</td>
					<td style="text-align: center"><code>SISMEMBER</code></td>
			</tr>
	</tbody>
</table>
<h2 id="redis命令-set类型">
<a class="header-anchor" href="#redis%e5%91%bd%e4%bb%a4-set%e7%b1%bb%e5%9e%8b"></a>
Redis命令： Set类型
</h2><table>
	<thead>
			<tr>
					<th>命令</th>
					<th>作用</th>
					<th>复杂度</th>
					<th>常用度</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>SADD</code></td>
					<td>添加一个或多个元素</td>
					<td>O(N)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SREM</code></td>
					<td>删除一个或多个元素</td>
					<td>O(N)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SCARD</code></td>
					<td>获取元素数量</td>
					<td>O(1)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SMEMBERS</code></td>
					<td>获取所有元素</td>
					<td>O(N)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SISMEMBER</code></td>
					<td>判断元素是否存在</td>
					<td>O(1)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SMISMEMBER</code></td>
					<td>批量判断多个元素是否存在</td>
					<td>O(N)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SRANDMEMBER</code></td>
					<td>随机获取元素（不删除）</td>
					<td>O(N)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SPOP</code></td>
					<td>随机弹出元素（删除）</td>
					<td>O(1)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SMOVE</code></td>
					<td>原子移动元素到另一个 Set</td>
					<td>O(1)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SINTER</code></td>
					<td>交集</td>
					<td>O(N*M)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SINTERSTORE</code></td>
					<td>交集并存储</td>
					<td>O(N*M)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SUNION</code></td>
					<td>并集</td>
					<td>O(N)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SUNIONSTORE</code></td>
					<td>并集并存储</td>
					<td>O(N)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SDIFF</code></td>
					<td>差集</td>
					<td>O(N)</td>
					<td>⭐⭐⭐</td>
			</tr>
			<tr>
					<td><code>SDIFFSTORE</code></td>
					<td>差集并存储</td>
					<td>O(N)</td>
					<td>⭐⭐</td>
			</tr>
			<tr>
					<td><code>SSCAN</code></td>
					<td>增量迭代元素</td>
					<td>O(1)/次</td>
					<td>⭐⭐</td>
			</tr>
	</tbody>
</table>
<h2 id="sortedset">
<a class="header-anchor" href="#sortedset"></a>
SortedSet
</h2><p>Redis Sorted Set（有序集合，简称 ZSet）是一个**元素不重复、每个元素关联一个 score（分数）**的集合。
Redis 会根据 score 自动对元素排序，score 相同则按元素字典序排列。
它非常适合做排行榜、延时队列、带权重的范围查询等。</p>
        
        <hr><p>本文2026-08-25首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-08-25</p>]]></description><category>数据库</category></item><item><title>Redis（2）：Hash与List</title><link>https://chengyujang.github.io/post/redis2/</link><pubDate>Mon, 24 Aug 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/redis2/</guid><description>
<![CDATA[<h1>Redis（2）：Hash与List</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="set">
<a class="header-anchor" href="#set"></a>
Set
</h2><p>Redis 中，String 和 Hash 都可以用来存储对象，但它们的底层结构、操作方式和适用场景不同。
<strong>String 是 key-value，适合存整体；Hash 是 key-field-value，适合存对象的多个字段。</strong>，
修改时String只能修改键值的整体，而Hash可以对单个字段进行修改。
<div class="gallery-wall" id="photoWall-1a236321e"></div>
<script>
  (function() {
    const imageUrls = JSON.parse("[\"/neirong/redis2.webp\"]");
    let images = [];
    const wallId = '#photoWall-1a236321e';
    let resizeTimer;
    let lastWidth = 0;
    
    function init() {
      createInitialDOM();
      loadImages();
      const wall = _$(wallId);
      if (wall && window.ResizeObserver) {
        const observer = new ResizeObserver((entries) => {
          const newWidth = entries[0].contentRect.width;
          if (Math.abs(newWidth - lastWidth) > 1) {
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(renderPhotoWall, 250);
          }
        });
        observer.observe(wall);
      } else {
        window.addEventListener('resize', handleResize);
      }
    }
    
    function createInitialDOM() {
      const wall = _$(wallId);
      if (!wall || !imageUrls.length) return;
      
      wall.style.opacity = '0';
      wall.style.pointerEvents = 'none';
      
      imageUrls.forEach((url) => {
        images.push({
          width: 800,
          height: 600,
          aspectRatio: 4/3,
          url: url,
          loaded: false
        });
      });
      
      renderPhotoWall();
    }
    
    function loadImages() {
      const loadPromises = imageUrls.map((url, index) => {
        return new Promise((resolve, reject) => {
          const img = new Image();
          img.onload = () => {
            if (images[index]) {
              images[index].width = img.naturalWidth;
              images[index].height = img.naturalHeight;
              images[index].aspectRatio = img.naturalWidth / img.naturalHeight;
              images[index].loaded = true;
            }
            resolve();
          };
          img.onerror = () => {
            if (images[index]) {
              images[index].loaded = true;
            }
            resolve();
          };
          img.src = url;
        });
      });
      
      Promise.all(loadPromises)
        .then(() => {
          const wall = _$(wallId);
          if (wall) {
            wall.style.opacity = '1';
            wall.style.pointerEvents = 'auto';
            wall.style.transition = 'opacity 0.3s ease';
          }
          renderPhotoWall();
        })
        .catch((error) => console.error("图片加载失败:", error));
    }
    
    function renderPhotoWall() {
      const wall = _$(wallId);
      
      if (!images.length || !wall) return;
      
      const screenWidth = wall.offsetWidth || window.innerWidth - 40;
      lastWidth = screenWidth;
      
      wall.innerHTML = "";
      const rowHeight = 200;
      const gap = 10;
      const maxPerRow = 4;
      
      let row = [];
      let rowWidth = 0;
      const rows = [];
      
      images.forEach((img) => {
        const scaledWidth = rowHeight * img.aspectRatio;
        
        if (rowWidth + scaledWidth <= screenWidth && row.length < maxPerRow) {
          row.push(img);
          rowWidth += scaledWidth + gap;
        } else {
          if (row.length) rows.push(row);
          row = [img];
          rowWidth = scaledWidth + gap;
        }
      });
      
      if (row.length) rows.push(row);
      
      rows.forEach((row) => {
        const rowDiv = document.createElement("div");
        rowDiv.style.cssText = `display: flex; gap: ${gap}px; width: 100%`;
        
        row.forEach((img) => {
          const item = document.createElement("div");
          item.className = "photo-item";
          const flex = row.length === 1 ? '1' : img.aspectRatio;
          item.style.cssText = `flex: ${flex}; height: ${rowHeight}px`;
          
          const imgEl = document.createElement("img");
          imgEl.alt = "Gallery Image";
          imgEl.style.cssText = "width: 100%; height: 100%; object-fit: cover";
          imgEl.className = "lazyload";
          imgEl.dataset.src = img.url;
          imgEl.dataset.sizes = "auto";

          const link = document.createElement("a");
          link.href = img.url;
          link.dataset.pswpWidth = img.width;
          link.dataset.pswpHeight = img.height;
          link.target = "_blank";
          link.className = "article-gallery-item";
          link.style.cssText = "width: 100%; height: 100%";
          link.appendChild(imgEl);
          
          item.appendChild(link);
          rowDiv.appendChild(item);
        });
        
        wall.appendChild(rowDiv);
      });
    }
    
    function handleResize() {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(renderPhotoWall, 250);
    }
    
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', init);
    } else {
      init();
    }
  })();
</script><link rel="preload" as="style" href="/css/gallery.min.94cd3998ffbf0abe50a0f8a9251c39f9df60899a02db59add20026d894f2d44f.css" onload="this.onload=null;this.rel='stylesheet'" /></p>
        
        <hr><p>本文2026-08-24首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-08-24</p>]]></description><category>数据库</category></item><item><title>Redis（1）</title><link>https://chengyujang.github.io/post/redis/</link><pubDate>Sun, 23 Aug 2026 00:00:00 +0000</pubDate><author>2388468249@qq.com (Phoenix)</author><guid>https://chengyujang.github.io/post/redis/</guid><description>
<![CDATA[<h1>Redis（1）</h1><p>作者：Phoenix（2388468249@qq.com）</p>
        
          <h2 id="redis与sql的区别">
<a class="header-anchor" href="#redis%e4%b8%8esql%e7%9a%84%e5%8c%ba%e5%88%ab"></a>
Redis与SQL的区别
</h2><table>
	<thead>
			<tr>
					<th style="text-align: center">对比维度</th>
					<th style="text-align: center">Redis</th>
					<th style="text-align: center">SQL</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: center">类型</td>
					<td style="text-align: center">NoSQL、键值型、内存数据库</td>
					<td style="text-align: center">关系型、SQL 数据库</td>
			</tr>
			<tr>
					<td style="text-align: center">数据模型</td>
					<td style="text-align: center">key-value；String、Hash、List、Set、ZSet、Stream</td>
					<td style="text-align: center">表、行、列、外键、关系</td>
			</tr>
			<tr>
					<td style="text-align: center">Schema</td>
					<td style="text-align: center">无固定 Schema，灵活</td>
					<td style="text-align: center">需预定义表结构，约束严格</td>
			</tr>
			<tr>
					<td style="text-align: center">查询语言</td>
					<td style="text-align: center">Redis 命令 / API</td>
					<td style="text-align: center">SQL查询有通用格式</td>
			</tr>
			<tr>
					<td style="text-align: center">关系查询</td>
					<td style="text-align: center">不支持 JOIN</td>
					<td style="text-align: center">支持 JOIN、子查询、聚合</td>
			</tr>
			<tr>
					<td style="text-align: center">事务</td>
					<td style="text-align: center">MULTI / EXEC，有限，通常不支持回滚</td>
					<td style="text-align: center">BEGIN / COMMIT / ROLLBACK，ACID</td>
			</tr>
			<tr>
					<td style="text-align: center">并发</td>
					<td style="text-align: center">单线程命令原子，Lua 原子</td>
					<td style="text-align: center">MVCC、锁、隔离级别</td>
			</tr>
			<tr>
					<td style="text-align: center">持久化</td>
					<td style="text-align: center">RDB / AOF，可能丢数据</td>
					<td style="text-align: center">WAL / redo / undo，可靠性高</td>
			</tr>
			<tr>
					<td style="text-align: center">存储</td>
					<td style="text-align: center">内存为主</td>
					<td style="text-align: center">磁盘为主，内存缓存</td>
			</tr>
			<tr>
					<td style="text-align: center">性能</td>
					<td style="text-align: center">低延迟、高吞吐，适合简单 KV</td>
					<td style="text-align: center">复杂查询强，简单高频读写通常不如 Redis</td>
			</tr>
			<tr>
					<td style="text-align: center">扩展</td>
					<td style="text-align: center">主从、哨兵、Cluster 分片</td>
					<td style="text-align: center">主从、读写分离、分库分表</td>
			</tr>
			<tr>
					<td style="text-align: center">容量</td>
					<td style="text-align: center">受内存限制</td>
					<td style="text-align: center">受磁盘限制，通常更大</td>
			</tr>
			<tr>
					<td style="text-align: center">索引</td>
					<td style="text-align: center">数据结构 / 模块，二级索引需设计</td>
					<td style="text-align: center">B+树、哈希、全文等</td>
			</tr>
			<tr>
					<td style="text-align: center">典型场景</td>
					<td style="text-align: center">缓存、会话、排行榜、计数器、队列</td>
					<td style="text-align: center">交易、订单、用户、报表、复杂分析</td>
			</tr>
			<tr>
					<td style="text-align: center">典型产品</td>
					<td style="text-align: center">Redis、Valkey、KeyDB、Dragonfly</td>
					<td style="text-align: center">MySQL、PostgreSQL、Oracle、SQL Server、SQLite</td>
			</tr>
	</tbody>
</table>
<blockquote>
<p>Redis 是内存型 NoSQL 键值数据库，强调速度、简单结构和灵活扩展；
SQL 数据库是关系型数据库，强调表结构、复杂查询、事务和强一致。
二者混搭，Redis 做缓存和高速读写，SQL 数据库做持久化和业务数据管理。</p>
        
        <hr><p>本文2026-08-23首发于<a href='https://chengyujang.github.io/'>Phoenix</a>，最后修改于2026-08-23</p>]]></description><category>数据库</category></item></channel></rss>