<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Gwen&#39;s warm and sweet home</title>
  
  
  <link href="https://gwenliu.cn/atom.xml" rel="self"/>
  
  <link href="https://gwenliu.cn/"/>
  <updated>2026-04-12T17:35:58.150Z</updated>
  <id>https://gwenliu.cn/</id>
  
  <author>
    <name>刘高文</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Git 核心知识</title>
    <link href="https://gwenliu.cn/posts/eea73257.html"/>
    <id>https://gwenliu.cn/posts/eea73257.html</id>
    <published>2026-04-12T17:35:58.150Z</published>
    <updated>2026-04-12T17:35:58.150Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一、Git-核心概述">一、Git 核心概述</h2><h3 id="1-定位与目标">1. 定位与目标</h3><ul><li><p>分布式版本控制工具，解决4大开发痛点：备份、代码还原、协同开发、追溯提交记录</p></li><li><p>核心优势：无需联网工作（本地完整版本库）、高速、支持非线性开发（多分支）、适配超大型项目（如Linux内核）</p></li></ul><h3 id="2-与集中式工具（SVN-CVS）的区别">2. 与集中式工具（SVN/CVS）的区别</h3><table><thead><tr><th>类型</th><th>核心特点</th><th>依赖网络</th><th>代表工具</th></tr></thead><tbody><tr><td>集中式</td><td>版本库存中央服务器</td><td>必须联网</td><td>SVN、CVS</td></tr><tr><td>分布式</td><td>每人电脑都是完整版本库</td><td>无需联网</td><td>Git</td></tr></tbody></table><h3 id="3-起源">3. 起源</h3><ul><li>2005年由Linus Torvalds开发，用于解决Linux内核开发的版本管理问题</li></ul><h2 id="二、安装与环境配置">二、安装与环境配置</h2><h3 id="1-安装">1. 安装</h3><ul><li><p>下载地址：<a href="https://git-scm.com/download">https://git-scm.com/download</a></p></li><li><p>验证：右键出现「Git GUI Here」「Git Bash Here」即为成功</p></li></ul><h3 id="2-必做配置（用户身份）">2. 必做配置（用户身份）</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 设置用户名和邮箱（每次提交会关联该信息）</span></span><br><span class="line">git config --global user.name <span class="string">&quot;用户名&quot;</span></span><br><span class="line">git config --global user.email <span class="string">&quot;邮箱&quot;</span></span><br><span class="line"><span class="comment"># 查看配置</span></span><br><span class="line">git config --global user.name</span><br><span class="line">git config --global user.email</span><br></pre></td></tr></table></figure><h3 id="3-优化配置（可选）">3. 优化配置（可选）</h3><ul><li><p>别名配置（简化命令）：</p><ol><li><p>创建 <code>.bashrc</code> 文件：<code>touch ~/.bashrc</code></p></li><li><p>写入别名：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">alias</span> git-log=<span class="string">&#x27;git log --pretty=oneline --all --graph --abbrev-commit&#x27;</span> <span class="comment"># 精简日志</span></span><br><span class="line"><span class="built_in">alias</span> ll=<span class="string">&#x27;ls -al&#x27;</span> <span class="comment"># 查看目录详情</span></span><br></pre></td></tr></table></figure></li><li><p>生效：<code>source ~/.bashrc</code></p></li></ol></li><li><p>乱码解决：</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git config --global core.quotepath <span class="literal">false</span></span><br><span class="line"><span class="comment"># 编辑 git 安装目录下的 etc/bash.bashrc，添加：</span></span><br><span class="line"><span class="built_in">export</span> LANG=<span class="string">&quot;zh_CN.UTF-8&quot;</span></span><br><span class="line"><span class="built_in">export</span> LC_ALL=<span class="string">&quot;zh_CN.UTF-8&quot;</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="三、本地仓库核心操作">三、本地仓库核心操作</h2><h3 id="1-工作流程">1. 工作流程</h3><p><code>工作区（编写代码）→ 暂存区（add）→ 本地仓库（commit）</code></p><h3 id="2-关键命令">2. 关键命令</h3><table><thead><tr><th>操作</th><th>命令</th><th>说明</th></tr></thead><tbody><tr><td>初始化本地仓库</td><td><code>git init</code></td><td>在空目录执行，生成隐藏 <code>.git</code> 目录</td></tr><tr><td>查看文件状态</td><td><code>git status</code></td><td>显示工作区/暂存区变更（未跟踪/已暂存）</td></tr><tr><td>工作区→暂存区</td><td><code>git add 文件名</code> / <code>git add .</code></td><td><code>.</code> 表示所有变更文件</td></tr><tr><td>暂存区→本地仓库</td><td><code>git commit -m &quot;提交注释&quot;</code></td><td>注释必须清晰（如：“feat: 添加登录功能”）</td></tr><tr><td>查看提交日志</td><td><code>git-log</code>（别名）/ <code>git log [选项]</code></td><td>选项：–all（所有分支）、–graph（图形化）</td></tr><tr><td>版本回退</td><td><code>git reset --hard 提交ID</code></td><td>提交ID通过 <code>git-log</code> 或 <code>git reflog</code> 获取（reflog可看已删除记录）</td></tr><tr><td>忽略文件配置</td><td>创建 <code>.gitignore</code> 文件</td><td>写入忽略规则（如 <code>*.log</code>、<code>build/</code>）</td></tr></tbody></table><h2 id="四、分支操作（核心功能）">四、分支操作（核心功能）</h2><h3 id="1-分支意义">1. 分支意义</h3><p>隔离开发（新功能、Bug修复），不影响主线开发</p><h3 id="2-常用命令">2. 常用命令</h3><table><thead><tr><th>操作</th><th>命令</th><th>说明</th></tr></thead><tbody><tr><td>查看本地分支</td><td><code>git branch</code></td><td>星号标注当前分支</td></tr><tr><td>创建分支</td><td><code>git branch 分支名</code></td><td>基于当前分支创建新分支</td></tr><tr><td>创建并切换分支</td><td><code>git checkout -b 分支名</code></td><td>等价于「创建+切换」两步</td></tr><tr><td>切换分支</td><td><code>git checkout 分支名</code></td><td>切换前需提交本地变更</td></tr><tr><td>合并分支</td><td><code>git merge 待合并分支名</code></td><td>在目标分支（如master）执行</td></tr><tr><td>删除分支</td><td><code>git branch -d 分支名</code> / <code>git branch -D 分支名</code></td><td><code>-d</code> 需先合并，<code>-D</code> 强制删除</td></tr></tbody></table><h3 id="3-冲突解决">3. 冲突解决</h3><p>当两个分支修改同一文件同一行时触发：</p><ol><li><p>打开冲突文件，删除冲突标记（<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> <code>=======</code> <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>）</p></li><li><p>编辑为期望的内容</p></li><li><p>执行 <code>git add .</code>（标记冲突已解决）</p></li><li><p>执行 <code>git commit -m &quot;解决冲突&quot;</code></p></li></ol><h3 id="4-分支规范（开发必备）">4. 分支规范（开发必备）</h3><ul><li><p><code>master</code>：生产分支，线上运行代码，禁止直接修改</p></li><li><p><code>develop</code>：开发主分支，从master创建，开发完成后合并到master</p></li><li><p><code>feature/xxx</code>：功能分支，从develop创建，完成后合并回develop</p></li><li><p><code>hotfix/xxx</code>：紧急修复分支，从master创建，修复后合并到master+develop</p></li></ul><h2 id="五、远程仓库操作（协同开发）">五、远程仓库操作（协同开发）</h2><h3 id="1-常用托管平台">1. 常用托管平台</h3><ul><li><p>GitHub：<a href="https://github.com/">https://github.com/</a>（国外，开源项目首选）</p></li><li><p>码云（Gitee）：<a href="https://gitee.com/">https://gitee.com/</a>（国内，速度快）</p></li><li><p>GitLab：<a href="https://about.gitlab.com/">https://about.gitlab.com/</a>（企业内部私服）</p></li></ul><h3 id="2-前置配置（SSH免密登录）">2. 前置配置（SSH免密登录）</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="3-核心命令">3. 核心命令</h3><table><thead><tr><th>操作</th><th>命令</th><th>说明</th></tr></thead><tbody><tr><td>关联远程仓库</td><td><code>git remote add origin 远程仓库地址</code></td><td>origin为默认远程仓库名</td></tr><tr><td>查看远程仓库</td><td><code>git remote</code></td><td>显示关联的远程仓库名</td></tr><tr><td>本地→远程推送</td><td><code>git push --set-upstream origin 分支名</code></td><td>首次推送需关联分支，后续可简化为 <code>git push</code></td></tr><tr><td>远程→本地克隆</td><td><code>git clone 远程仓库地址 [本地目录]</code></td><td>本地目录可选，自动生成仓库目录</td></tr><tr><td>远程→本地拉取（合并）</td><td><code>git pull origin 分支名</code></td><td>等价于 <code>git fetch + git merge</code>，自动合并</td></tr><tr><td>远程→本地抓取（不合并）</td><td><code>git fetch origin 分支名</code></td><td>仅下载更新，不合并到工作区</td></tr></tbody></table><h3 id="4-协同冲突解决">4. 协同冲突解决</h3><ol><li><p>推送前先拉取：<code>git pull</code>（获取远程最新代码）</p></li><li><p>若触发冲突，按「本地分支冲突解决」步骤处理</p></li><li><p>解决后重新推送：<code>git push</code></p></li></ol><h2 id="六、IDEA-集成-Git（实操）">六、IDEA 集成 Git（实操）</h2><h3 id="1-配置Git路径">1. 配置Git路径</h3><ul><li>File → Settings → Version Control → Git → 选择Git安装目录下的 <code>bin/git.exe</code> → Test验证</li></ul><h3 id="2-核心操作入口">2. 核心操作入口</h3><table><thead><tr><th>操作</th><th>入口/快捷键</th></tr></thead><tbody><tr><td>初始化本地仓库</td><td>VCS → Import into Version Control → Create Git Repository</td></tr><tr><td>提交本地变更</td><td>Ctrl+K（Commit）→ 勾选文件+写注释 → Commit</td></tr><tr><td>推送到远程</td><td>Ctrl+Shift+K（Push）→ 选择分支 → Push</td></tr><tr><td>克隆远程仓库</td><td>Checkout from Version Control → Git → 输入远程地址 → Clone</td></tr><tr><td>分支操作</td><td>右下角「Git: 分支名」→ New Branch/Switch Branch</td></tr><tr><td>拉取远程更新</td><td>Ctrl+T（Update Project）→ 选择Pull</td></tr><tr><td>解决冲突</td><td>冲突文件标红 → 打开编辑 → 右键 → Add to VCS → Commit</td></tr></tbody></table><h3 id="3-关键注意事项">3. 关键注意事项</h3><ul><li><p>切换分支前必须提交本地变更</p></li><li><p>推送代码前先拉取，避免冲突</p></li><li><p>不要手动删除 <code>.git</code> 目录，否则版本记录丢失</p></li></ul><h2 id="附：核心命令速查">附：核心命令速查</h2><table><thead><tr><th>场景</th><th>命令组合</th></tr></thead><tbody><tr><td>新项目初始化</td><td><code>git init</code> → <code>git add .</code> → <code>git commit -m &quot;init&quot;</code> → <code>git remote add origin 地址</code> → <code>git push</code></td></tr><tr><td>参与已有项目</td><td><code>git clone 地址</code> → <code>git checkout 开发分支</code> → 开发 → <code>git add .</code> → <code>git commit</code> → <code>git pull</code> → <code>git push</code></td></tr><tr><td>版本回退</td><td><code>git-log</code>（查提交ID）→ <code>git reset --hard 提交ID</code></td></tr><tr><td>分支开发流程</td><td><code>git checkout -b feature/xxx</code> → 开发 → <code>git commit</code> → <code>git checkout develop</code> → <code>git merge feature/xxx</code></td></tr></tbody></table><blockquote><p>（注：文档部分内容可能由 AI 生成）</p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;一、Git-核心概述&quot;&gt;一、Git 核心概述&lt;/h2&gt;
&lt;h3 id=&quot;1-定位与目标&quot;&gt;1. 定位与目标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;分布式版本控制工具，解决4大开发痛点：备份、代码还原、协同开发、追溯提交记录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;核心优</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title></title>
    <link href="https://gwenliu.cn/posts/2ec67ab4.html"/>
    <id>https://gwenliu.cn/posts/2ec67ab4.html</id>
    <published>2026-04-12T17:35:58.122Z</published>
    <updated>2026-04-12T17:35:58.122Z</updated>
    
    <content type="html"><![CDATA[<h1>打造个人开发云端环境</h1><p>我们如果希望可随时随地通过桌面客户端、移动端或小程序等连接使用。</p><p>不受本地设备限制，满足随时开启办公、AI 开发、设计、游戏的需求。可随时切换不同规格配置的电脑，按需使用，弹性灵活的升级 和 释放。就可以选择 云主机 或 云电脑。</p><blockquote><p>本次我们选择使用门槛最低的功能最强大的 <strong>“阿里无影云电脑 + Happy Coder”</strong> 来实现在云端实现随时随地 AI 编程</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260201045344280.BkrvAqZX.png" alt="image-20260201045344280"></p><h3 id="1、云电脑是什么">1、云电脑是什么</h3><ul><li>你再也看不到主机箱了，云电脑的核心部件都跑在阿里云上，你只需要准备显示屏和键鼠就行</li><li>正因为核心部件都在云上，所以你可以随时升降电脑配置、随地跨设备使用云电脑</li><li>并且只有开机期间才需要付费</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260201040412804.BTBewn2n.png" alt="image-20260201040412804"></p><h3 id="2、云电脑的使用场景">2、云电脑的使用场景</h3><ul><li>**AI 办公 与 AI 开发：**AI 模型随时接入辅助日常办公，多环境多系统，适用与AI开发</li><li>**云上设计 / 编程：**可随时升降配置，实时感受高配电脑的丝滑设计体验</li><li><strong>AI 领域尝鲜</strong>：AI 领域发展非常迅速，几乎每天都会有新的工具</li><li>**教培学习：**教学电脑内容一键共享，省去软件文件下载、配置时间</li><li>**电竞娱乐：**云游戏一键开启畅玩《黑神话：悟空》《永劫无间》等超多云游戏</li><li>**出差办公：**出差无需携带笨重打电脑平板、手机等随时变为办公电脑</li><li>**低配机、MacBook、手机打高端游戏：**低配机随时复活变高配，MacBook、手机也畅玩 3A 大作游戏</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260201044503810.DZrHOR-u.png" alt="image-20260201044503810"></p><h3 id="3、云电脑有什么优势">3、云电脑有什么优势</h3><p>深入浅出从三个方面解读云电脑的优势：突破性能瓶颈、拓展设备功能、跨越平台限制</p><h3 id="3-1、突破性能瓶颈">3.1、突破性能瓶颈</h3><p>通过无影客户端，低配置的传统电脑也能运行大型软件 或 游戏，包括 编程 都可以。</p><blockquote><p>在编程开发、AI 大模型部署 等，都可随时升级提高配置，以满足实际需求</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260201040810890.DJ8Dx1gV.png" alt="image-20260201040810890"></p><h3 id="3-2、拓展设备功能">3.2、拓展设备功能</h3><p>主打休闲娱乐的 Pad 类设备，只要装上无影云电脑客户端，也能立刻化身为办公利器，工作休闲两不误。</p><blockquote><p>有没有发现 ？出门再也不用背电脑了！就连电视机，也可以秒变电脑。</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260201042041634.ChjlC0Kg.png" alt="image-20260201042041634"></p><h3 id="3-3、跨越平台限制">3.3、跨越平台限制</h3><p>对于仅支持限定平台的软件或游戏，云电脑可以帮你跨越这一限制。不用捣鼓麻烦的双系统 或 虚拟机，也能在 Mac 上轻松玩 3A 游戏 ！</p><blockquote><p>包括编程开发，需要用到 Linux 系统、Windows 等多平台测试开发时，随时切换省时省力</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260201042214018.DqFt4xwz.png" alt="image-20260201042214018"></p><h3 id="4、云电脑怎么用">4、云电脑怎么用</h3><p>只需安装 并 登录无影客户端，就能在客户端内一键启动云电脑。</p><ul><li>电脑端：支持 Windows 客户端、macOS 客户端</li><li>Web 端：在 Chrome、Firefox 等浏览器中支持打开 Web 端进 行登录</li><li>移动端：支持 iOS 端、Android 端</li></ul><blockquote><p>无影云电脑客户端下载地址：<a href="https://www.aliyun.com/product/wuying/download">https://www.aliyun.com/product/wuying/download</a></p></blockquote><h3 id="4-1、安装无影客户端（电脑端）">4.1、安装无影客户端（电脑端）</h3><ul><li>请根据您的本地设备类型和操作系统版本，下载对应的客户端版本；</li><li>安装成功后，即可通过客户端随时随地访问无影服务</li><li>推荐使用阿里系账号扫码登录即可</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260206210230299.CmdP0jtb.png" alt="image-20260206210230299"></p><p>选择个人版，使用支付宝登录</p><p><img src="https://www.vibevibe.cn/assets/image-20260202222641438.1v7bnasz.png" alt="image-20260202222641438"></p><p>新用户第一次注册，可免费试用一个月（学习使用完全够用）</p><p><img src="https://www.vibevibe.cn/assets/image-20260203190342789.O_dPTsaz.png" alt="image-20260203190342789"></p><p>确认领取并下单</p><ul><li>黄金款：系统盘 60G + 数据盘 40 G + 公网带宽 10 Mbps + 40 核时算力（免费赠送一个月、到期续费 9.9元/月）</li><li>240 核时算力 （免费 1年有效期）</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260203224450286.BsBCUecB.png" alt="image-20260203224450286"></p><p>设置云电脑基础信息</p><ul><li>云电脑名称：自定义一个名称（类似本地电脑的名称）</li><li>常用地：就近原则（选择距离自己城市近的节点，理论上速度更快）</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260203224822787.BMiRJgfN.png" alt="image-20260203224822787"></p><p>点击立即下单即可</p><p><img src="https://www.vibevibe.cn/assets/image-20260203230146847.DWx2ZR8K.png" alt="image-20260203230146847"></p><p>下单成功后，扫描开通免密支付</p><blockquote><p>注：自动续费可以去支付宝取消即可。不影响新注册免费用政策，后续不用也不会继续收费，不用担心</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260203235745450.BSAB05b8.png" alt="image-20260203235745450"></p><p>支付宝扫码成功后，点击 “已完成开通并授权扣款” 按钮</p><p><img src="https://www.vibevibe.cn/assets/image-20260204000019220.Da1CHc6I.png" alt="image-20260204000019220"></p><p>进入订购成功页面</p><p><img src="https://www.vibevibe.cn/assets/image-20260204000140841.DuZ_Fp54.png" alt="image-20260204000140841"></p><p>可关闭订购成功页面，进入无影云电脑客户端首页，直接点击 “连接” 按钮 即可进入云电脑</p><p><img src="https://www.vibevibe.cn/assets/image-20260204000837531.CsoPxH9u.png" alt="image-20260204000837531"></p><p>第一次进入默认是 Windows 系统，所有操作跟本地电脑一模一样</p><p><img src="https://www.vibevibe.cn/assets/image-20260204001044451.Bg0fesec.png" alt="image-20260204001044451"></p><p>注：</p><ul><li>在云电脑中安装开发环境、开发工具等与本地电脑一模一样</li><li>同时，关于 AI 编程相关工具安装 和 模型配置 同理</li></ul><h3 id="4-2、无影云电脑切换操作系统">4.2、无影云电脑切换操作系统</h3><ul><li>默认是 Windows 可随时切换 Linux 系统</li><li>也可随时切回 Windows 系统，方法同样</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260204002406928.DEacE8qZ.png" alt="image-20260204002406928"></p><p>确定后，再次确认即可切换操作系统</p><p><img src="https://www.vibevibe.cn/assets/image-20260204002601380.B9PZJGGO.png" alt="image-20260204002601380"></p><p>系统切换成功后，进入 Linux 系统</p><p><img src="https://www.vibevibe.cn/assets/image-20260204210109896.BCJxjFKd.png" alt="image-20260204210109896"></p><h3 id="4-3、安装无影客户端（移动端）">4.3、安装无影客户端（移动端）</h3><p>如果在移动设备上使用</p><ul><li>通过应用商店搜索下载安装 <strong>无影云电脑 App</strong>（管理 和 操作云电脑）</li><li>通过支付宝扫码登录后，也可以通过支付宝小程序管理 无影云电脑（只能管理不能操作云电脑）</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260204220317499.DfvjfPh2.png" alt="image-20260204220317499"></p><h3 id="4-4、云电脑开机灵活选择配置">4.4、云电脑开机灵活选择配置</h3><p>云电脑最强大一直就在于它可以在每次开机前随时选择我们需要的配置</p><table><thead><tr><th style="text-align:left"><strong>模式名称</strong></th><th style="text-align:left"><strong>CPU 核心数</strong></th><th style="text-align:left">内存</th><th style="text-align:left">GPU 显存</th><th style="text-align:left"><strong>核时算力费率</strong></th><th style="text-align:left"><strong>建议适用场景</strong></th></tr></thead><tbody><tr><td style="text-align:left"><strong>经济模式</strong></td><td style="text-align:left">4核</td><td style="text-align:left">8 GiB</td><td style="text-align:left">-</td><td style="text-align:left">4 核时算力 / 小时</td><td style="text-align:left">轻量级代码编辑、文档处理、简单脚本运行</td></tr><tr><td style="text-align:left"><strong>流畅模式</strong></td><td style="text-align:left">8核</td><td style="text-align:left">16 GiB</td><td style="text-align:left">-</td><td style="text-align:left">8 核时算力 / 小时</td><td style="text-align:left"><strong>日常 AI 开发首选</strong>。流畅运行 VS Code 和 多个 AI Agent 会话</td></tr><tr><td style="text-align:left"><strong>性能模式</strong></td><td style="text-align:left">16核</td><td style="text-align:left">32 GiB</td><td style="text-align:left">-</td><td style="text-align:left">16 核时算力 / 小时</td><td style="text-align:left">大型项目编译、多容器运行、复杂架构分析</td></tr><tr><td style="text-align:left"><strong>电竞模式</strong></td><td style="text-align:left">12核</td><td style="text-align:left">46 GiB</td><td style="text-align:left">11 GiB</td><td style="text-align:left">60 核时算力 / 小时</td><td style="text-align:left">需要 GPU 加速的任务、运行大型本地模型或图形渲染</td></tr></tbody></table><blockquote><p>试用可选择最低配置，不够用时随时切换即可（配置越高 每小时消耗的核时越多）</p></blockquote><p><img src="https://www.vibevibe.cn/assets/image-20260205223928504.Chx2hDcm.png" alt="image-20260205223928504"></p><h3 id="5、在云电脑上部署安装-Happy-Coder-实现全面上云">5、在云电脑上部署安装 Happy Coder 实现全面上云</h3><ul><li>和本地一样安装安装配置好 Claude Code 工具 与 对应的模型，保证与本地一样可以正常使用</li><li>在云电脑上安装 Happy Coder，具体步骤与本地一样</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260205194841161.CM1cS5Dj.png" alt="image-20260205194841161"></p><ul><li>安装成功后，使用 <code>happy claude</code> 选择 Mobile App 终端进行身份验证，回车确认</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260205195159053.eB7X84qa.png" alt="image-20260205195159053"></p><p>选择 ”Mobile App“ 后，会生成移动端认证二维码 和 URL 地址，进行身份验证</p><ul><li>使用 Happy 手机端 App 扫描二维码</li><li>或 手动输入 URL 进行身份验证</li></ul><p><img src="https://www.vibevibe.cn/assets/image-20260205202715658.hHiSpdRJ.png" alt="image-20260205202715658"></p><h3 id="5-1、在手机端-Happy-App-上连接云电脑终端">5.1、在手机端 Happy App 上连接云电脑终端</h3><p>打开手机端 Happy App 通过扫描二维码 或 手动输入 URL 进行身份验证，输入提示词即可连接云电脑上 Claude Code 进行项目的开发</p><p><img src="https://www.vibevibe.cn/assets/image-20260205205229841.DKbzIx5g.png" alt="image-20260205205229841"></p><p>同时云电脑端的 Claude Code 也会同步</p><p><img src="https://www.vibevibe.cn/assets/image-20260205205508549.CpC9lwcY.png" alt="image-20260205205508549"></p><h3 id="5-2、随时可接管">5.2、随时可接管</h3><ul><li>当你回到桌前，不需要在手机上点退出</li><li>只需敲击电脑键盘的<strong>任意键</strong>控制权会瞬间从手机跳回电脑终端，手机端自动进入“观察模式”</li><li>同时，控制权要再次回到手机端，只需要在 Happy App 的对话框输入指令即可，电脑终端再次回到“观察模式”</li></ul><blockquote><p>另外，云电脑还有一个好处是，直接可以通过 “无影云电脑 App” 在手机上随时操作（接管）Claude Code</p></blockquote><h3 id="5-3、在无影云电脑-App-上操控云电脑">5.3、在无影云电脑 App 上操控云电脑</h3><p><img src="https://www.vibevibe.cn/assets/image-20260205210533916.CS_QSVE3.png" alt="image-20260205210533916"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1&gt;打造个人开发云端环境&lt;/h1&gt;
&lt;p&gt;我们如果希望可随时随地通过桌面客户端、移动端或小程序等连接使用。&lt;/p&gt;
&lt;p&gt;不受本地设备限制，满足随时开启办公、AI 开发、设计、游戏的需求。可随时切换不同规格配置的电脑，按需使用，弹性灵活的升级 和 释放。就可以选择 云主机 或</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title></title>
    <link href="https://gwenliu.cn/posts/5d8a73c1.html"/>
    <id>https://gwenliu.cn/posts/5d8a73c1.html</id>
    <published>2026-04-12T17:35:58.118Z</published>
    <updated>2026-04-12T17:35:58.118Z</updated>
    
    <content type="html"><![CDATA[<h1>Redis快速入门</h1><h2 id="1-1-认识Redis">1.1.认识Redis</h2><p>Redis诞生于2009年全称是<strong>Re</strong>mote  <strong>D</strong>ictionary <strong>S</strong>erver 远程词典服务器，是一个基于内存的键值型NoSQL数据库。</p><p><strong>特征</strong>：</p><ul><li>键值（key-value）型，value支持多种不同数据结构，功能丰富</li><li>单线程，每个命令具备原子性</li><li>低延迟，速度快（基于内存、IO多路复用、良好的编码）。</li><li>支持数据持久化</li><li>支持主从集群、分片集群</li><li>支持多语言客户端</li></ul><p><strong>作者</strong>：Antirez</p><p>Redis的官方网站地址：<a href="https://redis.io/">https://redis.io/</a></p><h2 id="1-2-安装Redis">1.2.安装Redis</h2><p>大多数企业都是基于Linux服务器来部署项目，而且Redis官方也没有提供Windows版本的安装包。因此本教程中我们会基于Linux系统来安装Redis.</p><p>此处选择的Linux版本为CentOS 7.</p><h3 id="1-2-1-依赖库">1.2.1.依赖库</h3><p>Redis是基于C语言编写的，因此首先需要安装Redis所需要的gcc依赖：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install -y gcc tcl</span><br></pre></td></tr></table></figure><h3 id="1-2-2-上传安装包并解压">1.2.2.上传安装包并解压</h3><ol><li><p>Redis安装包上传到虚拟机的任意目录：</p></li><li><p>解压缩（xxx为redis版本号）：</p></li></ol><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -xzf redis-xxx.tar.gz</span><br></pre></td></tr></table></figure><ol start="3"><li>解压后进入redis目录并运行编译命令：</li></ol><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> redis-xxx</span><br><span class="line"></span><br><span class="line">make &amp;&amp; make install</span><br></pre></td></tr></table></figure><p>默认的安装路径是在 <code>/usr/local/bin</code>目录下：</p><p>该目录已经默认配置到环境变量，因此可以在任意目录下运行这些命令。其中：</p><ul><li>redis-cli：是redis提供的命令行客户端</li><li>redis-server：是redis的服务端启动脚本</li><li>redis-sentinel：是redis的哨兵启动脚本</li></ul><h3 id="1-2-3-启动">1.2.3.启动</h3><p>redis的启动方式有很多种，例如：</p><ul><li>默认启动</li><li>指定配置启动</li><li>开机自启</li></ul><h3 id="1-3-4-默认启动">1.3.4.默认启动</h3><p>安装完成后，在任意目录输入redis-server命令即可启动Redis：</p><figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-<span class="keyword">server</span></span><br></pre></td></tr></table></figure><p>这种启动属于<code>前台启动</code>，会阻塞整个会话窗口，窗口关闭或者按下<code>CTRL + C</code>则Redis停止。不推荐使用。</p><h3 id="1-3-5-指定配置启动">1.3.5.指定配置启动</h3><p>如果要让Redis以<code>后台</code>方式启动，则必须修改Redis配置文件，就在我们之前解压的redis安装包下（<code>/usr/local/src/redis-6.2.6</code>），名字叫redis.conf：</p><p>我们先将这个配置文件备份一份：</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">cp</span> redis.<span class="keyword">conf</span> redis.<span class="keyword">conf</span>.bck</span><br></pre></td></tr></table></figure><p>然后修改redis.conf文件中的一些配置：</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 允许访问的地址，默认是127.0.0.1，会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问，生产环境不要设置为0.0.0.0</span></span><br><span class="line"><span class="attr">bind</span> <span class="string">0.0.0.0</span></span><br><span class="line"><span class="comment"># 守护进程，修改为yes后即可后台运行</span></span><br><span class="line"><span class="attr">daemonize</span> <span class="string">yes </span></span><br><span class="line"><span class="comment"># 密码，设置后访问Redis必须输入密码</span></span><br><span class="line"><span class="attr">requirepass</span> <span class="string">123321</span></span><br></pre></td></tr></table></figure><p>Redis的其它常见配置：</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 监听的端口</span></span><br><span class="line"><span class="attr">port</span> <span class="string">6379</span></span><br><span class="line"><span class="comment"># 工作目录，默认是当前目录，也就是运行redis-server时的命令，日志、持久化等文件会保存在这个目录</span></span><br><span class="line"><span class="attr">dir</span> <span class="string">.</span></span><br><span class="line"><span class="comment"># 数据库数量，设置为1，代表只使用1个库，默认有16个库，编号0~15</span></span><br><span class="line"><span class="attr">databases</span> <span class="string">1</span></span><br><span class="line"><span class="comment"># 设置redis能够使用的最大内存</span></span><br><span class="line"><span class="attr">maxmemory</span> <span class="string">512mb</span></span><br><span class="line"><span class="comment"># 日志文件，默认为空，不记录日志，可以指定日志文件名</span></span><br><span class="line"><span class="attr">logfile</span> <span class="string">&quot;redis.log&quot;</span></span><br></pre></td></tr></table></figure><p>启动Redis：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进入redis安装目录 </span></span><br><span class="line"><span class="built_in">cd</span> /usr/local/src/redis-6.2.6</span><br><span class="line"><span class="comment"># 启动</span></span><br><span class="line">redis-server redis.conf</span><br></pre></td></tr></table></figure><p>停止服务：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 利用redis-cli来执行 shutdown 命令，即可停止 Redis 服务，</span></span><br><span class="line"><span class="comment"># 因为之前配置了密码，因此需要通过 -u 来指定密码</span></span><br><span class="line">redis-cli -u 123321 shutdown</span><br></pre></td></tr></table></figure><h3 id="1-3-6-开机自启">1.3.6.开机自启</h3><p>我们也可以通过配置来实现开机自启。</p><p>首先，新建一个系统服务文件：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vi /etc/systemd/system/redis.service</span><br></pre></td></tr></table></figure><p>内容如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">[Unit]</span><br><span class="line">Description=redis-server</span><br><span class="line">After=network.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">Type=forking</span><br><span class="line">ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf</span><br><span class="line">PrivateTmp=true</span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></table></figure><p>然后重载系统服务：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl daemon-reload</span><br></pre></td></tr></table></figure><p>现在，我们可以用下面这组命令来操作redis了：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 启动</span></span><br><span class="line">systemctl start redis</span><br><span class="line"><span class="comment"># 停止</span></span><br><span class="line">systemctl stop redis</span><br><span class="line"><span class="comment"># 重启</span></span><br><span class="line">systemctl restart redis</span><br><span class="line"><span class="comment"># 查看状态</span></span><br><span class="line">systemctl status redis</span><br></pre></td></tr></table></figure><p>执行下面的命令，可以让redis开机自启：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl <span class="built_in">enable</span> redis</span><br></pre></td></tr></table></figure><h2 id="1-3-Redis桌面客户端">1.3.Redis桌面客户端</h2><p>安装完成Redis，我们就可以操作Redis，实现数据的CRUD了。这需要用到Redis客户端，包括：</p><ul><li>命令行客户端</li><li>图形化桌面客户端</li><li>编程客户端</li></ul><h3 id="1-4-1-Redis命令行客户端">1.4.1.Redis命令行客户端</h3><p>Redis安装完成后就自带了命令行客户端：redis-cli，使用方式如下：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-cli [options] [commonds]</span><br></pre></td></tr></table></figure><p>其中常见的options有：</p><ul><li><code>-h 127.0.0.1</code>：指定要连接的redis节点的IP地址，默认是127.0.0.1</li><li><code>-p 6379</code>：指定要连接的redis节点的端口，默认是6379</li><li><code>-a 123321</code>：指定redis的访问密码</li></ul><p>其中的commonds就是Redis的操作命令，例如：</p><ul><li><code>ping</code>：与redis服务端做心跳测试，服务端正常会返回<code>pong</code></li></ul><p>不指定commond时，会进入<code>redis-cli</code>的交互控制台：</p><h3 id="1-4-2-图形化桌面客户端">1.4.2.图形化桌面客户端</h3><p>GitHub上的大神编写了Redis的图形化桌面客户端，地址：<a href="https://github.com/uglide/RedisDesktopManager">https://github.com/uglide/RedisDesktopManager</a></p><p>不过该仓库提供的是RedisDesktopManager的源码，并未提供windows安装包。</p><p>在下面这个仓库可以找到安装包：<a href="https://github.com/lework/RedisDesktopManager-Windows/releases">https://github.com/lework/RedisDesktopManager-Windows/releases</a></p><h3 id="1-4-3-安装">1.4.3.安装</h3><p>在课前资料中可以找到Redis的图形化桌面客户端：</p><p>解压缩后，运行安装程序即可安装：</p><p>安装完成后，在安装目录下找到rdm.exe文件：</p><p>双击即可运行：</p><h3 id="1-4-4-建立连接">1.4.4.建立连接</h3><p>点击左上角的<code>连接到Redis服务器</code>按钮：</p><p>在弹出的窗口中填写Redis服务信息：</p><p>点击确定后，在左侧菜单会出现这个链接：</p><p>点击即可建立连接了。</p><p>Redis默认有16个仓库，编号从0至15.  通过配置文件可以设置仓库数量，但是不超过16，并且不能自定义仓库名称。</p><p>如果是基于redis-cli连接Redis服务，可以通过select命令来选择数据库：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 选择 0号库</span></span><br><span class="line"><span class="keyword">select</span> 0</span><br></pre></td></tr></table></figure><h1>2.Redis常见命令</h1><p>Redis是典型的key-value数据库，key一般是字符串，而value包含很多不同的数据类型：</p><p>Redis为了方便我们学习，将操作不同数据类型的命令也做了分组，在官网（ <a href="https://redis.io/commands">https://redis.io/commands </a>）可以查看到不同的命令：</p><p>不同类型的命令称为一个group，我们也可以通过help命令来查看各种不同group的命令：</p><p>接下来，我们就学习常见的五种基本数据类型的相关命令。</p><h2 id="2-1-Redis通用命令">2.1.Redis通用命令</h2><p>通用指令是部分数据类型的，都可以使用的指令，常见的有：</p><ul><li>KEYS：查看符合模板的所有key</li><li>DEL：删除一个指定的key</li><li>EXISTS：判断key是否存在</li><li>EXPIRE：给一个key设置有效期，有效期到期时该key会被自动删除</li><li>TTL：查看一个KEY的剩余有效期</li></ul><p>通过help [command] 可以查看一个命令的具体用法，例如：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看keys命令的帮助信息：</span></span><br><span class="line">127.0.0.1:6379&gt; <span class="built_in">help</span> keys</span><br></pre></td></tr></table></figure><h2 id="2-2-String类型">2.2.String类型</h2><p>String类型，也就是字符串类型，是Redis中最简单的存储类型。</p><p>其value是字符串，不过根据字符串的格式不同，又可以分为3类：</p><ul><li>string：普通字符串</li><li>int：整数类型，可以做自增、自减操作</li><li>float：浮点类型，可以做自增、自减操作</li></ul><p>不管是哪种格式，底层都是字节数组形式存储，只不过是编码方式不同。字符串类型的最大空间不能超过512m.</p><h3 id="2-2-1-String的常见命令">2.2.1.String的常见命令</h3><p>String的常见命令有：</p><ul><li>SET：添加或者修改已经存在的一个String类型的键值对</li><li>GET：根据key获取String类型的value</li><li>MSET：批量添加多个String类型的键值对</li><li>MGET：根据多个key获取多个String类型的value</li><li>INCR：让一个整型的key自增1</li><li>INCRBY:让一个整型的key自增并指定步长，例如：incrby num 2 让num值自增2</li><li>INCRBYFLOAT：让一个浮点类型的数字自增并指定步长</li><li>SETNX：添加一个String类型的键值对，前提是这个key不存在，否则不执行</li><li>SETEX：添加一个String类型的键值对，并且指定有效期</li></ul><h3 id="2-2-2-Key结构">2.2.2.Key结构</h3><p>Redis没有类似MySQL中的Table的概念，我们该如何区分不同类型的key呢？</p><p>例如，需要存储用户、商品信息到redis，有一个用户id是1，有一个商品id恰好也是1，此时如果使用id作为key，那就会冲突了，该怎么办？</p><p>我们可以通过给key添加前缀加以区分，不过这个前缀不是随便加的，有一定的规范：</p><p>Redis的key允许有多个单词形成层级结构，多个单词之间用’:'隔开，格式如下：</p><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">项目名:业务名:类型:<span class="built_in">id</span></span><br></pre></td></tr></table></figure><p>这个格式并非固定，也可以根据自己的需求来删除或添加词条。这样以来，我们就可以把不同类型的数据区分开了。从而避免了key的冲突问题。</p><p>例如我们的项目名称叫 heima，有user和product两种不同类型的数据，我们可以这样定义key：</p><ul><li><p>user相关的key：<strong>heima:user:1</strong></p></li><li><p>product相关的key：<strong>heima:product:1</strong></p></li></ul><p>如果Value是一个Java对象，例如一个User对象，则可以将对象序列化为JSON字符串后存储：</p><table><thead><tr><th><strong>KEY</strong></th><th><strong>VALUE</strong></th></tr></thead><tbody><tr><td>heima:user:1</td><td>{“id”:1,  “name”: “Jack”, “age”: 21}</td></tr><tr><td>heima:product:1</td><td>{“id”:1,  “name”: “小米11”, “price”: 4999}</td></tr></tbody></table><h2 id="2-3-Hash类型">2.3.Hash类型</h2><p>Hash类型，也叫散列，其value是一个无序字典，类似于Java中的HashMap结构。</p><p>String结构是将对象序列化为JSON字符串后存储，当需要修改对象某个字段时很不方便：</p><p>Hash结构可以将对象中的每个字段独立存储，可以针对单个字段做CRUD：</p><p>Hash的常见命令有：</p><ul><li>HSET key field value：添加或者修改hash类型key的field的值</li><li>HGET key field：获取一个hash类型key的field的值</li><li>HMSET：批量添加多个hash类型key的field的值</li><li>HMGET：批量获取多个hash类型key的field的值</li><li>HGETALL：获取一个hash类型的key中的所有的field和value</li><li>HKEYS：获取一个hash类型的key中的所有的field</li><li>HINCRBY:让一个hash类型key的字段值自增并指定步长</li><li>HSETNX：添加一个hash类型的key的field值，前提是这个field不存在，否则不执行</li></ul><h2 id="2-4-List类型">2.4.List类型</h2><p>Redis中的List类型与Java中的LinkedList类似，可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。</p><p>特征也与LinkedList类似：</p><ul><li>有序</li><li>元素可以重复</li><li>插入和删除快</li><li>查询速度一般</li></ul><p>常用来存储一个有序数据，例如：朋友圈点赞列表，评论列表等。</p><p>List的常见命令有：</p><ul><li>LPUSH key element … ：向列表左侧插入一个或多个元素</li><li>LPOP key：移除并返回列表左侧的第一个元素，没有则返回nil</li><li>RPUSH key element … ：向列表右侧插入一个或多个元素</li><li>RPOP key：移除并返回列表右侧的第一个元素</li><li>LRANGE key star end：返回一段角标范围内的所有元素</li><li>BLPOP和BRPOP：与LPOP和RPOP类似，只不过在没有元素时等待指定时间，而不是直接返回nil</li></ul><h2 id="2-5-Set类型">2.5.Set类型</h2><p>Redis的Set结构与Java中的HashSet类似，可以看做是一个value为null的HashMap。因为也是一个hash表，因此具备与HashSet类似的特征：</p><ul><li>无序</li><li>元素不可重复</li><li>查找快</li><li>支持交集、并集、差集等功能</li></ul><p>Set的常见命令有：</p><ul><li>SADD key member … ：向set中添加一个或多个元素</li><li>SREM key member … : 移除set中的指定元素</li><li>SCARD key： 返回set中元素的个数</li><li>SISMEMBER key member：判断一个元素是否存在于set中</li><li>SMEMBERS：获取set中的所有元素</li><li>SINTER key1 key2 … ：求key1与key2的交集</li></ul><h2 id="2-6-SortedSet类型">2.6.SortedSet类型</h2><p>Redis的SortedSet是一个可排序的set集合，与Java中的TreeSet有些类似，但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性，可以基于score属性对元素排序，底层的实现是一个跳表（SkipList）加 hash表。</p><p>SortedSet具备下列特性：</p><ul><li>可排序</li><li>元素不重复</li><li>查询速度快</li></ul><p>因为SortedSet的可排序特性，经常被用来实现排行榜这样的功能。</p><p>SortedSet的常见命令有：</p><ul><li>ZADD key score member：添加一个或多个元素到sorted set ，如果已经存在则更新其score值</li><li>ZREM key member：删除sorted set中的一个指定元素</li><li>ZSCORE key member : 获取sorted set中的指定元素的score值</li><li>ZRANK key member：获取sorted set 中的指定元素的排名</li><li>ZCARD key：获取sorted set中的元素个数</li><li>ZCOUNT key min max：统计score值在给定范围内的所有元素的个数</li><li>ZINCRBY key increment member：让sorted set中的指定元素自增，步长为指定的increment值</li><li>ZRANGE key min max：按照score排序后，获取指定排名范围内的元素</li><li>ZRANGEBYSCORE key min max：按照score排序后，获取指定score范围内的元素</li><li>ZDIFF、ZINTER、ZUNION：求差集、交集、并集</li></ul><p>注意：所有的排名默认都是升序，如果要降序则在命令的Z后面添加REV即可，例如：</p><ul><li><p><strong>升序</strong>获取sorted set 中的指定元素的排名：ZRANK key member</p></li><li><p><strong>降序</strong>获取sorted set 中的指定元素的排名：ZREVRANK key memeber</p></li></ul><h1>3.Redis的Java客户端</h1><p>在Redis官网中提供了各种语言的客户端，地址：<a href="https://redis.io/docs/clients/">https://redis.io/docs/clients/</a></p><p>标记为*的就是推荐使用的java客户端，包括：</p><ul><li>Jedis和Lettuce：这两个主要是提供了Redis命令对应的API，方便我们操作Redis，而SpringDataRedis又对这两种做了抽象和封装，因此我们后期会直接以SpringDataRedis来学习。</li><li>Redisson：是在Redis基础上实现了分布式的可伸缩的java数据结构，例如Map、Queue等，而且支持跨进程的同步机制：Lock、Semaphore等待，比较适合用来实现特殊的功能需求。</li></ul><h2 id="3-1-Jedis客户端">3.1.Jedis客户端</h2><p>Jedis的官网地址： <a href="https://github.com/redis/jedis">https://github.com/redis/jedis</a></p><h3 id="3-1-1-快速入门">3.1.1.快速入门</h3><p>我们先来个快速入门：</p><p>1）引入依赖：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--jedis--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>redis.clients<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jedis<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>3.7.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--单元测试--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.junit.jupiter<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>junit-jupiter<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.7.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><p>2）建立连接</p><p>新建一个单元测试类，内容如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> Jedis jedis;</span><br><span class="line"></span><br><span class="line"><span class="meta">@BeforeEach</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">setUp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 1.建立连接</span></span><br><span class="line">    <span class="comment">// jedis = new Jedis(&quot;192.168.150.101&quot;, 6379);</span></span><br><span class="line">    jedis = JedisConnectionFactory.getJedis();</span><br><span class="line">    <span class="comment">// 2.设置密码</span></span><br><span class="line">    jedis.auth(<span class="string">&quot;123321&quot;</span>);</span><br><span class="line">    <span class="comment">// 3.选择库</span></span><br><span class="line">    jedis.select(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>3）测试：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">testString</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 存入数据</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> jedis.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;虎哥&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;result = &quot;</span> + result);</span><br><span class="line">    <span class="comment">// 获取数据</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">name</span> <span class="operator">=</span> jedis.get(<span class="string">&quot;name&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;name = &quot;</span> + name);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">testHash</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 插入hash数据</span></span><br><span class="line">    jedis.hset(<span class="string">&quot;user:1&quot;</span>, <span class="string">&quot;name&quot;</span>, <span class="string">&quot;Jack&quot;</span>);</span><br><span class="line">    jedis.hset(<span class="string">&quot;user:1&quot;</span>, <span class="string">&quot;age&quot;</span>, <span class="string">&quot;21&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取</span></span><br><span class="line">    Map&lt;String, String&gt; map = jedis.hgetAll(<span class="string">&quot;user:1&quot;</span>);</span><br><span class="line">    System.out.println(map);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>4）释放资源</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@AfterEach</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">tearDown</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (jedis != <span class="literal">null</span>) &#123;</span><br><span class="line">        jedis.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-1-2-连接池">3.1.2.连接池</h3><p>Jedis本身是线程不安全的，并且频繁的创建和销毁连接会有性能损耗，因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.heima.jedis.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JedisConnectionFactory</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> JedisPool jedisPool;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="comment">// 配置连接池</span></span><br><span class="line">        <span class="type">JedisPoolConfig</span> <span class="variable">poolConfig</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JedisPoolConfig</span>();</span><br><span class="line">        poolConfig.setMaxTotal(<span class="number">8</span>);</span><br><span class="line">        poolConfig.setMaxIdle(<span class="number">8</span>);</span><br><span class="line">        poolConfig.setMinIdle(<span class="number">0</span>);</span><br><span class="line">        poolConfig.setMaxWaitMillis(<span class="number">1000</span>);</span><br><span class="line">        <span class="comment">// 创建连接池对象，参数：连接池配置、服务端ip、服务端端口、超时时间、密码</span></span><br><span class="line">        jedisPool = <span class="keyword">new</span> <span class="title class_">JedisPool</span>(poolConfig, <span class="string">&quot;192.168.150.101&quot;</span>, <span class="number">6379</span>, <span class="number">1000</span>, <span class="string">&quot;123321&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Jedis <span class="title function_">getJedis</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> jedisPool.getResource();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="3-2-SpringDataRedis客户端">3.2.SpringDataRedis客户端</h2><p>SpringData是Spring中数据操作的模块，包含对各种数据库的集成，其中对Redis的集成模块就叫做SpringDataRedis，官网地址：<a href="https://spring.io/projects/spring-data-redis">https://spring.io/projects/spring-data-redis</a></p><ul><li>提供了对不同Redis客户端的整合（Lettuce和Jedis）</li><li>提供了RedisTemplate统一API来操作Redis</li><li>支持Redis的发布订阅模型</li><li>支持Redis哨兵和Redis集群</li><li>支持基于Lettuce的响应式编程</li><li>支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化</li><li>支持基于Redis的JDKCollection实现</li></ul><p>SpringDataRedis中提供了RedisTemplate工具类，其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中：</p><h3 id="3-2-1-快速入门">3.2.1.快速入门</h3><p>SpringBoot已经提供了对SpringDataRedis的支持，使用非常简单。</p><p>首先，新建一个maven项目，然后按照下面步骤执行：</p><h4 id="1）引入依赖">1）引入依赖</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span> <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.5.7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">relativePath</span>/&gt;</span> <span class="comment">&lt;!-- lookup parent from repository --&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.heima<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>redis-demo<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">name</span>&gt;</span>redis-demo<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">description</span>&gt;</span>Demo project for Spring Boot<span class="tag">&lt;/<span class="name">description</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">java.version</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">java.version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--redis依赖--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-data-redis<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--common-pool--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.commons<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>commons-pool2<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--Jackson依赖--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.fasterxml.jackson.core<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jackson-databind<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">excludes</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">exclude</span>&gt;</span></span><br><span class="line">                            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">                            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">excludes</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="2）配置Redis">2）配置Redis</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="attr">redis:</span></span><br><span class="line">    <span class="attr">host:</span> <span class="number">192.168</span><span class="number">.150</span><span class="number">.101</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">6379</span></span><br><span class="line">    <span class="attr">password:</span> <span class="number">123321</span></span><br><span class="line">    <span class="attr">lettuce:</span></span><br><span class="line">      <span class="attr">pool:</span></span><br><span class="line">        <span class="attr">max-active:</span> <span class="number">8</span></span><br><span class="line">        <span class="attr">max-idle:</span> <span class="number">8</span></span><br><span class="line">        <span class="attr">min-idle:</span> <span class="number">0</span></span><br><span class="line">        <span class="attr">max-wait:</span> <span class="string">100ms</span></span><br></pre></td></tr></table></figure><h4 id="3）注入RedisTemplate">3）注入RedisTemplate</h4><p>因为有了SpringBoot的自动装配，我们可以拿来就用：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RedisStringTests</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> RedisTemplate redisTemplate;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="4）编写测试">4）编写测试</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RedisStringTests</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> RedisTemplate edisTemplate;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">testString</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 写入一条String数据</span></span><br><span class="line">        redisTemplate.opsForValue().set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;虎哥&quot;</span>);</span><br><span class="line">        <span class="comment">// 获取string数据</span></span><br><span class="line">        <span class="type">Object</span> <span class="variable">name</span> <span class="operator">=</span> stringRedisTemplate.opsForValue().get(<span class="string">&quot;name&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;name = &quot;</span> + name);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-2-2-自定义序列化">3.2.2.自定义序列化</h3><p>RedisTemplate可以接收任意Object作为值写入Redis：</p><p>只不过写入前会把Object序列化为字节形式，默认是采用JDK序列化，得到的结果是这样的：</p><p>缺点：</p><ul><li>可读性差</li><li>内存占用较大</li></ul><p>我们可以自定义RedisTemplate的序列化方式，代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RedisConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> RedisTemplate&lt;String, Object&gt; <span class="title function_">redisTemplate</span><span class="params">(RedisConnectionFactory connectionFactory)</span>&#123;</span><br><span class="line">        <span class="comment">// 创建RedisTemplate对象</span></span><br><span class="line">        RedisTemplate&lt;String, Object&gt; template = <span class="keyword">new</span> <span class="title class_">RedisTemplate</span>&lt;&gt;();</span><br><span class="line">        <span class="comment">// 设置连接工厂</span></span><br><span class="line">        template.setConnectionFactory(connectionFactory);</span><br><span class="line">        <span class="comment">// 创建JSON序列化工具</span></span><br><span class="line">        <span class="type">GenericJackson2JsonRedisSerializer</span> <span class="variable">jsonRedisSerializer</span> <span class="operator">=</span> </span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">GenericJackson2JsonRedisSerializer</span>();</span><br><span class="line">        <span class="comment">// 设置Key的序列化</span></span><br><span class="line">        template.setKeySerializer(RedisSerializer.string());</span><br><span class="line">        template.setHashKeySerializer(RedisSerializer.string());</span><br><span class="line">        <span class="comment">// 设置Value的序列化</span></span><br><span class="line">        template.setValueSerializer(jsonRedisSerializer);</span><br><span class="line">        template.setHashValueSerializer(jsonRedisSerializer);</span><br><span class="line">        <span class="comment">// 返回</span></span><br><span class="line">        <span class="keyword">return</span> template;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这里采用了JSON序列化来代替默认的JDK序列化方式。最终结果如图：</p><p><img src="assets/XOAq3cN.png" alt=""></p><p>整体可读性有了很大提升，并且能将Java对象自动的序列化为JSON字符串，并且查询时能自动把JSON反序列化为Java对象。不过，其中记录了序列化时对应的class名称，目的是为了查询时实现自动反序列化。这会带来额外的内存开销。</p><h3 id="3-2-3-StringRedisTemplate">3.2.3.StringRedisTemplate</h3><p>为了节省内存空间，我们可以不使用JSON序列化器来处理value，而是统一使用String序列化器，要求只能存储String类型的key和value。当需要存储Java对象时，手动完成对象的序列化和反序列化。</p><p>因为存入和读取时的序列化及反序列化都是我们自己实现的，SpringDataRedis就不会将class信息写入Redis了。</p><p>这种用法比较普遍，因此SpringDataRedis就提供了RedisTemplate的子类：StringRedisTemplate，它的key和value的序列化方式默认就是String方式。</p><p>省去了我们自定义RedisTemplate的序列化方式的步骤，而是直接使用：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Autowired</span></span><br><span class="line"><span class="keyword">private</span> StringRedisTemplate stringRedisTemplate;</span><br><span class="line"><span class="comment">// JSON序列化工具</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">ObjectMapper</span> <span class="variable">mapper</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ObjectMapper</span>();</span><br><span class="line"></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">testSaveUser</span><span class="params">()</span> <span class="keyword">throws</span> JsonProcessingException &#123;</span><br><span class="line">    <span class="comment">// 创建对象</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>(<span class="string">&quot;虎哥&quot;</span>, <span class="number">21</span>);</span><br><span class="line">    <span class="comment">// 手动序列化</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">json</span> <span class="operator">=</span> mapper.writeValueAsString(user);</span><br><span class="line">    <span class="comment">// 写入数据</span></span><br><span class="line">    stringRedisTemplate.opsForValue().set(<span class="string">&quot;user:200&quot;</span>, json);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取数据</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">jsonUser</span> <span class="operator">=</span> stringRedisTemplate.opsForValue().get(<span class="string">&quot;user:200&quot;</span>);</span><br><span class="line">    <span class="comment">// 手动反序列化</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user1</span> <span class="operator">=</span> mapper.readValue(jsonUser, User.class);</span><br><span class="line">    System.out.println(<span class="string">&quot;user1 = &quot;</span> + user1);</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1&gt;Redis快速入门&lt;/h1&gt;
&lt;h2 id=&quot;1-1-认识Redis&quot;&gt;1.1.认识Redis&lt;/h2&gt;
&lt;p&gt;Redis诞生于2009年全称是&lt;strong&gt;Re&lt;/strong&gt;mote  &lt;strong&gt;D&lt;/strong&gt;ictionary &lt;strong&gt;S&lt;/</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title></title>
    <link href="https://gwenliu.cn/posts/9b7c12e4.html"/>
    <id>https://gwenliu.cn/posts/9b7c12e4.html</id>
    <published>2026-04-12T17:35:58.042Z</published>
    <updated>2026-04-12T17:35:58.042Z</updated>
    
    <content type="html"><![CDATA[<h1>Linux 从入门到项目部署完全指南</h1><p>本文整合了Linux教程的Word文档与PPT核心内容，构建结构化知识体系，涵盖Linux基础、常用命令、软件安装及项目部署全流程，适用于学习笔记和教学文档，兼顾实用性与易懂性。</p><h2 id="一、Linux概述">一、Linux概述</h2><h3 id="1-1-什么是Linux">1.1 什么是Linux</h3><p>Linux是一套免费使用、自由传播的操作系统，与Windows、MacOS并列主流操作系统，广泛应用于服务器领域。作为JavaEE开发工程师，Linux是部署数据库（MySQL）、中间件（Redis、MQ）及项目的核心环境，其基础使用是必备技能。</p><h3 id="1-2-主流操作系统分类">1.2 主流操作系统分类</h3><table><thead><tr><th>领域</th><th>代表系统</th><th>特点</th></tr></thead><tbody><tr><td>桌面操作系统</td><td>Windows、MacOS、Linux</td><td>Windows用户最多，MacOS体验佳，Linux用户少</td></tr><tr><td>服务器操作系统</td><td>Unix、Linux、Windows Server</td><td>Linux安全稳定且免费，占有率最高</td></tr><tr><td>移动设备操作系统</td><td>Android、iOS、HarmonyOS</td><td>Android基于Linux开源，iOS闭源</td></tr><tr><td>嵌入式操作系统</td><td>Linux（嵌入式版本）</td><td>轻量化、适配嵌入式硬件</td></tr></tbody></table><h3 id="1-3-Linux系统版本">1.3 Linux系统版本</h3><ul><li><p><strong>内核版</strong>：由Linus Torvalds团队开发维护，免费开源，负责控制硬件。</p></li><li><p><strong>发行版</strong>：基于内核扩展，厂商维护，分收费/免费版本，常用发行版包括：</p><ul><li><p>Ubuntu：桌面应用为主，免费</p></li><li><p>RedHat：企业级，收费</p></li><li><p>CentOS：RedHat社区版，免费（推荐学习使用）</p></li><li><p>Fedora：功能完备，快速更新，免费</p></li><li><p>红旗Linux：国内厂商开发</p></li></ul></li></ul><h3 id="1-4-系统安装">1.4 系统安装</h3><h4 id="1-4-1-安装方式">1.4.1 安装方式</h4><table><thead><tr><th>安装方式</th><th>概述</th><th>适用场景</th></tr></thead><tbody><tr><td>物理机安装</td><td>直接安装到服务器硬件</td><td>企业生产环境</td></tr><tr><td>虚拟机安装</td><td>通过虚拟机软件模拟硬件环境安装</td><td>学习阶段（推荐使用VMware）</td></tr></tbody></table><h4 id="1-4-2-虚拟机安装步骤（VMware）">1.4.2 虚拟机安装步骤（VMware）</h4><ol><li><p>下载并安装VMware（课程资料提供安装包，已安装则无需重复）。</p></li><li><p>配置虚拟网络：打开VMware→编辑→虚拟网络编辑器，选择NAT模式，设置子网IP为<code>192.168.100.0</code>，应用并确定。</p></li><li><p>挂载Linux镜像：解压CentOS7镜像到无中文目录，双击<code>.vmx</code>文件用VMware打开。</p></li><li><p>启动虚拟机：选择“我已移动该虚拟机”，登录用户名<code>root</code>，密码<code>1234</code>（Linux输入密码不显示）。</p></li></ol><h3 id="1-5-远程连接工具">1.5 远程连接工具</h3><h4 id="1-5-1-工具介绍">1.5.1 工具介绍</h4><p>SSH（Secure Shell）是远程连接Linux的安全协议，常用工具：FinalShell、Putty、Xshell，课程推荐FinalShell（免费且功能全面）。</p><h4 id="1-5-2-FinalShell连接步骤">1.5.2 FinalShell连接步骤</h4><ol><li><p>安装FinalShell（课程资料提供安装包，双击默认安装）。</p></li><li><p>新建SSH连接：主机<code>192.168.100.128</code>，端口<code>22</code>，用户名<code>root</code>，密码<code>1234</code>。</p></li><li><p>双击连接：连接成功后即可通过FinalShell操作Linux。</p></li></ol><h3 id="1-6-Linux目录结构">1.6 Linux目录结构</h3><h4 id="核心特点">核心特点</h4><ul><li><p>根目录<code>/</code>是所有目录的顶点，目录结构呈倒挂树状。</p></li><li><p>与Windows的盘符（C盘、D盘）结构不同，Linux无盘符概念。</p></li></ul><h4 id="主要目录功能">主要目录功能</h4><table><thead><tr><th>目录</th><th>功能描述</th></tr></thead><tbody><tr><td><code>/bin</code></td><td>存放二进制可执行文件（普通用户可执行）</td></tr><tr><td><code>/sbin</code></td><td>存放系统管理二进制文件（仅root可执行）</td></tr><tr><td><code>/etc</code></td><td>存放系统配置文件</td></tr><tr><td><code>/home</code></td><td>普通用户主目录</td></tr><tr><td><code>/root</code></td><td>超级用户（root）主目录</td></tr><tr><td><code>/usr</code></td><td>存放系统应用程序</td></tr><tr><td><code>/var</code></td><td>存放动态数据（如日志文件）</td></tr><tr><td><code>/tmp</code></td><td>存放临时文件</td></tr><tr><td><code>/boot</code></td><td>存放系统引导相关文件</td></tr></tbody></table><h2 id="二、Linux常用命令">二、Linux常用命令</h2><h3 id="2-1-命令基础">2.1 命令基础</h3><ul><li><p><strong>格式</strong>：<code>command [-options] [parameter]</code></p><ul><li><p><code>command</code>：命令名（如ls、cd）</p></li><li><p><code>[-options]</code>：命令选项（可选，如-l、-a）</p></li><li><p><code>[parameter]</code>：命令参数（可选，如目录名、文件名）</p></li></ul></li><li><p><strong>使用技巧</strong>：</p><ul><li><p>Tab键自动补全命令/路径</p></li><li><p>连续两次Tab键显示操作提示</p></li><li><p>上下箭头快速调用历史命令</p></li><li><p><code>clear</code>或<code>Ctrl+l</code>清屏</p></li></ul></li></ul><h3 id="2-2-目录操作命令">2.2 目录操作命令</h3><h4 id="2-2-1-ls（列出目录内容）">2.2.1 ls（列出目录内容）</h4><ul><li><p>作用：显示指定目录下的文件和目录</p></li><li><p>语法：<code>ls [-al] [dir]</code></p></li><li><p>选项：</p><ul><li><p><code>-a</code>：显示所有文件（含隐藏文件，以<code>.</code>开头）</p></li><li><p><code>-l</code>：显示详细信息（文件类型、权限、大小等），简写为<code>ll</code></p></li></ul></li><li><p>示例：</p><ul><li><p><code>ls -al</code>：查看当前目录所有文件详细信息</p></li><li><p><code>ls -al /etc</code>：查看/etc目录所有文件详细信息</p></li></ul></li></ul><h4 id="2-2-2-cd（切换目录）">2.2.2 cd（切换目录）</h4><ul><li><p>作用：切换当前工作目录</p></li><li><p>语法：<code>cd [dirName]</code></p></li><li><p>特殊符号：</p><ul><li><p><code>~</code>：用户主目录（root用户为<code>/root</code>）</p></li><li><p><code>.</code>：当前目录</p></li><li><p><code>..</code>：上级目录</p></li></ul></li><li><p>示例：</p><ul><li><p><code>cd ..</code>：切换到上级目录</p></li><li><p><code>cd ~</code>：切换到主目录</p></li><li><p><code>cd /usr/local</code>：切换到指定目录</p></li></ul></li></ul><h4 id="2-2-3-mkdir（创建目录）">2.2.3 mkdir（创建目录）</h4><ul><li><p>作用：创建目录</p></li><li><p>语法：<code>mkdir [-p] dirName</code></p></li><li><p>选项：<code>-p</code>：递归创建多层目录（父目录不存在则自动创建）</p></li><li><p>示例：</p><ul><li><p><code>mkdir itcast</code>：创建单层目录</p></li><li><p><code>mkdir -p itcast/test</code>：创建多层目录</p></li></ul></li></ul><h4 id="2-2-4-rm（删除文件-目录）">2.2.4 rm（删除文件/目录）</h4><ul><li><p>作用：删除文件或目录</p></li><li><p>语法：<code>rm [-rf] name</code></p></li><li><p>选项：</p><ul><li><p><code>-r</code>：递归删除（用于目录）</p></li><li><p><code>-f</code>：强制删除（无需确认）</p></li></ul></li><li><p>示例：</p><ul><li><p><code>rm -f 1.txt</code>：强制删除文件</p></li><li><p><code>rm -rf itcast/</code>：强制删除目录及所有内容（谨慎使用！）</p></li></ul></li></ul><h3 id="2-3-文件操作命令">2.3 文件操作命令</h3><h4 id="2-3-1-cat（查看文件内容）">2.3.1 cat（查看文件内容）</h4><ul><li><p>作用：显示文件全部内容</p></li><li><p>语法：<code>cat [-n] fileName</code></p></li><li><p>选项：<code>-n</code>：显示行号</p></li><li><p>示例：<code>cat -n /etc/profile</code>：查看文件并显示行号</p></li></ul><h4 id="2-3-2-more（分页查看文件）">2.3.2 more（分页查看文件）</h4><ul><li><p>作用：分页显示大文件内容</p></li><li><p>语法：<code>more fileName</code></p></li><li><p>操作：</p><ul><li><p>回车键：向下滚动一行</p></li><li><p>空格键：向下滚动一屏</p></li><li><p><code>b</code>：返回上一屏</p></li><li><p><code>q</code>/<code>Ctrl+C</code>：退出</p></li></ul></li><li><p>示例：<code>more /etc/profile</code>：分页查看文件</p></li></ul><h4 id="2-3-3-head-tail（查看文件首尾）">2.3.3 head/tail（查看文件首尾）</h4><ul><li><p><code>head</code>：查看文件开头</p><ul><li><p>语法：<code>head [-n] fileName</code>（默认前10行，<code>-n</code>指定行数）</p></li><li><p>示例：<code>head -20 1.log</code>：查看前20行</p></li></ul></li><li><p><code>tail</code>：查看文件结尾</p><ul><li><p>语法：<code>tail [-n/-f] fileName</code></p></li><li><p>选项：<code>-f</code>：动态监控文件（常用于日志）</p></li><li><p>示例：<code>tail -f /var/log/messages</code>：动态查看日志</p></li></ul></li></ul><h3 id="2-4-拷贝移动命令">2.4 拷贝移动命令</h3><h4 id="2-4-1-cp（复制文件-目录）">2.4.1 cp（复制文件/目录）</h4><ul><li><p>作用：复制文件或目录</p></li><li><p>语法：<code>cp [-r] source dest</code></p></li><li><p>选项：<code>-r</code>：复制目录（含子目录和文件）</p></li><li><p>示例：</p><ul><li><p><code>cp 1.txt itcast/</code>：复制文件到目录</p></li><li><p><code>cp -r itcast/ itheima/</code>：复制目录</p></li></ul></li></ul><h4 id="2-4-2-mv（移动-重命名）">2.4.2 mv（移动/重命名）</h4><ul><li><p>作用：移动文件/目录或重命名</p></li><li><p>语法：<code>mv source dest</code></p></li><li><p>规则：若<code>dest</code>是已存在目录则移动，否则重命名</p></li><li><p>示例：</p><ul><li><p><code>mv 1.txt 2.txt</code>：重命名文件</p></li><li><p><code>mv 2.txt itcast/</code>：移动文件到目录</p></li></ul></li></ul><h3 id="2-5-打包压缩命令（tar）">2.5 打包压缩命令（tar）</h3><ul><li><p>作用：打包、解包、压缩、解压</p></li><li><p>语法：<code>tar [-zcxvf] fileName [files]</code></p></li><li><p>选项说明：</p><ul><li><p><code>-z</code>：通过gzip压缩/解压</p></li><li><p><code>-c</code>：创建包文件</p></li><li><p><code>-x</code>：解包/解压</p></li><li><p><code>-v</code>：显示执行过程</p></li><li><p><code>-f</code>：指定包文件名</p></li></ul></li><li><p>示例：</p><ul><li><p>打包：<code>tar -cvf itcast.tar itcast/</code>（仅打包，无压缩）</p></li><li><p>打包压缩：<code>tar -zcvf itcast.tar.gz itcast/</code>（.tar.gz格式）</p></li><li><p>解压：<code>tar -zxvf itcast.tar.gz</code>（解压到当前目录）</p></li><li><p>指定目录解压：<code>tar -zxvf itcast.tar.gz -C /usr/local</code></p></li></ul></li></ul><h3 id="2-6-文本编辑命令（vim）">2.6 文本编辑命令（vim）</h3><h4 id="2-6-1-安装vim">2.6.1 安装vim</h4><ul><li>语法：<code>yum install vim</code>（CentOS默认未安装，执行后输入<code>y</code>确认）</li></ul><h4 id="2-6-2-vim三种模式及操作">2.6.2 vim三种模式及操作</h4><table><thead><tr><th>模式</th><th>进入方式</th><th>核心操作</th></tr></thead><tbody><tr><td>命令模式</td><td>打开文件默认进入</td><td>移动光标（<code>gg</code>到首行、<code>G</code>到尾行）、删除（<code>dd</code>删行、<code>ndd</code>删n行）、撤销（<code>u</code>）</td></tr><tr><td>插入模式</td><td>命令模式按<code>i/a/o</code></td><td>编辑文件内容，按<code>ESC</code>返回命令模式</td></tr><tr><td>底行模式</td><td>命令模式按<code>:</code>或<code>/</code></td><td><code>:wq</code>保存退出、<code>:q!</code>强制退出、<code>:set nu</code>显示行号、<code>/关键字</code>查找内容</td></tr></tbody></table><ul><li>示例：<code>vim /etc/profile</code>：打开文件→<code>i</code>编辑→<code>ESC</code>→<code>:wq</code>保存退出</li></ul><h3 id="2-7-查找命令">2.7 查找命令</h3><h4 id="2-7-1-find（查找文件）">2.7.1 find（查找文件）</h4><ul><li><p>作用：按文件名查找文件/目录</p></li><li><p>语法：<code>find dirName -option fileName</code></p></li><li><p>示例：</p><ul><li><p><code>find . -name &quot;*.java&quot;</code>：当前目录及子目录查找.java文件</p></li><li><p><code>find /usr -name &quot;*.txt&quot;</code>：/usr目录及子目录查找.txt文件</p></li></ul></li></ul><h4 id="2-7-2-grep（查找文件内容）">2.7.2 grep（查找文件内容）</h4><ul><li><p>作用：查找文件中指定关键字</p></li><li><p>语法：<code>grep [-inAB] word fileName</code></p></li><li><p>选项：</p><ul><li><p><code>-i</code>：忽略大小写</p></li><li><p><code>-n</code>：显示行号</p></li><li><p><code>-A5</code>：显示关键字行及后5行</p></li><li><p><code>-B5</code>：显示关键字行及前5行</p></li></ul></li><li><p>示例：<code>grep -n &quot;spring&quot; application.yml</code>：查找文件中含spring的行并显示行号</p></li></ul><h2 id="三、Linux软件安装">三、Linux软件安装</h2><h3 id="3-1-安装方式分类">3.1 安装方式分类</h3><table><thead><tr><th>安装方式</th><th>特点</th><th>适用场景</th></tr></thead><tbody><tr><td>二进制发布包</td><td>已编译打包，解压+配置即可使用</td><td>JDK、Tomcat等</td></tr><tr><td>rpm安装</td><td>红帽标准包，无法自动解决依赖</td><td>简单软件安装</td></tr><tr><td>yum安装</td><td>在线安装，自动解决依赖（需联网）</td><td>系统工具、依赖库</td></tr><tr><td>源码编译安装</td><td>需编译打包，灵活性高</td><td>Nginx、自定义软件</td></tr></tbody></table><h3 id="3-2-安装JDK（二进制发布包）">3.2 安装JDK（二进制发布包）</h3><ol><li><p>上传安装包：通过FinalShell将<code>jdk-17.0.10_linux-x64_bin.tar.gz</code>上传到<code>/root</code>目录。</p></li><li><p>解压到指定目录：<code>tar -zxvf jdk-17.0.10_linux-x64_bin.tar.gz -C /usr/local/</code>。</p></li><li><p>配置环境变量：</p><ul><li><p>编辑配置文件：<code>vim /etc/profile</code></p></li><li><p>末尾添加：</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">        </span><br></pre></td></tr></table></figure></li><li><p>生效配置：<code>source /etc/profile</code></p></li></ul></li><li><p>验证安装：<code>java -version</code>（显示版本号则成功）</p></li></ol><h3 id="3-3-安装MySQL（二进制发布包）">3.3 安装MySQL（二进制发布包）</h3><h4 id="3-3-1-准备工作（卸载冲突软件）">3.3.1 准备工作（卸载冲突软件）</h4><ul><li><p>查找冲突软件：<code>rpm -qa | grep mariadb</code>（CentOS默认自带）</p></li><li><p>卸载冲突软件：<code>rpm -e --nodeps 软件名</code>（如<code>mariadb-libs-5.5.60-1.el7_5.x86_64</code>）</p></li></ul><h4 id="3-3-2-安装步骤">3.3.2 安装步骤</h4><ol><li><p>上传并解压：将<code>mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz</code>上传到<code>/root</code>，解压后移动到<code>/usr/local/mysql</code>：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>配置环境变量：</p><ul><li><p>编辑<code>/etc/profile</code>，末尾添加：</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">        </span><br></pre></td></tr></table></figure></li><li><p>生效配置：<code>source /etc/profile</code></p></li></ul></li><li><p>注册系统服务：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>初始化数据库：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure><ul><li>记录初始化日志中的<strong>临时密码</strong>（如<code>1bR3oPP-DUut</code>）</li></ul></li></ol><h4 id="3-3-3-启动与配置MySQL">3.3.3 启动与配置MySQL</h4><ol><li><p>启动服务：<code>systemctl start mysql</code></p></li><li><p>登录MySQL：<code>mysql -uroot -p临时密码</code></p></li><li><p>修改密码+授权远程访问：</p> <figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>防火墙配置（开放3306端口）：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li></ol><h3 id="3-4-安装Nginx（源码编译安装）">3.4 安装Nginx（源码编译安装）</h3><ol><li><p>安装依赖：<code>yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel</code></p></li><li><p>上传并解压：将<code>nginx-1.20.2.tar.gz</code>上传到<code>/root</code>，解压：<code>tar -zxvf nginx-1.20.2.tar.gz</code></p></li><li><p>编译配置：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>编译安装：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>启动Nginx：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>验证：浏览器访问<code>192.168.100.128</code>，显示“Welcome to nginx!”则成功</p></li></ol><h2 id="四、项目部署">四、项目部署</h2><h3 id="4-1-前端项目部署（Nginx）">4.1 前端项目部署（Nginx）</h3><ol><li><p>清理默认资源：删除<code>/usr/local/nginx/html</code>目录下的默认文件（50x.html、index.html）。</p></li><li><p>上传前端资源：将前端打包后的静态资源（assets、index.html等）上传到<code>/usr/local/nginx/html</code>。</p></li><li><p>配置Nginx反向代理：</p><ul><li><p>编辑配置文件：<code>vim /usr/local/nginx/conf/nginx.conf</code></p></li><li><p>替换server节点配置：</p>  <figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">        </span><br></pre></td></tr></table></figure></li></ul></li><li><p>重启Nginx：<code>/usr/local/nginx/sbin/nginx -s reload</code></p></li><li><p>访问测试：浏览器输入<code>192.168.100.128</code>，正常显示前端页面则成功</p></li></ol><h3 id="4-2-后端项目部署（SpringBoot）">4.2 后端项目部署（SpringBoot）</h3><h4 id="4-2-1-环境准备">4.2.1 环境准备</h4><ol><li><p>修改项目配置：编辑<code>application.yml</code>，配置Linux上的MySQL信息：</p> <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>打包项目：通过Maven执行<code>package</code>命令（跳过测试），生成jar包（如<code>tlias-web-management-0.0.1-SNAPSHOT.jar</code>）。</p></li></ol><h4 id="4-2-2-部署步骤">4.2.2 部署步骤</h4><ol><li><p>上传jar包：通过FinalShell将jar包上传到Linux的<code>/usr/local/app</code>目录（无目录则创建：<code>mkdir -p /usr/local/app</code>）。</p></li><li><p>配置阿里云OSS环境变量（若项目使用OSS）：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure></li><li><p>后台运行项目：</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">    </span><br></pre></td></tr></table></figure><ul><li><p><code>nohup</code>：后台运行（关闭终端不停止）</p></li><li><p><code>&amp;&gt; tlias.log</code>：日志输出到tlias.log文件</p></li></ul></li><li><p>查看运行状态：</p><ul><li><p>查看进程：<code>ps -ef | grep tlias</code></p></li><li><p>停止服务：<code>kill -9 进程ID</code></p></li><li><p>查看日志：<code>tail -f tlias.log</code></p></li></ul></li></ol><h4 id="4-2-3-访问测试">4.2.3 访问测试</h4><ul><li>前端页面操作接口，或直接访问后端接口（如<code>http://192.168.100.128/api/emp/list</code>），返回正常数据则部署成功。</li></ul><h2 id="五、常用工具与命令汇总">五、常用工具与命令汇总</h2><h3 id="5-1-Nginx常用命令">5.1 Nginx常用命令</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="5-2-防火墙常用命令">5.2 防火墙常用命令</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="5-3-服务管理命令">5.3 服务管理命令</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><p>要不要我帮你整理一份<strong>Linux命令速查手册</strong>（含所有核心命令的语法、选项、示例），方便你随时查阅使用？</p><blockquote><p>（注：文档部分内容可能由 AI 生成）</p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h1&gt;Linux 从入门到项目部署完全指南&lt;/h1&gt;
&lt;p&gt;本文整合了Linux教程的Word文档与PPT核心内容，构建结构化知识体系，涵盖Linux基础、常用命令、软件安装及项目部署全流程，适用于学习笔记和教学文档，兼顾实用性与易懂性。&lt;/p&gt;
&lt;h2 id=&quot;一、Linux</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title></title>
    <link href="https://gwenliu.cn/posts/6f42b1d9.html"/>
    <id>https://gwenliu.cn/posts/6f42b1d9.html</id>
    <published>2026-04-12T17:35:58.026Z</published>
    <updated>2026-04-12T17:35:58.026Z</updated>
    
    <content type="html"><![CDATA[<p>本文基于Docker实战文档整理，构建结构化知识体系，涵盖Docker核心概念、基础操作、数据卷、自定义镜像、网络配置及项目部署全流程，同时附上完整的Docker安装指南。内容兼顾入门友好性与实战实用性，适用于个人学习笔记及教学场景。</p><h1>一、Docker概述与核心优势</h1><h2 id="1-1-传统部署的痛点">1.1 传统部署的痛点</h2><p>在传统Linux环境部署项目时，普遍面临以下问题：</p><ul><li><p>命令繁多且难记忆，学习成本高；</p></li><li><p>软件安装包名称复杂，获取渠道不统一；</p></li><li><p>安装部署步骤繁琐，容易因环境差异出错；</p></li><li><p>多服务器部署时，环境一致性难以保证，脚本复用性低。</p></li></ul><h2 id="1-2-Docker的核心价值">1.2 Docker的核心价值</h2><p>Docker是一款开源的容器化技术，核心优势在于<strong>解耦应用与运行环境</strong>，实现“一次构建，到处运行”，具体体现在：</p><ul><li><p>简化部署流程：无需手动处理依赖、配置环境，一条命令即可完成软件部署；</p></li><li><p>跨平台兼容：相同的Docker命令可在CentOS、Ubuntu、macOS、Windows（WSL）等系统运行；</p></li><li><p>环境一致性：容器包含应用运行所需的完整环境，避免“开发环境正常，生产环境报错”；</p></li><li><p>高效运维：支持批量容器管理，大幅降低多服务器部署的工作量。</p></li></ul><h2 id="1-3-学习目标">1.3 学习目标</h2><ul><li><p>能利用Docker部署常见软件（如MySQL、Nginx）；</p></li><li><p>能利用Docker打包并部署Java应用；</p></li><li><p>理解Docker数据卷的基本作用及使用方式；</p></li><li><p>能看懂并编写Docker Compose文件，实现多容器协同部署。</p></li></ul><h1>二、Docker快速入门</h1><p>本教程统一使用预置Docker环境的CentOS虚拟机（无需额外安装）；若需在其他机器安装Docker，可参考本文附录。</p><h2 id="2-1-快速部署MySQL（对比传统部署）">2.1 快速部署MySQL（对比传统部署）</h2><h3 id="2-1-1-传统部署MySQL步骤">2.1.1 传统部署MySQL步骤</h3><ol><li><p>搜索并下载对应系统的MySQL安装包；</p></li><li><p>上传安装包至Linux环境；</p></li><li><p>解压文件并配置环境变量；</p></li><li><p>执行安装命令并解决依赖问题；</p></li><li><p>初始化数据库并配置权限。</p></li></ol><h3 id="2-1-2-Docker部署MySQL（一步完成）">2.1.2 Docker部署MySQL（一步完成）</h3><p>在命令行输入以下命令，直接创建并运行MySQL容器：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">docker run <span class="literal">-d</span> \</span><br><span class="line">  <span class="literal">--name</span> mysql \</span><br><span class="line">  <span class="literal">-p</span> <span class="number">3307</span>:<span class="number">3306</span> \</span><br><span class="line">  <span class="literal">-e</span> TZ=Asia/Shanghai \</span><br><span class="line">  <span class="literal">-e</span> MYSQL_ROOT_PASSWORD=<span class="number">123</span> \</span><br><span class="line">  mysql:<span class="number">8</span></span><br></pre></td></tr></table></figure><h3 id="2-1-3-运行效果与说明">2.1.3 运行效果与说明</h3><p>命令执行后，终端会输出容器ID（如6097d43dc087…），表示MySQL容器创建成功，可直接通过客户端工具连接（主机：虚拟机IP，端口：3307，密码：123）。</p><p>Docker自动完成的操作：</p><ul><li><p>从镜像仓库搜索并下载<code>mysql:8</code>镜像（本地已存在则直接使用）；</p></li><li><p>基于镜像创建容器，并配置端口映射、时区、初始密码等参数；</p></li><li><p>自动启动容器内的MySQL服务，无需手动干预。</p></li></ul><h2 id="2-2-核心概念：镜像与容器">2.2 核心概念：镜像与容器</h2><ul><li><p><strong>镜像（Image）</strong>：可理解为“软件安装包+运行环境”的只读模板，包含程序运行所需的系统函数库、依赖、配置等。例如<code>mysql:8</code>就是MySQL 8版本的镜像。</p></li><li><p><strong>容器（Container）</strong>：镜像的运行实例，是独立的隔离环境。容器可启动、停止、删除，每个容器之间相互隔离，不影响主机环境。</p></li></ul><h2 id="2-3-镜像仓库（Docker-Registry）">2.3 镜像仓库（Docker Registry）</h2><p>Docker镜像的存储与管理平台，用于存放各类软件的镜像，分为三类：</p><ul><li><p>官方仓库：Docker Hub（<a href="https://hub.docker.com">https://hub.docker.com</a>），包含官方基础镜像及各大厂商提供的软件镜像（国内访问较慢）；</p></li><li><p>第三方仓库：阿里云、华为云等提供的镜像仓库，支持镜像加速，提升下载速度；</p></li><li><p>私有仓库：企业内部搭建的仓库，用于存储机密项目的自定义镜像。</p></li></ul><p>镜像来源：① 直接从镜像仓库下载；② 基于基础镜像自定义构建。</p><h2 id="2-4-快速入门总结">2.4 快速入门总结</h2><p>Docker部署应用的核心流程：通过Docker命令告知Docker守护进程 → 守护进程从镜像仓库拉取对应镜像 → 基于镜像创建并启动容器 → 应用部署完成。</p><h1>三、Docker基础操作</h1><h2 id="3-1-核心命令汇总">3.1 核心命令汇总</h2><p>以下是Docker日常使用的核心命令，涵盖镜像管理、容器管理等场景：</p><table><thead><tr><th>命令</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>docker pull</td><td>从镜像仓库拉取镜像</td><td>docker pull nginx:1.20.2</td></tr><tr><td>docker push</td><td>推送镜像到镜像仓库</td><td>docker push myapp:1.0</td></tr><tr><td>docker images</td><td>查看本地所有镜像</td><td>docker images</td></tr><tr><td>docker rmi</td><td>删除本地镜像（需先删除依赖容器）</td><td>docker rmi nginx:1.20.2</td></tr><tr><td>docker run</td><td>创建并运行容器（不可重复创建同名容器）</td><td>docker run -d --name nginx -p 80:80 nginx</td></tr><tr><td>docker stop</td><td>停止指定容器</td><td>docker stop nginx</td></tr><tr><td>docker start</td><td>启动已停止的容器</td><td>docker start nginx</td></tr><tr><td>docker restart</td><td>重启容器</td><td>docker restart nginx</td></tr><tr><td>docker rm</td><td>删除容器（运行中容器需加 -f 强制删除）</td><td>docker rm -f nginx</td></tr><tr><td>docker ps</td><td>查看容器（默认显示运行中，-a 显示所有）</td><td>docker ps -a</td></tr><tr><td>docker logs</td><td>查看容器运行日志（-f 实时监控）</td><td>docker logs -f mysql</td></tr><tr><td>docker exec</td><td>进入运行中的容器</td><td>docker exec -it nginx bash</td></tr><tr><td>docker save</td><td>将镜像保存为本地压缩文件</td><td>docker save -o nginx.tar nginx:1.20.2</td></tr><tr><td>docker load</td><td>加载本地压缩文件为镜像</td><td>docker load -i nginx.tar</td></tr><tr><td>docker inspect</td><td>查看容器/镜像详细信息</td><td>docker inspect mysql</td></tr></tbody></table><h3 id="3-1-1-开机自启配置">3.1.1 开机自启配置</h3><p>默认情况下，虚拟机重启后Docker及容器需手动启动，可通过以下命令设置开机自启：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># Docker服务开机自启</span></span><br><span class="line">systemctl enable docker</span><br><span class="line"></span><br><span class="line"><span class="comment"># 单个容器开机自启（替换为容器名/容器ID）</span></span><br><span class="line">docker update <span class="literal">--restart</span>=always mysql</span><br></pre></td></tr></table></figure><h3 id="3-1-2-命令演示（以Nginx为例）">3.1.2 命令演示（以Nginx为例）</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 拉取Nginx 1.20.2版本镜像</span></span><br><span class="line">docker pull nginx:<span class="number">1.20</span>.<span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 查看本地镜像</span></span><br><span class="line">docker images</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 创建并运行Nginx容器</span></span><br><span class="line">docker run <span class="literal">-d</span> <span class="literal">--name</span> nginx <span class="literal">-p</span> <span class="number">80</span>:<span class="number">80</span> nginx:<span class="number">1.20</span>.<span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 查看运行中容器</span></span><br><span class="line">docker <span class="built_in">ps</span> <span class="literal">-a</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. 访问测试：浏览器输入 http://虚拟机IP（如192.168.200.128）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 6. 停止Nginx容器</span></span><br><span class="line">docker stop nginx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 7. 查看所有容器（包括已停止）</span></span><br><span class="line">docker <span class="built_in">ps</span> <span class="literal">-a</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 8. 重新启动Nginx容器</span></span><br><span class="line">docker <span class="built_in">start</span> nginx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 9. 进入Nginx容器内部</span></span><br><span class="line">docker exec <span class="literal">-it</span> nginx bash</span><br><span class="line"></span><br><span class="line"><span class="comment"># 10. 强制删除Nginx容器</span></span><br><span class="line">docker <span class="built_in">rm</span> <span class="operator">-f</span> nginx</span><br></pre></td></tr></table></figure><h2 id="3-2-数据卷（Volume）">3.2 数据卷（Volume）</h2><h3 id="3-2-1-核心问题：容器与数据解耦">3.2.1 核心问题：容器与数据解耦</h3><p>容器是隔离环境，内部文件默认存储在容器内部：① 容器销毁后，数据会丢失（如MySQL数据）；② 直接操作容器内文件不方便（如修改Nginx配置）。因此需要通过数据卷实现“容器内目录”与“宿主机目录”的映射。</p><h3 id="3-2-2-数据卷定义与优势">3.2.2 数据卷定义与优势</h3><p>数据卷是Docker管理的虚拟目录，作为容器内目录与宿主机目录的桥梁，优势：</p><ul><li><p>数据持久化：容器销毁后，数据存储在宿主机，不会丢失；</p></li><li><p>解耦环境：容器仅关注运行，数据存储由宿主机管理；</p></li><li><p>灵活映射：可通过数据卷间接映射，避免容器与宿主机目录强耦合。</p></li></ul><p>默认数据卷存储路径：<code>/var/lib/docker/volumes/[数据卷名]/_data</code></p><h3 id="3-2-3-数据卷核心命令">3.2.3 数据卷核心命令</h3><table><thead><tr><th>命令</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>docker volume create</td><td>创建数据卷</td><td>docker volume create nginx-html</td></tr><tr><td>docker volume ls</td><td>查看所有数据卷</td><td>docker volume ls</td></tr><tr><td>docker volume rm</td><td>删除指定数据卷</td><td>docker volume rm nginx-html</td></tr><tr><td>docker volume inspect</td><td>查看数据卷详情（含宿主机路径）</td><td>docker volume inspect nginx-html</td></tr><tr><td>docker volume prune</td><td>删除未使用的数据卷（清理空间）</td><td>docker volume prune</td></tr></tbody></table><h3 id="3-2-4-数据卷挂载演示（Nginx）">3.2.4 数据卷挂载演示（Nginx）</h3><p>通过<code>-v 数据卷名:容器内目录</code>实现挂载（创建容器时配置，不可事后修改）：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 创建Nginx容器并挂载数据卷（数据卷自动创建）</span></span><br><span class="line">docker run <span class="literal">-d</span> <span class="literal">--name</span> nginx <span class="literal">-p</span> <span class="number">80</span>:<span class="number">80</span> <span class="literal">-v</span> html:/usr/share/nginx/html nginx:<span class="number">1.20</span>.<span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 查看数据卷列表</span></span><br><span class="line">docker volume <span class="built_in">ls</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 查看html数据卷详情（获取宿主机映射路径）</span></span><br><span class="line">docker volume inspect html</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 进入宿主机映射目录，修改index.html</span></span><br><span class="line"><span class="built_in">cd</span> /var/lib/docker/volumes/html/_data</span><br><span class="line">vi index.html</span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. 浏览器访问虚拟机IP，查看修改效果</span></span><br><span class="line"><span class="comment"># 6. 进入容器内部验证：容器内文件同步更新</span></span><br><span class="line">docker exec <span class="literal">-it</span> nginx bash</span><br><span class="line"><span class="built_in">cat</span> /usr/share/nginx/html/index.html</span><br></pre></td></tr></table></figure><h3 id="3-2-5-匿名数据卷">3.2.5 匿名数据卷</h3><p>创建容器时未指定数据卷名，仅指定容器内目录，Docker会自动创建“匿名数据卷”（名称为随机哈希值）。例如MySQL容器默认会匿名挂载<code>/var/lib/mysql</code>目录，确保数据持久化。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 查看MySQL容器的挂载信息</span></span><br><span class="line">docker inspect mysql</span><br><span class="line"></span><br><span class="line"><span class="comment"># 关键信息：.Config.Volumes（声明需挂载目录）、.Mounts（实际挂载信息，含匿名数据卷名）</span></span><br></pre></td></tr></table></figure><h3 id="3-2-6-本地目录-文件直接挂载">3.2.6 本地目录/文件直接挂载</h3><p>数据卷默认路径较深，可直接将容器目录挂载到宿主机指定目录（更直观），语法：<code>-v 宿主机目录:容器内目录</code>（宿主机目录需以/或./开头，否则识别为数据卷）。</p><p>示例：MySQL本地目录挂载（提前在宿主机创建/root/mysql/data、conf、init目录）</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">docker run <span class="literal">-d</span> \</span><br><span class="line"><span class="literal">--name</span> mysql \</span><br><span class="line"><span class="literal">-p</span> <span class="number">3307</span>:<span class="number">3306</span> \</span><br><span class="line"><span class="literal">-e</span> MYSQL_ROOT_PASSWORD=<span class="number">123</span> \</span><br><span class="line"><span class="literal">-e</span> TZ=Asia/Shanghai \</span><br><span class="line"><span class="literal">-v</span> /root/mysql/<span class="keyword">data</span>:/var/lib/mysql \  <span class="comment"># 数据目录挂载</span></span><br><span class="line"><span class="literal">-v</span> /root/mysql/init:/docker<span class="literal">-entrypoint-initdb</span>.d \  <span class="comment"># 初始化SQL目录</span></span><br><span class="line"><span class="literal">-v</span> /root/mysql/conf:/etc/mysql/conf.d \  <span class="comment"># 配置文件目录</span></span><br><span class="line">mysql:<span class="number">8</span></span><br></pre></td></tr></table></figure><h2 id="3-3-自定义镜像（Dockerfile）">3.3 自定义镜像（Dockerfile）</h2><h3 id="3-3-1-自定义镜像场景">3.3.1 自定义镜像场景</h3><p>官方镜像无法满足需求时（如部署自定义Java项目），需基于基础镜像构建自定义镜像。镜像本质是“分层文件集合”，每层对应构建过程的一个操作步骤。</p><h3 id="3-3-2-Dockerfile核心语法">3.3.2 Dockerfile核心语法</h3><p>Dockerfile是记录镜像构建步骤的文本文件，常用指令：</p><table><thead><tr><th>指令</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>FROM</td><td>指定基础镜像（必须放在首行）</td><td>FROM centos:7</td></tr><tr><td>ENV</td><td>设置环境变量（后续指令可复用）</td><td>ENV JAVA_HOME=/usr/local/jdk-17.0.10</td></tr><tr><td>COPY</td><td>拷贝宿主机文件到镜像内</td><td>COPY app.jar /app/app.jar</td></tr><tr><td>RUN</td><td>执行Linux shell命令（构建时运行）</td><td>RUN tar -xzf jdk17.tar.gz -C /usr/local/</td></tr><tr><td>EXPOSE</td><td>声明容器运行时监听的端口（仅说明，不映射）</td><td>EXPOSE 8080</td></tr><tr><td>WORKDIR</td><td>设置容器运行时的工作目录</td><td>WORKDIR /app</td></tr><tr><td>ENTRYPOINT</td><td>指定容器启动时执行的命令（不可被覆盖）</td><td>ENTRYPOINT [“java”,“-jar”,“app.jar”]</td></tr></tbody></table><h3 id="3-3-3-自定义Java应用镜像示例">3.3.3 自定义Java应用镜像示例</h3><p>需求：基于CentOS 7构建包含JDK 17和Java项目（app.jar）的镜像。</p><h4 id="步骤1：准备文件">步骤1：准备文件</h4><p>在宿主机创建myapp目录，放入三个文件：① Dockerfile；② jdk17.tar.gz（JDK压缩包）；③ app.jar（项目打包文件）。</p><h4 id="步骤2：编写Dockerfile">步骤2：编写Dockerfile</h4><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 基础镜像</span></span><br><span class="line"><span class="keyword">FROM</span> centos:<span class="number">7</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 拷贝并解压JDK</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> jdk17.tar.gz /usr/local/</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> tar -xzf /usr/local/jdk17.tar.gz -C /usr/local/ &amp;&amp; <span class="built_in">rm</span> /usr/local/jdk17.tar.gz</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置JDK环境变量</span></span><br><span class="line"><span class="keyword">ENV</span> JAVA_HOME=/usr/local/jdk-<span class="number">17.0</span>.<span class="number">10</span></span><br><span class="line"><span class="keyword">ENV</span> PATH=$JAVA_HOME/bin:$PATH</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建应用目录并设置工作目录</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">mkdir</span> -p /app</span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /app</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 拷贝项目JAR包</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> app.jar app.jar</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 声明端口</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8080</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动命令</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;java&quot;</span>,<span class="string">&quot;-Djava.security.egd=file:/dev/./urandom&quot;</span>,<span class="string">&quot;-jar&quot;</span>,<span class="string">&quot;/app/app.jar&quot;</span>]</span></span><br></pre></td></tr></table></figure><h4 id="步骤3：构建镜像">步骤3：构建镜像</h4><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 进入myapp目录</span></span><br><span class="line"><span class="built_in">cd</span> /root/myapp</span><br><span class="line"></span><br><span class="line"><span class="comment"># 构建镜像（-t 指定镜像名:版本，. 表示Dockerfile在当前目录）</span></span><br><span class="line">docker build <span class="literal">-t</span> myapp:<span class="number">1.0</span> .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看构建后的镜像</span></span><br><span class="line">docker images</span><br></pre></td></tr></table></figure><h2 id="3-4-Docker网络">3.4 Docker网络</h2><h3 id="3-4-1-容器互联问题">3.4.1 容器互联问题</h3><p>容器默认使用Docker桥接网络，可通过IP互联，但容器IP是虚拟IP，重启后可能变化，直接写死IP会导致连接失败。解决方案：自定义网络，通过容器名互联。</p><h3 id="3-4-2-网络核心命令">3.4.2 网络核心命令</h3><table><thead><tr><th>命令</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>docker network create</td><td>创建自定义网络</td><td>docker network create itheima</td></tr><tr><td>docker network ls</td><td>查看所有网络</td><td>docker network ls</td></tr><tr><td>docker network connect</td><td>将容器加入指定网络</td><td>docker network connect itheima mysql</td></tr><tr><td>docker network disconnect</td><td>将容器移出网络</td><td>docker network disconnect itheima mysql</td></tr><tr><td>docker network rm</td><td>删除指定网络</td><td>docker network rm itheima</td></tr><tr><td>docker network inspect</td><td>查看网络详细信息</td><td>docker network inspect itheima</td></tr></tbody></table><h3 id="3-4-3-自定义网络演示（容器名互联）">3.4.3 自定义网络演示（容器名互联）</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 创建自定义网络 itheima</span></span><br><span class="line">docker network create itheima</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 查看网络列表（包含默认bridge、host、none网络）</span></span><br><span class="line">docker network <span class="built_in">ls</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 将mysql和myapp容器加入itheima网络</span></span><br><span class="line">docker network connect itheima mysql</span><br><span class="line">docker network connect itheima myapp</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 进入myapp容器，通过容器名ping mysql（无需记IP）</span></span><br><span class="line">docker exec <span class="literal">-it</span> myapp bash</span><br><span class="line">ping mysql  <span class="comment"># 成功互联，输出类似：64 bytes from mysql.itheima (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms</span></span><br></pre></td></tr></table></figure><h1>四、项目部署实战（tlias项目）</h1><p>本实战基于tlias-web-management项目，实现“后端Java服务+前端Nginx+MySQL”的完整部署，分为手动部署和Docker Compose批量部署两种方式。</p><h2 id="4-1-手动部署（分步实现）">4.1 手动部署（分步实现）</h2><h3 id="4-1-1-部署服务端（Java项目）">4.1.1 部署服务端（Java项目）</h3><h4 id="步骤1：项目准备与打包">步骤1：项目准备与打包</h4><ul><li>修改项目配置文件<code>application.yml</code>，将MySQL地址改为容器名（加入同一网络后可通过容器名访问）：</li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="attr">datasource:</span></span><br><span class="line">    <span class="attr">driver-class-name:</span> <span class="string">com.mysql.cj.jdbc.Driver</span></span><br><span class="line">    <span class="attr">url:</span> <span class="string">jdbc:mysql://mysql:3306/tlias</span>  <span class="comment"># mysql为容器名</span></span><br><span class="line">    <span class="attr">username:</span> <span class="string">root</span></span><br><span class="line">    <span class="attr">password:</span> <span class="number">123</span></span><br></pre></td></tr></table></figure><ul><li>通过Maven执行<code>package</code>命令（跳过测试），将打包后的JAR包命名为<code>tlias.jar</code>。</li></ul><h4 id="步骤2：编写Dockerfile-2">步骤2：编写Dockerfile</h4><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 基础镜像</span></span><br><span class="line"><span class="keyword">FROM</span> centos:<span class="number">7</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 拷贝并解压JDK</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> jdk17.tar.gz /usr/local/</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> tar -xzf /usr/local/jdk17.tar.gz -C /usr/local/ &amp;&amp; <span class="built_in">rm</span> /usr/local/jdk17.tar.gz</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置JDK环境变量</span></span><br><span class="line"><span class="keyword">ENV</span> JAVA_HOME=/usr/local/jdk-<span class="number">17.0</span>.<span class="number">10</span></span><br><span class="line"><span class="keyword">ENV</span> PATH=$JAVA_HOME/bin:$PATH</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置阿里云OSS环境变量（项目依赖时添加）</span></span><br><span class="line"><span class="keyword">ENV</span> OSS_ACCESS_KEY_ID=LTAI5tP6dc4cvccdvvySE39X</span><br><span class="line"><span class="keyword">ENV</span> OSS_ACCESS_KEY_SECRET=ZSyIT31qhxIkS0dH1H9WzHqPiyM3Ot</span><br><span class="line"></span><br><span class="line"><span class="comment"># 统一编码</span></span><br><span class="line"><span class="keyword">ENV</span> LANG=en_US.UTF-<span class="number">8</span></span><br><span class="line"><span class="keyword">ENV</span> LANGUAGE=en_US:en</span><br><span class="line"><span class="keyword">ENV</span> LC_ALL=en_US.UTF-<span class="number">8</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建应用目录并设置工作目录</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">mkdir</span> -p /tlias</span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /tlias</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 拷贝项目JAR包</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> tlias.jar tlias.jar</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 声明端口</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8080</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动命令</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">&quot;java&quot;</span>,<span class="string">&quot;-jar&quot;</span>,<span class="string">&quot;/tlias/tlias.jar&quot;</span>]</span></span><br></pre></td></tr></table></figure><h4 id="步骤3：构建镜像并启动容器">步骤3：构建镜像并启动容器</h4><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 宿主机创建/root/tlias目录，上传Dockerfile、tlias.jar、jdk17.tar.gz</span></span><br><span class="line">mkdir <span class="literal">-p</span> /root/tlias</span><br><span class="line"><span class="built_in">cd</span> /root/tlias</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 构建镜像</span></span><br><span class="line">docker build <span class="literal">-t</span> tlias:<span class="number">1.0</span> .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 启动容器（加入itheima网络，与MySQL互联）</span></span><br><span class="line">docker run <span class="literal">-d</span> <span class="literal">--name</span> tlias<span class="literal">-server</span> <span class="literal">--network</span> itheima <span class="literal">-p</span> <span class="number">8080</span>:<span class="number">8080</span> tlias:<span class="number">1.0</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 查看运行日志（验证启动成功）</span></span><br><span class="line">docker logs <span class="operator">-f</span> tlias<span class="literal">-server</span></span><br></pre></td></tr></table></figure><h3 id="4-1-2-部署前端（Nginx）">4.1.2 部署前端（Nginx）</h3><h4 id="步骤1：准备前端资源">步骤1：准备前端资源</h4><ul><li><p>宿主机创建<code>/usr/local/tlias-web</code>目录，包含<code>html</code>（前端静态资源）和<code>conf</code>（Nginx配置文件）子目录；</p></li><li><p>将前端打包后的静态资源（assets、index.html等）上传到<code>/usr/local/tlias-web/html</code>；</p></li><li><p>将配置好的nginx.conf上传到<code>/usr/local/tlias-web/conf</code>（配置反向代理到后端服务）。</p></li></ul><h4 id="步骤2：启动Nginx容器">步骤2：启动Nginx容器</h4><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">docker run <span class="literal">-d</span> \</span><br><span class="line"><span class="literal">--name</span> nginx<span class="literal">-tlias</span> \</span><br><span class="line"><span class="literal">-v</span> /usr/local/tlias<span class="literal">-web</span>/html:/usr/share/nginx/html \  <span class="comment"># 静态资源挂载</span></span><br><span class="line"><span class="literal">-v</span> /usr/local/tlias<span class="literal">-web</span>/conf/nginx.conf:/etc/nginx/nginx.conf \  <span class="comment"># 配置文件挂载</span></span><br><span class="line"><span class="literal">--network</span> itheima \  <span class="comment"># 加入同一网络</span></span><br><span class="line"><span class="literal">-p</span> <span class="number">80</span>:<span class="number">80</span> \</span><br><span class="line">nginx:<span class="number">1.20</span>.<span class="number">2</span></span><br></pre></td></tr></table></figure><h4 id="步骤3：访问测试">步骤3：访问测试</h4><p>浏览器输入<code>http://虚拟机IP</code>，能正常显示前端页面并调用后端接口，说明部署成功。</p><h2 id="4-2-Docker-Compose批量部署">4.2 Docker Compose批量部署</h2><h3 id="4-2-1-Docker-Compose优势">4.2.1 Docker Compose优势</h3><p>多容器项目（如前端、后端、MySQL）手动部署步骤繁琐，Docker Compose可通过一个<code>docker-compose.yml</code>文件定义所有容器的配置，一键完成创建、启动、网络配置等操作。</p><h3 id="4-2-2-核心语法（与docker-run参数对应）">4.2.2 核心语法（与docker run参数对应）</h3><table><thead><tr><th>docker run 参数</th><th>docker-compose.yml 指令</th><th>说明</th></tr></thead><tbody><tr><td>–name</td><td>container_name</td><td>容器名称</td></tr><tr><td>-p</td><td>ports</td><td>端口映射</td></tr><tr><td>-e</td><td>environment</td><td>环境变量</td></tr><tr><td>-v</td><td>volumes</td><td>数据卷/目录挂载</td></tr><tr><td>–network</td><td>networks</td><td>加入的网络</td></tr><tr><td>镜像名</td><td>image</td><td>使用的镜像</td></tr><tr><td>-f（Dockerfile）</td><td>build.context/dockerfile</td><td>构建自定义镜像的配置</td></tr></tbody></table><h3 id="4-2-3-docker-compose-yml编写（tlias项目）">4.2.3 docker-compose.yml编写（tlias项目）</h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="comment"># MySQL服务</span></span><br><span class="line">  <span class="attr">mysql:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">mysql:8</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">mysql</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;3307:3306&quot;</span></span><br><span class="line">    <span class="attr">environment:</span></span><br><span class="line">      <span class="attr">TZ:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line">      <span class="attr">MYSQL_ROOT_PASSWORD:</span> <span class="number">123</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/usr/local/app/mysql/conf:/etc/mysql/conf.d&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/usr/local/app/mysql/data:/var/lib/mysql&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/usr/local/app/mysql/init:/docker-entrypoint-initdb.d&quot;</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">tlias-net</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 后端Java服务</span></span><br><span class="line">  <span class="attr">tlias:</span></span><br><span class="line">    <span class="attr">build:</span></span><br><span class="line">      <span class="attr">context:</span> <span class="string">.</span>  <span class="comment"># Dockerfile所在目录（当前目录）</span></span><br><span class="line">      <span class="attr">dockerfile:</span> <span class="string">Dockerfile</span>  <span class="comment"># Dockerfile文件名</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">tlias-server</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8080:8080&quot;</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">tlias-net</span></span><br><span class="line">    <span class="attr">depends_on:</span>  <span class="comment"># 依赖mysql服务，启动顺序：先启动mysql再启动tlias</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">mysql</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 前端Nginx服务</span></span><br><span class="line">  <span class="attr">nginx:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">nginx:1.20.2</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">nginx-tlias</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;80:80&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/usr/local/app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/usr/local/app/nginx/html:/usr/share/nginx/html&quot;</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">tlias-net</span></span><br><span class="line">    <span class="attr">depends_on:</span>  <span class="comment"># 依赖tlias服务</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">tlias</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义网络（所有服务加入此网络，实现容器名互联）</span></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line">  <span class="attr">tlias-net:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">itheima</span>  <span class="comment"># 网络名称为itheima</span></span><br></pre></td></tr></table></figure><h3 id="4-2-4-Docker-Compose核心命令">4.2.4 Docker Compose核心命令</h3><table><thead><tr><th>命令</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>docker compose up -d</td><td>后台启动所有服务（创建容器、网络等）</td><td>docker compose up -d</td></tr><tr><td>docker compose down</td><td>停止并删除所有容器、网络（数据卷保留）</td><td>docker compose down</td></tr><tr><td>docker compose ps</td><td>查看当前服务的容器状态</td><td>docker compose ps</td></tr><tr><td>docker compose logs 服务名</td><td>查看指定服务的运行日志</td><td>docker compose logs tlias</td></tr><tr><td>docker compose stop/start/restart</td><td>停止/启动/重启所有服务</td><td>docker compose restart</td></tr><tr><td>docker compose exec 服务名 命令</td><td>进入指定服务的容器执行命令</td><td>docker compose exec mysql bash</td></tr></tbody></table><h3 id="4-2-5-部署演示">4.2.5 部署演示</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 宿主机创建/usr/local/app目录，上传以下文件/目录：</span></span><br><span class="line"><span class="comment"># - docker-compose.yml</span></span><br><span class="line"><span class="comment"># - Dockerfile、tlias.jar、jdk17.tar.gz（后端构建依赖）</span></span><br><span class="line"><span class="comment"># - mysql/conf、mysql/data、mysql/init（MySQL配置/数据/初始化SQL）</span></span><br><span class="line"><span class="comment"># - nginx/conf、nginx/html（Nginx配置/前端资源）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 进入/usr/local/app目录</span></span><br><span class="line"><span class="built_in">cd</span> /usr/local/app</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 一键部署所有服务（后台运行）</span></span><br><span class="line">docker compose up <span class="literal">-d</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 查看容器状态</span></span><br><span class="line">docker compose <span class="built_in">ps</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. 访问测试：浏览器输入http://虚拟机IP</span></span><br></pre></td></tr></table></figure><h1>五、附录：Docker安装与配置（CentOS）</h1><h2 id="5-1-卸载旧版Docker（可选）">5.1 卸载旧版Docker（可选）</h2><p>若系统已安装旧版Docker，先执行卸载命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">yum remove docker \</span><br><span class="line">    docker-client \</span><br><span class="line">    docker-client-latest \</span><br><span class="line">    docker-common \</span><br><span class="line">    docker-latest \</span><br><span class="line">    docker-latest-logrotate \</span><br><span class="line">    docker-logrotate \</span><br><span class="line">    docker-engine \</span><br><span class="line">    docker-selinux</span><br></pre></td></tr></table></figure><h2 id="5-2-配置Docker的YUM源">5.2 配置Docker的YUM源</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 安装yum工具依赖</span></span><br><span class="line"><span class="built_in">sudo</span> yum install -y yum-utils device-mapper-persistent-data lvm2</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 配置阿里云Docker YUM源（国内加速）</span></span><br><span class="line"><span class="built_in">sudo</span> yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo</span><br><span class="line"><span class="built_in">sudo</span> sed -i <span class="string">&#x27;s+download.docker.com+mirrors.aliyun.com/docker-ce+&#x27;</span> /etc/yum.repos.d/docker-ce.repo</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 更新yum缓存</span></span><br><span class="line"><span class="built_in">sudo</span> yum makecache fast</span><br></pre></td></tr></table></figure><h2 id="5-3-安装Docker">5.3 安装Docker</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin</span><br></pre></td></tr></table></figure><h2 id="5-4-启动与校验">5.4 启动与校验</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 启动Docker服务</span></span><br><span class="line">systemctl start docker</span><br><span class="line"></span><br><span class="line"><span class="comment"># 停止Docker服务</span></span><br><span class="line">systemctl stop docker</span><br><span class="line"></span><br><span class="line"><span class="comment"># 重启Docker服务</span></span><br><span class="line">systemctl restart docker</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置Docker开机自启</span></span><br><span class="line">systemctl <span class="built_in">enable</span> docker</span><br><span class="line"></span><br><span class="line"><span class="comment"># 校验安装成功（无报错即正常）</span></span><br><span class="line">docker ps</span><br></pre></td></tr></table></figure><h2 id="5-5-配置镜像加速（国内必备）">5.5 配置镜像加速（国内必备）</h2><p>配置国内镜像源，提升镜像下载速度：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment"># 1. 删除旧配置文件（若存在）</span></span><br><span class="line"><span class="built_in">rm</span> -f /etc/docker/daemon.json</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 写入镜像加速配置（多个源备选）</span></span><br><span class="line"><span class="built_in">tee</span> /etc/docker/daemon.json &lt;&lt;-<span class="string">&#x27;EOF&#x27;</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="string">&quot;registry-mirrors&quot;</span>: [</span><br><span class="line">        <span class="string">&quot;http://hub-mirror.c.163.com&quot;</span>,</span><br><span class="line">        <span class="string">&quot;https://mirrors.tuna.tsinghua.edu.cn&quot;</span>,</span><br><span class="line">        <span class="string">&quot;http://mirrors.sohu.com&quot;</span>,</span><br><span class="line">        <span class="string">&quot;https://ustc-edu-cn.mirror.aliyuncs.com&quot;</span>,</span><br><span class="line">        <span class="string">&quot;https://ccr.ccs.tencentyun.com&quot;</span>,</span><br><span class="line">        <span class="string">&quot;https://docker.m.daocloud.io&quot;</span>,</span><br><span class="line">        <span class="string">&quot;https://docker.awsl9527.cn&quot;</span></span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br><span class="line">EOF</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 重新加载配置</span></span><br><span class="line">systemctl daemon-reload</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 重启Docker使配置生效</span></span><br><span class="line">systemctl restart docker</span><br></pre></td></tr></table></figure><blockquote><p>（注：文档部分内容可能由 AI 生成）</p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;本文基于Docker实战文档整理，构建结构化知识体系，涵盖Docker核心概念、基础操作、数据卷、自定义镜像、网络配置及项目部署全流程，同时附上完整的Docker安装指南。内容兼顾入门友好性与实战实用性，适用于个人学习笔记及教学场景。&lt;/p&gt;
&lt;h1&gt;一、Docker概述与</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>大模型通识学习笔记</title>
    <link href="https://gwenliu.cn/posts/0d19b4ce.html"/>
    <id>https://gwenliu.cn/posts/0d19b4ce.html</id>
    <published>2026-04-12T16:00:00.000Z</published>
    <updated>2026-04-12T16:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、为什么要学“大模型通识”</h1><p>真正做 AI 应用时，很多人不是卡在“不会调 API”，而是卡在：</p><ul><li>不知道大模型擅长什么</li><li>不知道提示词该怎么设计</li><li>不知道什么时候该上 RAG</li><li>不知道 Agent 到底是不是刚需</li></ul><p>所以“大模型通识”并不是玄学，而是帮助你回答一个核心问题：</p><blockquote><p>面对一个真实需求，应该怎样把大模型正确接进来</p></blockquote><h1>二、提示词（Prompt）到底是什么</h1><p>Prompt 可以理解成：</p><blockquote><p>你给模型的任务说明书</p></blockquote><p>它通常包含这些部分：</p><ul><li>角色设定</li><li>背景信息</li><li>任务目标</li><li>输出格式</li><li>限制条件</li><li>示例</li></ul><h2 id="2-1-Prompt-的常见分类">2.1 Prompt 的常见分类</h2><h3 id="1-按样例数量分">1. 按样例数量分</h3><ul><li>Zero-shot：不给示例</li><li>One-shot：给 1 个示例</li><li>Few-shot：给多个示例</li></ul><h3 id="2-按内容结构分">2. 按内容结构分</h3><ul><li>指令型 Prompt</li><li>角色扮演型 Prompt</li><li>格式约束型 Prompt</li><li>带检索上下文的 Prompt</li></ul><h2 id="2-2-Prompt-写得好到底好在哪">2.2 Prompt 写得好到底好在哪</h2><p>一个好 Prompt 的目标不是“写得长”，而是：</p><ul><li>任务边界清晰</li><li>输出形式明确</li><li>模型知道优先级</li><li>模型知道什么不能做</li></ul><h2 id="2-3-常见-Prompt-误区">2.3 常见 Prompt 误区</h2><ul><li>把所有要求堆成一段大白话</li><li>不限制输出格式</li><li>想让模型同时完成太多任务</li><li>没给示例，却希望模型 100% 稳定</li></ul><h1>三、上下文窗口意味着什么</h1><p>上下文窗口指的是模型一次能“看到”的输入与历史内容总量。</p><p>这会直接影响：</p><ul><li>能不能处理长文档</li><li>能不能做多轮对话</li><li>能不能把足够多的参考资料塞进去</li></ul><p>但上下文长不代表效果一定更好。<br>如果塞进去的大量内容本身就杂乱，模型一样会困惑。</p><p>所以更重要的是：</p><ul><li>上下文是否相关</li><li>信息是否结构化</li><li>是否有冗余噪音</li></ul><h1>四、RAG 什么时候需要上</h1><p>RAG 的核心场景是：</p><ul><li>模型内置知识不够</li><li>业务知识经常更新</li><li>你希望回答必须基于指定资料</li></ul><h2 id="4-1-RAG-解决的是哪两类问题">4.1 RAG 解决的是哪两类问题</h2><h3 id="1-知识冻结">1. 知识冻结</h3><p>模型训练完成后，它的知识不是实时更新的。</p><h3 id="2-幻觉">2. 幻觉</h3><p>模型在不知道时，也可能一本正经地编。</p><p>RAG 的作用就是：</p><ul><li>先检索资料</li><li>再把资料交给模型生成答案</li></ul><h2 id="4-2-不是所有场景都要上-RAG">4.2 不是所有场景都要上 RAG</h2><p>以下情况不一定需要：</p><ul><li>只是闲聊</li><li>只做通用写作</li><li>任务完全不依赖私有知识</li></ul><p>所以判断标准不是“RAG 很火”，而是：</p><blockquote><p>这个任务是不是强依赖外部知识</p></blockquote><h1>五、Agent 到底是什么</h1><p>很多场景里，Agent 被说得很神秘。<br>其实可以先简单理解成：</p><blockquote><p>具有任务分解、工具调用和流程决策能力的系统</p></blockquote><p>它通常比单次问答更进一步，因为它会：</p><ul><li>判断该做什么</li><li>决定调用哪个工具</li><li>根据工具结果继续下一步</li></ul><h2 id="5-1-Agent-不等于“会聊天”">5.1 Agent 不等于“会聊天”</h2><p>聊天机器人可以只有对话能力；<br>但 Agent 往往还具备：</p><ul><li>搜索</li><li>调接口</li><li>查数据库</li><li>执行工作流</li></ul><h2 id="5-2-什么场景适合-Agent">5.2 什么场景适合 Agent</h2><ul><li>多步骤任务</li><li>需要工具联动</li><li>需要“看结果再决定下一步”</li></ul><p>比如：</p><ul><li>自动做资料搜集</li><li>先检索再总结</li><li>先调用 API 再组织答复</li></ul><h1>六、Workflow 和 Agent 的区别</h1><p>这两个很容易混。</p><h2 id="6-1-Workflow">6.1 Workflow</h2><p>更像：</p><blockquote><p>人提前设计好的固定流程</p></blockquote><p>优点：</p><ul><li>稳定</li><li>可控</li><li>可复现</li></ul><h2 id="6-2-Agent">6.2 Agent</h2><p>更像：</p><blockquote><p>在给定目标后，由系统动态决定路径</p></blockquote><p>优点：</p><ul><li>灵活</li><li>适合复杂任务</li></ul><p>缺点：</p><ul><li>不稳定性更高</li><li>调试更难</li></ul><h2 id="6-3-实践建议">6.3 实践建议</h2><p>如果流程固定、可预见，优先 Workflow。<br>如果步骤依赖中间结果、需要动态决策，再考虑 Agent。</p><h1>七、如何评价一个大模型应用是否做得好</h1><p>很多人只看“模型回答得像不像人”。<br>但真正评估应用效果，应该至少看：</p><ul><li>准确性</li><li>稳定性</li><li>时延</li><li>成本</li><li>可控性</li><li>可解释性</li></ul><h2 id="7-1-常见评估维度">7.1 常见评估维度</h2><h3 id="1-准确性">1. 准确性</h3><p>回答是不是对的。</p><h3 id="2-格式一致性">2. 格式一致性</h3><p>输出是不是总能符合要求。</p><h3 id="3-鲁棒性">3. 鲁棒性</h3><p>换个问法后，系统是否还稳定。</p><h3 id="4-成本">4. 成本</h3><p>同样效果下，是否花了过多 token 和模型费用。</p><h1>八、做大模型应用时最常见的误区</h1><h2 id="8-1-把问题全归咎于模型">8.1 把问题全归咎于模型</h2><p>很多失败并不是模型不够强，而是：</p><ul><li>Prompt 混乱</li><li>检索质量差</li><li>工具链设计不合理</li><li>输出格式没约束</li></ul><h2 id="8-2-过度迷信“全自动”">8.2 过度迷信“全自动”</h2><p>越复杂的自动化系统，越需要：</p><ul><li>明确边界</li><li>做失败兜底</li><li>提供人工接管点</li></ul><h2 id="8-3-只追最新模型，不重视系统设计">8.3 只追最新模型，不重视系统设计</h2><p>模型升级有帮助，但很多时候：</p><blockquote><p>一个设计合理的系统 + 次顶级模型<br>比一个设计混乱的系统 + 顶级模型 更稳定</p></blockquote><h1>九、一个实用的学习路径</h1><p>建议顺序：</p><ol><li>先理解 Prompt</li><li>再理解上下文与 Token 限制</li><li>学 RAG</li><li>学工具调用</li><li>学 Workflow</li><li>最后学 Agent</li></ol><p>这样比一上来堆所有概念更容易建立体系。</p><h1>十、总结</h1><p>大模型应用层真正要学的不是“神奇技巧”，而是：</p><ul><li>怎样清晰表达任务</li><li>怎样给模型提供正确上下文</li><li>怎样在需要时引入检索和工具</li><li>怎样让输出稳定、可控、可评估</li></ul><p>当你把 Prompt、RAG、Workflow、Agent 放在一张图里理解，很多概念都会突然清楚。</p>]]></content>
    
    
    <summary type="html">面向学习与应用视角，梳理提示词、上下文、RAG、Agent、评估与常见误区，建立大模型应用层的整体认知。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 发展史" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E5%8F%91%E5%B1%95%E5%8F%B2/"/>
    
    
    <category term="RAG" scheme="https://gwenliu.cn/tags/RAG/"/>
    
    <category term="大模型" scheme="https://gwenliu.cn/tags/%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    
    <category term="Prompt" scheme="https://gwenliu.cn/tags/Prompt/"/>
    
    <category term="Agent" scheme="https://gwenliu.cn/tags/Agent/"/>
    
  </entry>
  
  <entry>
    <title>大模型原理学习笔记</title>
    <link href="https://gwenliu.cn/posts/8f42ae31.html"/>
    <id>https://gwenliu.cn/posts/8f42ae31.html</id>
    <published>2026-04-12T15:50:00.000Z</published>
    <updated>2026-04-12T15:50:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、理解大模型要先抓住哪条主线</h1><p>大模型原理最容易学乱，因为术语很多：Transformer、预训练、SFT、RLHF、DPO、蒸馏、MoE……</p><p>如果只背名词，很快就会混。</p><p>更好的理解顺序是：</p><ol><li>先理解 Transformer 为什么能建模长文本</li><li>再理解预训练为什么能让模型“会说话”</li><li>再理解微调和对齐为什么能让模型“更听话”</li><li>最后理解推理、部署与优化为什么影响真实体验</li></ol><h1>二、Transformer 是什么</h1><p>大语言模型的核心架构大多来自 Transformer。</p><p>它相较于传统 RNN/LSTM 的关键突破是：</p><ul><li>更容易并行训练</li><li>更擅长处理长距离依赖</li><li>更适合大规模数据和大参数量扩展</li></ul><h2 id="2-1-Attention-的直觉理解">2.1 Attention 的直觉理解</h2><p>Attention 可以理解成：</p><blockquote><p>模型在生成当前词时，会去看输入序列中哪些位置最相关</p></blockquote><p>比如句子：</p><p><code>小明把球给了小红，因为她要去上课。</code></p><p>模型在理解“她”指代谁时，就需要关注上下文中的人物关系。<br>Attention 的作用，就是动态决定“看哪里更重要”。</p><h2 id="2-2-Self-Attention-的作用">2.2 Self-Attention 的作用</h2><p>Self-Attention 指的是：</p><ul><li>序列中的每个 token</li><li>都可以和同一序列里其他 token 建立关联</li></ul><p>它的结果是：</p><ul><li>模型更容易建模上下文关系</li><li>更适合自然语言这种强上下文任务</li></ul><h1>三、为什么预训练能让模型变强</h1><p>预训练本质上是在做一件事：</p><blockquote><p>用海量文本让模型学习语言分布</p></blockquote><p>在训练时，模型并不是“背答案”，而是不断学习：</p><ul><li>哪些词更可能一起出现</li><li>什么样的句式更自然</li><li>哪些知识在语料里更常见</li></ul><h2 id="3-1-预训练阶段模型学到了什么">3.1 预训练阶段模型学到了什么</h2><ul><li>语言模式</li><li>常识知识</li><li>写作结构</li><li>指令跟随的基础能力</li></ul><p>但要注意：</p><p>预训练后的模型并不一定“擅长完成任务”，它更像一个<strong>会续写文本的强大语言引擎</strong>。</p><h2 id="3-2-为什么预训练最烧钱">3.2 为什么预训练最烧钱</h2><p>因为它通常具备这些特征：</p><ul><li>数据量最大</li><li>训练时间最长</li><li>计算资源消耗最高</li></ul><p>所以在工业实践里，预训练往往是成本最高的一步。</p><h1>四、为什么还需要微调</h1><p>光靠预训练，模型虽然“会说”，但不一定“会按要求做”。</p><p>于是就有了后续的微调与对齐训练。</p><h2 id="4-1-SFT（监督微调）">4.1 SFT（监督微调）</h2><p>SFT 即 Supervised Fine-Tuning。</p><p>可以理解为：</p><ul><li>给模型输入“问题”</li><li>同时提供“高质量示范答案”</li><li>让模型学会在任务场景下输出更符合要求的结果</li></ul><p>适用目标：</p><ul><li>学会问答格式</li><li>学会写总结、翻译、代码解释等任务输出</li><li>提升任务可控性</li></ul><h2 id="4-2-奖励模型与对齐">4.2 奖励模型与对齐</h2><p>模型不只是要“像人类那样回答”，还要：</p><ul><li>更安全</li><li>更有帮助</li><li>更符合偏好</li></ul><p>因此会有偏好数据和奖励模型，用来评估“哪个回答更好”。</p><h1>五、RLHF 与 DPO 怎么理解</h1><h2 id="5-1-RLHF（基于人类反馈的强化学习）">5.1 RLHF（基于人类反馈的强化学习）</h2><p>RLHF 的大致流程是：</p><ol><li>模型先输出多个候选回答</li><li>人类对这些回答做偏好排序</li><li>训练奖励模型学习人类偏好</li><li>再通过强化学习优化主模型</li></ol><p>目的不是让模型“更会背知识”，而是让它：</p><ul><li>更符合人类偏好</li><li>更少出现危险输出</li><li>更擅长遵循任务意图</li></ul><h2 id="5-2-DPO（直接偏好优化）">5.2 DPO（直接偏好优化）</h2><p>DPO 可以看成是对 RLHF 流程的一种简化。</p><p>它的特点是：</p><ul><li>不再显式训练复杂的强化学习环节</li><li>直接用偏好样本优化模型</li></ul><p>优势在于：</p><ul><li>训练流程更简单</li><li>工程实现更直接</li><li>在很多场景下效果足够好</li></ul><h1>六、现代大模型训练范式可以怎么记</h1><p>你可以把一条典型训练链路记成：</p><ol><li>Transformer 架构</li><li>预训练（学语言与知识分布）</li><li>SFT（学任务格式）</li><li>偏好对齐（RLHF / DPO）</li><li>推理优化与部署</li></ol><p>这条主线比单独记术语更容易掌握。</p><h1>七、推理阶段为什么也很重要</h1><p>很多人只盯训练，但真实体验往往取决于推理阶段。</p><p>推理时常见关注点包括：</p><ul><li>首 token 延迟</li><li>吞吐量</li><li>上下文长度</li><li>显存占用</li><li>输出稳定性</li></ul><h2 id="7-1-为什么同一个模型体验差异很大">7.1 为什么同一个模型体验差异很大</h2><p>因为最终体验不仅由模型参数决定，还受这些因素影响：</p><ul><li>推理框架</li><li>量化方式</li><li>缓存机制</li><li>GPU / CPU 性能</li><li>系统提示词与采样参数</li></ul><h1>八、开源模型与闭源模型的核心差异</h1><h2 id="8-1-开源模型优势">8.1 开源模型优势</h2><ul><li>可私有化部署</li><li>可微调</li><li>可控性更强</li><li>成本更可预测</li></ul><h2 id="8-2-闭源模型优势">8.2 闭源模型优势</h2><ul><li>整体能力通常更强</li><li>对齐质量更成熟</li><li>工程体验更完整</li></ul><p>实际项目里常见思路不是“只选一种”，而是：</p><ul><li>通用复杂任务用闭源</li><li>高隐私、低成本、可定制任务用开源</li></ul><h1>九、学习大模型原理时最容易踩的坑</h1><h2 id="9-1-只背缩写，不理解目的">9.1 只背缩写，不理解目的</h2><p>比如：</p><ul><li>只记住 SFT、RLHF、DPO 名字</li><li>但不知道它们分别解决什么问题</li></ul><p>更好的问法应该是：</p><ul><li>这一步是为了学语言？</li><li>还是为了学任务？</li><li>还是为了学偏好？</li></ul><h2 id="9-2-只盯参数量，不看系统能力">9.2 只盯参数量，不看系统能力</h2><p>参数量大不等于一定更好。</p><p>真实效果还和：</p><ul><li>训练数据质量</li><li>对齐质量</li><li>工程实现</li><li>工具调用能力</li></ul><p>密切相关。</p><h1>十、总结</h1><p>理解大模型原理，最有效的方式不是一上来扎进公式，而是先抓住这条主线：</p><blockquote><p>Transformer 负责建模<br>预训练负责学语言<br>SFT 负责学任务<br>对齐训练负责学偏好<br>推理优化负责真实体验</p></blockquote><p>只要这条线理顺，后面的术语和训练方法就不会再乱。</p><h1>延伸阅读</h1><ul><li>Attention Is All You Need: <a href="https://arxiv.org/abs/1706.03762">https://arxiv.org/abs/1706.03762</a></li><li>Direct Preference Optimization: <a href="https://arxiv.org/abs/2305.18290">https://arxiv.org/abs/2305.18290</a></li></ul>]]></content>
    
    
    <summary type="html">以训练范式为主线，梳理大语言模型从 Transformer 到预训练、对齐训练、推理部署的关键机制。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="从零理解 AI" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/%E4%BB%8E%E9%9B%B6%E7%90%86%E8%A7%A3-AI/"/>
    
    
    <category term="大模型" scheme="https://gwenliu.cn/tags/%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    
    <category term="Transformer" scheme="https://gwenliu.cn/tags/Transformer/"/>
    
    <category term="预训练" scheme="https://gwenliu.cn/tags/%E9%A2%84%E8%AE%AD%E7%BB%83/"/>
    
    <category term="对齐训练" scheme="https://gwenliu.cn/tags/%E5%AF%B9%E9%BD%90%E8%AE%AD%E7%BB%83/"/>
    
  </entry>
  
  <entry>
    <title>Embeddings 和向量数据库入门</title>
    <link href="https://gwenliu.cn/posts/b83d1c7e.html"/>
    <id>https://gwenliu.cn/posts/b83d1c7e.html</id>
    <published>2026-04-12T15:40:00.000Z</published>
    <updated>2026-04-12T15:40:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、什么是 Embedding</h1><p>Embedding 可以理解为：<strong>把文本、图片、音频或视频映射成一组数值向量</strong>。<br>这些数值不是给人直接阅读的，而是给模型和检索系统计算“相似度”用的。</p><p>举个最简单的例子：</p><ul><li>“苹果手机”</li><li>“iPhone”</li></ul><p>虽然文本不同，但语义接近，所以它们生成出来的向量通常也会更接近。</p><p>这就是 Embedding 的核心价值：<strong>让机器能计算语义上的相近程度</strong>。</p><h2 id="1-1-Embedding-常见类型">1.1 Embedding 常见类型</h2><ul><li>文本 Embedding：最常见，用于搜索、推荐、RAG</li><li>图片 Embedding：用于以图搜图、图像相似检索</li><li>多模态 Embedding：把文本和图片映射到同一语义空间</li></ul><h1>二、为什么需要向量数据库</h1><p>如果只有少量数据，向量可以直接存在内存或普通数据库里。<br>但一旦数据规模变大，就会遇到两个问题：</p><ol><li>向量维度高，普通精确检索成本高</li><li>相似度搜索会随着数据量增加而变慢</li></ol><p>这时就需要向量数据库，或者带向量索引能力的数据库。</p><p>它们的主要作用是：</p><ul><li>高效存储向量</li><li>支持相似度搜索</li><li>提供 ANN（近似最近邻）索引</li><li>搭配元数据过滤做更实用的检索</li></ul><h1>三、向量数据库到底在查什么</h1><p>本质上不是“按关键词匹配”，而是在查：</p><blockquote><p>哪些向量和当前查询向量距离最近</p></blockquote><p>所以向量检索更偏语义，而关键词检索更偏字面。</p><h2 id="3-1-常见距离度量">3.1 常见距离度量</h2><h3 id="1-余弦相似度">1. 余弦相似度</h3><p>衡量两个向量方向是否接近。<br>文本语义检索中非常常见。</p><h3 id="2-欧氏距离">2. 欧氏距离</h3><p>衡量两个点在空间中的直线距离。</p><h3 id="3-点积">3. 点积</h3><p>在一些模型和实现里也常被使用。</p><p>不同模型、不同库，对距离度量支持会不同，不能混用。</p><h1>四、向量数据库的工作流</h1><p>一条典型链路通常是：</p><ol><li>准备原始文本</li><li>切分文档</li><li>调 Embedding 模型把每个 chunk 编码成向量</li><li>把向量和元数据写入数据库</li><li>查询时把用户问题也编码成向量</li><li>到数据库里做 Top-K 相似检索</li><li>返回最相关片段给上层应用</li></ol><p>如果用于 RAG，最后还会多一步：</p><ol start="8"><li>把检索结果拼进 Prompt，再交给大模型生成答案</li></ol><h1>五、为什么 RAG 离不开 Embedding</h1><p>RAG 的关键不是“把文档塞给模型”，而是：</p><ul><li>先从大量文档里找到真正相关的片段</li><li>再把这些片段作为上下文提供给大模型</li></ul><p>而这个“找到相关片段”的过程，最主流的实现方式就是：</p><p><strong>Embedding + 向量检索</strong></p><p>所以可以简单记成：</p><ul><li>Embedding 负责“表示语义”</li><li>向量数据库负责“高效召回”</li><li>LLM 负责“基于召回结果组织答案”</li></ul><h1>六、主流向量数据库与方案</h1><h2 id="6-1-专用向量数据库">6.1 专用向量数据库</h2><p>代表：</p><ul><li>Milvus</li><li>Weaviate</li><li>Qdrant</li><li>Pinecone</li></ul><p>优点：</p><ul><li>向量检索能力强</li><li>索引与检索能力成熟</li><li>适合大规模语义搜索</li></ul><p>缺点：</p><ul><li>系统栈更复杂</li><li>运维与学习成本更高</li></ul><h2 id="6-2-带向量能力的通用数据库">6.2 带向量能力的通用数据库</h2><p>代表：</p><ul><li>PostgreSQL + pgvector</li><li>Elasticsearch / OpenSearch</li><li>Redis Vector Similarity</li></ul><p>优点：</p><ul><li>可以和现有业务数据放在一起</li><li>上手门槛更低</li><li>便于做结构化过滤</li></ul><p>缺点：</p><ul><li>在超大规模纯向量检索场景下，可能不如专用方案</li></ul><h1>七、如何选择方案</h1><h2 id="7-1-小规模项目">7.1 小规模项目</h2><p>如果你是：</p><ul><li>个人项目</li><li>内部知识库</li><li>文档量有限</li></ul><p>优先建议：</p><ul><li>PostgreSQL + pgvector</li><li>Elasticsearch / OpenSearch</li></ul><p>原因是：</p><ul><li>部署简单</li><li>成本低</li><li>和现有业务系统更容易集成</li></ul><h2 id="7-2-中大规模检索系统">7.2 中大规模检索系统</h2><p>如果你是：</p><ul><li>大规模知识库</li><li>高并发搜索</li><li>多租户 RAG 平台</li></ul><p>可以考虑：</p><ul><li>Qdrant</li><li>Milvus</li><li>Weaviate</li></ul><p>重点看：</p><ul><li>检索延迟</li><li>索引能力</li><li>过滤能力</li><li>运维复杂度</li></ul><h1>八、做 Embedding 时最容易踩的坑</h1><h2 id="8-1-文档不切分，直接整篇编码">8.1 文档不切分，直接整篇编码</h2><p>问题：</p><ul><li>向量过粗</li><li>检索命中不精准</li></ul><p>正确做法：</p><ul><li>按语义或长度切 chunk</li><li>控制 chunk size</li><li>保留适度 overlap</li></ul><h2 id="8-2-混用不同模型的向量">8.2 混用不同模型的向量</h2><p>不同模型生成的向量空间通常不兼容。</p><p>所以：</p><ul><li>入库和查询必须使用同一个 Embedding 模型</li></ul><h2 id="8-3-只存向量，不存元数据">8.3 只存向量，不存元数据</h2><p>检索结果真正可用，往往依赖元数据：</p><ul><li>标题</li><li>来源</li><li>页码</li><li>时间</li><li>作者</li><li>业务标签</li></ul><p>元数据会直接影响检索后的可解释性和可过滤性。</p><h1>九、和关键词搜索的关系</h1><p>向量检索不一定替代关键词搜索，很多场景里它们是互补关系。</p><h2 id="9-1-关键词搜索适合">9.1 关键词搜索适合</h2><ul><li>查专有名词</li><li>查准确字段</li><li>查编号、产品名、报错码</li></ul><h2 id="9-2-向量检索适合">9.2 向量检索适合</h2><ul><li>查语义近义表达</li><li>用户问题表达不标准</li><li>需要召回“意思接近”的内容</li></ul><h2 id="9-3-实践建议">9.3 实践建议</h2><p>很多成熟系统会做“混合检索”：</p><ul><li>BM25 / 关键词检索</li><li>向量检索</li><li>最后再融合排序</li></ul><p>这通常比单一方案更稳。</p><h1>十、总结</h1><p>Embedding 和向量数据库不是“高深黑盒”，它们可以简单记成：</p><ul><li>Embedding：把内容变成可计算语义相似度的向量</li><li>向量数据库：把这些向量高效存起来，并支持相似度检索</li></ul><p>如果你想真正学好 RAG，这一块是绕不过去的基础。</p><h1>延伸阅读</h1><ul><li>OpenAI Embeddings Guide: <a href="https://platform.openai.com/docs/guides/embeddings">https://platform.openai.com/docs/guides/embeddings</a></li><li>pgvector 官方仓库: <a href="https://github.com/pgvector/pgvector">https://github.com/pgvector/pgvector</a></li></ul>]]></content>
    
    
    <summary type="html">理解向量表示、相似度检索与向量数据库的核心概念，建立 RAG 与语义搜索的基础知识框架。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="从零理解 AI" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/%E4%BB%8E%E9%9B%B6%E7%90%86%E8%A7%A3-AI/"/>
    
    
    <category term="Embeddings" scheme="https://gwenliu.cn/tags/Embeddings/"/>
    
    <category term="向量数据库" scheme="https://gwenliu.cn/tags/%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="RAG" scheme="https://gwenliu.cn/tags/RAG/"/>
    
    <category term="检索" scheme="https://gwenliu.cn/tags/%E6%A3%80%E7%B4%A2/"/>
    
  </entry>
  
  <entry>
    <title>AIGC 图像生成入门与实践</title>
    <link href="https://gwenliu.cn/posts/4c9f1a2d.html"/>
    <id>https://gwenliu.cn/posts/4c9f1a2d.html</id>
    <published>2026-04-12T15:20:00.000Z</published>
    <updated>2026-04-12T15:20:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、AIGC 图像生成到底在做什么</h1><p>AIGC 图像生成可以简单理解为：<strong>让模型根据文本、参考图或结构约束，生成符合要求的新图像</strong>。<br>常见输入包括：</p><ul><li>文本提示词：告诉模型“画什么”</li><li>参考图：告诉模型“长什么样”</li><li>结构条件：告诉模型“构图怎么摆”</li><li>参数控制：告诉模型“生成时偏向什么风格”</li></ul><p>从学习路径上看，它并不只是“会写提示词”这么简单，而是由<strong>模型、工作流、参数、后处理</strong>四部分共同决定结果。</p><h2 id="1-1-常见应用场景">1.1 常见应用场景</h2><ul><li>插画、立绘、壁纸、头像生成</li><li>商品图、海报、封面、广告素材</li><li>游戏原画草图、角色概念图</li><li>设计灵感探索与风格迭代</li><li>影视分镜、镜头草案、视觉参考</li></ul><h2 id="1-2-和传统修图的区别">1.2 和传统修图的区别</h2><p>传统修图更像“对已有图像做加工”；<br>AIGC 更像“基于条件重新生成一张新图”。</p><p>所以在 AIGC 场景里，重点不再只是 PS 技巧，而是：</p><ul><li>你是否知道该选什么模型</li><li>你是否能把需求拆成可表达的提示词</li><li>你是否会搭建一条稳定的生成流程</li></ul><h1>二、图像生成模型的核心原理</h1><p>目前主流开源图像生成模型大多建立在**扩散模型（Diffusion Model）**之上。</p><p>它的大致思路是：</p><ol><li>先把清晰图像逐步加噪，得到一张“纯噪声图”</li><li>再训练模型学会如何一步步从噪声还原出图像</li><li>推理时，从噪声开始，按照提示词逐步去噪，得到结果</li></ol><p>你可以把它理解成：</p><ul><li>训练阶段：模型学“如何从模糊混乱中恢复图像”</li><li>生成阶段：模型按你的要求“把噪声雕刻成图”</li></ul><h2 id="2-1-为什么同一句提示词每次出图不同">2.1 为什么同一句提示词每次出图不同</h2><p>因为生成起点通常是一张随机噪声图。</p><p>所以哪怕提示词一样，只要以下任一项变化，结果就可能不同：</p><ul><li>随机种子（seed）</li><li>采样器（sampler）</li><li>步数（steps）</li><li>CFG Scale</li><li>模型或 LoRA</li></ul><h2 id="2-2-影响结果的-5-个关键参数">2.2 影响结果的 5 个关键参数</h2><h3 id="1-Seed">1. Seed</h3><p>决定随机起点。<br>固定 seed，才能更稳定地复现实验结果。</p><h3 id="2-Steps">2. Steps</h3><p>去噪步数。<br>步数太低，细节不足；步数过高，耗时上升且不一定继续增益。</p><h3 id="3-CFG-Scale">3. CFG Scale</h3><p>模型对提示词的服从程度。</p><ul><li>太低：不听话</li><li>太高：容易生硬、失真</li></ul><h3 id="4-Sampler">4. Sampler</h3><p>采样方式。<br>不同采样器会影响风格、速度和稳定性。</p><h3 id="5-分辨率">5. 分辨率</h3><p>分辨率不是越高越好。<br>先在较合理尺寸下出图，再放大修复，通常更稳。</p><h1>三、主流工具链怎么选</h1><h2 id="3-1-闭源在线产品">3.1 闭源在线产品</h2><p>代表：Midjourney、即梦、可灵、海螺、豆包等。</p><p>优点：</p><ul><li>上手快</li><li>界面友好</li><li>不依赖本地显卡</li></ul><p>缺点：</p><ul><li>价格和额度受平台限制</li><li>模型与参数透明度较低</li><li>工作流可控性不如开源工具</li></ul><p>适合：</p><ul><li>快速体验</li><li>非技术用户</li><li>对私有化和可控性要求不高的场景</li></ul><h2 id="3-2-Stable-Diffusion-生态">3.2 Stable Diffusion 生态</h2><p>这是当前最主流的开源图像生成生态之一。</p><p>优点：</p><ul><li>可私有部署</li><li>可换底模、LoRA、ControlNet、VAE</li><li>社区资源极其丰富</li></ul><p>缺点：</p><ul><li>学习成本高</li><li>环境配置复杂</li><li>参数、模型组合很多，新手容易迷路</li></ul><p>适合：</p><ul><li>有持续生成需求</li><li>需要自定义风格</li><li>想构建自己的工作流</li></ul><h2 id="3-3-ComfyUI">3.3 ComfyUI</h2><p>ComfyUI 本质上是一个<strong>节点式工作流编排工具</strong>。<br>它不是新的图像模型，而是把 Stable Diffusion 生态里的各个步骤可视化了。</p><p>你可以在 ComfyUI 里显式控制：</p><ul><li>文本编码</li><li>模型加载</li><li>采样</li><li>ControlNet</li><li>LoRA</li><li>图像放大</li><li>面部修复</li></ul><p>它特别适合“流程稳定后反复复用”的场景。</p><h1>四、从零出图的一条基础工作流</h1><p>下面是一条最适合新手理解的基础链路：</p><ol><li>选底模</li><li>写正向提示词</li><li>写反向提示词</li><li>调整采样器、步数、CFG</li><li>批量出图</li><li>保留 seed，二次微调</li><li>放大与修复</li></ol><h2 id="4-1-正向提示词怎么写">4.1 正向提示词怎么写</h2><p>推荐顺序：</p><p><code>主体 + 场景 + 构图 + 光线 + 风格 + 细节 + 画质</code></p><p>示例：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1 girl, long black hair, white dress, flower field, sunset light, cinematic composition, soft light, detailed face, delicate illustration, high quality</span><br></pre></td></tr></table></figure><h2 id="4-2-反向提示词怎么写">4.2 反向提示词怎么写</h2><p>反向提示词用来排除常见问题。</p><p>常见内容：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">low quality, blurry, bad anatomy, extra fingers, malformed hands, deformed face, watermark, text, duplicate</span><br></pre></td></tr></table></figure><h2 id="4-3-新手常见误区">4.3 新手常见误区</h2><ul><li>提示词写得过长但没有重点</li><li>一次改太多参数，导致无法定位问题</li><li>不固定 seed，结果无法复盘</li><li>还没学会基础采样就急着堆 LoRA 和插件</li></ul><h1>五、如何提高出图稳定性</h1><h2 id="5-1-固定一套“最小可用基线”">5.1 固定一套“最小可用基线”</h2><p>先固定：</p><ul><li>一个常用底模</li><li>一个采样器</li><li>一组默认参数</li><li>一套反向提示词</li></ul><p>这样你调参时，才知道究竟是哪个变量造成了变化。</p><h2 id="5-2-先出草图，再做精修">5.2 先出草图，再做精修</h2><p>推荐流程：</p><ol><li>小尺寸快速试图</li><li>选中构图最好的一张</li><li>固定 seed 精修</li><li>放大</li><li>面部修复或局部重绘</li></ol><h2 id="5-3-LoRA-的使用原则">5.3 LoRA 的使用原则</h2><p>LoRA 更适合“补充风格或角色特征”，不适合一上来叠太多。</p><p>建议：</p><ul><li>一次先挂 1 个 LoRA</li><li>强度从 0.6~0.8 开始试</li><li>多个 LoRA 叠加时注意风格冲突</li></ul><h1>六、学习顺序建议</h1><p>如果你刚开始学，顺序可以这样排：</p><ol><li>先理解扩散模型和基本参数</li><li>学会写基础提示词</li><li>学会固定 seed 做复现</li><li>再学 LoRA</li><li>再学 ControlNet / 局部重绘 / 放大</li><li>最后学 ComfyUI 节点工作流</li></ol><p>不要一开始就追求“最复杂工作流”，先把最小链路跑通最重要。</p><h1>七、实践建议</h1><h2 id="7-1-设备建议">7.1 设备建议</h2><p>本地部署时，显卡显存会直接决定体验。</p><p>一般来说：</p><ul><li>低显存：适合学习和低分辨率试图</li><li>中高显存：更适合 LoRA、ControlNet、较高分辨率</li></ul><h2 id="7-2-素材与版权">7.2 素材与版权</h2><p>图像生成虽快，但仍需注意：</p><ul><li>商用授权</li><li>模型训练来源风险</li><li>人物肖像与品牌元素</li><li>二次传播合规问题</li></ul><p>尤其是面向商业项目时，必须额外确认版权与平台协议。</p><h1>八、总结</h1><p>AIGC 图像生成真正的核心，不是“多会写玄学提示词”，而是：</p><ul><li>理解模型能力边界</li><li>建立稳定工作流</li><li>做好参数复现</li><li>学会逐步精修</li></ul><p>当你把“模型 + 提示词 + 工作流 + 后处理”这 4 件事串起来之后，出图质量才会真正稳定。</p><h1>延伸阅读</h1><ul><li>OpenAI Image Generation Docs: <a href="https://platform.openai.com/docs/guides/image-generation">https://platform.openai.com/docs/guides/image-generation</a></li><li>Stability AI API Docs: <a href="https://platform.stability.ai/docs">https://platform.stability.ai/docs</a></li><li>ComfyUI Docs: <a href="https://docs.comfy.org/">https://docs.comfy.org/</a></li></ul>]]></content>
    
    
    <summary type="html">从概念、模型、工具链到工作流，系统梳理 AIGC 图像生成的核心知识与落地方法。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 使用教程" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="AIGC" scheme="https://gwenliu.cn/tags/AIGC/"/>
    
    <category term="图像生成" scheme="https://gwenliu.cn/tags/%E5%9B%BE%E5%83%8F%E7%94%9F%E6%88%90/"/>
    
    <category term="Stable Diffusion" scheme="https://gwenliu.cn/tags/Stable-Diffusion/"/>
    
    <category term="ComfyUI" scheme="https://gwenliu.cn/tags/ComfyUI/"/>
    
  </entry>
  
  <entry>
    <title>AI 应用开发学习路线</title>
    <link href="https://gwenliu.cn/posts/3a9d6c52.html"/>
    <id>https://gwenliu.cn/posts/3a9d6c52.html</id>
    <published>2026-04-12T15:00:00.000Z</published>
    <updated>2026-04-12T15:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、这篇路线适合谁</h1><p>这篇文章主要写给三类人：</p><ul><li>完全零基础，想系统学 AI 应用开发的人</li><li>会一点工具使用，但还不会真正做项目的人</li><li>已经接触过 Dify、Coze、ChatGPT，但知识点很散的人</li></ul><p>如果你最后的目标是：</p><ul><li>看懂主流 AI 产品是怎么搭起来的</li><li>自己做一个知识库问答、内容生成器或学习助手</li><li>能把项目部署出来并持续迭代</li></ul><p>那这条路线是合适的。</p><hr><h1>二、先给结论：零基础不要一上来就学 Agent</h1><p>很多人一接触 AI，就被“智能体”“自动化”“多 Agent”这些词吸引住了，结果越学越乱。</p><p>更稳的顺序其实是：</p><ol><li>先补开发基础</li><li>再建立大模型通识</li><li>再学 API 调用和 Prompt</li><li>再学 Embedding、向量数据库和 RAG</li><li>再学 Dify、Coze 这类工作流平台</li><li>最后再学 Agent 和完整项目</li></ol><p>你可以把它理解成三句话：</p><blockquote><p>先学会把环境跑起来<br>再学会把模型用起来<br>最后学会把系统做出来</p></blockquote><hr><h1>三、阶段 0：先把开发基础补齐</h1><p>很多人以为自己学的是 AI，最后卡住的却是：</p><ul><li>不会创建项目</li><li>不会装依赖</li><li>不会看终端报错</li><li>不会用 Git 保存过程</li><li>不会用 Docker 跑数据库和服务</li></ul><p>所以第一阶段的重点不是“炫技”，而是把最基本的开发能力补上。</p><h2 id="3-1-这一阶段必须掌握什么">3.1 这一阶段必须掌握什么</h2><p>建议至少补下面 5 项：</p><ol><li><p>Python 基础<br>变量、函数、条件、循环、列表、字典、文件读写、模块、虚拟环境</p></li><li><p>Git 基础<br><code>clone</code>、<code>add</code>、<code>commit</code>、<code>pull</code>、<code>push</code>、<code>branch</code>、<code>merge</code></p></li><li><p>终端和 Linux 常用命令<br>目录切换、文件操作、端口查看、进程查看、日志查看</p></li><li><p>HTTP / JSON 基础<br>要知道接口请求是什么、请求体是什么、JSON 长什么样</p></li><li><p>Docker 基础<br>镜像、容器、端口映射、数据卷、<code>docker compose</code></p></li></ol><h2 id="3-2-为什么这一步不能跳">3.2 为什么这一步不能跳</h2><p>因为后面你无论学：</p><ul><li>OpenAI API</li><li>Claude Code</li><li>Dify</li><li>RAG</li><li>向量数据库</li></ul><p>都会碰到这些场景：</p><ul><li>装依赖</li><li>配环境变量</li><li>看日志</li><li>跑本地服务</li><li>连数据库</li><li>提交代码</li></ul><p>开发基础不稳，后面的所有高级概念都只能停留在“看懂了几个名词”的层面。</p><h2 id="3-3-推荐资料">3.3 推荐资料</h2><ul><li>Python 官方教程（简体中文）<br><a href="https://docs.python.org/zh-cn/3/tutorial/index.html">https://docs.python.org/zh-cn/3/tutorial/index.html</a></li><li>Pro Git 中文版<br><a href="https://git-scm.com/book/zh/v2">https://git-scm.com/book/zh/v2</a></li><li>Docker Get Started<br><a href="https://docs.docker.com/get-started/">https://docs.docker.com/get-started/</a></li></ul><h2 id="3-4-可配合阅读的站内笔记">3.4 可配合阅读的站内笔记</h2><ul><li>《版本控制Git》</li><li>《Linux 操作指南》</li><li>《Docker操作指南》</li><li>《Markdown语法教学》</li></ul><h2 id="3-5-学到什么程度算过关">3.5 学到什么程度算过关</h2><p>至少做到下面几件事：</p><ol><li>能在本地创建并运行一个 Python 项目</li><li>能从 GitHub 拉代码并提交一次改动</li><li>能看懂最常见的终端报错</li><li>能用 Docker 跑起一个数据库或服务</li></ol><hr><h1>四、阶段 1：建立大模型通识</h1><p>这个阶段的目标不是调模型，而是先把一些基础问题想明白：</p><ul><li>大模型到底是什么</li><li>它为什么能回答问题</li><li>它擅长什么，不擅长什么</li><li>Prompt、RAG、Workflow、Agent 分别解决什么问题</li></ul><p>如果这一层没打通，后面很容易出现一种情况：</p><blockquote><p>工具会点，名词会说，但不知道为什么这么配</p></blockquote><h2 id="4-1-这一阶段重点理解什么">4.1 这一阶段重点理解什么</h2><p>建议先搞清楚这些概念：</p><ul><li>Token</li><li>上下文窗口</li><li>Prompt</li><li>Transformer</li><li>预训练</li><li>SFT</li><li>对齐训练</li><li>幻觉</li><li>RAG</li><li>Workflow</li><li>Agent</li></ul><h2 id="4-2-更适合入门的学习顺序">4.2 更适合入门的学习顺序</h2><p>推荐顺序是：</p><ol><li>大模型是怎么“学会语言”的</li><li>Prompt 为什么能影响结果</li><li>为什么模型会幻觉</li><li>为什么很多业务场景需要外部知识</li><li>为什么 Workflow 和 Agent 不是一回事</li></ol><h2 id="4-3-推荐资料">4.3 推荐资料</h2><ul><li>Hugging Face LLM Course<br><a href="https://huggingface.co/course">https://huggingface.co/course</a></li><li>Anthropic Prompt Engineering Overview<br><a href="https://docs.anthropic.com/en/docs/prompt-engineering">https://docs.anthropic.com/en/docs/prompt-engineering</a></li></ul><h2 id="4-4-可配合阅读的站内笔记">4.4 可配合阅读的站内笔记</h2><ul><li>《大模型通识》</li><li>《大模型原理》</li><li>《Embeddings和向量数据库》</li></ul><h2 id="4-5-学到什么程度算过关">4.5 学到什么程度算过关</h2><p>至少能清楚解释下面 3 个问题：</p><ol><li>为什么“会聊天”不等于“会做业务”</li><li>为什么 Prompt 不能解决所有问题</li><li>为什么 RAG 和 Agent 都不是越早上越好</li></ol><hr><h1>五、阶段 2：学会调用模型，而不是只会聊天</h1><p>这一步是分水岭。</p><p>很多人会用现成 AI 工具，但不会自己调接口，不会控制输出格式，也不会把模型接进自己的程序。</p><p>如果你想做应用，这一步必须迈过去。</p><h2 id="5-1-这一步要学什么">5.1 这一步要学什么</h2><p>重点是这些能力：</p><ul><li>看懂官方 API 文档</li><li>发送一次最基本的模型请求</li><li>理解输入、输出、消息结构</li><li>做结构化输出</li><li>学会写第一版 Prompt</li><li>会记录测试样例并比较效果</li></ul><h2 id="5-2-建议的练手顺序">5.2 建议的练手顺序</h2><p>建议从简单到复杂：</p><ol><li>文本问答</li><li>文本总结</li><li>结构化提取</li><li>多轮对话</li><li>图像生成或图像理解</li><li>工具调用</li></ol><h2 id="5-3-为什么很多初学者总觉得“学不会”">5.3 为什么很多初学者总觉得“学不会”</h2><p>常见原因不是模型太难，而是上来就做太大的东西。</p><p>更好的方式是每次只练一个能力，比如：</p><ul><li>只练“把一段文章提炼成 JSON”</li><li>只练“把用户输入改写成更清楚的问题”</li><li>只练“用一个模型接口完成单一任务”</li></ul><p>先把“小能力”练稳，再去做大系统。</p><h2 id="5-4-推荐资料">5.4 推荐资料</h2><ul><li>OpenAI 平台总览<br><a href="https://platform.openai.com/docs/overview">https://platform.openai.com/docs/overview</a></li><li>OpenAI Tutorials<br><a href="https://platform.openai.com/docs/tutorials">https://platform.openai.com/docs/tutorials</a></li><li>Anthropic Prompt Engineering<br><a href="https://docs.anthropic.com/en/docs/prompt-engineering">https://docs.anthropic.com/en/docs/prompt-engineering</a></li><li>Claude Code Overview<br><a href="https://docs.anthropic.com/en/docs/claude-code/overview">https://docs.anthropic.com/en/docs/claude-code/overview</a></li></ul><h2 id="5-5-可配合阅读的站内笔记">5.5 可配合阅读的站内笔记</h2><ul><li>《Claude code使用教程》</li><li>《AIGC图像生成》</li></ul><h2 id="5-6-学到什么程度算过关">5.6 学到什么程度算过关</h2><p>至少能独立完成一个小程序：</p><ul><li>输入一段文本</li><li>调用模型</li><li>输出固定格式的结果</li><li>能处理一两个常见报错</li></ul><hr><h1>六、阶段 3：学 RAG，把知识接进应用</h1><p>很多“看起来挺聪明”的 AI Demo，一旦离开通用知识就不行了。</p><p>比如：</p><ul><li>企业知识库问答</li><li>产品文档问答</li><li>课程资料检索</li><li>私有资料总结</li></ul><p>这时就不能只靠模型脑子里的旧知识，而要把你的资料接进来，这就是 RAG 最重要的价值。</p><h2 id="6-1-学-RAG-时要理解的完整链路">6.1 学 RAG 时要理解的完整链路</h2><p>一套最基本的 RAG 系统，通常至少包含：</p><ol><li>文档读取</li><li>文档清洗</li><li>文档切分</li><li>Embedding 向量化</li><li>向量存储</li><li>检索召回</li><li>必要时重排</li><li>把检索结果拼进 Prompt</li><li>生成最终回答</li><li>评估回答质量</li></ol><h2 id="6-2-初学者最容易踩的坑">6.2 初学者最容易踩的坑</h2><ul><li>不切块，整篇直接喂模型</li><li>只存文本，不存元数据</li><li>检索不到也硬答</li><li>只看生成效果，不测召回效果</li><li>混淆关键词搜索和语义检索</li></ul><h2 id="6-3-推荐资料">6.3 推荐资料</h2><ul><li>OpenAI Embeddings Guide<br><a href="https://platform.openai.com/docs/guides/embeddings">https://platform.openai.com/docs/guides/embeddings</a></li><li>LangChain RAG Tutorial<br><a href="https://python.langchain.com/docs/tutorials/rag/">https://python.langchain.com/docs/tutorials/rag/</a></li><li>pgvector<br><a href="https://github.com/pgvector/pgvector">https://github.com/pgvector/pgvector</a></li><li>Dify Knowledge Base<br><a href="https://docs.dify.ai/en/guides/knowledge-base">https://docs.dify.ai/en/guides/knowledge-base</a></li></ul><h2 id="6-4-可配合阅读的站内笔记">6.4 可配合阅读的站内笔记</h2><ul><li>《Embeddings和向量数据库》</li><li>《RAG技术》</li></ul><h2 id="6-5-学到什么程度算过关">6.5 学到什么程度算过关</h2><p>你至少要能做出一个最小版本：</p><ul><li>上传几篇文档</li><li>能根据提问检索到相关片段</li><li>能返回带上下文的答案</li><li>知道答案是怎么来的</li></ul><hr><h1>七、阶段 4：学 Dify 和 Coze，开始做工作流</h1><p>当你已经知道模型接口怎么调，也知道 RAG 是怎么回事后，就可以开始学平台了。</p><h2 id="7-1-为什么建议先学-Dify，再学-Coze">7.1 为什么建议先学 Dify，再学 Coze</h2><p>我更建议零基础先学 Dify，原因很简单：</p><ul><li>工作流节点更清楚</li><li>知识库能力更直观</li><li>更适合理解“一个 AI 应用是怎么编排起来的”</li></ul><p>Coze 也很好上手，但更偏“快速把一个 Bot 或轻应用搭起来”。<br>如果底层概念还不牢，容易变成只会点界面。</p><h2 id="7-2-这一阶段重点学什么">7.2 这一阶段重点学什么</h2><p>在平台里重点练这些能力：</p><ul><li>输入设计</li><li>Prompt 设计</li><li>参数提取</li><li>分支判断</li><li>知识检索</li><li>工具调用</li><li>发布与调试</li></ul><h2 id="7-3-推荐资料">7.3 推荐资料</h2><ul><li>Dify 30-Minute Quick Start<br><a href="https://docs.dify.ai/en/use-dify/getting-started/quick-start">https://docs.dify.ai/en/use-dify/getting-started/quick-start</a></li><li>Dify Workflow &amp; Chatflow<br><a href="https://docs.dify.ai/en/use-dify/build/workflow-chatflow">https://docs.dify.ai/en/use-dify/build/workflow-chatflow</a></li><li>Dify Chunking Guide<br><a href="https://docs.dify.ai/en/guides/knowledge-base/create-knowledge-and-upload-documents/chunking-and-cleaning-text">https://docs.dify.ai/en/guides/knowledge-base/create-knowledge-and-upload-documents/chunking-and-cleaning-text</a></li></ul><h2 id="7-4-可配合阅读的站内笔记">7.4 可配合阅读的站内笔记</h2><ul><li>《Dify部署与应用》</li><li>《Coze应用教程》</li></ul><h2 id="7-5-学到什么程度算过关">7.5 学到什么程度算过关</h2><p>至少做出 1 个可分享的工作流应用，比如：</p><ul><li>文档问答助手</li><li>内容生成器</li><li>学习资料整理助手</li></ul><hr><h1>八、阶段 5：最后再学 Agent</h1><p>Agent 很重要，但不适合作为零基础第一站。</p><p>因为 Agent 不是“一个更厉害的聊天框”，而是把：</p><ul><li>模型</li><li>工具</li><li>状态</li><li>决策</li><li>失败兜底</li></ul><p>这些东西都放到一起考虑。</p><h2 id="8-1-什么情况下再学-Agent-最合适">8.1 什么情况下再学 Agent 最合适</h2><p>当你已经会这些东西时，再学 Agent 会顺很多：</p><ul><li>会写 Prompt</li><li>会调模型 API</li><li>会搭 RAG</li><li>会做工作流</li><li>知道什么叫输入、输出、状态、工具</li></ul><h2 id="8-2-这一阶段重点理解什么">8.2 这一阶段重点理解什么</h2><ul><li>Agent 和 Workflow 的区别</li><li>什么时候该让模型“自己决定下一步”</li><li>工具调用怎么设计才稳</li><li>多步任务怎么拆</li><li>怎么做失败重试和人工接管</li><li>怎么评估 Agent 是否真的有效</li></ul><h2 id="8-3-推荐资料">8.3 推荐资料</h2><ul><li>OpenAI 平台总览中的 Agentic Applications 入口<br><a href="https://platform.openai.com/docs/overview">https://platform.openai.com/docs/overview</a></li><li>Hugging Face Agents Course<br><a href="https://huggingface.co/learn/agents-course/en/unit0/introduction">https://huggingface.co/learn/agents-course/en/unit0/introduction</a></li></ul><h2 id="8-4-学到什么程度算过关">8.4 学到什么程度算过关</h2><p>你能独立做一个简单 Agent，并回答清楚下面两个问题：</p><ol><li>为什么这里必须用 Agent，而不是普通工作流</li><li>失败时系统如何停下来，而不是一直乱跑</li></ol><hr><h1>九、阶段 6：开始做完整项目</h1><p>知识只有放进项目里，才会真正变成能力。</p><p>对零基础来说，我更建议先做下面这 3 类项目。</p><h2 id="9-1-项目-1：个人知识库问答助手">9.1 项目 1：个人知识库问答助手</h2><p>覆盖能力：</p><ul><li>文档处理</li><li>Embedding</li><li>向量检索</li><li>RAG</li></ul><p>适合练：</p><ul><li>文档切分</li><li>检索质量</li><li>回答可追溯</li></ul><h2 id="9-2-项目-2：内容生成工作流">9.2 项目 2：内容生成工作流</h2><p>比如：</p><ul><li>小红书文案生成</li><li>公众号提纲整理</li><li>多平台内容改写</li></ul><p>覆盖能力：</p><ul><li>Prompt</li><li>结构化输出</li><li>Workflow</li></ul><h2 id="9-3-项目-3：学习助手或资料整理-Agent">9.3 项目 3：学习助手或资料整理 Agent</h2><p>比如：</p><ul><li>自动搜索资料并整理摘要</li><li>根据课程资料生成学习清单</li><li>从多份文档中提炼知识点</li></ul><p>覆盖能力：</p><ul><li>Agent</li><li>工具调用</li><li>多步任务编排</li></ul><hr><h1>十、给零基础学习者的一份 12 周计划</h1><p>如果你希望有更具体的时间安排，可以按这个节奏来：</p><h2 id="第-1-2-周：开发基础">第 1-2 周：开发基础</h2><ul><li>Python 基础语法</li><li>Git 基础</li><li>终端基础</li><li>Docker 入门</li></ul><p>输出成果：</p><ul><li>跑通一个本地 Python 小脚本</li><li>用 Git 提交一次代码</li><li>用 Docker 跑起一个服务</li></ul><h2 id="第-3-4-周：大模型通识-Prompt">第 3-4 周：大模型通识 + Prompt</h2><ul><li>理解大模型基础概念</li><li>学 Prompt 设计</li><li>知道上下文、幻觉、输出格式控制</li></ul><p>输出成果：</p><ul><li>写出 3 组不同目标的 Prompt</li><li>比较不同 Prompt 的效果差异</li></ul><h2 id="第-5-6-周：模型-API-调用">第 5-6 周：模型 API 调用</h2><ul><li>跑通至少一个模型接口</li><li>做文本总结、结构化提取、问答</li></ul><p>输出成果：</p><ul><li>做一个可以运行的小工具</li></ul><h2 id="第-7-8-周：Embeddings-RAG">第 7-8 周：Embeddings + RAG</h2><ul><li>学文档切分</li><li>学向量化</li><li>学向量数据库</li><li>学检索与回答拼接</li></ul><p>输出成果：</p><ul><li>做一个最小知识库问答 Demo</li></ul><h2 id="第-9-10-周：Dify-Coze-工作流">第 9-10 周：Dify / Coze 工作流</h2><ul><li>用可视化平台做一个可分享应用</li><li>练调试、分支、知识库接入</li></ul><p>输出成果：</p><ul><li>发布一个工作流应用</li></ul><h2 id="第-11-12-周：完整项目-部署">第 11-12 周：完整项目 + 部署</h2><ul><li>选一个方向做成完整项目</li><li>补日志、评估、错误处理、部署</li></ul><p>输出成果：</p><ul><li>一个能真正演示和复用的项目</li></ul><hr><h1>十一、学习过程中最容易犯的 5 个错误</h1><h2 id="11-1-一上来就追最新名词">11.1 一上来就追最新名词</h2><p>最容易让人焦虑的不是不会，而是学得太散。</p><p>新名词层出不穷，但真正有用的能力往往还是：</p><ul><li>调接口</li><li>看日志</li><li>搭检索</li><li>做工作流</li><li>做评估</li></ul><h2 id="11-2-只看视频，不自己做">11.2 只看视频，不自己做</h2><p>看懂不等于会做。<br>每学完一个阶段，都要留下一个能运行的东西。</p><h2 id="11-3-只看生成效果，不看系统设计">11.3 只看生成效果，不看系统设计</h2><p>一个 AI 应用好不好，不只看回答像不像人，还要看：</p><ul><li>稳不稳定</li><li>成本高不高</li><li>能不能复现</li><li>出错后怎么处理</li></ul><h2 id="11-4-过早依赖平台">11.4 过早依赖平台</h2><p>平台很方便，但你至少要知道：</p><ul><li>节点背后做了什么</li><li>为什么这样编排</li><li>为什么这里要加检索或分支</li></ul><h2 id="11-5-不做记录">11.5 不做记录</h2><p>建议你把这些东西都记下来：</p><ul><li>用过的 Prompt</li><li>成功样例</li><li>失败样例</li><li>参数设置</li><li>系统结构图</li></ul><p>长期来看，这些记录会比你看过多少教程更值钱。</p><hr><h1>十二、最后的建议</h1><p>零基础学 AI 应用开发，不是比谁知道的名词多，而是比谁能一步一步把东西做出来。</p><p>真正有效的路线通常很朴素：</p><ol><li>先把基础工具学会</li><li>再把模型接口调通</li><li>再把知识接进来</li><li>再把流程编排起来</li><li>最后再追求 Agent 和复杂系统</li></ol><p>当你能独立做出一个：</p><ul><li>可以运行</li><li>可以解释</li><li>可以迭代</li><li>可以部署</li></ul><p>的项目时，你就已经不只是“会用 AI”，而是真的进入 AI 应用开发了。</p><hr><h1>参考资料</h1><ul><li>Python 官方教程：<a href="https://docs.python.org/zh-cn/3/tutorial/index.html">https://docs.python.org/zh-cn/3/tutorial/index.html</a></li><li>Pro Git 中文版：<a href="https://git-scm.com/book/zh/v2">https://git-scm.com/book/zh/v2</a></li><li>Docker Get Started：<a href="https://docs.docker.com/get-started/">https://docs.docker.com/get-started/</a></li><li>OpenAI Docs Overview：<a href="https://platform.openai.com/docs/overview">https://platform.openai.com/docs/overview</a></li><li>OpenAI Tutorials：<a href="https://platform.openai.com/docs/tutorials">https://platform.openai.com/docs/tutorials</a></li><li>OpenAI Embeddings Guide：<a href="https://platform.openai.com/docs/guides/embeddings">https://platform.openai.com/docs/guides/embeddings</a></li><li>Anthropic Prompt Engineering：<a href="https://docs.anthropic.com/en/docs/prompt-engineering">https://docs.anthropic.com/en/docs/prompt-engineering</a></li><li>Claude Code Overview：<a href="https://docs.anthropic.com/en/docs/claude-code/overview">https://docs.anthropic.com/en/docs/claude-code/overview</a></li><li>Hugging Face LLM Course：<a href="https://huggingface.co/course">https://huggingface.co/course</a></li><li>Hugging Face Agents Course：<a href="https://huggingface.co/learn/agents-course/en/unit0/introduction">https://huggingface.co/learn/agents-course/en/unit0/introduction</a></li><li>Dify Docs：<a href="https://docs.dify.ai/">https://docs.dify.ai/</a></li><li>LangChain RAG Tutorial：<a href="https://python.langchain.com/docs/tutorials/rag/">https://python.langchain.com/docs/tutorials/rag/</a></li><li>pgvector：<a href="https://github.com/pgvector/pgvector">https://github.com/pgvector/pgvector</a></li></ul>]]></content>
    
    
    <summary type="html">面向零基础学习者，从开发基础、模型认知、API 调用、RAG、工作流到 Agent，整理一条更适合从零开始的学习路径。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 使用教程" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="AI" scheme="https://gwenliu.cn/tags/AI/"/>
    
    <category term="学习路线" scheme="https://gwenliu.cn/tags/%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/"/>
    
    <category term="零基础" scheme="https://gwenliu.cn/tags/%E9%9B%B6%E5%9F%BA%E7%A1%80/"/>
    
    <category term="应用开发" scheme="https://gwenliu.cn/tags/%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/"/>
    
  </entry>
  
  <entry>
    <title>Markdown语法教学</title>
    <link href="https://gwenliu.cn/posts/a1c93e7f.html"/>
    <id>https://gwenliu.cn/posts/a1c93e7f.html</id>
    <published>2026-04-11T12:20:00.000Z</published>
    <updated>2026-04-11T12:20:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>Markdown语法教学</h1><p>本文档系统整理Markdown内核语法，按“基础语法→ 高级美化语法→ 特殊扩展语法”分类，每个语法点均附<strong>语法说明</strong>、<strong>实操示例</strong>和<strong>注意事项</strong>，适合零基础入门学习，可直接复制示例到Markdown编辑器（如Typora、Obsidian、VS Code）中实操验证。</p><p>内核优势：纯文本编写，语法简洁易记，可导出为HTML、PDF、Word等格式，广泛用于博客写作、学习笔记、技术文档、简历撰写等场景。</p><h1>一、基础语法</h1><p>这部分是Markdown的内核基础，掌握后可满足80%的日常写作需求，重点记忆“符号+规则”即可。</p><h2 id="1-1-标题">1.1 标题</h2><h3 id="语法说明">语法说明</h3><p>用“#”符号开头，后面加空格，再写标题内容；“#”数量对应标题层级（1-6级），级数越多，标题越小。</p><h3 id="实操示例">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 一级标题（最大，常用文档主标题）</span></span><br><span class="line"><span class="section">## 二级标题（常用章节标题）</span></span><br><span class="line"><span class="section">### 三级标题（常用小节标题）</span></span><br><span class="line"><span class="section">#### 四级标题</span></span><br><span class="line"><span class="section">##### 五级标题</span></span><br><span class="line"><span class="section">###### 六级标题（最小）</span></span><br></pre></td></tr></table></figure><h3 id="注意事项">注意事项</h3><ul><li><p>和标题文本之间必须加<strong>1个空格</strong>，否则会被识别为普通文本；</p></li><li><p>建议最多用到三级标题，层级过多会导致文档结构混乱；</p></li><li><p>部分编辑器（如Typora）支持选中文本后按“Ctrl+1~6”快速生成对应层级标题。</p></li></ul><h2 id="1-2-文本样式（加粗、斜体、删除线等）">1.2 文本样式（加粗、斜体、删除线等）</h2><h3 id="语法说明-2">语法说明</h3><p>通过特定符号包裹文本，实现加粗、斜体、删除线、下划线等样式，支持组合使用。</p><h3 id="实操示例-2">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="strong">**这是加粗文本**</span>（两个星号包裹）</span><br><span class="line"><span class="emphasis">*这是斜体文本*</span>（一个星号包裹）</span><br><span class="line"><span class="strong">**<span class="emphasis">*这是加粗+斜体文本*</span>**</span>（三个星号包裹）</span><br><span class="line">~~这是删除线文本~~（两个波浪线包裹）</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">u</span>&gt;</span></span>这是下划线文本<span class="language-xml"><span class="tag">&lt;/<span class="name">u</span>&gt;</span></span>（Markdown原生不支持，用HTML标签实现）</span><br><span class="line">==这是高亮文本==（部分编辑器支持，如Typora，需开启高亮功能）</span><br></pre></td></tr></table></figure><h3 id="注意事项-2">注意事项</h3><ul><li><p>包裹符号必须<strong>成对出现</strong>，且前后不能有多余空格；</p></li><li><p>下划线用HTML的<u>标签实现，兼容性比其他样式稍差；</p></li><li><p>高亮功能并非所有编辑器都支持，若不生效，可改用加粗替代。</p></li></ul><h2 id="1-3-列表（有序、无序、任务）">1.3 列表（有序、无序、任务）</h2><p>用于整理多条并列内容，分为有串行表（带序号）、无串行表（带符号）和任务列表（带复选框）。</p><h3 id="1-无串行表">1. 无串行表</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> 无串行表项1（用减号开头，加空格）</span><br><span class="line"><span class="bullet">+</span> 无串行表项2（用加号开头，加空格）</span><br><span class="line"><span class="bullet">*</span> 无串行表项3（用星号开头，加空格）</span><br><span class="line"><span class="bullet">  -</span> 子列表项（前面加2个空格，再用符号）</span><br><span class="line"><span class="bullet">  -</span> 子列表项</span><br></pre></td></tr></table></figure><h3 id="2-有串行表">2. 有串行表</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">1.</span> 有串行表项1（数字+点+空格）</span><br><span class="line"><span class="bullet">2.</span> 有串行表项2</span><br><span class="line"><span class="bullet">3.</span> 有串行表项3</span><br><span class="line"><span class="bullet">   1.</span> 子列表项（前面加2个空格）</span><br><span class="line"><span class="bullet">   2.</span> 子列表项</span><br></pre></td></tr></table></figure><h3 id="3-任务列表">3. 任务列表</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> [ ] 未完成任务（中括号内留空）</span><br><span class="line"><span class="bullet">-</span> [x] 已完成任务（中括号内加x，不区分大小写）</span><br><span class="line"><span class="bullet">-</span> [ ] 待学习：Markdown高级语法</span><br></pre></td></tr></table></figure><h3 id="注意事项-3">注意事项</h3><ul><li><p>所有列表符号后面必须加<strong>1个空格</strong>，否则无法识别；</p></li><li><p>无串行表的“-、+、*”效果完全一致，推荐统一用“-”，更易记；</p></li><li><p>子列表需在父列表项前加<strong>2个或4个空格</strong>（不同编辑器兼容不同，推荐2个）；</p></li><li><p>任务列表的中括号“[ ]”内部必须紧凑，不能有空格（如“[ ]”正确，“[  ]”错误）。</p></li></ul><h2 id="1-4-段落与换行">1.4 段落与换行</h2><h3 id="语法说明-3">语法说明</h3><p>Markdown中，段落之间需空<strong>1行</strong>；同一段落内换行，需在换行处加<strong>2个及以上空格</strong>，或用<br/>标签。</p><h3 id="实操示例-3">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">这是第一个段落。</span><br><span class="line">（这里空1行）</span><br><span class="line">这是第二个段落。</span><br><span class="line"></span><br><span class="line">这是同一段落的第一行（后面加2个空格）  </span><br><span class="line">这是同一段落的第二行（换行成功）</span><br><span class="line">这是同一段落的第三行<span class="language-xml"><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span>直接用br标签换行（兼容性更强）</span><br></pre></td></tr></table></figure><h3 id="注意事项-4">注意事项</h3><ul><li><p>不要用“Enter键直接换行”代替段落间隔，否则会被识别为同一段落；</p></li><li><p>加空格换行的方式在部分在线编辑器中可能失效，推荐用<br/>标签实现强制换行。</p></li></ul><h2 id="1-5-引用（块引用）">1.5 引用（块引用）</h2><h3 id="语法说明-4">语法说明</h3><p>用“&gt;”符号开头，加空格，后面写引用内容，支持多级引用和嵌套其他语法。</p><h3 id="实操示例-4">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="quote">&gt; 一级引用：这是引用的内容（比如引用别人的话、文献内容）</span></span><br><span class="line"><span class="quote">&gt; </span></span><br><span class="line"><span class="quote">&gt; &gt; 二级引用：嵌套引用（在一级引用基础上再加一个&gt;）</span></span><br><span class="line"><span class="quote">&gt; </span></span><br><span class="line"><span class="quote">&gt; 引用中可嵌套其他语法：</span></span><br><span class="line"><span class="quote">&gt; - 嵌套无串行表</span></span><br><span class="line"><span class="quote">&gt; 1. 嵌套有串行表</span></span><br><span class="line"><span class="quote">&gt; <span class="strong">**嵌套加粗文本**</span></span></span><br></pre></td></tr></table></figure><h3 id="注意事项-5">注意事项</h3><ul><li><p>“&gt;”后面加空格更规范，部分编辑器不加空格也能识别，但不推荐；</p></li><li><p>多级引用最多嵌套2-3级，过多会影响阅读体验；</p></li><li><p>引用块内换行时，需在换行处也加“&gt;”，否则会跳出引用块。</p></li></ul><h2 id="1-6-链接（外部链接、内部链接）">1.6 链接（外部链接、内部链接）</h2><p>用于添加可点击的链接，分为“外部链接（跳转到网页）”和“内部链接（跳转到文档内锚点）”。</p><h3 id="1-外部链接（最常用）">1. 外部链接（最常用）</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 语法1：[<span class="string">链接显示文本</span>](<span class="link">链接地址 &quot;可选的提示文本&quot;</span>)</span><br><span class="line">[<span class="string">百度一下</span>](<span class="link">https://www.baidu.com &quot;点击跳转到百度&quot;</span>)</span><br><span class="line"></span><br><span class="line">// 语法2：直接写链接地址（自动识别）</span><br><span class="line">https://www.baidu.com</span><br></pre></td></tr></table></figure><h3 id="2-内部链接（文档内跳转）">2. 内部链接（文档内跳转）</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 第一步：给目标位置设置锚点（通常用标题）</span><br><span class="line"><span class="section">### 1.6 链接（外部链接、内部链接）<span class="language-xml"><span class="tag">&lt;<span class="name">span</span> <span class="attr">id</span>=<span class="string">&quot;link-anchor&quot;</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span></span><br><span class="line"></span><br><span class="line">// 第二步：创建跳转链接</span><br><span class="line">[<span class="string">跳转到“链接”章节</span>](<span class="link">#link-anchor</span>)</span><br></pre></td></tr></table></figure><h3 id="注意事项-6">注意事项</h3><ul><li><p>外部链接的括号内，链接地址必须完整（含http/https）；</p></li><li><p>提示文本用双引号包裹，鼠标悬停在链接上时显示，可选填；</p></li><li><p>内部链接的锚点ID需唯一，否则可能跳转失败；部分编辑器支持直接用标题文本作为锚点（如<a href="#16-%E9%93%BE%E6%8E%A5%EF%BC%88%E5%A4%96%E9%83%A8%E9%93%BE%E6%8E%A5%E3%80%81%E5%86%85%E9%83%A8%E9%93%BE%E6%8E%A5%EF%BC%89">跳转到链接章节</a>），但兼容性较差，推荐用span标签手动设置锚点。</p></li></ul><h2 id="1-7-图片">1.7 图片</h2><h3 id="语法说明-5">语法说明</h3><p>语法与外部链接类似，只是在前面多一个“!”；格式：<code>![图片加载失败时的提示文本](图片地址 &quot;可选的图片标题&quot;)</code>。</p><h3 id="实操示例-5">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 1. 网络图片（用图片URL）</span><br><span class="line">![<span class="string">风景图</span>](<span class="link">https://example.com/fengjing.jpg &quot;美丽的风景&quot;</span>)</span><br><span class="line"></span><br><span class="line">// 2. 本地图片（用相对路径或绝对路径）</span><br><span class="line">// 相对路径（推荐，图片放在文档同级目录的images文档夹中）</span><br><span class="line">![<span class="string">本地图片</span>](<span class="link">./images/photo.jpg</span>)</span><br><span class="line">// 绝对路径（不推荐，换设备/目录后会失效）</span><br><span class="line">![<span class="string">本地图片</span>](<span class="link">D:/notes/images/photo.jpg</span>)</span><br></pre></td></tr></table></figure><h3 id="注意事项-7">注意事项</h3><ul><li><p>网络图片URL需能直接访问，否则图片无法显示；</p></li><li><p>本地图片推荐用<strong>相对路径</strong>，方便文档迁移和分享；</p></li><li><p>部分编辑器支持拖拽图片自动生成图片语法，高效便捷。</p></li></ul><h2 id="1-8-代码块与行内代码">1.8 代码块与行内代码</h2><p>用于展示代码，分为“行内代码（嵌入文本中）”和“代码块（独立区块）”。</p><h3 id="1-行内代码">1. 行内代码</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">用反引号<span class="code">`包裹代码，比如：在终端输入`</span>docker run -d nginx`命令启动Nginx容器。</span><br></pre></td></tr></table></figure><h3 id="2-代码块（推荐）">2. 代码块（推荐）</h3><p>// 语法：用3个反引号包裹代码，开头的反引号后可加编程语言名称（实现语法高亮）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 这是Python代码示例</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">hello</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;Hello, Markdown!&quot;</span>)</span><br><span class="line">hello()</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 这是Shell脚本示例</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;Hello World&quot;</span></span><br></pre></td></tr></table></figure><h3 id="注意事项-8">注意事项</h3><ul><li><p>反引号是键盘上“ESC键下方、1键左侧”的符号（`），不是单引号（'）；</p></li><li><p>代码块指定编程语言后，编辑器会自动实现语法高亮，推荐必加；</p></li><li><p>部分旧编辑器不支持语法高亮，仅显示为普通文本，不影响代码可读性。</p></li></ul><h1>二、高级美化语法</h1><p>掌握基础语法后，通过这些语法可让文档更美观、更具可读性，适合用于正式的技术文档、博客文章等场景。</p><h2 id="2-1-表格（规范排版数据）">2.1 表格（规范排版数据）</h2><h3 id="语法说明-6">语法说明</h3><p>用“|”分隔列，用“-”分隔表头和表体；可通过“:”控制列对齐方式。</p><h3 id="实操示例-6">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 基础表格（无对齐）</span><br><span class="line">| 姓名 | 年龄 | 职业 |</span><br><span class="line">| --- | --- | --- |</span><br><span class="line">| 张三 | 25 | 进程员 |</span><br><span class="line">| 李四 | 30 | 产品经理 |</span><br></pre></td></tr></table></figure><h4 id="效果展示">效果展示</h4><table><thead><tr><th>姓名</th><th>年龄</th><th>职业</th></tr></thead><tbody><tr><td>张三</td><td>25</td><td>进程员</td></tr><tr><td>李四</td><td>30</td><td>产品经理</td></tr></tbody></table><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 带对齐的表格（推荐）</span><br><span class="line">| 左对齐 | 居中对齐 | 右对齐 |</span><br><span class="line">| :--- | :---: | ---: |  // :在左边=左对齐，两边都有=居中，右边=右对齐</span><br><span class="line">| 内容1 | 内容2 | 内容3 |</span><br><span class="line">| 内容4 | 内容5 | 内容6 |</span><br></pre></td></tr></table></figure><h4 id="效果展示-2">效果展示</h4><table><thead><tr><th style="text-align:left">左对齐</th><th style="text-align:center">居中对齐</th><th style="text-align:right">右对齐</th></tr></thead><tbody><tr><td style="text-align:left">内容1</td><td style="text-align:center">内容2</td><td style="text-align:right">内容3</td></tr><tr><td style="text-align:left">内容4</td><td style="text-align:center">内容5</td><td style="text-align:right">内容6</td></tr></tbody></table><h3 id="注意事项-9">注意事项</h3><ul><li><p>表头和表体之间的“-”至少需要1个，推荐用3个及以上，更美观；</p></li><li><p>对齐符号“:”需紧贴“-”，否则对齐失效；</p></li><li><p>表格内容中若包含“|”，需用“\”转义（如“|”），否则会被识别为列分隔符；</p></li><li><p>复杂表格（如合并单元格）Markdown原生不支持，需用HTML的<table>标签实现（见2.6节）。</p></li></ul><h2 id="2-2-分割线（分隔内容区块）">2.2 分割线（分隔内容区块）</h2><h3 id="语法说明-7">语法说明</h3><p>用3个及以上的“-、*、_”符号，单独占一行，实现分割线效果。</p><h3 id="实操示例-7">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">这是分割线上面的内容</span><br><span class="line">---  // 减号分割线（推荐，最常用）</span><br><span class="line">这是分割线中间的内容</span><br><span class="line"><span class="strong">***  // 星号分割线</span></span><br><span class="line"><span class="strong">这是分割线下面的内容</span></span><br><span class="line"><span class="strong">___  // 下划线分割线</span></span><br></pre></td></tr></table></figure><h4 id="效果展示-3">效果展示</h4><p>三种分割线：</p><h2 id="这是分割线上面的内容">这是分割线上面的内容</h2><p>这是分割线中间的内容</p><hr><p>这是分割线下面的内容</p><hr><h3 id="注意事项-10">注意事项</h3><ul><li><p>分割线符号必须<strong>单独占一行</strong>，前后最好各空1行，否则可能与前后文本粘连；</p></li><li><p>推荐统一用“—”，简洁易记，兼容性最好。</p></li></ul><h2 id="2-3-高亮块（突出重点内容）">2.3 高亮块（突出重点内容）</h2><p>用于突出显示重要提示、警告、注意事项等内容，不同编辑器支持的语法略有差异，推荐两种常用方式。</p><h3 id="实操示例-8">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">// 方式1：用引用块+特殊符号（兼容性最好，所有编辑器都支持）</span><br><span class="line"><span class="quote">&gt; 💡 提示：这是重点提示内容，用引用块+emoji实现高亮效果。</span></span><br><span class="line"><span class="quote">&gt; ⚠️  警告：这是警告内容，注意规避风险。</span></span><br></pre></td></tr></table></figure><h4 id="效果展示-4">效果展示</h4><blockquote><p>💡 提示：这是重点提示内容，用引用块+emoji实现高亮效果。<br>⚠️  警告：这是警告内容，注意规避风险。</p></blockquote><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">// 方式2：用:::包裹（部分编辑器支持，如VuePress、VitePress）</span><br><span class="line">::: tip 提示</span><br><span class="line">这是提示类型的高亮块，可自定义标题。</span><br><span class="line">:::</span><br><span class="line"></span><br><span class="line">::: warning 警告</span><br><span class="line">这是警告类型的高亮块。</span><br><span class="line">:::</span><br><span class="line"></span><br><span class="line">::: danger 危险</span><br><span class="line">这是危险类型的高亮块。</span><br><span class="line">:::</span><br></pre></td></tr></table></figure><h3 id="注意事项-11">注意事项</h3><ul><li><p>方式1兼容性最好，推荐优先使用；emoji可通过“Win+.”快捷键调出选择面板（Windows）；</p></li><li><p>方式2的语法为扩展语法，部分编辑器（如Typora）需开启对应功能才能识别。</p></li></ul><h2 id="2-4-分栏（多列布局）">2.4 分栏（多列布局）</h2><p>实现多列并行显示，适合展示对比内容，Markdown原生不支持，需用HTML标签或扩展语法。</p><h3 id="实操示例-9">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">// 方式1：用HTML的div标签（兼容性最好）</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;display: flex; gap: 20px;&quot;</span>&gt;</span></span></span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;flex: 1;&quot;</span>&gt;</span></span></span><br><span class="line"><span class="code">    &lt;h4&gt;左栏内容&lt;/h4&gt;</span></span><br><span class="line"><span class="code">    &lt;p&gt;这是分栏的左栏，可放文本、列表等内容。&lt;/p&gt;</span></span><br><span class="line"><span class="code">  &lt;/div&gt;</span></span><br><span class="line"><span class="code">  &lt;div style=&quot;flex: 1;&quot;&gt;</span></span><br><span class="line"><span class="code">    &lt;h4&gt;右栏内容&lt;/h4&gt;</span></span><br><span class="line"><span class="code">    &lt;p&gt;这是分栏的右栏，两栏宽度相等。&lt;/p&gt;</span></span><br><span class="line"><span class="code">  &lt;/div&gt;</span></span><br><span class="line"><span class="code">&lt;/div&gt;</span></span><br><span class="line"><span class="code"></span></span><br><span class="line">// 方式2：用扩展语法（部分编辑器支持，如Typora）</span><br><span class="line">::: columns</span><br><span class="line">::: column</span><br><span class="line">左栏内容：这是分栏示例</span><br><span class="line">:::</span><br><span class="line">::: column</span><br><span class="line">右栏内容：适合对比展示</span><br><span class="line">:::</span><br><span class="line">:::</span><br></pre></td></tr></table></figure><h3 id="注意事项-12">注意事项</h3><ul><li><p>方式1的flex布局可通过调整style属性自定义分栏宽度、间距等；</p></li><li><p>分栏内容中若包含Markdown语法，部分编辑器可能无法识别，需用HTML标签（如<p>、<h4>）替代。</p></li></ul><h2 id="2-5-脚注（补充说明）">2.5 脚注（补充说明）</h2><h3 id="语法说明-8">语法说明</h3><p>用于添加文档末尾的补充说明，不影响正文阅读；格式：<code>正文内容[^脚注标识]</code>，文档末尾添加<code>[^脚注标识]：脚注内容</code>。</p><h3 id="实操示例-10">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 文档正文的脚注标识</span><br><span class="line">这是需要补充说明的正文内容[^1]，脚注会显示在文档末尾。</span><br><span class="line"></span><br><span class="line">// 文档末尾的脚注内容</span><br><span class="line">[^1]：这是脚注的具体说明，可用于补充引用来源、术语解释等。</span><br></pre></td></tr></table></figure><h4 id="效果展示-5">效果展示</h4><p>正文内容：这是需要补充说明的正文内容[^1]，脚注会显示在文档末尾。<br>脚注内容：正文内容[^1]：这是脚注的具体说明，可用于补充引用来源、术语解释等。</p><h3 id="注意事项-13">注意事项</h3><ul><li><p>脚注标识可以是数字、字母等，只要前后一致即可；</p></li><li><p>脚注默认显示在文档末尾，点击正文的脚注标识可快速跳转；</p></li><li><p>部分编辑器不支持脚注，会直接显示原始语法，需提前测试。</p></li></ul><h2 id="2-6-HTML标签扩展（复杂美化）">2.6 HTML标签扩展（复杂美化）</h2><p>Markdown支持嵌入HTML标签，用于实现原生语法无法实现的复杂效果（如合并单元格、自定义样式等）。</p><h3 id="实操示例-11">实操示例</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">// 1. 合并单元格表格（Markdown原生不支持，用HTML实现）</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">table</span> <span class="attr">border</span>=<span class="string">&quot;1&quot;</span> <span class="attr">cellpadding</span>=<span class="string">&quot;5&quot;</span>&gt;</span></span></span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">tr</span>&gt;</span></span></span><br><span class="line"><span class="code">    &lt;th colspan=&quot;2&quot;&gt;合并两列的表头&lt;/th&gt;  // colspan：横向合并</span></span><br><span class="line"><span class="code">  &lt;/tr&gt;</span></span><br><span class="line"><span class="code">  &lt;tr&gt;</span></span><br><span class="line"><span class="code">    &lt;td rowspan=&quot;2&quot;&gt;合并两行的单元格&lt;/td&gt;  // rowspan：纵向合并</span></span><br><span class="line"><span class="code">    &lt;td&gt;普通单元格1&lt;/td&gt;</span></span><br><span class="line"><span class="code">  &lt;/tr&gt;</span></span><br><span class="line"><span class="code">  &lt;tr&gt;</span></span><br><span class="line"><span class="code">    &lt;td&gt;普通单元格2&lt;/td&gt;</span></span><br><span class="line"><span class="code">  &lt;/tr&gt;</span></span><br><span class="line"><span class="code">&lt;/table&gt;</span></span><br><span class="line"><span class="code"></span></span><br><span class="line">// 2. 自定义文本样式（颜色、大小）</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">span</span> <span class="attr">style</span>=<span class="string">&quot;color: red; font-size: 16px;&quot;</span>&gt;</span></span>红色、16号字体的文本<span class="language-xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;background-color: #f0f0f0; padding: 10px;&quot;</span>&gt;</span></span>带灰色背景的文本块<span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure><h4 id="效果展示-6">效果展示</h4><table border="1" cellpadding="5">  <tr>    <th colspan="2">合并两列的表头</th>  // colspan：横向合并  </tr>  <tr>    <td rowspan="2">合并两行的单元格</td>  // rowspan：纵向合并    <td>普通单元格1</td>  </tr>  <tr>    <td>普通单元格2</td>  </tr></table><span style="color: red; font-size: 16px;">红色、16号字体的文本</span><div style="background-color: #f0f0f0; padding: 10px;">带灰色背景的文本块</div><h3 id="注意事项-14">注意事项</h3><ul><li><p>HTML标签需正确闭合，否则可能导致格式错乱；</p></li><li><p>尽量少用HTML标签，避免破坏Markdown的简洁性；仅在原生语法无法实现时使用；</p></li><li><p>不同编辑器对HTML标签的支持程度不同，需提前测试效果。</p></li></ul>]]></content>
    
    
    <summary type="html">从基础写法到常用扩展，把 Markdown 的内核语法慢慢讲清楚。</summary>
    
    
    
    <category term="学习笔记" scheme="https://gwenliu.cn/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
    <category term="程序员必学" scheme="https://gwenliu.cn/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E7%A8%8B%E5%BA%8F%E5%91%98%E5%BF%85%E5%AD%A6/"/>
    
    
    <category term="Markdown" scheme="https://gwenliu.cn/tags/Markdown/"/>
    
    <category term="写作" scheme="https://gwenliu.cn/tags/%E5%86%99%E4%BD%9C/"/>
    
    <category term="学习笔记" scheme="https://gwenliu.cn/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>Claude Code 使用教程</title>
    <link href="https://gwenliu.cn/posts/c4a8d3b1.html"/>
    <id>https://gwenliu.cn/posts/c4a8d3b1.html</id>
    <published>2026-03-04T16:00:00.000Z</published>
    <updated>2026-04-12T15:05:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、Claude Code 是什么</h1><p>Claude Code 是 Anthropic 推出的命令行编程助手。</p><p>它的特点不是“单纯聊天”，而是直接工作在终端里，能配合你的项目目录完成一系列开发任务，比如：</p><ul><li>阅读和理解代码库</li><li>定位报错</li><li>修改文件</li><li>运行命令</li><li>编写文档</li><li>辅助做重构和排查</li></ul><p>如果你已经习惯在终端、VS Code 或 JetBrains 里开发，那它会比单独开一个网页聊天窗口更顺手。</p><hr><h1>二、它适合哪些人</h1><p>Claude Code 比较适合下面几类人：</p><ul><li>已经有一点代码基础，想提高开发效率的人</li><li>需要快速理解陌生项目的人</li><li>想把“提问 + 改代码 + 跑命令”放在同一流程里的人</li></ul><p>如果你完全没有任何编程基础，也可以先把它当成：</p><ul><li>代码讲解器</li><li>报错分析器</li><li>学习时的陪练工具</li></ul><p>但前提仍然是要自己能看懂一点最基础的终端和项目结构。</p><hr><h1>三、安装前要准备什么</h1><p>根据 Anthropic 官方文档，最基本的前置条件有两项：</p><ol><li>Node.js 18 或更高版本</li><li>一个 <a href="http://Claude.ai">Claude.ai</a> 账号或 Anthropic Console 账号</li></ol><p>除此之外，我建议再准备：</p><ul><li>Git</li><li>一个终端工具（PowerShell、Windows Terminal、macOS Terminal 等）</li><li>一个本地项目目录，用来实际练手</li></ul><h2 id="3-1-建议同时装好的基础工具">3.1 建议同时装好的基础工具</h2><ul><li>Node.js：负责安装和运行 CLI</li><li>Git：方便你在项目里查看和提交改动</li><li>VS Code 或 JetBrains：不是必须，但更适合配合项目一起使用</li></ul><h2 id="3-2-如何确认环境是否可用">3.2 如何确认环境是否可用</h2><p>在终端里执行：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">node <span class="literal">-v</span></span><br><span class="line">git <span class="literal">--version</span></span><br></pre></td></tr></table></figure><p>如果都能正常显示版本号，说明环境基本没问题。</p><hr><h1>四、如何安装 Claude Code</h1><p>官方文档里最直接的方式是通过 npm 全局安装：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install <span class="literal">-g</span> @anthropic<span class="literal">-ai</span>/claude<span class="literal">-code</span></span><br></pre></td></tr></table></figure><p>安装完成后，进入你的项目目录，再执行：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">claude</span><br></pre></td></tr></table></figure><p>如果命令能启动，说明安装成功。</p><h2 id="4-1-一次最简单的启动流程">4.1 一次最简单的启动流程</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> your<span class="literal">-project</span></span><br><span class="line">claude</span><br></pre></td></tr></table></figure><p>第一次使用时，通常会涉及登录、授权或基础配置。<br>具体页面和提示可能随着版本更新而变化，按终端提示完成即可。</p><h2 id="4-2-如果提示命令不存在怎么办">4.2 如果提示命令不存在怎么办</h2><p>优先检查这几项：</p><ol><li><code>npm install -g</code> 是否安装成功</li><li>当前终端是否已经重启</li><li>npm 的全局安装路径是否在系统 <code>PATH</code> 里</li></ol><p>在 Windows 上，很多“装了但找不到命令”的问题，本质上都是终端还没重新打开，或者环境变量没刷新。</p><hr><h1>五、初学者第一次上手，建议怎么用</h1><p>很多人第一次打开 Claude Code，就直接丢一句“帮我做个系统”，然后觉得它不稳定。</p><p>更合理的方式是：</p><h2 id="5-1-先让它解释项目">5.1 先让它解释项目</h2><p>比如你可以先问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">先帮我解释一下这个项目目录是做什么的，不要改代码。</span><br></pre></td></tr></table></figure><p>或者：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请先告诉我入口文件、配置文件和核心模块分别在哪里。</span><br></pre></td></tr></table></figure><p>这样做的好处是，你先建立上下文，再决定下一步。</p><h2 id="5-2-再让它做一个小任务">5.2 再让它做一个小任务</h2><p>比如：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">这个页面为什么报错？请先定位原因，再告诉我准备怎么改。</span><br></pre></td></tr></table></figure><p>或者：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">帮我给这个接口补一段注释，不要动其他逻辑。</span><br></pre></td></tr></table></figure><p>先做小任务，可以更容易看出它是不是理解对了。</p><h2 id="5-3-最后再让它做较完整的修改">5.3 最后再让它做较完整的修改</h2><p>当它已经理解项目结构后，再交给它：</p><ul><li>修一个明确的 bug</li><li>新增一个小功能</li><li>优化一段重复逻辑</li><li>补测试或补文档</li></ul><hr><h1>六、适合初学者的 5 种常见用法</h1><h2 id="6-1-读代码">6.1 读代码</h2><p>适合场景：</p><ul><li>刚接手一个新项目</li><li>某个模块看不懂</li><li>想快速知道一个函数被谁调用</li></ul><p>可以这样问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请从初学者角度解释这个模块的作用，并说明它依赖了哪些文件。</span><br></pre></td></tr></table></figure><h2 id="6-2-排查报错">6.2 排查报错</h2><p>适合场景：</p><ul><li>控制台报错</li><li>页面空白</li><li>构建失败</li></ul><p>可以这样问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">这是报错信息，请帮我定位问题，并给出最可能的修复方向。</span><br></pre></td></tr></table></figure><h2 id="6-3-做小功能">6.3 做小功能</h2><p>适合场景：</p><ul><li>增加一个按钮</li><li>新增一个接口字段</li><li>改一处文案或流程</li></ul><p>可以这样问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请先给我一个修改计划，确认后再动代码。</span><br></pre></td></tr></table></figure><h2 id="6-4-补文档">6.4 补文档</h2><p>适合场景：</p><ul><li>README 不完整</li><li>接口文档缺失</li><li>需要给同学解释项目</li></ul><p>可以这样问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请根据当前代码，帮我整理一份面向新人的使用说明。</span><br></pre></td></tr></table></figure><h2 id="6-5-做学习陪练">6.5 做学习陪练</h2><p>如果你还在学习阶段，Claude Code 也很适合拿来问：</p><ul><li>这段代码是什么意思</li><li>为什么会这样写</li><li>这段逻辑还能怎么拆</li><li>如果我自己写，应该先从哪一步开始</li></ul><hr><h1>七、怎样提问，效果会更好</h1><p>Claude Code 不是读心术。<br>你给的信息越清楚，它的结果通常越稳定。</p><h2 id="7-1-一个更好的提问方式">7.1 一个更好的提问方式</h2><p>建议一次说清楚这 4 件事：</p><ol><li>你要它做什么</li><li>改动范围在哪里</li><li>有什么限制</li><li>你希望它先解释还是直接动手</li></ol><p>比如：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请只修改 src/api/user.ts 这一处文件，帮我把登录接口的返回结果改成统一结构。先告诉我你的修改计划，不要直接改。</span><br></pre></td></tr></table></figure><h2 id="7-2-初学者常犯的提问问题">7.2 初学者常犯的提问问题</h2><ul><li>需求太大：一句话要它“重构整个项目”</li><li>范围太模糊：没有说改哪部分</li><li>限制不清楚：没说能不能动配置、能不能装依赖</li><li>不先确认：直接让它大改</li></ul><hr><h1>八、使用 Claude Code 时的基本工作流</h1><p>如果你想把它真正用顺，建议养成下面这套流程：</p><ol><li>进入项目目录</li><li>先让它解释上下文</li><li>再给一个边界清楚的小任务</li><li>看它的修改计划</li><li>审查它的改动</li><li>跑测试或构建</li><li>最后再决定是否提交</li></ol><p>这套流程看起来慢，但其实更稳。<br>尤其对初学者来说，“可控”比“快”更重要。</p><hr><h1>九、常见问题</h1><h2 id="9-1-安装成功了，但-claude-命令不能用">9.1 安装成功了，但 <code>claude</code> 命令不能用</h2><p>优先排查：</p><ul><li>是否重开了终端</li><li>Node.js 是否安装正确</li><li>npm 全局路径是否加入了环境变量</li></ul><h2 id="9-2-能启动，但进不去或无法使用">9.2 能启动，但进不去或无法使用</h2><p>这通常和以下因素有关：</p><ul><li>账号状态</li><li>登录授权</li><li>当前网络环境是否能访问官方服务</li></ul><p>这类问题优先看终端原始报错，再对照官方文档排查。</p><h2 id="9-3-它改了我不想改的地方怎么办">9.3 它改了我不想改的地方怎么办</h2><p>这本质上不是工具坏了，而是约束不够清楚。</p><p>下一次最好直接说：</p><ul><li>只改哪个文件</li><li>不允许动哪些配置</li><li>先出计划，不要直接改</li></ul><h2 id="9-4-它给我的结果我看不懂怎么办">9.4 它给我的结果我看不懂怎么办</h2><p>直接补一句：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">请用初学者能看懂的方式解释，并举一个小例子。</span><br></pre></td></tr></table></figure><p>这类提示通常很有用。</p><hr><h1>十、给初学者的几条使用建议</h1><h2 id="10-1-不要把它当成“自动完成全部工作”的工具">10.1 不要把它当成“自动完成全部工作”的工具</h2><p>它更适合当：</p><ul><li>加速器</li><li>解释器</li><li>排查助手</li><li>草稿生成器</li></ul><p>而不是替你承担全部判断。</p><h2 id="10-2-先学会审查结果">10.2 先学会审查结果</h2><p>再好的工具，也会出现：</p><ul><li>理解偏差</li><li>过度修改</li><li>没看见隐藏依赖</li><li>没覆盖边界情况</li></ul><p>所以最终的代码和命令，还是要你自己确认。</p><h2 id="10-3-先从小任务建立信任">10.3 先从小任务建立信任</h2><p>别一开始就把整个项目交给它。<br>先让它：</p><ul><li>解释 1 个文件</li><li>修 1 个 bug</li><li>改 1 个组件</li><li>写 1 段文档</li></ul><p>这样你会更快找到适合自己的使用方式。</p><hr><h1>十一、推荐的继续学习顺序</h1><p>如果你已经能正常使用 Claude Code，下一步建议补：</p><ol><li>Prompt 基础</li><li>API 调用基础</li><li>Git 工作流</li><li>RAG 和工作流平台</li></ol><p>因为当你同时懂一点开发、Prompt 和系统结构后，Claude Code 的使用效果会明显更好。</p><hr><h1>参考资料</h1><ul><li>Claude Code Overview<br><a href="https://docs.anthropic.com/en/docs/claude-code/overview">https://docs.anthropic.com/en/docs/claude-code/overview</a></li><li>Anthropic Prompt Engineering<br><a href="https://docs.anthropic.com/en/docs/prompt-engineering">https://docs.anthropic.com/en/docs/prompt-engineering</a></li></ul>]]></content>
    
    
    <summary type="html">从安装、启动、基本使用到常见问题，梳理一篇更适合初学者上手的 Claude Code 入门说明。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 使用教程" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="Claude Code" scheme="https://gwenliu.cn/tags/Claude-Code/"/>
    
    <category term="AI 编程" scheme="https://gwenliu.cn/tags/AI-%E7%BC%96%E7%A8%8B/"/>
    
    <category term="Anthropic" scheme="https://gwenliu.cn/tags/Anthropic/"/>
    
    <category term="CLI" scheme="https://gwenliu.cn/tags/CLI/"/>
    
  </entry>
  
  <entry>
    <title>Coze 应用教程</title>
    <link href="https://gwenliu.cn/posts/18e5ab72.html"/>
    <id>https://gwenliu.cn/posts/18e5ab72.html</id>
    <published>2026-01-13T16:00:00.000Z</published>
    <updated>2026-04-12T15:10:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、Coze 是什么</h1><p>Coze 可以把它理解成一个更偏产品化的 AI 应用搭建平台。</p><p>它适合做的事情包括：</p><ul><li>快速搭一个聊天 Bot</li><li>把插件、知识库、提示词组合成一个应用</li><li>用工作流把一个任务拆成多个步骤</li><li>发布成网页、应用或分享链接进行测试</li></ul><p>如果 Dify 更像“低代码 AI 工作流平台”，那 Coze 给很多人的第一感受会更像“更轻一些的 AI Bot 搭建平台”。</p><hr><h1>二、零基础应该先理解哪几个概念</h1><p>无论界面怎么改版，Coze 的核心概念大致都绕不开这几项：</p><h2 id="2-1-Bot">2.1 Bot</h2><p>Bot 可以理解成一个对话式应用。</p><p>通常它至少包含：</p><ul><li>角色设定</li><li>回复规则</li><li>模型选择</li><li>可选的知识库</li><li>可选的插件或工具</li></ul><p>如果你只是想做一个能聊、能回答、能调用少量工具的小应用，Bot 通常是最先接触到的入口。</p><h2 id="2-2-Workflow">2.2 Workflow</h2><p>Workflow 更像一个明确的处理流程。</p><p>你先把步骤排好，再让系统按步骤执行，比如：</p><ol><li>接收用户输入</li><li>提取关键信息</li><li>调工具或知识库</li><li>组织输出</li></ol><p>它的优点是更可控、更容易调试。</p><h2 id="2-3-知识库">2.3 知识库</h2><p>如果你的应用要基于固定资料回答问题，比如：</p><ul><li>产品手册</li><li>课程资料</li><li>公司文档</li></ul><p>那通常需要接入知识库，而不是只靠模型本身的通用知识。</p><h2 id="2-4-插件-工具">2.4 插件 / 工具</h2><p>插件的作用，就是让应用不只会“说话”，还能“做事”，比如：</p><ul><li>搜索新闻</li><li>查询网页</li><li>读外部数据</li><li>调用第三方能力</li></ul><h2 id="2-5-发布与调试">2.5 发布与调试</h2><p>一个应用能不能真正拿给别人用，不在于你是否把页面点通了，而在于：</p><ul><li>测试数据是否覆盖得足够</li><li>失败时有没有兜底</li><li>输出格式是不是稳定</li><li>发布后的入口是否清楚</li></ul><hr><h1>三、零基础建议怎么学 Coze</h1><p>我更建议按下面的顺序学：</p><ol><li>先学 Bot</li><li>再学知识库</li><li>再学 Workflow</li><li>最后再做复杂应用</li></ol><p>为什么？</p><p>因为 Bot 能帮你先理解最基本的三件事：</p><ul><li>角色和提示词怎么写</li><li>模型怎么选</li><li>调试是怎么做的</li></ul><p>如果一上来就做复杂工作流，零基础很容易在节点、变量、分支里迷路。</p><hr><h1>四、先做一个最基础的 Bot</h1><p>最适合入门的，不是“最复杂的智能体”，而是一个职责单一的小 Bot。</p><p>比如：</p><ul><li>新闻整理助手</li><li>学习资料问答助手</li><li>文章润色助手</li></ul><h2 id="4-1-搭建时的基本步骤">4.1 搭建时的基本步骤</h2><p>一个典型流程通常是：</p><ol><li>创建应用</li><li>设定 Bot 名称和用途</li><li>选择底层模型</li><li>写清楚角色与回复规则</li><li>按需加入知识库或插件</li><li>在调试面板里反复测试</li><li>发布后继续观察效果</li></ol><h2 id="4-2-写角色设定时要注意什么">4.2 写角色设定时要注意什么</h2><p>很多人写提示词时喜欢堆很多大段描述，但真正有效的写法通常更清楚：</p><ul><li>你是谁</li><li>你的任务是什么</li><li>你优先回答什么</li><li>你不能做什么</li><li>输出格式是什么</li></ul><p>比如一个学习助手，不要只写“你是一个聪明的助手”，而要写清楚：</p><ul><li>面向谁</li><li>语气是什么</li><li>回复是否要分点</li><li>是否要引用知识库</li></ul><h2 id="4-3-调试时重点看什么">4.3 调试时重点看什么</h2><p>重点看这 4 件事：</p><ol><li>它有没有理解用户问题</li><li>它有没有正确调用工具</li><li>它输出是否稳定</li><li>它在不知道时会不会乱答</li></ol><hr><h1>五、再做一个工作流，理解“编排”这件事</h1><p>当你已经能把 Bot 调顺后，就可以开始接触 Workflow。</p><h2 id="5-1-什么任务适合用-Workflow">5.1 什么任务适合用 Workflow</h2><p>适合用 Workflow 的，通常是步骤比较固定的任务，比如：</p><ul><li>用户输入关键词后，先搜索，再总结</li><li>用户上传资料后，先提取内容，再归纳重点</li><li>先做意图识别，再走不同分支</li></ul><p>如果你的任务本来就可以拆成“第一步、第二步、第三步”，那 Workflow 通常比纯聊天更稳。</p><h2 id="5-2-一个典型工作流的结构">5.2 一个典型工作流的结构</h2><p>你可以把最常见的工作流记成这条链路：</p><ol><li>输入</li><li>参数提取或意图识别</li><li>条件判断</li><li>调模型 / 调工具 / 查知识库</li><li>输出</li></ol><h2 id="5-3-初学者最适合练的两个工作流">5.3 初学者最适合练的两个工作流</h2><h3 id="1-新闻整理工作流">1. 新闻整理工作流</h3><p>输入一个主题，比如“今天的 AI 新闻”，然后：</p><ol><li>提取关键词</li><li>调新闻插件或搜索能力</li><li>把结果整理成固定格式</li></ol><p>这个案例适合练：</p><ul><li>输入处理</li><li>工具调用</li><li>输出格式控制</li></ul><h3 id="2-意图分流工作流">2. 意图分流工作流</h3><p>比如一个简单点餐或客服场景：</p><ol><li>判断用户意图</li><li>根据不同意图走不同节点</li><li>最后统一输出结果</li></ol><p>这个案例适合练：</p><ul><li>意图识别</li><li>多分支处理</li><li>兜底逻辑</li></ul><hr><h1>六、什么时候要接知识库</h1><p>如果你的应用需要基于固定资料回答，而这些资料又不适合全部写进提示词，那就应该接知识库。</p><p>常见场景有：</p><ul><li>课程问答</li><li>产品手册问答</li><li>企业内部 FAQ</li><li>论文或笔记总结</li></ul><h2 id="6-1-接知识库前先想清楚什么">6.1 接知识库前先想清楚什么</h2><p>先别着急导文件，先想 3 个问题：</p><ol><li>你的资料是否足够干净</li><li>你的资料是否真的适合问答</li><li>你的问题是知识查询，还是纯生成任务</li></ol><p>很多知识库效果不好，不是平台不行，而是资料本身：</p><ul><li>太乱</li><li>太长</li><li>重复太多</li><li>没有明显结构</li></ul><h2 id="6-2-知识库接入后怎么验证">6.2 知识库接入后怎么验证</h2><p>接好之后不要只看最终回答，要先看：</p><ul><li>检索出来的片段对不对</li><li>是否经常漏召回</li><li>是否经常召回无关内容</li></ul><p>检索错了，后面的回答再流畅也不可靠。</p><hr><h1>七、Coze 和 Dify 怎么选</h1><p>这两个平台都值得学，但适合的切入点不完全一样。</p><h2 id="7-1-更适合先学-Coze-的情况">7.1 更适合先学 Coze 的情况</h2><ul><li>你想快速做一个 Bot</li><li>你更偏向产品体验和应用搭建</li><li>你想尽快做一个能分享的 Demo</li></ul><h2 id="7-2-更适合先学-Dify-的情况">7.2 更适合先学 Dify 的情况</h2><ul><li>你想更系统地理解工作流</li><li>你要做知识库问答</li><li>你更关心节点、变量、分支、检索这些底层编排能力</li></ul><h2 id="7-3-我给零基础的建议">7.3 我给零基础的建议</h2><p>如果只是想快速建立信心，可以先用 Coze 做一个简单应用。<br>如果是想长期做 AI 应用开发，最好还是把 Dify、RAG、API 调用一起补上。</p><hr><h1>八、初学者最容易犯的错</h1><h2 id="8-1-把所有任务都塞进一个-Bot">8.1 把所有任务都塞进一个 Bot</h2><p>比如同时让一个 Bot：</p><ul><li>查资料</li><li>写文案</li><li>调工具</li><li>做总结</li><li>做翻译</li><li>做客服</li></ul><p>这样通常很难调稳定。<br>更好的方式是一个 Bot 只负责一类任务。</p><h2 id="8-2-只看能不能跑，不看输出稳不稳">8.2 只看能不能跑，不看输出稳不稳</h2><p>有时候第一次测试看起来能跑，但换一个问法就坏了。<br>所以一定要准备多组样例反复测。</p><h2 id="8-3-不做兜底">8.3 不做兜底</h2><p>用户输入永远比你想象得更乱。</p><p>所以流程里最好考虑：</p><ul><li>识别失败怎么办</li><li>工具没结果怎么办</li><li>知识库没命中怎么办</li></ul><h2 id="8-4-过度依赖插件">8.4 过度依赖插件</h2><p>插件当然重要，但不要把问题都寄托在插件上。<br>很多场景真正决定效果的是：</p><ul><li>提示词</li><li>输入约束</li><li>输出结构</li><li>分支设计</li></ul><hr><h1>九、一个更适合零基础的练习顺序</h1><p>建议这样练：</p><ol><li>做一个简单 Bot</li><li>给 Bot 补一套更清楚的提示词</li><li>加入知识库</li><li>做一个只有 3 到 5 个节点的工作流</li><li>给工作流补条件分支</li><li>最后再做复杂应用</li></ol><p>每做完一步，最好都问自己两个问题：</p><ol><li>这一步为什么有效</li><li>如果效果不好，问题最可能出在哪里</li></ol><hr><h1>十、总结</h1><p>Coze 的价值，不只是“点几下就能做个 Bot”，而是它让你用更轻的方式接触到 AI 应用搭建这件事。</p><p>对于零基础学习者来说，更重要的不是一次做多复杂，而是先把下面这些基本功练出来：</p><ul><li>会写角色和任务说明</li><li>会调试输出</li><li>会做简单工作流</li><li>会判断什么时候该加知识库</li><li>会在失败时加兜底</li></ul><p>当你能把一个小应用做得稳定、清楚、可复用时，你就已经跨过“只会用聊天工具”的阶段了。</p>]]></content>
    
    
    <summary type="html">从 Bot、工作流、知识库到发布调试，梳理一篇更适合入门者理解的 Coze 上手说明。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 使用教程" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="Coze" scheme="https://gwenliu.cn/tags/Coze/"/>
    
    <category term="智能体" scheme="https://gwenliu.cn/tags/%E6%99%BA%E8%83%BD%E4%BD%93/"/>
    
    <category term="工作流" scheme="https://gwenliu.cn/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/"/>
    
    <category term="AI 应用" scheme="https://gwenliu.cn/tags/AI-%E5%BA%94%E7%94%A8/"/>
    
  </entry>
  
  <entry>
    <title>RAG 技术入门</title>
    <link href="https://gwenliu.cn/posts/7c2d91fe.html"/>
    <id>https://gwenliu.cn/posts/7c2d91fe.html</id>
    <published>2025-12-01T16:00:00.000Z</published>
    <updated>2026-04-12T15:20:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、RAG 到底解决什么问题</h1><p>RAG 是 Retrieval-Augmented Generation，也就是“检索增强生成”。</p><p>它解决的核心问题不是“让模型更聪明”，而是：</p><blockquote><p>当模型本身不知道，或者不该只靠自己记忆回答时，怎样把外部知识准确接进来</p></blockquote><p>最典型的场景包括：</p><ul><li>企业知识库问答</li><li>产品文档问答</li><li>课程资料辅助学习</li><li>私有笔记总结</li><li>法务、客服、售后类问答</li></ul><p>这些场景有一个共同点：</p><ul><li>信息量大</li><li>更新频繁</li><li>很多内容不在模型训练数据里</li></ul><p>只靠通用模型，很容易：</p><ul><li>答得不准</li><li>答非所问</li><li>一本正经地胡说</li></ul><p>这就是 RAG 的价值所在。</p><hr><h1>二、先别把 RAG 想得太神秘</h1><p>RAG 本质上可以拆成两段：</p><ol><li>先从外部资料中找出相关内容</li><li>再把这些内容交给模型生成答案</li></ol><p>也就是说，RAG 不是“另一个模型”，而是一套系统设计方法。</p><p>你可以把它理解成：</p><ul><li>检索负责“找资料”</li><li>模型负责“读资料并组织答案”</li></ul><p>如果检索错了，模型通常也答不好。<br>所以做 RAG 时，很多问题并不出在“生成”，而是出在“召回”。</p><hr><h1>三、一套最基础的 RAG 链路长什么样</h1><p>对初学者来说，最重要的是先看清全流程。</p><h2 id="3-1-典型链路">3.1 典型链路</h2><p>一个最常见的 RAG 系统，通常包含下面 8 个步骤：</p><ol><li>收集文档</li><li>清洗文档</li><li>文档切块</li><li>生成 Embedding</li><li>存进向量库</li><li>用户提问并转成查询向量</li><li>检索 Top-K 相关片段</li><li>把片段和问题一起交给模型生成答案</li></ol><p>如果你愿意再做得更稳一点，通常还会加上：</p><ol start="9"><li>重排</li><li>结果评估</li><li>来源展示</li><li>无命中兜底</li></ol><hr><h1>四、先学文档处理，再学检索</h1><p>很多初学者一上来就研究向量数据库，其实更应该先把文档处理做好。</p><p>因为垃圾进，垃圾出。</p><h2 id="4-1-文档清洗要做什么">4.1 文档清洗要做什么</h2><p>常见清洗工作包括：</p><ul><li>去掉页眉页脚</li><li>去掉无意义空行</li><li>去掉重复内容</li><li>处理表格、代码块、列表结构</li><li>统一标题层级</li></ul><p>如果你的原始文档本来就很乱，后面的向量检索往往也不会太理想。</p><h2 id="4-2-为什么切块这么重要">4.2 为什么切块这么重要</h2><p>切块是 RAG 的核心环节之一。</p><p>切得太大，会出现：</p><ul><li>无关信息太多</li><li>主题混杂</li><li>模型读取成本高</li></ul><p>切得太小，会出现：</p><ul><li>上下文不完整</li><li>检索到了碎片，但答不清楚</li></ul><p>所以 RAG 的第一门基本功，往往不是调模型，而是学会“怎么切块”。</p><h2 id="4-3-初学者怎么理解切块策略">4.3 初学者怎么理解切块策略</h2><p>最容易入门的思路有两种：</p><h3 id="1-按结构切">1. 按结构切</h3><p>比如按：</p><ul><li>标题</li><li>小节</li><li>段落</li></ul><p>这种方式更贴近人类阅读习惯。</p><h3 id="2-按长度切">2. 按长度切</h3><p>比如：</p><ul><li>固定字符数</li><li>固定 token 数</li><li>带少量 overlap</li></ul><p>这种方式更容易工程化，但要注意不要切得太死板。</p><hr><h1>五、Embedding 和向量数据库分别负责什么</h1><h2 id="5-1-Embedding-的作用">5.1 Embedding 的作用</h2><p>Embedding 的作用，是把一段文本表示成向量。</p><p>这样系统就可以计算：</p><ul><li>哪些文本更相似</li><li>哪些问题和哪段资料更接近</li></ul><p>所以 Embedding 负责的是“把语义变成可计算的数字表示”。</p><h2 id="5-2-向量数据库的作用">5.2 向量数据库的作用</h2><p>向量数据库负责的是：</p><ul><li>存储向量</li><li>建立索引</li><li>做快速相似度检索</li></ul><p>如果数据量很小，直接用内存或简单文件也能做实验。<br>但一旦数据量上来，向量库或带向量能力的数据库就很重要了。</p><h2 id="5-3-初学者怎么选">5.3 初学者怎么选</h2><p>如果你是个人学习或小项目，优先考虑：</p><ul><li>FAISS</li><li>PostgreSQL + pgvector</li><li>Chroma 这类更容易起步的方案</li></ul><p>如果是更大规模、更偏生产场景，再看：</p><ul><li>Milvus</li><li>Qdrant</li><li>Weaviate</li></ul><p>初学阶段最重要的不是选“最火”的，而是选“最容易看懂整条链路”的。</p><hr><h1>六、检索不等于回答，回答也不等于准确</h1><p>很多人第一次做 RAG，会把所有注意力都放在最后回答上。</p><p>其实你应该拆开看三层：</p><ol><li>有没有检索到相关内容</li><li>检索到的内容够不够回答问题</li><li>模型是否基于这些内容正确组织了回答</li></ol><h2 id="6-1-什么叫检索好">6.1 什么叫检索好</h2><p>至少要满足：</p><ul><li>相关内容能被找出来</li><li>无关内容不要太多</li><li>检索结果覆盖关键事实</li></ul><h2 id="6-2-为什么有时候检索到了，结果还是差">6.2 为什么有时候检索到了，结果还是差</h2><p>常见原因有：</p><ul><li>检索片段太碎</li><li>上下文顺序混乱</li><li>模型提示词没约束好</li><li>没有要求“基于资料回答”</li><li>没有处理无命中场景</li></ul><p>所以 RAG 的质量，永远是系统工程，不是只靠一个模型参数。</p><hr><h1>七、进阶一点：为什么很多系统还会加重排</h1><p>当资料变多以后，单纯依赖第一次向量召回，结果不一定总是最优。</p><p>这时很多系统会再加一层“重排”：</p><ul><li>先粗召回一批候选片段</li><li>再对候选片段重新排序</li><li>最后把更相关的内容送给模型</li></ul><p>它的价值在于：</p><ul><li>提高精度</li><li>降低无关噪声</li><li>让最终上下文更聚焦</li></ul><p>对零基础来说，第一步不用急着上重排，但要先知道它为什么存在。</p><hr><h1>八、做 RAG 时应该重点评估什么</h1><p>不要只问一句“这个回答像不像对的”。<br>至少要拆成下面几项来看：</p><h2 id="8-1-召回是否正确">8.1 召回是否正确</h2><p>问题：</p><ul><li>该找到的内容找到了吗</li><li>有没有明显漏召回</li></ul><h2 id="8-2-召回是否干净">8.2 召回是否干净</h2><p>问题：</p><ul><li>无关段落是不是太多</li><li>噪声是否影响后续回答</li></ul><h2 id="8-3-最终回答是否忠实于资料">8.3 最终回答是否忠实于资料</h2><p>问题：</p><ul><li>是否引用了不存在的结论</li><li>是否把资料里的意思说偏了</li></ul><h2 id="8-4-无命中时是否会胡说">8.4 无命中时是否会胡说</h2><p>一个成熟一点的 RAG 系统，应该敢于说：</p><ul><li>没找到相关资料</li><li>当前知识库里没有足够依据</li></ul><p>而不是强行编一个看起来顺的答案。</p><hr><h1>九、零基础最适合做的第一个 RAG 项目</h1><p>我最推荐的第一个练手项目是：</p><h2 id="9-1-个人资料问答助手">9.1 个人资料问答助手</h2><p>你可以准备一批自己的资料，比如：</p><ul><li>课程讲义</li><li>学习笔记</li><li>产品说明</li><li>项目文档</li></ul><p>然后做一个最小系统：</p><ol><li>上传资料</li><li>切块并向量化</li><li>用户提问</li><li>检索相关内容</li><li>返回答案并附带来源</li></ol><p>这个项目的好处是：</p><ul><li>目标清楚</li><li>资料可控</li><li>容易做效果对比</li></ul><h2 id="9-2-第一个版本别做太复杂">9.2 第一个版本别做太复杂</h2><p>第一版只要做到这些就够了：</p><ul><li>文本资料导入</li><li>基本切块</li><li>Top-K 检索</li><li>基于资料回答</li></ul><p>等这一版稳定后，再慢慢补：</p><ul><li>元数据过滤</li><li>重排</li><li>多轮对话</li><li>多模态 RAG</li></ul><hr><h1>十、初学者最容易犯的错</h1><h2 id="10-1-一上来就追求“全能”">10.1 一上来就追求“全能”</h2><p>比如：</p><ul><li>一次接 PDF、Word、图片、网页、音频</li><li>一次上向量检索、关键词检索、重排、多轮记忆</li></ul><p>这样很容易把自己绕晕。</p><p>第一版最重要的是把主链路跑通。</p><h2 id="10-2-不存元数据">10.2 不存元数据</h2><p>很多人只存文本和向量，不存：</p><ul><li>文档名</li><li>标题</li><li>页码</li><li>标签</li><li>来源链接</li></ul><p>这样后面就很难做：</p><ul><li>来源展示</li><li>条件过滤</li><li>召回分析</li></ul><h2 id="10-3-不做无命中兜底">10.3 不做无命中兜底</h2><p>RAG 不是万能问答机。<br>不知道的时候，应该让系统明确说不知道。</p><h2 id="10-4-只调模型，不调检索">10.4 只调模型，不调检索</h2><p>如果检索本身就错了，再换模型通常也救不回来。</p><hr><h1>十一、学 RAG 时推荐看的资料</h1><h2 id="11-1-官方和一手资料">11.1 官方和一手资料</h2><ul><li>OpenAI Embeddings Guide<br><a href="https://platform.openai.com/docs/guides/embeddings">https://platform.openai.com/docs/guides/embeddings</a></li><li>LangChain RAG Tutorial<br><a href="https://python.langchain.com/docs/tutorials/rag/">https://python.langchain.com/docs/tutorials/rag/</a></li><li>pgvector<br><a href="https://github.com/pgvector/pgvector">https://github.com/pgvector/pgvector</a></li><li>Dify Knowledge Base<br><a href="https://docs.dify.ai/en/guides/knowledge-base">https://docs.dify.ai/en/guides/knowledge-base</a></li></ul><h2 id="11-2-可配合阅读的站内文章">11.2 可配合阅读的站内文章</h2><ul><li>《Embeddings和向量数据库》</li><li>《Dify部署与应用》</li></ul><hr><h1>十二、总结</h1><p>RAG 最值得学的地方，不是它有多“高级”，而是它把 AI 应用开发里最关键的一件事摆到了台面上：</p><blockquote><p>模型不能只靠记忆回答，系统要学会先找资料，再组织答案</p></blockquote><p>真正把 RAG 做好，靠的不是某一个神奇技巧，而是整条链路都尽量清楚：</p><ul><li>文档是否干净</li><li>切块是否合理</li><li>向量表示是否合适</li><li>检索是否准确</li><li>回答是否忠实</li><li>无命中时是否诚实</li></ul><p>当你能从这几个角度看一个 RAG 系统时，你就已经不是“会搭个 Demo”，而是在真正理解它了。</p>]]></content>
    
    
    <summary type="html">从文档处理、切块、向量化、检索、重排到回答生成，系统梳理 RAG 的核心链路与入门实践。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 项目" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E9%A1%B9%E7%9B%AE/"/>
    
    
    <category term="向量数据库" scheme="https://gwenliu.cn/tags/%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="RAG" scheme="https://gwenliu.cn/tags/RAG/"/>
    
    <category term="Embedding" scheme="https://gwenliu.cn/tags/Embedding/"/>
    
    <category term="检索增强" scheme="https://gwenliu.cn/tags/%E6%A3%80%E7%B4%A2%E5%A2%9E%E5%BC%BA/"/>
    
  </entry>
  
  <entry>
    <title>Dify 部署与应用</title>
    <link href="https://gwenliu.cn/posts/21eb078f.html"/>
    <id>https://gwenliu.cn/posts/21eb078f.html</id>
    <published>2025-03-11T16:00:00.000Z</published>
    <updated>2026-04-12T15:15:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>一、Dify 是什么</h1><p>Dify 可以理解成一个面向 AI 应用开发的低代码平台。</p><p>它的核心价值不只是“能调模型”，而是把下面这些常见能力整合到了一起：</p><ul><li>模型接入</li><li>Prompt 编排</li><li>知识库</li><li>工作流</li><li>发布和调试</li><li>API 化调用</li></ul><p>所以它很适合用来做：</p><ul><li>企业知识库问答</li><li>内容生成工作流</li><li>表单处理和信息提取</li><li>客服类应用</li><li>内部工具型 AI 助手</li></ul><hr><h1>二、先理解 Dify 里几种常见应用类型</h1><p>在真正开始部署之前，建议先把 Dify 的几种应用类型区分清楚。</p><h2 id="2-1-Chatbot">2.1 Chatbot</h2><p>Chatbot 更偏“对话式应用”。</p><p>适合：</p><ul><li>简单问答</li><li>轻量知识库对话</li><li>日常助手</li></ul><p>优点是上手快，但复杂流程控制相对有限。</p><h2 id="2-2-Workflow">2.2 Workflow</h2><p>Workflow 是单次执行的流程编排。</p><p>它通常从输入开始，按节点一步一步往下走，直到输出结果。</p><p>适合：</p><ul><li>自动摘要</li><li>内容生成</li><li>表单处理</li><li>数据处理流水线</li></ul><h2 id="2-3-Chatflow">2.3 Chatflow</h2><p>Chatflow 可以理解成“带对话层的工作流”。</p><p>它和 Workflow 共用可视化画布，但用户入口是聊天界面。</p><p>适合：</p><ul><li>多轮问答助手</li><li>引导式客服</li><li>需要边问边做的对话应用</li></ul><h2 id="2-4-知识库">2.4 知识库</h2><p>如果你的应用需要基于文档、FAQ、内部资料来回答问题，就离不开知识库。</p><p>知识库不是简单上传文件，而是一整套：</p><ul><li>文档导入</li><li>文本清洗</li><li>切块</li><li>向量化</li><li>检索</li><li>召回测试</li></ul><hr><h1>三、为什么很多人会觉得 Dify 好用</h1><p>因为它把 AI 应用里最常见的几件事，都做成了相对清晰的模块。</p><p>尤其对初学者来说，你能比较直观地看见：</p><ul><li>输入从哪里来</li><li>数据经过了哪些节点</li><li>哪一步调了模型</li><li>哪一步查了知识库</li><li>最后结果是怎么出来的</li></ul><p>这比一上来直接写一整套框架代码，更容易建立系统感。</p><hr><h1>四、用 Docker 部署 Dify 的基本思路</h1><p>对大多数个人学习者来说，Docker Compose 是最稳妥的本地部署方式。</p><h2 id="4-1-部署前准备">4.1 部署前准备</h2><p>建议先准备好：</p><ul><li>Git</li><li>Docker Desktop 或 Docker Engine</li><li>足够的磁盘空间</li><li>一个能访问模型服务的环境</li></ul><p>如果是 Windows，本地部署通常还要确保 Docker Desktop 能正常运行。</p><h2 id="4-2-基本部署流程">4.2 基本部署流程</h2><p>最常见的本地部署步骤如下：</p><h3 id="第一步：拉取仓库">第一步：拉取仓库</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/langgenius/dify.git</span><br></pre></td></tr></table></figure><h3 id="第二步：进入-Docker-目录">第二步：进入 Docker 目录</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> dify/docker</span><br></pre></td></tr></table></figure><h3 id="第三步：复制环境变量模板">第三步：复制环境变量模板</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cp</span> .env.example .<span class="built_in">env</span></span><br></pre></td></tr></table></figure><h3 id="第四步：按需修改配置">第四步：按需修改配置</h3><p>通常至少要关注这些内容：</p><ul><li><code>APP_URL</code></li><li>数据库和缓存相关配置</li><li>文件存储配置</li><li>模型提供商密钥或插件配置</li></ul><h3 id="第五步：启动服务">第五步：启动服务</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure><p>服务启动后，首次访问通常需要完成初始化安装流程。</p><h2 id="4-3-初次安装后优先配置什么">4.3 初次安装后优先配置什么</h2><p>我建议第一时间检查下面几项：</p><ol><li>模型提供商是否已接好</li><li>默认模型是否设置正确</li><li>文件上传和知识库相关配置是否正常</li><li>外部访问地址是否正确</li></ol><hr><h1>五、部署完成后，先不要急着做复杂应用</h1><p>很多人部署好之后，马上想做一个全能助手。<br>这通常不是最好的学习顺序。</p><p>更合理的顺序是：</p><ol><li>先做一个最简单的 Workflow</li><li>再做一个带知识库的问答应用</li><li>最后再尝试复杂流程</li></ol><hr><h1>六、零基础最适合先做什么应用</h1><h2 id="6-1-一个简单的内容生成-Workflow">6.1 一个简单的内容生成 Workflow</h2><p>这是最适合入门的练手项目之一。</p><p>基本思路是：</p><ol><li>用户输入原始材料</li><li>工作流提取重点</li><li>模型按指定风格生成结果</li><li>输出最终文案</li></ol><p>这个项目适合练：</p><ul><li>输入变量</li><li>LLM 节点</li><li>输出控制</li><li>多节点串联</li></ul><h2 id="6-2-一个知识库问答-Chatflow">6.2 一个知识库问答 Chatflow</h2><p>如果你已经有一批资料，比如：</p><ul><li>产品文档</li><li>学习笔记</li><li>常见问题</li></ul><p>那可以尝试做一个知识库问答应用。</p><p>它适合练：</p><ul><li>文档上传</li><li>Chunk 切分</li><li>检索测试</li><li>回答引用上下文</li></ul><hr><h1>七、知识库是 Dify 里非常值得重点学的一块</h1><p>很多人觉得 AI 问答“不准”，其实问题并不在模型，而在知识库处理得不够好。</p><h2 id="7-1-知识库的核心链路">7.1 知识库的核心链路</h2><p>你可以把 Dify 知识库记成下面这条链路：</p><ol><li>导入文档</li><li>清洗文本</li><li>切块</li><li>向量化</li><li>建索引</li><li>检索召回</li><li>把召回结果交给模型</li></ol><h2 id="7-2-切块为什么重要">7.2 切块为什么重要</h2><p>文档不是越大块越好，也不是越碎越好。</p><p>常见问题有：</p><ul><li>块太大：相关信息被噪音淹没</li><li>块太小：上下文不完整</li><li>原始文本太脏：表格、页眉页脚、乱码影响检索</li></ul><p>所以在知识库里，切块策略和文本清洗往往直接决定后续效果。</p><h2 id="7-3-学知识库时建议重点观察什么">7.3 学知识库时建议重点观察什么</h2><p>不要只看最终回答，先看这几项：</p><ol><li>检索出来的片段是不是对的</li><li>命中的内容是否够完整</li><li>是否经常召回无关文本</li><li>没命中时系统会不会胡说</li></ol><hr><h1>八、Workflow 和 Chatflow 到底怎么选</h1><p>这两个概念很容易混。</p><h2 id="8-1-用-Workflow-的情况">8.1 用 Workflow 的情况</h2><p>如果你的任务是：</p><ul><li>输入一次，跑一次</li><li>步骤相对固定</li><li>不强调多轮对话</li></ul><p>那优先用 Workflow。</p><p>例如：</p><ul><li>文章改写</li><li>合同摘要</li><li>表单结构化提取</li></ul><h2 id="8-2-用-Chatflow-的情况">8.2 用 Chatflow 的情况</h2><p>如果你的任务是：</p><ul><li>用户会持续提问</li><li>系统需要保留对话上下文</li><li>每轮回复仍然要走固定流程</li></ul><p>那更适合用 Chatflow。</p><p>例如：</p><ul><li>产品助手</li><li>课程问答助手</li><li>引导式客服</li></ul><h2 id="8-3-一个简单判断标准">8.3 一个简单判断标准</h2><p>如果你想的是“流程”，优先 Workflow。<br>如果你想的是“对话”，优先 Chatflow。</p><hr><h1>九、初学者最容易踩的坑</h1><h2 id="9-1-先搭平台，后补概念">9.1 先搭平台，后补概念</h2><p>只会拖节点，不知道节点背后做了什么，这种学习方式很容易卡住。</p><p>最好至少先补一点：</p><ul><li>Prompt</li><li>API 调用</li><li>RAG</li><li>向量检索</li></ul><h2 id="9-2-只看最终输出，不看中间变量">9.2 只看最终输出，不看中间变量</h2><p>很多问题不是最后一步错了，而是前面的：</p><ul><li>参数提取错了</li><li>条件判断错了</li><li>检索结果错了</li></ul><p>所以调试时一定要看中间变量和节点日志。</p><h2 id="9-3-过早做复杂工作流">9.3 过早做复杂工作流</h2><p>初学者建议先做 3 到 5 个节点的最小流程。</p><p>先把简单链路做通，再慢慢增加：</p><ul><li>条件分支</li><li>知识检索</li><li>工具调用</li><li>文件处理</li></ul><h2 id="9-4-忽视知识库维护">9.4 忽视知识库维护</h2><p>知识库不是“一次上传，永远不管”。</p><p>如果内容更新了、切块策略不合理、旧文档没处理好，效果会很快变差。</p><hr><h1>十、我更推荐的练习顺序</h1><p>如果你是从零开始，建议按下面顺序练：</p><ol><li>先部署好 Dify</li><li>做一个最小 Workflow</li><li>再做一个最小 Chatflow</li><li>接入知识库</li><li>做一次召回测试</li><li>最后做一个完整应用</li></ol><p>这样学，你会比较清楚每一步在系统里扮演什么角色。</p><hr><h1>十一、总结</h1><p>Dify 真正有价值的地方，不只是“可视化”，而是它把 AI 应用的核心组件都摆在了你眼前：</p><ul><li>模型</li><li>Prompt</li><li>知识库</li><li>工作流</li><li>调试</li><li>发布</li></ul><p>如果你想从零开始学 AI 应用开发，Dify 是一个非常好的中间层工具。<br>它既不会像纯代码框架那样一开始就把你压住，也不会像纯聊天工具那样把底层逻辑完全藏起来。</p><p>学 Dify 时，最重要的不是追求画布多复杂，而是先把每一层含义弄明白：</p><ul><li>输入是什么</li><li>节点在做什么</li><li>检索为什么有效</li><li>输出为什么稳定或不稳定</li></ul><p>把这些想清楚之后，你做出来的应用才会越来越像“系统”，而不是只是一张能跑的流程图。</p><hr><h1>参考资料</h1><ul><li>Dify Docs<br><a href="https://docs.dify.ai/">https://docs.dify.ai/</a></li><li>Dify 30-Minute Quick Start<br><a href="https://docs.dify.ai/en/use-dify/getting-started/quick-start">https://docs.dify.ai/en/use-dify/getting-started/quick-start</a></li><li>Workflow &amp; Chatflow<br><a href="https://docs.dify.ai/en/use-dify/build/workflow-chatflow">https://docs.dify.ai/en/use-dify/build/workflow-chatflow</a></li><li>Knowledge Base<br><a href="https://docs.dify.ai/en/guides/knowledge-base">https://docs.dify.ai/en/guides/knowledge-base</a></li><li>Chunking Guide<br><a href="https://docs.dify.ai/en/guides/knowledge-base/create-knowledge-and-upload-documents/chunking-and-cleaning-text">https://docs.dify.ai/en/guides/knowledge-base/create-knowledge-and-upload-documents/chunking-and-cleaning-text</a></li></ul>]]></content>
    
    
    <summary type="html">从平台定位、Docker 部署、知识库、工作流到实际应用场景，系统梳理 Dify 的入门与上手方法。</summary>
    
    
    
    <category term="AI学习" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/"/>
    
    <category term="AI 使用教程" scheme="https://gwenliu.cn/categories/AI%E5%AD%A6%E4%B9%A0/AI-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    
    
    <category term="工作流" scheme="https://gwenliu.cn/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/"/>
    
    <category term="Dify" scheme="https://gwenliu.cn/tags/Dify/"/>
    
    <category term="知识库" scheme="https://gwenliu.cn/tags/%E7%9F%A5%E8%AF%86%E5%BA%93/"/>
    
    <category term="部署" scheme="https://gwenliu.cn/tags/%E9%83%A8%E7%BD%B2/"/>
    
  </entry>
  
</feed>
